roark-analytics-python-livekit
A Roark analytics integration for LiveKit Agents. Drop one helper into your agent entrypoint — Roark captures call lifecycle, transcripts, tool calls, metrics, and a stereo audio recording. No other code changes required.
- Tested with
livekit-agents1.x - Python 3.10+
- Built for self-hosted LiveKit — works against your own
livekit-serverand in localconsolemode
Maintained by Roark. File issues at https://github.com/roarkhq/sdk-roark-analytics-python-livekit/issues.
Contents
- Quick start
- How it works
- Examples
- Kill switches
- Troubleshooting
- Configuration reference
- Development
- License
Quick start
1. Install
pip install roark-analytics-python-livekit
2. Configure
Set one env var:
ROARK_API_KEY=rk_live_...
The Roark API key is all you configure — the helpers know their own service endpoints.
3. Wire observe_session
from livekit.agents import Agent, AgentSession, JobContext
from roark_analytics_python_livekit import observe_session
SYSTEM_PROMPT = "You are a friendly voice assistant."
class Assistant(Agent):
def __init__(self):
super().__init__(instructions=SYSTEM_PROMPT)
async def entrypoint(ctx: JobContext):
# Connect before observe_session: the room sid (used as the call id) is only
# available once connected.
await ctx.connect()
session = AgentSession(stt=..., llm=..., tts=...)
await observe_session(
ctx, session,
api_key="rk_live_...",
agent_id="support-bot-v3",
agent_name="Support Bot v3",
agent_prompt=SYSTEM_PROMPT,
)
await session.start(room=ctx.room, agent=Assistant())
That's it — transcripts, tool calls, metrics, and the stereo recording flow to Roark automatically.
How it works
The helper subscribes to the standard AgentSession event surface and ships
a compact event timeline to Roark:
| Phase | Source | What's captured |
|---|---|---|
| Session start | JobContext.connect() |
call-started POST. Agent is lazy-registered on Roark the first time it sees this agent_id. |
| Transcripts | session.on("conversation_item_added") |
ChatMessage role + content. Both user and assistant turns. |
| Tool calls | session.on("function_tools_executed") |
Paired tool_call / tool_result records, keyed by tool_call_id. |
| Metrics | session.on("metrics_collected") |
EOU / STT / LLM / TTS / Agent latency + LLM token usage. |
| Audio | Taps on session.input.audio (user) + session.output.audio (agent) |
Stereo PCM (L=user, R=agent), chunked PUTs to Roark via /v1/integrations/livekit-sdk/chunk-upload-url. Tapping the session's own audio I/O works the same in dev (room) and console mode. |
| Session end | ctx.add_shutdown_callback(...) (or explicit await state.aflush()) |
Flushes pending state, drains in-flight uploads, POSTs call-ended. Roark stitches the chunks into a WAV on its side. |
Failures are logged and swallowed — the helpers never raise into the session. Your agent keeps running even if Roark is unreachable.
Examples
A complete, runnable self-hosted example ships in
examples/ — a uv project with a
Roark-instrumented support agent plus a short README. The simplest way to try it
is local console mode (mic + speakers, no LiveKit server or browser needed):
cd examples
uv sync
cp .env.example .env # fill in provider keys + ROARK_API_KEY
uv run --env-file .env agent.py console
See examples/README.md for local-server mode (a
self-hosted livekit-server + a room client). Everything runs on your own
machine — no LiveKit Cloud.
Kill switches
Use these env vars to disable Roark instrumentation at runtime without touching code:
| Variable | Effect |
|---|---|
ROARK_OBSERVABILITY_ENABLED=false |
observe_session becomes a no-op (returns None). |
Treated as off: false, 0, no, off (case-insensitive). Anything else
(including the variable being absent) keeps the feature enabled.
Troubleshooting
Calls aren't finalizing on Roark
The helper registers a shutdown_callback on the JobContext, which fires
when LiveKit ends the job. If your transport tears down without firing the
hook, call await state.aflush(reason="...") explicitly from your own
disconnect handler — aflush() is idempotent.
Transcripts arrive empty
Transcripts are sourced from the conversation_item_added event on
AgentSession. If you're using a custom pipeline that bypasses
AgentSession.start(room=…, agent=…), that event may never fire — verify by
adding your own session.on("conversation_item_added", print) listener.
Recording is missing one side
The user side is tapped from session.input.audio; the agent side from
session.output.audio. The taps are installed by observe_session, so it
must be called before session.start() (otherwise the session captures
its audio I/O before the taps are in place). Check the worker logs for
tapping user audio input / tapping agent audio output INFO lines — if one
is missing, that side will be silent on the merged stereo recording.
Configuration reference
| Parameter | Type | Default | Notes |
|---|---|---|---|
api_key |
str |
— | Required. Roark API key. |
agent_id |
str |
— | Required. Customer-stable agent identifier. |
agent_name |
str | None |
None |
Display name. |
agent_prompt |
str | None |
None |
System prompt; persisted as the agent's prompt revision. |
livekit_call_id |
str | None |
ctx.job.room.sid → ctx.room.sid → ctx.job.id → UUID |
Stable call identifier, sent on every Roark record as livekitCallId. Defaults to the room sid (the id Roark keys the call on); resolve the live ctx.room.sid by calling observe_session after ctx.connect(). |
capture_audio |
bool |
True |
Set to False to skip stereo capture (saves bandwidth). |
capture_logs |
bool |
True |
Reserved for future log streaming. |
is_test |
bool |
False |
Tag the call as a test on the Roark dashboard. |
**metadata |
dict |
{} |
Free-form metadata forwarded on call-started. |
Development
pip install -e ".[dev]"
pytest
ruff check .
License
MIT — see LICENSE.
Metadata
Release files for roark-analytics-python-livekit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| roark_analytics_python_livekit-0.1.0.tar.gz | 418.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| roark_analytics_python_livekit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 446.0 kB
Release files / roark_analytics_python_livekit-0.1.0.tar.gz
| Download URL | roark_analytics_python_livekit-0.1.0.tar.gz |
|---|---|
| Size | 418.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
affb18f025580d40f468c96f8864f7ee083d1d8a2995e6fc5532e683673d7286
|
|
BLAKE2b-256 checksum How to use checksums |
53d131b64f31eb20a9388792b75960e98b2b590c1a432c984e2d6e75c1d8da85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 4, 2026.
Transparency logRelease files / roark_analytics_python_livekit-0.1.0-py3-none-any.whl
| Download URL | roark_analytics_python_livekit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 27.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8a52e2717a6e4937db3314e2a34dcb60773830036231eaeb3eb801e240bfa7b6
|
|
BLAKE2b-256 checksum How to use checksums |
06eeed1c7412f37a4de1439d1d98ef7bec3449473c7e8da844f8c8ea4ef7b2a6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 4, 2026.
Transparency log