Repository navigation
DRU-660 -- The calls server: Pipecat carries the call - #735
Merged
Merged
Conversation
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
September 27, 2026 14:37
bedef93 to
994d6f1
Compare
czpython
force-pushed
the
codex/dru-659-druks-answers-a-call
branch
4 times, most recently
from
October 4, 2026 11:06
6c8108d to
e698e63
Compare
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 11:19
994d6f1 to
39c6d5e
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 13:30
39c6d5e to
87a9dae
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 13:32
87a9dae to
90970ce
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 13:42
90970ce to
bf47513
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 13:46
bf47513 to
1b71381
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 14:09
1b71381 to
5d1c193
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 14:13
5d1c193 to
8dfb607
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 14:16
8dfb607 to
fa22f19
Compare
czpython
force-pushed
the
codex/dru-660-voice-server
branch
from
October 4, 2026 14:19
fa22f19 to
3d276fd
Compare
czpython
enabled auto-merge (squash)
October 4, 2026 14:22
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
The calls server carries a phone call. It takes Twilio's audio stream, asks Druks to pick up the call, holds the call with the speech-to-speech model, runs the Bot's tools through
/mcp, and posts each line to Druks. It is its own program on Pipecat, with its own image and its own release cycle.druks-calls/holds the packagecalls, with its ownpyproject.tomlanduv.lock. It pinspipecat-ai1.12.0 with the Google, MCP, OpenAI, and WebSocket extras. The backend does not depend on it, and it imports nothing from Druks.app.pyservesGET /healthzand a WebSocket at/_calls/{token}. At the handshake it postspickupto{DRUKS_URL}/_external/calls/events/with the token and the stream'sX-Twilio-Signature. It closes the stream when Druks refuses, and it refuses a stream beyondMAX_CALLSlive calls.Call.runbuilds one pipeline for each call: the Twilio transport, the realtime service of the model's vendor (openai/…orgoogle/…), and one MCP client with the pickup's key and conversation header. The model gets the pickup's prompt, then the facts, then the tools. A model that cannot connect ends the call.lineunder its number, and Druks orders a call by those numbers.end_callis the model's tool to end the call. A call also ends afterno_speech_secondsof silence, atmax_call_seconds, or when the caller hangs up. The server then postsended.CallsEventsat/_external/calls/events/, and a call's stream URL iswss://<webhook host>/_calls/<call token>.Twilio.linktakes the address for a number's calls ascalls_url.openaiorgoogle, because the calls server runs only those two. It has a new optional field, the transcription model, which an OpenAI model uses to write the caller's words as text.deploy/calls/Dockerfilebuilds the image fromdruks-calls/, withgoss.yamlbeside it.build-calls-image.ymlpublishesghcr.io/czpython/druks-callsonly when the server changes.on-pull-request-calls.ymlruns its tests, builds the image, and runs the goss checks, also only when it changes. The backend PR workflow lintsdruks-calls/.deploy/compose.yamlhas no calls service anddruks.tomlhas no switch for it.docs/deployment.mdgives the service to add tocompose.override.yaml. A Druks upgrade restarts it only when a new calls image exists.deploy/caddy/Caddyfilepasses/_calls/*to the calls server, on the webhook host and on the:8000listener.docs/deployment.mdcovers the calls server and how to add it,docs/full-local.mdthe tunnel for calls,docs/chat.mdwhen a call ends, andAGENTS.mdthe project.