AIX: OpenAI: [Mistral, 2025-10-15]: non-standard delta.content for thinking blocks

This commit is contained in:
Enrico Ros
2025-10-15 15:05:19 -07:00
parent c79237b419
commit 48426d5022
2 changed files with 29 additions and 1 deletions
@@ -212,6 +212,26 @@ export function createOpenAIChatCompletionsChunkParser(): ChatGenerateParseFunct
pt.appendAutoText_weak(delta.content);
}
// [Mistral, 2025-10-15] SPEC-VIOLATION Text (array format from Mistral thinking models)
else if (Array.isArray(delta.content)) {
for (const contentBlock of delta.content)
if (contentBlock.type === 'thinking' && Array.isArray(contentBlock.thinking)) {
// Extract text from thinking blocks and send as reasoning
for (const thinkingPart of contentBlock.thinking)
if (thinkingPart.type === 'text' && typeof (thinkingPart.text as unknown) === 'string') {
pt.appendReasoningText(thinkingPart.text);
deltaHasReasoning = true;
} else {
// Handle other thinking part types if necessary
console.log('AIX: OpenAI-dispatch: unexpected thinking part type from Mistral:', thinkingPart);
}
} else {
// Handle other content types if necessary
console.log('AIX: OpenAI-dispatch: unexpected content block type from Mistral:', contentBlock);
}
}
// 2025-03-26: we don't have the full concurrency combinations of content/reasoning/reasoning_content yet
// if (delta.content !== undefined && delta.content !== null)
// throw new Error(`unexpected delta content type: ${typeof delta.content}`);
@@ -560,7 +560,15 @@ export namespace OpenAIWire_API_Chat_Completions {
role: z.literal('assistant').optional()
.nullable(), // [Deepseek] added .nullable()
// delta-text content
content: z.string().nullable().optional(),
content: z.string().nullish()
// [Mistral, 2025-10-15] Mistral SPEC-BREAKING thinking fragments
.or(z.array(z.object({
type: z.string(), // 'thinking', but relaxed
thinking: z.array(z.object({
type: z.string(),
text: z.string(),
})).optional(),
}))),
// delta-reasoning content
reasoning_content: z.string().nullable().optional(), // [Deepseek, 2025-01-20]
reasoning: z.string().optional() // [OpenRouter, 2025-01-24]