@agentproto/catalog-sync 0.5.13 → 0.6.0
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/dist/bin.mjs +268 -11
- package/dist/bin.mjs.map +1 -1
- package/dist/generators/llm-opencode.d.ts +8 -0
- package/dist/generators/llm-opencode.mjs +313 -0
- package/dist/generators/llm-opencode.mjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +263 -8
- package/dist/index.mjs.map +1 -1
- package/dist/runner.mjs +3 -1
- package/dist/runner.mjs.map +1 -1
- package/package.json +8 -3
- package/snapshots/llm-huggingface.json +2596 -2550
- package/snapshots/llm-moonshot.json +30 -30
- package/snapshots/llm-opencode-go.json +455 -0
- package/snapshots/llm-opencode-zen.json +1332 -0
- package/snapshots/llm-openrouter.json +5661 -4096
- package/snapshots/voice-elevenlabs.json +4828 -4828
package/dist/index.mjs
CHANGED
|
@@ -142,7 +142,9 @@ function resolveHeaders(headers) {
|
|
|
142
142
|
}
|
|
143
143
|
var CATALOG_CHANGELOG_PATH = "packages/model-catalog/CATALOG-CHANGELOG.md";
|
|
144
144
|
function isChangelogEligible(relPath) {
|
|
145
|
-
|
|
145
|
+
if (!relPath.endsWith(".generated.ts")) return false;
|
|
146
|
+
if (relPath.startsWith("packages/catalog-sync/generated/")) return false;
|
|
147
|
+
return true;
|
|
146
148
|
}
|
|
147
149
|
async function runGenerators(gens, opts) {
|
|
148
150
|
const files = {};
|
|
@@ -497,6 +499,259 @@ var llmRequestyGenerator = defineGenerator({
|
|
|
497
499
|
sources: sources2,
|
|
498
500
|
generate: generate2
|
|
499
501
|
});
|
|
502
|
+
var MODELS_DEV_URL = "https://models.dev/api.json";
|
|
503
|
+
var ModelSchema3 = z.object({
|
|
504
|
+
id: z.string().optional(),
|
|
505
|
+
name: z.string().optional(),
|
|
506
|
+
family: z.string().optional(),
|
|
507
|
+
/** ISO `YYYY-MM-DD` already — no unix-seconds conversion (cf. Requesty). */
|
|
508
|
+
release_date: z.string().optional(),
|
|
509
|
+
provider: z.object({
|
|
510
|
+
/** Which AI-SDK package serves this model — the ONLY discriminator
|
|
511
|
+
* for the endpoint's three wire surfaces (see
|
|
512
|
+
* {@link anthropicSurfaceIds}). */
|
|
513
|
+
npm: z.string().optional()
|
|
514
|
+
}).passthrough().optional(),
|
|
515
|
+
cost: z.object({
|
|
516
|
+
input: z.number().optional(),
|
|
517
|
+
output: z.number().optional(),
|
|
518
|
+
cache_read: z.number().optional(),
|
|
519
|
+
cache_write: z.number().optional()
|
|
520
|
+
}).passthrough().optional()
|
|
521
|
+
}).passthrough();
|
|
522
|
+
var ProviderSchema = z.object({
|
|
523
|
+
id: z.string().optional(),
|
|
524
|
+
name: z.string().optional(),
|
|
525
|
+
/** The endpoint's base URL, e.g. `https://opencode.ai/zen/go/v1`. */
|
|
526
|
+
api: z.string().optional(),
|
|
527
|
+
doc: z.string().optional(),
|
|
528
|
+
env: z.array(z.string()).optional(),
|
|
529
|
+
npm: z.string().optional(),
|
|
530
|
+
models: z.record(z.string(), ModelSchema3).optional()
|
|
531
|
+
}).passthrough();
|
|
532
|
+
var SnapshotSchema3 = z.record(z.string(), ProviderSchema);
|
|
533
|
+
function round63(n) {
|
|
534
|
+
return Math.round(n * 1e6) / 1e6;
|
|
535
|
+
}
|
|
536
|
+
function fmt3(n) {
|
|
537
|
+
if (!Number.isFinite(n)) return "0";
|
|
538
|
+
return `${round63(n)}`;
|
|
539
|
+
}
|
|
540
|
+
function cacheMultiplier(cachePer1M, inputPer1M) {
|
|
541
|
+
if (cachePer1M === void 0 || !Number.isFinite(cachePer1M)) return void 0;
|
|
542
|
+
if (inputPer1M <= 0) return void 0;
|
|
543
|
+
return round63(cachePer1M / inputPer1M);
|
|
544
|
+
}
|
|
545
|
+
var VENDOR_BY_ID_PREFIX = [
|
|
546
|
+
[/^claude-/, "anthropic"],
|
|
547
|
+
[/^gemini-/, "google"],
|
|
548
|
+
[/^gpt-/, "openai"],
|
|
549
|
+
[/^grok-/, "x-ai"],
|
|
550
|
+
[/^glm-/, "z-ai"],
|
|
551
|
+
[/^kimi-/, "moonshotai"],
|
|
552
|
+
[/^deepseek-/, "deepseek"],
|
|
553
|
+
[/^minimax-/, "minimax"],
|
|
554
|
+
[/^qwen/, "qwen"],
|
|
555
|
+
[/^mimo-/, "xiaomi"],
|
|
556
|
+
[/^hy\d/, "tencent"],
|
|
557
|
+
[/^longcat-/, "meituan"],
|
|
558
|
+
[/^(ling|ring)-/, "inclusionai"],
|
|
559
|
+
[/^nemotron-/, "nvidia"],
|
|
560
|
+
[/^trinity-/, "arcee-ai"],
|
|
561
|
+
[/^laguna-/, "poolside"],
|
|
562
|
+
[/^north-/, "cohere"],
|
|
563
|
+
[/^muse-spark-/, "meta"]
|
|
564
|
+
];
|
|
565
|
+
function vendorForOpencodeModelId(bareId) {
|
|
566
|
+
for (const [pattern, vendor] of VENDOR_BY_ID_PREFIX) {
|
|
567
|
+
if (pattern.test(bareId)) return vendor;
|
|
568
|
+
}
|
|
569
|
+
return "opencode";
|
|
570
|
+
}
|
|
571
|
+
function routeKey(provider, bareId) {
|
|
572
|
+
return `${provider}/${bareId}`;
|
|
573
|
+
}
|
|
574
|
+
function serializeEntry3(e) {
|
|
575
|
+
const fields = [
|
|
576
|
+
`inputPer1M: ${fmt3(e.inputPer1M)}`,
|
|
577
|
+
`outputPer1M: ${fmt3(e.outputPer1M)}`
|
|
578
|
+
];
|
|
579
|
+
if (e.cacheReadMultiplier !== void 0) {
|
|
580
|
+
fields.push(`cacheReadMultiplier: ${fmt3(e.cacheReadMultiplier)}`);
|
|
581
|
+
}
|
|
582
|
+
if (e.cacheWriteMultiplier !== void 0) {
|
|
583
|
+
fields.push(`cacheWriteMultiplier: ${fmt3(e.cacheWriteMultiplier)}`);
|
|
584
|
+
}
|
|
585
|
+
if (e.addedAt !== void 0) {
|
|
586
|
+
fields.push(`addedAt: ${JSON.stringify(e.addedAt)}`);
|
|
587
|
+
}
|
|
588
|
+
fields.push(`vendor: ${JSON.stringify(e.vendor)}`);
|
|
589
|
+
fields.push(`provider: ${JSON.stringify(e.provider)}`);
|
|
590
|
+
return `{
|
|
591
|
+
${fields.join(",\n ")},
|
|
592
|
+
}`;
|
|
593
|
+
}
|
|
594
|
+
var GO = {
|
|
595
|
+
providerKey: "opencode-go",
|
|
596
|
+
ledgerId: "llm-opencode-go",
|
|
597
|
+
generatorName: "llm:opencode-go",
|
|
598
|
+
outputPath: "packages/model-catalog/src/llm/opencode-go-routes.generated.ts",
|
|
599
|
+
routesConst: "OPENCODE_GO_ROUTES",
|
|
600
|
+
anthropicConst: "OPENCODE_GO_ANTHROPIC_MODELS",
|
|
601
|
+
label: "OpenCode Go"
|
|
602
|
+
};
|
|
603
|
+
var ZEN = {
|
|
604
|
+
providerKey: "opencode",
|
|
605
|
+
ledgerId: "llm-opencode-zen",
|
|
606
|
+
generatorName: "llm:opencode-zen",
|
|
607
|
+
outputPath: "packages/model-catalog/src/llm/opencode-zen-routes.generated.ts",
|
|
608
|
+
routesConst: "OPENCODE_ZEN_ROUTES",
|
|
609
|
+
anthropicConst: "OPENCODE_ZEN_ANTHROPIC_MODELS",
|
|
610
|
+
label: "OpenCode Zen"
|
|
611
|
+
};
|
|
612
|
+
function serializeFile3(endpoint, entries, anthropicIds) {
|
|
613
|
+
const keys = Object.keys(entries).sort();
|
|
614
|
+
const lines = [
|
|
615
|
+
`// AUTO-GENERATED by @agentproto/catalog-sync (${endpoint.generatorName}).`,
|
|
616
|
+
"// Do not edit by hand \u2014 re-run `pnpm --filter @agentproto/catalog-sync generate`.",
|
|
617
|
+
`// Source: ${MODELS_DEV_URL} (provider "${endpoint.providerKey}" \u2014 ${endpoint.label})`,
|
|
618
|
+
"// Prices come VERBATIM from the source's cost.input / cost.output, which",
|
|
619
|
+
"// models.dev already publishes as USD per 1M tokens (no per-token",
|
|
620
|
+
"// conversion, unlike the Requesty table). cacheReadMultiplier /",
|
|
621
|
+
"// cacheWriteMultiplier are cost.cache_read / cost.cache_write expressed",
|
|
622
|
+
"// relative to cost.input, and are omitted when the base input price is 0",
|
|
623
|
+
"// (every `-free` variant) because a free model has no cache discount.",
|
|
624
|
+
"// Zero-priced models are KEPT \u2014 on these endpoints zero is the truth, not",
|
|
625
|
+
"// a missing price.",
|
|
626
|
+
"// Keys are `<provider>/<bare-id>`, the form opencode's own config uses and",
|
|
627
|
+
"// the form the runtime derives the billing endpoint from; `vendor` is a",
|
|
628
|
+
"// heuristic attribution of the model's BUILDER and is metadata only.",
|
|
629
|
+
"// addedAt is the ISO date this id was first seen by a sync run \u2014 backfilled",
|
|
630
|
+
"// from the source's own `release_date`, then NEVER mutated; see",
|
|
631
|
+
"// packages/catalog-sync/src/added-at.ts and the package README.",
|
|
632
|
+
"",
|
|
633
|
+
'import type { LLMPricing } from "./catalog.js"',
|
|
634
|
+
"",
|
|
635
|
+
`export const ${endpoint.routesConst}: Record<string, LLMPricing> = {`
|
|
636
|
+
];
|
|
637
|
+
for (const key of keys) {
|
|
638
|
+
lines.push(` ${JSON.stringify(key)}: ${serializeEntry3(entries[key])},`);
|
|
639
|
+
}
|
|
640
|
+
lines.push("}");
|
|
641
|
+
lines.push("");
|
|
642
|
+
lines.push("/**");
|
|
643
|
+
lines.push(` * BARE ids on ${endpoint.label} whose wire surface is the Anthropic Messages`);
|
|
644
|
+
lines.push(' * API \u2014 the source\'s `provider.npm === "@ai-sdk/anthropic"`. These are the');
|
|
645
|
+
lines.push(" * ONLY ids reachable through the Anthropic-compatible gateway preset of the");
|
|
646
|
+
lines.push(" * same name (claude-code / claude-sdk); the rest of the endpoint's lineup");
|
|
647
|
+
lines.push(" * speaks OpenAI chat/completions or the OpenAI Responses API and has to go");
|
|
648
|
+
lines.push(" * through the opencode adapter instead. Bare (not `<provider>/<id>`) because");
|
|
649
|
+
lines.push(" * that is what an Anthropic client puts in `ANTHROPIC_MODEL` / on the wire.");
|
|
650
|
+
lines.push(" */");
|
|
651
|
+
lines.push(`export const ${endpoint.anthropicConst}: readonly string[] = [`);
|
|
652
|
+
for (const id of [...anthropicIds].sort()) {
|
|
653
|
+
lines.push(` ${JSON.stringify(id)},`);
|
|
654
|
+
}
|
|
655
|
+
lines.push("]");
|
|
656
|
+
lines.push("");
|
|
657
|
+
return lines.join("\n");
|
|
658
|
+
}
|
|
659
|
+
function projectSnapshot(providerKey, provider) {
|
|
660
|
+
const models = {};
|
|
661
|
+
for (const bareId of Object.keys(provider.models ?? {}).sort()) {
|
|
662
|
+
const model = provider.models?.[bareId];
|
|
663
|
+
if (!model) continue;
|
|
664
|
+
models[bareId] = {
|
|
665
|
+
...model.id !== void 0 ? { id: model.id } : {},
|
|
666
|
+
...model.name !== void 0 ? { name: model.name } : {},
|
|
667
|
+
...model.family !== void 0 ? { family: model.family } : {},
|
|
668
|
+
...model.release_date !== void 0 ? { release_date: model.release_date } : {},
|
|
669
|
+
...model.provider?.npm !== void 0 ? { provider: { npm: model.provider.npm } } : {},
|
|
670
|
+
...model.cost !== void 0 ? {
|
|
671
|
+
cost: {
|
|
672
|
+
...model.cost.input !== void 0 ? { input: model.cost.input } : {},
|
|
673
|
+
...model.cost.output !== void 0 ? { output: model.cost.output } : {},
|
|
674
|
+
...model.cost.cache_read !== void 0 ? { cache_read: model.cost.cache_read } : {},
|
|
675
|
+
...model.cost.cache_write !== void 0 ? { cache_write: model.cost.cache_write } : {}
|
|
676
|
+
}
|
|
677
|
+
} : {}
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
const projected = {
|
|
681
|
+
...provider.id !== void 0 ? { id: provider.id } : {},
|
|
682
|
+
...provider.name !== void 0 ? { name: provider.name } : {},
|
|
683
|
+
...provider.api !== void 0 ? { api: provider.api } : {},
|
|
684
|
+
...provider.doc !== void 0 ? { doc: provider.doc } : {},
|
|
685
|
+
...provider.env !== void 0 ? { env: provider.env } : {},
|
|
686
|
+
...provider.npm !== void 0 ? { npm: provider.npm } : {},
|
|
687
|
+
models
|
|
688
|
+
};
|
|
689
|
+
return `${JSON.stringify({ [providerKey]: projected }, null, 2)}
|
|
690
|
+
`;
|
|
691
|
+
}
|
|
692
|
+
function snapshotRelPath(ledgerId) {
|
|
693
|
+
return `packages/catalog-sync/snapshots/${ledgerId}.json`;
|
|
694
|
+
}
|
|
695
|
+
function anthropicSurfaceIds(models) {
|
|
696
|
+
return Object.entries(models).filter(([, model]) => model.provider?.npm === "@ai-sdk/anthropic").map(([bareId]) => bareId).sort();
|
|
697
|
+
}
|
|
698
|
+
async function generateFor(endpoint, source, ctx) {
|
|
699
|
+
const parsed = SnapshotSchema3.parse(await ctx.fetchSource(source));
|
|
700
|
+
const provider = parsed[endpoint.providerKey];
|
|
701
|
+
if (!provider) {
|
|
702
|
+
throw new Error(
|
|
703
|
+
`${endpoint.generatorName}: models.dev payload carries no "${endpoint.providerKey}" provider (source ${source.url}). Refusing to emit an empty route table.`
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
const models = provider.models ?? {};
|
|
707
|
+
const entries = {};
|
|
708
|
+
const releasedAt = {};
|
|
709
|
+
for (const [bareId, model] of Object.entries(models)) {
|
|
710
|
+
const inputPer1M = model.cost?.input;
|
|
711
|
+
const outputPer1M = model.cost?.output;
|
|
712
|
+
if (inputPer1M === void 0 || outputPer1M === void 0) continue;
|
|
713
|
+
if (!Number.isFinite(inputPer1M) || !Number.isFinite(outputPer1M)) continue;
|
|
714
|
+
const key = routeKey(endpoint.providerKey, bareId);
|
|
715
|
+
const entry = {
|
|
716
|
+
inputPer1M: round63(inputPer1M),
|
|
717
|
+
outputPer1M: round63(outputPer1M),
|
|
718
|
+
vendor: vendorForOpencodeModelId(bareId),
|
|
719
|
+
provider: endpoint.providerKey
|
|
720
|
+
};
|
|
721
|
+
const read = cacheMultiplier(model.cost?.cache_read, inputPer1M);
|
|
722
|
+
if (read !== void 0) entry.cacheReadMultiplier = read;
|
|
723
|
+
const write = cacheMultiplier(model.cost?.cache_write, inputPer1M);
|
|
724
|
+
if (write !== void 0) entry.cacheWriteMultiplier = write;
|
|
725
|
+
entries[key] = entry;
|
|
726
|
+
if (model.release_date !== void 0) releasedAt[key] = model.release_date;
|
|
727
|
+
}
|
|
728
|
+
const ledger = computeAddedAtLedger(
|
|
729
|
+
Object.keys(entries),
|
|
730
|
+
readLedger(endpoint.ledgerId),
|
|
731
|
+
releasedAt,
|
|
732
|
+
todayIso()
|
|
733
|
+
);
|
|
734
|
+
for (const [key, entry] of Object.entries(entries)) entry.addedAt = ledger[key];
|
|
735
|
+
return {
|
|
736
|
+
[endpoint.outputPath]: serializeFile3(endpoint, entries, anthropicSurfaceIds(models)),
|
|
737
|
+
[ledgerRelPath(endpoint.ledgerId)]: serializeLedger(ledger),
|
|
738
|
+
[snapshotRelPath(endpoint.ledgerId)]: projectSnapshot(endpoint.providerKey, provider)
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
var goSources = [{ id: GO.ledgerId, url: MODELS_DEV_URL }];
|
|
742
|
+
var zenSources = [{ id: ZEN.ledgerId, url: MODELS_DEV_URL }];
|
|
743
|
+
var llmOpencodeGoGenerator = defineGenerator({
|
|
744
|
+
name: GO.generatorName,
|
|
745
|
+
modality: "llm",
|
|
746
|
+
sources: goSources,
|
|
747
|
+
generate: (ctx) => generateFor(GO, goSources[0], ctx)
|
|
748
|
+
});
|
|
749
|
+
var llmOpencodeZenGenerator = defineGenerator({
|
|
750
|
+
name: ZEN.generatorName,
|
|
751
|
+
modality: "llm",
|
|
752
|
+
sources: zenSources,
|
|
753
|
+
generate: (ctx) => generateFor(ZEN, zenSources[0], ctx)
|
|
754
|
+
});
|
|
500
755
|
var HUGGINGFACE_MODELS_URL = "https://router.huggingface.co/v1/models";
|
|
501
756
|
var OUTPUT_PATH3 = "packages/model-catalog/src/llm/huggingface-routes.generated.ts";
|
|
502
757
|
var HFProviderSchema = z.object({
|
|
@@ -514,7 +769,7 @@ var HFModelSchema = z.object({
|
|
|
514
769
|
id: z.string(),
|
|
515
770
|
providers: z.array(HFProviderSchema).optional()
|
|
516
771
|
}).passthrough();
|
|
517
|
-
var
|
|
772
|
+
var SnapshotSchema4 = z.object({
|
|
518
773
|
data: z.array(HFModelSchema)
|
|
519
774
|
});
|
|
520
775
|
function round4(n) {
|
|
@@ -536,7 +791,7 @@ function serializeProvider(p) {
|
|
|
536
791
|
${fields.join(",\n ")},
|
|
537
792
|
}`;
|
|
538
793
|
}
|
|
539
|
-
function
|
|
794
|
+
function serializeEntry4(id, e) {
|
|
540
795
|
const providerLines = e.providers.map(serializeProvider).join(",\n");
|
|
541
796
|
return [
|
|
542
797
|
` ${JSON.stringify(id)}: {`,
|
|
@@ -547,7 +802,7 @@ function serializeEntry3(id, e) {
|
|
|
547
802
|
` },`
|
|
548
803
|
].join("\n");
|
|
549
804
|
}
|
|
550
|
-
function
|
|
805
|
+
function serializeFile4(entries) {
|
|
551
806
|
const ids = Object.keys(entries).sort();
|
|
552
807
|
const lines = [
|
|
553
808
|
"// AUTO-GENERATED by @agentproto/catalog-sync (llm:huggingface).",
|
|
@@ -580,7 +835,7 @@ function serializeFile3(entries) {
|
|
|
580
835
|
"export const HUGGINGFACE_ROUTES: Record<string, HuggingFaceRoute> = {"
|
|
581
836
|
];
|
|
582
837
|
for (const id of ids) {
|
|
583
|
-
lines.push(
|
|
838
|
+
lines.push(serializeEntry4(id, entries[id]));
|
|
584
839
|
}
|
|
585
840
|
lines.push("}");
|
|
586
841
|
lines.push("");
|
|
@@ -589,7 +844,7 @@ function serializeFile3(entries) {
|
|
|
589
844
|
async function generate3(ctx) {
|
|
590
845
|
const src = sources3[0];
|
|
591
846
|
if (!src) throw new Error("llm:huggingface: no source configured");
|
|
592
|
-
const parsed =
|
|
847
|
+
const parsed = SnapshotSchema4.parse(await ctx.fetchSource(src));
|
|
593
848
|
const entries = {};
|
|
594
849
|
for (const model of parsed.data) {
|
|
595
850
|
const liveProviders = (model.providers ?? []).filter((p) => p.status === "live");
|
|
@@ -610,7 +865,7 @@ async function generate3(ctx) {
|
|
|
610
865
|
}).sort((a, b) => a.provider.localeCompare(b.provider));
|
|
611
866
|
entries[model.id] = { wireId: model.id, providers };
|
|
612
867
|
}
|
|
613
|
-
return { [OUTPUT_PATH3]:
|
|
868
|
+
return { [OUTPUT_PATH3]: serializeFile4(entries) };
|
|
614
869
|
}
|
|
615
870
|
var sources3 = [
|
|
616
871
|
{
|
|
@@ -1156,6 +1411,6 @@ var OPENAI_LLM_SOURCE = {
|
|
|
1156
1411
|
};
|
|
1157
1412
|
var OPENAI_SOURCES = [OPENAI_LLM_SOURCE];
|
|
1158
1413
|
|
|
1159
|
-
export { CATALOG_CHANGELOG_HEADER, CATALOG_CHANGELOG_PATH, OPENAI_LLM_SOURCE, OPENAI_SOURCES, appendChangelog, computeAddedAtLedger, defineGenerator, diffModelIds, extractRecordIds, imageReplicate, isoDateFromUnixSeconds, ledgerAbsPath, ledgerRelPath, llmHuggingfaceGenerator, llmOpenRouterGenerator, llmRequestyGenerator, readLedger, refreshSources, renderChangelogSection, reviewedRefresh, runGenerators, serializeLedger, todayIso, voiceElevenlabs, voiceMinimax };
|
|
1414
|
+
export { CATALOG_CHANGELOG_HEADER, CATALOG_CHANGELOG_PATH, OPENAI_LLM_SOURCE, OPENAI_SOURCES, appendChangelog, computeAddedAtLedger, defineGenerator, diffModelIds, extractRecordIds, imageReplicate, isoDateFromUnixSeconds, ledgerAbsPath, ledgerRelPath, llmHuggingfaceGenerator, llmOpenRouterGenerator, llmOpencodeGoGenerator, llmOpencodeZenGenerator, llmRequestyGenerator, readLedger, refreshSources, renderChangelogSection, reviewedRefresh, runGenerators, serializeLedger, todayIso, voiceElevenlabs, voiceMinimax };
|
|
1160
1415
|
//# sourceMappingURL=index.mjs.map
|
|
1161
1416
|
//# sourceMappingURL=index.mjs.map
|