{"version":3,"sources":["../../src/voice/audio_recognition_transcription_timeout.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\nimport { ChatContext } from '../llm/chat_context.js';\nimport { type SpeechEvent, SpeechEventType } from '../stt/stt.js';\nimport { Task } from '../utils.js';\nimport { type VAD, type VADEvent, VADEventType } from '../vad.js';\nimport {\n  AudioRecognition,\n  type AudioRecognitionOptions,\n  type RecognitionHooks,\n} from './audio_recognition.js';\n\ntype RecognitionInternals = {\n  sttPipeline?: { close?: () => Promise<void> };\n  vadSpeechStarted: boolean;\n  isInterruptionEnabled: boolean;\n  isAgentSpeaking: boolean;\n  transcriptBuffer: SpeechEvent[];\n  transcriptionTimeoutTimer?: ReturnType<typeof setTimeout>;\n  turnSpeechDuration: number;\n  turnTranscriptReceived: boolean;\n  userTurnStart?: number;\n  vadTask?: Task<void>;\n  onSTTEvent: (event: SpeechEvent) => Promise<void>;\n  createVadTask: (vad: VAD, signal: AbortSignal) => Promise<void>;\n  armTranscriptionTimeout: (speechDuration: number, elapsedDelay: number) => void;\n};\n\nfunction createHooks(): RecognitionHooks {\n  return {\n    onInterruption: vi.fn(),\n    onBackchannelConfirmed: vi.fn(),\n    onStartOfSpeech: vi.fn(),\n    onVADInferenceDone: vi.fn(),\n    onEndOfSpeech: vi.fn(),\n    onInterimTranscript: vi.fn(),\n    onFinalTranscript: vi.fn(),\n    onTranscriptionTimeout: vi.fn(),\n    onEndOfTurn: vi.fn(async () => false),\n    onEotPrediction: vi.fn(),\n    onAgentBackchannelOpportunity: vi.fn(),\n    onPreemptiveGeneration: vi.fn(),\n    onUserTurnExceeded: vi.fn(),\n    retrieveChatCtx: () => ChatContext.empty(),\n  };\n}\n\nfunction createRecognition(options: Partial<AudioRecognitionOptions> = {}) {\n  const hooks = createHooks();\n  const recognition = new AudioRecognition({\n    recognitionHooks: hooks,\n    turnDetectionMode: 'manual',\n    minEndpointingDelay: 0,\n    maxEndpointingDelay: 0,\n    ...options,\n  });\n  return { hooks, recognition, internals: recognition as unknown as RecognitionInternals };\n}\n\nfunction vadEvent(\n  type: VADEventType.START_OF_SPEECH | VADEventType.END_OF_SPEECH,\n  options: Partial<VADEvent> = {},\n): VADEvent {\n  return {\n    type,\n    samplesIndex: 0,\n    timestamp: Date.now(),\n    speechDuration: 1000,\n    silenceDuration: 0,\n    frames: [],\n    probability: 1,\n    inferenceDuration: 0,\n    speaking: type === VADEventType.START_OF_SPEECH,\n    rawAccumulatedSilence: 0,\n    rawAccumulatedSpeech: 0,\n    ...options,\n  };\n}\n\nasync function driveVad(internals: RecognitionInternals, events: VADEvent[]): Promise<void> {\n  const stream = {\n    updateInputStream() {},\n    detachInputStream() {},\n    close() {},\n    async *[Symbol.asyncIterator]() {\n      yield* events;\n    },\n  };\n  const vad = { stream: () => stream } as unknown as VAD;\n  await internals.createVadTask(vad, new AbortController().signal);\n}\n\nfunction transcriptEvent(type: SpeechEventType, text: string): SpeechEvent {\n  return { type, alternatives: [{ text, confidence: 1 }] };\n}\n\ndescribe('AudioRecognition transcription timeout', () => {\n  beforeEach(() => {\n    vi.useFakeTimers();\n    vi.setSystemTime(10_000);\n  });\n\n  afterEach(() => {\n    vi.clearAllTimers();\n    vi.useRealTimers();\n  });\n\n  it('held final transcript cancels the timeout', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.userTurnStart = Date.now();\n    internals.armTranscriptionTimeout(1000, 0);\n    internals.isInterruptionEnabled = true;\n    internals.isAgentSpeaking = true;\n    const event = transcriptEvent(SpeechEventType.FINAL_TRANSCRIPT, 'held transcript');\n\n    await internals.onSTTEvent(event);\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(internals.transcriptionTimeoutTimer).toBeUndefined();\n    expect(internals.turnTranscriptReceived).toBe(true);\n    expect(internals.transcriptBuffer).toEqual([event]);\n    expect(hooks.onFinalTranscript).not.toHaveBeenCalled();\n    expect(hooks.onTranscriptionTimeout).not.toHaveBeenCalled();\n  });\n\n  it('preflight transcript does not cancel the timeout', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.userTurnStart = Date.now();\n    internals.armTranscriptionTimeout(1000, 0);\n\n    await internals.onSTTEvent(\n      transcriptEvent(SpeechEventType.PREFLIGHT_TRANSCRIPT, 'preflight transcript'),\n    );\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(internals.turnTranscriptReceived).toBe(false);\n    expect(hooks.onTranscriptionTimeout).toHaveBeenCalledOnce();\n  });\n\n  it('accounts for VAD endpointing delay', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH, { silenceDuration: 500, inferenceDuration: 250 }),\n    ]);\n\n    await vi.advanceTimersByTimeAsync(1249);\n    expect(hooks.onTranscriptionTimeout).not.toHaveBeenCalled();\n    await vi.advanceTimersByTimeAsync(1);\n    expect(hooks.onTranscriptionTimeout).toHaveBeenCalledOnce();\n  });\n\n  it('does not arm for late VAD end-of-speech after a committed turn', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    internals.vadSpeechStarted = false;\n\n    await driveVad(internals, [vadEvent(VADEventType.END_OF_SPEECH)]);\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(internals.transcriptionTimeoutTimer).toBeUndefined();\n    expect(hooks.onTranscriptionTimeout).not.toHaveBeenCalled();\n  });\n\n  it('clearUserTurn resets the timeout state', () => {\n    const { recognition, internals } = createRecognition({ transcriptionTimeout: 1000 });\n    internals.userTurnStart = Date.now();\n    internals.turnSpeechDuration = 2000;\n    internals.turnTranscriptReceived = true;\n    internals.transcriptionTimeoutTimer = setTimeout(() => {}, 60_000);\n\n    recognition.clearUserTurn();\n\n    expect(internals.transcriptionTimeoutTimer).toBeUndefined();\n    expect(internals.turnSpeechDuration).toBe(0);\n    expect(internals.turnTranscriptReceived).toBe(false);\n    expect(internals.userTurnStart).toBeUndefined();\n    internals.userTurnStart = Date.now();\n    internals.armTranscriptionTimeout(1000, 0);\n    expect(internals.transcriptionTimeoutTimer).toBeDefined();\n  });\n\n  it('fires when VAD speech is not transcribed', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH, { speechDuration: 2000 }),\n    ]);\n\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(hooks.onTranscriptionTimeout).toHaveBeenCalledWith(2000, 9000);\n  });\n\n  it('does not fire when a final transcript arrives', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n    await internals.onSTTEvent(transcriptEvent(SpeechEventType.FINAL_TRANSCRIPT, 'hello'));\n\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(hooks.onTranscriptionTimeout).not.toHaveBeenCalled();\n  });\n\n  it('fires when only an interim transcript arrives', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n    await internals.onSTTEvent(transcriptEvent(SpeechEventType.INTERIM_TRANSCRIPT, 'hello'));\n\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(hooks.onTranscriptionTimeout).toHaveBeenCalledOnce();\n  });\n\n  it('is disabled by default', async () => {\n    const { hooks, internals } = createRecognition();\n    internals.sttPipeline = {};\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n\n    await vi.advanceTimersByTimeAsync(10_000);\n\n    expect(hooks.onTranscriptionTimeout).not.toHaveBeenCalled();\n  });\n\n  it('fires while the agent is speaking', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    internals.isAgentSpeaking = true;\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(hooks.onTranscriptionTimeout).toHaveBeenCalledOnce();\n  });\n\n  it('does not fire without STT', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(hooks.onTranscriptionTimeout).not.toHaveBeenCalled();\n  });\n\n  it('accumulates speech across bursts', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n    await vi.advanceTimersByTimeAsync(500);\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(hooks.onTranscriptionTimeout).toHaveBeenCalledWith(2000, 9000);\n  });\n\n  it('refires on the next attempt in the same uncommitted turn', async () => {\n    const { hooks, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {};\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n    await vi.advanceTimersByTimeAsync(2000);\n    await driveVad(internals, [\n      vadEvent(VADEventType.START_OF_SPEECH),\n      vadEvent(VADEventType.END_OF_SPEECH),\n    ]);\n    await vi.advanceTimersByTimeAsync(2000);\n\n    expect(hooks.onTranscriptionTimeout).toHaveBeenNthCalledWith(1, 1000, 9000);\n    expect(hooks.onTranscriptionTimeout).toHaveBeenNthCalledWith(2, 2000, 9000);\n  });\n\n  it('does not re-arm for a buffered end-of-speech delivered during close', async () => {\n    // `close()` only aborts the VAD consumer partway through its teardown, so an\n    // END_OF_SPEECH buffered before the abort is still processed while\n    // `sttPipeline` is set — python cancels the timeout at the very end of\n    // `_aclose()` for exactly this reason.\n    let releaseEndOfSpeech!: () => void;\n    const endOfSpeechGate = new Promise<void>((resolve) => {\n      releaseEndOfSpeech = resolve;\n    });\n    const stream = {\n      updateInputStream() {},\n      detachInputStream() {},\n      close() {},\n      async *[Symbol.asyncIterator]() {\n        yield vadEvent(VADEventType.START_OF_SPEECH);\n        await endOfSpeechGate;\n        // A silence duration at or beyond the timeout collapses the remaining\n        // delay to 0, so the callback lands on the very next macrotask.\n        yield vadEvent(VADEventType.END_OF_SPEECH, { silenceDuration: 2000 });\n      },\n    };\n    const vad = { stream: () => stream } as unknown as VAD;\n\n    const { hooks, recognition, internals } = createRecognition({ transcriptionTimeout: 2000 });\n    internals.sttPipeline = {\n      // `close()` awaits this before it aborts the VAD task and before it clears\n      // `sttPipeline`, which is precisely the window the buffered event lands in.\n      close: async () => {\n        releaseEndOfSpeech();\n        await vi.advanceTimersByTimeAsync(0);\n      },\n    };\n    internals.vadTask = Task.from(({ signal }) => internals.createVadTask(vad, signal));\n    await vi.advanceTimersByTimeAsync(0);\n    expect(internals.userTurnStart).toBeDefined();\n\n    await recognition.close();\n\n    expect(hooks.onTranscriptionTimeout).not.toHaveBeenCalled();\n    expect(internals.transcriptionTimeoutTimer).toBeUndefined();\n  });\n});\n"],"mappings":"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","names":[]}