@livekit/agents 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/_exceptions.cjs.map +1 -1
  2. package/dist/_exceptions.d.ts.map +1 -1
  3. package/dist/_exceptions.js.map +1 -1
  4. package/dist/audio.cjs +10 -0
  5. package/dist/audio.cjs.map +1 -1
  6. package/dist/audio.d.cts +1 -1
  7. package/dist/audio.d.ts +1 -1
  8. package/dist/audio.d.ts.map +1 -1
  9. package/dist/audio.js +10 -0
  10. package/dist/audio.js.map +1 -1
  11. package/dist/beta/workflows/task_group.cjs +7 -4
  12. package/dist/beta/workflows/task_group.cjs.map +1 -1
  13. package/dist/beta/workflows/task_group.d.ts.map +1 -1
  14. package/dist/beta/workflows/task_group.js +7 -4
  15. package/dist/beta/workflows/task_group.js.map +1 -1
  16. package/dist/inference/api_protos.d.cts +26 -26
  17. package/dist/inference/api_protos.d.ts +26 -26
  18. package/dist/inference/interruption/http_transport.cjs.map +1 -1
  19. package/dist/inference/interruption/http_transport.d.cts +3 -1
  20. package/dist/inference/interruption/http_transport.d.ts +3 -1
  21. package/dist/inference/interruption/http_transport.d.ts.map +1 -1
  22. package/dist/inference/interruption/http_transport.js.map +1 -1
  23. package/dist/inference/interruption/ws_transport.cjs +37 -32
  24. package/dist/inference/interruption/ws_transport.cjs.map +1 -1
  25. package/dist/inference/interruption/ws_transport.d.ts.map +1 -1
  26. package/dist/inference/interruption/ws_transport.js +37 -32
  27. package/dist/inference/interruption/ws_transport.js.map +1 -1
  28. package/dist/inference/tts.cjs +14 -1
  29. package/dist/inference/tts.cjs.map +1 -1
  30. package/dist/inference/tts.d.cts +42 -4
  31. package/dist/inference/tts.d.ts +42 -4
  32. package/dist/inference/tts.d.ts.map +1 -1
  33. package/dist/inference/tts.js +24 -3
  34. package/dist/inference/tts.js.map +1 -1
  35. package/dist/inference/tts.test.cjs +72 -0
  36. package/dist/inference/tts.test.cjs.map +1 -1
  37. package/dist/inference/tts.test.js +72 -0
  38. package/dist/inference/tts.test.js.map +1 -1
  39. package/dist/ipc/job_proc_lazy_main.cjs +7 -2
  40. package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
  41. package/dist/ipc/job_proc_lazy_main.js +7 -2
  42. package/dist/ipc/job_proc_lazy_main.js.map +1 -1
  43. package/dist/ipc/supervised_proc.cjs +4 -1
  44. package/dist/ipc/supervised_proc.cjs.map +1 -1
  45. package/dist/ipc/supervised_proc.d.ts.map +1 -1
  46. package/dist/ipc/supervised_proc.js +4 -1
  47. package/dist/ipc/supervised_proc.js.map +1 -1
  48. package/dist/ipc/supervised_proc.test.cjs +82 -0
  49. package/dist/ipc/supervised_proc.test.cjs.map +1 -1
  50. package/dist/ipc/supervised_proc.test.js +82 -0
  51. package/dist/ipc/supervised_proc.test.js.map +1 -1
  52. package/dist/job.cjs +2 -1
  53. package/dist/job.cjs.map +1 -1
  54. package/dist/job.d.ts.map +1 -1
  55. package/dist/job.js +2 -1
  56. package/dist/job.js.map +1 -1
  57. package/dist/llm/chat_context.cjs +102 -31
  58. package/dist/llm/chat_context.cjs.map +1 -1
  59. package/dist/llm/chat_context.d.ts.map +1 -1
  60. package/dist/llm/chat_context.js +102 -31
  61. package/dist/llm/chat_context.js.map +1 -1
  62. package/dist/llm/chat_context.test.cjs +123 -5
  63. package/dist/llm/chat_context.test.cjs.map +1 -1
  64. package/dist/llm/chat_context.test.js +123 -5
  65. package/dist/llm/chat_context.test.js.map +1 -1
  66. package/dist/llm/fallback_adapter.cjs +2 -0
  67. package/dist/llm/fallback_adapter.cjs.map +1 -1
  68. package/dist/llm/fallback_adapter.d.ts.map +1 -1
  69. package/dist/llm/fallback_adapter.js +2 -0
  70. package/dist/llm/fallback_adapter.js.map +1 -1
  71. package/dist/llm/index.cjs +2 -0
  72. package/dist/llm/index.cjs.map +1 -1
  73. package/dist/llm/index.d.cts +1 -1
  74. package/dist/llm/index.d.ts +1 -1
  75. package/dist/llm/index.d.ts.map +1 -1
  76. package/dist/llm/index.js +2 -0
  77. package/dist/llm/index.js.map +1 -1
  78. package/dist/llm/utils.cjs +89 -0
  79. package/dist/llm/utils.cjs.map +1 -1
  80. package/dist/llm/utils.d.cts +8 -0
  81. package/dist/llm/utils.d.ts +8 -0
  82. package/dist/llm/utils.d.ts.map +1 -1
  83. package/dist/llm/utils.js +88 -0
  84. package/dist/llm/utils.js.map +1 -1
  85. package/dist/llm/utils.test.cjs +90 -0
  86. package/dist/llm/utils.test.cjs.map +1 -1
  87. package/dist/llm/utils.test.js +98 -2
  88. package/dist/llm/utils.test.js.map +1 -1
  89. package/dist/stt/stt.cjs +8 -0
  90. package/dist/stt/stt.cjs.map +1 -1
  91. package/dist/stt/stt.d.cts +8 -0
  92. package/dist/stt/stt.d.ts +8 -0
  93. package/dist/stt/stt.d.ts.map +1 -1
  94. package/dist/stt/stt.js +8 -0
  95. package/dist/stt/stt.js.map +1 -1
  96. package/dist/tts/fallback_adapter.cjs +6 -0
  97. package/dist/tts/fallback_adapter.cjs.map +1 -1
  98. package/dist/tts/fallback_adapter.d.ts.map +1 -1
  99. package/dist/tts/fallback_adapter.js +6 -0
  100. package/dist/tts/fallback_adapter.js.map +1 -1
  101. package/dist/typed_promise.cjs +48 -0
  102. package/dist/typed_promise.cjs.map +1 -0
  103. package/dist/typed_promise.d.cts +24 -0
  104. package/dist/typed_promise.d.ts +24 -0
  105. package/dist/typed_promise.d.ts.map +1 -0
  106. package/dist/typed_promise.js +28 -0
  107. package/dist/typed_promise.js.map +1 -0
  108. package/dist/utils.cjs +30 -2
  109. package/dist/utils.cjs.map +1 -1
  110. package/dist/utils.d.cts +18 -0
  111. package/dist/utils.d.ts +18 -0
  112. package/dist/utils.d.ts.map +1 -1
  113. package/dist/utils.js +27 -2
  114. package/dist/utils.js.map +1 -1
  115. package/dist/version.cjs +1 -1
  116. package/dist/version.js +1 -1
  117. package/dist/voice/agent_activity.cjs +10 -0
  118. package/dist/voice/agent_activity.cjs.map +1 -1
  119. package/dist/voice/agent_activity.d.ts.map +1 -1
  120. package/dist/voice/agent_activity.js +11 -0
  121. package/dist/voice/agent_activity.js.map +1 -1
  122. package/dist/voice/agent_session.cjs +1 -1
  123. package/dist/voice/agent_session.cjs.map +1 -1
  124. package/dist/voice/agent_session.d.cts +4 -2
  125. package/dist/voice/agent_session.d.ts +4 -2
  126. package/dist/voice/agent_session.d.ts.map +1 -1
  127. package/dist/voice/agent_session.js +1 -1
  128. package/dist/voice/agent_session.js.map +1 -1
  129. package/dist/voice/events.cjs +11 -0
  130. package/dist/voice/events.cjs.map +1 -1
  131. package/dist/voice/events.d.cts +12 -1
  132. package/dist/voice/events.d.ts +12 -1
  133. package/dist/voice/events.d.ts.map +1 -1
  134. package/dist/voice/events.js +10 -0
  135. package/dist/voice/events.js.map +1 -1
  136. package/dist/voice/generation.cjs +23 -4
  137. package/dist/voice/generation.cjs.map +1 -1
  138. package/dist/voice/generation.d.ts.map +1 -1
  139. package/dist/voice/generation.js +32 -5
  140. package/dist/voice/generation.js.map +1 -1
  141. package/dist/voice/generation_tts_timeout.test.cjs +85 -0
  142. package/dist/voice/generation_tts_timeout.test.cjs.map +1 -0
  143. package/dist/voice/generation_tts_timeout.test.js +84 -0
  144. package/dist/voice/generation_tts_timeout.test.js.map +1 -0
  145. package/dist/voice/index.cjs.map +1 -1
  146. package/dist/voice/index.d.cts +1 -1
  147. package/dist/voice/index.d.ts +1 -1
  148. package/dist/voice/index.d.ts.map +1 -1
  149. package/dist/voice/index.js +3 -1
  150. package/dist/voice/index.js.map +1 -1
  151. package/dist/voice/recorder_io/recorder_io.cjs +1 -2
  152. package/dist/voice/recorder_io/recorder_io.cjs.map +1 -1
  153. package/dist/voice/recorder_io/recorder_io.d.ts.map +1 -1
  154. package/dist/voice/recorder_io/recorder_io.js +2 -3
  155. package/dist/voice/recorder_io/recorder_io.js.map +1 -1
  156. package/dist/voice/report.cjs +1 -1
  157. package/dist/voice/report.cjs.map +1 -1
  158. package/dist/voice/report.js +1 -1
  159. package/dist/voice/report.js.map +1 -1
  160. package/dist/voice/report.test.cjs +70 -0
  161. package/dist/voice/report.test.cjs.map +1 -1
  162. package/dist/voice/report.test.js +70 -0
  163. package/dist/voice/report.test.js.map +1 -1
  164. package/dist/voice/room_io/room_io.cjs +5 -1
  165. package/dist/voice/room_io/room_io.cjs.map +1 -1
  166. package/dist/voice/room_io/room_io.d.ts.map +1 -1
  167. package/dist/voice/room_io/room_io.js +5 -1
  168. package/dist/voice/room_io/room_io.js.map +1 -1
  169. package/dist/voice/room_io/room_io.test.cjs +18 -0
  170. package/dist/voice/room_io/room_io.test.cjs.map +1 -0
  171. package/dist/voice/room_io/room_io.test.js +17 -0
  172. package/dist/voice/room_io/room_io.test.js.map +1 -0
  173. package/package.json +4 -2
  174. package/src/_exceptions.ts +5 -0
  175. package/src/audio.ts +12 -1
  176. package/src/beta/workflows/task_group.ts +14 -5
  177. package/src/inference/interruption/http_transport.ts +2 -1
  178. package/src/inference/interruption/ws_transport.ts +44 -34
  179. package/src/inference/tts.test.ts +87 -0
  180. package/src/inference/tts.ts +71 -9
  181. package/src/ipc/job_proc_lazy_main.ts +7 -2
  182. package/src/ipc/supervised_proc.test.ts +96 -0
  183. package/src/ipc/supervised_proc.ts +8 -1
  184. package/src/job.ts +1 -0
  185. package/src/llm/chat_context.test.ts +137 -5
  186. package/src/llm/chat_context.ts +119 -38
  187. package/src/llm/fallback_adapter.ts +5 -2
  188. package/src/llm/index.ts +2 -0
  189. package/src/llm/utils.test.ts +103 -2
  190. package/src/llm/utils.ts +128 -0
  191. package/src/stt/stt.ts +9 -1
  192. package/src/tts/fallback_adapter.ts +9 -2
  193. package/src/typed_promise.ts +67 -0
  194. package/src/utils.ts +45 -2
  195. package/src/voice/agent_activity.ts +11 -0
  196. package/src/voice/agent_session.ts +13 -7
  197. package/src/voice/events.ts +21 -0
  198. package/src/voice/generation.ts +35 -8
  199. package/src/voice/generation_tts_timeout.test.ts +112 -0
  200. package/src/voice/index.ts +6 -1
  201. package/src/voice/recorder_io/recorder_io.ts +2 -7
  202. package/src/voice/report.test.ts +78 -0
  203. package/src/voice/report.ts +1 -1
  204. package/src/voice/room_io/room_io.test.ts +38 -0
  205. package/src/voice/room_io/room_io.ts +7 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/llm/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport sharp from 'sharp';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport { ChatContext, ChatMessage, type ImageContent } from './chat_context.js';\nimport { computeChatCtxDiff, serializeImage } from './utils.js';\n\nfunction createChatMessage(\n id: string,\n content: string,\n role: 'user' | 'assistant' | 'system' = 'user',\n): ChatMessage {\n return ChatMessage.create({\n id,\n content,\n role,\n });\n}\n\nfunction createChatContext(messages: ChatMessage[]): ChatContext {\n const ctx = new ChatContext();\n for (const message of messages) {\n ctx.items.push(message);\n }\n return ctx;\n}\n\nfunction createImageContent(\n image: string | VideoFrame,\n inferenceDetail: 'auto' | 'high' | 'low' = 'auto',\n options?: {\n mimeType?: string;\n inferenceWidth?: number;\n inferenceHeight?: number;\n },\n): ImageContent {\n return {\n id: 'test-id',\n type: 'image_content',\n image,\n inferenceDetail,\n mimeType: options?.mimeType,\n inferenceWidth: options?.inferenceWidth,\n inferenceHeight: options?.inferenceHeight,\n _cache: {},\n };\n}\n\nasync function decodeImageToRaw(base64Data: string) {\n const imageBuffer = Buffer.from(base64Data, 'base64');\n const decodedImage = await sharp(imageBuffer).raw().toBuffer({ resolveWithObject: true });\n return { imageBuffer, decodedImage };\n}\n\nfunction createSolidColorFrame(\n width: number,\n height: number,\n color: { r: number; g: number; b: number; a?: number },\n bufferType: VideoBufferType = VideoBufferType.RGBA,\n): VideoFrame {\n const channels = bufferType === VideoBufferType.RGB24 ? 3 : 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = color.r;\n frameData[i + 1] = color.g;\n frameData[i + 2] = color.b;\n if (channels === 4 && color.a !== undefined) {\n frameData[i + 3] = color.a;\n }\n }\n\n return new VideoFrame(frameData, width, height, bufferType);\n}\n\nfunction createGradientFrame(width: number, height: number): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * channels;\n frameData[idx] = Math.floor((x / (width - 1)) * 255);\n frameData[idx + 1] = Math.floor((y / (height - 1)) * 255);\n frameData[idx + 2] = 128;\n frameData[idx + 3] = 255;\n }\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction createPatternFrame(width: number, height: number, patterns: number[][]): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < patterns.length; i++) {\n const offset = i * 4;\n const pattern = patterns[i]!;\n frameData[offset] = pattern[0]!;\n frameData[offset + 1] = pattern[1]!;\n frameData[offset + 2] = pattern[2]!;\n frameData[offset + 3] = pattern[3]!;\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction verifyPngHeader(imageBuffer: Buffer) {\n expect(imageBuffer[0]).toBe(0x89);\n expect(imageBuffer[1]).toBe(0x50);\n expect(imageBuffer[2]).toBe(0x4e);\n expect(imageBuffer[3]).toBe(0x47);\n}\n\nfunction expectPixel(\n data: Buffer,\n index: number,\n expected: { r: number; g: number; b: number; a: number },\n) {\n expect(data[index]).toBe(expected.r);\n expect(data[index + 1]).toBe(expected.g);\n expect(data[index + 2]).toBe(expected.b);\n expect(data[index + 3]).toBe(expected.a);\n}\n\ndescribe('computeChatCtxDiff', () => {\n it('should return empty operations for identical contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle empty old context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n [null, '1'], // first item goes to root\n ['1', '2'],\n ]);\n });\n\n it('should handle empty new context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1', '2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['2', '3']]);\n });\n\n it('should handle removing items from the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['3']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([[null, '1']]);\n });\n\n it('should handle removing items from the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items in the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['1', '2']]);\n });\n\n it('should handle removing items from the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle complex mixed operations', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 2, 3, 4]\n // New: [1, 5, 3, 6]\n // Remove: [2, 4]\n // Create: [5 after 1, 6 after 3]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg5, msg3, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([\n ['1', '5'],\n ['3', '6'],\n ]);\n });\n\n it('should handle reordering items', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n // Old: [1, 2, 3]\n // New: [3, 1, 2]\n // This should remove all and recreate in new order\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg3, msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n // Since order changed completely, should have some operations\n expect(result.toRemove.length + result.toCreate.length).toBeGreaterThan(0);\n });\n\n it('should handle identical single item contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n\n const oldCtx = createChatContext([msg1]);\n const newCtx = createChatContext([msg1]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle longest common subsequence correctly', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n\n // Old: [1, 2, 3, 4, 5]\n // New: [1, 3, 5]\n // LCS should be [1, 3, 5], remove [2, 4]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4, msg5]);\n const newCtx = createChatContext([msg1, msg3, msg5]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle interleaved additions and common subsequence', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 3, 5]\n // New: [1, 2, 3, 4, 5, 6]\n // LCS: [1, 3, 5], add [2 after 1, 4 after 3, 6 after 5]\n\n const oldCtx = createChatContext([msg1, msg3, msg5]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4, msg5, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n ['1', '2'],\n ['3', '4'],\n ['5', '6'],\n ]);\n });\n});\n\ndescribe('serializeImage', () => {\n let consoleWarnSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});\n vi.clearAllMocks();\n });\n\n describe('Data URL handling', () => {\n it('should serialize a valid JPEG data URL', async () => {\n const originalBase64 = '/9j/4AAQSkZJRg==';\n const imageContent = createImageContent(`data:image/jpeg;base64,${originalBase64}`, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: originalBase64,\n mimeType: 'image/jpeg',\n inferenceDetail: 'high',\n });\n\n expect(result.base64Data).toBe(originalBase64);\n });\n\n it('should serialize a valid PNG data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n 'low',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n inferenceDetail: 'low',\n });\n });\n\n it('should serialize a valid WebP data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAA',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'UklGRiQAAABXRUJQVlA4IBgAAAA',\n mimeType: 'image/webp',\n inferenceDetail: 'auto',\n });\n });\n\n it('should serialize a valid GIF data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n mimeType: 'image/gif',\n inferenceDetail: 'auto',\n });\n });\n\n it('should warn and use provided mimeType when it differs from data URL mime type', async () => {\n const imageContent = createImageContent('data:image/jpeg;base64,/9j/4AAQSkZJRg==', 'auto', {\n mimeType: 'image/png',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(consoleWarnSpy).toHaveBeenCalledWith(\n \"Provided mimeType 'image/png' does not match data URL mime type 'image/jpeg'. Using provided mimeType.\",\n );\n expect(result).toEqual({\n base64Data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n });\n\n it('should throw error for invalid data URL format', async () => {\n const imageContent = createImageContent('data:;base64,/9j/4AAQSkZJRg==', 'auto');\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Invalid data URL format');\n });\n\n it('should throw error for unsupported mime type', async () => {\n const imageContent = createImageContent(\n 'data:image/bmp;base64,Qk06AAAAAAAAADYAAAAoAAAA',\n 'auto',\n );\n\n await expect(serializeImage(imageContent)).rejects.toThrow(\n 'Unsupported mimeType image/bmp. Must be jpeg, png, webp, or gif',\n );\n });\n });\n\n describe('External URL handling', () => {\n it('should serialize an external URL without mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: undefined,\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n\n it('should serialize an external URL with mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'low', {\n mimeType: 'image/jpeg',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: 'image/jpeg',\n inferenceDetail: 'low',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n });\n\n describe('VideoFrame handling', () => {\n it('should serialize a VideoFrame without resize parameters', async () => {\n const width = 4;\n const height = 4;\n const videoFrame = createSolidColorFrame(width, height, { r: 255, g: 0, b: 0, a: 255 });\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n expect(result.base64Data).toBeDefined();\n expect(result.base64Data).toMatch(/^[A-Za-z0-9+/]+=*$/);\n expect(result.externalUrl).toBeUndefined();\n\n const { imageBuffer, decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n verifyPngHeader(imageBuffer);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n expect(decodedImage.info.channels).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expectPixel(decodedData, i, { r: 255, g: 0, b: 0, a: 255 });\n }\n });\n\n it('should serialize a VideoFrame with a gradient pattern', async () => {\n const width = 8;\n const height = 8;\n const videoFrame = createGradientFrame(width, height);\n const imageContent = createImageContent(videoFrame, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'high',\n });\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n\n const decodedData = decodedImage.data;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n const expectedR = Math.floor((x / (width - 1)) * 255);\n const expectedG = Math.floor((y / (height - 1)) * 255);\n\n expectPixel(decodedData, idx, { r: expectedR, g: expectedG, b: 128, a: 255 });\n }\n }\n });\n\n it('should preserve exact pixel data through serialization', async () => {\n const width = 2;\n const height = 2;\n\n const patterns = [\n [255, 0, 0, 255],\n [0, 255, 0, 255],\n [0, 0, 255, 255],\n [255, 255, 255, 255],\n ];\n\n const videoFrame = createPatternFrame(width, height, patterns);\n const imageContent = createImageContent(videoFrame, 'low');\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n const decoded = decodedImage.data;\n\n expectPixel(decoded, 0, { r: 255, g: 0, b: 0, a: 255 });\n expectPixel(decoded, 4, { r: 0, g: 255, b: 0, a: 255 });\n expectPixel(decoded, width * 4, { r: 0, g: 0, b: 255, a: 255 });\n expectPixel(decoded, (width + 1) * 4, { r: 255, g: 255, b: 255, a: 255 });\n });\n\n it('should handle resize parameters correctly', async () => {\n const width = 2;\n const height = 2;\n const videoFrame = createSolidColorFrame(width, height, { r: 100, g: 100, b: 100, a: 255 });\n\n const imageContent = createImageContent(videoFrame, 'auto', {\n inferenceWidth: 4,\n inferenceHeight: 4,\n });\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(4);\n expect(decodedImage.info.height).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expect(decodedData[i]).toBeCloseTo(100, -1);\n expect(decodedData[i + 1]).toBeCloseTo(100, -1);\n expect(decodedData[i + 2]).toBeCloseTo(100, -1);\n expect(decodedData[i + 3]).toBe(255);\n }\n });\n\n it('should handle RGB24 VideoBufferType correctly', async () => {\n const width = 2;\n const height = 2;\n const channels = 3;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = 255;\n frameData[i + 1] = 128;\n frameData[i + 2] = 64;\n }\n\n const videoFrame = new VideoFrame(frameData, width, height, VideoBufferType.RGB24);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.channels).toBeGreaterThanOrEqual(3);\n\n const decodedData = decodedImage.data;\n const decodedChannels = decodedImage.info.channels;\n\n for (let i = 0; i < decodedData.length; i += decodedChannels) {\n expect(decodedData[i]).toBe(255);\n expect(decodedData[i + 1]).toBe(128);\n expect(decodedData[i + 2]).toBe(64);\n if (decodedChannels === 4) {\n expect(decodedData[i + 3]).toBe(255);\n }\n }\n });\n\n it('should handle different RGBA-like formats correctly', async () => {\n const width = 1;\n const height = 1;\n const testFormats = [\n VideoBufferType.RGBA,\n VideoBufferType.BGRA,\n VideoBufferType.ARGB,\n VideoBufferType.ABGR,\n ];\n\n for (const format of testFormats) {\n const frameData = new Uint8Array([100, 150, 200, 250]);\n const videoFrame = new VideoFrame(frameData, width, height, format);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n expect(result.base64Data).toBeDefined();\n }\n });\n });\n\n describe('Error handling', () => {\n it('should throw error for unsupported image type', async () => {\n const imageContent = createImageContent(123 as any, 'auto'); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Unsupported image type');\n });\n });\n});\n"],"mappings":"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","names":["sharp"]}
1
+ {"version":3,"sources":["../../src/llm/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport sharp from 'sharp';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport {\n AgentHandoffItem,\n ChatContext,\n ChatMessage,\n FunctionCall,\n FunctionCallOutput,\n type ImageContent,\n} from './chat_context.js';\nimport { computeChatCtxDiff, formatChatHistory, serializeImage } from './utils.js';\n\nfunction createChatMessage(\n id: string,\n content: string,\n role: 'user' | 'assistant' | 'system' = 'user',\n): ChatMessage {\n return ChatMessage.create({\n id,\n content,\n role,\n });\n}\n\nfunction createChatContext(messages: ChatMessage[]): ChatContext {\n const ctx = new ChatContext();\n for (const message of messages) {\n ctx.items.push(message);\n }\n return ctx;\n}\n\nfunction createImageContent(\n image: string | VideoFrame,\n inferenceDetail: 'auto' | 'high' | 'low' = 'auto',\n options?: {\n mimeType?: string;\n inferenceWidth?: number;\n inferenceHeight?: number;\n },\n): ImageContent {\n return {\n id: 'test-id',\n type: 'image_content',\n image,\n inferenceDetail,\n mimeType: options?.mimeType,\n inferenceWidth: options?.inferenceWidth,\n inferenceHeight: options?.inferenceHeight,\n _cache: {},\n };\n}\n\nasync function decodeImageToRaw(base64Data: string) {\n const imageBuffer = Buffer.from(base64Data, 'base64');\n const decodedImage = await sharp(imageBuffer).raw().toBuffer({ resolveWithObject: true });\n return { imageBuffer, decodedImage };\n}\n\nfunction createSolidColorFrame(\n width: number,\n height: number,\n color: { r: number; g: number; b: number; a?: number },\n bufferType: VideoBufferType = VideoBufferType.RGBA,\n): VideoFrame {\n const channels = bufferType === VideoBufferType.RGB24 ? 3 : 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = color.r;\n frameData[i + 1] = color.g;\n frameData[i + 2] = color.b;\n if (channels === 4 && color.a !== undefined) {\n frameData[i + 3] = color.a;\n }\n }\n\n return new VideoFrame(frameData, width, height, bufferType);\n}\n\nfunction createGradientFrame(width: number, height: number): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * channels;\n frameData[idx] = Math.floor((x / (width - 1)) * 255);\n frameData[idx + 1] = Math.floor((y / (height - 1)) * 255);\n frameData[idx + 2] = 128;\n frameData[idx + 3] = 255;\n }\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction createPatternFrame(width: number, height: number, patterns: number[][]): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < patterns.length; i++) {\n const offset = i * 4;\n const pattern = patterns[i]!;\n frameData[offset] = pattern[0]!;\n frameData[offset + 1] = pattern[1]!;\n frameData[offset + 2] = pattern[2]!;\n frameData[offset + 3] = pattern[3]!;\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction verifyPngHeader(imageBuffer: Buffer) {\n expect(imageBuffer[0]).toBe(0x89);\n expect(imageBuffer[1]).toBe(0x50);\n expect(imageBuffer[2]).toBe(0x4e);\n expect(imageBuffer[3]).toBe(0x47);\n}\n\nfunction expectPixel(\n data: Buffer,\n index: number,\n expected: { r: number; g: number; b: number; a: number },\n) {\n expect(data[index]).toBe(expected.r);\n expect(data[index + 1]).toBe(expected.g);\n expect(data[index + 2]).toBe(expected.b);\n expect(data[index + 3]).toBe(expected.a);\n}\n\ndescribe('computeChatCtxDiff', () => {\n it('should return empty operations for identical contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle empty old context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n [null, '1'], // first item goes to root\n ['1', '2'],\n ]);\n });\n\n it('should handle empty new context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1', '2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['2', '3']]);\n });\n\n it('should handle removing items from the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['3']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([[null, '1']]);\n });\n\n it('should handle removing items from the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items in the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['1', '2']]);\n });\n\n it('should handle removing items from the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle complex mixed operations', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 2, 3, 4]\n // New: [1, 5, 3, 6]\n // Remove: [2, 4]\n // Create: [5 after 1, 6 after 3]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg5, msg3, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([\n ['1', '5'],\n ['3', '6'],\n ]);\n });\n\n it('should handle reordering items', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n // Old: [1, 2, 3]\n // New: [3, 1, 2]\n // This should remove all and recreate in new order\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg3, msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n // Since order changed completely, should have some operations\n expect(result.toRemove.length + result.toCreate.length).toBeGreaterThan(0);\n });\n\n it('should handle identical single item contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n\n const oldCtx = createChatContext([msg1]);\n const newCtx = createChatContext([msg1]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle longest common subsequence correctly', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n\n // Old: [1, 2, 3, 4, 5]\n // New: [1, 3, 5]\n // LCS should be [1, 3, 5], remove [2, 4]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4, msg5]);\n const newCtx = createChatContext([msg1, msg3, msg5]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle interleaved additions and common subsequence', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 3, 5]\n // New: [1, 2, 3, 4, 5, 6]\n // LCS: [1, 3, 5], add [2 after 1, 4 after 3, 6 after 5]\n\n const oldCtx = createChatContext([msg1, msg3, msg5]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4, msg5, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n ['1', '2'],\n ['3', '4'],\n ['5', '6'],\n ]);\n });\n});\n\ndescribe('formatChatHistory', () => {\n it('should format mixed chat history items for logging', () => {\n const ctx = new ChatContext([\n ChatMessage.create({\n id: 'msg_system',\n role: 'system',\n content: 'You are helpful.',\n createdAt: 1,\n }),\n ChatMessage.create({\n id: 'msg_user',\n role: 'user',\n content: [\n 'Show me my order',\n createImageContent('https://example.com/receipt.png'),\n { type: 'audio_content', frame: [], transcript: 'order 123' },\n ],\n createdAt: 2,\n }),\n FunctionCall.create({\n id: 'fn_call',\n callId: 'call_1',\n name: 'lookup_order',\n args: '{\"orderId\":\"123\"}',\n createdAt: 3,\n }),\n FunctionCallOutput.create({\n id: 'fn_output',\n callId: 'call_1',\n name: 'lookup_order',\n output: '{\"status\":\"shipped\",\"ok\":true}',\n isError: false,\n createdAt: 4,\n }),\n AgentHandoffItem.create({\n id: 'handoff',\n oldAgentId: 'support',\n newAgentId: 'returns',\n createdAt: 5,\n }),\n ]);\n\n expect(formatChatHistory(ctx)).toBe(\n [\n 'Chat history (5 items)',\n '',\n '[0] message system',\n ' You are helpful.',\n '',\n '[1] message user',\n ' Show me my order',\n ' [image url=https://example.com/receipt.png]',\n ' [audio transcript=\"order 123\"]',\n '',\n '[2] function_call lookup_order call_id=call_1',\n ' {',\n ' \"orderId\": \"123\"',\n ' }',\n '',\n '[3] function_call_output lookup_order call_id=call_1',\n ' {',\n ' \"status\": \"shipped\",',\n ' \"ok\": true',\n ' }',\n '',\n '[4] agent_handoff',\n ' support -> returns',\n ].join('\\n'),\n );\n });\n\n it('should optionally include ids and timestamps', () => {\n const ctx = new ChatContext([\n FunctionCallOutput.create({\n id: 'fn_output',\n callId: 'call_1',\n name: 'lookup_order',\n output: 'plain text error',\n isError: true,\n createdAt: 123.456,\n }),\n ]);\n\n expect(formatChatHistory(ctx, { includeIds: true, includeTimestamps: true })).toBe(\n [\n 'Chat history (1 items)',\n '',\n '[0] function_call_output lookup_order call_id=call_1 error=true id=fn_output created_at=123.456',\n ' plain text error',\n ].join('\\n'),\n );\n });\n});\n\ndescribe('serializeImage', () => {\n let consoleWarnSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});\n vi.clearAllMocks();\n });\n\n describe('Data URL handling', () => {\n it('should serialize a valid JPEG data URL', async () => {\n const originalBase64 = '/9j/4AAQSkZJRg==';\n const imageContent = createImageContent(`data:image/jpeg;base64,${originalBase64}`, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: originalBase64,\n mimeType: 'image/jpeg',\n inferenceDetail: 'high',\n });\n\n expect(result.base64Data).toBe(originalBase64);\n });\n\n it('should serialize a valid PNG data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n 'low',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n inferenceDetail: 'low',\n });\n });\n\n it('should serialize a valid WebP data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAA',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'UklGRiQAAABXRUJQVlA4IBgAAAA',\n mimeType: 'image/webp',\n inferenceDetail: 'auto',\n });\n });\n\n it('should serialize a valid GIF data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n mimeType: 'image/gif',\n inferenceDetail: 'auto',\n });\n });\n\n it('should warn and use provided mimeType when it differs from data URL mime type', async () => {\n const imageContent = createImageContent('data:image/jpeg;base64,/9j/4AAQSkZJRg==', 'auto', {\n mimeType: 'image/png',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(consoleWarnSpy).toHaveBeenCalledWith(\n \"Provided mimeType 'image/png' does not match data URL mime type 'image/jpeg'. Using provided mimeType.\",\n );\n expect(result).toEqual({\n base64Data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n });\n\n it('should throw error for invalid data URL format', async () => {\n const imageContent = createImageContent('data:;base64,/9j/4AAQSkZJRg==', 'auto');\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Invalid data URL format');\n });\n\n it('should throw error for unsupported mime type', async () => {\n const imageContent = createImageContent(\n 'data:image/bmp;base64,Qk06AAAAAAAAADYAAAAoAAAA',\n 'auto',\n );\n\n await expect(serializeImage(imageContent)).rejects.toThrow(\n 'Unsupported mimeType image/bmp. Must be jpeg, png, webp, or gif',\n );\n });\n });\n\n describe('External URL handling', () => {\n it('should serialize an external URL without mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: undefined,\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n\n it('should serialize an external URL with mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'low', {\n mimeType: 'image/jpeg',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: 'image/jpeg',\n inferenceDetail: 'low',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n });\n\n describe('VideoFrame handling', () => {\n it('should serialize a VideoFrame without resize parameters', async () => {\n const width = 4;\n const height = 4;\n const videoFrame = createSolidColorFrame(width, height, { r: 255, g: 0, b: 0, a: 255 });\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n expect(result.base64Data).toBeDefined();\n expect(result.base64Data).toMatch(/^[A-Za-z0-9+/]+=*$/);\n expect(result.externalUrl).toBeUndefined();\n\n const { imageBuffer, decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n verifyPngHeader(imageBuffer);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n expect(decodedImage.info.channels).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expectPixel(decodedData, i, { r: 255, g: 0, b: 0, a: 255 });\n }\n });\n\n it('should serialize a VideoFrame with a gradient pattern', async () => {\n const width = 8;\n const height = 8;\n const videoFrame = createGradientFrame(width, height);\n const imageContent = createImageContent(videoFrame, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'high',\n });\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n\n const decodedData = decodedImage.data;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n const expectedR = Math.floor((x / (width - 1)) * 255);\n const expectedG = Math.floor((y / (height - 1)) * 255);\n\n expectPixel(decodedData, idx, { r: expectedR, g: expectedG, b: 128, a: 255 });\n }\n }\n });\n\n it('should preserve exact pixel data through serialization', async () => {\n const width = 2;\n const height = 2;\n\n const patterns = [\n [255, 0, 0, 255],\n [0, 255, 0, 255],\n [0, 0, 255, 255],\n [255, 255, 255, 255],\n ];\n\n const videoFrame = createPatternFrame(width, height, patterns);\n const imageContent = createImageContent(videoFrame, 'low');\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n const decoded = decodedImage.data;\n\n expectPixel(decoded, 0, { r: 255, g: 0, b: 0, a: 255 });\n expectPixel(decoded, 4, { r: 0, g: 255, b: 0, a: 255 });\n expectPixel(decoded, width * 4, { r: 0, g: 0, b: 255, a: 255 });\n expectPixel(decoded, (width + 1) * 4, { r: 255, g: 255, b: 255, a: 255 });\n });\n\n it('should handle resize parameters correctly', async () => {\n const width = 2;\n const height = 2;\n const videoFrame = createSolidColorFrame(width, height, { r: 100, g: 100, b: 100, a: 255 });\n\n const imageContent = createImageContent(videoFrame, 'auto', {\n inferenceWidth: 4,\n inferenceHeight: 4,\n });\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(4);\n expect(decodedImage.info.height).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expect(decodedData[i]).toBeCloseTo(100, -1);\n expect(decodedData[i + 1]).toBeCloseTo(100, -1);\n expect(decodedData[i + 2]).toBeCloseTo(100, -1);\n expect(decodedData[i + 3]).toBe(255);\n }\n });\n\n it('should handle RGB24 VideoBufferType correctly', async () => {\n const width = 2;\n const height = 2;\n const channels = 3;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = 255;\n frameData[i + 1] = 128;\n frameData[i + 2] = 64;\n }\n\n const videoFrame = new VideoFrame(frameData, width, height, VideoBufferType.RGB24);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.channels).toBeGreaterThanOrEqual(3);\n\n const decodedData = decodedImage.data;\n const decodedChannels = decodedImage.info.channels;\n\n for (let i = 0; i < decodedData.length; i += decodedChannels) {\n expect(decodedData[i]).toBe(255);\n expect(decodedData[i + 1]).toBe(128);\n expect(decodedData[i + 2]).toBe(64);\n if (decodedChannels === 4) {\n expect(decodedData[i + 3]).toBe(255);\n }\n }\n });\n\n it('should handle different RGBA-like formats correctly', async () => {\n const width = 1;\n const height = 1;\n const testFormats = [\n VideoBufferType.RGBA,\n VideoBufferType.BGRA,\n VideoBufferType.ARGB,\n VideoBufferType.ABGR,\n ];\n\n for (const format of testFormats) {\n const frameData = new Uint8Array([100, 150, 200, 250]);\n const videoFrame = new VideoFrame(frameData, width, height, format);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n expect(result.base64Data).toBeDefined();\n }\n });\n });\n\n describe('Error handling', () => {\n it('should throw error for unsupported image type', async () => {\n const imageContent = createImageContent(123 as any, 'auto'); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Unsupported image type');\n });\n });\n});\n"],"mappings":"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","names":["sharp"]}
@@ -1,8 +1,14 @@
1
1
  import { VideoBufferType, VideoFrame } from "@livekit/rtc-node";
2
2
  import sharp from "sharp";
3
3
  import { beforeEach, describe, expect, it, vi } from "vitest";
4
- import { ChatContext, ChatMessage } from "./chat_context.js";
5
- import { computeChatCtxDiff, serializeImage } from "./utils.js";
4
+ import {
5
+ AgentHandoffItem,
6
+ ChatContext,
7
+ ChatMessage,
8
+ FunctionCall,
9
+ FunctionCallOutput
10
+ } from "./chat_context.js";
11
+ import { computeChatCtxDiff, formatChatHistory, serializeImage } from "./utils.js";
6
12
  function createChatMessage(id, content, role = "user") {
7
13
  return ChatMessage.create({
8
14
  id,
@@ -243,6 +249,96 @@ describe("computeChatCtxDiff", () => {
243
249
  ]);
244
250
  });
245
251
  });
252
+ describe("formatChatHistory", () => {
253
+ it("should format mixed chat history items for logging", () => {
254
+ const ctx = new ChatContext([
255
+ ChatMessage.create({
256
+ id: "msg_system",
257
+ role: "system",
258
+ content: "You are helpful.",
259
+ createdAt: 1
260
+ }),
261
+ ChatMessage.create({
262
+ id: "msg_user",
263
+ role: "user",
264
+ content: [
265
+ "Show me my order",
266
+ createImageContent("https://example.com/receipt.png"),
267
+ { type: "audio_content", frame: [], transcript: "order 123" }
268
+ ],
269
+ createdAt: 2
270
+ }),
271
+ FunctionCall.create({
272
+ id: "fn_call",
273
+ callId: "call_1",
274
+ name: "lookup_order",
275
+ args: '{"orderId":"123"}',
276
+ createdAt: 3
277
+ }),
278
+ FunctionCallOutput.create({
279
+ id: "fn_output",
280
+ callId: "call_1",
281
+ name: "lookup_order",
282
+ output: '{"status":"shipped","ok":true}',
283
+ isError: false,
284
+ createdAt: 4
285
+ }),
286
+ AgentHandoffItem.create({
287
+ id: "handoff",
288
+ oldAgentId: "support",
289
+ newAgentId: "returns",
290
+ createdAt: 5
291
+ })
292
+ ]);
293
+ expect(formatChatHistory(ctx)).toBe(
294
+ [
295
+ "Chat history (5 items)",
296
+ "",
297
+ "[0] message system",
298
+ " You are helpful.",
299
+ "",
300
+ "[1] message user",
301
+ " Show me my order",
302
+ " [image url=https://example.com/receipt.png]",
303
+ ' [audio transcript="order 123"]',
304
+ "",
305
+ "[2] function_call lookup_order call_id=call_1",
306
+ " {",
307
+ ' "orderId": "123"',
308
+ " }",
309
+ "",
310
+ "[3] function_call_output lookup_order call_id=call_1",
311
+ " {",
312
+ ' "status": "shipped",',
313
+ ' "ok": true',
314
+ " }",
315
+ "",
316
+ "[4] agent_handoff",
317
+ " support -> returns"
318
+ ].join("\n")
319
+ );
320
+ });
321
+ it("should optionally include ids and timestamps", () => {
322
+ const ctx = new ChatContext([
323
+ FunctionCallOutput.create({
324
+ id: "fn_output",
325
+ callId: "call_1",
326
+ name: "lookup_order",
327
+ output: "plain text error",
328
+ isError: true,
329
+ createdAt: 123.456
330
+ })
331
+ ]);
332
+ expect(formatChatHistory(ctx, { includeIds: true, includeTimestamps: true })).toBe(
333
+ [
334
+ "Chat history (1 items)",
335
+ "",
336
+ "[0] function_call_output lookup_order call_id=call_1 error=true id=fn_output created_at=123.456",
337
+ " plain text error"
338
+ ].join("\n")
339
+ );
340
+ });
341
+ });
246
342
  describe("serializeImage", () => {
247
343
  let consoleWarnSpy;
248
344
  beforeEach(() => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/llm/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport sharp from 'sharp';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport { ChatContext, ChatMessage, type ImageContent } from './chat_context.js';\nimport { computeChatCtxDiff, serializeImage } from './utils.js';\n\nfunction createChatMessage(\n id: string,\n content: string,\n role: 'user' | 'assistant' | 'system' = 'user',\n): ChatMessage {\n return ChatMessage.create({\n id,\n content,\n role,\n });\n}\n\nfunction createChatContext(messages: ChatMessage[]): ChatContext {\n const ctx = new ChatContext();\n for (const message of messages) {\n ctx.items.push(message);\n }\n return ctx;\n}\n\nfunction createImageContent(\n image: string | VideoFrame,\n inferenceDetail: 'auto' | 'high' | 'low' = 'auto',\n options?: {\n mimeType?: string;\n inferenceWidth?: number;\n inferenceHeight?: number;\n },\n): ImageContent {\n return {\n id: 'test-id',\n type: 'image_content',\n image,\n inferenceDetail,\n mimeType: options?.mimeType,\n inferenceWidth: options?.inferenceWidth,\n inferenceHeight: options?.inferenceHeight,\n _cache: {},\n };\n}\n\nasync function decodeImageToRaw(base64Data: string) {\n const imageBuffer = Buffer.from(base64Data, 'base64');\n const decodedImage = await sharp(imageBuffer).raw().toBuffer({ resolveWithObject: true });\n return { imageBuffer, decodedImage };\n}\n\nfunction createSolidColorFrame(\n width: number,\n height: number,\n color: { r: number; g: number; b: number; a?: number },\n bufferType: VideoBufferType = VideoBufferType.RGBA,\n): VideoFrame {\n const channels = bufferType === VideoBufferType.RGB24 ? 3 : 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = color.r;\n frameData[i + 1] = color.g;\n frameData[i + 2] = color.b;\n if (channels === 4 && color.a !== undefined) {\n frameData[i + 3] = color.a;\n }\n }\n\n return new VideoFrame(frameData, width, height, bufferType);\n}\n\nfunction createGradientFrame(width: number, height: number): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * channels;\n frameData[idx] = Math.floor((x / (width - 1)) * 255);\n frameData[idx + 1] = Math.floor((y / (height - 1)) * 255);\n frameData[idx + 2] = 128;\n frameData[idx + 3] = 255;\n }\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction createPatternFrame(width: number, height: number, patterns: number[][]): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < patterns.length; i++) {\n const offset = i * 4;\n const pattern = patterns[i]!;\n frameData[offset] = pattern[0]!;\n frameData[offset + 1] = pattern[1]!;\n frameData[offset + 2] = pattern[2]!;\n frameData[offset + 3] = pattern[3]!;\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction verifyPngHeader(imageBuffer: Buffer) {\n expect(imageBuffer[0]).toBe(0x89);\n expect(imageBuffer[1]).toBe(0x50);\n expect(imageBuffer[2]).toBe(0x4e);\n expect(imageBuffer[3]).toBe(0x47);\n}\n\nfunction expectPixel(\n data: Buffer,\n index: number,\n expected: { r: number; g: number; b: number; a: number },\n) {\n expect(data[index]).toBe(expected.r);\n expect(data[index + 1]).toBe(expected.g);\n expect(data[index + 2]).toBe(expected.b);\n expect(data[index + 3]).toBe(expected.a);\n}\n\ndescribe('computeChatCtxDiff', () => {\n it('should return empty operations for identical contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle empty old context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n [null, '1'], // first item goes to root\n ['1', '2'],\n ]);\n });\n\n it('should handle empty new context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1', '2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['2', '3']]);\n });\n\n it('should handle removing items from the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['3']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([[null, '1']]);\n });\n\n it('should handle removing items from the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items in the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['1', '2']]);\n });\n\n it('should handle removing items from the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle complex mixed operations', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 2, 3, 4]\n // New: [1, 5, 3, 6]\n // Remove: [2, 4]\n // Create: [5 after 1, 6 after 3]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg5, msg3, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([\n ['1', '5'],\n ['3', '6'],\n ]);\n });\n\n it('should handle reordering items', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n // Old: [1, 2, 3]\n // New: [3, 1, 2]\n // This should remove all and recreate in new order\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg3, msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n // Since order changed completely, should have some operations\n expect(result.toRemove.length + result.toCreate.length).toBeGreaterThan(0);\n });\n\n it('should handle identical single item contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n\n const oldCtx = createChatContext([msg1]);\n const newCtx = createChatContext([msg1]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle longest common subsequence correctly', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n\n // Old: [1, 2, 3, 4, 5]\n // New: [1, 3, 5]\n // LCS should be [1, 3, 5], remove [2, 4]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4, msg5]);\n const newCtx = createChatContext([msg1, msg3, msg5]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle interleaved additions and common subsequence', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 3, 5]\n // New: [1, 2, 3, 4, 5, 6]\n // LCS: [1, 3, 5], add [2 after 1, 4 after 3, 6 after 5]\n\n const oldCtx = createChatContext([msg1, msg3, msg5]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4, msg5, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n ['1', '2'],\n ['3', '4'],\n ['5', '6'],\n ]);\n });\n});\n\ndescribe('serializeImage', () => {\n let consoleWarnSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});\n vi.clearAllMocks();\n });\n\n describe('Data URL handling', () => {\n it('should serialize a valid JPEG data URL', async () => {\n const originalBase64 = '/9j/4AAQSkZJRg==';\n const imageContent = createImageContent(`data:image/jpeg;base64,${originalBase64}`, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: originalBase64,\n mimeType: 'image/jpeg',\n inferenceDetail: 'high',\n });\n\n expect(result.base64Data).toBe(originalBase64);\n });\n\n it('should serialize a valid PNG data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n 'low',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n inferenceDetail: 'low',\n });\n });\n\n it('should serialize a valid WebP data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAA',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'UklGRiQAAABXRUJQVlA4IBgAAAA',\n mimeType: 'image/webp',\n inferenceDetail: 'auto',\n });\n });\n\n it('should serialize a valid GIF data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n mimeType: 'image/gif',\n inferenceDetail: 'auto',\n });\n });\n\n it('should warn and use provided mimeType when it differs from data URL mime type', async () => {\n const imageContent = createImageContent('data:image/jpeg;base64,/9j/4AAQSkZJRg==', 'auto', {\n mimeType: 'image/png',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(consoleWarnSpy).toHaveBeenCalledWith(\n \"Provided mimeType 'image/png' does not match data URL mime type 'image/jpeg'. Using provided mimeType.\",\n );\n expect(result).toEqual({\n base64Data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n });\n\n it('should throw error for invalid data URL format', async () => {\n const imageContent = createImageContent('data:;base64,/9j/4AAQSkZJRg==', 'auto');\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Invalid data URL format');\n });\n\n it('should throw error for unsupported mime type', async () => {\n const imageContent = createImageContent(\n 'data:image/bmp;base64,Qk06AAAAAAAAADYAAAAoAAAA',\n 'auto',\n );\n\n await expect(serializeImage(imageContent)).rejects.toThrow(\n 'Unsupported mimeType image/bmp. Must be jpeg, png, webp, or gif',\n );\n });\n });\n\n describe('External URL handling', () => {\n it('should serialize an external URL without mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: undefined,\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n\n it('should serialize an external URL with mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'low', {\n mimeType: 'image/jpeg',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: 'image/jpeg',\n inferenceDetail: 'low',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n });\n\n describe('VideoFrame handling', () => {\n it('should serialize a VideoFrame without resize parameters', async () => {\n const width = 4;\n const height = 4;\n const videoFrame = createSolidColorFrame(width, height, { r: 255, g: 0, b: 0, a: 255 });\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n expect(result.base64Data).toBeDefined();\n expect(result.base64Data).toMatch(/^[A-Za-z0-9+/]+=*$/);\n expect(result.externalUrl).toBeUndefined();\n\n const { imageBuffer, decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n verifyPngHeader(imageBuffer);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n expect(decodedImage.info.channels).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expectPixel(decodedData, i, { r: 255, g: 0, b: 0, a: 255 });\n }\n });\n\n it('should serialize a VideoFrame with a gradient pattern', async () => {\n const width = 8;\n const height = 8;\n const videoFrame = createGradientFrame(width, height);\n const imageContent = createImageContent(videoFrame, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'high',\n });\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n\n const decodedData = decodedImage.data;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n const expectedR = Math.floor((x / (width - 1)) * 255);\n const expectedG = Math.floor((y / (height - 1)) * 255);\n\n expectPixel(decodedData, idx, { r: expectedR, g: expectedG, b: 128, a: 255 });\n }\n }\n });\n\n it('should preserve exact pixel data through serialization', async () => {\n const width = 2;\n const height = 2;\n\n const patterns = [\n [255, 0, 0, 255],\n [0, 255, 0, 255],\n [0, 0, 255, 255],\n [255, 255, 255, 255],\n ];\n\n const videoFrame = createPatternFrame(width, height, patterns);\n const imageContent = createImageContent(videoFrame, 'low');\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n const decoded = decodedImage.data;\n\n expectPixel(decoded, 0, { r: 255, g: 0, b: 0, a: 255 });\n expectPixel(decoded, 4, { r: 0, g: 255, b: 0, a: 255 });\n expectPixel(decoded, width * 4, { r: 0, g: 0, b: 255, a: 255 });\n expectPixel(decoded, (width + 1) * 4, { r: 255, g: 255, b: 255, a: 255 });\n });\n\n it('should handle resize parameters correctly', async () => {\n const width = 2;\n const height = 2;\n const videoFrame = createSolidColorFrame(width, height, { r: 100, g: 100, b: 100, a: 255 });\n\n const imageContent = createImageContent(videoFrame, 'auto', {\n inferenceWidth: 4,\n inferenceHeight: 4,\n });\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(4);\n expect(decodedImage.info.height).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expect(decodedData[i]).toBeCloseTo(100, -1);\n expect(decodedData[i + 1]).toBeCloseTo(100, -1);\n expect(decodedData[i + 2]).toBeCloseTo(100, -1);\n expect(decodedData[i + 3]).toBe(255);\n }\n });\n\n it('should handle RGB24 VideoBufferType correctly', async () => {\n const width = 2;\n const height = 2;\n const channels = 3;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = 255;\n frameData[i + 1] = 128;\n frameData[i + 2] = 64;\n }\n\n const videoFrame = new VideoFrame(frameData, width, height, VideoBufferType.RGB24);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.channels).toBeGreaterThanOrEqual(3);\n\n const decodedData = decodedImage.data;\n const decodedChannels = decodedImage.info.channels;\n\n for (let i = 0; i < decodedData.length; i += decodedChannels) {\n expect(decodedData[i]).toBe(255);\n expect(decodedData[i + 1]).toBe(128);\n expect(decodedData[i + 2]).toBe(64);\n if (decodedChannels === 4) {\n expect(decodedData[i + 3]).toBe(255);\n }\n }\n });\n\n it('should handle different RGBA-like formats correctly', async () => {\n const width = 1;\n const height = 1;\n const testFormats = [\n VideoBufferType.RGBA,\n VideoBufferType.BGRA,\n VideoBufferType.ARGB,\n VideoBufferType.ABGR,\n ];\n\n for (const format of testFormats) {\n const frameData = new Uint8Array([100, 150, 200, 250]);\n const videoFrame = new VideoFrame(frameData, width, height, format);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n expect(result.base64Data).toBeDefined();\n }\n });\n });\n\n describe('Error handling', () => {\n it('should throw error for unsupported image type', async () => {\n const imageContent = createImageContent(123 as any, 'auto'); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Unsupported image type');\n });\n });\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/llm/utils.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport sharp from 'sharp';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport {\n AgentHandoffItem,\n ChatContext,\n ChatMessage,\n FunctionCall,\n FunctionCallOutput,\n type ImageContent,\n} from './chat_context.js';\nimport { computeChatCtxDiff, formatChatHistory, serializeImage } from './utils.js';\n\nfunction createChatMessage(\n id: string,\n content: string,\n role: 'user' | 'assistant' | 'system' = 'user',\n): ChatMessage {\n return ChatMessage.create({\n id,\n content,\n role,\n });\n}\n\nfunction createChatContext(messages: ChatMessage[]): ChatContext {\n const ctx = new ChatContext();\n for (const message of messages) {\n ctx.items.push(message);\n }\n return ctx;\n}\n\nfunction createImageContent(\n image: string | VideoFrame,\n inferenceDetail: 'auto' | 'high' | 'low' = 'auto',\n options?: {\n mimeType?: string;\n inferenceWidth?: number;\n inferenceHeight?: number;\n },\n): ImageContent {\n return {\n id: 'test-id',\n type: 'image_content',\n image,\n inferenceDetail,\n mimeType: options?.mimeType,\n inferenceWidth: options?.inferenceWidth,\n inferenceHeight: options?.inferenceHeight,\n _cache: {},\n };\n}\n\nasync function decodeImageToRaw(base64Data: string) {\n const imageBuffer = Buffer.from(base64Data, 'base64');\n const decodedImage = await sharp(imageBuffer).raw().toBuffer({ resolveWithObject: true });\n return { imageBuffer, decodedImage };\n}\n\nfunction createSolidColorFrame(\n width: number,\n height: number,\n color: { r: number; g: number; b: number; a?: number },\n bufferType: VideoBufferType = VideoBufferType.RGBA,\n): VideoFrame {\n const channels = bufferType === VideoBufferType.RGB24 ? 3 : 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = color.r;\n frameData[i + 1] = color.g;\n frameData[i + 2] = color.b;\n if (channels === 4 && color.a !== undefined) {\n frameData[i + 3] = color.a;\n }\n }\n\n return new VideoFrame(frameData, width, height, bufferType);\n}\n\nfunction createGradientFrame(width: number, height: number): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * channels;\n frameData[idx] = Math.floor((x / (width - 1)) * 255);\n frameData[idx + 1] = Math.floor((y / (height - 1)) * 255);\n frameData[idx + 2] = 128;\n frameData[idx + 3] = 255;\n }\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction createPatternFrame(width: number, height: number, patterns: number[][]): VideoFrame {\n const channels = 4;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < patterns.length; i++) {\n const offset = i * 4;\n const pattern = patterns[i]!;\n frameData[offset] = pattern[0]!;\n frameData[offset + 1] = pattern[1]!;\n frameData[offset + 2] = pattern[2]!;\n frameData[offset + 3] = pattern[3]!;\n }\n\n return new VideoFrame(frameData, width, height, VideoBufferType.RGBA);\n}\n\nfunction verifyPngHeader(imageBuffer: Buffer) {\n expect(imageBuffer[0]).toBe(0x89);\n expect(imageBuffer[1]).toBe(0x50);\n expect(imageBuffer[2]).toBe(0x4e);\n expect(imageBuffer[3]).toBe(0x47);\n}\n\nfunction expectPixel(\n data: Buffer,\n index: number,\n expected: { r: number; g: number; b: number; a: number },\n) {\n expect(data[index]).toBe(expected.r);\n expect(data[index + 1]).toBe(expected.g);\n expect(data[index + 2]).toBe(expected.b);\n expect(data[index + 3]).toBe(expected.a);\n}\n\ndescribe('computeChatCtxDiff', () => {\n it('should return empty operations for identical contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle empty old context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n [null, '1'], // first item goes to root\n ['1', '2'],\n ]);\n });\n\n it('should handle empty new context', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1', '2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['2', '3']]);\n });\n\n it('should handle removing items from the end', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['3']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items to the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg2, msg3]);\n const newCtx = createChatContext([msg1, msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([[null, '1']]);\n });\n\n it('should handle removing items from the beginning', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg2, msg3]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['1']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle adding items in the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([['1', '2']]);\n });\n\n it('should handle removing items from the middle', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg3, msg4]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle complex mixed operations', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 2, 3, 4]\n // New: [1, 5, 3, 6]\n // Remove: [2, 4]\n // Create: [5 after 1, 6 after 3]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4]);\n const newCtx = createChatContext([msg1, msg5, msg3, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([\n ['1', '5'],\n ['3', '6'],\n ]);\n });\n\n it('should handle reordering items', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n\n // Old: [1, 2, 3]\n // New: [3, 1, 2]\n // This should remove all and recreate in new order\n\n const oldCtx = createChatContext([msg1, msg2, msg3]);\n const newCtx = createChatContext([msg3, msg1, msg2]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n // Since order changed completely, should have some operations\n expect(result.toRemove.length + result.toCreate.length).toBeGreaterThan(0);\n });\n\n it('should handle identical single item contexts', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n\n const oldCtx = createChatContext([msg1]);\n const newCtx = createChatContext([msg1]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle longest common subsequence correctly', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n\n // Old: [1, 2, 3, 4, 5]\n // New: [1, 3, 5]\n // LCS should be [1, 3, 5], remove [2, 4]\n\n const oldCtx = createChatContext([msg1, msg2, msg3, msg4, msg5]);\n const newCtx = createChatContext([msg1, msg3, msg5]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual(['2', '4']);\n expect(result.toCreate).toEqual([]);\n });\n\n it('should handle interleaved additions and common subsequence', () => {\n const msg1 = createChatMessage('1', 'Hello', 'user');\n const msg2 = createChatMessage('2', 'Hi there', 'assistant');\n const msg3 = createChatMessage('3', 'How are you?', 'user');\n const msg4 = createChatMessage('4', 'Fine thanks', 'assistant');\n const msg5 = createChatMessage('5', 'Good to hear', 'user');\n const msg6 = createChatMessage('6', 'Anything else?', 'assistant');\n\n // Old: [1, 3, 5]\n // New: [1, 2, 3, 4, 5, 6]\n // LCS: [1, 3, 5], add [2 after 1, 4 after 3, 6 after 5]\n\n const oldCtx = createChatContext([msg1, msg3, msg5]);\n const newCtx = createChatContext([msg1, msg2, msg3, msg4, msg5, msg6]);\n\n const result = computeChatCtxDiff(oldCtx, newCtx);\n\n expect(result.toRemove).toEqual([]);\n expect(result.toCreate).toEqual([\n ['1', '2'],\n ['3', '4'],\n ['5', '6'],\n ]);\n });\n});\n\ndescribe('formatChatHistory', () => {\n it('should format mixed chat history items for logging', () => {\n const ctx = new ChatContext([\n ChatMessage.create({\n id: 'msg_system',\n role: 'system',\n content: 'You are helpful.',\n createdAt: 1,\n }),\n ChatMessage.create({\n id: 'msg_user',\n role: 'user',\n content: [\n 'Show me my order',\n createImageContent('https://example.com/receipt.png'),\n { type: 'audio_content', frame: [], transcript: 'order 123' },\n ],\n createdAt: 2,\n }),\n FunctionCall.create({\n id: 'fn_call',\n callId: 'call_1',\n name: 'lookup_order',\n args: '{\"orderId\":\"123\"}',\n createdAt: 3,\n }),\n FunctionCallOutput.create({\n id: 'fn_output',\n callId: 'call_1',\n name: 'lookup_order',\n output: '{\"status\":\"shipped\",\"ok\":true}',\n isError: false,\n createdAt: 4,\n }),\n AgentHandoffItem.create({\n id: 'handoff',\n oldAgentId: 'support',\n newAgentId: 'returns',\n createdAt: 5,\n }),\n ]);\n\n expect(formatChatHistory(ctx)).toBe(\n [\n 'Chat history (5 items)',\n '',\n '[0] message system',\n ' You are helpful.',\n '',\n '[1] message user',\n ' Show me my order',\n ' [image url=https://example.com/receipt.png]',\n ' [audio transcript=\"order 123\"]',\n '',\n '[2] function_call lookup_order call_id=call_1',\n ' {',\n ' \"orderId\": \"123\"',\n ' }',\n '',\n '[3] function_call_output lookup_order call_id=call_1',\n ' {',\n ' \"status\": \"shipped\",',\n ' \"ok\": true',\n ' }',\n '',\n '[4] agent_handoff',\n ' support -> returns',\n ].join('\\n'),\n );\n });\n\n it('should optionally include ids and timestamps', () => {\n const ctx = new ChatContext([\n FunctionCallOutput.create({\n id: 'fn_output',\n callId: 'call_1',\n name: 'lookup_order',\n output: 'plain text error',\n isError: true,\n createdAt: 123.456,\n }),\n ]);\n\n expect(formatChatHistory(ctx, { includeIds: true, includeTimestamps: true })).toBe(\n [\n 'Chat history (1 items)',\n '',\n '[0] function_call_output lookup_order call_id=call_1 error=true id=fn_output created_at=123.456',\n ' plain text error',\n ].join('\\n'),\n );\n });\n});\n\ndescribe('serializeImage', () => {\n let consoleWarnSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});\n vi.clearAllMocks();\n });\n\n describe('Data URL handling', () => {\n it('should serialize a valid JPEG data URL', async () => {\n const originalBase64 = '/9j/4AAQSkZJRg==';\n const imageContent = createImageContent(`data:image/jpeg;base64,${originalBase64}`, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: originalBase64,\n mimeType: 'image/jpeg',\n inferenceDetail: 'high',\n });\n\n expect(result.base64Data).toBe(originalBase64);\n });\n\n it('should serialize a valid PNG data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n 'low',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n inferenceDetail: 'low',\n });\n });\n\n it('should serialize a valid WebP data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAA',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'UklGRiQAAABXRUJQVlA4IBgAAAA',\n mimeType: 'image/webp',\n inferenceDetail: 'auto',\n });\n });\n\n it('should serialize a valid GIF data URL', async () => {\n const imageContent = createImageContent(\n 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n 'auto',\n );\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n base64Data: 'R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',\n mimeType: 'image/gif',\n inferenceDetail: 'auto',\n });\n });\n\n it('should warn and use provided mimeType when it differs from data URL mime type', async () => {\n const imageContent = createImageContent('data:image/jpeg;base64,/9j/4AAQSkZJRg==', 'auto', {\n mimeType: 'image/png',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(consoleWarnSpy).toHaveBeenCalledWith(\n \"Provided mimeType 'image/png' does not match data URL mime type 'image/jpeg'. Using provided mimeType.\",\n );\n expect(result).toEqual({\n base64Data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n });\n\n it('should throw error for invalid data URL format', async () => {\n const imageContent = createImageContent('data:;base64,/9j/4AAQSkZJRg==', 'auto');\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Invalid data URL format');\n });\n\n it('should throw error for unsupported mime type', async () => {\n const imageContent = createImageContent(\n 'data:image/bmp;base64,Qk06AAAAAAAAADYAAAAoAAAA',\n 'auto',\n );\n\n await expect(serializeImage(imageContent)).rejects.toThrow(\n 'Unsupported mimeType image/bmp. Must be jpeg, png, webp, or gif',\n );\n });\n });\n\n describe('External URL handling', () => {\n it('should serialize an external URL without mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: undefined,\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n\n it('should serialize an external URL with mimeType', async () => {\n const imageContent = createImageContent('https://example.com/image.jpg', 'low', {\n mimeType: 'image/jpeg',\n });\n\n const result = await serializeImage(imageContent);\n\n expect(result).toEqual({\n mimeType: 'image/jpeg',\n inferenceDetail: 'low',\n externalUrl: 'https://example.com/image.jpg',\n });\n });\n });\n\n describe('VideoFrame handling', () => {\n it('should serialize a VideoFrame without resize parameters', async () => {\n const width = 4;\n const height = 4;\n const videoFrame = createSolidColorFrame(width, height, { r: 255, g: 0, b: 0, a: 255 });\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'auto',\n });\n expect(result.base64Data).toBeDefined();\n expect(result.base64Data).toMatch(/^[A-Za-z0-9+/]+=*$/);\n expect(result.externalUrl).toBeUndefined();\n\n const { imageBuffer, decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n verifyPngHeader(imageBuffer);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n expect(decodedImage.info.channels).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expectPixel(decodedData, i, { r: 255, g: 0, b: 0, a: 255 });\n }\n });\n\n it('should serialize a VideoFrame with a gradient pattern', async () => {\n const width = 8;\n const height = 8;\n const videoFrame = createGradientFrame(width, height);\n const imageContent = createImageContent(videoFrame, 'high');\n\n const result = await serializeImage(imageContent);\n\n expect(result).toMatchObject({\n mimeType: 'image/png',\n inferenceDetail: 'high',\n });\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(width);\n expect(decodedImage.info.height).toBe(height);\n\n const decodedData = decodedImage.data;\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = (y * width + x) * 4;\n const expectedR = Math.floor((x / (width - 1)) * 255);\n const expectedG = Math.floor((y / (height - 1)) * 255);\n\n expectPixel(decodedData, idx, { r: expectedR, g: expectedG, b: 128, a: 255 });\n }\n }\n });\n\n it('should preserve exact pixel data through serialization', async () => {\n const width = 2;\n const height = 2;\n\n const patterns = [\n [255, 0, 0, 255],\n [0, 255, 0, 255],\n [0, 0, 255, 255],\n [255, 255, 255, 255],\n ];\n\n const videoFrame = createPatternFrame(width, height, patterns);\n const imageContent = createImageContent(videoFrame, 'low');\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n const decoded = decodedImage.data;\n\n expectPixel(decoded, 0, { r: 255, g: 0, b: 0, a: 255 });\n expectPixel(decoded, 4, { r: 0, g: 255, b: 0, a: 255 });\n expectPixel(decoded, width * 4, { r: 0, g: 0, b: 255, a: 255 });\n expectPixel(decoded, (width + 1) * 4, { r: 255, g: 255, b: 255, a: 255 });\n });\n\n it('should handle resize parameters correctly', async () => {\n const width = 2;\n const height = 2;\n const videoFrame = createSolidColorFrame(width, height, { r: 100, g: 100, b: 100, a: 255 });\n\n const imageContent = createImageContent(videoFrame, 'auto', {\n inferenceWidth: 4,\n inferenceHeight: 4,\n });\n\n const result = await serializeImage(imageContent);\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.width).toBe(4);\n expect(decodedImage.info.height).toBe(4);\n\n const decodedData = decodedImage.data;\n for (let i = 0; i < decodedData.length; i += 4) {\n expect(decodedData[i]).toBeCloseTo(100, -1);\n expect(decodedData[i + 1]).toBeCloseTo(100, -1);\n expect(decodedData[i + 2]).toBeCloseTo(100, -1);\n expect(decodedData[i + 3]).toBe(255);\n }\n });\n\n it('should handle RGB24 VideoBufferType correctly', async () => {\n const width = 2;\n const height = 2;\n const channels = 3;\n const frameData = new Uint8Array(width * height * channels);\n\n for (let i = 0; i < frameData.length; i += channels) {\n frameData[i] = 255;\n frameData[i + 1] = 128;\n frameData[i + 2] = 64;\n }\n\n const videoFrame = new VideoFrame(frameData, width, height, VideoBufferType.RGB24);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n\n const { decodedImage } = await decodeImageToRaw(result.base64Data!);\n\n expect(decodedImage.info.channels).toBeGreaterThanOrEqual(3);\n\n const decodedData = decodedImage.data;\n const decodedChannels = decodedImage.info.channels;\n\n for (let i = 0; i < decodedData.length; i += decodedChannels) {\n expect(decodedData[i]).toBe(255);\n expect(decodedData[i + 1]).toBe(128);\n expect(decodedData[i + 2]).toBe(64);\n if (decodedChannels === 4) {\n expect(decodedData[i + 3]).toBe(255);\n }\n }\n });\n\n it('should handle different RGBA-like formats correctly', async () => {\n const width = 1;\n const height = 1;\n const testFormats = [\n VideoBufferType.RGBA,\n VideoBufferType.BGRA,\n VideoBufferType.ARGB,\n VideoBufferType.ABGR,\n ];\n\n for (const format of testFormats) {\n const frameData = new Uint8Array([100, 150, 200, 250]);\n const videoFrame = new VideoFrame(frameData, width, height, format);\n const imageContent = createImageContent(videoFrame, 'auto');\n\n const result = await serializeImage(imageContent);\n\n expect(result.mimeType).toBe('image/png');\n expect(result.base64Data).toBeDefined();\n }\n });\n });\n\n describe('Error handling', () => {\n it('should throw error for unsupported image type', async () => {\n const imageContent = createImageContent(123 as any, 'auto'); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n await expect(serializeImage(imageContent)).rejects.toThrow('Unsupported image type');\n });\n });\n});\n"],"mappings":"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","names":[]}
package/dist/stt/stt.cjs CHANGED
@@ -119,6 +119,14 @@ class SpeechStream {
119
119
  this.pumpInput();
120
120
  (0, import_utils.startSoon)(() => this.mainTask().finally(() => this.queue.close()));
121
121
  }
122
+ /**
123
+ * Runs the STT with retry logic. Errors are emitted via {@link STT} error events
124
+ * and then re-thrown to trigger `.finally()` cleanup.
125
+ *
126
+ * @throws {APIError} When the STT request fails with a non-retryable error
127
+ * @throws {APIConnectionError} When all retry attempts are exhausted
128
+ * @internal Not annotated with Throws<> because this is fire-and-forget via startSoon()
129
+ */
122
130
  async mainTask() {
123
131
  for (let i = 0; i < this._connOptions.maxRetry + 1; i++) {
124
132
  try {