diff --git a/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts b/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts index 1dabaf8ab..03f673dfe 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/dashscope.test.ts @@ -587,7 +587,7 @@ describe('DashScopeOpenAICompatibleProvider', () => { }); }); - it('should add empty text item with cache control if last item is not text for streaming requests', () => { + it('should add cache control directly to image content if last item is not text for streaming requests', () => { const requestWithNonTextLast: OpenAI.Chat.ChatCompletionCreateParams = { model: 'qwen-max', stream: true, // This will trigger cache control on last message @@ -612,12 +612,12 @@ describe('DashScopeOpenAICompatibleProvider', () => { const content = result.messages[0] .content as OpenAI.Chat.ChatCompletionContentPart[]; - expect(content).toHaveLength(3); + expect(content).toHaveLength(2); - // Should add empty text item with cache control - expect(content[2]).toEqual({ - type: 'text', - text: '', + // Should add cache control directly to the image item + expect(content[1]).toEqual({ + type: 'image_url', + image_url: { url: 'https://example.com/image.jpg' }, cache_control: { type: 'ephemeral' }, }); }); @@ -691,7 +691,7 @@ describe('DashScopeOpenAICompatibleProvider', () => { expect(content).toEqual([ { type: 'text', - text: '', + text: ' ', cache_control: { type: 'ephemeral' }, }, ]); diff --git a/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts b/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts index 9130238f1..1ad7fa111 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/dashscope.ts @@ -7,7 +7,6 @@ import { tokenLimit } from '../../tokenLimits.js'; import type { OpenAICompatibleProvider, DashScopeRequestMetadata, - ChatCompletionContentPartTextWithCache, ChatCompletionContentPartWithCache, ChatCompletionToolWithCache, } from './types.js'; @@ -225,7 +224,7 @@ export class DashScopeOpenAICompatibleProvider { type: 'text', text: content, - } as ChatCompletionContentPartTextWithCache, + } as ChatCompletionContentPartWithCache, ]; } return [...content] as ChatCompletionContentPartWithCache[]; @@ -241,28 +240,18 @@ export class DashScopeOpenAICompatibleProvider return [ { type: 'text', - text: '', + text: ' ', cache_control: { type: 'ephemeral' }, - } as ChatCompletionContentPartTextWithCache, + } as ChatCompletionContentPartWithCache, ]; } + // Add cache_control to the last item regardless of its type (text, image, or refusal) const lastItem = contentArray[contentArray.length - 1]; - - if (lastItem.type === 'text') { - // Add cache_control to the last text item - contentArray[contentArray.length - 1] = { - ...lastItem, - cache_control: { type: 'ephemeral' }, - } as ChatCompletionContentPartTextWithCache; - } else { - // If the last item is not text, add a new text item with cache_control - contentArray.push({ - type: 'text', - text: '', - cache_control: { type: 'ephemeral' }, - } as ChatCompletionContentPartTextWithCache); - } + contentArray[contentArray.length - 1] = { + ...lastItem, + cache_control: { type: 'ephemeral' }, + } as ChatCompletionContentPartWithCache; return contentArray; } diff --git a/packages/core/src/core/openaiContentGenerator/provider/index.ts b/packages/core/src/core/openaiContentGenerator/provider/index.ts index 9886b70f9..2f3c9ac1d 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/index.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/index.ts @@ -5,6 +5,5 @@ export { DefaultOpenAICompatibleProvider } from './default.js'; export type { OpenAICompatibleProvider, DashScopeRequestMetadata, - ChatCompletionContentPartTextWithCache, ChatCompletionContentPartWithCache, } from './types.js'; diff --git a/packages/core/src/core/openaiContentGenerator/provider/types.ts b/packages/core/src/core/openaiContentGenerator/provider/types.ts index ea7c434d7..119fdd91d 100644 --- a/packages/core/src/core/openaiContentGenerator/provider/types.ts +++ b/packages/core/src/core/openaiContentGenerator/provider/types.ts @@ -1,15 +1,10 @@ import type OpenAI from 'openai'; // Extended types to support cache_control for DashScope -export interface ChatCompletionContentPartTextWithCache - extends OpenAI.Chat.ChatCompletionContentPartText { - cache_control?: { type: 'ephemeral' }; -} - export type ChatCompletionContentPartWithCache = - | ChatCompletionContentPartTextWithCache - | OpenAI.Chat.ChatCompletionContentPartImage - | OpenAI.Chat.ChatCompletionContentPartRefusal; + OpenAI.Chat.ChatCompletionContentPart & { + cache_control?: { type: 'ephemeral' }; + }; export type ChatCompletionToolWithCache = OpenAI.Chat.ChatCompletionTool & { cache_control?: { type: 'ephemeral' };