discussion_helper.api module
The HTTP surface: a conversation you can watch, interrupt and end.
Module summary
A spoken conversation does not fit a request. It has no single answer, it lasts minutes, and the interesting part is what happens during it. So this surface is not one endpoint that returns a reply — it is a session you create, a stream you follow, and a button you press.
Three ways in, and they are genuinely different products rather than three spellings of one:
A local session (
POST /sessions) opens the microphone on this machine. The caller is a dashboard, a hotkey, an agent — something that starts a conversation it is not itself part of, and then watches.A remote session (
POST /sessionswithtransport="remote", thenWS /sessions/{id}/audio) puts the microphone at the other end of the socket. The browser captures and plays; this end recognises, thinks and speaks. That is how every hosted voice agent works, and the audio really does cross the wire as PCM.A single text turn (
POST /turn) runs one exchange through the same loop with no audio at all. The honest use is testing — and it is what makes the MCP surface meaningful, since an agent has no microphone.
What this surface refuses to pretend
It does not pretend an HTTP request can hold a microphone. POST /sessions
returns immediately with an id; everything live happens on the event stream or
the socket. And POST /sessions/{id}/interrupt goes through the same
Voice.stop() the microphone’s barge-in uses, because a button that
stopped the audio some other way would stop it in some other way.
- class discussion_helper.api.StartRequest(*, transport='fake', turns=<factory>, allow_barge_in=True, barge_in_grace_s=0.35, max_reply_sentences=0, silence_timeout_s=0.0, voice='', language='')[source]
Bases:
BaseModelBody for
POST /sessions.- Parameters:
transport (str) –
"local"opens the microphone on the machine running this server."remote"waits for a client to connect to the session’s WebSocket and send audio or text."fake"uses scripted parts — the same loop with no hardware, which is what makes this surface testable and what a caller should reach for first.voice (str) – Passed to the voice.
language (str) – Passed to the voice.
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class discussion_helper.api.TurnRequest(*, text, history=<factory>, with_audio=False, voice='', language='')[source]
Bases:
BaseModelBody for
POST /turn: one exchange, no audio.- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].