@egma/livekit package works with JavaScript and TypeScript workers. simulation reports the agent’s tools, installs test mocks, and sends the agent’s trace to its simulation record. monitor sends production traces to Monitoring.
Use simulation for every LiveKit simulation, including tests without mocks. You can call both functions in one worker; each acts only in its own kind of room. First connect the worker through LiveKit.
Install
Use Node.js 22 or newer. Install the published package in your voice agent’s repository:
Both functions export spans, so the package requires
1.5.5, the first LiveKit Agents JS release with the public mock-tool hook and OpenTelemetry fan-out bridge. Calling either function on an older version gives a direct version error. You do not need to pin to 1.6.4.
Configure Egma
Create a project-scoped API key in Settings → API keys, or runegma project api-key create --name "LiveKit worker" from an initialized agent repository.
Set these values in the worker’s deployment environment:
Keep the key in your deployment’s secret store. The URL must be reachable from the worker. For a remote or containerized worker, use your server’s reachable address instead of
localhost. Both simulations and monitoring need these settings.
Add the SDK to your worker
Callmonitor(ctx) first in the job entrypoint. Call await simulation(agent, ctx, session) after creating the agent and session, before session.start.
Set the Egma variables before running the worker. This example defines the complete entrypoint for a small receptionist. It uses LiveKit’s model inference settings and Zod for the tool schema:
Monitor production
Use the configured Egma URL and project key, deploy the worker, and make a production call. Open Monitoring in the key’s project. LiveKit sends its own traces; you do not need to turn on a second monitoring setting in Egma. The helper exports OTLP/HTTP protobuf batches to/v1/traces and flushes the last batch when the job stops. It keeps LiveKit Cloud observability enabled.
The egma-sim- room prefix is reserved for simulations. monitor skips those rooms; simulation exports their traces to the simulation record. Use another prefix when your system creates production rooms.
Existing OpenTelemetry setup
Callmonitor before you install custom tracing when possible. The helper adds to a compatible existing provider. It does not replace an incompatible provider.
If another integration already owns the provider, pass existingTelemetry with that provider and a registerSpanProcessor callback. The callback must add the Egma processor to a mutable processor group inside that same provider, such as LiveKit’s telemetry.FanoutSpanProcessor.
OpenTelemetry JS 2.x cannot add a processor directly to an already-created provider. If your existing provider has no way to add one, change its setup to include that processor group before registering it.
If no conversation appears
Check the worker’s deployment and OpenTelemetry logs. Confirm that the key is scoped to the correct project and has write access. Check that the worker can reachEGMA_URL. An organization-wide key cannot ingest traces.
Missing settings, invalid settings, an unsupported LiveKit version, or a conflicting tracer provider cause a direct setup error. Network failures happen in the worker; Egma can show a conversation only after its trace arrives. Restart the worker after changing the Egma settings or tracing setup.
Mock tool responses
Use the exact registered tool name in the test. For the example above:answer or error. In a simulation room, simulation sets up trace export, connects if needed, sends the agent’s tool names and schemas to Egma, and installs the mocks selected by the test. It follows agent handoffs in the same session.
The function sends the agent’s own conversation trace to Egma even when a test has no mocks. The simulation transcript includes the agent’s turns and tool calls, including real tools. Calls answered by a mock are marked mocked. Simulation spans are batched every second and flushed when the session closes and when the job stops.
Call
simulation once for the initial agent. LiveKit keeps its JavaScript mock-tool state at process level, and the exporter is bound to the job’s room. Egma rejects a second overlapping session or another job in the same process. Keep the normal LiveKit arrangement of one job per child process. Cleanup runs when the session closes or the job stops.
The function has no total startup deadline. It waits while the simulation room is active; individual token requests and hello attempts keep their transport timeouts. A permanent refusal, room disconnect, or Egma participant departure ends startup. Do not catch NotReported and start the session anyway. Check the room connection, Egma’s participant, and the installed SDK when it occurs. Missing settings or an incompatible tracing setup throw a plain Error instead. Without the SDK report, Egma fails the LiveKit simulation.
Check the simulation’s tool calls to confirm the mock matched. See Mock tool responses.
After your normal session.start returns, LiveKit publishes its native agent state. Egma waits for an initialized state before sending the first simulated input. This wait uses the simulation’s configured duration. You do not need another readiness callback.
When that simulation ends, Egma finishes pending output and its exact participant leaves the room. The SDK closes the AgentSession you supplied, which completes LiveKit’s native session trace, flushes the final evidence, and releases entrypoint code that is waiting for session close. An abrupt room disconnect closes the session as well. These listeners are installed only after the Egma participant accepts the tool report in a simulation room.
Test in chat mode
For a chat connection, keep theegma-sim-chat- branch shown in the example. It disables audio input and output and turns off speech-synchronized transcription. Also keep independent audio publishers off in that branch.
Other room names use your normal voice settings. Egma stops a chat simulation if the worker publishes audio.
Read test startup data
Add the values your agent needs at startup to a test:job_dispatch_metadata as a compact JSON string. It adds no Egma keys and leaves room metadata empty. The SDK detects simulations from the room name.
Function reference
MonitorOptions and SimulationOptions accept the same settings:
ExistingTelemetry contains provider and registerSpanProcessor. It can also supply createCloudSpanProcessor to customize how the LiveKit Cloud processor is created. The package exports both option types.
Each function returns before reading settings in the room type it does not handle. The active function still needs EGMA_URL and EGMA_API_KEY, so a worker used only for simulations needs both settings too. Use a separate worker process for each LiveKit job.