symfonic.agent.fastapi.shared_chat¶
shared_chat ¶
Explicit compatibility composition with one selected native chat handler.
create_shared_chat_router ¶
create_shared_chat_router(agent: Any, host: Any, conversation: Any, *, prefix: str = '/api/v1', app: Any = None, typed_resume: bool = False, metrics_collector: Any = None) -> Any
Select native chat, durable legacy chats listing, and explicit refusals.
Pass conversation.transcript_reader() as agent: the authority's own
reader, with no facade constructed. compatibility_reader(reader_factory)
still composes the facade's public transcript read instead. Mount
this root once, in place of the compatibility root. /stream is served
by the same Agent host and authority with the compatibility chunk frames,
an issued session id in the X-Session-ID header, and an error frame
for an empty or tool-limit final (legacy sends done('') for empty).
/stream/typed runs the same turn with the frozen typed frames, and
refuses a pause terminal; resume refuses with 409 before calling the
facade. No pause token or native host ticket is translated or assumed
interchangeable.
typed_resume=True opts into guarded durable resume: it requires the
PostgreSQL authority and the supported human continuation host (refused
at mount otherwise), lets /stream/typed alone pause, and serves
/resume for those pauses on any worker. /chat and /stream
still refuse the human capability.
metrics_collector mounts /metrics/conversations and its detail
over the collector the host's telemetry writes, answered only for the
conversations this authority answers the principal's transcript for.
/metrics/summary stays unmounted: it is a tenant aggregate. Only turns
whose Agent composes telemetry over that collector are recorded;
nothing here verifies that pairing per turn.
Pass the outermost FastAPI app and include this router directly in it;
mounting the selected app beneath another app is not governed.
Source code in src/symfonic/agent/fastapi/shared_chat.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | |
mount_selected_chat_root ¶
mount_selected_chat_root(app: Any, *, selection: str = 'agent', legacy_agent: Any = None, compatibility_reader: Any = None, host: Any = None, conversation: Any = None, prefix: str = '/api/v1', typed_resume: bool = False, metrics_collector: Any = None) -> Any
Compose exactly one chat family in the outermost served FastAPI app.
This is the supported native HTTP boundary. The caller must serve app
directly; a selected child mounted below an external parent cannot inspect
an earlier parent route and is outside this contract. Only selection="agent"
is supported; legacy selection or legacy_agent raises the removed factory's
versioned migration error without invoking it. The native default requires
host and conversation and shares one authenticated conversation authority
between /chat and /chats. With compatibility_reader omitted it
composes conversation.transcript_reader(), the authority's own reader,
so no SymfonicAgent is constructed. That reader is composed after the
host, resume, metrics, production-auth, owner and route-conflict
refusals, so a refused mount leaves the authority's single reader slot for
a corrected mount on a fresh app; an explicitly supplied reader the
authority composed (including compatibility_reader(factory)) is still
accepted. Any other authority type is refused before a reader is composed.