braiin
Version:
Behavioral Reasoning AI for Intelligent Navigation
145 lines (144 loc) • 5.29 kB
JavaScript
;
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;