import * as fs from 'fs'; import * as path from 'path'; import * as readline from 'readline'; import { AGENTGUARD_SPEND_VERSION } from '../index'; import { fetchCatalog, getCachedCatalog, syncPricingIntoCostTable, type OpenRouterModel } from '../openrouter-catalog'; import { getModelCost, knownModelCosts } from '../cost-table'; import { TASK_TEMPLATES, getTaskTemplate } from '../templates'; import { agentguardHome, banner, cyanBold, dim, green, statusBar, yellow } from './colors'; export interface ModelRow { id: string; name: string; inputCentsPerMtok: number | null; outputCentsPerMtok: number | null; capability: string; } export function rowsFromCatalog(models: OpenRouterModel[]): ModelRow[] { return models.map((model) => { const input = Number(model.pricing?.prompt); const output = Number(model.pricing?.completion); return { id: model.id, name: model.name ?? model.id, inputCentsPerMtok: Number.isFinite(input) ? input * 100 * 1_000_000 : null, outputCentsPerMtok: Number.isFinite(output) ? output * 100 * 1_000_000 : null, capability: capabilityForModel(model.id), }; }); } export function rowsFromCostTable(): ModelRow[] { return Object.entries(knownModelCosts()).map(([id, cost]) => ({ id, name: id, inputCentsPerMtok: cost.inputCentsPerKtok * 1000, outputCentsPerMtok: cost.outputCentsPerKtok * 1000, capability: capabilityForModel(id), })); } export function filterRows(rows: ModelRow[], opts: { search?: string; capability?: string; task?: string }): ModelRow[] { let out = rows; if (opts.task) { const template = getTaskTemplate(opts.task); if (template) { const allowed = new Set(template.allowedModels); out = out.filter((row) => allowed.has(row.id) || row.capability === template.requiredCapability); } } if (opts.capability) out = out.filter((row) => row.capability === opts.capability); if (opts.search) { const needle = opts.search.toLowerCase(); out = out.filter((row) => row.id.toLowerCase().includes(needle) || row.name.toLowerCase().includes(needle)); } return out.sort((a, b) => displayCost(a) - displayCost(b) || a.id.localeCompare(b.id)); } export function suggestedAssignments(task: string): Record { const template = getTaskTemplate(task); if (!template) return {}; return { primary: [template.primaryModel], fallback: [template.fallbackModel], allowed: template.allowedModels, }; } export async function runModels(argv: string[]): Promise { if (argv.includes('--help') || argv.includes('-h')) { console.log('agentguard models [--sync-pricing] [--search ] [--capability ] [--task