@defai.digital/agent-domain 13.0.3

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 (77) hide show
  1. package/LICENSE +214 -0
  2. package/dist/enhanced-executor.d.ts +170 -0
  3. package/dist/enhanced-executor.d.ts.map +1 -0
  4. package/dist/enhanced-executor.js +1072 -0
  5. package/dist/enhanced-executor.js.map +1 -0
  6. package/dist/executor.d.ts +120 -0
  7. package/dist/executor.d.ts.map +1 -0
  8. package/dist/executor.js +929 -0
  9. package/dist/executor.js.map +1 -0
  10. package/dist/index.d.ts +25 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +34 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/loader.d.ts +50 -0
  15. package/dist/loader.d.ts.map +1 -0
  16. package/dist/loader.js +160 -0
  17. package/dist/loader.js.map +1 -0
  18. package/dist/persistent-registry.d.ts +105 -0
  19. package/dist/persistent-registry.d.ts.map +1 -0
  20. package/dist/persistent-registry.js +183 -0
  21. package/dist/persistent-registry.js.map +1 -0
  22. package/dist/production-factories.d.ts +70 -0
  23. package/dist/production-factories.d.ts.map +1 -0
  24. package/dist/production-factories.js +434 -0
  25. package/dist/production-factories.js.map +1 -0
  26. package/dist/prompt-executor.d.ts +119 -0
  27. package/dist/prompt-executor.d.ts.map +1 -0
  28. package/dist/prompt-executor.js +211 -0
  29. package/dist/prompt-executor.js.map +1 -0
  30. package/dist/registry.d.ts +57 -0
  31. package/dist/registry.d.ts.map +1 -0
  32. package/dist/registry.js +123 -0
  33. package/dist/registry.js.map +1 -0
  34. package/dist/selection-service.d.ts +74 -0
  35. package/dist/selection-service.d.ts.map +1 -0
  36. package/dist/selection-service.js +322 -0
  37. package/dist/selection-service.js.map +1 -0
  38. package/dist/selector.d.ts +51 -0
  39. package/dist/selector.d.ts.map +1 -0
  40. package/dist/selector.js +249 -0
  41. package/dist/selector.js.map +1 -0
  42. package/dist/stub-checkpoint.d.ts +23 -0
  43. package/dist/stub-checkpoint.d.ts.map +1 -0
  44. package/dist/stub-checkpoint.js +137 -0
  45. package/dist/stub-checkpoint.js.map +1 -0
  46. package/dist/stub-delegation-tracker.d.ts +25 -0
  47. package/dist/stub-delegation-tracker.d.ts.map +1 -0
  48. package/dist/stub-delegation-tracker.js +118 -0
  49. package/dist/stub-delegation-tracker.js.map +1 -0
  50. package/dist/stub-parallel-executor.d.ts +19 -0
  51. package/dist/stub-parallel-executor.d.ts.map +1 -0
  52. package/dist/stub-parallel-executor.js +176 -0
  53. package/dist/stub-parallel-executor.js.map +1 -0
  54. package/dist/types.d.ts +614 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +15 -0
  57. package/dist/types.js.map +1 -0
  58. package/dist/workflow-templates.d.ts +117 -0
  59. package/dist/workflow-templates.d.ts.map +1 -0
  60. package/dist/workflow-templates.js +342 -0
  61. package/dist/workflow-templates.js.map +1 -0
  62. package/package.json +51 -0
  63. package/src/enhanced-executor.ts +1395 -0
  64. package/src/executor.ts +1153 -0
  65. package/src/index.ts +172 -0
  66. package/src/loader.ts +191 -0
  67. package/src/persistent-registry.ts +235 -0
  68. package/src/production-factories.ts +613 -0
  69. package/src/prompt-executor.ts +310 -0
  70. package/src/registry.ts +167 -0
  71. package/src/selection-service.ts +411 -0
  72. package/src/selector.ts +299 -0
  73. package/src/stub-checkpoint.ts +187 -0
  74. package/src/stub-delegation-tracker.ts +161 -0
  75. package/src/stub-parallel-executor.ts +224 -0
  76. package/src/types.ts +784 -0
  77. package/src/workflow-templates.ts +393 -0
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Stub Checkpoint Implementation
3
+ *
4
+ * Provides minimal checkpoint storage and manager for when no real
5
+ * implementation is provided via AgentDomainConfig factories.
6
+ *
7
+ * Uses in-memory storage (data lost between invocations).
8
+ * For production use, provide real implementations via config.
9
+ */
10
+
11
+ import type { CheckpointConfig } from '@defai.digital/contracts';
12
+ import type {
13
+ CheckpointStoragePort,
14
+ CheckpointManagerPort,
15
+ Checkpoint,
16
+ CheckpointStorageFactory,
17
+ CheckpointManagerFactory,
18
+ } from './types.js';
19
+
20
+ let _warnedOnce = false;
21
+
22
+ /**
23
+ * In-memory checkpoint storage (stub)
24
+ */
25
+ function createInMemoryCheckpointStorage(): CheckpointStoragePort {
26
+ const checkpoints = new Map<string, Checkpoint>();
27
+
28
+ return {
29
+ async save(checkpoint: Checkpoint): Promise<void> {
30
+ checkpoints.set(checkpoint.checkpointId, { ...checkpoint });
31
+ },
32
+
33
+ async load(checkpointId: string): Promise<Checkpoint | null> {
34
+ return checkpoints.get(checkpointId) ?? null;
35
+ },
36
+
37
+ async loadLatest(agentId: string, sessionId?: string): Promise<Checkpoint | null> {
38
+ let latest: Checkpoint | null = null;
39
+ let latestTime = 0;
40
+
41
+ for (const cp of checkpoints.values()) {
42
+ if (cp.agentId !== agentId) continue;
43
+ if (sessionId !== undefined && cp.sessionId !== sessionId) continue;
44
+
45
+ const time = new Date(cp.createdAt).getTime();
46
+ if (time > latestTime) {
47
+ latestTime = time;
48
+ latest = cp;
49
+ }
50
+ }
51
+
52
+ return latest;
53
+ },
54
+
55
+ async list(agentId: string, sessionId?: string): Promise<Checkpoint[]> {
56
+ const results: Checkpoint[] = [];
57
+
58
+ for (const cp of checkpoints.values()) {
59
+ if (cp.agentId !== agentId) continue;
60
+ if (sessionId !== undefined && cp.sessionId !== sessionId) continue;
61
+ results.push({ ...cp });
62
+ }
63
+
64
+ return results.sort(
65
+ (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
66
+ );
67
+ },
68
+
69
+ async delete(checkpointId: string): Promise<boolean> {
70
+ return checkpoints.delete(checkpointId);
71
+ },
72
+
73
+ async deleteExpired(): Promise<number> {
74
+ const now = Date.now();
75
+ let count = 0;
76
+
77
+ for (const [id, cp] of checkpoints.entries()) {
78
+ if (cp.expiresAt && new Date(cp.expiresAt).getTime() < now) {
79
+ checkpoints.delete(id);
80
+ count++;
81
+ }
82
+ }
83
+
84
+ return count;
85
+ },
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Creates a stub checkpoint manager
91
+ */
92
+ function createStubCheckpointManager(
93
+ agentId: string,
94
+ sessionId: string | undefined,
95
+ storage: CheckpointStoragePort,
96
+ config: CheckpointConfig
97
+ ): CheckpointManagerPort {
98
+ return {
99
+ getConfig(): CheckpointConfig {
100
+ return { ...config };
101
+ },
102
+
103
+ shouldCheckpoint(stepIndex: number): boolean {
104
+ if (!config.enabled) return false;
105
+ return (stepIndex + 1) % config.intervalSteps === 0;
106
+ },
107
+
108
+ async createCheckpoint(
109
+ stepIndex: number,
110
+ stepId: string,
111
+ previousOutputs: Record<string, unknown>,
112
+ metadata?: Record<string, unknown>
113
+ ): Promise<Checkpoint> {
114
+ const now = new Date();
115
+ const checkpoint: Checkpoint = {
116
+ checkpointId: crypto.randomUUID(),
117
+ agentId,
118
+ sessionId,
119
+ stepIndex,
120
+ stepId,
121
+ previousOutputs: { ...previousOutputs },
122
+ metadata,
123
+ createdAt: now.toISOString(),
124
+ expiresAt: config.retentionHours
125
+ ? new Date(now.getTime() + config.retentionHours * 3600 * 1000).toISOString()
126
+ : undefined,
127
+ };
128
+
129
+ await storage.save(checkpoint);
130
+ return checkpoint;
131
+ },
132
+
133
+ async getLatestCheckpoint(): Promise<Checkpoint | null> {
134
+ return storage.loadLatest(agentId, sessionId);
135
+ },
136
+
137
+ async getResumeContext(checkpointId: string): Promise<{
138
+ startFromStep: number;
139
+ previousOutputs: Record<string, unknown>;
140
+ } | null> {
141
+ const checkpoint = await storage.load(checkpointId);
142
+ if (!checkpoint) return null;
143
+
144
+ return {
145
+ startFromStep: checkpoint.stepIndex + 1,
146
+ previousOutputs: { ...checkpoint.previousOutputs },
147
+ };
148
+ },
149
+
150
+ async cleanup(): Promise<number> {
151
+ return storage.deleteExpired();
152
+ },
153
+ };
154
+ }
155
+
156
+ /**
157
+ * Stub checkpoint storage factory
158
+ */
159
+ export const stubCheckpointStorageFactory: CheckpointStorageFactory = () => {
160
+ if (!_warnedOnce) {
161
+ console.warn(
162
+ '[agent-domain] Using stub checkpoint storage. ' +
163
+ 'For persistent checkpoints, provide checkpointStorageFactory in config.'
164
+ );
165
+ _warnedOnce = true;
166
+ }
167
+ return createInMemoryCheckpointStorage();
168
+ };
169
+
170
+ /**
171
+ * Stub checkpoint manager factory
172
+ */
173
+ export const stubCheckpointManagerFactory: CheckpointManagerFactory = (
174
+ agentId: string,
175
+ sessionId: string | undefined,
176
+ storage: CheckpointStoragePort,
177
+ config: CheckpointConfig
178
+ ) => {
179
+ return createStubCheckpointManager(agentId, sessionId, storage, config);
180
+ };
181
+
182
+ /**
183
+ * Reset the warning flag (for testing)
184
+ */
185
+ export function resetCheckpointStubWarning(): void {
186
+ _warnedOnce = false;
187
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Stub Delegation Tracker Implementation
3
+ *
4
+ * Provides a minimal delegation tracker for when no real implementation
5
+ * is provided via AgentDomainConfig.delegationTrackerFactory.
6
+ *
7
+ * This stub:
8
+ * - Logs a warning on first use
9
+ * - Allows delegations within depth limits
10
+ * - Tracks basic context and history
11
+ *
12
+ * For production use, provide a real implementation via config.
13
+ */
14
+
15
+ import type {
16
+ DelegationContext,
17
+ DelegationCheckResult,
18
+ DelegationResult,
19
+ DelegationRequest as ContractDelegationRequest,
20
+ } from '@defai.digital/contracts';
21
+ import {
22
+ createRootDelegationContext,
23
+ DelegationErrorCodes,
24
+ } from '@defai.digital/contracts';
25
+ import type { DelegationTrackerPort, DelegationTrackerFactory } from './types.js';
26
+
27
+ let _warnedOnce = false;
28
+
29
+ /**
30
+ * Creates a stub delegation tracker
31
+ *
32
+ * This is used when no delegationTrackerFactory is provided in config.
33
+ * It provides basic functionality but logs a warning.
34
+ */
35
+ function createStubDelegationTracker(
36
+ agentId: string,
37
+ parentContext: DelegationContext | undefined,
38
+ maxDepth: number
39
+ ): DelegationTrackerPort {
40
+ // Warn once about stub usage
41
+ if (!_warnedOnce) {
42
+ console.warn(
43
+ '[agent-domain] Using stub delegation tracker. ' +
44
+ 'For full delegation support, provide delegationTrackerFactory in AgentDomainConfig.'
45
+ );
46
+ _warnedOnce = true;
47
+ }
48
+
49
+ // Initialize context
50
+ let context: DelegationContext;
51
+
52
+ if (parentContext) {
53
+ // Create child context
54
+ context = {
55
+ ...parentContext,
56
+ currentDepth: parentContext.currentDepth + 1,
57
+ delegationChain: [...parentContext.delegationChain, agentId],
58
+ };
59
+ } else {
60
+ // Create root context
61
+ context = createRootDelegationContext(
62
+ agentId,
63
+ crypto.randomUUID(),
64
+ maxDepth
65
+ );
66
+ }
67
+
68
+ const delegationHistory: DelegationResult[] = [];
69
+
70
+ return {
71
+ getContext(): DelegationContext {
72
+ return { ...context };
73
+ },
74
+
75
+ canDelegate(toAgentId: string): DelegationCheckResult {
76
+ // INV-DT-001: Check depth limit
77
+ if (context.currentDepth >= context.maxDepth) {
78
+ return {
79
+ allowed: false,
80
+ reason: DelegationErrorCodes.MAX_DEPTH_EXCEEDED,
81
+ message: `Maximum delegation depth ${context.maxDepth} reached`,
82
+ };
83
+ }
84
+
85
+ // INV-DT-002: Check for circular delegation
86
+ if (context.delegationChain.includes(toAgentId)) {
87
+ return {
88
+ allowed: false,
89
+ reason: DelegationErrorCodes.CIRCULAR_DELEGATION,
90
+ message: `Cannot delegate to ${toAgentId} - already in delegation chain`,
91
+ };
92
+ }
93
+
94
+ return {
95
+ allowed: true,
96
+ reason: 'ALLOWED',
97
+ message: `Delegation to ${toAgentId} is allowed`,
98
+ };
99
+ },
100
+
101
+ createDelegationRequest(
102
+ toAgentId: string,
103
+ task: string,
104
+ input?: unknown,
105
+ timeout?: number
106
+ ): ContractDelegationRequest | null {
107
+ const checkResult = this.canDelegate(toAgentId);
108
+ if (!checkResult.allowed) {
109
+ return null;
110
+ }
111
+
112
+ return {
113
+ fromAgentId: agentId,
114
+ toAgentId,
115
+ task,
116
+ input,
117
+ timeout,
118
+ context,
119
+ };
120
+ },
121
+
122
+ createChildContext(toAgentId: string): DelegationContext {
123
+ return {
124
+ ...context,
125
+ currentDepth: context.currentDepth + 1,
126
+ delegationChain: [...context.delegationChain, toAgentId],
127
+ };
128
+ },
129
+
130
+ recordResult(result: DelegationResult): void {
131
+ delegationHistory.push(result);
132
+ },
133
+
134
+ getHistory(): DelegationResult[] {
135
+ return [...delegationHistory];
136
+ },
137
+
138
+ isRoot(): boolean {
139
+ return context.currentDepth === 0;
140
+ },
141
+
142
+ getRemainingDepth(): number {
143
+ return context.maxDepth - context.currentDepth;
144
+ },
145
+ };
146
+ }
147
+
148
+ /**
149
+ * Stub delegation tracker factory
150
+ *
151
+ * Use this as a fallback when no factory is provided in config.
152
+ */
153
+ export const stubDelegationTrackerFactory: DelegationTrackerFactory =
154
+ createStubDelegationTracker;
155
+
156
+ /**
157
+ * Reset the warning flag (for testing)
158
+ */
159
+ export function resetStubWarning(): void {
160
+ _warnedOnce = false;
161
+ }
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Stub Parallel Executor Implementation
3
+ *
4
+ * Provides minimal parallel execution for when no real implementation
5
+ * is provided via AgentDomainConfig factories.
6
+ *
7
+ * This stub executes steps sequentially (not actually in parallel).
8
+ * For real parallel execution, provide parallelExecutorFactory in config.
9
+ */
10
+
11
+ import {
12
+ type ParallelExecutionConfig,
13
+ createDefaultParallelExecutionConfig,
14
+ type AgentWorkflowStep,
15
+ TIMEOUT_ORCHESTRATION_EXECUTION,
16
+ } from '@defai.digital/contracts';
17
+ import type {
18
+ ParallelExecutorPort,
19
+ ParallelStepExecutor,
20
+ ParallelGroupResult,
21
+ ParallelStepResult,
22
+ ParallelExecutorFactory,
23
+ } from './types.js';
24
+
25
+ let _warnedOnce = false;
26
+
27
+ /**
28
+ * Creates a stub parallel executor that executes steps sequentially
29
+ */
30
+ function createStubParallelExecutor(
31
+ config: Partial<ParallelExecutionConfig> = {}
32
+ ): ParallelExecutorPort {
33
+ if (!_warnedOnce) {
34
+ console.warn(
35
+ '[agent-domain] Using stub parallel executor (sequential execution). ' +
36
+ 'For real parallel execution, provide parallelExecutorFactory in config.'
37
+ );
38
+ _warnedOnce = true;
39
+ }
40
+
41
+ const cfg = { ...createDefaultParallelExecutionConfig(), ...config };
42
+ let cancelled = false;
43
+
44
+ return {
45
+ getConfig(): ParallelExecutionConfig {
46
+ return { ...cfg };
47
+ },
48
+
49
+ async executeGroup(
50
+ steps: AgentWorkflowStep[],
51
+ executor: ParallelStepExecutor,
52
+ previousOutputs: Record<string, unknown> = {}
53
+ ): Promise<ParallelGroupResult> {
54
+ const startTime = Date.now();
55
+ const stepResults: ParallelStepResult[] = [];
56
+ const outputs = { ...previousOutputs };
57
+ let failedCount = 0;
58
+ let cancelledCount = 0;
59
+
60
+ // Build execution layers (respecting dependencies)
61
+ const layers = this.buildExecutionLayers(steps);
62
+
63
+ // Execute layers sequentially (stub doesn't do real parallelism)
64
+ for (const layer of layers) {
65
+ if (cancelled) {
66
+ // Mark remaining steps as cancelled
67
+ for (const step of layer) {
68
+ stepResults.push({
69
+ stepId: step.stepId,
70
+ success: false,
71
+ cancelled: true,
72
+ durationMs: 0,
73
+ });
74
+ cancelledCount++;
75
+ }
76
+ continue;
77
+ }
78
+
79
+ // Execute steps in layer sequentially
80
+ for (const step of layer) {
81
+ if (cancelled) {
82
+ stepResults.push({
83
+ stepId: step.stepId,
84
+ success: false,
85
+ cancelled: true,
86
+ durationMs: 0,
87
+ });
88
+ cancelledCount++;
89
+ continue;
90
+ }
91
+
92
+ const stepStart = Date.now();
93
+ // Create cancellable timeout to prevent timer leaks
94
+ let timeoutId: ReturnType<typeof setTimeout> | undefined;
95
+ const stepTimeoutMs = cfg.groupTimeoutMs ?? TIMEOUT_ORCHESTRATION_EXECUTION;
96
+ const timeoutPromise = new Promise((_, reject) => {
97
+ timeoutId = setTimeout(() => { reject(new Error('Step timed out')); }, stepTimeoutMs);
98
+ });
99
+
100
+ try {
101
+ const output = await Promise.race([
102
+ executor(step, outputs),
103
+ timeoutPromise,
104
+ ]);
105
+
106
+ // Clean up timeout
107
+ if (timeoutId !== undefined) {
108
+ clearTimeout(timeoutId);
109
+ }
110
+
111
+ outputs[step.stepId] = output;
112
+ stepResults.push({
113
+ stepId: step.stepId,
114
+ success: true,
115
+ output,
116
+ durationMs: Date.now() - stepStart,
117
+ });
118
+ } catch (error) {
119
+ // Clean up timeout on error too
120
+ if (timeoutId !== undefined) {
121
+ clearTimeout(timeoutId);
122
+ }
123
+ const result: ParallelStepResult = {
124
+ stepId: step.stepId,
125
+ success: false,
126
+ error: error instanceof Error ? error.message : 'Unknown error',
127
+ durationMs: Date.now() - stepStart,
128
+ };
129
+ stepResults.push(result);
130
+ failedCount++;
131
+
132
+ // If step is critical (not parallel) and failFast strategy, stop execution
133
+ if (!step.parallel && cfg.failureStrategy === 'failFast') {
134
+ cancelled = true;
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ return {
141
+ stepResults,
142
+ totalDurationMs: Date.now() - startTime,
143
+ allSucceeded: failedCount === 0 && cancelledCount === 0,
144
+ failedCount,
145
+ cancelledCount,
146
+ };
147
+ },
148
+
149
+ buildExecutionLayers(steps: AgentWorkflowStep[]): AgentWorkflowStep[][] {
150
+ // Simple topological sort based on dependencies
151
+ const layers: AgentWorkflowStep[][] = [];
152
+ const completed = new Set<string>();
153
+ const remaining = [...steps];
154
+
155
+ // Guard against infinite loops with max iteration limit
156
+ const maxIterations = steps.length + 1;
157
+ let iterations = 0;
158
+
159
+ while (remaining.length > 0 && iterations < maxIterations) {
160
+ iterations++;
161
+ // Find steps with all dependencies satisfied
162
+ const ready: AgentWorkflowStep[] = [];
163
+ const stillWaiting: AgentWorkflowStep[] = [];
164
+
165
+ for (const step of remaining) {
166
+ const deps = step.dependencies ?? [];
167
+ if (deps.every((dep) => completed.has(dep))) {
168
+ ready.push(step);
169
+ } else {
170
+ stillWaiting.push(step);
171
+ }
172
+ }
173
+
174
+ if (ready.length === 0 && stillWaiting.length > 0) {
175
+ // Circular dependency or missing dependency - execute remaining steps
176
+ const unresolvableSteps = stillWaiting.map((s) => s.stepId).join(', ');
177
+ console.warn(
178
+ `[buildExecutionLayers] Circular or unresolvable dependencies detected. ` +
179
+ `Unresolvable steps: ${unresolvableSteps}`
180
+ );
181
+ layers.push(stillWaiting);
182
+ break;
183
+ }
184
+
185
+ if (ready.length > 0) {
186
+ layers.push(ready);
187
+ for (const step of ready) {
188
+ completed.add(step.stepId);
189
+ }
190
+ }
191
+
192
+ remaining.length = 0;
193
+ remaining.push(...stillWaiting);
194
+ }
195
+
196
+ if (iterations >= maxIterations) {
197
+ console.error(
198
+ `[buildExecutionLayers] Max iterations (${maxIterations}) reached. ` +
199
+ `This indicates a bug in the algorithm or malformed input.`
200
+ );
201
+ }
202
+
203
+ return layers;
204
+ },
205
+
206
+ cancel(): void {
207
+ cancelled = true;
208
+ },
209
+ };
210
+ }
211
+
212
+ /**
213
+ * Stub parallel executor factory
214
+ */
215
+ export const stubParallelExecutorFactory: ParallelExecutorFactory = (config) => {
216
+ return createStubParallelExecutor(config);
217
+ };
218
+
219
+ /**
220
+ * Reset the warning flag (for testing)
221
+ */
222
+ export function resetParallelStubWarning(): void {
223
+ _warnedOnce = false;
224
+ }