@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.
@@ -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;