|
|
|
|
|
import config from '../config/config.js'; |
|
|
import os from 'os'; |
|
|
import { REASONING_EFFORT_MAP, DEFAULT_STOP_SEQUENCES } from '../constants/index.js'; |
|
|
import { toGenerationConfig } from './parameterNormalizer.js'; |
|
|
|
|
|
|
|
|
const CLAUDE_THOUGHT_SIGNATURE = 'RXNZRENrZ0lDaEFDR0FJcVFMZzVPTmZsd1ZHNmZKK3labDJ0TkNlRzc5QUpzUHV2OW9UZG1yc0JUUGNsUjFBQWhKNWlYcXhlU0dTaEtxeWJ1NUdaM2YvMXByaHJCSnk3OEhsWkxOd1NEREI5Mi8zQXFlYkUvY3RISEJvTXlGVHNzdzRJZXkxUTFkUURJakE3R3AwSXJQeW0xdWxLMVBXcFhuRElPdmJFRFd4LzV2cUZaQTg2NWU1SkM3QnY2dkxwZE43M2dLYkljaThobGR3cXF3S1VMbHE5b3NMdjc3QnNhZm5mbDhlbUd5NmJ6WVRpUnRWcXA0MDJabmZ2Tnl3T2hJd1BBV0l1SUNTdjFTemswZlNmemR0Z2R5eGgxaUJOZHhHNXVhZWhKdWhlUUwza3RDZWVxa2dMNFE0ZjRKWkFnR3pKOHNvaStjZ1pqRXJHT1lyNjJkdkxnUUVoT1E5MjN6bEUwRFd4aXdPU1JOK3VSRWdHZ0FKVkhZcjBKVzhrVTZvaEVaYk1IVkE4aG14ZElGMm9YK1ZxRnFUSGFDZWZEYWNQNTJVOW94VmJ0cFhrNnJUanQ2ZHpadEFMWThXQWs5RFI3bTJTbGova2VraXFzVVBRbFdIaFNUN3diZGpuVkYvdUVoODRWbXQ5WjdtaThtR2JEcTdaTHVOalF0T3hHMVpXbXJmeUpCMExwa0R1SnZDV01qZ3BqTHdsU0R4SUpmeEFoT2JzQlVpRzdLTDYwcUluanZaK1VTcXdjZGhmN0U3ZjgrN0l2ZXczRC9DZUYvdlptQ0JqU2JTcUdYYmFIQmdC'; |
|
|
const GEMINI_THOUGHT_SIGNATURE = 'EqAHCp0HAXLI2nygRbdzD4Vgzxxi7tbM87zIRkNgPLqTj+Jxv9mY8Q0G87DzbTtvsIFhWB0RZMoEK6ntm5GmUe6ADtxHk4zgHUs/FKqTu8tzUdPRDrKn3KCAtFW4LJqijZoFxNKMyQRmlgPUX4tGYE7pllD77UK6SjCwKhKZoSVZLMiPXP9YFktbida1Q5upXMrzG1t8abPmpFo983T/rgWlNqJp+Fb+bsoH0zuSpmU4cPKO3LIGsxBhvRhM/xydahZD+VpEX7TEJAN58z1RomFyx9u0IR7ukwZr2UyoNA+uj8OChUDFupQsVwbm3XE1UAt22BGvfYIyyZ42fxgOgsFFY+AZ72AOufcmZb/8vIw3uEUgxHczdl+NGLuS4Hsy/AAntdcH9sojSMF3qTf+ZK1FMav23SPxUBtU5T9HCEkKqQWRnMsVGYV1pupFisWo85hRLDTUipxVy9ug1hN8JBYBNmGLf8KtWLhVp7Z11PIAZj3C6HzoVyiVeuiorwNrn0ZaaXNe+y5LHuDF0DNZhrIfnXByq6grLLSAv4fTLeCJvfGzTWWyZDMbVXNx1HgumKq8calP9wv33t0hfEaOlcmfGIyh1J/N+rOGR0WXcuZZP5/VsFR44S2ncpwTPT+MmR0PsjocDenRY5m/X4EXbGGkZ+cfPnWoA64bn3eLeJTwxl9W1ZbmYS6kjpRGUMxExgRNOzWoGISddHCLcQvN7o50K8SF5k97rxiS5q4rqDmqgRPXzQTQnZyoL3dCxScX9cvLSjNCZDcotonDBAWHfkXZ0/EmFiONQcLJdANtAjwoA44Mbn50gubrTsNd7d0Rm/hbNEh/ZceUalV5MMcl6tJtahCJoybQMsnjWuBXl7cXiKmqAvxTDxIaBgQBYAo4FrbV4zQv35zlol+O3YiyjJn/U0oBeO5pEcH1d0vnLgYP71jZVY2FjWRKnDR9aw4JhiuqAa+i0tupkBy+H4/SVwHADFQq6wcsL8qvXlwktJL9MIAoaXDkIssw6gKE9EuGd7bSO9f+sA8CZ0I8LfJ3jcHUsE/3qd4pFrn5RaET56+1p8ZHZDDUQ0p1okApUCCYsC2WuL6O9P4fcg3yitAA/AfUUNjHKANE+ANneQ0efMG7fx9bvI+iLbXgPupApoov24JRkmhHsrJiu9bp+G/pImd2PNv7ArunJ6upl0VAUWtRyLWyGfdl6etGuY8vVJ7JdWEQ8aWzRK3g6e+8YmDtP5DAfw=='; |
|
|
const CLAUDE_TOOL_SIGNATURE = 'RXVNQkNrZ0lDaEFDR0FJcVFLZGsvMnlyR0VTbmNKMXEyTFIrcWwyY2ozeHhoZHRPb0VOYWJ2VjZMSnE2MlBhcEQrUWdIM3ZWeHBBUG9rbGN1aXhEbXprZTcvcGlkbWRDQWs5MWcrTVNERnRhbWJFOU1vZWZGc1pWSGhvTUxsMXVLUzRoT3BIaWwyeXBJakNYa05EVElMWS9talprdUxvRjFtMmw5dnkrbENhSDNNM3BYNTM0K1lRZ0NaWTQvSUNmOXo4SkhZVzU2Sm1WcTZBcVNRUURBRGVMV1BQRXk1Q0JsS0dCZXlNdHp2NGRJQVlGbDFSMDBXNGhqNHNiSWNKeGY0UGZVQTBIeE1mZjJEYU5BRXdrWUJ4MmNzRFMrZGM1N1hnUlVNblpkZ0hTVHVNaGdod1lBUT09'; |
|
|
const GEMINI_TOOL_SIGNATURE = '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'; |
|
|
|
|
|
export function getThoughtSignatureForModel(actualModelName) { |
|
|
if (!actualModelName) return CLAUDE_THOUGHT_SIGNATURE; |
|
|
const lower = actualModelName.toLowerCase(); |
|
|
if (lower.includes('claude')) return CLAUDE_THOUGHT_SIGNATURE; |
|
|
if (lower.includes('gemini')) return GEMINI_THOUGHT_SIGNATURE; |
|
|
return CLAUDE_THOUGHT_SIGNATURE; |
|
|
} |
|
|
|
|
|
export function getToolSignatureForModel(actualModelName) { |
|
|
if (!actualModelName) return CLAUDE_TOOL_SIGNATURE; |
|
|
const lower = actualModelName.toLowerCase(); |
|
|
if (lower.includes('claude')) return CLAUDE_TOOL_SIGNATURE; |
|
|
if (lower.includes('gemini')) return GEMINI_TOOL_SIGNATURE; |
|
|
return CLAUDE_TOOL_SIGNATURE; |
|
|
} |
|
|
|
|
|
|
|
|
export function sanitizeToolName(name) { |
|
|
if (!name || typeof name !== 'string') return 'tool'; |
|
|
let cleaned = name.replace(/[^a-zA-Z0-9_-]/g, '_'); |
|
|
cleaned = cleaned.replace(/^_+|_+$/g, ''); |
|
|
if (!cleaned) cleaned = 'tool'; |
|
|
if (cleaned.length > 128) cleaned = cleaned.slice(0, 128); |
|
|
return cleaned; |
|
|
} |
|
|
|
|
|
|
|
|
const EXCLUDED_KEYS = new Set([ |
|
|
'$schema', 'additionalProperties', 'minLength', 'maxLength', |
|
|
'minItems', 'maxItems', 'uniqueItems', 'exclusiveMaximum', |
|
|
'exclusiveMinimum', 'const', 'anyOf', 'oneOf', 'allOf', |
|
|
'any_of', 'one_of', 'all_of', 'multipleOf' |
|
|
]); |
|
|
|
|
|
export function cleanParameters(obj) { |
|
|
if (!obj || typeof obj !== 'object') return obj; |
|
|
const cleaned = Array.isArray(obj) ? [] : {}; |
|
|
for (const [key, value] of Object.entries(obj)) { |
|
|
if (EXCLUDED_KEYS.has(key)) continue; |
|
|
cleaned[key] = (value && typeof value === 'object') ? cleanParameters(value) : value; |
|
|
} |
|
|
return cleaned; |
|
|
} |
|
|
|
|
|
|
|
|
export function modelMapping(modelName) { |
|
|
if (modelName === 'claude-sonnet-4-5-thinking') return 'claude-sonnet-4-5'; |
|
|
if (modelName === 'claude-opus-4-5') return 'claude-opus-4-5-thinking'; |
|
|
if (modelName === 'gemini-2.5-flash-thinking') return 'gemini-2.5-flash'; |
|
|
return modelName; |
|
|
} |
|
|
|
|
|
export function isEnableThinking(modelName) { |
|
|
return modelName.includes('-thinking') || |
|
|
modelName === 'gemini-2.5-pro' || |
|
|
modelName.startsWith('gemini-3-pro-') || |
|
|
modelName === 'rev19-uic3-1p' || |
|
|
modelName === 'gpt-oss-120b-medium'; |
|
|
} |
|
|
|
|
|
|
|
|
export function generateGenerationConfig(parameters, enableThinking, actualModelName) { |
|
|
|
|
|
const normalizedParams = { |
|
|
temperature: parameters.temperature ?? config.defaults.temperature, |
|
|
top_p: parameters.top_p ?? config.defaults.top_p, |
|
|
top_k: parameters.top_k ?? config.defaults.top_k, |
|
|
max_tokens: parameters.max_tokens ?? config.defaults.max_tokens, |
|
|
thinking_budget: parameters.thinking_budget, |
|
|
}; |
|
|
|
|
|
|
|
|
if (normalizedParams.thinking_budget === undefined && parameters.reasoning_effort !== undefined) { |
|
|
const defaultThinkingBudget = config.defaults.thinking_budget ?? 1024; |
|
|
normalizedParams.thinking_budget = REASONING_EFFORT_MAP[parameters.reasoning_effort] ?? defaultThinkingBudget; |
|
|
} |
|
|
|
|
|
|
|
|
const generationConfig = toGenerationConfig(normalizedParams, enableThinking, actualModelName); |
|
|
|
|
|
|
|
|
generationConfig.stopSequences = DEFAULT_STOP_SEQUENCES; |
|
|
|
|
|
return generationConfig; |
|
|
} |
|
|
|
|
|
|
|
|
export function extractSystemInstruction(openaiMessages) { |
|
|
const baseSystem = config.systemInstruction || ''; |
|
|
if (!config.useContextSystemPrompt) return baseSystem; |
|
|
|
|
|
const systemTexts = []; |
|
|
for (const message of openaiMessages) { |
|
|
if (message.role === 'system') { |
|
|
const content = typeof message.content === 'string' |
|
|
? message.content |
|
|
: (Array.isArray(message.content) |
|
|
? message.content.filter(item => item.type === 'text').map(item => item.text).join('') |
|
|
: ''); |
|
|
if (content.trim()) systemTexts.push(content.trim()); |
|
|
} else { |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
const parts = []; |
|
|
if (baseSystem.trim()) parts.push(baseSystem.trim()); |
|
|
if (systemTexts.length > 0) parts.push(systemTexts.join('\n\n')); |
|
|
return parts.join('\n\n'); |
|
|
} |
|
|
|
|
|
|
|
|
export function prepareImageRequest(requestBody) { |
|
|
if (!requestBody || !requestBody.request) return requestBody; |
|
|
let imageSize = "1K"; |
|
|
if (requestBody.model.includes('4K')){ |
|
|
imageSize = "4K"; |
|
|
} else if (requestBody.model.includes('2K')){ |
|
|
imageSize = "2K"; |
|
|
} else { |
|
|
imageSize = "1K"; |
|
|
} |
|
|
if (imageSize !== "1K"){ |
|
|
requestBody.model = requestBody.model.slice(0, -3); |
|
|
} |
|
|
requestBody.request.generationConfig = { |
|
|
candidateCount: 1, |
|
|
imageConfig: { |
|
|
imageSize: imageSize |
|
|
} |
|
|
}; |
|
|
requestBody.requestType = 'image_gen'; |
|
|
delete requestBody.request.systemInstruction; |
|
|
delete requestBody.request.tools; |
|
|
delete requestBody.request.toolConfig; |
|
|
return requestBody; |
|
|
} |
|
|
|
|
|
|
|
|
export function getDefaultIp() { |
|
|
const interfaces = os.networkInterfaces(); |
|
|
if (interfaces.WLAN) { |
|
|
for (const inter of interfaces.WLAN) { |
|
|
if (inter.family === 'IPv4' && !inter.internal) { |
|
|
return inter.address; |
|
|
} |
|
|
} |
|
|
} else if (interfaces.wlan2) { |
|
|
for (const inter of interfaces.wlan2) { |
|
|
if (inter.family === 'IPv4' && !inter.internal) { |
|
|
return inter.address; |
|
|
} |
|
|
} |
|
|
} |
|
|
return '127.0.0.1'; |
|
|
} |
|
|
|
|
|
|
|
|
export { generateRequestId } from './idGenerator.js'; |
|
|
export { generateRequestBody } from './converters/openai.js'; |
|
|
export { generateClaudeRequestBody } from './converters/claude.js'; |
|
|
export { generateGeminiRequestBody } from './converters/gemini.js'; |
|
|
|