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,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Integration
|
|
3
|
+
* Provides proper Claude reasoning capabilities instead of simple echo
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
// Check if we have Anthropic API key
|
|
7
|
+
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
|
8
|
+
export class ClaudeCodeIntegration {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.conversationHistory = [];
|
|
11
|
+
this.maxHistoryLength = 10;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Main execution method for Claude reasoning
|
|
15
|
+
*/
|
|
16
|
+
async executeThink(params) {
|
|
17
|
+
// Extract the actual prompt/thought
|
|
18
|
+
const input = params.thought || params.prompt || params.content || '';
|
|
19
|
+
// If we're running inside Claude Code MCP context
|
|
20
|
+
if (this.isRunningInClaudeCode()) {
|
|
21
|
+
return await this.useNativeClaudeReasoning(input, params);
|
|
22
|
+
}
|
|
23
|
+
// If we have Anthropic API key, use it
|
|
24
|
+
if (ANTHROPIC_API_KEY) {
|
|
25
|
+
return await this.callClaudeAPI(input, params);
|
|
26
|
+
}
|
|
27
|
+
// Fallback to structured reasoning
|
|
28
|
+
return await this.structuredReasoning(input, params);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if we're running inside Claude Code environment
|
|
32
|
+
*/
|
|
33
|
+
isRunningInClaudeCode() {
|
|
34
|
+
// Check for Claude Code environment markers
|
|
35
|
+
return !!(process.env.CLAUDE_CODE_SESSION ||
|
|
36
|
+
process.env.ANTHROPIC_SESSION_ID ||
|
|
37
|
+
process.env.CLAUDE_CODE_ACTIVE ||
|
|
38
|
+
process.env.CLAUDE_PROJECT_ROOT ||
|
|
39
|
+
process.env.CLAUDE_WORKSPACE ||
|
|
40
|
+
(process.env.USER?.includes('claude') && process.env.HOME?.includes('claude')));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Use native Claude reasoning when running inside Claude Code
|
|
44
|
+
*/
|
|
45
|
+
async useNativeClaudeReasoning(input, params) {
|
|
46
|
+
// Since we're already inside Claude, we can provide structured reasoning
|
|
47
|
+
const mode = params.mode || 'analyze';
|
|
48
|
+
const reasoningPrompt = this.buildReasoningPrompt(input, mode, params.context);
|
|
49
|
+
// Add to conversation history
|
|
50
|
+
this.addToHistory({ role: 'user', content: input });
|
|
51
|
+
// Generate structured response based on mode
|
|
52
|
+
const response = await this.generateStructuredResponse(reasoningPrompt, mode);
|
|
53
|
+
// Add to history
|
|
54
|
+
this.addToHistory({ role: 'assistant', content: response });
|
|
55
|
+
return response;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Call Anthropic API directly if available
|
|
59
|
+
*/
|
|
60
|
+
async callClaudeAPI(input, params) {
|
|
61
|
+
if (!ANTHROPIC_API_KEY) {
|
|
62
|
+
return this.structuredReasoning(input, params);
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
'x-api-key': ANTHROPIC_API_KEY,
|
|
70
|
+
'anthropic-version': '2023-06-01'
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify({
|
|
73
|
+
model: 'claude-3-opus-20240229',
|
|
74
|
+
max_tokens: 2000,
|
|
75
|
+
messages: [
|
|
76
|
+
{
|
|
77
|
+
role: 'user',
|
|
78
|
+
content: this.buildReasoningPrompt(input, params.mode || 'analyze', params.context)
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
temperature: 0.7
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
throw new Error(`Anthropic API error: ${response.statusText}`);
|
|
86
|
+
}
|
|
87
|
+
const data = await response.json();
|
|
88
|
+
return data.content[0].text;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error('Claude API error:', error);
|
|
92
|
+
// Fallback to structured reasoning
|
|
93
|
+
return this.structuredReasoning(input, params);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Structured reasoning fallback when no API is available
|
|
98
|
+
*/
|
|
99
|
+
async structuredReasoning(input, params) {
|
|
100
|
+
const mode = params.mode || 'analyze';
|
|
101
|
+
const context = params.context || {};
|
|
102
|
+
// Multi-stage reasoning pipeline
|
|
103
|
+
const analysis = await this.analyzeContext(input, context);
|
|
104
|
+
const plan = await this.generatePlan(input, analysis, mode);
|
|
105
|
+
const synthesis = await this.synthesize(plan, context);
|
|
106
|
+
return this.formatResponse(synthesis, mode);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Analyze the context and input
|
|
110
|
+
*/
|
|
111
|
+
async analyzeContext(input, context) {
|
|
112
|
+
const steps = [];
|
|
113
|
+
// Step 1: Parse input intent
|
|
114
|
+
steps.push({
|
|
115
|
+
step: 1,
|
|
116
|
+
type: 'intent_analysis',
|
|
117
|
+
content: `Analyzing request: "${input.substring(0, 100)}..."`,
|
|
118
|
+
confidence: 0.85
|
|
119
|
+
});
|
|
120
|
+
// Step 2: Context evaluation
|
|
121
|
+
if (context && Object.keys(context).length > 0) {
|
|
122
|
+
steps.push({
|
|
123
|
+
step: 2,
|
|
124
|
+
type: 'context_evaluation',
|
|
125
|
+
content: `Evaluating context with ${Object.keys(context).length} parameters`,
|
|
126
|
+
confidence: 0.9
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// Step 3: Identify key components
|
|
130
|
+
const keyComponents = this.extractKeyComponents(input);
|
|
131
|
+
steps.push({
|
|
132
|
+
step: 3,
|
|
133
|
+
type: 'component_identification',
|
|
134
|
+
content: `Identified key components: ${keyComponents.join(', ')}`,
|
|
135
|
+
confidence: 0.8
|
|
136
|
+
});
|
|
137
|
+
return steps;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Generate a plan based on analysis
|
|
141
|
+
*/
|
|
142
|
+
async generatePlan(input, analysis, mode) {
|
|
143
|
+
const steps = [...analysis];
|
|
144
|
+
// Add planning steps based on mode
|
|
145
|
+
switch (mode) {
|
|
146
|
+
case 'analyze':
|
|
147
|
+
steps.push({
|
|
148
|
+
step: steps.length + 1,
|
|
149
|
+
type: 'analysis_plan',
|
|
150
|
+
content: 'Breaking down the problem into analytical components',
|
|
151
|
+
confidence: 0.85
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
case 'plan':
|
|
155
|
+
steps.push({
|
|
156
|
+
step: steps.length + 1,
|
|
157
|
+
type: 'execution_plan',
|
|
158
|
+
content: 'Creating step-by-step execution strategy',
|
|
159
|
+
confidence: 0.9
|
|
160
|
+
});
|
|
161
|
+
break;
|
|
162
|
+
case 'synthesize':
|
|
163
|
+
steps.push({
|
|
164
|
+
step: steps.length + 1,
|
|
165
|
+
type: 'synthesis_plan',
|
|
166
|
+
content: 'Combining insights from multiple perspectives',
|
|
167
|
+
confidence: 0.85
|
|
168
|
+
});
|
|
169
|
+
break;
|
|
170
|
+
case 'reflect':
|
|
171
|
+
steps.push({
|
|
172
|
+
step: steps.length + 1,
|
|
173
|
+
type: 'reflection_plan',
|
|
174
|
+
content: 'Evaluating outcomes and learning from results',
|
|
175
|
+
confidence: 0.8
|
|
176
|
+
});
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
return steps;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Synthesize the final response
|
|
183
|
+
*/
|
|
184
|
+
async synthesize(plan, context) {
|
|
185
|
+
const synthesis = this.combinePlanSteps(plan);
|
|
186
|
+
return {
|
|
187
|
+
reasoning: plan,
|
|
188
|
+
synthesis,
|
|
189
|
+
confidence: this.calculateConfidence(plan)
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Format the response based on mode
|
|
194
|
+
*/
|
|
195
|
+
formatResponse(result, mode) {
|
|
196
|
+
const prefix = this.getModePrefix(mode);
|
|
197
|
+
let response = `${prefix}\n\n`;
|
|
198
|
+
// Add reasoning steps if verbose
|
|
199
|
+
if (process.env.VERBOSE_REASONING === 'true') {
|
|
200
|
+
response += '## Reasoning Steps:\n';
|
|
201
|
+
result.reasoning.forEach(step => {
|
|
202
|
+
response += `${step.step}. [${step.type}] ${step.content}\n`;
|
|
203
|
+
});
|
|
204
|
+
response += '\n';
|
|
205
|
+
}
|
|
206
|
+
// Add synthesis
|
|
207
|
+
response += `## Response:\n${result.synthesis}\n`;
|
|
208
|
+
// Add confidence if relevant
|
|
209
|
+
if (result.confidence < 0.7) {
|
|
210
|
+
response += `\n*Note: Lower confidence (${(result.confidence * 100).toFixed(0)}%) - consider additional validation*`;
|
|
211
|
+
}
|
|
212
|
+
return response;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Build reasoning prompt based on mode and context
|
|
216
|
+
*/
|
|
217
|
+
buildReasoningPrompt(input, mode, context) {
|
|
218
|
+
let prompt = '';
|
|
219
|
+
switch (mode) {
|
|
220
|
+
case 'analyze':
|
|
221
|
+
prompt = `Analyze the following request and provide a detailed breakdown:\n"${input}"`;
|
|
222
|
+
break;
|
|
223
|
+
case 'plan':
|
|
224
|
+
prompt = `Create a comprehensive plan for the following objective:\n"${input}"`;
|
|
225
|
+
break;
|
|
226
|
+
case 'synthesize':
|
|
227
|
+
prompt = `Synthesize insights and create a unified response for:\n"${input}"`;
|
|
228
|
+
break;
|
|
229
|
+
case 'reflect':
|
|
230
|
+
prompt = `Reflect on the following and provide insights:\n"${input}"`;
|
|
231
|
+
break;
|
|
232
|
+
default:
|
|
233
|
+
prompt = `Process the following request:\n"${input}"`;
|
|
234
|
+
}
|
|
235
|
+
if (context) {
|
|
236
|
+
prompt += `\n\nContext:\n${JSON.stringify(context, null, 2)}`;
|
|
237
|
+
}
|
|
238
|
+
if (this.conversationHistory.length > 0) {
|
|
239
|
+
prompt += '\n\nRecent conversation history:\n';
|
|
240
|
+
this.conversationHistory.slice(-3).forEach(msg => {
|
|
241
|
+
prompt += `${msg.role}: ${msg.content.substring(0, 200)}...\n`;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return prompt;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Generate structured response based on mode
|
|
248
|
+
*/
|
|
249
|
+
async generateStructuredResponse(prompt, mode) {
|
|
250
|
+
// This method generates a structured response when running in Claude Code
|
|
251
|
+
const response = {
|
|
252
|
+
mode,
|
|
253
|
+
timestamp: new Date().toISOString(),
|
|
254
|
+
analysis: this.performAnalysis(prompt),
|
|
255
|
+
recommendations: this.generateRecommendations(prompt, mode),
|
|
256
|
+
implementation: mode === 'plan' ? this.generateImplementationSteps(prompt) : undefined,
|
|
257
|
+
synthesis: this.generateSynthesis(prompt, mode)
|
|
258
|
+
};
|
|
259
|
+
return this.formatStructuredResponse(response);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Helper methods
|
|
263
|
+
*/
|
|
264
|
+
extractKeyComponents(input) {
|
|
265
|
+
// Simple keyword extraction
|
|
266
|
+
const keywords = input.toLowerCase().match(/\b(\w{4,})\b/g) || [];
|
|
267
|
+
return [...new Set(keywords)].slice(0, 5);
|
|
268
|
+
}
|
|
269
|
+
combinePlanSteps(steps) {
|
|
270
|
+
const mainSteps = steps.filter(s => (s.confidence || 0) >= 0.8);
|
|
271
|
+
return mainSteps.map(s => s.content).join('. ');
|
|
272
|
+
}
|
|
273
|
+
calculateConfidence(steps) {
|
|
274
|
+
if (steps.length === 0)
|
|
275
|
+
return 0.5;
|
|
276
|
+
const sum = steps.reduce((acc, step) => acc + (step.confidence || 0.5), 0);
|
|
277
|
+
return sum / steps.length;
|
|
278
|
+
}
|
|
279
|
+
getModePrefix(mode) {
|
|
280
|
+
const prefixes = {
|
|
281
|
+
analyze: '🔍 **Analysis**',
|
|
282
|
+
plan: '📋 **Planning**',
|
|
283
|
+
synthesize: '🔄 **Synthesis**',
|
|
284
|
+
reflect: '💭 **Reflection**'
|
|
285
|
+
};
|
|
286
|
+
return prefixes[mode] || '🤔 **Reasoning**';
|
|
287
|
+
}
|
|
288
|
+
addToHistory(message) {
|
|
289
|
+
this.conversationHistory.push(message);
|
|
290
|
+
if (this.conversationHistory.length > this.maxHistoryLength) {
|
|
291
|
+
this.conversationHistory.shift();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
performAnalysis(prompt) {
|
|
295
|
+
return `Analyzing the request structure and identifying key requirements...`;
|
|
296
|
+
}
|
|
297
|
+
generateRecommendations(prompt, mode) {
|
|
298
|
+
return [
|
|
299
|
+
'Consider breaking down complex tasks into smaller components',
|
|
300
|
+
'Validate assumptions with concrete examples',
|
|
301
|
+
'Ensure alignment with project goals'
|
|
302
|
+
];
|
|
303
|
+
}
|
|
304
|
+
generateImplementationSteps(prompt) {
|
|
305
|
+
return [
|
|
306
|
+
'Initialize required components',
|
|
307
|
+
'Set up configuration and dependencies',
|
|
308
|
+
'Implement core functionality',
|
|
309
|
+
'Add error handling and validation',
|
|
310
|
+
'Test and refine'
|
|
311
|
+
];
|
|
312
|
+
}
|
|
313
|
+
generateSynthesis(prompt, mode) {
|
|
314
|
+
return `Based on the analysis, the recommended approach involves systematic implementation with iterative refinement.`;
|
|
315
|
+
}
|
|
316
|
+
formatStructuredResponse(response) {
|
|
317
|
+
let formatted = '';
|
|
318
|
+
if (response.analysis) {
|
|
319
|
+
formatted += `### Analysis\n${response.analysis}\n\n`;
|
|
320
|
+
}
|
|
321
|
+
if (response.recommendations && response.recommendations.length > 0) {
|
|
322
|
+
formatted += `### Recommendations\n`;
|
|
323
|
+
response.recommendations.forEach((rec, i) => {
|
|
324
|
+
formatted += `${i + 1}. ${rec}\n`;
|
|
325
|
+
});
|
|
326
|
+
formatted += '\n';
|
|
327
|
+
}
|
|
328
|
+
if (response.implementation && response.implementation.length > 0) {
|
|
329
|
+
formatted += `### Implementation Steps\n`;
|
|
330
|
+
response.implementation.forEach((step, i) => {
|
|
331
|
+
formatted += `${i + 1}. ${step}\n`;
|
|
332
|
+
});
|
|
333
|
+
formatted += '\n';
|
|
334
|
+
}
|
|
335
|
+
if (response.synthesis) {
|
|
336
|
+
formatted += `### Synthesis\n${response.synthesis}\n`;
|
|
337
|
+
}
|
|
338
|
+
return formatted;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Export the tool for MCP registration
|
|
342
|
+
export const claudeIntegrationTool = {
|
|
343
|
+
name: 'think',
|
|
344
|
+
description: 'Claude reasoning and analysis tool with structured thinking',
|
|
345
|
+
inputSchema: z.object({
|
|
346
|
+
thought: z.string().optional(),
|
|
347
|
+
prompt: z.string().optional(),
|
|
348
|
+
content: z.string().optional(),
|
|
349
|
+
context: z.any().optional(),
|
|
350
|
+
mode: z.enum(['analyze', 'plan', 'synthesize', 'reflect']).optional()
|
|
351
|
+
}),
|
|
352
|
+
execute: async (args, context) => {
|
|
353
|
+
const integration = new ClaudeCodeIntegration();
|
|
354
|
+
return await integration.executeThink(args);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Router
|
|
3
|
+
* Smart routing logic for AI requests
|
|
4
|
+
*/
|
|
5
|
+
import { detectEnvironment, getBestAvailableProvider, } from "./environment-detector.js";
|
|
6
|
+
import { callPerplexity } from "../perplexity-tools.js";
|
|
7
|
+
import { callGrok } from "../grok-tools.js";
|
|
8
|
+
import { callOpenAI } from "../openai-tools.js";
|
|
9
|
+
import { callGemini } from "../gemini-tools.js";
|
|
10
|
+
import * as fs from "fs/promises";
|
|
11
|
+
import * as path from "path";
|
|
12
|
+
export class AIRouter {
|
|
13
|
+
constructor(env) {
|
|
14
|
+
this.cache = new Map();
|
|
15
|
+
this.cacheTimeout = 5 * 60 * 1000; // 5 minutes
|
|
16
|
+
this.env = env || detectEnvironment();
|
|
17
|
+
}
|
|
18
|
+
async route(request) {
|
|
19
|
+
// Check cache first
|
|
20
|
+
const cacheKey = this.getCacheKey(request);
|
|
21
|
+
const cached = this.cache.get(cacheKey);
|
|
22
|
+
if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
|
|
23
|
+
return this.handleSave(cached.result, request.saveAs);
|
|
24
|
+
}
|
|
25
|
+
let result;
|
|
26
|
+
// Explicit provider requested
|
|
27
|
+
if (request.provider) {
|
|
28
|
+
result = await this.useProvider(request.provider, request);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Auto-select based on mode and model preference
|
|
32
|
+
result = await this.autoRoute(request);
|
|
33
|
+
}
|
|
34
|
+
// Cache the result
|
|
35
|
+
this.cache.set(cacheKey, { result, timestamp: Date.now() });
|
|
36
|
+
// Save if requested
|
|
37
|
+
return this.handleSave(result, request.saveAs);
|
|
38
|
+
}
|
|
39
|
+
async autoRoute(request) {
|
|
40
|
+
// Determine task type from mode
|
|
41
|
+
const taskType = this.getTaskType(request);
|
|
42
|
+
// Get best provider for task
|
|
43
|
+
const provider = getBestAvailableProvider(this.env, taskType);
|
|
44
|
+
if (!provider) {
|
|
45
|
+
return `[No AI providers available. Please set API keys in .env file]`;
|
|
46
|
+
}
|
|
47
|
+
return this.useProvider(provider, request);
|
|
48
|
+
}
|
|
49
|
+
async useProvider(provider, request) {
|
|
50
|
+
// Build messages array for the provider
|
|
51
|
+
const messages = [
|
|
52
|
+
{
|
|
53
|
+
role: "user",
|
|
54
|
+
content: request.prompt,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
try {
|
|
58
|
+
switch (provider) {
|
|
59
|
+
case "perplexity":
|
|
60
|
+
if (!this.env.apiKeys.perplexity) {
|
|
61
|
+
return "[Perplexity API key not configured]";
|
|
62
|
+
}
|
|
63
|
+
return await callPerplexity(messages);
|
|
64
|
+
case "grok":
|
|
65
|
+
if (!this.env.apiKeys.grok) {
|
|
66
|
+
return "[Grok API key not configured]";
|
|
67
|
+
}
|
|
68
|
+
return await callGrok(messages, undefined, request.temperature, request.maxTokens);
|
|
69
|
+
case "openai":
|
|
70
|
+
case "gpt5":
|
|
71
|
+
if (!this.env.apiKeys.openai) {
|
|
72
|
+
return "[OpenAI API key not configured]";
|
|
73
|
+
}
|
|
74
|
+
return await callOpenAI(messages, undefined, request.temperature, request.maxTokens);
|
|
75
|
+
case "gemini":
|
|
76
|
+
if (!this.env.apiKeys.gemini) {
|
|
77
|
+
return "[Gemini API key not configured]";
|
|
78
|
+
}
|
|
79
|
+
return await callGemini(request.prompt, undefined, undefined, request.temperature);
|
|
80
|
+
case "claude":
|
|
81
|
+
// In Claude Code, use native capabilities
|
|
82
|
+
if (this.env.type === "claude-code") {
|
|
83
|
+
return `[Using native Claude in Claude Code environment]\n${request.prompt}`;
|
|
84
|
+
}
|
|
85
|
+
if (!this.env.apiKeys.anthropic) {
|
|
86
|
+
return "[Anthropic API key not configured]";
|
|
87
|
+
}
|
|
88
|
+
// Would call Claude API here if implemented
|
|
89
|
+
return `[Claude API call would go here]`;
|
|
90
|
+
default:
|
|
91
|
+
return `[Unknown provider: ${provider}]`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
return `[Error calling ${provider}: ${error instanceof Error ? error.message : String(error)}]`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
getTaskType(request) {
|
|
99
|
+
if (request.mode === "reason")
|
|
100
|
+
return "reason";
|
|
101
|
+
if (request.mode === "analyze")
|
|
102
|
+
return "analyze";
|
|
103
|
+
if (request.mode === "generate")
|
|
104
|
+
return "code";
|
|
105
|
+
// Analyze prompt for hints
|
|
106
|
+
const prompt = request.prompt.toLowerCase();
|
|
107
|
+
if (prompt.includes("search") ||
|
|
108
|
+
prompt.includes("find") ||
|
|
109
|
+
prompt.includes("latest")) {
|
|
110
|
+
return "search";
|
|
111
|
+
}
|
|
112
|
+
if (prompt.includes("code") ||
|
|
113
|
+
prompt.includes("implement") ||
|
|
114
|
+
prompt.includes("function")) {
|
|
115
|
+
return "code";
|
|
116
|
+
}
|
|
117
|
+
if (prompt.includes("analyze") || prompt.includes("review")) {
|
|
118
|
+
return "analyze";
|
|
119
|
+
}
|
|
120
|
+
if (prompt.includes("brainstorm") ||
|
|
121
|
+
prompt.includes("ideas") ||
|
|
122
|
+
prompt.includes("creative")) {
|
|
123
|
+
return "brainstorm";
|
|
124
|
+
}
|
|
125
|
+
if (prompt.includes("reason") ||
|
|
126
|
+
prompt.includes("think") ||
|
|
127
|
+
prompt.includes("logic")) {
|
|
128
|
+
return "reason";
|
|
129
|
+
}
|
|
130
|
+
return "general";
|
|
131
|
+
}
|
|
132
|
+
getOpenAIModel(request) {
|
|
133
|
+
if (request.model === "gpt5" && this.env.availableProviders.gpt5) {
|
|
134
|
+
return "gpt-5-mini"; // Use mini by default for cost
|
|
135
|
+
}
|
|
136
|
+
if (request.model === "best") {
|
|
137
|
+
return "gpt-5";
|
|
138
|
+
}
|
|
139
|
+
if (request.model === "fast") {
|
|
140
|
+
return "gpt-5-mini";
|
|
141
|
+
}
|
|
142
|
+
if (request.model === "cheap") {
|
|
143
|
+
return "gpt-3.5-turbo";
|
|
144
|
+
}
|
|
145
|
+
// Default based on mode
|
|
146
|
+
if (request.mode === "reason") {
|
|
147
|
+
return "gpt-5";
|
|
148
|
+
}
|
|
149
|
+
if (request.mode === "analyze") {
|
|
150
|
+
return "gpt-5";
|
|
151
|
+
}
|
|
152
|
+
return "gpt-5-mini"; // Default
|
|
153
|
+
}
|
|
154
|
+
getCacheKey(request) {
|
|
155
|
+
return JSON.stringify({
|
|
156
|
+
prompt: request.prompt,
|
|
157
|
+
mode: request.mode,
|
|
158
|
+
model: request.model,
|
|
159
|
+
provider: request.provider,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async handleSave(result, saveAs) {
|
|
163
|
+
if (!saveAs)
|
|
164
|
+
return result;
|
|
165
|
+
try {
|
|
166
|
+
const filePath = path.resolve(saveAs);
|
|
167
|
+
await fs.writeFile(filePath, result, "utf8");
|
|
168
|
+
return `${result}\n\n[Saved to: ${filePath}]`;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return `${result}\n\n[Failed to save: ${error instanceof Error ? error.message : String(error)}]`;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal AI Tool
|
|
3
|
+
* Consolidated tool for all AI queries
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { AIRouter } from './ai-router.js';
|
|
7
|
+
/**
|
|
8
|
+
* Universal AI Tool
|
|
9
|
+
* Replaces: openai_*, gemini_*, grok_*, anthropic_*, and other model-specific tools
|
|
10
|
+
* Token cost: ~300 tokens (vs 2000+ for individual tools)
|
|
11
|
+
*/
|
|
12
|
+
export const aiTool = {
|
|
13
|
+
name: "ai",
|
|
14
|
+
description: "AI query", // Ultra-short description
|
|
15
|
+
parameters: z.object({
|
|
16
|
+
prompt: z.string(),
|
|
17
|
+
mode: z.enum(["chat", "analyze", "generate", "reason"])
|
|
18
|
+
.optional(),
|
|
19
|
+
model: z.enum(["auto", "best", "fast", "cheap", "gpt5", "gemini", "grok", "claude"])
|
|
20
|
+
.default("auto"),
|
|
21
|
+
provider: z.string()
|
|
22
|
+
.optional(),
|
|
23
|
+
temperature: z.number()
|
|
24
|
+
.min(0)
|
|
25
|
+
.max(2)
|
|
26
|
+
.optional(),
|
|
27
|
+
maxTokens: z.number()
|
|
28
|
+
.optional(),
|
|
29
|
+
saveAs: z.string()
|
|
30
|
+
.optional()
|
|
31
|
+
}),
|
|
32
|
+
execute: async (args, { log }) => {
|
|
33
|
+
const router = new AIRouter();
|
|
34
|
+
log?.info(`AI Tool: mode=${args.mode || 'auto'}, model=${args.model || 'auto'}, provider=${args.provider || 'auto'}`);
|
|
35
|
+
try {
|
|
36
|
+
const result = await router.route(args);
|
|
37
|
+
if (args.saveAs) {
|
|
38
|
+
log?.info(`Saved output to: ${args.saveAs}`);
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
44
|
+
log?.error(`AI Tool error: ${errorMessage}`);
|
|
45
|
+
return `[AI Tool Error: ${errorMessage}]`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidated Brainstorm Tool
|
|
3
|
+
* Creative ideation with single or multiple models
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { collaborativeOrchestrator } from '../../collaborative-orchestrator.js';
|
|
7
|
+
import { AIRouter } from './ai-router.js';
|
|
8
|
+
import * as fs from 'fs/promises';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
/**
|
|
11
|
+
* Unified Brainstorm Tool
|
|
12
|
+
* Replaces: openai_brainstorm, gemini_brainstorm, grok_brainstorm, and includes pingpong functionality
|
|
13
|
+
* Token cost: ~200 tokens (vs 1500+ for individual tools)
|
|
14
|
+
*/
|
|
15
|
+
export const brainstormTool = {
|
|
16
|
+
name: "brainstorm",
|
|
17
|
+
description: "Creative ideation", // Ultra-short description
|
|
18
|
+
parameters: z.object({
|
|
19
|
+
topic: z.string(),
|
|
20
|
+
approach: z.enum(["single", "multi", "debate", "build"])
|
|
21
|
+
.default("single"),
|
|
22
|
+
models: z.array(z.string())
|
|
23
|
+
.optional(),
|
|
24
|
+
rounds: z.number()
|
|
25
|
+
.min(1)
|
|
26
|
+
.max(10)
|
|
27
|
+
.default(3),
|
|
28
|
+
temperature: z.number()
|
|
29
|
+
.min(0)
|
|
30
|
+
.max(2)
|
|
31
|
+
.default(0.9),
|
|
32
|
+
saveAs: z.string()
|
|
33
|
+
.optional()
|
|
34
|
+
}),
|
|
35
|
+
execute: async (args, { log }) => {
|
|
36
|
+
log?.info(`Brainstorm: approach=${args.approach}, rounds=${args.rounds}`);
|
|
37
|
+
try {
|
|
38
|
+
let result;
|
|
39
|
+
if (args.approach === 'single') {
|
|
40
|
+
// Single model brainstorm
|
|
41
|
+
const router = new AIRouter();
|
|
42
|
+
result = await router.route({
|
|
43
|
+
prompt: `Brainstorm creative ideas for: ${args.topic}
|
|
44
|
+
|
|
45
|
+
Generate diverse, innovative ideas. Think outside the box.`,
|
|
46
|
+
mode: 'generate',
|
|
47
|
+
model: 'best',
|
|
48
|
+
temperature: args.temperature || 0.9
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Multi-model brainstorm using collaborative orchestrator
|
|
53
|
+
const style = args.approach === 'debate' ? 'debate' :
|
|
54
|
+
args.approach === 'build' ? 'build-upon' :
|
|
55
|
+
'collaborative';
|
|
56
|
+
result = await collaborativeOrchestrator.executeAdvancedPingPong({
|
|
57
|
+
problem: args.topic,
|
|
58
|
+
domain: 'architecture', // Default domain for brainstorming
|
|
59
|
+
rounds: args.rounds || 3,
|
|
60
|
+
models: args.models || ['gemini', 'grok', 'openai'],
|
|
61
|
+
temperature: args.temperature || 0.9,
|
|
62
|
+
maxTokensPerRound: 2000, // Default token limit per round
|
|
63
|
+
style: style,
|
|
64
|
+
saveSession: false
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Save if requested
|
|
68
|
+
if (args.saveAs) {
|
|
69
|
+
try {
|
|
70
|
+
const filePath = path.resolve(args.saveAs);
|
|
71
|
+
await fs.writeFile(filePath, result, 'utf8');
|
|
72
|
+
log?.info(`Saved brainstorm to: ${filePath}`);
|
|
73
|
+
return `${result}\n\n[Saved to: ${filePath}]`;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return `${result}\n\n[Failed to save: ${error instanceof Error ? error.message : String(error)}]`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
83
|
+
log?.error(`Brainstorm error: ${errorMessage}`);
|
|
84
|
+
return `[Brainstorm Error: ${errorMessage}]`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|