Add Slack native progress cards - #29496
Closed
simonvanlaak wants to merge 4 commits into
Closed
Conversation
simonvanlaak
marked this pull request as ready for review
May 21, 2026 07:54
2 tasks
teknium1
reviewed
Jul 13, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for the focused, opt-in Slack progress implementation. The native-card behavior is not present on current main, so the feature remains relevant.
Problems
- After the first native-stream failure,
native_failedis set atgateway/run.py:15755;_send_native_update()then returns immediately atgateway/run.py:15744. Later tool events therefore do not refresh the in-thread text fallback. Please keep updating the fallback after a native failure and add a multi-tool regression test. - The adapter target has moved: this PR edits
gateway/platforms/slack.py, while current main usesplugins/platforms/slack/adapter.py:405after5600105478ffde29d7566b45421b100eaa29c4ef. The adapter and its tests need to be transplanted to the active plugin surface.
Suggested changes
- Preserve a live textual fallback for all later tool updates once native streaming fails.
- Port the adapter and tests to
plugins/platforms/slack/adapter.pyand reconcile the gateway wiring with currentgateway/run.py:17246-17458.
Automated hermes-sweeper review.
menhguin
added a commit
to menhguin/hermes-agent
that referenced
this pull request
Jul 16, 2026
…ress (opt-in)
Renders tool progress on Slack as native collapsible task cards
(chat.startStream/appendStream/stopStream with task_update chunks — the
UI Slack's own AI features use) instead of markdown progress bubbles.
Opt-in via display.platforms.slack.tool_progress_native (default false):
flag off is byte-identical to current behavior on every platform.
Card features: one grouped plan-mode card per turn; per-tool entries
with friendly labels, descriptive completion titles and short output
previews; source-link chips on web tools; live numbered cards for
delegate_task children; interleaved 💭 cards carrying the model's full
reasoning (first-sentence TLDR title, complete text in the collapsible
body). Failed calls render 'complete + ✗' rather than Slack's error
status (red triangle reserved for genuine stream breakage); MCP
text-form errors are sniffed so a 403 doesn't render a checkmark.
Empirically measured Slack API behavior this encodes (docs are wrong or
silent on each): recipient_team_id AND recipient_user_id are required
for bot-token streams despite being documented optional;
task_update.title/status REPLACE per update while details APPENDS
across updates (all details sends are therefore deltas); a streamed
message has an absolute ~306s lifetime regardless of append activity —
handled by proactive rollover onto a fresh streamed message with open
tasks replayed ('⤵ continued below'); msg_too_long is per-chunk, not
cumulative (62k cumulative verified clean); leading whitespace can be
stripped at chunk joins while trailing survives.
Delivery correctness: all sends serialized through a FIFO asyncio.Lock;
tool.started drains the reasoning throttle buffer before the tool card
is scheduled (the model completes reasoning before emitting a tool
call, so the buffered tail belongs before the tool entry); reasoning
flushes cut at sentence boundaries with sub-40-char fragments carried
forward; any API failure self-disables and falls back silently to the
markdown path for the rest of the turn.
Files: gateway/slack_task_stream.py (new, self-contained);
gateway/run.py (flag-gated wiring only); gateway/display_config.py
(toggle + 5 tuning knobs via standard display-setting resolution).
Related: NousResearch#17321 NousResearch#29496 (earlier takes on this surface), NousResearch#54522 (same
feature via GatewayEventDispatcher — happy to migrate onto that seam as
a follow-up once it lands and grows reasoning/subagent event types),
NousResearch#48066 (final-answer draft streaming; complementary, different
transport). Depends on the reasoning-delivery fixes in the sibling
fix/gateway-reasoning-delivery PR.
Co-authored-by: Minh Nguyen <menhguin@users.noreply.github.com>
teknium1
pushed a commit
that referenced
this pull request
Aug 13, 2026
Adds platforms.slack.extra.native_task_cards: when enabled, live tool calls render as Slack-native plan/task cards via chat.startStream / chat.appendStream (task_display_mode: plan, task_update chunks) instead of text/edit progress bubbles. ID-bearing tool_start/tool_complete callbacks correlate concurrent same-name tool calls correctly; any native API failure falls back to one continuously edited text update. The stream is stopped exactly once when the turn finalizes. Salvaged from PR #29496 onto current main (TurnRunner/TurnContext seam); closes #29483.
teknium1
pushed a commit
that referenced
this pull request
Aug 13, 2026
…ace scoping, fallback Ports the test coverage from PR #29496 onto the salvaged implementation: adapter-level serialization/workspace isolation/disconnect sealing, and gateway-level ID-correlated concurrent duplicate tools plus the editable text fallback when the native stream fails.
Contributor
|
Merged via PR #85476 — your implementation was reapplied onto the current TurnRunner/TurnContext seam (gateway/run.py was decomposed since your branch) with your authorship preserved on both the feature and test commits. This closes your issue #29483 too. Thanks for the ID-correlated design and the workspace-scoped stream isolation — both survived intact. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #29483.
This adds an opt-in Slack gateway progress path that renders tool progress through Slack native streaming task cards. When
platforms.slack.extra.native_task_cards: trueis set, Hermes starts a Slack stream withtask_display_mode: plan, appendsplan_update/task_updatechunks as tools start and finish, and stops the stream once the run is finalized.Final assistant replies still use the normal Hermes Slack send path. The native stream is progress-only and remains Slack-specific.
Behavior
complete; tool errors map toerror.Docs
cli-config.yaml.examplenear the existing tool progress setting.Checks
python3 -m py_compile gateway/platforms/slack.py gateway/run.py tests/gateway/test_slack.py tests/gateway/test_run_progress_topics.pygit diff --checkUV_CACHE_DIR=/tmp/uv-cache uv run --with pytest --with pytest-xdist --with pytest-timeout --with pytest-asyncio pytest tests/gateway/test_slack.py::TestNativeTaskCardProgress tests/gateway/test_run_progress_topics.py -q- 39 passedUV_CACHE_DIR=/tmp/uv-cache uv run --with pytest --with pytest-xdist --with pytest-timeout --with pytest-asyncio pytest tests/gateway/test_slack.py -q- 192 passed, 33 existing AsyncMock warningsNotes
I did not perform live Slack runtime validation in this draft. The PR has focused unit coverage for the adapter payloads, gateway progress routing, fallback behavior, and final-response separation.