@livekit/agents 1.0.22 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/inference/api_protos.cjs +2 -2
  2. package/dist/inference/api_protos.cjs.map +1 -1
  3. package/dist/inference/api_protos.d.cts +16 -16
  4. package/dist/inference/api_protos.d.ts +16 -16
  5. package/dist/inference/api_protos.js +2 -2
  6. package/dist/inference/api_protos.js.map +1 -1
  7. package/dist/ipc/job_proc_lazy_main.cjs +35 -1
  8. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  9. package/dist/ipc/job_proc_lazy_main.js +13 -1
  10. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  11. package/dist/job.cjs +52 -6
  12. package/dist/job.cjs.map +1 -1
  13. package/dist/job.d.cts +2 -0
  14. package/dist/job.d.ts +2 -0
  15. package/dist/job.d.ts.map +1 -1
  16. package/dist/job.js +52 -6
  17. package/dist/job.js.map +1 -1
  18. package/dist/llm/llm.cjs +38 -3
  19. package/dist/llm/llm.cjs.map +1 -1
  20. package/dist/llm/llm.d.cts +1 -0
  21. package/dist/llm/llm.d.ts +1 -0
  22. package/dist/llm/llm.d.ts.map +1 -1
  23. package/dist/llm/llm.js +38 -3
  24. package/dist/llm/llm.js.map +1 -1
  25. package/dist/log.cjs +34 -10
  26. package/dist/log.cjs.map +1 -1
  27. package/dist/log.d.cts +7 -0
  28. package/dist/log.d.ts +7 -0
  29. package/dist/log.d.ts.map +1 -1
  30. package/dist/log.js +34 -11
  31. package/dist/log.js.map +1 -1
  32. package/dist/telemetry/index.cjs +23 -2
  33. package/dist/telemetry/index.cjs.map +1 -1
  34. package/dist/telemetry/index.d.cts +4 -1
  35. package/dist/telemetry/index.d.ts +4 -1
  36. package/dist/telemetry/index.d.ts.map +1 -1
  37. package/dist/telemetry/index.js +27 -2
  38. package/dist/telemetry/index.js.map +1 -1
  39. package/dist/telemetry/logging.cjs +65 -0
  40. package/dist/telemetry/logging.cjs.map +1 -0
  41. package/dist/telemetry/logging.d.cts +21 -0
  42. package/dist/telemetry/logging.d.ts +21 -0
  43. package/dist/telemetry/logging.d.ts.map +1 -0
  44. package/dist/telemetry/logging.js +40 -0
  45. package/dist/telemetry/logging.js.map +1 -0
  46. package/dist/telemetry/otel_http_exporter.cjs +144 -0
  47. package/dist/telemetry/otel_http_exporter.cjs.map +1 -0
  48. package/dist/telemetry/otel_http_exporter.d.cts +62 -0
  49. package/dist/telemetry/otel_http_exporter.d.ts +62 -0
  50. package/dist/telemetry/otel_http_exporter.d.ts.map +1 -0
  51. package/dist/telemetry/otel_http_exporter.js +120 -0
  52. package/dist/telemetry/otel_http_exporter.js.map +1 -0
  53. package/dist/telemetry/pino_otel_transport.cjs +217 -0
  54. package/dist/telemetry/pino_otel_transport.cjs.map +1 -0
  55. package/dist/telemetry/pino_otel_transport.d.cts +58 -0
  56. package/dist/telemetry/pino_otel_transport.d.ts +58 -0
  57. package/dist/telemetry/pino_otel_transport.d.ts.map +1 -0
  58. package/dist/telemetry/pino_otel_transport.js +189 -0
  59. package/dist/telemetry/pino_otel_transport.js.map +1 -0
  60. package/dist/telemetry/traces.cjs +225 -16
  61. package/dist/telemetry/traces.cjs.map +1 -1
  62. package/dist/telemetry/traces.d.cts +17 -0
  63. package/dist/telemetry/traces.d.ts +17 -0
  64. package/dist/telemetry/traces.d.ts.map +1 -1
  65. package/dist/telemetry/traces.js +211 -14
  66. package/dist/telemetry/traces.js.map +1 -1
  67. package/dist/tts/tts.cjs +62 -5
  68. package/dist/tts/tts.cjs.map +1 -1
  69. package/dist/tts/tts.d.cts +2 -0
  70. package/dist/tts/tts.d.ts +2 -0
  71. package/dist/tts/tts.d.ts.map +1 -1
  72. package/dist/tts/tts.js +62 -5
  73. package/dist/tts/tts.js.map +1 -1
  74. package/dist/utils.cjs +6 -0
  75. package/dist/utils.cjs.map +1 -1
  76. package/dist/utils.d.cts +1 -0
  77. package/dist/utils.d.ts +1 -0
  78. package/dist/utils.d.ts.map +1 -1
  79. package/dist/utils.js +5 -0
  80. package/dist/utils.js.map +1 -1
  81. package/dist/voice/agent_activity.cjs +93 -7
  82. package/dist/voice/agent_activity.cjs.map +1 -1
  83. package/dist/voice/agent_activity.d.cts +3 -0
  84. package/dist/voice/agent_activity.d.ts +3 -0
  85. package/dist/voice/agent_activity.d.ts.map +1 -1
  86. package/dist/voice/agent_activity.js +93 -7
  87. package/dist/voice/agent_activity.js.map +1 -1
  88. package/dist/voice/agent_session.cjs +122 -27
  89. package/dist/voice/agent_session.cjs.map +1 -1
  90. package/dist/voice/agent_session.d.cts +15 -0
  91. package/dist/voice/agent_session.d.ts +15 -0
  92. package/dist/voice/agent_session.d.ts.map +1 -1
  93. package/dist/voice/agent_session.js +122 -27
  94. package/dist/voice/agent_session.js.map +1 -1
  95. package/dist/voice/audio_recognition.cjs +69 -22
  96. package/dist/voice/audio_recognition.cjs.map +1 -1
  97. package/dist/voice/audio_recognition.d.cts +5 -0
  98. package/dist/voice/audio_recognition.d.ts +5 -0
  99. package/dist/voice/audio_recognition.d.ts.map +1 -1
  100. package/dist/voice/audio_recognition.js +69 -22
  101. package/dist/voice/audio_recognition.js.map +1 -1
  102. package/dist/voice/generation.cjs +43 -3
  103. package/dist/voice/generation.cjs.map +1 -1
  104. package/dist/voice/generation.d.ts.map +1 -1
  105. package/dist/voice/generation.js +43 -3
  106. package/dist/voice/generation.js.map +1 -1
  107. package/dist/voice/report.cjs +3 -2
  108. package/dist/voice/report.cjs.map +1 -1
  109. package/dist/voice/report.d.cts +7 -1
  110. package/dist/voice/report.d.ts +7 -1
  111. package/dist/voice/report.d.ts.map +1 -1
  112. package/dist/voice/report.js +3 -2
  113. package/dist/voice/report.js.map +1 -1
  114. package/package.json +8 -2
  115. package/src/inference/api_protos.ts +2 -2
  116. package/src/ipc/job_proc_lazy_main.ts +12 -1
  117. package/src/job.ts +59 -10
  118. package/src/llm/llm.ts +48 -5
  119. package/src/log.ts +52 -15
  120. package/src/telemetry/index.ts +22 -4
  121. package/src/telemetry/logging.ts +55 -0
  122. package/src/telemetry/otel_http_exporter.ts +191 -0
  123. package/src/telemetry/pino_otel_transport.ts +265 -0
  124. package/src/telemetry/traces.ts +320 -20
  125. package/src/tts/tts.ts +71 -9
  126. package/src/utils.ts +5 -0
  127. package/src/voice/agent_activity.ts +140 -22
  128. package/src/voice/agent_session.ts +174 -34
  129. package/src/voice/audio_recognition.ts +85 -26
  130. package/src/voice/generation.ts +59 -7
  131. package/src/voice/report.ts +10 -4
@@ -21,11 +21,13 @@ __export(agent_session_exports, {
21
21
  AgentSession: () => AgentSession
22
22
  });
23
23
  module.exports = __toCommonJS(agent_session_exports);
24
+ var import_api = require("@opentelemetry/api");
24
25
  var import_node_events = require("node:events");
25
26
  var import_inference = require("../inference/index.cjs");
26
27
  var import_job = require("../job.cjs");
27
28
  var import_chat_context = require("../llm/chat_context.cjs");
28
29
  var import_log = require("../log.cjs");
30
+ var import_telemetry = require("../telemetry/index.cjs");
29
31
  var import_agent_activity = require("./agent_activity.cjs");
30
32
  var import_events = require("./events.cjs");
31
33
  var import_io = require("./io.cjs");
@@ -62,8 +64,17 @@ class AgentSession extends import_node_events.EventEmitter {
62
64
  _output;
63
65
  closingTask = null;
64
66
  userAwayTimer = null;
67
+ sessionSpan;
68
+ userSpeakingSpan;
69
+ agentSpeakingSpan;
70
+ /** @internal */
71
+ rootSpanContext;
65
72
  /** @internal */
66
73
  _recordedEvents = [];
74
+ /** @internal */
75
+ _enableRecording = false;
76
+ /** @internal - Timestamp when the session started (milliseconds) */
77
+ _startedAt;
67
78
  constructor(opts) {
68
79
  super();
69
80
  const {
@@ -97,7 +108,8 @@ class AgentSession extends import_node_events.EventEmitter {
97
108
  this._output = new import_io.AgentOutput(this.onAudioOutputChanged, this.onTextOutputChanged);
98
109
  this._chatCtx = import_chat_context.ChatContext.empty();
99
110
  this.options = { ...defaultVoiceOptions, ...voiceOptions };
100
- this.on(import_events.AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed.bind(this));
111
+ this._onUserInputTranscribed = this._onUserInputTranscribed.bind(this);
112
+ this.on(import_events.AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);
101
113
  }
102
114
  emit(event, ...args) {
103
115
  const eventData = args[0];
@@ -122,19 +134,15 @@ class AgentSession extends import_node_events.EventEmitter {
122
134
  set userData(value) {
123
135
  this._userData = value;
124
136
  }
125
- async start({
126
- // TODO(brian): PR2 - Add setupCloudTracer() call if on LiveKit Cloud with recording enabled
127
- // TODO(brian): PR3 - Add span: this._sessionSpan = tracer.startSpan('agent_session'), store as instance property
128
- // TODO(brian): PR4 - Add setupCloudLogger() call in setupCloudTracer() to setup OTEL logging with Pino bridge
137
+ async _startImpl({
129
138
  agent,
130
139
  room,
131
140
  inputOptions,
132
141
  outputOptions,
133
- record = true
142
+ record,
143
+ span
134
144
  }) {
135
- if (this.started) {
136
- return;
137
- }
145
+ span.setAttribute(import_telemetry.traceTypes.ATTR_AGENT_LABEL, agent.id);
138
146
  this.agent = agent;
139
147
  this._updateAgentState("initializing");
140
148
  const tasks = [];
@@ -181,8 +189,43 @@ class AgentSession extends import_node_events.EventEmitter {
181
189
  `using transcript io: \`AgentSession\` -> ${this.output.transcription ? "`" + this.output.transcription.constructor.name + "`" : "(none)"}`
182
190
  );
183
191
  this.started = true;
192
+ this._startedAt = Date.now();
184
193
  this._updateAgentState("listening");
185
194
  }
195
+ async start({
196
+ agent,
197
+ room,
198
+ inputOptions,
199
+ outputOptions,
200
+ record = true
201
+ }) {
202
+ if (this.started) {
203
+ return;
204
+ }
205
+ const ctx = (0, import_job.getJobContext)();
206
+ record = record ?? ctx.info.job.enableRecording;
207
+ this._enableRecording = record;
208
+ this.logger.info(
209
+ { record, enableRecording: ctx.info.job.enableRecording },
210
+ "Configuring session recording"
211
+ );
212
+ if (this._enableRecording) {
213
+ await ctx.initRecording();
214
+ }
215
+ this.sessionSpan = import_telemetry.tracer.startSpan({
216
+ name: "agent_session",
217
+ context: import_api.ROOT_CONTEXT
218
+ });
219
+ this.rootSpanContext = import_api.trace.setSpan(import_api.ROOT_CONTEXT, this.sessionSpan);
220
+ await this._startImpl({
221
+ agent,
222
+ room,
223
+ inputOptions,
224
+ outputOptions,
225
+ record,
226
+ span: this.sessionSpan
227
+ });
228
+ }
186
229
  updateAgent(agent) {
187
230
  this.agent = agent;
188
231
  if (this.started) {
@@ -230,25 +273,31 @@ class AgentSession extends import_node_events.EventEmitter {
230
273
  return this.activity.generateReply({ userMessage, ...options });
231
274
  }
232
275
  async updateActivity(agent) {
233
- this.nextActivity = new import_agent_activity.AgentActivity(agent, this);
234
- const previousActivity = this.activity;
235
- if (this.activity) {
236
- await this.activity.drain();
237
- await this.activity.close();
238
- }
239
- this.activity = this.nextActivity;
240
- this.nextActivity = void 0;
241
- this._chatCtx.insert(
242
- new import_chat_context.AgentHandoffItem({
243
- oldAgentId: previousActivity == null ? void 0 : previousActivity.agent.id,
244
- newAgentId: agent.id
245
- })
246
- );
247
- this.logger.debug({ previousActivity, agent }, "Agent handoff inserted into chat context");
248
- await this.activity.start();
249
- if (this._input.audio) {
250
- this.activity.attachAudioInput(this._input.audio.stream);
276
+ const runWithContext = async () => {
277
+ this.nextActivity = new import_agent_activity.AgentActivity(agent, this);
278
+ const previousActivity = this.activity;
279
+ if (this.activity) {
280
+ await this.activity.drain();
281
+ await this.activity.close();
282
+ }
283
+ this.activity = this.nextActivity;
284
+ this.nextActivity = void 0;
285
+ this._chatCtx.insert(
286
+ new import_chat_context.AgentHandoffItem({
287
+ oldAgentId: previousActivity == null ? void 0 : previousActivity.agent.id,
288
+ newAgentId: agent.id
289
+ })
290
+ );
291
+ this.logger.debug({ previousActivity, agent }, "Agent handoff inserted into chat context");
292
+ await this.activity.start();
293
+ if (this._input.audio) {
294
+ this.activity.attachAudioInput(this._input.audio.stream);
295
+ }
296
+ };
297
+ if (this.rootSpanContext) {
298
+ return import_api.context.with(this.rootSpanContext, runWithContext);
251
299
  }
300
+ return runWithContext();
252
301
  }
253
302
  get chatCtx() {
254
303
  return this._chatCtx.copy();
@@ -294,10 +343,25 @@ class AgentSession extends import_node_events.EventEmitter {
294
343
  this.emit(import_events.AgentSessionEventTypes.ConversationItemAdded, (0, import_events.createConversationItemAddedEvent)(item));
295
344
  }
296
345
  /** @internal */
346
+ _toolItemsAdded(items) {
347
+ this._chatCtx.insert(items);
348
+ }
349
+ /** @internal */
297
350
  _updateAgentState(state) {
298
351
  if (this._agentState === state) {
299
352
  return;
300
353
  }
354
+ if (state === "speaking") {
355
+ if (this.agentSpeakingSpan === void 0) {
356
+ this.agentSpeakingSpan = import_telemetry.tracer.startSpan({
357
+ name: "agent_speaking",
358
+ context: this.rootSpanContext
359
+ });
360
+ }
361
+ } else if (this.agentSpeakingSpan !== void 0) {
362
+ this.agentSpeakingSpan.end();
363
+ this.agentSpeakingSpan = void 0;
364
+ }
301
365
  const oldState = this._agentState;
302
366
  this._agentState = state;
303
367
  if (state === "listening" && this.userState === "listening") {
@@ -315,6 +379,15 @@ class AgentSession extends import_node_events.EventEmitter {
315
379
  if (this.userState === state) {
316
380
  return;
317
381
  }
382
+ if (state === "speaking" && this.userSpeakingSpan === void 0) {
383
+ this.userSpeakingSpan = import_telemetry.tracer.startSpan({
384
+ name: "user_speaking",
385
+ context: this.rootSpanContext
386
+ });
387
+ } else if (this.userSpeakingSpan !== void 0) {
388
+ this.userSpeakingSpan.end();
389
+ this.userSpeakingSpan = void 0;
390
+ }
318
391
  const oldState = this.userState;
319
392
  this.userState = state;
320
393
  if (state === "listening" && this._agentState === "listening") {
@@ -366,11 +439,20 @@ class AgentSession extends import_node_events.EventEmitter {
366
439
  }
367
440
  }
368
441
  async closeImpl(reason, error = null, drain = false) {
442
+ if (this.rootSpanContext) {
443
+ return import_api.context.with(this.rootSpanContext, async () => {
444
+ await this.closeImplInner(reason, error, drain);
445
+ });
446
+ }
447
+ return this.closeImplInner(reason, error, drain);
448
+ }
449
+ async closeImplInner(reason, error = null, drain = false) {
369
450
  var _a, _b, _c;
370
451
  if (!this.started) {
371
452
  return;
372
453
  }
373
454
  this._cancelUserAwayTimer();
455
+ this.off(import_events.AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);
374
456
  if (this.activity) {
375
457
  if (!drain) {
376
458
  try {
@@ -389,10 +471,23 @@ class AgentSession extends import_node_events.EventEmitter {
389
471
  this.roomIO = void 0;
390
472
  await ((_c = this.activity) == null ? void 0 : _c.close());
391
473
  this.activity = void 0;
474
+ if (this.sessionSpan) {
475
+ this.sessionSpan.end();
476
+ this.sessionSpan = void 0;
477
+ }
478
+ if (this.userSpeakingSpan) {
479
+ this.userSpeakingSpan.end();
480
+ this.userSpeakingSpan = void 0;
481
+ }
482
+ if (this.agentSpeakingSpan) {
483
+ this.agentSpeakingSpan.end();
484
+ this.agentSpeakingSpan = void 0;
485
+ }
392
486
  this.started = false;
393
487
  this.emit(import_events.AgentSessionEventTypes.Close, (0, import_events.createCloseEvent)(reason, error));
394
488
  this.userState = "listening";
395
489
  this._agentState = "initializing";
490
+ this.rootSpanContext = void 0;
396
491
  this.logger.info({ reason, error }, "AgentSession closed");
397
492
  }
398
493
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/voice/agent_session.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame, Room } from '@livekit/rtc-node';\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport { EventEmitter } from 'node:events';\nimport type { ReadableStream } from 'node:stream/web';\nimport {\n LLM as InferenceLLM,\n STT as InferenceSTT,\n TTS as InferenceTTS,\n type LLMModels,\n type STTModelString,\n type TTSModelString,\n} from '../inference/index.js';\nimport { getJobContext } from '../job.js';\nimport { AgentHandoffItem, ChatContext, ChatMessage } from '../llm/chat_context.js';\nimport type { LLM, RealtimeModel, RealtimeModelError, ToolChoice } from '../llm/index.js';\nimport type { LLMError } from '../llm/llm.js';\nimport { log } from '../log.js';\nimport type { STT } from '../stt/index.js';\nimport type { STTError } from '../stt/stt.js';\nimport type { TTS, TTSError } from '../tts/tts.js';\nimport type { VAD } from '../vad.js';\nimport type { Agent } from './agent.js';\nimport { AgentActivity } from './agent_activity.js';\nimport type { _TurnDetector } from './audio_recognition.js';\nimport {\n type AgentEvent,\n AgentSessionEventTypes,\n type AgentState,\n type AgentStateChangedEvent,\n type CloseEvent,\n CloseReason,\n type ConversationItemAddedEvent,\n type ErrorEvent,\n type FunctionToolsExecutedEvent,\n type MetricsCollectedEvent,\n type SpeechCreatedEvent,\n type UserInputTranscribedEvent,\n type UserState,\n type UserStateChangedEvent,\n createAgentStateChangedEvent,\n createCloseEvent,\n createConversationItemAddedEvent,\n createUserStateChangedEvent,\n} from './events.js';\nimport { AgentInput, AgentOutput } from './io.js';\nimport { RoomIO, type RoomInputOptions, type RoomOutputOptions } from './room_io/index.js';\nimport type { UnknownUserData } from './run_context.js';\nimport type { SpeechHandle } from './speech_handle.js';\n\nexport interface VoiceOptions {\n allowInterruptions: boolean;\n discardAudioIfUninterruptible: boolean;\n minInterruptionDuration: number;\n minInterruptionWords: number;\n minEndpointingDelay: number;\n maxEndpointingDelay: number;\n maxToolSteps: number;\n preemptiveGeneration: boolean;\n userAwayTimeout?: number | null;\n}\n\nconst defaultVoiceOptions: VoiceOptions = {\n allowInterruptions: true,\n discardAudioIfUninterruptible: true,\n minInterruptionDuration: 500,\n minInterruptionWords: 0,\n minEndpointingDelay: 500,\n maxEndpointingDelay: 6000,\n maxToolSteps: 3,\n preemptiveGeneration: false,\n userAwayTimeout: 15.0,\n} as const;\n\nexport type TurnDetectionMode = 'stt' | 'vad' | 'realtime_llm' | 'manual' | _TurnDetector;\n\nexport type AgentSessionCallbacks = {\n [AgentSessionEventTypes.UserInputTranscribed]: (ev: UserInputTranscribedEvent) => void;\n [AgentSessionEventTypes.AgentStateChanged]: (ev: AgentStateChangedEvent) => void;\n [AgentSessionEventTypes.UserStateChanged]: (ev: UserStateChangedEvent) => void;\n [AgentSessionEventTypes.ConversationItemAdded]: (ev: ConversationItemAddedEvent) => void;\n [AgentSessionEventTypes.FunctionToolsExecuted]: (ev: FunctionToolsExecutedEvent) => void;\n [AgentSessionEventTypes.MetricsCollected]: (ev: MetricsCollectedEvent) => void;\n [AgentSessionEventTypes.SpeechCreated]: (ev: SpeechCreatedEvent) => void;\n [AgentSessionEventTypes.Error]: (ev: ErrorEvent) => void;\n [AgentSessionEventTypes.Close]: (ev: CloseEvent) => void;\n};\n\nexport type AgentSessionOptions<UserData = UnknownUserData> = {\n turnDetection?: TurnDetectionMode;\n stt?: STT | STTModelString;\n vad?: VAD;\n llm?: LLM | RealtimeModel | LLMModels;\n tts?: TTS | TTSModelString;\n userData?: UserData;\n voiceOptions?: Partial<VoiceOptions>;\n};\n\nexport class AgentSession<\n UserData = UnknownUserData,\n> extends (EventEmitter as new () => TypedEmitter<AgentSessionCallbacks>) {\n vad?: VAD;\n stt?: STT;\n llm?: LLM | RealtimeModel;\n tts?: TTS;\n turnDetection?: TurnDetectionMode;\n\n readonly options: VoiceOptions;\n\n private agent?: Agent;\n private activity?: AgentActivity;\n private nextActivity?: AgentActivity;\n private started = false;\n private userState: UserState = 'listening';\n\n private roomIO?: RoomIO;\n private logger = log();\n\n private _chatCtx: ChatContext;\n private _userData: UserData | undefined;\n private _agentState: AgentState = 'initializing';\n\n private _input: AgentInput;\n private _output: AgentOutput;\n\n private closingTask: Promise<void> | null = null;\n private userAwayTimer: NodeJS.Timeout | null = null;\n\n /** @internal */\n _recordedEvents: AgentEvent[] = [];\n\n constructor(opts: AgentSessionOptions<UserData>) {\n super();\n\n const {\n vad,\n stt,\n llm,\n tts,\n turnDetection,\n userData,\n voiceOptions = defaultVoiceOptions,\n } = opts;\n\n this.vad = vad;\n\n if (typeof stt === 'string') {\n this.stt = InferenceSTT.fromModelString(stt);\n } else {\n this.stt = stt;\n }\n\n if (typeof llm === 'string') {\n this.llm = InferenceLLM.fromModelString(llm);\n } else {\n this.llm = llm;\n }\n\n if (typeof tts === 'string') {\n this.tts = InferenceTTS.fromModelString(tts);\n } else {\n this.tts = tts;\n }\n\n this.turnDetection = turnDetection;\n this._userData = userData;\n\n // configurable IO\n this._input = new AgentInput(this.onAudioInputChanged);\n this._output = new AgentOutput(this.onAudioOutputChanged, this.onTextOutputChanged);\n\n // This is the \"global\" chat context, it holds the entire conversation history\n this._chatCtx = ChatContext.empty();\n this.options = { ...defaultVoiceOptions, ...voiceOptions };\n\n this.on(AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed.bind(this));\n }\n\n emit<K extends keyof AgentSessionCallbacks>(\n event: K,\n ...args: Parameters<AgentSessionCallbacks[K]>\n ): boolean {\n const eventData = args[0] as AgentEvent;\n this._recordedEvents.push(eventData);\n return super.emit(event, ...args);\n }\n\n get input(): AgentInput {\n return this._input;\n }\n\n get output(): AgentOutput {\n return this._output;\n }\n\n get userData(): UserData {\n if (this._userData === undefined) {\n throw new Error('Voice agent userData is not set');\n }\n\n return this._userData;\n }\n\n get history(): ChatContext {\n return this._chatCtx;\n }\n\n set userData(value: UserData) {\n this._userData = value;\n }\n\n async start({\n // TODO(brian): PR2 - Add setupCloudTracer() call if on LiveKit Cloud with recording enabled\n // TODO(brian): PR3 - Add span: this._sessionSpan = tracer.startSpan('agent_session'), store as instance property\n // TODO(brian): PR4 - Add setupCloudLogger() call in setupCloudTracer() to setup OTEL logging with Pino bridge\n agent,\n room,\n inputOptions,\n outputOptions,\n record = true,\n }: {\n agent: Agent;\n room: Room;\n inputOptions?: Partial<RoomInputOptions>;\n outputOptions?: Partial<RoomOutputOptions>;\n record?: boolean;\n }): Promise<void> {\n if (this.started) {\n return;\n }\n\n this.agent = agent;\n this._updateAgentState('initializing');\n\n const tasks: Promise<void>[] = [];\n // Check for existing input/output configuration and warn if needed\n if (this.input.audio && inputOptions?.audioEnabled !== false) {\n this.logger.warn('RoomIO audio input is enabled but input.audio is already set, ignoring..');\n }\n\n if (this.output.audio && outputOptions?.audioEnabled !== false) {\n this.logger.warn(\n 'RoomIO audio output is enabled but output.audio is already set, ignoring..',\n );\n }\n\n if (this.output.transcription && outputOptions?.transcriptionEnabled !== false) {\n this.logger.warn(\n 'RoomIO transcription output is enabled but output.transcription is already set, ignoring..',\n );\n }\n\n this.roomIO = new RoomIO({\n agentSession: this,\n room,\n inputOptions,\n outputOptions,\n });\n this.roomIO.start();\n\n const ctx = getJobContext();\n if (ctx && ctx.room === room && !room.isConnected) {\n this.logger.debug('Auto-connecting to room via job context');\n tasks.push(ctx.connect());\n }\n\n if (record) {\n if (ctx._primaryAgentSession === undefined) {\n ctx._primaryAgentSession = this;\n } else {\n throw new Error(\n 'Only one `AgentSession` can be the primary at a time. If you want to ignore primary designation, use session.start(record=False).',\n );\n }\n }\n\n // TODO(AJS-265): add shutdown callback to job context\n tasks.push(this.updateActivity(this.agent));\n\n await Promise.allSettled(tasks);\n\n // Log used IO configuration\n this.logger.debug(\n `using audio io: ${this.input.audio ? '`' + this.input.audio.constructor.name + '`' : '(none)'} -> \\`AgentSession\\` -> ${this.output.audio ? '`' + this.output.audio.constructor.name + '`' : '(none)'}`,\n );\n\n this.logger.debug(\n `using transcript io: \\`AgentSession\\` -> ${this.output.transcription ? '`' + this.output.transcription.constructor.name + '`' : '(none)'}`,\n );\n\n this.started = true;\n this._updateAgentState('listening');\n }\n\n updateAgent(agent: Agent): void {\n this.agent = agent;\n\n if (this.started) {\n this.updateActivity(agent);\n }\n }\n\n commitUserTurn() {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n this.activity.commitUserTurn();\n }\n\n clearUserTurn() {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n this.activity.clearUserTurn();\n }\n\n say(\n text: string | ReadableStream<string>,\n options?: {\n audio?: ReadableStream<AudioFrame>;\n allowInterruptions?: boolean;\n addToChatCtx?: boolean;\n },\n ): SpeechHandle {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n return this.activity.say(text, options);\n }\n\n interrupt() {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n return this.activity.interrupt();\n }\n\n generateReply(options?: {\n userInput?: string;\n instructions?: string;\n toolChoice?: ToolChoice;\n allowInterruptions?: boolean;\n }): SpeechHandle {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n const userMessage = options?.userInput\n ? new ChatMessage({\n role: 'user',\n content: options.userInput,\n })\n : undefined;\n\n if (this.activity.draining) {\n if (!this.nextActivity) {\n throw new Error('AgentSession is closing, cannot use generateReply()');\n }\n return this.nextActivity.generateReply({ userMessage, ...options });\n }\n\n return this.activity.generateReply({ userMessage, ...options });\n }\n\n private async updateActivity(agent: Agent): Promise<void> {\n // TODO(AJS-129): add lock to agent activity core lifecycle\n this.nextActivity = new AgentActivity(agent, this);\n\n const previousActivity = this.activity;\n\n if (this.activity) {\n await this.activity.drain();\n await this.activity.close();\n }\n\n this.activity = this.nextActivity;\n this.nextActivity = undefined;\n\n this._chatCtx.insert(\n new AgentHandoffItem({\n oldAgentId: previousActivity?.agent.id,\n newAgentId: agent.id,\n }),\n );\n this.logger.debug({ previousActivity, agent }, 'Agent handoff inserted into chat context');\n\n await this.activity.start();\n\n if (this._input.audio) {\n this.activity.attachAudioInput(this._input.audio.stream);\n }\n }\n\n get chatCtx(): ChatContext {\n return this._chatCtx.copy();\n }\n\n get agentState(): AgentState {\n return this._agentState;\n }\n\n get currentAgent(): Agent {\n if (!this.agent) {\n throw new Error('AgentSession is not running');\n }\n\n return this.agent;\n }\n\n async close(): Promise<void> {\n await this.closeImpl(CloseReason.USER_INITIATED);\n }\n\n /** @internal */\n _closeSoon({\n reason,\n drain = false,\n error = null,\n }: {\n reason: CloseReason;\n drain?: boolean;\n error?: RealtimeModelError | STTError | TTSError | LLMError | null;\n }): void {\n if (this.closingTask) {\n return;\n }\n this.closeImpl(reason, error, drain);\n }\n\n /** @internal */\n _onError(error: RealtimeModelError | STTError | TTSError | LLMError): void {\n if (this.closingTask || error.recoverable) {\n return;\n }\n\n this.logger.error(error, 'AgentSession is closing due to unrecoverable error');\n\n this.closingTask = (async () => {\n await this.closeImpl(CloseReason.ERROR, error);\n })().then(() => {\n this.closingTask = null;\n });\n }\n\n /** @internal */\n _conversationItemAdded(item: ChatMessage): void {\n this._chatCtx.insert(item);\n this.emit(AgentSessionEventTypes.ConversationItemAdded, createConversationItemAddedEvent(item));\n }\n\n /** @internal */\n _updateAgentState(state: AgentState) {\n if (this._agentState === state) {\n return;\n }\n\n // TODO(brian): PR3 - Add span: if state === 'speaking' && !this._agentSpeakingSpan, create tracer.startSpan('agent_speaking') with participant attributes\n // TODO(brian): PR3 - Add span: if state !== 'speaking' && this._agentSpeakingSpan, end and clear this._agentSpeakingSpan\n const oldState = this._agentState;\n this._agentState = state;\n\n // Handle user away timer based on state changes\n if (state === 'listening' && this.userState === 'listening') {\n this._setUserAwayTimer();\n } else {\n this._cancelUserAwayTimer();\n }\n\n this.emit(\n AgentSessionEventTypes.AgentStateChanged,\n createAgentStateChangedEvent(oldState, state),\n );\n }\n\n /** @internal */\n _updateUserState(state: UserState, _lastSpeakingTime?: number) {\n if (this.userState === state) {\n return;\n }\n\n // TODO(brian): PR3 - Add span: if state === 'speaking' && !this._userSpeakingSpan, create tracer.startSpan('user_speaking') with participant attributes\n // TODO(brian): PR3 - Add span: if state !== 'speaking' && this._userSpeakingSpan, end and clear this._userSpeakingSpan\n const oldState = this.userState;\n this.userState = state;\n\n // Handle user away timer based on state changes\n if (state === 'listening' && this._agentState === 'listening') {\n this._setUserAwayTimer();\n } else {\n this._cancelUserAwayTimer();\n }\n\n this.emit(\n AgentSessionEventTypes.UserStateChanged,\n createUserStateChangedEvent(oldState, state),\n );\n }\n\n // -- User changed input/output streams/sinks --\n private onAudioInputChanged(): void {\n if (!this.started) {\n return;\n }\n\n if (this.activity && this._input.audio) {\n this.activity.attachAudioInput(this._input.audio.stream);\n }\n }\n\n private onAudioOutputChanged(): void {}\n\n private onTextOutputChanged(): void {}\n\n private _setUserAwayTimer(): void {\n this._cancelUserAwayTimer();\n\n if (this.options.userAwayTimeout === null || this.options.userAwayTimeout === undefined) {\n return;\n }\n\n if (this.roomIO && !this.roomIO.isParticipantAvailable) {\n return;\n }\n\n this.userAwayTimer = setTimeout(() => {\n this.logger.debug('User away timeout triggered');\n this._updateUserState('away');\n }, this.options.userAwayTimeout * 1000);\n }\n\n private _cancelUserAwayTimer(): void {\n if (this.userAwayTimer !== null) {\n clearTimeout(this.userAwayTimer);\n this.userAwayTimer = null;\n }\n }\n\n private _onUserInputTranscribed(ev: UserInputTranscribedEvent): void {\n if (this.userState === 'away' && ev.isFinal) {\n this.logger.debug('User returned from away state due to speech input');\n this._updateUserState('listening');\n }\n }\n\n private async closeImpl(\n reason: CloseReason,\n error: RealtimeModelError | LLMError | TTSError | STTError | null = null,\n drain: boolean = false,\n ): Promise<void> {\n if (!this.started) {\n return;\n }\n\n this._cancelUserAwayTimer();\n\n if (this.activity) {\n if (!drain) {\n try {\n this.activity.interrupt();\n } catch (error) {\n // uninterruptible speech [copied from python]\n // TODO(shubhra): force interrupt or wait for it to finish?\n // it might be an audio played from the error callback\n }\n }\n await this.activity.drain();\n // wait any uninterruptible speech to finish\n await this.activity.currentSpeech?.waitForPlayout();\n this.activity.detachAudioInput();\n }\n\n // detach the inputs and outputs\n this.input.audio = null;\n this.output.audio = null;\n this.output.transcription = null;\n\n await this.roomIO?.close();\n this.roomIO = undefined;\n\n await this.activity?.close();\n this.activity = undefined;\n\n this.started = false;\n\n this.emit(AgentSessionEventTypes.Close, createCloseEvent(reason, error));\n\n this.userState = 'listening';\n this._agentState = 'initializing';\n\n this.logger.info({ reason, error }, 'AgentSession closed');\n }\n}\n"],"mappings":"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","names":["InferenceSTT","InferenceLLM","InferenceTTS","error"]}
1
+ {"version":3,"sources":["../../src/voice/agent_session.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame, Room } from '@livekit/rtc-node';\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport type { Context, Span } from '@opentelemetry/api';\nimport { ROOT_CONTEXT, context as otelContext, trace } from '@opentelemetry/api';\nimport { EventEmitter } from 'node:events';\nimport type { ReadableStream } from 'node:stream/web';\nimport {\n LLM as InferenceLLM,\n STT as InferenceSTT,\n TTS as InferenceTTS,\n type LLMModels,\n type STTModelString,\n type TTSModelString,\n} from '../inference/index.js';\nimport { getJobContext } from '../job.js';\nimport type { FunctionCall, FunctionCallOutput } from '../llm/chat_context.js';\nimport { AgentHandoffItem, ChatContext, ChatMessage } from '../llm/chat_context.js';\nimport type { LLM, RealtimeModel, RealtimeModelError, ToolChoice } from '../llm/index.js';\nimport type { LLMError } from '../llm/llm.js';\nimport { log } from '../log.js';\nimport type { STT } from '../stt/index.js';\nimport type { STTError } from '../stt/stt.js';\nimport { traceTypes, tracer } from '../telemetry/index.js';\nimport type { TTS, TTSError } from '../tts/tts.js';\nimport type { VAD } from '../vad.js';\nimport type { Agent } from './agent.js';\nimport { AgentActivity } from './agent_activity.js';\nimport type { _TurnDetector } from './audio_recognition.js';\nimport {\n type AgentEvent,\n AgentSessionEventTypes,\n type AgentState,\n type AgentStateChangedEvent,\n type CloseEvent,\n CloseReason,\n type ConversationItemAddedEvent,\n type ErrorEvent,\n type FunctionToolsExecutedEvent,\n type MetricsCollectedEvent,\n type SpeechCreatedEvent,\n type UserInputTranscribedEvent,\n type UserState,\n type UserStateChangedEvent,\n createAgentStateChangedEvent,\n createCloseEvent,\n createConversationItemAddedEvent,\n createUserStateChangedEvent,\n} from './events.js';\nimport { AgentInput, AgentOutput } from './io.js';\nimport { RoomIO, type RoomInputOptions, type RoomOutputOptions } from './room_io/index.js';\nimport type { UnknownUserData } from './run_context.js';\nimport type { SpeechHandle } from './speech_handle.js';\n\nexport interface VoiceOptions {\n allowInterruptions: boolean;\n discardAudioIfUninterruptible: boolean;\n minInterruptionDuration: number;\n minInterruptionWords: number;\n minEndpointingDelay: number;\n maxEndpointingDelay: number;\n maxToolSteps: number;\n preemptiveGeneration: boolean;\n userAwayTimeout?: number | null;\n}\n\nconst defaultVoiceOptions: VoiceOptions = {\n allowInterruptions: true,\n discardAudioIfUninterruptible: true,\n minInterruptionDuration: 500,\n minInterruptionWords: 0,\n minEndpointingDelay: 500,\n maxEndpointingDelay: 6000,\n maxToolSteps: 3,\n preemptiveGeneration: false,\n userAwayTimeout: 15.0,\n} as const;\n\nexport type TurnDetectionMode = 'stt' | 'vad' | 'realtime_llm' | 'manual' | _TurnDetector;\n\nexport type AgentSessionCallbacks = {\n [AgentSessionEventTypes.UserInputTranscribed]: (ev: UserInputTranscribedEvent) => void;\n [AgentSessionEventTypes.AgentStateChanged]: (ev: AgentStateChangedEvent) => void;\n [AgentSessionEventTypes.UserStateChanged]: (ev: UserStateChangedEvent) => void;\n [AgentSessionEventTypes.ConversationItemAdded]: (ev: ConversationItemAddedEvent) => void;\n [AgentSessionEventTypes.FunctionToolsExecuted]: (ev: FunctionToolsExecutedEvent) => void;\n [AgentSessionEventTypes.MetricsCollected]: (ev: MetricsCollectedEvent) => void;\n [AgentSessionEventTypes.SpeechCreated]: (ev: SpeechCreatedEvent) => void;\n [AgentSessionEventTypes.Error]: (ev: ErrorEvent) => void;\n [AgentSessionEventTypes.Close]: (ev: CloseEvent) => void;\n};\n\nexport type AgentSessionOptions<UserData = UnknownUserData> = {\n turnDetection?: TurnDetectionMode;\n stt?: STT | STTModelString;\n vad?: VAD;\n llm?: LLM | RealtimeModel | LLMModels;\n tts?: TTS | TTSModelString;\n userData?: UserData;\n voiceOptions?: Partial<VoiceOptions>;\n};\n\nexport class AgentSession<\n UserData = UnknownUserData,\n> extends (EventEmitter as new () => TypedEmitter<AgentSessionCallbacks>) {\n vad?: VAD;\n stt?: STT;\n llm?: LLM | RealtimeModel;\n tts?: TTS;\n turnDetection?: TurnDetectionMode;\n\n readonly options: VoiceOptions;\n\n private agent?: Agent;\n private activity?: AgentActivity;\n private nextActivity?: AgentActivity;\n private started = false;\n private userState: UserState = 'listening';\n\n private roomIO?: RoomIO;\n private logger = log();\n\n private _chatCtx: ChatContext;\n private _userData: UserData | undefined;\n private _agentState: AgentState = 'initializing';\n\n private _input: AgentInput;\n private _output: AgentOutput;\n\n private closingTask: Promise<void> | null = null;\n private userAwayTimer: NodeJS.Timeout | null = null;\n\n private sessionSpan?: Span;\n private userSpeakingSpan?: Span;\n private agentSpeakingSpan?: Span;\n\n /** @internal */\n rootSpanContext?: Context;\n\n /** @internal */\n _recordedEvents: AgentEvent[] = [];\n\n /** @internal */\n _enableRecording = false;\n\n /** @internal - Timestamp when the session started (milliseconds) */\n _startedAt?: number;\n\n constructor(opts: AgentSessionOptions<UserData>) {\n super();\n\n const {\n vad,\n stt,\n llm,\n tts,\n turnDetection,\n userData,\n voiceOptions = defaultVoiceOptions,\n } = opts;\n\n this.vad = vad;\n\n if (typeof stt === 'string') {\n this.stt = InferenceSTT.fromModelString(stt);\n } else {\n this.stt = stt;\n }\n\n if (typeof llm === 'string') {\n this.llm = InferenceLLM.fromModelString(llm);\n } else {\n this.llm = llm;\n }\n\n if (typeof tts === 'string') {\n this.tts = InferenceTTS.fromModelString(tts);\n } else {\n this.tts = tts;\n }\n\n this.turnDetection = turnDetection;\n this._userData = userData;\n\n // configurable IO\n this._input = new AgentInput(this.onAudioInputChanged);\n this._output = new AgentOutput(this.onAudioOutputChanged, this.onTextOutputChanged);\n\n // This is the \"global\" chat context, it holds the entire conversation history\n this._chatCtx = ChatContext.empty();\n this.options = { ...defaultVoiceOptions, ...voiceOptions };\n\n this._onUserInputTranscribed = this._onUserInputTranscribed.bind(this);\n this.on(AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);\n }\n\n emit<K extends keyof AgentSessionCallbacks>(\n event: K,\n ...args: Parameters<AgentSessionCallbacks[K]>\n ): boolean {\n const eventData = args[0] as AgentEvent;\n this._recordedEvents.push(eventData);\n return super.emit(event, ...args);\n }\n\n get input(): AgentInput {\n return this._input;\n }\n\n get output(): AgentOutput {\n return this._output;\n }\n\n get userData(): UserData {\n if (this._userData === undefined) {\n throw new Error('Voice agent userData is not set');\n }\n\n return this._userData;\n }\n\n get history(): ChatContext {\n return this._chatCtx;\n }\n\n set userData(value: UserData) {\n this._userData = value;\n }\n\n private async _startImpl({\n agent,\n room,\n inputOptions,\n outputOptions,\n record,\n span,\n }: {\n agent: Agent;\n room: Room;\n inputOptions?: Partial<RoomInputOptions>;\n outputOptions?: Partial<RoomOutputOptions>;\n record: boolean;\n span: Span;\n }): Promise<void> {\n span.setAttribute(traceTypes.ATTR_AGENT_LABEL, agent.id);\n\n this.agent = agent;\n this._updateAgentState('initializing');\n\n const tasks: Promise<void>[] = [];\n // Check for existing input/output configuration and warn if needed\n if (this.input.audio && inputOptions?.audioEnabled !== false) {\n this.logger.warn('RoomIO audio input is enabled but input.audio is already set, ignoring..');\n }\n\n if (this.output.audio && outputOptions?.audioEnabled !== false) {\n this.logger.warn(\n 'RoomIO audio output is enabled but output.audio is already set, ignoring..',\n );\n }\n\n if (this.output.transcription && outputOptions?.transcriptionEnabled !== false) {\n this.logger.warn(\n 'RoomIO transcription output is enabled but output.transcription is already set, ignoring..',\n );\n }\n\n this.roomIO = new RoomIO({\n agentSession: this,\n room,\n inputOptions,\n outputOptions,\n });\n this.roomIO.start();\n\n const ctx = getJobContext();\n if (ctx && ctx.room === room && !room.isConnected) {\n this.logger.debug('Auto-connecting to room via job context');\n tasks.push(ctx.connect());\n }\n\n if (record) {\n if (ctx._primaryAgentSession === undefined) {\n ctx._primaryAgentSession = this;\n } else {\n throw new Error(\n 'Only one `AgentSession` can be the primary at a time. If you want to ignore primary designation, use session.start(record=False).',\n );\n }\n }\n\n // TODO(AJS-265): add shutdown callback to job context\n tasks.push(this.updateActivity(this.agent));\n\n await Promise.allSettled(tasks);\n\n // Log used IO configuration\n this.logger.debug(\n `using audio io: ${this.input.audio ? '`' + this.input.audio.constructor.name + '`' : '(none)'} -> \\`AgentSession\\` -> ${this.output.audio ? '`' + this.output.audio.constructor.name + '`' : '(none)'}`,\n );\n\n this.logger.debug(\n `using transcript io: \\`AgentSession\\` -> ${this.output.transcription ? '`' + this.output.transcription.constructor.name + '`' : '(none)'}`,\n );\n\n this.started = true;\n this._startedAt = Date.now();\n this._updateAgentState('listening');\n }\n\n async start({\n agent,\n room,\n inputOptions,\n outputOptions,\n record = true,\n }: {\n agent: Agent;\n room: Room;\n inputOptions?: Partial<RoomInputOptions>;\n outputOptions?: Partial<RoomOutputOptions>;\n record?: boolean;\n }): Promise<void> {\n if (this.started) {\n return;\n }\n\n const ctx = getJobContext();\n\n record = record ?? ctx.info.job.enableRecording;\n this._enableRecording = record;\n\n this.logger.info(\n { record, enableRecording: ctx.info.job.enableRecording },\n 'Configuring session recording',\n );\n\n if (this._enableRecording) {\n await ctx.initRecording();\n }\n\n // Create agent_session as a ROOT span (new trace) to match Python behavior\n // This creates a separate trace for better cloud dashboard organization\n this.sessionSpan = tracer.startSpan({\n name: 'agent_session',\n context: ROOT_CONTEXT,\n });\n\n // Set the session span as the active span in the context\n // This ensures all child spans (agent_turn, user_turn, etc.) are parented to it\n this.rootSpanContext = trace.setSpan(ROOT_CONTEXT, this.sessionSpan);\n\n await this._startImpl({\n agent,\n room,\n inputOptions,\n outputOptions,\n record,\n span: this.sessionSpan,\n });\n }\n\n updateAgent(agent: Agent): void {\n this.agent = agent;\n\n if (this.started) {\n this.updateActivity(agent);\n }\n }\n\n commitUserTurn() {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n this.activity.commitUserTurn();\n }\n\n clearUserTurn() {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n this.activity.clearUserTurn();\n }\n\n say(\n text: string | ReadableStream<string>,\n options?: {\n audio?: ReadableStream<AudioFrame>;\n allowInterruptions?: boolean;\n addToChatCtx?: boolean;\n },\n ): SpeechHandle {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n return this.activity.say(text, options);\n }\n\n interrupt() {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n return this.activity.interrupt();\n }\n\n generateReply(options?: {\n userInput?: string;\n instructions?: string;\n toolChoice?: ToolChoice;\n allowInterruptions?: boolean;\n }): SpeechHandle {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n const userMessage = options?.userInput\n ? new ChatMessage({\n role: 'user',\n content: options.userInput,\n })\n : undefined;\n\n if (this.activity.draining) {\n if (!this.nextActivity) {\n throw new Error('AgentSession is closing, cannot use generateReply()');\n }\n return this.nextActivity.generateReply({ userMessage, ...options });\n }\n\n return this.activity.generateReply({ userMessage, ...options });\n }\n\n private async updateActivity(agent: Agent): Promise<void> {\n const runWithContext = async () => {\n // TODO(AJS-129): add lock to agent activity core lifecycle\n this.nextActivity = new AgentActivity(agent, this);\n\n const previousActivity = this.activity;\n\n if (this.activity) {\n await this.activity.drain();\n await this.activity.close();\n }\n\n this.activity = this.nextActivity;\n this.nextActivity = undefined;\n\n this._chatCtx.insert(\n new AgentHandoffItem({\n oldAgentId: previousActivity?.agent.id,\n newAgentId: agent.id,\n }),\n );\n this.logger.debug({ previousActivity, agent }, 'Agent handoff inserted into chat context');\n\n await this.activity.start();\n\n if (this._input.audio) {\n this.activity.attachAudioInput(this._input.audio.stream);\n }\n };\n\n // Run within session span context if available\n if (this.rootSpanContext) {\n return otelContext.with(this.rootSpanContext, runWithContext);\n }\n\n return runWithContext();\n }\n\n get chatCtx(): ChatContext {\n return this._chatCtx.copy();\n }\n\n get agentState(): AgentState {\n return this._agentState;\n }\n\n get currentAgent(): Agent {\n if (!this.agent) {\n throw new Error('AgentSession is not running');\n }\n\n return this.agent;\n }\n\n async close(): Promise<void> {\n await this.closeImpl(CloseReason.USER_INITIATED);\n }\n\n /** @internal */\n _closeSoon({\n reason,\n drain = false,\n error = null,\n }: {\n reason: CloseReason;\n drain?: boolean;\n error?: RealtimeModelError | STTError | TTSError | LLMError | null;\n }): void {\n if (this.closingTask) {\n return;\n }\n this.closeImpl(reason, error, drain);\n }\n\n /** @internal */\n _onError(error: RealtimeModelError | STTError | TTSError | LLMError): void {\n if (this.closingTask || error.recoverable) {\n return;\n }\n\n this.logger.error(error, 'AgentSession is closing due to unrecoverable error');\n\n this.closingTask = (async () => {\n await this.closeImpl(CloseReason.ERROR, error);\n })().then(() => {\n this.closingTask = null;\n });\n }\n\n /** @internal */\n _conversationItemAdded(item: ChatMessage): void {\n this._chatCtx.insert(item);\n this.emit(AgentSessionEventTypes.ConversationItemAdded, createConversationItemAddedEvent(item));\n }\n\n /** @internal */\n _toolItemsAdded(items: (FunctionCall | FunctionCallOutput)[]): void {\n this._chatCtx.insert(items);\n }\n\n /** @internal */\n _updateAgentState(state: AgentState) {\n if (this._agentState === state) {\n return;\n }\n\n if (state === 'speaking') {\n // TODO(brian): PR4 - Track error counts\n\n if (this.agentSpeakingSpan === undefined) {\n this.agentSpeakingSpan = tracer.startSpan({\n name: 'agent_speaking',\n context: this.rootSpanContext,\n });\n\n // TODO(brian): PR4 - Set participant attributes if roomIO.room.localParticipant is available\n // (Ref: Python agent_session.py line 1161-1164)\n }\n } else if (this.agentSpeakingSpan !== undefined) {\n // TODO(brian): PR4 - Set ATTR_END_TIME attribute if available\n this.agentSpeakingSpan.end();\n this.agentSpeakingSpan = undefined;\n }\n\n const oldState = this._agentState;\n this._agentState = state;\n\n // Handle user away timer based on state changes\n if (state === 'listening' && this.userState === 'listening') {\n this._setUserAwayTimer();\n } else {\n this._cancelUserAwayTimer();\n }\n\n this.emit(\n AgentSessionEventTypes.AgentStateChanged,\n createAgentStateChangedEvent(oldState, state),\n );\n }\n\n /** @internal */\n _updateUserState(state: UserState, _lastSpeakingTime?: number) {\n if (this.userState === state) {\n return;\n }\n\n if (state === 'speaking' && this.userSpeakingSpan === undefined) {\n this.userSpeakingSpan = tracer.startSpan({\n name: 'user_speaking',\n context: this.rootSpanContext,\n });\n\n // TODO(brian): PR4 - Set participant attributes if roomIO.linkedParticipant is available\n // (Ref: Python agent_session.py line 1192-1195)\n } else if (this.userSpeakingSpan !== undefined) {\n // TODO(brian): PR4 - Set ATTR_END_TIME attribute with lastSpeakingTime if available\n this.userSpeakingSpan.end();\n this.userSpeakingSpan = undefined;\n }\n\n const oldState = this.userState;\n this.userState = state;\n\n // Handle user away timer based on state changes\n if (state === 'listening' && this._agentState === 'listening') {\n this._setUserAwayTimer();\n } else {\n this._cancelUserAwayTimer();\n }\n\n this.emit(\n AgentSessionEventTypes.UserStateChanged,\n createUserStateChangedEvent(oldState, state),\n );\n }\n\n // -- User changed input/output streams/sinks --\n private onAudioInputChanged(): void {\n if (!this.started) {\n return;\n }\n\n if (this.activity && this._input.audio) {\n this.activity.attachAudioInput(this._input.audio.stream);\n }\n }\n\n private onAudioOutputChanged(): void {}\n\n private onTextOutputChanged(): void {}\n\n private _setUserAwayTimer(): void {\n this._cancelUserAwayTimer();\n\n if (this.options.userAwayTimeout === null || this.options.userAwayTimeout === undefined) {\n return;\n }\n\n if (this.roomIO && !this.roomIO.isParticipantAvailable) {\n return;\n }\n\n this.userAwayTimer = setTimeout(() => {\n this.logger.debug('User away timeout triggered');\n this._updateUserState('away');\n }, this.options.userAwayTimeout * 1000);\n }\n\n private _cancelUserAwayTimer(): void {\n if (this.userAwayTimer !== null) {\n clearTimeout(this.userAwayTimer);\n this.userAwayTimer = null;\n }\n }\n\n private _onUserInputTranscribed(ev: UserInputTranscribedEvent): void {\n if (this.userState === 'away' && ev.isFinal) {\n this.logger.debug('User returned from away state due to speech input');\n this._updateUserState('listening');\n }\n }\n\n private async closeImpl(\n reason: CloseReason,\n error: RealtimeModelError | LLMError | TTSError | STTError | null = null,\n drain: boolean = false,\n ): Promise<void> {\n if (this.rootSpanContext) {\n return otelContext.with(this.rootSpanContext, async () => {\n await this.closeImplInner(reason, error, drain);\n });\n }\n\n return this.closeImplInner(reason, error, drain);\n }\n\n private async closeImplInner(\n reason: CloseReason,\n error: RealtimeModelError | LLMError | TTSError | STTError | null = null,\n drain: boolean = false,\n ): Promise<void> {\n if (!this.started) {\n return;\n }\n\n this._cancelUserAwayTimer();\n this.off(AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);\n\n if (this.activity) {\n if (!drain) {\n try {\n this.activity.interrupt();\n } catch (error) {\n // TODO(shubhra): force interrupt or wait for it to finish?\n // it might be an audio played from the error callback\n }\n }\n await this.activity.drain();\n // wait any uninterruptible speech to finish\n await this.activity.currentSpeech?.waitForPlayout();\n this.activity.detachAudioInput();\n }\n\n // detach the inputs and outputs\n this.input.audio = null;\n this.output.audio = null;\n this.output.transcription = null;\n\n await this.roomIO?.close();\n this.roomIO = undefined;\n\n await this.activity?.close();\n this.activity = undefined;\n\n if (this.sessionSpan) {\n this.sessionSpan.end();\n this.sessionSpan = undefined;\n }\n\n if (this.userSpeakingSpan) {\n this.userSpeakingSpan.end();\n this.userSpeakingSpan = undefined;\n }\n\n if (this.agentSpeakingSpan) {\n this.agentSpeakingSpan.end();\n this.agentSpeakingSpan = undefined;\n }\n\n this.started = false;\n\n this.emit(AgentSessionEventTypes.Close, createCloseEvent(reason, error));\n\n this.userState = 'listening';\n this._agentState = 'initializing';\n this.rootSpanContext = undefined;\n\n this.logger.info({ reason, error }, 'AgentSession closed');\n }\n}\n"],"mappings":"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","names":["InferenceSTT","InferenceLLM","InferenceTTS","otelContext","error"]}
@@ -1,8 +1,10 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import type { AudioFrame, Room } from '@livekit/rtc-node';
3
3
  import type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';
4
+ import type { Context } from '@opentelemetry/api';
4
5
  import type { ReadableStream } from 'node:stream/web';
5
6
  import { type LLMModels, type STTModelString, type TTSModelString } from '../inference/index.js';
7
+ import type { FunctionCall, FunctionCallOutput } from '../llm/chat_context.js';
6
8
  import { ChatContext, ChatMessage } from '../llm/chat_context.js';
7
9
  import type { LLM, RealtimeModel, RealtimeModelError, ToolChoice } from '../llm/index.js';
8
10
  import type { LLMError } from '../llm/llm.js';
@@ -71,8 +73,17 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
71
73
  private _output;
72
74
  private closingTask;
73
75
  private userAwayTimer;
76
+ private sessionSpan?;
77
+ private userSpeakingSpan?;
78
+ private agentSpeakingSpan?;
79
+ /** @internal */
80
+ rootSpanContext?: Context;
74
81
  /** @internal */
75
82
  _recordedEvents: AgentEvent[];
83
+ /** @internal */
84
+ _enableRecording: boolean;
85
+ /** @internal - Timestamp when the session started (milliseconds) */
86
+ _startedAt?: number;
76
87
  constructor(opts: AgentSessionOptions<UserData>);
77
88
  emit<K extends keyof AgentSessionCallbacks>(event: K, ...args: Parameters<AgentSessionCallbacks[K]>): boolean;
78
89
  get input(): AgentInput;
@@ -80,6 +91,7 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
80
91
  get userData(): UserData;
81
92
  get history(): ChatContext;
82
93
  set userData(value: UserData);
94
+ private _startImpl;
83
95
  start({ agent, room, inputOptions, outputOptions, record, }: {
84
96
  agent: Agent;
85
97
  room: Room;
@@ -118,6 +130,8 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
118
130
  /** @internal */
119
131
  _conversationItemAdded(item: ChatMessage): void;
120
132
  /** @internal */
133
+ _toolItemsAdded(items: (FunctionCall | FunctionCallOutput)[]): void;
134
+ /** @internal */
121
135
  _updateAgentState(state: AgentState): void;
122
136
  /** @internal */
123
137
  _updateUserState(state: UserState, _lastSpeakingTime?: number): void;
@@ -128,6 +142,7 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
128
142
  private _cancelUserAwayTimer;
129
143
  private _onUserInputTranscribed;
130
144
  private closeImpl;
145
+ private closeImplInner;
131
146
  }
132
147
  export {};
133
148
  //# sourceMappingURL=agent_session.d.ts.map
@@ -1,8 +1,10 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import type { AudioFrame, Room } from '@livekit/rtc-node';
3
3
  import type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';
4
+ import type { Context } from '@opentelemetry/api';
4
5
  import type { ReadableStream } from 'node:stream/web';
5
6
  import { type LLMModels, type STTModelString, type TTSModelString } from '../inference/index.js';
7
+ import type { FunctionCall, FunctionCallOutput } from '../llm/chat_context.js';
6
8
  import { ChatContext, ChatMessage } from '../llm/chat_context.js';
7
9
  import type { LLM, RealtimeModel, RealtimeModelError, ToolChoice } from '../llm/index.js';
8
10
  import type { LLMError } from '../llm/llm.js';
@@ -71,8 +73,17 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
71
73
  private _output;
72
74
  private closingTask;
73
75
  private userAwayTimer;
76
+ private sessionSpan?;
77
+ private userSpeakingSpan?;
78
+ private agentSpeakingSpan?;
79
+ /** @internal */
80
+ rootSpanContext?: Context;
74
81
  /** @internal */
75
82
  _recordedEvents: AgentEvent[];
83
+ /** @internal */
84
+ _enableRecording: boolean;
85
+ /** @internal - Timestamp when the session started (milliseconds) */
86
+ _startedAt?: number;
76
87
  constructor(opts: AgentSessionOptions<UserData>);
77
88
  emit<K extends keyof AgentSessionCallbacks>(event: K, ...args: Parameters<AgentSessionCallbacks[K]>): boolean;
78
89
  get input(): AgentInput;
@@ -80,6 +91,7 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
80
91
  get userData(): UserData;
81
92
  get history(): ChatContext;
82
93
  set userData(value: UserData);
94
+ private _startImpl;
83
95
  start({ agent, room, inputOptions, outputOptions, record, }: {
84
96
  agent: Agent;
85
97
  room: Room;
@@ -118,6 +130,8 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
118
130
  /** @internal */
119
131
  _conversationItemAdded(item: ChatMessage): void;
120
132
  /** @internal */
133
+ _toolItemsAdded(items: (FunctionCall | FunctionCallOutput)[]): void;
134
+ /** @internal */
121
135
  _updateAgentState(state: AgentState): void;
122
136
  /** @internal */
123
137
  _updateUserState(state: UserState, _lastSpeakingTime?: number): void;
@@ -128,6 +142,7 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
128
142
  private _cancelUserAwayTimer;
129
143
  private _onUserInputTranscribed;
130
144
  private closeImpl;
145
+ private closeImplInner;
131
146
  }
132
147
  export {};
133
148
  //# sourceMappingURL=agent_session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent_session.d.ts","sourceRoot":"","sources":["../../src/voice/agent_session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent_session.d.ts","sourceRoot":"","sources":["../../src/voice/agent_session.ts"],"names":[],"mappings":"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"}