In plain terms
Three ways to attach your own code:
The event bus is also for watching. Prefer
hooks when you already have the agent object. Prefer onAny for tracers.
hooks — the four doorbells
loopHooks.beforeToolExec.
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Agentium 4.0.0 · Upgrade from 3.x.
Hooks watch a run. Guardrails can say no. Loop hooks steer the tool loop.
| Thing | Job | Example |
|---|---|---|
hooks | Watch. Log. Count. | ”Print when a run starts.” |
guardrails | Block. | ”Refuse if the user says a password.” |
loopHooks | Steer inside the tool loop. | ”Skip delete_all and pretend it failed.” |
hooks when you already have the agent object. Prefer onAny for tracers.
| Hook | When |
|---|---|
beforeRun | Right before the model is called |
afterRun | After a successful answer |
onToolCall | A tool is about to run |
onError | Something threw |
hooks: {
beforeRun: async (ctx) => console.log("start", ctx.runId),
afterRun: async (ctx, output) => console.log(output.usage.totalTokens, "tokens"),
onToolCall: async (ctx, name, args) => console.log("tool", name, args),
onError: async (ctx, err) => console.error(err.message),
}
loopHooks.beforeToolExec.
guardrails: {
input: [{
name: "no-secrets",
validate: async (input) => {
const text = typeof input === "string" ? input : "";
if (text.includes("sk-")) return { pass: false, reason: "looks like an API key" };
return { pass: true };
},
}],
}
loopHooks: {
beforeToolExec: async (name) => {
if (name === "drop_database") return { skip: true, result: "blocked" };
},
onRoundtripComplete: async (n, tokens) => {
if (tokens.totalTokens > 50_000) return { stop: true };
},
}