@livekit/agents 1.0.18 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/inference/api_protos.d.cts +12 -12
- package/dist/inference/api_protos.d.ts +12 -12
- package/dist/inference/tts.cjs +1 -1
- package/dist/inference/tts.cjs.map +1 -1
- package/dist/inference/tts.js +1 -1
- package/dist/inference/tts.js.map +1 -1
- package/dist/ipc/job_proc_lazy_main.cjs +6 -2
- package/dist/ipc/job_proc_lazy_main.cjs.map +1 -1
- package/dist/ipc/job_proc_lazy_main.js +6 -2
- package/dist/ipc/job_proc_lazy_main.js.map +1 -1
- package/dist/job.cjs +31 -0
- package/dist/job.cjs.map +1 -1
- package/dist/job.d.cts +6 -0
- package/dist/job.d.ts +6 -0
- package/dist/job.d.ts.map +1 -1
- package/dist/job.js +31 -0
- package/dist/job.js.map +1 -1
- package/dist/llm/chat_context.cjs +33 -0
- package/dist/llm/chat_context.cjs.map +1 -1
- package/dist/llm/chat_context.d.cts +22 -2
- package/dist/llm/chat_context.d.ts +22 -2
- package/dist/llm/chat_context.d.ts.map +1 -1
- package/dist/llm/chat_context.js +32 -0
- package/dist/llm/chat_context.js.map +1 -1
- package/dist/llm/index.cjs +2 -0
- package/dist/llm/index.cjs.map +1 -1
- package/dist/llm/index.d.cts +1 -1
- package/dist/llm/index.d.ts +1 -1
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +2 -0
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/llm.cjs.map +1 -1
- package/dist/llm/llm.d.ts.map +1 -1
- package/dist/llm/llm.js.map +1 -1
- package/dist/llm/provider_format/google.test.cjs +48 -0
- package/dist/llm/provider_format/google.test.cjs.map +1 -1
- package/dist/llm/provider_format/google.test.js +54 -1
- package/dist/llm/provider_format/google.test.js.map +1 -1
- package/dist/llm/provider_format/index.d.cts +1 -1
- package/dist/llm/provider_format/index.d.ts +1 -1
- package/dist/llm/provider_format/openai.cjs +1 -2
- package/dist/llm/provider_format/openai.cjs.map +1 -1
- package/dist/llm/provider_format/openai.js +1 -2
- package/dist/llm/provider_format/openai.js.map +1 -1
- package/dist/llm/provider_format/openai.test.cjs +32 -0
- package/dist/llm/provider_format/openai.test.cjs.map +1 -1
- package/dist/llm/provider_format/openai.test.js +38 -1
- package/dist/llm/provider_format/openai.test.js.map +1 -1
- package/dist/log.cjs.map +1 -1
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js.map +1 -1
- package/dist/telemetry/index.cjs +51 -0
- package/dist/telemetry/index.cjs.map +1 -0
- package/dist/telemetry/index.d.cts +4 -0
- package/dist/telemetry/index.d.ts +4 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +12 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/trace_types.cjs +191 -0
- package/dist/telemetry/trace_types.cjs.map +1 -0
- package/dist/telemetry/trace_types.d.cts +56 -0
- package/dist/telemetry/trace_types.d.ts +56 -0
- package/dist/telemetry/trace_types.d.ts.map +1 -0
- package/dist/telemetry/trace_types.js +113 -0
- package/dist/telemetry/trace_types.js.map +1 -0
- package/dist/telemetry/traces.cjs +196 -0
- package/dist/telemetry/traces.cjs.map +1 -0
- package/dist/telemetry/traces.d.cts +97 -0
- package/dist/telemetry/traces.d.ts +97 -0
- package/dist/telemetry/traces.d.ts.map +1 -0
- package/dist/telemetry/traces.js +173 -0
- package/dist/telemetry/traces.js.map +1 -0
- package/dist/telemetry/utils.cjs +86 -0
- package/dist/telemetry/utils.cjs.map +1 -0
- package/dist/telemetry/utils.d.cts +5 -0
- package/dist/telemetry/utils.d.ts +5 -0
- package/dist/telemetry/utils.d.ts.map +1 -0
- package/dist/telemetry/utils.js +51 -0
- package/dist/telemetry/utils.js.map +1 -0
- package/dist/tts/tts.cjs.map +1 -1
- package/dist/tts/tts.d.ts.map +1 -1
- package/dist/tts/tts.js.map +1 -1
- package/dist/voice/agent.cjs +15 -0
- package/dist/voice/agent.cjs.map +1 -1
- package/dist/voice/agent.d.cts +4 -1
- package/dist/voice/agent.d.ts +4 -1
- package/dist/voice/agent.d.ts.map +1 -1
- package/dist/voice/agent.js +15 -0
- package/dist/voice/agent.js.map +1 -1
- package/dist/voice/agent_activity.cjs +2 -0
- package/dist/voice/agent_activity.cjs.map +1 -1
- package/dist/voice/agent_activity.d.ts.map +1 -1
- package/dist/voice/agent_activity.js +2 -0
- package/dist/voice/agent_activity.js.map +1 -1
- package/dist/voice/agent_session.cjs +29 -1
- package/dist/voice/agent_session.cjs.map +1 -1
- package/dist/voice/agent_session.d.cts +6 -2
- package/dist/voice/agent_session.d.ts +6 -2
- package/dist/voice/agent_session.d.ts.map +1 -1
- package/dist/voice/agent_session.js +30 -2
- package/dist/voice/agent_session.js.map +1 -1
- package/dist/voice/audio_recognition.cjs.map +1 -1
- package/dist/voice/audio_recognition.d.ts.map +1 -1
- package/dist/voice/audio_recognition.js.map +1 -1
- package/dist/voice/generation.cjs.map +1 -1
- package/dist/voice/generation.d.ts.map +1 -1
- package/dist/voice/generation.js.map +1 -1
- package/dist/voice/index.cjs +2 -0
- package/dist/voice/index.cjs.map +1 -1
- package/dist/voice/index.d.cts +1 -0
- package/dist/voice/index.d.ts +1 -0
- package/dist/voice/index.d.ts.map +1 -1
- package/dist/voice/index.js +1 -0
- package/dist/voice/index.js.map +1 -1
- package/dist/voice/report.cjs +69 -0
- package/dist/voice/report.cjs.map +1 -0
- package/dist/voice/report.d.cts +26 -0
- package/dist/voice/report.d.ts +26 -0
- package/dist/voice/report.d.ts.map +1 -0
- package/dist/voice/report.js +44 -0
- package/dist/voice/report.js.map +1 -0
- package/package.json +10 -3
- package/src/index.ts +2 -1
- package/src/inference/tts.ts +1 -1
- package/src/ipc/job_proc_lazy_main.ts +10 -2
- package/src/job.ts +48 -0
- package/src/llm/chat_context.ts +53 -1
- package/src/llm/index.ts +1 -0
- package/src/llm/llm.ts +2 -0
- package/src/llm/provider_format/google.test.ts +72 -1
- package/src/llm/provider_format/openai.test.ts +55 -1
- package/src/llm/provider_format/openai.ts +3 -2
- package/src/log.ts +1 -0
- package/src/telemetry/index.ts +10 -0
- package/src/telemetry/trace_types.ts +88 -0
- package/src/telemetry/traces.ts +266 -0
- package/src/telemetry/utils.ts +61 -0
- package/src/tts/tts.ts +4 -0
- package/src/voice/agent.ts +22 -0
- package/src/voice/agent_activity.ts +6 -0
- package/src/voice/agent_session.ts +44 -1
- package/src/voice/audio_recognition.ts +2 -0
- package/src/voice/generation.ts +3 -0
- package/src/voice/index.ts +1 -0
- package/src/voice/report.ts +77 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/llm/provider_format/google.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport { initializeLogger } from '../../log.js';\nimport { ChatContext, FunctionCall, FunctionCallOutput } from '../chat_context.js';\nimport { serializeImage } from '../utils.js';\nimport { toChatCtx } from './google.js';\n\nvi.mock('../utils.js', () => ({\n serializeImage: vi.fn(),\n}));\n\ndescribe('Google Provider Format - toChatCtx', () => {\n const serializeImageMock = vi.mocked(serializeImage);\n\n initializeLogger({ level: 'silent', pretty: false });\n\n beforeEach(async () => {\n vi.clearAllMocks();\n });\n\n it('should convert simple text messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle system messages separately', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual(['You are a helpful assistant']);\n });\n\n it('should handle multiple system messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'system', content: 'Be concise in your responses' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual([\n 'You are a helpful assistant',\n 'Be concise in your responses',\n ]);\n });\n\n it('should handle multi-part text content', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: ['Line 1', 'Line 2', 'Line 3'] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Line 1' }, { text: 'Line 2' }, { text: 'Line 3' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with external URL images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Check out this image:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Check out this image:' },\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with base64 images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n mimeType: 'image/png',\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'assistant',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n inferenceDetail: 'auto',\n _cache: {},\n },\n 'Here is the image you requested',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n inlineData: {\n data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n },\n },\n { text: 'Here is the image you requested' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle VideoFrame images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'low',\n mimeType: 'image/jpeg',\n base64Data: '/9j/4AAQSkZJRg==',\n });\n\n const frameData = new Uint8Array(4 * 4 * 4); // 4x4 RGBA\n const videoFrame = new VideoFrame(frameData, 4, 4, VideoBufferType.RGBA);\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'frame1',\n type: 'image_content',\n image: videoFrame,\n inferenceDetail: 'low',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n inlineData: {\n data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should cache serialized images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n mimeType: 'image/png',\n base64Data: 'cached-data',\n });\n\n const imageContent = {\n id: 'img1',\n type: 'image_content' as const,\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high' as const,\n _cache: {},\n };\n\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [imageContent] });\n\n await toChatCtx(ctx, false);\n await toChatCtx(ctx, false);\n\n expect(serializeImageMock).toHaveBeenCalledTimes(1);\n expect(imageContent._cache).toHaveProperty('serialized_image');\n });\n\n it('should handle tool calls and outputs', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: 'Let me help you with that.' });\n const toolCall = FunctionCall.create({\n id: msg.id + '/tool_1',\n callId: 'call_123',\n name: 'get_weather',\n args: '{\"location\": \"San Francisco\"}',\n });\n const toolOutput = FunctionCallOutput.create({\n callId: 'call_123',\n name: 'get_weather',\n output: '{\"temperature\": 72, \"condition\": \"sunny\"}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: 'Let me help you with that.' },\n {\n functionCall: {\n id: 'call_123',\n name: 'get_weather',\n args: { location: 'San Francisco' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_123',\n name: 'get_weather',\n response: { output: '{\"temperature\": 72, \"condition\": \"sunny\"}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle multiple tool calls in one message', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: \"I'll check both locations.\" });\n const toolCall1 = new FunctionCall({\n id: msg.id + '/tool_1',\n callId: 'call_1',\n name: 'get_weather',\n args: '{\"location\": \"NYC\"}',\n });\n const toolCall2 = new FunctionCall({\n id: msg.id + '/tool_2',\n callId: 'call_2',\n name: 'get_weather',\n args: '{\"location\": \"LA\"}',\n });\n const toolOutput1 = new FunctionCallOutput({\n callId: 'call_1',\n name: 'get_weather',\n output: '{\"temperature\": 65}',\n isError: false,\n });\n const toolOutput2 = new FunctionCallOutput({\n callId: 'call_2',\n name: 'get_weather',\n output: '{\"temperature\": 78}',\n isError: false,\n });\n\n ctx.insert([toolCall1, toolCall2, toolOutput1, toolOutput2]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: \"I'll check both locations.\" },\n {\n functionCall: {\n id: 'call_1',\n name: 'get_weather',\n args: { location: 'NYC' },\n },\n },\n {\n functionCall: {\n id: 'call_2',\n name: 'get_weather',\n args: { location: 'LA' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_1',\n name: 'get_weather',\n response: { output: '{\"temperature\": 65}' },\n },\n },\n {\n functionResponse: {\n id: 'call_2',\n name: 'get_weather',\n response: { output: '{\"temperature\": 78}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool calls without accompanying message', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_123',\n callId: 'call_456',\n name: 'calculate',\n args: '{\"a\": 5, \"b\": 3}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_456',\n name: 'calculate',\n output: '{\"result\": 8}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_456',\n name: 'calculate',\n args: { a: 5, b: 3 },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_456',\n name: 'calculate',\n response: { output: '{\"result\": 8}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool call errors', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_error',\n callId: 'call_error',\n name: 'failing_function',\n args: '{}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_error',\n name: 'failing_function',\n output: 'Function failed to execute',\n isError: true,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_error',\n name: 'failing_function',\n args: {},\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_error',\n name: 'failing_function',\n response: { error: 'Function failed to execute' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should inject dummy user message when last turn is not user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: '.' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when last turn is already user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when disabled', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content with text and multiple images', async () => {\n serializeImageMock\n .mockResolvedValueOnce({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n })\n .mockResolvedValueOnce({\n inferenceDetail: 'low',\n mimeType: 'image/png',\n base64Data: 'base64data',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Here are two images:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image1.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n 'And the second one:',\n {\n id: 'img2',\n type: 'image_content',\n image: 'data:image/png;base64,base64data',\n inferenceDetail: 'low',\n _cache: {},\n },\n 'What do you think?',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Here are two images:' },\n {\n fileData: {\n fileUri: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n },\n },\n { text: 'And the second one:' },\n {\n inlineData: {\n data: 'base64data',\n mimeType: 'image/png',\n },\n },\n { text: 'What do you think?' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle content with only images and no text', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'auto',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should group consecutive messages by role', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'First user message' });\n ctx.addMessage({ role: 'user', content: 'Second user message' });\n ctx.addMessage({ role: 'assistant', content: 'First assistant response' });\n ctx.addMessage({ role: 'assistant', content: 'Second assistant response' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First user message' }, { text: 'Second user message' }],\n },\n {\n role: 'model',\n parts: [{ text: 'First assistant response' }, { text: 'Second assistant response' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle empty content arrays', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle image with default MIME type when missing', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n // No mimeType provided\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg', // Should default to image/jpeg\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should skip empty groups', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello', createdAt: 1000 });\n\n const orphanOutput = new FunctionCallOutput({\n callId: 'orphan_call',\n output: 'This should be ignored',\n isError: false,\n createdAt: 2000,\n });\n ctx.insert(orphanOutput);\n\n ctx.addMessage({ role: 'assistant', content: 'Hi!', createdAt: 3000 });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should filter out standalone function calls without outputs', async () => {\n const ctx = ChatContext.empty();\n\n const funcCall = new FunctionCall({\n id: 'func_standalone',\n callId: 'call_999',\n name: 'standalone_function',\n args: '{}',\n });\n\n ctx.insert(funcCall);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content types', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: ['First part', 'Second part'],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First part' }, { text: 'Second part' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/llm/provider_format/google.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport { initializeLogger } from '../../log.js';\nimport {\n AgentHandoffItem,\n ChatContext,\n FunctionCall,\n FunctionCallOutput,\n} from '../chat_context.js';\nimport { serializeImage } from '../utils.js';\nimport { toChatCtx } from './google.js';\n\nvi.mock('../utils.js', () => ({\n serializeImage: vi.fn(),\n}));\n\ndescribe('Google Provider Format - toChatCtx', () => {\n const serializeImageMock = vi.mocked(serializeImage);\n\n initializeLogger({ level: 'silent', pretty: false });\n\n beforeEach(async () => {\n vi.clearAllMocks();\n });\n\n it('should convert simple text messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle system messages separately', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual(['You are a helpful assistant']);\n });\n\n it('should handle multiple system messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'system', content: 'Be concise in your responses' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual([\n 'You are a helpful assistant',\n 'Be concise in your responses',\n ]);\n });\n\n it('should handle multi-part text content', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: ['Line 1', 'Line 2', 'Line 3'] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Line 1' }, { text: 'Line 2' }, { text: 'Line 3' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with external URL images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Check out this image:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Check out this image:' },\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with base64 images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n mimeType: 'image/png',\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'assistant',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n inferenceDetail: 'auto',\n _cache: {},\n },\n 'Here is the image you requested',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n inlineData: {\n data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n },\n },\n { text: 'Here is the image you requested' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle VideoFrame images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'low',\n mimeType: 'image/jpeg',\n base64Data: '/9j/4AAQSkZJRg==',\n });\n\n const frameData = new Uint8Array(4 * 4 * 4); // 4x4 RGBA\n const videoFrame = new VideoFrame(frameData, 4, 4, VideoBufferType.RGBA);\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'frame1',\n type: 'image_content',\n image: videoFrame,\n inferenceDetail: 'low',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n inlineData: {\n data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should cache serialized images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n mimeType: 'image/png',\n base64Data: 'cached-data',\n });\n\n const imageContent = {\n id: 'img1',\n type: 'image_content' as const,\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high' as const,\n _cache: {},\n };\n\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [imageContent] });\n\n await toChatCtx(ctx, false);\n await toChatCtx(ctx, false);\n\n expect(serializeImageMock).toHaveBeenCalledTimes(1);\n expect(imageContent._cache).toHaveProperty('serialized_image');\n });\n\n it('should handle tool calls and outputs', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: 'Let me help you with that.' });\n const toolCall = FunctionCall.create({\n id: msg.id + '/tool_1',\n callId: 'call_123',\n name: 'get_weather',\n args: '{\"location\": \"San Francisco\"}',\n });\n const toolOutput = FunctionCallOutput.create({\n callId: 'call_123',\n name: 'get_weather',\n output: '{\"temperature\": 72, \"condition\": \"sunny\"}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: 'Let me help you with that.' },\n {\n functionCall: {\n id: 'call_123',\n name: 'get_weather',\n args: { location: 'San Francisco' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_123',\n name: 'get_weather',\n response: { output: '{\"temperature\": 72, \"condition\": \"sunny\"}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle multiple tool calls in one message', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: \"I'll check both locations.\" });\n const toolCall1 = new FunctionCall({\n id: msg.id + '/tool_1',\n callId: 'call_1',\n name: 'get_weather',\n args: '{\"location\": \"NYC\"}',\n });\n const toolCall2 = new FunctionCall({\n id: msg.id + '/tool_2',\n callId: 'call_2',\n name: 'get_weather',\n args: '{\"location\": \"LA\"}',\n });\n const toolOutput1 = new FunctionCallOutput({\n callId: 'call_1',\n name: 'get_weather',\n output: '{\"temperature\": 65}',\n isError: false,\n });\n const toolOutput2 = new FunctionCallOutput({\n callId: 'call_2',\n name: 'get_weather',\n output: '{\"temperature\": 78}',\n isError: false,\n });\n\n ctx.insert([toolCall1, toolCall2, toolOutput1, toolOutput2]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: \"I'll check both locations.\" },\n {\n functionCall: {\n id: 'call_1',\n name: 'get_weather',\n args: { location: 'NYC' },\n },\n },\n {\n functionCall: {\n id: 'call_2',\n name: 'get_weather',\n args: { location: 'LA' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_1',\n name: 'get_weather',\n response: { output: '{\"temperature\": 65}' },\n },\n },\n {\n functionResponse: {\n id: 'call_2',\n name: 'get_weather',\n response: { output: '{\"temperature\": 78}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool calls without accompanying message', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_123',\n callId: 'call_456',\n name: 'calculate',\n args: '{\"a\": 5, \"b\": 3}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_456',\n name: 'calculate',\n output: '{\"result\": 8}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_456',\n name: 'calculate',\n args: { a: 5, b: 3 },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_456',\n name: 'calculate',\n response: { output: '{\"result\": 8}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool call errors', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_error',\n callId: 'call_error',\n name: 'failing_function',\n args: '{}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_error',\n name: 'failing_function',\n output: 'Function failed to execute',\n isError: true,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_error',\n name: 'failing_function',\n args: {},\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_error',\n name: 'failing_function',\n response: { error: 'Function failed to execute' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should inject dummy user message when last turn is not user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: '.' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when last turn is already user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when disabled', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content with text and multiple images', async () => {\n serializeImageMock\n .mockResolvedValueOnce({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n })\n .mockResolvedValueOnce({\n inferenceDetail: 'low',\n mimeType: 'image/png',\n base64Data: 'base64data',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Here are two images:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image1.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n 'And the second one:',\n {\n id: 'img2',\n type: 'image_content',\n image: 'data:image/png;base64,base64data',\n inferenceDetail: 'low',\n _cache: {},\n },\n 'What do you think?',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Here are two images:' },\n {\n fileData: {\n fileUri: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n },\n },\n { text: 'And the second one:' },\n {\n inlineData: {\n data: 'base64data',\n mimeType: 'image/png',\n },\n },\n { text: 'What do you think?' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle content with only images and no text', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'auto',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should group consecutive messages by role', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'First user message' });\n ctx.addMessage({ role: 'user', content: 'Second user message' });\n ctx.addMessage({ role: 'assistant', content: 'First assistant response' });\n ctx.addMessage({ role: 'assistant', content: 'Second assistant response' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First user message' }, { text: 'Second user message' }],\n },\n {\n role: 'model',\n parts: [{ text: 'First assistant response' }, { text: 'Second assistant response' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle empty content arrays', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle image with default MIME type when missing', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n // No mimeType provided\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg', // Should default to image/jpeg\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should skip empty groups', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello', createdAt: 1000 });\n\n const orphanOutput = new FunctionCallOutput({\n callId: 'orphan_call',\n output: 'This should be ignored',\n isError: false,\n createdAt: 2000,\n });\n ctx.insert(orphanOutput);\n\n ctx.addMessage({ role: 'assistant', content: 'Hi!', createdAt: 3000 });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should filter out standalone function calls without outputs', async () => {\n const ctx = ChatContext.empty();\n\n const funcCall = new FunctionCall({\n id: 'func_standalone',\n callId: 'call_999',\n name: 'standalone_function',\n args: '{}',\n });\n\n ctx.insert(funcCall);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content types', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: ['First part', 'Second part'],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First part' }, { text: 'Second part' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should filter out agent handoff items', async () => {\n const ctx = ChatContext.empty();\n\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n // Insert an agent handoff item\n const handoff = new AgentHandoffItem({\n oldAgentId: 'agent_1',\n newAgentId: 'agent_2',\n });\n ctx.insert(handoff);\n\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n // Agent handoff should be filtered out, only messages should remain\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle multiple agent handoffs without errors', async () => {\n const ctx = ChatContext.empty();\n\n ctx.addMessage({ role: 'user', content: 'Start' });\n\n // Multiple handoffs\n ctx.insert(new AgentHandoffItem({ oldAgentId: undefined, newAgentId: 'agent_1' }));\n ctx.addMessage({ role: 'assistant', content: 'Response from agent 1' });\n\n ctx.insert(new AgentHandoffItem({ oldAgentId: 'agent_1', newAgentId: 'agent_2' }));\n ctx.addMessage({ role: 'assistant', content: 'Response from agent 2' });\n\n ctx.insert(new AgentHandoffItem({ oldAgentId: 'agent_2', newAgentId: 'agent_3' }));\n ctx.addMessage({ role: 'assistant', content: 'Response from agent 3' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n // All handoffs should be filtered out\n // Note: Google provider groups consecutive messages by the same role\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Start' }],\n },\n {\n role: 'model',\n parts: [\n { text: 'Response from agent 1' },\n { text: 'Response from agent 2' },\n { text: 'Response from agent 3' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { VideoBufferType, VideoFrame } from "@livekit/rtc-node";
|
|
2
2
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import { initializeLogger } from "../../log.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AgentHandoffItem,
|
|
6
|
+
ChatContext,
|
|
7
|
+
FunctionCall,
|
|
8
|
+
FunctionCallOutput
|
|
9
|
+
} from "../chat_context.js";
|
|
5
10
|
import { serializeImage } from "../utils.js";
|
|
6
11
|
import { toChatCtx } from "./google.js";
|
|
7
12
|
vi.mock("../utils.js", () => ({
|
|
@@ -671,5 +676,53 @@ describe("Google Provider Format - toChatCtx", () => {
|
|
|
671
676
|
]);
|
|
672
677
|
expect(formatData.systemMessages).toBeNull();
|
|
673
678
|
});
|
|
679
|
+
it("should filter out agent handoff items", async () => {
|
|
680
|
+
const ctx = ChatContext.empty();
|
|
681
|
+
ctx.addMessage({ role: "user", content: "Hello" });
|
|
682
|
+
const handoff = new AgentHandoffItem({
|
|
683
|
+
oldAgentId: "agent_1",
|
|
684
|
+
newAgentId: "agent_2"
|
|
685
|
+
});
|
|
686
|
+
ctx.insert(handoff);
|
|
687
|
+
ctx.addMessage({ role: "assistant", content: "Hi there!" });
|
|
688
|
+
const [result, formatData] = await toChatCtx(ctx, false);
|
|
689
|
+
expect(result).toEqual([
|
|
690
|
+
{
|
|
691
|
+
role: "user",
|
|
692
|
+
parts: [{ text: "Hello" }]
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
role: "model",
|
|
696
|
+
parts: [{ text: "Hi there!" }]
|
|
697
|
+
}
|
|
698
|
+
]);
|
|
699
|
+
expect(formatData.systemMessages).toBeNull();
|
|
700
|
+
});
|
|
701
|
+
it("should handle multiple agent handoffs without errors", async () => {
|
|
702
|
+
const ctx = ChatContext.empty();
|
|
703
|
+
ctx.addMessage({ role: "user", content: "Start" });
|
|
704
|
+
ctx.insert(new AgentHandoffItem({ oldAgentId: void 0, newAgentId: "agent_1" }));
|
|
705
|
+
ctx.addMessage({ role: "assistant", content: "Response from agent 1" });
|
|
706
|
+
ctx.insert(new AgentHandoffItem({ oldAgentId: "agent_1", newAgentId: "agent_2" }));
|
|
707
|
+
ctx.addMessage({ role: "assistant", content: "Response from agent 2" });
|
|
708
|
+
ctx.insert(new AgentHandoffItem({ oldAgentId: "agent_2", newAgentId: "agent_3" }));
|
|
709
|
+
ctx.addMessage({ role: "assistant", content: "Response from agent 3" });
|
|
710
|
+
const [result, formatData] = await toChatCtx(ctx, false);
|
|
711
|
+
expect(result).toEqual([
|
|
712
|
+
{
|
|
713
|
+
role: "user",
|
|
714
|
+
parts: [{ text: "Start" }]
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
role: "model",
|
|
718
|
+
parts: [
|
|
719
|
+
{ text: "Response from agent 1" },
|
|
720
|
+
{ text: "Response from agent 2" },
|
|
721
|
+
{ text: "Response from agent 3" }
|
|
722
|
+
]
|
|
723
|
+
}
|
|
724
|
+
]);
|
|
725
|
+
expect(formatData.systemMessages).toBeNull();
|
|
726
|
+
});
|
|
674
727
|
});
|
|
675
728
|
//# sourceMappingURL=google.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/llm/provider_format/google.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport { initializeLogger } from '../../log.js';\nimport { ChatContext, FunctionCall, FunctionCallOutput } from '../chat_context.js';\nimport { serializeImage } from '../utils.js';\nimport { toChatCtx } from './google.js';\n\nvi.mock('../utils.js', () => ({\n serializeImage: vi.fn(),\n}));\n\ndescribe('Google Provider Format - toChatCtx', () => {\n const serializeImageMock = vi.mocked(serializeImage);\n\n initializeLogger({ level: 'silent', pretty: false });\n\n beforeEach(async () => {\n vi.clearAllMocks();\n });\n\n it('should convert simple text messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle system messages separately', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual(['You are a helpful assistant']);\n });\n\n it('should handle multiple system messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'system', content: 'Be concise in your responses' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual([\n 'You are a helpful assistant',\n 'Be concise in your responses',\n ]);\n });\n\n it('should handle multi-part text content', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: ['Line 1', 'Line 2', 'Line 3'] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Line 1' }, { text: 'Line 2' }, { text: 'Line 3' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with external URL images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Check out this image:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Check out this image:' },\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with base64 images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n mimeType: 'image/png',\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'assistant',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n inferenceDetail: 'auto',\n _cache: {},\n },\n 'Here is the image you requested',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n inlineData: {\n data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n },\n },\n { text: 'Here is the image you requested' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle VideoFrame images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'low',\n mimeType: 'image/jpeg',\n base64Data: '/9j/4AAQSkZJRg==',\n });\n\n const frameData = new Uint8Array(4 * 4 * 4); // 4x4 RGBA\n const videoFrame = new VideoFrame(frameData, 4, 4, VideoBufferType.RGBA);\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'frame1',\n type: 'image_content',\n image: videoFrame,\n inferenceDetail: 'low',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n inlineData: {\n data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should cache serialized images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n mimeType: 'image/png',\n base64Data: 'cached-data',\n });\n\n const imageContent = {\n id: 'img1',\n type: 'image_content' as const,\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high' as const,\n _cache: {},\n };\n\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [imageContent] });\n\n await toChatCtx(ctx, false);\n await toChatCtx(ctx, false);\n\n expect(serializeImageMock).toHaveBeenCalledTimes(1);\n expect(imageContent._cache).toHaveProperty('serialized_image');\n });\n\n it('should handle tool calls and outputs', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: 'Let me help you with that.' });\n const toolCall = FunctionCall.create({\n id: msg.id + '/tool_1',\n callId: 'call_123',\n name: 'get_weather',\n args: '{\"location\": \"San Francisco\"}',\n });\n const toolOutput = FunctionCallOutput.create({\n callId: 'call_123',\n name: 'get_weather',\n output: '{\"temperature\": 72, \"condition\": \"sunny\"}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: 'Let me help you with that.' },\n {\n functionCall: {\n id: 'call_123',\n name: 'get_weather',\n args: { location: 'San Francisco' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_123',\n name: 'get_weather',\n response: { output: '{\"temperature\": 72, \"condition\": \"sunny\"}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle multiple tool calls in one message', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: \"I'll check both locations.\" });\n const toolCall1 = new FunctionCall({\n id: msg.id + '/tool_1',\n callId: 'call_1',\n name: 'get_weather',\n args: '{\"location\": \"NYC\"}',\n });\n const toolCall2 = new FunctionCall({\n id: msg.id + '/tool_2',\n callId: 'call_2',\n name: 'get_weather',\n args: '{\"location\": \"LA\"}',\n });\n const toolOutput1 = new FunctionCallOutput({\n callId: 'call_1',\n name: 'get_weather',\n output: '{\"temperature\": 65}',\n isError: false,\n });\n const toolOutput2 = new FunctionCallOutput({\n callId: 'call_2',\n name: 'get_weather',\n output: '{\"temperature\": 78}',\n isError: false,\n });\n\n ctx.insert([toolCall1, toolCall2, toolOutput1, toolOutput2]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: \"I'll check both locations.\" },\n {\n functionCall: {\n id: 'call_1',\n name: 'get_weather',\n args: { location: 'NYC' },\n },\n },\n {\n functionCall: {\n id: 'call_2',\n name: 'get_weather',\n args: { location: 'LA' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_1',\n name: 'get_weather',\n response: { output: '{\"temperature\": 65}' },\n },\n },\n {\n functionResponse: {\n id: 'call_2',\n name: 'get_weather',\n response: { output: '{\"temperature\": 78}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool calls without accompanying message', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_123',\n callId: 'call_456',\n name: 'calculate',\n args: '{\"a\": 5, \"b\": 3}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_456',\n name: 'calculate',\n output: '{\"result\": 8}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_456',\n name: 'calculate',\n args: { a: 5, b: 3 },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_456',\n name: 'calculate',\n response: { output: '{\"result\": 8}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool call errors', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_error',\n callId: 'call_error',\n name: 'failing_function',\n args: '{}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_error',\n name: 'failing_function',\n output: 'Function failed to execute',\n isError: true,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_error',\n name: 'failing_function',\n args: {},\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_error',\n name: 'failing_function',\n response: { error: 'Function failed to execute' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should inject dummy user message when last turn is not user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: '.' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when last turn is already user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when disabled', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content with text and multiple images', async () => {\n serializeImageMock\n .mockResolvedValueOnce({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n })\n .mockResolvedValueOnce({\n inferenceDetail: 'low',\n mimeType: 'image/png',\n base64Data: 'base64data',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Here are two images:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image1.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n 'And the second one:',\n {\n id: 'img2',\n type: 'image_content',\n image: 'data:image/png;base64,base64data',\n inferenceDetail: 'low',\n _cache: {},\n },\n 'What do you think?',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Here are two images:' },\n {\n fileData: {\n fileUri: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n },\n },\n { text: 'And the second one:' },\n {\n inlineData: {\n data: 'base64data',\n mimeType: 'image/png',\n },\n },\n { text: 'What do you think?' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle content with only images and no text', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'auto',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should group consecutive messages by role', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'First user message' });\n ctx.addMessage({ role: 'user', content: 'Second user message' });\n ctx.addMessage({ role: 'assistant', content: 'First assistant response' });\n ctx.addMessage({ role: 'assistant', content: 'Second assistant response' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First user message' }, { text: 'Second user message' }],\n },\n {\n role: 'model',\n parts: [{ text: 'First assistant response' }, { text: 'Second assistant response' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle empty content arrays', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle image with default MIME type when missing', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n // No mimeType provided\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg', // Should default to image/jpeg\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should skip empty groups', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello', createdAt: 1000 });\n\n const orphanOutput = new FunctionCallOutput({\n callId: 'orphan_call',\n output: 'This should be ignored',\n isError: false,\n createdAt: 2000,\n });\n ctx.insert(orphanOutput);\n\n ctx.addMessage({ role: 'assistant', content: 'Hi!', createdAt: 3000 });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should filter out standalone function calls without outputs', async () => {\n const ctx = ChatContext.empty();\n\n const funcCall = new FunctionCall({\n id: 'func_standalone',\n callId: 'call_999',\n name: 'standalone_function',\n args: '{}',\n });\n\n ctx.insert(funcCall);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content types', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: ['First part', 'Second part'],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First part' }, { text: 'Second part' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/llm/provider_format/google.test.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { VideoBufferType, VideoFrame } from '@livekit/rtc-node';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport { initializeLogger } from '../../log.js';\nimport {\n AgentHandoffItem,\n ChatContext,\n FunctionCall,\n FunctionCallOutput,\n} from '../chat_context.js';\nimport { serializeImage } from '../utils.js';\nimport { toChatCtx } from './google.js';\n\nvi.mock('../utils.js', () => ({\n serializeImage: vi.fn(),\n}));\n\ndescribe('Google Provider Format - toChatCtx', () => {\n const serializeImageMock = vi.mocked(serializeImage);\n\n initializeLogger({ level: 'silent', pretty: false });\n\n beforeEach(async () => {\n vi.clearAllMocks();\n });\n\n it('should convert simple text messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle system messages separately', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual(['You are a helpful assistant']);\n });\n\n it('should handle multiple system messages', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'system', content: 'You are a helpful assistant' });\n ctx.addMessage({ role: 'system', content: 'Be concise in your responses' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toEqual([\n 'You are a helpful assistant',\n 'Be concise in your responses',\n ]);\n });\n\n it('should handle multi-part text content', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: ['Line 1', 'Line 2', 'Line 3'] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Line 1' }, { text: 'Line 2' }, { text: 'Line 3' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with external URL images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Check out this image:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Check out this image:' },\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle messages with base64 images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n mimeType: 'image/png',\n base64Data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'assistant',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n inferenceDetail: 'auto',\n _cache: {},\n },\n 'Here is the image you requested',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n inlineData: {\n data: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB',\n mimeType: 'image/png',\n },\n },\n { text: 'Here is the image you requested' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle VideoFrame images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'low',\n mimeType: 'image/jpeg',\n base64Data: '/9j/4AAQSkZJRg==',\n });\n\n const frameData = new Uint8Array(4 * 4 * 4); // 4x4 RGBA\n const videoFrame = new VideoFrame(frameData, 4, 4, VideoBufferType.RGBA);\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'frame1',\n type: 'image_content',\n image: videoFrame,\n inferenceDetail: 'low',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n inlineData: {\n data: '/9j/4AAQSkZJRg==',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should cache serialized images', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n mimeType: 'image/png',\n base64Data: 'cached-data',\n });\n\n const imageContent = {\n id: 'img1',\n type: 'image_content' as const,\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high' as const,\n _cache: {},\n };\n\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [imageContent] });\n\n await toChatCtx(ctx, false);\n await toChatCtx(ctx, false);\n\n expect(serializeImageMock).toHaveBeenCalledTimes(1);\n expect(imageContent._cache).toHaveProperty('serialized_image');\n });\n\n it('should handle tool calls and outputs', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: 'Let me help you with that.' });\n const toolCall = FunctionCall.create({\n id: msg.id + '/tool_1',\n callId: 'call_123',\n name: 'get_weather',\n args: '{\"location\": \"San Francisco\"}',\n });\n const toolOutput = FunctionCallOutput.create({\n callId: 'call_123',\n name: 'get_weather',\n output: '{\"temperature\": 72, \"condition\": \"sunny\"}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: 'Let me help you with that.' },\n {\n functionCall: {\n id: 'call_123',\n name: 'get_weather',\n args: { location: 'San Francisco' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_123',\n name: 'get_weather',\n response: { output: '{\"temperature\": 72, \"condition\": \"sunny\"}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle multiple tool calls in one message', async () => {\n const ctx = ChatContext.empty();\n\n const msg = ctx.addMessage({ role: 'assistant', content: \"I'll check both locations.\" });\n const toolCall1 = new FunctionCall({\n id: msg.id + '/tool_1',\n callId: 'call_1',\n name: 'get_weather',\n args: '{\"location\": \"NYC\"}',\n });\n const toolCall2 = new FunctionCall({\n id: msg.id + '/tool_2',\n callId: 'call_2',\n name: 'get_weather',\n args: '{\"location\": \"LA\"}',\n });\n const toolOutput1 = new FunctionCallOutput({\n callId: 'call_1',\n name: 'get_weather',\n output: '{\"temperature\": 65}',\n isError: false,\n });\n const toolOutput2 = new FunctionCallOutput({\n callId: 'call_2',\n name: 'get_weather',\n output: '{\"temperature\": 78}',\n isError: false,\n });\n\n ctx.insert([toolCall1, toolCall2, toolOutput1, toolOutput2]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n { text: \"I'll check both locations.\" },\n {\n functionCall: {\n id: 'call_1',\n name: 'get_weather',\n args: { location: 'NYC' },\n },\n },\n {\n functionCall: {\n id: 'call_2',\n name: 'get_weather',\n args: { location: 'LA' },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_1',\n name: 'get_weather',\n response: { output: '{\"temperature\": 65}' },\n },\n },\n {\n functionResponse: {\n id: 'call_2',\n name: 'get_weather',\n response: { output: '{\"temperature\": 78}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool calls without accompanying message', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_123',\n callId: 'call_456',\n name: 'calculate',\n args: '{\"a\": 5, \"b\": 3}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_456',\n name: 'calculate',\n output: '{\"result\": 8}',\n isError: false,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_456',\n name: 'calculate',\n args: { a: 5, b: 3 },\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_456',\n name: 'calculate',\n response: { output: '{\"result\": 8}' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle tool call errors', async () => {\n const ctx = ChatContext.empty();\n\n const toolCall = new FunctionCall({\n id: 'func_error',\n callId: 'call_error',\n name: 'failing_function',\n args: '{}',\n });\n const toolOutput = new FunctionCallOutput({\n callId: 'call_error',\n name: 'failing_function',\n output: 'Function failed to execute',\n isError: true,\n });\n\n ctx.insert([toolCall, toolOutput]);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [\n {\n functionCall: {\n id: 'call_error',\n name: 'failing_function',\n args: {},\n },\n },\n ],\n },\n {\n role: 'user',\n parts: [\n {\n functionResponse: {\n id: 'call_error',\n name: 'failing_function',\n response: { error: 'Function failed to execute' },\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should inject dummy user message when last turn is not user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: '.' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when last turn is already user', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n const [result, formatData] = await toChatCtx(ctx, true);\n\n expect(result).toEqual([\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should not inject dummy user message when disabled', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello' });\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content with text and multiple images', async () => {\n serializeImageMock\n .mockResolvedValueOnce({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n })\n .mockResolvedValueOnce({\n inferenceDetail: 'low',\n mimeType: 'image/png',\n base64Data: 'base64data',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n 'Here are two images:',\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image1.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n 'And the second one:',\n {\n id: 'img2',\n type: 'image_content',\n image: 'data:image/png;base64,base64data',\n inferenceDetail: 'low',\n _cache: {},\n },\n 'What do you think?',\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n { text: 'Here are two images:' },\n {\n fileData: {\n fileUri: 'https://example.com/image1.jpg',\n mimeType: 'image/jpeg',\n },\n },\n { text: 'And the second one:' },\n {\n inlineData: {\n data: 'base64data',\n mimeType: 'image/png',\n },\n },\n { text: 'What do you think?' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle content with only images and no text', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'auto',\n externalUrl: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'auto',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg',\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should group consecutive messages by role', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'First user message' });\n ctx.addMessage({ role: 'user', content: 'Second user message' });\n ctx.addMessage({ role: 'assistant', content: 'First assistant response' });\n ctx.addMessage({ role: 'assistant', content: 'Second assistant response' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First user message' }, { text: 'Second user message' }],\n },\n {\n role: 'model',\n parts: [{ text: 'First assistant response' }, { text: 'Second assistant response' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle empty content arrays', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: [] });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle image with default MIME type when missing', async () => {\n serializeImageMock.mockResolvedValue({\n inferenceDetail: 'high',\n externalUrl: 'https://example.com/image.jpg',\n // No mimeType provided\n });\n\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: [\n {\n id: 'img1',\n type: 'image_content',\n image: 'https://example.com/image.jpg',\n inferenceDetail: 'high',\n _cache: {},\n },\n ],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [\n {\n fileData: {\n fileUri: 'https://example.com/image.jpg',\n mimeType: 'image/jpeg', // Should default to image/jpeg\n },\n },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should skip empty groups', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({ role: 'user', content: 'Hello', createdAt: 1000 });\n\n const orphanOutput = new FunctionCallOutput({\n callId: 'orphan_call',\n output: 'This should be ignored',\n isError: false,\n createdAt: 2000,\n });\n ctx.insert(orphanOutput);\n\n ctx.addMessage({ role: 'assistant', content: 'Hi!', createdAt: 3000 });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should filter out standalone function calls without outputs', async () => {\n const ctx = ChatContext.empty();\n\n const funcCall = new FunctionCall({\n id: 'func_standalone',\n callId: 'call_999',\n name: 'standalone_function',\n args: '{}',\n });\n\n ctx.insert(funcCall);\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle mixed content types', async () => {\n const ctx = ChatContext.empty();\n ctx.addMessage({\n role: 'user',\n content: ['First part', 'Second part'],\n });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'First part' }, { text: 'Second part' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should filter out agent handoff items', async () => {\n const ctx = ChatContext.empty();\n\n ctx.addMessage({ role: 'user', content: 'Hello' });\n\n // Insert an agent handoff item\n const handoff = new AgentHandoffItem({\n oldAgentId: 'agent_1',\n newAgentId: 'agent_2',\n });\n ctx.insert(handoff);\n\n ctx.addMessage({ role: 'assistant', content: 'Hi there!' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n // Agent handoff should be filtered out, only messages should remain\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Hello' }],\n },\n {\n role: 'model',\n parts: [{ text: 'Hi there!' }],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n\n it('should handle multiple agent handoffs without errors', async () => {\n const ctx = ChatContext.empty();\n\n ctx.addMessage({ role: 'user', content: 'Start' });\n\n // Multiple handoffs\n ctx.insert(new AgentHandoffItem({ oldAgentId: undefined, newAgentId: 'agent_1' }));\n ctx.addMessage({ role: 'assistant', content: 'Response from agent 1' });\n\n ctx.insert(new AgentHandoffItem({ oldAgentId: 'agent_1', newAgentId: 'agent_2' }));\n ctx.addMessage({ role: 'assistant', content: 'Response from agent 2' });\n\n ctx.insert(new AgentHandoffItem({ oldAgentId: 'agent_2', newAgentId: 'agent_3' }));\n ctx.addMessage({ role: 'assistant', content: 'Response from agent 3' });\n\n const [result, formatData] = await toChatCtx(ctx, false);\n\n // All handoffs should be filtered out\n // Note: Google provider groups consecutive messages by the same role\n expect(result).toEqual([\n {\n role: 'user',\n parts: [{ text: 'Start' }],\n },\n {\n role: 'model',\n parts: [\n { text: 'Response from agent 1' },\n { text: 'Response from agent 2' },\n { text: 'Response from agent 3' },\n ],\n },\n ]);\n expect(formatData.systemMessages).toBeNull();\n });\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ChatContext } from '../chat_context.js';
|
|
2
2
|
export type ProviderFormat = 'openai' | 'google';
|
|
3
|
-
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<
|
|
3
|
+
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<[Record<string, unknown>[], import("./google.js").GoogleFormatData] | Record<string, any>[]>;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ChatContext } from '../chat_context.js';
|
|
2
2
|
export type ProviderFormat = 'openai' | 'google';
|
|
3
|
-
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<
|
|
3
|
+
export declare function toChatCtx(format: ProviderFormat, chatCtx: ChatContext, injectDummyUserMessage?: boolean): Promise<[Record<string, unknown>[], import("./google.js").GoogleFormatData] | Record<string, any>[]>;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -77,9 +77,8 @@ async function toChatItem(item) {
|
|
|
77
77
|
tool_call_id: item.callId,
|
|
78
78
|
content: item.output
|
|
79
79
|
};
|
|
80
|
-
} else {
|
|
81
|
-
throw new Error(`Unsupported item type: ${item["type"]}`);
|
|
82
80
|
}
|
|
81
|
+
throw new Error(`Unsupported item type: ${item["type"]}`);
|
|
83
82
|
}
|
|
84
83
|
async function toImageContent(content) {
|
|
85
84
|
const cacheKey = "serialized_image";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/llm/provider_format/openai.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChatContext, ChatItem, ImageContent } from '../chat_context.js';\nimport { type SerializedImage, serializeImage } from '../utils.js';\nimport { groupToolCalls } from './utils.js';\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport async function toChatCtx(chatCtx: ChatContext, injectDummyUserMessage: boolean = true) {\n const itemGroups = groupToolCalls(chatCtx);\n const messages: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n for (const group of itemGroups) {\n if (group.isEmpty) continue;\n\n const message: Record<string, any> = group.message // eslint-disable-line @typescript-eslint/no-explicit-any\n ? await toChatItem(group.message)\n : { role: 'assistant' };\n\n const toolCalls = group.toolCalls.map((toolCall) => ({\n type: 'function',\n id: toolCall.callId,\n function: { name: toolCall.name, arguments: toolCall.args },\n }));\n\n if (toolCalls.length > 0) {\n message['tool_calls'] = toolCalls;\n }\n\n messages.push(message);\n\n for (const toolOutput of group.toolOutputs) {\n messages.push(await toChatItem(toolOutput));\n }\n }\n\n return messages;\n}\n\nasync function toChatItem(item: ChatItem) {\n if (item.type === 'message') {\n const listContent: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n let textContent = '';\n\n for (const content of item.content) {\n if (typeof content === 'string') {\n if (textContent) textContent += '\\n';\n textContent += content;\n } else if (content.type === 'image_content') {\n listContent.push(await toImageContent(content));\n } else {\n throw new Error(`Unsupported content type: ${content.type}`);\n }\n }\n\n const content =\n listContent.length == 0\n ? textContent\n : textContent.length == 0\n ? listContent\n : [...listContent, { type: 'text', text: textContent }];\n\n return { role: item.role, content };\n } else if (item.type === 'function_call') {\n return {\n role: 'assistant',\n tool_calls: [\n {\n id: item.callId,\n type: 'function',\n function: { name: item.name, arguments: item.args },\n },\n ],\n };\n } else if (item.type === 'function_call_output') {\n return {\n role: 'tool',\n tool_call_id: item.callId,\n content: item.output,\n };\n }
|
|
1
|
+
{"version":3,"sources":["../../../src/llm/provider_format/openai.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChatContext, ChatItem, ImageContent } from '../chat_context.js';\nimport { type SerializedImage, serializeImage } from '../utils.js';\nimport { groupToolCalls } from './utils.js';\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport async function toChatCtx(chatCtx: ChatContext, injectDummyUserMessage: boolean = true) {\n const itemGroups = groupToolCalls(chatCtx);\n const messages: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n for (const group of itemGroups) {\n if (group.isEmpty) continue;\n\n const message: Record<string, any> = group.message // eslint-disable-line @typescript-eslint/no-explicit-any\n ? await toChatItem(group.message)\n : { role: 'assistant' };\n\n const toolCalls = group.toolCalls.map((toolCall) => ({\n type: 'function',\n id: toolCall.callId,\n function: { name: toolCall.name, arguments: toolCall.args },\n }));\n\n if (toolCalls.length > 0) {\n message['tool_calls'] = toolCalls;\n }\n\n messages.push(message);\n\n for (const toolOutput of group.toolOutputs) {\n messages.push(await toChatItem(toolOutput));\n }\n }\n\n return messages;\n}\n\nasync function toChatItem(item: ChatItem) {\n if (item.type === 'message') {\n const listContent: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n let textContent = '';\n\n for (const content of item.content) {\n if (typeof content === 'string') {\n if (textContent) textContent += '\\n';\n textContent += content;\n } else if (content.type === 'image_content') {\n listContent.push(await toImageContent(content));\n } else {\n throw new Error(`Unsupported content type: ${content.type}`);\n }\n }\n\n const content =\n listContent.length == 0\n ? textContent\n : textContent.length == 0\n ? listContent\n : [...listContent, { type: 'text', text: textContent }];\n\n return { role: item.role, content };\n } else if (item.type === 'function_call') {\n return {\n role: 'assistant',\n tool_calls: [\n {\n id: item.callId,\n type: 'function',\n function: { name: item.name, arguments: item.args },\n },\n ],\n };\n } else if (item.type === 'function_call_output') {\n return {\n role: 'tool',\n tool_call_id: item.callId,\n content: item.output,\n };\n }\n // Skip other item types (e.g., agent_handoff)\n // These should be filtered by groupToolCalls, but this is a safety net\n throw new Error(`Unsupported item type: ${item['type']}`);\n}\n\nasync function toImageContent(content: ImageContent) {\n const cacheKey = 'serialized_image'; // TODO: use hash of encoding options if available\n let serialized: SerializedImage;\n\n if (content._cache[cacheKey] === undefined) {\n serialized = await serializeImage(content);\n content._cache[cacheKey] = serialized;\n }\n serialized = content._cache[cacheKey];\n\n // Convert SerializedImage to OpenAI format\n if (serialized.externalUrl) {\n return {\n type: 'image_url',\n image_url: {\n url: serialized.externalUrl,\n detail: serialized.inferenceDetail,\n },\n };\n }\n\n if (serialized.base64Data === undefined) {\n throw new Error('Serialized image has no data bytes');\n }\n\n return {\n type: 'image_url',\n image_url: {\n url: `data:${serialized.mimeType};base64,${serialized.base64Data}`,\n detail: serialized.inferenceDetail,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,mBAAqD;AACrD,IAAAA,gBAA+B;AAG/B,eAAsB,UAAU,SAAsB,yBAAkC,MAAM;AAC5F,QAAM,iBAAa,8BAAe,OAAO;AACzC,QAAM,WAAkC,CAAC;AAEzC,aAAW,SAAS,YAAY;AAC9B,QAAI,MAAM,QAAS;AAEnB,UAAM,UAA+B,MAAM,UACvC,MAAM,WAAW,MAAM,OAAO,IAC9B,EAAE,MAAM,YAAY;AAExB,UAAM,YAAY,MAAM,UAAU,IAAI,CAAC,cAAc;AAAA,MACnD,MAAM;AAAA,MACN,IAAI,SAAS;AAAA,MACb,UAAU,EAAE,MAAM,SAAS,MAAM,WAAW,SAAS,KAAK;AAAA,IAC5D,EAAE;AAEF,QAAI,UAAU,SAAS,GAAG;AACxB,cAAQ,YAAY,IAAI;AAAA,IAC1B;AAEA,aAAS,KAAK,OAAO;AAErB,eAAW,cAAc,MAAM,aAAa;AAC1C,eAAS,KAAK,MAAM,WAAW,UAAU,CAAC;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,WAAW,MAAgB;AACxC,MAAI,KAAK,SAAS,WAAW;AAC3B,UAAM,cAAqC,CAAC;AAC5C,QAAI,cAAc;AAElB,eAAWC,YAAW,KAAK,SAAS;AAClC,UAAI,OAAOA,aAAY,UAAU;AAC/B,YAAI,YAAa,gBAAe;AAChC,uBAAeA;AAAA,MACjB,WAAWA,SAAQ,SAAS,iBAAiB;AAC3C,oBAAY,KAAK,MAAM,eAAeA,QAAO,CAAC;AAAA,MAChD,OAAO;AACL,cAAM,IAAI,MAAM,6BAA6BA,SAAQ,IAAI,EAAE;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,UACJ,YAAY,UAAU,IAClB,cACA,YAAY,UAAU,IACpB,cACA,CAAC,GAAG,aAAa,EAAE,MAAM,QAAQ,MAAM,YAAY,CAAC;AAE5D,WAAO,EAAE,MAAM,KAAK,MAAM,QAAQ;AAAA,EACpC,WAAW,KAAK,SAAS,iBAAiB;AACxC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,QACV;AAAA,UACE,IAAI,KAAK;AAAA,UACT,MAAM;AAAA,UACN,UAAU,EAAE,MAAM,KAAK,MAAM,WAAW,KAAK,KAAK;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,KAAK,SAAS,wBAAwB;AAC/C,WAAO;AAAA,MACL,MAAM;AAAA,MACN,cAAc,KAAK;AAAA,MACnB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,IAAI,MAAM,0BAA0B,KAAK,MAAM,CAAC,EAAE;AAC1D;AAEA,eAAe,eAAe,SAAuB;AACnD,QAAM,WAAW;AACjB,MAAI;AAEJ,MAAI,QAAQ,OAAO,QAAQ,MAAM,QAAW;AAC1C,iBAAa,UAAM,6BAAe,OAAO;AACzC,YAAQ,OAAO,QAAQ,IAAI;AAAA,EAC7B;AACA,eAAa,QAAQ,OAAO,QAAQ;AAGpC,MAAI,WAAW,aAAa;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,WAAW;AAAA,QACT,KAAK,WAAW;AAAA,QAChB,QAAQ,WAAW;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,eAAe,QAAW;AACvC,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,WAAW;AAAA,MACT,KAAK,QAAQ,WAAW,QAAQ,WAAW,WAAW,UAAU;AAAA,MAChE,QAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF;","names":["import_utils","content"]}
|
|
@@ -54,9 +54,8 @@ async function toChatItem(item) {
|
|
|
54
54
|
tool_call_id: item.callId,
|
|
55
55
|
content: item.output
|
|
56
56
|
};
|
|
57
|
-
} else {
|
|
58
|
-
throw new Error(`Unsupported item type: ${item["type"]}`);
|
|
59
57
|
}
|
|
58
|
+
throw new Error(`Unsupported item type: ${item["type"]}`);
|
|
60
59
|
}
|
|
61
60
|
async function toImageContent(content) {
|
|
62
61
|
const cacheKey = "serialized_image";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/llm/provider_format/openai.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChatContext, ChatItem, ImageContent } from '../chat_context.js';\nimport { type SerializedImage, serializeImage } from '../utils.js';\nimport { groupToolCalls } from './utils.js';\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport async function toChatCtx(chatCtx: ChatContext, injectDummyUserMessage: boolean = true) {\n const itemGroups = groupToolCalls(chatCtx);\n const messages: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n for (const group of itemGroups) {\n if (group.isEmpty) continue;\n\n const message: Record<string, any> = group.message // eslint-disable-line @typescript-eslint/no-explicit-any\n ? await toChatItem(group.message)\n : { role: 'assistant' };\n\n const toolCalls = group.toolCalls.map((toolCall) => ({\n type: 'function',\n id: toolCall.callId,\n function: { name: toolCall.name, arguments: toolCall.args },\n }));\n\n if (toolCalls.length > 0) {\n message['tool_calls'] = toolCalls;\n }\n\n messages.push(message);\n\n for (const toolOutput of group.toolOutputs) {\n messages.push(await toChatItem(toolOutput));\n }\n }\n\n return messages;\n}\n\nasync function toChatItem(item: ChatItem) {\n if (item.type === 'message') {\n const listContent: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n let textContent = '';\n\n for (const content of item.content) {\n if (typeof content === 'string') {\n if (textContent) textContent += '\\n';\n textContent += content;\n } else if (content.type === 'image_content') {\n listContent.push(await toImageContent(content));\n } else {\n throw new Error(`Unsupported content type: ${content.type}`);\n }\n }\n\n const content =\n listContent.length == 0\n ? textContent\n : textContent.length == 0\n ? listContent\n : [...listContent, { type: 'text', text: textContent }];\n\n return { role: item.role, content };\n } else if (item.type === 'function_call') {\n return {\n role: 'assistant',\n tool_calls: [\n {\n id: item.callId,\n type: 'function',\n function: { name: item.name, arguments: item.args },\n },\n ],\n };\n } else if (item.type === 'function_call_output') {\n return {\n role: 'tool',\n tool_call_id: item.callId,\n content: item.output,\n };\n }
|
|
1
|
+
{"version":3,"sources":["../../../src/llm/provider_format/openai.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2025 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { ChatContext, ChatItem, ImageContent } from '../chat_context.js';\nimport { type SerializedImage, serializeImage } from '../utils.js';\nimport { groupToolCalls } from './utils.js';\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport async function toChatCtx(chatCtx: ChatContext, injectDummyUserMessage: boolean = true) {\n const itemGroups = groupToolCalls(chatCtx);\n const messages: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n for (const group of itemGroups) {\n if (group.isEmpty) continue;\n\n const message: Record<string, any> = group.message // eslint-disable-line @typescript-eslint/no-explicit-any\n ? await toChatItem(group.message)\n : { role: 'assistant' };\n\n const toolCalls = group.toolCalls.map((toolCall) => ({\n type: 'function',\n id: toolCall.callId,\n function: { name: toolCall.name, arguments: toolCall.args },\n }));\n\n if (toolCalls.length > 0) {\n message['tool_calls'] = toolCalls;\n }\n\n messages.push(message);\n\n for (const toolOutput of group.toolOutputs) {\n messages.push(await toChatItem(toolOutput));\n }\n }\n\n return messages;\n}\n\nasync function toChatItem(item: ChatItem) {\n if (item.type === 'message') {\n const listContent: Record<string, any>[] = []; // eslint-disable-line @typescript-eslint/no-explicit-any\n let textContent = '';\n\n for (const content of item.content) {\n if (typeof content === 'string') {\n if (textContent) textContent += '\\n';\n textContent += content;\n } else if (content.type === 'image_content') {\n listContent.push(await toImageContent(content));\n } else {\n throw new Error(`Unsupported content type: ${content.type}`);\n }\n }\n\n const content =\n listContent.length == 0\n ? textContent\n : textContent.length == 0\n ? listContent\n : [...listContent, { type: 'text', text: textContent }];\n\n return { role: item.role, content };\n } else if (item.type === 'function_call') {\n return {\n role: 'assistant',\n tool_calls: [\n {\n id: item.callId,\n type: 'function',\n function: { name: item.name, arguments: item.args },\n },\n ],\n };\n } else if (item.type === 'function_call_output') {\n return {\n role: 'tool',\n tool_call_id: item.callId,\n content: item.output,\n };\n }\n // Skip other item types (e.g., agent_handoff)\n // These should be filtered by groupToolCalls, but this is a safety net\n throw new Error(`Unsupported item type: ${item['type']}`);\n}\n\nasync function toImageContent(content: ImageContent) {\n const cacheKey = 'serialized_image'; // TODO: use hash of encoding options if available\n let serialized: SerializedImage;\n\n if (content._cache[cacheKey] === undefined) {\n serialized = await serializeImage(content);\n content._cache[cacheKey] = serialized;\n }\n serialized = content._cache[cacheKey];\n\n // Convert SerializedImage to OpenAI format\n if (serialized.externalUrl) {\n return {\n type: 'image_url',\n image_url: {\n url: serialized.externalUrl,\n detail: serialized.inferenceDetail,\n },\n };\n }\n\n if (serialized.base64Data === undefined) {\n throw new Error('Serialized image has no data bytes');\n }\n\n return {\n type: 'image_url',\n image_url: {\n url: `data:${serialized.mimeType};base64,${serialized.base64Data}`,\n detail: serialized.inferenceDetail,\n },\n };\n}\n"],"mappings":"AAIA,SAA+B,sBAAsB;AACrD,SAAS,sBAAsB;AAG/B,eAAsB,UAAU,SAAsB,yBAAkC,MAAM;AAC5F,QAAM,aAAa,eAAe,OAAO;AACzC,QAAM,WAAkC,CAAC;AAEzC,aAAW,SAAS,YAAY;AAC9B,QAAI,MAAM,QAAS;AAEnB,UAAM,UAA+B,MAAM,UACvC,MAAM,WAAW,MAAM,OAAO,IAC9B,EAAE,MAAM,YAAY;AAExB,UAAM,YAAY,MAAM,UAAU,IAAI,CAAC,cAAc;AAAA,MACnD,MAAM;AAAA,MACN,IAAI,SAAS;AAAA,MACb,UAAU,EAAE,MAAM,SAAS,MAAM,WAAW,SAAS,KAAK;AAAA,IAC5D,EAAE;AAEF,QAAI,UAAU,SAAS,GAAG;AACxB,cAAQ,YAAY,IAAI;AAAA,IAC1B;AAEA,aAAS,KAAK,OAAO;AAErB,eAAW,cAAc,MAAM,aAAa;AAC1C,eAAS,KAAK,MAAM,WAAW,UAAU,CAAC;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,WAAW,MAAgB;AACxC,MAAI,KAAK,SAAS,WAAW;AAC3B,UAAM,cAAqC,CAAC;AAC5C,QAAI,cAAc;AAElB,eAAWA,YAAW,KAAK,SAAS;AAClC,UAAI,OAAOA,aAAY,UAAU;AAC/B,YAAI,YAAa,gBAAe;AAChC,uBAAeA;AAAA,MACjB,WAAWA,SAAQ,SAAS,iBAAiB;AAC3C,oBAAY,KAAK,MAAM,eAAeA,QAAO,CAAC;AAAA,MAChD,OAAO;AACL,cAAM,IAAI,MAAM,6BAA6BA,SAAQ,IAAI,EAAE;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,UACJ,YAAY,UAAU,IAClB,cACA,YAAY,UAAU,IACpB,cACA,CAAC,GAAG,aAAa,EAAE,MAAM,QAAQ,MAAM,YAAY,CAAC;AAE5D,WAAO,EAAE,MAAM,KAAK,MAAM,QAAQ;AAAA,EACpC,WAAW,KAAK,SAAS,iBAAiB;AACxC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,QACV;AAAA,UACE,IAAI,KAAK;AAAA,UACT,MAAM;AAAA,UACN,UAAU,EAAE,MAAM,KAAK,MAAM,WAAW,KAAK,KAAK;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,KAAK,SAAS,wBAAwB;AAC/C,WAAO;AAAA,MACL,MAAM;AAAA,MACN,cAAc,KAAK;AAAA,MACnB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,IAAI,MAAM,0BAA0B,KAAK,MAAM,CAAC,EAAE;AAC1D;AAEA,eAAe,eAAe,SAAuB;AACnD,QAAM,WAAW;AACjB,MAAI;AAEJ,MAAI,QAAQ,OAAO,QAAQ,MAAM,QAAW;AAC1C,iBAAa,MAAM,eAAe,OAAO;AACzC,YAAQ,OAAO,QAAQ,IAAI;AAAA,EAC7B;AACA,eAAa,QAAQ,OAAO,QAAQ;AAGpC,MAAI,WAAW,aAAa;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,WAAW;AAAA,QACT,KAAK,WAAW;AAAA,QAChB,QAAQ,WAAW;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,WAAW,eAAe,QAAW;AACvC,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,WAAW;AAAA,MACT,KAAK,QAAQ,WAAW,QAAQ,WAAW,WAAW,UAAU;AAAA,MAChE,QAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF;","names":["content"]}
|
|
@@ -486,5 +486,37 @@ import_vitest.vi.mock("../utils.js", () => ({
|
|
|
486
486
|
}
|
|
487
487
|
]);
|
|
488
488
|
});
|
|
489
|
+
(0, import_vitest.it)("should filter out agent handoff items", async () => {
|
|
490
|
+
const ctx = import_chat_context.ChatContext.empty();
|
|
491
|
+
ctx.addMessage({ role: "user", content: "Hello" });
|
|
492
|
+
const handoff = new import_chat_context.AgentHandoffItem({
|
|
493
|
+
oldAgentId: "agent_1",
|
|
494
|
+
newAgentId: "agent_2"
|
|
495
|
+
});
|
|
496
|
+
ctx.insert(handoff);
|
|
497
|
+
ctx.addMessage({ role: "assistant", content: "Hi there!" });
|
|
498
|
+
const result = await (0, import_openai.toChatCtx)(ctx);
|
|
499
|
+
(0, import_vitest.expect)(result).toEqual([
|
|
500
|
+
{ role: "user", content: "Hello" },
|
|
501
|
+
{ role: "assistant", content: "Hi there!" }
|
|
502
|
+
]);
|
|
503
|
+
});
|
|
504
|
+
(0, import_vitest.it)("should handle multiple agent handoffs without errors", async () => {
|
|
505
|
+
const ctx = import_chat_context.ChatContext.empty();
|
|
506
|
+
ctx.addMessage({ role: "user", content: "Start" });
|
|
507
|
+
ctx.insert(new import_chat_context.AgentHandoffItem({ oldAgentId: void 0, newAgentId: "agent_1" }));
|
|
508
|
+
ctx.addMessage({ role: "assistant", content: "Response from agent 1" });
|
|
509
|
+
ctx.insert(new import_chat_context.AgentHandoffItem({ oldAgentId: "agent_1", newAgentId: "agent_2" }));
|
|
510
|
+
ctx.addMessage({ role: "assistant", content: "Response from agent 2" });
|
|
511
|
+
ctx.insert(new import_chat_context.AgentHandoffItem({ oldAgentId: "agent_2", newAgentId: "agent_3" }));
|
|
512
|
+
ctx.addMessage({ role: "assistant", content: "Response from agent 3" });
|
|
513
|
+
const result = await (0, import_openai.toChatCtx)(ctx);
|
|
514
|
+
(0, import_vitest.expect)(result).toEqual([
|
|
515
|
+
{ role: "user", content: "Start" },
|
|
516
|
+
{ role: "assistant", content: "Response from agent 1" },
|
|
517
|
+
{ role: "assistant", content: "Response from agent 2" },
|
|
518
|
+
{ role: "assistant", content: "Response from agent 3" }
|
|
519
|
+
]);
|
|
520
|
+
});
|
|
489
521
|
});
|
|
490
522
|
//# sourceMappingURL=openai.test.cjs.map
|