builder / lib /llm /request-builder.ts
Leon4gr45's picture
Upload folder using huggingface_hub (part 2)
391c43e verified
Raw
History Blame Contribute Delete
2.52 kB
import type { ProviderConfig, ProviderId } from '@/lib/llm/providers/types';
import type { WireFormat } from '@/lib/llm/providers/wire-format';
/** Resolve the upstream endpoint for a request, by wire format. */
export function getApiEndpoint(
provider: ProviderId,
config: ProviderConfig,
model?: string,
options?: { apiKey?: string; stream?: boolean },
overrideBaseUrl?: string,
wireFormat?: WireFormat,
): string {
const baseUrl = overrideBaseUrl || config.baseUrl || 'https://openrouter.ai/api/v1';
if (wireFormat === 'anthropic') {
return provider === 'anthropic' ? 'https://api.anthropic.com/v1/messages' : `${baseUrl}/messages`;
} else if (provider === 'gemini') {
const geminiModel = model || 'gemini-2.5-flash';
const action = options?.stream ? 'streamGenerateContent?alt=sse' : 'generateContent';
const key = options?.apiKey ? `${options.stream ? '&' : '?'}key=${options.apiKey}` : '';
return `https://generativelanguage.googleapis.com/v1beta/models/${geminiModel}:${action}${key}`;
} else {
return `${baseUrl}/chat/completions`;
}
}
/** Build request headers, by wire format. `referer` is the incoming request's referer (for OpenRouter attribution). */
export function buildHeaders(
provider: ProviderId,
apiKey: string | undefined,
referer: string | null,
config: ProviderConfig,
wireFormat?: WireFormat,
): Record<string, string> {
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
if (wireFormat === 'anthropic') {
headers['x-api-key'] = apiKey || '';
headers['anthropic-version'] = '2023-06-01';
if (provider === 'anthropic' && config.supportsFunctions) {
headers['anthropic-beta'] = 'tools-2024-04-04';
}
} else if (provider === 'gemini') {
// Gemini uses query-param key auth; no auth headers needed
} else {
if (apiKey) headers['Authorization'] = `Bearer ${apiKey}`;
if (provider === 'openrouter') {
headers['HTTP-Referer'] = referer || 'http://localhost:3000';
headers['X-Title'] = 'OSW-Studio';
}
}
return headers;
}
/** Sampling temperature. A few models reject anything but 1: OpenAI's gpt-5-nano and
* Opencode Go's Moonshot/Kimi models. Everything else uses 0.7. */
export function resolveTemperature(provider: ProviderId, model: string): number {
const m = (model || '').toLowerCase();
if (provider === 'openai' && m.includes('gpt-5-nano')) return 1;
if (provider === 'opencode-go' && m.startsWith('kimi-')) return 1;
return 0.7;
}