OpenAI gpt-4o-mini-tts (female voice nova by default; TTS_MODEL/TTS_VOICE) renders OGG/Opus,
sent with sendVoice in order with rendered output. Up to 4500 characters per call, split
into 1500-character parts at paragraph/sentence/word boundaries; all parts are synthesized
before any is sent, and API errors come back to the agent as text with the key hidden.
On whenever OPENAI_API_KEY is set.
Add docs/a2a.md (concepts, file formats, endpoints, sessions, task
lifecycle, configuration, security notes, curl examples) describing
what src/Volcanic.AgenticCore.A2A.Server actually does. Add an A2A
project paragraph to architecture.md, an "A2A" section to
telegram-bot.md (/a2a, notify_owner, isolated sessions, port 8080),
A2A_ENABLED/A2A_PUBLIC_URL and the aspnet image to docker.md, and
project-map/test-command updates to CLAUDE.md.
Mark the A2A server design spec implemented and record the deviations
found while building it (A2AHostOptions, synchronous
IA2ACallerDirectory.Find, generic WorkspaceCallerDirectory, per-status
push payload, split file-part error handling, the outbound guarded
handler, the per-caller server/router architecture, the restart grace
period, the owner= log field, the aspnet image, and the actual push
retry schedule). Note the aspnet image in the docker-deployment spec
too, without rewriting its historical decisions.
mcr.microsoft.com/dotnet/aspnet:10.0-noble already sets ASPNETCORE_HTTP_PORTS=8080;
also setting ASPNETCORE_URLS made Kestrel log an override warning on every start.
- Each run's first text delta replaces the response artifact (append:false) and a resumed task
drops the previous run's response, so a failed/canceled continuation never keeps old text.
- Resumed is built from a fresh store read, history chronological (question, then answer),
timestamps on the TaskUpdater clock.
- Pool.Track refuses a second unfinished run of the same task; the pre-check rejects
continuations of a running task with UnsupportedOperation.
- Tests: continuation history, streaming continuation, response replacement, concurrent
continuation; busy test waits for the model call; TimeoutException in waits; push test
matches TASK_STATE_COMPLETED; harness cleans up on failed start.
A continued task (input-required -> new message) produced only status updates, so the SDK
answered 'Agent handler did not produce any response events'. The handler now enqueues the
resumed task (caller message and question in history, working) as the first event.
The guarded SocketsHttpHandler sets UseProxy = false: a proxy would make the connection and
skip the ConnectCallback address check.