@livekit/agents 1.0.0-next.0 → 1.0.0-next.1
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.
- package/dist/llm/llm.cjs +1 -2
- package/dist/llm/llm.cjs.map +1 -1
- package/dist/llm/llm.d.ts.map +1 -1
- package/dist/llm/llm.js +1 -2
- package/dist/llm/llm.js.map +1 -1
- package/dist/stream/deferred_stream.test.cjs +10 -10
- package/dist/stream/deferred_stream.test.cjs.map +1 -1
- package/dist/stream/deferred_stream.test.js +1 -1
- package/dist/stream/deferred_stream.test.js.map +1 -1
- package/dist/stt/stt.cjs +1 -2
- package/dist/stt/stt.cjs.map +1 -1
- package/dist/stt/stt.d.ts.map +1 -1
- package/dist/stt/stt.js +1 -2
- package/dist/stt/stt.js.map +1 -1
- package/dist/tts/tts.cjs +2 -3
- package/dist/tts/tts.cjs.map +1 -1
- package/dist/tts/tts.d.ts.map +1 -1
- package/dist/tts/tts.js +1 -2
- package/dist/tts/tts.js.map +1 -1
- package/dist/utils.cjs +19 -2
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +11 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +17 -1
- package/dist/utils.js.map +1 -1
- package/dist/utils.test.cjs +30 -31
- package/dist/utils.test.cjs.map +1 -1
- package/dist/utils.test.js +1 -1
- package/dist/utils.test.js.map +1 -1
- package/dist/voice/audio_recognition.cjs +2 -3
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js +1 -2
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/transcription/synchronizer.cjs +1 -2
- package/dist/voice/transcription/synchronizer.cjs.map +1 -1
- package/dist/voice/transcription/synchronizer.d.ts.map +1 -1
- package/dist/voice/transcription/synchronizer.js +1 -2
- package/dist/voice/transcription/synchronizer.js.map +1 -1
- package/package.json +1 -2
- package/src/llm/llm.ts +1 -2
- package/src/stream/deferred_stream.test.ts +1 -1
- package/src/stt/stt.ts +1 -2
- package/src/tts/tts.ts +1 -2
- package/src/utils.test.ts +1 -1
- package/src/utils.ts +28 -1
- package/src/voice/audio_recognition.ts +1 -2
- package/src/voice/transcription/synchronizer.ts +1 -2
package/dist/utils.test.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport { delay } from '@std/async';\nimport { ReadableStream } from 'node:stream/web';\nimport { describe, expect, it } from 'vitest';\nimport { initializeLogger } from '../src/log.js';\nimport {\n Event,\n TASK_TIMEOUT_ERROR,\n Task,\n TaskResult,\n isPending,\n resampleStream,\n} from '../src/utils.js';\n\ndescribe('utils', () => {\n // initialize logger\n initializeLogger({ pretty: true, level: 'debug' });\n\n describe('Task', () => {\n it('should execute task successfully and return result', async () => {\n const expectedResult = 'task completed';\n const task = Task.from(async () => {\n await delay(10);\n return expectedResult;\n });\n\n expect(task.done).toBe(false);\n const result = await task.result;\n expect(result).toBe(expectedResult);\n expect(task.done).toBe(true);\n });\n\n it('should handle task errors properly', async () => {\n const expectedError = new Error('Task failed');\n const task = Task.from(async () => {\n await delay(10);\n throw expectedError;\n });\n\n expect(task.done).toBe(false);\n await expect(task.result).rejects.toThrow(expectedError);\n expect(task.done).toBe(true);\n });\n\n it('should cancel task when cancel is called', async () => {\n let taskStarted = false;\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n taskStarted = true;\n await delay(100, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Wait a bit to ensure task starts\n await delay(10);\n expect(taskStarted).toBe(true);\n expect(task.done).toBe(false);\n\n // Cancel the task\n task.cancel();\n\n // The task should reject with AbortError\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should use provided AbortController', async () => {\n const controller = new AbortController();\n const task = Task.from(async (ctrl) => {\n expect(ctrl).toBe(controller);\n await delay(100, { signal: ctrl.signal });\n return 'completed';\n }, controller);\n\n await delay(10);\n controller.abort();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate resolution', async () => {\n const task = Task.from(async () => {\n return 'immediate';\n });\n\n const result = await task.result;\n expect(result).toBe('immediate');\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate rejection', async () => {\n const expectedError = new Error('Immediate error');\n const task = Task.from(async () => {\n throw expectedError;\n });\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect(error).toBe(expectedError);\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle multiple calls to cancel', async () => {\n const task = Task.from(async (controller) => {\n await delay(100, { signal: controller.signal });\n return 'should not complete';\n });\n\n await delay(10);\n\n // Multiple cancellations should not cause issues\n task.cancel();\n task.cancel();\n task.cancel();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle task that checks abort signal manually', async () => {\n const arr: number[] = [];\n const task = Task.from(async (controller) => {\n for (let i = 0; i < 10; i++) {\n if (controller.signal.aborted) {\n throw new Error('Task was aborted');\n }\n await delay(10);\n arr.push(i);\n }\n return 'completed';\n });\n\n await delay(39);\n task.cancel();\n\n expect(arr).toEqual([0, 1, 2]);\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Task was aborted');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle cleanup in finally block', async () => {\n let cleanupExecuted = false;\n\n const task = Task.from(async (controller) => {\n try {\n await delay(100, { signal: controller.signal });\n return 'completed';\n } finally {\n cleanupExecuted = true;\n }\n });\n\n await delay(10);\n task.cancel();\n\n try {\n await task.result;\n } catch {\n // Ignore the abort error\n }\n\n // Cleanup should still execute even when cancelled\n expect(cleanupExecuted).toBe(true);\n });\n\n it('should handle accessing result multiple times', async () => {\n const task = Task.from(async () => {\n await delay(10);\n return 'result';\n });\n\n const result1 = await task.result;\n const result2 = await task.result;\n const result3 = await task.result;\n\n expect(result1).toBe('result');\n expect(result2).toBe('result');\n expect(result3).toBe('result');\n expect(task.done).toBe(true);\n });\n\n it('should handle accessing result promise before completion', async () => {\n const task = Task.from(async () => {\n await delay(50);\n return 'delayed result';\n });\n\n // Get references to result promise before completion\n const resultPromise1 = task.result;\n const resultPromise2 = task.result;\n\n expect(task.done).toBe(false);\n\n // Both promises should resolve to the same value\n const [result1, result2] = await Promise.all([resultPromise1, resultPromise2]);\n\n expect(result1).toBe('delayed result');\n expect(result2).toBe('delayed result');\n expect(task.done).toBe(true);\n });\n\n it('should cancel child tasks when parent task is canceled', async () => {\n let parentStarted = false;\n let child1Started = false;\n let child2Started = false;\n let parentCompleted = false;\n let child1Completed = false;\n let child2Completed = false;\n\n let child1Task: Task<string> | undefined = undefined;\n let child2Task: Task<string> | undefined = undefined;\n\n const parentTask = Task.from(async (controller) => {\n parentStarted = true;\n\n // Create two child tasks using the parent's controller\n child1Task = Task.from(async (childController) => {\n child1Started = true;\n await delay(100, { signal: childController.signal });\n child1Completed = true;\n return 'child1';\n }, controller);\n\n child2Task = Task.from(async (childController) => {\n child2Started = true;\n await delay(100, { signal: childController.signal });\n child2Completed = true;\n return 'child2';\n }, controller);\n\n // Wait for both child tasks\n const results = await Promise.all([child1Task.result, child2Task.result]);\n parentCompleted = true;\n return results;\n });\n\n // Let tasks start\n await delay(20);\n\n // Verify tasks have started\n expect(parentStarted).toBe(true);\n expect(child1Started).toBe(true);\n expect(child2Started).toBe(true);\n\n // Cancel parent task\n parentTask.cancel();\n\n // Use Promise.allSettled to handle all promise settlements\n const [parentResult, child1Result, child2Result] = await Promise.allSettled([\n parentTask.result,\n child1Task!.result,\n child2Task!.result,\n ]);\n\n // Verify all tasks were rejected with AbortError\n expect(parentResult.status).toBe('rejected');\n expect((parentResult as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child1Result.status).toBe('rejected');\n expect((child1Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child2Result.status).toBe('rejected');\n expect((child2Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n // Verify none of the tasks completed\n expect(parentCompleted).toBe(false);\n expect(child1Completed).toBe(false);\n expect(child2Completed).toBe(false);\n expect(parentTask.done).toBe(true);\n expect(child1Task!.done).toBe(true);\n expect(child2Task!.done).toBe(true);\n });\n\n it('should handle nested tasks that complete successfully', async () => {\n const results: string[] = [];\n\n const parentTask = Task.from(async (controller) => {\n results.push('parent-start');\n\n // Create first child task\n const child1Task = Task.from(async () => {\n results.push('child1-start');\n await delay(25);\n results.push('child1-end');\n return 'child1-result';\n }, controller);\n\n // Create second child task that depends on first\n const child2Task = Task.from(async (childController) => {\n results.push('child2-start');\n\n // Create a grandchild task\n const grandchildTask = Task.from(async () => {\n results.push('grandchild-start');\n await delay(10);\n results.push('grandchild-end');\n return 'grandchild-result';\n }, childController);\n\n const grandchildResult = await grandchildTask.result;\n await delay(10);\n results.push('child2-end');\n return `child2-result-with-${grandchildResult}`;\n }, controller);\n\n // Wait for all tasks\n const [child1Result, child2Result] = await Promise.all([\n child1Task.result,\n child2Task.result,\n ]);\n\n results.push('parent-end');\n return {\n parent: 'parent-result',\n child1: child1Result,\n child2: child2Result,\n };\n });\n\n // Wait for everything to complete\n const finalResult = await parentTask.result;\n\n // Verify results\n expect(finalResult).toEqual({\n parent: 'parent-result',\n child1: 'child1-result',\n child2: 'child2-result-with-grandchild-result',\n });\n\n // Verify execution order\n // Check important ordering constraints without being strict about parallel task ordering\n expect(results).toEqual([\n 'parent-start',\n 'child1-start',\n 'child2-start',\n 'grandchild-start',\n 'grandchild-end',\n 'child2-end',\n 'child1-end',\n 'parent-end',\n ]);\n\n // All tasks should be done\n expect(parentTask.done).toBe(true);\n });\n\n it('should propagate errors from nested tasks', async () => {\n let parentError: Error | null = null;\n let child1Completed = false;\n let child2Started = false;\n\n const parentTask = Task.from(async (controller) => {\n const child1Task = Task.from(async () => {\n await delay(20);\n throw new Error('child1 error');\n }, controller);\n\n const child2Task = Task.from(async () => {\n child2Started = true;\n await delay(30);\n child1Completed = true;\n return 'child2-result';\n }, controller);\n\n // This will throw when child1 fails\n const results = await Promise.all([child1Task.result, child2Task.result]);\n return results;\n });\n\n // Wait for the parent task to fail\n try {\n await parentTask.result;\n expect.fail('Parent task should have thrown');\n } catch (error: unknown) {\n parentError = error as Error;\n }\n\n // Verify the error propagated correctly\n expect(parentError?.message).toBe('child1 error');\n expect(child1Completed).toBe(false);\n expect(child2Started).toBe(true);\n expect(parentTask.done).toBe(true);\n });\n\n it('should cancel and wait for task completion', async () => {\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n await delay(5000, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Cancel and wait should complete quickly when task is aborted\n const start = Date.now();\n const result = await task.cancelAndWait(1000);\n const duration = Date.now() - start;\n\n expect(result).toBe(TaskResult.Aborted);\n expect(duration).toBeLessThan(100); // Should not wait for full timeout\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should timeout if task does not respond to cancellation', async () => {\n const task = Task.from(async () => {\n await delay(1000);\n });\n\n // This should timeout because the task ignores cancellation\n try {\n await task.cancelAndWait(200);\n expect.fail('Task should have timed out');\n } catch (error: unknown) {\n expect(error).toBe(TASK_TIMEOUT_ERROR);\n }\n });\n\n it('should handle task that completes before timeout', async () => {\n const task = Task.from(async () => {\n await delay(50);\n });\n\n // Start the task\n await delay(10);\n\n // Cancel and wait - but task will complete normally before being canceled\n const result = await task.cancelAndWait(1000);\n\n // Task should have completed normally\n expect(result).toBe(TaskResult.Completed);\n expect(task.done).toBe(true);\n });\n\n it('should propagate non-abort errors from cancelAndWait', async () => {\n const task = Task.from(async () => {\n await delay(10);\n throw new TypeError('Custom error');\n });\n\n try {\n await task.cancelAndWait(1000);\n expect.fail('Task should have thrown');\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Custom error');\n expect((error as Error).name).toBe('TypeError');\n }\n });\n });\n\n describe('Event', () => {\n it('wait resolves immediately when the event is already set', async () => {\n const event = new Event();\n event.set();\n\n const result = await event.wait();\n expect(result).toBe(true);\n });\n\n it('wait resolves after set is called', async () => {\n // check promise is pending\n const event = new Event();\n const waiterPromise = event.wait();\n\n await delay(10);\n expect(await isPending(waiterPromise)).toBe(true);\n\n // check promise is resolved after set is called\n event.set();\n const result = await waiterPromise;\n expect(result).toBe(true);\n });\n\n it('all waiters resolve once set is called', async () => {\n const event = new Event();\n const waiters = [event.wait(), event.wait(), event.wait()];\n\n await delay(10);\n const pendings = await Promise.all(waiters.map((w) => isPending(w)));\n expect(pendings).toEqual([true, true, true]);\n\n event.set();\n const results = await Promise.all(waiters);\n expect(results).toEqual([true, true, true]);\n });\n\n it('wait after 2 seconds is still pending before set', async () => {\n const event = new Event();\n const waiter = event.wait();\n\n await delay(2000);\n expect(await isPending(waiter)).toBe(true);\n\n event.set();\n const result = await waiter;\n expect(result).toBe(true);\n });\n\n it('wait after set and clear should be pending', async () => {\n const event = new Event();\n const waiterBeforeSet = event.wait();\n event.set();\n event.clear();\n\n const waiterAfterSet = event.wait();\n\n const result = await Promise.race([\n waiterBeforeSet.then(() => 'before'),\n waiterAfterSet.then(() => 'after'),\n ]);\n\n expect(result).toBe('before');\n expect(await isPending(waiterBeforeSet)).toBe(false);\n expect(await isPending(waiterAfterSet)).toBe(true);\n\n event.set();\n expect(await waiterAfterSet).toBe(true);\n });\n });\n\n describe('resampleStream', () => {\n const createAudioFrame = (sampleRate: number, samples: number, channels = 1): AudioFrame => {\n const data = new Int16Array(samples * channels);\n for (let i = 0; i < data.length; i++) {\n data[i] = Math.sin((i / samples) * Math.PI * 2) * 16000;\n }\n return new AudioFrame(data, sampleRate, channels, samples);\n };\n\n const streamToArray = async (stream: ReadableStream<AudioFrame>): Promise<AudioFrame[]> => {\n const reader = stream.getReader();\n const chunks: AudioFrame[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return chunks;\n };\n\n it('should resample audio frames to target sample rate', async () => {\n const inputRate = 48000;\n const outputRate = 16000;\n const inputFrame = createAudioFrame(inputRate, 960); // 20ms at 48kHz\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle same input and output rate', async () => {\n const sampleRate = 44100;\n const inputFrame = createAudioFrame(sampleRate, 1024);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: sampleRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(sampleRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle multiple input frames', async () => {\n const inputRate = 32000;\n const outputRate = 48000;\n const frame1 = createAudioFrame(inputRate, 640);\n const frame2 = createAudioFrame(inputRate, 640);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(frame1);\n controller.enqueue(frame2);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(frame1.channels);\n }\n });\n\n it('should handle empty stream', async () => {\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: 44100 });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames).toEqual([]);\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport { ReadableStream } from 'node:stream/web';\nimport { describe, expect, it } from 'vitest';\nimport { initializeLogger } from '../src/log.js';\nimport {\n Event,\n TASK_TIMEOUT_ERROR,\n Task,\n TaskResult,\n delay,\n isPending,\n resampleStream,\n} from '../src/utils.js';\n\ndescribe('utils', () => {\n // initialize logger\n initializeLogger({ pretty: true, level: 'debug' });\n\n describe('Task', () => {\n it('should execute task successfully and return result', async () => {\n const expectedResult = 'task completed';\n const task = Task.from(async () => {\n await delay(10);\n return expectedResult;\n });\n\n expect(task.done).toBe(false);\n const result = await task.result;\n expect(result).toBe(expectedResult);\n expect(task.done).toBe(true);\n });\n\n it('should handle task errors properly', async () => {\n const expectedError = new Error('Task failed');\n const task = Task.from(async () => {\n await delay(10);\n throw expectedError;\n });\n\n expect(task.done).toBe(false);\n await expect(task.result).rejects.toThrow(expectedError);\n expect(task.done).toBe(true);\n });\n\n it('should cancel task when cancel is called', async () => {\n let taskStarted = false;\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n taskStarted = true;\n await delay(100, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Wait a bit to ensure task starts\n await delay(10);\n expect(taskStarted).toBe(true);\n expect(task.done).toBe(false);\n\n // Cancel the task\n task.cancel();\n\n // The task should reject with AbortError\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should use provided AbortController', async () => {\n const controller = new AbortController();\n const task = Task.from(async (ctrl) => {\n expect(ctrl).toBe(controller);\n await delay(100, { signal: ctrl.signal });\n return 'completed';\n }, controller);\n\n await delay(10);\n controller.abort();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate resolution', async () => {\n const task = Task.from(async () => {\n return 'immediate';\n });\n\n const result = await task.result;\n expect(result).toBe('immediate');\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate rejection', async () => {\n const expectedError = new Error('Immediate error');\n const task = Task.from(async () => {\n throw expectedError;\n });\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect(error).toBe(expectedError);\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle multiple calls to cancel', async () => {\n const task = Task.from(async (controller) => {\n await delay(100, { signal: controller.signal });\n return 'should not complete';\n });\n\n await delay(10);\n\n // Multiple cancellations should not cause issues\n task.cancel();\n task.cancel();\n task.cancel();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle task that checks abort signal manually', async () => {\n const arr: number[] = [];\n const task = Task.from(async (controller) => {\n for (let i = 0; i < 10; i++) {\n if (controller.signal.aborted) {\n throw new Error('Task was aborted');\n }\n await delay(10);\n arr.push(i);\n }\n return 'completed';\n });\n\n await delay(39);\n task.cancel();\n\n expect(arr).toEqual([0, 1, 2]);\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Task was aborted');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle cleanup in finally block', async () => {\n let cleanupExecuted = false;\n\n const task = Task.from(async (controller) => {\n try {\n await delay(100, { signal: controller.signal });\n return 'completed';\n } finally {\n cleanupExecuted = true;\n }\n });\n\n await delay(10);\n task.cancel();\n\n try {\n await task.result;\n } catch {\n // Ignore the abort error\n }\n\n // Cleanup should still execute even when cancelled\n expect(cleanupExecuted).toBe(true);\n });\n\n it('should handle accessing result multiple times', async () => {\n const task = Task.from(async () => {\n await delay(10);\n return 'result';\n });\n\n const result1 = await task.result;\n const result2 = await task.result;\n const result3 = await task.result;\n\n expect(result1).toBe('result');\n expect(result2).toBe('result');\n expect(result3).toBe('result');\n expect(task.done).toBe(true);\n });\n\n it('should handle accessing result promise before completion', async () => {\n const task = Task.from(async () => {\n await delay(50);\n return 'delayed result';\n });\n\n // Get references to result promise before completion\n const resultPromise1 = task.result;\n const resultPromise2 = task.result;\n\n expect(task.done).toBe(false);\n\n // Both promises should resolve to the same value\n const [result1, result2] = await Promise.all([resultPromise1, resultPromise2]);\n\n expect(result1).toBe('delayed result');\n expect(result2).toBe('delayed result');\n expect(task.done).toBe(true);\n });\n\n it('should cancel child tasks when parent task is canceled', async () => {\n let parentStarted = false;\n let child1Started = false;\n let child2Started = false;\n let parentCompleted = false;\n let child1Completed = false;\n let child2Completed = false;\n\n let child1Task: Task<string> | undefined = undefined;\n let child2Task: Task<string> | undefined = undefined;\n\n const parentTask = Task.from(async (controller) => {\n parentStarted = true;\n\n // Create two child tasks using the parent's controller\n child1Task = Task.from(async (childController) => {\n child1Started = true;\n await delay(100, { signal: childController.signal });\n child1Completed = true;\n return 'child1';\n }, controller);\n\n child2Task = Task.from(async (childController) => {\n child2Started = true;\n await delay(100, { signal: childController.signal });\n child2Completed = true;\n return 'child2';\n }, controller);\n\n // Wait for both child tasks\n const results = await Promise.all([child1Task.result, child2Task.result]);\n parentCompleted = true;\n return results;\n });\n\n // Let tasks start\n await delay(20);\n\n // Verify tasks have started\n expect(parentStarted).toBe(true);\n expect(child1Started).toBe(true);\n expect(child2Started).toBe(true);\n\n // Cancel parent task\n parentTask.cancel();\n\n // Use Promise.allSettled to handle all promise settlements\n const [parentResult, child1Result, child2Result] = await Promise.allSettled([\n parentTask.result,\n child1Task!.result,\n child2Task!.result,\n ]);\n\n // Verify all tasks were rejected with AbortError\n expect(parentResult.status).toBe('rejected');\n expect((parentResult as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child1Result.status).toBe('rejected');\n expect((child1Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child2Result.status).toBe('rejected');\n expect((child2Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n // Verify none of the tasks completed\n expect(parentCompleted).toBe(false);\n expect(child1Completed).toBe(false);\n expect(child2Completed).toBe(false);\n expect(parentTask.done).toBe(true);\n expect(child1Task!.done).toBe(true);\n expect(child2Task!.done).toBe(true);\n });\n\n it('should handle nested tasks that complete successfully', async () => {\n const results: string[] = [];\n\n const parentTask = Task.from(async (controller) => {\n results.push('parent-start');\n\n // Create first child task\n const child1Task = Task.from(async () => {\n results.push('child1-start');\n await delay(25);\n results.push('child1-end');\n return 'child1-result';\n }, controller);\n\n // Create second child task that depends on first\n const child2Task = Task.from(async (childController) => {\n results.push('child2-start');\n\n // Create a grandchild task\n const grandchildTask = Task.from(async () => {\n results.push('grandchild-start');\n await delay(10);\n results.push('grandchild-end');\n return 'grandchild-result';\n }, childController);\n\n const grandchildResult = await grandchildTask.result;\n await delay(10);\n results.push('child2-end');\n return `child2-result-with-${grandchildResult}`;\n }, controller);\n\n // Wait for all tasks\n const [child1Result, child2Result] = await Promise.all([\n child1Task.result,\n child2Task.result,\n ]);\n\n results.push('parent-end');\n return {\n parent: 'parent-result',\n child1: child1Result,\n child2: child2Result,\n };\n });\n\n // Wait for everything to complete\n const finalResult = await parentTask.result;\n\n // Verify results\n expect(finalResult).toEqual({\n parent: 'parent-result',\n child1: 'child1-result',\n child2: 'child2-result-with-grandchild-result',\n });\n\n // Verify execution order\n // Check important ordering constraints without being strict about parallel task ordering\n expect(results).toEqual([\n 'parent-start',\n 'child1-start',\n 'child2-start',\n 'grandchild-start',\n 'grandchild-end',\n 'child2-end',\n 'child1-end',\n 'parent-end',\n ]);\n\n // All tasks should be done\n expect(parentTask.done).toBe(true);\n });\n\n it('should propagate errors from nested tasks', async () => {\n let parentError: Error | null = null;\n let child1Completed = false;\n let child2Started = false;\n\n const parentTask = Task.from(async (controller) => {\n const child1Task = Task.from(async () => {\n await delay(20);\n throw new Error('child1 error');\n }, controller);\n\n const child2Task = Task.from(async () => {\n child2Started = true;\n await delay(30);\n child1Completed = true;\n return 'child2-result';\n }, controller);\n\n // This will throw when child1 fails\n const results = await Promise.all([child1Task.result, child2Task.result]);\n return results;\n });\n\n // Wait for the parent task to fail\n try {\n await parentTask.result;\n expect.fail('Parent task should have thrown');\n } catch (error: unknown) {\n parentError = error as Error;\n }\n\n // Verify the error propagated correctly\n expect(parentError?.message).toBe('child1 error');\n expect(child1Completed).toBe(false);\n expect(child2Started).toBe(true);\n expect(parentTask.done).toBe(true);\n });\n\n it('should cancel and wait for task completion', async () => {\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n await delay(5000, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Cancel and wait should complete quickly when task is aborted\n const start = Date.now();\n const result = await task.cancelAndWait(1000);\n const duration = Date.now() - start;\n\n expect(result).toBe(TaskResult.Aborted);\n expect(duration).toBeLessThan(100); // Should not wait for full timeout\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should timeout if task does not respond to cancellation', async () => {\n const task = Task.from(async () => {\n await delay(1000);\n });\n\n // This should timeout because the task ignores cancellation\n try {\n await task.cancelAndWait(200);\n expect.fail('Task should have timed out');\n } catch (error: unknown) {\n expect(error).toBe(TASK_TIMEOUT_ERROR);\n }\n });\n\n it('should handle task that completes before timeout', async () => {\n const task = Task.from(async () => {\n await delay(50);\n });\n\n // Start the task\n await delay(10);\n\n // Cancel and wait - but task will complete normally before being canceled\n const result = await task.cancelAndWait(1000);\n\n // Task should have completed normally\n expect(result).toBe(TaskResult.Completed);\n expect(task.done).toBe(true);\n });\n\n it('should propagate non-abort errors from cancelAndWait', async () => {\n const task = Task.from(async () => {\n await delay(10);\n throw new TypeError('Custom error');\n });\n\n try {\n await task.cancelAndWait(1000);\n expect.fail('Task should have thrown');\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Custom error');\n expect((error as Error).name).toBe('TypeError');\n }\n });\n });\n\n describe('Event', () => {\n it('wait resolves immediately when the event is already set', async () => {\n const event = new Event();\n event.set();\n\n const result = await event.wait();\n expect(result).toBe(true);\n });\n\n it('wait resolves after set is called', async () => {\n // check promise is pending\n const event = new Event();\n const waiterPromise = event.wait();\n\n await delay(10);\n expect(await isPending(waiterPromise)).toBe(true);\n\n // check promise is resolved after set is called\n event.set();\n const result = await waiterPromise;\n expect(result).toBe(true);\n });\n\n it('all waiters resolve once set is called', async () => {\n const event = new Event();\n const waiters = [event.wait(), event.wait(), event.wait()];\n\n await delay(10);\n const pendings = await Promise.all(waiters.map((w) => isPending(w)));\n expect(pendings).toEqual([true, true, true]);\n\n event.set();\n const results = await Promise.all(waiters);\n expect(results).toEqual([true, true, true]);\n });\n\n it('wait after 2 seconds is still pending before set', async () => {\n const event = new Event();\n const waiter = event.wait();\n\n await delay(2000);\n expect(await isPending(waiter)).toBe(true);\n\n event.set();\n const result = await waiter;\n expect(result).toBe(true);\n });\n\n it('wait after set and clear should be pending', async () => {\n const event = new Event();\n const waiterBeforeSet = event.wait();\n event.set();\n event.clear();\n\n const waiterAfterSet = event.wait();\n\n const result = await Promise.race([\n waiterBeforeSet.then(() => 'before'),\n waiterAfterSet.then(() => 'after'),\n ]);\n\n expect(result).toBe('before');\n expect(await isPending(waiterBeforeSet)).toBe(false);\n expect(await isPending(waiterAfterSet)).toBe(true);\n\n event.set();\n expect(await waiterAfterSet).toBe(true);\n });\n });\n\n describe('resampleStream', () => {\n const createAudioFrame = (sampleRate: number, samples: number, channels = 1): AudioFrame => {\n const data = new Int16Array(samples * channels);\n for (let i = 0; i < data.length; i++) {\n data[i] = Math.sin((i / samples) * Math.PI * 2) * 16000;\n }\n return new AudioFrame(data, sampleRate, channels, samples);\n };\n\n const streamToArray = async (stream: ReadableStream<AudioFrame>): Promise<AudioFrame[]> => {\n const reader = stream.getReader();\n const chunks: AudioFrame[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return chunks;\n };\n\n it('should resample audio frames to target sample rate', async () => {\n const inputRate = 48000;\n const outputRate = 16000;\n const inputFrame = createAudioFrame(inputRate, 960); // 20ms at 48kHz\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle same input and output rate', async () => {\n const sampleRate = 44100;\n const inputFrame = createAudioFrame(sampleRate, 1024);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: sampleRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(sampleRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle multiple input frames', async () => {\n const inputRate = 32000;\n const outputRate = 48000;\n const frame1 = createAudioFrame(inputRate, 640);\n const frame2 = createAudioFrame(inputRate, 640);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(frame1);\n controller.enqueue(frame2);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(frame1.channels);\n }\n });\n\n it('should handle empty stream', async () => {\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: 44100 });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames).toEqual([]);\n });\n });\n});\n"],"mappings":"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","names":[]}
|
package/dist/utils.test.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AudioFrame } from "@livekit/rtc-node";
|
|
2
|
-
import { delay } from "@std/async";
|
|
3
2
|
import { ReadableStream } from "node:stream/web";
|
|
4
3
|
import { describe, expect, it } from "vitest";
|
|
5
4
|
import { initializeLogger } from "../src/log.js";
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
TASK_TIMEOUT_ERROR,
|
|
9
8
|
Task,
|
|
10
9
|
TaskResult,
|
|
10
|
+
delay,
|
|
11
11
|
isPending,
|
|
12
12
|
resampleStream
|
|
13
13
|
} from "../src/utils.js";
|
package/dist/utils.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport { delay } from '@std/async';\nimport { ReadableStream } from 'node:stream/web';\nimport { describe, expect, it } from 'vitest';\nimport { initializeLogger } from '../src/log.js';\nimport {\n Event,\n TASK_TIMEOUT_ERROR,\n Task,\n TaskResult,\n isPending,\n resampleStream,\n} from '../src/utils.js';\n\ndescribe('utils', () => {\n // initialize logger\n initializeLogger({ pretty: true, level: 'debug' });\n\n describe('Task', () => {\n it('should execute task successfully and return result', async () => {\n const expectedResult = 'task completed';\n const task = Task.from(async () => {\n await delay(10);\n return expectedResult;\n });\n\n expect(task.done).toBe(false);\n const result = await task.result;\n expect(result).toBe(expectedResult);\n expect(task.done).toBe(true);\n });\n\n it('should handle task errors properly', async () => {\n const expectedError = new Error('Task failed');\n const task = Task.from(async () => {\n await delay(10);\n throw expectedError;\n });\n\n expect(task.done).toBe(false);\n await expect(task.result).rejects.toThrow(expectedError);\n expect(task.done).toBe(true);\n });\n\n it('should cancel task when cancel is called', async () => {\n let taskStarted = false;\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n taskStarted = true;\n await delay(100, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Wait a bit to ensure task starts\n await delay(10);\n expect(taskStarted).toBe(true);\n expect(task.done).toBe(false);\n\n // Cancel the task\n task.cancel();\n\n // The task should reject with AbortError\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should use provided AbortController', async () => {\n const controller = new AbortController();\n const task = Task.from(async (ctrl) => {\n expect(ctrl).toBe(controller);\n await delay(100, { signal: ctrl.signal });\n return 'completed';\n }, controller);\n\n await delay(10);\n controller.abort();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate resolution', async () => {\n const task = Task.from(async () => {\n return 'immediate';\n });\n\n const result = await task.result;\n expect(result).toBe('immediate');\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate rejection', async () => {\n const expectedError = new Error('Immediate error');\n const task = Task.from(async () => {\n throw expectedError;\n });\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect(error).toBe(expectedError);\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle multiple calls to cancel', async () => {\n const task = Task.from(async (controller) => {\n await delay(100, { signal: controller.signal });\n return 'should not complete';\n });\n\n await delay(10);\n\n // Multiple cancellations should not cause issues\n task.cancel();\n task.cancel();\n task.cancel();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle task that checks abort signal manually', async () => {\n const arr: number[] = [];\n const task = Task.from(async (controller) => {\n for (let i = 0; i < 10; i++) {\n if (controller.signal.aborted) {\n throw new Error('Task was aborted');\n }\n await delay(10);\n arr.push(i);\n }\n return 'completed';\n });\n\n await delay(39);\n task.cancel();\n\n expect(arr).toEqual([0, 1, 2]);\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Task was aborted');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle cleanup in finally block', async () => {\n let cleanupExecuted = false;\n\n const task = Task.from(async (controller) => {\n try {\n await delay(100, { signal: controller.signal });\n return 'completed';\n } finally {\n cleanupExecuted = true;\n }\n });\n\n await delay(10);\n task.cancel();\n\n try {\n await task.result;\n } catch {\n // Ignore the abort error\n }\n\n // Cleanup should still execute even when cancelled\n expect(cleanupExecuted).toBe(true);\n });\n\n it('should handle accessing result multiple times', async () => {\n const task = Task.from(async () => {\n await delay(10);\n return 'result';\n });\n\n const result1 = await task.result;\n const result2 = await task.result;\n const result3 = await task.result;\n\n expect(result1).toBe('result');\n expect(result2).toBe('result');\n expect(result3).toBe('result');\n expect(task.done).toBe(true);\n });\n\n it('should handle accessing result promise before completion', async () => {\n const task = Task.from(async () => {\n await delay(50);\n return 'delayed result';\n });\n\n // Get references to result promise before completion\n const resultPromise1 = task.result;\n const resultPromise2 = task.result;\n\n expect(task.done).toBe(false);\n\n // Both promises should resolve to the same value\n const [result1, result2] = await Promise.all([resultPromise1, resultPromise2]);\n\n expect(result1).toBe('delayed result');\n expect(result2).toBe('delayed result');\n expect(task.done).toBe(true);\n });\n\n it('should cancel child tasks when parent task is canceled', async () => {\n let parentStarted = false;\n let child1Started = false;\n let child2Started = false;\n let parentCompleted = false;\n let child1Completed = false;\n let child2Completed = false;\n\n let child1Task: Task<string> | undefined = undefined;\n let child2Task: Task<string> | undefined = undefined;\n\n const parentTask = Task.from(async (controller) => {\n parentStarted = true;\n\n // Create two child tasks using the parent's controller\n child1Task = Task.from(async (childController) => {\n child1Started = true;\n await delay(100, { signal: childController.signal });\n child1Completed = true;\n return 'child1';\n }, controller);\n\n child2Task = Task.from(async (childController) => {\n child2Started = true;\n await delay(100, { signal: childController.signal });\n child2Completed = true;\n return 'child2';\n }, controller);\n\n // Wait for both child tasks\n const results = await Promise.all([child1Task.result, child2Task.result]);\n parentCompleted = true;\n return results;\n });\n\n // Let tasks start\n await delay(20);\n\n // Verify tasks have started\n expect(parentStarted).toBe(true);\n expect(child1Started).toBe(true);\n expect(child2Started).toBe(true);\n\n // Cancel parent task\n parentTask.cancel();\n\n // Use Promise.allSettled to handle all promise settlements\n const [parentResult, child1Result, child2Result] = await Promise.allSettled([\n parentTask.result,\n child1Task!.result,\n child2Task!.result,\n ]);\n\n // Verify all tasks were rejected with AbortError\n expect(parentResult.status).toBe('rejected');\n expect((parentResult as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child1Result.status).toBe('rejected');\n expect((child1Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child2Result.status).toBe('rejected');\n expect((child2Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n // Verify none of the tasks completed\n expect(parentCompleted).toBe(false);\n expect(child1Completed).toBe(false);\n expect(child2Completed).toBe(false);\n expect(parentTask.done).toBe(true);\n expect(child1Task!.done).toBe(true);\n expect(child2Task!.done).toBe(true);\n });\n\n it('should handle nested tasks that complete successfully', async () => {\n const results: string[] = [];\n\n const parentTask = Task.from(async (controller) => {\n results.push('parent-start');\n\n // Create first child task\n const child1Task = Task.from(async () => {\n results.push('child1-start');\n await delay(25);\n results.push('child1-end');\n return 'child1-result';\n }, controller);\n\n // Create second child task that depends on first\n const child2Task = Task.from(async (childController) => {\n results.push('child2-start');\n\n // Create a grandchild task\n const grandchildTask = Task.from(async () => {\n results.push('grandchild-start');\n await delay(10);\n results.push('grandchild-end');\n return 'grandchild-result';\n }, childController);\n\n const grandchildResult = await grandchildTask.result;\n await delay(10);\n results.push('child2-end');\n return `child2-result-with-${grandchildResult}`;\n }, controller);\n\n // Wait for all tasks\n const [child1Result, child2Result] = await Promise.all([\n child1Task.result,\n child2Task.result,\n ]);\n\n results.push('parent-end');\n return {\n parent: 'parent-result',\n child1: child1Result,\n child2: child2Result,\n };\n });\n\n // Wait for everything to complete\n const finalResult = await parentTask.result;\n\n // Verify results\n expect(finalResult).toEqual({\n parent: 'parent-result',\n child1: 'child1-result',\n child2: 'child2-result-with-grandchild-result',\n });\n\n // Verify execution order\n // Check important ordering constraints without being strict about parallel task ordering\n expect(results).toEqual([\n 'parent-start',\n 'child1-start',\n 'child2-start',\n 'grandchild-start',\n 'grandchild-end',\n 'child2-end',\n 'child1-end',\n 'parent-end',\n ]);\n\n // All tasks should be done\n expect(parentTask.done).toBe(true);\n });\n\n it('should propagate errors from nested tasks', async () => {\n let parentError: Error | null = null;\n let child1Completed = false;\n let child2Started = false;\n\n const parentTask = Task.from(async (controller) => {\n const child1Task = Task.from(async () => {\n await delay(20);\n throw new Error('child1 error');\n }, controller);\n\n const child2Task = Task.from(async () => {\n child2Started = true;\n await delay(30);\n child1Completed = true;\n return 'child2-result';\n }, controller);\n\n // This will throw when child1 fails\n const results = await Promise.all([child1Task.result, child2Task.result]);\n return results;\n });\n\n // Wait for the parent task to fail\n try {\n await parentTask.result;\n expect.fail('Parent task should have thrown');\n } catch (error: unknown) {\n parentError = error as Error;\n }\n\n // Verify the error propagated correctly\n expect(parentError?.message).toBe('child1 error');\n expect(child1Completed).toBe(false);\n expect(child2Started).toBe(true);\n expect(parentTask.done).toBe(true);\n });\n\n it('should cancel and wait for task completion', async () => {\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n await delay(5000, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Cancel and wait should complete quickly when task is aborted\n const start = Date.now();\n const result = await task.cancelAndWait(1000);\n const duration = Date.now() - start;\n\n expect(result).toBe(TaskResult.Aborted);\n expect(duration).toBeLessThan(100); // Should not wait for full timeout\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should timeout if task does not respond to cancellation', async () => {\n const task = Task.from(async () => {\n await delay(1000);\n });\n\n // This should timeout because the task ignores cancellation\n try {\n await task.cancelAndWait(200);\n expect.fail('Task should have timed out');\n } catch (error: unknown) {\n expect(error).toBe(TASK_TIMEOUT_ERROR);\n }\n });\n\n it('should handle task that completes before timeout', async () => {\n const task = Task.from(async () => {\n await delay(50);\n });\n\n // Start the task\n await delay(10);\n\n // Cancel and wait - but task will complete normally before being canceled\n const result = await task.cancelAndWait(1000);\n\n // Task should have completed normally\n expect(result).toBe(TaskResult.Completed);\n expect(task.done).toBe(true);\n });\n\n it('should propagate non-abort errors from cancelAndWait', async () => {\n const task = Task.from(async () => {\n await delay(10);\n throw new TypeError('Custom error');\n });\n\n try {\n await task.cancelAndWait(1000);\n expect.fail('Task should have thrown');\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Custom error');\n expect((error as Error).name).toBe('TypeError');\n }\n });\n });\n\n describe('Event', () => {\n it('wait resolves immediately when the event is already set', async () => {\n const event = new Event();\n event.set();\n\n const result = await event.wait();\n expect(result).toBe(true);\n });\n\n it('wait resolves after set is called', async () => {\n // check promise is pending\n const event = new Event();\n const waiterPromise = event.wait();\n\n await delay(10);\n expect(await isPending(waiterPromise)).toBe(true);\n\n // check promise is resolved after set is called\n event.set();\n const result = await waiterPromise;\n expect(result).toBe(true);\n });\n\n it('all waiters resolve once set is called', async () => {\n const event = new Event();\n const waiters = [event.wait(), event.wait(), event.wait()];\n\n await delay(10);\n const pendings = await Promise.all(waiters.map((w) => isPending(w)));\n expect(pendings).toEqual([true, true, true]);\n\n event.set();\n const results = await Promise.all(waiters);\n expect(results).toEqual([true, true, true]);\n });\n\n it('wait after 2 seconds is still pending before set', async () => {\n const event = new Event();\n const waiter = event.wait();\n\n await delay(2000);\n expect(await isPending(waiter)).toBe(true);\n\n event.set();\n const result = await waiter;\n expect(result).toBe(true);\n });\n\n it('wait after set and clear should be pending', async () => {\n const event = new Event();\n const waiterBeforeSet = event.wait();\n event.set();\n event.clear();\n\n const waiterAfterSet = event.wait();\n\n const result = await Promise.race([\n waiterBeforeSet.then(() => 'before'),\n waiterAfterSet.then(() => 'after'),\n ]);\n\n expect(result).toBe('before');\n expect(await isPending(waiterBeforeSet)).toBe(false);\n expect(await isPending(waiterAfterSet)).toBe(true);\n\n event.set();\n expect(await waiterAfterSet).toBe(true);\n });\n });\n\n describe('resampleStream', () => {\n const createAudioFrame = (sampleRate: number, samples: number, channels = 1): AudioFrame => {\n const data = new Int16Array(samples * channels);\n for (let i = 0; i < data.length; i++) {\n data[i] = Math.sin((i / samples) * Math.PI * 2) * 16000;\n }\n return new AudioFrame(data, sampleRate, channels, samples);\n };\n\n const streamToArray = async (stream: ReadableStream<AudioFrame>): Promise<AudioFrame[]> => {\n const reader = stream.getReader();\n const chunks: AudioFrame[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return chunks;\n };\n\n it('should resample audio frames to target sample rate', async () => {\n const inputRate = 48000;\n const outputRate = 16000;\n const inputFrame = createAudioFrame(inputRate, 960); // 20ms at 48kHz\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle same input and output rate', async () => {\n const sampleRate = 44100;\n const inputFrame = createAudioFrame(sampleRate, 1024);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: sampleRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(sampleRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle multiple input frames', async () => {\n const inputRate = 32000;\n const outputRate = 48000;\n const frame1 = createAudioFrame(inputRate, 640);\n const frame2 = createAudioFrame(inputRate, 640);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(frame1);\n controller.enqueue(frame2);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(frame1.channels);\n }\n });\n\n it('should handle empty stream', async () => {\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: 44100 });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames).toEqual([]);\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport { ReadableStream } from 'node:stream/web';\nimport { describe, expect, it } from 'vitest';\nimport { initializeLogger } from '../src/log.js';\nimport {\n Event,\n TASK_TIMEOUT_ERROR,\n Task,\n TaskResult,\n delay,\n isPending,\n resampleStream,\n} from '../src/utils.js';\n\ndescribe('utils', () => {\n // initialize logger\n initializeLogger({ pretty: true, level: 'debug' });\n\n describe('Task', () => {\n it('should execute task successfully and return result', async () => {\n const expectedResult = 'task completed';\n const task = Task.from(async () => {\n await delay(10);\n return expectedResult;\n });\n\n expect(task.done).toBe(false);\n const result = await task.result;\n expect(result).toBe(expectedResult);\n expect(task.done).toBe(true);\n });\n\n it('should handle task errors properly', async () => {\n const expectedError = new Error('Task failed');\n const task = Task.from(async () => {\n await delay(10);\n throw expectedError;\n });\n\n expect(task.done).toBe(false);\n await expect(task.result).rejects.toThrow(expectedError);\n expect(task.done).toBe(true);\n });\n\n it('should cancel task when cancel is called', async () => {\n let taskStarted = false;\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n taskStarted = true;\n await delay(100, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Wait a bit to ensure task starts\n await delay(10);\n expect(taskStarted).toBe(true);\n expect(task.done).toBe(false);\n\n // Cancel the task\n task.cancel();\n\n // The task should reject with AbortError\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should use provided AbortController', async () => {\n const controller = new AbortController();\n const task = Task.from(async (ctrl) => {\n expect(ctrl).toBe(controller);\n await delay(100, { signal: ctrl.signal });\n return 'completed';\n }, controller);\n\n await delay(10);\n controller.abort();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate resolution', async () => {\n const task = Task.from(async () => {\n return 'immediate';\n });\n\n const result = await task.result;\n expect(result).toBe('immediate');\n expect(task.done).toBe(true);\n });\n\n it('should handle immediate rejection', async () => {\n const expectedError = new Error('Immediate error');\n const task = Task.from(async () => {\n throw expectedError;\n });\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect(error).toBe(expectedError);\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle multiple calls to cancel', async () => {\n const task = Task.from(async (controller) => {\n await delay(100, { signal: controller.signal });\n return 'should not complete';\n });\n\n await delay(10);\n\n // Multiple cancellations should not cause issues\n task.cancel();\n task.cancel();\n task.cancel();\n\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).name).toBe('AbortError');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle task that checks abort signal manually', async () => {\n const arr: number[] = [];\n const task = Task.from(async (controller) => {\n for (let i = 0; i < 10; i++) {\n if (controller.signal.aborted) {\n throw new Error('Task was aborted');\n }\n await delay(10);\n arr.push(i);\n }\n return 'completed';\n });\n\n await delay(39);\n task.cancel();\n\n expect(arr).toEqual([0, 1, 2]);\n try {\n await task.result;\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Task was aborted');\n }\n\n expect(task.done).toBe(true);\n });\n\n it('should handle cleanup in finally block', async () => {\n let cleanupExecuted = false;\n\n const task = Task.from(async (controller) => {\n try {\n await delay(100, { signal: controller.signal });\n return 'completed';\n } finally {\n cleanupExecuted = true;\n }\n });\n\n await delay(10);\n task.cancel();\n\n try {\n await task.result;\n } catch {\n // Ignore the abort error\n }\n\n // Cleanup should still execute even when cancelled\n expect(cleanupExecuted).toBe(true);\n });\n\n it('should handle accessing result multiple times', async () => {\n const task = Task.from(async () => {\n await delay(10);\n return 'result';\n });\n\n const result1 = await task.result;\n const result2 = await task.result;\n const result3 = await task.result;\n\n expect(result1).toBe('result');\n expect(result2).toBe('result');\n expect(result3).toBe('result');\n expect(task.done).toBe(true);\n });\n\n it('should handle accessing result promise before completion', async () => {\n const task = Task.from(async () => {\n await delay(50);\n return 'delayed result';\n });\n\n // Get references to result promise before completion\n const resultPromise1 = task.result;\n const resultPromise2 = task.result;\n\n expect(task.done).toBe(false);\n\n // Both promises should resolve to the same value\n const [result1, result2] = await Promise.all([resultPromise1, resultPromise2]);\n\n expect(result1).toBe('delayed result');\n expect(result2).toBe('delayed result');\n expect(task.done).toBe(true);\n });\n\n it('should cancel child tasks when parent task is canceled', async () => {\n let parentStarted = false;\n let child1Started = false;\n let child2Started = false;\n let parentCompleted = false;\n let child1Completed = false;\n let child2Completed = false;\n\n let child1Task: Task<string> | undefined = undefined;\n let child2Task: Task<string> | undefined = undefined;\n\n const parentTask = Task.from(async (controller) => {\n parentStarted = true;\n\n // Create two child tasks using the parent's controller\n child1Task = Task.from(async (childController) => {\n child1Started = true;\n await delay(100, { signal: childController.signal });\n child1Completed = true;\n return 'child1';\n }, controller);\n\n child2Task = Task.from(async (childController) => {\n child2Started = true;\n await delay(100, { signal: childController.signal });\n child2Completed = true;\n return 'child2';\n }, controller);\n\n // Wait for both child tasks\n const results = await Promise.all([child1Task.result, child2Task.result]);\n parentCompleted = true;\n return results;\n });\n\n // Let tasks start\n await delay(20);\n\n // Verify tasks have started\n expect(parentStarted).toBe(true);\n expect(child1Started).toBe(true);\n expect(child2Started).toBe(true);\n\n // Cancel parent task\n parentTask.cancel();\n\n // Use Promise.allSettled to handle all promise settlements\n const [parentResult, child1Result, child2Result] = await Promise.allSettled([\n parentTask.result,\n child1Task!.result,\n child2Task!.result,\n ]);\n\n // Verify all tasks were rejected with AbortError\n expect(parentResult.status).toBe('rejected');\n expect((parentResult as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child1Result.status).toBe('rejected');\n expect((child1Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n expect(child2Result.status).toBe('rejected');\n expect((child2Result as PromiseRejectedResult).reason.name).toBe('AbortError');\n\n // Verify none of the tasks completed\n expect(parentCompleted).toBe(false);\n expect(child1Completed).toBe(false);\n expect(child2Completed).toBe(false);\n expect(parentTask.done).toBe(true);\n expect(child1Task!.done).toBe(true);\n expect(child2Task!.done).toBe(true);\n });\n\n it('should handle nested tasks that complete successfully', async () => {\n const results: string[] = [];\n\n const parentTask = Task.from(async (controller) => {\n results.push('parent-start');\n\n // Create first child task\n const child1Task = Task.from(async () => {\n results.push('child1-start');\n await delay(25);\n results.push('child1-end');\n return 'child1-result';\n }, controller);\n\n // Create second child task that depends on first\n const child2Task = Task.from(async (childController) => {\n results.push('child2-start');\n\n // Create a grandchild task\n const grandchildTask = Task.from(async () => {\n results.push('grandchild-start');\n await delay(10);\n results.push('grandchild-end');\n return 'grandchild-result';\n }, childController);\n\n const grandchildResult = await grandchildTask.result;\n await delay(10);\n results.push('child2-end');\n return `child2-result-with-${grandchildResult}`;\n }, controller);\n\n // Wait for all tasks\n const [child1Result, child2Result] = await Promise.all([\n child1Task.result,\n child2Task.result,\n ]);\n\n results.push('parent-end');\n return {\n parent: 'parent-result',\n child1: child1Result,\n child2: child2Result,\n };\n });\n\n // Wait for everything to complete\n const finalResult = await parentTask.result;\n\n // Verify results\n expect(finalResult).toEqual({\n parent: 'parent-result',\n child1: 'child1-result',\n child2: 'child2-result-with-grandchild-result',\n });\n\n // Verify execution order\n // Check important ordering constraints without being strict about parallel task ordering\n expect(results).toEqual([\n 'parent-start',\n 'child1-start',\n 'child2-start',\n 'grandchild-start',\n 'grandchild-end',\n 'child2-end',\n 'child1-end',\n 'parent-end',\n ]);\n\n // All tasks should be done\n expect(parentTask.done).toBe(true);\n });\n\n it('should propagate errors from nested tasks', async () => {\n let parentError: Error | null = null;\n let child1Completed = false;\n let child2Started = false;\n\n const parentTask = Task.from(async (controller) => {\n const child1Task = Task.from(async () => {\n await delay(20);\n throw new Error('child1 error');\n }, controller);\n\n const child2Task = Task.from(async () => {\n child2Started = true;\n await delay(30);\n child1Completed = true;\n return 'child2-result';\n }, controller);\n\n // This will throw when child1 fails\n const results = await Promise.all([child1Task.result, child2Task.result]);\n return results;\n });\n\n // Wait for the parent task to fail\n try {\n await parentTask.result;\n expect.fail('Parent task should have thrown');\n } catch (error: unknown) {\n parentError = error as Error;\n }\n\n // Verify the error propagated correctly\n expect(parentError?.message).toBe('child1 error');\n expect(child1Completed).toBe(false);\n expect(child2Started).toBe(true);\n expect(parentTask.done).toBe(true);\n });\n\n it('should cancel and wait for task completion', async () => {\n let taskCompleted = false;\n\n const task = Task.from(async (controller) => {\n await delay(5000, { signal: controller.signal });\n taskCompleted = true;\n return 'should not complete';\n });\n\n // Cancel and wait should complete quickly when task is aborted\n const start = Date.now();\n const result = await task.cancelAndWait(1000);\n const duration = Date.now() - start;\n\n expect(result).toBe(TaskResult.Aborted);\n expect(duration).toBeLessThan(100); // Should not wait for full timeout\n expect(taskCompleted).toBe(false);\n expect(task.done).toBe(true);\n });\n\n it('should timeout if task does not respond to cancellation', async () => {\n const task = Task.from(async () => {\n await delay(1000);\n });\n\n // This should timeout because the task ignores cancellation\n try {\n await task.cancelAndWait(200);\n expect.fail('Task should have timed out');\n } catch (error: unknown) {\n expect(error).toBe(TASK_TIMEOUT_ERROR);\n }\n });\n\n it('should handle task that completes before timeout', async () => {\n const task = Task.from(async () => {\n await delay(50);\n });\n\n // Start the task\n await delay(10);\n\n // Cancel and wait - but task will complete normally before being canceled\n const result = await task.cancelAndWait(1000);\n\n // Task should have completed normally\n expect(result).toBe(TaskResult.Completed);\n expect(task.done).toBe(true);\n });\n\n it('should propagate non-abort errors from cancelAndWait', async () => {\n const task = Task.from(async () => {\n await delay(10);\n throw new TypeError('Custom error');\n });\n\n try {\n await task.cancelAndWait(1000);\n expect.fail('Task should have thrown');\n } catch (error: unknown) {\n expect((error as Error).message).toBe('Custom error');\n expect((error as Error).name).toBe('TypeError');\n }\n });\n });\n\n describe('Event', () => {\n it('wait resolves immediately when the event is already set', async () => {\n const event = new Event();\n event.set();\n\n const result = await event.wait();\n expect(result).toBe(true);\n });\n\n it('wait resolves after set is called', async () => {\n // check promise is pending\n const event = new Event();\n const waiterPromise = event.wait();\n\n await delay(10);\n expect(await isPending(waiterPromise)).toBe(true);\n\n // check promise is resolved after set is called\n event.set();\n const result = await waiterPromise;\n expect(result).toBe(true);\n });\n\n it('all waiters resolve once set is called', async () => {\n const event = new Event();\n const waiters = [event.wait(), event.wait(), event.wait()];\n\n await delay(10);\n const pendings = await Promise.all(waiters.map((w) => isPending(w)));\n expect(pendings).toEqual([true, true, true]);\n\n event.set();\n const results = await Promise.all(waiters);\n expect(results).toEqual([true, true, true]);\n });\n\n it('wait after 2 seconds is still pending before set', async () => {\n const event = new Event();\n const waiter = event.wait();\n\n await delay(2000);\n expect(await isPending(waiter)).toBe(true);\n\n event.set();\n const result = await waiter;\n expect(result).toBe(true);\n });\n\n it('wait after set and clear should be pending', async () => {\n const event = new Event();\n const waiterBeforeSet = event.wait();\n event.set();\n event.clear();\n\n const waiterAfterSet = event.wait();\n\n const result = await Promise.race([\n waiterBeforeSet.then(() => 'before'),\n waiterAfterSet.then(() => 'after'),\n ]);\n\n expect(result).toBe('before');\n expect(await isPending(waiterBeforeSet)).toBe(false);\n expect(await isPending(waiterAfterSet)).toBe(true);\n\n event.set();\n expect(await waiterAfterSet).toBe(true);\n });\n });\n\n describe('resampleStream', () => {\n const createAudioFrame = (sampleRate: number, samples: number, channels = 1): AudioFrame => {\n const data = new Int16Array(samples * channels);\n for (let i = 0; i < data.length; i++) {\n data[i] = Math.sin((i / samples) * Math.PI * 2) * 16000;\n }\n return new AudioFrame(data, sampleRate, channels, samples);\n };\n\n const streamToArray = async (stream: ReadableStream<AudioFrame>): Promise<AudioFrame[]> => {\n const reader = stream.getReader();\n const chunks: AudioFrame[] = [];\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return chunks;\n };\n\n it('should resample audio frames to target sample rate', async () => {\n const inputRate = 48000;\n const outputRate = 16000;\n const inputFrame = createAudioFrame(inputRate, 960); // 20ms at 48kHz\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle same input and output rate', async () => {\n const sampleRate = 44100;\n const inputFrame = createAudioFrame(sampleRate, 1024);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(inputFrame);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: sampleRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(sampleRate);\n expect(frame.channels).toBe(inputFrame.channels);\n }\n });\n\n it('should handle multiple input frames', async () => {\n const inputRate = 32000;\n const outputRate = 48000;\n const frame1 = createAudioFrame(inputRate, 640);\n const frame2 = createAudioFrame(inputRate, 640);\n\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.enqueue(frame1);\n controller.enqueue(frame2);\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames.length).toBeGreaterThan(0);\n\n for (const frame of outputFrames) {\n expect(frame.sampleRate).toBe(outputRate);\n expect(frame.channels).toBe(frame1.channels);\n }\n });\n\n it('should handle empty stream', async () => {\n const inputStream = new ReadableStream<AudioFrame>({\n start(controller) {\n controller.close();\n },\n });\n\n const outputStream = resampleStream({ stream: inputStream, outputRate: 44100 });\n const outputFrames = await streamToArray(outputStream);\n\n expect(outputFrames).toEqual([]);\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
@@ -22,7 +22,6 @@ __export(audio_recognition_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(audio_recognition_exports);
|
|
24
24
|
var import_rtc_node = require("@livekit/rtc-node");
|
|
25
|
-
var import_async = require("@std/async");
|
|
26
25
|
var import_web = require("node:stream/web");
|
|
27
26
|
var import_chat_context = require("../llm/chat_context.cjs");
|
|
28
27
|
var import_log = require("../log.cjs");
|
|
@@ -200,7 +199,7 @@ class AudioRecognition {
|
|
|
200
199
|
}
|
|
201
200
|
}
|
|
202
201
|
const extraSleep = lastSpeakingTime + endpointingDelay - Date.now();
|
|
203
|
-
await (0,
|
|
202
|
+
await (0, import_utils.delay)(Math.max(extraSleep, 0), { signal: controller.signal });
|
|
204
203
|
this.logger.debug({ transcript: this.audioTranscript }, "end of user turn");
|
|
205
204
|
const committed = await this.hooks.onEndOfTurn({
|
|
206
205
|
newTranscript: this.audioTranscript,
|
|
@@ -337,7 +336,7 @@ class AudioRecognition {
|
|
|
337
336
|
const silenceFrame = new import_rtc_node.AudioFrame(silence, this.sampleRate, 1, numSamples);
|
|
338
337
|
this.silenceAudioWriter.write(silenceFrame);
|
|
339
338
|
}
|
|
340
|
-
await (0,
|
|
339
|
+
await (0, import_utils.delay)(delayDuration, { signal: controller.signal });
|
|
341
340
|
}
|
|
342
341
|
if (this.audioInterimTranscript) {
|
|
343
342
|
this.audioTranscript = `${this.audioTranscript} ${this.audioInterimTranscript}`.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/voice/audio_recognition.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport { delay } from '@std/async';\nimport type { WritableStreamDefaultWriter } from 'node:stream/web';\nimport { ReadableStream } from 'node:stream/web';\nimport { type ChatContext } from '../llm/chat_context.js';\nimport { log } from '../log.js';\nimport { DeferredReadableStream, isStreamReaderReleaseError } from '../stream/deferred_stream.js';\nimport { IdentityTransform } from '../stream/identity_transform.js';\nimport { mergeReadableStreams } from '../stream/merge_readable_streams.js';\nimport { type SpeechEvent, SpeechEventType } from '../stt/stt.js';\nimport { Task } from '../utils.js';\nimport { type VAD, type VADEvent, VADEventType } from '../vad.js';\nimport type { TurnDetectionMode } from './agent_session.js';\nimport type { STTNode } from './io.js';\n\nexport interface EndOfTurnInfo {\n newTranscript: string;\n transcriptionDelay: number;\n endOfUtteranceDelay: number;\n}\n\nexport interface RecognitionHooks {\n onStartOfSpeech: (ev: VADEvent) => void;\n onVADInferenceDone: (ev: VADEvent) => void;\n onEndOfSpeech: (ev: VADEvent) => void;\n onInterimTranscript: (ev: SpeechEvent) => void;\n onFinalTranscript: (ev: SpeechEvent) => void;\n onEndOfTurn: (info: EndOfTurnInfo) => Promise<boolean>;\n\n retrieveChatCtx: () => ChatContext;\n}\n\nexport interface _TurnDetector {\n unlikelyThreshold: (language?: string) => Promise<number | undefined>;\n supportsLanguage: (language?: string) => Promise<boolean>;\n predictEndOfTurn(chatCtx: ChatContext): Promise<number>;\n}\n\nexport interface AudioRecognitionOptions {\n recognitionHooks: RecognitionHooks;\n stt?: STTNode;\n vad?: VAD;\n turnDetector?: _TurnDetector;\n turnDetectionMode?: Exclude<TurnDetectionMode, _TurnDetector>;\n minEndpointingDelay: number;\n maxEndpointingDelay: number;\n}\n\nexport class AudioRecognition {\n private hooks: RecognitionHooks;\n private stt?: STTNode;\n private vad?: VAD;\n private turnDetector?: _TurnDetector;\n private turnDetectionMode?: Exclude<TurnDetectionMode, _TurnDetector>;\n private minEndpointingDelay: number;\n private maxEndpointingDelay: number;\n private lastLanguage?: string;\n\n private deferredInputStream: DeferredReadableStream<AudioFrame>;\n private logger = log();\n private lastFinalTranscriptTime = 0;\n private audioTranscript = '';\n private audioInterimTranscript = '';\n private lastSpeakingTime = 0;\n private userTurnCommitted = false;\n private speaking = false;\n private sampleRate?: number;\n\n private vadInputStream: ReadableStream<AudioFrame>;\n private sttInputStream: ReadableStream<AudioFrame>;\n private silenceAudioTransform = new IdentityTransform<AudioFrame>();\n private silenceAudioWriter: WritableStreamDefaultWriter<AudioFrame>;\n\n // all cancellable tasks\n private bounceEOUTask?: Task<void>;\n private commitUserTurnTask?: Task<void>;\n private vadTask?: Task<void>;\n private sttTask?: Task<void>;\n\n constructor(opts: AudioRecognitionOptions) {\n this.hooks = opts.recognitionHooks;\n this.stt = opts.stt;\n this.vad = opts.vad;\n this.turnDetector = opts.turnDetector;\n this.turnDetectionMode = opts.turnDetectionMode;\n this.minEndpointingDelay = opts.minEndpointingDelay;\n this.maxEndpointingDelay = opts.maxEndpointingDelay;\n this.lastLanguage = undefined;\n\n this.deferredInputStream = new DeferredReadableStream<AudioFrame>();\n const [vadInputStream, sttInputStream] = this.deferredInputStream.stream.tee();\n this.vadInputStream = vadInputStream;\n this.sttInputStream = mergeReadableStreams(sttInputStream, this.silenceAudioTransform.readable);\n this.silenceAudioWriter = this.silenceAudioTransform.writable.getWriter();\n }\n\n /**\n * Current transcript of the user's speech, including interim transcript if available.\n */\n get currentTranscript(): string {\n if (this.audioInterimTranscript) {\n return `${this.audioTranscript} ${this.audioInterimTranscript}`.trim();\n }\n return this.audioTranscript;\n }\n\n async start() {\n this.vadTask = Task.from(({ signal }) => this.createVadTask(this.vad, signal));\n this.vadTask.result.catch((err) => {\n this.logger.error(`Error running VAD task: ${err}`);\n });\n\n this.sttTask = Task.from(({ signal }) => this.createSttTask(this.stt, signal));\n this.sttTask.result.catch((err) => {\n this.logger.error(`Error running STT task: ${err}`);\n });\n }\n\n private async onSTTEvent(ev: SpeechEvent) {\n if (\n this.turnDetectionMode === 'manual' &&\n this.userTurnCommitted &&\n (this.bounceEOUTask === undefined ||\n this.bounceEOUTask.done ||\n ev.type == SpeechEventType.INTERIM_TRANSCRIPT)\n ) {\n // ignore stt event if user turn already committed and EOU task is done\n // or it's an interim transcript\n this.logger.debug(\n {\n userTurnCommitted: this.userTurnCommitted,\n eouTaskDone: this.bounceEOUTask?.done,\n evType: ev.type,\n turnDetectionMode: this.turnDetectionMode,\n },\n 'ignoring stt event',\n );\n return;\n }\n\n switch (ev.type) {\n case SpeechEventType.FINAL_TRANSCRIPT:\n this.hooks.onFinalTranscript(ev);\n const transcript = ev.alternatives?.[0]?.text;\n this.lastLanguage = ev.alternatives?.[0]?.language;\n\n if (!transcript) {\n // stt final transcript received but no transcript\n return;\n }\n\n this.logger.debug(\n {\n user_transcript: transcript,\n language: this.lastLanguage,\n },\n 'received user transcript',\n );\n\n this.lastFinalTranscriptTime = Date.now();\n this.audioTranscript += ` ${transcript}`;\n this.audioTranscript = this.audioTranscript.trimStart();\n this.audioInterimTranscript = '';\n\n if (!this.speaking) {\n if (!this.vad) {\n // Copied from python agents:\n // vad disabled, use stt timestamp\n // TODO: this would screw up transcription latency metrics\n // but we'll live with it for now.\n // the correct way is to ensure STT fires SpeechEventType.END_OF_SPEECH\n // and using that timestamp for _last_speaking_time\n this.lastSpeakingTime = Date.now();\n }\n\n if (this.vadBaseTurnDetection || this.userTurnCommitted) {\n const chatCtx = this.hooks.retrieveChatCtx();\n this.logger.debug('running EOU detection on stt FINAL_TRANSCRIPT');\n this.runEOUDetection(chatCtx);\n }\n }\n break;\n case SpeechEventType.INTERIM_TRANSCRIPT:\n this.logger.debug({ transcript: ev.alternatives?.[0]?.text }, 'interim transcript');\n this.hooks.onInterimTranscript(ev);\n this.audioInterimTranscript = ev.alternatives?.[0]?.text ?? '';\n break;\n case SpeechEventType.END_OF_SPEECH:\n if (this.turnDetectionMode !== 'stt') break;\n this.userTurnCommitted = true;\n\n if (!this.speaking) {\n const chatCtx = this.hooks.retrieveChatCtx();\n this.logger.debug('running EOU detection on stt END_OF_SPEECH');\n this.runEOUDetection(chatCtx);\n }\n }\n }\n\n private runEOUDetection(chatCtx: ChatContext) {\n this.logger.debug(\n {\n stt: this.stt,\n audioTranscript: this.audioTranscript,\n turnDetectionMode: this.turnDetectionMode,\n },\n 'running EOU detection',\n );\n\n if (this.stt && !this.audioTranscript && this.turnDetectionMode !== 'manual') {\n // stt enabled but no transcript yet\n this.logger.debug('skipping EOU detection');\n return;\n }\n\n chatCtx = chatCtx.copy();\n chatCtx.addMessage({ role: 'user', content: this.audioTranscript });\n\n const turnDetector =\n // disable EOU model if manual turn detection enabled\n this.audioTranscript && this.turnDetectionMode !== 'manual' ? this.turnDetector : undefined;\n\n const bounceEOUTask = (lastSpeakingTime: number) => async (controller: AbortController) => {\n let endpointingDelay = this.minEndpointingDelay;\n\n // TODO(AJS-74): need to support actual turn detection model plugins for following code to run\n if (turnDetector) {\n this.logger.debug('Running turn detector model');\n if (!turnDetector.supportsLanguage(this.lastLanguage)) {\n this.logger.debug(`Turn detector does not support language ${this.lastLanguage}`);\n } else {\n const endOfTurnProbability = await turnDetector.predictEndOfTurn(chatCtx);\n this.logger.debug(\n { endOfTurnProbability, language: this.lastLanguage },\n 'end of turn probability',\n );\n\n const unlikelyThreshold = await turnDetector.unlikelyThreshold(this.lastLanguage);\n this.logger.debug(\n {\n unlikelyThreshold,\n endOfTurnProbability,\n language: this.lastLanguage,\n transcript: this.audioTranscript,\n },\n 'EOU Detection',\n );\n\n if (unlikelyThreshold && endOfTurnProbability < unlikelyThreshold) {\n endpointingDelay = this.maxEndpointingDelay;\n }\n }\n }\n\n const extraSleep = lastSpeakingTime + endpointingDelay - Date.now();\n // add delay to see if there's a potential upcoming EOU task that cancels this one\n await delay(Math.max(extraSleep, 0), { signal: controller.signal });\n\n this.logger.debug({ transcript: this.audioTranscript }, 'end of user turn');\n\n const committed = await this.hooks.onEndOfTurn({\n newTranscript: this.audioTranscript,\n transcriptionDelay: Math.max(this.lastFinalTranscriptTime - lastSpeakingTime, 0),\n endOfUtteranceDelay: Date.now() - lastSpeakingTime,\n });\n\n if (committed) {\n // clear the transcript if the user turn was committed\n this.audioTranscript = '';\n }\n\n this.userTurnCommitted = false;\n };\n\n // cancel any existing EOU task\n this.bounceEOUTask?.cancel();\n this.bounceEOUTask = Task.from(bounceEOUTask(this.lastSpeakingTime));\n\n this.bounceEOUTask.result\n .then(() => {\n this.logger.debug('EOU detection task completed');\n })\n .catch((err: unknown) => {\n if (err instanceof Error && err.message.includes('This operation was aborted')) {\n // ignore aborted errors\n return;\n }\n this.logger.error(err, 'Error in EOU detection task:');\n });\n }\n\n private async createSttTask(stt: STTNode | undefined, signal: AbortSignal) {\n if (!stt) return;\n\n this.logger.debug('createSttTask: create stt stream from stt node');\n\n const sttStream = await stt(this.sttInputStream, {});\n\n if (signal.aborted || sttStream === null) return;\n\n if (sttStream instanceof ReadableStream) {\n const reader = sttStream.getReader();\n\n signal.addEventListener('abort', async () => {\n try {\n reader.releaseLock();\n await sttStream?.cancel();\n } catch (e) {\n this.logger.debug('createSttTask: error during abort handler:', e);\n }\n });\n\n try {\n while (true) {\n if (signal.aborted) break;\n\n const { done, value: ev } = await reader.read();\n if (done) break;\n\n if (typeof ev === 'string') {\n throw new Error('STT node must yield SpeechEvent');\n } else {\n await this.onSTTEvent(ev);\n }\n }\n } catch (e) {\n if (isStreamReaderReleaseError(e)) {\n return;\n }\n this.logger.error({ error: e }, 'createSttTask: error reading sttStream');\n } finally {\n reader.releaseLock();\n try {\n await sttStream.cancel();\n } catch (e) {\n this.logger.debug(\n 'createSttTask: error cancelling sttStream (may already be cancelled):',\n e,\n );\n }\n }\n }\n }\n\n private async createVadTask(vad: VAD | undefined, signal: AbortSignal) {\n if (!vad) return;\n\n const vadStream = vad.stream();\n vadStream.updateInputStream(this.vadInputStream);\n\n const abortHandler = () => {\n vadStream.detachInputStream();\n vadStream.close();\n signal.removeEventListener('abort', abortHandler);\n };\n signal.addEventListener('abort', abortHandler);\n\n try {\n for await (const ev of vadStream) {\n if (signal.aborted) break;\n\n switch (ev.type) {\n case VADEventType.START_OF_SPEECH:\n this.logger.debug('VAD task: START_OF_SPEECH');\n this.hooks.onStartOfSpeech(ev);\n this.speaking = true;\n\n this.bounceEOUTask?.cancel();\n break;\n case VADEventType.INFERENCE_DONE:\n this.hooks.onVADInferenceDone(ev);\n break;\n case VADEventType.END_OF_SPEECH:\n this.logger.debug('VAD task: END_OF_SPEECH');\n this.hooks.onEndOfSpeech(ev);\n this.speaking = false;\n // when VAD fires END_OF_SPEECH, it already waited for the silence_duration\n this.lastSpeakingTime = Date.now() - ev.silenceDuration;\n\n if (\n this.vadBaseTurnDetection ||\n (this.turnDetectionMode === 'stt' && this.userTurnCommitted)\n ) {\n const chatCtx = this.hooks.retrieveChatCtx();\n this.runEOUDetection(chatCtx);\n }\n break;\n }\n }\n } catch (e) {\n this.logger.error(e, 'Error in VAD task');\n } finally {\n this.logger.debug('VAD task closed');\n }\n }\n\n setInputAudioStream(audioStream: ReadableStream<AudioFrame>) {\n this.deferredInputStream.setSource(audioStream);\n }\n\n detachInputAudioStream() {\n this.deferredInputStream.detachSource();\n }\n\n clearUserTurn() {\n this.audioTranscript = '';\n this.audioInterimTranscript = '';\n this.userTurnCommitted = false;\n\n this.sttTask?.cancelAndWait().finally(() => {\n this.sttTask = Task.from(({ signal }) => this.createSttTask(this.stt, signal));\n this.sttTask.result.catch((err) => {\n this.logger.error(`Error running STT task: ${err}`);\n });\n });\n }\n\n commitUserTurn(audioDetached: boolean) {\n const commitUserTurnTask =\n (delayDuration: number = 500) =>\n async (controller: AbortController) => {\n if (Date.now() - this.lastFinalTranscriptTime > delayDuration) {\n // flush the stt by pushing silence\n if (audioDetached && this.sampleRate !== undefined) {\n const numSamples = Math.floor(this.sampleRate * 0.5);\n const silence = new Int16Array(numSamples * 2);\n const silenceFrame = new AudioFrame(silence, this.sampleRate, 1, numSamples);\n this.silenceAudioWriter.write(silenceFrame);\n }\n\n // wait for the final transcript to be available\n await delay(delayDuration, { signal: controller.signal });\n }\n\n if (this.audioInterimTranscript) {\n // append interim transcript in case the final transcript is not ready\n this.audioTranscript = `${this.audioTranscript} ${this.audioInterimTranscript}`.trim();\n }\n this.audioInterimTranscript = '';\n\n const chatCtx = this.hooks.retrieveChatCtx();\n this.logger.debug('running EOU detection on commitUserTurn');\n this.runEOUDetection(chatCtx);\n this.userTurnCommitted = true;\n };\n\n // cancel any existing commit user turn task\n this.commitUserTurnTask?.cancel();\n this.commitUserTurnTask = Task.from(commitUserTurnTask());\n\n this.commitUserTurnTask.result\n .then(() => {\n this.logger.debug('User turn committed');\n })\n .catch((err: unknown) => {\n this.logger.error(err, 'Error in user turn commit task:');\n });\n }\n\n async close() {\n this.detachInputAudioStream();\n await this.commitUserTurnTask?.cancelAndWait();\n await this.sttTask?.cancelAndWait();\n await this.vadTask?.cancelAndWait();\n await this.bounceEOUTask?.cancelAndWait();\n }\n\n private get vadBaseTurnDetection() {\n return ['vad', undefined].includes(this.turnDetectionMode);\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/voice/audio_recognition.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { AudioFrame } from '@livekit/rtc-node';\nimport type { WritableStreamDefaultWriter } from 'node:stream/web';\nimport { ReadableStream } from 'node:stream/web';\nimport { type ChatContext } from '../llm/chat_context.js';\nimport { log } from '../log.js';\nimport { DeferredReadableStream, isStreamReaderReleaseError } from '../stream/deferred_stream.js';\nimport { IdentityTransform } from '../stream/identity_transform.js';\nimport { mergeReadableStreams } from '../stream/merge_readable_streams.js';\nimport { type SpeechEvent, SpeechEventType } from '../stt/stt.js';\nimport { Task, delay } from '../utils.js';\nimport { type VAD, type VADEvent, VADEventType } from '../vad.js';\nimport type { TurnDetectionMode } from './agent_session.js';\nimport type { STTNode } from './io.js';\n\nexport interface EndOfTurnInfo {\n newTranscript: string;\n transcriptionDelay: number;\n endOfUtteranceDelay: number;\n}\n\nexport interface RecognitionHooks {\n onStartOfSpeech: (ev: VADEvent) => void;\n onVADInferenceDone: (ev: VADEvent) => void;\n onEndOfSpeech: (ev: VADEvent) => void;\n onInterimTranscript: (ev: SpeechEvent) => void;\n onFinalTranscript: (ev: SpeechEvent) => void;\n onEndOfTurn: (info: EndOfTurnInfo) => Promise<boolean>;\n\n retrieveChatCtx: () => ChatContext;\n}\n\nexport interface _TurnDetector {\n unlikelyThreshold: (language?: string) => Promise<number | undefined>;\n supportsLanguage: (language?: string) => Promise<boolean>;\n predictEndOfTurn(chatCtx: ChatContext): Promise<number>;\n}\n\nexport interface AudioRecognitionOptions {\n recognitionHooks: RecognitionHooks;\n stt?: STTNode;\n vad?: VAD;\n turnDetector?: _TurnDetector;\n turnDetectionMode?: Exclude<TurnDetectionMode, _TurnDetector>;\n minEndpointingDelay: number;\n maxEndpointingDelay: number;\n}\n\nexport class AudioRecognition {\n private hooks: RecognitionHooks;\n private stt?: STTNode;\n private vad?: VAD;\n private turnDetector?: _TurnDetector;\n private turnDetectionMode?: Exclude<TurnDetectionMode, _TurnDetector>;\n private minEndpointingDelay: number;\n private maxEndpointingDelay: number;\n private lastLanguage?: string;\n\n private deferredInputStream: DeferredReadableStream<AudioFrame>;\n private logger = log();\n private lastFinalTranscriptTime = 0;\n private audioTranscript = '';\n private audioInterimTranscript = '';\n private lastSpeakingTime = 0;\n private userTurnCommitted = false;\n private speaking = false;\n private sampleRate?: number;\n\n private vadInputStream: ReadableStream<AudioFrame>;\n private sttInputStream: ReadableStream<AudioFrame>;\n private silenceAudioTransform = new IdentityTransform<AudioFrame>();\n private silenceAudioWriter: WritableStreamDefaultWriter<AudioFrame>;\n\n // all cancellable tasks\n private bounceEOUTask?: Task<void>;\n private commitUserTurnTask?: Task<void>;\n private vadTask?: Task<void>;\n private sttTask?: Task<void>;\n\n constructor(opts: AudioRecognitionOptions) {\n this.hooks = opts.recognitionHooks;\n this.stt = opts.stt;\n this.vad = opts.vad;\n this.turnDetector = opts.turnDetector;\n this.turnDetectionMode = opts.turnDetectionMode;\n this.minEndpointingDelay = opts.minEndpointingDelay;\n this.maxEndpointingDelay = opts.maxEndpointingDelay;\n this.lastLanguage = undefined;\n\n this.deferredInputStream = new DeferredReadableStream<AudioFrame>();\n const [vadInputStream, sttInputStream] = this.deferredInputStream.stream.tee();\n this.vadInputStream = vadInputStream;\n this.sttInputStream = mergeReadableStreams(sttInputStream, this.silenceAudioTransform.readable);\n this.silenceAudioWriter = this.silenceAudioTransform.writable.getWriter();\n }\n\n /**\n * Current transcript of the user's speech, including interim transcript if available.\n */\n get currentTranscript(): string {\n if (this.audioInterimTranscript) {\n return `${this.audioTranscript} ${this.audioInterimTranscript}`.trim();\n }\n return this.audioTranscript;\n }\n\n async start() {\n this.vadTask = Task.from(({ signal }) => this.createVadTask(this.vad, signal));\n this.vadTask.result.catch((err) => {\n this.logger.error(`Error running VAD task: ${err}`);\n });\n\n this.sttTask = Task.from(({ signal }) => this.createSttTask(this.stt, signal));\n this.sttTask.result.catch((err) => {\n this.logger.error(`Error running STT task: ${err}`);\n });\n }\n\n private async onSTTEvent(ev: SpeechEvent) {\n if (\n this.turnDetectionMode === 'manual' &&\n this.userTurnCommitted &&\n (this.bounceEOUTask === undefined ||\n this.bounceEOUTask.done ||\n ev.type == SpeechEventType.INTERIM_TRANSCRIPT)\n ) {\n // ignore stt event if user turn already committed and EOU task is done\n // or it's an interim transcript\n this.logger.debug(\n {\n userTurnCommitted: this.userTurnCommitted,\n eouTaskDone: this.bounceEOUTask?.done,\n evType: ev.type,\n turnDetectionMode: this.turnDetectionMode,\n },\n 'ignoring stt event',\n );\n return;\n }\n\n switch (ev.type) {\n case SpeechEventType.FINAL_TRANSCRIPT:\n this.hooks.onFinalTranscript(ev);\n const transcript = ev.alternatives?.[0]?.text;\n this.lastLanguage = ev.alternatives?.[0]?.language;\n\n if (!transcript) {\n // stt final transcript received but no transcript\n return;\n }\n\n this.logger.debug(\n {\n user_transcript: transcript,\n language: this.lastLanguage,\n },\n 'received user transcript',\n );\n\n this.lastFinalTranscriptTime = Date.now();\n this.audioTranscript += ` ${transcript}`;\n this.audioTranscript = this.audioTranscript.trimStart();\n this.audioInterimTranscript = '';\n\n if (!this.speaking) {\n if (!this.vad) {\n // Copied from python agents:\n // vad disabled, use stt timestamp\n // TODO: this would screw up transcription latency metrics\n // but we'll live with it for now.\n // the correct way is to ensure STT fires SpeechEventType.END_OF_SPEECH\n // and using that timestamp for _last_speaking_time\n this.lastSpeakingTime = Date.now();\n }\n\n if (this.vadBaseTurnDetection || this.userTurnCommitted) {\n const chatCtx = this.hooks.retrieveChatCtx();\n this.logger.debug('running EOU detection on stt FINAL_TRANSCRIPT');\n this.runEOUDetection(chatCtx);\n }\n }\n break;\n case SpeechEventType.INTERIM_TRANSCRIPT:\n this.logger.debug({ transcript: ev.alternatives?.[0]?.text }, 'interim transcript');\n this.hooks.onInterimTranscript(ev);\n this.audioInterimTranscript = ev.alternatives?.[0]?.text ?? '';\n break;\n case SpeechEventType.END_OF_SPEECH:\n if (this.turnDetectionMode !== 'stt') break;\n this.userTurnCommitted = true;\n\n if (!this.speaking) {\n const chatCtx = this.hooks.retrieveChatCtx();\n this.logger.debug('running EOU detection on stt END_OF_SPEECH');\n this.runEOUDetection(chatCtx);\n }\n }\n }\n\n private runEOUDetection(chatCtx: ChatContext) {\n this.logger.debug(\n {\n stt: this.stt,\n audioTranscript: this.audioTranscript,\n turnDetectionMode: this.turnDetectionMode,\n },\n 'running EOU detection',\n );\n\n if (this.stt && !this.audioTranscript && this.turnDetectionMode !== 'manual') {\n // stt enabled but no transcript yet\n this.logger.debug('skipping EOU detection');\n return;\n }\n\n chatCtx = chatCtx.copy();\n chatCtx.addMessage({ role: 'user', content: this.audioTranscript });\n\n const turnDetector =\n // disable EOU model if manual turn detection enabled\n this.audioTranscript && this.turnDetectionMode !== 'manual' ? this.turnDetector : undefined;\n\n const bounceEOUTask = (lastSpeakingTime: number) => async (controller: AbortController) => {\n let endpointingDelay = this.minEndpointingDelay;\n\n // TODO(AJS-74): need to support actual turn detection model plugins for following code to run\n if (turnDetector) {\n this.logger.debug('Running turn detector model');\n if (!turnDetector.supportsLanguage(this.lastLanguage)) {\n this.logger.debug(`Turn detector does not support language ${this.lastLanguage}`);\n } else {\n const endOfTurnProbability = await turnDetector.predictEndOfTurn(chatCtx);\n this.logger.debug(\n { endOfTurnProbability, language: this.lastLanguage },\n 'end of turn probability',\n );\n\n const unlikelyThreshold = await turnDetector.unlikelyThreshold(this.lastLanguage);\n this.logger.debug(\n {\n unlikelyThreshold,\n endOfTurnProbability,\n language: this.lastLanguage,\n transcript: this.audioTranscript,\n },\n 'EOU Detection',\n );\n\n if (unlikelyThreshold && endOfTurnProbability < unlikelyThreshold) {\n endpointingDelay = this.maxEndpointingDelay;\n }\n }\n }\n\n const extraSleep = lastSpeakingTime + endpointingDelay - Date.now();\n // add delay to see if there's a potential upcoming EOU task that cancels this one\n await delay(Math.max(extraSleep, 0), { signal: controller.signal });\n\n this.logger.debug({ transcript: this.audioTranscript }, 'end of user turn');\n\n const committed = await this.hooks.onEndOfTurn({\n newTranscript: this.audioTranscript,\n transcriptionDelay: Math.max(this.lastFinalTranscriptTime - lastSpeakingTime, 0),\n endOfUtteranceDelay: Date.now() - lastSpeakingTime,\n });\n\n if (committed) {\n // clear the transcript if the user turn was committed\n this.audioTranscript = '';\n }\n\n this.userTurnCommitted = false;\n };\n\n // cancel any existing EOU task\n this.bounceEOUTask?.cancel();\n this.bounceEOUTask = Task.from(bounceEOUTask(this.lastSpeakingTime));\n\n this.bounceEOUTask.result\n .then(() => {\n this.logger.debug('EOU detection task completed');\n })\n .catch((err: unknown) => {\n if (err instanceof Error && err.message.includes('This operation was aborted')) {\n // ignore aborted errors\n return;\n }\n this.logger.error(err, 'Error in EOU detection task:');\n });\n }\n\n private async createSttTask(stt: STTNode | undefined, signal: AbortSignal) {\n if (!stt) return;\n\n this.logger.debug('createSttTask: create stt stream from stt node');\n\n const sttStream = await stt(this.sttInputStream, {});\n\n if (signal.aborted || sttStream === null) return;\n\n if (sttStream instanceof ReadableStream) {\n const reader = sttStream.getReader();\n\n signal.addEventListener('abort', async () => {\n try {\n reader.releaseLock();\n await sttStream?.cancel();\n } catch (e) {\n this.logger.debug('createSttTask: error during abort handler:', e);\n }\n });\n\n try {\n while (true) {\n if (signal.aborted) break;\n\n const { done, value: ev } = await reader.read();\n if (done) break;\n\n if (typeof ev === 'string') {\n throw new Error('STT node must yield SpeechEvent');\n } else {\n await this.onSTTEvent(ev);\n }\n }\n } catch (e) {\n if (isStreamReaderReleaseError(e)) {\n return;\n }\n this.logger.error({ error: e }, 'createSttTask: error reading sttStream');\n } finally {\n reader.releaseLock();\n try {\n await sttStream.cancel();\n } catch (e) {\n this.logger.debug(\n 'createSttTask: error cancelling sttStream (may already be cancelled):',\n e,\n );\n }\n }\n }\n }\n\n private async createVadTask(vad: VAD | undefined, signal: AbortSignal) {\n if (!vad) return;\n\n const vadStream = vad.stream();\n vadStream.updateInputStream(this.vadInputStream);\n\n const abortHandler = () => {\n vadStream.detachInputStream();\n vadStream.close();\n signal.removeEventListener('abort', abortHandler);\n };\n signal.addEventListener('abort', abortHandler);\n\n try {\n for await (const ev of vadStream) {\n if (signal.aborted) break;\n\n switch (ev.type) {\n case VADEventType.START_OF_SPEECH:\n this.logger.debug('VAD task: START_OF_SPEECH');\n this.hooks.onStartOfSpeech(ev);\n this.speaking = true;\n\n this.bounceEOUTask?.cancel();\n break;\n case VADEventType.INFERENCE_DONE:\n this.hooks.onVADInferenceDone(ev);\n break;\n case VADEventType.END_OF_SPEECH:\n this.logger.debug('VAD task: END_OF_SPEECH');\n this.hooks.onEndOfSpeech(ev);\n this.speaking = false;\n // when VAD fires END_OF_SPEECH, it already waited for the silence_duration\n this.lastSpeakingTime = Date.now() - ev.silenceDuration;\n\n if (\n this.vadBaseTurnDetection ||\n (this.turnDetectionMode === 'stt' && this.userTurnCommitted)\n ) {\n const chatCtx = this.hooks.retrieveChatCtx();\n this.runEOUDetection(chatCtx);\n }\n break;\n }\n }\n } catch (e) {\n this.logger.error(e, 'Error in VAD task');\n } finally {\n this.logger.debug('VAD task closed');\n }\n }\n\n setInputAudioStream(audioStream: ReadableStream<AudioFrame>) {\n this.deferredInputStream.setSource(audioStream);\n }\n\n detachInputAudioStream() {\n this.deferredInputStream.detachSource();\n }\n\n clearUserTurn() {\n this.audioTranscript = '';\n this.audioInterimTranscript = '';\n this.userTurnCommitted = false;\n\n this.sttTask?.cancelAndWait().finally(() => {\n this.sttTask = Task.from(({ signal }) => this.createSttTask(this.stt, signal));\n this.sttTask.result.catch((err) => {\n this.logger.error(`Error running STT task: ${err}`);\n });\n });\n }\n\n commitUserTurn(audioDetached: boolean) {\n const commitUserTurnTask =\n (delayDuration: number = 500) =>\n async (controller: AbortController) => {\n if (Date.now() - this.lastFinalTranscriptTime > delayDuration) {\n // flush the stt by pushing silence\n if (audioDetached && this.sampleRate !== undefined) {\n const numSamples = Math.floor(this.sampleRate * 0.5);\n const silence = new Int16Array(numSamples * 2);\n const silenceFrame = new AudioFrame(silence, this.sampleRate, 1, numSamples);\n this.silenceAudioWriter.write(silenceFrame);\n }\n\n // wait for the final transcript to be available\n await delay(delayDuration, { signal: controller.signal });\n }\n\n if (this.audioInterimTranscript) {\n // append interim transcript in case the final transcript is not ready\n this.audioTranscript = `${this.audioTranscript} ${this.audioInterimTranscript}`.trim();\n }\n this.audioInterimTranscript = '';\n\n const chatCtx = this.hooks.retrieveChatCtx();\n this.logger.debug('running EOU detection on commitUserTurn');\n this.runEOUDetection(chatCtx);\n this.userTurnCommitted = true;\n };\n\n // cancel any existing commit user turn task\n this.commitUserTurnTask?.cancel();\n this.commitUserTurnTask = Task.from(commitUserTurnTask());\n\n this.commitUserTurnTask.result\n .then(() => {\n this.logger.debug('User turn committed');\n })\n .catch((err: unknown) => {\n this.logger.error(err, 'Error in user turn commit task:');\n });\n }\n\n async close() {\n this.detachInputAudioStream();\n await this.commitUserTurnTask?.cancelAndWait();\n await this.sttTask?.cancelAndWait();\n await this.vadTask?.cancelAndWait();\n await this.bounceEOUTask?.cancelAndWait();\n }\n\n private get vadBaseTurnDetection() {\n return ['vad', undefined].includes(this.turnDetectionMode);\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio_recognition.d.ts","sourceRoot":"","sources":["../../src/voice/audio_recognition.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"audio_recognition.d.ts","sourceRoot":"","sources":["../../src/voice/audio_recognition.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AudioFrame } from "@livekit/rtc-node";
|
|
2
|
-
import { delay } from "@std/async";
|
|
3
2
|
import { ReadableStream } from "node:stream/web";
|
|
4
3
|
import {} from "../llm/chat_context.js";
|
|
5
4
|
import { log } from "../log.js";
|
|
@@ -7,7 +6,7 @@ import { DeferredReadableStream, isStreamReaderReleaseError } from "../stream/de
|
|
|
7
6
|
import { IdentityTransform } from "../stream/identity_transform.js";
|
|
8
7
|
import { mergeReadableStreams } from "../stream/merge_readable_streams.js";
|
|
9
8
|
import { SpeechEventType } from "../stt/stt.js";
|
|
10
|
-
import { Task } from "../utils.js";
|
|
9
|
+
import { Task, delay } from "../utils.js";
|
|
11
10
|
import { VADEventType } from "../vad.js";
|
|
12
11
|
class AudioRecognition {
|
|
13
12
|
hooks;
|