Feature · @linda/hooks

Nineteen lifecycle hooks.

Every moment in the agent loop you might care about is a hook. Programmatic handlers, JSON-declared webhooks, or both. Each one can observe, transform, or veto.

The veto + transform pipeline

Every hook handler can return:

  • undefined — pass through unchanged.
  • { veto: true, reason: "..." } — block the action; the agent gets the reason.
  • { mutation: { value: "..." } } — rewrite the payload.

Multiple handlers run in registration order. The first veto wins. Mutations chain.

linda.on("beforeFieldFill", ({ field, value, source }) => {
  if (field === "email" && !value.includes("@")) {
    return { veto: true, reason: "needs @" };
  }
  if (source === "agent") {
    return { mutation: { value: value.toLowerCase() } };
  }
});

linda.on("onComplete", async ({ data }) => {
  await fetch("/api/save", {
    method: "POST",
    body: JSON.stringify(data),
  });
});

The events

  • onUserMessage Fires every time the user sends a message.
  • onAgentMessage Fires when the model finishes a response.
  • beforeFieldFill Veto or transform an agent's attempt to fill a form field.
  • afterFieldFill Fires after a successful fill — log, persist, validate.
  • onComplete Fires when the agent decides the flow is done.
  • onFileUpload Fires when a user drops a file; parsed artifacts attached.
  • onSkillActivate Fires when the model loads a skill from /skills/installed/.
  • onHandoff Fires on multi-agent handoff. Hook can veto.
  • onToolCall Fires before any tool call. Useful for audit logs.
  • onError Fires on any uncaught error in the loop.
  • onOpen Fires when the chat overlay opens.
  • onClose Fires when the chat overlay closes.
  • onStreamDelta Fires on every streamed token (~30/s).
  • onStateChange Fires when the persistent state mutates.
  • beforeTransport Mutate the LLM request envelope before send.
  • afterTransport Inspect the LLM response after receive.
  • onTriggerFire Fires when a behavioral trigger (exit-intent, hesitation) fires.
  • onCapabilitiesChange Fires when browser capabilities change at runtime.
  • onSlashCommand Fires when the user types /reset, /skills, etc.

Declarative webhooks

If you're using the script-tag UMD and don't ship JS yourself, hooks can be declared as JSON pointing at HTTP endpoints. Linda POSTs the event payload, awaits, and applies the veto/mutation from the response.

{
  "hooks": {
    "onComplete": "https://api.example.com/linda-complete",
    "beforeFieldFill": "https://api.example.com/linda-validate"
  }
}

Read the full hooks docs →

Ship an agent-driven flow this afternoon.

Install Linda, paste a config, and your form turns into an agent that fills its own inputs.