| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- /**
- * OpenAI-compatible provider — proxies requests to any OpenAI-compatible backend
- * (vLLM, Ollama, LiteLLM, etc.) using native fetch().
- */
- export function createProvider(config) {
- const { id, baseUrl, apiKey, models } = config;
- // Normalize baseUrl: strip trailing slash, ensure /v1 is present
- let normalizedUrl = baseUrl.replace(/\/+$/, '');
- if (!normalizedUrl.endsWith('/v1')) {
- normalizedUrl += '/v1';
- }
- const completionsUrl = `${normalizedUrl}/chat/completions`;
- function buildHeaders() {
- const headers = { 'Content-Type': 'application/json' };
- if (apiKey) headers['Authorization'] = `Bearer ${apiKey}`;
- return headers;
- }
- function buildBody(messages, modelId, options, stream) {
- const providerModelId = models[modelId] || modelId;
- const body = { model: providerModelId, messages, stream };
- if (options.temperature !== undefined) body.temperature = options.temperature;
- if (options.max_tokens !== undefined) body.max_tokens = options.max_tokens;
- if (options.top_p !== undefined) body.top_p = options.top_p;
- if (options.stop !== undefined) body.stop = options.stop;
- return body;
- }
- async function request(messages, modelId, options, stream) {
- const body = buildBody(messages, modelId, options, stream);
- const headers = buildHeaders();
- let response;
- try {
- response = await fetch(completionsUrl, {
- method: 'POST',
- headers,
- body: JSON.stringify(body)
- });
- } catch (error) {
- throw new Error(`OpenAI-compatible provider request failed: ${error.message}`);
- }
- if (!response.ok) {
- let errorBody = '';
- try { errorBody = await response.text(); } catch { /* ignore */ }
- throw new Error(
- `OpenAI-compatible provider returned ${response.status}${errorBody ? `: ${errorBody}` : ''}`
- );
- }
- return response;
- }
- async function chat(messages, modelId, options = {}) {
- const response = await request(messages, modelId, options, false);
- return response.json();
- }
- async function chatStream(messages, modelId, options = {}) {
- const response = await request(messages, modelId, options, true);
- return response.body;
- }
- return { id, chat, chatStream };
- }
|