@agentproto/catalog-sync 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/bin.mjs +259 -17
- package/dist/bin.mjs.map +1 -1
- package/dist/generators/llm-requesty.d.ts +5 -0
- package/dist/generators/llm-requesty.mjs +132 -0
- package/dist/generators/llm-requesty.mjs.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.mjs +247 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -2
- package/snapshots/llm-huggingface.json +5489 -0
- package/snapshots/llm-moonshot.json +61 -61
- package/snapshots/llm-openrouter.json +29319 -35
- package/snapshots/llm-requesty.json +14447 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types.ts","../../src/generators/llm-requesty.ts"],"names":[],"mappings":"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","file":"llm-requesty.mjs","sourcesContent":["/**\n * catalog-sync generator contract.\n *\n * FROZEN — a sibling agent builds provider generators against this surface.\n * Do not change field names, shapes, or the `defineGenerator` signature\n * without coordinating. Adding new generators is the expected extension\n * path; editing this file is not.\n */\n\nexport interface CatalogSource {\n id: string\n url: string\n /** HTTP method for the live (`--refresh`) fetch. Default `\"GET\"`. */\n method?: \"GET\" | \"POST\"\n /**\n * Request headers for the live fetch. A value may embed `env:VAR_NAME`\n * tokens, resolved from `process.env` at fetch time (e.g.\n * `{ \"xi-api-key\": \"env:ELEVENLABS_API_KEY\" }` or\n * `{ Authorization: \"Bearer env:MINIMAX_API_KEY\" }`). If any referenced env\n * var is unset, the source is treated as un-refreshable — the committed\n * snapshot is reused rather than fetched without auth. Offline reads\n * (default, no `--refresh`) ignore headers entirely.\n */\n headers?: Record<string, string>\n /** JSON request body for POST sources (e.g. MiniMax `get_voice`). */\n body?: unknown\n}\n\nexport interface GeneratorContext {\n /**\n * Reads the pinned snapshot at `snapshots/<src.id>.json`; if missing and\n * `refresh=true`, fetches `src.url` and writes the snapshot. Returns\n * parsed JSON.\n *\n * Offline by default: when no snapshot exists and `refresh` is false this\n * throws — generators MUST be runnable without network access so CI and\n * tests are deterministic. The only network path is behind `--refresh`.\n */\n fetchSource(src: CatalogSource): Promise<unknown>\n refresh: boolean\n}\n\n/** Repo-relative path → TS source text. */\nexport type GeneratedFiles = Record<string, string>\n\nexport interface CatalogGenerator {\n /** e.g. \"llm:openrouter\" */\n name: string\n modality: \"llm\" | \"image\" | \"video\" | \"audio\" | \"voice\"\n sources: CatalogSource[]\n generate(ctx: GeneratorContext): Promise<GeneratedFiles>\n}\n\n/** Identity helper — lets a generator module declare itself with type inference. */\nexport function defineGenerator(g: CatalogGenerator): CatalogGenerator {\n return g\n}\n","import { z } from \"zod\"\n\nimport { defineGenerator, type GeneratedFiles, type GeneratorContext } from \"../types.js\"\n\n/**\n * PINNED source. The Requesty `/v1/models` payload lists every route the\n * router exposes with per-token USD pricing. We never fetch it at build or\n * test time — only behind `--refresh`, which writes\n * `snapshots/llm-requesty.json` so the next offline run is deterministic.\n * Live fetch requires `Authorization: Bearer $REQUESTY_API_KEY` (see\n * `sources` below) — without the key set, the framework reuses the\n * committed snapshot rather than fetching unauthenticated.\n */\nconst REQUESTY_MODELS_URL = \"https://router.requesty.ai/v1/models\"\n\n/** Repo-relative drop-in target for {@link @agentproto/model-catalog}. */\nconst OUTPUT_PATH = \"packages/model-catalog/src/llm/requesty-routes.generated.ts\"\n\n// ── Source schema ────────────────────────────────────────────────────────\n// UNLIKE OpenRouter, Requesty prices are JSON **numbers** in USD-PER-TOKEN\n// (e.g. `4e-7` = $0.40/1M), not strings, and live flat on the model entry\n// rather than nested under a `pricing` object. `cached_price` is a cache\n// READ price (no cache-write price exists in this source — we never emit\n// `cacheWriteMultiplier`). `supports_caching` gates whether `cached_price`\n// is actually meaningful: some entries carry a non-zero `cached_price` with\n// `supports_caching: false` (cache pricing published but not offered), so\n// the multiplier must only be derived when the flag is true. passthrough()\n// keeps the other live keys (context_window, supports_vision, description,\n// …) forward-compatible without a regenerate — we only read what we model.\n\nconst ModelSchema = z\n .object({\n id: z.string(),\n input_price: z.number().optional(),\n output_price: z.number().optional(),\n cached_price: z.number().optional(),\n supports_caching: z.boolean().optional(),\n })\n .passthrough()\n\nconst SnapshotSchema = z.object({\n data: z.array(ModelSchema),\n})\n\n// ── Output shape (mirrors model-catalog's LLMPricing) ────────────────────\n// Drop-in for `packages/model-catalog/src/llm/requesty-routes.generated.ts`.\n// Structurally identical to LLMPricing — inputPer1M / outputPer1M in USD per\n// 1M tokens, plus cacheReadMultiplier when the source carries a meaningful\n// `cached_price`. No `cacheWriteMultiplier` — Requesty has no cache-write\n// price to derive one from.\n\ninterface LLMPricingEntry {\n inputPer1M: number\n outputPer1M: number\n cacheReadMultiplier?: number\n vendor: string\n provider: \"requesty\"\n}\n\n// ── Number helpers ──────────────────────────────────────────────────────\n\n/** Round to 6 decimal places, killing binary-float noise from the per-token × 1e6 product. */\nfunction round6(n: number): number {\n return Math.round(n * 1_000_000) / 1_000_000\n}\n\n/**\n * Convert a per-token USD number to USD-per-1M-tokens, or undefined if\n * unpriced. UNLIKE OpenRouter (per-token USD strings), Requesty already\n * gives per-token USD as a JSON number, so there's no `Number(...)` parse\n * step — just the same ×1e6 + round6 normalization.\n */\nfunction per1m(tokenPrice: number | undefined): number | undefined {\n if (tokenPrice === undefined) return undefined\n if (!Number.isFinite(tokenPrice)) return undefined\n return round6(tokenPrice * 1_000_000)\n}\n\n/** Shortest faithful decimal string (matches existing file: 1, 0.5, 0.7448, 1.25). */\nfunction fmt(n: number): string {\n if (!Number.isFinite(n)) return \"0\"\n return `${round6(n)}`\n}\n\n/** Vendor slug = first segment of the Requesty route id (`vendor/model`). */\nfunction vendorOf(id: string): string {\n if (!id.includes(\"/\")) return id\n return id.split(\"/\")[0] ?? id\n}\n\n// ── Serialization ────────────────────────────────────────────────────────\n\nfunction serializeEntry(e: LLMPricingEntry): string {\n const fields: string[] = [\n `inputPer1M: ${fmt(e.inputPer1M)}`,\n `outputPer1M: ${fmt(e.outputPer1M)}`,\n ]\n if (e.cacheReadMultiplier !== undefined) {\n fields.push(`cacheReadMultiplier: ${fmt(e.cacheReadMultiplier)}`)\n }\n fields.push(`vendor: ${JSON.stringify(e.vendor)}`)\n fields.push(`provider: ${JSON.stringify(e.provider)}`)\n return `{\\n ${fields.join(\",\\n \")},\\n }`\n}\n\nfunction serializeFile(entries: Record<string, LLMPricingEntry>): string {\n const ids = Object.keys(entries).sort()\n const providers = Array.from(new Set(ids.map(vendorOf))).sort()\n\n const lines: string[] = [\n \"// AUTO-GENERATED by @agentproto/catalog-sync (llm:requesty).\",\n \"// Do not edit by hand — re-run `pnpm --filter @agentproto/catalog-sync generate`.\",\n `// Source: ${REQUESTY_MODELS_URL}`,\n \"// Pricing carries provider USD (inputPer1M / outputPer1M) plus a cache\",\n \"// multiplier (cacheReadMultiplier) derived from the source's cached_price\",\n \"// per-token field when `supports_caching` is true. Requesty has no\",\n \"// cache-write price, so cacheWriteMultiplier is never emitted.\",\n \"\",\n 'import type { LLMPricing } from \"./catalog.js\"',\n \"\",\n \"export const REQUESTY_ROUTES: Record<string, LLMPricing> = {\",\n ]\n for (const id of ids) {\n lines.push(` ${JSON.stringify(id)}: ${serializeEntry(entries[id]!)},`)\n }\n lines.push(\"}\")\n lines.push(\"\")\n lines.push(\"/** Provider slugs treated as Requesty routes by the picker. */\")\n lines.push(\"export const REQUESTY_PROVIDERS: readonly string[] = [\")\n for (const p of providers) {\n lines.push(` ${JSON.stringify(p)},`)\n }\n lines.push(\"]\")\n lines.push(\"\")\n return lines.join(\"\\n\")\n}\n\n// ── Generator ───────────────────────────────────────────────────────────\n\nasync function generate(ctx: GeneratorContext): Promise<GeneratedFiles> {\n const src = sources[0]\n if (!src) throw new Error(\"llm:requesty: no source configured\")\n const parsed = SnapshotSchema.parse(await ctx.fetchSource(src))\n\n const entries: Record<string, LLMPricingEntry> = {}\n for (const model of parsed.data) {\n const inputPer1M = per1m(model.input_price)\n const outputPer1M = per1m(model.output_price)\n if (inputPer1M === undefined || outputPer1M === undefined) continue\n // Skip unpriced routes.\n if (inputPer1M === 0 && outputPer1M === 0) continue\n\n const entry: LLMPricingEntry = {\n inputPer1M,\n outputPer1M,\n vendor: vendorOf(model.id),\n provider: \"requesty\",\n }\n\n if (model.supports_caching === true && inputPer1M > 0) {\n const cachePer1M = per1m(model.cached_price)\n if (cachePer1M !== undefined) {\n entry.cacheReadMultiplier = round6(cachePer1M / inputPer1M)\n }\n }\n\n entries[model.id] = entry\n }\n\n return { [OUTPUT_PATH]: serializeFile(entries) }\n}\n\nconst sources = [\n {\n id: \"llm-requesty\",\n url: REQUESTY_MODELS_URL,\n // Live refresh needs the account key (Bearer). Without REQUESTY_API_KEY\n // set, the framework reuses the committed snapshot.\n headers: { Authorization: \"Bearer env:REQUESTY_API_KEY\" },\n },\n]\n\nexport const llmRequestyGenerator = defineGenerator({\n name: \"llm:requesty\",\n modality: \"llm\",\n sources,\n generate,\n})\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,12 @@ import { CatalogGenerator } from './types.js';
|
|
|
2
2
|
export { CatalogSource, GeneratedFiles, GeneratorContext, defineGenerator } from './types.js';
|
|
3
3
|
export { RunGeneratorsOptions, RunGeneratorsResult, runGenerators } from './runner.js';
|
|
4
4
|
export { llmOpenRouterGenerator } from './generators/llm-openrouter.js';
|
|
5
|
+
export { llmRequestyGenerator } from './generators/llm-requesty.js';
|
|
5
6
|
export { CatalogFileDiff, RefreshableSource, ReviewedRefreshOptions, ReviewedRefreshResult, SourceRefreshResult, refreshSources, reviewedRefresh } from './refresh-workflow.js';
|
|
6
7
|
export { OPENAI_LLM_SOURCE, OPENAI_SOURCES } from './sources/openai.js';
|
|
7
8
|
|
|
9
|
+
declare const llmHuggingfaceGenerator: CatalogGenerator;
|
|
10
|
+
|
|
8
11
|
/**
|
|
9
12
|
* voice-elevenlabs generator — reads the ElevenLabs /v1/voices snapshot and
|
|
10
13
|
* emits a CatalogVoice[]-shaped generated TS file.
|
|
@@ -39,4 +42,4 @@ declare const voiceMinimax: CatalogGenerator;
|
|
|
39
42
|
|
|
40
43
|
declare const imageReplicate: CatalogGenerator;
|
|
41
44
|
|
|
42
|
-
export { CatalogGenerator, imageReplicate, voiceElevenlabs, voiceMinimax };
|
|
45
|
+
export { CatalogGenerator, imageReplicate, llmHuggingfaceGenerator, voiceElevenlabs, voiceMinimax };
|
package/dist/index.mjs
CHANGED
|
@@ -231,6 +231,246 @@ var llmOpenRouterGenerator = defineGenerator({
|
|
|
231
231
|
sources,
|
|
232
232
|
generate
|
|
233
233
|
});
|
|
234
|
+
var REQUESTY_MODELS_URL = "https://router.requesty.ai/v1/models";
|
|
235
|
+
var OUTPUT_PATH2 = "packages/model-catalog/src/llm/requesty-routes.generated.ts";
|
|
236
|
+
var ModelSchema2 = z.object({
|
|
237
|
+
id: z.string(),
|
|
238
|
+
input_price: z.number().optional(),
|
|
239
|
+
output_price: z.number().optional(),
|
|
240
|
+
cached_price: z.number().optional(),
|
|
241
|
+
supports_caching: z.boolean().optional()
|
|
242
|
+
}).passthrough();
|
|
243
|
+
var SnapshotSchema2 = z.object({
|
|
244
|
+
data: z.array(ModelSchema2)
|
|
245
|
+
});
|
|
246
|
+
function round62(n) {
|
|
247
|
+
return Math.round(n * 1e6) / 1e6;
|
|
248
|
+
}
|
|
249
|
+
function per1m2(tokenPrice) {
|
|
250
|
+
if (tokenPrice === void 0) return void 0;
|
|
251
|
+
if (!Number.isFinite(tokenPrice)) return void 0;
|
|
252
|
+
return round62(tokenPrice * 1e6);
|
|
253
|
+
}
|
|
254
|
+
function fmt2(n) {
|
|
255
|
+
if (!Number.isFinite(n)) return "0";
|
|
256
|
+
return `${round62(n)}`;
|
|
257
|
+
}
|
|
258
|
+
function vendorOf2(id) {
|
|
259
|
+
if (!id.includes("/")) return id;
|
|
260
|
+
return id.split("/")[0] ?? id;
|
|
261
|
+
}
|
|
262
|
+
function serializeEntry2(e) {
|
|
263
|
+
const fields = [
|
|
264
|
+
`inputPer1M: ${fmt2(e.inputPer1M)}`,
|
|
265
|
+
`outputPer1M: ${fmt2(e.outputPer1M)}`
|
|
266
|
+
];
|
|
267
|
+
if (e.cacheReadMultiplier !== void 0) {
|
|
268
|
+
fields.push(`cacheReadMultiplier: ${fmt2(e.cacheReadMultiplier)}`);
|
|
269
|
+
}
|
|
270
|
+
fields.push(`vendor: ${JSON.stringify(e.vendor)}`);
|
|
271
|
+
fields.push(`provider: ${JSON.stringify(e.provider)}`);
|
|
272
|
+
return `{
|
|
273
|
+
${fields.join(",\n ")},
|
|
274
|
+
}`;
|
|
275
|
+
}
|
|
276
|
+
function serializeFile2(entries) {
|
|
277
|
+
const ids = Object.keys(entries).sort();
|
|
278
|
+
const providers = Array.from(new Set(ids.map(vendorOf2))).sort();
|
|
279
|
+
const lines = [
|
|
280
|
+
"// AUTO-GENERATED by @agentproto/catalog-sync (llm:requesty).",
|
|
281
|
+
"// Do not edit by hand \u2014 re-run `pnpm --filter @agentproto/catalog-sync generate`.",
|
|
282
|
+
`// Source: ${REQUESTY_MODELS_URL}`,
|
|
283
|
+
"// Pricing carries provider USD (inputPer1M / outputPer1M) plus a cache",
|
|
284
|
+
"// multiplier (cacheReadMultiplier) derived from the source's cached_price",
|
|
285
|
+
"// per-token field when `supports_caching` is true. Requesty has no",
|
|
286
|
+
"// cache-write price, so cacheWriteMultiplier is never emitted.",
|
|
287
|
+
"",
|
|
288
|
+
'import type { LLMPricing } from "./catalog.js"',
|
|
289
|
+
"",
|
|
290
|
+
"export const REQUESTY_ROUTES: Record<string, LLMPricing> = {"
|
|
291
|
+
];
|
|
292
|
+
for (const id of ids) {
|
|
293
|
+
lines.push(` ${JSON.stringify(id)}: ${serializeEntry2(entries[id])},`);
|
|
294
|
+
}
|
|
295
|
+
lines.push("}");
|
|
296
|
+
lines.push("");
|
|
297
|
+
lines.push("/** Provider slugs treated as Requesty routes by the picker. */");
|
|
298
|
+
lines.push("export const REQUESTY_PROVIDERS: readonly string[] = [");
|
|
299
|
+
for (const p of providers) {
|
|
300
|
+
lines.push(` ${JSON.stringify(p)},`);
|
|
301
|
+
}
|
|
302
|
+
lines.push("]");
|
|
303
|
+
lines.push("");
|
|
304
|
+
return lines.join("\n");
|
|
305
|
+
}
|
|
306
|
+
async function generate2(ctx) {
|
|
307
|
+
const src = sources2[0];
|
|
308
|
+
if (!src) throw new Error("llm:requesty: no source configured");
|
|
309
|
+
const parsed = SnapshotSchema2.parse(await ctx.fetchSource(src));
|
|
310
|
+
const entries = {};
|
|
311
|
+
for (const model of parsed.data) {
|
|
312
|
+
const inputPer1M = per1m2(model.input_price);
|
|
313
|
+
const outputPer1M = per1m2(model.output_price);
|
|
314
|
+
if (inputPer1M === void 0 || outputPer1M === void 0) continue;
|
|
315
|
+
if (inputPer1M === 0 && outputPer1M === 0) continue;
|
|
316
|
+
const entry = {
|
|
317
|
+
inputPer1M,
|
|
318
|
+
outputPer1M,
|
|
319
|
+
vendor: vendorOf2(model.id),
|
|
320
|
+
provider: "requesty"
|
|
321
|
+
};
|
|
322
|
+
if (model.supports_caching === true && inputPer1M > 0) {
|
|
323
|
+
const cachePer1M = per1m2(model.cached_price);
|
|
324
|
+
if (cachePer1M !== void 0) {
|
|
325
|
+
entry.cacheReadMultiplier = round62(cachePer1M / inputPer1M);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
entries[model.id] = entry;
|
|
329
|
+
}
|
|
330
|
+
return { [OUTPUT_PATH2]: serializeFile2(entries) };
|
|
331
|
+
}
|
|
332
|
+
var sources2 = [
|
|
333
|
+
{
|
|
334
|
+
id: "llm-requesty",
|
|
335
|
+
url: REQUESTY_MODELS_URL,
|
|
336
|
+
// Live refresh needs the account key (Bearer). Without REQUESTY_API_KEY
|
|
337
|
+
// set, the framework reuses the committed snapshot.
|
|
338
|
+
headers: { Authorization: "Bearer env:REQUESTY_API_KEY" }
|
|
339
|
+
}
|
|
340
|
+
];
|
|
341
|
+
var llmRequestyGenerator = defineGenerator({
|
|
342
|
+
name: "llm:requesty",
|
|
343
|
+
modality: "llm",
|
|
344
|
+
sources: sources2,
|
|
345
|
+
generate: generate2
|
|
346
|
+
});
|
|
347
|
+
var HUGGINGFACE_MODELS_URL = "https://router.huggingface.co/v1/models";
|
|
348
|
+
var OUTPUT_PATH3 = "packages/model-catalog/src/llm/huggingface-routes.generated.ts";
|
|
349
|
+
var HFProviderSchema = z.object({
|
|
350
|
+
provider: z.string(),
|
|
351
|
+
status: z.string(),
|
|
352
|
+
context_length: z.number().optional(),
|
|
353
|
+
pricing: z.object({
|
|
354
|
+
input: z.number().optional(),
|
|
355
|
+
output: z.number().optional()
|
|
356
|
+
}).optional(),
|
|
357
|
+
supports_tools: z.boolean().optional(),
|
|
358
|
+
supports_structured_output: z.boolean().optional()
|
|
359
|
+
}).passthrough();
|
|
360
|
+
var HFModelSchema = z.object({
|
|
361
|
+
id: z.string(),
|
|
362
|
+
providers: z.array(HFProviderSchema).optional()
|
|
363
|
+
}).passthrough();
|
|
364
|
+
var SnapshotSchema3 = z.object({
|
|
365
|
+
data: z.array(HFModelSchema)
|
|
366
|
+
});
|
|
367
|
+
function round4(n) {
|
|
368
|
+
return Math.round(n * 1e4) / 1e4;
|
|
369
|
+
}
|
|
370
|
+
function serializeProvider(p) {
|
|
371
|
+
const fields = [
|
|
372
|
+
`provider: ${JSON.stringify(p.provider)}`,
|
|
373
|
+
`status: ${JSON.stringify(p.status)}`
|
|
374
|
+
];
|
|
375
|
+
if (p.contextLength !== void 0) fields.push(`contextLength: ${p.contextLength}`);
|
|
376
|
+
if (p.inputPer1M !== void 0) fields.push(`inputPer1M: ${p.inputPer1M}`);
|
|
377
|
+
if (p.outputPer1M !== void 0) fields.push(`outputPer1M: ${p.outputPer1M}`);
|
|
378
|
+
if (p.supportsTools !== void 0) fields.push(`supportsTools: ${p.supportsTools}`);
|
|
379
|
+
if (p.supportsStructuredOutput !== void 0) {
|
|
380
|
+
fields.push(`supportsStructuredOutput: ${p.supportsStructuredOutput}`);
|
|
381
|
+
}
|
|
382
|
+
return ` {
|
|
383
|
+
${fields.join(",\n ")},
|
|
384
|
+
}`;
|
|
385
|
+
}
|
|
386
|
+
function serializeEntry3(id, e) {
|
|
387
|
+
const providerLines = e.providers.map(serializeProvider).join(",\n");
|
|
388
|
+
return [
|
|
389
|
+
` ${JSON.stringify(id)}: {`,
|
|
390
|
+
` wireId: ${JSON.stringify(e.wireId)},`,
|
|
391
|
+
` providers: [`,
|
|
392
|
+
providerLines,
|
|
393
|
+
` ],`,
|
|
394
|
+
` },`
|
|
395
|
+
].join("\n");
|
|
396
|
+
}
|
|
397
|
+
function serializeFile3(entries) {
|
|
398
|
+
const ids = Object.keys(entries).sort();
|
|
399
|
+
const lines = [
|
|
400
|
+
"// AUTO-GENERATED by @agentproto/catalog-sync (llm:huggingface).",
|
|
401
|
+
"// Do not edit by hand \u2014 re-run `pnpm --filter @agentproto/catalog-sync generate`.",
|
|
402
|
+
`// Source: ${HUGGINGFACE_MODELS_URL}`,
|
|
403
|
+
"// Per-model LIVE inference providers from the HuggingFace router. HF wire",
|
|
404
|
+
"// ids are case-sensitive and preserved verbatim. Provider entries are",
|
|
405
|
+
"// SPARSE on some models \u2014 every field below except provider/status is",
|
|
406
|
+
"// optional and emitted only when the upstream response carries it. Only",
|
|
407
|
+
'// providers with status === "live" are kept; models with zero live',
|
|
408
|
+
"// providers are skipped. inputPer1M/outputPer1M are USD per 1M tokens",
|
|
409
|
+
"// (HuggingFace router convention \u2014 already at that scale, unlike",
|
|
410
|
+
"// OpenRouter's per-token strings).",
|
|
411
|
+
"",
|
|
412
|
+
"export interface HuggingFaceRouteProvider {",
|
|
413
|
+
" provider: string",
|
|
414
|
+
" status: string",
|
|
415
|
+
" contextLength?: number",
|
|
416
|
+
" inputPer1M?: number",
|
|
417
|
+
" outputPer1M?: number",
|
|
418
|
+
" supportsTools?: boolean",
|
|
419
|
+
" supportsStructuredOutput?: boolean",
|
|
420
|
+
"}",
|
|
421
|
+
"",
|
|
422
|
+
"export interface HuggingFaceRoute {",
|
|
423
|
+
" wireId: string",
|
|
424
|
+
" providers: HuggingFaceRouteProvider[]",
|
|
425
|
+
"}",
|
|
426
|
+
"",
|
|
427
|
+
"export const HUGGINGFACE_ROUTES: Record<string, HuggingFaceRoute> = {"
|
|
428
|
+
];
|
|
429
|
+
for (const id of ids) {
|
|
430
|
+
lines.push(serializeEntry3(id, entries[id]));
|
|
431
|
+
}
|
|
432
|
+
lines.push("}");
|
|
433
|
+
lines.push("");
|
|
434
|
+
return lines.join("\n");
|
|
435
|
+
}
|
|
436
|
+
async function generate3(ctx) {
|
|
437
|
+
const src = sources3[0];
|
|
438
|
+
if (!src) throw new Error("llm:huggingface: no source configured");
|
|
439
|
+
const parsed = SnapshotSchema3.parse(await ctx.fetchSource(src));
|
|
440
|
+
const entries = {};
|
|
441
|
+
for (const model of parsed.data) {
|
|
442
|
+
const liveProviders = (model.providers ?? []).filter((p) => p.status === "live");
|
|
443
|
+
if (liveProviders.length === 0) continue;
|
|
444
|
+
const providers = liveProviders.map((p) => {
|
|
445
|
+
const entry = {
|
|
446
|
+
provider: p.provider,
|
|
447
|
+
status: p.status
|
|
448
|
+
};
|
|
449
|
+
if (p.context_length !== void 0) entry.contextLength = p.context_length;
|
|
450
|
+
if (p.pricing?.input !== void 0) entry.inputPer1M = round4(p.pricing.input);
|
|
451
|
+
if (p.pricing?.output !== void 0) entry.outputPer1M = round4(p.pricing.output);
|
|
452
|
+
if (p.supports_tools !== void 0) entry.supportsTools = p.supports_tools;
|
|
453
|
+
if (p.supports_structured_output !== void 0) {
|
|
454
|
+
entry.supportsStructuredOutput = p.supports_structured_output;
|
|
455
|
+
}
|
|
456
|
+
return entry;
|
|
457
|
+
}).sort((a, b) => a.provider.localeCompare(b.provider));
|
|
458
|
+
entries[model.id] = { wireId: model.id, providers };
|
|
459
|
+
}
|
|
460
|
+
return { [OUTPUT_PATH3]: serializeFile3(entries) };
|
|
461
|
+
}
|
|
462
|
+
var sources3 = [
|
|
463
|
+
{
|
|
464
|
+
id: "llm-huggingface",
|
|
465
|
+
url: HUGGINGFACE_MODELS_URL
|
|
466
|
+
}
|
|
467
|
+
];
|
|
468
|
+
var llmHuggingfaceGenerator = defineGenerator({
|
|
469
|
+
name: "llm:huggingface",
|
|
470
|
+
modality: "llm",
|
|
471
|
+
sources: sources3,
|
|
472
|
+
generate: generate3
|
|
473
|
+
});
|
|
234
474
|
|
|
235
475
|
// src/generators/serialize-voices.ts
|
|
236
476
|
function serializeVoice(v) {
|
|
@@ -274,7 +514,7 @@ var ELEVENLABS_SOURCE = {
|
|
|
274
514
|
// Live refresh needs the account key; offline reads ignore this.
|
|
275
515
|
headers: { "xi-api-key": "env:ELEVENLABS_API_KEY" }
|
|
276
516
|
};
|
|
277
|
-
var
|
|
517
|
+
var OUTPUT_PATH4 = "packages/catalog-sync/generated/voice-elevenlabs.generated.ts";
|
|
278
518
|
var voiceElevenlabs = defineGenerator({
|
|
279
519
|
name: "voice:elevenlabs",
|
|
280
520
|
modality: "voice",
|
|
@@ -285,7 +525,7 @@ var voiceElevenlabs = defineGenerator({
|
|
|
285
525
|
);
|
|
286
526
|
const voices = mapElevenLabsVoices(snapshot);
|
|
287
527
|
return {
|
|
288
|
-
[
|
|
528
|
+
[OUTPUT_PATH4]: serializeVoiceModule(
|
|
289
529
|
"voice:elevenlabs",
|
|
290
530
|
"ELEVENLABS_VOICES",
|
|
291
531
|
voices
|
|
@@ -305,7 +545,7 @@ var MINIMAX_SOURCE = {
|
|
|
305
545
|
},
|
|
306
546
|
body: { voice_type: "system" }
|
|
307
547
|
};
|
|
308
|
-
var
|
|
548
|
+
var OUTPUT_PATH5 = "packages/catalog-sync/generated/voice-minimax.generated.ts";
|
|
309
549
|
var voiceMinimax = defineGenerator({
|
|
310
550
|
name: "voice:minimax",
|
|
311
551
|
modality: "voice",
|
|
@@ -316,7 +556,7 @@ var voiceMinimax = defineGenerator({
|
|
|
316
556
|
);
|
|
317
557
|
const voices = mapMinimaxVoices(snapshot);
|
|
318
558
|
return {
|
|
319
|
-
[
|
|
559
|
+
[OUTPUT_PATH5]: serializeVoiceModule(
|
|
320
560
|
"voice:minimax",
|
|
321
561
|
"MINIMAX_VOICES",
|
|
322
562
|
voices
|
|
@@ -640,10 +880,10 @@ function resolveHeaders2(headers) {
|
|
|
640
880
|
}
|
|
641
881
|
return { headers: out, missing };
|
|
642
882
|
}
|
|
643
|
-
async function refreshSources(
|
|
883
|
+
async function refreshSources(sources4, opts) {
|
|
644
884
|
const results = [];
|
|
645
885
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
646
|
-
for (const { source, refreshable, notes } of
|
|
886
|
+
for (const { source, refreshable, notes } of sources4) {
|
|
647
887
|
if (!opts.refresh) {
|
|
648
888
|
results.push({
|
|
649
889
|
id: source.id,
|
|
@@ -762,6 +1002,6 @@ var OPENAI_LLM_SOURCE = {
|
|
|
762
1002
|
};
|
|
763
1003
|
var OPENAI_SOURCES = [OPENAI_LLM_SOURCE];
|
|
764
1004
|
|
|
765
|
-
export { OPENAI_LLM_SOURCE, OPENAI_SOURCES, defineGenerator, imageReplicate, llmOpenRouterGenerator, refreshSources, reviewedRefresh, runGenerators, voiceElevenlabs, voiceMinimax };
|
|
1005
|
+
export { OPENAI_LLM_SOURCE, OPENAI_SOURCES, defineGenerator, imageReplicate, llmHuggingfaceGenerator, llmOpenRouterGenerator, llmRequestyGenerator, refreshSources, reviewedRefresh, runGenerators, voiceElevenlabs, voiceMinimax };
|
|
766
1006
|
//# sourceMappingURL=index.mjs.map
|
|
767
1007
|
//# sourceMappingURL=index.mjs.map
|