scripts/reconcile-model-catalog.mjs
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env node
import { readFile } from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { getModel } from '@earendil-works/pi-ai/compat';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const source = JSON.parse(await readFile(path.join(root, 'catalog', 'source.json'), 'utf8'));
const today = process.env.MODEL_CATALOG_RECONCILE_DATE ?? new Date().toISOString().slice(0, 10);
const rows = [];
let candidates = 0;
for (const entry of source.entries ?? []) {
const [provider, ...modelParts] = String(entry.canonical).split('/');
const modelId = modelParts.join('/');
const native = provider === 'openai' || provider === 'anthropic'
? getModel(provider, modelId) !== undefined
: false;
for (const lane of Object.keys(entry.lanes ?? {})) {
const recorded = entry.laneStatus?.[lane];
let classification = recorded?.state ?? 'backfill';
if (lane === 'apiKey' && native) {
if (classification === 'backfill') {
classification = 'native_candidate';
candidates += 1;
} else if (classification === 'native_verified') {
classification = recorded.retainUntil && recorded.retainUntil <= today
? 'removable'
: 'legacy_retained';
}
}
rows.push({ canonical: entry.canonical, lane, native, classification });
}
}
for (const row of rows) {
console.log(
`${row.classification.padEnd(18)} ${row.canonical} [${row.lane}] ` +
`(Pi native: ${row.native ? 'yes' : 'no'})`,
);
}
if (candidates > 0) {
console.error(
`${candidates} catalog lane(s) are now Pi-native candidates. Run native equivalence/live gates, ` +
'then mark native_verified with a retainUntil date in catalog/source.json.',
);
process.exitCode = 2;
}