fix: add image response support
Convert Google's inlineData format to Anthropic's image format: - response-converter.js: Handle inlineData in non-streaming responses - sse-parser.js: Parse inlineData for thinking models - sse-streamer.js: Stream inlineData as image content blocks Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,11 @@ export async function parseThinkingSSEResponse(response, originalModel) {
|
||||
if (!part.text) continue;
|
||||
flushThinking();
|
||||
accumulatedText += part.text;
|
||||
} else if (part.inlineData) {
|
||||
// Handle image content
|
||||
flushThinking();
|
||||
flushText();
|
||||
finalParts.push(part);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -105,7 +110,7 @@ export async function parseThinkingSSEResponse(response, originalModel) {
|
||||
usageMetadata
|
||||
};
|
||||
|
||||
const partTypes = finalParts.map(p => p.thought ? 'thought' : (p.functionCall ? 'functionCall' : 'text'));
|
||||
const partTypes = finalParts.map(p => p.thought ? 'thought' : (p.functionCall ? 'functionCall' : (p.inlineData ? 'inlineData' : 'text')));
|
||||
logger.debug('[CloudCode] Response received (SSE), part types:', partTypes);
|
||||
if (finalParts.some(p => p.thought)) {
|
||||
const thinkingPart = finalParts.find(p => p.thought);
|
||||
|
||||
@@ -209,6 +209,39 @@ export async function* streamSSEResponse(response, originalModel) {
|
||||
partial_json: JSON.stringify(part.functionCall.args || {})
|
||||
}
|
||||
};
|
||||
} else if (part.inlineData) {
|
||||
// Handle image content from Google format
|
||||
if (currentBlockType === 'thinking' && currentThinkingSignature) {
|
||||
yield {
|
||||
type: 'content_block_delta',
|
||||
index: blockIndex,
|
||||
delta: { type: 'signature_delta', signature: currentThinkingSignature }
|
||||
};
|
||||
currentThinkingSignature = '';
|
||||
}
|
||||
if (currentBlockType !== null) {
|
||||
yield { type: 'content_block_stop', index: blockIndex };
|
||||
blockIndex++;
|
||||
}
|
||||
currentBlockType = 'image';
|
||||
|
||||
// Emit image block as a complete block
|
||||
yield {
|
||||
type: 'content_block_start',
|
||||
index: blockIndex,
|
||||
content_block: {
|
||||
type: 'image',
|
||||
source: {
|
||||
type: 'base64',
|
||||
media_type: part.inlineData.mimeType,
|
||||
data: part.inlineData.data
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
yield { type: 'content_block_stop', index: blockIndex };
|
||||
blockIndex++;
|
||||
currentBlockType = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user