Overview
What the engine does, what it refuses to do, and where it sits.
ulai-agent-server is the voice engine. It joins an Ulai SFU room, connects an
AI backend, and runs the conversation — the audio chain, turn detection,
barge-in, the silence ladder and the end-call contract.
It ships as a container image. There is nothing to build and nothing to compile.
It holds no database, no agent store and no credentials. Everything about how a call runs — the prompt, the voice, the GCP project, the service-account key — arrives from whatever drives it, per call. That is why the configuration below is so short.
docker run -d --name agent_server --restart unless-stopped \
-p 127.0.0.1:50052:50052 \
-p 8000:8000 \
-e APP_GRPC_LISTEN_PORT=50052 \
-e APP_HTTP_PORT=8000 \
-e ULAI_GRPC_API_KEY='<64-character key>' \
asia-south1-docker.pkg.dev/arctic-operand-415316/ulai/agent_server:v1.02
Check it:
curl -s http://localhost:8000/health # → ok
That is the whole installation. See deploy it for the full walk-through, including the part that actually makes calls happen.
The agent server does not place calls by itself. It waits on port 50052 for
an agent client to tell it which room to join and which agent to run.
agent client ──gRPC :50052──▶ agent server ──▶ Ulai SFU room
(drives calls) (this image) (the conversation)
Both sides must share the same key: whatever you set as ULAI_GRPC_API_KEY
here, the client must present. Nothing happens until a client connects.
What the engine does, what it refuses to do, and where it sits.
Pull, run, verify, and connect a client.
Why the environment is short, and what arrives per call instead.
The short list that is environment, and the long list that is not.
Two ports, and what talks to them.
Deployment, observability and troubleshooting.