Skip to content

docs: add say_stream notes to the experiments page#1463

Open
lukegalbraithrussell wants to merge 4 commits intodocs-agent-kitfrom
docs-say_stream-docs
Open

docs: add say_stream notes to the experiments page#1463
lukegalbraithrussell wants to merge 4 commits intodocs-agent-kitfrom
docs-say_stream-docs

Conversation

@lukegalbraithrussell
Copy link
Copy Markdown
Contributor

@lukegalbraithrussell lukegalbraithrussell commented Mar 19, 2026

Summary

This PR adds docs for the say_stream helper in the sending messages page. Picture is the preview:

/tools/bolt-python/concepts/message-sending:

image

Testing

Category

  • slack_bolt.App and/or its core components
  • slack_bolt.async_app.AsyncApp and/or its core components
  • Adapters in slack_bolt.adapter
  • Document pages under /docs
  • Others

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

  • I've read and understood the Contributing Guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've run ./scripts/install_all_and_run_tests.sh after making the changes.

"label": "Experiments",
"items": ["tools/bolt-python/experiments"]
},
"tools/bolt-python/experiments",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was my bad; should've been a page from the beginning

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.31%. Comparing base (ba7df02) to head (fd123aa).
⚠️ Report is 1 commits behind head on docs-agent-kit.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@                Coverage Diff                 @@
##           docs-agent-kit    #1463      +/-   ##
==================================================
- Coverage           91.43%   91.31%   -0.12%     
==================================================
  Files                 232      229       -3     
  Lines                7340     7266      -74     
==================================================
- Hits                 6711     6635      -76     
- Misses                629      631       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Base automatically changed from say_stream to main March 19, 2026 13:57
@WilliamBergamin WilliamBergamin requested a review from a team as a code owner March 19, 2026 13:57
@zimeg zimeg changed the title Docs: say_stream docs: add say_stream notes to the experiments page Mar 19, 2026
@zimeg zimeg added docs Improvements or additions to documentation semver:patch experiment Experimental feature documented with ExperimentalWarning and pydoc Experiment section labels Mar 19, 2026
@zimeg
Copy link
Copy Markdown
Member

zimeg commented Mar 19, 2026

⚠️ Merge conflicts bewarned! These commits might show odd diff now I think?

@lukegalbraithrussell
Copy link
Copy Markdown
Contributor Author

⚠️ Merge conflicts bewarned! These commits might show odd diff now I think?

@zimeg I reset the branch to just be docs changes!

Copy link
Copy Markdown
Contributor

@WilliamBergamin WilliamBergamin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work on this 🥇 Wasn't sure how to frame all this but this is spot on


## `say_stream` utility {#say-stream}

The `say_stream` utility is a listener argument available on `app.event` and `app.message` listeners.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 💯

| `recipient_team_id` | Sourced from the event `team_id` (`enterprise_id` if the app is installed on an org).
| `recipient_user_id` | Sourced from the `user_id` of the event.

If neither a `channel_id` or `thread_ts` can be sourced, then the utility will merely be `None`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic 🥇

@app.message("")
def handle_message(client: WebClient, say_stream: SayStream):
stream = say_stream()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: do we need this empty space?

@lukegalbraithrussell lukegalbraithrussell changed the base branch from main to docs-agent-kit March 20, 2026 18:49
Copy link
Copy Markdown
Contributor

@srtaalej srtaalej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks really great luke! ⭐

* [`chat_stopStream`](/reference/methods/chat.stopStream)

The Python Slack SDK provides a [`chat_stream()`](https://docs.slack.dev/tools/python-slack-sdk/reference/web/client.html#slack_sdk.web.client.WebClient.chat_stream) helper utility to streamline calling these methods. Here's an excerpt from our [Assistant template app](https://github.com/slack-samples/bolt-python-assistant-template):
Bolt for Python provides a `say_stream` listener argument available on `app.event` and `app.message` listeners.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super nice ⭐

| `recipient_team_id` | Sourced from the event `team_id` (`enterprise_id` if the app is installed on an org).
| `recipient_user_id` | Sourced from the `user_id` of the event.

If neither a `channel_id` or `thread_ts` can be sourced, then the utility will merely be `None`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: i feel like this can be clearer

Suggested change
If neither a `channel_id` or `thread_ts` can be sourced, then the utility will merely be `None`.
If neither a `channel_id` or `thread_ts` can be sourced, then the utility will just be `None`.

Copy link
Copy Markdown
Member

@mwbrooks mwbrooks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Looking great! I've left a few minor suggestions but nothing is blocking.

Comment on lines +46 to 50
You can have your app's messages stream in to replicate conventional agent behavior. This is done through three Web API methods:

* [`chat_startStream`](/reference/methods/chat.startStream)
* [`chat_appendStream`](/reference/methods/chat.appendStream)
* [`chat_stopStream`](/reference/methods/chat.stopStream)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit(non-blocking): Showing the 3 Web API methods to manually stream messages at the very top is a little confusing. Also, L54 mentions that say_stream uses this API under-the-hood and there's a nice callout at the bottom explaining how to manually use the Web API Streaming methods.

Could this sentence be merged with the next paragraph? For example:

You can have your app's messages stream in to replicate conventional agent behaviour. Bolt for Python provides a say_stream utility is available on app.event and app.message listeners.

* [`chat_stopStream`](/reference/methods/chat.stopStream)

The Python Slack SDK provides a [`chat_stream()`](https://docs.slack.dev/tools/python-slack-sdk/reference/web/client.html#slack_sdk.web.client.WebClient.chat_stream) helper utility to streamline calling these methods. Here's an excerpt from our [Assistant template app](https://github.com/slack-samples/bolt-python-assistant-template):
Bolt for Python provides a `say_stream` listener argument available on `app.event` and `app.message` listeners.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The current sentence is correct, but "argument" is often thought of as a simple variable or object. We use the term "utility" below, so maybe can clarify that say_stream is a utility provided as a listener argument.

Suggested change
Bolt for Python provides a `say_stream` listener argument available on `app.event` and `app.message` listeners.
Bolt for Python provides a `say_stream` utility as a listener argument for `app.event` and `app.message` listeners.

### Limitations

The `chat_stream()` method currently only works when the `thread_ts` field is available in the event context (DMs and threaded replies). Top-level channel messages do not have a `thread_ts` field, and the `ts` field is not yet provided to `BoltAgent`. No newline at end of file
The `chat_stream()` method currently only works when the `thread_ts` field is available in the event context (DMs and threaded replies). Top-level channel messages do not have a `thread_ts` field, and the `ts` field is not yet provided to `BoltAgent`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I believe we've fixed this issue so say_stream() is now available on top-level channel messages and uses the ts as the thread_ts value. We've also updated chat_stream() to be say_stream().

.cc @WilliamBergamin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation experiment Experimental feature documented with ExperimentalWarning and pydoc Experiment section semver:patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants