( response: ChatCompletionResponse, )
| 279 | // Response translation |
| 280 | |
| 281 | export function translateToAnthropic( |
| 282 | response: ChatCompletionResponse, |
| 283 | ): AnthropicResponse { |
| 284 | // Merge content from all choices |
| 285 | const allTextBlocks: Array<AnthropicTextBlock> = [] |
| 286 | const allToolUseBlocks: Array<AnthropicToolUseBlock> = [] |
| 287 | let stopReason: "stop" | "length" | "tool_calls" | "content_filter" | null = |
| 288 | null // default |
| 289 | stopReason = response.choices[0]?.finish_reason ?? stopReason |
| 290 | |
| 291 | // Process all choices to extract text and tool use blocks |
| 292 | for (const choice of response.choices) { |
| 293 | const textBlocks = getAnthropicTextBlocks(choice.message.content) |
| 294 | const toolUseBlocks = getAnthropicToolUseBlocks(choice.message.tool_calls) |
| 295 | |
| 296 | allTextBlocks.push(...textBlocks) |
| 297 | allToolUseBlocks.push(...toolUseBlocks) |
| 298 | |
| 299 | // Use the finish_reason from the first choice, or prioritize tool_calls |
| 300 | if (choice.finish_reason === "tool_calls" || stopReason === "stop") { |
| 301 | stopReason = choice.finish_reason |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | // Note: GitHub Copilot doesn't generate thinking blocks, so we don't include them in responses |
| 306 | |
| 307 | return { |
| 308 | id: response.id, |
| 309 | type: "message", |
| 310 | role: "assistant", |
| 311 | model: response.model, |
| 312 | content: [...allTextBlocks, ...allToolUseBlocks], |
| 313 | stop_reason: mapOpenAIStopReasonToAnthropic(stopReason), |
| 314 | stop_sequence: null, |
| 315 | usage: { |
| 316 | input_tokens: |
| 317 | (response.usage?.prompt_tokens ?? 0) |
| 318 | - (response.usage?.prompt_tokens_details?.cached_tokens ?? 0), |
| 319 | output_tokens: response.usage?.completion_tokens ?? 0, |
| 320 | ...(response.usage?.prompt_tokens_details?.cached_tokens |
| 321 | !== undefined && { |
| 322 | cache_read_input_tokens: |
| 323 | response.usage.prompt_tokens_details.cached_tokens, |
| 324 | }), |
| 325 | }, |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | function getAnthropicTextBlocks( |
| 330 | messageContent: Message["content"], |
no test coverage detected
searching dependent graphs…