Download src/utils/model/openRouterModels.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 4.27 kB
-
https://huggingface.co/chenbhao/codev/resolve/main/src/utils/model/openRouterModels.ts
- Command line
-
hf download hf://chenbhao/codev/src/utils/model/openRouterModels.ts
-
curl -L -o openRouterModels.ts https://huggingface.co/chenbhao/codev/resolve/main/src/utils/model/openRouterModels.ts
4.27 kB
| import type { ModelOption } from './modelOptions.js' | |
| let openRouterModelsCache: ModelOption[] | null = null | |
| let cacheTimestamp: number = 0 | |
| let isFetching = false | |
| const CACHE_DURATION = 5 * 60 * 1000 // 5 minutes | |
| export interface OpenRouterModel { | |
| id: string | |
| name: string | |
| description: string | |
| context_length: number | |
| pricing: { | |
| prompt: string | |
| completion: string | |
| } | |
| } | |
| function formatPrice(price: string): string { | |
| const numPrice = parseFloat(price) | |
| if (numPrice === 0) return 'Free' | |
| if (numPrice < 0.000001) return '$<0.000001' | |
| return `$${price}` | |
| } | |
| export async function fetchOpenRouterModels( | |
| apiKey?: string, | |
| ): Promise<ModelOption[]> { | |
| // Check cache | |
| if ( | |
| openRouterModelsCache !== null && | |
| Date.now() - cacheTimestamp < CACHE_DURATION | |
| ) { | |
| return openRouterModelsCache | |
| } | |
| // Prevent concurrent fetches | |
| if (isFetching) { | |
| return [] | |
| } | |
| isFetching = true | |
| // Import auth utilities to get API key | |
| const { getGlobalConfig } = await import('../config.js') | |
| const config = getGlobalConfig() | |
| const key = apiKey || config.openRouterApiKey | |
| if (!key) { | |
| isFetching = false | |
| return [] | |
| } | |
| try { | |
| const response = await fetch('https://openrouter.ai/api/v1/models', { | |
| headers: { | |
| Authorization: `Bearer ${key}`, | |
| }, | |
| }) | |
| if (!response.ok) { | |
| throw new Error(`Failed to fetch models: ${response.statusText}`) | |
| } | |
| const data = await response.json() | |
| const models: OpenRouterModel[] = data.data || [] | |
| // Filter out non-model items (routers, aggregators, etc.) | |
| const validModels = models.filter(model => { | |
| const id = model.id.toLowerCase() | |
| const name = model.name.toLowerCase() | |
| // Skip items that are routers, aggregators, or services | |
| const skipPatterns = [ | |
| 'router', | |
| 'aggregator', | |
| 'aggregation', | |
| 'free.*router', | |
| 'routing', | |
| 'service', | |
| 'platform', | |
| 'hub', | |
| ] | |
| // Skip if ID or name matches any skip pattern | |
| for (const pattern of skipPatterns) { | |
| if (new RegExp(pattern).test(id) || new RegExp(pattern).test(name)) { | |
| return false | |
| } | |
| } | |
| // Skip items without proper model ID format (should contain provider/model) | |
| if (!id.includes('/') || id.startsWith('router') || id.startsWith('free')) { | |
| return false | |
| } | |
| // Skip items without pricing information | |
| if (!model.pricing || !model.pricing.prompt || !model.pricing.completion) { | |
| return false | |
| } | |
| return true | |
| }) | |
| // Convert to ModelOption format | |
| const options: ModelOption[] = validModels.map(model => { | |
| // Truncate description if too long | |
| let description = model.description || model.id | |
| if (description.length > 100) { | |
| description = description.substring(0, 97) + '...' | |
| } | |
| return { | |
| value: model.id, | |
| label: model.name, | |
| description: description, | |
| } | |
| }) | |
| // Update cache | |
| openRouterModelsCache = options | |
| cacheTimestamp = Date.now() | |
| return options | |
| } catch (error) { | |
| console.error('Failed to fetch OpenRouter models:', error) | |
| return [] | |
| } finally { | |
| isFetching = false | |
| } | |
| } | |
| export function getCachedOpenRouterModels(): ModelOption[] { | |
| return openRouterModelsCache || [] | |
| } | |
| export function hasOpenRouterModelsCache(): boolean { | |
| return openRouterModelsCache !== null | |
| } | |
| export function getFirstFreeModel(): ModelOption | null { | |
| if (!openRouterModelsCache || openRouterModelsCache.length === 0) { | |
| return null | |
| } | |
| return openRouterModelsCache.find(model => { | |
| // Check if this model is free by looking at the model name | |
| // Models with ":free" or "(free)" in the name are free | |
| const label = (model.label || '').toLowerCase() | |
| const value = (model.value || '').toLowerCase() | |
| return label.includes(':free') || label.includes('(free)') || value.includes(':free') || value.includes('(free)') | |
| }) || null | |
| } | |
| export function clearOpenRouterModelsCache(): void { | |
| openRouterModelsCache = null | |
| cacheTimestamp = 0 | |
| } | |
| // Start background fetch if OpenRouter is configured | |
| export function startOpenRouterModelsFetch(): void { | |
| // Non-blocking background fetch | |
| void fetchOpenRouterModels() | |
| } |