{"version":3,"sources":["../../src/voice/agent.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { AudioFrame } from '@livekit/rtc-node';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { 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 { type Instructions, ReadonlyChatContext } from '../llm/chat_context.js';\nimport { DuplexModel, type DuplexSession } from '../llm/duplex.js';\nimport { DuplexRealtimeAdapter, DuplexRealtimeSession } from '../llm/duplex_adapter.js';\nimport type { ChatMessage, FunctionCall } from '../llm/index.js';\nimport {\n  type ChatChunk,\n  ChatContext,\n  LLM,\n  RealtimeModel,\n  type ToolChoice,\n  ToolContext,\n  type ToolContextLike,\n  ToolError,\n  toToolContext,\n} from '../llm/index.js';\nimport { log } from '../log.js';\nimport type { STT, SpeechEvent } from '../stt/index.js';\nimport { StreamAdapter as STTStreamAdapter } from '../stt/index.js';\nimport { SentenceTokenizer as BasicSentenceTokenizer } from '../tokenize/basic/index.js';\nimport type { TTS } from '../tts/index.js';\nimport { SynthesizeStream, StreamAdapter as TTSStreamAdapter } from '../tts/index.js';\nimport { type FlushSentinel, USERDATA_TIMED_TRANSCRIPT } from '../types.js';\nimport { Event, Future, Task, toStream } from '../utils.js';\nimport type { VAD } from '../vad.js';\nimport { type AgentActivity, agentActivityStorage } from './agent_activity.js';\nimport type { AgentSession, ExpressiveOptions, TurnDetectionMode } from './agent_session.js';\nimport {\n  type AgentCreateOptions,\n  type AgentTaskCreateOptions,\n  createAgentTaskV2,\n  createAgentV2,\n} from './agent_v2.js';\nimport type { UserTurnExceededEvent } from './events.js';\nimport type { TimedString } from './io.js';\nimport type { SpeechHandle } from './speech_handle.js';\nimport type { ToolHandlingOptions } from './tool_executor.js';\nimport type { TurnHandlingOptions } from './turn_config/turn_handling.js';\nimport { migrateTurnHandling } from './turn_config/utils.js';\n\nexport type {\n  AgentContext,\n  AgentCreateOptions,\n  AgentHookNodeResult,\n  AgentHooks,\n  AgentTaskContext,\n  AgentTaskCreateOptions,\n} from './agent_v2.js';\n\n// speechHandle identifies which SpeechHandle owns the current tool call, enabling\n// SpeechHandle.waitForPlayout() to distinguish self-wait (deadlock) from waiting\n// on a different handle scheduled inside the tool.\nexport const functionCallStorage = new AsyncLocalStorage<{\n  functionCall?: FunctionCall;\n  speechHandle?: SpeechHandle;\n}>();\nexport const speechHandleStorage = new AsyncLocalStorage<SpeechHandle>();\nconst activityTaskInfoStorage = new WeakMap<Task<any>, _ActivityTaskInfo>();\n\ntype _ActivityTaskInfo = {\n  functionCall: FunctionCall | null;\n  speechHandle: SpeechHandle | null;\n  inlineTask: boolean;\n};\n\n/** @internal */\nexport function _setActivityTaskInfo<T>(\n  task: Task<T>,\n  options: {\n    functionCall?: FunctionCall | null;\n    speechHandle?: SpeechHandle | null;\n    inlineTask?: boolean;\n  },\n): void {\n  const info = activityTaskInfoStorage.get(task) ?? {\n    functionCall: null,\n    speechHandle: null,\n    inlineTask: false,\n  };\n\n  if (Object.hasOwn(options, 'functionCall')) {\n    info.functionCall = options.functionCall ?? null;\n  }\n  if (Object.hasOwn(options, 'speechHandle')) {\n    info.speechHandle = options.speechHandle ?? null;\n  }\n  if (Object.hasOwn(options, 'inlineTask')) {\n    info.inlineTask = options.inlineTask ?? false;\n  }\n\n  activityTaskInfoStorage.set(task, info);\n}\n\n/** @internal */\nexport function _getActivityTaskInfo<T>(task: Task<T>): _ActivityTaskInfo | undefined {\n  return activityTaskInfoStorage.get(task);\n}\nexport const STOP_RESPONSE_SYMBOL = Symbol('StopResponse');\n\nexport class StopResponse extends Error {\n  constructor() {\n    super();\n    this.name = 'StopResponse';\n\n    Object.defineProperty(this, STOP_RESPONSE_SYMBOL, {\n      value: true,\n    });\n  }\n}\n\nexport function isStopResponse(value: unknown): value is StopResponse {\n  return (\n    value !== undefined &&\n    value !== null &&\n    typeof value === 'object' &&\n    STOP_RESPONSE_SYMBOL in value\n  );\n}\n\nexport interface ModelSettings {\n  /** The tool choice to use when calling the LLM. */\n  toolChoice?: ToolChoice;\n}\n\n/**\n * Fields to change on an {@link Agent}, passed to {@link Agent.updateOptions}.\n *\n * Only the fields you pass are changed. Omitting a field and passing it as `undefined` mean\n * the same thing — leave the agent's current value alone — matching `is_given()` /\n * `NOT_GIVEN` in the Python framework. Pass `null` to disable a model on this agent, which\n * also overrides any session-level model.\n */\nexport interface AgentUpdateOptions {\n  /** New STT model. Pass `null` to disable the agent STT and override any session STT. */\n  stt?: STT | STTModelString | null;\n  /** New VAD model. Pass `null` to disable the agent VAD and override any session VAD. */\n  vad?: VAD | null;\n  /**\n   * New LLM model. Pass `null` to disable the agent LLM and override any session LLM.\n   *\n   * A {@link RealtimeModel} or {@link DuplexModel} can only be set while the agent is stopped.\n   * Swapping to or from one while running throws because it replaces the whole pipeline.\n   * Use `AgentSession.updateAgent()` for that.\n   */\n  llm?: LLM | RealtimeModel | DuplexModel | LLMModels | null;\n  /** New TTS model. Pass `null` to disable the agent TTS and override any session TTS. */\n  tts?: TTS | TTSModelString | null;\n  /** Expressive TTS delivery. Pass `false` to override and disable the session setting. */\n  expressive?: boolean | ExpressiveOptions;\n}\n\nexport interface AgentOptions<UserData> {\n  id?: string;\n  instructions: string | Instructions;\n  chatCtx?: ChatContext;\n  tools?: ToolContextLike<UserData>;\n  stt?: STT | STTModelString | null;\n  vad?: VAD | null;\n  llm?: LLM | RealtimeModel | DuplexModel | LLMModels | null;\n  tts?: TTS | TTSModelString | null;\n  /** Expressive TTS delivery. When set, overrides the session value for this agent. */\n  expressive?: boolean | ExpressiveOptions;\n  turnHandling?: TurnHandlingOptions;\n  toolHandling?: ToolHandlingOptions;\n  minConsecutiveSpeechDelay?: number;\n  useTtsAlignedTranscript?: boolean;\n  /** @deprecated use turnHandling.turnDetection instead */\n  turnDetection?: TurnDetectionMode;\n  /** @deprecated use turnHandling.interruption.enabled instead */\n  allowInterruptions?: boolean;\n}\n\nexport class Agent<UserData = any> {\n  private _id: string;\n  /** @internal */\n  _stt?: STT | null;\n  /** @internal */\n  _vad?: VAD | null;\n  /** @internal */\n  _llm?: LLM | RealtimeModel | null;\n  /** @internal */\n  _tts?: TTS | null;\n  /** @internal */\n  _expressive?: boolean | ExpressiveOptions;\n  private _turnHandling?: Partial<TurnHandlingOptions>;\n\n  private _minConsecutiveSpeechDelay?: number;\n  private _useTtsAlignedTranscript?: boolean;\n\n  /** @internal */\n  _agentActivity?: AgentActivity;\n\n  /** @internal */\n  _chatCtx: ChatContext;\n\n  /** @internal */\n  _instructions: string | Instructions;\n\n  /** @internal */\n  _toolCtx: ToolContext<UserData>;\n\n  /** @internal */\n  _asyncToolOptions?: ToolHandlingOptions['asyncOptions'];\n\n  static create<UserData = unknown>(options: AgentCreateOptions<UserData>): Agent<UserData> {\n    return createAgentV2(Agent, options);\n  }\n\n  constructor({\n    id,\n    instructions,\n    chatCtx,\n    tools,\n    turnDetection,\n    stt,\n    vad,\n    llm,\n    tts,\n    expressive,\n    allowInterruptions,\n    turnHandling,\n    toolHandling,\n    minConsecutiveSpeechDelay,\n    useTtsAlignedTranscript,\n  }: AgentOptions<UserData>) {\n    if (id) {\n      this._id = id;\n    } else {\n      const className = this.constructor.name;\n      if (className === 'Agent') {\n        this._id = 'default_agent';\n      } else {\n        this._id = className\n          .replace(/([A-Z])/g, '_$1')\n          .toLowerCase()\n          .replace(/^_/, '');\n      }\n    }\n\n    this._instructions = instructions;\n    this._toolCtx = toToolContext(tools) ?? ToolContext.empty<UserData>();\n    this._chatCtx = chatCtx\n      ? chatCtx.copy({\n          toolCtx: this._toolCtx,\n        })\n      : ChatContext.empty();\n\n    const resolvedTurnHandling = migrateTurnHandling({\n      turnDetection,\n      allowInterruptions,\n      turnHandling,\n    });\n    this._turnHandling =\n      Object.keys(resolvedTurnHandling).length > 0 ? resolvedTurnHandling : undefined;\n    this._asyncToolOptions = toolHandling?.asyncOptions;\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 if (llm instanceof DuplexModel) {\n      this._llm = new DuplexRealtimeAdapter(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._minConsecutiveSpeechDelay = minConsecutiveSpeechDelay;\n    this._useTtsAlignedTranscript = useTtsAlignedTranscript;\n    this._expressive = expressive;\n\n    this._agentActivity = undefined;\n  }\n\n  get vad(): VAD | undefined {\n    return this._vad ?? undefined;\n  }\n\n  get stt(): STT | undefined {\n    return this._stt ?? undefined;\n  }\n\n  get llm(): LLM | RealtimeModel | undefined {\n    return this._llm ?? undefined;\n  }\n\n  /** The running duplex provider session, for provider-specific APIs. */\n  get duplexSession(): DuplexSession {\n    const session = this.getActivityOrThrow().realtimeLLMSession;\n    if (!(session instanceof DuplexRealtimeSession)) {\n      throw new Error('no duplex session, this agent is not running a DuplexModel');\n    }\n    return session.duplexSession;\n  }\n\n  get tts(): TTS | undefined {\n    return this._tts ?? undefined;\n  }\n\n  /** Expressive TTS delivery for this agent, or `undefined` to use the session value. */\n  get expressive(): boolean | ExpressiveOptions | undefined {\n    return this._expressive;\n  }\n\n  get useTtsAlignedTranscript(): boolean | undefined {\n    return this._useTtsAlignedTranscript;\n  }\n\n  get chatCtx(): ReadonlyChatContext {\n    return new ReadonlyChatContext(this._chatCtx.items);\n  }\n\n  get id(): string {\n    return this._id;\n  }\n\n  get instructions(): string | Instructions {\n    return this._instructions;\n  }\n\n  get toolCtx(): ToolContext<UserData> {\n    return this._toolCtx.copy();\n  }\n\n  get session(): AgentSession<UserData> {\n    return this.getActivityOrThrow().agentSession as AgentSession<UserData>;\n  }\n\n  get turnHandling(): Partial<TurnHandlingOptions> | undefined {\n    return this._turnHandling;\n  }\n\n  get minConsecutiveSpeechDelay(): number | undefined {\n    return this._minConsecutiveSpeechDelay;\n  }\n\n  async onEnter(): Promise<void> {}\n\n  async onExit(): Promise<void> {}\n\n  async transcriptionNode(\n    text: ReadableStream<string | TimedString> | AsyncIterable<string | TimedString>,\n    modelSettings: ModelSettings,\n  ): Promise<ReadableStream<string | TimedString> | null> {\n    return Agent.default.transcriptionNode(this, text, modelSettings);\n  }\n\n  async onUserTurnCompleted(_chatCtx: ChatContext, _newMessage: ChatMessage): Promise<void> {}\n\n  async onUserTurnExceeded(ev: UserTurnExceededEvent): Promise<void> {\n    await this.session.generateReply({\n      userInput: ev.transcript,\n      instructions:\n        'The user has been speaking too long without giving a chance to reply. ' +\n        'Politely cut in with a short reply or notice. Keep it short since the user cannot interrupt it.',\n      allowInterruptions: false,\n      toolChoice: 'none',\n      inputModality: 'audio',\n    });\n  }\n\n  async sttNode(\n    audio: ReadableStream<AudioFrame> | AsyncIterable<AudioFrame>,\n    modelSettings: ModelSettings,\n  ): Promise<ReadableStream<SpeechEvent | string> | null> {\n    return Agent.default.sttNode(this, audio, modelSettings);\n  }\n\n  async llmNode(\n    chatCtx: ChatContext,\n    toolCtx: ToolContext,\n    modelSettings: ModelSettings,\n  ): Promise<ReadableStream<ChatChunk | string | FlushSentinel> | null> {\n    return Agent.default.llmNode(this, chatCtx, toolCtx, modelSettings);\n  }\n\n  async ttsNode(\n    text: ReadableStream<string> | AsyncIterable<string>,\n    modelSettings: ModelSettings,\n  ): Promise<ReadableStream<AudioFrame> | null> {\n    return Agent.default.ttsNode(this, text, modelSettings);\n  }\n\n  async realtimeAudioOutputNode(\n    audio: ReadableStream<AudioFrame> | AsyncIterable<AudioFrame>,\n    modelSettings: ModelSettings,\n  ): Promise<ReadableStream<AudioFrame> | null> {\n    return Agent.default.realtimeAudioOutputNode(this, audio, modelSettings);\n  }\n\n  // realtime_audio_output_node\n\n  getActivityOrThrow(): AgentActivity {\n    if (!this._agentActivity) {\n      throw new Error('Agent activity not found');\n    }\n    return this._agentActivity;\n  }\n\n  async updateChatCtx(chatCtx: ChatContext): Promise<void> {\n    if (!this._agentActivity) {\n      this._chatCtx = chatCtx.copy({ toolCtx: this.toolCtx });\n      return;\n    }\n\n    await this._agentActivity.updateChatCtx(chatCtx);\n  }\n\n  async updateInstructions(instructions: string | Instructions): Promise<void> {\n    if (!this._agentActivity) {\n      this._instructions = instructions;\n      return;\n    }\n\n    await this._agentActivity.updateInstructions(instructions);\n  }\n\n  async updateOptions(options: AgentUpdateOptions = {}): Promise<void> {\n    const resolved: AgentUpdateOptions = { ...options };\n    if (typeof resolved.stt === 'string') {\n      resolved.stt = InferenceSTT.fromModelString(resolved.stt);\n    }\n    if (typeof resolved.llm === 'string') {\n      resolved.llm = InferenceLLM.fromModelString(resolved.llm);\n    } else if (resolved.llm instanceof DuplexModel) {\n      resolved.llm = new DuplexRealtimeAdapter(resolved.llm);\n    }\n    if (typeof resolved.tts === 'string') {\n      resolved.tts = InferenceTTS.fromModelString(resolved.tts);\n    }\n\n    if (!this._agentActivity) {\n      if (resolved.stt !== undefined) this._stt = resolved.stt as STT | null;\n      if (resolved.vad !== undefined) this._vad = resolved.vad as VAD | null;\n      if (resolved.llm !== undefined) {\n        this._llm = resolved.llm as LLM | RealtimeModel | null;\n      }\n      if (resolved.tts !== undefined) this._tts = resolved.tts as TTS | null;\n      if (resolved.expressive !== undefined) this._expressive = resolved.expressive;\n      return;\n    }\n\n    await this._agentActivity.updateModels(resolved);\n    if (resolved.expressive !== undefined) this._expressive = resolved.expressive;\n  }\n\n  // TODO(parity): Add when AgentConfigUpdate is ported to ChatContext.\n  async updateTools(tools: ToolContextLike<UserData>): Promise<void> {\n    if (!this._agentActivity) {\n      this._toolCtx = toToolContext(tools);\n      this._chatCtx = this._chatCtx.copy({ toolCtx: this._toolCtx });\n      return;\n    }\n\n    await this._agentActivity.updateTools(tools);\n  }\n\n  static default = {\n    async sttNode(\n      agent: Agent,\n      audio: ReadableStream<AudioFrame> | AsyncIterable<AudioFrame>,\n      _modelSettings: ModelSettings,\n    ): Promise<ReadableStream<SpeechEvent | string> | null> {\n      const input = audio instanceof ReadableStream ? audio : toStream(audio);\n      const activity = agent.getActivityOrThrow();\n      if (!activity.stt) {\n        throw new Error('sttNode called but no STT node is available');\n      }\n\n      let wrappedStt = activity.stt;\n\n      if (!wrappedStt.capabilities.streaming) {\n        const vad = agent.vad || activity.vad;\n        if (!vad) {\n          throw new Error(\n            'STT does not support streaming, add a VAD to the AgentTask/VoiceAgent to enable streaming',\n          );\n        }\n        wrappedStt = new STTStreamAdapter(wrappedStt, vad);\n      }\n\n      const connOptions = activity.agentSession.connOptions.sttConnOptions;\n      const stream = wrappedStt.stream({ connOptions });\n\n      // Set startTimeOffset to provide linear timestamps across reconnections\n      const audioInputStartedAt =\n        activity.inputStartedAt ?? // Use input started at proxied from AudioRecognition if available\n        activity.agentSession._recorderIO?.recordingStartedAt ?? // Fallback to recording start time if available\n        activity.agentSession._startedAt ?? // Fallback to session start time\n        Date.now(); // Fallback to current time\n\n      stream.startTimeOffset = (Date.now() - audioInputStartedAt) / 1000;\n\n      stream.updateInputStream(input);\n\n      let cleaned = false;\n      const cleanup = () => {\n        if (cleaned) return;\n        cleaned = true;\n        stream.detachInputStream();\n        stream.close();\n      };\n\n      return new ReadableStream({\n        async start(controller) {\n          try {\n            for await (const event of stream) {\n              controller.enqueue(event);\n            }\n            controller.close();\n          } finally {\n            // Always clean up the STT stream, whether it ends naturally or is cancelled\n            cleanup();\n          }\n        },\n        cancel() {\n          cleanup();\n        },\n      });\n    },\n\n    async llmNode(\n      agent: Agent,\n      chatCtx: ChatContext,\n      toolCtx: ToolContext,\n      modelSettings: ModelSettings,\n    ): Promise<ReadableStream<ChatChunk | string> | null> {\n      const activity = agent.getActivityOrThrow();\n      if (!activity.llm) {\n        throw new Error('llmNode called but no LLM node is available');\n      }\n\n      if (!(activity.llm instanceof LLM)) {\n        throw new Error(\n          'llmNode should only be used with LLM (non-multimodal/realtime APIs) nodes',\n        );\n      }\n\n      const { toolChoice } = modelSettings;\n      const connOptions = activity.agentSession.connOptions.llmConnOptions;\n\n      // parallelToolCalls is not passed here - it will use the value from LLM's modelOptions\n      // This allows users to configure it via: new inference.LLM({ modelOptions: { parallel_tool_calls: false } })\n      const stream = activity.llm.chat({\n        chatCtx,\n        toolCtx,\n        toolChoice,\n        connOptions,\n      });\n\n      let cleaned = false;\n      const cleanup = () => {\n        if (cleaned) return;\n        cleaned = true;\n        stream.close();\n      };\n\n      return new ReadableStream({\n        async start(controller) {\n          try {\n            for await (const chunk of stream) {\n              controller.enqueue(chunk);\n            }\n            controller.close();\n          } finally {\n            cleanup();\n          }\n        },\n        cancel() {\n          cleanup();\n        },\n      });\n    },\n\n    async ttsNode(\n      agent: Agent,\n      text: ReadableStream<string> | AsyncIterable<string>,\n      _modelSettings: ModelSettings,\n    ): Promise<ReadableStream<AudioFrame> | null> {\n      const input = text instanceof ReadableStream ? text : toStream(text);\n      const activity = agent.getActivityOrThrow();\n      if (!activity.tts) {\n        throw new Error('ttsNode called but no TTS node is available');\n      }\n\n      const expressiveActive = activity._resolveExpressiveOptions() !== undefined;\n      let wrappedTts = activity.tts;\n\n      if (!activity.tts.capabilities.streaming) {\n        wrappedTts = new TTSStreamAdapter(\n          wrappedTts,\n          // markup only exists in the stream when expressive is active. Python also\n          // passes retain_format here, but that predates expressive mode and is a\n          // separate gap — turning it on would change tokenization for every\n          // non-streaming TTS plugin, none of which can be expressive today.\n          new BasicSentenceTokenizer({ xmlAware: expressiveActive }),\n        );\n      }\n\n      // Mark whether expressive is active for this synthesis, synchronously just before\n      // stream() snapshots it. Doing it here (the single synthesis choke point for both\n      // generateReply and say()) scopes it to this turn rather than leaving stale state on\n      // the instance. The provider's chunk defaults then drive the TTS's input tokenizer.\n      activity.tts._setExpressive(expressiveActive);\n\n      const connOptions = activity.agentSession.connOptions.ttsConnOptions;\n      const stream = wrappedTts.stream({ connOptions });\n      stream.updateInputStream(input);\n\n      let cleaned = false;\n      const cleanup = async () => {\n        if (cleaned) return;\n        cleaned = true;\n        stream.close();\n        await input.cancel('tts node cleanup').catch(() => {});\n        if (wrappedTts !== activity.tts) {\n          await wrappedTts.close();\n        }\n      };\n\n      return new ReadableStream({\n        async start(controller) {\n          try {\n            for await (const chunk of stream) {\n              if (chunk === SynthesizeStream.END_OF_STREAM) {\n                break;\n              }\n              // Attach timed transcripts to frame.userdata\n              if (chunk.timedTranscripts && chunk.timedTranscripts.length > 0) {\n                chunk.frame.userdata[USERDATA_TIMED_TRANSCRIPT] = chunk.timedTranscripts;\n              }\n              controller.enqueue(chunk.frame);\n            }\n            controller.close();\n          } finally {\n            await cleanup();\n          }\n        },\n        cancel() {\n          return cleanup();\n        },\n      });\n    },\n\n    async transcriptionNode(\n      agent: Agent,\n      text: ReadableStream<string | TimedString> | AsyncIterable<string | TimedString>,\n      _modelSettings: ModelSettings,\n    ): Promise<ReadableStream<string | TimedString> | null> {\n      return text instanceof ReadableStream ? text : toStream(text);\n    },\n\n    async realtimeAudioOutputNode(\n      _agent: Agent,\n      audio: ReadableStream<AudioFrame> | AsyncIterable<AudioFrame>,\n      _modelSettings: ModelSettings,\n    ): Promise<ReadableStream<AudioFrame> | null> {\n      return audio instanceof ReadableStream ? audio : toStream(audio);\n    },\n  };\n}\n\nexport interface AgentTaskOptions<UserData = any> extends AgentOptions<UserData> {\n  preserveFunctionCallHistory?: boolean;\n}\n\nexport class AgentTask<ResultT = unknown, UserData = any> extends Agent<UserData> {\n  private started = false;\n  private future = new Future<ResultT>();\n  private readonly inactive = new Event();\n  private _preserveFunctionCallHistory: boolean;\n\n  /** @internal */\n  _oldAgent?: Agent;\n\n  #logger = log();\n\n  static create<ResultT = unknown, UserData = unknown>(\n    options: AgentTaskCreateOptions<ResultT, UserData>,\n  ): AgentTask<ResultT, UserData> {\n    return createAgentTaskV2<ResultT, UserData>(AgentTask, options);\n  }\n\n  constructor(options: AgentTaskOptions<UserData>) {\n    const { preserveFunctionCallHistory = false, ...rest } = options;\n    super(rest);\n    this._preserveFunctionCallHistory = preserveFunctionCallHistory;\n    this.inactive.set();\n  }\n\n  get done(): boolean {\n    return this.future.done;\n  }\n\n  /** @internal */\n  async _waitForInactive(): Promise<void> {\n    await this.inactive.wait();\n  }\n\n  complete(result: ResultT | Error): void {\n    if (this.future.done) {\n      throw new Error(`${this.constructor.name} is already done`);\n    }\n\n    if (result instanceof Error) {\n      this.future.reject(result);\n    } else {\n      this.future.resolve(result);\n    }\n\n    const speechHandle = speechHandleStorage.getStore();\n    if (speechHandle) {\n      speechHandle._maybeRunFinalOutput = result;\n    }\n  }\n\n  async run(): Promise<ResultT> {\n    if (this.started) {\n      throw new Error(\n        `Task ${this.constructor.name} has already started and cannot be awaited multiple times`,\n      );\n    }\n    this.started = true;\n\n    const currentTask = Task.current();\n    if (!currentTask) {\n      throw new Error(`${this.constructor.name} must be executed inside a Task context`);\n    }\n\n    const taskInfo = _getActivityTaskInfo(currentTask);\n    if (!taskInfo || !taskInfo.inlineTask) {\n      throw new Error(\n        `${this.constructor.name} should only be awaited inside function tools or the onEnter/onExit methods of an Agent`,\n      );\n    }\n\n    const speechHandle = speechHandleStorage.getStore();\n    const oldActivity = agentActivityStorage.getStore();\n    if (!oldActivity) {\n      throw new Error(`${this.constructor.name} must be executed inside an AgentActivity context`);\n    }\n\n    // A non-blocking tool (one that called ctx.update) detaches from its speech\n    // task, so that task completes before a later ctx.foreground/AgentTask does.\n    // Binding the guard below to the already-finished task would fire it\n    // immediately and tear the AgentTask down; the tool's still-running promise\n    // and the foreground hold keep it alive instead.\n    const ownerIsNonBlocking =\n      taskInfo.functionCall?.extra.__livekit_agents_tool_non_blocking === true;\n    const oldAgent = oldActivity.agent;\n    this._oldAgent = oldAgent;\n    const session = oldActivity.agentSession;\n\n    const blockedTasks: Task<any>[] = [currentTask];\n    const onEnterTask = oldActivity._onEnterTask;\n\n    if (onEnterTask && !onEnterTask.done && onEnterTask !== currentTask) {\n      blockedTasks.push(onEnterTask);\n    }\n\n    this.inactive.clear();\n    try {\n      return await oldActivity._withInlineTaskSlot({\n        speechHandle,\n        blockedTasks,\n        fn: async () => {\n          if (!ownerIsNonBlocking) {\n            currentTask.addDoneCallback(() => {\n              if (this.future.done) return;\n\n              // If the Task finished before the AgentTask was completed, complete it with an error.\n              this.#logger.error(\n                `The Task finished before ${this.constructor.name} was completed.`,\n              );\n              this.complete(\n                new Error(`The Task finished before ${this.constructor.name} was completed.`),\n              );\n            });\n          }\n\n          if (\n            taskInfo.functionCall &&\n            oldActivity.llm instanceof RealtimeModel &&\n            !oldActivity.llm.capabilities.manualFunctionCalls\n          ) {\n            this.#logger.error(\n              `Realtime model does not support resuming function calls from chat context, ` +\n                `using AgentTask inside a function tool may have unexpected behavior.`,\n            );\n          }\n\n          await session._updateActivity(this, {\n            previousActivity: 'pause',\n            newActivity: 'start',\n            blockedTasks,\n            waitOnEnter: false,\n          });\n\n          if (!this._agentActivity && !this.done) {\n            this.complete(\n              new ToolError(`activity did not start for ${this.id}, likely due to session closing`),\n            );\n          }\n\n          let runState = session._globalRunState;\n          let pendingOnEnterTask: Task<void> | undefined;\n          const taskOnEnter = this._agentActivity?._onEnterTask;\n          if (taskOnEnter) {\n            if (runState && !runState.done()) {\n              // Keep the run alive until onEnter has registered any speech it creates.\n              runState._watchHandle(taskOnEnter);\n              pendingOnEnterTask = taskOnEnter;\n            } else {\n              await taskOnEnter.result;\n            }\n          }\n\n          const suspendedHandles: Array<SpeechHandle | Task<any>> = [];\n          if (runState && !runState.done()) {\n            const suspendHandle = (handle: SpeechHandle | Task<any>) => {\n              if (runState!._unwatchHandle(handle)) {\n                suspendedHandles.push(handle);\n              }\n            };\n\n            if (speechHandle) suspendHandle(speechHandle);\n            for (const blockedTask of blockedTasks) {\n              suspendHandle(blockedTask);\n            }\n            if (suspendedHandles.length > 0) {\n              runState._markDoneIfNeeded();\n            }\n          }\n\n          try {\n            return await this.future.await;\n          } finally {\n            // The active RunResult may have changed while the task waited for user input.\n            runState = session._globalRunState;\n            if (runState && !runState.done()) {\n              for (const handle of suspendedHandles) {\n                runState._watchHandle(handle);\n              }\n            }\n\n            if (pendingOnEnterTask) {\n              try {\n                await pendingOnEnterTask.result;\n              } catch (error) {\n                this.#logger.error(\n                  { error },\n                  `error in onEnter task of agent ${this.constructor.name}`,\n                );\n              }\n            }\n\n            if (session._closing && this._agentActivity === undefined) {\n              // The activity never started because close owns the previous activity.\n            } else if (session.currentAgent !== this) {\n              this.#logger.warn(\n                `${this.constructor.name} completed, but the agent has changed in the meantime. ` +\n                  `Ignoring handoff to the previous agent, likely due to AgentSession.updateAgent being invoked.`,\n              );\n              // Shutdown closes the parent after this task returns. Closing it here\n              // would wait for the tool that is currently awaiting this task.\n              if (!session._closing) await oldActivity.close();\n            } else {\n              const mergedChatCtx = oldAgent._chatCtx.merge(this._chatCtx, {\n                excludeFunctionCall: !this._preserveFunctionCallHistory,\n                excludeInstructions: true,\n              });\n              oldAgent._chatCtx.items = mergedChatCtx.items;\n\n              await session._updateActivity(oldAgent, {\n                previousActivity: 'close',\n                newActivity: 'resume',\n                waitOnEnter: false,\n              });\n            }\n          }\n        },\n      });\n    } finally {\n      this.inactive.set();\n    }\n  }\n}\n"],"mappings":"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","names":["import_utils","InferenceSTT","InferenceLLM","InferenceTTS","STTStreamAdapter","TTSStreamAdapter","BasicSentenceTokenizer","_a"]}