mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
- Increase dialog max-width to 2xl for better content display - Add tabbed interface to feature modal (prompt/model/testing) - Streamline model selection with compact button layout - Remove unused OpenAI O3/O4 models from registry - Add model string validation and fallback logic - Add "Uncategorized" category support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
321 lines
8.3 KiB
JavaScript
321 lines
8.3 KiB
JavaScript
/**
|
|
* Model Registry - Centralized model definitions and metadata
|
|
*
|
|
* This module provides a central registry of all available models
|
|
* across different providers (Claude, Codex/OpenAI).
|
|
*/
|
|
|
|
/**
|
|
* Model Categories
|
|
*/
|
|
const MODEL_CATEGORIES = {
|
|
CLAUDE: 'claude',
|
|
OPENAI: 'openai',
|
|
CODEX: 'codex'
|
|
};
|
|
|
|
/**
|
|
* Model Tiers (capability levels)
|
|
*/
|
|
const MODEL_TIERS = {
|
|
BASIC: 'basic', // Fast, cheap, simple tasks
|
|
STANDARD: 'standard', // Balanced performance
|
|
PREMIUM: 'premium' // Most capable, complex tasks
|
|
};
|
|
|
|
const CODEX_MODEL_IDS = [
|
|
'gpt-5.1-codex-max',
|
|
'gpt-5.1-codex',
|
|
'gpt-5.1-codex-mini',
|
|
'gpt-5.1'
|
|
];
|
|
|
|
/**
|
|
* All available models with full metadata
|
|
*/
|
|
const MODELS = {
|
|
// Claude Models
|
|
haiku: {
|
|
id: 'haiku',
|
|
name: 'Claude Haiku',
|
|
modelString: 'claude-haiku-4-5',
|
|
provider: 'claude',
|
|
category: MODEL_CATEGORIES.CLAUDE,
|
|
tier: MODEL_TIERS.BASIC,
|
|
description: 'Fast and efficient for simple tasks',
|
|
capabilities: ['code', 'text', 'tools'],
|
|
maxTokens: 8192,
|
|
contextWindow: 200000,
|
|
supportsThinking: true,
|
|
requiresAuth: 'CLAUDE_CODE_OAUTH_TOKEN'
|
|
},
|
|
sonnet: {
|
|
id: 'sonnet',
|
|
name: 'Claude Sonnet',
|
|
modelString: 'claude-sonnet-4-20250514',
|
|
provider: 'claude',
|
|
category: MODEL_CATEGORIES.CLAUDE,
|
|
tier: MODEL_TIERS.STANDARD,
|
|
description: 'Balanced performance and capabilities',
|
|
capabilities: ['code', 'text', 'tools', 'analysis'],
|
|
maxTokens: 8192,
|
|
contextWindow: 200000,
|
|
supportsThinking: true,
|
|
requiresAuth: 'CLAUDE_CODE_OAUTH_TOKEN'
|
|
},
|
|
opus: {
|
|
id: 'opus',
|
|
name: 'Claude Opus 4.5',
|
|
modelString: 'claude-opus-4-5-20251101',
|
|
provider: 'claude',
|
|
category: MODEL_CATEGORIES.CLAUDE,
|
|
tier: MODEL_TIERS.PREMIUM,
|
|
description: 'Most capable model for complex tasks',
|
|
capabilities: ['code', 'text', 'tools', 'analysis', 'reasoning'],
|
|
maxTokens: 8192,
|
|
contextWindow: 200000,
|
|
supportsThinking: true,
|
|
requiresAuth: 'CLAUDE_CODE_OAUTH_TOKEN',
|
|
default: true
|
|
},
|
|
|
|
// OpenAI GPT-5.1 Codex Models
|
|
'gpt-5.1-codex-max': {
|
|
id: 'gpt-5.1-codex-max',
|
|
name: 'GPT-5.1 Codex Max',
|
|
modelString: 'gpt-5.1-codex-max',
|
|
provider: 'codex',
|
|
category: MODEL_CATEGORIES.OPENAI,
|
|
tier: MODEL_TIERS.PREMIUM,
|
|
description: 'Latest flagship - deep and fast reasoning for coding',
|
|
capabilities: ['code', 'text', 'tools', 'reasoning'],
|
|
maxTokens: 32768,
|
|
contextWindow: 128000,
|
|
supportsThinking: false,
|
|
requiresAuth: 'OPENAI_API_KEY',
|
|
codexDefault: true
|
|
},
|
|
'gpt-5.1-codex': {
|
|
id: 'gpt-5.1-codex',
|
|
name: 'GPT-5.1 Codex',
|
|
modelString: 'gpt-5.1-codex',
|
|
provider: 'codex',
|
|
category: MODEL_CATEGORIES.OPENAI,
|
|
tier: MODEL_TIERS.STANDARD,
|
|
description: 'Optimized for code generation',
|
|
capabilities: ['code', 'text', 'tools'],
|
|
maxTokens: 32768,
|
|
contextWindow: 128000,
|
|
supportsThinking: false,
|
|
requiresAuth: 'OPENAI_API_KEY'
|
|
},
|
|
'gpt-5.1-codex-mini': {
|
|
id: 'gpt-5.1-codex-mini',
|
|
name: 'GPT-5.1 Codex Mini',
|
|
modelString: 'gpt-5.1-codex-mini',
|
|
provider: 'codex',
|
|
category: MODEL_CATEGORIES.OPENAI,
|
|
tier: MODEL_TIERS.BASIC,
|
|
description: 'Faster and cheaper option',
|
|
capabilities: ['code', 'text'],
|
|
maxTokens: 16384,
|
|
contextWindow: 128000,
|
|
supportsThinking: false,
|
|
requiresAuth: 'OPENAI_API_KEY'
|
|
},
|
|
'gpt-5.1': {
|
|
id: 'gpt-5.1',
|
|
name: 'GPT-5.1',
|
|
modelString: 'gpt-5.1',
|
|
provider: 'codex',
|
|
category: MODEL_CATEGORIES.OPENAI,
|
|
tier: MODEL_TIERS.STANDARD,
|
|
description: 'Broad world knowledge with strong reasoning',
|
|
capabilities: ['code', 'text', 'reasoning'],
|
|
maxTokens: 32768,
|
|
contextWindow: 128000,
|
|
supportsThinking: false,
|
|
requiresAuth: 'OPENAI_API_KEY'
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Model Registry class for querying and managing models
|
|
*/
|
|
class ModelRegistry {
|
|
/**
|
|
* Get all registered models
|
|
* @returns {Object} All models
|
|
*/
|
|
static getAllModels() {
|
|
return MODELS;
|
|
}
|
|
|
|
/**
|
|
* Get model by ID
|
|
* @param {string} modelId Model ID
|
|
* @returns {Object|null} Model definition or null
|
|
*/
|
|
static getModel(modelId) {
|
|
return MODELS[modelId] || null;
|
|
}
|
|
|
|
/**
|
|
* Get models by provider
|
|
* @param {string} provider Provider name ('claude' or 'codex')
|
|
* @returns {Object[]} Array of models for the provider
|
|
*/
|
|
static getModelsByProvider(provider) {
|
|
return Object.values(MODELS).filter(m => m.provider === provider);
|
|
}
|
|
|
|
/**
|
|
* Get models by category
|
|
* @param {string} category Category name
|
|
* @returns {Object[]} Array of models in the category
|
|
*/
|
|
static getModelsByCategory(category) {
|
|
return Object.values(MODELS).filter(m => m.category === category);
|
|
}
|
|
|
|
/**
|
|
* Get models by tier
|
|
* @param {string} tier Tier name
|
|
* @returns {Object[]} Array of models in the tier
|
|
*/
|
|
static getModelsByTier(tier) {
|
|
return Object.values(MODELS).filter(m => m.tier === tier);
|
|
}
|
|
|
|
/**
|
|
* Get default model for a provider
|
|
* @param {string} provider Provider name
|
|
* @returns {Object|null} Default model or null
|
|
*/
|
|
static getDefaultModel(provider = 'claude') {
|
|
const models = this.getModelsByProvider(provider);
|
|
if (provider === 'claude') {
|
|
return models.find(m => m.default) || models[0];
|
|
}
|
|
if (provider === 'codex') {
|
|
return models.find(m => m.codexDefault) || models[0];
|
|
}
|
|
return models[0];
|
|
}
|
|
|
|
/**
|
|
* Get model string (full model name) for a model ID
|
|
* @param {string} modelId Model ID
|
|
* @returns {string} Full model string
|
|
*/
|
|
static getModelString(modelId) {
|
|
const model = this.getModel(modelId);
|
|
return model ? model.modelString : modelId;
|
|
}
|
|
|
|
/**
|
|
* Determine provider for a model ID
|
|
* @param {string} modelId Model ID
|
|
* @returns {string} Provider name ('claude' or 'codex')
|
|
*/
|
|
static getProviderForModel(modelId) {
|
|
const model = this.getModel(modelId);
|
|
if (model) {
|
|
return model.provider;
|
|
}
|
|
|
|
// Fallback detection for models not explicitly registered (keeps legacy Codex IDs working)
|
|
if (CODEX_MODEL_IDS.includes(modelId)) {
|
|
return 'codex';
|
|
}
|
|
|
|
return 'claude';
|
|
}
|
|
|
|
/**
|
|
* Check if a model is a Claude model
|
|
* @param {string} modelId Model ID
|
|
* @returns {boolean} Whether it's a Claude model
|
|
*/
|
|
static isClaudeModel(modelId) {
|
|
return this.getProviderForModel(modelId) === 'claude';
|
|
}
|
|
|
|
/**
|
|
* Check if a model is a Codex/OpenAI model
|
|
* @param {string} modelId Model ID
|
|
* @returns {boolean} Whether it's a Codex model
|
|
*/
|
|
static isCodexModel(modelId) {
|
|
return this.getProviderForModel(modelId) === 'codex';
|
|
}
|
|
|
|
/**
|
|
* Get models grouped by provider for UI display
|
|
* @returns {Object} Models grouped by provider
|
|
*/
|
|
static getModelsGroupedByProvider() {
|
|
return {
|
|
claude: this.getModelsByProvider('claude'),
|
|
codex: this.getModelsByProvider('codex')
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get all model IDs as an array
|
|
* @returns {string[]} Array of model IDs
|
|
*/
|
|
static getAllModelIds() {
|
|
return Object.keys(MODELS);
|
|
}
|
|
|
|
/**
|
|
* Check if model supports a specific capability
|
|
* @param {string} modelId Model ID
|
|
* @param {string} capability Capability name
|
|
* @returns {boolean} Whether the model supports the capability
|
|
*/
|
|
static modelSupportsCapability(modelId, capability) {
|
|
const model = this.getModel(modelId);
|
|
return model ? model.capabilities.includes(capability) : false;
|
|
}
|
|
|
|
/**
|
|
* Check if model supports extended thinking
|
|
* @param {string} modelId Model ID
|
|
* @returns {boolean} Whether the model supports thinking
|
|
*/
|
|
static modelSupportsThinking(modelId) {
|
|
const model = this.getModel(modelId);
|
|
return model ? model.supportsThinking : false;
|
|
}
|
|
|
|
/**
|
|
* Get required authentication for a model
|
|
* @param {string} modelId Model ID
|
|
* @returns {string|null} Required auth env variable name
|
|
*/
|
|
static getRequiredAuth(modelId) {
|
|
const model = this.getModel(modelId);
|
|
return model ? model.requiresAuth : null;
|
|
}
|
|
|
|
/**
|
|
* Check if authentication is available for a model
|
|
* @param {string} modelId Model ID
|
|
* @returns {boolean} Whether auth is available
|
|
*/
|
|
static hasAuthForModel(modelId) {
|
|
const authVar = this.getRequiredAuth(modelId);
|
|
if (!authVar) return false;
|
|
return !!process.env[authVar];
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
MODEL_CATEGORIES,
|
|
MODEL_TIERS,
|
|
MODELS,
|
|
ModelRegistry
|
|
};
|