@livekit/agents 1.0.47 → 1.0.49

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 (151) hide show
  1. package/dist/beta/index.cjs +29 -0
  2. package/dist/beta/index.cjs.map +1 -0
  3. package/dist/beta/index.d.cts +2 -0
  4. package/dist/beta/index.d.ts +2 -0
  5. package/dist/beta/index.d.ts.map +1 -0
  6. package/dist/beta/index.js +7 -0
  7. package/dist/beta/index.js.map +1 -0
  8. package/dist/beta/workflows/index.cjs +29 -0
  9. package/dist/beta/workflows/index.cjs.map +1 -0
  10. package/dist/beta/workflows/index.d.cts +2 -0
  11. package/dist/beta/workflows/index.d.ts +2 -0
  12. package/dist/beta/workflows/index.d.ts.map +1 -0
  13. package/dist/beta/workflows/index.js +7 -0
  14. package/dist/beta/workflows/index.js.map +1 -0
  15. package/dist/beta/workflows/task_group.cjs +162 -0
  16. package/dist/beta/workflows/task_group.cjs.map +1 -0
  17. package/dist/beta/workflows/task_group.d.cts +32 -0
  18. package/dist/beta/workflows/task_group.d.ts +32 -0
  19. package/dist/beta/workflows/task_group.d.ts.map +1 -0
  20. package/dist/beta/workflows/task_group.js +138 -0
  21. package/dist/beta/workflows/task_group.js.map +1 -0
  22. package/dist/cpu.cjs +189 -0
  23. package/dist/cpu.cjs.map +1 -0
  24. package/dist/cpu.d.cts +24 -0
  25. package/dist/cpu.d.ts +24 -0
  26. package/dist/cpu.d.ts.map +1 -0
  27. package/dist/cpu.js +152 -0
  28. package/dist/cpu.js.map +1 -0
  29. package/dist/cpu.test.cjs +227 -0
  30. package/dist/cpu.test.cjs.map +1 -0
  31. package/dist/cpu.test.js +204 -0
  32. package/dist/cpu.test.js.map +1 -0
  33. package/dist/index.cjs +3 -0
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +2 -1
  36. package/dist/index.d.ts +2 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +2 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/inference/api_protos.d.cts +59 -59
  41. package/dist/inference/api_protos.d.ts +59 -59
  42. package/dist/inference/llm.cjs.map +1 -1
  43. package/dist/inference/llm.d.cts +1 -1
  44. package/dist/inference/llm.d.ts +1 -1
  45. package/dist/inference/llm.d.ts.map +1 -1
  46. package/dist/inference/llm.js.map +1 -1
  47. package/dist/inference/tts.cjs.map +1 -1
  48. package/dist/inference/tts.d.cts +6 -0
  49. package/dist/inference/tts.d.ts +6 -0
  50. package/dist/inference/tts.d.ts.map +1 -1
  51. package/dist/inference/tts.js.map +1 -1
  52. package/dist/llm/chat_context.cjs +89 -1
  53. package/dist/llm/chat_context.cjs.map +1 -1
  54. package/dist/llm/chat_context.d.cts +10 -1
  55. package/dist/llm/chat_context.d.ts +10 -1
  56. package/dist/llm/chat_context.d.ts.map +1 -1
  57. package/dist/llm/chat_context.js +89 -1
  58. package/dist/llm/chat_context.js.map +1 -1
  59. package/dist/llm/chat_context.test.cjs +43 -0
  60. package/dist/llm/chat_context.test.cjs.map +1 -1
  61. package/dist/llm/chat_context.test.js +43 -0
  62. package/dist/llm/chat_context.test.js.map +1 -1
  63. package/dist/llm/index.cjs +2 -0
  64. package/dist/llm/index.cjs.map +1 -1
  65. package/dist/llm/index.d.cts +1 -1
  66. package/dist/llm/index.d.ts +1 -1
  67. package/dist/llm/index.d.ts.map +1 -1
  68. package/dist/llm/index.js +3 -1
  69. package/dist/llm/index.js.map +1 -1
  70. package/dist/llm/provider_format/index.d.cts +1 -1
  71. package/dist/llm/provider_format/index.d.ts +1 -1
  72. package/dist/llm/tool_context.cjs +7 -0
  73. package/dist/llm/tool_context.cjs.map +1 -1
  74. package/dist/llm/tool_context.d.cts +10 -2
  75. package/dist/llm/tool_context.d.ts +10 -2
  76. package/dist/llm/tool_context.d.ts.map +1 -1
  77. package/dist/llm/tool_context.js +6 -0
  78. package/dist/llm/tool_context.js.map +1 -1
  79. package/dist/utils.cjs +1 -0
  80. package/dist/utils.cjs.map +1 -1
  81. package/dist/utils.d.ts.map +1 -1
  82. package/dist/utils.js +1 -0
  83. package/dist/utils.js.map +1 -1
  84. package/dist/version.cjs +1 -1
  85. package/dist/version.js +1 -1
  86. package/dist/voice/agent.cjs +9 -0
  87. package/dist/voice/agent.cjs.map +1 -1
  88. package/dist/voice/agent.d.cts +1 -0
  89. package/dist/voice/agent.d.ts +1 -0
  90. package/dist/voice/agent.d.ts.map +1 -1
  91. package/dist/voice/agent.js +9 -0
  92. package/dist/voice/agent.js.map +1 -1
  93. package/dist/voice/agent_activity.cjs +67 -16
  94. package/dist/voice/agent_activity.cjs.map +1 -1
  95. package/dist/voice/agent_activity.d.cts +7 -0
  96. package/dist/voice/agent_activity.d.ts +7 -0
  97. package/dist/voice/agent_activity.d.ts.map +1 -1
  98. package/dist/voice/agent_activity.js +68 -17
  99. package/dist/voice/agent_activity.js.map +1 -1
  100. package/dist/voice/agent_session.cjs +27 -1
  101. package/dist/voice/agent_session.cjs.map +1 -1
  102. package/dist/voice/agent_session.d.cts +6 -0
  103. package/dist/voice/agent_session.d.ts +6 -0
  104. package/dist/voice/agent_session.d.ts.map +1 -1
  105. package/dist/voice/agent_session.js +27 -1
  106. package/dist/voice/agent_session.js.map +1 -1
  107. package/dist/voice/room_io/room_io.cjs +11 -2
  108. package/dist/voice/room_io/room_io.cjs.map +1 -1
  109. package/dist/voice/room_io/room_io.d.ts.map +1 -1
  110. package/dist/voice/room_io/room_io.js +12 -3
  111. package/dist/voice/room_io/room_io.js.map +1 -1
  112. package/dist/voice/testing/fake_llm.cjs +127 -0
  113. package/dist/voice/testing/fake_llm.cjs.map +1 -0
  114. package/dist/voice/testing/fake_llm.d.cts +30 -0
  115. package/dist/voice/testing/fake_llm.d.ts +30 -0
  116. package/dist/voice/testing/fake_llm.d.ts.map +1 -0
  117. package/dist/voice/testing/fake_llm.js +103 -0
  118. package/dist/voice/testing/fake_llm.js.map +1 -0
  119. package/dist/voice/testing/index.cjs +3 -0
  120. package/dist/voice/testing/index.cjs.map +1 -1
  121. package/dist/voice/testing/index.d.cts +1 -0
  122. package/dist/voice/testing/index.d.ts +1 -0
  123. package/dist/voice/testing/index.d.ts.map +1 -1
  124. package/dist/voice/testing/index.js +2 -0
  125. package/dist/voice/testing/index.js.map +1 -1
  126. package/dist/worker.cjs +6 -29
  127. package/dist/worker.cjs.map +1 -1
  128. package/dist/worker.d.ts.map +1 -1
  129. package/dist/worker.js +6 -19
  130. package/dist/worker.js.map +1 -1
  131. package/package.json +1 -1
  132. package/src/beta/index.ts +9 -0
  133. package/src/beta/workflows/index.ts +9 -0
  134. package/src/beta/workflows/task_group.ts +194 -0
  135. package/src/cpu.test.ts +239 -0
  136. package/src/cpu.ts +173 -0
  137. package/src/index.ts +2 -1
  138. package/src/inference/llm.ts +2 -0
  139. package/src/inference/tts.ts +8 -1
  140. package/src/llm/chat_context.test.ts +48 -0
  141. package/src/llm/chat_context.ts +123 -0
  142. package/src/llm/index.ts +1 -0
  143. package/src/llm/tool_context.ts +14 -0
  144. package/src/utils.ts +5 -0
  145. package/src/voice/agent.ts +11 -0
  146. package/src/voice/agent_activity.ts +102 -16
  147. package/src/voice/agent_session.ts +33 -2
  148. package/src/voice/room_io/room_io.ts +14 -3
  149. package/src/voice/testing/fake_llm.ts +138 -0
  150. package/src/voice/testing/index.ts +2 -0
  151. package/src/worker.ts +34 -50
@@ -48,6 +48,7 @@ const defaultVoiceOptions = {
48
48
  maxToolSteps: 3,
49
49
  preemptiveGeneration: false,
50
50
  userAwayTimeout: 15,
51
+ aecWarmupDuration: 3e3,
51
52
  useTtsAlignedTranscript: true
52
53
  };
53
54
  class AgentSession extends import_node_events.EventEmitter {
@@ -74,6 +75,7 @@ class AgentSession extends import_node_events.EventEmitter {
74
75
  _output;
75
76
  closingTask = null;
76
77
  userAwayTimer = null;
78
+ _aecWarmupTimer = null;
77
79
  // Connection options for STT, LLM, and TTS
78
80
  _connOptions;
79
81
  // Unrecoverable error counts, reset after agent speaking
@@ -83,6 +85,8 @@ class AgentSession extends import_node_events.EventEmitter {
83
85
  userSpeakingSpan;
84
86
  agentSpeakingSpan;
85
87
  /** @internal */
88
+ _aecWarmupRemaining = 0;
89
+ /** @internal */
86
90
  _recorderIO;
87
91
  /** @internal */
88
92
  rootSpanContext;
@@ -134,6 +138,7 @@ class AgentSession extends import_node_events.EventEmitter {
134
138
  this._output = new import_io.AgentOutput(this.onAudioOutputChanged, this.onTextOutputChanged);
135
139
  this._chatCtx = import_chat_context.ChatContext.empty();
136
140
  this.options = { ...defaultVoiceOptions, ...voiceOptions };
141
+ this._aecWarmupRemaining = this.options.aecWarmupDuration ?? 0;
137
142
  this._onUserInputTranscribed = this._onUserInputTranscribed.bind(this);
138
143
  this.on(import_events.AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);
139
144
  }
@@ -526,7 +531,9 @@ class AgentSession extends import_node_events.EventEmitter {
526
531
  if (this.closingTask) {
527
532
  return;
528
533
  }
529
- this.closeImpl(reason, error, drain);
534
+ this.closingTask = this.closeImpl(reason, error, drain).finally(() => {
535
+ this.closingTask = null;
536
+ });
530
537
  }
531
538
  /** @internal */
532
539
  _onError(error) {
@@ -584,6 +591,13 @@ class AgentSession extends import_node_events.EventEmitter {
584
591
  this.agentSpeakingSpan.end();
585
592
  this.agentSpeakingSpan = void 0;
586
593
  }
594
+ if (state === "speaking" && this._aecWarmupRemaining > 0 && this._aecWarmupTimer === null) {
595
+ this._aecWarmupTimer = setTimeout(() => this._onAecWarmupExpired(), this._aecWarmupRemaining);
596
+ this.logger.debug(
597
+ { warmupDurationMs: this._aecWarmupRemaining },
598
+ "aec warmup active, disabling interruptions"
599
+ );
600
+ }
587
601
  const oldState = this._agentState;
588
602
  this._agentState = state;
589
603
  if (state === "listening" && this.userState === "listening") {
@@ -660,6 +674,17 @@ class AgentSession extends import_node_events.EventEmitter {
660
674
  this.userAwayTimer = null;
661
675
  }
662
676
  }
677
+ /** @internal */
678
+ _onAecWarmupExpired() {
679
+ if (this._aecWarmupRemaining > 0) {
680
+ this.logger.debug("aec warmup expired, re-enabling interruptions");
681
+ }
682
+ this._aecWarmupRemaining = 0;
683
+ if (this._aecWarmupTimer !== null) {
684
+ clearTimeout(this._aecWarmupTimer);
685
+ this._aecWarmupTimer = null;
686
+ }
687
+ }
663
688
  _onUserInputTranscribed(ev) {
664
689
  if (this.userState === "away" && ev.isFinal) {
665
690
  this.logger.debug("User returned from away state due to speech input");
@@ -680,6 +705,7 @@ class AgentSession extends import_node_events.EventEmitter {
680
705
  return;
681
706
  }
682
707
  this._cancelUserAwayTimer();
708
+ this._onAecWarmupExpired();
683
709
  this.off(import_events.AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);
684
710
  if (this.activity) {
685
711
  if (!drain) {
@@ -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 { Mutex } from '@livekit/mutex';\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 type { z } from 'zod';\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 { type JobContext, 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 {\n DEFAULT_API_CONNECT_OPTIONS,\n DEFAULT_SESSION_CONNECT_OPTIONS,\n type ResolvedSessionConnectOptions,\n type SessionConnectOptions,\n} from '../types.js';\nimport { Task } from '../utils.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 ShutdownReason,\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 { RecorderIO } from './recorder_io/index.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';\nimport { RunResult } from './testing/run_result.js';\nimport { setParticipantSpanAttributes } from './utils.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 useTtsAlignedTranscript: boolean;\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 useTtsAlignedTranscript: true,\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 connOptions?: SessionConnectOptions;\n};\n\ntype ActivityTransitionOptions = {\n previousActivity?: 'close' | 'pause';\n newActivity?: 'start' | 'resume';\n blockedTasks?: Task<any>[];\n waitOnEnter?: boolean;\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 updateActivityTask?: Task<void>;\n private started = false;\n private userState: UserState = 'listening';\n private readonly activityLock = new Mutex();\n\n /** @internal */\n _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 // Connection options for STT, LLM, and TTS\n private _connOptions: ResolvedSessionConnectOptions;\n\n // Unrecoverable error counts, reset after agent speaking\n private llmErrorCounts = 0;\n private ttsErrorCounts = 0;\n\n private sessionSpan?: Span;\n private userSpeakingSpan?: Span;\n private agentSpeakingSpan?: Span;\n\n /** @internal */\n _recorderIO?: RecorderIO;\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 /** @internal - Current run state for testing */\n _globalRunState?: RunResult;\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 connOptions,\n } = opts;\n\n // Merge user-provided connOptions with defaults\n this._connOptions = {\n sttConnOptions: { ...DEFAULT_API_CONNECT_OPTIONS, ...connOptions?.sttConnOptions },\n llmConnOptions: { ...DEFAULT_API_CONNECT_OPTIONS, ...connOptions?.llmConnOptions },\n ttsConnOptions: { ...DEFAULT_API_CONNECT_OPTIONS, ...connOptions?.ttsConnOptions },\n maxUnrecoverableErrors:\n connOptions?.maxUnrecoverableErrors ??\n DEFAULT_SESSION_CONNECT_OPTIONS.maxUnrecoverableErrors,\n };\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 /** Connection options for STT, LLM, and TTS. */\n get connOptions(): ResolvedSessionConnectOptions {\n return this._connOptions;\n }\n\n get useTtsAlignedTranscript(): boolean {\n return this.options.useTtsAlignedTranscript;\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 span,\n }: {\n agent: Agent;\n room?: Room;\n inputOptions?: Partial<RoomInputOptions>;\n outputOptions?: Partial<RoomOutputOptions>;\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\n if (room && !this._roomIO) {\n // Check for existing input/output configuration and warn if needed\n if (this.input.audio && inputOptions?.audioEnabled !== false) {\n this.logger.warn(\n 'RoomIO audio input is enabled but input.audio is already set, ignoring..',\n );\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\n let ctx: JobContext | undefined = undefined;\n try {\n ctx = getJobContext();\n } catch {\n // JobContext is not available in evals\n }\n\n if (ctx) {\n if (room && 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 (ctx._primaryAgentSession === undefined) {\n ctx._primaryAgentSession = this;\n } else if (this._enableRecording) {\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 if (this.input.audio && this.output.audio && this._enableRecording) {\n this._recorderIO = new RecorderIO({ agentSession: this });\n this.input.audio = this._recorderIO.recordInput(this.input.audio);\n this.output.audio = this._recorderIO.recordOutput(this.output.audio);\n\n // Start recording to session directory\n const sessionDir = ctx.sessionDirectory;\n if (sessionDir) {\n tasks.push(this._recorderIO.start(`${sessionDir}/audio.ogg`));\n }\n }\n }\n\n // TODO(AJS-265): add shutdown callback to job context\n // Initial start does not wait on onEnter\n tasks.push(this._updateActivity(this.agent, { waitOnEnter: false }));\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,\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 let ctx: JobContext | undefined = undefined;\n try {\n ctx = getJobContext();\n\n if (record === undefined) {\n record = ctx.job.enableRecording;\n }\n\n this._enableRecording = record;\n\n if (this._enableRecording) {\n ctx.initRecording();\n }\n } catch (error) {\n // JobContext is not available in evals\n this.logger.warn('JobContext is not available');\n }\n\n this.sessionSpan = tracer.startSpan({\n name: 'agent_session',\n context: ROOT_CONTEXT,\n });\n\n this.rootSpanContext = trace.setSpan(ROOT_CONTEXT, this.sessionSpan);\n\n await this._startImpl({\n agent,\n room,\n inputOptions,\n outputOptions,\n span: this.sessionSpan,\n });\n }\n\n updateAgent(agent: Agent): void {\n this.agent = agent;\n\n if (!this.started) {\n return;\n }\n\n const _updateActivityTask = async (oldTask: Task<void> | undefined, agent: Agent) => {\n if (oldTask) {\n try {\n await oldTask.result;\n } catch (error) {\n this.logger.error(error, 'previous updateAgent transition failed');\n }\n }\n\n await this._updateActivity(agent);\n };\n\n const oldTask = this.updateActivityTask;\n this.updateActivityTask = Task.from(\n async () => _updateActivityTask(oldTask, agent),\n undefined,\n 'AgentSession_updateActivityTask',\n );\n\n const runState = this._globalRunState;\n if (runState) {\n // Don't mark the RunResult as done, if there is currently an agent transition happening.\n // (used to make sure we're correctly adding the AgentHandoffResult before completion)\n runState._watchHandle(this.updateActivityTask);\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 const doSay = (activity: AgentActivity, nextActivity?: AgentActivity) => {\n if (activity.schedulingPaused) {\n if (!nextActivity) {\n throw new Error('AgentSession is closing, cannot use say()');\n }\n return nextActivity.say(text, options);\n }\n return activity.say(text, options);\n };\n\n const runState = this._globalRunState;\n let handle: SpeechHandle;\n\n // attach to the session span if called outside of the AgentSession\n const activeSpan = trace.getActiveSpan();\n if (!activeSpan && this.rootSpanContext) {\n handle = otelContext.with(this.rootSpanContext, () =>\n doSay(this.activity!, this.nextActivity),\n );\n } else {\n handle = doSay(this.activity, this.nextActivity);\n }\n\n if (runState) {\n runState._watchHandle(handle);\n }\n\n return handle;\n }\n\n interrupt(options?: { force?: boolean }) {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n return this.activity.interrupt(options);\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 const doGenerateReply = (activity: AgentActivity, nextActivity?: AgentActivity) => {\n if (activity.schedulingPaused) {\n if (!nextActivity) {\n throw new Error('AgentSession is closing, cannot use generateReply()');\n }\n return nextActivity.generateReply({ userMessage, ...options });\n }\n return activity.generateReply({ userMessage, ...options });\n };\n\n // attach to the session span if called outside of the AgentSession\n const activeSpan = trace.getActiveSpan();\n let handle: SpeechHandle;\n if (!activeSpan && this.rootSpanContext) {\n handle = otelContext.with(this.rootSpanContext, () =>\n doGenerateReply(this.activity!, this.nextActivity),\n );\n } else {\n handle = doGenerateReply(this.activity!, this.nextActivity);\n }\n\n if (this._globalRunState) {\n this._globalRunState._watchHandle(handle);\n }\n\n return handle;\n }\n\n /**\n * Run a test with user input and return a result for assertions.\n *\n * This method is primarily used for testing agent behavior without\n * requiring a real room connection.\n *\n * @example\n * ```typescript\n * const result = await session.run({ userInput: 'Hello' });\n * result.expect.nextEvent().isMessage({ role: 'assistant' });\n * result.expect.noMoreEvents();\n * ```\n *\n * @param options - Run options including user input and optional output type\n * @returns A RunResult that resolves when the agent finishes responding\n */\n run<T = unknown>({\n userInput,\n outputType,\n }: {\n userInput: string;\n outputType?: z.ZodType<T>;\n }): RunResult<T> {\n if (this._globalRunState && !this._globalRunState.done()) {\n throw new Error('nested runs are not supported');\n }\n\n const runState = new RunResult<T>({\n userInput,\n outputType,\n });\n\n this._globalRunState = runState;\n\n // Defer generateReply through the activityLock to ensure any in-progress\n // activity transition (e.g. AgentTask started from onEnter) completes first.\n // TS Task.from starts onEnter synchronously, so the transition may already be\n // mid-flight by the time run() is called after session.start() resolves.\n // Acquiring and immediately releasing the lock guarantees FIFO ordering:\n // the transition's lock section finishes before we route generateReply.\n (async () => {\n try {\n const unlock = await this.activityLock.lock();\n unlock();\n this.generateReply({ userInput });\n } catch (e) {\n runState._reject(e instanceof Error ? e : new Error(String(e)));\n }\n })();\n\n return runState;\n }\n\n /** @internal */\n async _updateActivity(agent: Agent, options: ActivityTransitionOptions = {}): Promise<void> {\n const { previousActivity = 'close', newActivity = 'start', blockedTasks = [] } = options;\n const waitOnEnter = options.waitOnEnter ?? newActivity === 'start';\n\n const runWithContext = async () => {\n const unlock = await this.activityLock.lock();\n let onEnterTask: Task<void> | undefined;\n\n try {\n this.agent = agent;\n const prevActivityObj = this.activity;\n\n if (newActivity === 'start') {\n const prevAgent = prevActivityObj?.agent;\n if (\n agent._agentActivity &&\n // allow updating the same agent that is running\n (agent !== prevAgent || previousActivity !== 'close')\n ) {\n throw new Error('Cannot start agent: an activity is already running');\n }\n this.nextActivity = new AgentActivity(agent, this);\n } else if (newActivity === 'resume') {\n if (!agent._agentActivity) {\n throw new Error('Cannot resume agent: no existing activity to resume');\n }\n this.nextActivity = agent._agentActivity;\n }\n\n if (prevActivityObj && prevActivityObj !== this.nextActivity) {\n if (previousActivity === 'pause') {\n await prevActivityObj.pause({ blockedTasks });\n } else {\n await prevActivityObj.drain();\n await prevActivityObj.close();\n }\n }\n\n this.activity = this.nextActivity;\n this.nextActivity = undefined;\n\n const runState = this._globalRunState;\n const handoffItem = new AgentHandoffItem({\n oldAgentId: prevActivityObj?.agent.id,\n newAgentId: agent.id,\n });\n\n if (runState) {\n runState._agentHandoff({\n item: handoffItem,\n oldAgent: prevActivityObj?.agent,\n newAgent: this.activity!.agent,\n });\n }\n\n this._chatCtx.insert(handoffItem);\n this.logger.debug(\n { previousAgentId: prevActivityObj?.agent.id, newAgentId: agent.id },\n 'Agent handoff inserted into chat context',\n );\n\n if (newActivity === 'start') {\n await this.activity!.start();\n } else {\n await this.activity!.resume();\n }\n\n onEnterTask = this.activity!._onEnterTask;\n\n if (this._input.audio) {\n this.activity!.attachAudioInput(this._input.audio.stream);\n }\n } finally {\n unlock();\n }\n\n if (waitOnEnter) {\n if (!onEnterTask) {\n throw new Error('expected onEnter task to be available while waitOnEnter=true');\n }\n await onEnterTask.result;\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 shutdown(options?: { drain?: boolean; reason?: ShutdownReason }): void {\n const { drain = true, reason = CloseReason.USER_INITIATED } = options ?? {};\n\n this._closeSoon({\n reason,\n drain,\n });\n }\n\n /** @internal */\n _closeSoon({\n reason,\n drain = false,\n error = null,\n }: {\n reason: ShutdownReason;\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 // Track error counts per type to implement max_unrecoverable_errors logic\n if (error.type === 'llm_error') {\n this.llmErrorCounts += 1;\n if (this.llmErrorCounts <= this._connOptions.maxUnrecoverableErrors) {\n return;\n }\n } else if (error.type === 'tts_error') {\n this.ttsErrorCounts += 1;\n if (this.ttsErrorCounts <= this._connOptions.maxUnrecoverableErrors) {\n return;\n }\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, options?: { startTime?: number; otelContext?: Context }) {\n if (this._agentState === state) {\n return;\n }\n\n if (state === 'speaking') {\n // Reset error counts when agent starts speaking\n this.llmErrorCounts = 0;\n this.ttsErrorCounts = 0;\n\n if (this.agentSpeakingSpan === undefined) {\n this.agentSpeakingSpan = tracer.startSpan({\n name: 'agent_speaking',\n context: options?.otelContext ?? this.rootSpanContext,\n startTime: options?.startTime,\n });\n\n const localParticipant = this._roomIO?.localParticipant;\n if (localParticipant) {\n setParticipantSpanAttributes(this.agentSpeakingSpan, localParticipant);\n }\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 startTime: lastSpeakingTime,\n });\n\n const linked = this._roomIO?.linkedParticipant;\n if (linked) {\n setParticipantSpanAttributes(this.userSpeakingSpan, linked);\n }\n } else if (this.userSpeakingSpan !== undefined) {\n this.userSpeakingSpan.end(lastSpeakingTime);\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: ShutdownReason,\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: ShutdownReason,\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 await this.activity.interrupt({ force: true }).await;\n } catch (error) {\n // Uninterruptible speech can throw during forced interruption.\n this.logger.warn({ error }, 'Error interrupting activity');\n }\n }\n\n await this.activity.drain();\n // wait any uninterruptible speech to finish\n await this.activity.currentSpeech?.waitForPlayout();\n\n if (reason !== CloseReason.ERROR) {\n this.activity.commitUserTurn({ audioDetached: true, throwIfNotReady: false });\n }\n\n try {\n this.activity.detachAudioInput();\n } catch (error) {\n // Ignore detach errors during cleanup - source may not have been set\n }\n }\n\n // Close recorder before detaching inputs/outputs (keep reference for session report)\n if (this._recorderIO) {\n await this._recorderIO.close();\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 this.llmErrorCounts = 0;\n this.ttsErrorCounts = 0;\n\n this.logger.info({ reason, error }, 'AgentSession closed');\n }\n}\n"],"mappings":"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","names":["import_utils","InferenceSTT","InferenceLLM","InferenceTTS","oldTask","agent","otelContext","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 { Mutex } from '@livekit/mutex';\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 type { z } from 'zod';\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 { type JobContext, 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 {\n DEFAULT_API_CONNECT_OPTIONS,\n DEFAULT_SESSION_CONNECT_OPTIONS,\n type ResolvedSessionConnectOptions,\n type SessionConnectOptions,\n} from '../types.js';\nimport { Task } from '../utils.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 ShutdownReason,\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 { RecorderIO } from './recorder_io/index.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';\nimport { RunResult } from './testing/run_result.js';\nimport { setParticipantSpanAttributes } from './utils.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 aecWarmupDuration: number | null;\n useTtsAlignedTranscript: boolean;\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 aecWarmupDuration: 3000,\n useTtsAlignedTranscript: true,\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 connOptions?: SessionConnectOptions;\n};\n\ntype ActivityTransitionOptions = {\n previousActivity?: 'close' | 'pause';\n newActivity?: 'start' | 'resume';\n blockedTasks?: Task<any>[];\n waitOnEnter?: boolean;\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 updateActivityTask?: Task<void>;\n private started = false;\n private userState: UserState = 'listening';\n private readonly activityLock = new Mutex();\n\n /** @internal */\n _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 _aecWarmupTimer: NodeJS.Timeout | null = null;\n\n // Connection options for STT, LLM, and TTS\n private _connOptions: ResolvedSessionConnectOptions;\n\n // Unrecoverable error counts, reset after agent speaking\n private llmErrorCounts = 0;\n private ttsErrorCounts = 0;\n\n private sessionSpan?: Span;\n private userSpeakingSpan?: Span;\n private agentSpeakingSpan?: Span;\n\n /** @internal */\n _aecWarmupRemaining = 0;\n\n /** @internal */\n _recorderIO?: RecorderIO;\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 /** @internal - Current run state for testing */\n _globalRunState?: RunResult;\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 connOptions,\n } = opts;\n\n // Merge user-provided connOptions with defaults\n this._connOptions = {\n sttConnOptions: { ...DEFAULT_API_CONNECT_OPTIONS, ...connOptions?.sttConnOptions },\n llmConnOptions: { ...DEFAULT_API_CONNECT_OPTIONS, ...connOptions?.llmConnOptions },\n ttsConnOptions: { ...DEFAULT_API_CONNECT_OPTIONS, ...connOptions?.ttsConnOptions },\n maxUnrecoverableErrors:\n connOptions?.maxUnrecoverableErrors ??\n DEFAULT_SESSION_CONNECT_OPTIONS.maxUnrecoverableErrors,\n };\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 this._aecWarmupRemaining = this.options.aecWarmupDuration ?? 0;\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 /** Connection options for STT, LLM, and TTS. */\n get connOptions(): ResolvedSessionConnectOptions {\n return this._connOptions;\n }\n\n get useTtsAlignedTranscript(): boolean {\n return this.options.useTtsAlignedTranscript;\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 span,\n }: {\n agent: Agent;\n room?: Room;\n inputOptions?: Partial<RoomInputOptions>;\n outputOptions?: Partial<RoomOutputOptions>;\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\n if (room && !this._roomIO) {\n // Check for existing input/output configuration and warn if needed\n if (this.input.audio && inputOptions?.audioEnabled !== false) {\n this.logger.warn(\n 'RoomIO audio input is enabled but input.audio is already set, ignoring..',\n );\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\n let ctx: JobContext | undefined = undefined;\n try {\n ctx = getJobContext();\n } catch {\n // JobContext is not available in evals\n }\n\n if (ctx) {\n if (room && 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 (ctx._primaryAgentSession === undefined) {\n ctx._primaryAgentSession = this;\n } else if (this._enableRecording) {\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 if (this.input.audio && this.output.audio && this._enableRecording) {\n this._recorderIO = new RecorderIO({ agentSession: this });\n this.input.audio = this._recorderIO.recordInput(this.input.audio);\n this.output.audio = this._recorderIO.recordOutput(this.output.audio);\n\n // Start recording to session directory\n const sessionDir = ctx.sessionDirectory;\n if (sessionDir) {\n tasks.push(this._recorderIO.start(`${sessionDir}/audio.ogg`));\n }\n }\n }\n\n // TODO(AJS-265): add shutdown callback to job context\n // Initial start does not wait on onEnter\n tasks.push(this._updateActivity(this.agent, { waitOnEnter: false }));\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,\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 let ctx: JobContext | undefined = undefined;\n try {\n ctx = getJobContext();\n\n if (record === undefined) {\n record = ctx.job.enableRecording;\n }\n\n this._enableRecording = record;\n\n if (this._enableRecording) {\n ctx.initRecording();\n }\n } catch (error) {\n // JobContext is not available in evals\n this.logger.warn('JobContext is not available');\n }\n\n this.sessionSpan = tracer.startSpan({\n name: 'agent_session',\n context: ROOT_CONTEXT,\n });\n\n this.rootSpanContext = trace.setSpan(ROOT_CONTEXT, this.sessionSpan);\n\n await this._startImpl({\n agent,\n room,\n inputOptions,\n outputOptions,\n span: this.sessionSpan,\n });\n }\n\n updateAgent(agent: Agent): void {\n this.agent = agent;\n\n if (!this.started) {\n return;\n }\n\n const _updateActivityTask = async (oldTask: Task<void> | undefined, agent: Agent) => {\n if (oldTask) {\n try {\n await oldTask.result;\n } catch (error) {\n this.logger.error(error, 'previous updateAgent transition failed');\n }\n }\n\n await this._updateActivity(agent);\n };\n\n const oldTask = this.updateActivityTask;\n this.updateActivityTask = Task.from(\n async () => _updateActivityTask(oldTask, agent),\n undefined,\n 'AgentSession_updateActivityTask',\n );\n\n const runState = this._globalRunState;\n if (runState) {\n // Don't mark the RunResult as done, if there is currently an agent transition happening.\n // (used to make sure we're correctly adding the AgentHandoffResult before completion)\n runState._watchHandle(this.updateActivityTask);\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 const doSay = (activity: AgentActivity, nextActivity?: AgentActivity) => {\n if (activity.schedulingPaused) {\n if (!nextActivity) {\n throw new Error('AgentSession is closing, cannot use say()');\n }\n return nextActivity.say(text, options);\n }\n return activity.say(text, options);\n };\n\n const runState = this._globalRunState;\n let handle: SpeechHandle;\n\n // attach to the session span if called outside of the AgentSession\n const activeSpan = trace.getActiveSpan();\n if (!activeSpan && this.rootSpanContext) {\n handle = otelContext.with(this.rootSpanContext, () =>\n doSay(this.activity!, this.nextActivity),\n );\n } else {\n handle = doSay(this.activity, this.nextActivity);\n }\n\n if (runState) {\n runState._watchHandle(handle);\n }\n\n return handle;\n }\n\n interrupt(options?: { force?: boolean }) {\n if (!this.activity) {\n throw new Error('AgentSession is not running');\n }\n\n return this.activity.interrupt(options);\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 const doGenerateReply = (activity: AgentActivity, nextActivity?: AgentActivity) => {\n if (activity.schedulingPaused) {\n if (!nextActivity) {\n throw new Error('AgentSession is closing, cannot use generateReply()');\n }\n return nextActivity.generateReply({ userMessage, ...options });\n }\n return activity.generateReply({ userMessage, ...options });\n };\n\n // attach to the session span if called outside of the AgentSession\n const activeSpan = trace.getActiveSpan();\n let handle: SpeechHandle;\n if (!activeSpan && this.rootSpanContext) {\n handle = otelContext.with(this.rootSpanContext, () =>\n doGenerateReply(this.activity!, this.nextActivity),\n );\n } else {\n handle = doGenerateReply(this.activity!, this.nextActivity);\n }\n\n if (this._globalRunState) {\n this._globalRunState._watchHandle(handle);\n }\n\n return handle;\n }\n\n /**\n * Run a test with user input and return a result for assertions.\n *\n * This method is primarily used for testing agent behavior without\n * requiring a real room connection.\n *\n * @example\n * ```typescript\n * const result = await session.run({ userInput: 'Hello' });\n * result.expect.nextEvent().isMessage({ role: 'assistant' });\n * result.expect.noMoreEvents();\n * ```\n *\n * @param options - Run options including user input and optional output type\n * @returns A RunResult that resolves when the agent finishes responding\n */\n run<T = unknown>({\n userInput,\n outputType,\n }: {\n userInput: string;\n outputType?: z.ZodType<T>;\n }): RunResult<T> {\n if (this._globalRunState && !this._globalRunState.done()) {\n throw new Error('nested runs are not supported');\n }\n\n const runState = new RunResult<T>({\n userInput,\n outputType,\n });\n\n this._globalRunState = runState;\n\n // Defer generateReply through the activityLock to ensure any in-progress\n // activity transition (e.g. AgentTask started from onEnter) completes first.\n // TS Task.from starts onEnter synchronously, so the transition may already be\n // mid-flight by the time run() is called after session.start() resolves.\n // Acquiring and immediately releasing the lock guarantees FIFO ordering:\n // the transition's lock section finishes before we route generateReply.\n (async () => {\n try {\n const unlock = await this.activityLock.lock();\n unlock();\n this.generateReply({ userInput });\n } catch (e) {\n runState._reject(e instanceof Error ? e : new Error(String(e)));\n }\n })();\n\n return runState;\n }\n\n /** @internal */\n async _updateActivity(agent: Agent, options: ActivityTransitionOptions = {}): Promise<void> {\n const { previousActivity = 'close', newActivity = 'start', blockedTasks = [] } = options;\n const waitOnEnter = options.waitOnEnter ?? newActivity === 'start';\n\n const runWithContext = async () => {\n const unlock = await this.activityLock.lock();\n let onEnterTask: Task<void> | undefined;\n\n try {\n this.agent = agent;\n const prevActivityObj = this.activity;\n\n if (newActivity === 'start') {\n const prevAgent = prevActivityObj?.agent;\n if (\n agent._agentActivity &&\n // allow updating the same agent that is running\n (agent !== prevAgent || previousActivity !== 'close')\n ) {\n throw new Error('Cannot start agent: an activity is already running');\n }\n this.nextActivity = new AgentActivity(agent, this);\n } else if (newActivity === 'resume') {\n if (!agent._agentActivity) {\n throw new Error('Cannot resume agent: no existing activity to resume');\n }\n this.nextActivity = agent._agentActivity;\n }\n\n if (prevActivityObj && prevActivityObj !== this.nextActivity) {\n if (previousActivity === 'pause') {\n await prevActivityObj.pause({ blockedTasks });\n } else {\n await prevActivityObj.drain();\n await prevActivityObj.close();\n }\n }\n\n this.activity = this.nextActivity;\n this.nextActivity = undefined;\n\n const runState = this._globalRunState;\n const handoffItem = new AgentHandoffItem({\n oldAgentId: prevActivityObj?.agent.id,\n newAgentId: agent.id,\n });\n\n if (runState) {\n runState._agentHandoff({\n item: handoffItem,\n oldAgent: prevActivityObj?.agent,\n newAgent: this.activity!.agent,\n });\n }\n\n this._chatCtx.insert(handoffItem);\n this.logger.debug(\n { previousAgentId: prevActivityObj?.agent.id, newAgentId: agent.id },\n 'Agent handoff inserted into chat context',\n );\n\n if (newActivity === 'start') {\n await this.activity!.start();\n } else {\n await this.activity!.resume();\n }\n\n onEnterTask = this.activity!._onEnterTask;\n\n if (this._input.audio) {\n this.activity!.attachAudioInput(this._input.audio.stream);\n }\n } finally {\n unlock();\n }\n\n if (waitOnEnter) {\n if (!onEnterTask) {\n throw new Error('expected onEnter task to be available while waitOnEnter=true');\n }\n await onEnterTask.result;\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 shutdown(options?: { drain?: boolean; reason?: ShutdownReason }): void {\n const { drain = true, reason = CloseReason.USER_INITIATED } = options ?? {};\n\n this._closeSoon({\n reason,\n drain,\n });\n }\n\n /** @internal */\n _closeSoon({\n reason,\n drain = false,\n error = null,\n }: {\n reason: ShutdownReason;\n drain?: boolean;\n error?: RealtimeModelError | STTError | TTSError | LLMError | null;\n }): void {\n if (this.closingTask) {\n return;\n }\n this.closingTask = this.closeImpl(reason, error, drain).finally(() => {\n this.closingTask = null;\n });\n }\n\n /** @internal */\n _onError(error: RealtimeModelError | STTError | TTSError | LLMError): void {\n if (this.closingTask || error.recoverable) {\n return;\n }\n\n // Track error counts per type to implement max_unrecoverable_errors logic\n if (error.type === 'llm_error') {\n this.llmErrorCounts += 1;\n if (this.llmErrorCounts <= this._connOptions.maxUnrecoverableErrors) {\n return;\n }\n } else if (error.type === 'tts_error') {\n this.ttsErrorCounts += 1;\n if (this.ttsErrorCounts <= this._connOptions.maxUnrecoverableErrors) {\n return;\n }\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, options?: { startTime?: number; otelContext?: Context }) {\n if (this._agentState === state) {\n return;\n }\n\n if (state === 'speaking') {\n // Reset error counts when agent starts speaking\n this.llmErrorCounts = 0;\n this.ttsErrorCounts = 0;\n\n if (this.agentSpeakingSpan === undefined) {\n this.agentSpeakingSpan = tracer.startSpan({\n name: 'agent_speaking',\n context: options?.otelContext ?? this.rootSpanContext,\n startTime: options?.startTime,\n });\n\n const localParticipant = this._roomIO?.localParticipant;\n if (localParticipant) {\n setParticipantSpanAttributes(this.agentSpeakingSpan, localParticipant);\n }\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 if (state === 'speaking' && this._aecWarmupRemaining > 0 && this._aecWarmupTimer === null) {\n this._aecWarmupTimer = setTimeout(() => this._onAecWarmupExpired(), this._aecWarmupRemaining);\n this.logger.debug(\n { warmupDurationMs: this._aecWarmupRemaining },\n 'aec warmup active, disabling interruptions',\n );\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 startTime: lastSpeakingTime,\n });\n\n const linked = this._roomIO?.linkedParticipant;\n if (linked) {\n setParticipantSpanAttributes(this.userSpeakingSpan, linked);\n }\n } else if (this.userSpeakingSpan !== undefined) {\n this.userSpeakingSpan.end(lastSpeakingTime);\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 /** @internal */\n _onAecWarmupExpired(): void {\n if (this._aecWarmupRemaining > 0) {\n this.logger.debug('aec warmup expired, re-enabling interruptions');\n }\n\n this._aecWarmupRemaining = 0;\n if (this._aecWarmupTimer !== null) {\n clearTimeout(this._aecWarmupTimer);\n this._aecWarmupTimer = 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: ShutdownReason,\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: ShutdownReason,\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._onAecWarmupExpired();\n this.off(AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);\n\n if (this.activity) {\n if (!drain) {\n try {\n await this.activity.interrupt({ force: true }).await;\n } catch (error) {\n this.logger.warn({ error }, 'Error interrupting activity');\n }\n }\n\n await this.activity.drain();\n // wait any uninterruptible speech to finish\n await this.activity.currentSpeech?.waitForPlayout();\n\n if (reason !== CloseReason.ERROR) {\n this.activity.commitUserTurn({ audioDetached: true, throwIfNotReady: false });\n }\n\n try {\n this.activity.detachAudioInput();\n } catch (error) {\n // Ignore detach errors during cleanup - source may not have been set\n }\n }\n\n // Close recorder before detaching inputs/outputs (keep reference for session report)\n if (this._recorderIO) {\n await this._recorderIO.close();\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 this.llmErrorCounts = 0;\n this.ttsErrorCounts = 0;\n\n this.logger.info({ reason, error }, 'AgentSession closed');\n }\n}\n"],"mappings":"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","names":["import_utils","InferenceSTT","InferenceLLM","InferenceTTS","oldTask","agent","otelContext","error"]}
@@ -34,6 +34,7 @@ export interface VoiceOptions {
34
34
  maxToolSteps: number;
35
35
  preemptiveGeneration: boolean;
36
36
  userAwayTimeout?: number | null;
37
+ aecWarmupDuration: number | null;
37
38
  useTtsAlignedTranscript: boolean;
38
39
  }
39
40
  export type TurnDetectionMode = 'stt' | 'vad' | 'realtime_llm' | 'manual' | _TurnDetector;
@@ -89,6 +90,7 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
89
90
  private _output;
90
91
  private closingTask;
91
92
  private userAwayTimer;
93
+ private _aecWarmupTimer;
92
94
  private _connOptions;
93
95
  private llmErrorCounts;
94
96
  private ttsErrorCounts;
@@ -96,6 +98,8 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
96
98
  private userSpeakingSpan?;
97
99
  private agentSpeakingSpan?;
98
100
  /** @internal */
101
+ _aecWarmupRemaining: number;
102
+ /** @internal */
99
103
  _recorderIO?: RecorderIO;
100
104
  /** @internal */
101
105
  rootSpanContext?: Context;
@@ -196,6 +200,8 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
196
200
  private onTextOutputChanged;
197
201
  private _setUserAwayTimer;
198
202
  private _cancelUserAwayTimer;
203
+ /** @internal */
204
+ _onAecWarmupExpired(): void;
199
205
  private _onUserInputTranscribed;
200
206
  private closeImpl;
201
207
  private closeImplInner;
@@ -34,6 +34,7 @@ export interface VoiceOptions {
34
34
  maxToolSteps: number;
35
35
  preemptiveGeneration: boolean;
36
36
  userAwayTimeout?: number | null;
37
+ aecWarmupDuration: number | null;
37
38
  useTtsAlignedTranscript: boolean;
38
39
  }
39
40
  export type TurnDetectionMode = 'stt' | 'vad' | 'realtime_llm' | 'manual' | _TurnDetector;
@@ -89,6 +90,7 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
89
90
  private _output;
90
91
  private closingTask;
91
92
  private userAwayTimer;
93
+ private _aecWarmupTimer;
92
94
  private _connOptions;
93
95
  private llmErrorCounts;
94
96
  private ttsErrorCounts;
@@ -96,6 +98,8 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
96
98
  private userSpeakingSpan?;
97
99
  private agentSpeakingSpan?;
98
100
  /** @internal */
101
+ _aecWarmupRemaining: number;
102
+ /** @internal */
99
103
  _recorderIO?: RecorderIO;
100
104
  /** @internal */
101
105
  rootSpanContext?: Context;
@@ -196,6 +200,8 @@ export declare class AgentSession<UserData = UnknownUserData> extends AgentSessi
196
200
  private onTextOutputChanged;
197
201
  private _setUserAwayTimer;
198
202
  private _cancelUserAwayTimer;
203
+ /** @internal */
204
+ _onAecWarmupExpired(): void;
199
205
  private _onUserInputTranscribed;
200
206
  private closeImpl;
201
207
  private closeImplInner;
@@ -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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"}
@@ -39,6 +39,7 @@ const defaultVoiceOptions = {
39
39
  maxToolSteps: 3,
40
40
  preemptiveGeneration: false,
41
41
  userAwayTimeout: 15,
42
+ aecWarmupDuration: 3e3,
42
43
  useTtsAlignedTranscript: true
43
44
  };
44
45
  class AgentSession extends EventEmitter {
@@ -65,6 +66,7 @@ class AgentSession extends EventEmitter {
65
66
  _output;
66
67
  closingTask = null;
67
68
  userAwayTimer = null;
69
+ _aecWarmupTimer = null;
68
70
  // Connection options for STT, LLM, and TTS
69
71
  _connOptions;
70
72
  // Unrecoverable error counts, reset after agent speaking
@@ -74,6 +76,8 @@ class AgentSession extends EventEmitter {
74
76
  userSpeakingSpan;
75
77
  agentSpeakingSpan;
76
78
  /** @internal */
79
+ _aecWarmupRemaining = 0;
80
+ /** @internal */
77
81
  _recorderIO;
78
82
  /** @internal */
79
83
  rootSpanContext;
@@ -125,6 +129,7 @@ class AgentSession extends EventEmitter {
125
129
  this._output = new AgentOutput(this.onAudioOutputChanged, this.onTextOutputChanged);
126
130
  this._chatCtx = ChatContext.empty();
127
131
  this.options = { ...defaultVoiceOptions, ...voiceOptions };
132
+ this._aecWarmupRemaining = this.options.aecWarmupDuration ?? 0;
128
133
  this._onUserInputTranscribed = this._onUserInputTranscribed.bind(this);
129
134
  this.on(AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);
130
135
  }
@@ -517,7 +522,9 @@ class AgentSession extends EventEmitter {
517
522
  if (this.closingTask) {
518
523
  return;
519
524
  }
520
- this.closeImpl(reason, error, drain);
525
+ this.closingTask = this.closeImpl(reason, error, drain).finally(() => {
526
+ this.closingTask = null;
527
+ });
521
528
  }
522
529
  /** @internal */
523
530
  _onError(error) {
@@ -575,6 +582,13 @@ class AgentSession extends EventEmitter {
575
582
  this.agentSpeakingSpan.end();
576
583
  this.agentSpeakingSpan = void 0;
577
584
  }
585
+ if (state === "speaking" && this._aecWarmupRemaining > 0 && this._aecWarmupTimer === null) {
586
+ this._aecWarmupTimer = setTimeout(() => this._onAecWarmupExpired(), this._aecWarmupRemaining);
587
+ this.logger.debug(
588
+ { warmupDurationMs: this._aecWarmupRemaining },
589
+ "aec warmup active, disabling interruptions"
590
+ );
591
+ }
578
592
  const oldState = this._agentState;
579
593
  this._agentState = state;
580
594
  if (state === "listening" && this.userState === "listening") {
@@ -651,6 +665,17 @@ class AgentSession extends EventEmitter {
651
665
  this.userAwayTimer = null;
652
666
  }
653
667
  }
668
+ /** @internal */
669
+ _onAecWarmupExpired() {
670
+ if (this._aecWarmupRemaining > 0) {
671
+ this.logger.debug("aec warmup expired, re-enabling interruptions");
672
+ }
673
+ this._aecWarmupRemaining = 0;
674
+ if (this._aecWarmupTimer !== null) {
675
+ clearTimeout(this._aecWarmupTimer);
676
+ this._aecWarmupTimer = null;
677
+ }
678
+ }
654
679
  _onUserInputTranscribed(ev) {
655
680
  if (this.userState === "away" && ev.isFinal) {
656
681
  this.logger.debug("User returned from away state due to speech input");
@@ -671,6 +696,7 @@ class AgentSession extends EventEmitter {
671
696
  return;
672
697
  }
673
698
  this._cancelUserAwayTimer();
699
+ this._onAecWarmupExpired();
674
700
  this.off(AgentSessionEventTypes.UserInputTranscribed, this._onUserInputTranscribed);
675
701
  if (this.activity) {
676
702
  if (!drain) {