@lov3kaizen/agentsea-crews 0.5.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/dist/index.mjs ADDED
@@ -0,0 +1,2528 @@
1
+ import {
2
+ CrewDashboard,
3
+ DebugMode,
4
+ createDashboard,
5
+ createDebugMode
6
+ } from "./chunk-4PF73ECN.mjs";
7
+ import {
8
+ CodeReviewTasks,
9
+ CustomerSupportTasks,
10
+ ResearchTasks,
11
+ WritingTasks,
12
+ createCodeReviewCrew,
13
+ createCodeReviewCrewConfig,
14
+ createCustomerSupportCrew,
15
+ createCustomerSupportCrewConfig,
16
+ createResearchCrew,
17
+ createResearchCrewConfig,
18
+ createWritingCrew,
19
+ createWritingCrewConfig
20
+ } from "./chunk-G3PAPYOI.mjs";
21
+ import {
22
+ AgentCapabilities,
23
+ AgentRegistry,
24
+ AuctionStrategy,
25
+ BaseDelegationStrategy,
26
+ BestMatchStrategy,
27
+ CollaborationManager,
28
+ ConflictResolver,
29
+ ConsensusStrategy,
30
+ Crew,
31
+ CrewAgent,
32
+ DelegationCoordinator,
33
+ DelegationError,
34
+ ExecutionContext,
35
+ HierarchicalStrategy,
36
+ Role,
37
+ RoundRobinStrategy,
38
+ STRATEGY_TYPES,
39
+ Task,
40
+ TaskQueue,
41
+ createAgentRegistry,
42
+ createAuctionStrategy,
43
+ createBestMatchStrategy,
44
+ createCollaborationManager,
45
+ createConflictResolver,
46
+ createConsensusStrategy,
47
+ createCrew,
48
+ createCrewAgent,
49
+ createDelegationCoordinator,
50
+ createExecutionContext,
51
+ createHierarchicalStrategy,
52
+ createRole,
53
+ createRoundRobinStrategy,
54
+ createStrategy,
55
+ createTask,
56
+ createTaskQueue
57
+ } from "./chunk-QMK3HWFX.mjs";
58
+
59
+ // src/types/role.types.ts
60
+ var PROFICIENCY_WEIGHTS = {
61
+ novice: 0.25,
62
+ intermediate: 0.5,
63
+ expert: 0.75,
64
+ master: 1
65
+ };
66
+
67
+ // src/types/task.types.ts
68
+ var PRIORITY_WEIGHTS = {
69
+ critical: 100,
70
+ high: 75,
71
+ medium: 50,
72
+ low: 25
73
+ };
74
+
75
+ // src/workflows/WorkflowBuilder.ts
76
+ import { nanoid } from "nanoid";
77
+ var BranchBuilder = class {
78
+ parent;
79
+ condition;
80
+ thenSteps = [];
81
+ elseSteps = [];
82
+ constructor(parent, condition) {
83
+ this.parent = parent;
84
+ this.condition = condition;
85
+ }
86
+ /**
87
+ * Add steps for true branch
88
+ */
89
+ then(builder) {
90
+ const subBuilder = new WorkflowBuilder(`then-${nanoid(6)}`);
91
+ builder(subBuilder);
92
+ this.thenSteps = subBuilder.getSteps();
93
+ return this;
94
+ }
95
+ /**
96
+ * Add steps for false branch
97
+ */
98
+ otherwise(builder) {
99
+ const subBuilder = new WorkflowBuilder(`else-${nanoid(6)}`);
100
+ builder(subBuilder);
101
+ this.elseSteps = subBuilder.getSteps();
102
+ return this;
103
+ }
104
+ /**
105
+ * Complete the branch and return to parent builder
106
+ */
107
+ endBranch() {
108
+ const conditionalConfig = {
109
+ name: `conditional-${nanoid(6)}`,
110
+ condition: this.condition,
111
+ thenSteps: this.thenSteps.map((s) => s.config),
112
+ elseSteps: this.elseSteps.length > 0 ? this.elseSteps.map((s) => s.config) : void 0
113
+ };
114
+ this.parent.addConditional(
115
+ conditionalConfig,
116
+ this.thenSteps,
117
+ this.elseSteps
118
+ );
119
+ return this.parent;
120
+ }
121
+ };
122
+ var LoopBuilder = class {
123
+ parent;
124
+ condition;
125
+ bodySteps = [];
126
+ maxIter = 100;
127
+ constructor(parent, condition) {
128
+ this.parent = parent;
129
+ this.condition = condition;
130
+ }
131
+ /**
132
+ * Set loop body
133
+ */
134
+ do(builder) {
135
+ const subBuilder = new WorkflowBuilder(`loop-body-${nanoid(6)}`);
136
+ builder(subBuilder);
137
+ this.bodySteps = subBuilder.getSteps();
138
+ return this;
139
+ }
140
+ /**
141
+ * Set maximum iterations
142
+ */
143
+ maxIterations(max) {
144
+ this.maxIter = max;
145
+ return this;
146
+ }
147
+ /**
148
+ * Complete the loop and return to parent builder
149
+ */
150
+ endLoop() {
151
+ const loopConfig = {
152
+ name: `loop-${nanoid(6)}`,
153
+ condition: this.condition,
154
+ maxIterations: this.maxIter,
155
+ bodySteps: this.bodySteps.map((s) => s.config)
156
+ };
157
+ this.parent.addLoop(loopConfig, this.bodySteps);
158
+ return this.parent;
159
+ }
160
+ };
161
+ var WorkflowBuilder = class {
162
+ name;
163
+ description;
164
+ steps = [];
165
+ stepHandlers = /* @__PURE__ */ new Map();
166
+ checkpointEnabled = false;
167
+ checkpointInterval = "after-step";
168
+ constructor(name) {
169
+ this.name = name;
170
+ }
171
+ /**
172
+ * Set workflow description
173
+ */
174
+ describe(description) {
175
+ this.description = description;
176
+ return this;
177
+ }
178
+ /**
179
+ * Add a sequential step
180
+ */
181
+ addStep(name, handler, options = {}) {
182
+ const stepConfig = {
183
+ name,
184
+ type: "task",
185
+ ...options
186
+ };
187
+ this.steps.push({
188
+ type: "step",
189
+ config: stepConfig,
190
+ handler
191
+ });
192
+ this.stepHandlers.set(name, handler);
193
+ return this;
194
+ }
195
+ /**
196
+ * Add parallel steps
197
+ */
198
+ parallel(...steps) {
199
+ const parallelConfig = {
200
+ name: `parallel-${nanoid(6)}`,
201
+ steps: steps.map((s) => ({
202
+ name: s.name,
203
+ type: "task"
204
+ })),
205
+ waitFor: "all"
206
+ };
207
+ const children = steps.map((s) => ({
208
+ type: "step",
209
+ config: { name: s.name, type: "task" },
210
+ handler: s.handler
211
+ }));
212
+ for (const step of steps) {
213
+ this.stepHandlers.set(step.name, step.handler);
214
+ }
215
+ this.steps.push({
216
+ type: "parallel",
217
+ config: parallelConfig,
218
+ children
219
+ });
220
+ return this;
221
+ }
222
+ /**
223
+ * Add sequential steps
224
+ */
225
+ sequential(...steps) {
226
+ for (const step of steps) {
227
+ this.addStep(step.name, step.handler);
228
+ }
229
+ return this;
230
+ }
231
+ /**
232
+ * Add conditional branch
233
+ */
234
+ when(condition) {
235
+ return new BranchBuilder(this, condition);
236
+ }
237
+ /**
238
+ * Add a loop
239
+ */
240
+ while(condition) {
241
+ return new LoopBuilder(this, condition);
242
+ }
243
+ /**
244
+ * Add a checkpoint
245
+ */
246
+ checkpoint(name) {
247
+ this.steps.push({
248
+ type: "checkpoint",
249
+ config: {
250
+ name,
251
+ type: "checkpoint"
252
+ }
253
+ });
254
+ return this;
255
+ }
256
+ /**
257
+ * Enable automatic checkpointing
258
+ */
259
+ enableCheckpoints(interval = "after-step") {
260
+ this.checkpointEnabled = true;
261
+ this.checkpointInterval = interval;
262
+ return this;
263
+ }
264
+ /**
265
+ * Add a task step with agent assignment
266
+ */
267
+ task(name, description, options = {}) {
268
+ const stepConfig = {
269
+ name,
270
+ type: "task",
271
+ agentName: options.agent,
272
+ taskConfig: {
273
+ description,
274
+ expectedOutput: `Result of ${name}`,
275
+ requiredCapabilities: options.requiredCapabilities
276
+ },
277
+ timeoutMs: options.timeout
278
+ };
279
+ this.steps.push({
280
+ type: "step",
281
+ config: stepConfig
282
+ });
283
+ return this;
284
+ }
285
+ /**
286
+ * Add a crew step (delegate to entire crew)
287
+ */
288
+ crew(name, description, options = {}) {
289
+ const stepConfig = {
290
+ name,
291
+ type: "crew",
292
+ taskConfig: {
293
+ description,
294
+ expectedOutput: `Result of crew: ${name}`
295
+ },
296
+ timeoutMs: options.timeout
297
+ };
298
+ this.steps.push({
299
+ type: "step",
300
+ config: stepConfig
301
+ });
302
+ return this;
303
+ }
304
+ /**
305
+ * Internal: add conditional step
306
+ */
307
+ addConditional(config, thenSteps, elseSteps) {
308
+ this.steps.push({
309
+ type: "conditional",
310
+ config,
311
+ children: [...thenSteps, ...elseSteps]
312
+ });
313
+ for (const step of [...thenSteps, ...elseSteps]) {
314
+ if (step.handler) {
315
+ this.stepHandlers.set(
316
+ step.config.name,
317
+ step.handler
318
+ );
319
+ }
320
+ }
321
+ }
322
+ /**
323
+ * Internal: add loop step
324
+ */
325
+ addLoop(config, bodySteps) {
326
+ this.steps.push({
327
+ type: "loop",
328
+ config,
329
+ children: bodySteps
330
+ });
331
+ for (const step of bodySteps) {
332
+ if (step.handler) {
333
+ this.stepHandlers.set(
334
+ step.config.name,
335
+ step.handler
336
+ );
337
+ }
338
+ }
339
+ }
340
+ /**
341
+ * Internal: get steps for sub-builders
342
+ */
343
+ getSteps() {
344
+ return [...this.steps];
345
+ }
346
+ /**
347
+ * Build the workflow definition
348
+ */
349
+ build() {
350
+ return {
351
+ id: nanoid(),
352
+ name: this.name,
353
+ description: this.description,
354
+ steps: this.steps.map((s) => s.config),
355
+ handlers: this.stepHandlers,
356
+ checkpointing: this.checkpointEnabled ? { enabled: true, interval: this.checkpointInterval } : void 0
357
+ };
358
+ }
359
+ /**
360
+ * Get a step handler by name
361
+ */
362
+ getHandler(stepName) {
363
+ return this.stepHandlers.get(stepName);
364
+ }
365
+ /**
366
+ * Validate the workflow
367
+ */
368
+ validate() {
369
+ const errors = [];
370
+ if (this.steps.length === 0) {
371
+ errors.push("Workflow has no steps");
372
+ }
373
+ const names = /* @__PURE__ */ new Set();
374
+ for (const step of this.steps) {
375
+ const name = step.config.name;
376
+ if (names.has(name)) {
377
+ errors.push(`Duplicate step name: ${name}`);
378
+ }
379
+ names.add(name);
380
+ }
381
+ for (const step of this.steps) {
382
+ if (step.type === "step") {
383
+ const name = step.config.name;
384
+ if (!this.stepHandlers.has(name) && !step.config.agentName) {
385
+ errors.push(`Step "${name}" has no handler and no assigned agent`);
386
+ }
387
+ }
388
+ }
389
+ return {
390
+ valid: errors.length === 0,
391
+ errors
392
+ };
393
+ }
394
+ };
395
+ function workflow(name) {
396
+ return new WorkflowBuilder(name);
397
+ }
398
+
399
+ // src/workflows/DAGExecutor.ts
400
+ import { nanoid as nanoid2 } from "nanoid";
401
+ var DAGExecutor = class {
402
+ dag;
403
+ _handlers;
404
+ config;
405
+ nodeStates = /* @__PURE__ */ new Map();
406
+ cache = /* @__PURE__ */ new Map();
407
+ aborted = false;
408
+ constructor(dag, handlers, config = {}) {
409
+ this.dag = dag;
410
+ this._handlers = handlers;
411
+ this.config = {
412
+ maxParallel: config.maxParallel ?? 5,
413
+ defaultTimeout: config.defaultTimeout ?? 6e4,
414
+ retryOnFailure: config.retryOnFailure ?? true,
415
+ maxRetries: config.maxRetries ?? 2,
416
+ enableCaching: config.enableCaching ?? false
417
+ };
418
+ for (const node of dag.nodes) {
419
+ this.nodeStates.set(node.id, {
420
+ status: "pending",
421
+ retries: 0
422
+ });
423
+ }
424
+ }
425
+ /**
426
+ * Execute the DAG
427
+ */
428
+ async execute(context) {
429
+ const startTime = Date.now();
430
+ const events = [];
431
+ for await (const event of this.executeStream(context)) {
432
+ events.push(event);
433
+ }
434
+ const results = /* @__PURE__ */ new Map();
435
+ for (const [nodeId, state] of this.nodeStates) {
436
+ if (state.result) {
437
+ results.set(nodeId, state.result);
438
+ }
439
+ }
440
+ const failedNodes = Array.from(this.nodeStates.entries()).filter(([, state]) => state.status === "failed").map(([id]) => id);
441
+ return {
442
+ success: failedNodes.length === 0 && !this.aborted,
443
+ results,
444
+ events,
445
+ executionTimeMs: Date.now() - startTime,
446
+ failedNodes: failedNodes.length > 0 ? failedNodes : void 0
447
+ };
448
+ }
449
+ /**
450
+ * Execute the DAG with streaming events
451
+ */
452
+ async *executeStream(context) {
453
+ this.aborted = false;
454
+ yield {
455
+ type: "dag:start",
456
+ dagId: this.dag.id,
457
+ timestamp: /* @__PURE__ */ new Date()
458
+ };
459
+ while (!this.isComplete()) {
460
+ if (this.aborted) {
461
+ yield {
462
+ type: "dag:aborted",
463
+ dagId: this.dag.id,
464
+ timestamp: /* @__PURE__ */ new Date()
465
+ };
466
+ break;
467
+ }
468
+ const readyNodes = this.getReadyNodes();
469
+ if (readyNodes.length === 0) {
470
+ const pendingCount = this.getPendingCount();
471
+ if (pendingCount > 0) {
472
+ yield {
473
+ type: "dag:error",
474
+ dagId: this.dag.id,
475
+ error: "Deadlock detected: no nodes ready but pending nodes exist",
476
+ timestamp: /* @__PURE__ */ new Date()
477
+ };
478
+ break;
479
+ }
480
+ continue;
481
+ }
482
+ const batch = readyNodes.slice(0, this.config.maxParallel);
483
+ const promises = [];
484
+ for (const node of batch) {
485
+ this.updateNodeState(node.id, {
486
+ status: "running",
487
+ startTime: /* @__PURE__ */ new Date()
488
+ });
489
+ yield {
490
+ type: "node:start",
491
+ dagId: this.dag.id,
492
+ nodeId: node.id,
493
+ nodeName: node.name,
494
+ timestamp: /* @__PURE__ */ new Date()
495
+ };
496
+ promises.push(this.executeNode(node, context));
497
+ }
498
+ const results = await Promise.all(promises);
499
+ for (const { nodeId, result, error } of results) {
500
+ const node = this.dag.nodes.find((n) => n.id === nodeId);
501
+ if (error) {
502
+ const state = this.nodeStates.get(nodeId);
503
+ if (this.config.retryOnFailure && state.retries < this.config.maxRetries) {
504
+ this.updateNodeState(nodeId, {
505
+ status: "pending",
506
+ retries: state.retries + 1
507
+ });
508
+ yield {
509
+ type: "node:retry",
510
+ dagId: this.dag.id,
511
+ nodeId,
512
+ nodeName: node.name,
513
+ attempt: state.retries + 1,
514
+ error,
515
+ timestamp: /* @__PURE__ */ new Date()
516
+ };
517
+ } else {
518
+ this.updateNodeState(nodeId, {
519
+ status: "failed",
520
+ error,
521
+ endTime: /* @__PURE__ */ new Date()
522
+ });
523
+ yield {
524
+ type: "node:error",
525
+ dagId: this.dag.id,
526
+ nodeId,
527
+ nodeName: node.name,
528
+ error,
529
+ timestamp: /* @__PURE__ */ new Date()
530
+ };
531
+ for (const depId of this.getDependentNodes(nodeId)) {
532
+ this.updateNodeState(depId, { status: "skipped" });
533
+ yield {
534
+ type: "node:skipped",
535
+ dagId: this.dag.id,
536
+ nodeId: depId,
537
+ nodeName: this.dag.nodes.find((n) => n.id === depId)?.name ?? "",
538
+ reason: `Dependency ${node.name} failed`,
539
+ timestamp: /* @__PURE__ */ new Date()
540
+ };
541
+ }
542
+ }
543
+ } else {
544
+ this.updateNodeState(nodeId, {
545
+ status: "completed",
546
+ result,
547
+ endTime: /* @__PURE__ */ new Date()
548
+ });
549
+ if (this.config.enableCaching) {
550
+ this.cache.set(nodeId, result);
551
+ }
552
+ yield {
553
+ type: "node:complete",
554
+ dagId: this.dag.id,
555
+ nodeId,
556
+ nodeName: node.name,
557
+ result,
558
+ timestamp: /* @__PURE__ */ new Date()
559
+ };
560
+ }
561
+ }
562
+ }
563
+ yield {
564
+ type: "dag:complete",
565
+ dagId: this.dag.id,
566
+ success: this.isSuccessful(),
567
+ timestamp: /* @__PURE__ */ new Date()
568
+ };
569
+ }
570
+ /**
571
+ * Execute a single node
572
+ */
573
+ async executeNode(node, context) {
574
+ if (this.config.enableCaching && this.cache.has(node.id)) {
575
+ return { nodeId: node.id, result: this.cache.get(node.id) };
576
+ }
577
+ const nodeName = node.name ?? node.id;
578
+ const handler = this._handlers.get(nodeName);
579
+ if (!handler) {
580
+ return {
581
+ nodeId: node.id,
582
+ result: null,
583
+ error: `No handler found for node: ${nodeName}`
584
+ };
585
+ }
586
+ const workflowContext = this.buildWorkflowContext(node, context);
587
+ const timeout = node.stepConfig?.timeoutMs ?? this.config.defaultTimeout;
588
+ try {
589
+ const result = await Promise.race([
590
+ handler(workflowContext),
591
+ this.createTimeout(timeout, nodeName)
592
+ ]);
593
+ return { nodeId: node.id, result };
594
+ } catch (error) {
595
+ return {
596
+ nodeId: node.id,
597
+ result: null,
598
+ error: error instanceof Error ? error.message : String(error)
599
+ };
600
+ }
601
+ }
602
+ /**
603
+ * Build workflow context for a node
604
+ */
605
+ buildWorkflowContext(node, context) {
606
+ const stepResults = /* @__PURE__ */ new Map();
607
+ for (const depId of node.dependencies ?? []) {
608
+ const state = this.nodeStates.get(depId);
609
+ if (state?.result) {
610
+ const depNode = this.dag.nodes.find((n) => n.id === depId);
611
+ if (depNode) {
612
+ const depNodeName = depNode.name ?? depNode.id;
613
+ stepResults.set(depNodeName, state.result);
614
+ }
615
+ }
616
+ }
617
+ return {
618
+ stepName: node.name ?? node.id,
619
+ stepResults,
620
+ variables: new Map(context.entries()),
621
+ setVariable: (key, value) => context.set(key, value),
622
+ getVariable: (key) => context.get(key),
623
+ emit: (event) => context.emit(event),
624
+ isAborted: () => context.isAborted || this.aborted
625
+ };
626
+ }
627
+ /**
628
+ * Create a timeout promise
629
+ */
630
+ createTimeout(ms, stepName) {
631
+ return new Promise((_, reject) => {
632
+ setTimeout(() => {
633
+ reject(new Error(`Step "${stepName}" timed out after ${ms}ms`));
634
+ }, ms);
635
+ });
636
+ }
637
+ /**
638
+ * Get nodes ready for execution
639
+ */
640
+ getReadyNodes() {
641
+ const ready = [];
642
+ for (const node of this.dag.nodes) {
643
+ const state = this.nodeStates.get(node.id);
644
+ if (state?.status !== "pending") continue;
645
+ const depsCompleted = (node.dependencies ?? []).every((depId) => {
646
+ const depState = this.nodeStates.get(depId);
647
+ return depState?.status === "completed";
648
+ });
649
+ if (depsCompleted) {
650
+ ready.push(node);
651
+ }
652
+ }
653
+ return ready;
654
+ }
655
+ /**
656
+ * Get nodes that depend on a given node
657
+ */
658
+ getDependentNodes(nodeId) {
659
+ const dependents = [];
660
+ for (const node of this.dag.nodes) {
661
+ if (node.dependencies?.includes(nodeId)) {
662
+ dependents.push(node.id);
663
+ dependents.push(...this.getDependentNodes(node.id));
664
+ }
665
+ }
666
+ return [...new Set(dependents)];
667
+ }
668
+ /**
669
+ * Update node state
670
+ */
671
+ updateNodeState(nodeId, update) {
672
+ const current = this.nodeStates.get(nodeId) ?? {
673
+ status: "pending",
674
+ retries: 0
675
+ };
676
+ this.nodeStates.set(nodeId, { ...current, ...update });
677
+ }
678
+ /**
679
+ * Check if all nodes are done
680
+ */
681
+ isComplete() {
682
+ for (const state of this.nodeStates.values()) {
683
+ if (state.status === "pending" || state.status === "running") {
684
+ return false;
685
+ }
686
+ }
687
+ return true;
688
+ }
689
+ /**
690
+ * Check if execution was successful
691
+ */
692
+ isSuccessful() {
693
+ for (const state of this.nodeStates.values()) {
694
+ if (state.status === "failed") {
695
+ return false;
696
+ }
697
+ }
698
+ return !this.aborted;
699
+ }
700
+ /**
701
+ * Get count of pending nodes
702
+ */
703
+ getPendingCount() {
704
+ let count = 0;
705
+ for (const state of this.nodeStates.values()) {
706
+ if (state.status === "pending") count++;
707
+ }
708
+ return count;
709
+ }
710
+ /**
711
+ * Abort execution
712
+ */
713
+ abort() {
714
+ this.aborted = true;
715
+ }
716
+ /**
717
+ * Validate the DAG
718
+ */
719
+ validate() {
720
+ const errors = [];
721
+ const warnings = [];
722
+ if (this.dag.nodes.length === 0) {
723
+ errors.push("DAG has no nodes");
724
+ }
725
+ const nodeIds = new Set(this.dag.nodes.map((n) => n.id));
726
+ for (const node of this.dag.nodes) {
727
+ const nodeName = node.name ?? node.id;
728
+ for (const depId of node.dependencies ?? []) {
729
+ if (!nodeIds.has(depId)) {
730
+ errors.push(`Node "${nodeName}" has missing dependency: ${depId}`);
731
+ }
732
+ }
733
+ }
734
+ const cycle = this.detectCycle();
735
+ if (cycle) {
736
+ errors.push(`Cycle detected: ${cycle.join(" -> ")}`);
737
+ }
738
+ for (const node of this.dag.nodes) {
739
+ const nodeName = node.name ?? node.id;
740
+ if (!this._handlers.has(nodeName)) {
741
+ warnings.push(`Node "${nodeName}" has no handler`);
742
+ }
743
+ }
744
+ return {
745
+ valid: errors.length === 0,
746
+ errors,
747
+ warnings
748
+ };
749
+ }
750
+ /**
751
+ * Detect cycles in the DAG
752
+ */
753
+ detectCycle() {
754
+ const visited = /* @__PURE__ */ new Set();
755
+ const recursionStack = /* @__PURE__ */ new Set();
756
+ const path = [];
757
+ const dfs = (nodeId) => {
758
+ visited.add(nodeId);
759
+ recursionStack.add(nodeId);
760
+ path.push(nodeId);
761
+ const node = this.dag.nodes.find((n) => n.id === nodeId);
762
+ if (node) {
763
+ for (const depId of node.dependencies ?? []) {
764
+ if (!visited.has(depId)) {
765
+ if (dfs(depId)) return true;
766
+ } else if (recursionStack.has(depId)) {
767
+ path.push(depId);
768
+ return true;
769
+ }
770
+ }
771
+ }
772
+ recursionStack.delete(nodeId);
773
+ path.pop();
774
+ return false;
775
+ };
776
+ for (const node of this.dag.nodes) {
777
+ if (!visited.has(node.id)) {
778
+ if (dfs(node.id)) {
779
+ const cycleStart = path.indexOf(path[path.length - 1]);
780
+ return path.slice(cycleStart).map((id) => this.dag.nodes.find((n) => n.id === id)?.name ?? id);
781
+ }
782
+ }
783
+ }
784
+ return null;
785
+ }
786
+ /**
787
+ * Get execution state for all nodes
788
+ */
789
+ getState() {
790
+ return new Map(this.nodeStates);
791
+ }
792
+ /**
793
+ * Get execution statistics
794
+ */
795
+ getStatistics() {
796
+ let completed = 0;
797
+ let failed = 0;
798
+ let skipped = 0;
799
+ let pending = 0;
800
+ let running = 0;
801
+ for (const state of this.nodeStates.values()) {
802
+ switch (state.status) {
803
+ case "completed":
804
+ completed++;
805
+ break;
806
+ case "failed":
807
+ failed++;
808
+ break;
809
+ case "skipped":
810
+ skipped++;
811
+ break;
812
+ case "pending":
813
+ pending++;
814
+ break;
815
+ case "running":
816
+ running++;
817
+ break;
818
+ }
819
+ }
820
+ return {
821
+ totalNodes: this.dag.nodes.length,
822
+ completed,
823
+ failed,
824
+ skipped,
825
+ pending,
826
+ running
827
+ };
828
+ }
829
+ };
830
+ function createDAGFromSteps(steps, _handlers) {
831
+ const nodes = [];
832
+ const previousNodeIds = [];
833
+ for (let i = 0; i < steps.length; i++) {
834
+ const step = steps[i];
835
+ const nodeId = nanoid2();
836
+ const node = {
837
+ id: nodeId,
838
+ name: step.name,
839
+ stepConfig: step,
840
+ dependencies: [...previousNodeIds]
841
+ // Sequential by default
842
+ };
843
+ nodes.push(node);
844
+ previousNodeIds.length = 0;
845
+ previousNodeIds.push(nodeId);
846
+ }
847
+ return {
848
+ id: nanoid2(),
849
+ nodes,
850
+ edges: []
851
+ };
852
+ }
853
+ function createDAGExecutor(dag, handlers, config) {
854
+ return new DAGExecutor(dag, handlers, config);
855
+ }
856
+
857
+ // src/workflows/ParallelExecution.ts
858
+ var ParallelExecutor = class {
859
+ options;
860
+ constructor(options = {}) {
861
+ this.options = {
862
+ maxConcurrency: options.maxConcurrency ?? 5,
863
+ taskTimeout: options.taskTimeout ?? 6e4,
864
+ failFast: options.failFast ?? false,
865
+ continueOnError: options.continueOnError ?? true
866
+ };
867
+ }
868
+ /**
869
+ * Execute tasks in parallel
870
+ */
871
+ async executeBatch(tasks, executor, _context) {
872
+ const startTime = Date.now();
873
+ const results = [];
874
+ let aborted = false;
875
+ const semaphore = new Semaphore(this.options.maxConcurrency);
876
+ const taskPromises = tasks.map(async (task) => {
877
+ if (aborted) {
878
+ return {
879
+ taskId: task.id,
880
+ status: "failed",
881
+ error: "Batch aborted",
882
+ executionTimeMs: 0
883
+ };
884
+ }
885
+ await semaphore.acquire();
886
+ const taskStartTime = Date.now();
887
+ try {
888
+ const result = await Promise.race([
889
+ executor(task),
890
+ this.createTimeout(this.options.taskTimeout)
891
+ ]);
892
+ return {
893
+ taskId: task.id,
894
+ status: "success",
895
+ result,
896
+ executionTimeMs: Date.now() - taskStartTime
897
+ };
898
+ } catch (error) {
899
+ const isTimeout = error instanceof TimeoutError;
900
+ if (this.options.failFast && !isTimeout) {
901
+ aborted = true;
902
+ }
903
+ return {
904
+ taskId: task.id,
905
+ status: isTimeout ? "timeout" : "failed",
906
+ error: error instanceof Error ? error.message : String(error),
907
+ executionTimeMs: Date.now() - taskStartTime
908
+ };
909
+ } finally {
910
+ semaphore.release();
911
+ }
912
+ });
913
+ const parallelResults = await Promise.all(taskPromises);
914
+ results.push(...parallelResults);
915
+ const successCount = results.filter((r) => r.status === "success").length;
916
+ const failureCount = results.filter((r) => r.status !== "success").length;
917
+ return {
918
+ results,
919
+ totalTimeMs: Date.now() - startTime,
920
+ successCount,
921
+ failureCount,
922
+ allSuccessful: failureCount === 0
923
+ };
924
+ }
925
+ /**
926
+ * Execute tasks with agent assignment
927
+ */
928
+ async executeWithAgents(tasks, agents, context) {
929
+ const agentQueue = new AgentPool(agents);
930
+ const executor = async (task) => {
931
+ const agent = await agentQueue.acquire();
932
+ try {
933
+ return await agent.executeTask(task);
934
+ } finally {
935
+ agentQueue.release(agent);
936
+ }
937
+ };
938
+ return this.executeBatch(tasks, executor, context);
939
+ }
940
+ /**
941
+ * Map over items with parallel execution
942
+ */
943
+ async map(items, mapper) {
944
+ const semaphore = new Semaphore(this.options.maxConcurrency);
945
+ let aborted = false;
946
+ const results = await Promise.all(
947
+ items.map(async (item, index) => {
948
+ if (aborted) {
949
+ return { item, error: "Aborted" };
950
+ }
951
+ await semaphore.acquire();
952
+ try {
953
+ const result = await mapper(item, index);
954
+ return { item, result };
955
+ } catch (error) {
956
+ if (this.options.failFast) {
957
+ aborted = true;
958
+ }
959
+ return {
960
+ item,
961
+ error: error instanceof Error ? error.message : String(error)
962
+ };
963
+ } finally {
964
+ semaphore.release();
965
+ }
966
+ })
967
+ );
968
+ return results;
969
+ }
970
+ /**
971
+ * Execute tasks in batches
972
+ */
973
+ async executeBatches(items, batchSize, processor) {
974
+ const results = [];
975
+ const batches = [];
976
+ for (let i = 0; i < items.length; i += batchSize) {
977
+ batches.push(items.slice(i, i + batchSize));
978
+ }
979
+ const semaphore = new Semaphore(this.options.maxConcurrency);
980
+ await Promise.all(
981
+ batches.map(async (batch) => {
982
+ await semaphore.acquire();
983
+ try {
984
+ const batchResults = await processor(batch);
985
+ results.push(...batchResults);
986
+ } finally {
987
+ semaphore.release();
988
+ }
989
+ })
990
+ );
991
+ return results;
992
+ }
993
+ /**
994
+ * Create a timeout promise
995
+ */
996
+ createTimeout(ms) {
997
+ return new Promise((_, reject) => {
998
+ setTimeout(() => {
999
+ reject(new TimeoutError(`Task timed out after ${ms}ms`));
1000
+ }, ms);
1001
+ });
1002
+ }
1003
+ };
1004
+ var Semaphore = class {
1005
+ permits;
1006
+ waiting = [];
1007
+ constructor(permits) {
1008
+ this.permits = permits;
1009
+ }
1010
+ async acquire() {
1011
+ if (this.permits > 0) {
1012
+ this.permits--;
1013
+ return;
1014
+ }
1015
+ return new Promise((resolve) => {
1016
+ this.waiting.push(resolve);
1017
+ });
1018
+ }
1019
+ release() {
1020
+ if (this.waiting.length > 0) {
1021
+ const next = this.waiting.shift();
1022
+ next();
1023
+ } else {
1024
+ this.permits++;
1025
+ }
1026
+ }
1027
+ };
1028
+ var AgentPool = class {
1029
+ available;
1030
+ waiting = [];
1031
+ constructor(agents) {
1032
+ this.available = [...agents];
1033
+ }
1034
+ async acquire() {
1035
+ if (this.available.length > 0) {
1036
+ return this.available.pop();
1037
+ }
1038
+ return new Promise((resolve) => {
1039
+ this.waiting.push(resolve);
1040
+ });
1041
+ }
1042
+ release(agent) {
1043
+ if (this.waiting.length > 0) {
1044
+ const next = this.waiting.shift();
1045
+ next(agent);
1046
+ } else {
1047
+ this.available.push(agent);
1048
+ }
1049
+ }
1050
+ };
1051
+ var TimeoutError = class extends Error {
1052
+ constructor(message) {
1053
+ super(message);
1054
+ this.name = "TimeoutError";
1055
+ }
1056
+ };
1057
+ function createParallelExecutor(options) {
1058
+ return new ParallelExecutor(options);
1059
+ }
1060
+
1061
+ // src/workflows/Checkpointing.ts
1062
+ import { nanoid as nanoid3 } from "nanoid";
1063
+ var InMemoryCheckpointStorage = class {
1064
+ checkpoints = /* @__PURE__ */ new Map();
1065
+ save(checkpoint) {
1066
+ this.checkpoints.set(checkpoint.id, checkpoint);
1067
+ return Promise.resolve(checkpoint.id);
1068
+ }
1069
+ load(checkpointId) {
1070
+ return Promise.resolve(this.checkpoints.get(checkpointId) ?? null);
1071
+ }
1072
+ list(workflowId) {
1073
+ const ids = [];
1074
+ for (const [id, checkpoint] of this.checkpoints) {
1075
+ if (checkpoint.workflowId === workflowId) {
1076
+ ids.push(id);
1077
+ }
1078
+ }
1079
+ return Promise.resolve(ids);
1080
+ }
1081
+ delete(checkpointId) {
1082
+ this.checkpoints.delete(checkpointId);
1083
+ return Promise.resolve();
1084
+ }
1085
+ deleteAll(workflowId) {
1086
+ for (const [id, checkpoint] of this.checkpoints) {
1087
+ if (checkpoint.workflowId === workflowId) {
1088
+ this.checkpoints.delete(id);
1089
+ }
1090
+ }
1091
+ return Promise.resolve();
1092
+ }
1093
+ clear() {
1094
+ this.checkpoints.clear();
1095
+ }
1096
+ };
1097
+ var CheckpointManager = class {
1098
+ storage;
1099
+ config;
1100
+ autoCheckpointTimer;
1101
+ stepCounter = 0;
1102
+ currentWorkflowId;
1103
+ constructor(config = {}) {
1104
+ this.storage = config.storage ?? new InMemoryCheckpointStorage();
1105
+ this.config = {
1106
+ autoCheckpointInterval: config.autoCheckpointInterval ?? "after-step",
1107
+ maxCheckpoints: config.maxCheckpoints ?? 10,
1108
+ compress: config.compress ?? false
1109
+ };
1110
+ }
1111
+ /**
1112
+ * Save a checkpoint
1113
+ */
1114
+ async save(workflowId, state) {
1115
+ const checkpoint = {
1116
+ id: nanoid3(),
1117
+ workflowId,
1118
+ timestamp: /* @__PURE__ */ new Date(),
1119
+ stepIndex: state.currentStepIndex,
1120
+ stepResults: state.stepResults,
1121
+ variables: Object.fromEntries(state.variables),
1122
+ metadata: state.metadata
1123
+ };
1124
+ await this.storage.save(checkpoint);
1125
+ await this.cleanupOldCheckpoints(workflowId);
1126
+ return checkpoint;
1127
+ }
1128
+ /**
1129
+ * Load a checkpoint
1130
+ */
1131
+ async load(checkpointId) {
1132
+ return this.storage.load(checkpointId);
1133
+ }
1134
+ /**
1135
+ * Load the latest checkpoint for a workflow
1136
+ */
1137
+ async loadLatest(workflowId) {
1138
+ const checkpointIds = await this.storage.list(workflowId);
1139
+ if (checkpointIds.length === 0) {
1140
+ return null;
1141
+ }
1142
+ let latest = null;
1143
+ for (const id of checkpointIds) {
1144
+ const checkpoint = await this.storage.load(id);
1145
+ if (checkpoint) {
1146
+ if (!latest || checkpoint.timestamp > latest.timestamp) {
1147
+ latest = checkpoint;
1148
+ }
1149
+ }
1150
+ }
1151
+ return latest;
1152
+ }
1153
+ /**
1154
+ * Delete a checkpoint
1155
+ */
1156
+ async delete(checkpointId) {
1157
+ await this.storage.delete(checkpointId);
1158
+ }
1159
+ /**
1160
+ * Delete all checkpoints for a workflow
1161
+ */
1162
+ async deleteAll(workflowId) {
1163
+ await this.storage.deleteAll(workflowId);
1164
+ }
1165
+ /**
1166
+ * List checkpoints for a workflow
1167
+ */
1168
+ async list(workflowId) {
1169
+ const ids = await this.storage.list(workflowId);
1170
+ const checkpoints = [];
1171
+ for (const id of ids) {
1172
+ const checkpoint = await this.storage.load(id);
1173
+ if (checkpoint) {
1174
+ checkpoints.push(checkpoint);
1175
+ }
1176
+ }
1177
+ checkpoints.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
1178
+ return checkpoints;
1179
+ }
1180
+ /**
1181
+ * Enable automatic checkpointing
1182
+ */
1183
+ enableAutoCheckpoint(workflowId, getState) {
1184
+ this.currentWorkflowId = workflowId;
1185
+ this.stepCounter = 0;
1186
+ if (typeof this.config.autoCheckpointInterval === "number") {
1187
+ this.autoCheckpointTimer = setInterval(() => {
1188
+ void (async () => {
1189
+ try {
1190
+ await this.save(workflowId, getState());
1191
+ } catch (error) {
1192
+ console.error("Auto-checkpoint failed:", error);
1193
+ }
1194
+ })();
1195
+ }, this.config.autoCheckpointInterval);
1196
+ }
1197
+ }
1198
+ /**
1199
+ * Disable automatic checkpointing
1200
+ */
1201
+ disableAutoCheckpoint() {
1202
+ if (this.autoCheckpointTimer) {
1203
+ clearInterval(this.autoCheckpointTimer);
1204
+ this.autoCheckpointTimer = void 0;
1205
+ }
1206
+ this.currentWorkflowId = void 0;
1207
+ }
1208
+ /**
1209
+ * Notify that a step completed (for step-based checkpointing)
1210
+ */
1211
+ async onStepComplete(workflowId, state) {
1212
+ if (this.config.autoCheckpointInterval === "after-step") {
1213
+ await this.save(workflowId, state);
1214
+ }
1215
+ this.stepCounter++;
1216
+ }
1217
+ /**
1218
+ * Restore workflow state from checkpoint
1219
+ */
1220
+ async restore(checkpointId) {
1221
+ const checkpoint = await this.load(checkpointId);
1222
+ if (!checkpoint) {
1223
+ return null;
1224
+ }
1225
+ return {
1226
+ currentStepIndex: checkpoint.stepIndex ?? 0,
1227
+ stepResults: checkpoint.stepResults instanceof Map ? checkpoint.stepResults : new Map(Object.entries(checkpoint.stepResults)),
1228
+ variables: new Map(Object.entries(checkpoint.variables)),
1229
+ metadata: checkpoint.metadata ?? {}
1230
+ };
1231
+ }
1232
+ /**
1233
+ * Cleanup old checkpoints
1234
+ */
1235
+ async cleanupOldCheckpoints(workflowId) {
1236
+ const checkpoints = await this.list(workflowId);
1237
+ if (checkpoints.length > this.config.maxCheckpoints) {
1238
+ const toDelete = checkpoints.slice(this.config.maxCheckpoints);
1239
+ for (const checkpoint of toDelete) {
1240
+ await this.storage.delete(checkpoint.id);
1241
+ }
1242
+ }
1243
+ }
1244
+ /**
1245
+ * Export checkpoints for a workflow
1246
+ */
1247
+ async export(workflowId) {
1248
+ const checkpoints = await this.list(workflowId);
1249
+ return JSON.stringify(checkpoints, null, 2);
1250
+ }
1251
+ /**
1252
+ * Import checkpoints
1253
+ */
1254
+ async import(data) {
1255
+ const checkpoints = JSON.parse(data);
1256
+ let count = 0;
1257
+ for (const checkpoint of checkpoints) {
1258
+ checkpoint.timestamp = new Date(checkpoint.timestamp);
1259
+ await this.storage.save(checkpoint);
1260
+ count++;
1261
+ }
1262
+ return count;
1263
+ }
1264
+ /**
1265
+ * Get statistics
1266
+ */
1267
+ async getStatistics(workflowId) {
1268
+ const checkpoints = await this.list(workflowId);
1269
+ let totalSize = 0;
1270
+ let oldestTimestamp = null;
1271
+ let newestTimestamp = null;
1272
+ for (const checkpoint of checkpoints) {
1273
+ totalSize += JSON.stringify(checkpoint).length;
1274
+ if (!oldestTimestamp || checkpoint.timestamp < oldestTimestamp) {
1275
+ oldestTimestamp = checkpoint.timestamp;
1276
+ }
1277
+ if (!newestTimestamp || checkpoint.timestamp > newestTimestamp) {
1278
+ newestTimestamp = checkpoint.timestamp;
1279
+ }
1280
+ }
1281
+ return {
1282
+ checkpointCount: checkpoints.length,
1283
+ estimatedSizeBytes: totalSize,
1284
+ oldestCheckpoint: oldestTimestamp,
1285
+ newestCheckpoint: newestTimestamp
1286
+ };
1287
+ }
1288
+ };
1289
+ function createCheckpointManager(config) {
1290
+ return new CheckpointManager(config);
1291
+ }
1292
+
1293
+ // src/memory/SharedMemory.ts
1294
+ import { EventEmitter } from "eventemitter3";
1295
+ var SharedMemory = class extends EventEmitter {
1296
+ namespaces = /* @__PURE__ */ new Map();
1297
+ agentNamespaces = /* @__PURE__ */ new Map();
1298
+ history = [];
1299
+ config;
1300
+ constructor(config = {}) {
1301
+ super();
1302
+ this.config = {
1303
+ maxEntriesPerNamespace: config.maxEntriesPerNamespace ?? 1e3,
1304
+ trackHistory: config.trackHistory ?? true,
1305
+ maxHistoryEntries: config.maxHistoryEntries ?? 100,
1306
+ persist: config.persist ?? false
1307
+ };
1308
+ this.createNamespace("shared");
1309
+ }
1310
+ // ============ Shared Operations ============
1311
+ /**
1312
+ * Set a shared value
1313
+ */
1314
+ setShared(key, value, agent) {
1315
+ this.set("shared", key, value, agent);
1316
+ }
1317
+ /**
1318
+ * Get a shared value
1319
+ */
1320
+ getShared(key) {
1321
+ return this.get("shared", key);
1322
+ }
1323
+ /**
1324
+ * Delete a shared value
1325
+ */
1326
+ deleteShared(key, agent) {
1327
+ return this.delete("shared", key, agent);
1328
+ }
1329
+ /**
1330
+ * Check if shared key exists
1331
+ */
1332
+ hasShared(key) {
1333
+ return this.has("shared", key);
1334
+ }
1335
+ /**
1336
+ * Get all shared keys
1337
+ */
1338
+ getSharedKeys() {
1339
+ return this.getKeys("shared");
1340
+ }
1341
+ // ============ Agent-Specific Operations ============
1342
+ /**
1343
+ * Set a value for a specific agent
1344
+ */
1345
+ setForAgent(agentName, key, value) {
1346
+ if (!this.agentNamespaces.has(agentName)) {
1347
+ const namespace2 = `agent:${agentName}`;
1348
+ this.createNamespace(namespace2);
1349
+ this.agentNamespaces.set(agentName, namespace2);
1350
+ }
1351
+ const namespace = this.agentNamespaces.get(agentName);
1352
+ this.set(namespace, key, value, agentName);
1353
+ }
1354
+ /**
1355
+ * Get a value for a specific agent
1356
+ */
1357
+ getForAgent(agentName, key) {
1358
+ const namespace = this.agentNamespaces.get(agentName);
1359
+ if (!namespace) return void 0;
1360
+ return this.get(namespace, key);
1361
+ }
1362
+ /**
1363
+ * Delete a value for a specific agent
1364
+ */
1365
+ deleteForAgent(agentName, key) {
1366
+ const namespace = this.agentNamespaces.get(agentName);
1367
+ if (!namespace) return false;
1368
+ return this.delete(namespace, key, agentName);
1369
+ }
1370
+ /**
1371
+ * Get all keys for an agent
1372
+ */
1373
+ getAgentKeys(agentName) {
1374
+ const namespace = this.agentNamespaces.get(agentName);
1375
+ if (!namespace) return [];
1376
+ return this.getKeys(namespace);
1377
+ }
1378
+ /**
1379
+ * Clear all agent data
1380
+ */
1381
+ clearAgent(agentName) {
1382
+ const namespace = this.agentNamespaces.get(agentName);
1383
+ if (namespace) {
1384
+ this.clearNamespace(namespace, agentName);
1385
+ }
1386
+ }
1387
+ // ============ Broadcast Operations ============
1388
+ /**
1389
+ * Broadcast a value to all agents
1390
+ */
1391
+ broadcast(key, value, fromAgent) {
1392
+ this.setShared(key, value, fromAgent);
1393
+ this.emit("change", {
1394
+ type: "set",
1395
+ key: `broadcast:${key}`,
1396
+ value,
1397
+ agent: fromAgent,
1398
+ timestamp: /* @__PURE__ */ new Date()
1399
+ });
1400
+ }
1401
+ // ============ Namespace Operations ============
1402
+ /**
1403
+ * Create a namespace
1404
+ */
1405
+ createNamespace(name) {
1406
+ if (this.namespaces.has(name)) {
1407
+ return this.namespaces.get(name);
1408
+ }
1409
+ const namespace = {
1410
+ name,
1411
+ data: /* @__PURE__ */ new Map(),
1412
+ created: /* @__PURE__ */ new Date(),
1413
+ lastAccessed: /* @__PURE__ */ new Date()
1414
+ };
1415
+ this.namespaces.set(name, namespace);
1416
+ this.emit("namespaceCreated", name);
1417
+ return namespace;
1418
+ }
1419
+ /**
1420
+ * Delete a namespace
1421
+ */
1422
+ deleteNamespace(name) {
1423
+ if (name === "shared") {
1424
+ throw new Error("Cannot delete shared namespace");
1425
+ }
1426
+ if (!this.namespaces.has(name)) {
1427
+ return false;
1428
+ }
1429
+ this.namespaces.delete(name);
1430
+ this.emit("namespaceDeleted", name);
1431
+ return true;
1432
+ }
1433
+ /**
1434
+ * Clear a namespace
1435
+ */
1436
+ clearNamespace(name, agent) {
1437
+ const namespace = this.namespaces.get(name);
1438
+ if (namespace) {
1439
+ namespace.data.clear();
1440
+ namespace.lastAccessed = /* @__PURE__ */ new Date();
1441
+ if (this.config.trackHistory) {
1442
+ this.addToHistory({
1443
+ type: "clear",
1444
+ agent,
1445
+ timestamp: /* @__PURE__ */ new Date()
1446
+ });
1447
+ }
1448
+ }
1449
+ }
1450
+ /**
1451
+ * Get namespace names
1452
+ */
1453
+ getNamespaces() {
1454
+ return Array.from(this.namespaces.keys());
1455
+ }
1456
+ // ============ Low-Level Operations ============
1457
+ /**
1458
+ * Set a value in a namespace
1459
+ */
1460
+ set(namespace, key, value, agent) {
1461
+ const ns = this.namespaces.get(namespace);
1462
+ if (!ns) {
1463
+ throw new Error(`Namespace not found: ${namespace}`);
1464
+ }
1465
+ if (ns.data.size >= this.config.maxEntriesPerNamespace && !ns.data.has(key)) {
1466
+ const firstKey = ns.data.keys().next().value;
1467
+ if (firstKey !== void 0) {
1468
+ ns.data.delete(firstKey);
1469
+ }
1470
+ }
1471
+ const previousValue = ns.data.get(key);
1472
+ ns.data.set(key, value);
1473
+ ns.lastAccessed = /* @__PURE__ */ new Date();
1474
+ if (this.config.trackHistory) {
1475
+ this.addToHistory({
1476
+ type: "set",
1477
+ key: `${namespace}:${key}`,
1478
+ value,
1479
+ previousValue,
1480
+ agent,
1481
+ timestamp: /* @__PURE__ */ new Date()
1482
+ });
1483
+ }
1484
+ this.emit("change", {
1485
+ type: "set",
1486
+ key: `${namespace}:${key}`,
1487
+ value,
1488
+ previousValue,
1489
+ agent,
1490
+ timestamp: /* @__PURE__ */ new Date()
1491
+ });
1492
+ }
1493
+ /**
1494
+ * Get a value from a namespace
1495
+ */
1496
+ get(namespace, key) {
1497
+ const ns = this.namespaces.get(namespace);
1498
+ if (!ns) return void 0;
1499
+ ns.lastAccessed = /* @__PURE__ */ new Date();
1500
+ return ns.data.get(key);
1501
+ }
1502
+ /**
1503
+ * Delete a value from a namespace
1504
+ */
1505
+ delete(namespace, key, agent) {
1506
+ const ns = this.namespaces.get(namespace);
1507
+ if (!ns) return false;
1508
+ const previousValue = ns.data.get(key);
1509
+ const deleted = ns.data.delete(key);
1510
+ ns.lastAccessed = /* @__PURE__ */ new Date();
1511
+ if (deleted && this.config.trackHistory) {
1512
+ this.addToHistory({
1513
+ type: "delete",
1514
+ key: `${namespace}:${key}`,
1515
+ previousValue,
1516
+ agent,
1517
+ timestamp: /* @__PURE__ */ new Date()
1518
+ });
1519
+ }
1520
+ if (deleted) {
1521
+ this.emit("change", {
1522
+ type: "delete",
1523
+ key: `${namespace}:${key}`,
1524
+ previousValue,
1525
+ agent,
1526
+ timestamp: /* @__PURE__ */ new Date()
1527
+ });
1528
+ }
1529
+ return deleted;
1530
+ }
1531
+ /**
1532
+ * Check if key exists in namespace
1533
+ */
1534
+ has(namespace, key) {
1535
+ const ns = this.namespaces.get(namespace);
1536
+ if (!ns) return false;
1537
+ return ns.data.has(key);
1538
+ }
1539
+ /**
1540
+ * Get all keys in a namespace
1541
+ */
1542
+ getKeys(namespace) {
1543
+ const ns = this.namespaces.get(namespace);
1544
+ if (!ns) return [];
1545
+ return Array.from(ns.data.keys());
1546
+ }
1547
+ // ============ History ============
1548
+ /**
1549
+ * Add to history
1550
+ */
1551
+ addToHistory(event) {
1552
+ this.history.push(event);
1553
+ if (this.history.length > this.config.maxHistoryEntries) {
1554
+ this.history.shift();
1555
+ }
1556
+ }
1557
+ /**
1558
+ * Get change history
1559
+ */
1560
+ getHistory(filter) {
1561
+ let events = [...this.history];
1562
+ if (filter) {
1563
+ if (filter.agent) {
1564
+ events = events.filter((e) => e.agent === filter.agent);
1565
+ }
1566
+ if (filter.key) {
1567
+ events = events.filter((e) => e.key?.includes(filter.key));
1568
+ }
1569
+ if (filter.type) {
1570
+ events = events.filter((e) => e.type === filter.type);
1571
+ }
1572
+ if (filter.since) {
1573
+ events = events.filter((e) => e.timestamp >= filter.since);
1574
+ }
1575
+ }
1576
+ return events;
1577
+ }
1578
+ /**
1579
+ * Clear history
1580
+ */
1581
+ clearHistory() {
1582
+ this.history.length = 0;
1583
+ }
1584
+ // ============ Serialization ============
1585
+ /**
1586
+ * Export all data
1587
+ */
1588
+ export() {
1589
+ const data = {};
1590
+ for (const [name, namespace] of this.namespaces) {
1591
+ data[name] = Object.fromEntries(namespace.data);
1592
+ }
1593
+ return data;
1594
+ }
1595
+ /**
1596
+ * Import data
1597
+ */
1598
+ import(data) {
1599
+ for (const [name, entries] of Object.entries(data)) {
1600
+ if (!this.namespaces.has(name)) {
1601
+ this.createNamespace(name);
1602
+ }
1603
+ const namespace = this.namespaces.get(name);
1604
+ for (const [key, value] of Object.entries(entries)) {
1605
+ namespace.data.set(key, value);
1606
+ }
1607
+ }
1608
+ }
1609
+ /**
1610
+ * Clear all data
1611
+ */
1612
+ clear() {
1613
+ for (const namespace of this.namespaces.values()) {
1614
+ namespace.data.clear();
1615
+ }
1616
+ this.history.length = 0;
1617
+ }
1618
+ /**
1619
+ * Get statistics
1620
+ */
1621
+ getStatistics() {
1622
+ const entriesByNamespace = {};
1623
+ let totalEntries = 0;
1624
+ for (const [name, namespace] of this.namespaces) {
1625
+ entriesByNamespace[name] = namespace.data.size;
1626
+ totalEntries += namespace.data.size;
1627
+ }
1628
+ return {
1629
+ totalNamespaces: this.namespaces.size,
1630
+ totalEntries,
1631
+ entriesByNamespace,
1632
+ historyEntries: this.history.length
1633
+ };
1634
+ }
1635
+ };
1636
+ function createSharedMemory(config) {
1637
+ return new SharedMemory(config);
1638
+ }
1639
+
1640
+ // src/memory/ConversationHistory.ts
1641
+ import { nanoid as nanoid4 } from "nanoid";
1642
+ var ConversationHistory = class {
1643
+ agentMessages = /* @__PURE__ */ new Map();
1644
+ threads = /* @__PURE__ */ new Map();
1645
+ allMessages = [];
1646
+ config;
1647
+ currentThreadId;
1648
+ constructor(config = {}) {
1649
+ this.config = {
1650
+ maxMessagesPerAgent: config.maxMessagesPerAgent ?? 100,
1651
+ maxTotalMessages: config.maxTotalMessages ?? 1e3,
1652
+ enableThreads: config.enableThreads ?? true,
1653
+ autoSummarize: config.autoSummarize ?? false
1654
+ };
1655
+ }
1656
+ // ============ Message Operations ============
1657
+ /**
1658
+ * Add a message
1659
+ */
1660
+ addMessage(agentName, message) {
1661
+ const fullMessage = {
1662
+ ...message,
1663
+ id: nanoid4(),
1664
+ agentName,
1665
+ timestamp: /* @__PURE__ */ new Date(),
1666
+ threadId: this.currentThreadId
1667
+ };
1668
+ if (!this.agentMessages.has(agentName)) {
1669
+ this.agentMessages.set(agentName, []);
1670
+ }
1671
+ const agentMsgs = this.agentMessages.get(agentName);
1672
+ agentMsgs.push(fullMessage);
1673
+ if (agentMsgs.length > this.config.maxMessagesPerAgent) {
1674
+ agentMsgs.shift();
1675
+ }
1676
+ this.allMessages.push(fullMessage);
1677
+ if (this.allMessages.length > this.config.maxTotalMessages) {
1678
+ this.allMessages.shift();
1679
+ }
1680
+ if (this.config.enableThreads && this.currentThreadId) {
1681
+ const thread = this.threads.get(this.currentThreadId);
1682
+ if (thread) {
1683
+ thread.messages.push(fullMessage);
1684
+ thread.lastActivity = /* @__PURE__ */ new Date();
1685
+ if (!thread.participants.includes(agentName)) {
1686
+ thread.participants.push(agentName);
1687
+ }
1688
+ }
1689
+ }
1690
+ return fullMessage;
1691
+ }
1692
+ /**
1693
+ * Add a user message
1694
+ */
1695
+ addUserMessage(content, agentName) {
1696
+ return this.addMessage(agentName ?? "user", {
1697
+ role: "user",
1698
+ content
1699
+ });
1700
+ }
1701
+ /**
1702
+ * Add an assistant message
1703
+ */
1704
+ addAssistantMessage(agentName, content, metadata) {
1705
+ return this.addMessage(agentName, {
1706
+ role: "assistant",
1707
+ content,
1708
+ metadata
1709
+ });
1710
+ }
1711
+ /**
1712
+ * Add a system message
1713
+ */
1714
+ addSystemMessage(agentName, content) {
1715
+ return this.addMessage(agentName, {
1716
+ role: "system",
1717
+ content
1718
+ });
1719
+ }
1720
+ /**
1721
+ * Add a tool message
1722
+ */
1723
+ addToolMessage(agentName, toolName, input, output) {
1724
+ return this.addMessage(agentName, {
1725
+ role: "tool",
1726
+ content: typeof output === "string" ? output : JSON.stringify(output),
1727
+ metadata: {
1728
+ toolCall: {
1729
+ name: toolName,
1730
+ input,
1731
+ output
1732
+ }
1733
+ }
1734
+ });
1735
+ }
1736
+ // ============ Retrieval ============
1737
+ /**
1738
+ * Get messages for an agent
1739
+ */
1740
+ getAgentHistory(agentName, options = {}) {
1741
+ let messages = this.agentMessages.get(agentName) ?? [];
1742
+ if (options.since) {
1743
+ messages = messages.filter((m) => m.timestamp >= options.since);
1744
+ }
1745
+ if (options.role) {
1746
+ messages = messages.filter((m) => m.role === options.role);
1747
+ }
1748
+ if (options.limit) {
1749
+ messages = messages.slice(-options.limit);
1750
+ }
1751
+ return [...messages];
1752
+ }
1753
+ /**
1754
+ * Get full history
1755
+ */
1756
+ getFullHistory(options = {}) {
1757
+ let messages = [...this.allMessages];
1758
+ if (options.since) {
1759
+ messages = messages.filter((m) => m.timestamp >= options.since);
1760
+ }
1761
+ if (options.agents) {
1762
+ messages = messages.filter((m) => options.agents.includes(m.agentName));
1763
+ }
1764
+ if (options.limit) {
1765
+ messages = messages.slice(-options.limit);
1766
+ }
1767
+ return messages;
1768
+ }
1769
+ /**
1770
+ * Get conversation between agents
1771
+ */
1772
+ getConversation(agent1, agent2, limit) {
1773
+ const messages = this.allMessages.filter(
1774
+ (m) => m.agentName === agent1 || m.agentName === agent2
1775
+ );
1776
+ if (limit) {
1777
+ return messages.slice(-limit);
1778
+ }
1779
+ return [...messages];
1780
+ }
1781
+ /**
1782
+ * Get recent messages
1783
+ */
1784
+ getRecent(count = 10) {
1785
+ return this.allMessages.slice(-count);
1786
+ }
1787
+ /**
1788
+ * Search history
1789
+ */
1790
+ searchHistory(query, options = {}) {
1791
+ const searchQuery = options.caseSensitive ? query : query.toLowerCase();
1792
+ let results = this.allMessages.filter((m) => {
1793
+ const content = options.caseSensitive ? m.content : m.content.toLowerCase();
1794
+ return content.includes(searchQuery);
1795
+ });
1796
+ if (options.agent) {
1797
+ results = results.filter((m) => m.agentName === options.agent);
1798
+ }
1799
+ if (options.limit) {
1800
+ results = results.slice(-options.limit);
1801
+ }
1802
+ return results;
1803
+ }
1804
+ // ============ Thread Operations ============
1805
+ /**
1806
+ * Create a new thread
1807
+ */
1808
+ createThread(title, participants = []) {
1809
+ const thread = {
1810
+ id: nanoid4(),
1811
+ title,
1812
+ participants,
1813
+ messages: [],
1814
+ created: /* @__PURE__ */ new Date(),
1815
+ lastActivity: /* @__PURE__ */ new Date()
1816
+ };
1817
+ this.threads.set(thread.id, thread);
1818
+ this.currentThreadId = thread.id;
1819
+ return thread;
1820
+ }
1821
+ /**
1822
+ * Switch to a thread
1823
+ */
1824
+ switchThread(threadId) {
1825
+ if (this.threads.has(threadId)) {
1826
+ this.currentThreadId = threadId;
1827
+ return true;
1828
+ }
1829
+ return false;
1830
+ }
1831
+ /**
1832
+ * Get current thread
1833
+ */
1834
+ getCurrentThread() {
1835
+ if (!this.currentThreadId) return void 0;
1836
+ return this.threads.get(this.currentThreadId);
1837
+ }
1838
+ /**
1839
+ * Get a thread
1840
+ */
1841
+ getThread(threadId) {
1842
+ return this.threads.get(threadId);
1843
+ }
1844
+ /**
1845
+ * Get all threads
1846
+ */
1847
+ getThreads() {
1848
+ return Array.from(this.threads.values()).sort(
1849
+ (a, b) => b.lastActivity.getTime() - a.lastActivity.getTime()
1850
+ );
1851
+ }
1852
+ /**
1853
+ * Delete a thread
1854
+ */
1855
+ deleteThread(threadId) {
1856
+ if (this.currentThreadId === threadId) {
1857
+ this.currentThreadId = void 0;
1858
+ }
1859
+ return this.threads.delete(threadId);
1860
+ }
1861
+ // ============ Context Building ============
1862
+ /**
1863
+ * Build context for an agent (recent conversation)
1864
+ */
1865
+ buildAgentContext(agentName, maxMessages = 20) {
1866
+ return this.getAgentHistory(agentName, { limit: maxMessages });
1867
+ }
1868
+ /**
1869
+ * Build context for LLM (formatted messages)
1870
+ */
1871
+ buildLLMContext(agentName, options = {}) {
1872
+ const messages = this.getAgentHistory(agentName, {
1873
+ limit: options.maxMessages ?? 20
1874
+ });
1875
+ return messages.filter((m) => {
1876
+ if (m.role === "system" && !options.includeSystem) return false;
1877
+ if (m.role === "tool" && !options.includeTools) return false;
1878
+ return true;
1879
+ }).map((m) => ({
1880
+ role: m.role,
1881
+ content: m.content
1882
+ }));
1883
+ }
1884
+ /**
1885
+ * Summarize conversation (placeholder for LLM summarization)
1886
+ */
1887
+ summarize(messages) {
1888
+ const agentSummaries = {};
1889
+ let totalMessages = 0;
1890
+ let toolCalls = 0;
1891
+ for (const msg of messages) {
1892
+ totalMessages++;
1893
+ if (msg.agentName) {
1894
+ const agent = msg.agentName;
1895
+ agentSummaries[agent] = (agentSummaries[agent] ?? 0) + 1;
1896
+ }
1897
+ if (msg.metadata?.toolCall) {
1898
+ toolCalls++;
1899
+ }
1900
+ }
1901
+ const parts = [];
1902
+ parts.push(`Conversation with ${totalMessages} messages`);
1903
+ if (Object.keys(agentSummaries).length > 0) {
1904
+ const agentList = Object.entries(agentSummaries).map(([name, count]) => `${name} (${count})`).join(", ");
1905
+ parts.push(`Participants: ${agentList}`);
1906
+ }
1907
+ if (toolCalls > 0) {
1908
+ parts.push(`Tool calls: ${toolCalls}`);
1909
+ }
1910
+ return parts.join(". ");
1911
+ }
1912
+ // ============ Utilities ============
1913
+ /**
1914
+ * Get all participating agents
1915
+ */
1916
+ getParticipants() {
1917
+ return Array.from(this.agentMessages.keys());
1918
+ }
1919
+ /**
1920
+ * Get message count
1921
+ */
1922
+ getMessageCount(agentName) {
1923
+ if (agentName) {
1924
+ return this.agentMessages.get(agentName)?.length ?? 0;
1925
+ }
1926
+ return this.allMessages.length;
1927
+ }
1928
+ /**
1929
+ * Clear all history
1930
+ */
1931
+ clear() {
1932
+ this.agentMessages.clear();
1933
+ this.threads.clear();
1934
+ this.allMessages.length = 0;
1935
+ this.currentThreadId = void 0;
1936
+ }
1937
+ /**
1938
+ * Clear history for an agent
1939
+ */
1940
+ clearAgent(agentName) {
1941
+ this.agentMessages.delete(agentName);
1942
+ for (let i = this.allMessages.length - 1; i >= 0; i--) {
1943
+ if (this.allMessages[i].agentName === agentName) {
1944
+ this.allMessages.splice(i, 1);
1945
+ }
1946
+ }
1947
+ }
1948
+ /**
1949
+ * Export history
1950
+ */
1951
+ export() {
1952
+ return {
1953
+ messages: [...this.allMessages],
1954
+ threads: Array.from(this.threads.values())
1955
+ };
1956
+ }
1957
+ /**
1958
+ * Import history
1959
+ */
1960
+ import(data) {
1961
+ for (const msg of data.messages) {
1962
+ msg.timestamp = new Date(msg.timestamp);
1963
+ if (!this.agentMessages.has(msg.agentName)) {
1964
+ this.agentMessages.set(msg.agentName, []);
1965
+ }
1966
+ this.agentMessages.get(msg.agentName).push(msg);
1967
+ this.allMessages.push(msg);
1968
+ }
1969
+ if (data.threads) {
1970
+ for (const thread of data.threads) {
1971
+ thread.created = new Date(thread.created);
1972
+ thread.lastActivity = new Date(thread.lastActivity);
1973
+ for (const msg of thread.messages) {
1974
+ msg.timestamp = new Date(msg.timestamp);
1975
+ }
1976
+ this.threads.set(thread.id, thread);
1977
+ }
1978
+ }
1979
+ }
1980
+ /**
1981
+ * Get statistics
1982
+ */
1983
+ getStatistics() {
1984
+ const messagesByAgent = {};
1985
+ const messagesByRole = {};
1986
+ for (const msg of this.allMessages) {
1987
+ messagesByAgent[msg.agentName] = (messagesByAgent[msg.agentName] ?? 0) + 1;
1988
+ messagesByRole[msg.role] = (messagesByRole[msg.role] ?? 0) + 1;
1989
+ }
1990
+ const agentCount = Object.keys(messagesByAgent).length;
1991
+ return {
1992
+ totalMessages: this.allMessages.length,
1993
+ messagesByAgent,
1994
+ messagesByRole,
1995
+ totalThreads: this.threads.size,
1996
+ averageMessagesPerAgent: agentCount > 0 ? this.allMessages.length / agentCount : 0
1997
+ };
1998
+ }
1999
+ };
2000
+ function createConversationHistory(config) {
2001
+ return new ConversationHistory(config);
2002
+ }
2003
+
2004
+ // src/memory/KnowledgeBase.ts
2005
+ import { nanoid as nanoid5 } from "nanoid";
2006
+ var KnowledgeBase = class {
2007
+ items = /* @__PURE__ */ new Map();
2008
+ tagIndex = /* @__PURE__ */ new Map();
2009
+ typeIndex = /* @__PURE__ */ new Map();
2010
+ contributorIndex = /* @__PURE__ */ new Map();
2011
+ config;
2012
+ constructor(config = {}) {
2013
+ this.config = {
2014
+ maxItems: config.maxItems ?? 1e4,
2015
+ autoIndex: config.autoIndex ?? true,
2016
+ minConfidence: config.minConfidence ?? 0,
2017
+ deduplicate: config.deduplicate ?? true
2018
+ };
2019
+ }
2020
+ // ============ CRUD Operations ============
2021
+ /**
2022
+ * Add knowledge item
2023
+ */
2024
+ add(item) {
2025
+ if (item.confidence < this.config.minConfidence) {
2026
+ throw new Error(
2027
+ `Confidence ${item.confidence} below threshold ${this.config.minConfidence}`
2028
+ );
2029
+ }
2030
+ if (this.config.deduplicate) {
2031
+ const duplicate = this.findDuplicate(item.title, item.content);
2032
+ if (duplicate) {
2033
+ return this.update(duplicate.id, {
2034
+ ...item,
2035
+ confidence: Math.max(duplicate.confidence, item.confidence)
2036
+ });
2037
+ }
2038
+ }
2039
+ if (this.items.size >= this.config.maxItems) {
2040
+ this.evictLeastUsed();
2041
+ }
2042
+ const fullItem = {
2043
+ ...item,
2044
+ id: nanoid5(),
2045
+ created: /* @__PURE__ */ new Date(),
2046
+ updated: /* @__PURE__ */ new Date(),
2047
+ accessCount: 0
2048
+ };
2049
+ this.items.set(fullItem.id, fullItem);
2050
+ if (this.config.autoIndex) {
2051
+ this.indexItem(fullItem);
2052
+ }
2053
+ return fullItem;
2054
+ }
2055
+ /**
2056
+ * Get knowledge item
2057
+ */
2058
+ get(id) {
2059
+ const item = this.items.get(id);
2060
+ if (item) {
2061
+ item.accessCount++;
2062
+ }
2063
+ return item;
2064
+ }
2065
+ /**
2066
+ * Update knowledge item
2067
+ */
2068
+ update(id, updates) {
2069
+ const item = this.items.get(id);
2070
+ if (!item) {
2071
+ throw new Error(`Knowledge item not found: ${id}`);
2072
+ }
2073
+ if (this.config.autoIndex) {
2074
+ this.unindexItem(item);
2075
+ }
2076
+ const updatedItem = {
2077
+ ...item,
2078
+ ...updates,
2079
+ updated: /* @__PURE__ */ new Date()
2080
+ };
2081
+ this.items.set(id, updatedItem);
2082
+ if (this.config.autoIndex) {
2083
+ this.indexItem(updatedItem);
2084
+ }
2085
+ return updatedItem;
2086
+ }
2087
+ /**
2088
+ * Delete knowledge item
2089
+ */
2090
+ delete(id) {
2091
+ const item = this.items.get(id);
2092
+ if (!item) return false;
2093
+ if (this.config.autoIndex) {
2094
+ this.unindexItem(item);
2095
+ }
2096
+ return this.items.delete(id);
2097
+ }
2098
+ // ============ Search & Query ============
2099
+ /**
2100
+ * Search knowledge base
2101
+ */
2102
+ search(query, options = {}) {
2103
+ let results = this.textSearch(query);
2104
+ if (options.type) {
2105
+ results = results.filter((item) => item.type === options.type);
2106
+ }
2107
+ if (options.tags && options.tags.length > 0) {
2108
+ results = results.filter(
2109
+ (item) => options.tags.some((tag) => item.tags.includes(tag))
2110
+ );
2111
+ }
2112
+ if (options.contributor) {
2113
+ results = results.filter(
2114
+ (item) => item.contributor === options.contributor
2115
+ );
2116
+ }
2117
+ if (options.minConfidence !== void 0) {
2118
+ results = results.filter(
2119
+ (item) => item.confidence >= options.minConfidence
2120
+ );
2121
+ }
2122
+ results = this.sortResults(results, options.sortBy ?? "relevance", query);
2123
+ if (options.limit) {
2124
+ results = results.slice(0, options.limit);
2125
+ }
2126
+ for (const item of results) {
2127
+ item.accessCount++;
2128
+ }
2129
+ return results;
2130
+ }
2131
+ /**
2132
+ * Get by tag
2133
+ */
2134
+ getByTag(tag, limit) {
2135
+ const ids = this.tagIndex.get(tag.toLowerCase());
2136
+ if (!ids) return [];
2137
+ let items = Array.from(ids).map((id) => this.items.get(id)).filter(Boolean);
2138
+ if (limit) {
2139
+ items = items.slice(0, limit);
2140
+ }
2141
+ return items;
2142
+ }
2143
+ /**
2144
+ * Get by type
2145
+ */
2146
+ getByType(type, limit) {
2147
+ const ids = this.typeIndex.get(type);
2148
+ if (!ids) return [];
2149
+ let items = Array.from(ids).map((id) => this.items.get(id)).filter(Boolean);
2150
+ if (limit) {
2151
+ items = items.slice(0, limit);
2152
+ }
2153
+ return items;
2154
+ }
2155
+ /**
2156
+ * Get by contributor
2157
+ */
2158
+ getByContributor(contributor, limit) {
2159
+ const ids = this.contributorIndex.get(contributor);
2160
+ if (!ids) return [];
2161
+ let items = Array.from(ids).map((id) => this.items.get(id)).filter(Boolean);
2162
+ if (limit) {
2163
+ items = items.slice(0, limit);
2164
+ }
2165
+ return items;
2166
+ }
2167
+ /**
2168
+ * Get related items
2169
+ */
2170
+ getRelated(id, limit = 5) {
2171
+ const item = this.items.get(id);
2172
+ if (!item) return [];
2173
+ const relatedIds = /* @__PURE__ */ new Set();
2174
+ for (const tag of item.tags) {
2175
+ const taggedIds = this.tagIndex.get(tag.toLowerCase());
2176
+ if (taggedIds) {
2177
+ for (const relatedId of taggedIds) {
2178
+ if (relatedId !== id) {
2179
+ relatedIds.add(relatedId);
2180
+ }
2181
+ }
2182
+ }
2183
+ }
2184
+ const scored = Array.from(relatedIds).map((relatedId) => {
2185
+ const relatedItem = this.items.get(relatedId);
2186
+ const overlap = item.tags.filter(
2187
+ (t) => relatedItem.tags.includes(t)
2188
+ ).length;
2189
+ return { item: relatedItem, score: overlap };
2190
+ });
2191
+ return scored.sort((a, b) => b.score - a.score).slice(0, limit).map((s) => s.item);
2192
+ }
2193
+ // ============ Agent Contributions ============
2194
+ /**
2195
+ * Contribute knowledge from an agent
2196
+ */
2197
+ contributeKnowledge(agentName, type, title, content, tags = [], confidence = 0.8) {
2198
+ return this.add({
2199
+ type,
2200
+ title,
2201
+ content,
2202
+ tags,
2203
+ contributor: agentName,
2204
+ confidence
2205
+ });
2206
+ }
2207
+ /**
2208
+ * Add a fact
2209
+ */
2210
+ addFact(title, content, tags = [], source) {
2211
+ return this.add({
2212
+ type: "fact",
2213
+ title,
2214
+ content,
2215
+ tags,
2216
+ source,
2217
+ confidence: 0.9
2218
+ });
2219
+ }
2220
+ /**
2221
+ * Add a procedure
2222
+ */
2223
+ addProcedure(title, steps, tags = []) {
2224
+ return this.add({
2225
+ type: "procedure",
2226
+ title,
2227
+ content: steps.map((s, i) => `${i + 1}. ${s}`).join("\n"),
2228
+ tags,
2229
+ confidence: 0.85
2230
+ });
2231
+ }
2232
+ /**
2233
+ * Add an insight
2234
+ */
2235
+ addInsight(title, content, contributor, tags = []) {
2236
+ return this.add({
2237
+ type: "insight",
2238
+ title,
2239
+ content,
2240
+ tags,
2241
+ contributor,
2242
+ confidence: 0.7
2243
+ });
2244
+ }
2245
+ /**
2246
+ * Add a warning
2247
+ */
2248
+ addWarning(title, content, tags = []) {
2249
+ return this.add({
2250
+ type: "warning",
2251
+ title,
2252
+ content,
2253
+ tags,
2254
+ confidence: 0.95
2255
+ });
2256
+ }
2257
+ // ============ Indexing ============
2258
+ /**
2259
+ * Index an item
2260
+ */
2261
+ indexItem(item) {
2262
+ for (const tag of item.tags) {
2263
+ const tagLower = tag.toLowerCase();
2264
+ if (!this.tagIndex.has(tagLower)) {
2265
+ this.tagIndex.set(tagLower, /* @__PURE__ */ new Set());
2266
+ }
2267
+ this.tagIndex.get(tagLower).add(item.id);
2268
+ }
2269
+ if (!this.typeIndex.has(item.type)) {
2270
+ this.typeIndex.set(item.type, /* @__PURE__ */ new Set());
2271
+ }
2272
+ this.typeIndex.get(item.type).add(item.id);
2273
+ if (item.contributor) {
2274
+ if (!this.contributorIndex.has(item.contributor)) {
2275
+ this.contributorIndex.set(item.contributor, /* @__PURE__ */ new Set());
2276
+ }
2277
+ this.contributorIndex.get(item.contributor).add(item.id);
2278
+ }
2279
+ }
2280
+ /**
2281
+ * Remove item from indices
2282
+ */
2283
+ unindexItem(item) {
2284
+ for (const tag of item.tags) {
2285
+ const tagLower = tag.toLowerCase();
2286
+ this.tagIndex.get(tagLower)?.delete(item.id);
2287
+ }
2288
+ this.typeIndex.get(item.type)?.delete(item.id);
2289
+ if (item.contributor) {
2290
+ this.contributorIndex.get(item.contributor)?.delete(item.id);
2291
+ }
2292
+ }
2293
+ /**
2294
+ * Text search
2295
+ */
2296
+ textSearch(query) {
2297
+ const queryLower = query.toLowerCase();
2298
+ const queryWords = queryLower.split(/\s+/);
2299
+ const scored = [];
2300
+ for (const item of this.items.values()) {
2301
+ let score = 0;
2302
+ const titleLower = item.title.toLowerCase();
2303
+ const contentLower = item.content.toLowerCase();
2304
+ if (titleLower.includes(queryLower)) {
2305
+ score += 3;
2306
+ }
2307
+ if (contentLower.includes(queryLower)) {
2308
+ score += 1;
2309
+ }
2310
+ for (const word of queryWords) {
2311
+ if (titleLower.includes(word)) score += 0.5;
2312
+ if (contentLower.includes(word)) score += 0.2;
2313
+ if (item.tags.some((t) => t.toLowerCase().includes(word))) score += 0.3;
2314
+ }
2315
+ if (score > 0) {
2316
+ scored.push({ item, score });
2317
+ }
2318
+ }
2319
+ return scored.sort((a, b) => b.score - a.score).map((s) => s.item);
2320
+ }
2321
+ /**
2322
+ * Sort results
2323
+ */
2324
+ sortResults(items, sortBy, _query) {
2325
+ switch (sortBy) {
2326
+ case "recency":
2327
+ return items.sort((a, b) => b.updated.getTime() - a.updated.getTime());
2328
+ case "confidence":
2329
+ return items.sort((a, b) => b.confidence - a.confidence);
2330
+ case "access":
2331
+ return items.sort((a, b) => b.accessCount - a.accessCount);
2332
+ case "relevance":
2333
+ default:
2334
+ return items;
2335
+ }
2336
+ }
2337
+ /**
2338
+ * Find duplicate
2339
+ */
2340
+ findDuplicate(title, content) {
2341
+ const titleLower = title.toLowerCase();
2342
+ const contentLower = content.toLowerCase().substring(0, 200);
2343
+ for (const item of this.items.values()) {
2344
+ if (item.title.toLowerCase() === titleLower || item.content.toLowerCase().substring(0, 200) === contentLower) {
2345
+ return item;
2346
+ }
2347
+ }
2348
+ return void 0;
2349
+ }
2350
+ /**
2351
+ * Evict least used item
2352
+ */
2353
+ evictLeastUsed() {
2354
+ let leastUsed;
2355
+ let minAccess = Infinity;
2356
+ for (const item of this.items.values()) {
2357
+ if (item.accessCount < minAccess) {
2358
+ minAccess = item.accessCount;
2359
+ leastUsed = item;
2360
+ }
2361
+ }
2362
+ if (leastUsed) {
2363
+ this.delete(leastUsed.id);
2364
+ }
2365
+ }
2366
+ // ============ Utilities ============
2367
+ /**
2368
+ * Get all tags
2369
+ */
2370
+ getTags() {
2371
+ return Array.from(this.tagIndex.keys());
2372
+ }
2373
+ /**
2374
+ * Get all types
2375
+ */
2376
+ getTypes() {
2377
+ return Array.from(this.typeIndex.keys());
2378
+ }
2379
+ /**
2380
+ * Get all contributors
2381
+ */
2382
+ getContributors() {
2383
+ return Array.from(this.contributorIndex.keys());
2384
+ }
2385
+ /**
2386
+ * Get all items
2387
+ */
2388
+ getAll() {
2389
+ return Array.from(this.items.values());
2390
+ }
2391
+ /**
2392
+ * Get count
2393
+ */
2394
+ getCount() {
2395
+ return this.items.size;
2396
+ }
2397
+ /**
2398
+ * Clear all
2399
+ */
2400
+ clear() {
2401
+ this.items.clear();
2402
+ this.tagIndex.clear();
2403
+ this.typeIndex.clear();
2404
+ this.contributorIndex.clear();
2405
+ }
2406
+ /**
2407
+ * Export
2408
+ */
2409
+ export() {
2410
+ return Array.from(this.items.values());
2411
+ }
2412
+ /**
2413
+ * Import
2414
+ */
2415
+ import(items) {
2416
+ let count = 0;
2417
+ for (const item of items) {
2418
+ item.created = new Date(item.created);
2419
+ item.updated = new Date(item.updated);
2420
+ this.items.set(item.id, item);
2421
+ if (this.config.autoIndex) {
2422
+ this.indexItem(item);
2423
+ }
2424
+ count++;
2425
+ }
2426
+ return count;
2427
+ }
2428
+ /**
2429
+ * Get statistics
2430
+ */
2431
+ getStatistics() {
2432
+ const itemsByType = {};
2433
+ const itemsByContributor = {};
2434
+ let totalConfidence = 0;
2435
+ for (const item of this.items.values()) {
2436
+ itemsByType[item.type] = (itemsByType[item.type] ?? 0) + 1;
2437
+ if (item.contributor) {
2438
+ itemsByContributor[item.contributor] = (itemsByContributor[item.contributor] ?? 0) + 1;
2439
+ }
2440
+ totalConfidence += item.confidence;
2441
+ }
2442
+ const mostUsedTags = Array.from(this.tagIndex.entries()).map(([tag, ids]) => ({ tag, count: ids.size })).sort((a, b) => b.count - a.count).slice(0, 10);
2443
+ return {
2444
+ totalItems: this.items.size,
2445
+ itemsByType,
2446
+ itemsByContributor,
2447
+ totalTags: this.tagIndex.size,
2448
+ averageConfidence: this.items.size > 0 ? totalConfidence / this.items.size : 0,
2449
+ mostUsedTags
2450
+ };
2451
+ }
2452
+ };
2453
+ function createKnowledgeBase(config) {
2454
+ return new KnowledgeBase(config);
2455
+ }
2456
+ export {
2457
+ AgentCapabilities,
2458
+ AgentRegistry,
2459
+ AuctionStrategy,
2460
+ BaseDelegationStrategy,
2461
+ BestMatchStrategy,
2462
+ BranchBuilder,
2463
+ CheckpointManager,
2464
+ CodeReviewTasks,
2465
+ CollaborationManager,
2466
+ ConflictResolver,
2467
+ ConsensusStrategy,
2468
+ ConversationHistory,
2469
+ Crew,
2470
+ CrewAgent,
2471
+ CrewDashboard,
2472
+ CustomerSupportTasks,
2473
+ DAGExecutor,
2474
+ DebugMode,
2475
+ DelegationCoordinator,
2476
+ DelegationError,
2477
+ ExecutionContext,
2478
+ HierarchicalStrategy,
2479
+ InMemoryCheckpointStorage,
2480
+ KnowledgeBase,
2481
+ LoopBuilder,
2482
+ PRIORITY_WEIGHTS,
2483
+ PROFICIENCY_WEIGHTS,
2484
+ ParallelExecutor,
2485
+ ResearchTasks,
2486
+ Role,
2487
+ RoundRobinStrategy,
2488
+ STRATEGY_TYPES,
2489
+ SharedMemory,
2490
+ Task,
2491
+ TaskQueue,
2492
+ WorkflowBuilder,
2493
+ WritingTasks,
2494
+ createAgentRegistry,
2495
+ createAuctionStrategy,
2496
+ createBestMatchStrategy,
2497
+ createCheckpointManager,
2498
+ createCodeReviewCrew,
2499
+ createCodeReviewCrewConfig,
2500
+ createCollaborationManager,
2501
+ createConflictResolver,
2502
+ createConsensusStrategy,
2503
+ createConversationHistory,
2504
+ createCrew,
2505
+ createCrewAgent,
2506
+ createCustomerSupportCrew,
2507
+ createCustomerSupportCrewConfig,
2508
+ createDAGExecutor,
2509
+ createDAGFromSteps,
2510
+ createDashboard,
2511
+ createDebugMode,
2512
+ createDelegationCoordinator,
2513
+ createExecutionContext,
2514
+ createHierarchicalStrategy,
2515
+ createKnowledgeBase,
2516
+ createParallelExecutor,
2517
+ createResearchCrew,
2518
+ createResearchCrewConfig,
2519
+ createRole,
2520
+ createRoundRobinStrategy,
2521
+ createSharedMemory,
2522
+ createStrategy,
2523
+ createTask,
2524
+ createTaskQueue,
2525
+ createWritingCrew,
2526
+ createWritingCrewConfig,
2527
+ workflow
2528
+ };