@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,1112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SwarmAdapter - Bridge between V3 Swarm and @sparkleideas/agentic-flow@alpha Patterns
|
|
3
|
+
*
|
|
4
|
+
* Provides bidirectional conversion and delegation patterns between:
|
|
5
|
+
* - Claude Flow v3 UnifiedSwarmCoordinator
|
|
6
|
+
* - @sparkleideas/agentic-flow's AttentionCoordinator, SwarmTopology, and Expert routing
|
|
7
|
+
*
|
|
8
|
+
* This implements ADR-001: Adopt @sparkleideas/agentic-flow as Core Foundation
|
|
9
|
+
* by aligning V3 swarm patterns with @sparkleideas/agentic-flow's coordination mechanisms.
|
|
10
|
+
*
|
|
11
|
+
* Key Alignments:
|
|
12
|
+
* - Topology: mesh, hierarchical, ring, star (maps V3's centralized -> star)
|
|
13
|
+
* - AgentOutput: { agentId, agentType, embedding, value, confidence }
|
|
14
|
+
* - SpecializedAgent: { id, type, specialization, capabilities, load }
|
|
15
|
+
* - Expert routing via MoE attention for task assignment
|
|
16
|
+
* - GraphRoPE for topology-aware coordination
|
|
17
|
+
*
|
|
18
|
+
* @module v3/integration/swarm-adapter
|
|
19
|
+
* @version 3.0.0-alpha.1
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { EventEmitter } from 'events';
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// @sparkleideas/agentic-flow Pattern Types (Target Interface)
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @sparkleideas/agentic-flow SwarmTopology types
|
|
30
|
+
* V3's 'centralized' maps to 'star', 'hybrid' is represented as 'mesh' with hierarchical overlay
|
|
31
|
+
*/
|
|
32
|
+
export type AgenticFlowTopology = 'mesh' | 'hierarchical' | 'ring' | 'star';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @sparkleideas/agentic-flow Attention mechanism types
|
|
36
|
+
*/
|
|
37
|
+
export type AgenticFlowAttentionMechanism =
|
|
38
|
+
| 'flash' // Flash Attention - fastest, 75% memory reduction
|
|
39
|
+
| 'linear' // Linear attention for long sequences
|
|
40
|
+
| 'hyperbolic' // Hyperbolic attention for hierarchical data
|
|
41
|
+
| 'moe' // Mixture of Experts attention
|
|
42
|
+
| 'multi-head'; // Standard multi-head attention
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @sparkleideas/agentic-flow AgentOutput interface
|
|
46
|
+
* This is the expected output format from agents in @sparkleideas/agentic-flow swarms
|
|
47
|
+
*/
|
|
48
|
+
export interface AgenticFlowAgentOutput {
|
|
49
|
+
/** Agent identifier */
|
|
50
|
+
agentId: string;
|
|
51
|
+
/** Agent type/role */
|
|
52
|
+
agentType: string;
|
|
53
|
+
/** Embedding vector for the agent's output (semantic representation) */
|
|
54
|
+
embedding: number[] | Float32Array;
|
|
55
|
+
/** The actual value/result produced by the agent */
|
|
56
|
+
value: unknown;
|
|
57
|
+
/** Confidence score for this output (0.0 - 1.0) */
|
|
58
|
+
confidence: number;
|
|
59
|
+
/** Optional metadata */
|
|
60
|
+
metadata?: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @sparkleideas/agentic-flow SpecializedAgent interface
|
|
65
|
+
* Represents an expert agent with specific capabilities
|
|
66
|
+
*/
|
|
67
|
+
export interface AgenticFlowSpecializedAgent {
|
|
68
|
+
/** Agent identifier */
|
|
69
|
+
id: string;
|
|
70
|
+
/** Agent type */
|
|
71
|
+
type: string;
|
|
72
|
+
/** Specialization area */
|
|
73
|
+
specialization: string;
|
|
74
|
+
/** List of capabilities */
|
|
75
|
+
capabilities: string[];
|
|
76
|
+
/** Current load (0.0 - 1.0) */
|
|
77
|
+
load: number;
|
|
78
|
+
/** Embedding for expert matching */
|
|
79
|
+
embedding?: number[];
|
|
80
|
+
/** Performance score */
|
|
81
|
+
performanceScore?: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @sparkleideas/agentic-flow Expert routing result
|
|
86
|
+
*/
|
|
87
|
+
export interface AgenticFlowExpertRoute {
|
|
88
|
+
/** Selected expert IDs */
|
|
89
|
+
selectedExperts: AgenticFlowSpecializedAgent[];
|
|
90
|
+
/** Routing scores for each expert */
|
|
91
|
+
scores: Map<string, number>;
|
|
92
|
+
/** Routing mechanism used */
|
|
93
|
+
mechanism: 'moe' | 'similarity' | 'load-balanced';
|
|
94
|
+
/** Routing latency in ms */
|
|
95
|
+
latencyMs: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @sparkleideas/agentic-flow Attention coordination result
|
|
100
|
+
*/
|
|
101
|
+
export interface AgenticFlowAttentionResult {
|
|
102
|
+
/** Consensus output */
|
|
103
|
+
consensus: unknown;
|
|
104
|
+
/** Attention weights for each agent */
|
|
105
|
+
attentionWeights: Map<string, number>;
|
|
106
|
+
/** Top contributing agents */
|
|
107
|
+
topAgents: Array<{ id: string; name: string; weight: number }>;
|
|
108
|
+
/** Coordination mechanism used */
|
|
109
|
+
mechanism: AgenticFlowAttentionMechanism;
|
|
110
|
+
/** Execution time in ms */
|
|
111
|
+
executionTimeMs: number;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* GraphRoPE coordination context
|
|
116
|
+
* Topology-aware positional encoding for better coordination
|
|
117
|
+
*/
|
|
118
|
+
export interface GraphRoPEContext {
|
|
119
|
+
/** Node positions in the topology graph */
|
|
120
|
+
nodePositions: Map<string, number[]>;
|
|
121
|
+
/** Edge weights between nodes */
|
|
122
|
+
edgeWeights: Map<string, Map<string, number>>;
|
|
123
|
+
/** Rotary position encoding dimension */
|
|
124
|
+
ropeDimension: number;
|
|
125
|
+
/** Whether to use relative positions */
|
|
126
|
+
useRelativePositions: boolean;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// V3 Swarm Types (Source Interface from @sparkleideas/swarm)
|
|
131
|
+
// ============================================================================
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* V3 Topology types (from @sparkleideas/swarm)
|
|
135
|
+
*/
|
|
136
|
+
export type V3TopologyType = 'mesh' | 'hierarchical' | 'centralized' | 'hybrid';
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* V3 Agent Domain types (from @sparkleideas/swarm)
|
|
140
|
+
*/
|
|
141
|
+
export type V3AgentDomain = 'queen' | 'security' | 'core' | 'integration' | 'support';
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* V3 Agent State interface (simplified from @sparkleideas/swarm)
|
|
145
|
+
*/
|
|
146
|
+
export interface V3AgentState {
|
|
147
|
+
id: { id: string; swarmId: string; type: string; instance: number };
|
|
148
|
+
name: string;
|
|
149
|
+
type: string;
|
|
150
|
+
status: string;
|
|
151
|
+
capabilities: {
|
|
152
|
+
codeGeneration: boolean;
|
|
153
|
+
codeReview: boolean;
|
|
154
|
+
testing: boolean;
|
|
155
|
+
documentation: boolean;
|
|
156
|
+
research: boolean;
|
|
157
|
+
analysis: boolean;
|
|
158
|
+
coordination: boolean;
|
|
159
|
+
languages: string[];
|
|
160
|
+
frameworks: string[];
|
|
161
|
+
domains: string[];
|
|
162
|
+
tools: string[];
|
|
163
|
+
maxConcurrentTasks: number;
|
|
164
|
+
reliability: number;
|
|
165
|
+
speed: number;
|
|
166
|
+
quality: number;
|
|
167
|
+
};
|
|
168
|
+
metrics: {
|
|
169
|
+
tasksCompleted: number;
|
|
170
|
+
tasksFailed: number;
|
|
171
|
+
successRate: number;
|
|
172
|
+
averageExecutionTime: number;
|
|
173
|
+
health: number;
|
|
174
|
+
};
|
|
175
|
+
workload: number;
|
|
176
|
+
health: number;
|
|
177
|
+
lastHeartbeat: Date;
|
|
178
|
+
topologyRole?: 'queen' | 'worker' | 'coordinator' | 'peer';
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* V3 Task Definition interface (simplified from @sparkleideas/swarm)
|
|
183
|
+
*/
|
|
184
|
+
export interface V3TaskDefinition {
|
|
185
|
+
id: { id: string; swarmId: string; sequence: number; priority: string };
|
|
186
|
+
type: string;
|
|
187
|
+
name: string;
|
|
188
|
+
description: string;
|
|
189
|
+
priority: string;
|
|
190
|
+
status: string;
|
|
191
|
+
assignedTo?: { id: string };
|
|
192
|
+
metadata: Record<string, unknown>;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// Adapter Configuration
|
|
197
|
+
// ============================================================================
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* SwarmAdapter configuration options
|
|
201
|
+
*/
|
|
202
|
+
export interface SwarmAdapterConfig {
|
|
203
|
+
/** Enable attention-based coordination */
|
|
204
|
+
enableAttentionCoordination: boolean;
|
|
205
|
+
/** Enable MoE expert routing */
|
|
206
|
+
enableMoERouting: boolean;
|
|
207
|
+
/** Enable GraphRoPE topology awareness */
|
|
208
|
+
enableGraphRoPE: boolean;
|
|
209
|
+
/** Default attention mechanism */
|
|
210
|
+
defaultAttentionMechanism: AgenticFlowAttentionMechanism;
|
|
211
|
+
/** Number of experts for MoE routing */
|
|
212
|
+
moeTopK: number;
|
|
213
|
+
/** GraphRoPE dimension */
|
|
214
|
+
ropeDimension: number;
|
|
215
|
+
/** Enable delegation to @sparkleideas/agentic-flow when available */
|
|
216
|
+
enableDelegation: boolean;
|
|
217
|
+
/** Fallback on delegation failure */
|
|
218
|
+
fallbackOnError: boolean;
|
|
219
|
+
/** Debug mode */
|
|
220
|
+
debug: boolean;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Default adapter configuration
|
|
225
|
+
*/
|
|
226
|
+
const DEFAULT_CONFIG: SwarmAdapterConfig = {
|
|
227
|
+
enableAttentionCoordination: true,
|
|
228
|
+
enableMoERouting: true,
|
|
229
|
+
enableGraphRoPE: true,
|
|
230
|
+
defaultAttentionMechanism: 'flash',
|
|
231
|
+
moeTopK: 3,
|
|
232
|
+
ropeDimension: 64,
|
|
233
|
+
enableDelegation: true,
|
|
234
|
+
fallbackOnError: true,
|
|
235
|
+
debug: false,
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// ============================================================================
|
|
239
|
+
// SwarmAdapter Class
|
|
240
|
+
// ============================================================================
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* SwarmAdapter - Bridges V3 Swarm with @sparkleideas/agentic-flow patterns
|
|
244
|
+
*
|
|
245
|
+
* Key Features:
|
|
246
|
+
* - Topology conversion (V3 <-> @sparkleideas/agentic-flow)
|
|
247
|
+
* - Agent output format conversion
|
|
248
|
+
* - Specialized agent wrapping
|
|
249
|
+
* - MoE expert routing integration
|
|
250
|
+
* - Attention-based consensus coordination
|
|
251
|
+
* - GraphRoPE topology-aware positioning
|
|
252
|
+
*
|
|
253
|
+
* Usage:
|
|
254
|
+
* ```typescript
|
|
255
|
+
* import { SwarmAdapter, createSwarmAdapter } from '@sparkleideas/integration';
|
|
256
|
+
*
|
|
257
|
+
* const adapter = await createSwarmAdapter({
|
|
258
|
+
* enableAttentionCoordination: true,
|
|
259
|
+
* enableMoERouting: true,
|
|
260
|
+
* });
|
|
261
|
+
*
|
|
262
|
+
* // Convert V3 agents to @sparkleideas/agentic-flow format
|
|
263
|
+
* const specializedAgents = adapter.toSpecializedAgents(v3Agents);
|
|
264
|
+
*
|
|
265
|
+
* // Route task to experts using MoE
|
|
266
|
+
* const routes = await adapter.routeToExperts(taskEmbedding, specializedAgents);
|
|
267
|
+
*
|
|
268
|
+
* // Coordinate agent outputs with attention
|
|
269
|
+
* const consensus = await adapter.coordinateWithAttention(agentOutputs);
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
export class SwarmAdapter extends EventEmitter {
|
|
273
|
+
private config: SwarmAdapterConfig;
|
|
274
|
+
private initialized: boolean = false;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Reference to @sparkleideas/agentic-flow core for delegation
|
|
278
|
+
*/
|
|
279
|
+
private agenticFlowCore: any = null;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Reference to @sparkleideas/agentic-flow AttentionCoordinator
|
|
283
|
+
*/
|
|
284
|
+
private attentionCoordinator: any = null;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* GraphRoPE context for topology-aware coordination
|
|
288
|
+
*/
|
|
289
|
+
private graphRoPEContext: GraphRoPEContext | null = null;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Cached topology mapping
|
|
293
|
+
*/
|
|
294
|
+
private topologyCache: Map<string, number[]> = new Map();
|
|
295
|
+
|
|
296
|
+
constructor(config: Partial<SwarmAdapterConfig> = {}) {
|
|
297
|
+
super();
|
|
298
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// ==========================================================================
|
|
302
|
+
// Lifecycle
|
|
303
|
+
// ==========================================================================
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Initialize the SwarmAdapter
|
|
307
|
+
*/
|
|
308
|
+
async initialize(): Promise<void> {
|
|
309
|
+
if (this.initialized) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
this.emit('initializing');
|
|
314
|
+
|
|
315
|
+
try {
|
|
316
|
+
// Attempt to connect to @sparkleideas/agentic-flow for delegation
|
|
317
|
+
if (this.config.enableDelegation) {
|
|
318
|
+
await this.connectToAgenticFlow();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Initialize GraphRoPE context if enabled
|
|
322
|
+
if (this.config.enableGraphRoPE) {
|
|
323
|
+
this.graphRoPEContext = {
|
|
324
|
+
nodePositions: new Map(),
|
|
325
|
+
edgeWeights: new Map(),
|
|
326
|
+
ropeDimension: this.config.ropeDimension,
|
|
327
|
+
useRelativePositions: true,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
this.initialized = true;
|
|
332
|
+
this.emit('initialized', {
|
|
333
|
+
agenticFlowAvailable: this.agenticFlowCore !== null,
|
|
334
|
+
attentionAvailable: this.attentionCoordinator !== null,
|
|
335
|
+
});
|
|
336
|
+
} catch (error) {
|
|
337
|
+
this.emit('initialization-failed', { error });
|
|
338
|
+
throw error;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Shutdown the adapter
|
|
344
|
+
*/
|
|
345
|
+
async shutdown(): Promise<void> {
|
|
346
|
+
this.topologyCache.clear();
|
|
347
|
+
this.graphRoPEContext = null;
|
|
348
|
+
this.agenticFlowCore = null;
|
|
349
|
+
this.attentionCoordinator = null;
|
|
350
|
+
this.initialized = false;
|
|
351
|
+
this.emit('shutdown');
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// ==========================================================================
|
|
355
|
+
// Topology Conversion
|
|
356
|
+
// ==========================================================================
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Convert V3 topology type to @sparkleideas/agentic-flow topology
|
|
360
|
+
*
|
|
361
|
+
* Mapping:
|
|
362
|
+
* - mesh -> mesh
|
|
363
|
+
* - hierarchical -> hierarchical
|
|
364
|
+
* - centralized -> star (@sparkleideas/agentic-flow uses 'star' for central coordinator pattern)
|
|
365
|
+
* - hybrid -> mesh (treated as mesh with additional hierarchical overlay)
|
|
366
|
+
*/
|
|
367
|
+
convertTopology(v3Topology: V3TopologyType): AgenticFlowTopology {
|
|
368
|
+
const mapping: Record<V3TopologyType, AgenticFlowTopology> = {
|
|
369
|
+
mesh: 'mesh',
|
|
370
|
+
hierarchical: 'hierarchical',
|
|
371
|
+
centralized: 'star',
|
|
372
|
+
hybrid: 'mesh', // Hybrid is treated as mesh with hierarchical overlay
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
return mapping[v3Topology] || 'mesh';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Convert @sparkleideas/agentic-flow topology to V3 topology type
|
|
380
|
+
*/
|
|
381
|
+
convertTopologyFromAgenticFlow(topology: AgenticFlowTopology): V3TopologyType {
|
|
382
|
+
const mapping: Record<AgenticFlowTopology, V3TopologyType> = {
|
|
383
|
+
mesh: 'mesh',
|
|
384
|
+
hierarchical: 'hierarchical',
|
|
385
|
+
ring: 'mesh', // Ring is treated as mesh in V3
|
|
386
|
+
star: 'centralized',
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
return mapping[topology] || 'mesh';
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ==========================================================================
|
|
393
|
+
// Agent Conversion
|
|
394
|
+
// ==========================================================================
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Convert V3 Agent to @sparkleideas/agentic-flow AgentOutput format
|
|
398
|
+
*
|
|
399
|
+
* Creates the embedding from agent capabilities and produces
|
|
400
|
+
* the standardized AgentOutput interface expected by @sparkleideas/agentic-flow.
|
|
401
|
+
*/
|
|
402
|
+
toAgentOutput(
|
|
403
|
+
agent: V3AgentState,
|
|
404
|
+
value: unknown,
|
|
405
|
+
confidence?: number
|
|
406
|
+
): AgenticFlowAgentOutput {
|
|
407
|
+
// Generate embedding from agent capabilities
|
|
408
|
+
const embedding = this.generateAgentEmbedding(agent);
|
|
409
|
+
|
|
410
|
+
// Calculate confidence from agent metrics if not provided
|
|
411
|
+
const calculatedConfidence = confidence ??
|
|
412
|
+
agent.metrics.successRate * agent.health;
|
|
413
|
+
|
|
414
|
+
return {
|
|
415
|
+
agentId: agent.id.id,
|
|
416
|
+
agentType: agent.type,
|
|
417
|
+
embedding,
|
|
418
|
+
value,
|
|
419
|
+
confidence: Math.min(1.0, Math.max(0.0, calculatedConfidence)),
|
|
420
|
+
metadata: {
|
|
421
|
+
domain: this.inferDomain(agent),
|
|
422
|
+
capabilities: agent.capabilities.domains,
|
|
423
|
+
workload: agent.workload,
|
|
424
|
+
successRate: agent.metrics.successRate,
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Convert V3 Agent to @sparkleideas/agentic-flow SpecializedAgent format
|
|
431
|
+
*
|
|
432
|
+
* Creates an expert representation suitable for MoE routing
|
|
433
|
+
*/
|
|
434
|
+
toSpecializedAgent(agent: V3AgentState): AgenticFlowSpecializedAgent {
|
|
435
|
+
const embedding = this.generateAgentEmbedding(agent);
|
|
436
|
+
|
|
437
|
+
// Determine specialization from capabilities
|
|
438
|
+
const specialization = this.determineSpecialization(agent);
|
|
439
|
+
|
|
440
|
+
// Collect capabilities as strings
|
|
441
|
+
const capabilities = this.collectCapabilities(agent);
|
|
442
|
+
|
|
443
|
+
return {
|
|
444
|
+
id: agent.id.id,
|
|
445
|
+
type: agent.type,
|
|
446
|
+
specialization,
|
|
447
|
+
capabilities,
|
|
448
|
+
load: agent.workload,
|
|
449
|
+
embedding,
|
|
450
|
+
performanceScore: agent.metrics.successRate * agent.health,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Convert multiple V3 agents to SpecializedAgents
|
|
456
|
+
*/
|
|
457
|
+
toSpecializedAgents(agents: V3AgentState[]): AgenticFlowSpecializedAgent[] {
|
|
458
|
+
return agents.map((agent) => this.toSpecializedAgent(agent));
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Convert @sparkleideas/agentic-flow SpecializedAgent back to partial V3 format
|
|
463
|
+
* (for updates/sync)
|
|
464
|
+
*/
|
|
465
|
+
fromSpecializedAgent(
|
|
466
|
+
specializedAgent: AgenticFlowSpecializedAgent
|
|
467
|
+
): Partial<V3AgentState> {
|
|
468
|
+
return {
|
|
469
|
+
id: {
|
|
470
|
+
id: specializedAgent.id,
|
|
471
|
+
swarmId: 'converted',
|
|
472
|
+
type: specializedAgent.type,
|
|
473
|
+
instance: 0,
|
|
474
|
+
},
|
|
475
|
+
name: specializedAgent.id,
|
|
476
|
+
type: specializedAgent.type,
|
|
477
|
+
workload: specializedAgent.load,
|
|
478
|
+
capabilities: {
|
|
479
|
+
codeGeneration: specializedAgent.capabilities.includes('code-generation'),
|
|
480
|
+
codeReview: specializedAgent.capabilities.includes('code-review'),
|
|
481
|
+
testing: specializedAgent.capabilities.includes('testing'),
|
|
482
|
+
documentation: specializedAgent.capabilities.includes('documentation'),
|
|
483
|
+
research: specializedAgent.capabilities.includes('research'),
|
|
484
|
+
analysis: specializedAgent.capabilities.includes('analysis'),
|
|
485
|
+
coordination: specializedAgent.capabilities.includes('coordination'),
|
|
486
|
+
languages: [],
|
|
487
|
+
frameworks: [],
|
|
488
|
+
domains: [specializedAgent.specialization],
|
|
489
|
+
tools: [],
|
|
490
|
+
maxConcurrentTasks: 3,
|
|
491
|
+
reliability: specializedAgent.performanceScore ?? 0.9,
|
|
492
|
+
speed: 1.0,
|
|
493
|
+
quality: specializedAgent.performanceScore ?? 0.9,
|
|
494
|
+
},
|
|
495
|
+
health: specializedAgent.performanceScore ?? 1.0,
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// ==========================================================================
|
|
500
|
+
// MoE Expert Routing
|
|
501
|
+
// ==========================================================================
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Route a task to the best experts using MoE attention
|
|
505
|
+
*
|
|
506
|
+
* Implements @sparkleideas/agentic-flow's expert routing pattern for task assignment.
|
|
507
|
+
* Uses cosine similarity with load balancing for optimal routing.
|
|
508
|
+
*/
|
|
509
|
+
async routeToExperts(
|
|
510
|
+
taskEmbedding: number[],
|
|
511
|
+
experts: AgenticFlowSpecializedAgent[],
|
|
512
|
+
topK?: number
|
|
513
|
+
): Promise<AgenticFlowExpertRoute> {
|
|
514
|
+
this.ensureInitialized();
|
|
515
|
+
const startTime = performance.now();
|
|
516
|
+
const k = topK ?? this.config.moeTopK;
|
|
517
|
+
|
|
518
|
+
// If delegation is available and enabled, use @sparkleideas/agentic-flow's MoE
|
|
519
|
+
if (this.config.enableMoERouting && this.agenticFlowCore?.moe) {
|
|
520
|
+
try {
|
|
521
|
+
const result = await this.agenticFlowCore.moe.route({
|
|
522
|
+
query: taskEmbedding,
|
|
523
|
+
experts: experts.map((e) => ({
|
|
524
|
+
id: e.id,
|
|
525
|
+
embedding: e.embedding,
|
|
526
|
+
load: e.load,
|
|
527
|
+
})),
|
|
528
|
+
topK: k,
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
return {
|
|
532
|
+
selectedExperts: experts.filter((e) =>
|
|
533
|
+
result.selected.includes(e.id)
|
|
534
|
+
),
|
|
535
|
+
scores: new Map(Object.entries(result.scores)),
|
|
536
|
+
mechanism: 'moe',
|
|
537
|
+
latencyMs: performance.now() - startTime,
|
|
538
|
+
};
|
|
539
|
+
} catch (error) {
|
|
540
|
+
this.emit('delegation-failed', {
|
|
541
|
+
method: 'routeToExperts',
|
|
542
|
+
error: (error as Error).message,
|
|
543
|
+
});
|
|
544
|
+
if (!this.config.fallbackOnError) throw error;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Local implementation: similarity + load balancing
|
|
549
|
+
const scores = new Map<string, number>();
|
|
550
|
+
|
|
551
|
+
for (const expert of experts) {
|
|
552
|
+
if (!expert.embedding) {
|
|
553
|
+
scores.set(expert.id, 0);
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Compute cosine similarity
|
|
558
|
+
const similarity = this.cosineSimilarity(taskEmbedding, expert.embedding);
|
|
559
|
+
|
|
560
|
+
// Adjust for load (prefer less loaded experts)
|
|
561
|
+
const loadFactor = 1 - expert.load * 0.3;
|
|
562
|
+
|
|
563
|
+
// Boost by performance score
|
|
564
|
+
const perfFactor = expert.performanceScore ?? 0.9;
|
|
565
|
+
|
|
566
|
+
const finalScore = similarity * loadFactor * perfFactor;
|
|
567
|
+
scores.set(expert.id, finalScore);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Sort by score and select top K
|
|
571
|
+
const sortedExperts = experts
|
|
572
|
+
.filter((e) => scores.get(e.id) !== undefined)
|
|
573
|
+
.sort((a, b) => (scores.get(b.id) ?? 0) - (scores.get(a.id) ?? 0));
|
|
574
|
+
|
|
575
|
+
const selectedExperts = sortedExperts.slice(0, k);
|
|
576
|
+
|
|
577
|
+
return {
|
|
578
|
+
selectedExperts,
|
|
579
|
+
scores,
|
|
580
|
+
mechanism: 'load-balanced',
|
|
581
|
+
latencyMs: performance.now() - startTime,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// ==========================================================================
|
|
586
|
+
// Attention-Based Coordination
|
|
587
|
+
// ==========================================================================
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Coordinate agent outputs using attention mechanisms
|
|
591
|
+
*
|
|
592
|
+
* Implements @sparkleideas/agentic-flow's attention-based consensus pattern
|
|
593
|
+
* for multi-agent coordination.
|
|
594
|
+
*/
|
|
595
|
+
async coordinateWithAttention(
|
|
596
|
+
agentOutputs: AgenticFlowAgentOutput[],
|
|
597
|
+
mechanism?: AgenticFlowAttentionMechanism
|
|
598
|
+
): Promise<AgenticFlowAttentionResult> {
|
|
599
|
+
this.ensureInitialized();
|
|
600
|
+
const startTime = performance.now();
|
|
601
|
+
const useMechanism = mechanism ?? this.config.defaultAttentionMechanism;
|
|
602
|
+
|
|
603
|
+
// If delegation is available, use @sparkleideas/agentic-flow's AttentionCoordinator
|
|
604
|
+
if (
|
|
605
|
+
this.config.enableAttentionCoordination &&
|
|
606
|
+
this.attentionCoordinator
|
|
607
|
+
) {
|
|
608
|
+
try {
|
|
609
|
+
const result = await this.attentionCoordinator.coordinateAgents({
|
|
610
|
+
outputs: agentOutputs.map((o) => o.value),
|
|
611
|
+
embeddings: agentOutputs.map((o) =>
|
|
612
|
+
Array.isArray(o.embedding)
|
|
613
|
+
? o.embedding
|
|
614
|
+
: Array.from(o.embedding)
|
|
615
|
+
),
|
|
616
|
+
mechanism: useMechanism,
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
const attentionWeights = new Map<string, number>();
|
|
620
|
+
for (let i = 0; i < agentOutputs.length; i++) {
|
|
621
|
+
attentionWeights.set(agentOutputs[i].agentId, result.weights[i] ?? 0);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return {
|
|
625
|
+
consensus: result.consensus,
|
|
626
|
+
attentionWeights,
|
|
627
|
+
topAgents: this.extractTopAgents(agentOutputs, attentionWeights),
|
|
628
|
+
mechanism: useMechanism,
|
|
629
|
+
executionTimeMs: performance.now() - startTime,
|
|
630
|
+
};
|
|
631
|
+
} catch (error) {
|
|
632
|
+
this.emit('delegation-failed', {
|
|
633
|
+
method: 'coordinateWithAttention',
|
|
634
|
+
error: (error as Error).message,
|
|
635
|
+
});
|
|
636
|
+
if (!this.config.fallbackOnError) throw error;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Local implementation: weighted consensus based on confidence
|
|
641
|
+
const attentionWeights = new Map<string, number>();
|
|
642
|
+
|
|
643
|
+
// Compute attention weights from embeddings
|
|
644
|
+
const n = agentOutputs.length;
|
|
645
|
+
if (n === 0) {
|
|
646
|
+
return {
|
|
647
|
+
consensus: null,
|
|
648
|
+
attentionWeights,
|
|
649
|
+
topAgents: [],
|
|
650
|
+
mechanism: useMechanism,
|
|
651
|
+
executionTimeMs: performance.now() - startTime,
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// Compute pairwise similarity matrix
|
|
656
|
+
const scores: number[] = [];
|
|
657
|
+
for (let i = 0; i < n; i++) {
|
|
658
|
+
let score = agentOutputs[i].confidence;
|
|
659
|
+
|
|
660
|
+
// Add similarity bonus with other agents (agreement signal)
|
|
661
|
+
for (let j = 0; j < n; j++) {
|
|
662
|
+
if (i !== j) {
|
|
663
|
+
const embI = Array.isArray(agentOutputs[i].embedding)
|
|
664
|
+
? agentOutputs[i].embedding
|
|
665
|
+
: Array.from(agentOutputs[i].embedding);
|
|
666
|
+
const embJ = Array.isArray(agentOutputs[j].embedding)
|
|
667
|
+
? agentOutputs[j].embedding
|
|
668
|
+
: Array.from(agentOutputs[j].embedding);
|
|
669
|
+
score += this.cosineSimilarity(embI as number[], embJ as number[]) * 0.1;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
scores.push(score);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Softmax for attention weights
|
|
677
|
+
const maxScore = Math.max(...scores);
|
|
678
|
+
const expScores = scores.map((s) => Math.exp(s - maxScore));
|
|
679
|
+
const sumExp = expScores.reduce((a, b) => a + b, 0);
|
|
680
|
+
|
|
681
|
+
for (let i = 0; i < n; i++) {
|
|
682
|
+
const weight = expScores[i] / sumExp;
|
|
683
|
+
attentionWeights.set(agentOutputs[i].agentId, weight);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// Select consensus as highest weighted output
|
|
687
|
+
const maxWeightIdx = scores.indexOf(Math.max(...scores));
|
|
688
|
+
const consensus = agentOutputs[maxWeightIdx].value;
|
|
689
|
+
|
|
690
|
+
return {
|
|
691
|
+
consensus,
|
|
692
|
+
attentionWeights,
|
|
693
|
+
topAgents: this.extractTopAgents(agentOutputs, attentionWeights),
|
|
694
|
+
mechanism: useMechanism,
|
|
695
|
+
executionTimeMs: performance.now() - startTime,
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// ==========================================================================
|
|
700
|
+
// GraphRoPE Topology Awareness
|
|
701
|
+
// ==========================================================================
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Update GraphRoPE context with current topology
|
|
705
|
+
*
|
|
706
|
+
* Creates positional encodings based on agent positions
|
|
707
|
+
* in the swarm topology graph.
|
|
708
|
+
*/
|
|
709
|
+
updateGraphRoPEContext(
|
|
710
|
+
agents: V3AgentState[],
|
|
711
|
+
edges: Array<{ from: string; to: string; weight: number }>
|
|
712
|
+
): void {
|
|
713
|
+
if (!this.config.enableGraphRoPE || !this.graphRoPEContext) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
const nodePositions = new Map<string, number[]>();
|
|
718
|
+
const edgeWeights = new Map<string, Map<string, number>>();
|
|
719
|
+
|
|
720
|
+
// Generate positional encoding for each agent
|
|
721
|
+
for (let i = 0; i < agents.length; i++) {
|
|
722
|
+
const agent = agents[i];
|
|
723
|
+
const position = this.generatePositionalEncoding(i, this.config.ropeDimension);
|
|
724
|
+
nodePositions.set(agent.id.id, position);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// Store edge weights
|
|
728
|
+
for (const edge of edges) {
|
|
729
|
+
if (!edgeWeights.has(edge.from)) {
|
|
730
|
+
edgeWeights.set(edge.from, new Map());
|
|
731
|
+
}
|
|
732
|
+
edgeWeights.get(edge.from)!.set(edge.to, edge.weight);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
this.graphRoPEContext.nodePositions = nodePositions;
|
|
736
|
+
this.graphRoPEContext.edgeWeights = edgeWeights;
|
|
737
|
+
|
|
738
|
+
this.emit('graphrope-updated', {
|
|
739
|
+
nodeCount: nodePositions.size,
|
|
740
|
+
edgeCount: edges.length,
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Get topology-aware embedding for an agent
|
|
746
|
+
*
|
|
747
|
+
* Combines agent's base embedding with positional encoding
|
|
748
|
+
* from the topology graph.
|
|
749
|
+
*/
|
|
750
|
+
getTopologyAwareEmbedding(
|
|
751
|
+
agent: V3AgentState,
|
|
752
|
+
baseEmbedding?: number[]
|
|
753
|
+
): number[] {
|
|
754
|
+
const embedding =
|
|
755
|
+
baseEmbedding ?? this.generateAgentEmbedding(agent);
|
|
756
|
+
|
|
757
|
+
if (!this.config.enableGraphRoPE || !this.graphRoPEContext) {
|
|
758
|
+
return embedding;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const position = this.graphRoPEContext.nodePositions.get(agent.id.id);
|
|
762
|
+
if (!position) {
|
|
763
|
+
return embedding;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// Apply rotary position encoding
|
|
767
|
+
return this.applyRoPE(embedding, position);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// ==========================================================================
|
|
771
|
+
// Domain Mapping
|
|
772
|
+
// ==========================================================================
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* Map V3 domain to @sparkleideas/agentic-flow specialization
|
|
776
|
+
*/
|
|
777
|
+
mapDomainToSpecialization(domain: V3AgentDomain): string {
|
|
778
|
+
const mapping: Record<V3AgentDomain, string> = {
|
|
779
|
+
queen: 'coordination',
|
|
780
|
+
security: 'security-analysis',
|
|
781
|
+
core: 'architecture',
|
|
782
|
+
integration: 'implementation',
|
|
783
|
+
support: 'testing-performance',
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
return mapping[domain] || 'general';
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Map @sparkleideas/agentic-flow specialization to V3 domain
|
|
791
|
+
*/
|
|
792
|
+
mapSpecializationToDomain(specialization: string): V3AgentDomain {
|
|
793
|
+
const lower = specialization.toLowerCase();
|
|
794
|
+
|
|
795
|
+
if (lower.includes('coord') || lower.includes('orchestrat')) {
|
|
796
|
+
return 'queen';
|
|
797
|
+
}
|
|
798
|
+
if (lower.includes('security') || lower.includes('audit')) {
|
|
799
|
+
return 'security';
|
|
800
|
+
}
|
|
801
|
+
if (lower.includes('arch') || lower.includes('design')) {
|
|
802
|
+
return 'core';
|
|
803
|
+
}
|
|
804
|
+
if (lower.includes('impl') || lower.includes('code') || lower.includes('integrat')) {
|
|
805
|
+
return 'integration';
|
|
806
|
+
}
|
|
807
|
+
if (
|
|
808
|
+
lower.includes('test') ||
|
|
809
|
+
lower.includes('perf') ||
|
|
810
|
+
lower.includes('deploy')
|
|
811
|
+
) {
|
|
812
|
+
return 'support';
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
return 'core'; // Default
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// ==========================================================================
|
|
819
|
+
// Utility Methods
|
|
820
|
+
// ==========================================================================
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Check if delegation to @sparkleideas/agentic-flow is available
|
|
824
|
+
*/
|
|
825
|
+
isDelegationAvailable(): boolean {
|
|
826
|
+
return this.agenticFlowCore !== null;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Get adapter configuration
|
|
831
|
+
*/
|
|
832
|
+
getConfig(): SwarmAdapterConfig {
|
|
833
|
+
return { ...this.config };
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Reconfigure the adapter
|
|
838
|
+
*/
|
|
839
|
+
async reconfigure(config: Partial<SwarmAdapterConfig>): Promise<void> {
|
|
840
|
+
this.config = { ...this.config, ...config };
|
|
841
|
+
this.emit('reconfigured', { config: this.config });
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// ==========================================================================
|
|
845
|
+
// Private Methods
|
|
846
|
+
// ==========================================================================
|
|
847
|
+
|
|
848
|
+
private async connectToAgenticFlow(): Promise<void> {
|
|
849
|
+
try {
|
|
850
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
851
|
+
const agenticFlowModule: any = await import('@sparkleideas/agentic-flow').catch(() => null);
|
|
852
|
+
|
|
853
|
+
if (
|
|
854
|
+
agenticFlowModule &&
|
|
855
|
+
typeof agenticFlowModule.createAgenticFlow === 'function'
|
|
856
|
+
) {
|
|
857
|
+
this.agenticFlowCore = await agenticFlowModule.createAgenticFlow({});
|
|
858
|
+
|
|
859
|
+
// Check for AttentionCoordinator
|
|
860
|
+
if (this.agenticFlowCore.attention) {
|
|
861
|
+
this.attentionCoordinator = this.agenticFlowCore.attention;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
this.emit('agentic-flow-connected', {
|
|
865
|
+
version: this.agenticFlowCore.version,
|
|
866
|
+
hasAttention: !!this.attentionCoordinator,
|
|
867
|
+
hasMoE: !!this.agenticFlowCore.moe,
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
this.logDebug('Connected to @sparkleideas/agentic-flow', {
|
|
871
|
+
version: this.agenticFlowCore.version,
|
|
872
|
+
});
|
|
873
|
+
} else {
|
|
874
|
+
this.agenticFlowCore = null;
|
|
875
|
+
this.emit('agentic-flow-unavailable', {
|
|
876
|
+
reason: 'package not found or incompatible',
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
} catch (error) {
|
|
880
|
+
this.agenticFlowCore = null;
|
|
881
|
+
this.emit('agentic-flow-connection-failed', {
|
|
882
|
+
error: (error as Error).message,
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
private generateAgentEmbedding(agent: V3AgentState): number[] {
|
|
888
|
+
// Generate hash-based embedding from agent properties
|
|
889
|
+
// For ML embeddings, use: import('@sparkleideas/agentic-flow').computeEmbedding
|
|
890
|
+
const embedding = new Array(128).fill(0);
|
|
891
|
+
|
|
892
|
+
// Encode agent type
|
|
893
|
+
const typeHash = this.simpleHash(agent.type);
|
|
894
|
+
for (let i = 0; i < 16; i++) {
|
|
895
|
+
embedding[i] = ((typeHash >> i) & 1) * 0.5;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
// Encode capabilities
|
|
899
|
+
const capString = agent.capabilities.domains.join(',');
|
|
900
|
+
const capHash = this.simpleHash(capString);
|
|
901
|
+
for (let i = 16; i < 32; i++) {
|
|
902
|
+
embedding[i] = ((capHash >> (i - 16)) & 1) * 0.5;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// Encode metrics
|
|
906
|
+
embedding[32] = agent.metrics.successRate;
|
|
907
|
+
embedding[33] = agent.health;
|
|
908
|
+
embedding[34] = 1 - agent.workload;
|
|
909
|
+
embedding[35] = agent.metrics.tasksCompleted / 100;
|
|
910
|
+
|
|
911
|
+
// Encode role
|
|
912
|
+
const roleWeights: Record<string, number> = {
|
|
913
|
+
queen: 1.0,
|
|
914
|
+
coordinator: 0.9,
|
|
915
|
+
worker: 0.5,
|
|
916
|
+
peer: 0.5,
|
|
917
|
+
};
|
|
918
|
+
embedding[36] = roleWeights[agent.topologyRole ?? 'worker'] ?? 0.5;
|
|
919
|
+
|
|
920
|
+
// Normalize
|
|
921
|
+
const norm = Math.sqrt(
|
|
922
|
+
embedding.reduce((sum, v) => sum + v * v, 0)
|
|
923
|
+
);
|
|
924
|
+
if (norm > 0) {
|
|
925
|
+
for (let i = 0; i < embedding.length; i++) {
|
|
926
|
+
embedding[i] /= norm;
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
return embedding;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
private determineSpecialization(agent: V3AgentState): string {
|
|
934
|
+
const caps = agent.capabilities;
|
|
935
|
+
|
|
936
|
+
if (caps.coordination) return 'coordination';
|
|
937
|
+
if (caps.codeGeneration && caps.codeReview) return 'development';
|
|
938
|
+
if (caps.testing) return 'testing';
|
|
939
|
+
if (caps.research || caps.analysis) return 'analysis';
|
|
940
|
+
if (caps.documentation) return 'documentation';
|
|
941
|
+
|
|
942
|
+
// Check domains
|
|
943
|
+
if (caps.domains.includes('security')) return 'security';
|
|
944
|
+
if (caps.domains.includes('performance')) return 'performance';
|
|
945
|
+
if (caps.domains.includes('architecture')) return 'architecture';
|
|
946
|
+
|
|
947
|
+
return agent.type;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
private collectCapabilities(agent: V3AgentState): string[] {
|
|
951
|
+
const caps: string[] = [];
|
|
952
|
+
|
|
953
|
+
if (agent.capabilities.codeGeneration) caps.push('code-generation');
|
|
954
|
+
if (agent.capabilities.codeReview) caps.push('code-review');
|
|
955
|
+
if (agent.capabilities.testing) caps.push('testing');
|
|
956
|
+
if (agent.capabilities.documentation) caps.push('documentation');
|
|
957
|
+
if (agent.capabilities.research) caps.push('research');
|
|
958
|
+
if (agent.capabilities.analysis) caps.push('analysis');
|
|
959
|
+
if (agent.capabilities.coordination) caps.push('coordination');
|
|
960
|
+
|
|
961
|
+
caps.push(...agent.capabilities.languages);
|
|
962
|
+
caps.push(...agent.capabilities.frameworks);
|
|
963
|
+
caps.push(...agent.capabilities.domains);
|
|
964
|
+
|
|
965
|
+
return caps;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
private inferDomain(agent: V3AgentState): V3AgentDomain {
|
|
969
|
+
if (agent.type === 'queen' || agent.capabilities.coordination) {
|
|
970
|
+
return 'queen';
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
const domains = agent.capabilities.domains;
|
|
974
|
+
if (domains.includes('security')) return 'security';
|
|
975
|
+
if (domains.includes('core') || domains.includes('architecture')) return 'core';
|
|
976
|
+
if (domains.includes('integration')) return 'integration';
|
|
977
|
+
if (domains.includes('testing') || domains.includes('performance')) {
|
|
978
|
+
return 'support';
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
return 'core';
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
private extractTopAgents(
|
|
985
|
+
outputs: AgenticFlowAgentOutput[],
|
|
986
|
+
weights: Map<string, number>
|
|
987
|
+
): Array<{ id: string; name: string; weight: number }> {
|
|
988
|
+
return outputs
|
|
989
|
+
.map((o) => ({
|
|
990
|
+
id: o.agentId,
|
|
991
|
+
name: o.agentType,
|
|
992
|
+
weight: weights.get(o.agentId) ?? 0,
|
|
993
|
+
}))
|
|
994
|
+
.sort((a, b) => b.weight - a.weight)
|
|
995
|
+
.slice(0, 5);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
private cosineSimilarity(a: number[], b: number[]): number {
|
|
999
|
+
let dot = 0;
|
|
1000
|
+
let normA = 0;
|
|
1001
|
+
let normB = 0;
|
|
1002
|
+
const len = Math.min(a.length, b.length);
|
|
1003
|
+
|
|
1004
|
+
for (let i = 0; i < len; i++) {
|
|
1005
|
+
dot += a[i] * b[i];
|
|
1006
|
+
normA += a[i] * a[i];
|
|
1007
|
+
normB += b[i] * b[i];
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
1011
|
+
return denom > 0 ? dot / denom : 0;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
private simpleHash(str: string): number {
|
|
1015
|
+
let hash = 0;
|
|
1016
|
+
for (let i = 0; i < str.length; i++) {
|
|
1017
|
+
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
1018
|
+
hash = hash & hash;
|
|
1019
|
+
}
|
|
1020
|
+
return Math.abs(hash);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
private generatePositionalEncoding(
|
|
1024
|
+
position: number,
|
|
1025
|
+
dimension: number
|
|
1026
|
+
): number[] {
|
|
1027
|
+
const encoding = new Array(dimension).fill(0);
|
|
1028
|
+
|
|
1029
|
+
for (let i = 0; i < dimension; i++) {
|
|
1030
|
+
const angle = position / Math.pow(10000, (2 * Math.floor(i / 2)) / dimension);
|
|
1031
|
+
encoding[i] = i % 2 === 0 ? Math.sin(angle) : Math.cos(angle);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
return encoding;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
private applyRoPE(embedding: number[], position: number[]): number[] {
|
|
1038
|
+
const result = [...embedding];
|
|
1039
|
+
const dim = Math.min(embedding.length, position.length);
|
|
1040
|
+
|
|
1041
|
+
// Apply rotary encoding (simplified)
|
|
1042
|
+
for (let i = 0; i < dim - 1; i += 2) {
|
|
1043
|
+
const cos = position[i];
|
|
1044
|
+
const sin = position[i + 1] ?? 0;
|
|
1045
|
+
|
|
1046
|
+
const x1 = embedding[i];
|
|
1047
|
+
const x2 = embedding[i + 1] ?? 0;
|
|
1048
|
+
|
|
1049
|
+
result[i] = x1 * cos - x2 * sin;
|
|
1050
|
+
result[i + 1] = x1 * sin + x2 * cos;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
return result;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
private ensureInitialized(): void {
|
|
1057
|
+
if (!this.initialized) {
|
|
1058
|
+
throw new Error('SwarmAdapter not initialized. Call initialize() first.');
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
private logDebug(message: string, data?: unknown): void {
|
|
1063
|
+
if (this.config.debug) {
|
|
1064
|
+
console.debug(`[SwarmAdapter] ${message}`, data || '');
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
// ============================================================================
|
|
1070
|
+
// Factory Functions
|
|
1071
|
+
// ============================================================================
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* Create and initialize a SwarmAdapter
|
|
1075
|
+
*/
|
|
1076
|
+
export async function createSwarmAdapter(
|
|
1077
|
+
config?: Partial<SwarmAdapterConfig>
|
|
1078
|
+
): Promise<SwarmAdapter> {
|
|
1079
|
+
const adapter = new SwarmAdapter(config);
|
|
1080
|
+
await adapter.initialize();
|
|
1081
|
+
return adapter;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
/**
|
|
1085
|
+
* Singleton instance for simple usage
|
|
1086
|
+
*/
|
|
1087
|
+
let defaultAdapter: SwarmAdapter | null = null;
|
|
1088
|
+
|
|
1089
|
+
/**
|
|
1090
|
+
* Get the default adapter instance (creates if needed)
|
|
1091
|
+
*/
|
|
1092
|
+
export async function getDefaultSwarmAdapter(
|
|
1093
|
+
config?: Partial<SwarmAdapterConfig>
|
|
1094
|
+
): Promise<SwarmAdapter> {
|
|
1095
|
+
if (!defaultAdapter) {
|
|
1096
|
+
defaultAdapter = new SwarmAdapter(config);
|
|
1097
|
+
await defaultAdapter.initialize();
|
|
1098
|
+
}
|
|
1099
|
+
return defaultAdapter;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
/**
|
|
1103
|
+
* Reset the default adapter (useful for testing)
|
|
1104
|
+
*/
|
|
1105
|
+
export async function resetDefaultSwarmAdapter(): Promise<void> {
|
|
1106
|
+
if (defaultAdapter) {
|
|
1107
|
+
await defaultAdapter.shutdown();
|
|
1108
|
+
defaultAdapter = null;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
export default SwarmAdapter;
|