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.
Files changed (214) hide show
  1. package/.env.example +260 -0
  2. package/CHANGELOG.md +54 -0
  3. package/CODE_OF_CONDUCT.md +56 -0
  4. package/CONTRIBUTING.md +54 -0
  5. package/Dockerfile +36 -0
  6. package/LICENSE +644 -0
  7. package/README.md +201 -0
  8. package/SECURITY.md +95 -0
  9. package/dist/personality/komaai-expressions.js +12 -0
  10. package/dist/profiles/balanced.json +33 -0
  11. package/dist/profiles/code_focus.json +33 -0
  12. package/dist/profiles/full.json +33 -0
  13. package/dist/profiles/minimal.json +33 -0
  14. package/dist/profiles/research_power.json +33 -0
  15. package/dist/scripts/build-profiles.js +46 -0
  16. package/dist/src/application/services/focus/FocusModeRegistry.js +46 -0
  17. package/dist/src/application/services/focus/FocusTool.service.js +109 -0
  18. package/dist/src/application/services/focus/ModeRegistry.js +46 -0
  19. package/dist/src/application/services/focus/modes/focus-deep.mode.js +27 -0
  20. package/dist/src/application/services/focus/modes/status.mode.js +50 -0
  21. package/dist/src/application/services/focus/modes/tachibot-status.mode.js +50 -0
  22. package/dist/src/collaborative-orchestrator.js +391 -0
  23. package/dist/src/config/model-constants.js +188 -0
  24. package/dist/src/config/model-defaults.js +57 -0
  25. package/dist/src/config/model-preferences.js +382 -0
  26. package/dist/src/config/timeout-config.js +130 -0
  27. package/dist/src/config.js +173 -0
  28. package/dist/src/domain/interfaces/IFocusMode.js +5 -0
  29. package/dist/src/domain/interfaces/IProvider.js +6 -0
  30. package/dist/src/domain/interfaces/ITool.js +5 -0
  31. package/dist/src/focus-deep.js +245 -0
  32. package/dist/src/infrastructure/ascii/art/robots.ascii.js +16 -0
  33. package/dist/src/mcp-client.js +90 -0
  34. package/dist/src/memory/index.js +17 -0
  35. package/dist/src/memory/memory-config.js +135 -0
  36. package/dist/src/memory/memory-interface.js +174 -0
  37. package/dist/src/memory/memory-manager.js +383 -0
  38. package/dist/src/memory/providers/devlog-provider.js +385 -0
  39. package/dist/src/memory/providers/hybrid-provider.js +399 -0
  40. package/dist/src/memory/providers/local-provider.js +388 -0
  41. package/dist/src/memory/providers/mem0-provider.js +337 -0
  42. package/dist/src/modes/architect.js +477 -0
  43. package/dist/src/modes/auditor.js +362 -0
  44. package/dist/src/modes/challenger.js +841 -0
  45. package/dist/src/modes/code-reviewer.js +382 -0
  46. package/dist/src/modes/commit-guardian.js +424 -0
  47. package/dist/src/modes/documentation-writer.js +572 -0
  48. package/dist/src/modes/scout.js +587 -0
  49. package/dist/src/modes/shared/helpers/challenger-helpers.js +454 -0
  50. package/dist/src/modes/shared/helpers/index.js +17 -0
  51. package/dist/src/modes/shared/helpers/scout-helpers.js +270 -0
  52. package/dist/src/modes/shared/helpers/verifier-helpers.js +332 -0
  53. package/dist/src/modes/test-architect.js +767 -0
  54. package/dist/src/modes/verifier.js +378 -0
  55. package/dist/src/monitoring/performance-monitor.js +435 -0
  56. package/dist/src/optimization/batch-executor.js +121 -0
  57. package/dist/src/optimization/context-pruner.js +196 -0
  58. package/dist/src/optimization/cost-monitor.js +338 -0
  59. package/dist/src/optimization/index.js +65 -0
  60. package/dist/src/optimization/model-router.js +264 -0
  61. package/dist/src/optimization/result-cache.js +114 -0
  62. package/dist/src/optimization/token-optimizer.js +257 -0
  63. package/dist/src/optimization/token-tracker.js +118 -0
  64. package/dist/src/orchestrator-instructions.js +128 -0
  65. package/dist/src/orchestrator-lite.js +139 -0
  66. package/dist/src/orchestrator.js +191 -0
  67. package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionEngine.js +1 -0
  68. package/dist/src/orchestrators/collaborative/interfaces/IToolExecutionStrategy.js +5 -0
  69. package/dist/src/orchestrators/collaborative/interfaces/IVisualizationRenderer.js +1 -0
  70. package/dist/src/orchestrators/collaborative/registries/ModelProviderRegistry.js +95 -0
  71. package/dist/src/orchestrators/collaborative/registries/ToolAdapterRegistry.js +64 -0
  72. package/dist/src/orchestrators/collaborative/services/tool-execution/ToolExecutionService.js +502 -0
  73. package/dist/src/orchestrators/collaborative/services/visualization/VisualizationService.js +206 -0
  74. package/dist/src/orchestrators/collaborative/types/session-types.js +5 -0
  75. package/dist/src/profiles/balanced.js +37 -0
  76. package/dist/src/profiles/code_focus.js +37 -0
  77. package/dist/src/profiles/debug_intensive.js +59 -0
  78. package/dist/src/profiles/full.js +37 -0
  79. package/dist/src/profiles/minimal.js +37 -0
  80. package/dist/src/profiles/research_code.js +59 -0
  81. package/dist/src/profiles/research_power.js +37 -0
  82. package/dist/src/profiles/types.js +5 -0
  83. package/dist/src/profiles/workflow_builder.js +53 -0
  84. package/dist/src/prompt-engineer-lite.js +78 -0
  85. package/dist/src/prompt-engineer.js +399 -0
  86. package/dist/src/reasoning-chain.js +508 -0
  87. package/dist/src/sequential-thinking.js +291 -0
  88. package/dist/src/server-diagnostic.js +74 -0
  89. package/dist/src/server-raw.js +158 -0
  90. package/dist/src/server-simple.js +58 -0
  91. package/dist/src/server.js +514 -0
  92. package/dist/src/session/session-logger.js +617 -0
  93. package/dist/src/session/session-manager.js +571 -0
  94. package/dist/src/session/session-tools.js +400 -0
  95. package/dist/src/tools/advanced-modes.js +200 -0
  96. package/dist/src/tools/claude-integration.js +356 -0
  97. package/dist/src/tools/consolidated/ai-router.js +174 -0
  98. package/dist/src/tools/consolidated/ai-tool.js +48 -0
  99. package/dist/src/tools/consolidated/brainstorm-tool.js +87 -0
  100. package/dist/src/tools/consolidated/environment-detector.js +80 -0
  101. package/dist/src/tools/consolidated/index.js +50 -0
  102. package/dist/src/tools/consolidated/search-tool.js +110 -0
  103. package/dist/src/tools/consolidated/workflow-tool.js +238 -0
  104. package/dist/src/tools/gemini-tools.js +329 -0
  105. package/dist/src/tools/grok-enhanced.js +376 -0
  106. package/dist/src/tools/grok-tools.js +299 -0
  107. package/dist/src/tools/lmstudio-tools.js +223 -0
  108. package/dist/src/tools/openai-tools.js +498 -0
  109. package/dist/src/tools/openrouter-tools.js +317 -0
  110. package/dist/src/tools/optimized-wrapper.js +204 -0
  111. package/dist/src/tools/perplexity-tools.js +294 -0
  112. package/dist/src/tools/pingpong-tool.js +343 -0
  113. package/dist/src/tools/qwen-wrapper.js +74 -0
  114. package/dist/src/tools/tool-router.js +444 -0
  115. package/dist/src/tools/unified-ai-provider.js +260 -0
  116. package/dist/src/tools/workflow-runner.js +425 -0
  117. package/dist/src/tools/workflow-validator-tool.js +107 -0
  118. package/dist/src/types.js +23 -0
  119. package/dist/src/utils/input-validator.js +130 -0
  120. package/dist/src/utils/model-router.js +91 -0
  121. package/dist/src/utils/progress-stream.js +255 -0
  122. package/dist/src/utils/provider-router.js +88 -0
  123. package/dist/src/utils/smart-api-client.js +146 -0
  124. package/dist/src/utils/table-builder.js +218 -0
  125. package/dist/src/utils/timestamp-formatter.js +134 -0
  126. package/dist/src/utils/tool-compressor.js +257 -0
  127. package/dist/src/utils/tool-config.js +201 -0
  128. package/dist/src/validators/dependency-graph-validator.js +147 -0
  129. package/dist/src/validators/interpolation-validator.js +222 -0
  130. package/dist/src/validators/output-usage-validator.js +151 -0
  131. package/dist/src/validators/syntax-validator.js +102 -0
  132. package/dist/src/validators/tool-registry-validator.js +123 -0
  133. package/dist/src/validators/tool-types.js +97 -0
  134. package/dist/src/validators/types.js +8 -0
  135. package/dist/src/validators/workflow-validator.js +134 -0
  136. package/dist/src/visualizer-lite.js +42 -0
  137. package/dist/src/visualizer.js +179 -0
  138. package/dist/src/workflows/circuit-breaker.js +199 -0
  139. package/dist/src/workflows/custom-workflows.js +451 -0
  140. package/dist/src/workflows/engine/AutoSynthesizer.js +97 -0
  141. package/dist/src/workflows/engine/StepParameterResolver.js +74 -0
  142. package/dist/src/workflows/engine/VariableInterpolator.js +123 -0
  143. package/dist/src/workflows/engine/WorkflowDiscovery.js +125 -0
  144. package/dist/src/workflows/engine/WorkflowExecutionEngine.js +485 -0
  145. package/dist/src/workflows/engine/WorkflowExecutor.js +113 -0
  146. package/dist/src/workflows/engine/WorkflowFileManager.js +244 -0
  147. package/dist/src/workflows/engine/WorkflowHelpers.js +114 -0
  148. package/dist/src/workflows/engine/WorkflowOutputFormatter.js +83 -0
  149. package/dist/src/workflows/engine/events/WorkflowEventBus.js +132 -0
  150. package/dist/src/workflows/engine/events/interfaces/IEventBus.js +5 -0
  151. package/dist/src/workflows/engine/handlers/ErrorRecoveryHandler.js +162 -0
  152. package/dist/src/workflows/engine/handlers/PromptEnhancementHandler.js +115 -0
  153. package/dist/src/workflows/engine/handlers/SessionPersistenceHandler.js +167 -0
  154. package/dist/src/workflows/engine/handlers/StepExecutionHandler.js +231 -0
  155. package/dist/src/workflows/engine/handlers/ToolInvocationHandler.js +46 -0
  156. package/dist/src/workflows/engine/interfaces/IAutoSynthesizer.js +5 -0
  157. package/dist/src/workflows/engine/interfaces/IStepParameterResolver.js +5 -0
  158. package/dist/src/workflows/engine/interfaces/IVariableInterpolator.js +5 -0
  159. package/dist/src/workflows/engine/interfaces/IWorkflowDiscovery.js +4 -0
  160. package/dist/src/workflows/engine/interfaces/IWorkflowFileManager.js +5 -0
  161. package/dist/src/workflows/engine/interfaces/IWorkflowOutputFormatter.js +5 -0
  162. package/dist/src/workflows/engine/state/WorkflowStateMachine.js +194 -0
  163. package/dist/src/workflows/engine/state/interfaces/IStateMachine.js +17 -0
  164. package/dist/src/workflows/fallback-strategies.js +373 -0
  165. package/dist/src/workflows/message-queue.js +455 -0
  166. package/dist/src/workflows/model-router.js +189 -0
  167. package/dist/src/workflows/orchestrator-examples.js +174 -0
  168. package/dist/src/workflows/orchestrator-integration.js +200 -0
  169. package/dist/src/workflows/self-healing.js +524 -0
  170. package/dist/src/workflows/tool-mapper.js +407 -0
  171. package/dist/src/workflows/tool-orchestrator.js +796 -0
  172. package/dist/src/workflows/workflow-engine.js +573 -0
  173. package/dist/src/workflows/workflow-parser.js +283 -0
  174. package/dist/src/workflows/workflow-types.js +95 -0
  175. package/dist/src/workflows.js +568 -0
  176. package/dist/test-workflow-file-output.js +93 -0
  177. package/docs/API_KEYS.md +570 -0
  178. package/docs/CLAUDE_CODE_SETUP.md +181 -0
  179. package/docs/CLAUDE_DESKTOP_MANUAL.md +127 -0
  180. package/docs/CONFIGURATION.md +745 -0
  181. package/docs/FOCUS_MODES.md +240 -0
  182. package/docs/INSTALLATION_BOTH.md +145 -0
  183. package/docs/TERMS.md +352 -0
  184. package/docs/TOOLS_REFERENCE.md +1622 -0
  185. package/docs/TOOL_PARAMETERS.md +496 -0
  186. package/docs/TOOL_PROFILES.md +236 -0
  187. package/docs/WORKFLOWS.md +987 -0
  188. package/docs/WORKFLOW_OUTPUT.md +198 -0
  189. package/docs/WORKFLOW_PROGRESS_TRACKING.md +305 -0
  190. package/docs/workflows/design-brainstorm.md +335 -0
  191. package/package.json +97 -0
  192. package/profiles/balanced.json +37 -0
  193. package/profiles/code_focus.json +37 -0
  194. package/profiles/debug_intensive.json +34 -0
  195. package/profiles/full.json +37 -0
  196. package/profiles/minimal.json +37 -0
  197. package/profiles/research_power.json +37 -0
  198. package/profiles/workflow_builder.json +37 -0
  199. package/smithery.yaml +66 -0
  200. package/start.sh +8 -0
  201. package/tools.config.json +81 -0
  202. package/tsconfig.json +18 -0
  203. package/workflows/accessibility-code-audit.yaml +92 -0
  204. package/workflows/code-architecture-review.yaml +202 -0
  205. package/workflows/code-review.yaml +142 -0
  206. package/workflows/core/iterative-problem-solver.yaml +283 -0
  207. package/workflows/creative-brainstorm-yaml.yaml +215 -0
  208. package/workflows/pingpong.yaml +141 -0
  209. package/workflows/system/README.md +412 -0
  210. package/workflows/system/challenger.yaml +175 -0
  211. package/workflows/system/scout.yaml +164 -0
  212. package/workflows/system/verifier.yaml +133 -0
  213. package/workflows/ultra-creative-brainstorm.yaml +318 -0
  214. package/workflows/ux-research-flow.yaml +92 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Environment Detector
3
+ * Detects the current environment and available providers
4
+ */
5
+ export function detectEnvironment() {
6
+ const env = {
7
+ type: 'standalone',
8
+ nativeProviders: [],
9
+ availableProviders: {},
10
+ apiKeys: {},
11
+ skipNativeAPIs: []
12
+ };
13
+ // Detect environment type
14
+ if (process.env.CLAUDE_CODE_SESSION || process.env.ANTHROPIC_SESSION_ID) {
15
+ env.type = 'claude-code';
16
+ env.nativeProviders.push('claude');
17
+ env.skipNativeAPIs.push('anthropic');
18
+ }
19
+ else if (process.env.CURSOR_SESSION || process.env.CURSOR_IDE) {
20
+ env.type = 'cursor';
21
+ env.nativeProviders.push('openai');
22
+ env.skipNativeAPIs.push('openai');
23
+ }
24
+ else if (process.env.CODEX_SESSION) {
25
+ env.type = 'codex';
26
+ env.nativeProviders.push('openai');
27
+ env.skipNativeAPIs.push('openai');
28
+ }
29
+ else if (process.env.VSCODE_PID) {
30
+ env.type = 'vscode';
31
+ }
32
+ // Check available API keys
33
+ const providers = {
34
+ openai: process.env.OPENAI_API_KEY,
35
+ anthropic: process.env.ANTHROPIC_API_KEY,
36
+ grok: process.env.GROK_API_KEY,
37
+ perplexity: process.env.PERPLEXITY_API_KEY,
38
+ gemini: process.env.GOOGLE_API_KEY,
39
+ deepseek: process.env.DEEPSEEK_API_KEY,
40
+ openrouter: process.env.OPENROUTER_API_KEY
41
+ };
42
+ for (const [provider, key] of Object.entries(providers)) {
43
+ env.availableProviders[provider] = !!key;
44
+ env.apiKeys[provider] = key;
45
+ }
46
+ // Check GPT-5 feature flag
47
+ if (process.env.ENABLE_GPT5 === 'true' && env.availableProviders.openai) {
48
+ env.availableProviders['gpt5'] = true;
49
+ }
50
+ return env;
51
+ }
52
+ export function getBestAvailableProvider(env, taskType) {
53
+ // Task-specific routing
54
+ const preferences = {
55
+ reason: ['grok', 'openai', 'gemini', 'anthropic', 'deepseek'],
56
+ search: ['perplexity', 'grok', 'openai'],
57
+ code: ['openai', 'anthropic', 'deepseek', 'gemini'],
58
+ analyze: ['gemini', 'openai', 'anthropic', 'grok'],
59
+ brainstorm: ['gemini', 'grok', 'openai', 'anthropic'],
60
+ general: ['openai', 'anthropic', 'gemini', 'grok', 'perplexity']
61
+ };
62
+ const preferred = preferences[taskType] || preferences.general;
63
+ for (const provider of preferred) {
64
+ // Check if we should use native provider
65
+ if (env.nativeProviders.includes(provider)) {
66
+ return provider;
67
+ }
68
+ // Check if API key is available and not skipped
69
+ if (env.availableProviders[provider] && !env.skipNativeAPIs.includes(provider)) {
70
+ return provider;
71
+ }
72
+ }
73
+ // Try any available provider
74
+ for (const [provider, available] of Object.entries(env.availableProviders)) {
75
+ if (available && !env.skipNativeAPIs.includes(provider)) {
76
+ return provider;
77
+ }
78
+ }
79
+ return null;
80
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Consolidated Tools Export
3
+ * 12 smart tools replacing 62 individual tools
4
+ * Target: 6,500 tokens (from 13,400)
5
+ */
6
+ // Core tools are defined directly in server.ts, not here
7
+ // export { thinkTool } from '../core/think-tool.js';
8
+ // export { focusTool } from '../core/focus-tool.js';
9
+ // New consolidated tools
10
+ export { aiTool } from './ai-tool.js';
11
+ export { searchTool } from './search-tool.js';
12
+ export { brainstormTool } from './brainstorm-tool.js';
13
+ export { workflowTool } from './workflow-tool.js';
14
+ // Additional consolidated tools (to be implemented - commented out for now)
15
+ // export { analyzeTool } from './analyze-tool.js';
16
+ // export { generateTool } from './generate-tool.js';
17
+ // export { reasonTool } from './reason-tool.js';
18
+ // export { verifyTool } from './verify-tool.js';
19
+ // export { challengeTool } from './challenge-tool.js';
20
+ // export { orchestrateTool } from './orchestrate-tool.js';
21
+ // Export all as array for easy registration
22
+ export const consolidatedTools = [
23
+ 'think',
24
+ 'focus',
25
+ 'workflow',
26
+ 'ai',
27
+ 'search',
28
+ 'analyze',
29
+ 'generate',
30
+ 'reason',
31
+ 'brainstorm',
32
+ 'verify',
33
+ 'challenge',
34
+ 'orchestrate'
35
+ ];
36
+ // Tool descriptions for documentation
37
+ export const toolDescriptions = {
38
+ think: 'Internal reasoning and caching',
39
+ focus: 'Multi-mode orchestration (16+ modes)',
40
+ workflow: 'Execute YAML workflows',
41
+ ai: 'Universal AI query',
42
+ search: 'Web search (auto-selects provider)',
43
+ analyze: 'Any analysis type',
44
+ generate: 'Code/text generation',
45
+ reason: 'Complex reasoning',
46
+ brainstorm: 'Creative ideation',
47
+ verify: 'Multi-model verification',
48
+ challenge: 'Critical thinking',
49
+ orchestrate: 'Custom workflows/PingPong'
50
+ };
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Consolidated Search Tool
3
+ * Smart web search with provider selection
4
+ */
5
+ import { z } from "zod";
6
+ import { detectEnvironment } from './environment-detector.js';
7
+ import { callPerplexity, PerplexityModel } from '../perplexity-tools.js';
8
+ import { callGrok } from '../grok-tools.js';
9
+ import * as fs from 'fs/promises';
10
+ import * as path from 'path';
11
+ /**
12
+ * Unified Search Tool
13
+ * Replaces: perplexity_ask, perplexity_research, grok_search, perplexity_code_search, perplexity_fact_check
14
+ * Token cost: ~200 tokens (vs 1000+ for individual tools)
15
+ */
16
+ export const searchTool = {
17
+ name: "search",
18
+ description: "Web search", // Ultra-short description
19
+ parameters: z.object({
20
+ query: z.string(),
21
+ type: z.enum(["general", "research", "code", "fact", "latest"])
22
+ .default("general"),
23
+ provider: z.enum(["auto", "perplexity", "grok"])
24
+ .default("auto"),
25
+ live: z.boolean()
26
+ .optional(),
27
+ maxSources: z.number()
28
+ .optional(),
29
+ recency: z.enum(["hour", "day", "week", "month", "year"])
30
+ .optional(),
31
+ saveAs: z.string()
32
+ .optional()
33
+ }),
34
+ execute: async (args, { log }) => {
35
+ const env = detectEnvironment();
36
+ // Determine provider
37
+ let selectedProvider = args.provider || 'auto';
38
+ if (selectedProvider === 'auto') {
39
+ // Auto-select based on type and availability
40
+ if (args.type === 'latest' || args.live) {
41
+ // Prefer Grok for latest/live search
42
+ selectedProvider = env.availableProviders.grok ? 'grok' : 'perplexity';
43
+ }
44
+ else {
45
+ // Prefer Perplexity for general search
46
+ selectedProvider = env.availableProviders.perplexity ? 'perplexity' : 'grok';
47
+ }
48
+ // Fallback if neither available
49
+ if (!env.availableProviders[selectedProvider]) {
50
+ return '[No search providers available. Please set PERPLEXITY_API_KEY or GROK_API_KEY]';
51
+ }
52
+ }
53
+ log?.info(`Search: provider=${selectedProvider}, type=${args.type}, live=${args.live}`);
54
+ try {
55
+ let result;
56
+ if (selectedProvider === 'grok' && env.availableProviders.grok) {
57
+ // Use Grok search
58
+ const grokOptions = {
59
+ live: args.live,
60
+ maxSources: args.maxSources
61
+ };
62
+ const messages = [{
63
+ role: 'user',
64
+ content: args.query
65
+ }];
66
+ result = await callGrok(messages, grokOptions);
67
+ }
68
+ else if (selectedProvider === 'perplexity' && env.availableProviders.perplexity) {
69
+ // Use Perplexity search
70
+ const messages = [{
71
+ role: 'user',
72
+ content: args.query
73
+ }];
74
+ // Select Perplexity model based on type
75
+ let model = PerplexityModel.SONAR_PRO;
76
+ if (args.type === 'research') {
77
+ model = PerplexityModel.SONAR_DEEP_RESEARCH;
78
+ }
79
+ // Map type to search domain if needed
80
+ let searchDomain;
81
+ if (args.type === 'code') {
82
+ searchDomain = 'github.com stackoverflow.com';
83
+ }
84
+ result = await callPerplexity(messages, model, searchDomain, args.recency);
85
+ }
86
+ else {
87
+ return `[${selectedProvider} search not available. Please check API keys]`;
88
+ }
89
+ // Save if requested
90
+ if (args.saveAs) {
91
+ try {
92
+ const filePath = path.resolve(args.saveAs);
93
+ await fs.writeFile(filePath, result, 'utf8');
94
+ log?.info(`Saved search results to: ${filePath}`);
95
+ return `${result}\n\n[Saved to: ${filePath}]`;
96
+ }
97
+ catch (error) {
98
+ log?.error(`Failed to save: ${error}`);
99
+ return `${result}\n\n[Failed to save: ${error instanceof Error ? error.message : String(error)}]`;
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ catch (error) {
105
+ const errorMessage = error instanceof Error ? error.message : String(error);
106
+ log?.error(`Search error: ${errorMessage}`);
107
+ return `[Search Error: ${errorMessage}]`;
108
+ }
109
+ }
110
+ };
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Workflow Tool
3
+ * Execute YAML workflows and custom orchestrations
4
+ */
5
+ import { z } from "zod";
6
+ import * as yaml from 'yaml';
7
+ import * as fs from 'fs/promises';
8
+ import * as path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { AIRouter } from './ai-router.js';
11
+ import { searchTool } from './search-tool.js';
12
+ import { brainstormTool } from './brainstorm-tool.js';
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+ /**
16
+ * Workflow Execution Tool
17
+ * Replaces: nextThought, workflow tools, and session management
18
+ * Token cost: ~150 tokens
19
+ */
20
+ export const workflowTool = {
21
+ name: "workflow",
22
+ description: "Execute workflows", // Ultra-short description
23
+ parameters: z.object({
24
+ task: z.string(),
25
+ template: z.string()
26
+ .optional(),
27
+ steps: z.array(z.string())
28
+ .optional(),
29
+ inputs: z.record(z.string())
30
+ .optional(),
31
+ saveAs: z.string()
32
+ .optional(),
33
+ format: z.enum(["md", "json", "yaml"])
34
+ .default("md")
35
+ }),
36
+ execute: async (args, { log }) => {
37
+ log?.info(`Workflow: task="${args.task}", template=${args.template || 'inline'}`);
38
+ try {
39
+ let workflow;
40
+ if (args.template) {
41
+ // Load workflow from template
42
+ workflow = await loadWorkflowTemplate(args.template);
43
+ }
44
+ else if (args.steps) {
45
+ // Create inline workflow
46
+ workflow = createInlineWorkflow(args.task, args.steps);
47
+ }
48
+ else {
49
+ // Default simple workflow
50
+ workflow = createDefaultWorkflow(args.task);
51
+ }
52
+ // Execute workflow
53
+ const result = await executeWorkflow(workflow, args.inputs || {}, log);
54
+ // Format output
55
+ const formatted = formatWorkflowOutput(result, args.format || 'md', workflow);
56
+ // Save if requested
57
+ if (args.saveAs || workflow.output?.saveAs) {
58
+ const savePath = args.saveAs || workflow.output?.saveAs;
59
+ if (savePath) {
60
+ const filePath = path.resolve(savePath);
61
+ await fs.writeFile(filePath, formatted, 'utf8');
62
+ log?.info(`Saved workflow output to: ${filePath}`);
63
+ return `${formatted}\n\n[Saved to: ${filePath}]`;
64
+ }
65
+ }
66
+ return formatted;
67
+ }
68
+ catch (error) {
69
+ const errorMessage = error instanceof Error ? error.message : String(error);
70
+ log?.error(`Workflow error: ${errorMessage}`);
71
+ return `[Workflow Error: ${errorMessage}]`;
72
+ }
73
+ }
74
+ };
75
+ async function loadWorkflowTemplate(templatePath) {
76
+ try {
77
+ // Check if it's a built-in template
78
+ const builtInPath = path.join(__dirname, '../../../workflows/templates', `${templatePath}.yaml`);
79
+ const customPath = path.resolve(templatePath);
80
+ let workflowPath = customPath;
81
+ try {
82
+ await fs.access(builtInPath);
83
+ workflowPath = builtInPath;
84
+ }
85
+ catch {
86
+ // Use custom path
87
+ }
88
+ const content = await fs.readFile(workflowPath, 'utf8');
89
+ return yaml.parse(content);
90
+ }
91
+ catch (error) {
92
+ throw new Error(`Failed to load workflow template: ${error instanceof Error ? error.message : String(error)}`);
93
+ }
94
+ }
95
+ function createInlineWorkflow(task, steps) {
96
+ return {
97
+ name: 'inline-workflow',
98
+ description: task,
99
+ steps: steps.map((step, index) => {
100
+ const [action, ...rest] = step.split(':');
101
+ return {
102
+ id: `step_${index + 1}`,
103
+ tool: action.trim(),
104
+ prompt: rest.join(':').trim()
105
+ };
106
+ })
107
+ };
108
+ }
109
+ function createDefaultWorkflow(task) {
110
+ return {
111
+ name: 'default-workflow',
112
+ description: task,
113
+ steps: [
114
+ {
115
+ id: 'analyze',
116
+ tool: 'ai',
117
+ action: 'analyze',
118
+ prompt: task
119
+ },
120
+ {
121
+ id: 'execute',
122
+ tool: 'ai',
123
+ action: 'generate',
124
+ prompt: `Execute: ${task}\nBased on analysis: {{analyze.output}}`
125
+ }
126
+ ]
127
+ };
128
+ }
129
+ async function executeWorkflow(workflow, inputs, log) {
130
+ const results = { ...inputs };
131
+ const router = new AIRouter();
132
+ for (const step of workflow.steps) {
133
+ log?.info(`Executing step: ${step.id}`);
134
+ // Check condition
135
+ if (step.condition && !evaluateCondition(step.condition, results)) {
136
+ log?.info(`Skipping step ${step.id} due to condition`);
137
+ continue;
138
+ }
139
+ // Resolve variables in step
140
+ const resolvedStep = resolveVariables(step, results);
141
+ // Handle external MCP
142
+ if (step.external_mcp) {
143
+ results[step.id] = {
144
+ output: `[External MCP: ${step.external_mcp} - ${step.action}]`,
145
+ external: true
146
+ };
147
+ continue;
148
+ }
149
+ // Execute based on tool
150
+ let stepResult;
151
+ switch (step.tool) {
152
+ case 'ai':
153
+ case 'analyze':
154
+ case 'generate':
155
+ case 'reason':
156
+ stepResult = await router.route({
157
+ prompt: resolvedStep.prompt || resolvedStep.input || '',
158
+ mode: resolvedStep.action
159
+ });
160
+ break;
161
+ case 'search':
162
+ stepResult = await searchTool.execute({
163
+ query: resolvedStep.query || resolvedStep.prompt || '',
164
+ provider: resolvedStep.provider,
165
+ type: resolvedStep.type
166
+ }, { log });
167
+ break;
168
+ case 'brainstorm':
169
+ stepResult = await brainstormTool.execute({
170
+ topic: resolvedStep.prompt || resolvedStep.topic || '',
171
+ approach: resolvedStep.approach
172
+ }, { log });
173
+ break;
174
+ case 'think':
175
+ stepResult = `[Thinking: ${resolvedStep.thought || resolvedStep.prompt}]`;
176
+ break;
177
+ case 'write_file':
178
+ case 'save':
179
+ const savePath = path.resolve(resolvedStep.path || `output_${step.id}.md`);
180
+ const content = resolvedStep.content || resolvedStep.prompt || '';
181
+ await fs.writeFile(savePath, content, 'utf8');
182
+ stepResult = `Saved to: ${savePath}`;
183
+ break;
184
+ default:
185
+ stepResult = `[Tool ${step.tool} not implemented in consolidated version]`;
186
+ }
187
+ results[step.id] = {
188
+ output: stepResult,
189
+ timestamp: new Date().toISOString()
190
+ };
191
+ }
192
+ return results;
193
+ }
194
+ function resolveVariables(obj, context) {
195
+ if (typeof obj === 'string') {
196
+ return obj.replace(/\{\{([^}]+)\}\}/g, (match, path) => {
197
+ const keys = path.trim().split('.');
198
+ let value = context;
199
+ for (const key of keys) {
200
+ value = value?.[key];
201
+ }
202
+ return value?.output || value || match;
203
+ });
204
+ }
205
+ if (typeof obj === 'object' && obj !== null) {
206
+ const resolved = {};
207
+ for (const [key, value] of Object.entries(obj)) {
208
+ resolved[key] = resolveVariables(value, context);
209
+ }
210
+ return resolved;
211
+ }
212
+ return obj;
213
+ }
214
+ function evaluateCondition(condition, context) {
215
+ // Simple condition evaluation
216
+ const resolved = resolveVariables(condition, context);
217
+ return resolved !== 'false' && resolved !== '' && resolved !== null;
218
+ }
219
+ function formatWorkflowOutput(results, format, workflow) {
220
+ if (format === 'json') {
221
+ return JSON.stringify(results, null, 2);
222
+ }
223
+ if (format === 'yaml') {
224
+ return yaml.stringify(results);
225
+ }
226
+ // Markdown format
227
+ let output = `# Workflow: ${workflow.name}\n\n`;
228
+ output += `*${workflow.description}*\n\n`;
229
+ for (const step of workflow.steps) {
230
+ const result = results[step.id];
231
+ if (result) {
232
+ output += `## Step: ${step.id}\n\n`;
233
+ output += result.output || JSON.stringify(result);
234
+ output += '\n\n';
235
+ }
236
+ }
237
+ return output;
238
+ }