UNPKG

aiwg

Version:

Cognitive architecture for AI-augmented software development with structured memory, ensemble validation, and closed-loop correction. FAIR-aligned artifacts, 84% cost reduction via human-in-the-loop, standards adopted by 100+ organizations.

290 lines (248 loc) 8.44 kB
/** * Model Catalog CLI Commands * * Provides CLI interface for catalog operations: * - list: List all models with filtering * - info: Show detailed model information * - search: Search models by query * * @implements @.aiwg/architecture/enhanced-model-selection-design.md#9-model-catalog-system * @module src/catalog/cli */ import { loadCatalog, getModel, listModels, getProvider, listProviders, searchModels, } from './loader.mjs'; /** * Format quality rating as stars */ function formatQualityRating(rating) { const ratingMap = { excellent: '★★★★★', good: '★★★★☆', fair: '★★★☆☆', poor: '★★☆☆☆', unknown: '☆☆☆☆☆', }; return ratingMap[rating] || '☆☆☆☆☆'; } /** * Format currency amount */ function formatPrice(amount) { return `$${amount.toFixed(5)}`; } /** * Format large numbers with commas */ function formatNumber(num) { return num.toLocaleString(); } /** * Display a table of models */ function displayModelsTable(models) { if (models.length === 0) { console.log('No models found.'); return; } console.log(''); console.log( '┌─────────────────────────────────┬───────────┬──────────┬─────────┬──────────┐' ); console.log( '│ Model ID │ Display │ Context │ Vision │ Status │' ); console.log( '├─────────────────────────────────┼───────────┼──────────┼─────────┼──────────┤' ); for (const model of models) { const id = model.id.padEnd(31).substring(0, 31); const display = model.displayName.padEnd(9).substring(0, 9); const context = `${Math.floor(model.capabilities.contextWindow / 1000)}K`.padEnd(8); const vision = model.capabilities.vision ? '✓' : ' '; const status = model.status.padEnd(8); console.log(`│ ${id}${display}${context}${vision}${status} │`); } console.log( '└─────────────────────────────────┴───────────┴──────────┴─────────┴──────────┘' ); console.log(''); } /** * Display detailed model information */ function displayModelInfo(model) { console.log(''); console.log(`Model: ${model.id}`); console.log(''); console.log(`Provider: ${model.provider}`); console.log(`Display Name: ${model.displayName}`); if (model.releaseDate) { console.log(`Release Date: ${model.releaseDate}`); } console.log(`Status: ${model.status}`); if (model.deprecated) { console.log(''); console.log('⚠ DEPRECATED'); if (model.deprecationDate) { console.log(`Deprecated: ${model.deprecationDate}`); } if (model.successorModel) { console.log(`Successor: ${model.successorModel}`); } } console.log(''); console.log('Capabilities:'); console.log(` Context Window: ${formatNumber(model.capabilities.contextWindow)} tokens`); console.log(` Max Output: ${formatNumber(model.capabilities.maxOutputTokens)} tokens`); console.log(` Vision: ${model.capabilities.vision ? '✓' : '✗'}`); console.log(` Tool Use: ${model.capabilities.toolUse ? '✓' : '✗'}`); console.log(` Streaming: ${model.capabilities.streaming ? '✓' : '✗'}`); console.log(''); console.log('Quality Ratings:'); console.log( ` Reasoning: ${formatQualityRating(model.capabilities.reasoning)} ${model.capabilities.reasoning}` ); console.log( ` Coding: ${formatQualityRating(model.capabilities.coding)} ${model.capabilities.coding}` ); console.log( ` Speed: ${formatQualityRating(model.capabilities.speed)} ${model.capabilities.speed}` ); if (model.pricing) { console.log(''); console.log(`Pricing (${model.pricing.currency} per 1K tokens):`); console.log(` Input: ${formatPrice(model.pricing.inputPer1kTokens)}`); console.log(` Output: ${formatPrice(model.pricing.outputPer1kTokens)}`); console.log(` (Last updated: ${model.pricing.lastUpdated})`); } if (model.aliases.length > 0) { console.log(''); console.log(`Aliases: ${model.aliases.join(', ')}`); } if (model.tags.length > 0) { console.log(`Tags: ${model.tags.join(', ')}`); } console.log(''); console.log(`Source: ${model.source}`); console.log(`Last Verified: ${model.lastVerified}`); console.log(''); } /** * Handle 'catalog list' command */ export async function handleCatalogList(args) { const filter = {}; // Parse filter arguments for (let i = 0; i < args.length; i++) { if (args[i] === '--provider' && i + 1 < args.length) { filter.provider = args[i + 1]; i++; } else if (args[i] === '--status' && i + 1 < args.length) { filter.status = args[i + 1]; i++; } else if (args[i] === '--tag' && i + 1 < args.length) { filter.tag = args[i + 1]; i++; } else if (args[i] === '--min-context' && i + 1 < args.length) { filter.minContext = parseInt(args[i + 1], 10); i++; } } const models = await listModels(filter); // Group by provider if no provider filter if (!filter.provider) { const providers = new Set(models.map((m) => m.provider)); for (const provider of providers) { const providerModels = models.filter((m) => m.provider === provider); const providerInfo = await getProvider(provider); console.log(''); console.log( `AIWG Model Catalog - ${providerInfo?.displayName || provider.toUpperCase()}` ); displayModelsTable(providerModels); } } else { const providerInfo = await getProvider(filter.provider); console.log(''); console.log( `AIWG Model Catalog - ${providerInfo?.displayName || filter.provider.toUpperCase()}` ); displayModelsTable(models); } const catalog = await loadCatalog(); console.log(`Last refreshed: ${catalog.metadata.lastRefresh}`); console.log("Run 'aiwg catalog refresh' to update"); console.log(''); } /** * Handle 'catalog info' command */ export async function handleCatalogInfo(args) { const modelId = args[0]; if (!modelId) { console.error('Error: Model ID required'); console.log('Usage: aiwg catalog info <model-id>'); process.exit(1); } const model = await getModel(modelId); if (!model) { console.error(`Error: Model '${modelId}' not found in catalog`); console.log("Run 'aiwg catalog list' to see available models"); process.exit(1); } displayModelInfo(model); } /** * Handle 'catalog search' command */ export async function handleCatalogSearch(args) { const query = args.join(' '); if (!query) { console.error('Error: Search query required'); console.log('Usage: aiwg catalog search <query>'); process.exit(1); } const models = await searchModels(query); console.log(''); console.log(`Search results for: "${query}"`); displayModelsTable(models); } /** * Main catalog command router */ export async function main(args) { const subcommand = args[0]; const subcommandArgs = args.slice(1); switch (subcommand) { case 'list': await handleCatalogList(subcommandArgs); break; case 'info': await handleCatalogInfo(subcommandArgs); break; case 'search': await handleCatalogSearch(subcommandArgs); break; case undefined: console.error('Error: Catalog subcommand required'); console.log('Available: list, info, search'); console.log(''); console.log('Examples:'); console.log(' aiwg catalog list'); console.log(' aiwg catalog list --provider anthropic'); console.log(' aiwg catalog info claude-opus-4-5-20251101'); console.log(' aiwg catalog search opus'); process.exit(1); break; default: console.error(`Error: Unknown catalog subcommand '${subcommand}'`); console.log('Available: list, info, search'); process.exit(1); } }