Skip to main content
This example gives your team a conversational agent with its own Slack presence: mention @assistant in a channel to start a conversation, and every reply in that thread routes back to the same session, so the agent keeps its memory for the life of the thread. It is the simplest end-to-end factory workflow — one agent, one trigger pair, no repository — and the best first install, because the output lands directly in front of the people evaluating it.

How it works

The example is the canonical demonstration of spawn vs. deliver routing on the same event, split by whether the thread already belongs to a session: The moving parts:
  • A fresh mention spawns and binds in one step. The spawn route’s bind: { target: slack.thread } writes the thread binding as part of session creation, so the agent never has to “subscribe” manually.
  • $.auto.attributions lists the sessions bound to the thread (for an addressed mention, filtered to the addressed agent). exists: false means “no session of mine holds this thread yet” — spawn; exists: true means one does — deliver into it.
  • Every reply in a bound thread arrives as chat.message.subscribed and delivers to the bound session via attributedSessions, interrupting whatever the session was doing so the conversation feels live.
  • The inline identity: block is what makes the agent a mentionable presence — display name, @assistant handle, avatar — in the connected Slack workspace. See connections and identities.
This trigger pair is validated at apply time, not just convention: a chat deliver trigger routed by attributedSessions must filter $.auto.authored: false (so the agent never loops on its own messages), and a spawn trigger sharing an event with such a deliver trigger must carry the mutually exclusive $.auto.attributions filters shown here. Configurations that break either rule fail to apply. See the trigger reference.

Reference-only example

Chat Assistant is retired from the managed roster. This page remains a worked example of chat spawn/deliver attribution; there is no current managed entrypoint to import.

The full configuration

.auto/fragments/environments/agent-runtime.yaml
.auto/agents/assistant.yaml
There is no mount and no GitHub tool: the agent’s entire surface is the chat tool plus the auto tool, which is what makes it safe to point at a whole workspace.

Walkthrough

1

Someone mentions the agent

A teammate writes @assistant can you summarize this thread?. Slack delivers the event; ingress resolves the mention to this agent and normalizes it to chat.message.mentioned. No session of this agent holds the thread, so $.auto.attributions is absent — the mention trigger matches.
2

Spawn, bound to the thread

routing: spawn starts a session, and bind: { target: slack.thread } binds the thread to it at spawn. The event payload ({{message.text}}, {{chat.channelId}}, {{chat.threadId}}, author) arrives as the session’s first message.
3

The agent replies in-thread

The agent calls chat.send with provider slack, the triggering channel, and the triggering thread — falling back to the message timestamp as the new thread root when the mention wasn’t already in a thread. chat.send returns the threadId, so subsequent sends stay threaded.
4

Replies keep the context

The teammate replies in the thread — no re-mention needed. The reply arrives as chat.message.subscribed, now carrying $.auto.attributions for the bound session, so thread-reply delivers it straight into the running session via attributedSessions. The agent answers with its full conversational memory. $.auto.authored: false guarantees its own messages never echo back into it.
5

Parallel threads, parallel sessions

A mention in a different thread has no attribution for this agent, so it spawns a second, independent session bound to that thread. Each conversation gets its own memory; onUnmatched: drop means replies to a thread whose session has ended are dropped silently rather than resurrecting a context-free agent.

Variations

  • Make it an expert. The base agent is deliberately tool-poor. Add a read-only git mount of your repo and it answers codebase questions; add a docs MCP server (any mcp_remote tool or hosted connection provider) and it cites your internal docs. Adjust the systemPrompt’s hard limits to match whatever you grant. See tools.
  • Direct messages. DMs arrive as chat.message.direct and auto-subscribe their thread. Add that event key to the triggers to make the assistant answer DMs with the same spawn/deliver split.
  • Other chat providers. Slack, Discord, and Telegram share the same chat.* event contract. Point connection: at the other workspace’s connection and adjust the $.chat.provider filter — or drop the filter and let one assistant listen across providers. See Slack events and Telegram events.
  • A different persona. Rename the agent, identity.displayName, identity.username, and the avatar asset — identity is entirely yours; the routing machinery doesn’t care.
  • Smoke test. After apply, mention the agent in a test channel, confirm the in-thread reply, then reply again and confirm it remembers the conversation. This doubles as the standard end-to-end check that events, sessions, and the Slack connection are all healthy.