Skip to content

Commit 2173a70

Browse files
feat(slack): add agent sessions and streaming (#7296)
* feat(slack): add agent sessions and streaming * fix(slack): preserve agent workflow compatibility * fix(slack): enforce agent API compatibility * feat(slack): stream trigger responses to agent sessions * fix(slack): polish trigger response streaming * fix(slack): finalize agent session streaming * feat(slack): add slash command triggers
1 parent e5e67b3 commit 2173a70

55 files changed

Lines changed: 4015 additions & 197 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/docs/content/docs/integrations/slack.mdx

Lines changed: 84 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Slack
3-
description: Send, update, delete messages, manage views and modals, add or remove reactions, manage canvases, get channel info and user presence in Slack
3+
description: Send and manage Slack messages, Agent Sessions, streamed replies, views, reactions, conversations, and canvases
44
---
55

66
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -24,9 +24,23 @@ With the Slack integration in Sim, you can:
2424
- **Read messages**: Retrieve recent messages from channels or DMs, with filtering by time range
2525
- **Manage channels and users**: List channels, members, and users in your Slack workspace
2626
- **Download files**: Retrieve files shared in Slack channels for processing within a workflow
27+
- **Build Slack agents**: Manage Agent Sessions, stream replies, handle stop/title/context events, and configure Agent View actions and suggested prompts for custom bots
2728

2829
In Sim, the Slack integration enables your agents to programmatically interact with Slack as part of their workflows. This allows for automation scenarios such as sending notifications with dynamic updates, managing conversational flows with editable status messages, acknowledging important messages with reactions, and maintaining clean channels by removing outdated bot messages. The integration can also be used in trigger mode to start a workflow when a message is sent to a channel.
2930

31+
## Stream Trigger Responses
32+
33+
Custom-bot Slack triggers can stream workflow outputs directly back into the conversation that started a run. Enable **Stream response to Slack** on a Message, App Mention, or Assistant Thread Started trigger, then select the outputs to deliver.
34+
35+
- A selected Agent output streams immediately as it is generated. If the Agent later calls a tool, any pre-tool commentary already streamed remains visible.
36+
- A selected non-streaming block output is sent when that block invocation completes.
37+
- Loop and parallel invocations each create their own Slack response.
38+
- The response status label defaults to `Running` and can be customized in the trigger's advanced settings.
39+
- Optional thinking and tool-call updates appear as Slack tasks in a timeline or plan.
40+
- Slack Agent Sessions remain in processing state for the run, return to active when it finishes, and the native Slack stop button cancels active workflow executions.
41+
42+
Automatic trigger responses require a custom bot created by the Slack setup wizard. They are not available with the shared Sim Slack app.
43+
3044
## AI-Generated Content
3145

3246
Sim workflows may use AI models to generate messages and responses sent to Slack. AI-generated content may be inaccurate or contain errors. Always review automated outputs, especially for critical communications.
@@ -39,7 +53,7 @@ If you encounter issues with the Slack integration, contact us at [help@sim.ai](
3953

4054
## Usage Instructions
4155

42-
Integrate Slack into the workflow. Can send, update, and delete messages, send ephemeral messages visible only to a specific user, open/update/push modal views, publish Home tab views, create canvases, read messages, and add or remove reactions. Requires Bot Token instead of OAuth in advanced mode. Can be used in trigger mode to trigger a workflow when a message is sent to a channel.
56+
Integrate Slack messaging and administration into a workflow. Custom Slack bots can manage Agent Sessions, stream incremental Markdown or structured chunks, react to Agent Session events, and configure Agent View suggested prompts. Standard messaging and management operations support both the Sim app and custom bot credentials.
4357

4458

4559

@@ -802,9 +816,9 @@ Get a stable permalink URL to a specific Slack message.
802816
| `channel` | string | Channel ID containing the message |
803817
| `permalink` | string | The permalink URL to the message |
804818

805-
### Slack Set Assistant Status
819+
### Slack Set Suggested Prompts
806820

807-
Set or clear the assistant thread status indicator (the loading shimmer) on a Slack AI app thread. Pass an empty status to clear it.
821+
Set the clickable suggested prompts shown in a Slack assistant thread (the prompt chips in an AI app).
808822

809823
#### Input
810824

@@ -814,61 +828,86 @@ Set or clear the assistant thread status indicator (the loading shimmer) on a Sl
814828
| `botToken` | string | No | Bot token for Custom Bot |
815829
| `channel` | string | Yes | Channel ID containing the assistant thread \(e.g., C1234567890 or D1234567890\) |
816830
| `threadTs` | string | Yes | Thread timestamp \(thread_ts\) of the assistant thread \(e.g., 1405894322.002768\) |
817-
| `status` | string | No | Status text to display, e.g. 'Working on it…'. Omit or pass an empty string to clear the status. |
818-
| `loadingMessages` | json | No | Optional list of messages to rotate through as an animated loading indicator \(max 10\). |
831+
| `prompts` | json | Yes | Array of prompts, each with a "title" \(shown on the chip\) and a "message" \(sent when clicked\). Max 4. |
832+
| `promptsTitle` | string | No | Optional heading for the prompt list, e.g. 'Suggested Prompts' |
819833

820834
#### Output
821835

822836
| Parameter | Type | Description |
823837
| --------- | ---- | ----------- |
824-
| `ok` | boolean | Whether the status was set successfully |
825-
| `channel` | string | Channel ID the status was set on |
826-
| `threadTs` | string | Thread timestamp the status was set on |
838+
| `ok` | boolean | Whether the suggested prompts were set successfully |
839+
| `channel` | string | Channel ID the prompts were set on |
840+
| `threadTs` | string | Thread timestamp the prompts were set on |
827841

828-
### Slack Set Assistant Title
842+
### Slack Set Agent Suggested Prompts
829843

830-
Set the title of a Slack assistant thread (shown in the AI app thread header).
844+
Set suggested prompts in Slack Agent View, optionally scoped to a specific thread.
831845

832846
#### Input
833847

834848
| Parameter | Type | Required | Description |
835849
| --------- | ---- | -------- | ----------- |
836-
| `authMethod` | string | No | Authentication method: oauth or bot_token |
837-
| `botToken` | string | No | Bot token for Custom Bot |
838-
| `channel` | string | Yes | Channel ID containing the assistant thread \(e.g., C1234567890 or D1234567890\) |
839-
| `threadTs` | string | Yes | Thread timestamp \(thread_ts\) of the assistant thread \(e.g., 1405894322.002768\) |
840-
| `title` | string | Yes | The title to display for the assistant thread |
850+
| `authMethod` | string | No | Slack authentication method |
851+
| `botToken` | string | No | Custom Slack bot token |
852+
| `channel` | string | Yes | Agent direct-message channel ID |
853+
| `threadTs` | string | No | Optional thread timestamp for legacy thread-scoped prompts |
854+
| `prompts` | json | Yes | One to four prompt objects with title and message fields |
855+
| `promptsTitle` | string | No | Optional heading displayed above the prompt chips |
841856

842857
#### Output
843858

844859
| Parameter | Type | Description |
845860
| --------- | ---- | ----------- |
846-
| `ok` | boolean | Whether the title was set successfully |
847-
| `channel` | string | Channel ID the title was set on |
848-
| `threadTs` | string | Thread timestamp the title was set on |
861+
| `ok` | boolean | Whether Slack updated the suggested prompts |
849862

850-
### Slack Set Suggested Prompts
863+
### Slack Set Agent Session Status
851864

852-
Set the clickable suggested prompts shown in a Slack assistant thread (the prompt chips in an AI app).
865+
Create or update the state of a Slack agent session associated with a thread.
853866

854867
#### Input
855868

856869
| Parameter | Type | Required | Description |
857870
| --------- | ---- | -------- | ----------- |
858-
| `authMethod` | string | No | Authentication method: oauth or bot_token |
859-
| `botToken` | string | No | Bot token for Custom Bot |
860-
| `channel` | string | Yes | Channel ID containing the assistant thread \(e.g., C1234567890 or D1234567890\) |
861-
| `threadTs` | string | Yes | Thread timestamp \(thread_ts\) of the assistant thread \(e.g., 1405894322.002768\) |
862-
| `prompts` | json | Yes | Array of prompts, each with a "title" \(shown on the chip\) and a "message" \(sent when clicked\). Max 4. |
863-
| `promptsTitle` | string | No | Optional heading for the prompt list, e.g. 'Suggested Prompts' |
871+
| `authMethod` | string | No | Slack authentication method |
872+
| `botToken` | string | No | Custom Slack bot token |
873+
| `channel` | string | Yes | Channel ID containing the agent session thread |
874+
| `threadTs` | string | Yes | Timestamp of the thread associated with the agent session |
875+
| `status` | string | Yes | Agent session state: active, processing, suspended, or closed |
876+
| `title` | string | No | Title used when creating the agent session, up to 200 characters |
877+
| `initiatorUserId` | string | No | Slack user ID that initiated the session |
878+
| `iconEmoji` | string | No | Emoji used to customize the agent identity |
879+
| `iconUrl` | string | No | Image URL used to customize the agent identity |
880+
| `username` | string | No | Display name used to customize the agent identity |
864881

865882
#### Output
866883

867884
| Parameter | Type | Description |
868885
| --------- | ---- | ----------- |
869-
| `ok` | boolean | Whether the suggested prompts were set successfully |
870-
| `channel` | string | Channel ID the prompts were set on |
871-
| `threadTs` | string | Thread timestamp the prompts were set on |
886+
| `ok` | boolean | Whether Slack updated the agent session |
887+
| `status` | string | Requested agent session status |
888+
| `agentStatus` | string | Agent status recorded by Slack |
889+
| `title` | string | Current agent session title, or null when the session has no title |
890+
891+
### Slack Rename Agent Session
892+
893+
Rename the Slack agent session associated with a thread.
894+
895+
#### Input
896+
897+
| Parameter | Type | Required | Description |
898+
| --------- | ---- | -------- | ----------- |
899+
| `authMethod` | string | No | Slack authentication method |
900+
| `botToken` | string | No | Custom Slack bot token |
901+
| `channel` | string | Yes | Channel ID containing the agent session thread |
902+
| `threadTs` | string | Yes | Timestamp of the thread associated with the agent session |
903+
| `title` | string | Yes | New agent session title, from 1 to 200 characters |
904+
905+
#### Output
906+
907+
| Parameter | Type | Description |
908+
| --------- | ---- | ----------- |
909+
| `ok` | boolean | Whether Slack renamed the agent session |
910+
| `title` | string | Updated agent session title |
872911

873912
### Slack List Channels
874913

@@ -1873,7 +1912,7 @@ A **Trigger** is a block that starts a workflow when an event happens in this se
18731912

18741913
### Slack
18751914

1876-
Trigger from Slack events (mentions, messages, reactions)
1915+
Trigger from Slack events, interactions, and slash commands
18771916

18781917
#### Configuration
18791918

@@ -1886,9 +1925,16 @@ Trigger from Slack events (mentions, messages, reactions)
18861925
| `channelFilter` | channel-selector | No | Restrict to specific channels. Leave empty to trigger on any channel the bot has been added to. |
18871926
| `manualChannelFilter` | string | No | Comma-separated channel IDs to restrict to. Set IDs directly here. |
18881927
| `threads` | string | No | Include thread replies, exclude them \(top-level only\), or fire only on thread replies. |
1928+
| `streamResponse` | boolean | No | Create a Slack agent session and stream selected workflow outputs into the conversation that started this run. Custom bots only. |
1929+
| `streamOutputs` | workflow-output-selector | No | Each selected block invocation creates its own Slack response. Agent outputs stream live; other outputs are sent when the block completes. |
1930+
| `streamTaskTitle` | string | No | Optional status Slack shows while each selected response is being produced. Leave empty to use Running. |
1931+
| `streamTaskDisplayMode` | string | No | Choose how Slack displays thinking and tool progress. |
1932+
| `streamIncludeThinking` | boolean | No | Show agent thinking as Slack task updates while the response is generated. |
1933+
| `streamIncludeToolCalls` | boolean | No | Show tool execution lifecycle as Slack task updates. |
18891934
| `emoji` | string | No | Comma-separated emoji names to restrict to. Leave empty to match any emoji. |
18901935
| `nameContains` | string | No | Only fire when the created channel name contains this text. |
18911936
| `interactionFilter` | string | No | Comma-separated action_ids \(buttons/selects\) or callback_ids \(modals\) to restrict to. Leave empty to fire on any interaction. |
1937+
| `commandFilter` | string | No | Restrict this trigger to one slash command. Leave empty to fire for every command configured on the bot. |
18921938
| `filterBotMessages` | boolean | No | Ignore messages sent by other bots. This app's own output is always ignored. |
18931939
| `includeOwnMessages` | boolean | No | Also fire on this app's own messages and reactions. Can cause loops — use with care. |
18941940
| `includeFiles` | boolean | No | Download and include file attachments from messages. Requires files:read. |
@@ -1909,7 +1955,14 @@ Trigger from Slack events (mentions, messages, reactions)
19091955
|`text` | string | Message text content. For slash commands, the text after the command. For interactivity, the source message text \(falls back to the triggering action value\) |
19101956
|`timestamp` | string | Message timestamp from the triggering event |
19111957
|`thread_ts` | string | Parent thread timestamp \(if message is in a thread\) |
1958+
|`streaming_message_ts` | array | Message timestamps streamed during a stopped agent session |
1959+
|`title` | string | Current agent session title |
1960+
|`previous_title` | string | Previous agent session title |
1961+
|`tab` | string | App Home tab that was opened, including messages for Agent View |
1962+
|`context` | json | Current Agent View context. Normalized from context on app_context_changed/app_home_opened or app_context on message.im |
19121963
|`team_id` | string | Slack workspace/team ID |
1964+
|`user_team_id` | string | Slack workspace/team ID of the user who triggered the event. Used for Slack Connect response streaming. |
1965+
|`enterprise_id` | string | Slack Enterprise Grid organization ID |
19131966
|`event_id` | string | Unique event identifier |
19141967
|`reaction` | string | Emoji reaction name \(e.g., thumbsup\). Present for reaction_added/reaction_removed events |
19151968
|`item_user` | string | User ID of the original message author. Present for reaction_added/reaction_removed events |

apps/sim/app/api/webhooks/slack/custom/[credentialId]/route.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { parseWebhookBody } from '@/lib/webhooks/processor'
66
import { handleSlackChallenge } from '@/lib/webhooks/providers/slack'
77
import {
88
dispatchSlackCustomBotCredential,
9+
handleSlackAgentSessionStopped,
910
verifySlackCustomBotCredentialRequest,
1011
} from '@/lib/webhooks/slack-custom-ingress'
1112
import { getSlackDispatchResponse } from '@/lib/webhooks/slack-dispatch'
@@ -68,12 +69,15 @@ async function handleSlackCustomBotWebhook(
6869
return authError
6970
}
7071

71-
const dispatchResults = await dispatchSlackCustomBotCredential({
72-
credentialId,
73-
body,
74-
request,
75-
requestId,
76-
receivedAt,
77-
})
72+
const [, dispatchResults] = await Promise.all([
73+
handleSlackAgentSessionStopped(credentialId, body),
74+
dispatchSlackCustomBotCredential({
75+
credentialId,
76+
body,
77+
request,
78+
requestId,
79+
receivedAt,
80+
}),
81+
])
7882
return getSlackDispatchResponse(dispatchResults)
7983
}

0 commit comments

Comments
 (0)