Salambo
Browse documentation
Build agentsBuild channel-aware agents

Build channel-aware agents

Adapt agent behavior to Slack, Microsoft Teams, and API conversations without exposing provider credentials.

View Markdown

Salambo delivers message text as the normal agent input. For integration-triggered turns, tools and hooks also receive bounded channel metadata in ctx.external.

Branch by provider

js
export default function channelPolicy(pi) {
  pi.on("before_agent_start", (event, ctx) => {
    const external = ctx.external;

    if (!external) {
      return;
    }

    const instruction =
      external.provider === "slack"
        ? "Use short paragraphs suitable for Slack."
        : external.provider === "microsoft_teams"
          ? "Use a concise Teams-friendly response."
          : "Use a concise chat response.";

    return {
      systemPrompt: `${event.systemPrompt}\n\n${instruction}`,
    };
  });
}

For API, playground, scheduled, or other non-channel turns, ctx.external is null.

Use conversation identity in a tool

js
pi.registerTool({
  name: "current_conversation",
  description: "Return the current external conversation identity.",
  parameters: {
    type: "object",
    properties: {},
    additionalProperties: false,
  },
  async execute(_id, _params, _signal, _update, ctx) {
    if (!ctx.external) {
      return {
        content: [
          { type: "text", text: "This turn is not from a chat integration." },
        ],
      };
    }

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify({
            provider: ctx.external.provider,
            conversationId: ctx.external.conversationId,
            conversationType: ctx.external.conversationType,
          }),
        },
      ],
    };
  },
});

Security boundary

ctx.external contains identifiers and routing metadata. It does not contain:

  • Slack or Teams access tokens;
  • signing secrets or client secrets;
  • provider credentials;
  • the message text;
  • arbitrary raw webhook bodies.

Treat identifiers as customer metadata. Do not publish them in artifacts or external logs unless the product requires it.

See the exact external event context, then choose a channel-aware recipe.