Skip to content

symfonic.agent.backend.transcript

transcript

The transcript handle the conversation adapter hands the kernel.

Two parallel views of one turn: the facade-typed Message list an adopter gets back, and the LangChain list the provider is actually sent. They are kept side by side rather than derived from one another because the wire view has to carry provider-specific structure (remapped tool-call ids, multimodal content blocks) that the typed view deliberately does not model.

The kernel never opens this object. It receives it from open_turn, hands it back on every port call, and that is the whole of its involvement — which is what lets the wire format change without the invocation loop noticing.

Transcript dataclass

Transcript(typed: list[Message] = list(), wire: list[BaseMessage] = list())

One invocation's messages, in both vocabularies.

append_wire

append_wire(message: Any) -> None

Append a provider message, ignoring a round that produced none.

Source code in src/symfonic/agent/backend/transcript.py
def append_wire(self, message: Any) -> None:
    """Append a provider message, ignoring a round that produced none."""
    if message is not None:
        self.wire.append(message)