Browse documentation
Channel-aware agent recipes
Practical extension patterns for Slack and Microsoft Teams conversations.
View MarkdownThese recipes use ctx.external while keeping message transport, authentication, deduplication, and replies owned by Salambo.
Slack thread-aware instructions
export default function slackBehavior(pi) {
pi.on('before_agent_start', (event, ctx) => {
const external = ctx.external;
if (external?.provider !== 'slack') {
return;
}
const location = external.refs.threadTs
? 'an existing Slack thread'
: 'a new Slack conversation';
return {
systemPrompt: `${event.systemPrompt}\n\nThis request came from ${location}. Reply concisely and do not repeat the full question.`,
};
});
}Teams channel-aware instructions
export default function teamsBehavior(pi) {
pi.on('before_agent_start', (event, ctx) => {
const external = ctx.external;
if (external?.provider !== 'microsoft_teams') {
return;
}
const audience = external.refs.channelId
? 'a Teams channel'
: 'a direct Teams conversation';
return {
systemPrompt: `${event.systemPrompt}\n\nThe audience is ${audience}. Keep the answer clear for everyone in that conversation.`,
};
});
}Restrict a sensitive tool to direct messages
pi.on('tool_call', (event, ctx) => {
if (event.toolName !== 'lookup_private_customer_record') {
return;
}
if (ctx.external && ctx.external.conversationType !== 'dm') {
return {
block: true,
reason:
'Private customer records can only be queried from a direct message.',
};
}
});Decide separately whether API-originated turns (ctx.external === null) are allowed. The example allows them.
Attach routing metadata to tool details
async function execute(_id, params, _signal, _update, ctx) {
const external = ctx.external;
return {
content: [{ type: 'text', text: 'Request recorded.' }],
details: {
requestId: params.requestId,
provider: external?.provider ?? null,
conversationId: external?.conversationId ?? null,
},
};
}Do not copy provider tokens, complete messages, or unnecessary sender identifiers into tool results.
Preserve transport ownership
Extensions should adapt agent behavior, not send Slack or Teams replies directly. Salambo owns webhook verification, idempotency, conversation mapping, turn creation, and provider delivery.
For setup, use the Slack guide or Microsoft Teams guide.