fix(context-engine): snapshot select_context read-only inputs; scope on_turn_complete coverage doc
Addresses the hermes-sweeper review on #51226: - _apply_context_engine_selection now passes shallow copies of the read-only conversation_messages / incoming_message to the hook, so an engine mutating them in place cannot corrupt persisted transcript state (enforces the request-only contract, not just documents it). Adds a mutation-regression test asserting persisted history + incoming message are untouched. - on_turn_complete docstring: scope the coverage claim to the standard finalization seam. Some abnormal early-return paths (content-policy block, provider terminal failure) currently persist+return without finalization and don't emit the hook; documented as best-effort with a shared-seam follow-up, rather than over-promising a guaranteed callback for every early exit.
This commit is contained in:
+17
-8
@@ -286,12 +286,21 @@ class ContextEngine(ABC):
|
||||
) -> None:
|
||||
"""Observe a finished user turn (post-turn ingestion / observation).
|
||||
|
||||
Called once after the assistant/tool loop completes for a turn, with
|
||||
the finalized in-memory transcript snapshot. This is the complement to
|
||||
``select_context()``: selection happens *before* the request, while
|
||||
observation happens *after* the turn. It lets an engine ingest, index,
|
||||
summarize, or update routing / topic / session state from what actually
|
||||
happened — so the next ``select_context()`` can act on it.
|
||||
Called from the standard turn-finalization path once the assistant/tool
|
||||
loop completes, with the finalized in-memory transcript snapshot. This
|
||||
is the complement to ``select_context()``: selection happens *before*
|
||||
the request, while observation happens *after* the turn. It lets an
|
||||
engine ingest, index, summarize, or update routing / topic / session
|
||||
state from what actually happened — so the next ``select_context()``
|
||||
can act on it.
|
||||
|
||||
Coverage: this fires from the normal finalization seam. Some abnormal
|
||||
early-return paths in the loop (e.g. a content-policy block or a
|
||||
provider terminal failure) persist and return without routing through
|
||||
finalization, and therefore do not currently emit this hook. Treat it
|
||||
as a best-effort post-turn observation for completed turns, not a
|
||||
guaranteed callback for every possible early exit; unifying all
|
||||
terminal paths behind one finalization seam is a separate follow-up.
|
||||
|
||||
Together the two hooks remove the need to abuse ``should_compress()`` /
|
||||
``compress()`` as a generic per-turn callback just to observe history,
|
||||
@@ -310,8 +319,8 @@ class ContextEngine(ABC):
|
||||
``input_tokens`` / ``output_tokens`` / ``cache_read_tokens`` /
|
||||
``cache_write_tokens`` / ``reasoning_tokens`` buckets) so an engine can
|
||||
weigh how large/expensive the selected context actually was when
|
||||
deciding the next ``select_context()``. It is ``None`` on turns that
|
||||
never reached a provider response (early failure / interrupt); engines
|
||||
deciding the next ``select_context()``. It is ``None`` on finalized
|
||||
turns that never reached a provider response (e.g. interrupt); engines
|
||||
must treat it as optional.
|
||||
|
||||
Default is a no-op.
|
||||
|
||||
Reference in New Issue
Block a user