Skip to content

fix(slack): keep transient status in assistant UI - #45109

Closed
goblin-zavala wants to merge 1 commit into
NousResearch:mainfrom
goblin-zavala:operator/slack-assistant-status-upstream-pr
Closed

fix(slack): keep transient status in assistant UI#45109
goblin-zavala wants to merge 1 commit into
NousResearch:mainfrom
goblin-zavala:operator/slack-assistant-status-upstream-pr

Conversation

@goblin-zavala

Copy link
Copy Markdown

Summary

Keeps transient gateway lifecycle/status updates in Slack Assistant status instead of falling back into permanent chat messages.

This preserves the Slack Assistant bottom status affordance for semantic states like compacting context, recalling prior context, reading files, and drafting the reply, while keeping internal lifecycle plumbing out of user-visible message history.

What changed

  • Routes supported status events through assistant_threads_setStatus when Slack thread metadata is available.
  • Maps transient lifecycle messages such as preflight compression/context compaction into compact Assistant status text.
  • Avoids posting internal status/progress strings as normal Slack chat messages.
  • Clears Assistant status after final sends / streaming final edits.
  • Adds focused Slack tests for status routing, missing scope fallback, and final status clearing.

Tests

  • pytest -o 'addopts=' tests/gateway/test_slack.py -k 'send_or_update_status or gateway_restart_status_wording_is_natural or sets_status_in_thread or noop_without_thread or missing_scope or stop_typing or send_clears_status_after_final_post or streaming_final_edit_clears_status' -q
    • 13 passed, 186 deselected
  • python -m py_compile gateway/run.py gateway/platforms/slack.py tests/gateway/test_slack.py
  • git diff --check HEAD~1..HEAD

@liuhao1024

Copy link
Copy Markdown
Contributor

Review: Org-specific MCP tool names in shared Slack adapter

The _assistant_activity_status() method in gateway/platforms/slack.py hardcodes several organization-specific MCP tool names in the activity_map:

(("mcp_zoblin_connections_close", "close_"), "is checking Close"),
(("mcp_zoblin_connections_growth_n8n", "n8n"), "is checking n8n"),
(("mcp_zoblin_connections_railway", "railway"), "is checking Railway"),
(("mcp_google_sheets", "sheet"), "is checking Sheets"),
(("mcp_ga4", "analytics"), "is checking analytics"),

These are specific to one deployment's MCP server configuration (zoblin_connections_*) and won't match any other user's tool set. They'll silently never trigger for anyone else, which is harmless but clutters the shared adapter.

Suggestion: Move these to the generic fallback path or make the activity map configurable. The generic entries (read_file, terminal, web_search, etc.) are universally useful — the MCP-specific ones belong in user/plugin configuration, not in the shared platform adapter.

@goblin-zavala

Copy link
Copy Markdown
Author

Closing: this was opened from the wrong ownership model. These Hermes operator changes are local/private unless Zavala explicitly chooses a remote under zavala-ai.

@goblin-zavala
goblin-zavala deleted the operator/slack-assistant-status-upstream-pr branch June 12, 2026 18:12
teknium1 added a commit that referenced this pull request Jul 18, 2026
Builds on the salvaged typing_status_text plumbing (PR #62007): instead
of a static 'is thinking...', Slack's assistant status line now updates
live as the agent works — 'is running pytest tests/…', 'is reading
docs/api.md…' — and reverts to the static text between tool calls.

Mechanics:
- agent/display.py: build_status_phrase() derives a <=49-char present-
  tense phrase from the existing _TOOL_VERBS table (+ 'is using <name>'
  for plugin/MCP tools; None for _thinking).
- base adapter: supports_status_text capability flag + set_status_text()
  per-chat store, cleared when the typing loop winds down.
- Slack adapter: send_typing() renders the live phrase when set, falling
  back to typing_status_text then 'is thinking...'.
- gateway/run.py: progress_callback stashes the phrase on tool.started
  and clears on tool.completed. Rendering rides the existing
  _keep_typing refresh cadence — zero additional Slack API calls, no
  rate-limit exposure. Works with tool_progress: off (Slack default);
  the callback is now armed whenever the adapter supports status text.
- display.live_status config (full|verb|off, default full): 'verb' hides
  argument previews for shared/customer-facing channels.

Also fixes a latent crash in the cherry-picked from_dict: malformed
non-dict 'extra' sections broke typing_status_text resolution (uses the
already-coerced extra dict).

Design notes: status text is a side-effect display channel only — never
enters the transcript, no prompt-cache impact. Lifecycle guarantees from
the stuck-status fix family are preserved (per-thread tracking,
clear-on-finish via existing stop_typing paths). Related: #45109
(closed; same direction via lifecycle states), #59010/#51363 (native
task cards — complementary, larger scope).
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
Builds on the salvaged typing_status_text plumbing (PR NousResearch#62007): instead
of a static 'is thinking...', Slack's assistant status line now updates
live as the agent works — 'is running pytest tests/…', 'is reading
docs/api.md…' — and reverts to the static text between tool calls.

Mechanics:
- agent/display.py: build_status_phrase() derives a <=49-char present-
  tense phrase from the existing _TOOL_VERBS table (+ 'is using <name>'
  for plugin/MCP tools; None for _thinking).
- base adapter: supports_status_text capability flag + set_status_text()
  per-chat store, cleared when the typing loop winds down.
- Slack adapter: send_typing() renders the live phrase when set, falling
  back to typing_status_text then 'is thinking...'.
- gateway/run.py: progress_callback stashes the phrase on tool.started
  and clears on tool.completed. Rendering rides the existing
  _keep_typing refresh cadence — zero additional Slack API calls, no
  rate-limit exposure. Works with tool_progress: off (Slack default);
  the callback is now armed whenever the adapter supports status text.
- display.live_status config (full|verb|off, default full): 'verb' hides
  argument previews for shared/customer-facing channels.

Also fixes a latent crash in the cherry-picked from_dict: malformed
non-dict 'extra' sections broke typing_status_text resolution (uses the
already-coerced extra dict).

Design notes: status text is a side-effect display channel only — never
enters the transcript, no prompt-cache impact. Lifecycle guarantees from
the stuck-status fix family are preserved (per-thread tracking,
clear-on-finish via existing stop_typing paths). Related: NousResearch#45109
(closed; same direction via lifecycle states), NousResearch#59010/NousResearch#51363 (native
task cards — complementary, larger scope).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants