@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,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Optimizer - Integrates @sparkleideas/agentic-flow Agent Booster capabilities
|
|
3
|
+
*
|
|
4
|
+
* Combines:
|
|
5
|
+
* - Agent Booster (352x code edit speedup)
|
|
6
|
+
* - ReasoningBank (32% token reduction via semantic retrieval)
|
|
7
|
+
* - Configuration Tuning (batch/cache/topology optimization)
|
|
8
|
+
*
|
|
9
|
+
* @module v3/integration/token-optimizer
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { EventEmitter } from 'events';
|
|
13
|
+
|
|
14
|
+
// Types for @sparkleideas/agentic-flow integration
|
|
15
|
+
interface TokenStats {
|
|
16
|
+
saved: number;
|
|
17
|
+
baseline: number;
|
|
18
|
+
reduction: number;
|
|
19
|
+
method: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface MemoryContext {
|
|
23
|
+
query: string;
|
|
24
|
+
memories: Array<{ content: string; score: number }>;
|
|
25
|
+
compactPrompt: string;
|
|
26
|
+
tokensSaved: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface EditOptimization {
|
|
30
|
+
speedupFactor: number;
|
|
31
|
+
executionMs: number;
|
|
32
|
+
method: 'agent-booster' | 'traditional';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Dynamic import helper to handle module resolution
|
|
36
|
+
async function safeImport<T>(modulePath: string): Promise<T | null> {
|
|
37
|
+
try {
|
|
38
|
+
return await import(modulePath);
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Token Optimizer - Reduces token usage via @sparkleideas/agentic-flow integration
|
|
46
|
+
*/
|
|
47
|
+
export class TokenOptimizer extends EventEmitter {
|
|
48
|
+
private stats = {
|
|
49
|
+
totalTokensSaved: 0,
|
|
50
|
+
editsOptimized: 0,
|
|
51
|
+
cacheHits: 0,
|
|
52
|
+
cacheMisses: 0,
|
|
53
|
+
memoriesRetrieved: 0,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
private agenticFlowAvailable = false;
|
|
57
|
+
private reasoningBank: any = null;
|
|
58
|
+
private agentBooster: any = null;
|
|
59
|
+
private configTuning: any = null;
|
|
60
|
+
private localCache = new Map<string, { data: any; timestamp: number }>();
|
|
61
|
+
|
|
62
|
+
async initialize(): Promise<void> {
|
|
63
|
+
try {
|
|
64
|
+
// Dynamic import of @sparkleideas/agentic-flow main module
|
|
65
|
+
const af = await safeImport<any>('@sparkleideas/agentic-flow');
|
|
66
|
+
|
|
67
|
+
if (af) {
|
|
68
|
+
this.agenticFlowAvailable = true;
|
|
69
|
+
|
|
70
|
+
// Load ReasoningBank (exported path)
|
|
71
|
+
const rb = await safeImport<any>('@sparkleideas/agentic-flow/reasoningbank');
|
|
72
|
+
if (rb && rb.retrieveMemories) {
|
|
73
|
+
this.reasoningBank = rb;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Load Agent Booster (exported path)
|
|
77
|
+
const ab = await safeImport<any>('@sparkleideas/agentic-flow/agent-booster');
|
|
78
|
+
if (ab) {
|
|
79
|
+
// Agent booster may export different API
|
|
80
|
+
this.agentBooster = ab.agentBooster || ab.AgentBooster || ab;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Config tuning is part of main module or agent-booster
|
|
84
|
+
// Use our fallback with anti-drift defaults
|
|
85
|
+
if (af.configTuning) {
|
|
86
|
+
this.configTuning = af.configTuning;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} catch {
|
|
90
|
+
this.agenticFlowAvailable = false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.emit('initialized', {
|
|
94
|
+
agenticFlowAvailable: this.agenticFlowAvailable,
|
|
95
|
+
reasoningBank: !!this.reasoningBank,
|
|
96
|
+
agentBooster: !!this.agentBooster,
|
|
97
|
+
configTuning: !!this.configTuning,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Retrieve compact context instead of full file content
|
|
103
|
+
* Saves ~32% tokens via semantic retrieval
|
|
104
|
+
*/
|
|
105
|
+
async getCompactContext(query: string, options?: {
|
|
106
|
+
limit?: number;
|
|
107
|
+
threshold?: number;
|
|
108
|
+
}): Promise<MemoryContext> {
|
|
109
|
+
const limit = options?.limit ?? 5;
|
|
110
|
+
const threshold = options?.threshold ?? 0.7;
|
|
111
|
+
|
|
112
|
+
if (!this.reasoningBank) {
|
|
113
|
+
// Fallback: return empty context
|
|
114
|
+
return {
|
|
115
|
+
query,
|
|
116
|
+
memories: [],
|
|
117
|
+
compactPrompt: '',
|
|
118
|
+
tokensSaved: 0,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const memories = await this.reasoningBank.retrieveMemories(query, {
|
|
123
|
+
limit,
|
|
124
|
+
threshold,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const compactPrompt = this.reasoningBank.formatMemoriesForPrompt(memories);
|
|
128
|
+
|
|
129
|
+
// Estimate tokens saved (baseline ~1000 tokens for full context)
|
|
130
|
+
const baseline = 1000;
|
|
131
|
+
const used = Math.ceil(compactPrompt.length / 4); // ~4 chars per token
|
|
132
|
+
const saved = Math.max(0, baseline - used);
|
|
133
|
+
|
|
134
|
+
this.stats.totalTokensSaved += saved;
|
|
135
|
+
this.stats.memoriesRetrieved += memories.length;
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
query,
|
|
139
|
+
memories,
|
|
140
|
+
compactPrompt,
|
|
141
|
+
tokensSaved: saved,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Optimized code edit using Agent Booster (352x faster)
|
|
147
|
+
* Faster edits = fewer timeouts = fewer retry tokens
|
|
148
|
+
*/
|
|
149
|
+
async optimizedEdit(
|
|
150
|
+
filePath: string,
|
|
151
|
+
oldContent: string,
|
|
152
|
+
newContent: string,
|
|
153
|
+
language: string
|
|
154
|
+
): Promise<EditOptimization> {
|
|
155
|
+
if (!this.agentBooster) {
|
|
156
|
+
// Fallback: return unoptimized result
|
|
157
|
+
return {
|
|
158
|
+
speedupFactor: 1,
|
|
159
|
+
executionMs: 352, // baseline
|
|
160
|
+
method: 'traditional',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const result = await this.agentBooster.editCode({
|
|
165
|
+
filePath,
|
|
166
|
+
oldContent,
|
|
167
|
+
newContent,
|
|
168
|
+
language,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
this.stats.editsOptimized++;
|
|
172
|
+
|
|
173
|
+
// Each 350ms saved prevents potential timeout/retry
|
|
174
|
+
// Estimate 50 tokens saved per optimized edit
|
|
175
|
+
if (result.method === 'agent-booster') {
|
|
176
|
+
this.stats.totalTokensSaved += 50;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
speedupFactor: result.speedupFactor,
|
|
181
|
+
executionMs: result.executionTimeMs,
|
|
182
|
+
method: result.method,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get optimal swarm configuration to prevent failures
|
|
188
|
+
* 100% success rate = no wasted retry tokens
|
|
189
|
+
*/
|
|
190
|
+
getOptimalConfig(agentCount: number): {
|
|
191
|
+
batchSize: number;
|
|
192
|
+
cacheSizeMB: number;
|
|
193
|
+
topology: string;
|
|
194
|
+
expectedSuccessRate: number;
|
|
195
|
+
} {
|
|
196
|
+
if (!this.configTuning) {
|
|
197
|
+
// Anti-drift defaults
|
|
198
|
+
return {
|
|
199
|
+
batchSize: 4,
|
|
200
|
+
cacheSizeMB: 50,
|
|
201
|
+
topology: 'hierarchical',
|
|
202
|
+
expectedSuccessRate: 0.95,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const batch = this.configTuning.getOptimalBatchSize();
|
|
207
|
+
const cache = this.configTuning.getOptimalCacheConfig();
|
|
208
|
+
const topo = this.configTuning.selectTopology(agentCount);
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
batchSize: batch.size,
|
|
212
|
+
cacheSizeMB: cache.sizeMB,
|
|
213
|
+
topology: topo.topology,
|
|
214
|
+
expectedSuccessRate: batch.expectedSuccessRate,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Cache-aware embedding lookup
|
|
220
|
+
* 95% hit rate = 95% fewer embedding API calls
|
|
221
|
+
*/
|
|
222
|
+
async cachedLookup<T>(key: string, generator: () => Promise<T>): Promise<T> {
|
|
223
|
+
// Use local cache if configTuning not available
|
|
224
|
+
const cacheEntry = this.localCache.get(key);
|
|
225
|
+
if (cacheEntry && Date.now() - cacheEntry.timestamp < 300000) { // 5 min TTL
|
|
226
|
+
this.stats.cacheHits++;
|
|
227
|
+
this.stats.totalTokensSaved += 100;
|
|
228
|
+
return cacheEntry.data as T;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (this.configTuning) {
|
|
232
|
+
const cached = await this.configTuning.cacheGet(key);
|
|
233
|
+
if (cached) {
|
|
234
|
+
this.stats.cacheHits++;
|
|
235
|
+
this.stats.totalTokensSaved += 100;
|
|
236
|
+
return cached as T;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
this.stats.cacheMisses++;
|
|
241
|
+
const result = await generator();
|
|
242
|
+
|
|
243
|
+
// Store in local cache
|
|
244
|
+
this.localCache.set(key, { data: result, timestamp: Date.now() });
|
|
245
|
+
|
|
246
|
+
if (this.configTuning) {
|
|
247
|
+
await this.configTuning.cacheSet(key, result);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get optimization statistics
|
|
255
|
+
*/
|
|
256
|
+
getStats(): typeof this.stats & {
|
|
257
|
+
agenticFlowAvailable: boolean;
|
|
258
|
+
cacheHitRate: string;
|
|
259
|
+
estimatedMonthlySavings: string;
|
|
260
|
+
} {
|
|
261
|
+
const total = this.stats.cacheHits + this.stats.cacheMisses;
|
|
262
|
+
const hitRate = total > 0 ? (this.stats.cacheHits / total * 100).toFixed(1) : '0';
|
|
263
|
+
|
|
264
|
+
// Estimate $0.01 per 1000 tokens
|
|
265
|
+
const savings = (this.stats.totalTokensSaved / 1000 * 0.01).toFixed(2);
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
...this.stats,
|
|
269
|
+
agenticFlowAvailable: this.agenticFlowAvailable,
|
|
270
|
+
cacheHitRate: `${hitRate}%`,
|
|
271
|
+
estimatedMonthlySavings: `$${savings}`,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Generate token savings report
|
|
277
|
+
*/
|
|
278
|
+
generateReport(): string {
|
|
279
|
+
const stats = this.getStats();
|
|
280
|
+
return `
|
|
281
|
+
## Token Optimization Report
|
|
282
|
+
|
|
283
|
+
| Metric | Value |
|
|
284
|
+
|--------|-------|
|
|
285
|
+
| Tokens Saved | ${stats.totalTokensSaved.toLocaleString()} |
|
|
286
|
+
| Edits Optimized | ${stats.editsOptimized} |
|
|
287
|
+
| Cache Hit Rate | ${stats.cacheHitRate} |
|
|
288
|
+
| Memories Retrieved | ${stats.memoriesRetrieved} |
|
|
289
|
+
| Est. Monthly Savings | ${stats.estimatedMonthlySavings} |
|
|
290
|
+
| Agentic-Flow Active | ${stats.agenticFlowAvailable ? '✓' : '✗'} |
|
|
291
|
+
`.trim();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Singleton instance
|
|
296
|
+
let optimizer: TokenOptimizer | null = null;
|
|
297
|
+
|
|
298
|
+
export async function getTokenOptimizer(): Promise<TokenOptimizer> {
|
|
299
|
+
if (!optimizer) {
|
|
300
|
+
optimizer = new TokenOptimizer();
|
|
301
|
+
await optimizer.initialize();
|
|
302
|
+
}
|
|
303
|
+
return optimizer;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export default TokenOptimizer;
|