Skip to content

feat(gateway): expose subagent tool calls and thinking to user (fixes #169) - #186

Merged
teknium1 merged 1 commit into
NousResearch:mainfrom
cutepawss:feat/subagent-progress
Mar 1, 2026
Merged

feat(gateway): expose subagent tool calls and thinking to user (fixes #169)#186
teknium1 merged 1 commit into
NousResearch:mainfrom
cutepawss:feat/subagent-progress

Conversation

@cutepawss

Copy link
Copy Markdown
Contributor

PR: feat(gateway): expose subagent tool calls and thinking to user

Fixes #169

What & Why

When subagents run via delegate_task, the user sits with zero progress indication — just a static spinner for potentially minutes. This PR relays the child agent's tool calls and reasoning to the parent display in real time.

Implementation

Three minimal, isolated changes:

1. agent/display.pyKawaiiSpinner.print_above()

New method that prints a line above the active spinner without disrupting animation. Uses the captured self._out reference (not sys.stdout) so it works inside the child's redirect_stdout(devnull).

2. tools/delegate_tool.py_build_child_progress_callback()

Builds a per-child callback with two display paths:

CLI: prints tree-view lines above the delegation spinner:

  🔀 Delegating: research quantum computing
     ├─ 💭 "I'll search for papers first..."
     ├─ 🔍 web_search  "quantum computing"
     ├─ 📖 read_file  "paper.pdf"
     └─ ⠹ working... (18.2s)

Gateway (Telegram/Discord): batches tool names and sends a summary every 5 calls to avoid message spam. Remaining items are flushed when the subagent completes.

Returns None when no display mechanism exists → zero behavior change for headless/test use.

3. run_agent.py — thinking callback

After each API response, fires tool_progress_callback("_thinking", first_line) with the model's first line of text content. <REASONING_SCRATCHPAD>, <think>, and <reasoning> XML tags are stripped before display.

What This Does NOT Change

  • quiet_mode=True and redirect_stdout(devnull) on child agents — unchanged
  • Existing spinner behavior for non-delegation tools — unchanged
  • Existing completion summary (┊ 🔀 delegate "goal" 18.4s) — unchanged
  • Any agent/API logic — unchanged

How to Test

# Run test suite (20 new tests)
pytest tests/agent/test_subagent_progress.py -v

# Full suite
pytest tests/ -v
# 638 passed, 1 failed (pre-existing, unrelated)

# Manual: run hermes CLI, ask it something that triggers delegation
hermes
> Research the latest advances in quantum computing and summarize
# Should see tree-view lines above the spinner during subagent work

Platform Tested

  • macOS (Python 3.14)

Checklist

…ousResearch#169)

When subagents run via delegate_task, the user now sees real-time
progress instead of silence:

CLI: tree-view activity lines print above the delegation spinner
  🔀 Delegating: research quantum computing
     ├─ 💭 "I'll search for papers first..."
     ├─ 🔍 web_search  "quantum computing"
     ├─ 📖 read_file  "paper.pdf"
     └─ ⠹ working... (18.2s)

Gateway (Telegram/Discord): batched progress summaries sent every
5 tool calls to avoid message spam. Remaining tools flushed on
subagent completion.

Changes:
- agent/display.py: add KawaiiSpinner.print_above() to print
  status lines above an active spinner without disrupting animation.
  Uses captured stdout (self._out) so it works inside the child's
  redirect_stdout(devnull).

- tools/delegate_tool.py: add _build_child_progress_callback()
  that creates a per-child callback relaying tool calls and
  thinking events to the parent's spinner (CLI) or progress
  queue (gateway). Each child gets its own callback instance,
  so parallel subagents don't share state. Includes _flush()
  for gateway batch completion.

- run_agent.py: fire tool_progress_callback with '_thinking'
  event when the model produces text content. Guarded by
  _delegate_depth > 0 so only subagents fire this (prevents
  gateway spam from main agent). REASONING_SCRATCHPAD/think/
  reasoning XML tags are stripped before display.

Tests: 21 new tests covering print_above, callback builder,
thinking relay, SCRATCHPAD filtering, batching, flush, thread
isolation, delegate_depth guard, and prefix handling.
@cutepawss
cutepawss force-pushed the feat/subagent-progress branch from 862ccd7 to 62bc53c Compare February 28, 2026 14:15
@teknium1
teknium1 merged commit dd69f16 into NousResearch:main Mar 1, 2026
teknium1 added a commit that referenced this pull request Mar 1, 2026
Two fixes to the subagent progress display from PR #186:

1. Task index prefix: show 1-indexed prefix ([1], [2], ...) for ALL
   tasks in batch mode (task_count > 1). Single tasks get no prefix.
   Previously task 0 had no prefix while others did, making batch
   output confusing.

2. Completion indicator: use spinner.print_above() instead of raw
   print() for per-task completion lines (✓ [1/2] ...). Raw print
   collided with the active spinner, mushing the completion text
   onto the spinner line. Now prints cleanly above.

Added task_count parameter to _build_child_progress_callback and
_run_single_child. Updated tests accordingly.
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
…ousResearch#169) (NousResearch#186)

When subagents run via delegate_task, the user now sees real-time
progress instead of silence:

CLI: tree-view activity lines print above the delegation spinner
  🔀 Delegating: research quantum computing
     ├─ 💭 "I'll search for papers first..."
     ├─ 🔍 web_search  "quantum computing"
     ├─ 📖 read_file  "paper.pdf"
     └─ ⠹ working... (18.2s)

Gateway (Telegram/Discord): batched progress summaries sent every
5 tool calls to avoid message spam. Remaining tools flushed on
subagent completion.

Changes:
- agent/display.py: add KawaiiSpinner.print_above() to print
  status lines above an active spinner without disrupting animation.
  Uses captured stdout (self._out) so it works inside the child's
  redirect_stdout(devnull).

- tools/delegate_tool.py: add _build_child_progress_callback()
  that creates a per-child callback relaying tool calls and
  thinking events to the parent's spinner (CLI) or progress
  queue (gateway). Each child gets its own callback instance,
  so parallel subagents don't share state. Includes _flush()
  for gateway batch completion.

- run_agent.py: fire tool_progress_callback with '_thinking'
  event when the model produces text content. Guarded by
  _delegate_depth > 0 so only subagents fire this (prevents
  gateway spam from main agent). REASONING_SCRATCHPAD/think/
  reasoning XML tags are stripped before display.

Tests: 21 new tests covering print_above, callback builder,
thinking relay, SCRATCHPAD filtering, batching, flush, thread
isolation, delegate_depth guard, and prefix handling.
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
Two fixes to the subagent progress display from PR NousResearch#186:

1. Task index prefix: show 1-indexed prefix ([1], [2], ...) for ALL
   tasks in batch mode (task_count > 1). Single tasks get no prefix.
   Previously task 0 had no prefix while others did, making batch
   output confusing.

2. Completion indicator: use spinner.print_above() instead of raw
   print() for per-task completion lines (✓ [1/2] ...). Raw print
   collided with the active spinner, mushing the completion text
   onto the spinner line. Now prints cleanly above.

Added task_count parameter to _build_child_progress_callback and
_run_single_child. Updated tests accordingly.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…ousResearch#169) (NousResearch#186)

When subagents run via delegate_task, the user now sees real-time
progress instead of silence:

CLI: tree-view activity lines print above the delegation spinner
  🔀 Delegating: research quantum computing
     ├─ 💭 "I'll search for papers first..."
     ├─ 🔍 web_search  "quantum computing"
     ├─ 📖 read_file  "paper.pdf"
     └─ ⠹ working... (18.2s)

Gateway (Telegram/Discord): batched progress summaries sent every
5 tool calls to avoid message spam. Remaining tools flushed on
subagent completion.

Changes:
- agent/display.py: add KawaiiSpinner.print_above() to print
  status lines above an active spinner without disrupting animation.
  Uses captured stdout (self._out) so it works inside the child's
  redirect_stdout(devnull).

- tools/delegate_tool.py: add _build_child_progress_callback()
  that creates a per-child callback relaying tool calls and
  thinking events to the parent's spinner (CLI) or progress
  queue (gateway). Each child gets its own callback instance,
  so parallel subagents don't share state. Includes _flush()
  for gateway batch completion.

- run_agent.py: fire tool_progress_callback with '_thinking'
  event when the model produces text content. Guarded by
  _delegate_depth > 0 so only subagents fire this (prevents
  gateway spam from main agent). REASONING_SCRATCHPAD/think/
  reasoning XML tags are stripped before display.

Tests: 21 new tests covering print_above, callback builder,
thinking relay, SCRATCHPAD filtering, batching, flush, thread
isolation, delegate_depth guard, and prefix handling.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
Two fixes to the subagent progress display from PR NousResearch#186:

1. Task index prefix: show 1-indexed prefix ([1], [2], ...) for ALL
   tasks in batch mode (task_count > 1). Single tasks get no prefix.
   Previously task 0 had no prefix while others did, making batch
   output confusing.

2. Completion indicator: use spinner.print_above() instead of raw
   print() for per-task completion lines (✓ [1/2] ...). Raw print
   collided with the active spinner, mushing the completion text
   onto the spinner line. Now prints cleanly above.

Added task_count parameter to _build_child_progress_callback and
_run_single_child. Updated tests accordingly.
teddyjfpender added a commit to teddyjfpender/superforecasting-agent that referenced this pull request Jul 2, 2026
… proof, living models

The forecasting-ability arc: make the SYSTEM research like a superforecaster,
make the OPERATOR one, and measure both honestly.

R1 — VOI-directed research + adequacy judge (forecasting/research_audit.py):
- build_research_plan turns the question's OWN levers (update_triggers,
  change_my_mind clauses, outcome_paths) into hunt angles alongside the
  standard four (primary source, base rate, recent, contrarian) — pure
  template work, no LLM
- audit_research: six deterministic checks (reference class, evidence floor,
  source independence, disconfirming stance via the existing EvidenceItem
  stance field, recency, trigger coverage) + an optional fail-open LLM
  change_my_mind-coverage check; weighted 0-100 score
- the autonomous chain re-runs research (max_audit_rounds=2, gap list injected
  via a new supplemental seam) keyed ONLY on research-stage-controllable gaps
  (reference classes are a base_rate artifact — correctly excluded), with a
  no-progress spend guard
- research_adequate hook rule (lenient OFF / standard WARN / strict ERROR,
  participates in the resolved-policy pass); research_plan/research_audit tool
  actions; protocol teaches the loop

R2 — operator practice loop (the goal is the USER becoming the forecaster):
- operator_estimates table; resolution scores the human's numbers (fail-open,
  binary Brier; non-binary marked-skipped honestly)
- forecast practice <ref> and forecast drill --n (replay resolved questions
  with pre-resolution evidence only, instant feedback, polite non-TTY refusal)
- operator_calibration_summary: personal curve + trend + vs_system pairing on
  shared questions; calibration --operator CLI + gateway payload section
- estimate-first mode strictly opt-in (forecasting.practice.estimate_first)

R3 — market-hidden benchmark arm completed (task NousResearch#186): the withhold core was
found already committed (verified, not duplicated); added the missing scoring
report market_hidden_pool_report — agent vs withheld-market Brier, win-rate,
equal-weight log-odds pool beats-both, and the P1.3 fitted-simplex LOO
complementarity (reused, not reimplemented). Hand-verified the leak: the
hidden arm exposes neither the price nor the marker to the agent while keeping
both for scoring; the open-arm control proves the probe bites.

R4 — living models: model_runs scored at resolution (binary Brier / numeric
interval coverage + abs error; a refresh run's own proposal can never
masquerade as a model observation), on-read model_skill (track_record math,
cold-start 1.0, min 10 resolved), skill multipliers applied at the
deterministic re-pool with audit-trailed metadata (config default ON,
identity on cold start), nightly model refresh default ON.

Adversarial review: 4 findings — 1 real (uncached model_skill rescan per
refresh; cached) and 3 disproved with documented reasoning.
tests/forecasting: 2070 passed (+103). E2E journey harness green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Feature Request: Expose subagent actions/thoughts to the user

2 participants