feat(gateway): live per-tool status line on Slack

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).
This commit is contained in:
teknium1
2026-07-18 11:58:31 -07:00
committed by Teknium
parent 16604d59ca
commit d4396797c3
10 changed files with 325 additions and 4 deletions
@@ -436,6 +436,34 @@ The same key customizes Google Chat's visible working-state marker message
note that on Google Chat it is a real posted message that gets patched into the
reply, not an ephemeral status.
### Live Status (per-tool)
By default the status line updates **live as the agent works**: instead of a
static `is thinking...`, it shows what the agent is doing right now — `is
running pytest tests/…`, `is reading docs/api.md…`, `is searching the web for
slack api limits…`. Between tool calls it reverts to the static text. This
rides the existing status-refresh cadence, so it makes no additional Slack API
calls, and it works even with `tool_progress: off` (Slack's default) — unlike
progress bubbles, the status line is ephemeral and leaves nothing behind in
the channel.
Control it with `display.live_status` (global or per-platform):
```yaml
display:
platforms:
slack:
# full = verb + argument ("is running pytest…") [default]
# verb = verb only ("is running…") — hides commands/paths,
# useful in shared or customer-facing channels
# off = static text (typing_status_text or "is thinking...")
live_status: full
```
| Key | Default | Description |
|-----|---------|-------------|
| `display.live_status` | `"full"` | Live per-tool status line. `full` shows verb + argument preview; `verb` shows the verb only (keeps file paths and commands out of shared channels); `off` restores the static text. Requires the `assistant:write` scope, same as the static status line. |
### Session Isolation
```yaml