What a call looks like
lokutor.call span itself arrives when the call ends.
Set it up
- In the dashboard, open Settings → Observability.
- Endpoint: the OTLP endpoint your tool gives you, the value it tells you to put in
OTEL_EXPORTER_OTLP_ENDPOINT./v1/tracesis added unless the address already ends in it. - Headers: what your tool needs to accept the data, usually an API key. Values are masked once saved.
- Save, then Send a test trace. Lokutor exports one span named
lokutor.testwith what you saved and shows your endpoint’s answer: accepted, or the error it returned (a wrong key shows as401).
Any tool that accepts OTLP over HTTP works. Lokutor sends protobuf over https only, to a public address: an endpoint that resolves to a private, loopback or link-local address is refused, as are redirects to plain http.
Spans and attributes
Every span carries the resource attributesservice.name = lokutor-voice-agent and lokutor.account.id. Names follow OpenTelemetry’s generative AI conventions where one exists (chat, execute_tool, gen_ai.*). Lokutor’s own are under lokutor.*.
lokutor.call
The call, from start to hang-up. Span kind server.
lokutor.turn
One caller turn, from the last moment the caller was speaking to the first audio of the reply: the wait the caller hears.
A stage that did not run, or could not be timed, is left out rather than sent as 0.
lokutor.agent_turn
The agent speaking without the caller having spoken: lokutor.trigger is opening, silence_timeout (a check-in after silence), farewell, or host_note (after a transfer nobody answered). lokutor.latency.response_ms is from the request to its first audio.
chat
A language-model request. Span kind client, gen_ai.operation.name = chat.
Every token is counted once, so adding
gen_ai.usage.* up over a trace gives the call’s total:
- reply: the turn’s request.
- after_tools: a turn with tools asks the model again after they run. This span carries what those requests added and has no duration of its own.
- speculative: to answer faster, Lokutor may start a reply while the caller is still finishing. When the turn uses it, its tokens are on the turn’s
replyspan: the speculative span saysusedand carries none (a reply the turn took over while it was still streaming has no speculative span at all). When it is thrown away (unusedand the other outcomes), its tokens are here: they were spent all the same.
execute_tool {name}
A tool call: gen_ai.tool.name, and lokutor.tool.outcome = ok, failed or cancelled (the call ended, or the caller spoke again first). A failed tool also sets the span’s status to error. The error’s text is not sent: it can contain your system’s URLs or data.