mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-21 10:22:18 +00:00
fix(mcp): round-3 polish — generation capture adjacency + gateway contract note
Third review pass (Hermes subagent) declared convergence: no BLOCKING, the round-2 generation-aware publish / context-engine staging / CLI reload / ACP routing all verified correct by hand and by test. - agent_init: capture _tool_snapshot_generation immediately before the tool snapshot (was ~425 lines earlier); removes a harmless skew window so the recorded generation always matches the snapshot it describes. - gateway/run.py _execute_mcp_reload: keep preserving each cached agent's build-time enabled_toolsets EXACTLY (do NOT merge newly-connected servers like CLI/TUI do) and document WHY — gateway sessions can be deliberately locked down, and test_reload_mcp_preserves_per_agent_toolset_overrides asserts this. A reviewer suggested "parity" here; it would have violated that contract.
This commit is contained in:
parent
88d523220f
commit
f3e967aae5
2 changed files with 19 additions and 7 deletions
|
|
@ -537,12 +537,8 @@ def init_agent(
|
|||
agent._skip_mcp_refresh = False
|
||||
# Registry generation the current tool snapshot was derived from. Lets a
|
||||
# late/concurrent refresh reject a stale (older-generation) rebuild instead
|
||||
# of clobbering a newer one. See tools.mcp_tool.refresh_agent_mcp_tools.
|
||||
try:
|
||||
from tools.registry import registry as _registry
|
||||
agent._tool_snapshot_generation = _registry._generation
|
||||
except Exception:
|
||||
agent._tool_snapshot_generation = 0
|
||||
# of clobbering a newer one. Set adjacent to the tool snapshot below.
|
||||
agent._tool_snapshot_generation = 0
|
||||
# Rate limit tracking — updated from x-ratelimit-* response headers
|
||||
# after each API call. Accessed by /usage slash command.
|
||||
agent._rate_limit_state: Optional["RateLimitState"] = None
|
||||
|
|
@ -964,7 +960,14 @@ def init_agent(
|
|||
print(f"🔄 Fallback chain ({len(agent._fallback_chain)} providers): " +
|
||||
" → ".join(f"{f['model']} ({f['provider']})" for f in agent._fallback_chain))
|
||||
|
||||
# Get available tools with filtering
|
||||
# Get available tools with filtering. Capture the registry generation this
|
||||
# snapshot is derived from FIRST, so a later concurrent refresh can tell
|
||||
# whether it holds a newer or staler view (see refresh_agent_mcp_tools).
|
||||
try:
|
||||
from tools.registry import registry as _snapshot_registry
|
||||
agent._tool_snapshot_generation = _snapshot_registry._generation
|
||||
except Exception:
|
||||
agent._tool_snapshot_generation = 0
|
||||
agent.tools = _ra().get_tool_definitions(
|
||||
enabled_toolsets=enabled_toolsets,
|
||||
disabled_toolsets=disabled_toolsets,
|
||||
|
|
|
|||
|
|
@ -11668,6 +11668,15 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
|
|||
continue
|
||||
if _agent is None:
|
||||
continue
|
||||
# Preserve each cached agent's build-time toolset
|
||||
# selection EXACTLY: a gateway session built with a
|
||||
# restricted enabled_toolsets (e.g. ["safe"]) must
|
||||
# NOT silently gain tools after a reload. This is the
|
||||
# opposite of the interactive CLI/TUI /reload-mcp,
|
||||
# which is a single user re-applying their own config
|
||||
# edit; gateway agents are per-session and may be
|
||||
# deliberately locked down. (Contract is asserted by
|
||||
# test_reload_mcp_preserves_per_agent_toolset_overrides.)
|
||||
refresh_agent_mcp_tools(_agent, quiet_mode=True)
|
||||
except Exception as _exc:
|
||||
logger.debug(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue