symfonic.agent.cutover.projection¶
projection ¶
Projecting one kernel outcome onto the legacy AgentResponse/StreamChunk.
The outward half of the delegate's translation, split out of
:mod:~symfonic.agent.cutover.delegate when TA8.10 gave that module the
inbound half to carry as well. The seam is the direction of travel: this module
only ever reads a finished kernel value and writes the shape a legacy caller
already holds. It compiles nothing, calls no kernel, and holds no state.
The shapes themselves belong to :mod:symfonic.agent.response_projection, the
native owner the compatibility HTTP routes call (CORE-414). This facade adds
only what the delegate measures and those routes do not: memory_entries_used
and extracted_ops from its turn observation (CORE-227, :mod:~.turn_effects),
and the presented final_response of a run. A caller that passes no
observation gets exactly the native projection.
Translation is not interpretation. Where the legacy shape has a column the
kernel path cannot fill โ activation_log, system_prompt_tokens โ the
empty value is written rather than an estimate, because the empty value is true
and an estimate is a fabrication that survives into a metric.
as_chunk ¶
as_chunk(event: AgentEvent, *, run_id: str, effects: TurnObservation | None = None) -> StreamChunk | None
Project one kernel event onto the legacy chunk shape.
The native projection decides every shape, the raised error, and the
declared ask_user/interrupt gap; see
:func:symfonic.agent.response_projection.as_chunk. With effects, the
done chunk reports the measured memory count and operations in place
of the native empty values; streamed text is never rewritten.
Source code in src/symfonic/agent/cutover/projection.py
as_response ¶
as_response(result: AgentResult[Any], *, run_id: str, session_id: str, effects: TurnObservation | None = None) -> AgentResponse
Project the kernel's result onto the legacy response shape.
The native projection runs first, so an exhausted round budget still raises
:class:~symfonic.agent.cutover.errors.RecursionExhaustedError (a
GraphRecursionError) before any observation is read; see
:func:symfonic.agent.response_projection.as_response. With effects,
the measured memory count, the operations, and the presented text replace
the native empty values. The presented text keeps the legacy tri-state:
an answerless turn is None, not "".