groundswell 0.0.1
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/settings.local.json +9 -0
- package/.claude/system_prompts/task-breakdown.md +100 -0
- package/PRPs/001-hierarchical-workflow-engine.md +2438 -0
- package/PRPs/PRDs/001-hierarchical-workflow-engine.md +543 -0
- package/PRPs/PRDs/002-agent-prompt.md +390 -0
- package/PRPs/PRDs/003-agent-prompt.md +943 -0
- package/PRPs/PRDs/004-agent-prompt.md +1136 -0
- package/PRPs/PRDs/tasks-001.json +492 -0
- package/PRPs/README.md +83 -0
- package/PRPs/templates/prp_base.md +222 -0
- package/README.md +218 -0
- package/docs/agent.md +422 -0
- package/docs/prompt.md +419 -0
- package/docs/workflow.md +600 -0
- package/examples/README.md +244 -0
- package/examples/examples/01-basic-workflow.ts +100 -0
- package/examples/examples/02-decorator-options.ts +217 -0
- package/examples/examples/03-parent-child.ts +241 -0
- package/examples/examples/04-observers-debugger.ts +340 -0
- package/examples/examples/05-error-handling.ts +387 -0
- package/examples/examples/06-concurrent-tasks.ts +352 -0
- package/examples/examples/07-agent-loops.ts +432 -0
- package/examples/examples/08-sdk-features.ts +667 -0
- package/examples/examples/09-reflection.ts +573 -0
- package/examples/examples/10-introspection.ts +550 -0
- package/examples/index.ts +143 -0
- package/examples/utils/helpers.ts +57 -0
- package/llms_full.txt +5890 -0
- package/package.json +63 -0
- package/plan/P1P2/PRP.md +527 -0
- package/plan/P1P2/research/LRU_CACHE_BEST_PRACTICES.md +1929 -0
- package/plan/P1P2/research/LRU_CACHE_CODE_PATTERNS.md +857 -0
- package/plan/P1P2/research/LRU_CACHE_INTEGRATION_GUIDE.md +738 -0
- package/plan/P1P2/research/LRU_CACHE_RESEARCH_INDEX.md +424 -0
- package/plan/P1P2/research/REFLECTION_INDEX.md +291 -0
- package/plan/P1P2/research/REFLECTION_RESEARCH_REPORT.md +1342 -0
- package/plan/P1P2/research/RESEARCH_SUMMARY.md +342 -0
- package/plan/P1P2/research/anthropic-sdk.md +174 -0
- package/plan/P1P2/research/async-local-storage.md +200 -0
- package/plan/P1P2/research/reflection-code-patterns.md +1205 -0
- package/plan/P1P2/research/reflection-decision-matrix.md +421 -0
- package/plan/P1P2/research/reflection-implementation-guide.md +1341 -0
- package/plan/P1P2/research/reflection-integration-guide.md +834 -0
- package/plan/P1P2/research/reflection-patterns.md +1468 -0
- package/plan/P1P2/research/reflection-quick-reference.md +558 -0
- package/plan/P1P2/research/zod-schema.md +152 -0
- package/plan/P3P4/PRP.md +1388 -0
- package/plan/P3P4/research/caching-lru.md +116 -0
- package/plan/P3P4/research/introspection-tools.md +177 -0
- package/plan/P3P4/research/reflection-patterns.md +117 -0
- package/plan/P4P5/PRP.md +1136 -0
- package/plan/P4P5/research/RESEARCH_SUMMARY.md +151 -0
- package/plan/architecture/external_deps.md +358 -0
- package/plan/architecture/system_context.md +242 -0
- package/plan/backlog.json +867 -0
- package/plan/research/INTROSPECTION_RESEARCH_SUMMARY.md +378 -0
- package/plan/research/README-INTROSPECTION.md +352 -0
- package/plan/research/agent-introspection-patterns.md +1085 -0
- package/plan/research/introspection-security-guide.md +928 -0
- package/plan/research/introspection-tool-examples.md +875 -0
- package/scripts/generate-llms-full.ts +206 -0
- package/src/__tests__/integration/agent-workflow.test.ts +256 -0
- package/src/__tests__/integration/tree-mirroring.test.ts +114 -0
- package/src/__tests__/unit/agent.test.ts +169 -0
- package/src/__tests__/unit/cache-key.test.ts +182 -0
- package/src/__tests__/unit/cache.test.ts +172 -0
- package/src/__tests__/unit/context.test.ts +138 -0
- package/src/__tests__/unit/decorators.test.ts +100 -0
- package/src/__tests__/unit/introspection-tools.test.ts +277 -0
- package/src/__tests__/unit/prompt.test.ts +135 -0
- package/src/__tests__/unit/reflection.test.ts +210 -0
- package/src/__tests__/unit/tree-debugger.test.ts +85 -0
- package/src/__tests__/unit/workflow.test.ts +81 -0
- package/src/cache/cache-key.ts +244 -0
- package/src/cache/cache.ts +236 -0
- package/src/cache/index.ts +8 -0
- package/src/core/agent.ts +573 -0
- package/src/core/context.ts +119 -0
- package/src/core/event-tree.ts +260 -0
- package/src/core/factory.ts +123 -0
- package/src/core/index.ts +17 -0
- package/src/core/logger.ts +87 -0
- package/src/core/mcp-handler.ts +184 -0
- package/src/core/prompt.ts +150 -0
- package/src/core/workflow-context.ts +349 -0
- package/src/core/workflow.ts +302 -0
- package/src/debugger/index.ts +1 -0
- package/src/debugger/tree-debugger.ts +210 -0
- package/src/decorators/index.ts +3 -0
- package/src/decorators/observed-state.ts +95 -0
- package/src/decorators/step.ts +139 -0
- package/src/decorators/task.ts +96 -0
- package/src/examples/index.ts +2 -0
- package/src/examples/tdd-orchestrator.ts +65 -0
- package/src/examples/test-cycle-workflow.ts +64 -0
- package/src/index.ts +140 -0
- package/src/reflection/index.ts +5 -0
- package/src/reflection/reflection.ts +407 -0
- package/src/tools/index.ts +36 -0
- package/src/tools/introspection.ts +464 -0
- package/src/types/agent.ts +90 -0
- package/src/types/decorators.ts +25 -0
- package/src/types/error-strategy.ts +13 -0
- package/src/types/error.ts +20 -0
- package/src/types/events.ts +74 -0
- package/src/types/index.ts +55 -0
- package/src/types/logging.ts +24 -0
- package/src/types/observer.ts +18 -0
- package/src/types/prompt.ts +40 -0
- package/src/types/reflection.ts +117 -0
- package/src/types/sdk-primitives.ts +128 -0
- package/src/types/snapshot.ts +14 -0
- package/src/types/workflow-context.ts +163 -0
- package/src/types/workflow.ts +37 -0
- package/src/utils/id.ts +11 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/observable.ts +77 -0
- package/tasks.json +0 -0
- package/tsconfig.json +22 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReflectionManager - Implements reflection and self-correction for agents
|
|
3
|
+
*
|
|
4
|
+
* Provides multi-level reflection (workflow, agent, prompt) with configurable
|
|
5
|
+
* retry limits and history tracking.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
ReflectionAPI,
|
|
10
|
+
ReflectionConfig,
|
|
11
|
+
ReflectionContext,
|
|
12
|
+
ReflectionResult,
|
|
13
|
+
ReflectionEntry,
|
|
14
|
+
WorkflowEvent,
|
|
15
|
+
} from '../types/index.js';
|
|
16
|
+
import type { Agent } from '../core/agent.js';
|
|
17
|
+
import type { Prompt } from '../core/prompt.js';
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Schema for parsing reflection responses from the agent
|
|
22
|
+
*/
|
|
23
|
+
const ReflectionResponseSchema = z.object({
|
|
24
|
+
shouldRetry: z.boolean(),
|
|
25
|
+
reason: z.string(),
|
|
26
|
+
revisedPromptData: z.record(z.unknown()).optional(),
|
|
27
|
+
revisedSystemPrompt: z.string().optional(),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Default reflection prompt template
|
|
32
|
+
*/
|
|
33
|
+
const REFLECTION_PROMPT_TEMPLATE = `A previous operation failed with the following error:
|
|
34
|
+
|
|
35
|
+
Error: {{errorMessage}}
|
|
36
|
+
Stack: {{errorStack}}
|
|
37
|
+
|
|
38
|
+
Level: {{level}}
|
|
39
|
+
Node: {{nodeName}} ({{nodeId}})
|
|
40
|
+
Attempt: {{attemptNumber}} of {{maxAttempts}}
|
|
41
|
+
|
|
42
|
+
Previous attempts:
|
|
43
|
+
{{previousAttempts}}
|
|
44
|
+
|
|
45
|
+
Analyze the error and determine:
|
|
46
|
+
1. Can this operation be retried with modifications?
|
|
47
|
+
2. What changes would help it succeed?
|
|
48
|
+
3. Is this a transient error (worth retrying) or a fundamental issue (should abort)?
|
|
49
|
+
|
|
50
|
+
Consider:
|
|
51
|
+
- Rate limits and quota errors should NOT be retried via reflection
|
|
52
|
+
- Authentication errors should NOT be retried via reflection
|
|
53
|
+
- Schema validation errors may be retried with revised data
|
|
54
|
+
- Logic errors may be retried with revised prompts
|
|
55
|
+
|
|
56
|
+
Respond with JSON:
|
|
57
|
+
{
|
|
58
|
+
"shouldRetry": boolean,
|
|
59
|
+
"reason": string,
|
|
60
|
+
"revisedPromptData": { /* optional revised data */ },
|
|
61
|
+
"revisedSystemPrompt": "optional revised system prompt"
|
|
62
|
+
}`;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* ReflectionManager - Manages reflection and self-correction
|
|
66
|
+
*/
|
|
67
|
+
export class ReflectionManager implements ReflectionAPI {
|
|
68
|
+
private readonly config: ReflectionConfig;
|
|
69
|
+
private readonly history: ReflectionEntry[] = [];
|
|
70
|
+
private readonly agent?: Agent;
|
|
71
|
+
private eventEmitter?: (event: WorkflowEvent) => void;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Create a new ReflectionManager
|
|
75
|
+
* @param config Reflection configuration
|
|
76
|
+
* @param agent Optional agent to use for reflection analysis
|
|
77
|
+
*/
|
|
78
|
+
constructor(config: ReflectionConfig, agent?: Agent) {
|
|
79
|
+
this.config = config;
|
|
80
|
+
this.agent = agent;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Set the event emitter for workflow events
|
|
85
|
+
*/
|
|
86
|
+
setEventEmitter(emitter: (event: WorkflowEvent) => void): void {
|
|
87
|
+
this.eventEmitter = emitter;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Check if reflection is enabled
|
|
92
|
+
*/
|
|
93
|
+
isEnabled(): boolean {
|
|
94
|
+
return this.config.enabled;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get the maximum number of attempts
|
|
99
|
+
*/
|
|
100
|
+
getMaxAttempts(): number {
|
|
101
|
+
return this.config.maxAttempts;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get the retry delay in milliseconds
|
|
106
|
+
*/
|
|
107
|
+
getRetryDelayMs(): number {
|
|
108
|
+
return this.config.retryDelayMs ?? 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Trigger a reflection on the current context
|
|
113
|
+
*/
|
|
114
|
+
async triggerReflection(reason?: string): Promise<void> {
|
|
115
|
+
if (!this.config.enabled) {
|
|
116
|
+
throw new Error('Reflection is not enabled');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Record that reflection was triggered
|
|
120
|
+
const entry: ReflectionEntry = {
|
|
121
|
+
timestamp: Date.now(),
|
|
122
|
+
level: 'workflow',
|
|
123
|
+
reason: reason ?? 'Manual reflection trigger',
|
|
124
|
+
error: new Error(reason ?? 'Manual trigger'),
|
|
125
|
+
resolution: 'skip',
|
|
126
|
+
success: false,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
this.history.push(entry);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get the history of reflection attempts
|
|
134
|
+
*/
|
|
135
|
+
getReflectionHistory(): ReflectionEntry[] {
|
|
136
|
+
return [...this.history];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Perform reflection analysis on an error
|
|
141
|
+
*/
|
|
142
|
+
async reflect(context: ReflectionContext): Promise<ReflectionResult> {
|
|
143
|
+
// Emit reflection start event
|
|
144
|
+
if (this.eventEmitter) {
|
|
145
|
+
this.eventEmitter({
|
|
146
|
+
type: 'reflectionStart',
|
|
147
|
+
level: context.level,
|
|
148
|
+
node: context.failedNode,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let result: ReflectionResult;
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
// Check for non-retryable errors
|
|
156
|
+
if (this.isNonRetryableError(context.error)) {
|
|
157
|
+
result = {
|
|
158
|
+
shouldRetry: false,
|
|
159
|
+
reason: `Non-retryable error: ${context.error.message}`,
|
|
160
|
+
};
|
|
161
|
+
} else if (this.agent) {
|
|
162
|
+
// Use agent for reflection analysis
|
|
163
|
+
result = await this.reflectWithAgent(context);
|
|
164
|
+
} else {
|
|
165
|
+
// Use simple heuristic-based reflection
|
|
166
|
+
result = this.reflectWithHeuristics(context);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Record the reflection entry
|
|
170
|
+
const entry: ReflectionEntry = {
|
|
171
|
+
timestamp: Date.now(),
|
|
172
|
+
level: context.level,
|
|
173
|
+
reason: result.reason,
|
|
174
|
+
error: context.error,
|
|
175
|
+
resolution: result.shouldRetry ? 'retry' : 'abort',
|
|
176
|
+
success: false, // Will be updated by caller if retry succeeds
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
this.history.push(entry);
|
|
180
|
+
|
|
181
|
+
// Apply retry delay if configured
|
|
182
|
+
if (result.shouldRetry && this.config.retryDelayMs) {
|
|
183
|
+
await this.delay(this.config.retryDelayMs);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return result;
|
|
187
|
+
} finally {
|
|
188
|
+
// Emit reflection end event
|
|
189
|
+
if (this.eventEmitter) {
|
|
190
|
+
this.eventEmitter({
|
|
191
|
+
type: 'reflectionEnd',
|
|
192
|
+
level: context.level,
|
|
193
|
+
success: result!?.shouldRetry ?? false,
|
|
194
|
+
node: context.failedNode,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Mark the last reflection entry as successful
|
|
202
|
+
*/
|
|
203
|
+
markLastReflectionSuccessful(): void {
|
|
204
|
+
if (this.history.length > 0) {
|
|
205
|
+
this.history[this.history.length - 1].success = true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Check if an error is non-retryable
|
|
211
|
+
*/
|
|
212
|
+
private isNonRetryableError(error: Error): boolean {
|
|
213
|
+
const message = error.message.toLowerCase();
|
|
214
|
+
|
|
215
|
+
// Rate limit and quota errors
|
|
216
|
+
if (
|
|
217
|
+
message.includes('rate limit') ||
|
|
218
|
+
message.includes('quota exceeded') ||
|
|
219
|
+
message.includes('429')
|
|
220
|
+
) {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Authentication errors
|
|
225
|
+
if (
|
|
226
|
+
message.includes('authentication') ||
|
|
227
|
+
message.includes('unauthorized') ||
|
|
228
|
+
message.includes('401') ||
|
|
229
|
+
message.includes('403') ||
|
|
230
|
+
message.includes('invalid api key')
|
|
231
|
+
) {
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Network errors that should use exponential backoff instead
|
|
236
|
+
if (
|
|
237
|
+
message.includes('econnrefused') ||
|
|
238
|
+
message.includes('etimedout') ||
|
|
239
|
+
message.includes('network')
|
|
240
|
+
) {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Perform reflection using an agent
|
|
249
|
+
*/
|
|
250
|
+
private async reflectWithAgent(
|
|
251
|
+
context: ReflectionContext
|
|
252
|
+
): Promise<ReflectionResult> {
|
|
253
|
+
if (!this.agent) {
|
|
254
|
+
throw new Error('No agent configured for reflection');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Build the reflection prompt
|
|
258
|
+
const promptText = this.buildReflectionPrompt(context);
|
|
259
|
+
|
|
260
|
+
// Create a prompt for reflection analysis
|
|
261
|
+
const reflectionPrompt = new (await import('../core/prompt.js')).Prompt({
|
|
262
|
+
user: promptText,
|
|
263
|
+
responseFormat: ReflectionResponseSchema,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
const response = await this.agent.prompt(reflectionPrompt);
|
|
268
|
+
return {
|
|
269
|
+
shouldRetry: response.shouldRetry,
|
|
270
|
+
reason: response.reason,
|
|
271
|
+
revisedPromptData: response.revisedPromptData,
|
|
272
|
+
revisedSystemPrompt: response.revisedSystemPrompt,
|
|
273
|
+
};
|
|
274
|
+
} catch (reflectionError) {
|
|
275
|
+
// If reflection itself fails, don't retry the original
|
|
276
|
+
return {
|
|
277
|
+
shouldRetry: false,
|
|
278
|
+
reason: `Reflection analysis failed: ${reflectionError instanceof Error ? reflectionError.message : 'Unknown error'}`,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Perform reflection using simple heuristics
|
|
285
|
+
*/
|
|
286
|
+
private reflectWithHeuristics(context: ReflectionContext): ReflectionResult {
|
|
287
|
+
const errorMessage = context.error.message.toLowerCase();
|
|
288
|
+
|
|
289
|
+
// Check for validation errors (often retryable)
|
|
290
|
+
if (
|
|
291
|
+
errorMessage.includes('validation') ||
|
|
292
|
+
errorMessage.includes('parse') ||
|
|
293
|
+
errorMessage.includes('schema') ||
|
|
294
|
+
errorMessage.includes('json')
|
|
295
|
+
) {
|
|
296
|
+
return {
|
|
297
|
+
shouldRetry: true,
|
|
298
|
+
reason:
|
|
299
|
+
'Validation/parsing error detected - retry may succeed with adjusted approach',
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Check for timeout errors
|
|
304
|
+
if (errorMessage.includes('timeout')) {
|
|
305
|
+
return {
|
|
306
|
+
shouldRetry: context.attemptNumber < 2,
|
|
307
|
+
reason:
|
|
308
|
+
context.attemptNumber < 2
|
|
309
|
+
? 'Timeout error - retry once'
|
|
310
|
+
: 'Timeout error - too many attempts',
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Default: retry if under max attempts
|
|
315
|
+
const shouldRetry = context.attemptNumber < this.config.maxAttempts;
|
|
316
|
+
return {
|
|
317
|
+
shouldRetry,
|
|
318
|
+
reason: shouldRetry
|
|
319
|
+
? `Attempt ${context.attemptNumber} failed - retrying`
|
|
320
|
+
: `Max attempts (${this.config.maxAttempts}) reached`,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Build the reflection prompt from context
|
|
326
|
+
*/
|
|
327
|
+
private buildReflectionPrompt(context: ReflectionContext): string {
|
|
328
|
+
const previousAttemptsText =
|
|
329
|
+
context.previousAttempts.length > 0
|
|
330
|
+
? context.previousAttempts
|
|
331
|
+
.map(
|
|
332
|
+
(a, i) =>
|
|
333
|
+
` ${i + 1}. [${a.level}] ${a.reason} -> ${a.resolution} (${a.success ? 'success' : 'failed'})`
|
|
334
|
+
)
|
|
335
|
+
.join('\n')
|
|
336
|
+
: ' None';
|
|
337
|
+
|
|
338
|
+
return REFLECTION_PROMPT_TEMPLATE.replace('{{errorMessage}}', context.error.message)
|
|
339
|
+
.replace('{{errorStack}}', context.error.stack ?? 'No stack trace')
|
|
340
|
+
.replace('{{level}}', context.level)
|
|
341
|
+
.replace('{{nodeName}}', context.failedNode.name)
|
|
342
|
+
.replace('{{nodeId}}', context.failedNode.id)
|
|
343
|
+
.replace('{{attemptNumber}}', String(context.attemptNumber))
|
|
344
|
+
.replace('{{maxAttempts}}', String(this.config.maxAttempts))
|
|
345
|
+
.replace('{{previousAttempts}}', previousAttemptsText);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Helper to create a delay
|
|
350
|
+
*/
|
|
351
|
+
private delay(ms: number): Promise<void> {
|
|
352
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Execute a function with reflection support
|
|
358
|
+
* @param fn Function to execute
|
|
359
|
+
* @param reflection ReflectionManager instance
|
|
360
|
+
* @param createContext Function to create reflection context from error
|
|
361
|
+
* @returns Result of the function
|
|
362
|
+
*/
|
|
363
|
+
export async function executeWithReflection<T>(
|
|
364
|
+
fn: () => Promise<T>,
|
|
365
|
+
reflection: ReflectionManager,
|
|
366
|
+
createContext: (
|
|
367
|
+
error: Error,
|
|
368
|
+
attempt: number,
|
|
369
|
+
history: ReflectionEntry[]
|
|
370
|
+
) => ReflectionContext
|
|
371
|
+
): Promise<T> {
|
|
372
|
+
let lastError: Error | null = null;
|
|
373
|
+
const maxAttempts = reflection.getMaxAttempts();
|
|
374
|
+
|
|
375
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
376
|
+
try {
|
|
377
|
+
const result = await fn();
|
|
378
|
+
|
|
379
|
+
// If we succeeded after a reflection, mark it as successful
|
|
380
|
+
if (attempt > 1) {
|
|
381
|
+
reflection.markLastReflectionSuccessful();
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return result;
|
|
385
|
+
} catch (error) {
|
|
386
|
+
lastError = error as Error;
|
|
387
|
+
|
|
388
|
+
if (!reflection.isEnabled() || attempt === maxAttempts) {
|
|
389
|
+
throw error;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const context = createContext(
|
|
393
|
+
lastError,
|
|
394
|
+
attempt,
|
|
395
|
+
reflection.getReflectionHistory()
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
const result = await reflection.reflect(context);
|
|
399
|
+
|
|
400
|
+
if (!result.shouldRetry) {
|
|
401
|
+
throw lastError;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
throw lastError ?? new Error('Max reflection attempts exceeded');
|
|
407
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tools module exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
// Tool definitions
|
|
7
|
+
INTROSPECTION_TOOLS,
|
|
8
|
+
inspectCurrentNodeTool,
|
|
9
|
+
readAncestorChainTool,
|
|
10
|
+
listSiblingsChildrenTool,
|
|
11
|
+
inspectPriorOutputsTool,
|
|
12
|
+
inspectCacheStatusTool,
|
|
13
|
+
requestSpawnWorkflowTool,
|
|
14
|
+
// Handlers
|
|
15
|
+
INTROSPECTION_HANDLERS,
|
|
16
|
+
handleInspectCurrentNode,
|
|
17
|
+
handleReadAncestorChain,
|
|
18
|
+
handleListSiblingsChildren,
|
|
19
|
+
handleInspectPriorOutputs,
|
|
20
|
+
handleInspectCacheStatus,
|
|
21
|
+
handleRequestSpawnWorkflow,
|
|
22
|
+
// Utilities
|
|
23
|
+
registerIntrospectionTools,
|
|
24
|
+
executeIntrospectionTool,
|
|
25
|
+
} from './introspection.js';
|
|
26
|
+
|
|
27
|
+
export type {
|
|
28
|
+
CurrentNodeInfo,
|
|
29
|
+
AncestorInfo,
|
|
30
|
+
AncestorChainResult,
|
|
31
|
+
NodeInfo,
|
|
32
|
+
SiblingsChildrenResult,
|
|
33
|
+
PriorOutputInfo,
|
|
34
|
+
CacheStatusResult,
|
|
35
|
+
SpawnWorkflowRequest,
|
|
36
|
+
} from './introspection.js';
|