Skip to content

symfonic.agent.backend.reply_receipts

reply_receipts

Opt-in accepted-provider-reply provenance, not invocation commit evidence.

The callback runs at FINALIZE: subsequent finalizers/teardown can still fail. Consumers must await successful Agent.run before treating its receipt as a completed invocation. This port never normalizes text or executes operations.

CompletedReplyReceipt dataclass

CompletedReplyReceipt(invocation_id: str, run_id: str, scope_path: str, session_id: str, round: int, source: str, raw_text: str, extraction_seen: bool = False, extraction_ops: tuple[Any, ...] = (), request: Any = None, model: Any = None, _transcript: Any = None)

Immutable text/provenance of one accepted final provider reply.

Model/request handles are identity witnesses, not immutable provider data. Raw provider payload is never exposed or copied to a generic AgentResult.

ReplyProvenanceCapability

ReplyProvenanceCapability(scope: Any, receive: Any)

Explicit composition opt-in for a synchronous accepted-final observer.

Scope is supplied by the trusted AgentHost composer, not inferred from a caller's run ID. No transport/presentation/default activation is implied.

Source code in src/symfonic/agent/backend/reply_receipts.py
def __init__(self, scope: Any, receive: Any) -> None:
    if not isinstance(getattr(scope, "path", None), str) or not callable(receive):
        raise TypeError("reply provenance requires a scope and synchronous receiver")
    from inspect import iscoroutinefunction

    if iscoroutinefunction(receive) or iscoroutinefunction(type(receive).__call__):
        raise TypeError("reply provenance receiver must be synchronous")
    self.scope_path, self.receive = scope.path, receive