mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-08 13:12:08 +00:00
fix(gateway): stop per-turn agent-cache eviction from model + message_id signature churn
Two independent bugs evicted the cached gateway AIAgent on every turn, preventing the prompt cache from ever warming: 1. Model normalization mismatch: the post-run fallback-eviction check compared _agent.model (stripped in AIAgent.__init__) against the raw _resolve_gateway_model() config string. For vendor-prefixed config on native providers (e.g. 'deepseek/deepseek-v4-pro' vs 'deepseek-v4-pro') this was always unequal, so the agent was evicted after every successful run. Normalize _cfg_model the same way (skip aggregators). 2. Discord triggering message_id leaked into the cached system prompt via build_session_context_prompt()'s Discord IDs block. message_id changes every turn, so the agent-cache signature (computed from the ephemeral prompt) changed every Discord turn -> rebuild every message. The id is now injected per-turn into the user message (where per-turn content belongs and does not touch the cache signature); the cached IDs block carries a static pointer to it, preserving reply/react/pin via the discord tools. Adapted from #28846. Bug #1 fix is the contributor's; bug #2 reworked to be non-destructive (keeps the triggering-id capability instead of deleting it). Redundant auto-reset eviction (already on main via #9893/#48031) and the wrong-premise reset_context_note plumbing from the original PR were dropped. Co-authored-by: Hermes Agent <hermes@nousresearch.com>
This commit is contained in:
parent
e7ca53e6b8
commit
d6c53dcdcb
4 changed files with 91 additions and 1 deletions
|
|
@ -235,6 +235,48 @@ class TestBuildSessionContextPrompt:
|
|||
assert "Discord" in prompt
|
||||
assert "cannot search" in prompt.lower() or "do not have access" in prompt.lower()
|
||||
|
||||
def test_discord_prompt_stable_across_message_id(self):
|
||||
"""The cached system prompt must NOT vary with the triggering message_id.
|
||||
|
||||
message_id changes every turn; baking it into the Discord IDs block
|
||||
busts the gateway agent-cache signature and rebuilds the AIAgent on
|
||||
every message (destroying prompt caching). The volatile id is injected
|
||||
per-turn into the user message instead — the cached block only carries
|
||||
a static pointer.
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
import gateway.session as _gs
|
||||
|
||||
config = GatewayConfig(
|
||||
platforms={
|
||||
Platform.DISCORD: PlatformConfig(enabled=True, token="fake-d...oken"),
|
||||
},
|
||||
)
|
||||
|
||||
def _prompt_for(msg_id):
|
||||
source = SessionSource(
|
||||
platform=Platform.DISCORD,
|
||||
chat_id="chan-1",
|
||||
chat_name="Server",
|
||||
chat_type="group",
|
||||
user_name="alice",
|
||||
guild_id="guild-123",
|
||||
message_id=msg_id,
|
||||
)
|
||||
ctx = build_session_context(source, config)
|
||||
return build_session_context_prompt(ctx)
|
||||
|
||||
# Force the Discord IDs block on (it only emits when discord tools load).
|
||||
with patch.object(_gs, "_discord_tools_loaded", return_value=True):
|
||||
p1 = _prompt_for("1001")
|
||||
p2 = _prompt_for("2002")
|
||||
p3 = _prompt_for("3003")
|
||||
|
||||
assert p1 == p2 == p3, "system prompt must be stable across message_id"
|
||||
assert "1001" not in p1 and "2002" not in p2 and "3003" not in p3
|
||||
# Static pointer tells the agent where the volatile id actually lives.
|
||||
assert "provided per-turn in the incoming user message" in p1
|
||||
|
||||
def test_slack_prompt_includes_platform_notes(self):
|
||||
config = GatewayConfig(
|
||||
platforms={
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue