claude-flow 3.5.21 → 3.5.23
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/.claude/helpers/hook-handler.cjs +4 -2
- package/README.md +9 -7
- package/package.json +1 -1
- package/v3/@claude-flow/cli/README.md +9 -7
- package/v3/@claude-flow/cli/dist/src/commands/hooks.js +698 -55
- package/v3/@claude-flow/cli/dist/src/commands/init.js +3 -1
- package/v3/@claude-flow/cli/dist/src/commands/neural.js +11 -5
- package/v3/@claude-flow/cli/dist/src/index.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/index.js +2 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/coordination-tools.js +191 -12
- package/v3/@claude-flow/cli/dist/src/mcp-tools/hive-mind-tools.js +224 -23
- package/v3/@claude-flow/cli/dist/src/mcp-tools/memory-tools.js +1 -0
- package/v3/@claude-flow/cli/dist/src/memory/ewc-consolidation.d.ts +24 -0
- package/v3/@claude-flow/cli/dist/src/memory/ewc-consolidation.js +59 -0
- package/v3/@claude-flow/cli/dist/src/memory/intelligence.d.ts +53 -0
- package/v3/@claude-flow/cli/dist/src/memory/intelligence.js +225 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +7 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +27 -1
- package/v3/@claude-flow/cli/dist/src/ruvector/index.d.ts +4 -0
- package/v3/@claude-flow/cli/dist/src/ruvector/index.js +12 -0
- package/v3/@claude-flow/cli/dist/src/services/ruvector-training.d.ts +9 -1
- package/v3/@claude-flow/cli/dist/src/services/ruvector-training.js +223 -39
- package/v3/@claude-flow/cli/dist/src/services/worker-daemon.d.ts +4 -0
- package/v3/@claude-flow/cli/dist/src/services/worker-daemon.js +33 -5
- package/v3/@claude-flow/cli/package.json +1 -1
|
@@ -82,6 +82,7 @@ class LocalSonaCoordinator {
|
|
|
82
82
|
signalCount = 0;
|
|
83
83
|
trajectories = [];
|
|
84
84
|
adaptationTimes = [];
|
|
85
|
+
currentTrajectorySteps = [];
|
|
85
86
|
constructor(config) {
|
|
86
87
|
this.config = config;
|
|
87
88
|
// Pre-allocate circular buffer
|
|
@@ -136,6 +137,164 @@ class LocalSonaCoordinator {
|
|
|
136
137
|
return 0;
|
|
137
138
|
return this.adaptationTimes.reduce((a, b) => a + b, 0) / this.adaptationTimes.length;
|
|
138
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Add a step to the current in-progress trajectory
|
|
142
|
+
*/
|
|
143
|
+
addTrajectoryStep(step) {
|
|
144
|
+
this.currentTrajectorySteps.push(step);
|
|
145
|
+
// Prevent unbounded growth
|
|
146
|
+
if (this.currentTrajectorySteps.length > this.config.maxTrajectorySize) {
|
|
147
|
+
this.currentTrajectorySteps.shift();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* End the current trajectory with a verdict and apply RL updates.
|
|
152
|
+
* Reward mapping: success=1.0, partial=0.5, failure=-0.5
|
|
153
|
+
*
|
|
154
|
+
* For successful/partial trajectories, boosts confidence of similar patterns
|
|
155
|
+
* in the ReasoningBank. For failures, reduces confidence scores.
|
|
156
|
+
*/
|
|
157
|
+
async endTrajectory(verdict, bank) {
|
|
158
|
+
const rewardMap = {
|
|
159
|
+
success: 1.0,
|
|
160
|
+
partial: 0.5,
|
|
161
|
+
failure: -0.5
|
|
162
|
+
};
|
|
163
|
+
const reward = rewardMap[verdict] ?? 0;
|
|
164
|
+
// Record the completed trajectory
|
|
165
|
+
const completedTrajectory = {
|
|
166
|
+
steps: [...this.currentTrajectorySteps],
|
|
167
|
+
verdict,
|
|
168
|
+
timestamp: Date.now()
|
|
169
|
+
};
|
|
170
|
+
this.recordTrajectory(completedTrajectory);
|
|
171
|
+
// Update pattern confidences based on reward
|
|
172
|
+
let patternsUpdated = 0;
|
|
173
|
+
const allPatterns = bank.getAll();
|
|
174
|
+
for (const step of this.currentTrajectorySteps) {
|
|
175
|
+
if (!step.embedding || step.embedding.length === 0)
|
|
176
|
+
continue;
|
|
177
|
+
// Find patterns similar to this trajectory step
|
|
178
|
+
const similar = bank.findSimilar(step.embedding, {
|
|
179
|
+
k: 3,
|
|
180
|
+
threshold: 0.3
|
|
181
|
+
});
|
|
182
|
+
for (const match of similar) {
|
|
183
|
+
const pattern = bank.get(match.id);
|
|
184
|
+
if (!pattern)
|
|
185
|
+
continue;
|
|
186
|
+
// Adjust confidence: positive reward boosts, negative reduces
|
|
187
|
+
const delta = reward * 0.1; // small step per update
|
|
188
|
+
const newConfidence = Math.max(0.0, Math.min(1.0, pattern.confidence + delta));
|
|
189
|
+
pattern.confidence = newConfidence;
|
|
190
|
+
pattern.usageCount++;
|
|
191
|
+
pattern.lastUsedAt = Date.now();
|
|
192
|
+
patternsUpdated++;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Clear current trajectory
|
|
196
|
+
this.currentTrajectorySteps = [];
|
|
197
|
+
return { reward, patternsUpdated };
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Distill learning from recent successful trajectories.
|
|
201
|
+
* Applies LoRA-style confidence updates and integrates EWC++ consolidation.
|
|
202
|
+
*
|
|
203
|
+
* For each successful trajectory step with high confidence,
|
|
204
|
+
* increases the pattern's stored confidence by loraLearningRate * reward.
|
|
205
|
+
* Before applying updates, checks EWC penalty to prevent catastrophic forgetting.
|
|
206
|
+
*/
|
|
207
|
+
async distillLearning(bank) {
|
|
208
|
+
let patternsDistilled = 0;
|
|
209
|
+
let totalEwcPenalty = 0;
|
|
210
|
+
// Get recent successful trajectories
|
|
211
|
+
const recentSuccessful = this.trajectories.filter(t => t.verdict === 'success' || t.verdict === 'partial').slice(-10); // last 10 successful
|
|
212
|
+
if (recentSuccessful.length === 0) {
|
|
213
|
+
return { patternsDistilled: 0, ewcPenalty: 0 };
|
|
214
|
+
}
|
|
215
|
+
// Try to get EWC consolidator
|
|
216
|
+
let ewcConsolidator = null;
|
|
217
|
+
try {
|
|
218
|
+
const ewcModule = await import('./ewc-consolidation.js');
|
|
219
|
+
ewcConsolidator = await ewcModule.getEWCConsolidator({
|
|
220
|
+
lambda: this.config.ewcLambda
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// EWC not available, proceed without consolidation protection
|
|
225
|
+
}
|
|
226
|
+
const rewardMap = {
|
|
227
|
+
success: 1.0,
|
|
228
|
+
partial: 0.5
|
|
229
|
+
};
|
|
230
|
+
// Collect confidence changes for EWC Fisher update
|
|
231
|
+
const confidenceChanges = [];
|
|
232
|
+
for (const trajectory of recentSuccessful) {
|
|
233
|
+
const reward = rewardMap[trajectory.verdict] ?? 0;
|
|
234
|
+
for (const step of trajectory.steps) {
|
|
235
|
+
if (!step.embedding || step.embedding.length === 0)
|
|
236
|
+
continue;
|
|
237
|
+
const similar = bank.findSimilar(step.embedding, {
|
|
238
|
+
k: 3,
|
|
239
|
+
threshold: 0.4
|
|
240
|
+
});
|
|
241
|
+
for (const match of similar) {
|
|
242
|
+
const pattern = bank.get(match.id);
|
|
243
|
+
if (!pattern)
|
|
244
|
+
continue;
|
|
245
|
+
// Only distill from high-confidence matches
|
|
246
|
+
if (match.confidence < 0.5)
|
|
247
|
+
continue;
|
|
248
|
+
const oldConfidence = pattern.confidence;
|
|
249
|
+
// Check EWC penalty before applying update
|
|
250
|
+
if (ewcConsolidator) {
|
|
251
|
+
const oldWeights = [oldConfidence];
|
|
252
|
+
const proposedConfidence = Math.min(1.0, oldConfidence + this.config.loraLearningRate * reward);
|
|
253
|
+
const newWeights = [proposedConfidence];
|
|
254
|
+
const penalty = ewcConsolidator.getPenalty(oldWeights, newWeights);
|
|
255
|
+
totalEwcPenalty += penalty;
|
|
256
|
+
// If penalty is too high, reduce the update magnitude
|
|
257
|
+
if (penalty > this.config.ewcLambda) {
|
|
258
|
+
const dampedDelta = (this.config.loraLearningRate * reward) / (1 + penalty);
|
|
259
|
+
pattern.confidence = Math.max(0.0, Math.min(1.0, oldConfidence + dampedDelta));
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
pattern.confidence = proposedConfidence;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
// No EWC: apply full LoRA update
|
|
267
|
+
pattern.confidence = Math.max(0.0, Math.min(1.0, oldConfidence + this.config.loraLearningRate * reward));
|
|
268
|
+
}
|
|
269
|
+
pattern.lastUsedAt = Date.now();
|
|
270
|
+
patternsDistilled++;
|
|
271
|
+
confidenceChanges.push({
|
|
272
|
+
id: pattern.id,
|
|
273
|
+
oldConf: oldConfidence,
|
|
274
|
+
newConf: pattern.confidence,
|
|
275
|
+
embedding: pattern.embedding
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// Update EWC Fisher matrix with confidence changes
|
|
281
|
+
if (ewcConsolidator && confidenceChanges.length > 0) {
|
|
282
|
+
for (const change of confidenceChanges) {
|
|
283
|
+
// Use confidence delta as gradient proxy
|
|
284
|
+
const gradient = change.embedding.map(e => e * Math.abs(change.newConf - change.oldConf));
|
|
285
|
+
ewcConsolidator.recordGradient(change.id, gradient, true);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Persist updated patterns
|
|
289
|
+
bank.flushToDisk();
|
|
290
|
+
return { patternsDistilled, ewcPenalty: totalEwcPenalty };
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Get current trajectory steps (for inspection)
|
|
294
|
+
*/
|
|
295
|
+
getCurrentTrajectorySteps() {
|
|
296
|
+
return [...this.currentTrajectorySteps];
|
|
297
|
+
}
|
|
139
298
|
/**
|
|
140
299
|
* Get statistics
|
|
141
300
|
*/
|
|
@@ -478,6 +637,9 @@ export async function recordStep(step) {
|
|
|
478
637
|
metadata: step.metadata,
|
|
479
638
|
timestamp: step.timestamp || Date.now()
|
|
480
639
|
});
|
|
640
|
+
// Add to current trajectory for RL tracking
|
|
641
|
+
const stepWithEmbedding = { ...step, embedding };
|
|
642
|
+
sonaCoordinator.addTrajectoryStep(stepWithEmbedding);
|
|
481
643
|
// Store in ReasoningBank for retrieval
|
|
482
644
|
if (reasoningBank) {
|
|
483
645
|
reasoningBank.store({
|
|
@@ -489,6 +651,15 @@ export async function recordStep(step) {
|
|
|
489
651
|
metadata: step.metadata
|
|
490
652
|
});
|
|
491
653
|
}
|
|
654
|
+
// When a 'result' step arrives, end the trajectory and run RL loop
|
|
655
|
+
if (step.type === 'result' && reasoningBank) {
|
|
656
|
+
// Determine verdict from metadata or default to 'partial'
|
|
657
|
+
const verdict = step.metadata?.verdict || 'partial';
|
|
658
|
+
await sonaCoordinator.endTrajectory(verdict, reasoningBank);
|
|
659
|
+
// Distill learning from recent successful trajectories
|
|
660
|
+
await sonaCoordinator.distillLearning(reasoningBank);
|
|
661
|
+
globalStats.lastAdaptation = Date.now();
|
|
662
|
+
}
|
|
492
663
|
globalStats.trajectoriesRecorded++;
|
|
493
664
|
savePersistedStats();
|
|
494
665
|
return true;
|
|
@@ -512,6 +683,15 @@ export async function recordTrajectory(steps, verdict) {
|
|
|
512
683
|
verdict,
|
|
513
684
|
timestamp: Date.now()
|
|
514
685
|
});
|
|
686
|
+
// Apply RL: update pattern confidences based on verdict
|
|
687
|
+
if (reasoningBank) {
|
|
688
|
+
// Load steps into the coordinator for endTrajectory processing
|
|
689
|
+
for (const step of steps) {
|
|
690
|
+
sonaCoordinator.addTrajectoryStep(step);
|
|
691
|
+
}
|
|
692
|
+
await sonaCoordinator.endTrajectory(verdict, reasoningBank);
|
|
693
|
+
await sonaCoordinator.distillLearning(reasoningBank);
|
|
694
|
+
}
|
|
515
695
|
globalStats.trajectoriesRecorded++;
|
|
516
696
|
globalStats.lastAdaptation = Date.now();
|
|
517
697
|
savePersistedStats();
|
|
@@ -597,6 +777,51 @@ export function getSonaCoordinator() {
|
|
|
597
777
|
export function getReasoningBank() {
|
|
598
778
|
return reasoningBank;
|
|
599
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* End the current trajectory with a verdict and apply RL updates.
|
|
782
|
+
* This is the public API for the SONA RL loop.
|
|
783
|
+
*
|
|
784
|
+
* @param verdict - 'success' (reward=1.0), 'partial' (0.5), or 'failure' (-0.5)
|
|
785
|
+
* @returns Update statistics or null if not initialized
|
|
786
|
+
*/
|
|
787
|
+
export async function endTrajectoryWithVerdict(verdict) {
|
|
788
|
+
if (!sonaCoordinator || !reasoningBank) {
|
|
789
|
+
const init = await initializeIntelligence();
|
|
790
|
+
if (!init.success)
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
try {
|
|
794
|
+
const result = await sonaCoordinator.endTrajectory(verdict, reasoningBank);
|
|
795
|
+
globalStats.lastAdaptation = Date.now();
|
|
796
|
+
savePersistedStats();
|
|
797
|
+
return result;
|
|
798
|
+
}
|
|
799
|
+
catch {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Distill learning from recent successful trajectories.
|
|
805
|
+
* Applies LoRA-style confidence updates with EWC++ consolidation protection.
|
|
806
|
+
*
|
|
807
|
+
* @returns Distillation statistics or null if not initialized
|
|
808
|
+
*/
|
|
809
|
+
export async function distillLearning() {
|
|
810
|
+
if (!sonaCoordinator || !reasoningBank) {
|
|
811
|
+
const init = await initializeIntelligence();
|
|
812
|
+
if (!init.success)
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
try {
|
|
816
|
+
const result = await sonaCoordinator.distillLearning(reasoningBank);
|
|
817
|
+
globalStats.lastAdaptation = Date.now();
|
|
818
|
+
savePersistedStats();
|
|
819
|
+
return result;
|
|
820
|
+
}
|
|
821
|
+
catch {
|
|
822
|
+
return null;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
600
825
|
/**
|
|
601
826
|
* Clear intelligence state
|
|
602
827
|
*/
|
|
@@ -65,6 +65,12 @@ export declare function getHNSWStatus(): {
|
|
|
65
65
|
* Clear the HNSW index (for rebuilding)
|
|
66
66
|
*/
|
|
67
67
|
export declare function clearHNSWIndex(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Invalidate the in-memory HNSW cache so the next search rebuilds from DB.
|
|
70
|
+
* Call this after deleting entries that had embeddings to prevent ghost
|
|
71
|
+
* vectors from appearing in search results.
|
|
72
|
+
*/
|
|
73
|
+
export declare function rebuildSearchIndex(): void;
|
|
68
74
|
/**
|
|
69
75
|
* Quantize a Float32 embedding to Int8 (4x memory reduction)
|
|
70
76
|
* Uses symmetric quantization with scale factor stored per-vector
|
|
@@ -398,6 +404,7 @@ declare const _default: {
|
|
|
398
404
|
listEntries: typeof listEntries;
|
|
399
405
|
getEntry: typeof getEntry;
|
|
400
406
|
deleteEntry: typeof deleteEntry;
|
|
407
|
+
rebuildSearchIndex: typeof rebuildSearchIndex;
|
|
401
408
|
MEMORY_SCHEMA_V3: string;
|
|
402
409
|
getInitialMetadata: typeof getInitialMetadata;
|
|
403
410
|
};
|
|
@@ -573,6 +573,15 @@ export function getHNSWStatus() {
|
|
|
573
573
|
export function clearHNSWIndex() {
|
|
574
574
|
hnswIndex = null;
|
|
575
575
|
}
|
|
576
|
+
/**
|
|
577
|
+
* Invalidate the in-memory HNSW cache so the next search rebuilds from DB.
|
|
578
|
+
* Call this after deleting entries that had embeddings to prevent ghost
|
|
579
|
+
* vectors from appearing in search results.
|
|
580
|
+
*/
|
|
581
|
+
export function rebuildSearchIndex() {
|
|
582
|
+
hnswIndex = null;
|
|
583
|
+
hnswInitializing = false;
|
|
584
|
+
}
|
|
576
585
|
// ============================================================================
|
|
577
586
|
// INT8 VECTOR QUANTIZATION (4x memory reduction)
|
|
578
587
|
// ============================================================================
|
|
@@ -2051,10 +2060,15 @@ export async function deleteEntry(options) {
|
|
|
2051
2060
|
error: `Key '${key}' not found in namespace '${namespace}'`
|
|
2052
2061
|
};
|
|
2053
2062
|
}
|
|
2063
|
+
// Capture the entry ID for HNSW cleanup
|
|
2064
|
+
const entryId = String(checkResult[0].values[0][0]);
|
|
2054
2065
|
// Delete the entry (soft delete by setting status to 'deleted')
|
|
2066
|
+
// Also null out the embedding to clean up vector data from SQLite
|
|
2055
2067
|
db.run(`
|
|
2056
2068
|
UPDATE memory_entries
|
|
2057
|
-
SET status = 'deleted',
|
|
2069
|
+
SET status = 'deleted',
|
|
2070
|
+
embedding = NULL,
|
|
2071
|
+
updated_at = strftime('%s', 'now') * 1000
|
|
2058
2072
|
WHERE key = '${key.replace(/'/g, "''")}'
|
|
2059
2073
|
AND namespace = '${namespace.replace(/'/g, "''")}'
|
|
2060
2074
|
AND status = 'active'
|
|
@@ -2066,6 +2080,17 @@ export async function deleteEntry(options) {
|
|
|
2066
2080
|
const data = db.export();
|
|
2067
2081
|
fs.writeFileSync(dbPath, Buffer.from(data));
|
|
2068
2082
|
db.close();
|
|
2083
|
+
// Clean up in-memory HNSW index so ghost vectors don't appear in searches.
|
|
2084
|
+
// Remove the entry from the HNSW entries map and invalidate the index.
|
|
2085
|
+
// The next search will rebuild the HNSW index from the remaining DB rows.
|
|
2086
|
+
if (hnswIndex?.entries) {
|
|
2087
|
+
hnswIndex.entries.delete(entryId);
|
|
2088
|
+
saveHNSWMetadata();
|
|
2089
|
+
// Invalidate the HNSW index so it rebuilds from DB on next search.
|
|
2090
|
+
// We can't surgically remove a vector from the HNSW graph, so we
|
|
2091
|
+
// clear the entire index; it will be lazily rebuilt from SQLite.
|
|
2092
|
+
rebuildSearchIndex();
|
|
2093
|
+
}
|
|
2069
2094
|
return {
|
|
2070
2095
|
success: true,
|
|
2071
2096
|
deleted: true,
|
|
@@ -2099,6 +2124,7 @@ export default {
|
|
|
2099
2124
|
listEntries,
|
|
2100
2125
|
getEntry,
|
|
2101
2126
|
deleteEntry,
|
|
2127
|
+
rebuildSearchIndex,
|
|
2102
2128
|
MEMORY_SCHEMA_V3,
|
|
2103
2129
|
getInitialMetadata
|
|
2104
2130
|
};
|
|
@@ -27,6 +27,10 @@ export { SemanticRouter, createSemanticRouter, type Intent, type RouteResult, ty
|
|
|
27
27
|
* Check if ruvector packages are available
|
|
28
28
|
*/
|
|
29
29
|
export declare function isRuvectorAvailable(): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Check if @ruvector/learning-wasm is available and loadable
|
|
32
|
+
*/
|
|
33
|
+
export declare function isWasmBackendAvailable(): Promise<boolean>;
|
|
30
34
|
/**
|
|
31
35
|
* Get ruvector version if available
|
|
32
36
|
*/
|
|
@@ -45,6 +45,18 @@ export async function isRuvectorAvailable() {
|
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if @ruvector/learning-wasm is available and loadable
|
|
50
|
+
*/
|
|
51
|
+
export async function isWasmBackendAvailable() {
|
|
52
|
+
try {
|
|
53
|
+
const wasm = await import('@ruvector/learning-wasm');
|
|
54
|
+
return typeof wasm.WasmMicroLoRA === 'function' && typeof wasm.initSync === 'function';
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
48
60
|
/**
|
|
49
61
|
* Get ruvector version if available
|
|
50
62
|
*/
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
* Created with ❤️ by ruv.io
|
|
15
15
|
*/
|
|
16
16
|
type BenchmarkResult = any;
|
|
17
|
+
/**
|
|
18
|
+
* Get which backend is active for training
|
|
19
|
+
*/
|
|
20
|
+
export declare function getActiveBackend(): 'wasm' | 'js-fallback';
|
|
17
21
|
export interface TrainingConfig {
|
|
18
22
|
dim?: number;
|
|
19
23
|
learningRate?: number;
|
|
@@ -41,11 +45,14 @@ export interface TrainingResult {
|
|
|
41
45
|
benchmark?: BenchmarkResult[];
|
|
42
46
|
}
|
|
43
47
|
/**
|
|
44
|
-
* Initialize the RuVector training system
|
|
48
|
+
* Initialize the RuVector training system.
|
|
49
|
+
* Attempts to load @ruvector/learning-wasm for WASM-accelerated training.
|
|
50
|
+
* Falls back to a pure-JS implementation if WASM is unavailable.
|
|
45
51
|
*/
|
|
46
52
|
export declare function initializeTraining(config?: TrainingConfig): Promise<{
|
|
47
53
|
success: boolean;
|
|
48
54
|
features: string[];
|
|
55
|
+
backend: 'wasm' | 'js-fallback';
|
|
49
56
|
error?: string;
|
|
50
57
|
}>;
|
|
51
58
|
/**
|
|
@@ -177,6 +184,7 @@ export declare function sonaFlush(): void;
|
|
|
177
184
|
*/
|
|
178
185
|
export declare function getTrainingStats(): {
|
|
179
186
|
initialized: boolean;
|
|
187
|
+
backend: 'wasm' | 'js-fallback';
|
|
180
188
|
totalAdaptations: number;
|
|
181
189
|
totalForwards: number;
|
|
182
190
|
microLoraStats?: {
|