Spaces:
Running
Running
File size: 4,524 Bytes
15a5288 |
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
import type { ProviderEntry, ProviderFetcher } from './types';
interface HFRouterModel {
id: string;
object: string;
created: number;
owned_by: string;
providers?: HFRouterProvider[];
}
interface HFRouterProvider {
provider: string;
status?: "live" | "offline" | "staging" | "deprecated";
context_length?: number;
pricing?: {
input: number; // cents per million tokens
output: number; // cents per million tokens
};
supports_tools?: boolean;
supports_structured_output?: boolean;
}
export class HuggingFaceRouterFetcher implements ProviderFetcher {
name = 'huggingface-router';
async fetchModels(): Promise<ProviderEntry[]> {
try {
const response = await fetch('https://router.huggingface.co/v1/models');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json() as { data: HFRouterModel[] };
return this.normalizeModels(data.data);
} catch (error) {
console.error('Failed to fetch HuggingFace router models:', error);
throw error;
}
}
private normalizeModels(models: HFRouterModel[]): ProviderEntry[] {
const entries: ProviderEntry[] = [];
for (const model of models) {
if (!model.providers) continue;
for (const provider of model.providers) {
const entry: ProviderEntry = {
provider: this.normalizeProviderName(provider.provider),
model_id: model.id,
owned_by: model.owned_by,
created: model.created,
};
// Set status
if (provider.status) {
entry.status = provider.status === "staging" ? "offline" : provider.status;
}
// Convert pricing from cents to dollars per million tokens
if (provider.pricing) {
entry.pricing = {
input: provider.pricing.input / 100, // cents to dollars
output: provider.pricing.output / 100, // cents to dollars
};
}
// Copy context length
if (provider.context_length) {
entry.context_length = provider.context_length;
}
// Copy capability flags
if (provider.supports_tools !== undefined) {
entry.supports_tools = provider.supports_tools;
}
if (provider.supports_structured_output !== undefined) {
entry.supports_structured_output = provider.supports_structured_output;
}
entries.push(entry);
}
}
return entries;
}
private normalizeProviderName(providerName: string): string {
// Map HF router provider names to our standard names
const providerMap: Record<string, string> = {
'featherless-ai': 'featherless',
'fireworks-ai': 'fireworks',
'hf-inference': 'huggingface',
// Keep others as-is
};
return providerMap[providerName] || providerName;
}
}
// Helper function to extract HF router data from a model
export function extractHFRouterData(model: any): Map<string, ProviderEntry> {
const providerMap = new Map<string, ProviderEntry>();
if (!model.providers || !Array.isArray(model.providers)) {
return providerMap;
}
for (const provider of model.providers) {
if (!provider.provider) continue;
const entry: ProviderEntry = {
provider: provider.provider,
};
// Set status
if (provider.status) {
entry.status = provider.status === "staging" ? "offline" : provider.status;
}
// Convert pricing from cents to dollars if needed
if (provider.pricing) {
// Check if pricing is already in dollars (values < 100 likely dollars)
const needsConversion = provider.pricing.input >= 100 || provider.pricing.output >= 100;
entry.pricing = {
input: needsConversion ? provider.pricing.input / 100 : provider.pricing.input,
output: needsConversion ? provider.pricing.output / 100 : provider.pricing.output,
};
}
// Copy other fields
if (provider.context_length) {
entry.context_length = provider.context_length;
}
if (provider.supports_tools !== undefined) {
entry.supports_tools = provider.supports_tools;
}
if (provider.supports_structured_output !== undefined) {
entry.supports_structured_output = provider.supports_structured_output;
}
providerMap.set(provider.provider, entry);
}
return providerMap;
} |