Salambo
Browse documentation
Build agentsReact to lifecycle events

React to lifecycle events

Adapt prompts, tools, model behavior, and results with supported hosted hooks.

View Markdown

Use pi.on(eventName, handler) when behavior belongs around the agent lifecycle rather than inside a model-callable tool.

Make Slack responses concise

js
export default function channelBehavior(pi) {
  pi.on('before_agent_start', (event, ctx) => {
    if (ctx.external?.provider !== 'slack') {
      return;
    }

    return {
      systemPrompt: `${event.systemPrompt}\n\nFor Slack, keep the response concise and easy to scan.`,
    };
  });
}

All hosted handlers receive (event, ctx). event depends on the hook. ctx.external contains bounded integration metadata or null.

Select tools for a turn

Call runtime-changing methods inside a handler, not at module discovery time:

js
export default function toolPolicy(pi) {
  pi.on('before_agent_start', async (_event, ctx) => {
    if (ctx.external?.conversationType === 'channel') {
      await pi.setActiveTools(['read', 'bash', 'lookup_customer']);
    }
  });
}

The requested names must belong to the deployment's allowed tool set. Salambo restores the selected tools on durable follow-up turns.

Block a tool call

js
pi.on('tool_call', (event) => {
  if (
    event.toolName === 'bash' &&
    typeof event.input.command === 'string' &&
    event.input.command.includes('rm -rf')
  ) {
    return {
      block: true,
      reason: 'Destructive recursive deletion is not allowed.',
    };
  }
});

tool_call handlers may block a call. They may also mutate event.input in place; later handlers and execution receive the resulting input.

Annotate a tool result

js
pi.on('tool_result', (event) => {
  if (event.toolName !== 'lookup_customer' || event.isError) {
    return;
  }

  return {
    details: {
      ...event.details,
      reviewedBy: 'customer-policy-extension',
    },
  };
});

Choose a hook deliberately

GoalHook
Modify the prompt or select model/toolsbefore_agent_start
Allow or block a tool calltool_call
Transform a tool resulttool_result
Transform model context messagescontext
Adjust provider stream optionsbefore_provider_request
Inspect or replace provider payloadbefore_provider_payload
Observe provider response metadataafter_provider_response
Participate in compactionsession_before_compact, session_compact
Observe model or thinking changesmodel_update, thinking_level_update

Hooks are bounded to 10 seconds. A timeout, thrown error, or invalid result fails the active extension operation rather than silently ignoring it.

See the authoritative hook event reference for every supported event and return contract.