Skip to content

Notify on background-workflow completion (banner + agent summary) - #302

Merged
agentforce314 merged 1 commit into
mainfrom
feature/workflow-completion-notifications
Jun 11, 2026
Merged

Notify on background-workflow completion (banner + agent summary)#302
agentforce314 merged 1 commit into
mainfrom
feature/workflow-completion-notifications

Conversation

@agentforce314

Copy link
Copy Markdown
Owner

Problem

You ran /deep-research end-to-end — all 15 agents finished, Synthesize completed — but the REPL never told you. The only way to see it was done was to keep polling /workflows, and even then there was no pointer to the results.

Root cause: on completion, complete_workflow_taskenqueue_workflow_notification dutifully builds a <task-notification> (result + output location + token/agent stats) and pushes it onto the message_queue_manager queue… and nothing in the REPL ever drains that queue. drain_pending_notifications had zero production callers — its own docstring admits the consumer side ("WI-3.3") was deferred. The notification was built and dropped on the floor.

Fix

Wire the missing consumer, matching the Claude Code reference you showed (banner, then the agent reads + summarizes):

✔ deep-research completed · 15 agents · 847.7k tok · 6m 40s
  run journal → ~/.clawcodex/workflows/wf_1d92c718.json

● The research is done. Micron's HBM advantage comes down to its
  1-beta DRAM node (best perf-per-watt)… [agent summarizes the result]
  • src/repl/task_notifications.py (new, pure + fully unit-tested): deterministic completion banner from the terminal task state (// · name · agents · tokens · duration · run journal), an envelope-only fallback, and build_notification_turn() that wraps drained envelopes in a guiding <system-reminder> for the agent.
  • REPL glue (core.py): _deliver_pending_task_notifications() drains the queue at the turn boundary, prints each banner, then hands the envelopes to the agent as one turn so it summarizes and points to where the output lives. A daemon watcher wakes the idle prompt the moment a run finishes — so it surfaces without a keystroke — and is careful to never clobber a half-typed line or a permission dialog (only wakes when the prompt is running with an empty buffer).

The cross-thread wake (app.exit via loop.call_soon_threadsafe) was verified against prompt_toolkit 3.0.52 under a PTY before building on it.

Tests — 15, all green

Pure helpers; the REPL delivery method (banner + exactly one agent turn; no-op on empty queue); the wake guard (idle+empty exits; half-typed / not-running don't); the watcher (wakes when idle+pending, silent when not at prompt); and an end-to-end test driving the real production launcher (run_workflow_task) → enqueue → REPL delivery with a fake runner.

Note: 7 pre-existing tests/tui/test_workspace_search_c5.py failures are a ripgrep/env issue on this machine (they fail on a clean tree too) — unrelated to this change.

Scope note

Banner + agent-summary is the behavior you picked. p pause / s save and other surfaces are untouched. This consumer also covers background agent task notifications (same queue), not just workflows.

🤖 Generated with Claude Code

… run finishes

Background workflows enqueue a <task-notification> envelope on completion, but
nothing in the REPL ever drained that queue — its own docstring admits the
consumer ("WI-3.3") was deferred. So a finished /deep-research run surfaced only
by polling /workflows, with no completion signal and no pointer to the results.

Wire the consumer:

* src/repl/task_notifications.py (new, pure/tested): deterministic completion
  banner from the terminal task state (✔/✗/⊘ · name · agents · tokens · duration
  · run journal), an envelope fallback, and build_notification_turn() which wraps
  drained envelopes in a guiding system-reminder for the agent.

* REPL glue (core.py): _deliver_pending_task_notifications() drains the queue at
  the turn boundary, prints each banner, then feeds the envelopes to the agent as
  one turn so it reads the result and summarizes conversationally — the Claude
  Code "the research is done…" behavior. A daemon watcher wakes the idle ❯ prompt
  the moment a run finishes (verified cross-thread against prompt_toolkit 3.0.x
  via app.exit), so it surfaces without a keystroke — and never clobbers a
  half-typed line or a permission dialog.

Tests (15): pure helpers, the REPL delivery method (banner + single agent turn,
no-op on empty queue), the wake guard (idle+empty exits; half-typed/not-running
don't), the watcher (wakes when idle+pending, silent otherwise), and an
end-to-end run through the production launcher → enqueue → REPL delivery with a
fake runner. Pre-existing test_workspace_search_c5 failures (ripgrep env) are
unrelated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@agentforce314
agentforce314 merged commit 30e765b into main Jun 11, 2026
singlaamitesh pushed a commit to singlaamitesh/clawcodex that referenced this pull request Jul 7, 2026
…low-completion-notifications

Notify on background-workflow completion (banner + agent summary)
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.

1 participant