Skip to content

symfonic.agent.backend.response

response

Response handling: structured extraction and result/event projection.

The kernel produces an InvocationOutcome and a stream of KernelEvents and stops there. What an adopter actually receives โ€” AgentResult today, whatever T2.3.3 ships tomorrow โ€” is decided here, behind the port. That seam is why the public result shape can change without the invocation loop being edited.

ResponseAdapter

ResponseAdapter(chat_model: Any, output_type: type | None, *, repair_attempts: int = 0)

Implements ResponsePort against the simple facade's value types.

Source code in src/symfonic/agent/backend/response.py
def __init__(
    self, chat_model: Any, output_type: type | None, *, repair_attempts: int = 0
) -> None:
    self._chat_model = chat_model
    self._output_type = output_type
    self._repair_attempts = repair_attempts

extract async

extract(transcript: Transcript) -> Any

Run the terminal extraction pass (RES-8).

It emits no text_delta of its own, which is what keeps EVT-3's text/stream equality true when output_type is set.

Source code in src/symfonic/agent/backend/response.py
async def extract(self, transcript: Transcript) -> Any:
    """Run the terminal extraction pass (RES-8).

    It emits no ``text_delta`` of its own, which is what keeps EVT-3's
    text/stream equality true when ``output_type`` is set.
    """
    from symfonic.agent.structured import extract_structured_output

    return await extract_structured_output(
        self._chat_model,
        list(transcript.wire),
        self._output_type,
        repair_attempts=self._repair_attempts,
    )