diff --git a/libs/model-resolver/package.json b/libs/model-resolver/package.json new file mode 100644 index 00000000..ad2f07e0 --- /dev/null +++ b/libs/model-resolver/package.json @@ -0,0 +1,21 @@ +{ + "name": "@automaker/model-resolver", + "version": "1.0.0", + "description": "Model resolution utilities for AutoMaker", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "watch": "tsc --watch" + }, + "keywords": ["automaker", "model", "resolver"], + "author": "", + "license": "MIT", + "dependencies": { + "@automaker/types": "^1.0.0" + }, + "devDependencies": { + "@types/node": "^22.10.5", + "typescript": "^5.7.3" + } +} diff --git a/libs/model-resolver/src/index.ts b/libs/model-resolver/src/index.ts new file mode 100644 index 00000000..22852e18 --- /dev/null +++ b/libs/model-resolver/src/index.ts @@ -0,0 +1,13 @@ +/** + * @automaker/model-resolver + * Model resolution utilities for AutoMaker + */ + +// Re-export constants from types +export { CLAUDE_MODEL_MAP, DEFAULT_MODELS, type ModelAlias } from '@automaker/types'; + +// Export resolver functions +export { + resolveModelString, + getEffectiveModel, +} from './resolver'; diff --git a/libs/model-resolver/src/resolver.ts b/libs/model-resolver/src/resolver.ts new file mode 100644 index 00000000..120ab36c --- /dev/null +++ b/libs/model-resolver/src/resolver.ts @@ -0,0 +1,65 @@ +/** + * Model resolution utilities for handling model string mapping + * + * Provides centralized model resolution logic: + * - Maps Claude model aliases to full model strings + * - Provides default models per provider + * - Handles multiple model sources with priority + */ + +import { CLAUDE_MODEL_MAP, DEFAULT_MODELS } from '@automaker/types'; + +/** + * Resolve a model key/alias to a full model string + * + * @param modelKey - Model key (e.g., "opus", "gpt-5.2", "claude-sonnet-4-20250514") + * @param defaultModel - Fallback model if modelKey is undefined + * @returns Full model string + */ +export function resolveModelString( + modelKey?: string, + defaultModel: string = DEFAULT_MODELS.claude +): string { + // No model specified - use default + if (!modelKey) { + return defaultModel; + } + + // Full Claude model string - pass through unchanged + if (modelKey.includes("claude-")) { + console.log(`[ModelResolver] Using full Claude model string: ${modelKey}`); + return modelKey; + } + + // Look up Claude model alias + const resolved = CLAUDE_MODEL_MAP[modelKey]; + if (resolved) { + console.log( + `[ModelResolver] Resolved model alias: "${modelKey}" -> "${resolved}"` + ); + return resolved; + } + + // Unknown model key - use default + console.warn( + `[ModelResolver] Unknown model key "${modelKey}", using default: "${defaultModel}"` + ); + return defaultModel; +} + +/** + * Get the effective model from multiple sources + * Priority: explicit model > session model > default + * + * @param explicitModel - Explicitly provided model (highest priority) + * @param sessionModel - Model from session (medium priority) + * @param defaultModel - Fallback default model (lowest priority) + * @returns Resolved model string + */ +export function getEffectiveModel( + explicitModel?: string, + sessionModel?: string, + defaultModel?: string +): string { + return resolveModelString(explicitModel || sessionModel, defaultModel); +} diff --git a/libs/model-resolver/tsconfig.json b/libs/model-resolver/tsconfig.json new file mode 100644 index 00000000..54e9774b --- /dev/null +++ b/libs/model-resolver/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["ES2020"], + "types": ["node"], + "declaration": true, + "declarationMap": true, + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "moduleResolution": "node" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +}