Skip to content

fix: surface self-improvement review summaries across CLI, TUI, and gateway#18073

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-536fb6d5
Apr 30, 2026
Merged

fix: surface self-improvement review summaries across CLI, TUI, and gateway#18073
teknium1 merged 2 commits into
mainfrom
hermes/hermes-536fb6d5

Conversation

@teknium1

@teknium1 teknium1 commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Summary

The self-improvement background review's 💾 … summary (the line that tells you it patched a skill or saved a memory entry) now reliably surfaces to the user across every interface — CLI, Ink TUI (hermes --tui + dashboard /chat), and messaging gateways — and is attributed to the self-improvement loop so it's unambiguous.

Root cause

Real-world trigger: on 2026-04-30 the hermes-release skill was patched at 11:33:47 by a bg review (.usage.json records it) but no 💾 ever appeared in the still-open CLI session. Three silent failure modes:

  1. CLI: bg-thread _cprint called prompt_toolkit.print_formatted_text directly while a PromptSession was live → raced with the input-area redraw, line could end up buried.
  2. TUI: no wiring at all — the bg review had no surface to speak to. agent.background_review_callback was never set by the tui_gateway, so Ink never saw the summary.
  3. Attribution: even when the line did land, 💾 Skill updated gave no hint the self-improvement loop was responsible.

Changes

  • cli._cprint: detect cross-thread invocation with a live PT Application; schedule run_in_terminal via loop.call_soon_threadsafe. Input pauses, line prints clean, prompt redraws. Direct-print fallbacks preserved for no-app, same-thread, import-error, and attribute-error paths. Fixes every bg-thread emission (curator summaries, aux failures), not just the review.
  • run_agent._spawn_background_review: summary now reads 💾 Self-improvement review: <actions> in both the _safe_print path (CLI) and the background_review_callback path (TUI + gateway).
  • tui_gateway/server.py: in _init_session, attach agent.background_review_callback to an _emit('review.summary', sid, {text}) closure. Safe on agents with locked __slots__.
  • ui-tui/src/app/createGatewayEventHandler.ts: new review.summary case routes payload.text through sys(…) so it persists in the transcript, matching the background.complete pattern. Empty / whitespace payloads are ignored.
  • ui-tui/src/gatewayTypes.ts: extend GatewayEvent union with { type: 'review.summary', payload?: { text?: string } }.
  • Gateway platforms (Telegram, Discord, Slack, …): no code changes — existing background_review_callback post-delivery queue in gateway/run.py picks up the new prefix string automatically.

Validation

Before After
CLI bg-thread _cprint w/ live app direct _pt_print races w/ prompt redraw schedules run_in_terminal via app loop
TUI review summary delivery silent, no callback wired review.summary event → sys(…) transcript line
Gateway review summary delivery 💾 Skill created. 💾 Self-improvement review: Skill created.
Attribution none 💾 Self-improvement review: <actions> everywhere
Python tests 19 passed (6 new _cprint routing, 1 new bg-review prefix, 2 new tui_gateway callback)
tui_gateway suite 64/64 pass
cli + run_agent suites 588 + 1176 pass, 17 skipped
Ink vitest 36/36 pass (3 new for review.summary)
TypeScript type-check clean
Live E2E (Python) bg thread _cprint correctly schedules run_in_terminal inside a real PT Application

Scope limits

Unchanged: nudge thresholds, review prompt text, summary-action detection, gateway platform adapters, memory/skill core code. Surgical across three surfaces.

When the self-improvement background review fires after a turn, it runs
in a bg thread and emits a '  💾 <summary>' line to announce what it
saved to memory or skills. Two problems made this invisible to users
even when the review successfully modified a skill:

1. The print went through `_cprint` (prompt_toolkit's print_formatted_text)
   on a bg thread while the CLI's PromptSession was live. Direct
   print_formatted_text races with the input-area redraw and the line
   can land behind/above the prompt, scrolled off without the user
   seeing it.

2. The message said only '💾 Skill created.' / '💾 Memory updated'
   with no indication that the self-improvement loop was the one doing
   this. Users who did catch the line couldn't tell the background
   review from some other agent action.

Fixes:

- `_cprint` now detects when it's called from a non-app thread with a
  running prompt_toolkit Application, and routes through
  `run_in_terminal` via `loop.call_soon_threadsafe`. That pauses the
  input, prints the line above the prompt, and redraws — the normal
  prompt_toolkit contract for bg-thread output. Direct-print fallback
  preserved for the no-app / same-thread / import-error paths. Affects
  every bg-thread emission, not just the review summary (curator
  summaries and auxiliary failure prints benefit too).

- The summary now reads '  💾 Self-improvement review: <summary>' in
  both the CLI and the gateway `background_review_callback` path, so
  the origin is unambiguous.

Tests:
- New `tests/cli/test_cprint_bg_thread.py` covers all five routing
  branches (no app, app-not-running, cross-thread schedule, same-thread
  direct, app-loop-attribute-error, import-error).
- New case in `tests/run_agent/test_background_review.py` asserts the
  attributed prefix shows up in both `_safe_print` and
  `background_review_callback`.

Live E2E: exercised _cprint from a bg thread inside a real Application
event loop; confirmed get_app_or_none() sees the app, call_soon_threadsafe
schedules run_in_terminal, and the inner _pt_print runs.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard comp/agent Core agent loop, run_agent.py, prompt builder labels Apr 30, 2026
The Ink TUI (\`hermes --tui\` + dashboard \`/chat\`) had no wiring for the
background self-improvement review. When the review fired and patched
a skill or saved a memory entry, the change landed but the user had
no visual indication it happened — only the CLI had a print surface
for the '💾 Self-improvement review: …' line.

Changes:

- tui_gateway/server.py: in _init_session, attach
  agent.background_review_callback to an _emit('review.summary',
  sid, {text}) closure. Wrapped in try/except so agents with locked
  attribute slots don't break session startup.
- ui-tui/src/app/createGatewayEventHandler.ts: handle 'review.summary'
  by routing ev.payload.text through sys(…), matching the existing
  'background.complete' pattern. Empty / whitespace payloads are
  ignored so the transcript never gets a blank system line.
- ui-tui/src/gatewayTypes.ts: extend the GatewayEvent discriminated
  union with { type: 'review.summary', payload?: { text?: string } }.

Gateway platforms (Telegram, Discord, Slack, …) already route the
review summary via background_review_callback → post-delivery queue
in gateway/run.py, so they pick up the new 'Self-improvement review:'
prefix from the companion run_agent change with no platform edits.

Tests:
- tests/tui_gateway/test_review_summary_callback.py (Python, 2 tests):
  _init_session attaches a callback that emits the right event; the
  callback path survives agents that can't accept the attribute.
- ui-tui/src/__tests__/createGatewayEventHandler.test.ts (vitest, 2
  new cases): review.summary events feed sys(...) with the full text;
  empty / missing payloads are no-ops.
- TypeScript type-check passes.
- tui_gateway suite: 64/64 pass.
@teknium1 teknium1 changed the title fix(cli): surface self-improvement review summaries from bg thread fix: surface self-improvement review summaries across CLI, TUI, and gateway Apr 30, 2026
@teknium1 teknium1 merged commit bbbce92 into main Apr 30, 2026
10 of 11 checks passed
@teknium1 teknium1 deleted the hermes/hermes-536fb6d5 branch April 30, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants