@sparkleideas/integration 3.5.2-patch.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/README.md +270 -0
- package/package.json +55 -0
- package/src/__tests__/agent-adapter.test.ts +271 -0
- package/src/__tests__/agentic-flow-agent.test.ts +176 -0
- package/src/__tests__/token-optimizer.test.ts +176 -0
- package/src/agent-adapter.ts +651 -0
- package/src/agentic-flow-agent.ts +802 -0
- package/src/agentic-flow-bridge.ts +803 -0
- package/src/attention-coordinator.ts +679 -0
- package/src/feature-flags.ts +485 -0
- package/src/index.ts +466 -0
- package/src/long-running-worker.ts +871 -0
- package/src/multi-model-router.ts +1079 -0
- package/src/provider-adapter.ts +1168 -0
- package/src/sdk-bridge.ts +435 -0
- package/src/sona-adapter.ts +824 -0
- package/src/specialized-worker.ts +864 -0
- package/src/swarm-adapter.ts +1112 -0
- package/src/token-optimizer.ts +306 -0
- package/src/types.ts +494 -0
- package/src/worker-base.ts +822 -0
- package/src/worker-pool.ts +933 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,802 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgenticFlowAgent - Claude Flow Agent with @sparkleideas/agentic-flow Delegation
|
|
3
|
+
*
|
|
4
|
+
* Per ADR-001: "Use @sparkleideas/agentic-flow's Agent base class for all agents"
|
|
5
|
+
* This class wraps @sparkleideas/agentic-flow functionality while adding Claude Flow specifics.
|
|
6
|
+
*
|
|
7
|
+
* This implements the adapter pattern to bridge between:
|
|
8
|
+
* - Claude Flow's agent lifecycle (v3 DDD architecture)
|
|
9
|
+
* - @sparkleideas/agentic-flow's optimized agent implementations
|
|
10
|
+
*
|
|
11
|
+
* When @sparkleideas/agentic-flow is available, this class delegates core operations to
|
|
12
|
+
* @sparkleideas/agentic-flow's Agent implementations, eliminating 10,000+ lines of duplicate code.
|
|
13
|
+
*
|
|
14
|
+
* Performance Benefits:
|
|
15
|
+
* - Flash Attention: 2.49x-7.47x speedup for context processing
|
|
16
|
+
* - SONA Learning: <0.05ms adaptation for real-time learning
|
|
17
|
+
* - AgentDB: 150x-12,500x faster memory/pattern search
|
|
18
|
+
*
|
|
19
|
+
* @module v3/integration/agentic-flow-agent
|
|
20
|
+
* @version 3.0.0-alpha.1
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { EventEmitter } from 'events';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Agent status in the system
|
|
27
|
+
*/
|
|
28
|
+
export type AgentStatus = 'spawning' | 'active' | 'idle' | 'busy' | 'error' | 'terminated';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Agent type classification
|
|
32
|
+
*/
|
|
33
|
+
export type AgentType =
|
|
34
|
+
| 'coder'
|
|
35
|
+
| 'reviewer'
|
|
36
|
+
| 'tester'
|
|
37
|
+
| 'researcher'
|
|
38
|
+
| 'planner'
|
|
39
|
+
| 'architect'
|
|
40
|
+
| 'coordinator'
|
|
41
|
+
| 'security'
|
|
42
|
+
| 'performance'
|
|
43
|
+
| 'custom';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Core agent configuration interface
|
|
47
|
+
*/
|
|
48
|
+
export interface IAgentConfig {
|
|
49
|
+
readonly id: string;
|
|
50
|
+
readonly name: string;
|
|
51
|
+
readonly type: AgentType | string;
|
|
52
|
+
capabilities: string[];
|
|
53
|
+
maxConcurrentTasks: number;
|
|
54
|
+
priority: number;
|
|
55
|
+
timeout?: number;
|
|
56
|
+
retryPolicy?: {
|
|
57
|
+
maxRetries: number;
|
|
58
|
+
backoffMs: number;
|
|
59
|
+
backoffMultiplier: number;
|
|
60
|
+
};
|
|
61
|
+
resources?: {
|
|
62
|
+
maxMemoryMb?: number;
|
|
63
|
+
maxCpuPercent?: number;
|
|
64
|
+
};
|
|
65
|
+
metadata?: Record<string, unknown>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Core agent entity interface
|
|
70
|
+
*/
|
|
71
|
+
export interface IAgent {
|
|
72
|
+
readonly id: string;
|
|
73
|
+
readonly name: string;
|
|
74
|
+
readonly type: AgentType | string;
|
|
75
|
+
readonly config: IAgentConfig;
|
|
76
|
+
readonly createdAt: Date;
|
|
77
|
+
status: AgentStatus;
|
|
78
|
+
currentTaskCount: number;
|
|
79
|
+
lastActivity: Date;
|
|
80
|
+
sessionId?: string;
|
|
81
|
+
terminalId?: string;
|
|
82
|
+
memoryBankId?: string;
|
|
83
|
+
metrics?: {
|
|
84
|
+
tasksCompleted: number;
|
|
85
|
+
tasksFailed: number;
|
|
86
|
+
avgTaskDuration: number;
|
|
87
|
+
errorCount: number;
|
|
88
|
+
uptime: number;
|
|
89
|
+
};
|
|
90
|
+
health?: {
|
|
91
|
+
status: 'healthy' | 'degraded' | 'unhealthy';
|
|
92
|
+
lastCheck: Date;
|
|
93
|
+
issues?: string[];
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Agent session interface (not used in this implementation)
|
|
99
|
+
*/
|
|
100
|
+
export interface IAgentSession {
|
|
101
|
+
readonly id: string;
|
|
102
|
+
readonly agentId: string;
|
|
103
|
+
readonly startTime: Date;
|
|
104
|
+
status: 'active' | 'idle' | 'terminated';
|
|
105
|
+
terminalId: string;
|
|
106
|
+
memoryBankId: string;
|
|
107
|
+
lastActivity: Date;
|
|
108
|
+
endTime?: Date;
|
|
109
|
+
metadata?: Record<string, unknown>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Task interface for agent execution
|
|
114
|
+
*/
|
|
115
|
+
export interface Task {
|
|
116
|
+
/** Unique task identifier */
|
|
117
|
+
id: string;
|
|
118
|
+
/** Task type/category */
|
|
119
|
+
type: string;
|
|
120
|
+
/** Task description */
|
|
121
|
+
description: string;
|
|
122
|
+
/** Task input data */
|
|
123
|
+
input?: Record<string, unknown>;
|
|
124
|
+
/** Task priority (0-10) */
|
|
125
|
+
priority?: number;
|
|
126
|
+
/** Task timeout in milliseconds */
|
|
127
|
+
timeout?: number;
|
|
128
|
+
/** Task metadata */
|
|
129
|
+
metadata?: Record<string, unknown>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Task result interface
|
|
134
|
+
*/
|
|
135
|
+
export interface TaskResult {
|
|
136
|
+
/** Task identifier */
|
|
137
|
+
taskId: string;
|
|
138
|
+
/** Success status */
|
|
139
|
+
success: boolean;
|
|
140
|
+
/** Result data */
|
|
141
|
+
output?: unknown;
|
|
142
|
+
/** Error if failed */
|
|
143
|
+
error?: Error;
|
|
144
|
+
/** Execution duration in milliseconds */
|
|
145
|
+
duration: number;
|
|
146
|
+
/** Tokens used (if applicable) */
|
|
147
|
+
tokensUsed?: number;
|
|
148
|
+
/** Result metadata */
|
|
149
|
+
metadata?: Record<string, unknown>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Message interface for agent communication
|
|
154
|
+
*/
|
|
155
|
+
export interface Message {
|
|
156
|
+
/** Message identifier */
|
|
157
|
+
id: string;
|
|
158
|
+
/** Sender agent ID */
|
|
159
|
+
from: string;
|
|
160
|
+
/** Message type */
|
|
161
|
+
type: string;
|
|
162
|
+
/** Message payload */
|
|
163
|
+
payload: unknown;
|
|
164
|
+
/** Timestamp */
|
|
165
|
+
timestamp: number;
|
|
166
|
+
/** Correlation ID for request-response */
|
|
167
|
+
correlationId?: string;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Agent health information
|
|
172
|
+
*/
|
|
173
|
+
export interface AgentHealth {
|
|
174
|
+
/** Health status */
|
|
175
|
+
status: 'healthy' | 'degraded' | 'unhealthy';
|
|
176
|
+
/** Last health check timestamp */
|
|
177
|
+
lastCheck: number;
|
|
178
|
+
/** Active issues */
|
|
179
|
+
issues: string[];
|
|
180
|
+
/** Metrics */
|
|
181
|
+
metrics: {
|
|
182
|
+
uptime: number;
|
|
183
|
+
tasksCompleted: number;
|
|
184
|
+
tasksFailed: number;
|
|
185
|
+
avgLatency: number;
|
|
186
|
+
memoryUsageMb: number;
|
|
187
|
+
cpuPercent: number;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Interface for @sparkleideas/agentic-flow Agent reference (for delegation)
|
|
193
|
+
* This represents the @sparkleideas/agentic-flow Agent class API
|
|
194
|
+
*/
|
|
195
|
+
interface AgenticFlowAgentReference {
|
|
196
|
+
id: string;
|
|
197
|
+
type: string;
|
|
198
|
+
status: string;
|
|
199
|
+
initialize?(): Promise<void>;
|
|
200
|
+
shutdown?(): Promise<void>;
|
|
201
|
+
execute?(task: unknown): Promise<unknown>;
|
|
202
|
+
sendMessage?(to: string, message: unknown): Promise<void>;
|
|
203
|
+
getHealth?(): Promise<unknown>;
|
|
204
|
+
getMetrics?(): Promise<unknown>;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* AgenticFlowAgent Configuration
|
|
209
|
+
*/
|
|
210
|
+
export interface AgentConfig extends IAgentConfig {
|
|
211
|
+
/** Enable delegation to @sparkleideas/agentic-flow */
|
|
212
|
+
enableDelegation?: boolean;
|
|
213
|
+
/** @sparkleideas/agentic-flow specific configuration */
|
|
214
|
+
agenticFlowConfig?: Record<string, unknown>;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* AgenticFlowAgent - Base class for all Claude Flow v3 agents
|
|
219
|
+
*
|
|
220
|
+
* This class serves as the foundation for all agent types in Claude Flow v3,
|
|
221
|
+
* implementing ADR-001 by delegating to @sparkleideas/agentic-flow when available while
|
|
222
|
+
* maintaining backward compatibility with local implementations.
|
|
223
|
+
*
|
|
224
|
+
* Usage:
|
|
225
|
+
* ```typescript
|
|
226
|
+
* const agent = new AgenticFlowAgent({
|
|
227
|
+
* id: 'agent-123',
|
|
228
|
+
* name: 'Coder Agent',
|
|
229
|
+
* type: 'coder',
|
|
230
|
+
* capabilities: ['code-generation', 'refactoring'],
|
|
231
|
+
* maxConcurrentTasks: 3,
|
|
232
|
+
* priority: 5,
|
|
233
|
+
* });
|
|
234
|
+
*
|
|
235
|
+
* await agent.initialize();
|
|
236
|
+
*
|
|
237
|
+
* // Execute task with automatic delegation
|
|
238
|
+
* const result = await agent.executeTask({
|
|
239
|
+
* id: 'task-1',
|
|
240
|
+
* type: 'code',
|
|
241
|
+
* description: 'Implement authentication',
|
|
242
|
+
* });
|
|
243
|
+
*
|
|
244
|
+
* // Access health metrics
|
|
245
|
+
* const health = agent.getHealth();
|
|
246
|
+
* console.log('Agent health:', health.status);
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
export class AgenticFlowAgent extends EventEmitter implements IAgent {
|
|
250
|
+
// ===== IAgent Interface Implementation =====
|
|
251
|
+
|
|
252
|
+
readonly id: string;
|
|
253
|
+
readonly name: string;
|
|
254
|
+
readonly type: AgentType | string;
|
|
255
|
+
readonly config: IAgentConfig;
|
|
256
|
+
readonly createdAt: Date;
|
|
257
|
+
|
|
258
|
+
status: AgentStatus = 'spawning';
|
|
259
|
+
currentTaskCount: number = 0;
|
|
260
|
+
lastActivity: Date;
|
|
261
|
+
|
|
262
|
+
sessionId?: string;
|
|
263
|
+
terminalId?: string;
|
|
264
|
+
memoryBankId?: string;
|
|
265
|
+
|
|
266
|
+
metrics?: {
|
|
267
|
+
tasksCompleted: number;
|
|
268
|
+
tasksFailed: number;
|
|
269
|
+
avgTaskDuration: number;
|
|
270
|
+
errorCount: number;
|
|
271
|
+
uptime: number;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
health?: {
|
|
275
|
+
status: 'healthy' | 'degraded' | 'unhealthy';
|
|
276
|
+
lastCheck: Date;
|
|
277
|
+
issues?: string[];
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// ===== Private State =====
|
|
281
|
+
|
|
282
|
+
private initialized: boolean = false;
|
|
283
|
+
private currentTask: Task | null = null;
|
|
284
|
+
private taskStartTime: number = 0;
|
|
285
|
+
private totalTaskDuration: number = 0;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Reference to @sparkleideas/agentic-flow Agent for delegation (ADR-001)
|
|
289
|
+
* When set, core operations delegate to @sparkleideas/agentic-flow's optimized implementations
|
|
290
|
+
*/
|
|
291
|
+
private agenticFlowRef: AgenticFlowAgentReference | null = null;
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Indicates if delegation to @sparkleideas/agentic-flow is active
|
|
295
|
+
*/
|
|
296
|
+
private delegationEnabled: boolean = false;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Extended configuration
|
|
300
|
+
*/
|
|
301
|
+
private extendedConfig: AgentConfig;
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Create a new AgenticFlowAgent instance
|
|
305
|
+
*
|
|
306
|
+
* @param config - Agent configuration
|
|
307
|
+
*/
|
|
308
|
+
constructor(config: AgentConfig) {
|
|
309
|
+
super();
|
|
310
|
+
|
|
311
|
+
// Validate required fields
|
|
312
|
+
if (!config.id || !config.name || !config.type) {
|
|
313
|
+
throw new Error('Agent config must include id, name, and type');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
this.id = config.id;
|
|
317
|
+
this.name = config.name;
|
|
318
|
+
this.type = config.type;
|
|
319
|
+
this.config = config;
|
|
320
|
+
this.extendedConfig = config;
|
|
321
|
+
this.createdAt = new Date();
|
|
322
|
+
this.lastActivity = new Date();
|
|
323
|
+
|
|
324
|
+
// Initialize metrics
|
|
325
|
+
this.metrics = {
|
|
326
|
+
tasksCompleted: 0,
|
|
327
|
+
tasksFailed: 0,
|
|
328
|
+
avgTaskDuration: 0,
|
|
329
|
+
errorCount: 0,
|
|
330
|
+
uptime: 0,
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// Initialize health
|
|
334
|
+
this.health = {
|
|
335
|
+
status: 'healthy',
|
|
336
|
+
lastCheck: new Date(),
|
|
337
|
+
issues: [],
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
this.emit('created', { agentId: this.id, type: this.type });
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Set @sparkleideas/agentic-flow Agent reference for delegation
|
|
345
|
+
*
|
|
346
|
+
* This implements ADR-001: Adopt @sparkleideas/agentic-flow as Core Foundation
|
|
347
|
+
* When a reference is provided, task execution and other operations
|
|
348
|
+
* delegate to @sparkleideas/agentic-flow's optimized implementations.
|
|
349
|
+
*
|
|
350
|
+
* Benefits:
|
|
351
|
+
* - Flash Attention for faster context processing (2.49x-7.47x speedup)
|
|
352
|
+
* - SONA learning for real-time adaptation (<0.05ms)
|
|
353
|
+
* - AgentDB for faster memory search (150x-12,500x improvement)
|
|
354
|
+
*
|
|
355
|
+
* @param ref - The @sparkleideas/agentic-flow Agent reference
|
|
356
|
+
*/
|
|
357
|
+
setAgenticFlowReference(ref: AgenticFlowAgentReference): void {
|
|
358
|
+
this.agenticFlowRef = ref;
|
|
359
|
+
this.delegationEnabled = this.extendedConfig.enableDelegation !== false;
|
|
360
|
+
|
|
361
|
+
this.emit('delegation-enabled', {
|
|
362
|
+
agentId: this.id,
|
|
363
|
+
target: '@sparkleideas/agentic-flow',
|
|
364
|
+
enabled: this.delegationEnabled,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Check if delegation to @sparkleideas/agentic-flow is enabled
|
|
370
|
+
*/
|
|
371
|
+
isDelegationEnabled(): boolean {
|
|
372
|
+
return this.delegationEnabled && this.agenticFlowRef !== null;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Get the @sparkleideas/agentic-flow reference (if available)
|
|
377
|
+
*/
|
|
378
|
+
getAgenticFlowReference(): AgenticFlowAgentReference | null {
|
|
379
|
+
return this.agenticFlowRef;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Initialize the agent
|
|
384
|
+
*
|
|
385
|
+
* ADR-001: When @sparkleideas/agentic-flow is available, delegates initialization
|
|
386
|
+
* to @sparkleideas/agentic-flow's Agent.initialize() for optimized setup.
|
|
387
|
+
*/
|
|
388
|
+
async initialize(): Promise<void> {
|
|
389
|
+
if (this.initialized) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
this.emit('initializing', { agentId: this.id });
|
|
394
|
+
|
|
395
|
+
try {
|
|
396
|
+
// ADR-001: Delegate to @sparkleideas/agentic-flow when available
|
|
397
|
+
if (this.isDelegationEnabled() && this.agenticFlowRef?.initialize) {
|
|
398
|
+
await this.agenticFlowRef.initialize();
|
|
399
|
+
this.emit('delegation-success', {
|
|
400
|
+
method: 'initialize',
|
|
401
|
+
agentId: this.id,
|
|
402
|
+
});
|
|
403
|
+
} else {
|
|
404
|
+
// Local initialization
|
|
405
|
+
await this.localInitialize();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
this.status = 'idle';
|
|
409
|
+
this.initialized = true;
|
|
410
|
+
this.lastActivity = new Date();
|
|
411
|
+
|
|
412
|
+
this.emit('initialized', { agentId: this.id, status: this.status });
|
|
413
|
+
} catch (error) {
|
|
414
|
+
this.status = 'error';
|
|
415
|
+
this.health!.status = 'unhealthy';
|
|
416
|
+
this.health!.issues!.push(`Initialization failed: ${(error as Error).message}`);
|
|
417
|
+
|
|
418
|
+
this.emit('initialization-failed', {
|
|
419
|
+
agentId: this.id,
|
|
420
|
+
error: error as Error,
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
throw error;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Shutdown the agent gracefully
|
|
429
|
+
*
|
|
430
|
+
* ADR-001: When @sparkleideas/agentic-flow is available, delegates shutdown
|
|
431
|
+
* to @sparkleideas/agentic-flow's Agent.shutdown() for clean termination.
|
|
432
|
+
*/
|
|
433
|
+
async shutdown(): Promise<void> {
|
|
434
|
+
this.emit('shutting-down', { agentId: this.id });
|
|
435
|
+
|
|
436
|
+
try {
|
|
437
|
+
// Cancel current task if any
|
|
438
|
+
if (this.currentTask) {
|
|
439
|
+
this.emit('task-cancelled', {
|
|
440
|
+
agentId: this.id,
|
|
441
|
+
taskId: this.currentTask.id,
|
|
442
|
+
});
|
|
443
|
+
this.currentTask = null;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// ADR-001: Delegate to @sparkleideas/agentic-flow when available
|
|
447
|
+
if (this.isDelegationEnabled() && this.agenticFlowRef?.shutdown) {
|
|
448
|
+
await this.agenticFlowRef.shutdown();
|
|
449
|
+
this.emit('delegation-success', {
|
|
450
|
+
method: 'shutdown',
|
|
451
|
+
agentId: this.id,
|
|
452
|
+
});
|
|
453
|
+
} else {
|
|
454
|
+
// Local shutdown
|
|
455
|
+
await this.localShutdown();
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
this.status = 'terminated';
|
|
459
|
+
this.initialized = false;
|
|
460
|
+
this.currentTaskCount = 0;
|
|
461
|
+
|
|
462
|
+
this.emit('shutdown', { agentId: this.id });
|
|
463
|
+
} catch (error) {
|
|
464
|
+
this.emit('shutdown-error', {
|
|
465
|
+
agentId: this.id,
|
|
466
|
+
error: error as Error,
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
throw error;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Execute a task
|
|
475
|
+
*
|
|
476
|
+
* ADR-001: When @sparkleideas/agentic-flow is available, delegates task execution
|
|
477
|
+
* to @sparkleideas/agentic-flow's Agent.execute() which leverages:
|
|
478
|
+
* - Flash Attention for 2.49x-7.47x faster processing
|
|
479
|
+
* - SONA learning for real-time adaptation
|
|
480
|
+
* - AgentDB for 150x-12,500x faster memory retrieval
|
|
481
|
+
*
|
|
482
|
+
* @param task - Task to execute
|
|
483
|
+
* @returns Task result with output or error
|
|
484
|
+
*/
|
|
485
|
+
async executeTask(task: Task): Promise<TaskResult> {
|
|
486
|
+
this.ensureInitialized();
|
|
487
|
+
|
|
488
|
+
// Validate agent is available
|
|
489
|
+
if (this.status === 'terminated' || this.status === 'error') {
|
|
490
|
+
throw new Error(`Agent ${this.id} is not available (status: ${this.status})`);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Check concurrent task limit
|
|
494
|
+
if (this.currentTaskCount >= this.config.maxConcurrentTasks) {
|
|
495
|
+
throw new Error(`Agent ${this.id} has reached max concurrent tasks`);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
this.currentTask = task;
|
|
499
|
+
this.currentTaskCount++;
|
|
500
|
+
this.status = 'busy';
|
|
501
|
+
this.taskStartTime = Date.now();
|
|
502
|
+
this.lastActivity = new Date();
|
|
503
|
+
|
|
504
|
+
this.emit('task-started', {
|
|
505
|
+
agentId: this.id,
|
|
506
|
+
taskId: task.id,
|
|
507
|
+
taskType: task.type,
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
try {
|
|
511
|
+
let output: unknown;
|
|
512
|
+
|
|
513
|
+
// ADR-001: Delegate to @sparkleideas/agentic-flow when available for optimized execution
|
|
514
|
+
if (this.isDelegationEnabled() && this.agenticFlowRef?.execute) {
|
|
515
|
+
output = await this.agenticFlowRef.execute(task);
|
|
516
|
+
|
|
517
|
+
this.emit('delegation-success', {
|
|
518
|
+
method: 'executeTask',
|
|
519
|
+
agentId: this.id,
|
|
520
|
+
taskId: task.id,
|
|
521
|
+
});
|
|
522
|
+
} else {
|
|
523
|
+
// Local execution (fallback or when @sparkleideas/agentic-flow not available)
|
|
524
|
+
output = await this.localExecuteTask(task);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const duration = Date.now() - this.taskStartTime;
|
|
528
|
+
|
|
529
|
+
// Update metrics
|
|
530
|
+
this.metrics!.tasksCompleted++;
|
|
531
|
+
this.totalTaskDuration += duration;
|
|
532
|
+
this.metrics!.avgTaskDuration =
|
|
533
|
+
this.totalTaskDuration / this.metrics!.tasksCompleted;
|
|
534
|
+
|
|
535
|
+
const result: TaskResult = {
|
|
536
|
+
taskId: task.id,
|
|
537
|
+
success: true,
|
|
538
|
+
output,
|
|
539
|
+
duration,
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
this.emit('task-completed', {
|
|
543
|
+
agentId: this.id,
|
|
544
|
+
taskId: task.id,
|
|
545
|
+
duration,
|
|
546
|
+
success: true,
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
return result;
|
|
550
|
+
} catch (error) {
|
|
551
|
+
const duration = Date.now() - this.taskStartTime;
|
|
552
|
+
|
|
553
|
+
// Update metrics
|
|
554
|
+
this.metrics!.tasksFailed++;
|
|
555
|
+
this.metrics!.errorCount++;
|
|
556
|
+
|
|
557
|
+
const result: TaskResult = {
|
|
558
|
+
taskId: task.id,
|
|
559
|
+
success: false,
|
|
560
|
+
error: error as Error,
|
|
561
|
+
duration,
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
this.emit('task-failed', {
|
|
565
|
+
agentId: this.id,
|
|
566
|
+
taskId: task.id,
|
|
567
|
+
error: error as Error,
|
|
568
|
+
duration,
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
return result;
|
|
572
|
+
} finally {
|
|
573
|
+
this.currentTask = null;
|
|
574
|
+
this.currentTaskCount--;
|
|
575
|
+
this.status = this.currentTaskCount > 0 ? 'busy' : 'idle';
|
|
576
|
+
this.lastActivity = new Date();
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Send a message to another agent
|
|
582
|
+
*
|
|
583
|
+
* ADR-001: When @sparkleideas/agentic-flow is available, delegates to @sparkleideas/agentic-flow's
|
|
584
|
+
* message routing which uses optimized communication channels.
|
|
585
|
+
*
|
|
586
|
+
* @param to - Target agent ID
|
|
587
|
+
* @param message - Message to send
|
|
588
|
+
*/
|
|
589
|
+
async sendMessage(to: string, message: Message): Promise<void> {
|
|
590
|
+
this.ensureInitialized();
|
|
591
|
+
|
|
592
|
+
this.emit('message-sending', {
|
|
593
|
+
from: this.id,
|
|
594
|
+
to,
|
|
595
|
+
messageId: message.id,
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
try {
|
|
599
|
+
// ADR-001: Delegate to @sparkleideas/agentic-flow when available
|
|
600
|
+
if (this.isDelegationEnabled() && this.agenticFlowRef?.sendMessage) {
|
|
601
|
+
await this.agenticFlowRef.sendMessage(to, message);
|
|
602
|
+
|
|
603
|
+
this.emit('delegation-success', {
|
|
604
|
+
method: 'sendMessage',
|
|
605
|
+
agentId: this.id,
|
|
606
|
+
to,
|
|
607
|
+
});
|
|
608
|
+
} else {
|
|
609
|
+
// Local message sending (emit event for local routing)
|
|
610
|
+
this.emit('message-send', { from: this.id, to, message });
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
this.emit('message-sent', {
|
|
614
|
+
from: this.id,
|
|
615
|
+
to,
|
|
616
|
+
messageId: message.id,
|
|
617
|
+
});
|
|
618
|
+
} catch (error) {
|
|
619
|
+
this.emit('message-send-failed', {
|
|
620
|
+
from: this.id,
|
|
621
|
+
to,
|
|
622
|
+
messageId: message.id,
|
|
623
|
+
error: error as Error,
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
throw error;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Broadcast a message to all agents
|
|
632
|
+
*
|
|
633
|
+
* @param message - Message to broadcast
|
|
634
|
+
*/
|
|
635
|
+
async broadcastMessage(message: Message): Promise<void> {
|
|
636
|
+
this.ensureInitialized();
|
|
637
|
+
|
|
638
|
+
this.emit('message-broadcasting', {
|
|
639
|
+
from: this.id,
|
|
640
|
+
messageId: message.id,
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
// Emit broadcast event for local routing
|
|
644
|
+
this.emit('message-broadcast', { from: this.id, message });
|
|
645
|
+
|
|
646
|
+
this.emit('message-broadcasted', {
|
|
647
|
+
from: this.id,
|
|
648
|
+
messageId: message.id,
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Get current agent status
|
|
654
|
+
*/
|
|
655
|
+
getStatus(): AgentStatus {
|
|
656
|
+
return this.status;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Get agent health information
|
|
661
|
+
*
|
|
662
|
+
* ADR-001: When @sparkleideas/agentic-flow is available, delegates to @sparkleideas/agentic-flow's
|
|
663
|
+
* health monitoring which includes advanced metrics.
|
|
664
|
+
*/
|
|
665
|
+
getHealth(): AgentHealth {
|
|
666
|
+
const uptime = Date.now() - this.createdAt.getTime();
|
|
667
|
+
|
|
668
|
+
// Update metrics
|
|
669
|
+
if (this.metrics) {
|
|
670
|
+
this.metrics.uptime = uptime;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
const baseHealth: AgentHealth = {
|
|
674
|
+
status: this.health!.status,
|
|
675
|
+
lastCheck: Date.now(),
|
|
676
|
+
issues: this.health!.issues || [],
|
|
677
|
+
metrics: {
|
|
678
|
+
uptime,
|
|
679
|
+
tasksCompleted: this.metrics!.tasksCompleted,
|
|
680
|
+
tasksFailed: this.metrics!.tasksFailed,
|
|
681
|
+
avgLatency: this.metrics!.avgTaskDuration,
|
|
682
|
+
memoryUsageMb: this.estimateMemoryUsage(),
|
|
683
|
+
cpuPercent: 0, // Would need OS-level metrics
|
|
684
|
+
},
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
// Update health status based on metrics
|
|
688
|
+
const errorRate =
|
|
689
|
+
this.metrics!.tasksCompleted > 0
|
|
690
|
+
? this.metrics!.tasksFailed / (this.metrics!.tasksCompleted + this.metrics!.tasksFailed)
|
|
691
|
+
: 0;
|
|
692
|
+
|
|
693
|
+
if (errorRate > 0.5) {
|
|
694
|
+
this.health!.status = 'unhealthy';
|
|
695
|
+
baseHealth.status = 'unhealthy';
|
|
696
|
+
} else if (errorRate > 0.2) {
|
|
697
|
+
this.health!.status = 'degraded';
|
|
698
|
+
baseHealth.status = 'degraded';
|
|
699
|
+
} else {
|
|
700
|
+
this.health!.status = 'healthy';
|
|
701
|
+
baseHealth.status = 'healthy';
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
this.health!.lastCheck = new Date();
|
|
705
|
+
|
|
706
|
+
return baseHealth;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// ===== Private Methods =====
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Local initialization implementation (fallback)
|
|
713
|
+
*/
|
|
714
|
+
private async localInitialize(): Promise<void> {
|
|
715
|
+
// Initialize session if needed
|
|
716
|
+
if (!this.sessionId) {
|
|
717
|
+
this.sessionId = this.generateId('session');
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// Initialize memory bank if needed
|
|
721
|
+
if (!this.memoryBankId) {
|
|
722
|
+
this.memoryBankId = this.generateId('memory');
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Additional local initialization can be added here
|
|
726
|
+
await this.delay(10); // Allow async initialization to complete
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Local shutdown implementation (fallback)
|
|
731
|
+
*/
|
|
732
|
+
private async localShutdown(): Promise<void> {
|
|
733
|
+
// Clean up resources
|
|
734
|
+
this.currentTask = null;
|
|
735
|
+
this.currentTaskCount = 0;
|
|
736
|
+
|
|
737
|
+
// Additional local cleanup can be added here
|
|
738
|
+
await this.delay(10); // Allow async cleanup to complete
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Local task execution implementation (fallback)
|
|
743
|
+
* Override this method in subclasses for specific agent behavior
|
|
744
|
+
*/
|
|
745
|
+
protected async localExecuteTask(task: Task): Promise<unknown> {
|
|
746
|
+
// Minimal processing delay for timing metrics
|
|
747
|
+
await this.delay(1);
|
|
748
|
+
|
|
749
|
+
// This is a basic implementation that should be overridden by subclasses
|
|
750
|
+
// For now, just return the task input as output
|
|
751
|
+
return {
|
|
752
|
+
message: `Task ${task.id} processed by agent ${this.id}`,
|
|
753
|
+
input: task.input,
|
|
754
|
+
timestamp: Date.now(),
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Ensure agent is initialized before operations
|
|
760
|
+
*/
|
|
761
|
+
private ensureInitialized(): void {
|
|
762
|
+
if (!this.initialized) {
|
|
763
|
+
throw new Error(`Agent ${this.id} not initialized. Call initialize() first.`);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Estimate memory usage in MB (rough estimate)
|
|
769
|
+
*/
|
|
770
|
+
private estimateMemoryUsage(): number {
|
|
771
|
+
// Rough estimate: 1MB base + 100KB per task completed
|
|
772
|
+
return 1 + (this.metrics!.tasksCompleted * 0.1);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Generate a unique ID with prefix
|
|
777
|
+
*/
|
|
778
|
+
private generateId(prefix: string): string {
|
|
779
|
+
return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Utility delay function
|
|
784
|
+
*/
|
|
785
|
+
private delay(ms: number): Promise<void> {
|
|
786
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Create and initialize an AgenticFlowAgent
|
|
792
|
+
*
|
|
793
|
+
* @param config - Agent configuration
|
|
794
|
+
* @returns Initialized agent instance
|
|
795
|
+
*/
|
|
796
|
+
export async function createAgenticFlowAgent(
|
|
797
|
+
config: AgentConfig
|
|
798
|
+
): Promise<AgenticFlowAgent> {
|
|
799
|
+
const agent = new AgenticFlowAgent(config);
|
|
800
|
+
await agent.initialize();
|
|
801
|
+
return agent;
|
|
802
|
+
}
|