review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged)

For each issue anchor present in BASE 63279301bc non-test .py and absent on HEAD, the BASE comment/docstring block was re-attached at the HEAD location of the code it explained (matched by the distinctive code line / enclosing def). Sentences already covered by an existing HEAD comment were deduped; the issue number always survives. Insert-only: no code lines changed.
This commit is contained in:
Teknium
2026-09-03 09:44:26 -07:00
parent ad62a15e94
commit e83816a4d1
586 changed files with 13883 additions and 829 deletions
+40 -4
View File
@@ -103,7 +103,18 @@ class GatewayAgentCacheMixin:
) -> str:
"""Stable key from agent config: change → cached AIAgent rebuilt; unchanged → reused (frozen
prompt + schemas for cache hits). ``user_id`` / ``user_id_alt`` participate because Honcho
freezes them at init; omitting them in shared-thread keys would cross-attribute messages."""
freezes them at init; omitting them in shared-thread keys would cross-attribute messages.
``user_id`` and ``user_id_alt`` are the runtime user identities carried by the current message's
gateway source. They participate in the cache key because the Honcho memory provider freezes them
into ``HonchoSessionManager`` at first-message init (see
``plugins/memory/honcho/__init__.py::_do_session_init``). Without them in the signature, a
shared-thread session_key (one in which ``build_session_key`` intentionally omits the participant
ID, e.g. ``thread_sessions_per_user=False``) would reuse the cached AIAgent across distinct users,
causing the second user's messages to be attributed to the first user's resolved Honcho peer. This
broke #27371's per-user-peer contract in multi-user gateways. Per-user agent rebuilds in shared
threads trade prompt-cache warmth for correct memory attribution.
"""
import hashlib, json as _j
# Fingerprint the FULL credential, not a short prefix: OAuth/JWT-style tokens often share a
# common prefix (e.g. "eyJhbGci"), so a prefix would give false cache hits across auth switches.
@@ -287,7 +298,14 @@ class GatewayAgentCacheMixin:
compression-exhausted reset). New conversation-scoped dicts go in _CONVERSATION_SCOPED_STATE
so every boundary picks them up. Turn-scoped state (_running_agents/_ts, slot leases, turn-
lease tokens) is owned by _release_running_agent_state and NOT cleared. Idle agent-cache
eviction is NOT a boundary (a resumed turn rebuilds from these). getattr-guarded."""
eviction is NOT a boundary (a resumed turn rebuilds from these). getattr-guarded.
Why a funnel: these boundaries used to each carry a hand-copied pop-list of the per-session dicts,
and the lists drifted every time a new dict was added (#48031, #58403, #10702, #35809 were all
"boundary X forgot dict Y" bugs — e.g. /new cleared the /model override but not the /model --once
restore snapshot). Adding a new conversation-scoped dict now means adding its attribute name to
_CONVERSATION_SCOPED_STATE below; every boundary picks it up automatically.
"""
from gateway.run import _CONVERSATION_SCOPED_STATE
if not session_key:
return
@@ -333,6 +351,7 @@ class GatewayAgentCacheMixin:
if not session_key:
return 0
persistent = self._session_state(session_key).persistent
# Monotonic by design (#28686): incremented here, NEVER reset.
persistent.run_generation = int(persistent.run_generation) + 1
return persistent.run_generation
@@ -409,13 +428,18 @@ class GatewayAgentCacheMixin:
# so on a hung/still-draining run the flag survives and silently kills the session's NEXT
# message (interrupted=True, api_calls=0, empty response). Like /new and /model, the next
# message rebuilds from history; the old agent keeps its flag so a hung drain still dies.
# See #44212.
self._evict_cached_agent(session_key)
async def _refresh_agent_cache_message_count(self, session_key: str, session_id: Optional[str]) -> None:
"""Re-baseline a cached agent's stored message_count after THIS turn — the coherence guard
rebuilds on mismatch, so without this every turn would rebuild and destroy prompt caching.
Only the count is refreshed, only if the same agent is still cached. DB errors leave the
snapshot as-is (one spare rebuild)."""
snapshot as-is (one spare rebuild).
But the snapshot is taken at agent-BUILD time — before this turn writes its own user + assistant (+
tool) rows — and the cache entry is never rewritten on a reuse. See #45966.
"""
from gateway.run import _AGENT_PENDING_SENTINEL
_cache_lock = getattr(self, "_agent_cache_lock", None)
_cache = getattr(self, "_agent_cache", None)
@@ -542,7 +566,14 @@ class GatewayAgentCacheMixin:
holds reference cycles; without it RSS grows across /new). Soft = frees clients and child
subagents but PRESERVES terminal sandbox / browser / bg processes since the session may
resume; true boundaries call ``_cleanup_agent_resources`` first. Cleanup runs on a daemon
thread so ``_agent_cache_lock`` never spans slow socket teardown."""
thread so ``_agent_cache_lock`` never spans slow socket teardown.
Pops the entry AND soft-releases the evicted agent's LLM client pool so the httpx connection
(sockets + held buffers) is freed promptly rather than waiting on CPython GC — AIAgent holds
reference cycles (callbacks, tool state) that delay refcount collection, so a manual release is
required to keep gateway RSS flat across many /new, /model, undo and reset operations (#29298, same
leak class as #25315).
"""
from gateway.run import _AGENT_PENDING_SENTINEL
# Prompt-stability state rides the agent-cache lifecycle: a fresh agent must re-render its
# session-context bytes (the pin) and re-see the current voice-channel state once.
@@ -671,6 +702,11 @@ class GatewayAgentCacheMixin:
throttles. Above the anonymous-RSS budget this soft-evicts LRU agents (transcript rebuilt
from the persisted session next turn). Never touched: agents mid-turn, the most recently
used sessions, and transcripts not yet on disk.
A gateway serving many chats therefore holds every warm transcript indefinitely: agents that took a
turn within the TTL are never idle-swept, and the sweep additionally defers finalizable sessions
until they expire. RSS climbs until the cgroup throttles and SIGTERM can no longer flush inside
systemd's stop timeout (#80764).
"""
from gateway.run import _AGENT_PENDING_SENTINEL
from gateway.agent_cache_pressure import (