claude-flow 2.0.0-alpha.65 → 2.0.0-alpha.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/cache/agent-pool.json +33 -0
- package/.claude/cache/memory-optimization.json +19 -0
- package/.claude/cache/neural-optimization.json +25 -0
- package/.claude/cache/optimized-hooks.json +19 -0
- package/.claude/cache/parallel-processing.json +26 -0
- package/.claude/optimized-settings.json +270 -0
- package/.claude/settings-enhanced.json +278 -0
- package/.claude/settings.json +105 -8
- package/CHANGELOG.md +40 -0
- package/bin/claude-flow +1 -1
- package/dist/cli/simple-commands/hive-mind.js +1 -1
- package/dist/cli/simple-commands/hive-mind.js.map +1 -1
- package/dist/cli/simple-commands/hooks.js +6 -4
- package/dist/cli/simple-commands/hooks.js.map +1 -1
- package/dist/providers/anthropic-provider.d.ts +27 -0
- package/dist/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/providers/anthropic-provider.js +247 -0
- package/dist/providers/anthropic-provider.js.map +1 -0
- package/dist/providers/base-provider.d.ts +134 -0
- package/dist/providers/base-provider.d.ts.map +1 -0
- package/dist/providers/base-provider.js +407 -0
- package/dist/providers/base-provider.js.map +1 -0
- package/dist/providers/cohere-provider.d.ts +28 -0
- package/dist/providers/cohere-provider.d.ts.map +1 -0
- package/dist/providers/cohere-provider.js +407 -0
- package/dist/providers/cohere-provider.js.map +1 -0
- package/dist/providers/google-provider.d.ts +23 -0
- package/dist/providers/google-provider.d.ts.map +1 -0
- package/dist/providers/google-provider.js +362 -0
- package/dist/providers/google-provider.js.map +1 -0
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +18 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/ollama-provider.d.ts +23 -0
- package/dist/providers/ollama-provider.d.ts.map +1 -0
- package/dist/providers/ollama-provider.js +374 -0
- package/dist/providers/ollama-provider.js.map +1 -0
- package/dist/providers/openai-provider.d.ts +23 -0
- package/dist/providers/openai-provider.d.ts.map +1 -0
- package/dist/providers/openai-provider.js +349 -0
- package/dist/providers/openai-provider.js.map +1 -0
- package/dist/providers/provider-manager.d.ts +139 -0
- package/dist/providers/provider-manager.d.ts.map +1 -0
- package/dist/providers/provider-manager.js +513 -0
- package/dist/providers/provider-manager.js.map +1 -0
- package/dist/providers/types.d.ts +356 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +61 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/utils.d.ts +37 -0
- package/dist/providers/utils.d.ts.map +1 -0
- package/dist/providers/utils.js +322 -0
- package/dist/providers/utils.js.map +1 -0
- package/dist/services/agentic-flow-hooks/hook-manager.d.ts +70 -0
- package/dist/services/agentic-flow-hooks/hook-manager.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/hook-manager.js +512 -0
- package/dist/services/agentic-flow-hooks/hook-manager.js.map +1 -0
- package/dist/services/agentic-flow-hooks/index.d.ts +36 -0
- package/dist/services/agentic-flow-hooks/index.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/index.js +325 -0
- package/dist/services/agentic-flow-hooks/index.js.map +1 -0
- package/dist/services/agentic-flow-hooks/llm-hooks.d.ts +33 -0
- package/dist/services/agentic-flow-hooks/llm-hooks.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/llm-hooks.js +415 -0
- package/dist/services/agentic-flow-hooks/llm-hooks.js.map +1 -0
- package/dist/services/agentic-flow-hooks/memory-hooks.d.ts +45 -0
- package/dist/services/agentic-flow-hooks/memory-hooks.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/memory-hooks.js +532 -0
- package/dist/services/agentic-flow-hooks/memory-hooks.js.map +1 -0
- package/dist/services/agentic-flow-hooks/neural-hooks.d.ts +39 -0
- package/dist/services/agentic-flow-hooks/neural-hooks.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/neural-hooks.js +561 -0
- package/dist/services/agentic-flow-hooks/neural-hooks.js.map +1 -0
- package/dist/services/agentic-flow-hooks/performance-hooks.d.ts +33 -0
- package/dist/services/agentic-flow-hooks/performance-hooks.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/performance-hooks.js +621 -0
- package/dist/services/agentic-flow-hooks/performance-hooks.js.map +1 -0
- package/dist/services/agentic-flow-hooks/types.d.ts +379 -0
- package/dist/services/agentic-flow-hooks/types.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/types.js +8 -0
- package/dist/services/agentic-flow-hooks/types.js.map +1 -0
- package/dist/services/agentic-flow-hooks/workflow-hooks.d.ts +39 -0
- package/dist/services/agentic-flow-hooks/workflow-hooks.d.ts.map +1 -0
- package/dist/services/agentic-flow-hooks/workflow-hooks.js +742 -0
- package/dist/services/agentic-flow-hooks/workflow-hooks.js.map +1 -0
- package/package.json +2 -2
- package/scripts/install-arm64.js +78 -0
- package/scripts/optimize-performance.js +400 -0
- package/scripts/performance-monitor.js +263 -0
- package/src/cli/help-text.js +1 -1
- package/src/cli/simple-cli.js +1 -1
- package/src/cli/simple-commands/hive-mind.js +1 -1
- package/src/cli/simple-commands/hooks.js +8 -6
- package/src/providers/anthropic-provider.ts +282 -0
- package/src/providers/base-provider.ts +560 -0
- package/src/providers/cohere-provider.ts +521 -0
- package/src/providers/google-provider.ts +477 -0
- package/src/providers/index.ts +21 -0
- package/src/providers/ollama-provider.ts +489 -0
- package/src/providers/openai-provider.ts +476 -0
- package/src/providers/provider-manager.ts +654 -0
- package/src/providers/types.ts +531 -0
- package/src/providers/utils.ts +376 -0
- package/src/services/agentic-flow-hooks/hook-manager.ts +701 -0
- package/src/services/agentic-flow-hooks/index.ts +386 -0
- package/src/services/agentic-flow-hooks/llm-hooks.ts +557 -0
- package/src/services/agentic-flow-hooks/memory-hooks.ts +710 -0
- package/src/services/agentic-flow-hooks/neural-hooks.ts +758 -0
- package/src/services/agentic-flow-hooks/performance-hooks.ts +827 -0
- package/src/services/agentic-flow-hooks/types.ts +503 -0
- package/src/services/agentic-flow-hooks/workflow-hooks.ts +1026 -0
|
@@ -0,0 +1,1026 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-improving workflow hooks for agentic-flow
|
|
3
|
+
*
|
|
4
|
+
* Enables adaptive workflows with provider selection
|
|
5
|
+
* and continuous improvement based on outcomes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { agenticHookManager } from './hook-manager.js';
|
|
9
|
+
import type {
|
|
10
|
+
AgenticHookContext,
|
|
11
|
+
HookHandlerResult,
|
|
12
|
+
WorkflowHookPayload,
|
|
13
|
+
WorkflowDecision,
|
|
14
|
+
Learning,
|
|
15
|
+
SideEffect,
|
|
16
|
+
Pattern,
|
|
17
|
+
} from './types.js';
|
|
18
|
+
|
|
19
|
+
// ===== Workflow Start Hook =====
|
|
20
|
+
|
|
21
|
+
export const workflowStartHook = {
|
|
22
|
+
id: 'agentic-workflow-start',
|
|
23
|
+
type: 'workflow-start' as const,
|
|
24
|
+
priority: 100,
|
|
25
|
+
handler: async (
|
|
26
|
+
payload: WorkflowHookPayload,
|
|
27
|
+
context: AgenticHookContext
|
|
28
|
+
): Promise<HookHandlerResult> => {
|
|
29
|
+
const { workflowId, state } = payload;
|
|
30
|
+
|
|
31
|
+
const sideEffects: SideEffect[] = [];
|
|
32
|
+
|
|
33
|
+
// Load workflow history and learnings
|
|
34
|
+
const history = await loadWorkflowHistory(workflowId, context);
|
|
35
|
+
const learnings = await loadWorkflowLearnings(workflowId, context);
|
|
36
|
+
|
|
37
|
+
// Select optimal provider based on history
|
|
38
|
+
const provider = await selectOptimalProvider(
|
|
39
|
+
workflowId,
|
|
40
|
+
state,
|
|
41
|
+
history,
|
|
42
|
+
context
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Initialize workflow state
|
|
46
|
+
const enhancedState = {
|
|
47
|
+
...state,
|
|
48
|
+
startTime: Date.now(),
|
|
49
|
+
provider,
|
|
50
|
+
learnings: learnings.slice(-10), // Last 10 learnings
|
|
51
|
+
predictions: await generateWorkflowPredictions(workflowId, state, context),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Store workflow session
|
|
55
|
+
sideEffects.push({
|
|
56
|
+
type: 'memory',
|
|
57
|
+
action: 'store',
|
|
58
|
+
data: {
|
|
59
|
+
key: `workflow:session:${workflowId}:${context.sessionId}`,
|
|
60
|
+
value: enhancedState,
|
|
61
|
+
ttl: 86400, // 24 hours
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Track workflow start
|
|
66
|
+
sideEffects.push({
|
|
67
|
+
type: 'metric',
|
|
68
|
+
action: 'increment',
|
|
69
|
+
data: { name: `workflow.starts.${workflowId}` },
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
continue: true,
|
|
74
|
+
modified: true,
|
|
75
|
+
payload: {
|
|
76
|
+
...payload,
|
|
77
|
+
state: enhancedState,
|
|
78
|
+
},
|
|
79
|
+
sideEffects,
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// ===== Workflow Step Hook =====
|
|
85
|
+
|
|
86
|
+
export const workflowStepHook = {
|
|
87
|
+
id: 'agentic-workflow-step',
|
|
88
|
+
type: 'workflow-step' as const,
|
|
89
|
+
priority: 100,
|
|
90
|
+
handler: async (
|
|
91
|
+
payload: WorkflowHookPayload,
|
|
92
|
+
context: AgenticHookContext
|
|
93
|
+
): Promise<HookHandlerResult> => {
|
|
94
|
+
const { workflowId, step, state } = payload;
|
|
95
|
+
|
|
96
|
+
if (!step) {
|
|
97
|
+
return { continue: true };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const sideEffects: SideEffect[] = [];
|
|
101
|
+
|
|
102
|
+
// Measure step performance
|
|
103
|
+
const stepStart = Date.now();
|
|
104
|
+
|
|
105
|
+
// Check for step optimizations
|
|
106
|
+
const optimizations = await getStepOptimizations(
|
|
107
|
+
workflowId,
|
|
108
|
+
step,
|
|
109
|
+
context
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
if (optimizations.length > 0) {
|
|
113
|
+
// Apply step optimizations
|
|
114
|
+
const optimizedState = applyStepOptimizations(
|
|
115
|
+
state,
|
|
116
|
+
optimizations
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
sideEffects.push({
|
|
120
|
+
type: 'log',
|
|
121
|
+
action: 'write',
|
|
122
|
+
data: {
|
|
123
|
+
level: 'info',
|
|
124
|
+
message: `Applied ${optimizations.length} optimizations to step ${step}`,
|
|
125
|
+
data: { optimizations },
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
continue: true,
|
|
131
|
+
modified: true,
|
|
132
|
+
payload: {
|
|
133
|
+
...payload,
|
|
134
|
+
state: optimizedState,
|
|
135
|
+
},
|
|
136
|
+
sideEffects,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Track step execution
|
|
141
|
+
sideEffects.push({
|
|
142
|
+
type: 'memory',
|
|
143
|
+
action: 'store',
|
|
144
|
+
data: {
|
|
145
|
+
key: `workflow:step:${workflowId}:${step}:${Date.now()}`,
|
|
146
|
+
value: {
|
|
147
|
+
step,
|
|
148
|
+
state: summarizeState(state),
|
|
149
|
+
timestamp: Date.now(),
|
|
150
|
+
},
|
|
151
|
+
ttl: 86400,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
continue: true,
|
|
157
|
+
sideEffects,
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// ===== Workflow Decision Hook =====
|
|
163
|
+
|
|
164
|
+
export const workflowDecisionHook = {
|
|
165
|
+
id: 'agentic-workflow-decision',
|
|
166
|
+
type: 'workflow-decision' as const,
|
|
167
|
+
priority: 90,
|
|
168
|
+
handler: async (
|
|
169
|
+
payload: WorkflowHookPayload,
|
|
170
|
+
context: AgenticHookContext
|
|
171
|
+
): Promise<HookHandlerResult> => {
|
|
172
|
+
const { workflowId, decision, state } = payload;
|
|
173
|
+
|
|
174
|
+
if (!decision) {
|
|
175
|
+
return { continue: true };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const sideEffects: SideEffect[] = [];
|
|
179
|
+
|
|
180
|
+
// Enhance decision with historical data
|
|
181
|
+
const historicalOutcomes = await getDecisionOutcomes(
|
|
182
|
+
workflowId,
|
|
183
|
+
decision.point,
|
|
184
|
+
context
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Calculate confidence adjustments
|
|
188
|
+
const adjustedDecision = adjustDecisionConfidence(
|
|
189
|
+
decision,
|
|
190
|
+
historicalOutcomes
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// Generate alternative paths
|
|
194
|
+
const alternatives = await generateAlternativeDecisions(
|
|
195
|
+
workflowId,
|
|
196
|
+
decision,
|
|
197
|
+
state,
|
|
198
|
+
context
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
if (alternatives.length > 0) {
|
|
202
|
+
// Check if better alternative exists
|
|
203
|
+
const bestAlternative = alternatives.find(alt =>
|
|
204
|
+
alt.confidence > adjustedDecision.confidence * 1.2
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
if (bestAlternative) {
|
|
208
|
+
sideEffects.push({
|
|
209
|
+
type: 'notification',
|
|
210
|
+
action: 'emit',
|
|
211
|
+
data: {
|
|
212
|
+
event: 'workflow:decision:alternative',
|
|
213
|
+
data: {
|
|
214
|
+
original: adjustedDecision,
|
|
215
|
+
suggested: bestAlternative,
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Override with better decision
|
|
221
|
+
adjustedDecision.selected = bestAlternative.selected;
|
|
222
|
+
adjustedDecision.confidence = bestAlternative.confidence;
|
|
223
|
+
adjustedDecision.reasoning = `${adjustedDecision.reasoning} (AI-optimized)`;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Store decision for learning
|
|
228
|
+
sideEffects.push({
|
|
229
|
+
type: 'memory',
|
|
230
|
+
action: 'store',
|
|
231
|
+
data: {
|
|
232
|
+
key: `decision:${workflowId}:${decision.point}:${Date.now()}`,
|
|
233
|
+
value: {
|
|
234
|
+
...adjustedDecision,
|
|
235
|
+
alternatives,
|
|
236
|
+
state: summarizeState(state),
|
|
237
|
+
},
|
|
238
|
+
ttl: 604800, // 7 days
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// Track decision metrics
|
|
243
|
+
sideEffects.push({
|
|
244
|
+
type: 'metric',
|
|
245
|
+
action: 'update',
|
|
246
|
+
data: {
|
|
247
|
+
name: `workflow.decisions.confidence.${workflowId}`,
|
|
248
|
+
value: adjustedDecision.confidence,
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
continue: true,
|
|
254
|
+
modified: true,
|
|
255
|
+
payload: {
|
|
256
|
+
...payload,
|
|
257
|
+
decision: adjustedDecision,
|
|
258
|
+
},
|
|
259
|
+
sideEffects,
|
|
260
|
+
};
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// ===== Workflow Complete Hook =====
|
|
265
|
+
|
|
266
|
+
export const workflowCompleteHook = {
|
|
267
|
+
id: 'agentic-workflow-complete',
|
|
268
|
+
type: 'workflow-complete' as const,
|
|
269
|
+
priority: 100,
|
|
270
|
+
handler: async (
|
|
271
|
+
payload: WorkflowHookPayload,
|
|
272
|
+
context: AgenticHookContext
|
|
273
|
+
): Promise<HookHandlerResult> => {
|
|
274
|
+
const { workflowId, state, metrics } = payload;
|
|
275
|
+
|
|
276
|
+
const sideEffects: SideEffect[] = [];
|
|
277
|
+
|
|
278
|
+
// Calculate workflow performance
|
|
279
|
+
const performance = calculateWorkflowPerformance(state, metrics);
|
|
280
|
+
|
|
281
|
+
// Extract learnings from this execution
|
|
282
|
+
const learnings = await extractWorkflowLearnings(
|
|
283
|
+
workflowId,
|
|
284
|
+
state,
|
|
285
|
+
performance,
|
|
286
|
+
context
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
// Store learnings
|
|
290
|
+
for (const learning of learnings) {
|
|
291
|
+
sideEffects.push({
|
|
292
|
+
type: 'memory',
|
|
293
|
+
action: 'store',
|
|
294
|
+
data: {
|
|
295
|
+
key: `learning:${workflowId}:${learning.type}:${Date.now()}`,
|
|
296
|
+
value: learning,
|
|
297
|
+
ttl: 0, // Permanent
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Update workflow success patterns
|
|
303
|
+
if (performance.success) {
|
|
304
|
+
const pattern: Pattern = {
|
|
305
|
+
id: `workflow_success_${Date.now()}`,
|
|
306
|
+
type: 'success',
|
|
307
|
+
confidence: performance.score,
|
|
308
|
+
occurrences: 1,
|
|
309
|
+
context: {
|
|
310
|
+
workflowId,
|
|
311
|
+
provider: state.provider,
|
|
312
|
+
duration: metrics?.duration || 0,
|
|
313
|
+
decisions: countDecisions(state),
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
context.neural.patterns.add(pattern);
|
|
318
|
+
|
|
319
|
+
sideEffects.push({
|
|
320
|
+
type: 'neural',
|
|
321
|
+
action: 'train',
|
|
322
|
+
data: {
|
|
323
|
+
patterns: [pattern],
|
|
324
|
+
modelId: `workflow-optimizer-${workflowId}`,
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Generate improvement suggestions
|
|
330
|
+
const improvements = await generateImprovementSuggestions(
|
|
331
|
+
workflowId,
|
|
332
|
+
state,
|
|
333
|
+
performance,
|
|
334
|
+
learnings,
|
|
335
|
+
context
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
if (improvements.length > 0) {
|
|
339
|
+
sideEffects.push({
|
|
340
|
+
type: 'notification',
|
|
341
|
+
action: 'emit',
|
|
342
|
+
data: {
|
|
343
|
+
event: 'workflow:improvements:suggested',
|
|
344
|
+
data: {
|
|
345
|
+
workflowId,
|
|
346
|
+
improvements,
|
|
347
|
+
performance,
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Update workflow metrics
|
|
354
|
+
sideEffects.push(
|
|
355
|
+
{
|
|
356
|
+
type: 'metric',
|
|
357
|
+
action: 'update',
|
|
358
|
+
data: {
|
|
359
|
+
name: `workflow.completion.rate.${workflowId}`,
|
|
360
|
+
value: performance.success ? 1 : 0,
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
type: 'metric',
|
|
365
|
+
action: 'update',
|
|
366
|
+
data: {
|
|
367
|
+
name: `workflow.performance.score.${workflowId}`,
|
|
368
|
+
value: performance.score,
|
|
369
|
+
},
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
return {
|
|
374
|
+
continue: true,
|
|
375
|
+
sideEffects,
|
|
376
|
+
};
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
// ===== Workflow Error Hook =====
|
|
381
|
+
|
|
382
|
+
export const workflowErrorHook = {
|
|
383
|
+
id: 'agentic-workflow-error',
|
|
384
|
+
type: 'workflow-error' as const,
|
|
385
|
+
priority: 95,
|
|
386
|
+
handler: async (
|
|
387
|
+
payload: WorkflowHookPayload,
|
|
388
|
+
context: AgenticHookContext
|
|
389
|
+
): Promise<HookHandlerResult> => {
|
|
390
|
+
const { workflowId, error, state } = payload;
|
|
391
|
+
|
|
392
|
+
if (!error) {
|
|
393
|
+
return { continue: true };
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const sideEffects: SideEffect[] = [];
|
|
397
|
+
|
|
398
|
+
// Analyze error pattern
|
|
399
|
+
const errorPattern = await analyzeErrorPattern(
|
|
400
|
+
workflowId,
|
|
401
|
+
error,
|
|
402
|
+
state,
|
|
403
|
+
context
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
// Store error for learning
|
|
407
|
+
sideEffects.push({
|
|
408
|
+
type: 'memory',
|
|
409
|
+
action: 'store',
|
|
410
|
+
data: {
|
|
411
|
+
key: `error:${workflowId}:${Date.now()}`,
|
|
412
|
+
value: {
|
|
413
|
+
error: {
|
|
414
|
+
message: error.message,
|
|
415
|
+
stack: error.stack,
|
|
416
|
+
type: error.name,
|
|
417
|
+
},
|
|
418
|
+
pattern: errorPattern,
|
|
419
|
+
state: summarizeState(state),
|
|
420
|
+
timestamp: Date.now(),
|
|
421
|
+
},
|
|
422
|
+
ttl: 604800, // 7 days
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// Check for recovery strategies
|
|
427
|
+
const recovery = await findRecoveryStrategy(
|
|
428
|
+
workflowId,
|
|
429
|
+
error,
|
|
430
|
+
errorPattern,
|
|
431
|
+
context
|
|
432
|
+
);
|
|
433
|
+
|
|
434
|
+
if (recovery) {
|
|
435
|
+
sideEffects.push({
|
|
436
|
+
type: 'log',
|
|
437
|
+
action: 'write',
|
|
438
|
+
data: {
|
|
439
|
+
level: 'info',
|
|
440
|
+
message: 'Recovery strategy found',
|
|
441
|
+
data: recovery,
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
// Apply recovery
|
|
446
|
+
const recoveredState = applyRecoveryStrategy(state, recovery);
|
|
447
|
+
|
|
448
|
+
return {
|
|
449
|
+
continue: true,
|
|
450
|
+
modified: true,
|
|
451
|
+
payload: {
|
|
452
|
+
...payload,
|
|
453
|
+
state: recoveredState,
|
|
454
|
+
error: undefined, // Clear error after recovery
|
|
455
|
+
},
|
|
456
|
+
sideEffects,
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Learn from failure
|
|
461
|
+
const failureLearning: Learning = {
|
|
462
|
+
type: 'failure',
|
|
463
|
+
context: `Error in workflow ${workflowId}: ${error.message}`,
|
|
464
|
+
value: {
|
|
465
|
+
errorType: error.name,
|
|
466
|
+
state: summarizeState(state),
|
|
467
|
+
pattern: errorPattern,
|
|
468
|
+
},
|
|
469
|
+
applicability: errorPattern.confidence,
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
sideEffects.push({
|
|
473
|
+
type: 'memory',
|
|
474
|
+
action: 'store',
|
|
475
|
+
data: {
|
|
476
|
+
key: `learning:failure:${workflowId}:${Date.now()}`,
|
|
477
|
+
value: failureLearning,
|
|
478
|
+
ttl: 0, // Permanent
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
return {
|
|
483
|
+
continue: true,
|
|
484
|
+
sideEffects,
|
|
485
|
+
};
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
// ===== Helper Functions =====
|
|
490
|
+
|
|
491
|
+
async function loadWorkflowHistory(
|
|
492
|
+
workflowId: string,
|
|
493
|
+
context: AgenticHookContext
|
|
494
|
+
): Promise<any[]> {
|
|
495
|
+
const historyKey = `workflow:history:${workflowId}`;
|
|
496
|
+
return await context.memory.cache.get(historyKey) || [];
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
async function loadWorkflowLearnings(
|
|
500
|
+
workflowId: string,
|
|
501
|
+
context: AgenticHookContext
|
|
502
|
+
): Promise<Learning[]> {
|
|
503
|
+
const learningsKey = `workflow:learnings:${workflowId}`;
|
|
504
|
+
return await context.memory.cache.get(learningsKey) || [];
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
async function selectOptimalProvider(
|
|
508
|
+
workflowId: string,
|
|
509
|
+
state: any,
|
|
510
|
+
history: any[],
|
|
511
|
+
context: AgenticHookContext
|
|
512
|
+
): Promise<string> {
|
|
513
|
+
// Analyze historical performance by provider
|
|
514
|
+
const providerStats = new Map<string, { success: number; total: number }>();
|
|
515
|
+
|
|
516
|
+
for (const execution of history) {
|
|
517
|
+
const provider = execution.provider;
|
|
518
|
+
if (!provider) continue;
|
|
519
|
+
|
|
520
|
+
const stats = providerStats.get(provider) || { success: 0, total: 0 };
|
|
521
|
+
stats.total++;
|
|
522
|
+
if (execution.success) stats.success++;
|
|
523
|
+
providerStats.set(provider, stats);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Calculate success rates
|
|
527
|
+
let bestProvider = 'openai'; // Default
|
|
528
|
+
let bestRate = 0;
|
|
529
|
+
|
|
530
|
+
for (const [provider, stats] of providerStats) {
|
|
531
|
+
const rate = stats.success / stats.total;
|
|
532
|
+
if (rate > bestRate && stats.total >= 5) {
|
|
533
|
+
bestRate = rate;
|
|
534
|
+
bestProvider = provider;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Check current provider health
|
|
539
|
+
const healthKey = `provider:health:${bestProvider}`;
|
|
540
|
+
const health = await context.memory.cache.get(healthKey);
|
|
541
|
+
|
|
542
|
+
if (health && health.score < 0.5) {
|
|
543
|
+
// Provider unhealthy, select alternative
|
|
544
|
+
return selectAlternativeProvider(bestProvider, providerStats);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
return bestProvider;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
async function generateWorkflowPredictions(
|
|
551
|
+
workflowId: string,
|
|
552
|
+
state: any,
|
|
553
|
+
context: AgenticHookContext
|
|
554
|
+
): Promise<any> {
|
|
555
|
+
// Generate predictions for workflow execution
|
|
556
|
+
const predictions = {
|
|
557
|
+
estimatedDuration: 0,
|
|
558
|
+
successProbability: 0.7,
|
|
559
|
+
likelyBottlenecks: [],
|
|
560
|
+
recommendedOptimizations: [],
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
// Load historical durations
|
|
564
|
+
const history = await loadWorkflowHistory(workflowId, context);
|
|
565
|
+
if (history.length > 0) {
|
|
566
|
+
const durations = history
|
|
567
|
+
.filter(h => h.duration)
|
|
568
|
+
.map(h => h.duration);
|
|
569
|
+
|
|
570
|
+
if (durations.length > 0) {
|
|
571
|
+
predictions.estimatedDuration =
|
|
572
|
+
durations.reduce((a, b) => a + b, 0) / durations.length;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const successes = history.filter(h => h.success).length;
|
|
576
|
+
predictions.successProbability = successes / history.length;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
return predictions;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
async function getStepOptimizations(
|
|
583
|
+
workflowId: string,
|
|
584
|
+
step: string,
|
|
585
|
+
context: AgenticHookContext
|
|
586
|
+
): Promise<any[]> {
|
|
587
|
+
// Get optimizations for specific step
|
|
588
|
+
const optKey = `optimizations:${workflowId}:${step}`;
|
|
589
|
+
return await context.memory.cache.get(optKey) || [];
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function applyStepOptimizations(
|
|
593
|
+
state: any,
|
|
594
|
+
optimizations: any[]
|
|
595
|
+
): any {
|
|
596
|
+
let optimizedState = { ...state };
|
|
597
|
+
|
|
598
|
+
for (const opt of optimizations) {
|
|
599
|
+
switch (opt.type) {
|
|
600
|
+
case 'skip':
|
|
601
|
+
if (opt.condition && opt.condition(state)) {
|
|
602
|
+
optimizedState.skipSteps = [
|
|
603
|
+
...(optimizedState.skipSteps || []),
|
|
604
|
+
opt.target,
|
|
605
|
+
];
|
|
606
|
+
}
|
|
607
|
+
break;
|
|
608
|
+
|
|
609
|
+
case 'parallel':
|
|
610
|
+
optimizedState.parallelSteps = [
|
|
611
|
+
...(optimizedState.parallelSteps || []),
|
|
612
|
+
...opt.steps,
|
|
613
|
+
];
|
|
614
|
+
break;
|
|
615
|
+
|
|
616
|
+
case 'cache':
|
|
617
|
+
optimizedState.useCache = true;
|
|
618
|
+
optimizedState.cacheKeys = [
|
|
619
|
+
...(optimizedState.cacheKeys || []),
|
|
620
|
+
opt.key,
|
|
621
|
+
];
|
|
622
|
+
break;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
return optimizedState;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function summarizeState(state: any): any {
|
|
630
|
+
// Create summary of state for storage
|
|
631
|
+
return {
|
|
632
|
+
keys: Object.keys(state),
|
|
633
|
+
size: JSON.stringify(state).length,
|
|
634
|
+
hasError: !!state.error,
|
|
635
|
+
provider: state.provider,
|
|
636
|
+
timestamp: Date.now(),
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
async function getDecisionOutcomes(
|
|
641
|
+
workflowId: string,
|
|
642
|
+
decisionPoint: string,
|
|
643
|
+
context: AgenticHookContext
|
|
644
|
+
): Promise<any[]> {
|
|
645
|
+
// Get historical outcomes for decision point
|
|
646
|
+
const outcomeKey = `outcomes:${workflowId}:${decisionPoint}`;
|
|
647
|
+
return await context.memory.cache.get(outcomeKey) || [];
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function adjustDecisionConfidence(
|
|
651
|
+
decision: WorkflowDecision,
|
|
652
|
+
historicalOutcomes: any[]
|
|
653
|
+
): WorkflowDecision {
|
|
654
|
+
if (historicalOutcomes.length === 0) {
|
|
655
|
+
return decision;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Calculate success rate for selected option
|
|
659
|
+
const relevantOutcomes = historicalOutcomes.filter(o =>
|
|
660
|
+
o.selected === decision.selected
|
|
661
|
+
);
|
|
662
|
+
|
|
663
|
+
if (relevantOutcomes.length === 0) {
|
|
664
|
+
return decision;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const successRate = relevantOutcomes.filter(o => o.success).length /
|
|
668
|
+
relevantOutcomes.length;
|
|
669
|
+
|
|
670
|
+
// Adjust confidence based on historical success
|
|
671
|
+
const adjustedConfidence = decision.confidence * 0.7 + successRate * 0.3;
|
|
672
|
+
|
|
673
|
+
return {
|
|
674
|
+
...decision,
|
|
675
|
+
confidence: adjustedConfidence,
|
|
676
|
+
learnings: [
|
|
677
|
+
...decision.learnings,
|
|
678
|
+
{
|
|
679
|
+
type: 'success',
|
|
680
|
+
context: `Historical success rate: ${(successRate * 100).toFixed(1)}%`,
|
|
681
|
+
value: successRate,
|
|
682
|
+
applicability: Math.min(relevantOutcomes.length / 10, 1),
|
|
683
|
+
},
|
|
684
|
+
],
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
async function generateAlternativeDecisions(
|
|
689
|
+
workflowId: string,
|
|
690
|
+
decision: WorkflowDecision,
|
|
691
|
+
state: any,
|
|
692
|
+
context: AgenticHookContext
|
|
693
|
+
): Promise<WorkflowDecision[]> {
|
|
694
|
+
// Generate alternative decision paths
|
|
695
|
+
const alternatives: WorkflowDecision[] = [];
|
|
696
|
+
|
|
697
|
+
// Check each option not selected
|
|
698
|
+
for (const option of decision.options) {
|
|
699
|
+
if (option === decision.selected) continue;
|
|
700
|
+
|
|
701
|
+
// Calculate alternative confidence
|
|
702
|
+
const altConfidence = await calculateAlternativeConfidence(
|
|
703
|
+
workflowId,
|
|
704
|
+
decision.point,
|
|
705
|
+
option,
|
|
706
|
+
state,
|
|
707
|
+
context
|
|
708
|
+
);
|
|
709
|
+
|
|
710
|
+
if (altConfidence > 0.5) {
|
|
711
|
+
alternatives.push({
|
|
712
|
+
...decision,
|
|
713
|
+
selected: option,
|
|
714
|
+
confidence: altConfidence,
|
|
715
|
+
reasoning: `Alternative path based on historical analysis`,
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return alternatives;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function calculateWorkflowPerformance(
|
|
724
|
+
state: any,
|
|
725
|
+
metrics: any
|
|
726
|
+
): any {
|
|
727
|
+
const performance = {
|
|
728
|
+
success: !state.error,
|
|
729
|
+
score: 0,
|
|
730
|
+
duration: metrics?.duration || 0,
|
|
731
|
+
efficiency: 0,
|
|
732
|
+
reliability: 0,
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
// Calculate performance score
|
|
736
|
+
if (performance.success) {
|
|
737
|
+
performance.score = 0.7; // Base success score
|
|
738
|
+
|
|
739
|
+
// Adjust for duration
|
|
740
|
+
if (metrics?.duration && state.predictions?.estimatedDuration) {
|
|
741
|
+
const durationRatio = state.predictions.estimatedDuration / metrics.duration;
|
|
742
|
+
performance.efficiency = Math.min(durationRatio, 1);
|
|
743
|
+
performance.score += performance.efficiency * 0.2;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// Adjust for error rate
|
|
747
|
+
if (metrics?.errorRate !== undefined) {
|
|
748
|
+
performance.reliability = 1 - metrics.errorRate;
|
|
749
|
+
performance.score += performance.reliability * 0.1;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
return performance;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
async function extractWorkflowLearnings(
|
|
757
|
+
workflowId: string,
|
|
758
|
+
state: any,
|
|
759
|
+
performance: any,
|
|
760
|
+
context: AgenticHookContext
|
|
761
|
+
): Promise<Learning[]> {
|
|
762
|
+
const learnings: Learning[] = [];
|
|
763
|
+
|
|
764
|
+
// Learn from successful execution
|
|
765
|
+
if (performance.success) {
|
|
766
|
+
learnings.push({
|
|
767
|
+
type: 'success',
|
|
768
|
+
context: `Successful workflow execution with score ${performance.score}`,
|
|
769
|
+
value: {
|
|
770
|
+
provider: state.provider,
|
|
771
|
+
duration: performance.duration,
|
|
772
|
+
decisions: extractDecisions(state),
|
|
773
|
+
},
|
|
774
|
+
applicability: performance.score,
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// Learn from optimizations
|
|
779
|
+
if (state.appliedOptimizations) {
|
|
780
|
+
for (const opt of state.appliedOptimizations) {
|
|
781
|
+
learnings.push({
|
|
782
|
+
type: 'optimization',
|
|
783
|
+
context: `Applied ${opt.type} optimization at ${opt.step}`,
|
|
784
|
+
value: opt,
|
|
785
|
+
applicability: 0.8,
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
return learnings;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
function countDecisions(state: any): number {
|
|
794
|
+
// Count decisions made during workflow
|
|
795
|
+
return state.decisions?.length || 0;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
async function generateImprovementSuggestions(
|
|
799
|
+
workflowId: string,
|
|
800
|
+
state: any,
|
|
801
|
+
performance: any,
|
|
802
|
+
learnings: Learning[],
|
|
803
|
+
context: AgenticHookContext
|
|
804
|
+
): Promise<any[]> {
|
|
805
|
+
const suggestions: any[] = [];
|
|
806
|
+
|
|
807
|
+
// Suggest caching if repeated operations
|
|
808
|
+
if (performance.duration > 5000) {
|
|
809
|
+
suggestions.push({
|
|
810
|
+
type: 'cache',
|
|
811
|
+
target: 'frequent_operations',
|
|
812
|
+
reason: 'Long execution time detected',
|
|
813
|
+
expectedImprovement: '30-50% reduction in duration',
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// Suggest parallelization
|
|
818
|
+
if (state.sequentialSteps?.length > 3) {
|
|
819
|
+
suggestions.push({
|
|
820
|
+
type: 'parallel',
|
|
821
|
+
target: 'independent_steps',
|
|
822
|
+
reason: 'Multiple sequential steps detected',
|
|
823
|
+
expectedImprovement: '40-60% reduction in duration',
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Suggest provider switch based on learnings
|
|
828
|
+
const providerLearnings = learnings.filter(l =>
|
|
829
|
+
l.type === 'success' && l.value.provider
|
|
830
|
+
);
|
|
831
|
+
|
|
832
|
+
if (providerLearnings.length > 0) {
|
|
833
|
+
const providerScores = new Map<string, number>();
|
|
834
|
+
for (const learning of providerLearnings) {
|
|
835
|
+
const provider = learning.value.provider;
|
|
836
|
+
const score = providerScores.get(provider) || 0;
|
|
837
|
+
providerScores.set(provider, score + learning.applicability);
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
const currentScore = providerScores.get(state.provider) || 0;
|
|
841
|
+
for (const [provider, score] of providerScores) {
|
|
842
|
+
if (score > currentScore * 1.2) {
|
|
843
|
+
suggestions.push({
|
|
844
|
+
type: 'provider',
|
|
845
|
+
target: provider,
|
|
846
|
+
reason: `${provider} shows better historical performance`,
|
|
847
|
+
expectedImprovement: `${((score / currentScore - 1) * 100).toFixed(0)}% better reliability`,
|
|
848
|
+
});
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
return suggestions;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
async function analyzeErrorPattern(
|
|
857
|
+
workflowId: string,
|
|
858
|
+
error: Error,
|
|
859
|
+
state: any,
|
|
860
|
+
context: AgenticHookContext
|
|
861
|
+
): Promise<any> {
|
|
862
|
+
// Analyze error to find patterns
|
|
863
|
+
const pattern = {
|
|
864
|
+
type: classifyError(error),
|
|
865
|
+
confidence: 0.7,
|
|
866
|
+
context: {
|
|
867
|
+
step: state.currentStep,
|
|
868
|
+
provider: state.provider,
|
|
869
|
+
errorMessage: error.message,
|
|
870
|
+
},
|
|
871
|
+
};
|
|
872
|
+
|
|
873
|
+
// Check for similar errors
|
|
874
|
+
const errorHistory = await context.memory.cache.get(
|
|
875
|
+
`errors:${workflowId}:${pattern.type}`
|
|
876
|
+
) || [];
|
|
877
|
+
|
|
878
|
+
if (errorHistory.length > 5) {
|
|
879
|
+
pattern.confidence = 0.9;
|
|
880
|
+
pattern.context.recurring = true;
|
|
881
|
+
pattern.context.occurrences = errorHistory.length;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
return pattern;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
async function findRecoveryStrategy(
|
|
888
|
+
workflowId: string,
|
|
889
|
+
error: Error,
|
|
890
|
+
errorPattern: any,
|
|
891
|
+
context: AgenticHookContext
|
|
892
|
+
): Promise<any | null> {
|
|
893
|
+
// Find recovery strategy for error
|
|
894
|
+
if (errorPattern.type === 'timeout') {
|
|
895
|
+
return {
|
|
896
|
+
type: 'retry',
|
|
897
|
+
params: {
|
|
898
|
+
maxRetries: 3,
|
|
899
|
+
backoff: 'exponential',
|
|
900
|
+
timeout: 30000,
|
|
901
|
+
},
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
if (errorPattern.type === 'rate_limit') {
|
|
906
|
+
return {
|
|
907
|
+
type: 'throttle',
|
|
908
|
+
params: {
|
|
909
|
+
delay: 1000,
|
|
910
|
+
maxConcurrent: 1,
|
|
911
|
+
},
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
if (errorPattern.type === 'validation') {
|
|
916
|
+
return {
|
|
917
|
+
type: 'transform',
|
|
918
|
+
params: {
|
|
919
|
+
sanitize: true,
|
|
920
|
+
validate: true,
|
|
921
|
+
},
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
return null;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
function applyRecoveryStrategy(state: any, recovery: any): any {
|
|
929
|
+
const recoveredState = { ...state };
|
|
930
|
+
|
|
931
|
+
switch (recovery.type) {
|
|
932
|
+
case 'retry':
|
|
933
|
+
recoveredState.retryConfig = recovery.params;
|
|
934
|
+
recoveredState.shouldRetry = true;
|
|
935
|
+
break;
|
|
936
|
+
|
|
937
|
+
case 'throttle':
|
|
938
|
+
recoveredState.throttleConfig = recovery.params;
|
|
939
|
+
recoveredState.throttled = true;
|
|
940
|
+
break;
|
|
941
|
+
|
|
942
|
+
case 'transform':
|
|
943
|
+
recoveredState.transformConfig = recovery.params;
|
|
944
|
+
recoveredState.needsTransform = true;
|
|
945
|
+
break;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
recoveredState.recoveryApplied = recovery;
|
|
949
|
+
delete recoveredState.error; // Clear error state
|
|
950
|
+
|
|
951
|
+
return recoveredState;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
function selectAlternativeProvider(
|
|
955
|
+
currentProvider: string,
|
|
956
|
+
providerStats: Map<string, { success: number; total: number }>
|
|
957
|
+
): string {
|
|
958
|
+
// Select alternative provider based on stats
|
|
959
|
+
let bestAlternative = 'anthropic'; // Default fallback
|
|
960
|
+
let bestRate = 0;
|
|
961
|
+
|
|
962
|
+
for (const [provider, stats] of providerStats) {
|
|
963
|
+
if (provider === currentProvider) continue;
|
|
964
|
+
|
|
965
|
+
const rate = stats.success / stats.total;
|
|
966
|
+
if (rate > bestRate && stats.total >= 3) {
|
|
967
|
+
bestRate = rate;
|
|
968
|
+
bestAlternative = provider;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
return bestAlternative;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
async function calculateAlternativeConfidence(
|
|
976
|
+
workflowId: string,
|
|
977
|
+
decisionPoint: string,
|
|
978
|
+
option: string,
|
|
979
|
+
state: any,
|
|
980
|
+
context: AgenticHookContext
|
|
981
|
+
): Promise<number> {
|
|
982
|
+
// Calculate confidence for alternative option
|
|
983
|
+
const outcomeKey = `outcomes:${workflowId}:${decisionPoint}:${option}`;
|
|
984
|
+
const outcomes = await context.memory.cache.get(outcomeKey) || [];
|
|
985
|
+
|
|
986
|
+
if (outcomes.length === 0) {
|
|
987
|
+
return 0.5; // Default confidence
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
const successRate = outcomes.filter((o: any) => o.success).length /
|
|
991
|
+
outcomes.length;
|
|
992
|
+
|
|
993
|
+
// Adjust for recency
|
|
994
|
+
const recentOutcomes = outcomes.slice(-10);
|
|
995
|
+
const recentSuccessRate = recentOutcomes.filter((o: any) => o.success).length /
|
|
996
|
+
recentOutcomes.length;
|
|
997
|
+
|
|
998
|
+
return successRate * 0.7 + recentSuccessRate * 0.3;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
function extractDecisions(state: any): any[] {
|
|
1002
|
+
// Extract decisions from state
|
|
1003
|
+
return state.decisions || [];
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
function classifyError(error: Error): string {
|
|
1007
|
+
const message = error.message.toLowerCase();
|
|
1008
|
+
|
|
1009
|
+
if (message.includes('timeout')) return 'timeout';
|
|
1010
|
+
if (message.includes('rate limit')) return 'rate_limit';
|
|
1011
|
+
if (message.includes('validation')) return 'validation';
|
|
1012
|
+
if (message.includes('network')) return 'network';
|
|
1013
|
+
if (message.includes('auth')) return 'authentication';
|
|
1014
|
+
|
|
1015
|
+
return 'unknown';
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// ===== Register Hooks =====
|
|
1019
|
+
|
|
1020
|
+
export function registerWorkflowHooks(): void {
|
|
1021
|
+
agenticHookManager.register(workflowStartHook);
|
|
1022
|
+
agenticHookManager.register(workflowStepHook);
|
|
1023
|
+
agenticHookManager.register(workflowDecisionHook);
|
|
1024
|
+
agenticHookManager.register(workflowCompleteHook);
|
|
1025
|
+
agenticHookManager.register(workflowErrorHook);
|
|
1026
|
+
}
|