Roark analytics integration for LiveKit Agents — capture call lifecycle, transcripts, tool calls, metrics, and stereo recordings from any LiveKit Agents session.
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file roark_analytics_python_livekit-0.1.0.tar.gz.
File metadata
- Download URL: roark_analytics_python_livekit-0.1.0.tar.gz
- Upload date:
- Size: 418.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
affb18f025580d40f468c96f8864f7ee083d1d8a2995e6fc5532e683673d7286
|
|
| MD5 |
7406f4e84947a2aff64e70016f2dfc97
|
|
| BLAKE2b-256 |
53d131b64f31eb20a9388792b75960e98b2b590c1a432c984e2d6e75c1d8da85
|
Provenance
The following attestation bundles were made for roark_analytics_python_livekit-0.1.0.tar.gz:
Publisher:
release.yml on roarkhq/sdk-roark-analytics-python-livekit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
roark_analytics_python_livekit-0.1.0.tar.gz -
Subject digest:
affb18f025580d40f468c96f8864f7ee083d1d8a2995e6fc5532e683673d7286 - Sigstore transparency entry: 1720986366
- Sigstore integration time:
-
Permalink:
roarkhq/sdk-roark-analytics-python-livekit@9770b29ba20a474a1ee90b60d9a808fd284c8c48 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/roarkhq
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9770b29ba20a474a1ee90b60d9a808fd284c8c48 -
Trigger Event:
push
-
Statement type:
File details
Details for the file roark_analytics_python_livekit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: roark_analytics_python_livekit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a52e2717a6e4937db3314e2a34dcb60773830036231eaeb3eb801e240bfa7b6
|
|
| MD5 |
ee11395019b8d3259f13eacec08184af
|
|
| BLAKE2b-256 |
06eeed1c7412f37a4de1439d1d98ef7bec3449473c7e8da844f8c8ea4ef7b2a6
|
Provenance
The following attestation bundles were made for roark_analytics_python_livekit-0.1.0-py3-none-any.whl:
Publisher:
release.yml on roarkhq/sdk-roark-analytics-python-livekit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
roark_analytics_python_livekit-0.1.0-py3-none-any.whl -
Subject digest:
8a52e2717a6e4937db3314e2a34dcb60773830036231eaeb3eb801e240bfa7b6 - Sigstore transparency entry: 1720986465
- Sigstore integration time:
-
Permalink:
roarkhq/sdk-roark-analytics-python-livekit@9770b29ba20a474a1ee90b60d9a808fd284c8c48 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/roarkhq
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9770b29ba20a474a1ee90b60d9a808fd284c8c48 -
Trigger Event:
push
-
Statement type: