tachibot-mcp 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +260 -0
- package/CHANGELOG.md +54 -0
- package/CODE_OF_CONDUCT.md +56 -0
- package/CONTRIBUTING.md +54 -0
- package/Dockerfile +36 -0
- package/LICENSE +644 -0
- package/README.md +201 -0
- package/SECURITY.md +95 -0
- package/dist/personality/komaai-expressions.js +12 -0
- package/dist/profiles/balanced.json +33 -0
- package/dist/profiles/code_focus.json +33 -0
- package/dist/profiles/full.json +33 -0
- package/dist/profiles/minimal.json +33 -0
- package/dist/profiles/research_power.json +33 -0
- package/dist/scripts/build-profiles.js +46 -0
- package/dist/src/application/services/focus/FocusModeRegistry.js +46 -0
- package/dist/src/application/services/focus/FocusTool.service.js +109 -0
- package/dist/src/application/services/focus/ModeRegistry.js +46 -0
- package/dist/src/application/services/focus/modes/focus-deep.mode.js +27 -0
- package/dist/src/application/services/focus/modes/status.mode.js +50 -0
- package/dist/src/application/services/focus/modes/tachibot-status.mode.js +50 -0
- package/dist/src/collaborative-orchestrator.js +391 -0
- package/dist/src/config/model-constants.js +188 -0
- package/dist/src/config/model-defaults.js +57 -0
- package/dist/src/config/model-preferences.js +382 -0
- package/dist/src/config/timeout-config.js +130 -0
- package/dist/src/config.js +173 -0
- package/dist/src/domain/interfaces/IFocusMode.js +5 -0
- package/dist/src/domain/interfaces/IProvider.js +6 -0
- package/dist/src/domain/interfaces/ITool.js +5 -0
- package/dist/src/focus-deep.js +245 -0
- package/dist/src/infrastructure/ascii/art/robots.ascii.js +16 -0
- package/dist/src/mcp-client.js +90 -0
- package/dist/src/memory/index.js +17 -0
- package/dist/src/memory/memory-config.js +135 -0
- package/dist/src/memory/memory-interface.js +174 -0
- package/dist/src/memory/memory-manager.js +383 -0
- package/dist/src/memory/providers/devlog-provider.js +385 -0
- package/dist/src/memory/providers/hybrid-provider.js +399 -0
- package/dist/src/memory/providers/local-provider.js +388 -0
- package/dist/src/memory/providers/mem0-provider.js +337 -0
- package/dist/src/modes/architect.js +477 -0
- package/dist/src/modes/auditor.js +362 -0
- package/dist/src/modes/challenger.js +841 -0
- package/dist/src/modes/code-reviewer.js +382 -0
- package/dist/src/modes/commit-guardian.js +424 -0
- package/dist/src/modes/documentation-writer.js +572 -0
- package/dist/src/modes/scout.js +587 -0
- package/dist/src/modes/shared/helpers/challenger-helpers.js +454 -0
- package/dist/src/modes/shared/helpers/index.js +17 -0
- package/dist/src/modes/shared/helpers/scout-helpers.js +270 -0
- package/dist/src/modes/shared/helpers/verifier-helpers.js +332 -0
- package/dist/src/modes/test-architect.js +767 -0
- package/dist/src/modes/verifier.js +378 -0
- package/dist/src/monitoring/performance-monitor.js +435 -0
- package/dist/src/optimization/batch-executor.js +121 -0
- package/dist/src/optimization/context-pruner.js +196 -0
- package/dist/src/optimization/cost-monitor.js +338 -0
- package/dist/src/optimization/index.js +65 -0
- package/dist/src/optimization/model-router.js +264 -0
- package/dist/src/optimization/result-cache.js +114 -0
- package/dist/src/optimization/token-optimizer.js +257 -0
- package/dist/src/optimization/token-tracker.js +118 -0
- package/dist/src/orchestrator-instructions.js +128 -0
- package/dist/src/orchestrator-lite.js +139 -0
- package/dist/src/orchestrator.js +191 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionEngine.js +1 -0
- package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionStrategy.js +5 -0
- package/dist/src/orchestrators/collaborative/interfaces/IVisualizationRenderer.js +1 -0
- package/dist/src/orchestrators/collaborative/registries/ModelProviderRegistry.js +95 -0
- package/dist/src/orchestrators/collaborative/registries/ToolAdapterRegistry.js +64 -0
- package/dist/src/orchestrators/collaborative/services/tool-execution/ToolExecutionService.js +502 -0
- package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +206 -0
- package/dist/src/orchestrators/collaborative/types/session-types.js +5 -0
- package/dist/src/profiles/balanced.js +37 -0
- package/dist/src/profiles/code_focus.js +37 -0
- package/dist/src/profiles/debug_intensive.js +59 -0
- package/dist/src/profiles/full.js +37 -0
- package/dist/src/profiles/minimal.js +37 -0
- package/dist/src/profiles/research_code.js +59 -0
- package/dist/src/profiles/research_power.js +37 -0
- package/dist/src/profiles/types.js +5 -0
- package/dist/src/profiles/workflow_builder.js +53 -0
- package/dist/src/prompt-engineer-lite.js +78 -0
- package/dist/src/prompt-engineer.js +399 -0
- package/dist/src/reasoning-chain.js +508 -0
- package/dist/src/sequential-thinking.js +291 -0
- package/dist/src/server-diagnostic.js +74 -0
- package/dist/src/server-raw.js +158 -0
- package/dist/src/server-simple.js +58 -0
- package/dist/src/server.js +514 -0
- package/dist/src/session/session-logger.js +617 -0
- package/dist/src/session/session-manager.js +571 -0
- package/dist/src/session/session-tools.js +400 -0
- package/dist/src/tools/advanced-modes.js +200 -0
- package/dist/src/tools/claude-integration.js +356 -0
- package/dist/src/tools/consolidated/ai-router.js +174 -0
- package/dist/src/tools/consolidated/ai-tool.js +48 -0
- package/dist/src/tools/consolidated/brainstorm-tool.js +87 -0
- package/dist/src/tools/consolidated/environment-detector.js +80 -0
- package/dist/src/tools/consolidated/index.js +50 -0
- package/dist/src/tools/consolidated/search-tool.js +110 -0
- package/dist/src/tools/consolidated/workflow-tool.js +238 -0
- package/dist/src/tools/gemini-tools.js +329 -0
- package/dist/src/tools/grok-enhanced.js +376 -0
- package/dist/src/tools/grok-tools.js +299 -0
- package/dist/src/tools/lmstudio-tools.js +223 -0
- package/dist/src/tools/openai-tools.js +498 -0
- package/dist/src/tools/openrouter-tools.js +317 -0
- package/dist/src/tools/optimized-wrapper.js +204 -0
- package/dist/src/tools/perplexity-tools.js +294 -0
- package/dist/src/tools/pingpong-tool.js +343 -0
- package/dist/src/tools/qwen-wrapper.js +74 -0
- package/dist/src/tools/tool-router.js +444 -0
- package/dist/src/tools/unified-ai-provider.js +260 -0
- package/dist/src/tools/workflow-runner.js +425 -0
- package/dist/src/tools/workflow-validator-tool.js +107 -0
- package/dist/src/types.js +23 -0
- package/dist/src/utils/input-validator.js +130 -0
- package/dist/src/utils/model-router.js +91 -0
- package/dist/src/utils/progress-stream.js +255 -0
- package/dist/src/utils/provider-router.js +88 -0
- package/dist/src/utils/smart-api-client.js +146 -0
- package/dist/src/utils/table-builder.js +218 -0
- package/dist/src/utils/timestamp-formatter.js +134 -0
- package/dist/src/utils/tool-compressor.js +257 -0
- package/dist/src/utils/tool-config.js +201 -0
- package/dist/src/validators/dependency-graph-validator.js +147 -0
- package/dist/src/validators/interpolation-validator.js +222 -0
- package/dist/src/validators/output-usage-validator.js +151 -0
- package/dist/src/validators/syntax-validator.js +102 -0
- package/dist/src/validators/tool-registry-validator.js +123 -0
- package/dist/src/validators/tool-types.js +97 -0
- package/dist/src/validators/types.js +8 -0
- package/dist/src/validators/workflow-validator.js +134 -0
- package/dist/src/visualizer-lite.js +42 -0
- package/dist/src/visualizer.js +179 -0
- package/dist/src/workflows/circuit-breaker.js +199 -0
- package/dist/src/workflows/custom-workflows.js +451 -0
- package/dist/src/workflows/engine/AutoSynthesizer.js +97 -0
- package/dist/src/workflows/engine/StepParameterResolver.js +74 -0
- package/dist/src/workflows/engine/VariableInterpolator.js +123 -0
- package/dist/src/workflows/engine/WorkflowDiscovery.js +125 -0
- package/dist/src/workflows/engine/WorkflowExecutionEngine.js +485 -0
- package/dist/src/workflows/engine/WorkflowExecutor.js +113 -0
- package/dist/src/workflows/engine/WorkflowFileManager.js +244 -0
- package/dist/src/workflows/engine/WorkflowHelpers.js +114 -0
- package/dist/src/workflows/engine/WorkflowOutputFormatter.js +83 -0
- package/dist/src/workflows/engine/events/WorkflowEventBus.js +132 -0
- package/dist/src/workflows/engine/events/interfaces/IEventBus.js +5 -0
- package/dist/src/workflows/engine/handlers/ErrorRecoveryHandler.js +162 -0
- package/dist/src/workflows/engine/handlers/PromptEnhancementHandler.js +115 -0
- package/dist/src/workflows/engine/handlers/SessionPersistenceHandler.js +167 -0
- package/dist/src/workflows/engine/handlers/StepExecutionHandler.js +231 -0
- package/dist/src/workflows/engine/handlers/ToolInvocationHandler.js +46 -0
- package/dist/src/workflows/engine/interfaces/IAutoSynthesizer.js +5 -0
- package/dist/src/workflows/engine/interfaces/IStepParameterResolver.js +5 -0
- package/dist/src/workflows/engine/interfaces/IVariableInterpolator.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowDiscovery.js +4 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowFileManager.js +5 -0
- package/dist/src/workflows/engine/interfaces/IWorkflowOutputFormatter.js +5 -0
- package/dist/src/workflows/engine/state/WorkflowStateMachine.js +194 -0
- package/dist/src/workflows/engine/state/interfaces/IStateMachine.js +17 -0
- package/dist/src/workflows/fallback-strategies.js +373 -0
- package/dist/src/workflows/message-queue.js +455 -0
- package/dist/src/workflows/model-router.js +189 -0
- package/dist/src/workflows/orchestrator-examples.js +174 -0
- package/dist/src/workflows/orchestrator-integration.js +200 -0
- package/dist/src/workflows/self-healing.js +524 -0
- package/dist/src/workflows/tool-mapper.js +407 -0
- package/dist/src/workflows/tool-orchestrator.js +796 -0
- package/dist/src/workflows/workflow-engine.js +573 -0
- package/dist/src/workflows/workflow-parser.js +283 -0
- package/dist/src/workflows/workflow-types.js +95 -0
- package/dist/src/workflows.js +568 -0
- package/dist/test-workflow-file-output.js +93 -0
- package/docs/API_KEYS.md +570 -0
- package/docs/CLAUDE_CODE_SETUP.md +181 -0
- package/docs/CLAUDE_DESKTOP_MANUAL.md +127 -0
- package/docs/CONFIGURATION.md +745 -0
- package/docs/FOCUS_MODES.md +240 -0
- package/docs/INSTALLATION_BOTH.md +145 -0
- package/docs/TERMS.md +352 -0
- package/docs/TOOLS_REFERENCE.md +1622 -0
- package/docs/TOOL_PARAMETERS.md +496 -0
- package/docs/TOOL_PROFILES.md +236 -0
- package/docs/WORKFLOWS.md +987 -0
- package/docs/WORKFLOW_OUTPUT.md +198 -0
- package/docs/WORKFLOW_PROGRESS_TRACKING.md +305 -0
- package/docs/workflows/design-brainstorm.md +335 -0
- package/package.json +97 -0
- package/profiles/balanced.json +37 -0
- package/profiles/code_focus.json +37 -0
- package/profiles/debug_intensive.json +34 -0
- package/profiles/full.json +37 -0
- package/profiles/minimal.json +37 -0
- package/profiles/research_power.json +37 -0
- package/profiles/workflow_builder.json +37 -0
- package/smithery.yaml +66 -0
- package/start.sh +8 -0
- package/tools.config.json +81 -0
- package/tsconfig.json +18 -0
- package/workflows/accessibility-code-audit.yaml +92 -0
- package/workflows/code-architecture-review.yaml +202 -0
- package/workflows/code-review.yaml +142 -0
- package/workflows/core/iterative-problem-solver.yaml +283 -0
- package/workflows/creative-brainstorm-yaml.yaml +215 -0
- package/workflows/pingpong.yaml +141 -0
- package/workflows/system/README.md +412 -0
- package/workflows/system/challenger.yaml +175 -0
- package/workflows/system/scout.yaml +164 -0
- package/workflows/system/verifier.yaml +133 -0
- package/workflows/ultra-creative-brainstorm.yaml +318 -0
- package/workflows/ux-research-flow.yaml +92 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized Model Names and Constants
|
|
3
|
+
* Use these constants instead of hardcoded strings in workflows and tools
|
|
4
|
+
*/
|
|
5
|
+
// OpenAI GPT-5 Models (August 2025)
|
|
6
|
+
export const GPT5_MODELS = {
|
|
7
|
+
NANO: "gpt-5-nano", // Fastest, most cost-efficient ($0.05/$0.40 per 1M tokens)
|
|
8
|
+
MINI: "gpt-5-mini", // Balanced performance ($0.25/$2 per 1M tokens)
|
|
9
|
+
FULL: "gpt-5", // Most advanced ($1.25/$10 per 1M tokens)
|
|
10
|
+
};
|
|
11
|
+
// OpenAI GPT-4 Models
|
|
12
|
+
export const GPT4_MODELS = {
|
|
13
|
+
O_MINI: "gpt-5-mini", // Cost-efficient
|
|
14
|
+
O: "gpt-5", // Current best
|
|
15
|
+
_1_MINI: "gpt-4.1-mini", // Best value with 1M context
|
|
16
|
+
};
|
|
17
|
+
// Google Gemini Models (2025)
|
|
18
|
+
export const GEMINI_MODELS = {
|
|
19
|
+
FLASH: "gemini-2.5-flash", // Latest fast model
|
|
20
|
+
PRO: "gemini-2.5-pro", // Most advanced reasoning
|
|
21
|
+
FLASH_LITE: "gemini-2.5-flash-lite", // Cost-effective
|
|
22
|
+
};
|
|
23
|
+
// Perplexity Models
|
|
24
|
+
export const PERPLEXITY_MODELS = {
|
|
25
|
+
SONAR_PRO: "sonar-pro", // Main search model
|
|
26
|
+
SONAR_REASONING: "sonar-reasoning-pro", // Reasoning model
|
|
27
|
+
};
|
|
28
|
+
// Grok Models (xAI) - Updated 2025-11-07
|
|
29
|
+
export const GROK_MODELS = {
|
|
30
|
+
// New fast models (2025) - PRIMARY USE
|
|
31
|
+
CODE_FAST: "grok-code-fast-1", // Coding specialist: 256K→2M, $0.20/$1.50, 92 tok/sec
|
|
32
|
+
_4_FAST_REASONING: "grok-4-fast-reasoning", // Cheap reasoning: 2M→4M, $0.20/$0.50 (3x cheaper!)
|
|
33
|
+
_4_FAST: "grok-4-fast-non-reasoning", // Fast general: 2M→4M, $0.20/$0.50
|
|
34
|
+
// Expensive/specialized (use sparingly)
|
|
35
|
+
_4_HEAVY: "grok-4-0709", // Multi-agent: 256K→2M, $3/$15 (expensive!)
|
|
36
|
+
_3: "grok-3", // Legacy with search: 256K→2M
|
|
37
|
+
};
|
|
38
|
+
// Kimi Models (Moonshot AI via OpenRouter) - Added 2025-11-07
|
|
39
|
+
export const KIMI_MODELS = {
|
|
40
|
+
K2_THINKING: "moonshotai/kimi-k2-thinking", // 1T MoE, 32B active - Leading open-source agentic reasoning (256k context)
|
|
41
|
+
};
|
|
42
|
+
// All models combined for validation
|
|
43
|
+
export const ALL_MODELS = {
|
|
44
|
+
...GPT5_MODELS,
|
|
45
|
+
...GPT4_MODELS,
|
|
46
|
+
...GEMINI_MODELS,
|
|
47
|
+
...PERPLEXITY_MODELS,
|
|
48
|
+
...GROK_MODELS,
|
|
49
|
+
...KIMI_MODELS,
|
|
50
|
+
};
|
|
51
|
+
// Common workflow settings
|
|
52
|
+
export const DEFAULT_WORKFLOW_SETTINGS = {
|
|
53
|
+
maxTokens: 2000,
|
|
54
|
+
temperature: 0.7,
|
|
55
|
+
retries: 3,
|
|
56
|
+
timeout: 30000, // 30 seconds
|
|
57
|
+
};
|
|
58
|
+
// Tool-specific defaults for ALL tools
|
|
59
|
+
export const TOOL_DEFAULTS = {
|
|
60
|
+
// OpenAI GPT-5 tools
|
|
61
|
+
gpt5_nano: {
|
|
62
|
+
model: GPT5_MODELS.NANO,
|
|
63
|
+
maxTokens: 1000,
|
|
64
|
+
temperature: 1.0, // GPT-5 requires temperature=1
|
|
65
|
+
},
|
|
66
|
+
gpt5_mini: {
|
|
67
|
+
model: GPT5_MODELS.MINI,
|
|
68
|
+
maxTokens: 2000,
|
|
69
|
+
temperature: 1.0,
|
|
70
|
+
},
|
|
71
|
+
gpt5: {
|
|
72
|
+
model: GPT5_MODELS.FULL,
|
|
73
|
+
maxTokens: 4000,
|
|
74
|
+
temperature: 1.0,
|
|
75
|
+
},
|
|
76
|
+
// Gemini tools
|
|
77
|
+
gemini_query: {
|
|
78
|
+
model: GEMINI_MODELS.PRO,
|
|
79
|
+
maxTokens: 2048,
|
|
80
|
+
temperature: 0.7,
|
|
81
|
+
},
|
|
82
|
+
gemini_brainstorm: {
|
|
83
|
+
model: GEMINI_MODELS.PRO,
|
|
84
|
+
maxTokens: 2048,
|
|
85
|
+
temperature: 0.9,
|
|
86
|
+
},
|
|
87
|
+
gemini_analyze_code: {
|
|
88
|
+
model: GEMINI_MODELS.PRO,
|
|
89
|
+
maxTokens: 2048,
|
|
90
|
+
temperature: 0.3,
|
|
91
|
+
},
|
|
92
|
+
gemini_analyze_text: {
|
|
93
|
+
model: GEMINI_MODELS.PRO,
|
|
94
|
+
maxTokens: 2048,
|
|
95
|
+
temperature: 0.5,
|
|
96
|
+
},
|
|
97
|
+
// Perplexity tools
|
|
98
|
+
perplexity_ask: {
|
|
99
|
+
model: PERPLEXITY_MODELS.SONAR_PRO,
|
|
100
|
+
maxTokens: 2000,
|
|
101
|
+
temperature: 0.7,
|
|
102
|
+
},
|
|
103
|
+
perplexity_reason: {
|
|
104
|
+
model: PERPLEXITY_MODELS.SONAR_REASONING,
|
|
105
|
+
maxTokens: 4000,
|
|
106
|
+
temperature: 0.7,
|
|
107
|
+
},
|
|
108
|
+
perplexity_research: {
|
|
109
|
+
model: PERPLEXITY_MODELS.SONAR_PRO,
|
|
110
|
+
maxTokens: 3000,
|
|
111
|
+
temperature: 0.7,
|
|
112
|
+
},
|
|
113
|
+
// Grok tools - UPDATED with new fast models
|
|
114
|
+
grok: {
|
|
115
|
+
model: GROK_MODELS._4_FAST_REASONING, // Changed: 3x cheaper output
|
|
116
|
+
maxTokens: 4000,
|
|
117
|
+
temperature: 0.7,
|
|
118
|
+
},
|
|
119
|
+
grok_reason: {
|
|
120
|
+
model: GROK_MODELS._4_FAST_REASONING, // Changed: 3x cheaper, 8x context
|
|
121
|
+
maxTokens: 8000,
|
|
122
|
+
temperature: 0.7,
|
|
123
|
+
},
|
|
124
|
+
grok_code: {
|
|
125
|
+
model: GROK_MODELS.CODE_FAST, // Changed: Coding specialist, 3x faster
|
|
126
|
+
maxTokens: 4000,
|
|
127
|
+
temperature: 0.3,
|
|
128
|
+
},
|
|
129
|
+
grok_search: {
|
|
130
|
+
model: GROK_MODELS._4_FAST_REASONING, // Changed: Use fast reasoning with search
|
|
131
|
+
maxTokens: 3000,
|
|
132
|
+
temperature: 0.7,
|
|
133
|
+
},
|
|
134
|
+
grok_brainstorm: {
|
|
135
|
+
model: GROK_MODELS._4_FAST, // Changed: Fast non-reasoning for creativity
|
|
136
|
+
maxTokens: 4000,
|
|
137
|
+
temperature: 0.9,
|
|
138
|
+
},
|
|
139
|
+
grok_architect: {
|
|
140
|
+
model: GROK_MODELS._4_FAST_REASONING, // New: Architecture needs reasoning
|
|
141
|
+
maxTokens: 4000,
|
|
142
|
+
temperature: 0.6,
|
|
143
|
+
},
|
|
144
|
+
grok_debug: {
|
|
145
|
+
model: GROK_MODELS.CODE_FAST, // New: Use code specialist for debugging
|
|
146
|
+
maxTokens: 3000,
|
|
147
|
+
temperature: 0.3,
|
|
148
|
+
},
|
|
149
|
+
// Qwen tools (via OpenRouter)
|
|
150
|
+
qwen_coder: {
|
|
151
|
+
maxTokens: 4000,
|
|
152
|
+
temperature: 0.5,
|
|
153
|
+
},
|
|
154
|
+
// Kimi tools (via OpenRouter)
|
|
155
|
+
kimi_thinking: {
|
|
156
|
+
model: KIMI_MODELS.K2_THINKING,
|
|
157
|
+
maxTokens: 16000, // Large for detailed reasoning chains
|
|
158
|
+
temperature: 0.7, // Higher for creative reasoning
|
|
159
|
+
},
|
|
160
|
+
// Meta tools (think, focus, code_reviewer, etc.)
|
|
161
|
+
think: {
|
|
162
|
+
model: GPT5_MODELS.MINI,
|
|
163
|
+
maxTokens: 500,
|
|
164
|
+
temperature: 0.7,
|
|
165
|
+
},
|
|
166
|
+
focus: {
|
|
167
|
+
model: GPT5_MODELS.MINI,
|
|
168
|
+
maxTokens: 2000,
|
|
169
|
+
temperature: 0.8,
|
|
170
|
+
},
|
|
171
|
+
code_reviewer: {
|
|
172
|
+
model: GPT5_MODELS.MINI,
|
|
173
|
+
maxTokens: 2000,
|
|
174
|
+
temperature: 0.5,
|
|
175
|
+
},
|
|
176
|
+
test_architect: {
|
|
177
|
+
model: GPT5_MODELS.MINI,
|
|
178
|
+
maxTokens: 2000,
|
|
179
|
+
temperature: 0.6,
|
|
180
|
+
},
|
|
181
|
+
documentation_writer: {
|
|
182
|
+
model: GPT5_MODELS.MINI,
|
|
183
|
+
maxTokens: 2000,
|
|
184
|
+
temperature: 0.7,
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
// Default tool to use in workflows if not specified
|
|
188
|
+
export const DEFAULT_WORKFLOW_TOOL = "gpt5_mini";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Selection Configuration
|
|
3
|
+
*
|
|
4
|
+
* Provides configurable model selection for Scout, Challenger, and Verifier tools
|
|
5
|
+
* with smart defaults that balance cost and quality.
|
|
6
|
+
*
|
|
7
|
+
* Environment variables allow users to override defaults via Claude Desktop config.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Get Scout model configuration
|
|
11
|
+
*
|
|
12
|
+
* Defaults:
|
|
13
|
+
* - quick_scout: Flash + gpt-5-mini (speed + cost efficient)
|
|
14
|
+
* - research_scout: Pro + gpt-5-mini (quality + cost balance)
|
|
15
|
+
*/
|
|
16
|
+
export function getScoutModels() {
|
|
17
|
+
const quick = process.env.SCOUT_QUICK_MODELS?.split(',').map(m => m.trim()) ||
|
|
18
|
+
['qwen/qwen3-coder-plus', 'gemini-2.5-flash', 'gpt-5-mini'];
|
|
19
|
+
const research = process.env.SCOUT_RESEARCH_MODELS?.split(',').map(m => m.trim()) ||
|
|
20
|
+
['qwen/qwen3-coder-plus', 'gemini-2.5-pro', 'gpt-5-mini'];
|
|
21
|
+
return { quick, research };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get Challenger model configuration
|
|
25
|
+
*
|
|
26
|
+
* Defaults: Pro + gpt-5-mini (quality for critical analysis, cost efficient)
|
|
27
|
+
*/
|
|
28
|
+
export function getChallengerModels() {
|
|
29
|
+
return process.env.CHALLENGER_MODELS?.split(',').map(m => m.trim()) ||
|
|
30
|
+
['qwen/qwen3-coder-plus', 'gemini-2.5-pro', 'gpt-5-mini'];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get Verifier model configuration
|
|
34
|
+
*
|
|
35
|
+
* Defaults:
|
|
36
|
+
* - quick_verify: Flash + gpt-5-mini (fast checks, cost efficient)
|
|
37
|
+
* - standard modes: Pro + gpt-5-mini (quality + cost balance)
|
|
38
|
+
* - deep_verify: Pro + gpt-5 (maximum quality for critical verification)
|
|
39
|
+
*/
|
|
40
|
+
export function getVerifierModels() {
|
|
41
|
+
const quick = process.env.VERIFIER_QUICK_MODELS?.split(',').map(m => m.trim()) ||
|
|
42
|
+
['qwen/qwen3-coder-plus', 'gemini-2.5-flash', 'gpt-5-mini'];
|
|
43
|
+
const deep = process.env.VERIFIER_DEEP_MODELS?.split(',').map(m => m.trim()) ||
|
|
44
|
+
['qwen/qwen3-coder-plus', 'gemini-2.5-pro', 'gpt-5'];
|
|
45
|
+
const standard = process.env.VERIFIER_STANDARD_MODELS?.split(',').map(m => m.trim()) ||
|
|
46
|
+
['qwen/qwen3-coder-plus', 'gemini-2.5-pro', 'gpt-5-mini'];
|
|
47
|
+
return { quick, deep, standard };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get default fallback models (used when variant has no specific config)
|
|
51
|
+
*
|
|
52
|
+
* Default: Pro + gpt-5-mini (balanced quality and cost)
|
|
53
|
+
*/
|
|
54
|
+
export function getDefaultModels() {
|
|
55
|
+
return process.env.DEFAULT_MODELS?.split(',').map(m => m.trim()) ||
|
|
56
|
+
['qwen/qwen3-coder-plus', 'gemini-2.5-pro', 'gpt-5-mini'];
|
|
57
|
+
}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Preferences Configuration
|
|
3
|
+
* Allows users to set their preferred models based on available API tokens
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Default model configurations with user preferences
|
|
7
|
+
*/
|
|
8
|
+
export class ModelPreferencesManager {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.preferences = {};
|
|
11
|
+
this.availableModels = new Map();
|
|
12
|
+
this.loadPreferences();
|
|
13
|
+
this.initializeModels();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Load preferences from environment variables
|
|
17
|
+
*/
|
|
18
|
+
loadPreferences() {
|
|
19
|
+
// Check for user preferences in environment
|
|
20
|
+
const primaryModel = process.env.PRIMARY_REASONING_MODEL;
|
|
21
|
+
const backupModels = process.env.BACKUP_REASONING_MODELS?.split(",").map((m) => m.trim());
|
|
22
|
+
const enableExpensive = process.env.ENABLE_EXPENSIVE_MODELS === "true";
|
|
23
|
+
const preferGrok = process.env.PREFER_GROK === "true";
|
|
24
|
+
const preferO3 = process.env.PREFER_O3 === "true";
|
|
25
|
+
const defaultBackups = ["gpt5_mini", "gpt41_mini", "gpt5"];
|
|
26
|
+
this.preferences = {
|
|
27
|
+
primaryReasoning: primaryModel || "gpt5",
|
|
28
|
+
backupReasoning: backupModels && backupModels.length > 0 ? backupModels : defaultBackups,
|
|
29
|
+
primaryResearch: process.env.PRIMARY_RESEARCH_MODEL,
|
|
30
|
+
primaryAnalysis: process.env.PRIMARY_ANALYSIS_MODEL,
|
|
31
|
+
enableExpensiveModels: enableExpensive,
|
|
32
|
+
modelOverrides: {},
|
|
33
|
+
};
|
|
34
|
+
// Handle specific model preferences
|
|
35
|
+
if (preferGrok) {
|
|
36
|
+
this.preferences.primaryReasoning = "grok_heavy";
|
|
37
|
+
this.preferences.enableExpensiveModels = true;
|
|
38
|
+
}
|
|
39
|
+
if (preferO3) {
|
|
40
|
+
this.preferences.primaryReasoning = "openai_gpt5_reason";
|
|
41
|
+
this.preferences.enableExpensiveModels = true;
|
|
42
|
+
}
|
|
43
|
+
// Load model-specific overrides from environment
|
|
44
|
+
this.loadModelOverrides();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Load model-specific overrides
|
|
48
|
+
*/
|
|
49
|
+
loadModelOverrides() {
|
|
50
|
+
// GPT-5 configuration (assumes OpenAI key)
|
|
51
|
+
if (process.env.OPENAI_API_KEY) {
|
|
52
|
+
this.preferences.modelOverrides["gpt5"] = {
|
|
53
|
+
enabled: process.env.DISABLE_GPT5 !== "true",
|
|
54
|
+
priority: parseInt(process.env.GPT5_PRIORITY || "0"),
|
|
55
|
+
maxTokens: parseInt(process.env.GPT5_MAX_TOKENS || "8000"),
|
|
56
|
+
costLimit: parseFloat(process.env.GPT5_COST_LIMIT || "5.0"),
|
|
57
|
+
};
|
|
58
|
+
this.preferences.modelOverrides["gpt5_mini"] = {
|
|
59
|
+
enabled: process.env.DISABLE_GPT5_MINI === "true" ? false : true,
|
|
60
|
+
priority: parseInt(process.env.GPT5_MINI_PRIORITY || "1"),
|
|
61
|
+
maxTokens: parseInt(process.env.GPT5_MINI_MAX_TOKENS || "6000"),
|
|
62
|
+
costLimit: parseFloat(process.env.GPT5_MINI_COST_LIMIT || "2.5"),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Grok configuration
|
|
66
|
+
if (process.env.GROK_API_KEY) {
|
|
67
|
+
this.preferences.modelOverrides["grok_reason"] = {
|
|
68
|
+
enabled: true,
|
|
69
|
+
priority: parseInt(process.env.GROK_PRIORITY || "2"),
|
|
70
|
+
maxTokens: parseInt(process.env.GROK_MAX_TOKENS || "100000"),
|
|
71
|
+
costLimit: parseFloat(process.env.GROK_COST_LIMIT || "1.0"),
|
|
72
|
+
};
|
|
73
|
+
this.preferences.modelOverrides["grok_heavy"] = {
|
|
74
|
+
enabled: process.env.ENABLE_GROK_HEAVY === "true",
|
|
75
|
+
priority: parseInt(process.env.GROK_HEAVY_PRIORITY || "1"),
|
|
76
|
+
maxTokens: parseInt(process.env.GROK_HEAVY_MAX_TOKENS || "256000"),
|
|
77
|
+
costLimit: parseFloat(process.env.GROK_HEAVY_COST_LIMIT || "5.0"),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// GPT-5 reasoning configuration
|
|
81
|
+
if (process.env.OPENAI_API_KEY) {
|
|
82
|
+
this.preferences.modelOverrides["gpt5_reason"] = {
|
|
83
|
+
enabled: process.env.ENABLE_GPT5 === "true",
|
|
84
|
+
priority: parseInt(process.env.GPT5_REASON_PRIORITY || "1"),
|
|
85
|
+
maxTokens: parseInt(process.env.GPT5_REASON_MAX_TOKENS || "100000"),
|
|
86
|
+
costLimit: parseFloat(process.env.GPT5_REASON_COST_LIMIT || "2.0"),
|
|
87
|
+
};
|
|
88
|
+
this.preferences.modelOverrides["gpt5_mini_reason"] = {
|
|
89
|
+
enabled: true, // Always enabled, no confirmation needed
|
|
90
|
+
priority: parseInt(process.env.GPT5_MINI_REASON_PRIORITY || "2"),
|
|
91
|
+
maxTokens: parseInt(process.env.GPT5_MINI_REASON_MAX_TOKENS || "128000"),
|
|
92
|
+
costLimit: parseFloat(process.env.GPT5_MINI_REASON_COST_LIMIT || "1.5"),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// DeepSeek R1
|
|
96
|
+
if (process.env.DEEPSEEK_API_KEY) {
|
|
97
|
+
this.preferences.modelOverrides["deepseek_r1"] = {
|
|
98
|
+
enabled: process.env.ENABLE_DEEPSEEK_R1 === "true",
|
|
99
|
+
priority: parseInt(process.env.DEEPSEEK_R1_PRIORITY || "3"),
|
|
100
|
+
maxTokens: parseInt(process.env.DEEPSEEK_R1_MAX_TOKENS || "64000"),
|
|
101
|
+
costLimit: parseFloat(process.env.DEEPSEEK_R1_COST_LIMIT || "0.5"),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Qwen models via OpenRouter
|
|
105
|
+
if (process.env.OPENROUTER_API_KEY) {
|
|
106
|
+
this.preferences.modelOverrides["qwen_coder"] = {
|
|
107
|
+
enabled: true,
|
|
108
|
+
priority: parseInt(process.env.QWEN_CODER_PRIORITY || "4"),
|
|
109
|
+
maxTokens: parseInt(process.env.QWEN_CODER_MAX_TOKENS || "32000"),
|
|
110
|
+
costLimit: parseFloat(process.env.QWEN_CODER_COST_LIMIT || "0.3"),
|
|
111
|
+
};
|
|
112
|
+
this.preferences.modelOverrides["qwq_reason"] = {
|
|
113
|
+
enabled: true,
|
|
114
|
+
priority: parseInt(process.env.QWQ_PRIORITY || "3"),
|
|
115
|
+
maxTokens: parseInt(process.env.QWQ_MAX_TOKENS || "32000"),
|
|
116
|
+
costLimit: parseFloat(process.env.QWQ_COST_LIMIT || "0.2"),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Initialize available models based on API keys
|
|
122
|
+
*/
|
|
123
|
+
initializeModels() {
|
|
124
|
+
// Check which APIs are available
|
|
125
|
+
const hasGrok = !!process.env.GROK_API_KEY;
|
|
126
|
+
const hasOpenAI = !!process.env.OPENAI_API_KEY;
|
|
127
|
+
const hasGemini = !!process.env.GOOGLE_API_KEY;
|
|
128
|
+
const hasPerplexity = !!process.env.PERPLEXITY_API_KEY;
|
|
129
|
+
const hasOpenRouter = !!process.env.OPENROUTER_API_KEY;
|
|
130
|
+
const hasDeepSeek = !!process.env.DEEPSEEK_API_KEY;
|
|
131
|
+
// Set up available models with default configs
|
|
132
|
+
if (hasGrok) {
|
|
133
|
+
this.availableModels.set("grok_reason", {
|
|
134
|
+
enabled: true,
|
|
135
|
+
priority: 5,
|
|
136
|
+
});
|
|
137
|
+
this.availableModels.set("grok_heavy", {
|
|
138
|
+
enabled: this.preferences.enableExpensiveModels || false,
|
|
139
|
+
priority: 2,
|
|
140
|
+
});
|
|
141
|
+
this.availableModels.set("grok_code", {
|
|
142
|
+
enabled: true,
|
|
143
|
+
priority: 4,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (hasOpenAI) {
|
|
147
|
+
const gpt5Override = this.preferences.modelOverrides?.["gpt5"];
|
|
148
|
+
this.availableModels.set("gpt5", {
|
|
149
|
+
enabled: gpt5Override?.enabled !== false,
|
|
150
|
+
priority: gpt5Override?.priority ?? 0,
|
|
151
|
+
maxTokens: gpt5Override?.maxTokens,
|
|
152
|
+
costLimit: gpt5Override?.costLimit,
|
|
153
|
+
});
|
|
154
|
+
const gpt5MiniOverride = this.preferences.modelOverrides?.["gpt5_mini"];
|
|
155
|
+
this.availableModels.set("gpt5_mini", {
|
|
156
|
+
enabled: gpt5MiniOverride?.enabled !== false,
|
|
157
|
+
priority: gpt5MiniOverride?.priority ?? 1,
|
|
158
|
+
maxTokens: gpt5MiniOverride?.maxTokens,
|
|
159
|
+
costLimit: gpt5MiniOverride?.costLimit,
|
|
160
|
+
});
|
|
161
|
+
const gpt41Override = this.preferences.modelOverrides?.["gpt41_mini"];
|
|
162
|
+
this.availableModels.set("gpt41_mini", {
|
|
163
|
+
enabled: true,
|
|
164
|
+
priority: Math.max(gpt41Override?.priority ?? 4, 4),
|
|
165
|
+
maxTokens: gpt41Override?.maxTokens,
|
|
166
|
+
costLimit: gpt41Override?.costLimit,
|
|
167
|
+
});
|
|
168
|
+
// Removed deprecated gpt4o - use gpt5_mini instead
|
|
169
|
+
this.availableModels.set("gpt5_reason", {
|
|
170
|
+
enabled: this.preferences.enableExpensiveModels || false,
|
|
171
|
+
priority: 2,
|
|
172
|
+
});
|
|
173
|
+
this.availableModels.set("gpt5_mini_reason", {
|
|
174
|
+
enabled: true, // Always available
|
|
175
|
+
priority: 3,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
if (hasGemini) {
|
|
179
|
+
this.availableModels.set("gemini_25_pro", {
|
|
180
|
+
enabled: true,
|
|
181
|
+
priority: 6,
|
|
182
|
+
});
|
|
183
|
+
this.availableModels.set("gemini_brainstorm", {
|
|
184
|
+
enabled: true,
|
|
185
|
+
priority: 7,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
if (hasDeepSeek) {
|
|
189
|
+
this.availableModels.set("deepseek_r1", {
|
|
190
|
+
enabled: this.preferences.enableExpensiveModels || false,
|
|
191
|
+
priority: 3,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (hasOpenRouter) {
|
|
195
|
+
this.availableModels.set("qwen_coder", {
|
|
196
|
+
enabled: true,
|
|
197
|
+
priority: 5,
|
|
198
|
+
});
|
|
199
|
+
this.availableModels.set("qwq_reason", {
|
|
200
|
+
enabled: true,
|
|
201
|
+
priority: 4,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// Apply user overrides
|
|
205
|
+
for (const [model, config] of Object.entries(this.preferences.modelOverrides || {})) {
|
|
206
|
+
if (this.availableModels.has(model)) {
|
|
207
|
+
this.availableModels.set(model, {
|
|
208
|
+
...this.availableModels.get(model),
|
|
209
|
+
...config,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Ensure primary reasoning defaults to GPT-5 when available
|
|
214
|
+
if (!this.preferences.primaryReasoning &&
|
|
215
|
+
this.availableModels.get("gpt5")?.enabled) {
|
|
216
|
+
this.preferences.primaryReasoning = "gpt5";
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get the best model for a specific task
|
|
221
|
+
*/
|
|
222
|
+
getBestModelForTask(taskType, allowExpensive = false) {
|
|
223
|
+
// Check for explicit preferences first
|
|
224
|
+
if (taskType === "reasoning" && this.preferences.primaryReasoning) {
|
|
225
|
+
const model = this.availableModels.get(this.preferences.primaryReasoning);
|
|
226
|
+
if (model?.enabled) {
|
|
227
|
+
return this.preferences.primaryReasoning;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (taskType === "research" && this.preferences.primaryResearch) {
|
|
231
|
+
const model = this.availableModels.get(this.preferences.primaryResearch);
|
|
232
|
+
if (model?.enabled) {
|
|
233
|
+
return this.preferences.primaryResearch;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Find best available model by priority
|
|
237
|
+
const candidates = [];
|
|
238
|
+
for (const [modelId, config] of this.availableModels.entries()) {
|
|
239
|
+
if (!config.enabled)
|
|
240
|
+
continue;
|
|
241
|
+
// Skip expensive models unless allowed
|
|
242
|
+
if (!allowExpensive && !this.preferences.enableExpensiveModels) {
|
|
243
|
+
const expensiveModels = [
|
|
244
|
+
"grok_heavy",
|
|
245
|
+
"gpt5_reason",
|
|
246
|
+
"deepseek_r1",
|
|
247
|
+
];
|
|
248
|
+
if (expensiveModels.includes(modelId))
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
// Filter by task type
|
|
252
|
+
if (taskType === "reasoning") {
|
|
253
|
+
if (modelId.includes("reason") ||
|
|
254
|
+
modelId.includes("think") ||
|
|
255
|
+
modelId.includes("gpt5") ||
|
|
256
|
+
modelId === "grok_heavy" ||
|
|
257
|
+
modelId === "deepseek_r1") {
|
|
258
|
+
candidates.push([modelId, config]);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else if (taskType === "code") {
|
|
262
|
+
if (modelId.includes("code") || modelId.includes("coder")) {
|
|
263
|
+
candidates.push([modelId, config]);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else if (taskType === "research") {
|
|
267
|
+
if (modelId.includes("perplexity") ||
|
|
268
|
+
modelId.includes("scout") ||
|
|
269
|
+
modelId.includes("research")) {
|
|
270
|
+
candidates.push([modelId, config]);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
else if (taskType === "analysis") {
|
|
274
|
+
if (modelId.includes("analyze") ||
|
|
275
|
+
modelId.includes("gpt5") ||
|
|
276
|
+
modelId.includes("gemini")) {
|
|
277
|
+
candidates.push([modelId, config]);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Sort by priority (lower number = higher priority)
|
|
282
|
+
candidates.sort((a, b) => a[1].priority - b[1].priority);
|
|
283
|
+
return candidates.length > 0 ? candidates[0][0] : null;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Get fallback chain for a model
|
|
287
|
+
*/
|
|
288
|
+
getFallbackChain(primaryModel) {
|
|
289
|
+
const chain = [];
|
|
290
|
+
// Add user-specified backups first
|
|
291
|
+
if (this.preferences.backupReasoning) {
|
|
292
|
+
for (const backup of this.preferences.backupReasoning) {
|
|
293
|
+
const model = this.availableModels.get(backup);
|
|
294
|
+
if (model?.enabled && backup !== primaryModel) {
|
|
295
|
+
chain.push(backup);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// Ensure GPT-5 family fallback ordering is respected
|
|
300
|
+
const preferredFallbacks = ["gpt5_mini", "gpt41_mini", "gpt5"];
|
|
301
|
+
for (const candidate of preferredFallbacks) {
|
|
302
|
+
if (candidate !== primaryModel) {
|
|
303
|
+
const config = this.availableModels.get(candidate);
|
|
304
|
+
if (config?.enabled && !chain.includes(candidate)) {
|
|
305
|
+
chain.push(candidate);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Add automatic fallbacks based on availability and priority
|
|
310
|
+
const sortedModels = Array.from(this.availableModels.entries())
|
|
311
|
+
.filter(([id, config]) => config.enabled && id !== primaryModel)
|
|
312
|
+
.sort((a, b) => a[1].priority - b[1].priority)
|
|
313
|
+
.map(([id]) => id);
|
|
314
|
+
// Add top 3 alternatives not already in chain
|
|
315
|
+
for (const model of sortedModels) {
|
|
316
|
+
if (!chain.includes(model)) {
|
|
317
|
+
chain.push(model);
|
|
318
|
+
if (chain.length >= 3)
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return chain;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Check if a model is available and enabled
|
|
326
|
+
*/
|
|
327
|
+
isModelAvailable(modelId) {
|
|
328
|
+
const model = this.availableModels.get(modelId);
|
|
329
|
+
return model?.enabled || false;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Get model configuration
|
|
333
|
+
*/
|
|
334
|
+
getModelConfig(modelId) {
|
|
335
|
+
return this.availableModels.get(modelId) || null;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Update model preference at runtime
|
|
339
|
+
*/
|
|
340
|
+
setModelPreference(modelId, config) {
|
|
341
|
+
const existing = this.availableModels.get(modelId);
|
|
342
|
+
if (existing) {
|
|
343
|
+
this.availableModels.set(modelId, { ...existing, ...config });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get recommendations based on user's available APIs
|
|
348
|
+
*/
|
|
349
|
+
getRecommendations() {
|
|
350
|
+
const recommendations = [];
|
|
351
|
+
const hasGrok = !!process.env.GROK_API_KEY;
|
|
352
|
+
const hasOpenAI = !!process.env.OPENAI_API_KEY;
|
|
353
|
+
if (hasGrok && !this.preferences.enableExpensiveModels) {
|
|
354
|
+
recommendations.push("You have Grok API access. Enable ENABLE_EXPENSIVE_MODELS=true to use Grok Heavy (256k context).");
|
|
355
|
+
}
|
|
356
|
+
if (hasOpenAI && !this.isModelAvailable("gpt5_reason")) {
|
|
357
|
+
recommendations.push("You have OpenAI API access. Enable ENABLE_GPT5=true to use GPT-5 reasoning models.");
|
|
358
|
+
}
|
|
359
|
+
if (!this.preferences.primaryReasoning) {
|
|
360
|
+
const bestModel = this.getBestModelForTask("reasoning", true);
|
|
361
|
+
if (bestModel) {
|
|
362
|
+
recommendations.push(`Set PRIMARY_REASONING_MODEL=${bestModel} in .env for optimal performance.`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return recommendations;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Export current configuration for debugging
|
|
369
|
+
*/
|
|
370
|
+
exportConfiguration() {
|
|
371
|
+
return {
|
|
372
|
+
preferences: this.preferences,
|
|
373
|
+
availableModels: Array.from(this.availableModels.entries()).map(([id, config]) => ({
|
|
374
|
+
id,
|
|
375
|
+
config,
|
|
376
|
+
})),
|
|
377
|
+
recommendations: this.getRecommendations(),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
// Export singleton instance
|
|
382
|
+
export const modelPreferences = new ModelPreferencesManager();
|