manifest
Version:
Self-hosted Manifest LLM router with embedded server, SQLite database, and dashboard
190 lines • 8.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.collectChatGptSseResponse = exports.toResponsesRequest = exports.toAnthropicRequest = exports.toGoogleRequest = void 0;
exports.convertChatGptResponse = convertChatGptResponse;
exports.convertChatGptStreamChunk = convertChatGptStreamChunk;
exports.convertGoogleResponse = convertGoogleResponse;
exports.convertGoogleStreamChunk = convertGoogleStreamChunk;
exports.convertAnthropicResponse = convertAnthropicResponse;
exports.convertAnthropicStreamChunk = convertAnthropicStreamChunk;
exports.createAnthropicTransformer = createAnthropicTransformer;
exports.sanitizeOpenAiBody = sanitizeOpenAiBody;
const google_adapter_1 = require("./google-adapter");
Object.defineProperty(exports, "toGoogleRequest", { enumerable: true, get: function () { return google_adapter_1.toGoogleRequest; } });
const anthropic_adapter_1 = require("./anthropic-adapter");
Object.defineProperty(exports, "toAnthropicRequest", { enumerable: true, get: function () { return anthropic_adapter_1.toAnthropicRequest; } });
const chatgpt_adapter_1 = require("./chatgpt-adapter");
Object.defineProperty(exports, "toResponsesRequest", { enumerable: true, get: function () { return chatgpt_adapter_1.toResponsesRequest; } });
Object.defineProperty(exports, "collectChatGptSseResponse", { enumerable: true, get: function () { return chatgpt_adapter_1.collectChatGptSseResponse; } });
function convertChatGptResponse(body, model) {
return (0, chatgpt_adapter_1.fromResponsesResponse)(body, model);
}
function convertChatGptStreamChunk(chunk, model) {
return (0, chatgpt_adapter_1.transformResponsesStreamChunk)(chunk, model);
}
function convertGoogleResponse(googleBody, model) {
return (0, google_adapter_1.fromGoogleResponse)(googleBody, model);
}
function convertGoogleStreamChunk(chunk, model) {
return (0, google_adapter_1.transformGoogleStreamChunk)(chunk, model);
}
function convertAnthropicResponse(anthropicBody, model) {
return (0, anthropic_adapter_1.fromAnthropicResponse)(anthropicBody, model);
}
function convertAnthropicStreamChunk(chunk, model) {
return (0, anthropic_adapter_1.transformAnthropicStreamChunk)(chunk, model);
}
function createAnthropicTransformer(model) {
return (0, anthropic_adapter_1.createAnthropicStreamTransformer)(model);
}
const OPENAI_ONLY_FIELDS = new Set([
'store',
'metadata',
'service_tier',
'stream_options',
'modalities',
'audio',
'prediction',
'reasoning_effort',
]);
const PASSTHROUGH_PROVIDERS = new Set(['openai', 'openrouter']);
const MISTRAL_TOOL_CALL_ID_REGEX = /^[A-Za-z0-9]{9}$/;
const DEEPSEEK_MAX_TOKENS_LIMIT = 8192;
const OPENAI_MAX_COMPLETION_TOKENS_RE = /^(o\d|gpt-5)/i;
function supportsReasoningContent(endpointKey, model) {
if (endpointKey === 'deepseek')
return true;
if (endpointKey === 'openrouter')
return model.toLowerCase().startsWith('deepseek/');
return false;
}
function sanitizeOpenAiMessages(messages, endpointKey, model) {
if (!Array.isArray(messages))
return messages;
const preserveReasoningContent = supportsReasoningContent(endpointKey, model);
const isMistral = endpointKey === 'mistral';
const mistralIdMap = new Map();
const reservedMistralIds = new Set();
let generatedMistralIdCounter = 0;
const reserveMistralToolCallId = (toolCallId) => {
if (!isMistral || typeof toolCallId !== 'string')
return;
if (MISTRAL_TOOL_CALL_ID_REGEX.test(toolCallId)) {
reservedMistralIds.add(toolCallId);
}
};
if (isMistral) {
for (const message of messages) {
if (!message || typeof message !== 'object' || Array.isArray(message)) {
continue;
}
const rawMessage = message;
if (Array.isArray(rawMessage.tool_calls)) {
for (const toolCall of rawMessage.tool_calls) {
if (!toolCall || typeof toolCall !== 'object' || Array.isArray(toolCall)) {
continue;
}
reserveMistralToolCallId(toolCall.id);
}
}
if ('tool_call_id' in rawMessage) {
reserveMistralToolCallId(rawMessage.tool_call_id);
}
}
}
const nextGeneratedMistralId = () => {
do {
generatedMistralIdCounter += 1;
const candidate = `tc${generatedMistralIdCounter.toString(36).padStart(7, '0')}`;
if (!reservedMistralIds.has(candidate))
return candidate;
} while (true);
};
const normalizeMistralToolCallId = (toolCallId) => {
if (!isMistral || typeof toolCallId !== 'string')
return toolCallId;
const existing = mistralIdMap.get(toolCallId);
if (existing)
return existing;
if (MISTRAL_TOOL_CALL_ID_REGEX.test(toolCallId)) {
mistralIdMap.set(toolCallId, toolCallId);
reservedMistralIds.add(toolCallId);
return toolCallId;
}
const rewritten = nextGeneratedMistralId();
mistralIdMap.set(toolCallId, rewritten);
reservedMistralIds.add(rewritten);
return rewritten;
};
return messages.map((message) => {
if (!message || typeof message !== 'object' || Array.isArray(message)) {
return message;
}
const cleaned = { ...message };
if (!preserveReasoningContent) {
delete cleaned.reasoning_content;
}
if (isMistral && Array.isArray(cleaned.tool_calls)) {
cleaned.tool_calls = cleaned.tool_calls.map((toolCall) => {
if (!toolCall || typeof toolCall !== 'object' || Array.isArray(toolCall)) {
return toolCall;
}
const cleanedToolCall = { ...toolCall };
cleanedToolCall.id = normalizeMistralToolCallId(cleanedToolCall.id);
return cleanedToolCall;
});
}
if (isMistral && 'tool_call_id' in cleaned) {
cleaned.tool_call_id = normalizeMistralToolCallId(cleaned.tool_call_id);
}
return cleaned;
});
}
function normalizeDeepSeekMaxTokens(body) {
if (!('max_tokens' in body))
return;
const raw = body.max_tokens;
const parsed = typeof raw === 'number' ? raw : typeof raw === 'string' ? Number(raw) : Number.NaN;
if (!Number.isFinite(parsed) || parsed <= 0) {
delete body.max_tokens;
return;
}
body.max_tokens = Math.min(Math.trunc(parsed), DEEPSEEK_MAX_TOKENS_LIMIT);
if (body.max_tokens < 1)
delete body.max_tokens;
}
function sanitizeOpenAiBody(body, endpointKey, model) {
const passthroughTopLevel = PASSTHROUGH_PROVIDERS.has(endpointKey);
const bareForRegex = model.includes('/') ? model.substring(model.indexOf('/') + 1) : model;
const convertMaxTokens = endpointKey === 'openai' &&
OPENAI_MAX_COMPLETION_TOKENS_RE.test(bareForRegex) &&
'max_tokens' in body &&
!('max_completion_tokens' in body);
const cleaned = {};
for (const [key, value] of Object.entries(body)) {
if (key === 'messages') {
cleaned[key] = sanitizeOpenAiMessages(value, endpointKey, model);
continue;
}
if (passthroughTopLevel) {
if (convertMaxTokens && key === 'max_tokens') {
cleaned['max_completion_tokens'] = value;
continue;
}
cleaned[key] = value;
continue;
}
if (OPENAI_ONLY_FIELDS.has(key))
continue;
if (key === 'max_completion_tokens') {
if (!('max_tokens' in body))
cleaned['max_tokens'] = value;
continue;
}
cleaned[key] = value;
}
if (endpointKey === 'deepseek')
normalizeDeepSeekMaxTokens(cleaned);
return cleaned;
}
//# sourceMappingURL=provider-client-converters.js.map