ai-platform-converter
Version:
Lossless API parameter conversion between multiple AI platforms (OpenAI, Anthropic, Gemini, DeepSeek, Wenwen, Vertex AI, Huawei, BigModel)
166 lines (165 loc) • 5.75 kB
JavaScript
"use strict";
/**
* Convert OpenAI request to Anthropic format
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertOpenAIRequestToAnthropic = convertOpenAIRequestToAnthropic;
const common_1 = require("../../types/common");
const helpers_1 = require("../../utils/helpers");
function convertOpenAIRequestToAnthropic(request, options) {
const messages = [];
let systemMessage;
// Extract system message and convert other messages
for (const msg of request.messages) {
if (msg.role === 'system') {
// Anthropic uses separate system parameter
systemMessage = typeof msg.content === 'string'
? msg.content
: msg.content?.map(c => c.text || '').join('\n') || '';
}
else if (msg.role === 'tool') {
// Tool results need special handling
messages.push({
role: 'user',
content: [{
type: 'tool_result',
tool_use_id: msg.tool_call_id || '',
content: msg.content
}]
});
}
else {
const convertedMsg = convertOpenAIMessage(msg);
if (convertedMsg) {
messages.push(convertedMsg);
}
}
}
// Convert tools
const tools = request.tools?.map(tool => ({
name: tool.function.name,
description: tool.function.description,
input_schema: {
type: 'object',
properties: tool.function.parameters?.properties || {},
required: tool.function.parameters?.required || []
}
}));
// Convert tool_choice
let tool_choice;
if (request.tool_choice) {
if (request.tool_choice === 'auto') {
tool_choice = { type: 'auto' };
}
else if (request.tool_choice === 'required') {
tool_choice = { type: 'any' };
}
else if (request.tool_choice === 'none') {
tool_choice = undefined;
}
else if (typeof request.tool_choice === 'object') {
tool_choice = {
type: 'tool',
name: request.tool_choice.function.name
};
}
}
// Get max_tokens from request or use default
const max_tokens = request.max_tokens || 4096;
// Build Anthropic request
const anthropicRequest = {
model: request.model,
messages,
max_tokens,
system: systemMessage,
temperature: request.temperature,
top_p: request.top_p,
stop_sequences: Array.isArray(request.stop) ? request.stop : request.stop ? [request.stop] : undefined,
stream: request.stream,
tools,
tool_choice,
// Restore Anthropic-specific params from extensions
...(request._extensions?.anthropic || {}),
// Preserve extensions
_extensions: {
platform: common_1.Platform.OpenAI,
originalParams: options?.preserveExtensions ? (0, helpers_1.deepClone)(request) : undefined,
openai: {
n: request.n,
presence_penalty: request.presence_penalty,
frequency_penalty: request.frequency_penalty,
logit_bias: request.logit_bias,
user: request.user,
response_format: request.response_format,
seed: request.seed
}
}
};
return (0, helpers_1.removeUndefined)(anthropicRequest);
}
function convertOpenAIMessage(msg) {
// Handle string content
if (typeof msg.content === 'string') {
return {
role: msg.role === 'user' ? 'user' : 'assistant',
content: msg.content
};
}
// Handle null content (for tool calls)
if (msg.content === null && msg.tool_calls) {
const contentBlocks = msg.tool_calls.map(tc => ({
type: 'tool_use',
id: tc.id,
name: tc.function.name,
input: (0, helpers_1.safeJsonParse)(tc.function.arguments)
}));
return {
role: 'assistant',
content: contentBlocks
};
}
// Handle array content
if (Array.isArray(msg.content)) {
const contentBlocks = [];
for (const part of msg.content) {
if (part.type === 'text') {
contentBlocks.push({
type: 'text',
text: part.text
});
}
else if (part.type === 'image_url') {
const imageUrl = part.image_url?.url || '';
// Check if base64 or URL
if (imageUrl.startsWith('data:')) {
const match = imageUrl.match(/data:(image\/\w+);base64,(.+)/);
if (match) {
contentBlocks.push({
type: 'image',
source: {
type: 'base64',
media_type: match[1],
data: match[2]
}
});
}
}
else {
contentBlocks.push({
type: 'image',
source: {
type: 'url',
media_type: 'image/jpeg',
url: imageUrl
}
});
}
}
}
return {
role: msg.role === 'user' ? 'user' : 'assistant',
content: contentBlocks
};
}
return null;
}