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.
Files changed (120) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.claude/system_prompts/task-breakdown.md +100 -0
  3. package/PRPs/001-hierarchical-workflow-engine.md +2438 -0
  4. package/PRPs/PRDs/001-hierarchical-workflow-engine.md +543 -0
  5. package/PRPs/PRDs/002-agent-prompt.md +390 -0
  6. package/PRPs/PRDs/003-agent-prompt.md +943 -0
  7. package/PRPs/PRDs/004-agent-prompt.md +1136 -0
  8. package/PRPs/PRDs/tasks-001.json +492 -0
  9. package/PRPs/README.md +83 -0
  10. package/PRPs/templates/prp_base.md +222 -0
  11. package/README.md +218 -0
  12. package/docs/agent.md +422 -0
  13. package/docs/prompt.md +419 -0
  14. package/docs/workflow.md +600 -0
  15. package/examples/README.md +244 -0
  16. package/examples/examples/01-basic-workflow.ts +100 -0
  17. package/examples/examples/02-decorator-options.ts +217 -0
  18. package/examples/examples/03-parent-child.ts +241 -0
  19. package/examples/examples/04-observers-debugger.ts +340 -0
  20. package/examples/examples/05-error-handling.ts +387 -0
  21. package/examples/examples/06-concurrent-tasks.ts +352 -0
  22. package/examples/examples/07-agent-loops.ts +432 -0
  23. package/examples/examples/08-sdk-features.ts +667 -0
  24. package/examples/examples/09-reflection.ts +573 -0
  25. package/examples/examples/10-introspection.ts +550 -0
  26. package/examples/index.ts +143 -0
  27. package/examples/utils/helpers.ts +57 -0
  28. package/llms_full.txt +5890 -0
  29. package/package.json +63 -0
  30. package/plan/P1P2/PRP.md +527 -0
  31. package/plan/P1P2/research/LRU_CACHE_BEST_PRACTICES.md +1929 -0
  32. package/plan/P1P2/research/LRU_CACHE_CODE_PATTERNS.md +857 -0
  33. package/plan/P1P2/research/LRU_CACHE_INTEGRATION_GUIDE.md +738 -0
  34. package/plan/P1P2/research/LRU_CACHE_RESEARCH_INDEX.md +424 -0
  35. package/plan/P1P2/research/REFLECTION_INDEX.md +291 -0
  36. package/plan/P1P2/research/REFLECTION_RESEARCH_REPORT.md +1342 -0
  37. package/plan/P1P2/research/RESEARCH_SUMMARY.md +342 -0
  38. package/plan/P1P2/research/anthropic-sdk.md +174 -0
  39. package/plan/P1P2/research/async-local-storage.md +200 -0
  40. package/plan/P1P2/research/reflection-code-patterns.md +1205 -0
  41. package/plan/P1P2/research/reflection-decision-matrix.md +421 -0
  42. package/plan/P1P2/research/reflection-implementation-guide.md +1341 -0
  43. package/plan/P1P2/research/reflection-integration-guide.md +834 -0
  44. package/plan/P1P2/research/reflection-patterns.md +1468 -0
  45. package/plan/P1P2/research/reflection-quick-reference.md +558 -0
  46. package/plan/P1P2/research/zod-schema.md +152 -0
  47. package/plan/P3P4/PRP.md +1388 -0
  48. package/plan/P3P4/research/caching-lru.md +116 -0
  49. package/plan/P3P4/research/introspection-tools.md +177 -0
  50. package/plan/P3P4/research/reflection-patterns.md +117 -0
  51. package/plan/P4P5/PRP.md +1136 -0
  52. package/plan/P4P5/research/RESEARCH_SUMMARY.md +151 -0
  53. package/plan/architecture/external_deps.md +358 -0
  54. package/plan/architecture/system_context.md +242 -0
  55. package/plan/backlog.json +867 -0
  56. package/plan/research/INTROSPECTION_RESEARCH_SUMMARY.md +378 -0
  57. package/plan/research/README-INTROSPECTION.md +352 -0
  58. package/plan/research/agent-introspection-patterns.md +1085 -0
  59. package/plan/research/introspection-security-guide.md +928 -0
  60. package/plan/research/introspection-tool-examples.md +875 -0
  61. package/scripts/generate-llms-full.ts +206 -0
  62. package/src/__tests__/integration/agent-workflow.test.ts +256 -0
  63. package/src/__tests__/integration/tree-mirroring.test.ts +114 -0
  64. package/src/__tests__/unit/agent.test.ts +169 -0
  65. package/src/__tests__/unit/cache-key.test.ts +182 -0
  66. package/src/__tests__/unit/cache.test.ts +172 -0
  67. package/src/__tests__/unit/context.test.ts +138 -0
  68. package/src/__tests__/unit/decorators.test.ts +100 -0
  69. package/src/__tests__/unit/introspection-tools.test.ts +277 -0
  70. package/src/__tests__/unit/prompt.test.ts +135 -0
  71. package/src/__tests__/unit/reflection.test.ts +210 -0
  72. package/src/__tests__/unit/tree-debugger.test.ts +85 -0
  73. package/src/__tests__/unit/workflow.test.ts +81 -0
  74. package/src/cache/cache-key.ts +244 -0
  75. package/src/cache/cache.ts +236 -0
  76. package/src/cache/index.ts +8 -0
  77. package/src/core/agent.ts +573 -0
  78. package/src/core/context.ts +119 -0
  79. package/src/core/event-tree.ts +260 -0
  80. package/src/core/factory.ts +123 -0
  81. package/src/core/index.ts +17 -0
  82. package/src/core/logger.ts +87 -0
  83. package/src/core/mcp-handler.ts +184 -0
  84. package/src/core/prompt.ts +150 -0
  85. package/src/core/workflow-context.ts +349 -0
  86. package/src/core/workflow.ts +302 -0
  87. package/src/debugger/index.ts +1 -0
  88. package/src/debugger/tree-debugger.ts +210 -0
  89. package/src/decorators/index.ts +3 -0
  90. package/src/decorators/observed-state.ts +95 -0
  91. package/src/decorators/step.ts +139 -0
  92. package/src/decorators/task.ts +96 -0
  93. package/src/examples/index.ts +2 -0
  94. package/src/examples/tdd-orchestrator.ts +65 -0
  95. package/src/examples/test-cycle-workflow.ts +64 -0
  96. package/src/index.ts +140 -0
  97. package/src/reflection/index.ts +5 -0
  98. package/src/reflection/reflection.ts +407 -0
  99. package/src/tools/index.ts +36 -0
  100. package/src/tools/introspection.ts +464 -0
  101. package/src/types/agent.ts +90 -0
  102. package/src/types/decorators.ts +25 -0
  103. package/src/types/error-strategy.ts +13 -0
  104. package/src/types/error.ts +20 -0
  105. package/src/types/events.ts +74 -0
  106. package/src/types/index.ts +55 -0
  107. package/src/types/logging.ts +24 -0
  108. package/src/types/observer.ts +18 -0
  109. package/src/types/prompt.ts +40 -0
  110. package/src/types/reflection.ts +117 -0
  111. package/src/types/sdk-primitives.ts +128 -0
  112. package/src/types/snapshot.ts +14 -0
  113. package/src/types/workflow-context.ts +163 -0
  114. package/src/types/workflow.ts +37 -0
  115. package/src/utils/id.ts +11 -0
  116. package/src/utils/index.ts +3 -0
  117. package/src/utils/observable.ts +77 -0
  118. package/tasks.json +0 -0
  119. package/tsconfig.json +22 -0
  120. package/vitest.config.ts +16 -0
@@ -0,0 +1,352 @@
1
+ /**
2
+ * Example 6: Concurrent Tasks
3
+ *
4
+ * Demonstrates:
5
+ * - Using @Task with concurrent: true option
6
+ * - Manual parallel execution patterns
7
+ * - Comparing sequential vs concurrent execution
8
+ * - Fan-out/fan-in patterns
9
+ */
10
+
11
+ import {
12
+ Workflow,
13
+ Step,
14
+ Task,
15
+ ObservedState,
16
+ WorkflowTreeDebugger,
17
+ } from 'groundswell';
18
+ import { printHeader, printSection, sleep } from '../utils/helpers.js';
19
+
20
+ /**
21
+ * Simple worker workflow
22
+ */
23
+ class WorkerWorkflow extends Workflow {
24
+ @ObservedState()
25
+ workerId: string;
26
+
27
+ @ObservedState()
28
+ processingTime: number;
29
+
30
+ @ObservedState()
31
+ result: string = '';
32
+
33
+ constructor(id: string, processingTime: number, parent?: Workflow) {
34
+ super(`Worker-${id}`, parent);
35
+ this.workerId = id;
36
+ this.processingTime = processingTime;
37
+ }
38
+
39
+ @Step({ trackTiming: true, snapshotState: true })
40
+ async process(): Promise<string> {
41
+ this.logger.info(`Worker ${this.workerId} starting (${this.processingTime}ms)`);
42
+ await sleep(this.processingTime);
43
+ this.result = `Result from ${this.workerId}`;
44
+ this.logger.info(`Worker ${this.workerId} completed`);
45
+ return this.result;
46
+ }
47
+
48
+ async run(): Promise<string> {
49
+ this.setStatus('running');
50
+ const result = await this.process();
51
+ this.setStatus('completed');
52
+ return result;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Sequential execution pattern
58
+ */
59
+ class SequentialWorkflow extends Workflow {
60
+ @ObservedState()
61
+ workerCount: number;
62
+
63
+ @ObservedState()
64
+ completedWorkers: number = 0;
65
+
66
+ private workers: { id: string; time: number }[];
67
+
68
+ constructor(name: string, workers: { id: string; time: number }[]) {
69
+ super(name);
70
+ this.workers = workers;
71
+ this.workerCount = workers.length;
72
+ }
73
+
74
+ @Task()
75
+ async createWorker(config: { id: string; time: number }): Promise<WorkerWorkflow> {
76
+ return new WorkerWorkflow(config.id, config.time, this);
77
+ }
78
+
79
+ async run(): Promise<string[]> {
80
+ this.setStatus('running');
81
+ this.logger.info(`Starting ${this.workerCount} workers SEQUENTIALLY`);
82
+
83
+ const results: string[] = [];
84
+ const startTime = Date.now();
85
+
86
+ for (const config of this.workers) {
87
+ const worker = await this.createWorker(config);
88
+ const result = await worker.run();
89
+ results.push(result);
90
+ this.completedWorkers++;
91
+ }
92
+
93
+ const totalTime = Date.now() - startTime;
94
+ this.logger.info(`All workers completed in ${totalTime}ms`);
95
+
96
+ this.setStatus('completed');
97
+ return results;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Concurrent execution using @Task concurrent option
103
+ */
104
+ class ConcurrentTaskWorkflow extends Workflow {
105
+ @ObservedState()
106
+ workerCount: number;
107
+
108
+ private workers: { id: string; time: number }[];
109
+
110
+ constructor(name: string, workers: { id: string; time: number }[]) {
111
+ super(name);
112
+ this.workers = workers;
113
+ this.workerCount = workers.length;
114
+ }
115
+
116
+ // Note: The concurrent option auto-runs the returned workflows
117
+ @Task({ concurrent: true })
118
+ async createAllWorkers(): Promise<WorkerWorkflow[]> {
119
+ return this.workers.map(
120
+ (config) => new WorkerWorkflow(config.id, config.time, this)
121
+ );
122
+ }
123
+
124
+ async run(): Promise<void> {
125
+ this.setStatus('running');
126
+ this.logger.info(`Starting ${this.workerCount} workers with @Task concurrent`);
127
+
128
+ const startTime = Date.now();
129
+
130
+ // This will create all workers and run them concurrently
131
+ await this.createAllWorkers();
132
+
133
+ const totalTime = Date.now() - startTime;
134
+ this.logger.info(`All workers completed in ${totalTime}ms`);
135
+
136
+ this.setStatus('completed');
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Manual parallel execution pattern (more control)
142
+ */
143
+ class ManualParallelWorkflow extends Workflow {
144
+ @ObservedState()
145
+ workerCount: number;
146
+
147
+ private workers: { id: string; time: number }[];
148
+
149
+ constructor(name: string, workers: { id: string; time: number }[]) {
150
+ super(name);
151
+ this.workers = workers;
152
+ this.workerCount = workers.length;
153
+ }
154
+
155
+ @Task()
156
+ async createWorker(config: { id: string; time: number }): Promise<WorkerWorkflow> {
157
+ return new WorkerWorkflow(config.id, config.time, this);
158
+ }
159
+
160
+ async run(): Promise<string[]> {
161
+ this.setStatus('running');
162
+ this.logger.info(`Starting ${this.workerCount} workers MANUALLY PARALLEL`);
163
+
164
+ const startTime = Date.now();
165
+
166
+ // Create all workers first
167
+ const workerPromises: Promise<WorkerWorkflow>[] = [];
168
+ for (const config of this.workers) {
169
+ workerPromises.push(this.createWorker(config));
170
+ }
171
+ const workers = await Promise.all(workerPromises);
172
+
173
+ // Run all workers in parallel
174
+ const results = await Promise.all(workers.map((w) => w.run()));
175
+
176
+ const totalTime = Date.now() - startTime;
177
+ this.logger.info(`All workers completed in ${totalTime}ms`);
178
+
179
+ this.setStatus('completed');
180
+ return results;
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Fan-out / Fan-in pattern
186
+ */
187
+ class FanOutFanInWorkflow extends Workflow {
188
+ @ObservedState()
189
+ inputData: string[] = [];
190
+
191
+ @ObservedState()
192
+ processedData: string[] = [];
193
+
194
+ @Step({ logStart: true })
195
+ async prepareData(): Promise<void> {
196
+ this.logger.info('Preparing input data');
197
+ this.inputData = ['A', 'B', 'C', 'D', 'E'];
198
+ await sleep(50);
199
+ }
200
+
201
+ @Task()
202
+ async createProcessor(item: string): Promise<WorkerWorkflow> {
203
+ // Variable processing times
204
+ const time = 50 + Math.floor(Math.random() * 100);
205
+ return new WorkerWorkflow(item, time, this);
206
+ }
207
+
208
+ @Step({ snapshotState: true })
209
+ async fanOut(): Promise<string[]> {
210
+ this.logger.info(`Fan-out: Creating ${this.inputData.length} parallel processors`);
211
+
212
+ // Create all workers
213
+ const workers: WorkerWorkflow[] = [];
214
+ for (const item of this.inputData) {
215
+ workers.push(await this.createProcessor(item));
216
+ }
217
+
218
+ // Run all in parallel
219
+ const results = await Promise.all(workers.map((w) => w.run()));
220
+
221
+ return results;
222
+ }
223
+
224
+ @Step({ logFinish: true, snapshotState: true })
225
+ async fanIn(results: string[]): Promise<void> {
226
+ this.logger.info(`Fan-in: Aggregating ${results.length} results`);
227
+ this.processedData = results;
228
+ await sleep(50);
229
+ }
230
+
231
+ async run(): Promise<string[]> {
232
+ this.setStatus('running');
233
+
234
+ await this.prepareData();
235
+ const results = await this.fanOut();
236
+ await this.fanIn(results);
237
+
238
+ this.setStatus('completed');
239
+ return this.processedData;
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Run the concurrent tasks example
245
+ */
246
+ export async function runConcurrentTasksExample(): Promise<void> {
247
+ printHeader('Example 6: Concurrent Tasks');
248
+
249
+ const workerConfigs = [
250
+ { id: 'W1', time: 200 },
251
+ { id: 'W2', time: 150 },
252
+ { id: 'W3', time: 100 },
253
+ { id: 'W4', time: 180 },
254
+ ];
255
+
256
+ // Part 1: Sequential execution
257
+ printSection('Part 1: Sequential Execution');
258
+ {
259
+ const workflow = new SequentialWorkflow('Sequential', workerConfigs);
260
+ const debugger_ = new WorkflowTreeDebugger(workflow);
261
+
262
+ console.log('Expected time: ~630ms (200+150+100+180)');
263
+ const start = Date.now();
264
+ await workflow.run();
265
+ const elapsed = Date.now() - start;
266
+ console.log(`Actual time: ${elapsed}ms`);
267
+
268
+ console.log('\nTree:');
269
+ console.log(debugger_.toTreeString());
270
+ }
271
+
272
+ // Part 2: Manual parallel execution
273
+ printSection('Part 2: Manual Parallel Execution');
274
+ {
275
+ const workflow = new ManualParallelWorkflow('ManualParallel', workerConfigs);
276
+ const debugger_ = new WorkflowTreeDebugger(workflow);
277
+
278
+ console.log('Expected time: ~200ms (max of all workers)');
279
+ const start = Date.now();
280
+ await workflow.run();
281
+ const elapsed = Date.now() - start;
282
+ console.log(`Actual time: ${elapsed}ms`);
283
+
284
+ console.log('\nTree:');
285
+ console.log(debugger_.toTreeString());
286
+ }
287
+
288
+ // Part 3: @Task concurrent option
289
+ printSection('Part 3: @Task concurrent: true');
290
+ {
291
+ const workflow = new ConcurrentTaskWorkflow('TaskConcurrent', workerConfigs);
292
+ const debugger_ = new WorkflowTreeDebugger(workflow);
293
+
294
+ console.log('Expected time: ~200ms (using concurrent option)');
295
+ const start = Date.now();
296
+ await workflow.run();
297
+ const elapsed = Date.now() - start;
298
+ console.log(`Actual time: ${elapsed}ms`);
299
+
300
+ console.log('\nTree:');
301
+ console.log(debugger_.toTreeString());
302
+ }
303
+
304
+ // Part 4: Fan-out / Fan-in
305
+ printSection('Part 4: Fan-Out / Fan-In Pattern');
306
+ {
307
+ const workflow = new FanOutFanInWorkflow('FanOutFanIn');
308
+ const debugger_ = new WorkflowTreeDebugger(workflow);
309
+
310
+ const results = await workflow.run();
311
+
312
+ console.log('Results:', results);
313
+ console.log('\nTree:');
314
+ console.log(debugger_.toTreeString());
315
+
316
+ const stats = debugger_.getStats();
317
+ console.log('Statistics:', stats);
318
+ }
319
+
320
+ // Part 5: Performance comparison summary
321
+ printSection('Part 5: Performance Summary');
322
+ {
323
+ const configs = [
324
+ { id: 'A', time: 100 },
325
+ { id: 'B', time: 100 },
326
+ { id: 'C', time: 100 },
327
+ { id: 'D', time: 100 },
328
+ ];
329
+
330
+ // Sequential
331
+ const seq = new SequentialWorkflow('SeqTest', configs);
332
+ const seqStart = Date.now();
333
+ await seq.run();
334
+ const seqTime = Date.now() - seqStart;
335
+
336
+ // Parallel
337
+ const par = new ManualParallelWorkflow('ParTest', configs);
338
+ const parStart = Date.now();
339
+ await par.run();
340
+ const parTime = Date.now() - parStart;
341
+
342
+ console.log('4 workers x 100ms each:');
343
+ console.log(` Sequential: ${seqTime}ms`);
344
+ console.log(` Parallel: ${parTime}ms`);
345
+ console.log(` Speedup: ${(seqTime / parTime).toFixed(2)}x`);
346
+ }
347
+ }
348
+
349
+ // Run if executed directly
350
+ if (import.meta.url === `file://${process.argv[1]}`) {
351
+ runConcurrentTasksExample().catch(console.error);
352
+ }