UNPKG

braiin

Version:

Behavioral Reasoning AI for Intelligent Navigation

145 lines (144 loc) 5.29 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createOpenAIBackend = exports.buildCompletionParams = exports.buildMessages = void 0; const openai_1 = __importDefault(require("openai")); const llm_1 = require("../model/llm"); const stream_filter_1 = require("./stream.filter"); const DEFAULT_SERVER_URL = 'https://api.openai.com/v1'; const DEFAULT_MODEL = 'gpt-4o'; const DEFAULT_TEMPERATURE = 0; const DEFAULT_MAX_TOKENS = 8192; const buildMessages = (systemPrompt, prompt, history, enablePromptCaching = false) => { const systemContent = enablePromptCaching ? [{ type: 'text', text: systemPrompt, cache_control: { type: 'ephemeral' } }] : systemPrompt; return [ { role: 'system', content: systemContent }, ...history.map(msg => ({ role: msg.role, content: msg.content })), { role: 'user', content: prompt } ]; }; exports.buildMessages = buildMessages; const buildCompletionParams = (config, messages, stream = false) => { const params = { model: config.model ?? DEFAULT_MODEL, messages, max_tokens: config.maxTokens ?? DEFAULT_MAX_TOKENS, temperature: config.temperature ?? DEFAULT_TEMPERATURE, stream }; if (config.enforceJsonOutput) { params.response_format = { type: 'json_object' }; } return params; }; exports.buildCompletionParams = buildCompletionParams; const buildRequestSignal = (config) => { const signals = []; if (config.signal) signals.push(config.signal); if (config.timeoutMs !== undefined) signals.push(AbortSignal.timeout(config.timeoutMs)); if (signals.length === 0) return undefined; if (signals.length === 1) return signals[0]; return AbortSignal.any(signals); }; const handleCompletion = async (client, config, messages, signal) => { const params = (0, exports.buildCompletionParams)(config, messages, false); const completion = await client.chat.completions.create(params, { signal }); return { id: completion.id, object: completion.object, created: completion.created, model: completion.model, choices: completion.choices.map(choice => ({ index: choice.index, message: { role: choice.message.role, content: choice.message.content ?? '' }, finish_reason: choice.finish_reason ?? '' })) }; }; const handleStream = async (client, config, messages, callback, signal) => { const params = (0, exports.buildCompletionParams)(config, messages, true); const stream = await client.chat.completions.create(params, { signal }); let buffer = ''; let finishReason = ''; let id = ''; let model = config.model ?? DEFAULT_MODEL; let created = 0; for await (const chunk of stream) { id = chunk.id || id; model = chunk.model || model; created = chunk.created || created; const delta = chunk.choices?.[0]?.delta?.content; if (delta) { buffer += delta; callback(delta); } const fr = chunk.choices?.[0]?.finish_reason; if (fr) finishReason = fr; } callback(stream_filter_1.STREAM_END_MARKER); return { id, object: 'chat.completion', created, model, choices: [{ index: 0, message: { role: llm_1.LLMMessageRole.ASSISTANT, content: buffer }, finish_reason: finishReason }] }; }; const describeError = (error) => { if (error instanceof Error) { if (error.name === 'TimeoutError' || error.name === 'AbortError') { return { message: `Request aborted: ${error.message}`, type: 'timeout_error' }; } return { message: error.message, type: 'api_error' }; } return { message: 'Unknown error', type: 'api_error' }; }; const createOpenAIBackend = (config) => { const client = new openai_1.default({ apiKey: config.apiKey, baseURL: config.serverUrl ?? DEFAULT_SERVER_URL }); return { ask: async (systemPrompt, prompt, history, callback) => { const messages = (0, exports.buildMessages)(systemPrompt, prompt, history, config.enablePromptCaching); const signal = buildRequestSignal(config); try { if (callback) { return await handleStream(client, config, messages, callback, signal); } return await handleCompletion(client, config, messages, signal); } catch (error) { const { message, type } = describeError(error); return { id: '', object: '', created: 0, model: config.model ?? DEFAULT_MODEL, choices: [], error: { message, type, param: '', code: '' } }; } } }; }; exports.createOpenAIBackend = createOpenAIBackend;