Spaces:
No application file
No application file
File size: 2,450 Bytes
c20f20c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /**
* Shared model resolution utilities for API routes.
*
* Extracts the repeated parseModelString → resolveApiKey → resolveBaseUrl →
* resolveProxy → getModel boilerplate into a single call.
*/
import type { NextRequest } from 'next/server';
import { getModel, parseModelString, type ModelWithInfo } from '@/lib/ai/providers';
import { resolveApiKey, resolveBaseUrl, resolveProxy } from '@/lib/server/provider-config';
import { validateUrlForSSRF } from '@/lib/server/ssrf-guard';
export interface ResolvedModel extends ModelWithInfo {
/** Original model string (e.g. "openai/gpt-4o-mini") */
modelString: string;
}
/**
* Resolve a language model from explicit parameters.
*
* Use this when model config comes from the request body.
*/
export function resolveModel(params: {
modelString?: string;
apiKey?: string;
baseUrl?: string;
providerType?: string;
requiresApiKey?: boolean;
}): ResolvedModel {
const modelString = params.modelString || process.env.DEFAULT_MODEL || 'gpt-4o-mini';
const { providerId, modelId } = parseModelString(modelString);
const clientBaseUrl = params.baseUrl || undefined;
if (clientBaseUrl && process.env.NODE_ENV === 'production') {
const ssrfError = validateUrlForSSRF(clientBaseUrl);
if (ssrfError) {
throw new Error(ssrfError);
}
}
const apiKey = clientBaseUrl
? params.apiKey || ''
: resolveApiKey(providerId, params.apiKey || '');
const baseUrl = clientBaseUrl ? clientBaseUrl : resolveBaseUrl(providerId, params.baseUrl);
const proxy = resolveProxy(providerId);
const { model, modelInfo } = getModel({
providerId,
modelId,
apiKey,
baseUrl,
proxy,
providerType: params.providerType as 'openai' | 'anthropic' | 'google' | undefined,
requiresApiKey: params.requiresApiKey,
});
return { model, modelInfo, modelString };
}
/**
* Resolve a language model from standard request headers.
*
* Reads: x-model, x-api-key, x-base-url, x-provider-type, x-requires-api-key
*/
export function resolveModelFromHeaders(req: NextRequest): ResolvedModel {
return resolveModel({
modelString: req.headers.get('x-model') || undefined,
apiKey: req.headers.get('x-api-key') || undefined,
baseUrl: req.headers.get('x-base-url') || undefined,
providerType: req.headers.get('x-provider-type') || undefined,
requiresApiKey: req.headers.get('x-requires-api-key') === 'true' ? true : undefined,
});
}
|