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,46 @@
1
+ /**
2
+ * Tool Invocation Handler
3
+ * Handles actual tool execution via tool-mapper
4
+ * Subscribes to workflow.tool.invoke events
5
+ */
6
+ import { WorkflowEvents } from '../events/WorkflowEventBus.js';
7
+ export class ToolInvocationHandler {
8
+ constructor(eventBus) {
9
+ this.eventBus = eventBus;
10
+ // Subscribe to tool invoke events
11
+ this.eventBus.subscribe(WorkflowEvents.TOOL_INVOKED, this.handleToolInvoke.bind(this));
12
+ }
13
+ async handleToolInvoke(event) {
14
+ const { stepName, tool, input, options } = event;
15
+ const startTime = Date.now();
16
+ try {
17
+ // Dynamic import to avoid circular dependencies
18
+ const { executeWorkflowTool } = await import('../../tool-mapper.js');
19
+ console.error(`[ToolInvocation] Executing ${tool} for step ${stepName}`);
20
+ // Execute the tool
21
+ const toolResult = await executeWorkflowTool(tool, input, options);
22
+ const duration = Date.now() - startTime;
23
+ // Publish success event
24
+ await this.eventBus.publish(WorkflowEvents.TOOL_SUCCESS, {
25
+ stepName,
26
+ success: true,
27
+ result: toolResult.result,
28
+ modelUsed: toolResult.modelUsed,
29
+ duration,
30
+ tokensUsed: 0, // TODO: Extract from toolResult if available
31
+ cost: 0 // TODO: Calculate based on model and tokens
32
+ });
33
+ }
34
+ catch (error) {
35
+ const duration = Date.now() - startTime;
36
+ console.error(`[ToolInvocation] Error executing ${tool} for step ${stepName}:`, error);
37
+ // Publish failure event
38
+ await this.eventBus.publish(WorkflowEvents.TOOL_FAILURE, {
39
+ stepName,
40
+ success: false,
41
+ error: error,
42
+ duration
43
+ });
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Interface for automatic workflow synthesis
3
+ * Summarizes large multi-step workflow outputs to bypass MCP 25k token limit
4
+ */
5
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Interface for resolving step parameters (model, temperature, maxTokens)
3
+ * Handles interpolation of ${variable} syntax in step configuration
4
+ */
5
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Interface for variable interpolation in workflow templates
3
+ * Handles ${variable} and ${step.output} syntax in strings
4
+ */
5
+ export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Interface for workflow discovery and loading
3
+ */
4
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Interface for workflow file management
3
+ * Handles file references, output saving, and manifest updates
4
+ */
5
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Interface for formatting workflow execution results
3
+ * Supports multiple output formats (summary, detailed, JSON)
4
+ */
5
+ export {};
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Workflow State Machine
3
+ * Manages workflow state transitions with event emission
4
+ * Follows CircuitBreaker pattern (extends EventEmitter)
5
+ */
6
+ import { EventEmitter } from 'events';
7
+ import { WorkflowState } from './interfaces/IStateMachine.js';
8
+ export class WorkflowStateMachine extends EventEmitter {
9
+ constructor() {
10
+ super();
11
+ this.currentState = WorkflowState.INITIALIZED;
12
+ this.stateHistory = [];
13
+ // Valid state transitions (adjacency list)
14
+ this.validTransitions = new Map([
15
+ [WorkflowState.INITIALIZED, [
16
+ WorkflowState.VALIDATING,
17
+ WorkflowState.FAILED
18
+ ]],
19
+ [WorkflowState.VALIDATING, [
20
+ WorkflowState.RUNNING,
21
+ WorkflowState.FAILED
22
+ ]],
23
+ [WorkflowState.RUNNING, [
24
+ WorkflowState.STEP_EXECUTING,
25
+ WorkflowState.SYNTHESIZING,
26
+ WorkflowState.COMPLETED,
27
+ WorkflowState.FAILED,
28
+ WorkflowState.PAUSED
29
+ ]],
30
+ [WorkflowState.STEP_EXECUTING, [
31
+ WorkflowState.WAITING,
32
+ WorkflowState.RUNNING,
33
+ WorkflowState.RETRYING,
34
+ WorkflowState.FAILED
35
+ ]],
36
+ [WorkflowState.WAITING, [
37
+ WorkflowState.STEP_EXECUTING,
38
+ WorkflowState.RUNNING,
39
+ WorkflowState.FAILED
40
+ ]],
41
+ [WorkflowState.RETRYING, [
42
+ WorkflowState.STEP_EXECUTING,
43
+ WorkflowState.FAILED
44
+ ]],
45
+ [WorkflowState.SYNTHESIZING, [
46
+ WorkflowState.STEP_EXECUTING,
47
+ WorkflowState.COMPLETED,
48
+ WorkflowState.FAILED
49
+ ]],
50
+ [WorkflowState.PAUSED, [
51
+ WorkflowState.RUNNING,
52
+ WorkflowState.FAILED
53
+ ]],
54
+ [WorkflowState.COMPLETED, []],
55
+ [WorkflowState.FAILED, []]
56
+ ]);
57
+ this.recordState(WorkflowState.INITIALIZED, {
58
+ workflowId: '',
59
+ workflowName: ''
60
+ });
61
+ }
62
+ getCurrentState() {
63
+ return this.currentState;
64
+ }
65
+ canTransition(to) {
66
+ const allowedStates = this.validTransitions.get(this.currentState) || [];
67
+ return allowedStates.includes(to);
68
+ }
69
+ transition(to, context) {
70
+ const from = this.currentState;
71
+ // Validate transition
72
+ if (!this.canTransition(to)) {
73
+ throw new Error(`Invalid state transition: ${from} -> ${to}. ` +
74
+ `Allowed transitions from ${from}: ${this.validTransitions.get(from)?.join(', ') || 'none'}`);
75
+ }
76
+ // Update state
77
+ this.currentState = to;
78
+ this.recordState(to, context);
79
+ // Emit state change event
80
+ this.emit('state:changed', {
81
+ from,
82
+ to,
83
+ context,
84
+ timestamp: new Date()
85
+ });
86
+ // Emit specific workflow lifecycle events
87
+ this.emitLifecycleEvents(to, context);
88
+ }
89
+ emitLifecycleEvents(state, context) {
90
+ switch (state) {
91
+ case WorkflowState.VALIDATING:
92
+ this.emit('workflow:validating', context);
93
+ break;
94
+ case WorkflowState.RUNNING:
95
+ this.emit('workflow:started', context);
96
+ break;
97
+ case WorkflowState.STEP_EXECUTING:
98
+ this.emit('step:started', {
99
+ stepName: context.currentStep,
100
+ stepIndex: context.stepIndex,
101
+ totalSteps: context.totalSteps,
102
+ workflowId: context.workflowId
103
+ });
104
+ break;
105
+ case WorkflowState.WAITING:
106
+ this.emit('step:waiting', {
107
+ stepName: context.currentStep,
108
+ reason: context.metadata?.waitReason || 'dependency'
109
+ });
110
+ break;
111
+ case WorkflowState.RETRYING:
112
+ this.emit('step:retrying', {
113
+ stepName: context.currentStep,
114
+ attempt: context.metadata?.retryAttempt || 1,
115
+ maxAttempts: context.metadata?.maxRetries || 3,
116
+ error: context.error
117
+ });
118
+ break;
119
+ case WorkflowState.SYNTHESIZING:
120
+ this.emit('workflow:synthesizing', {
121
+ workflowId: context.workflowId,
122
+ reason: context.metadata?.synthesisReason || 'auto'
123
+ });
124
+ break;
125
+ case WorkflowState.COMPLETED:
126
+ this.emit('workflow:completed', {
127
+ workflowId: context.workflowId,
128
+ workflowName: context.workflowName,
129
+ totalSteps: context.totalSteps,
130
+ duration: this.calculateDuration()
131
+ });
132
+ break;
133
+ case WorkflowState.FAILED:
134
+ this.emit('workflow:failed', {
135
+ workflowId: context.workflowId,
136
+ workflowName: context.workflowName,
137
+ error: context.error,
138
+ failedAt: context.currentStep,
139
+ duration: this.calculateDuration()
140
+ });
141
+ break;
142
+ case WorkflowState.PAUSED:
143
+ this.emit('workflow:paused', {
144
+ workflowId: context.workflowId,
145
+ pausedAt: context.currentStep
146
+ });
147
+ break;
148
+ }
149
+ }
150
+ getStateHistory() {
151
+ return [...this.stateHistory];
152
+ }
153
+ reset() {
154
+ this.currentState = WorkflowState.INITIALIZED;
155
+ this.stateHistory = [];
156
+ this.recordState(WorkflowState.INITIALIZED, {
157
+ workflowId: '',
158
+ workflowName: ''
159
+ });
160
+ this.emit('state:reset');
161
+ }
162
+ recordState(state, context) {
163
+ this.stateHistory.push({
164
+ state,
165
+ timestamp: new Date(),
166
+ context
167
+ });
168
+ }
169
+ calculateDuration() {
170
+ if (this.stateHistory.length < 2)
171
+ return 0;
172
+ const start = this.stateHistory[0].timestamp.getTime();
173
+ const end = this.stateHistory[this.stateHistory.length - 1].timestamp.getTime();
174
+ return end - start;
175
+ }
176
+ /**
177
+ * Get human-readable state description
178
+ */
179
+ getStateDescription() {
180
+ const descriptions = {
181
+ [WorkflowState.INITIALIZED]: 'Ready to start',
182
+ [WorkflowState.VALIDATING]: 'Validating workflow configuration',
183
+ [WorkflowState.RUNNING]: 'Running workflow',
184
+ [WorkflowState.STEP_EXECUTING]: 'Executing step',
185
+ [WorkflowState.WAITING]: 'Waiting for dependencies',
186
+ [WorkflowState.RETRYING]: 'Retrying failed step',
187
+ [WorkflowState.SYNTHESIZING]: 'Synthesizing results',
188
+ [WorkflowState.COMPLETED]: 'Completed successfully',
189
+ [WorkflowState.FAILED]: 'Failed with errors',
190
+ [WorkflowState.PAUSED]: 'Paused'
191
+ };
192
+ return descriptions[this.currentState];
193
+ }
194
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * State Machine Interface
3
+ * Defines contract for workflow state management
4
+ */
5
+ export var WorkflowState;
6
+ (function (WorkflowState) {
7
+ WorkflowState["INITIALIZED"] = "INITIALIZED";
8
+ WorkflowState["VALIDATING"] = "VALIDATING";
9
+ WorkflowState["RUNNING"] = "RUNNING";
10
+ WorkflowState["STEP_EXECUTING"] = "STEP_EXECUTING";
11
+ WorkflowState["WAITING"] = "WAITING";
12
+ WorkflowState["RETRYING"] = "RETRYING";
13
+ WorkflowState["SYNTHESIZING"] = "SYNTHESIZING";
14
+ WorkflowState["COMPLETED"] = "COMPLETED";
15
+ WorkflowState["FAILED"] = "FAILED";
16
+ WorkflowState["PAUSED"] = "PAUSED";
17
+ })(WorkflowState || (WorkflowState = {}));
@@ -0,0 +1,373 @@
1
+ import { EventEmitter } from 'events';
2
+ /**
3
+ * Collection of predefined fallback strategies
4
+ */
5
+ export class FallbackStrategies {
6
+ constructor() {
7
+ this.strategies = [];
8
+ this.initializeStrategies();
9
+ }
10
+ initializeStrategies() {
11
+ // 1. Use cached results fallback
12
+ this.strategies.push({
13
+ name: 'cached-results',
14
+ description: 'Return previously cached successful results',
15
+ priority: 1,
16
+ canHandle: (context) => {
17
+ return context.previousResults !== undefined &&
18
+ context.previousResults.length > 0;
19
+ },
20
+ execute: async (context) => {
21
+ return {
22
+ result: context.previousResults[context.previousResults.length - 1],
23
+ fallbackUsed: 'cached-results',
24
+ warning: 'Using cached results due to service failure'
25
+ };
26
+ }
27
+ });
28
+ // 2. Use simpler alternative tool
29
+ this.strategies.push({
30
+ name: 'simpler-tool',
31
+ description: 'Use a simpler, more reliable tool',
32
+ priority: 2,
33
+ canHandle: (context) => {
34
+ const complexTools = ['focus', 'architect', 'verifier'];
35
+ return complexTools.includes(context.stepId);
36
+ },
37
+ execute: async (context) => {
38
+ const simplifiedTools = {
39
+ 'focus': 'think',
40
+ 'architect': 'code_reviewer',
41
+ 'verifier': 'auditor',
42
+ 'perplexity_research': 'perplexity_ask',
43
+ 'focus_deep_research': 'scout'
44
+ };
45
+ return {
46
+ alternativeTool: simplifiedTools[context.stepId] || 'think',
47
+ fallbackUsed: 'simpler-tool',
48
+ warning: `Using simpler alternative due to ${context.stepId} failure`
49
+ };
50
+ }
51
+ });
52
+ // 3. Use cheaper model fallback
53
+ this.strategies.push({
54
+ name: 'cheaper-model',
55
+ description: 'Fallback to GPT-5 Nano for cost efficiency',
56
+ priority: 3,
57
+ canHandle: (context) => {
58
+ const expensiveModels = ['gpt5'];
59
+ return expensiveModels.some(model => context.stepId.includes(model));
60
+ },
61
+ execute: async (context) => {
62
+ return {
63
+ alternativeTool: 'gpt-5-nano',
64
+ fallbackUsed: 'cheaper-model',
65
+ warning: 'Falling back to GPT-5 Nano for cost efficiency'
66
+ };
67
+ }
68
+ });
69
+ // 4. Retry with reduced scope
70
+ this.strategies.push({
71
+ name: 'reduced-scope',
72
+ description: 'Retry with reduced complexity or scope',
73
+ priority: 4,
74
+ canHandle: (context) => {
75
+ return context.attemptNumber < 3 &&
76
+ context.originalQuery !== undefined;
77
+ },
78
+ execute: async (context) => {
79
+ // Simplify the query by taking first sentence or reducing length
80
+ const simplifiedQuery = context.originalQuery
81
+ .split('.')[0]
82
+ .substring(0, 200);
83
+ return {
84
+ simplifiedQuery,
85
+ fallbackUsed: 'reduced-scope',
86
+ warning: 'Retrying with reduced query scope'
87
+ };
88
+ }
89
+ });
90
+ // 5. Basic error response
91
+ this.strategies.push({
92
+ name: 'basic-response',
93
+ description: 'Return basic error information',
94
+ priority: 99,
95
+ canHandle: () => true, // Always can handle as last resort
96
+ execute: async (context) => {
97
+ return {
98
+ error: true,
99
+ fallbackUsed: 'basic-response',
100
+ message: `Service ${context.stepId} is temporarily unavailable`,
101
+ reason: context.failureReason,
102
+ suggestion: 'Please try again later or use a different approach'
103
+ };
104
+ }
105
+ });
106
+ }
107
+ /**
108
+ * Get the best fallback strategy for the given context
109
+ */
110
+ getBestStrategy(context) {
111
+ // Sort by priority and find first that can handle
112
+ const availableStrategies = this.strategies
113
+ .filter(s => s.canHandle(context))
114
+ .sort((a, b) => a.priority - b.priority);
115
+ return availableStrategies[0] || null;
116
+ }
117
+ /**
118
+ * Execute fallback with the best available strategy
119
+ */
120
+ async executeFallback(context) {
121
+ const strategy = this.getBestStrategy(context);
122
+ if (!strategy) {
123
+ throw new Error(`No fallback strategy available for ${context.stepId}`);
124
+ }
125
+ console.error(`[Fallback] Using strategy: ${strategy.name} for ${context.stepId}`);
126
+ return strategy.execute(context);
127
+ }
128
+ /**
129
+ * Add custom fallback strategy
130
+ */
131
+ addStrategy(strategy) {
132
+ this.strategies.push(strategy);
133
+ // Re-sort by priority
134
+ this.strategies.sort((a, b) => a.priority - b.priority);
135
+ }
136
+ /**
137
+ * Remove a strategy by name
138
+ */
139
+ removeStrategy(name) {
140
+ this.strategies = this.strategies.filter(s => s.name !== name);
141
+ }
142
+ /**
143
+ * Get all registered strategies
144
+ */
145
+ getAllStrategies() {
146
+ return [...this.strategies];
147
+ }
148
+ }
149
+ /**
150
+ * Health monitoring for circuit breakers
151
+ */
152
+ export class HealthMonitor extends EventEmitter {
153
+ constructor() {
154
+ super(...arguments);
155
+ this.healthChecks = new Map();
156
+ this.healthStatus = new Map();
157
+ this.alertThresholds = {
158
+ consecutiveFailures: 3,
159
+ failureRate: 0.5,
160
+ responseTime: 10000 // 10 seconds
161
+ };
162
+ }
163
+ /**
164
+ * Start monitoring a service
165
+ */
166
+ startMonitoring(serviceId, checkFn, intervalMs = 30000) {
167
+ // Clear existing check if any
168
+ this.stopMonitoring(serviceId);
169
+ // Initial check
170
+ this.performHealthCheck(serviceId, checkFn);
171
+ // Set up interval
172
+ const interval = setInterval(() => {
173
+ this.performHealthCheck(serviceId, checkFn);
174
+ }, intervalMs);
175
+ this.healthChecks.set(serviceId, interval);
176
+ }
177
+ /**
178
+ * Stop monitoring a service
179
+ */
180
+ stopMonitoring(serviceId) {
181
+ const interval = this.healthChecks.get(serviceId);
182
+ if (interval) {
183
+ clearInterval(interval);
184
+ this.healthChecks.delete(serviceId);
185
+ }
186
+ }
187
+ /**
188
+ * Perform a health check
189
+ */
190
+ async performHealthCheck(serviceId, checkFn) {
191
+ const startTime = Date.now();
192
+ try {
193
+ const isHealthy = await checkFn();
194
+ const responseTime = Date.now() - startTime;
195
+ const wasHealthy = this.healthStatus.get(serviceId);
196
+ this.healthStatus.set(serviceId, isHealthy);
197
+ // Emit events based on health changes
198
+ if (wasHealthy === false && isHealthy) {
199
+ this.emit('service-recovered', { serviceId, responseTime });
200
+ }
201
+ else if (wasHealthy === true && !isHealthy) {
202
+ this.emit('service-degraded', { serviceId, responseTime });
203
+ }
204
+ // Check response time threshold
205
+ if (responseTime > this.alertThresholds.responseTime) {
206
+ this.emit('slow-response', { serviceId, responseTime });
207
+ }
208
+ }
209
+ catch (error) {
210
+ this.healthStatus.set(serviceId, false);
211
+ this.emit('health-check-failed', {
212
+ serviceId,
213
+ error: error.message
214
+ });
215
+ }
216
+ }
217
+ /**
218
+ * Get current health status
219
+ */
220
+ getHealthStatus() {
221
+ return new Map(this.healthStatus);
222
+ }
223
+ /**
224
+ * Check if a service is healthy
225
+ */
226
+ isHealthy(serviceId) {
227
+ return this.healthStatus.get(serviceId) || false;
228
+ }
229
+ /**
230
+ * Get overall system health score (0-1)
231
+ */
232
+ getSystemHealthScore() {
233
+ if (this.healthStatus.size === 0)
234
+ return 1;
235
+ let healthyCount = 0;
236
+ for (const isHealthy of this.healthStatus.values()) {
237
+ if (isHealthy)
238
+ healthyCount++;
239
+ }
240
+ return healthyCount / this.healthStatus.size;
241
+ }
242
+ /**
243
+ * Clean up all monitoring
244
+ */
245
+ cleanup() {
246
+ for (const serviceId of this.healthChecks.keys()) {
247
+ this.stopMonitoring(serviceId);
248
+ }
249
+ this.healthStatus.clear();
250
+ }
251
+ }
252
+ /**
253
+ * Proactive alert system for circuit breakers
254
+ */
255
+ export class AlertManager extends EventEmitter {
256
+ constructor() {
257
+ super();
258
+ this.alerts = new Map();
259
+ this.alertRules = new Map();
260
+ this.initializeDefaultRules();
261
+ }
262
+ initializeDefaultRules() {
263
+ // Critical failure rate
264
+ this.alertRules.set('critical-failure-rate', (stats) => {
265
+ return stats.failureRate > 0.8;
266
+ });
267
+ // Multiple services down
268
+ this.alertRules.set('multiple-services-down', (health) => {
269
+ return health.openBreakers > 3;
270
+ });
271
+ // Cascade failure risk
272
+ this.alertRules.set('cascade-risk', (stats) => {
273
+ return stats.halfOpenBreakers > 2 && stats.openBreakers > 1;
274
+ });
275
+ // Low system health
276
+ this.alertRules.set('low-system-health', (health) => {
277
+ return health.healthScore < 0.5;
278
+ });
279
+ }
280
+ /**
281
+ * Check alerts based on current state
282
+ */
283
+ checkAlerts(data) {
284
+ for (const [ruleName, ruleFn] of this.alertRules.entries()) {
285
+ if (ruleFn(data)) {
286
+ this.triggerAlert(ruleName, data);
287
+ }
288
+ }
289
+ }
290
+ /**
291
+ * Trigger an alert
292
+ */
293
+ triggerAlert(alertType, data) {
294
+ const alert = {
295
+ type: alertType,
296
+ timestamp: Date.now(),
297
+ data,
298
+ severity: this.getAlertSeverity(alertType)
299
+ };
300
+ // Store alert
301
+ if (!this.alerts.has(alertType)) {
302
+ this.alerts.set(alertType, []);
303
+ }
304
+ this.alerts.get(alertType).push(alert);
305
+ // Emit alert event
306
+ this.emit('alert', alert);
307
+ // Log critical alerts
308
+ if (alert.severity === 'critical') {
309
+ console.error(`[CRITICAL ALERT] ${alertType}:`, data);
310
+ }
311
+ }
312
+ /**
313
+ * Get alert severity
314
+ */
315
+ getAlertSeverity(alertType) {
316
+ const criticalAlerts = ['multiple-services-down', 'cascade-risk'];
317
+ const warningAlerts = ['critical-failure-rate', 'low-system-health'];
318
+ if (criticalAlerts.includes(alertType))
319
+ return 'critical';
320
+ if (warningAlerts.includes(alertType))
321
+ return 'warning';
322
+ return 'info';
323
+ }
324
+ /**
325
+ * Get recent alerts
326
+ */
327
+ getRecentAlerts(minutes = 5) {
328
+ const cutoff = Date.now() - (minutes * 60 * 1000);
329
+ const recent = [];
330
+ for (const alerts of this.alerts.values()) {
331
+ recent.push(...alerts.filter(a => a.timestamp > cutoff));
332
+ }
333
+ return recent.sort((a, b) => b.timestamp - a.timestamp);
334
+ }
335
+ /**
336
+ * Clear old alerts
337
+ */
338
+ clearOldAlerts(hours = 24) {
339
+ const cutoff = Date.now() - (hours * 60 * 60 * 1000);
340
+ for (const [type, alerts] of this.alerts.entries()) {
341
+ const filtered = alerts.filter(a => a.timestamp > cutoff);
342
+ if (filtered.length > 0) {
343
+ this.alerts.set(type, filtered);
344
+ }
345
+ else {
346
+ this.alerts.delete(type);
347
+ }
348
+ }
349
+ }
350
+ /**
351
+ * Add custom alert rule
352
+ */
353
+ addRule(name, ruleFn) {
354
+ this.alertRules.set(name, ruleFn);
355
+ }
356
+ /**
357
+ * Remove alert rule
358
+ */
359
+ removeRule(name) {
360
+ this.alertRules.delete(name);
361
+ }
362
+ }
363
+ // Export a singleton instance for global use
364
+ export const fallbackStrategies = new FallbackStrategies();
365
+ export const healthMonitor = new HealthMonitor();
366
+ export const alertManager = new AlertManager();
367
+ // Set up connections between components
368
+ healthMonitor.on('service-degraded', (data) => {
369
+ alertManager.checkAlerts({ serviceDown: data.serviceId });
370
+ });
371
+ healthMonitor.on('slow-response', (data) => {
372
+ alertManager.checkAlerts({ slowService: data.serviceId, responseTime: data.responseTime });
373
+ });