Skip to content

Run the Example

The repository ships one example, examples/basic-bridge - a complete, working embedding in about 25 lines. This page walks through it so you understand every moving part before writing your own.

A single main.py that:

  1. loads a .env file,
  2. starts the bridge with start_server(),
  3. shuts down gracefully on Ctrl-C / SIGTERM (draining live calls, letting a goodbye finish).

That is the whole thing - and that is the point. Unlike the sibling bridges there are no tool or vision hooks to wire: your Line agent’s brain lives on Cartesia’s platform, and the bridge forwards the Teams context to it automatically (Your Line Agent).

Terminal window
pip install cartesia-msteams-bridge
git clone https://github.com/komaa-com/cartesia-msteams-bridge-py
cd cartesia-msteams-bridge-py/examples/basic-bridge
cp ../../.env.example .env # fill in the three required values
python main.py

The three values in .env:

VariableWhat to put there
CARTESIA_API_KEYYour Cartesia API key (server-side only; each call mints a short-lived token, so the key never rides the agent socket).
CARTESIA_AGENT_IDThe deployed Line agent that should answer calls.
WORKER_SHARED_SECRETThe shared secret from StandIn pairing - both sides must match exactly.

Expose port 8080 with a tunnel (see Getting Started), set your StandIn identity’s agent WebSocket URL to the wss://…/voice/msteams/stream form, and place a Teams call - your Line agent answers.

import asyncio
import signal
from cartesia_msteams_bridge import load_config, load_dotenv, start_server
async def main() -> None:
cfg = load_config()
server = await start_server(cfg)
...
await stop.wait() # run until SIGTERM / Ctrl-C
await server.close() # drain live calls gracefully
  • load_dotenv() reads .env from the working directory (existing environment always wins), so the example runs the same way the CLI does.
  • load_config() reads every setting from environment variables and fails loud on a missing required variable or a non-numeric number - a typo stops startup with a clear message instead of silently misbehaving.
  • start_server(cfg) starts the WebSocket server and returns a BridgeServer handle. The connect_line keyword is the test seam (inject a fake agent); production uses the default, which mints a per-call access token and opens the Line stream.
  • await server.close() ends every live call with a spoken-protocol session.end (not a hard socket drop), letting an in-progress goodbye finish, before the process exits.
  • Embedding in a larger service? Hook your shutdown path to the handle: await server.drain() ends live calls without stopping the listener; server.close() drains and stops - see Library API.
  • Give the agent a deterministic opening line (CARTESIA_INTRODUCTION) and set the governor variables (MAX_CALL_MINUTES, CARTESIA_TTS_MODEL + CARTESIA_TTS_VOICE_ID, GOODBYE_TEXT) before going to production.
  • Teach your Line agent code to consume the bridge’s call_context and goodbye_request events - shapes in Your Line Agent.

If you only need the stock behavior, skip the embedding entirely and run the cartesia-msteams-bridge CLI.