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,74 @@
1
+ /**
2
+ * Wrapper tool to access OpenRouter/Qwen tools
3
+ * Since they don't show in Claude's UI, this provides a single entry point
4
+ */
5
+ import { z } from "zod";
6
+ import { qwenCoderTool, qwqReasoningTool, qwenGeneralTool, qwenCompetitiveTool, openRouterMultiModelTool } from "./openrouter-tools.js";
7
+ /**
8
+ * Unified Qwen tool that wraps all OpenRouter tools
9
+ */
10
+ export const qwenTool = {
11
+ name: "qwen",
12
+ description: "Access Qwen3-Coder, QwQ reasoning, and other OpenRouter models",
13
+ parameters: z.object({
14
+ tool: z.enum(["coder", "reason", "general", "competitive", "multi"]),
15
+ // Coder parameters
16
+ task: z.enum(["generate", "review", "optimize", "debug", "refactor", "explain"]).optional(),
17
+ code: z.string().optional(),
18
+ requirements: z.string().optional(),
19
+ language: z.string().optional(),
20
+ // Reasoning parameters
21
+ problem: z.string().optional(),
22
+ approach: z.enum(["logical", "mathematical", "systematic", "critical"]).optional(),
23
+ // General/Multi parameters
24
+ query: z.string().optional(),
25
+ model: z.string().optional(),
26
+ // Common
27
+ useFree: z.boolean().optional().default(false)
28
+ }),
29
+ execute: async (args, { log }) => {
30
+ log?.info(`Using Qwen tool: ${args.tool}`);
31
+ switch (args.tool) {
32
+ case "coder":
33
+ return await qwenCoderTool.execute({
34
+ task: args.task || "generate",
35
+ code: args.code,
36
+ requirements: args.requirements || args.query || "",
37
+ language: args.language,
38
+ useFree: args.useFree
39
+ }, { log });
40
+ case "reason":
41
+ return await qwqReasoningTool.execute({
42
+ problem: args.problem || args.query || args.requirements || "",
43
+ approach: args.approach,
44
+ useFree: args.useFree
45
+ }, { log });
46
+ case "general":
47
+ return await qwenGeneralTool.execute({
48
+ query: args.query || args.requirements || args.problem || "",
49
+ mode: "general",
50
+ useFree: args.useFree
51
+ }, { log });
52
+ case "competitive":
53
+ return await qwenCompetitiveTool.execute({
54
+ problem: args.problem || args.query || args.requirements || "",
55
+ language: args.language,
56
+ optimize: true
57
+ }, { log });
58
+ case "multi":
59
+ return await openRouterMultiModelTool.execute({
60
+ query: args.query || args.requirements || args.problem || "",
61
+ model: args.model || "qwen/qwen3-coder",
62
+ temperature: 0.7
63
+ }, { log });
64
+ default:
65
+ return "Unknown tool. Use: coder, reason, general, competitive, or multi";
66
+ }
67
+ }
68
+ };
69
+ /**
70
+ * Export the wrapper tool
71
+ */
72
+ export function getQwenWrapperTool() {
73
+ return qwenTool;
74
+ }
@@ -0,0 +1,444 @@
1
+ /**
2
+ * Smart Tool Router for Focus MCP Server
3
+ * Manages tool selection based on availability, preferences, and capabilities
4
+ */
5
+ // Tool capability categories
6
+ export var ToolCategory;
7
+ (function (ToolCategory) {
8
+ ToolCategory["REASONING"] = "reasoning";
9
+ ToolCategory["CODE"] = "code";
10
+ ToolCategory["BRAINSTORM"] = "brainstorm";
11
+ ToolCategory["SEARCH"] = "search";
12
+ ToolCategory["ANALYSIS"] = "analysis";
13
+ ToolCategory["DEBUG"] = "debug";
14
+ })(ToolCategory || (ToolCategory = {}));
15
+ // Tool provider types
16
+ export var ToolProvider;
17
+ (function (ToolProvider) {
18
+ ToolProvider["OPENAI"] = "openai";
19
+ ToolProvider["GROK"] = "grok";
20
+ ToolProvider["PERPLEXITY"] = "perplexity";
21
+ ToolProvider["GEMINI"] = "gemini";
22
+ ToolProvider["OPENROUTER"] = "openrouter";
23
+ ToolProvider["LMSTUDIO"] = "lmstudio";
24
+ ToolProvider["INTERNAL"] = "internal";
25
+ })(ToolProvider || (ToolProvider = {}));
26
+ /**
27
+ * Smart Tool Router Class
28
+ */
29
+ export class ToolRouter {
30
+ constructor(preferences = {}) {
31
+ this.preferences = {
32
+ fallbackEnabled: true,
33
+ costOptimization: false,
34
+ speedPriority: false,
35
+ qualityPriority: true,
36
+ verboseLogging: false,
37
+ ...preferences
38
+ };
39
+ this.registry = this.initializeRegistry();
40
+ this.toolCache = new Map();
41
+ }
42
+ /**
43
+ * Initialize the tool registry with all available tools
44
+ */
45
+ initializeRegistry() {
46
+ return {
47
+ [ToolCategory.REASONING]: [
48
+ {
49
+ name: "gpt5_reason",
50
+ provider: ToolProvider.OPENAI,
51
+ categories: [ToolCategory.REASONING],
52
+ priority: 1,
53
+ costTier: "high",
54
+ speedTier: "medium",
55
+ qualityTier: "excellent",
56
+ checkAvailability: () => !!process.env.OPENAI_API_KEY && process.env.ENABLE_GPT5 === 'true'
57
+ },
58
+ {
59
+ name: "gpt5_mini_reason",
60
+ provider: ToolProvider.OPENAI,
61
+ categories: [ToolCategory.REASONING],
62
+ priority: 2,
63
+ costTier: "medium",
64
+ speedTier: "fast",
65
+ qualityTier: "excellent",
66
+ checkAvailability: () => !!process.env.OPENAI_API_KEY
67
+ },
68
+ {
69
+ name: "qwq_reason",
70
+ provider: ToolProvider.OPENROUTER,
71
+ categories: [ToolCategory.REASONING],
72
+ priority: 3,
73
+ costTier: "medium",
74
+ speedTier: "medium",
75
+ qualityTier: "excellent",
76
+ checkAvailability: () => !!process.env.OPENROUTER_API_KEY
77
+ },
78
+ {
79
+ name: "grok_reason",
80
+ provider: ToolProvider.GROK,
81
+ categories: [ToolCategory.REASONING],
82
+ priority: 4,
83
+ costTier: "medium",
84
+ speedTier: "fast",
85
+ qualityTier: "excellent",
86
+ checkAvailability: () => !!process.env.GROK_API_KEY
87
+ },
88
+ {
89
+ name: "perplexity_reason",
90
+ provider: ToolProvider.PERPLEXITY,
91
+ categories: [ToolCategory.REASONING, ToolCategory.SEARCH],
92
+ priority: 5,
93
+ costTier: "medium",
94
+ speedTier: "fast",
95
+ qualityTier: "good",
96
+ checkAvailability: () => !!process.env.PERPLEXITY_API_KEY
97
+ },
98
+ {
99
+ name: "gemini_query",
100
+ provider: ToolProvider.GEMINI,
101
+ categories: [ToolCategory.REASONING],
102
+ priority: 6,
103
+ costTier: "low",
104
+ speedTier: "fast",
105
+ qualityTier: "good",
106
+ checkAvailability: () => !!process.env.GOOGLE_API_KEY
107
+ }
108
+ ],
109
+ [ToolCategory.CODE]: [
110
+ {
111
+ name: "qwen_coder",
112
+ provider: ToolProvider.OPENROUTER,
113
+ categories: [ToolCategory.CODE],
114
+ priority: 1,
115
+ costTier: "medium",
116
+ speedTier: "medium",
117
+ qualityTier: "excellent",
118
+ checkAvailability: () => !!process.env.OPENROUTER_API_KEY
119
+ },
120
+ {
121
+ name: "grok_code",
122
+ provider: ToolProvider.GROK,
123
+ categories: [ToolCategory.CODE, ToolCategory.ANALYSIS],
124
+ priority: 2,
125
+ costTier: "medium",
126
+ speedTier: "fast",
127
+ qualityTier: "excellent",
128
+ checkAvailability: () => !!process.env.GROK_API_KEY
129
+ },
130
+ {
131
+ name: "gpt5_code",
132
+ provider: ToolProvider.OPENAI,
133
+ categories: [ToolCategory.CODE, ToolCategory.ANALYSIS],
134
+ priority: 3,
135
+ costTier: "medium",
136
+ speedTier: "fast",
137
+ qualityTier: "excellent",
138
+ checkAvailability: () => !!process.env.OPENAI_API_KEY
139
+ },
140
+ {
141
+ name: "gemini_analyze_code",
142
+ provider: ToolProvider.GEMINI,
143
+ categories: [ToolCategory.CODE, ToolCategory.ANALYSIS],
144
+ priority: 4,
145
+ costTier: "low",
146
+ speedTier: "fast",
147
+ qualityTier: "good",
148
+ checkAvailability: () => !!process.env.GOOGLE_API_KEY
149
+ }
150
+ ],
151
+ [ToolCategory.BRAINSTORM]: [
152
+ {
153
+ name: "grok_brainstorm",
154
+ provider: ToolProvider.GROK,
155
+ categories: [ToolCategory.BRAINSTORM],
156
+ priority: 1,
157
+ costTier: "medium",
158
+ speedTier: "medium",
159
+ qualityTier: "excellent",
160
+ checkAvailability: () => !!process.env.GROK_API_KEY
161
+ },
162
+ {
163
+ name: "openai_brainstorm",
164
+ provider: ToolProvider.OPENAI,
165
+ categories: [ToolCategory.BRAINSTORM],
166
+ priority: 2,
167
+ costTier: "high",
168
+ speedTier: "medium",
169
+ qualityTier: "excellent",
170
+ checkAvailability: () => !!process.env.OPENAI_API_KEY
171
+ },
172
+ {
173
+ name: "gemini_brainstorm",
174
+ provider: ToolProvider.GEMINI,
175
+ categories: [ToolCategory.BRAINSTORM],
176
+ priority: 3,
177
+ costTier: "low",
178
+ speedTier: "fast",
179
+ qualityTier: "good",
180
+ checkAvailability: () => !!process.env.GOOGLE_API_KEY
181
+ }
182
+ ],
183
+ [ToolCategory.SEARCH]: [
184
+ {
185
+ name: "perplexity_ask",
186
+ provider: ToolProvider.PERPLEXITY,
187
+ categories: [ToolCategory.SEARCH],
188
+ priority: 1,
189
+ costTier: "medium",
190
+ speedTier: "fast",
191
+ qualityTier: "excellent",
192
+ checkAvailability: () => !!process.env.PERPLEXITY_API_KEY
193
+ },
194
+ {
195
+ name: "perplexity_research",
196
+ provider: ToolProvider.PERPLEXITY,
197
+ categories: [ToolCategory.SEARCH, ToolCategory.ANALYSIS],
198
+ priority: 2,
199
+ costTier: "medium",
200
+ speedTier: "medium",
201
+ qualityTier: "excellent",
202
+ checkAvailability: () => !!process.env.PERPLEXITY_API_KEY
203
+ }
204
+ ],
205
+ [ToolCategory.ANALYSIS]: [
206
+ {
207
+ name: "gpt5_mini_analyze",
208
+ provider: ToolProvider.OPENAI,
209
+ categories: [ToolCategory.ANALYSIS],
210
+ priority: 1,
211
+ costTier: "medium",
212
+ speedTier: "fast",
213
+ qualityTier: "excellent",
214
+ checkAvailability: () => !!process.env.OPENAI_API_KEY
215
+ },
216
+ {
217
+ name: "openai_compare",
218
+ provider: ToolProvider.OPENAI,
219
+ categories: [ToolCategory.ANALYSIS],
220
+ priority: 2,
221
+ costTier: "medium",
222
+ speedTier: "medium",
223
+ qualityTier: "excellent",
224
+ checkAvailability: () => !!process.env.OPENAI_API_KEY
225
+ },
226
+ {
227
+ name: "gemini_analyze_text",
228
+ provider: ToolProvider.GEMINI,
229
+ categories: [ToolCategory.ANALYSIS],
230
+ priority: 3,
231
+ costTier: "low",
232
+ speedTier: "fast",
233
+ qualityTier: "good",
234
+ checkAvailability: () => !!process.env.GOOGLE_API_KEY
235
+ }
236
+ ],
237
+ [ToolCategory.DEBUG]: [
238
+ {
239
+ name: "grok_debug",
240
+ provider: ToolProvider.GROK,
241
+ categories: [ToolCategory.DEBUG],
242
+ priority: 1,
243
+ costTier: "medium",
244
+ speedTier: "fast",
245
+ qualityTier: "excellent",
246
+ checkAvailability: () => !!process.env.GROK_API_KEY
247
+ },
248
+ {
249
+ name: "gpt5_code",
250
+ provider: ToolProvider.OPENAI,
251
+ categories: [ToolCategory.DEBUG, ToolCategory.CODE],
252
+ priority: 2,
253
+ costTier: "medium",
254
+ speedTier: "fast",
255
+ qualityTier: "excellent",
256
+ checkAvailability: () => !!process.env.OPENAI_API_KEY
257
+ }
258
+ ]
259
+ };
260
+ }
261
+ /**
262
+ * Set user preferences
263
+ */
264
+ setPreferences(preferences) {
265
+ this.preferences = { ...this.preferences, ...preferences };
266
+ }
267
+ /**
268
+ * Get the best tool for a category
269
+ */
270
+ getBestTool(category, userPreference) {
271
+ const tools = this.registry[category] || [];
272
+ const availableTools = tools.filter(t => t.checkAvailability());
273
+ if (availableTools.length === 0) {
274
+ if (this.preferences.verboseLogging) {
275
+ console.error(`No available tools for category: ${category}`);
276
+ }
277
+ return null;
278
+ }
279
+ // Check for user preference
280
+ if (userPreference) {
281
+ const preferredTool = availableTools.find(t => t.name === userPreference ||
282
+ t.provider === userPreference);
283
+ if (preferredTool) {
284
+ if (this.preferences.verboseLogging) {
285
+ console.error(`Using preferred tool: ${preferredTool.name}`);
286
+ }
287
+ return preferredTool;
288
+ }
289
+ }
290
+ // Check for provider preference
291
+ if (this.preferences.preferredProvider) {
292
+ const providerTools = availableTools.filter(t => t.provider === this.preferences.preferredProvider);
293
+ if (providerTools.length > 0) {
294
+ return this.selectByPriority(providerTools);
295
+ }
296
+ }
297
+ // Apply optimization preferences
298
+ let sortedTools = [...availableTools];
299
+ if (this.preferences.costOptimization) {
300
+ sortedTools.sort((a, b) => {
301
+ const costOrder = { "free": 0, "low": 1, "medium": 2, "high": 3 };
302
+ return costOrder[a.costTier] - costOrder[b.costTier];
303
+ });
304
+ }
305
+ else if (this.preferences.speedPriority) {
306
+ sortedTools.sort((a, b) => {
307
+ const speedOrder = { "fast": 0, "medium": 1, "slow": 2 };
308
+ return speedOrder[a.speedTier] - speedOrder[b.speedTier];
309
+ });
310
+ }
311
+ else if (this.preferences.qualityPriority) {
312
+ sortedTools.sort((a, b) => {
313
+ const qualityOrder = { "excellent": 0, "good": 1, "basic": 2 };
314
+ return qualityOrder[a.qualityTier] - qualityOrder[b.qualityTier];
315
+ });
316
+ }
317
+ // Return best by priority within the sorted group
318
+ return this.selectByPriority(sortedTools);
319
+ }
320
+ /**
321
+ * Select tool by priority from a list
322
+ */
323
+ selectByPriority(tools) {
324
+ if (tools.length === 0)
325
+ return null;
326
+ tools.sort((a, b) => a.priority - b.priority);
327
+ const selected = tools[0];
328
+ if (this.preferences.verboseLogging) {
329
+ console.error(`Selected tool: ${selected.name} (${selected.provider})`);
330
+ }
331
+ return selected;
332
+ }
333
+ /**
334
+ * Get fallback chain for a category
335
+ */
336
+ getFallbackChain(category) {
337
+ const tools = this.registry[category] || [];
338
+ const availableTools = tools
339
+ .filter(t => t.checkAvailability())
340
+ .sort((a, b) => a.priority - b.priority);
341
+ if (this.preferences.verboseLogging) {
342
+ console.error(`Fallback chain for ${category}:`, availableTools.map(t => t.name).join(" -> "));
343
+ }
344
+ return availableTools;
345
+ }
346
+ /**
347
+ * Get all available tools
348
+ */
349
+ getAllAvailableTools() {
350
+ const allTools = [];
351
+ Object.values(this.registry).forEach(categoryTools => {
352
+ categoryTools.forEach(tool => {
353
+ if (tool.checkAvailability() && !allTools.some(t => t.name === tool.name)) {
354
+ allTools.push(tool);
355
+ }
356
+ });
357
+ });
358
+ return allTools;
359
+ }
360
+ /**
361
+ * Get tool by name
362
+ */
363
+ getToolByName(name) {
364
+ // Check cache first
365
+ if (this.toolCache.has(name)) {
366
+ return this.toolCache.get(name);
367
+ }
368
+ // Search in registry
369
+ for (const categoryTools of Object.values(this.registry)) {
370
+ const tool = categoryTools.find(t => t.name === name);
371
+ if (tool) {
372
+ this.toolCache.set(name, tool);
373
+ return tool;
374
+ }
375
+ }
376
+ return null;
377
+ }
378
+ /**
379
+ * Get status report
380
+ */
381
+ getStatus() {
382
+ const providers = new Set();
383
+ const categories = Object.keys(this.registry);
384
+ let totalAvailable = 0;
385
+ let totalTools = 0;
386
+ const report = ["# Tool Router Status\n"];
387
+ categories.forEach(category => {
388
+ const tools = this.registry[category];
389
+ const available = tools.filter(t => t.checkAvailability());
390
+ report.push(`\n## ${category.toUpperCase()}`);
391
+ report.push(`Available: ${available.length}/${tools.length}`);
392
+ available.forEach(tool => {
393
+ providers.add(tool.provider);
394
+ report.push(` ✓ ${tool.name} (${tool.provider})`);
395
+ });
396
+ const unavailable = tools.filter(t => !t.checkAvailability());
397
+ if (unavailable.length > 0) {
398
+ unavailable.forEach(tool => {
399
+ report.push(` ✗ ${tool.name} (${tool.provider}) - Not configured`);
400
+ });
401
+ }
402
+ totalAvailable += available.length;
403
+ totalTools += tools.length;
404
+ });
405
+ report.unshift(`\nTotal: ${totalAvailable}/${totalTools} tools available`);
406
+ report.unshift(`Providers: ${Array.from(providers).join(", ")}`);
407
+ return report.join("\n");
408
+ }
409
+ /**
410
+ * Get recommendation for a task
411
+ */
412
+ getRecommendation(task) {
413
+ // Simple keyword-based category detection
414
+ const taskLower = task.toLowerCase();
415
+ let category;
416
+ if (taskLower.includes("code") || taskLower.includes("implement") || taskLower.includes("function")) {
417
+ category = ToolCategory.CODE;
418
+ }
419
+ else if (taskLower.includes("debug") || taskLower.includes("fix") || taskLower.includes("error")) {
420
+ category = ToolCategory.DEBUG;
421
+ }
422
+ else if (taskLower.includes("brainstorm") || taskLower.includes("idea") || taskLower.includes("creative")) {
423
+ category = ToolCategory.BRAINSTORM;
424
+ }
425
+ else if (taskLower.includes("search") || taskLower.includes("find") || taskLower.includes("research")) {
426
+ category = ToolCategory.SEARCH;
427
+ }
428
+ else if (taskLower.includes("analyze") || taskLower.includes("compare") || taskLower.includes("review")) {
429
+ category = ToolCategory.ANALYSIS;
430
+ }
431
+ else {
432
+ category = ToolCategory.REASONING;
433
+ }
434
+ const tool = this.getBestTool(category);
435
+ const alternatives = this.getFallbackChain(category).slice(1, 4); // Top 3 alternatives
436
+ return {
437
+ category,
438
+ tool,
439
+ alternatives
440
+ };
441
+ }
442
+ }
443
+ // Export singleton instance with default preferences
444
+ export const toolRouter = new ToolRouter();