mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
Replace the single 3300-line generate-models.ts with declarative provider definitions and ordered rule packs under scripts/model-generation/. Each provider is a defineProvider() call: an upstream source (usually the generic modelsDev() mapper), static models upstream lacks, and rules scoped to that provider. Cross-provider facts live in rule packs applied in a fixed order. Every rule() carries a why, matches models with plain data, and patches them with typed set/replace/apply semantics. Generated model data is unchanged: 1443 models across 41 providers compare equal against a snapshot of the same upstream responses, apart from a now stable key order. Committed models.generated.ts and provider shards are byte-identical. Also: - Bring packages/ai/scripts under tsgo and biome; the old generator had 20+ type errors that nothing checked. - Add --upstream-snapshot <dir> to record and replay upstream catalogs and --explain <provider>:<model> to list the rules applied to a model. - Report rules that matched no model so stale corrections get removed. - Export parseRadiusGatewayConfig so the generator can replay Radius too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018ExCU9zaZnN8vB5fKpTAjP
40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
import { defineProvider, type GeneratedModel, roundCost } from "../dsl.ts";
|
|
|
|
const AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
|
|
|
|
function perMillion(value: string | number | undefined): number {
|
|
const parsed = typeof value === "number" ? value : parseFloat(value ?? "0");
|
|
return roundCost((Number.isFinite(parsed) ? parsed : 0) * 1_000_000);
|
|
}
|
|
|
|
export const vercelAiGateway = defineProvider({
|
|
id: "vercel-ai-gateway",
|
|
source: async (context) => {
|
|
const models: GeneratedModel[] = [];
|
|
for (const model of await context.upstream.vercelAiGateway()) {
|
|
const tags = Array.isArray(model.tags) ? model.tags : [];
|
|
// Only include models that support tools
|
|
if (!tags.includes("tool-use")) continue;
|
|
models.push({
|
|
id: model.id,
|
|
name: model.name || model.id,
|
|
api: "anthropic-messages",
|
|
baseUrl: AI_GATEWAY_BASE_URL,
|
|
provider: "vercel-ai-gateway",
|
|
reasoning: tags.includes("reasoning"),
|
|
input: tags.includes("vision") ? ["text", "image"] : ["text"],
|
|
compat: { allowEmptySignature: true },
|
|
cost: {
|
|
input: perMillion(model.pricing?.input),
|
|
output: perMillion(model.pricing?.output),
|
|
cacheRead: perMillion(model.pricing?.input_cache_read),
|
|
cacheWrite: perMillion(model.pricing?.input_cache_write),
|
|
},
|
|
contextWindow: model.context_window || 4096,
|
|
maxTokens: model.max_tokens || 4096,
|
|
});
|
|
}
|
|
console.log(`Fetched ${models.length} tool-capable models from Vercel AI Gateway`);
|
|
return models;
|
|
},
|
|
});
|