Skip to Content
SimulatorsSlackAI-app threads

Simulators

AI-app threads

An app built on Bolt’s Assistant class sets a thread’s status, title and suggested prompts with assistant.threads.setStatus, assistant.threads.setTitle and assistant.threads.setSuggestedPrompts. Each takes a bot token and the thread_ts of a thread’s root: any top-level message the bot can read, in a DM or a channel, as on Slack. A reply’s ts returns invalid_thread_ts. The title reads back on the root as assistant_app_thread:

curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"design_studio"}' -o /dev/null
curl -s -X POST "$RYSTIC_URL/api/chat.postMessage" -H 'Authorization: Bearer xoxb-local' -d channel=DWDC0000001 -d 'text=How can I help?' | jq -c '{ok, ts}'
# -> {"ok":true,"ts":"1772323200.000001"}
curl -s -X POST "$RYSTIC_URL/api/assistant.threads.setTitle" -H 'Authorization: Bearer xoxb-local' -d channel_id=DWDC0000001 -d thread_ts=1772323200.000001 -d 'title=Holiday plans' | jq -c .
# -> {"ok":true}
curl -s "$RYSTIC_URL/api/conversations.replies?channel=DWDC0000001&ts=1772323200.000001" -H 'Authorization: Bearer xoxb-local' | jq -c '.messages[0].assistant_app_thread.title'
# -> "Holiday plans"

A status and suggested prompts are shown by the Slack client and returned by no Web API read, here as on Slack. An empty status clears the status. loading_messages takes 1 to 10 items and prompts at most 4, each with a title and a message. setSuggestedPrompts without thread_ts returns not_agent_app. A user token returns not_allowed_token_type from all five methods.

The Agent messaging replacements, agents.sessions.setStatus and agents.sessions.rename, check their arguments as Slack does. Past those checks, agents.sessions.rename returns not_authorized, as Slack does for an app that is not declared an agent, while agents.sessions.setStatus creates or updates the thread’s session and returns its status as Slack’s docs describe. Differs from Slack: neither success was measured, because the Slack app the simulator is measured with is not declared an agent.

Opening the container

A person opens an AI app’s container, or views another channel while it is open, in the Slack client, and no Web API method does either. The simulator serves both as client methods that answer only with X-Rystic-Surface: client and the person’s identity (a bound token or X-Rystic-Actor):

  • assistant.threads.open starts a thread in the person’s DM with the simulator’s app (its bot user, UWDCBOT0001 in design_studio): a root of subtype assistant_app_thread, theirs, titled Chats from <time>. It then sends assistant_thread_started. context_channel_id names the channel in view. The DM must exist; open it with conversations.open first.
  • assistant.threads.setContext takes the thread’s channel_id and thread_ts and the new context_channel_id, and sends assistant_thread_context_changed.

Both events reach your app over Socket Mode or the request URL like every other event:

curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"design_studio"}' -o /dev/null
curl -s -X POST "$RYSTIC_URL/api/assistant.threads.open" -H 'Authorization: Bearer xoxp-anything' -H 'X-Rystic-Actor: UWDC0000003' -H 'X-Rystic-Surface: client' -d context_channel_id=CWDC0000004 | jq -c .
# -> {"channel_id":"DWDC0000001","ok":true,"thread_ts":"1772323200.000001"}
curl -s "$RYSTIC_URL/_rystic/egress" | jq -c '.events[] | {type, thread: .payload.assistant_thread}'
# -> {"type":"assistant_thread_started","thread":{"channel_id":"DWDC0000001","context":{"channel_id":"CWDC0000004","team_id":"TWDC0000001"},"thread_ts":"1772323200.000001","user_id":"UWDC0000003"}}

Differs from Slack: both events, and the root assistant.threads.open writes, follow Slack’s documented examples and were never measured against Slack. The Slack app the simulator is measured with has no Agent experience, so the Slack client offers it no container, and turning that experience on cannot be undone. The simulator sends the events for any app’s bot user, where Slack sends them only to an app with the Agents feature on.

Last updated on