Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -16083,6 +16083,11 @@ async def _run_process_watcher(self, watcher: dict) -> None:
("compression", "protect_last_n"),
("agent", "disabled_toolsets"),
("memory", "provider"),
# memory_char_limit / user_char_limit are passed to MemoryStore at
# agent construction; changing them mid-session must rebuild the
# cached agent so the new limits take effect on the next message.
("memory", "memory_char_limit"),
("memory", "user_char_limit"),
)

_HONCHO_CACHE_BUSTING_KEYS = (
Expand Down
44 changes: 44 additions & 0 deletions tests/gateway/test_agent_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,50 @@ def test_reads_compression_subkeys(self):
assert out["compression.target_ratio"] == 0.3
assert out["compression.protect_last_n"] == 25

def test_reads_memory_char_limit_subkeys(self):
"""memory_char_limit / user_char_limit must be picked up so editing
the cap in config.yaml invalidates the cached agent on the next
message (no gateway restart)."""
from gateway.run import GatewayRunner

out = GatewayRunner._extract_cache_busting_config(
{
"memory": {
"memory_char_limit": 5000,
"user_char_limit": 2500,
"provider": "mem0", # unrelated — should not affect these
}
}
)
assert out["memory.memory_char_limit"] == 5000
assert out["memory.user_char_limit"] == 2500

def test_memory_char_limit_change_busts_signature(self):
"""Changing memory_char_limit between messages must produce a
different agent-config signature, so the gateway rebuilds the
cached AIAgent and the new cap takes effect immediately."""
from gateway.run import GatewayRunner

sig_default = GatewayRunner._agent_config_signature(
model="minimax/MiniMax-M2.7",
runtime={"api_key": "k", "base_url": "u", "provider": "p", "api_mode": ""},
enabled_toolsets=["memory"],
ephemeral_prompt="",
cache_keys=GatewayRunner._extract_cache_busting_config(
{"memory": {"memory_char_limit": 2200, "user_char_limit": 1375}}
),
)
sig_bumped = GatewayRunner._agent_config_signature(
model="minimax/MiniMax-M2.7",
runtime={"api_key": "k", "base_url": "u", "provider": "p", "api_mode": ""},
enabled_toolsets=["memory"],
ephemeral_prompt="",
cache_keys=GatewayRunner._extract_cache_busting_config(
{"memory": {"memory_char_limit": 5000, "user_char_limit": 2500}}
),
)
assert sig_default != sig_bumped

def test_missing_keys_yield_none(self):
"""Absent config keys must produce None values (still contribute to signature)."""
from gateway.run import GatewayRunner
Expand Down
2 changes: 1 addition & 1 deletion website/docs/user-guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ Older configs with `compression.summary_model`, `compression.summary_provider`,
`protect_first_n` controls how many **non-system** head messages are pinned across every compaction. Default `3` — the opening user/assistant exchange survives every summarizer pass so the original goal stays visible. On long-running rolling-compaction sessions where the opening turn is no longer relevant, set `protect_first_n: 0` to pin nothing but the system prompt + summary + tail. The system prompt itself is always preserved regardless of this setting.

:::tip Gateway hot-reload of compression and context length
As of recent releases, editing `model.context_length` or any `compression.*` key in `config.yaml` on a running gateway takes effect on the next message — no gateway restart, no `/reset`, no session rotation required. The cached-agent signature includes these keys, so the gateway transparently rebuilds the agent when it sees a change. API keys and tool/skill config still require the usual reload paths.
As of recent releases, editing `model.context_length`, any `compression.*` key, or `memory.memory_char_limit` / `memory.user_char_limit` in `config.yaml` on a running gateway takes effect on the next message — no gateway restart, no `/reset`, no session rotation required. The cached-agent signature includes these keys, so the gateway transparently rebuilds the agent when it sees a change. API keys and tool/skill config still require the usual reload paths.
:::

### Common setups
Expand Down