@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,651 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentAdapter - Bridge between Claude Flow and @sparkleideas/agentic-flow Agents
|
|
3
|
+
*
|
|
4
|
+
* Provides bidirectional conversion and delegation patterns between:
|
|
5
|
+
* - Claude Flow v3 DDD agent architecture
|
|
6
|
+
* - @sparkleideas/agentic-flow's optimized agent implementations
|
|
7
|
+
*
|
|
8
|
+
* This implements ADR-001: Adopt @sparkleideas/agentic-flow as Core Foundation
|
|
9
|
+
* by providing clean conversion and delegation patterns.
|
|
10
|
+
*
|
|
11
|
+
* Pattern follows existing adapters:
|
|
12
|
+
* - SONAAdapter: Adapts SONA learning capabilities
|
|
13
|
+
* - AttentionCoordinator: Adapts Flash Attention mechanisms
|
|
14
|
+
* - AgentAdapter: Adapts agent lifecycle and execution
|
|
15
|
+
*
|
|
16
|
+
* @module v3/integration/agent-adapter
|
|
17
|
+
* @version 3.0.0-alpha.1
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { EventEmitter } from 'events';
|
|
21
|
+
import {
|
|
22
|
+
AgenticFlowAgent,
|
|
23
|
+
AgentConfig,
|
|
24
|
+
Task,
|
|
25
|
+
TaskResult,
|
|
26
|
+
Message,
|
|
27
|
+
IAgent,
|
|
28
|
+
IAgentConfig,
|
|
29
|
+
AgentStatus,
|
|
30
|
+
AgentType,
|
|
31
|
+
} from './agentic-flow-agent.js';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Interface for @sparkleideas/agentic-flow Agent (external package)
|
|
35
|
+
* This represents the expected API from @sparkleideas/agentic-flow's Agent class
|
|
36
|
+
*/
|
|
37
|
+
interface AgenticFlowAgent_External {
|
|
38
|
+
id: string;
|
|
39
|
+
type: string;
|
|
40
|
+
name: string;
|
|
41
|
+
status: string;
|
|
42
|
+
config: Record<string, unknown>;
|
|
43
|
+
|
|
44
|
+
initialize?(): Promise<void>;
|
|
45
|
+
shutdown?(): Promise<void>;
|
|
46
|
+
execute?(task: unknown): Promise<unknown>;
|
|
47
|
+
sendMessage?(to: string, message: unknown): Promise<void>;
|
|
48
|
+
receiveMessage?(message: unknown): Promise<void>;
|
|
49
|
+
getHealth?(): Promise<unknown>;
|
|
50
|
+
getMetrics?(): Promise<{
|
|
51
|
+
tasksCompleted: number;
|
|
52
|
+
tasksFailed: number;
|
|
53
|
+
avgLatency: number;
|
|
54
|
+
uptime: number;
|
|
55
|
+
}>;
|
|
56
|
+
getStatus?(): string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Adapter configuration
|
|
61
|
+
*/
|
|
62
|
+
export interface AgentAdapterConfig {
|
|
63
|
+
/** Enable bidirectional sync with @sparkleideas/agentic-flow */
|
|
64
|
+
enableSync: boolean;
|
|
65
|
+
/** Auto-convert agent formats */
|
|
66
|
+
autoConvert: boolean;
|
|
67
|
+
/** Fallback to local on delegation failure */
|
|
68
|
+
fallbackOnError: boolean;
|
|
69
|
+
/** Debug mode */
|
|
70
|
+
debug: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Agent conversion result
|
|
75
|
+
*/
|
|
76
|
+
export interface AgentConversionResult {
|
|
77
|
+
/** Converted agent */
|
|
78
|
+
agent: AgenticFlowAgent;
|
|
79
|
+
/** Conversion success */
|
|
80
|
+
success: boolean;
|
|
81
|
+
/** Conversion warnings */
|
|
82
|
+
warnings: string[];
|
|
83
|
+
/** Fields that couldn't be mapped */
|
|
84
|
+
unmappedFields: string[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* AgentAdapter - Bridges Claude Flow and @sparkleideas/agentic-flow agents
|
|
89
|
+
*
|
|
90
|
+
* This adapter provides:
|
|
91
|
+
* 1. Format conversion between agent representations
|
|
92
|
+
* 2. Delegation management for optimized operations
|
|
93
|
+
* 3. Bidirectional synchronization of agent state
|
|
94
|
+
* 4. Fallback handling when @sparkleideas/agentic-flow is unavailable
|
|
95
|
+
*
|
|
96
|
+
* Usage:
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const adapter = new AgentAdapter({
|
|
99
|
+
* enableSync: true,
|
|
100
|
+
* autoConvert: true,
|
|
101
|
+
* fallbackOnError: true,
|
|
102
|
+
* });
|
|
103
|
+
*
|
|
104
|
+
* await adapter.initialize();
|
|
105
|
+
*
|
|
106
|
+
* // Convert @sparkleideas/agentic-flow agent to Claude Flow agent
|
|
107
|
+
* const { agent, success } = adapter.fromAgenticFlow(agenticFlowAgent);
|
|
108
|
+
*
|
|
109
|
+
* // Create Claude Flow agent with @sparkleideas/agentic-flow delegation
|
|
110
|
+
* const delegatedAgent = await adapter.createWithDelegation({
|
|
111
|
+
* id: 'agent-1',
|
|
112
|
+
* name: 'Coder',
|
|
113
|
+
* type: 'coder',
|
|
114
|
+
* capabilities: ['code-generation'],
|
|
115
|
+
* maxConcurrentTasks: 3,
|
|
116
|
+
* priority: 5,
|
|
117
|
+
* });
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export class AgentAdapter extends EventEmitter {
|
|
121
|
+
private config: AgentAdapterConfig;
|
|
122
|
+
private initialized: boolean = false;
|
|
123
|
+
private agentMap: Map<string, AgenticFlowAgent> = new Map();
|
|
124
|
+
private delegationMap: Map<string, AgenticFlowAgent_External> = new Map();
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Reference to @sparkleideas/agentic-flow core for accessing Agent factory
|
|
128
|
+
*/
|
|
129
|
+
private agenticFlowCore: any = null;
|
|
130
|
+
|
|
131
|
+
constructor(config: Partial<AgentAdapterConfig> = {}) {
|
|
132
|
+
super();
|
|
133
|
+
|
|
134
|
+
this.config = {
|
|
135
|
+
enableSync: config.enableSync ?? true,
|
|
136
|
+
autoConvert: config.autoConvert ?? true,
|
|
137
|
+
fallbackOnError: config.fallbackOnError ?? true,
|
|
138
|
+
debug: config.debug ?? false,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Initialize the adapter
|
|
144
|
+
*/
|
|
145
|
+
async initialize(): Promise<void> {
|
|
146
|
+
if (this.initialized) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
this.emit('initializing');
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
// Attempt to load @sparkleideas/agentic-flow for delegation
|
|
154
|
+
await this.connectToAgenticFlow();
|
|
155
|
+
|
|
156
|
+
this.initialized = true;
|
|
157
|
+
this.emit('initialized', {
|
|
158
|
+
agenticFlowAvailable: this.agenticFlowCore !== null,
|
|
159
|
+
});
|
|
160
|
+
} catch (error) {
|
|
161
|
+
this.emit('initialization-failed', { error });
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Shutdown the adapter
|
|
168
|
+
*/
|
|
169
|
+
async shutdown(): Promise<void> {
|
|
170
|
+
// Shutdown all managed agents
|
|
171
|
+
const shutdownPromises: Promise<void>[] = [];
|
|
172
|
+
const agents = this.getAllAgents();
|
|
173
|
+
|
|
174
|
+
for (const agent of agents) {
|
|
175
|
+
shutdownPromises.push(agent.shutdown());
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
await Promise.allSettled(shutdownPromises);
|
|
179
|
+
|
|
180
|
+
this.agentMap.clear();
|
|
181
|
+
this.delegationMap.clear();
|
|
182
|
+
this.initialized = false;
|
|
183
|
+
|
|
184
|
+
this.emit('shutdown');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Convert @sparkleideas/agentic-flow agent to Claude Flow AgenticFlowAgent
|
|
189
|
+
*
|
|
190
|
+
* This method creates a Claude Flow agent wrapper around an existing
|
|
191
|
+
* @sparkleideas/agentic-flow agent instance, enabling delegation and integration.
|
|
192
|
+
*
|
|
193
|
+
* @param agenticFlowAgent - @sparkleideas/agentic-flow agent instance
|
|
194
|
+
* @returns Conversion result with wrapped agent
|
|
195
|
+
*/
|
|
196
|
+
fromAgenticFlow(
|
|
197
|
+
agenticFlowAgent: AgenticFlowAgent_External
|
|
198
|
+
): AgentConversionResult {
|
|
199
|
+
const warnings: string[] = [];
|
|
200
|
+
const unmappedFields: string[] = [];
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
// Map @sparkleideas/agentic-flow config to Claude Flow config
|
|
204
|
+
const config: AgentConfig = {
|
|
205
|
+
id: agenticFlowAgent.id,
|
|
206
|
+
name: agenticFlowAgent.name,
|
|
207
|
+
type: this.mapAgentType(agenticFlowAgent.type, warnings),
|
|
208
|
+
capabilities: this.extractCapabilities(agenticFlowAgent.config, warnings),
|
|
209
|
+
maxConcurrentTasks: this.extractMaxTasks(agenticFlowAgent.config),
|
|
210
|
+
priority: this.extractPriority(agenticFlowAgent.config),
|
|
211
|
+
enableDelegation: true,
|
|
212
|
+
agenticFlowConfig: agenticFlowAgent.config,
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// Create Claude Flow agent
|
|
216
|
+
const agent = new AgenticFlowAgent(config);
|
|
217
|
+
|
|
218
|
+
// Set delegation reference
|
|
219
|
+
agent.setAgenticFlowReference({
|
|
220
|
+
id: agenticFlowAgent.id,
|
|
221
|
+
type: agenticFlowAgent.type,
|
|
222
|
+
status: agenticFlowAgent.status,
|
|
223
|
+
initialize: agenticFlowAgent.initialize?.bind(agenticFlowAgent),
|
|
224
|
+
shutdown: agenticFlowAgent.shutdown?.bind(agenticFlowAgent),
|
|
225
|
+
execute: agenticFlowAgent.execute?.bind(agenticFlowAgent),
|
|
226
|
+
sendMessage: agenticFlowAgent.sendMessage?.bind(agenticFlowAgent),
|
|
227
|
+
getHealth: agenticFlowAgent.getHealth?.bind(agenticFlowAgent),
|
|
228
|
+
getMetrics: agenticFlowAgent.getMetrics?.bind(agenticFlowAgent),
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Store mapping
|
|
232
|
+
this.agentMap.set(agent.id, agent);
|
|
233
|
+
this.delegationMap.set(agent.id, agenticFlowAgent);
|
|
234
|
+
|
|
235
|
+
// Sync status if enabled
|
|
236
|
+
if (this.config.enableSync) {
|
|
237
|
+
this.syncStatus(agent, agenticFlowAgent);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
this.emit('agent-converted', {
|
|
241
|
+
agentId: agent.id,
|
|
242
|
+
direction: 'from-agentic-flow',
|
|
243
|
+
warnings,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
agent,
|
|
248
|
+
success: true,
|
|
249
|
+
warnings,
|
|
250
|
+
unmappedFields,
|
|
251
|
+
};
|
|
252
|
+
} catch (error) {
|
|
253
|
+
warnings.push(`Conversion error: ${(error as Error).message}`);
|
|
254
|
+
|
|
255
|
+
// Create fallback agent if enabled
|
|
256
|
+
if (this.config.fallbackOnError) {
|
|
257
|
+
const fallbackAgent = new AgenticFlowAgent({
|
|
258
|
+
id: agenticFlowAgent.id,
|
|
259
|
+
name: agenticFlowAgent.name,
|
|
260
|
+
type: 'custom',
|
|
261
|
+
capabilities: [],
|
|
262
|
+
maxConcurrentTasks: 1,
|
|
263
|
+
priority: 0,
|
|
264
|
+
enableDelegation: false,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
agent: fallbackAgent,
|
|
269
|
+
success: false,
|
|
270
|
+
warnings,
|
|
271
|
+
unmappedFields,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Convert Claude Flow AgenticFlowAgent to @sparkleideas/agentic-flow format
|
|
281
|
+
*
|
|
282
|
+
* This exports the agent configuration in a format compatible with
|
|
283
|
+
* @sparkleideas/agentic-flow's Agent constructor/factory.
|
|
284
|
+
*
|
|
285
|
+
* @param agent - Claude Flow agent instance
|
|
286
|
+
* @returns @sparkleideas/agentic-flow compatible configuration
|
|
287
|
+
*/
|
|
288
|
+
toAgenticFlow(agent: AgenticFlowAgent): Record<string, unknown> {
|
|
289
|
+
return {
|
|
290
|
+
id: agent.id,
|
|
291
|
+
name: agent.name,
|
|
292
|
+
type: agent.type,
|
|
293
|
+
status: agent.status,
|
|
294
|
+
config: {
|
|
295
|
+
capabilities: agent.config.capabilities,
|
|
296
|
+
maxConcurrentTasks: agent.config.maxConcurrentTasks,
|
|
297
|
+
priority: agent.config.priority,
|
|
298
|
+
timeout: agent.config.timeout,
|
|
299
|
+
retryPolicy: agent.config.retryPolicy,
|
|
300
|
+
resources: agent.config.resources,
|
|
301
|
+
metadata: agent.config.metadata,
|
|
302
|
+
},
|
|
303
|
+
sessionId: agent.sessionId,
|
|
304
|
+
terminalId: agent.terminalId,
|
|
305
|
+
memoryBankId: agent.memoryBankId,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Create a Claude Flow agent with @sparkleideas/agentic-flow delegation
|
|
311
|
+
*
|
|
312
|
+
* This is the primary method for creating agents in v3 with
|
|
313
|
+
* automatic delegation to @sparkleideas/agentic-flow when available.
|
|
314
|
+
*
|
|
315
|
+
* ADR-001: Eliminates duplicate code by delegating to @sparkleideas/agentic-flow
|
|
316
|
+
* for core agent operations when the package is available.
|
|
317
|
+
*
|
|
318
|
+
* @param config - Agent configuration
|
|
319
|
+
* @returns Initialized agent with delegation enabled
|
|
320
|
+
*/
|
|
321
|
+
async createWithDelegation(config: AgentConfig): Promise<AgenticFlowAgent> {
|
|
322
|
+
this.ensureInitialized();
|
|
323
|
+
|
|
324
|
+
const agent = new AgenticFlowAgent({
|
|
325
|
+
...config,
|
|
326
|
+
enableDelegation: true,
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// If @sparkleideas/agentic-flow is available, create delegation reference
|
|
330
|
+
if (this.agenticFlowCore && this.agenticFlowCore.createAgent) {
|
|
331
|
+
try {
|
|
332
|
+
const agenticFlowAgent = await this.agenticFlowCore.createAgent({
|
|
333
|
+
id: config.id,
|
|
334
|
+
name: config.name,
|
|
335
|
+
type: config.type,
|
|
336
|
+
config: {
|
|
337
|
+
capabilities: config.capabilities,
|
|
338
|
+
maxConcurrentTasks: config.maxConcurrentTasks,
|
|
339
|
+
priority: config.priority,
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// Set delegation reference
|
|
344
|
+
agent.setAgenticFlowReference({
|
|
345
|
+
id: agenticFlowAgent.id,
|
|
346
|
+
type: agenticFlowAgent.type,
|
|
347
|
+
status: agenticFlowAgent.status,
|
|
348
|
+
initialize: agenticFlowAgent.initialize?.bind(agenticFlowAgent),
|
|
349
|
+
shutdown: agenticFlowAgent.shutdown?.bind(agenticFlowAgent),
|
|
350
|
+
execute: agenticFlowAgent.execute?.bind(agenticFlowAgent),
|
|
351
|
+
sendMessage: agenticFlowAgent.sendMessage?.bind(agenticFlowAgent),
|
|
352
|
+
getHealth: agenticFlowAgent.getHealth?.bind(agenticFlowAgent),
|
|
353
|
+
getMetrics: agenticFlowAgent.getMetrics?.bind(agenticFlowAgent),
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
this.delegationMap.set(agent.id, agenticFlowAgent);
|
|
357
|
+
|
|
358
|
+
this.emit('agent-created-with-delegation', {
|
|
359
|
+
agentId: agent.id,
|
|
360
|
+
delegated: true,
|
|
361
|
+
});
|
|
362
|
+
} catch (error) {
|
|
363
|
+
this.emit('delegation-setup-failed', {
|
|
364
|
+
agentId: agent.id,
|
|
365
|
+
error: (error as Error).message,
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Continue with local-only agent if fallback enabled
|
|
369
|
+
if (!this.config.fallbackOnError) {
|
|
370
|
+
throw error;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Initialize the agent
|
|
376
|
+
await agent.initialize();
|
|
377
|
+
|
|
378
|
+
// Store in map
|
|
379
|
+
this.agentMap.set(agent.id, agent);
|
|
380
|
+
|
|
381
|
+
return agent;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Get a managed agent by ID
|
|
386
|
+
*/
|
|
387
|
+
getAgent(agentId: string): AgenticFlowAgent | undefined {
|
|
388
|
+
return this.agentMap.get(agentId);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Get all managed agents
|
|
393
|
+
*/
|
|
394
|
+
getAllAgents(): AgenticFlowAgent[] {
|
|
395
|
+
const agents: AgenticFlowAgent[] = [];
|
|
396
|
+
this.agentMap.forEach((agent) => {
|
|
397
|
+
agents.push(agent);
|
|
398
|
+
});
|
|
399
|
+
return agents;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Check if an agent is delegated to @sparkleideas/agentic-flow
|
|
404
|
+
*/
|
|
405
|
+
isDelegated(agentId: string): boolean {
|
|
406
|
+
return this.delegationMap.has(agentId);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Get delegation reference for an agent
|
|
411
|
+
*/
|
|
412
|
+
getDelegationReference(agentId: string): AgenticFlowAgent_External | undefined {
|
|
413
|
+
return this.delegationMap.get(agentId);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Remove an agent from management
|
|
418
|
+
*/
|
|
419
|
+
async removeAgent(agentId: string): Promise<boolean> {
|
|
420
|
+
const agent = this.agentMap.get(agentId);
|
|
421
|
+
if (!agent) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Shutdown agent
|
|
426
|
+
await agent.shutdown();
|
|
427
|
+
|
|
428
|
+
// Remove from maps
|
|
429
|
+
this.agentMap.delete(agentId);
|
|
430
|
+
this.delegationMap.delete(agentId);
|
|
431
|
+
|
|
432
|
+
this.emit('agent-removed', { agentId });
|
|
433
|
+
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ===== Private Methods =====
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Connect to @sparkleideas/agentic-flow package dynamically
|
|
441
|
+
*/
|
|
442
|
+
private async connectToAgenticFlow(): Promise<void> {
|
|
443
|
+
try {
|
|
444
|
+
// Dynamic import to handle optional dependency
|
|
445
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
446
|
+
const agenticFlowModule: any = await import('@sparkleideas/agentic-flow').catch(() => null);
|
|
447
|
+
|
|
448
|
+
if (agenticFlowModule && typeof agenticFlowModule.createAgenticFlow === 'function') {
|
|
449
|
+
this.agenticFlowCore = await agenticFlowModule.createAgenticFlow({});
|
|
450
|
+
|
|
451
|
+
this.emit('agentic-flow-connected', {
|
|
452
|
+
version: this.agenticFlowCore.version,
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
this.logDebug('Connected to @sparkleideas/agentic-flow', {
|
|
456
|
+
version: this.agenticFlowCore.version,
|
|
457
|
+
});
|
|
458
|
+
} else {
|
|
459
|
+
this.agenticFlowCore = null;
|
|
460
|
+
this.emit('agentic-flow-unavailable', {
|
|
461
|
+
reason: 'package not found or incompatible',
|
|
462
|
+
});
|
|
463
|
+
this.logDebug('@sparkleideas/agentic-flow not available, using local implementations');
|
|
464
|
+
}
|
|
465
|
+
} catch (error) {
|
|
466
|
+
this.agenticFlowCore = null;
|
|
467
|
+
this.emit('agentic-flow-connection-failed', {
|
|
468
|
+
error: (error as Error).message,
|
|
469
|
+
});
|
|
470
|
+
this.logDebug('@sparkleideas/agentic-flow connection failed', error);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Map @sparkleideas/agentic-flow agent type to Claude Flow AgentType
|
|
476
|
+
*/
|
|
477
|
+
private mapAgentType(type: string, warnings: string[]): AgentType | string {
|
|
478
|
+
// Known valid agent types that pass through directly
|
|
479
|
+
const validTypes: AgentType[] = [
|
|
480
|
+
'coder',
|
|
481
|
+
'reviewer',
|
|
482
|
+
'tester',
|
|
483
|
+
'researcher',
|
|
484
|
+
'planner',
|
|
485
|
+
'architect',
|
|
486
|
+
'coordinator',
|
|
487
|
+
'security',
|
|
488
|
+
'performance',
|
|
489
|
+
'custom',
|
|
490
|
+
];
|
|
491
|
+
|
|
492
|
+
const lowercaseType = type.toLowerCase();
|
|
493
|
+
|
|
494
|
+
// If it's already a valid type, pass through
|
|
495
|
+
if (validTypes.includes(lowercaseType as AgentType)) {
|
|
496
|
+
return lowercaseType as AgentType;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Map alternative names to valid types
|
|
500
|
+
const typeMap: Record<string, AgentType> = {
|
|
501
|
+
'code-generator': 'coder',
|
|
502
|
+
'code-reviewer': 'reviewer',
|
|
503
|
+
'research': 'researcher',
|
|
504
|
+
'planning': 'planner',
|
|
505
|
+
'architecture': 'architect',
|
|
506
|
+
'coordination': 'coordinator',
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
const mapped = typeMap[lowercaseType];
|
|
510
|
+
if (mapped) {
|
|
511
|
+
return mapped;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Unknown type - generate warning and use as-is
|
|
515
|
+
warnings.push(`Unknown agent type '${type}', using as-is`);
|
|
516
|
+
return type;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Extract capabilities from @sparkleideas/agentic-flow config
|
|
521
|
+
*/
|
|
522
|
+
private extractCapabilities(
|
|
523
|
+
config: Record<string, unknown>,
|
|
524
|
+
warnings: string[]
|
|
525
|
+
): string[] {
|
|
526
|
+
if (Array.isArray(config.capabilities)) {
|
|
527
|
+
return config.capabilities as string[];
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (Array.isArray(config.skills)) {
|
|
531
|
+
warnings.push("Using 'skills' as capabilities");
|
|
532
|
+
return config.skills as string[];
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return [];
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Extract max concurrent tasks from config
|
|
540
|
+
*/
|
|
541
|
+
private extractMaxTasks(config: Record<string, unknown>): number {
|
|
542
|
+
if (typeof config.maxConcurrentTasks === 'number') {
|
|
543
|
+
return config.maxConcurrentTasks;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (typeof config.maxTasks === 'number') {
|
|
547
|
+
return config.maxTasks;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return 3; // Default
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Extract priority from config
|
|
555
|
+
*/
|
|
556
|
+
private extractPriority(config: Record<string, unknown>): number {
|
|
557
|
+
if (typeof config.priority === 'number') {
|
|
558
|
+
return config.priority;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return 5; // Default
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Sync status between Claude Flow and @sparkleideas/agentic-flow agents
|
|
566
|
+
*/
|
|
567
|
+
private syncStatus(
|
|
568
|
+
agent: AgenticFlowAgent,
|
|
569
|
+
agenticFlowAgent: AgenticFlowAgent_External
|
|
570
|
+
): void {
|
|
571
|
+
// Map @sparkleideas/agentic-flow status to Claude Flow status
|
|
572
|
+
const statusMap: Record<string, AgentStatus> = {
|
|
573
|
+
'initializing': 'spawning',
|
|
574
|
+
'ready': 'idle',
|
|
575
|
+
'active': 'active',
|
|
576
|
+
'working': 'busy',
|
|
577
|
+
'idle': 'idle',
|
|
578
|
+
'busy': 'busy',
|
|
579
|
+
'error': 'error',
|
|
580
|
+
'stopped': 'terminated',
|
|
581
|
+
'terminated': 'terminated',
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
const mappedStatus = statusMap[agenticFlowAgent.status.toLowerCase()];
|
|
585
|
+
if (mappedStatus && mappedStatus !== agent.status) {
|
|
586
|
+
agent.status = mappedStatus;
|
|
587
|
+
this.emit('status-synced', {
|
|
588
|
+
agentId: agent.id,
|
|
589
|
+
from: agenticFlowAgent.status,
|
|
590
|
+
to: mappedStatus,
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Ensure adapter is initialized
|
|
597
|
+
*/
|
|
598
|
+
private ensureInitialized(): void {
|
|
599
|
+
if (!this.initialized) {
|
|
600
|
+
throw new Error('AgentAdapter not initialized. Call initialize() first.');
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Debug logging
|
|
606
|
+
*/
|
|
607
|
+
private logDebug(message: string, data?: unknown): void {
|
|
608
|
+
if (this.config.debug) {
|
|
609
|
+
console.debug(`[AgentAdapter] ${message}`, data || '');
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Create and initialize an AgentAdapter
|
|
616
|
+
*/
|
|
617
|
+
export async function createAgentAdapter(
|
|
618
|
+
config?: Partial<AgentAdapterConfig>
|
|
619
|
+
): Promise<AgentAdapter> {
|
|
620
|
+
const adapter = new AgentAdapter(config);
|
|
621
|
+
await adapter.initialize();
|
|
622
|
+
return adapter;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Singleton instance for simple usage
|
|
627
|
+
*/
|
|
628
|
+
let defaultAdapter: AgentAdapter | null = null;
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Get the default adapter instance (creates if needed)
|
|
632
|
+
*/
|
|
633
|
+
export async function getDefaultAgentAdapter(
|
|
634
|
+
config?: Partial<AgentAdapterConfig>
|
|
635
|
+
): Promise<AgentAdapter> {
|
|
636
|
+
if (!defaultAdapter) {
|
|
637
|
+
defaultAdapter = new AgentAdapter(config);
|
|
638
|
+
await defaultAdapter.initialize();
|
|
639
|
+
}
|
|
640
|
+
return defaultAdapter;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Reset the default adapter (useful for testing)
|
|
645
|
+
*/
|
|
646
|
+
export async function resetDefaultAgentAdapter(): Promise<void> {
|
|
647
|
+
if (defaultAdapter) {
|
|
648
|
+
await defaultAdapter.shutdown();
|
|
649
|
+
defaultAdapter = null;
|
|
650
|
+
}
|
|
651
|
+
}
|