ai-platform-converter
Version:
Lossless API parameter conversion between multiple AI platforms (OpenAI, Anthropic, Gemini, DeepSeek, Wenwen, Vertex AI, Huawei, BigModel)
160 lines (159 loc) • 4.59 kB
JavaScript
;
/**
* Helper utilities for conversion
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.deepClone = deepClone;
exports.mergeObjects = mergeObjects;
exports.removeUndefined = removeUndefined;
exports.isOpenAICompatible = isOpenAICompatible;
exports.createConversionError = createConversionError;
exports.validateRequired = validateRequired;
exports.mapFinishReason = mapFinishReason;
exports.ensureArray = ensureArray;
exports.safeJsonParse = safeJsonParse;
exports.safeJsonStringify = safeJsonStringify;
const common_1 = require("../types/common");
/**
* Deep clone an object
*/
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(item => deepClone(item));
}
const cloned = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
cloned[key] = deepClone(obj[key]);
}
}
return cloned;
}
/**
* Merge objects, preserving all fields
*/
function mergeObjects(target, ...sources) {
const result = deepClone(target);
for (const source of sources) {
for (const key in source) {
if (source.hasOwnProperty(key)) {
const value = source[key];
if (value !== undefined) {
result[key] = value;
}
}
}
}
return result;
}
/**
* Remove undefined values from object
*/
function removeUndefined(obj) {
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key) && obj[key] !== undefined) {
result[key] = obj[key];
}
}
return result;
}
/**
* Check if platform uses OpenAI-compatible API
*/
function isOpenAICompatible(platform) {
return [
common_1.Platform.OpenAI,
common_1.Platform.DeepSeek,
common_1.Platform.Wenwen,
common_1.Platform.VertexAI,
common_1.Platform.Huawei,
common_1.Platform.BigModel
].includes(platform);
}
/**
* Create conversion error
*/
function createConversionError(message, fromPlatform, toPlatform, originalError) {
return new common_1.ConversionError(message, fromPlatform, toPlatform, originalError);
}
/**
* Validate required fields
*/
function validateRequired(obj, fields, platform) {
for (const field of fields) {
if (!(field in obj) || obj[field] === undefined || obj[field] === null) {
throw new Error(`Missing required field '${field}' for ${platform}`);
}
}
}
/**
* Map finish reason between platforms
*/
function mapFinishReason(reason, _fromPlatform, toPlatform) {
if (!reason)
return null;
// Mapping table - use original case for keys
const mappings = {
// Anthropic reasons
'end_turn': { openai: 'stop', gemini: 'STOP' },
'max_tokens': { openai: 'length', gemini: 'MAX_TOKENS' },
'stop_sequence': { openai: 'stop', gemini: 'STOP' },
'tool_use': { openai: 'tool_calls' },
// OpenAI reasons
'stop': { anthropic: 'end_turn', gemini: 'STOP' },
'length': { anthropic: 'max_tokens', gemini: 'MAX_TOKENS' },
'tool_calls': { anthropic: 'tool_use' },
'function_call': { anthropic: 'tool_use' },
'content_filter': { anthropic: 'end_turn', gemini: 'SAFETY' },
// Gemini reasons (uppercase)
'STOP': { openai: 'stop', anthropic: 'end_turn' },
'MAX_TOKENS': { openai: 'length', anthropic: 'max_tokens' },
'SAFETY': { openai: 'content_filter', anthropic: 'end_turn' }
};
const targetPlatform = toPlatform.toLowerCase();
// Try exact match first
if (mappings[reason] && mappings[reason][targetPlatform]) {
return mappings[reason][targetPlatform];
}
// Try lowercase match
const lowerKey = reason.toLowerCase();
if (mappings[lowerKey] && mappings[lowerKey][targetPlatform]) {
return mappings[lowerKey][targetPlatform];
}
// Default: return original if no mapping found
return reason;
}
/**
* Ensure array
*/
function ensureArray(value) {
if (value === undefined)
return [];
return Array.isArray(value) ? value : [value];
}
/**
* Safe JSON parse
*/
function safeJsonParse(str, defaultValue = {}) {
try {
return JSON.parse(str);
}
catch {
return defaultValue;
}
}
/**
* Safe JSON stringify
*/
function safeJsonStringify(obj, defaultValue = '{}') {
try {
return JSON.stringify(obj);
}
catch {
return defaultValue;
}
}