fix(agent): gate memory tool injection on platform_toolsets containing 'memory'#5788
Closed
Lempkey wants to merge 1 commit into
Closed
Conversation
…g 'memory'
Memory provider tool schemas (fact_store etc.) were injected into the
agent's tool surface unconditionally in AIAgent.__init__, regardless of
the platform's enabled_toolsets configuration. This meant that setting
platform_toolsets:
telegram: []
had no effect on memory tools — they were still appended to self.tools,
bypassing the toolset filter entirely.
The impact is severe for local model deployments: tool-formatted prompts
process at ~134 tok/s vs ~1230 tok/s for plain text on typical consumer
hardware (Qwen3-30B-A3B Q4_K_M / RTX 3090). With 8 memory tool schemas,
a simple "hello" on Telegram takes ~42 s instead of ~1.7 s.
Fix: add a guard before the injection loop so memory tools are only
injected when enabled_toolsets is None (no filter active — backward-
compatible default) or "memory" is explicitly listed in enabled_toolsets.
Fixes NousResearch#5544
Collaborator
Open
6 tasks
SelfParody
added a commit
to SelfParody/hermes-agent
that referenced
this pull request
May 2, 2026
…han subprocess leak v5 — addresses GPT-5.5 fusion-judge SHIP_WITH_FIXES on v4. One-line cosmetic fix: SIGTERM handler now uses cleanup-scope local alias `_os_local.kill(_os_local.getpid(), signum)` instead of bare `os.kill(os.getpid(), signum)`, completing the self-containment intent. Behavior unchanged (verified: SIGTERM still exits 143, SIGINT still 130). ═══ Code review history ═══ - v1: qwen3-max single review → SHIP_WITH_FIXES - v2: Fusion (Codex+Sonnet+Gemini, GPT-5.5 judge) → NEEDS_REWORK (7 fixes) - v3: Fusion → SHIP_WITH_FIXES (3 required + 4 hardening fixes) - v4: Fusion → SHIP_WITH_FIXES (1 cosmetic — use _os_local in SIGTERM) - v5 (this commit): cosmetic fix applied; behavior verified unchanged ═══ Final fix tracking ═══ | v2 required fix | Final | |---------------------------------------|-------| | 1. Fail-open import behavior | FIXED | | 2. SIGTERM exit code 143 | FIXED | | 3. Unmatched -t warning logic | FIXED | | 4. _stdio_pids robustness | FIXED | | 5. time/os imports verified | FIXED | | 6. Poll-loop logger.debug | FIXED | | 7. Idempotency guard | FIXED | | 8. SIGTERM uses self-contained _os | FIXED (v5) | ═══ Verified locally (final) ═══ hermes -z "ACK" -t web : 4.8s wall (was 65s — 93% reduction) hermes -z "ACK" -t slack : 5.5s wall (was 67s — 92% reduction) hermes -z "ACK" (no -t) : 75s (unchanged — backwards-compat) SIGINT mid-flight : exit 130 ✓ SIGTERM mid-flight : exit 143 ✓ Orphan accumulation : 0 new PPID=1 across 10+ runs Related issues: - Fixes the MCP subprocess component of NousResearch#18438 (gateway memory leak) - Supersedes the startup-drag portion of NousResearch#18523 (closed unmerged) - Extends toolset-gating pattern from NousResearch#18166 and NousResearch#5788 (memory) to MCPs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
|
Salvaged into PR #30177 (merged) — #30177 Your one-line gate is now on main as commit Thanks @Lempkey — this was a clean, correct, well-reasoned fix. Added you to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5544.
Root cause
Memory provider tool schemas (
fact_storeand friends) were injected into the agent's tool surface unconditionally inAIAgent.__init__(run_agent.py~line 1115), regardless of the platform'senabled_toolsetsconfiguration:Setting
platform_toolsets: telegram: []had no effect on memory tools — they were still appended toself.tools, bypassing the platform toolset filter that correctly gates every other tool category.Impact
On local model deployments the overhead is severe. Tool-formatted prompts process at ~134 tok/s vs ~1,230 tok/s for plain text (Qwen3-30B-A3B Q4_K_M on an RTX 3090). With 8 memory tool schemas injected, a simple "hello" on Telegram takes ~42 s instead of ~1.7 s. Smaller models also enter tool-call loops when memory tools are the only tools present.
What changed
A single guard before the injection loop (
run_agent.py~line 1115):enabled_toolsets is None→ no filter active, inject as before (full backward compatibility)"memory" in enabled_toolsets→ memory explicitly listed, injectenabled_toolsets = []or a list without"memory"→ skip injectionNo changes to any other file. The
AIAgentconstructor already storesenabled_toolsetsat line 682; the fix only reads it.Tests
Covers: no filter (None), explicit
["memory"]in list, empty list[], list without memory, no memory manager, multiple schemas all injected, multiple schemas all blocked.