@ruvector/ruvllm 2.4.1 → 2.5.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 +158 -398
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/intelligence.d.ts +136 -0
- package/dist/cjs/intelligence.d.ts.map +1 -0
- package/dist/cjs/intelligence.js +226 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/intelligence.d.ts +136 -0
- package/dist/esm/intelligence.d.ts.map +1 -0
- package/dist/esm/intelligence.js +188 -0
- package/package.json +3 -7
- package/scripts/training/validation-results.json +1 -1
- package/dist/cjs/rlm/controller.d.ts +0 -245
- package/dist/cjs/rlm/controller.d.ts.map +0 -1
- package/dist/cjs/rlm/controller.js +0 -554
- package/dist/cjs/rlm/index.d.ts +0 -62
- package/dist/cjs/rlm/index.d.ts.map +0 -1
- package/dist/cjs/rlm/index.js +0 -97
- package/dist/cjs/rlm/training.d.ts +0 -333
- package/dist/cjs/rlm/training.d.ts.map +0 -1
- package/dist/cjs/rlm/training.js +0 -680
- package/dist/cjs/rlm/types.d.ts +0 -189
- package/dist/cjs/rlm/types.d.ts.map +0 -1
- package/dist/cjs/rlm/types.js +0 -10
- package/dist/esm/rlm/controller.d.ts +0 -245
- package/dist/esm/rlm/controller.d.ts.map +0 -1
- package/dist/esm/rlm/controller.js +0 -550
- package/dist/esm/rlm/index.d.ts +0 -62
- package/dist/esm/rlm/index.d.ts.map +0 -1
- package/dist/esm/rlm/index.js +0 -71
- package/dist/esm/rlm/training.d.ts +0 -333
- package/dist/esm/rlm/training.d.ts.map +0 -1
- package/dist/esm/rlm/training.js +0 -672
- package/dist/esm/rlm/types.d.ts +0 -189
- package/dist/esm/rlm/types.d.ts.map +0 -1
- package/dist/esm/rlm/types.js +0 -9
- package/scripts/training/rlm-dataset.js +0 -671
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Intelligence Providers for SONA Learning (ADR-043)
|
|
3
|
+
*
|
|
4
|
+
* TypeScript bindings for the IntelligenceProvider trait, enabling
|
|
5
|
+
* external systems to feed quality signals into RuvLLM's learning loops.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { IntelligenceLoader, FileSignalProvider, QualitySignal } from '@ruvector/ruvllm';
|
|
10
|
+
*
|
|
11
|
+
* const loader = new IntelligenceLoader();
|
|
12
|
+
* loader.registerProvider(new FileSignalProvider('./signals.json'));
|
|
13
|
+
*
|
|
14
|
+
* const { signals, errors } = loader.loadAllSignals();
|
|
15
|
+
* console.log(`Loaded ${signals.length} signals`);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import * as fs from 'fs';
|
|
19
|
+
import * as path from 'path';
|
|
20
|
+
/** Maximum signal file size (10 MiB) */
|
|
21
|
+
const MAX_SIGNAL_FILE_SIZE = 10 * 1024 * 1024;
|
|
22
|
+
/** Maximum number of signals per file */
|
|
23
|
+
const MAX_SIGNALS_PER_FILE = 10000;
|
|
24
|
+
/** Valid outcome values */
|
|
25
|
+
const VALID_OUTCOMES = new Set(['success', 'partial_success', 'failure']);
|
|
26
|
+
/** Valid human verdict values */
|
|
27
|
+
const VALID_VERDICTS = new Set(['approved', 'rejected']);
|
|
28
|
+
function asOptionalNumber(val) {
|
|
29
|
+
if (val === undefined || val === null)
|
|
30
|
+
return undefined;
|
|
31
|
+
const n = Number(val);
|
|
32
|
+
return Number.isFinite(n) && n >= 0 && n <= 1 ? n : undefined;
|
|
33
|
+
}
|
|
34
|
+
function validateOutcome(val) {
|
|
35
|
+
const s = String(val ?? 'failure');
|
|
36
|
+
return VALID_OUTCOMES.has(s) ? s : 'failure';
|
|
37
|
+
}
|
|
38
|
+
function validateVerdict(val) {
|
|
39
|
+
if (val === undefined || val === null)
|
|
40
|
+
return undefined;
|
|
41
|
+
const s = String(val);
|
|
42
|
+
return VALID_VERDICTS.has(s) ? s : undefined;
|
|
43
|
+
}
|
|
44
|
+
function validateScore(val) {
|
|
45
|
+
const n = Number(val ?? 0);
|
|
46
|
+
if (!Number.isFinite(n) || n < 0 || n > 1)
|
|
47
|
+
return 0;
|
|
48
|
+
return n;
|
|
49
|
+
}
|
|
50
|
+
function mapQualityFactors(raw) {
|
|
51
|
+
return {
|
|
52
|
+
acceptanceCriteriaMet: asOptionalNumber(raw.acceptance_criteria_met),
|
|
53
|
+
testsPassing: asOptionalNumber(raw.tests_passing),
|
|
54
|
+
noRegressions: asOptionalNumber(raw.no_regressions),
|
|
55
|
+
lintClean: asOptionalNumber(raw.lint_clean),
|
|
56
|
+
typeCheckClean: asOptionalNumber(raw.type_check_clean),
|
|
57
|
+
followsPatterns: asOptionalNumber(raw.follows_patterns),
|
|
58
|
+
contextRelevance: asOptionalNumber(raw.context_relevance),
|
|
59
|
+
reasoningCoherence: asOptionalNumber(raw.reasoning_coherence),
|
|
60
|
+
executionEfficiency: asOptionalNumber(raw.execution_efficiency),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Built-in file-based intelligence provider.
|
|
65
|
+
*
|
|
66
|
+
* Reads quality signals from a JSON file. This is the default provider
|
|
67
|
+
* for non-Rust integrations that write signal files.
|
|
68
|
+
*/
|
|
69
|
+
export class FileSignalProvider {
|
|
70
|
+
constructor(filePath) {
|
|
71
|
+
this.filePath = path.resolve(filePath);
|
|
72
|
+
}
|
|
73
|
+
name() {
|
|
74
|
+
return 'file-signals';
|
|
75
|
+
}
|
|
76
|
+
loadSignals() {
|
|
77
|
+
if (!fs.existsSync(this.filePath)) {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
// Check file size before reading (prevent OOM)
|
|
81
|
+
const stat = fs.statSync(this.filePath);
|
|
82
|
+
if (stat.size > MAX_SIGNAL_FILE_SIZE) {
|
|
83
|
+
throw new Error(`Signal file exceeds max size (${stat.size} bytes, limit ${MAX_SIGNAL_FILE_SIZE})`);
|
|
84
|
+
}
|
|
85
|
+
const raw = fs.readFileSync(this.filePath, 'utf-8');
|
|
86
|
+
const data = JSON.parse(raw);
|
|
87
|
+
if (!Array.isArray(data)) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
// Check signal count
|
|
91
|
+
if (data.length > MAX_SIGNALS_PER_FILE) {
|
|
92
|
+
throw new Error(`Signal file contains ${data.length} signals, max is ${MAX_SIGNALS_PER_FILE}`);
|
|
93
|
+
}
|
|
94
|
+
return data.map((item) => {
|
|
95
|
+
const qfRaw = (item.quality_factors ?? item.qualityFactors);
|
|
96
|
+
return {
|
|
97
|
+
id: String(item.id ?? ''),
|
|
98
|
+
taskDescription: String(item.task_description ?? item.taskDescription ?? ''),
|
|
99
|
+
outcome: validateOutcome(item.outcome),
|
|
100
|
+
qualityScore: validateScore(item.quality_score ?? item.qualityScore),
|
|
101
|
+
humanVerdict: validateVerdict(item.human_verdict ?? item.humanVerdict),
|
|
102
|
+
qualityFactors: qfRaw ? mapQualityFactors(qfRaw) : undefined,
|
|
103
|
+
completedAt: String(item.completed_at ?? item.completedAt ?? new Date().toISOString()),
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
qualityWeights() {
|
|
108
|
+
try {
|
|
109
|
+
const weightsPath = path.join(path.dirname(this.filePath), 'quality-weights.json');
|
|
110
|
+
if (!fs.existsSync(weightsPath))
|
|
111
|
+
return undefined;
|
|
112
|
+
const raw = fs.readFileSync(weightsPath, 'utf-8');
|
|
113
|
+
const data = JSON.parse(raw);
|
|
114
|
+
return {
|
|
115
|
+
taskCompletion: Number(data.task_completion ?? data.taskCompletion ?? 0.5),
|
|
116
|
+
codeQuality: Number(data.code_quality ?? data.codeQuality ?? 0.3),
|
|
117
|
+
process: Number(data.process ?? 0.2),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Aggregates quality signals from multiple registered providers.
|
|
127
|
+
*
|
|
128
|
+
* If no providers are registered, loadAllSignals returns empty arrays
|
|
129
|
+
* with zero overhead.
|
|
130
|
+
*/
|
|
131
|
+
export class IntelligenceLoader {
|
|
132
|
+
constructor() {
|
|
133
|
+
this.providers = [];
|
|
134
|
+
}
|
|
135
|
+
/** Register an external intelligence provider */
|
|
136
|
+
registerProvider(provider) {
|
|
137
|
+
this.providers.push(provider);
|
|
138
|
+
}
|
|
139
|
+
/** Returns the number of registered providers */
|
|
140
|
+
get providerCount() {
|
|
141
|
+
return this.providers.length;
|
|
142
|
+
}
|
|
143
|
+
/** Returns the names of all registered providers */
|
|
144
|
+
get providerNames() {
|
|
145
|
+
return this.providers.map(p => p.name());
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Load signals from all registered providers.
|
|
149
|
+
*
|
|
150
|
+
* Non-fatal: if a provider fails, its error is captured but
|
|
151
|
+
* other providers continue loading.
|
|
152
|
+
*/
|
|
153
|
+
loadAllSignals() {
|
|
154
|
+
const signals = [];
|
|
155
|
+
const errors = [];
|
|
156
|
+
for (const provider of this.providers) {
|
|
157
|
+
try {
|
|
158
|
+
const providerSignals = provider.loadSignals();
|
|
159
|
+
signals.push(...providerSignals);
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
errors.push({
|
|
163
|
+
providerName: provider.name(),
|
|
164
|
+
message: e instanceof Error ? e.message : String(e),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { signals, errors };
|
|
169
|
+
}
|
|
170
|
+
/** Load signals grouped by provider with weight overrides */
|
|
171
|
+
loadGrouped() {
|
|
172
|
+
return this.providers.map(provider => {
|
|
173
|
+
let providerSignals = [];
|
|
174
|
+
try {
|
|
175
|
+
providerSignals = provider.loadSignals();
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Non-fatal
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
providerName: provider.name(),
|
|
182
|
+
signals: providerSignals,
|
|
183
|
+
weights: provider.qualityWeights?.(),
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWxsaWdlbmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludGVsbGlnZW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBRTdCLHdDQUF3QztBQUN4QyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBRTlDLHlDQUF5QztBQUN6QyxNQUFNLG9CQUFvQixHQUFHLEtBQU0sQ0FBQztBQUVwQywyQkFBMkI7QUFDM0IsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUUxRSxpQ0FBaUM7QUFDakMsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztBQXNGekQsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFZO0lBQ3BDLElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssSUFBSTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3hELE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN0QixPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNoRSxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsR0FBWTtJQUNuQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxDQUFDO0lBQ25DLE9BQU8sY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFD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bGlnZW5jZSBQcm92aWRlcnMgZm9yIFNPTkEgTGVhcm5pbmcgKEFEUi0wNDMpXG4gKlxuICogVHlwZVNjcmlwdCBiaW5kaW5ncyBmb3IgdGhlIEludGVsbGlnZW5jZVByb3ZpZGVyIHRyYWl0LCBlbmFibGluZ1xuICogZXh0ZXJuYWwgc3lzdGVtcyB0byBmZWVkIHF1YWxpdHkgc2lnbmFscyBpbnRvIFJ1dkxMTSdzIGxlYXJuaW5nIGxvb3BzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBJbnRlbGxpZ2VuY2VMb2FkZXIsIEZpbGVTaWduYWxQcm92aWRlciwgUXVhbGl0eVNpZ25hbCB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IGxvYWRlciA9IG5ldyBJbnRlbGxpZ2VuY2VMb2FkZXIoKTtcbiAqIGxvYWRlci5yZWdpc3RlclByb3ZpZGVyKG5ldyBGaWxlU2lnbmFsUHJvdmlkZXIoJy4vc2lnbmFscy5qc29uJykpO1xuICpcbiAqIGNvbnN0IHsgc2lnbmFscywgZXJyb3JzIH0gPSBsb2FkZXIubG9hZEFsbFNpZ25hbHMoKTtcbiAqIGNvbnNvbGUubG9nKGBMb2FkZWQgJHtzaWduYWxzLmxlbmd0aH0gc2lnbmFsc2ApO1xuICogYGBgXG4gKi9cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuLyoqIE1heGltdW0gc2lnbmFsIGZpbGUgc2l6ZSAoMTAgTWlCKSAqL1xuY29uc3QgTUFYX1NJR05BTF9GSUxFX1NJWkUgPSAxMCAqIDEwMjQgKiAxMDI0O1xuXG4vKiogTWF4aW11bSBudW1iZXIgb2Ygc2lnbmFscyBwZXIgZmlsZSAqL1xuY29uc3QgTUFYX1NJR05BTFNfUEVSX0ZJTEUgPSAxMF8wMDA7XG5cbi8qKiBWYWxpZCBvdXRjb21lIHZhbHVlcyAqL1xuY29uc3QgVkFMSURfT1VUQ09NRVMgPSBuZXcgU2V0KFsnc3VjY2VzcycsICdwYXJ0aWFsX3N1Y2Nlc3MnLCAnZmFpbHVyZSddKTtcblxuLyoqIFZhbGlkIGh1bWFuIHZlcmRpY3QgdmFsdWVzICovXG5jb25zdCBWQUxJRF9WRVJESUNUUyA9IG5ldyBTZXQoWydhcHByb3ZlZCcsICdyZWplY3RlZCddKTtcblxuLyoqXG4gKiBBIHF1YWxpdHkgc2lnbmFsIGZyb20gYW4gZXh0ZXJuYWwgc3lzdGVtLlxuICpcbiAqIFJlcHJlc2VudHMgb25lIGNvbXBsZXRlZCB0YXNrIHdpdGggcXVhbGl0eSBhc3Nlc3NtZW50IGRhdGFcbiAqIHRoYXQgY2FuIGZlZWQgaW50byBTT05BIHRyYWplY3RvcmllcywgdGhlIGVtYmVkZGluZyBjbGFzc2lmaWVyLFxuICogYW5kIG1vZGVsIHJvdXRlciBjYWxpYnJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdWFsaXR5U2lnbmFsIHtcbiAgLyoqIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGlzIHNpZ25hbCAqL1xuICBpZDogc3RyaW5nO1xuICAvKiogSHVtYW4tcmVhZGFibGUgdGFzayBkZXNjcmlwdGlvbiAodXNlZCBmb3IgZW1iZWRkaW5nIGdlbmVyYXRpb24pICovXG4gIHRhc2tEZXNjcmlwdGlvbjogc3RyaW5nO1xuICAvKiogRXhlY3V0aW9uIG91dGNvbWUgKi9cbiAgb3V0Y29tZTogJ3N1Y2Nlc3MnIHwgJ3BhcnRpYWxfc3VjY2VzcycgfCAnZmFpbHVyZSc7XG4gIC8qKiBDb21wb3NpdGUgcXVhbGl0eSBzY29yZSAoMC4wIC0gMS4wKSAqL1xuICBxdWFsaXR5U2NvcmU6IG51bWJlcjtcbiAgLyoqIE9wdGlvbmFsIGh1bWFuIHZlcmRpY3QgKi9cbiAgaHVtYW5WZXJkaWN0PzogJ2FwcHJvdmVkJyB8ICdyZWplY3RlZCc7XG4gIC8qKiBPcHRpb25hbCBzdHJ1Y3R1cmVkIHF1YWxpdHkgZmFjdG9ycyBmb3IgZGV0YWlsZWQgYW5hbHlzaXMgKi9cbiAgcXVhbGl0eUZhY3RvcnM/OiBRdWFsaXR5RmFjdG9ycztcbiAgLyoqIElTTyA4NjAxIHRpbWVzdGFtcCBvZiB0YXNrIGNvbXBsZXRpb24gKi9cbiAgY29tcGxldGVkQXQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBHcmFudWxhciBxdWFsaXR5IGZhY3RvciBicmVha2Rvd24uXG4gKlxuICogTm90IGFsbCBwcm92aWRlcnMgd2lsbCBoYXZlIGFsbCBmYWN0b3JzLiBVbmRlZmluZWQgZmllbGRzIG1lYW5cbiAqIFwibm90IGFzc2Vzc2VkXCIgKGRpc3RpbmN0IGZyb20gMC4wLCB3aGljaCBtZWFucyBcImFzc2Vzc2VkIGFzIHplcm9cIikuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVhbGl0eUZhY3RvcnMge1xuICBhY2NlcHRhbmNlQ3JpdGVyaWFNZXQ/OiBudW1iZXI7XG4gIHRlc3RzUGFzc2luZz86IG51bWJlcjtcbiAgbm9SZWdyZXNzaW9ucz86IG51bWJlcjtcbiAgbGludENsZWFuPzogbnVtYmVyO1xuICB0eXBlQ2hlY2tDbGVhbj86IG51bWJlcjtcbiAgZm9sbG93c1BhdHRlcm5zPzogbnVtYmVyO1xuICBjb250ZXh0UmVsZXZhbmNlPzogbnVtYmVyO1xuICByZWFzb25pbmdDb2hlcmVuY2U/OiBudW1iZXI7XG4gIGV4ZWN1dGlvbkVmZmljaWVuY3k/OiBudW1iZXI7XG59XG5cbi8qKlxuICogUXVhbGl0eSB3ZWlnaHQgb3ZlcnJpZGVzIGZyb20gYSBwcm92aWRlci5cbiAqXG4gKiBXZWlnaHRzIHNob3VsZCBzdW0gdG8gYXBwcm94aW1hdGVseSAxLjAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlkZXJRdWFsaXR5V2VpZ2h0cyB7XG4gIHRhc2tDb21wbGV0aW9uOiBudW1iZXI7XG4gIGNvZGVRdWFsaXR5OiBudW1iZXI7XG4gIHByb2Nlc3M6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBFcnJvciBmcm9tIGEgc2luZ2xlIHByb3ZpZGVyIGR1cmluZyBiYXRjaCBsb2FkaW5nLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3ZpZGVyRXJyb3Ige1xuICBwcm92aWRlck5hbWU6IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlc3VsdCBmcm9tIGEgc2luZ2xlIHByb3ZpZGVyIGR1cmluZyBncm91cGVkIGxvYWRpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlkZXJSZXN1bHQge1xuICBwcm92aWRlck5hbWU6IHN0cmluZztcbiAgc2lnbmFsczogUXVhbGl0eVNpZ25hbFtdO1xuICB3ZWlnaHRzPzogUHJvdmlkZXJRdWFsaXR5V2VpZ2h0cztcbn1cblxuLyoqXG4gKiBJbnRlcmZhY2UgZm9yIGV4dGVybmFsIHN5c3RlbXMgdGhhdCBzdXBwbHkgcXVhbGl0eSBzaWduYWxzIHRvIFJ1dkxMTS5cbiAqXG4gKiBJbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UgYW5kIHJlZ2lzdGVyIHdpdGggSW50ZWxsaWdlbmNlTG9hZGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEludGVsbGlnZW5jZVByb3ZpZGVyIHtcbiAgLyoqIEh1bWFuLXJlYWRhYmxlIG5hbWUgZm9yIHRoaXMgcHJvdmlkZXIgKi9cbiAgbmFtZSgpOiBzdHJpbmc7XG4gIC8qKiBMb2FkIHF1YWxpdHkgc2lnbmFscyBmcm9tIHRoaXMgcHJvdmlkZXIncyBkYXRhIHNvdXJjZSAqL1xuICBsb2FkU2lnbmFscygpOiBRdWFsaXR5U2lnbmFsW107XG4gIC8qKiBPcHRpb25hbCBxdWFsaXR5IHdlaWdodCBvdmVycmlkZXMgKi9cbiAgcXVhbGl0eVdlaWdodHM/KCk6IFByb3ZpZGVyUXVhbGl0eVdlaWdodHMgfCB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGFzT3B0aW9uYWxOdW1iZXIodmFsOiB1bmtub3duKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA9PT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgbiA9IE51bWJlcih2YWwpO1xuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG4pICYmIG4gPj0gMCAmJiBuIDw9IDEgPyBuIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZU91dGNvbWUodmFsOiB1bmtub3duKTogUXVhbGl0eVNpZ25hbFsnb3V0Y29tZSddIHtcbiAgY29uc3QgcyA9IFN0cmluZyh2YWwgPz8gJ2ZhaWx1cmUnKTtcbiAgcmV0dXJuIFZBTElEX09VVENPTUVTLmhhcyhzKSA/IHMgYXMgUXVhbGl0eVNpZ25hbFsnb3V0Y29tZSddIDogJ2ZhaWx1cmUnO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVZlcmRpY3QodmFsOiB1bmtub3duKTogUXVhbGl0eVNpZ25hbFsnaHVtYW5WZXJkaWN0J10gfCB1bmRlZmluZWQge1xuICBpZiAodmFsID09PSB1bmRlZmluZWQgfHwgdmFsID09PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBzID0gU3RyaW5nKHZhbCk7XG4gIHJldHVybiBWQUxJRF9WRVJESUNUUy5oYXMocykgPyBzIGFzIFF1YWxpdHlTaWduYWxbJ2h1bWFuVmVyZGljdCddIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVNjb3JlKHZhbDogdW5rbm93bik6IG51bWJlciB7XG4gIGNvbnN0IG4gPSBOdW1iZXIodmFsID8/IDApO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShuKSB8fCBuIDwgMCB8fCBuID4gMSkgcmV0dXJuIDA7XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBtYXBRdWFsaXR5RmFjdG9ycyhyYXc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUXVhbGl0eUZhY3RvcnMge1xuICByZXR1cm4ge1xuICAgIGFjY2VwdGFuY2VDcml0ZXJpYU1ldDogYXNPcHRpb25hbE51bWJlcihyYXcuYWNjZXB0YW5jZV9jcml0ZXJpYV9tZXQpLFxuICAgIHRlc3RzUGFzc2luZzogYXNPcHRpb25hbE51bWJlcihyYXcudGVzdHNfcGFzc2luZyksXG4gICAgbm9SZWdyZXNzaW9uczogYXNPcHRpb25hbE51bWJlcihyYXcubm9fcmVncmVzc2lvbnMpLFxuICAgIGxpbnRDbGVhbjogYXNPcHRpb25hbE51bWJlcihyYXcubGludF9jbGVhbiksXG4gICAgdHlwZUNoZWNrQ2xlYW46IGFzT3B0aW9uYWxOdW1iZXIocmF3LnR5cGVfY2hlY2tfY2xlYW4pLFxuICAgIGZvbGxvd3NQYXR0ZXJuczogYXNPcHRpb25hbE51bWJlcihyYXcuZm9sbG93c19wYXR0ZXJucyksXG4gICAgY29udGV4dFJlbGV2YW5jZTogYXNPcHRpb25hbE51bWJlcihyYXcuY29udGV4dF9yZWxldmFuY2UpLFxuICAgIHJlYXNvbmluZ0NvaGVyZW5jZTogYXNPcHRpb25hbE51bWJlcihyYXcucmVhc29uaW5nX2NvaGVyZW5jZSksXG4gICAgZXhlY3V0aW9uRWZmaWNpZW5jeTogYXNPcHRpb25hbE51bWJlcihyYXcuZXhlY3V0aW9uX2VmZmljaWVuY3kpLFxuICB9O1xufVxuXG4vKipcbiAqIEJ1aWx0LWluIGZpbGUtYmFzZWQgaW50ZWxsaWdlbmNlIHByb3ZpZGVyLlxuICpcbiAqIFJlYWRzIHF1YWxpdHkgc2lnbmFscyBmcm9tIGEgSlNPTiBmaWxlLiBUaGlzIGlzIHRoZSBkZWZhdWx0IHByb3ZpZGVyXG4gKiBmb3Igbm9uLVJ1c3QgaW50ZWdyYXRpb25zIHRoYXQgd3JpdGUgc2lnbmFsIGZpbGVzLlxuICovXG5leHBvcnQgY2xhc3MgRmlsZVNpZ25hbFByb3ZpZGVyIGltcGxlbWVudHMgSW50ZWxsaWdlbmNlUHJvdmlkZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoZmlsZVBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuZmlsZVBhdGggPSBwYXRoLnJlc29sdmUoZmlsZVBhdGgpO1xuICB9XG5cbiAgbmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnZmlsZS1zaWduYWxzJztcbiAgfVxuXG4gIGxvYWRTaWduYWxzKCk6IFF1YWxpdHlTaWduYWxbXSB7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMuZmlsZVBhdGgpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBzaXplIGJlZm9yZSByZWFkaW5nIChwcmV2ZW50IE9PTSlcbiAgICBjb25zdCBzdGF0ID0gZnMuc3RhdFN5bmModGhpcy5maWxlUGF0aCk7XG4gICAgaWYgKHN0YXQuc2l6ZSA+IE1BWF9TSUdOQUxfRklMRV9TSVpFKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBTaWduYWwgZmlsZSBleGNlZWRzIG1heCBzaXplICgke3N0YXQuc2l6ZX0gYnl0ZXMsIGxpbWl0ICR7TUFYX1NJR05BTF9GSUxFX1NJWkV9KWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcmF3ID0gZnMucmVhZEZpbGVTeW5jKHRoaXMuZmlsZVBhdGgsICd1dGYtOCcpO1xuICAgIGNvbnN0IGRhdGE6IHVua25vd24gPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgc2lnbmFsIGNvdW50XG4gICAgaWYgKGRhdGEubGVuZ3RoID4gTUFYX1NJR05BTFNfUEVSX0ZJTEUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFNpZ25hbCBmaWxlIGNvbnRhaW5zICR7ZGF0YS5sZW5ndGh9IHNpZ25hbHMsIG1heCBpcyAke01BWF9TSUdOQUxTX1BFUl9GSUxFfWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGEubWFwKChpdGVtOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgY29uc3QgcWZSYXcgPSAoaXRlbS5xdWFsaXR5X2ZhY3RvcnMgPz8gaXRlbS5xdWFsaXR5RmFjdG9ycykgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZDogU3RyaW5nKGl0ZW0uaWQgPz8gJycpLFxuICAgICAgICB0YXNrRGVzY3JpcHRpb246IFN0cmluZyhpdGVtLnRhc2tfZGVzY3JpcHRpb24gPz8gaXRlbS50YXNrRGVzY3JpcHRpb24gPz8gJycpLFxuICAgICAgICBvdXRjb21lOiB2YWxpZGF0ZU91dGNvbWUoaXRlbS5vdXRjb21lKSxcbiAgICAgICAgcXVhbGl0eVNjb3JlOiB2YWxpZGF0ZVNjb3JlKGl0ZW0ucXVhbGl0eV9zY29yZSA/PyBpdGVtLnF1YWxpdHlTY29yZSksXG4gICAgICAgIGh1bWFuVmVyZGljdDogdmFsaWRhdGVWZXJkaWN0KGl0ZW0uaHVtYW5fdmVyZGljdCA/PyBpdGVtLmh1bWFuVmVyZGljdCksXG4gICAgICAgIHF1YWxpdHlGYWN0b3JzOiBxZlJhdyA/IG1hcFF1YWxpdHlGYWN0b3JzKHFmUmF3KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgY29tcGxldGVkQXQ6IFN0cmluZyhpdGVtLmNvbXBsZXRlZF9hdCA/PyBpdGVtLmNvbXBsZXRlZEF0ID8/IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSksXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcXVhbGl0eVdlaWdodHMoKTogUHJvdmlkZXJRdWFsaXR5V2VpZ2h0cyB8IHVuZGVmaW5lZCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHdlaWdodHNQYXRoID0gcGF0aC5qb2luKHBhdGguZGlybmFtZSh0aGlzLmZpbGVQYXRoKSwgJ3F1YWxpdHktd2VpZ2h0cy5qc29uJyk7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMod2VpZ2h0c1BhdGgpKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgcmF3ID0gZnMucmVhZEZpbGVTeW5jKHdlaWdodHNQYXRoLCAndXRmLTgnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKHJhdykgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0YXNrQ29tcGxldGlvbjogTnVtYmVyKGRhdGEudGFza19jb21wbGV0aW9uID8/IGRhdGEudGFza0NvbXBsZXRpb24gPz8gMC41KSxcbiAgICAgICAgY29kZVF1YWxpdHk6IE51bWJlcihkYXRhLmNvZGVfcXVhbGl0eSA/PyBkYXRhLmNvZGVRdWFsaXR5ID8/IDAuMyksXG4gICAgICAgIHByb2Nlc3M6IE51bWJlcihkYXRhLnByb2Nlc3MgPz8gMC4yKSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEFnZ3JlZ2F0ZXMgcXVhbGl0eSBzaWduYWxzIGZyb20gbXVsdGlwbGUgcmVnaXN0ZXJlZCBwcm92aWRlcnMuXG4gKlxuICogSWYgbm8gcHJvdmlkZXJzIGFyZSByZWdpc3RlcmVkLCBsb2FkQWxsU2lnbmFscyByZXR1cm5zIGVtcHR5IGFycmF5c1xuICogd2l0aCB6ZXJvIG92ZXJoZWFkLlxuICovXG5leHBvcnQgY2xhc3MgSW50ZWxsaWdlbmNlTG9hZGVyIHtcbiAgcHJpdmF0ZSBwcm92aWRlcnM6IEludGVsbGlnZW5jZVByb3ZpZGVyW10gPSBbXTtcblxuICAvKiogUmVnaXN0ZXIgYW4gZXh0ZXJuYWwgaW50ZWxsaWdlbmNlIHByb3ZpZGVyICovXG4gIHJlZ2lzdGVyUHJvdmlkZXIocHJvdmlkZXI6IEludGVsbGlnZW5jZVByb3ZpZGVyKTogdm9pZCB7XG4gICAgdGhpcy5wcm92aWRlcnMucHVzaChwcm92aWRlcik7XG4gIH1cblxuICAvKiogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHJlZ2lzdGVyZWQgcHJvdmlkZXJzICovXG4gIGdldCBwcm92aWRlckNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucHJvdmlkZXJzLmxlbmd0aDtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiBhbGwgcmVnaXN0ZXJlZCBwcm92aWRlcnMgKi9cbiAgZ2V0IHByb3ZpZGVyTmFtZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLnByb3ZpZGVycy5tYXAocCA9PiBwLm5hbWUoKSk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBzaWduYWxzIGZyb20gYWxsIHJlZ2lzdGVyZWQgcHJvdmlkZXJzLlxuICAgKlxuICAgKiBOb24tZmF0YWw6IGlmIGEgcHJvdmlkZXIgZmFpbHMsIGl0cyBlcnJvciBpcyBjYXB0dXJlZCBidXRcbiAgICogb3RoZXIgcHJvdmlkZXJzIGNvbnRpbnVlIGxvYWRpbmcuXG4gICAqL1xuICBsb2FkQWxsU2lnbmFscygpOiB7IHNpZ25hbHM6IFF1YWxpdHlTaWduYWxbXTsgZXJyb3JzOiBQcm92aWRlckVycm9yW10gfSB7XG4gICAgY29uc3Qgc2lnbmFsczogUXVhbGl0eVNpZ25hbFtdID0gW107XG4gICAgY29uc3QgZXJyb3JzOiBQcm92aWRlckVycm9yW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgcHJvdmlkZXIgb2YgdGhpcy5wcm92aWRlcnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyU2lnbmFscyA9IHByb3ZpZGVyLmxvYWRTaWduYWxzKCk7XG4gICAgICAgIHNpZ25hbHMucHVzaCguLi5wcm92aWRlclNpZ25hbHMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgICAgcHJvdmlkZXJOYW1lOiBwcm92aWRlci5uYW1lKCksXG4gICAgICAgICAgbWVzc2FnZTogZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogU3RyaW5nKGUpLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBzaWduYWxzLCBlcnJvcnMgfTtcbiAgfVxuXG4gIC8qKiBMb2FkIHNpZ25hbHMgZ3JvdXBlZCBieSBwcm92aWRlciB3aXRoIHdlaWdodCBvdmVycmlkZXMgKi9cbiAgbG9hZEdyb3VwZWQoKTogUHJvdmlkZXJSZXN1bHRbXSB7XG4gICAgcmV0dXJuIHRoaXMucHJvdmlkZXJzLm1hcChwcm92aWRlciA9PiB7XG4gICAgICBsZXQgcHJvdmlkZXJTaWduYWxzOiBRdWFsaXR5U2lnbmFsW10gPSBbXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHByb3ZpZGVyU2lnbmFscyA9IHByb3ZpZGVyLmxvYWRTaWduYWxzKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gTm9uLWZhdGFsXG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcm92aWRlck5hbWU6IHByb3ZpZGVyLm5hbWUoKSxcbiAgICAgICAgc2lnbmFsczogcHJvdmlkZXJTaWduYWxzLFxuICAgICAgICB3ZWlnaHRzOiBwcm92aWRlci5xdWFsaXR5V2VpZ2h0cz8uKCksXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruvector/ruvllm",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Self-learning LLM orchestration with SONA adaptive learning, HNSW memory,
|
|
3
|
+
"version": "2.5.1",
|
|
4
|
+
"description": "Self-learning LLM orchestration with SONA adaptive learning, HNSW memory, FastGRNN routing, and SIMD inference",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
7
7
|
"types": "dist/cjs/index.d.ts",
|
|
@@ -74,8 +74,6 @@
|
|
|
74
74
|
"keywords": [
|
|
75
75
|
"ruvllm",
|
|
76
76
|
"llm",
|
|
77
|
-
"rlm",
|
|
78
|
-
"retrieval-language-model",
|
|
79
77
|
"self-learning",
|
|
80
78
|
"adaptive-learning",
|
|
81
79
|
"sona",
|
|
@@ -94,9 +92,7 @@
|
|
|
94
92
|
"deep-learning",
|
|
95
93
|
"napi",
|
|
96
94
|
"rust",
|
|
97
|
-
"ruvector"
|
|
98
|
-
"rag",
|
|
99
|
-
"contrastive-learning"
|
|
95
|
+
"ruvector"
|
|
100
96
|
],
|
|
101
97
|
"author": "rUv Team <team@ruv.io>",
|
|
102
98
|
"license": "MIT OR Apache-2.0",
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RLM Controller - Recursive Retrieval Language Model
|
|
3
|
-
*
|
|
4
|
-
* Implements a recursive retrieval-augmented generation system that:
|
|
5
|
-
* 1. Breaks down complex queries into sub-queries
|
|
6
|
-
* 2. Retrieves relevant memory spans for each query
|
|
7
|
-
* 3. Synthesizes coherent answers from retrieved context
|
|
8
|
-
* 4. Optionally reflects on and refines answers
|
|
9
|
-
*
|
|
10
|
-
* @example Basic Usage
|
|
11
|
-
* ```typescript
|
|
12
|
-
* import { RlmController } from '@ruvector/ruvllm';
|
|
13
|
-
*
|
|
14
|
-
* const rlm = new RlmController({
|
|
15
|
-
* maxDepth: 3,
|
|
16
|
-
* retrievalTopK: 10,
|
|
17
|
-
* enableCache: true,
|
|
18
|
-
* });
|
|
19
|
-
*
|
|
20
|
-
* // Add knowledge to memory
|
|
21
|
-
* await rlm.addMemory('Machine learning is a subset of AI that enables systems to learn from data.');
|
|
22
|
-
* await rlm.addMemory('Deep learning uses neural networks with many layers.');
|
|
23
|
-
*
|
|
24
|
-
* // Query with recursive retrieval
|
|
25
|
-
* const answer = await rlm.query('Explain the relationship between ML and deep learning');
|
|
26
|
-
* console.log(answer.text);
|
|
27
|
-
* console.log('Sources:', answer.sources.length);
|
|
28
|
-
* console.log('Confidence:', answer.confidence);
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @example Streaming
|
|
32
|
-
* ```typescript
|
|
33
|
-
* const rlm = new RlmController();
|
|
34
|
-
*
|
|
35
|
-
* for await (const event of rlm.queryStream('What is AI?')) {
|
|
36
|
-
* if (event.type === 'token') {
|
|
37
|
-
* process.stdout.write(event.text);
|
|
38
|
-
* } else {
|
|
39
|
-
* console.log('\n\nDone! Quality:', event.answer.qualityScore);
|
|
40
|
-
* }
|
|
41
|
-
* }
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @example With Reflection
|
|
45
|
-
* ```typescript
|
|
46
|
-
* const rlm = new RlmController({
|
|
47
|
-
* enableReflection: true,
|
|
48
|
-
* maxReflectionIterations: 2,
|
|
49
|
-
* minQualityScore: 0.8,
|
|
50
|
-
* });
|
|
51
|
-
*
|
|
52
|
-
* const answer = await rlm.query('Complex multi-part question...');
|
|
53
|
-
* // Answer will be iteratively refined until quality >= 0.8
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
import { RlmConfig, RlmAnswer, MemorySpan, StreamToken } from './types';
|
|
57
|
-
import { RuvLLM } from '../engine';
|
|
58
|
-
/**
|
|
59
|
-
* RlmController - Recursive Retrieval Language Model Controller
|
|
60
|
-
*
|
|
61
|
-
* Orchestrates retrieval-augmented generation with recursive sub-query
|
|
62
|
-
* decomposition, memory search, and optional self-reflection.
|
|
63
|
-
*/
|
|
64
|
-
export declare class RlmController {
|
|
65
|
-
private config;
|
|
66
|
-
private cache;
|
|
67
|
-
private engine;
|
|
68
|
-
private memoryIdCounter;
|
|
69
|
-
/**
|
|
70
|
-
* Create a new RLM controller
|
|
71
|
-
*
|
|
72
|
-
* @param config - Configuration options
|
|
73
|
-
* @param engine - Optional RuvLLM engine instance (creates new if not provided)
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* ```typescript
|
|
77
|
-
* // With default config
|
|
78
|
-
* const rlm = new RlmController();
|
|
79
|
-
*
|
|
80
|
-
* // With custom config
|
|
81
|
-
* const rlm = new RlmController({
|
|
82
|
-
* maxDepth: 5,
|
|
83
|
-
* enableReflection: true,
|
|
84
|
-
* });
|
|
85
|
-
*
|
|
86
|
-
* // With existing engine
|
|
87
|
-
* const engine = new RuvLLM({ learningEnabled: true });
|
|
88
|
-
* const rlm = new RlmController({}, engine);
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
constructor(config?: RlmConfig, engine?: RuvLLM);
|
|
92
|
-
/**
|
|
93
|
-
* Query the RLM with recursive retrieval
|
|
94
|
-
*
|
|
95
|
-
* @param input - The query string
|
|
96
|
-
* @returns Promise resolving to the answer with sources and metadata
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* const answer = await rlm.query('What is the capital of France?');
|
|
101
|
-
* console.log(answer.text); // "The capital of France is Paris..."
|
|
102
|
-
* console.log(answer.confidence); // 0.95
|
|
103
|
-
* console.log(answer.sources); // [{ id: '...', text: '...', similarityScore: 0.92 }]
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
query(input: string): Promise<RlmAnswer>;
|
|
107
|
-
/**
|
|
108
|
-
* Query with streaming response
|
|
109
|
-
*
|
|
110
|
-
* @param input - The query string
|
|
111
|
-
* @yields StreamToken events (either partial tokens or final answer)
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* ```typescript
|
|
115
|
-
* for await (const event of rlm.queryStream('Explain quantum computing')) {
|
|
116
|
-
* if (event.type === 'token') {
|
|
117
|
-
* // Partial token received
|
|
118
|
-
* process.stdout.write(event.text);
|
|
119
|
-
* } else {
|
|
120
|
-
* // Generation complete
|
|
121
|
-
* console.log('\n\nSources:', event.answer.sources.length);
|
|
122
|
-
* }
|
|
123
|
-
* }
|
|
124
|
-
* ```
|
|
125
|
-
*/
|
|
126
|
-
queryStream(input: string): AsyncGenerator<StreamToken>;
|
|
127
|
-
/**
|
|
128
|
-
* Add content to memory for retrieval
|
|
129
|
-
*
|
|
130
|
-
* @param text - The text content to store
|
|
131
|
-
* @param metadata - Optional metadata to associate with the memory
|
|
132
|
-
* @returns Promise resolving to the memory span ID
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```typescript
|
|
136
|
-
* const id1 = await rlm.addMemory(
|
|
137
|
-
* 'TypeScript is a typed superset of JavaScript.',
|
|
138
|
-
* { source: 'documentation', category: 'programming' }
|
|
139
|
-
* );
|
|
140
|
-
*
|
|
141
|
-
* const id2 = await rlm.addMemory(
|
|
142
|
-
* 'React is a JavaScript library for building UIs.'
|
|
143
|
-
* );
|
|
144
|
-
* ```
|
|
145
|
-
*/
|
|
146
|
-
addMemory(text: string, metadata?: Record<string, unknown>): Promise<string>;
|
|
147
|
-
/**
|
|
148
|
-
* Search memory for relevant spans
|
|
149
|
-
*
|
|
150
|
-
* @param query - The search query
|
|
151
|
-
* @param topK - Number of results to return (default: config.retrievalTopK)
|
|
152
|
-
* @returns Promise resolving to array of memory spans
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* ```typescript
|
|
156
|
-
* const spans = await rlm.searchMemory('JavaScript frameworks', 5);
|
|
157
|
-
* for (const span of spans) {
|
|
158
|
-
* console.log(`[${span.similarityScore.toFixed(2)}] ${span.text}`);
|
|
159
|
-
* }
|
|
160
|
-
* ```
|
|
161
|
-
*/
|
|
162
|
-
searchMemory(query: string, topK?: number): Promise<MemorySpan[]>;
|
|
163
|
-
/**
|
|
164
|
-
* Clear the response cache
|
|
165
|
-
*
|
|
166
|
-
* @example
|
|
167
|
-
* ```typescript
|
|
168
|
-
* rlm.clearCache();
|
|
169
|
-
* console.log('Cache cleared');
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
clearCache(): void;
|
|
173
|
-
/**
|
|
174
|
-
* Get current cache statistics
|
|
175
|
-
*
|
|
176
|
-
* @returns Object with cache size and hit rate info
|
|
177
|
-
*/
|
|
178
|
-
getCacheStats(): {
|
|
179
|
-
size: number;
|
|
180
|
-
entries: number;
|
|
181
|
-
};
|
|
182
|
-
/**
|
|
183
|
-
* Update configuration at runtime
|
|
184
|
-
*
|
|
185
|
-
* @param config - Partial configuration to merge
|
|
186
|
-
*/
|
|
187
|
-
updateConfig(config: Partial<RlmConfig>): void;
|
|
188
|
-
/**
|
|
189
|
-
* Get current configuration
|
|
190
|
-
*/
|
|
191
|
-
getConfig(): Required<RlmConfig>;
|
|
192
|
-
/**
|
|
193
|
-
* Generate sub-queries for complex questions
|
|
194
|
-
*/
|
|
195
|
-
private generateSubQueries;
|
|
196
|
-
/**
|
|
197
|
-
* Decompose a complex query into simpler parts
|
|
198
|
-
*/
|
|
199
|
-
private decomposeQuery;
|
|
200
|
-
/**
|
|
201
|
-
* Build context string from sources and sub-queries
|
|
202
|
-
*/
|
|
203
|
-
private buildContext;
|
|
204
|
-
/**
|
|
205
|
-
* Build the full prompt with context
|
|
206
|
-
*/
|
|
207
|
-
private buildPrompt;
|
|
208
|
-
/**
|
|
209
|
-
* Get generation config based on RLM settings
|
|
210
|
-
*/
|
|
211
|
-
private getGenerationConfig;
|
|
212
|
-
/**
|
|
213
|
-
* Estimate token usage
|
|
214
|
-
*/
|
|
215
|
-
private estimateTokenUsage;
|
|
216
|
-
/**
|
|
217
|
-
* Calculate quality score based on sources and confidence
|
|
218
|
-
*/
|
|
219
|
-
private calculateQualityScore;
|
|
220
|
-
/**
|
|
221
|
-
* Apply self-reflection to improve answer
|
|
222
|
-
*/
|
|
223
|
-
private applyReflection;
|
|
224
|
-
/**
|
|
225
|
-
* Get cached answer if valid
|
|
226
|
-
*/
|
|
227
|
-
private getCached;
|
|
228
|
-
/**
|
|
229
|
-
* Set cache entry
|
|
230
|
-
*/
|
|
231
|
-
private setCache;
|
|
232
|
-
/**
|
|
233
|
-
* Simple hash function for cache keys
|
|
234
|
-
*/
|
|
235
|
-
private hashQuery;
|
|
236
|
-
/**
|
|
237
|
-
* Prune expired cache entries
|
|
238
|
-
*/
|
|
239
|
-
private pruneCache;
|
|
240
|
-
/**
|
|
241
|
-
* Utility delay function for streaming simulation
|
|
242
|
-
*/
|
|
243
|
-
private delay;
|
|
244
|
-
}
|
|
245
|
-
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/rlm/controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,EACL,SAAS,EACT,SAAS,EACT,UAAU,EAGV,WAAW,EAGZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAkBnC;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAS;IAEhC;;;;;;;;;;;;;;;;;;;;;OAqBG;gBACS,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM;IAO/C;;;;;;;;;;;;;OAaG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAsD9C;;;;;;;;;;;;;;;;;;OAkBG;IACI,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC;IA2D9D;;;;;;;;;;;;;;;;;;OAkBG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAMlF;;;;;;;;;;;;;;OAcG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAavE;;;;;;;;OAQG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;OAIG;IACH,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAOlD;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAI9C;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,SAAS,CAAC;IAQhC;;OAEG;YACW,kBAAkB;IAkChC;;OAEG;IACH,OAAO,CAAC,cAAc;IAyBtB;;OAEG;IACH,OAAO,CAAC,YAAY;IAuBpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAQ3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAY7B;;OAEG;YACW,eAAe;IA0D7B;;OAEG;IACH,OAAO,CAAC,SAAS;IAiBjB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAchB;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,OAAO,CAAC,UAAU;IA0BlB;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
|