| |
| |
| |
| |
| |
|
|
| import type { |
| OpenAIResponsesResponse, |
| OpenAIResponsesOutputItem, |
| AnthropicResponse, |
| AnthropicContentBlock, |
| } from './types.js' |
| import { parseOpenAIToolArguments } from './toolArguments.js' |
|
|
| |
| |
| |
| export function openaiResponsesToAnthropic(response: OpenAIResponsesResponse, model: string): AnthropicResponse { |
| const content: AnthropicContentBlock[] = [] |
| let hasToolUse = false |
|
|
| for (const item of response.output || []) { |
| convertOutputItem(item, content) |
| if (item.type === 'function_call') hasToolUse = true |
| } |
|
|
| |
| if (content.length === 0) { |
| content.push({ type: 'text', text: '' }) |
| } |
|
|
| return { |
| id: response.id || `msg_${Date.now()}`, |
| type: 'message', |
| role: 'assistant', |
| content, |
| model: response.model || model, |
| stop_reason: mapStatus(response.status, hasToolUse), |
| stop_sequence: null, |
| usage: { |
| input_tokens: response.usage?.input_tokens ?? response.usage?.prompt_tokens ?? 0, |
| output_tokens: response.usage?.output_tokens ?? response.usage?.completion_tokens ?? 0, |
| }, |
| } |
| } |
|
|
| function convertOutputItem(item: OpenAIResponsesOutputItem, content: AnthropicContentBlock[]): void { |
| switch (item.type) { |
| case 'message': { |
| for (const part of item.content || []) { |
| if (part.type === 'output_text' || part.type === 'text') { |
| content.push({ type: 'text', text: part.text || '' }) |
| } else if (part.type === 'refusal') { |
| content.push({ type: 'text', text: part.refusal || '[Refusal]' }) |
| } |
| } |
| break |
| } |
| case 'function_call': { |
| content.push({ |
| type: 'tool_use', |
| id: item.call_id, |
| name: item.name, |
| input: parseOpenAIToolArguments(item.arguments), |
| }) |
| break |
| } |
| case 'reasoning': { |
| if (item.summary) { |
| for (const s of item.summary) { |
| if (s.text) { |
| content.push({ |
| type: 'thinking', |
| thinking: s.text, |
| }) |
| } |
| } |
| } |
| break |
| } |
| } |
| } |
|
|
| function mapStatus(status: string, hasToolUse: boolean): string { |
| switch (status) { |
| case 'completed': return hasToolUse ? 'tool_use' : 'end_turn' |
| case 'failed': return 'end_turn' |
| case 'cancelled': return 'end_turn' |
| case 'incomplete': return 'max_tokens' |
| default: return 'end_turn' |
| } |
| } |
|
|