# Build channel-aware agents

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

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](/docs/integrations/external-context), then choose a [channel-aware recipe](/docs/integrations/channel-recipes).
