@sparkleideas/integration 3.0.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,803 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic Flow Integration Bridge
|
|
3
|
+
*
|
|
4
|
+
* Core integration bridge for @sparkleideas/agentic-flow@alpha deep integration.
|
|
5
|
+
* Implements ADR-001: Adopt @sparkleideas/agentic-flow as Core Foundation
|
|
6
|
+
*
|
|
7
|
+
* Eliminates 10,000+ lines of duplicate code by building on @sparkleideas/agentic-flow
|
|
8
|
+
* rather than implementing parallel systems.
|
|
9
|
+
*
|
|
10
|
+
* @module v3/integration/agentic-flow-bridge
|
|
11
|
+
* @version 3.0.0-alpha.1
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { EventEmitter } from 'events';
|
|
15
|
+
import type {
|
|
16
|
+
IntegrationConfig,
|
|
17
|
+
IntegrationStatus,
|
|
18
|
+
RuntimeInfo,
|
|
19
|
+
ComponentHealth,
|
|
20
|
+
IntegrationEvent,
|
|
21
|
+
IntegrationEventType,
|
|
22
|
+
IntegrationError,
|
|
23
|
+
FeatureFlags,
|
|
24
|
+
DEFAULT_INTEGRATION_CONFIG,
|
|
25
|
+
} from './types.js';
|
|
26
|
+
import { SONAAdapter } from './sona-adapter.js';
|
|
27
|
+
import { AttentionCoordinator } from './attention-coordinator.js';
|
|
28
|
+
import { SDKBridge } from './sdk-bridge.js';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Interface for @sparkleideas/agentic-flow core module (dynamically loaded)
|
|
32
|
+
* This represents the external @sparkleideas/agentic-flow@alpha package API
|
|
33
|
+
*/
|
|
34
|
+
interface AgenticFlowSONAInterface {
|
|
35
|
+
setMode(mode: string): Promise<void>;
|
|
36
|
+
storePattern(params: unknown): Promise<string>;
|
|
37
|
+
findPatterns(query: string, options?: unknown): Promise<unknown[]>;
|
|
38
|
+
getStats(): Promise<unknown>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface AgenticFlowAttentionInterface {
|
|
42
|
+
compute(params: unknown): Promise<unknown>;
|
|
43
|
+
setMechanism(mechanism: string): Promise<void>;
|
|
44
|
+
getMetrics(): Promise<unknown>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface AgenticFlowAgentDBInterface {
|
|
48
|
+
search(query: number[], options?: unknown): Promise<unknown[]>;
|
|
49
|
+
insert(vector: number[], metadata?: unknown): Promise<string>;
|
|
50
|
+
enableCrossAgentSharing(options?: unknown): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Core interface for @sparkleideas/agentic-flow@alpha package
|
|
55
|
+
* Used for deep integration and code deduplication per ADR-001
|
|
56
|
+
*/
|
|
57
|
+
export interface AgenticFlowCore {
|
|
58
|
+
sona: AgenticFlowSONAInterface;
|
|
59
|
+
attention: AgenticFlowAttentionInterface;
|
|
60
|
+
@sparkleideas/agentdb: AgenticFlowAgentDBInterface;
|
|
61
|
+
version: string;
|
|
62
|
+
isConnected: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Factory function type for creating @sparkleideas/agentic-flow instance
|
|
67
|
+
*/
|
|
68
|
+
type AgenticFlowFactory = (config: unknown) => Promise<AgenticFlowCore>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* AgenticFlowBridge - Core integration class for @sparkleideas/agentic-flow@alpha
|
|
72
|
+
*
|
|
73
|
+
* This class serves as the main entry point for all @sparkleideas/agentic-flow integration,
|
|
74
|
+
* providing unified access to SONA learning, Flash Attention, and AgentDB.
|
|
75
|
+
*
|
|
76
|
+
* Performance Targets:
|
|
77
|
+
* - Flash Attention: 2.49x-7.47x speedup
|
|
78
|
+
* - AgentDB Search: 150x-12,500x improvement
|
|
79
|
+
* - SONA Adaptation: <0.05ms response time
|
|
80
|
+
* - Memory Reduction: 50-75%
|
|
81
|
+
*/
|
|
82
|
+
export class AgenticFlowBridge extends EventEmitter {
|
|
83
|
+
private config: IntegrationConfig;
|
|
84
|
+
private initialized: boolean = false;
|
|
85
|
+
private sona: SONAAdapter | null = null;
|
|
86
|
+
private attention: AttentionCoordinator | null = null;
|
|
87
|
+
private sdk: SDKBridge | null = null;
|
|
88
|
+
private componentHealth: Map<string, ComponentHealth> = new Map();
|
|
89
|
+
private runtimeInfo: RuntimeInfo | null = null;
|
|
90
|
+
private initializationPromise: Promise<void> | null = null;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Reference to the @sparkleideas/agentic-flow@alpha core instance
|
|
94
|
+
* When available, components delegate to this instead of local implementations
|
|
95
|
+
* This follows ADR-001: Adopt @sparkleideas/agentic-flow as Core Foundation
|
|
96
|
+
*/
|
|
97
|
+
private agenticFlowCore: AgenticFlowCore | null = null;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Indicates whether @sparkleideas/agentic-flow is available for delegation
|
|
101
|
+
*/
|
|
102
|
+
private agenticFlowAvailable: boolean = false;
|
|
103
|
+
|
|
104
|
+
constructor(config: Partial<IntegrationConfig> = {}) {
|
|
105
|
+
super();
|
|
106
|
+
this.config = this.mergeConfig(config);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Initialize the integration bridge
|
|
111
|
+
*
|
|
112
|
+
* This method is idempotent - calling it multiple times is safe.
|
|
113
|
+
* Components are lazily loaded based on configuration.
|
|
114
|
+
*/
|
|
115
|
+
async initialize(config?: Partial<IntegrationConfig>): Promise<void> {
|
|
116
|
+
// Return existing promise if initialization is in progress
|
|
117
|
+
if (this.initializationPromise) {
|
|
118
|
+
return this.initializationPromise;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Already initialized
|
|
122
|
+
if (this.initialized) {
|
|
123
|
+
if (config) {
|
|
124
|
+
await this.reconfigure(config);
|
|
125
|
+
}
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this.initializationPromise = this.doInitialize(config);
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
await this.initializationPromise;
|
|
133
|
+
} finally {
|
|
134
|
+
this.initializationPromise = null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private async doInitialize(config?: Partial<IntegrationConfig>): Promise<void> {
|
|
139
|
+
const startTime = Date.now();
|
|
140
|
+
|
|
141
|
+
if (config) {
|
|
142
|
+
this.config = this.mergeConfig(config);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this.emit('initializing', { config: this.config });
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
// Detect runtime environment
|
|
149
|
+
this.runtimeInfo = await this.detectRuntime();
|
|
150
|
+
this.logDebug('Runtime detected', this.runtimeInfo);
|
|
151
|
+
|
|
152
|
+
// ADR-001: Attempt to load @sparkleideas/agentic-flow@alpha dynamically
|
|
153
|
+
// This enables deep integration and code deduplication
|
|
154
|
+
await this.connectToAgenticFlow();
|
|
155
|
+
|
|
156
|
+
// Initialize SDK bridge first (required for version negotiation)
|
|
157
|
+
this.sdk = new SDKBridge({
|
|
158
|
+
targetVersion: 'alpha',
|
|
159
|
+
enableVersionNegotiation: true,
|
|
160
|
+
fallbackBehavior: 'warn',
|
|
161
|
+
enableCompatibilityLayer: true,
|
|
162
|
+
supportDeprecatedAPIs: true,
|
|
163
|
+
});
|
|
164
|
+
await this.sdk.initialize();
|
|
165
|
+
this.updateComponentHealth('sdk', 'healthy');
|
|
166
|
+
|
|
167
|
+
// Initialize SONA adapter if enabled
|
|
168
|
+
// Pass @sparkleideas/agentic-flow reference for delegation when available
|
|
169
|
+
if (this.config.features.enableSONA) {
|
|
170
|
+
this.sona = new SONAAdapter(this.config.sona);
|
|
171
|
+
if (this.agenticFlowCore) {
|
|
172
|
+
// Type cast: @sparkleideas/agentic-flow runtime API is compatible but typed as `unknown`
|
|
173
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
174
|
+
this.sona.setAgenticFlowReference(this.agenticFlowCore.sona as any);
|
|
175
|
+
}
|
|
176
|
+
await this.sona.initialize();
|
|
177
|
+
this.updateComponentHealth('sona', 'healthy');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Initialize Attention coordinator if enabled
|
|
181
|
+
// Pass @sparkleideas/agentic-flow reference for delegation when available
|
|
182
|
+
if (this.config.features.enableFlashAttention) {
|
|
183
|
+
this.attention = new AttentionCoordinator(this.config.attention);
|
|
184
|
+
if (this.agenticFlowCore) {
|
|
185
|
+
// Type cast: @sparkleideas/agentic-flow runtime API is compatible but typed as `unknown`
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
187
|
+
this.attention.setAgenticFlowReference(this.agenticFlowCore.attention as any);
|
|
188
|
+
}
|
|
189
|
+
await this.attention.initialize();
|
|
190
|
+
this.updateComponentHealth('attention', 'healthy');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
this.initialized = true;
|
|
194
|
+
|
|
195
|
+
const duration = Date.now() - startTime;
|
|
196
|
+
this.emit('initialized', {
|
|
197
|
+
duration,
|
|
198
|
+
components: this.getConnectedComponents(),
|
|
199
|
+
agenticFlowConnected: this.agenticFlowAvailable,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
this.logDebug(`Initialization complete in ${duration}ms`);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
this.emit('initialization-failed', { error });
|
|
205
|
+
throw this.wrapError(error as Error, 'INITIALIZATION_FAILED', 'bridge');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Connect to @sparkleideas/agentic-flow@alpha package dynamically
|
|
211
|
+
*
|
|
212
|
+
* This implements ADR-001: Adopt @sparkleideas/agentic-flow as Core Foundation
|
|
213
|
+
* When @sparkleideas/agentic-flow is available, components delegate to it for:
|
|
214
|
+
* - SONA learning (eliminating duplicate pattern storage)
|
|
215
|
+
* - Flash Attention (using native optimized implementations)
|
|
216
|
+
* - AgentDB (leveraging 150x-12,500x faster HNSW search)
|
|
217
|
+
*
|
|
218
|
+
* If @sparkleideas/agentic-flow is not installed, falls back to local implementations
|
|
219
|
+
* to maintain backward compatibility.
|
|
220
|
+
*/
|
|
221
|
+
private async connectToAgenticFlow(): Promise<void> {
|
|
222
|
+
try {
|
|
223
|
+
// Dynamic import to handle optional dependency
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
225
|
+
const agenticFlowModule: any = await import('@sparkleideas/agentic-flow').catch(() => null);
|
|
226
|
+
|
|
227
|
+
if (agenticFlowModule && typeof agenticFlowModule.createAgenticFlow === 'function') {
|
|
228
|
+
const factory: AgenticFlowFactory = agenticFlowModule.createAgenticFlow;
|
|
229
|
+
|
|
230
|
+
this.agenticFlowCore = await factory({
|
|
231
|
+
sona: this.config.sona,
|
|
232
|
+
attention: this.config.attention,
|
|
233
|
+
@sparkleideas/agentdb: this.config.@sparkleideas/agentdb,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
this.agenticFlowAvailable = true;
|
|
237
|
+
this.updateComponentHealth('@sparkleideas/agentic-flow', 'healthy');
|
|
238
|
+
|
|
239
|
+
this.emit('@sparkleideas/agentic-flow:connected', {
|
|
240
|
+
version: this.agenticFlowCore.version,
|
|
241
|
+
features: {
|
|
242
|
+
sona: true,
|
|
243
|
+
attention: true,
|
|
244
|
+
@sparkleideas/agentdb: true,
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
this.logDebug('Connected to @sparkleideas/agentic-flow', {
|
|
249
|
+
version: this.agenticFlowCore.version,
|
|
250
|
+
});
|
|
251
|
+
} else {
|
|
252
|
+
// Package not found or doesn't export expected factory
|
|
253
|
+
this.agenticFlowAvailable = false;
|
|
254
|
+
this.emit('@sparkleideas/agentic-flow:fallback', {
|
|
255
|
+
reason: 'package not found or incompatible',
|
|
256
|
+
});
|
|
257
|
+
this.logDebug('@sparkleideas/agentic-flow not available, using local implementations');
|
|
258
|
+
}
|
|
259
|
+
} catch (error) {
|
|
260
|
+
// Fallback to local implementation if @sparkleideas/agentic-flow fails to load
|
|
261
|
+
this.agenticFlowAvailable = false;
|
|
262
|
+
this.emit('@sparkleideas/agentic-flow:fallback', {
|
|
263
|
+
reason: 'initialization error',
|
|
264
|
+
error: (error as Error).message,
|
|
265
|
+
});
|
|
266
|
+
this.logDebug('@sparkleideas/agentic-flow initialization failed, using fallback', error);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Reconfigure the bridge with new settings
|
|
272
|
+
*/
|
|
273
|
+
async reconfigure(config: Partial<IntegrationConfig>): Promise<void> {
|
|
274
|
+
this.config = this.mergeConfig(config);
|
|
275
|
+
|
|
276
|
+
// Reconfigure active components
|
|
277
|
+
if (this.sona && config.sona) {
|
|
278
|
+
await this.sona.reconfigure(config.sona);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (this.attention && config.attention) {
|
|
282
|
+
await this.attention.reconfigure(config.attention);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
this.emit('reconfigured', { config: this.config });
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Get the SONA adapter for learning integration
|
|
290
|
+
*/
|
|
291
|
+
async getSONAAdapter(): Promise<SONAAdapter> {
|
|
292
|
+
this.ensureInitialized();
|
|
293
|
+
|
|
294
|
+
if (!this.config.features.enableSONA) {
|
|
295
|
+
throw this.createError(
|
|
296
|
+
'SONA is disabled in configuration',
|
|
297
|
+
'FEATURE_DISABLED',
|
|
298
|
+
'sona'
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (!this.sona) {
|
|
303
|
+
this.sona = new SONAAdapter(this.config.sona);
|
|
304
|
+
await this.sona.initialize();
|
|
305
|
+
this.updateComponentHealth('sona', 'healthy');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return this.sona;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Get the Attention coordinator for Flash Attention integration
|
|
313
|
+
*/
|
|
314
|
+
async getAttentionCoordinator(): Promise<AttentionCoordinator> {
|
|
315
|
+
this.ensureInitialized();
|
|
316
|
+
|
|
317
|
+
if (!this.config.features.enableFlashAttention) {
|
|
318
|
+
throw this.createError(
|
|
319
|
+
'Flash Attention is disabled in configuration',
|
|
320
|
+
'FEATURE_DISABLED',
|
|
321
|
+
'attention'
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (!this.attention) {
|
|
326
|
+
this.attention = new AttentionCoordinator(this.config.attention);
|
|
327
|
+
await this.attention.initialize();
|
|
328
|
+
this.updateComponentHealth('attention', 'healthy');
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return this.attention;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Get the SDK bridge for API compatibility
|
|
336
|
+
*/
|
|
337
|
+
async getSDKBridge(): Promise<SDKBridge> {
|
|
338
|
+
this.ensureInitialized();
|
|
339
|
+
|
|
340
|
+
if (!this.sdk) {
|
|
341
|
+
throw this.createError(
|
|
342
|
+
'SDK bridge not initialized',
|
|
343
|
+
'COMPONENT_UNAVAILABLE',
|
|
344
|
+
'sdk'
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return this.sdk;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Get current integration status
|
|
353
|
+
*/
|
|
354
|
+
getStatus(): IntegrationStatus {
|
|
355
|
+
const features: Record<string, boolean> = {};
|
|
356
|
+
for (const [key, value] of Object.entries(this.config.features)) {
|
|
357
|
+
features[key] = value;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return {
|
|
361
|
+
initialized: this.initialized,
|
|
362
|
+
connectedComponents: this.getConnectedComponents(),
|
|
363
|
+
runtime: this.runtimeInfo || this.getDefaultRuntimeInfo(),
|
|
364
|
+
features,
|
|
365
|
+
health: Object.fromEntries(this.componentHealth),
|
|
366
|
+
lastHealthCheck: Date.now(),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Get feature flags
|
|
372
|
+
*/
|
|
373
|
+
getFeatureFlags(): FeatureFlags {
|
|
374
|
+
return { ...this.config.features };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Check if a feature is enabled
|
|
379
|
+
*/
|
|
380
|
+
isFeatureEnabled(feature: keyof FeatureFlags): boolean {
|
|
381
|
+
return this.config.features[feature] ?? false;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Enable a feature dynamically
|
|
386
|
+
*/
|
|
387
|
+
async enableFeature(feature: keyof FeatureFlags): Promise<void> {
|
|
388
|
+
if (this.config.features[feature]) {
|
|
389
|
+
return; // Already enabled
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
this.config.features[feature] = true;
|
|
393
|
+
|
|
394
|
+
// Initialize the corresponding component if needed
|
|
395
|
+
switch (feature) {
|
|
396
|
+
case 'enableSONA':
|
|
397
|
+
if (!this.sona) {
|
|
398
|
+
this.sona = new SONAAdapter(this.config.sona);
|
|
399
|
+
await this.sona.initialize();
|
|
400
|
+
this.updateComponentHealth('sona', 'healthy');
|
|
401
|
+
}
|
|
402
|
+
break;
|
|
403
|
+
case 'enableFlashAttention':
|
|
404
|
+
if (!this.attention) {
|
|
405
|
+
this.attention = new AttentionCoordinator(this.config.attention);
|
|
406
|
+
await this.attention.initialize();
|
|
407
|
+
this.updateComponentHealth('attention', 'healthy');
|
|
408
|
+
}
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
this.emit('feature-enabled', { feature });
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Disable a feature dynamically
|
|
417
|
+
*/
|
|
418
|
+
async disableFeature(feature: keyof FeatureFlags): Promise<void> {
|
|
419
|
+
if (!this.config.features[feature]) {
|
|
420
|
+
return; // Already disabled
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
this.config.features[feature] = false;
|
|
424
|
+
|
|
425
|
+
// Cleanup the corresponding component
|
|
426
|
+
switch (feature) {
|
|
427
|
+
case 'enableSONA':
|
|
428
|
+
if (this.sona) {
|
|
429
|
+
await this.sona.shutdown();
|
|
430
|
+
this.sona = null;
|
|
431
|
+
this.componentHealth.delete('sona');
|
|
432
|
+
}
|
|
433
|
+
break;
|
|
434
|
+
case 'enableFlashAttention':
|
|
435
|
+
if (this.attention) {
|
|
436
|
+
await this.attention.shutdown();
|
|
437
|
+
this.attention = null;
|
|
438
|
+
this.componentHealth.delete('attention');
|
|
439
|
+
}
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
this.emit('feature-disabled', { feature });
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Perform health check on all components
|
|
448
|
+
*/
|
|
449
|
+
async healthCheck(): Promise<Record<string, ComponentHealth>> {
|
|
450
|
+
const results: Record<string, ComponentHealth> = {};
|
|
451
|
+
|
|
452
|
+
// Check SDK bridge
|
|
453
|
+
if (this.sdk) {
|
|
454
|
+
try {
|
|
455
|
+
const start = Date.now();
|
|
456
|
+
await this.sdk.ping();
|
|
457
|
+
results['sdk'] = {
|
|
458
|
+
name: 'sdk',
|
|
459
|
+
status: 'healthy',
|
|
460
|
+
latencyMs: Date.now() - start,
|
|
461
|
+
uptime: 1.0,
|
|
462
|
+
};
|
|
463
|
+
} catch (error) {
|
|
464
|
+
results['sdk'] = {
|
|
465
|
+
name: 'sdk',
|
|
466
|
+
status: 'unhealthy',
|
|
467
|
+
lastError: (error as Error).message,
|
|
468
|
+
latencyMs: 0,
|
|
469
|
+
uptime: 0,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// Check SONA
|
|
475
|
+
if (this.sona) {
|
|
476
|
+
try {
|
|
477
|
+
const start = Date.now();
|
|
478
|
+
await this.sona.getStats();
|
|
479
|
+
results['sona'] = {
|
|
480
|
+
name: 'sona',
|
|
481
|
+
status: 'healthy',
|
|
482
|
+
latencyMs: Date.now() - start,
|
|
483
|
+
uptime: 1.0,
|
|
484
|
+
};
|
|
485
|
+
} catch (error) {
|
|
486
|
+
results['sona'] = {
|
|
487
|
+
name: 'sona',
|
|
488
|
+
status: 'unhealthy',
|
|
489
|
+
lastError: (error as Error).message,
|
|
490
|
+
latencyMs: 0,
|
|
491
|
+
uptime: 0,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Check Attention
|
|
497
|
+
if (this.attention) {
|
|
498
|
+
try {
|
|
499
|
+
const start = Date.now();
|
|
500
|
+
await this.attention.getMetrics();
|
|
501
|
+
results['attention'] = {
|
|
502
|
+
name: 'attention',
|
|
503
|
+
status: 'healthy',
|
|
504
|
+
latencyMs: Date.now() - start,
|
|
505
|
+
uptime: 1.0,
|
|
506
|
+
};
|
|
507
|
+
} catch (error) {
|
|
508
|
+
results['attention'] = {
|
|
509
|
+
name: 'attention',
|
|
510
|
+
status: 'unhealthy',
|
|
511
|
+
lastError: (error as Error).message,
|
|
512
|
+
latencyMs: 0,
|
|
513
|
+
uptime: 0,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Update stored health status
|
|
519
|
+
for (const [name, health] of Object.entries(results)) {
|
|
520
|
+
this.componentHealth.set(name, health);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
this.emit('health-check', { results });
|
|
524
|
+
return results;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Shutdown the integration bridge gracefully
|
|
529
|
+
*/
|
|
530
|
+
async shutdown(): Promise<void> {
|
|
531
|
+
this.emit('shutting-down');
|
|
532
|
+
|
|
533
|
+
const shutdownPromises: Promise<void>[] = [];
|
|
534
|
+
|
|
535
|
+
if (this.sona) {
|
|
536
|
+
shutdownPromises.push(this.sona.shutdown());
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (this.attention) {
|
|
540
|
+
shutdownPromises.push(this.attention.shutdown());
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (this.sdk) {
|
|
544
|
+
shutdownPromises.push(this.sdk.shutdown());
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
await Promise.allSettled(shutdownPromises);
|
|
548
|
+
|
|
549
|
+
this.sona = null;
|
|
550
|
+
this.attention = null;
|
|
551
|
+
this.sdk = null;
|
|
552
|
+
this.agenticFlowCore = null;
|
|
553
|
+
this.agenticFlowAvailable = false;
|
|
554
|
+
this.initialized = false;
|
|
555
|
+
this.componentHealth.clear();
|
|
556
|
+
|
|
557
|
+
this.emit('shutdown');
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Check if @sparkleideas/agentic-flow@alpha is connected and available for delegation
|
|
562
|
+
*
|
|
563
|
+
* When true, components can delegate to @sparkleideas/agentic-flow for optimized
|
|
564
|
+
* implementations (per ADR-001).
|
|
565
|
+
*/
|
|
566
|
+
isAgenticFlowConnected(): boolean {
|
|
567
|
+
return this.agenticFlowAvailable && this.agenticFlowCore !== null;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Get the @sparkleideas/agentic-flow core instance for direct access
|
|
572
|
+
*
|
|
573
|
+
* Returns null if @sparkleideas/agentic-flow is not available.
|
|
574
|
+
* Prefer using getSONAAdapter() or getAttentionCoordinator() which
|
|
575
|
+
* handle delegation automatically.
|
|
576
|
+
*/
|
|
577
|
+
getAgenticFlowCore(): AgenticFlowCore | null {
|
|
578
|
+
return this.agenticFlowCore;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// ===== Private Methods =====
|
|
582
|
+
|
|
583
|
+
private mergeConfig(config: Partial<IntegrationConfig>): IntegrationConfig {
|
|
584
|
+
const defaultConfig: IntegrationConfig = {
|
|
585
|
+
sona: {
|
|
586
|
+
mode: 'balanced',
|
|
587
|
+
learningRate: 0.001,
|
|
588
|
+
similarityThreshold: 0.7,
|
|
589
|
+
maxPatterns: 10000,
|
|
590
|
+
enableTrajectoryTracking: true,
|
|
591
|
+
consolidationInterval: 3600000,
|
|
592
|
+
autoModeSelection: true,
|
|
593
|
+
},
|
|
594
|
+
attention: {
|
|
595
|
+
mechanism: 'flash',
|
|
596
|
+
numHeads: 8,
|
|
597
|
+
headDim: 64,
|
|
598
|
+
dropoutRate: 0.0,
|
|
599
|
+
causalMask: false,
|
|
600
|
+
useRoPE: true,
|
|
601
|
+
flashOptLevel: 2,
|
|
602
|
+
memoryOptimization: 'moderate',
|
|
603
|
+
},
|
|
604
|
+
@sparkleideas/agentdb: {
|
|
605
|
+
dimension: 1536,
|
|
606
|
+
indexType: 'hnsw',
|
|
607
|
+
hnswM: 16,
|
|
608
|
+
hnswEfConstruction: 200,
|
|
609
|
+
hnswEfSearch: 50,
|
|
610
|
+
metric: 'cosine',
|
|
611
|
+
enableCache: true,
|
|
612
|
+
cacheSizeMb: 256,
|
|
613
|
+
enableWAL: true,
|
|
614
|
+
},
|
|
615
|
+
features: {
|
|
616
|
+
enableSONA: true,
|
|
617
|
+
enableFlashAttention: true,
|
|
618
|
+
enableAgentDB: true,
|
|
619
|
+
enableTrajectoryTracking: true,
|
|
620
|
+
enableGNN: true,
|
|
621
|
+
enableIntelligenceBridge: true,
|
|
622
|
+
enableQUICTransport: false,
|
|
623
|
+
enableNightlyLearning: false,
|
|
624
|
+
enableAutoConsolidation: true,
|
|
625
|
+
},
|
|
626
|
+
runtimePreference: ['napi', 'wasm', 'js'],
|
|
627
|
+
lazyLoad: true,
|
|
628
|
+
debug: false,
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
return {
|
|
632
|
+
...defaultConfig,
|
|
633
|
+
...config,
|
|
634
|
+
sona: { ...defaultConfig.sona, ...config.sona },
|
|
635
|
+
attention: { ...defaultConfig.attention, ...config.attention },
|
|
636
|
+
@sparkleideas/agentdb: { ...defaultConfig.@sparkleideas/agentdb, ...config.@sparkleideas/agentdb },
|
|
637
|
+
features: { ...defaultConfig.features, ...config.features },
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
private async detectRuntime(): Promise<RuntimeInfo> {
|
|
642
|
+
const platform = process.platform as 'linux' | 'darwin' | 'win32';
|
|
643
|
+
const arch = process.arch as 'x64' | 'arm64' | 'ia32';
|
|
644
|
+
const nodeVersion = process.version;
|
|
645
|
+
|
|
646
|
+
// Check NAPI support
|
|
647
|
+
let napiSupport = false;
|
|
648
|
+
try {
|
|
649
|
+
// Attempt to load native module indicator
|
|
650
|
+
napiSupport = platform !== 'win32' || arch === 'x64';
|
|
651
|
+
} catch {
|
|
652
|
+
napiSupport = false;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// WASM is always supported in Node.js
|
|
656
|
+
const wasmSupport = true;
|
|
657
|
+
|
|
658
|
+
// Determine runtime based on preference
|
|
659
|
+
let runtime: 'napi' | 'wasm' | 'js' = 'js';
|
|
660
|
+
for (const pref of this.config.runtimePreference) {
|
|
661
|
+
if (pref === 'napi' && napiSupport) {
|
|
662
|
+
runtime = 'napi';
|
|
663
|
+
break;
|
|
664
|
+
} else if (pref === 'wasm' && wasmSupport) {
|
|
665
|
+
runtime = 'wasm';
|
|
666
|
+
break;
|
|
667
|
+
} else if (pref === 'js') {
|
|
668
|
+
runtime = 'js';
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Determine performance tier
|
|
674
|
+
let performanceTier: 'optimal' | 'good' | 'fallback';
|
|
675
|
+
if (runtime === 'napi') {
|
|
676
|
+
performanceTier = 'optimal';
|
|
677
|
+
} else if (runtime === 'wasm') {
|
|
678
|
+
performanceTier = 'good';
|
|
679
|
+
} else {
|
|
680
|
+
performanceTier = 'fallback';
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
return {
|
|
684
|
+
runtime,
|
|
685
|
+
platform,
|
|
686
|
+
arch,
|
|
687
|
+
nodeVersion,
|
|
688
|
+
wasmSupport,
|
|
689
|
+
napiSupport,
|
|
690
|
+
performanceTier,
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
private getDefaultRuntimeInfo(): RuntimeInfo {
|
|
695
|
+
return {
|
|
696
|
+
runtime: 'js',
|
|
697
|
+
platform: 'linux',
|
|
698
|
+
arch: 'x64',
|
|
699
|
+
nodeVersion: process.version,
|
|
700
|
+
wasmSupport: true,
|
|
701
|
+
napiSupport: false,
|
|
702
|
+
performanceTier: 'fallback',
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
private getConnectedComponents(): string[] {
|
|
707
|
+
const components: string[] = [];
|
|
708
|
+
|
|
709
|
+
if (this.sdk) components.push('sdk');
|
|
710
|
+
if (this.sona) components.push('sona');
|
|
711
|
+
if (this.attention) components.push('attention');
|
|
712
|
+
|
|
713
|
+
return components;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
private updateComponentHealth(
|
|
717
|
+
name: string,
|
|
718
|
+
status: 'healthy' | 'degraded' | 'unhealthy',
|
|
719
|
+
error?: string
|
|
720
|
+
): void {
|
|
721
|
+
this.componentHealth.set(name, {
|
|
722
|
+
name,
|
|
723
|
+
status,
|
|
724
|
+
lastError: error,
|
|
725
|
+
latencyMs: 0,
|
|
726
|
+
uptime: status === 'healthy' ? 1.0 : 0.0,
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
private ensureInitialized(): void {
|
|
731
|
+
if (!this.initialized) {
|
|
732
|
+
throw this.createError(
|
|
733
|
+
'Bridge not initialized. Call initialize() first.',
|
|
734
|
+
'INITIALIZATION_FAILED',
|
|
735
|
+
'bridge'
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
private createError(
|
|
741
|
+
message: string,
|
|
742
|
+
code: string,
|
|
743
|
+
component: string
|
|
744
|
+
): Error {
|
|
745
|
+
const error = new Error(message);
|
|
746
|
+
(error as any).code = code;
|
|
747
|
+
(error as any).component = component;
|
|
748
|
+
return error;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
private wrapError(error: Error, code: string, component: string): Error {
|
|
752
|
+
const wrapped = new Error(`${component}: ${error.message}`);
|
|
753
|
+
(wrapped as any).code = code;
|
|
754
|
+
(wrapped as any).component = component;
|
|
755
|
+
(wrapped as any).cause = error;
|
|
756
|
+
return wrapped;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
private logDebug(message: string, data?: unknown): void {
|
|
760
|
+
if (this.config.debug) {
|
|
761
|
+
console.debug(`[AgenticFlowBridge] ${message}`, data || '');
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* Create and initialize an AgenticFlowBridge instance
|
|
768
|
+
*/
|
|
769
|
+
export async function createAgenticFlowBridge(
|
|
770
|
+
config?: Partial<IntegrationConfig>
|
|
771
|
+
): Promise<AgenticFlowBridge> {
|
|
772
|
+
const bridge = new AgenticFlowBridge(config);
|
|
773
|
+
await bridge.initialize();
|
|
774
|
+
return bridge;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Singleton instance for simple usage
|
|
779
|
+
*/
|
|
780
|
+
let defaultBridge: AgenticFlowBridge | null = null;
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Get the default bridge instance (creates if needed)
|
|
784
|
+
*/
|
|
785
|
+
export async function getDefaultBridge(
|
|
786
|
+
config?: Partial<IntegrationConfig>
|
|
787
|
+
): Promise<AgenticFlowBridge> {
|
|
788
|
+
if (!defaultBridge) {
|
|
789
|
+
defaultBridge = new AgenticFlowBridge(config);
|
|
790
|
+
await defaultBridge.initialize();
|
|
791
|
+
}
|
|
792
|
+
return defaultBridge;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Reset the default bridge (useful for testing)
|
|
797
|
+
*/
|
|
798
|
+
export async function resetDefaultBridge(): Promise<void> {
|
|
799
|
+
if (defaultBridge) {
|
|
800
|
+
await defaultBridge.shutdown();
|
|
801
|
+
defaultBridge = null;
|
|
802
|
+
}
|
|
803
|
+
}
|