Skip to content

Fix/flush agent terminal output#3045

Closed
dlkakbs wants to merge 5 commits into
NousResearch:mainfrom
dlkakbs:fix/flush-agent-terminal-output
Closed

Fix/flush agent terminal output#3045
dlkakbs wants to merge 5 commits into
NousResearch:mainfrom
dlkakbs:fix/flush-agent-terminal-output

Conversation

@dlkakbs

@dlkakbs dlkakbs commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

The gateway memory flush agent spawns a temporary AIAgent on session reset/expiry to review conversation history and save memories. quiet_mode=True only suppresses initialization messages — tool call output was still leaking to the terminal.

The initial fix (commit d495fe4) set tmp_agent._print_fn = lambda *a, **kw: None after constructing the flush agent. However, this was incomplete for two reasons:

  • KawaiiSpinner captures sys.stdout at init time and writes directly to it — _print_fn is never consulted
  • quiet-mode cute messages (run_agent.py) used builtin print() instead of self._safe_print()

Additionally, two other background agents in the gateway were also missing the _print_fn no-op: the in-turn hygiene memory agent and the context compression agent.

This PR completes the fix by routing all output paths through _print_fn and applying the no-op to all background agents.

Related Issue

Fixes #2670 (side-effect follow-up)

Type of Change

🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • gateway/run.py: Set _print_fn = lambda *a, **kw: None on the flush agent, hygiene agent, and context compression agent
  • agent/display.py: Add optional print_fn parameter to KawaiiSpinner.init; _write() routes through it when set, bypassing sys.stdout
  • run_agent.py: Pass print_fn=self._print_fn to all KawaiiSpinner construction sites; change quiet-mode cute message from print() to self._safe_print()

All changes are backward-compatible — print_fn defaults to None which preserves existing behavior for normal agents.

How to Test

  1. Start the gateway with a Telegram (or any messaging) integration
  2. Have a multi-turn conversation so the session has history
  3. Send /new to reset the session
  4. Confirm no flush agent output (tool calls, memory writes, spinner lines) appears in the terminal
  5. Confirm memories are still saved correctly after reset (check memory files)
  6. Wait for session expiry without sending a message — confirm no background agent output appears

Checklist

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/gateway/test_flush_memory_stale_guard.py — 9/9 pass
  • I've run pytest tests/ -q and all tests pass
    Note: Pre-existing failures are environment/dependency issues unrelated to this change.
  • I've added tests for my changes
  • I've tested on my platform: macOS

Documentation & Housekeeping

  • I've updated relevant documentation — N/A
  • I've updated cli-config.yaml.example — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md — N/A
  • I've considered cross-platform impact — N/A
  • I've updated tool descriptions/schemas — N/A

dlkakbs and others added 4 commits March 26, 2026 16:50
quiet_mode=True only suppresses AIAgent init messages.
Tool call output still leaks to the terminal through
_safe_print → _print_fn during session reset/expiry.

Since NousResearch#2670 injected live memory state into the flush prompt,
the flush agent now reliably calls memory tools — making the
output leak noticeable for the first time.

Set _print_fn to a no-op so the background flush is fully silent.
… mock

- Add TestFlushAgentSilenced: verifies _print_fn is set to a no-op on
  the flush agent so tool output never leaks to the terminal
- Fix pre-existing test failures: replace patch('run_agent.AIAgent')
  with sys.modules mock to avoid importing run_agent (requires openai)
- Add autouse _mock_dotenv fixture so all tests in this file run
  without the dotenv package installed
…lence flush agent

The previous fix set tmp_agent._print_fn = no-op on the flush agent but
spinner output and quiet-mode cute messages bypassed _print_fn entirely:
- KawaiiSpinner captured sys.stdout at __init__ and wrote directly to it
- quiet-mode tool results used builtin print() instead of _safe_print()

Add optional print_fn parameter to KawaiiSpinner.__init__; _write routes
through it when set. Pass self._print_fn to all spinner construction sites
in run_agent.py and change the quiet-mode cute message print to _safe_print.
The existing gateway fix (tmp_agent._print_fn = lambda) now propagates
correctly through both paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two more background AIAgent instances in the gateway were created with
quiet_mode=True but without _print_fn = no-op, causing tool output to
leak to the terminal:
- _hyg_agent (in-turn hygiene memory agent)
- tmp_agent (_compress_context path)

Apply the same _print_fn no-op pattern used for the flush agent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dlkakbs dlkakbs force-pushed the fix/flush-agent-terminal-output branch from 3a05460 to a1da7a7 Compare March 26, 2026 13:51
Attribute was set but never read; upstream already removed it.
Leftover from conflict resolution during rebase onto upstream/main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #3297. Your commits were cherry-picked onto current main with authorship preserved. Thanks @dlkakbs!

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.

Memory flush agent overwrites live memory on session reset/gateway restart

2 participants