Conversation
🦋 Changeset detectedLatest commit: 6ad23e6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 39 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
davidzhao
added this pull request to stack #2502
September 15, 2026 06:32
Port of livekit/agents#7131. Dispatch timeline: the worker stamps receivedAt/acceptedAt/assignedAt on the running job info and the process pool stamps launchedAt; they travel in the startJobRequest message. job_entrypoint is back-dated to the availability request, carries one event per stage (job_received, job_accepted, job_assigned, process_assigned, entrypoint_started, job_started_on_server) and the seconds between adjacent stages as lk.job.*_latency attributes. It spans the whole job: created before the entrypoint, ended after job_shutdown; the entrypoint returning is an event, a throwing entrypoint is recorded redaction-aware. Join keys lk.room_sid, lk.dispatch_id, lk.job.worker_id, lk.job.agent_id land on job_entrypoint and agent_session; a linked SIP participant's sip.* attributes are copied onto agent_session under lk.sip.*, the phone number as lk.pii.sip.phoneNumber. The trace pipeline is up before the job's first span: JobContext prepares the cloud provider at job start (prepareCloudTracer) with a gated exporter that holds the job's spans, oldest first up to 1024, until initRecording decides, then uploads (redacting them if the session enabled redaction) or drops them; a job that never registers drops them at cleanup. setupCloudTracer reuses the prepared provider. Startup: room_connect around JobContext.connect, session_start grouping AgentSession.start() with start_agent_activity, setup_toolsets, RoomIO's wait_for_participant, wait_for_audio_track (track_subscribed and first_frame events, lk.first_frame_delay) and publish_audio_output; all parented explicitly via tracer.detachedSpan and never made current, so the long-lived tasks they spawn do not inherit them. Events on agent_session: participant_linked, participant_disconnected, connection_state_changed, agent_state_changed, user_state_changed. Shutdown: session_close around the AgentSession teardown with lk.close_reason and lk.close.drain, drain_agent_activity and on_exit nested; job_shutdown around the job's shutdown sequence with lk.shutdown.reason and lk.shutdown.user_initiated, children on_session_end, session_end_upload, room_disconnect and one shutdown_callback per callback named by lk.callback.name. The job's remaining spans are flushed after the root span ends, since the job process exits explicitly. Adaptations: Node has no forkserver, so ipc/_preload runs the framework's one-time warm-up in each job process before the user prewarm (the rtc-node native binding loads at import and its runtime cannot be started early); no entrypoint_cancelled event since promises are not cancelled; every shutdown callback gets a span (JS registers no framework callbacks there); pre_connect_audio is not implemented in JS; per-job telemetry release and asyncio.to_thread offloading have no counterpart. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
davidzhao
force-pushed
the
dz/telemetry-startup-shutdown
branch
from
September 15, 2026 06:46
8d6d8bf to
6ad23e6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Port of livekit/agents#7131. Stacked on #2496.
Description
Before the first turn and after the last one the trace had a single span,
job_entrypoint, so "the agent took 4 s to say hello" and "the job hung on shutdown" could not be split into their steps. This adds the dispatch timeline, the startup spans, the shutdown spans, and the join keys for lining the agent trace up with server, SIP, and client events.Dispatch timeline. The worker stamps
receivedAt,acceptedAt,assignedAton the running job info; the process pool stampslaunchedAt.job_entrypointis back-dated toreceivedAtand gets one timestamped event per stage (job_received,job_accepted,job_assigned,process_assigned,entrypoint_started,job_started_on_server) and the seconds between adjacent stages aslk.job.accept_latency,assignment_latency,launch_latency,entrypoint_latency, and their sumdispatch_latency. Unknown stages are skipped, not guessed.job_entrypointspans the whole job. Created before the user entrypoint runs and ended afterjob_shutdown; the entrypoint returning is anentrypoint_returnedevent, a throwing one is recorded redaction-aware.agent_sessionis now its child, so one trace covers dispatch → session → teardown. Join keyslk.room_sid,lk.dispatch_id,lk.job.worker_id,lk.job.agent_idon both; a linked SIP participant'ssip.*attributes land onagent_sessionaslk.sip.*, with onlysip.phoneNumberunderlk.pii..The trace pipeline is up before the job's first span. The cloud tracer provider used to be created in
initRecordinginsidesession.start(), so in a process's first job every earlier span was a non-recording stub.JobContext._prepareTelemetrynow creates the provider and a per-job gated exporter when the job starts; the gate holds the job's spans (oldest first, bounded at 1024) untilinitRecordingdecides, then uploads (redacting if the job asked for it) or drops them, and drops them at cleanup if the job never registers.Startup:
room_connect,session_start(groupingstart_agent_activity,setup_toolsets,wait_for_participant,wait_for_audio_trackwithtrack_subscribed/first_frameevents andlk.first_frame_delay,publish_audio_output), events onagent_sessionfor participant, connection and state changes. Startup spans are never made current: they are parented explicitly so the long-lived tasks they spawn do not inherit them.Shutdown:
session_close(lk.close_reason,lk.close.drain;drain_agent_activityandon_exitinside),job_shutdown(lk.shutdown.reason,lk.shutdown.user_initiated; childrenon_session_end,session_end_upload,room_disconnect, oneshutdown_callbackper callback named bylk.callback.name).Changes Made
ipc/job_trace.ts(new):startJobSpan,recordDispatchTimeline,serverTimestampMs,callbackName.telemetry/span_gate.ts(new):JobSpanGateExporter;telemetry/traces.ts:prepareCloudTracer/discardPreparedCloudTracer/flushCloudTraces,tracer.detachedSpan, shared auth/resource/metadata helpers;telemetry/redaction.ts:redactReadableSpanfor held spans released after the job chose redaction.ipc/job_proc_lazy_main.ts,job.ts,job_lifecycle.ts: prepare telemetry, root span lifecycle,job_shutdowntree, final trace flush beforeprocess.exit.worker.ts,ipc/proc_pool.ts: dispatch timestamps (epoch ms; structured-cloned through IPC, no proto change).voice/agent_session.ts,voice/agent_activity.ts,voice/room_io/*:session_start/session_close, explicit trace contexts, session events, SIP attributes,wait_for_audio_track(later participant switches parent to the session root).telemetry/session_context.ts:sessionSpan,sessionStartContext;telemetry/utils.ts:participantAttributes.ipc/_preload.ts(new): the framework's one-time warm-up before the user prewarm.Adaptations from the Python source
_preload.tswarms only the local inference binding; the rtc-node binding loads at import time and its runtime cannot be started early.asyncio.to_threadcleanup offloading: not applicable.entrypoint_cancelled: JS never cancels the entrypoint promise; omitted.pre_connect_audioevent: JS RoomIO has no pre-connect audio handler.shutdown_callbackspan.flushJobTracesstep: the JS job process never force-flushed traces beforeprocess.exit(0); without it the now-late-endingjob_entrypointwould be lost.AutoSubscribeis rendered assubscribe_all|subscribe_none|video_only|audio_onlyto match the Python attribute values.Testing
ipc/job_trace.test.ts,telemetry/startup_spans.test.ts,telemetry/prepared_tracer.test.ts,voice/session_lifecycle_span.test.ts;job_lifecycle.test.ts,proc_pool.test.ts,recording_disabled.test.ts,trace_types.test.tsextended.wait_for_audio_trackfirst-frame timing andpublish_audio_output.agentssuite green; build, typecheck, lint, API report updated.🤖 Generated with Claude Code