@ruvector/ruvllm
Advanced tools
| /** | ||
| * External Intelligence Providers for SONA Learning (ADR-043) | ||
| * | ||
| * TypeScript bindings for the IntelligenceProvider trait, enabling | ||
| * external systems to feed quality signals into RuvLLM's learning loops. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { IntelligenceLoader, FileSignalProvider, QualitySignal } from '@ruvector/ruvllm'; | ||
| * | ||
| * const loader = new IntelligenceLoader(); | ||
| * loader.registerProvider(new FileSignalProvider('./signals.json')); | ||
| * | ||
| * const { signals, errors } = loader.loadAllSignals(); | ||
| * console.log(`Loaded ${signals.length} signals`); | ||
| * ``` | ||
| */ | ||
| /** | ||
| * A quality signal from an external system. | ||
| * | ||
| * Represents one completed task with quality assessment data | ||
| * that can feed into SONA trajectories, the embedding classifier, | ||
| * and model router calibration. | ||
| */ | ||
| export interface QualitySignal { | ||
| /** Unique identifier for this signal */ | ||
| id: string; | ||
| /** Human-readable task description (used for embedding generation) */ | ||
| taskDescription: string; | ||
| /** Execution outcome */ | ||
| outcome: 'success' | 'partial_success' | 'failure'; | ||
| /** Composite quality score (0.0 - 1.0) */ | ||
| qualityScore: number; | ||
| /** Optional human verdict */ | ||
| humanVerdict?: 'approved' | 'rejected'; | ||
| /** Optional structured quality factors for detailed analysis */ | ||
| qualityFactors?: QualityFactors; | ||
| /** ISO 8601 timestamp of task completion */ | ||
| completedAt: string; | ||
| } | ||
| /** | ||
| * Granular quality factor breakdown. | ||
| * | ||
| * Not all providers will have all factors. Undefined fields mean | ||
| * "not assessed" (distinct from 0.0, which means "assessed as zero"). | ||
| */ | ||
| export interface QualityFactors { | ||
| acceptanceCriteriaMet?: number; | ||
| testsPassing?: number; | ||
| noRegressions?: number; | ||
| lintClean?: number; | ||
| typeCheckClean?: number; | ||
| followsPatterns?: number; | ||
| contextRelevance?: number; | ||
| reasoningCoherence?: number; | ||
| executionEfficiency?: number; | ||
| } | ||
| /** | ||
| * Quality weight overrides from a provider. | ||
| * | ||
| * Weights should sum to approximately 1.0. | ||
| */ | ||
| export interface ProviderQualityWeights { | ||
| taskCompletion: number; | ||
| codeQuality: number; | ||
| process: number; | ||
| } | ||
| /** | ||
| * Error from a single provider during batch loading. | ||
| */ | ||
| export interface ProviderError { | ||
| providerName: string; | ||
| message: string; | ||
| } | ||
| /** | ||
| * Result from a single provider during grouped loading. | ||
| */ | ||
| export interface ProviderResult { | ||
| providerName: string; | ||
| signals: QualitySignal[]; | ||
| weights?: ProviderQualityWeights; | ||
| } | ||
| /** | ||
| * Interface for external systems that supply quality signals to RuvLLM. | ||
| * | ||
| * Implement this interface and register with IntelligenceLoader. | ||
| */ | ||
| export interface IntelligenceProvider { | ||
| /** Human-readable name for this provider */ | ||
| name(): string; | ||
| /** Load quality signals from this provider's data source */ | ||
| loadSignals(): QualitySignal[]; | ||
| /** Optional quality weight overrides */ | ||
| qualityWeights?(): ProviderQualityWeights | undefined; | ||
| } | ||
| /** | ||
| * Built-in file-based intelligence provider. | ||
| * | ||
| * Reads quality signals from a JSON file. This is the default provider | ||
| * for non-Rust integrations that write signal files. | ||
| */ | ||
| export declare class FileSignalProvider implements IntelligenceProvider { | ||
| private readonly filePath; | ||
| constructor(filePath: string); | ||
| name(): string; | ||
| loadSignals(): QualitySignal[]; | ||
| qualityWeights(): ProviderQualityWeights | undefined; | ||
| } | ||
| /** | ||
| * Aggregates quality signals from multiple registered providers. | ||
| * | ||
| * If no providers are registered, loadAllSignals returns empty arrays | ||
| * with zero overhead. | ||
| */ | ||
| export declare class IntelligenceLoader { | ||
| private providers; | ||
| /** Register an external intelligence provider */ | ||
| registerProvider(provider: IntelligenceProvider): void; | ||
| /** Returns the number of registered providers */ | ||
| get providerCount(): number; | ||
| /** Returns the names of all registered providers */ | ||
| get providerNames(): string[]; | ||
| /** | ||
| * Load signals from all registered providers. | ||
| * | ||
| * Non-fatal: if a provider fails, its error is captured but | ||
| * other providers continue loading. | ||
| */ | ||
| loadAllSignals(): { | ||
| signals: QualitySignal[]; | ||
| errors: ProviderError[]; | ||
| }; | ||
| /** Load signals grouped by provider with weight overrides */ | ||
| loadGrouped(): ProviderResult[]; | ||
| } | ||
| //# sourceMappingURL=intelligence.d.ts.map |
| {"version":3,"file":"intelligence.d.ts","sourceRoot":"","sources":["../../src/intelligence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,sEAAsE;IACtE,eAAe,EAAE,MAAM,CAAC;IACxB,wBAAwB;IACxB,OAAO,EAAE,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACnD,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,YAAY,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACvC,gEAAgE;IAChE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,IAAI,IAAI,MAAM,CAAC;IACf,4DAA4D;IAC5D,WAAW,IAAI,aAAa,EAAE,CAAC;IAC/B,wCAAwC;IACxC,cAAc,CAAC,IAAI,sBAAsB,GAAG,SAAS,CAAC;CACvD;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,EAAE,MAAM;IAI5B,IAAI,IAAI,MAAM;IAId,WAAW,IAAI,aAAa,EAAE;IA8B9B,cAAc,IAAI,sBAAsB,GAAG,SAAS;CAiBrD;AAgBD;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,SAAS,CAA8B;IAE/C,iDAAiD;IACjD,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAItD,iDAAiD;IACjD,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,oDAAoD;IACpD,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAED;;;;;OAKG;IACH,cAAc,IAAI;QAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QAAC,MAAM,EAAE,aAAa,EAAE,CAAA;KAAE;IAmBvE,6DAA6D;IAC7D,WAAW,IAAI,cAAc,EAAE;CAehC"} |
| "use strict"; | ||
| /** | ||
| * External Intelligence Providers for SONA Learning (ADR-043) | ||
| * | ||
| * TypeScript bindings for the IntelligenceProvider trait, enabling | ||
| * external systems to feed quality signals into RuvLLM's learning loops. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { IntelligenceLoader, FileSignalProvider, QualitySignal } from '@ruvector/ruvllm'; | ||
| * | ||
| * const loader = new IntelligenceLoader(); | ||
| * loader.registerProvider(new FileSignalProvider('./signals.json')); | ||
| * | ||
| * const { signals, errors } = loader.loadAllSignals(); | ||
| * console.log(`Loaded ${signals.length} signals`); | ||
| * ``` | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.IntelligenceLoader = exports.FileSignalProvider = void 0; | ||
| /** | ||
| * Built-in file-based intelligence provider. | ||
| * | ||
| * Reads quality signals from a JSON file. This is the default provider | ||
| * for non-Rust integrations that write signal files. | ||
| */ | ||
| class FileSignalProvider { | ||
| constructor(filePath) { | ||
| this.filePath = filePath; | ||
| } | ||
| name() { | ||
| return 'file-signals'; | ||
| } | ||
| loadSignals() { | ||
| try { | ||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||
| const fs = require('fs'); | ||
| if (!fs.existsSync(this.filePath)) { | ||
| return []; | ||
| } | ||
| const raw = fs.readFileSync(this.filePath, 'utf-8'); | ||
| const data = JSON.parse(raw); | ||
| if (!Array.isArray(data)) { | ||
| return []; | ||
| } | ||
| return data.map((item) => ({ | ||
| id: String(item.id ?? ''), | ||
| taskDescription: String(item.task_description ?? item.taskDescription ?? ''), | ||
| outcome: String(item.outcome ?? 'failure'), | ||
| qualityScore: Number(item.quality_score ?? item.qualityScore ?? 0), | ||
| humanVerdict: item.human_verdict ?? item.humanVerdict | ||
| ? String(item.human_verdict ?? item.humanVerdict) | ||
| : undefined, | ||
| qualityFactors: (item.quality_factors || item.qualityFactors) | ||
| ? mapQualityFactors((item.quality_factors ?? item.qualityFactors)) | ||
| : undefined, | ||
| completedAt: String(item.completed_at ?? item.completedAt ?? new Date().toISOString()), | ||
| })); | ||
| } | ||
| catch { | ||
| return []; | ||
| } | ||
| } | ||
| qualityWeights() { | ||
| try { | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| const weightsPath = path.join(path.dirname(this.filePath), 'quality-weights.json'); | ||
| if (!fs.existsSync(weightsPath)) | ||
| return undefined; | ||
| const raw = fs.readFileSync(weightsPath, 'utf-8'); | ||
| const data = JSON.parse(raw); | ||
| return { | ||
| taskCompletion: Number(data.task_completion ?? data.taskCompletion ?? 0.5), | ||
| codeQuality: Number(data.code_quality ?? data.codeQuality ?? 0.3), | ||
| process: Number(data.process ?? 0.2), | ||
| }; | ||
| } | ||
| catch { | ||
| return undefined; | ||
| } | ||
| } | ||
| } | ||
| exports.FileSignalProvider = FileSignalProvider; | ||
| function mapQualityFactors(raw) { | ||
| return { | ||
| acceptanceCriteriaMet: raw.acceptance_criteria_met, | ||
| testsPassing: raw.tests_passing, | ||
| noRegressions: raw.no_regressions, | ||
| lintClean: raw.lint_clean, | ||
| typeCheckClean: raw.type_check_clean, | ||
| followsPatterns: raw.follows_patterns, | ||
| contextRelevance: raw.context_relevance, | ||
| reasoningCoherence: raw.reasoning_coherence, | ||
| executionEfficiency: raw.execution_efficiency, | ||
| }; | ||
| } | ||
| /** | ||
| * Aggregates quality signals from multiple registered providers. | ||
| * | ||
| * If no providers are registered, loadAllSignals returns empty arrays | ||
| * with zero overhead. | ||
| */ | ||
| class IntelligenceLoader { | ||
| constructor() { | ||
| this.providers = []; | ||
| } | ||
| /** Register an external intelligence provider */ | ||
| registerProvider(provider) { | ||
| this.providers.push(provider); | ||
| } | ||
| /** Returns the number of registered providers */ | ||
| get providerCount() { | ||
| return this.providers.length; | ||
| } | ||
| /** Returns the names of all registered providers */ | ||
| get providerNames() { | ||
| return this.providers.map(p => p.name()); | ||
| } | ||
| /** | ||
| * Load signals from all registered providers. | ||
| * | ||
| * Non-fatal: if a provider fails, its error is captured but | ||
| * other providers continue loading. | ||
| */ | ||
| loadAllSignals() { | ||
| const signals = []; | ||
| const errors = []; | ||
| for (const provider of this.providers) { | ||
| try { | ||
| const providerSignals = provider.loadSignals(); | ||
| signals.push(...providerSignals); | ||
| } | ||
| catch (e) { | ||
| errors.push({ | ||
| providerName: provider.name(), | ||
| message: e instanceof Error ? e.message : String(e), | ||
| }); | ||
| } | ||
| } | ||
| return { signals, errors }; | ||
| } | ||
| /** Load signals grouped by provider with weight overrides */ | ||
| loadGrouped() { | ||
| return this.providers.map(provider => { | ||
| let providerSignals = []; | ||
| try { | ||
| providerSignals = provider.loadSignals(); | ||
| } | ||
| catch { | ||
| // Non-fatal | ||
| } | ||
| return { | ||
| providerName: provider.name(), | ||
| signals: providerSignals, | ||
| weights: provider.qualityWeights?.(), | ||
| }; | ||
| }); | ||
| } | ||
| } | ||
| exports.IntelligenceLoader = IntelligenceLoader; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWxsaWdlbmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludGVsbGlnZW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7OztBQXNGSDs7Ozs7R0FLRztBQUNILE1BQWEsa0JBQWtCO0lBRzdCLFlBQVksUUFBZ0I7UUFDMUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQUk7UUFDRixPQUFPLGNBQWMsQ0FBQztJQUN4QixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQztZQUNILDhEQUE4RDtZQUM5RCxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xDLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQztZQUNELE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNwRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3pCLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQTZCLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ2xELEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUM7Z0JBQ3pCLGVBQWUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksRUFBRSxDQUFDO2dCQUM1RSxPQUFPLEVBQUUsTUFB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QW9CLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUM7Z0JBQ0gsZUFBZSxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQyxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLFlBQVk7WUFDZCxDQUFDO1lBQ0QsT0FBTztnQkFDTCxZQUFZLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRTtnQkFDN0IsT0FBTyxFQUFFLGVBQWU7Z0JBQ3hCLE9BQU8sRUFBRSxRQUFRLENBQUMsY0FBYyxFQUFFLEVBQUU7YUFDckMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBM0RELGdEQTJEQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRXh0ZXJuYWwgSW50ZWxsaWdlbmNlIFByb3ZpZGVycyBmb3IgU09OQSBMZWFybmluZyAoQURSLTA0MylcbiAqXG4gKiBUeXBlU2NyaXB0IGJpbmRpbmdzIGZvciB0aGUgSW50ZWxsaWdlbmNlUHJvdmlkZXIgdHJhaXQsIGVuYWJsaW5nXG4gKiBleHRlcm5hbCBzeXN0ZW1zIHRvIGZlZWQgcXVhbGl0eSBzaWduYWxzIGludG8gUnV2TExNJ3MgbGVhcm5pbmcgbG9vcHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IEludGVsbGlnZW5jZUxvYWRlciwgRmlsZVNpZ25hbFByb3ZpZGVyLCBRdWFsaXR5U2lnbmFsIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogY29uc3QgbG9hZGVyID0gbmV3IEludGVsbGlnZW5jZUxvYWRlcigpO1xuICogbG9hZGVyLnJlZ2lzdGVyUHJvdmlkZXIobmV3IEZpbGVTaWduYWxQcm92aWRlcignLi9zaWduYWxzLmpzb24nKSk7XG4gKlxuICogY29uc3QgeyBzaWduYWxzLCBlcnJvcnMgfSA9IGxvYWRlci5sb2FkQWxsU2lnbmFscygpO1xuICogY29uc29sZS5sb2coYExvYWRlZCAke3NpZ25hbHMubGVuZ3RofSBzaWduYWxzYCk7XG4gKiBgYGBcbiAqL1xuXG4vKipcbiAqIEEgcXVhbGl0eSBzaWduYWwgZnJvbSBhbiBleHRlcm5hbCBzeXN0ZW0uXG4gKlxuICogUmVwcmVzZW50cyBvbmUgY29tcGxldGVkIHRhc2sgd2l0aCBxdWFsaXR5IGFzc2Vzc21lbnQgZGF0YVxuICogdGhhdCBjYW4gZmVlZCBpbnRvIFNPTkEgdHJhamVjdG9yaWVzLCB0aGUgZW1iZWRkaW5nIGNsYXNzaWZpZXIsXG4gKiBhbmQgbW9kZWwgcm91dGVyIGNhbGlicmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1YWxpdHlTaWduYWwge1xuICAvKiogVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoaXMgc2lnbmFsICovXG4gIGlkOiBzdHJpbmc7XG4gIC8qKiBIdW1hbi1yZWFkYWJsZSB0YXNrIGRlc2NyaXB0aW9uICh1c2VkIGZvciBlbWJlZGRpbmcgZ2VuZXJhdGlvbikgKi9cbiAgdGFza0Rlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIC8qKiBFeGVjdXRpb24gb3V0Y29tZSAqL1xuICBvdXRjb21lOiAnc3VjY2VzcycgfCAncGFydGlhbF9zdWNjZXNzJyB8ICdmYWlsdXJlJztcbiAgLyoqIENvbXBvc2l0ZSBxdWFsaXR5IHNjb3JlICgwLjAgLSAxLjApICovXG4gIHF1YWxpdHlTY29yZTogbnVtYmVyO1xuICAvKiogT3B0aW9uYWwgaHVtYW4gdmVyZGljdCAqL1xuICBodW1hblZlcmRpY3Q/OiAnYXBwcm92ZWQnIHwgJ3JlamVjdGVkJztcbiAgLyoqIE9wdGlvbmFsIHN0cnVjdHVyZWQgcXVhbGl0eSBmYWN0b3JzIGZvciBkZXRhaWxlZCBhbmFseXNpcyAqL1xuICBxdWFsaXR5RmFjdG9ycz86IFF1YWxpdHlGYWN0b3JzO1xuICAvKiogSVNPIDg2MDEgdGltZXN0YW1wIG9mIHRhc2sgY29tcGxldGlvbiAqL1xuICBjb21wbGV0ZWRBdDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEdyYW51bGFyIHF1YWxpdHkgZmFjdG9yIGJyZWFrZG93bi5cbiAqXG4gKiBOb3QgYWxsIHByb3ZpZGVycyB3aWxsIGhhdmUgYWxsIGZhY3RvcnMuIFVuZGVmaW5lZCBmaWVsZHMgbWVhblxuICogXCJub3QgYXNzZXNzZWRcIiAoZGlzdGluY3QgZnJvbSAwLjAsIHdoaWNoIG1lYW5zIFwiYXNzZXNzZWQgYXMgemVyb1wiKS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdWFsaXR5RmFjdG9ycyB7XG4gIGFjY2VwdGFuY2VDcml0ZXJpYU1ldD86IG51bWJlcjtcbiAgdGVzdHNQYXNzaW5nPzogbnVtYmVyO1xuICBub1JlZ3Jlc3Npb25zPzogbnVtYmVyO1xuICBsaW50Q2xlYW4/OiBudW1iZXI7XG4gIHR5cGVDaGVja0NsZWFuPzogbnVtYmVyO1xuICBmb2xsb3dzUGF0dGVybnM/OiBudW1iZXI7XG4gIGNvbnRleHRSZWxldmFuY2U/OiBudW1iZXI7XG4gIHJlYXNvbmluZ0NvaGVyZW5jZT86IG51bWJlcjtcbiAgZXhlY3V0aW9uRWZmaWNpZW5jeT86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBRdWFsaXR5IHdlaWdodCBvdmVycmlkZXMgZnJvbSBhIHByb3ZpZGVyLlxuICpcbiAqIFdlaWdodHMgc2hvdWxkIHN1bSB0byBhcHByb3hpbWF0ZWx5IDEuMC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aWRlclF1YWxpdHlXZWlnaHRzIHtcbiAgdGFza0NvbXBsZXRpb246IG51bWJlcjtcbiAgY29kZVF1YWxpdHk6IG51bWJlcjtcbiAgcHJvY2VzczogbnVtYmVyO1xufVxuXG4vKipcbiAqIEVycm9yIGZyb20gYSBzaW5nbGUgcHJvdmlkZXIgZHVyaW5nIGJhdGNoIGxvYWRpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlkZXJFcnJvciB7XG4gIHByb3ZpZGVyTmFtZTogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVzdWx0IGZyb20gYSBzaW5nbGUgcHJvdmlkZXIgZHVyaW5nIGdyb3VwZWQgbG9hZGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aWRlclJlc3VsdCB7XG4gIHByb3ZpZGVyTmFtZTogc3RyaW5nO1xuICBzaWduYWxzOiBRdWFsaXR5U2lnbmFsW107XG4gIHdlaWdodHM/OiBQcm92aWRlclF1YWxpdHlXZWlnaHRzO1xufVxuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgZXh0ZXJuYWwgc3lzdGVtcyB0aGF0IHN1cHBseSBxdWFsaXR5IHNpZ25hbHMgdG8gUnV2TExNLlxuICpcbiAqIEltcGxlbWVudCB0aGlzIGludGVyZmFjZSBhbmQgcmVnaXN0ZXIgd2l0aCBJbnRlbGxpZ2VuY2VMb2FkZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZWxsaWdlbmNlUHJvdmlkZXIge1xuICAvKiogSHVtYW4tcmVhZGFibGUgbmFtZSBmb3IgdGhpcyBwcm92aWRlciAqL1xuICBuYW1lKCk6IHN0cmluZztcbiAgLyoqIExvYWQgcXVhbGl0eSBzaWduYWxzIGZyb20gdGhpcyBwcm92aWRlcidzIGRhdGEgc291cmNlICovXG4gIGxvYWRTaWduYWxzKCk6IFF1YWxpdHlTaWduYWxbXTtcbiAgLyoqIE9wdGlvbmFsIHF1YWxpdHkgd2VpZ2h0IG92ZXJyaWRlcyAqL1xuICBxdWFsaXR5V2VpZ2h0cz8oKTogUHJvdmlkZXJRdWFsaXR5V2VpZ2h0cyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBCdWlsdC1pbiBmaWxlLWJhc2VkIGludGVsbGlnZW5jZSBwcm92aWRlci5cbiAqXG4gKiBSZWFkcyBxdWFsaXR5IHNpZ25hbHMgZnJvbSBhIEpTT04gZmlsZS4gVGhpcyBpcyB0aGUgZGVmYXVsdCBwcm92aWRlclxuICogZm9yIG5vbi1SdXN0IGludGVncmF0aW9ucyB0aGF0IHdyaXRlIHNpZ25hbCBmaWxlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbGVTaWduYWxQcm92aWRlciBpbXBsZW1lbnRzIEludGVsbGlnZW5jZVByb3ZpZGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBmaWxlUGF0aDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgICB0aGlzLmZpbGVQYXRoID0gZmlsZVBhdGg7XG4gIH1cblxuICBuYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdmaWxlLXNpZ25hbHMnO1xuICB9XG5cbiAgbG9hZFNpZ25hbHMoKTogUXVhbGl0eVNpZ25hbFtdIHtcbiAgICB0cnkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXNcbiAgICAgIGNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKTtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmZpbGVQYXRoKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBjb25zdCByYXcgPSBmcy5yZWFkRmlsZVN5bmModGhpcy5maWxlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhLm1hcCgoaXRlbTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+ICh7XG4gICAgICAgIGlkOiBTdHJpbmcoaXRlbS5pZCA/PyAnJyksXG4gICAgICAgIHRhc2tEZXNjcmlwdGlvbjogU3RyaW5nKGl0ZW0udGFza19kZXNjcmlwdGlvbiA/PyBpdGVtLnRhc2tEZXNjcmlwdGlvbiA/PyAnJyksXG4gICAgICAgIG91dGNvbWU6IFN0cmluZyhpdGVtLm91dGNvbWUgPz8gJ2ZhaWx1cmUnKSBhcyBRdWFsaXR5U2lnbmFsWydvdXRjb21lJ10sXG4gICAgICAgIHF1YWxpdHlTY29yZTogTnVtYmVyKGl0ZW0ucXVhbGl0eV9zY29yZSA/PyBpdGVtLnF1YWxpdHlTY29yZSA/PyAwKSxcbiAgICAgICAgaHVtYW5WZXJkaWN0OiBpdGVtLmh1bWFuX3ZlcmRpY3QgPz8gaXRlbS5odW1hblZlcmRpY3RcbiAgICAgICAgICA/IFN0cmluZyhpdGVtLmh1bWFuX3ZlcmRpY3QgPz8gaXRlbS5odW1hblZlcmRpY3QpIGFzIFF1YWxpdHlTaWduYWxbJ2h1bWFuVmVyZGljdCddXG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgIHF1YWxpdHlGYWN0b3JzOiAoaXRlbS5xdWFsaXR5X2ZhY3RvcnMgfHwgaXRlbS5xdWFsaXR5RmFjdG9ycylcbiAgICAgICAgICA/IG1hcFF1YWxpdHlGYWN0b3JzKChpdGVtLnF1YWxpdHlfZmFjdG9ycyA/PyBpdGVtLnF1YWxpdHlGYWN0b3JzKSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgY29tcGxldGVkQXQ6IFN0cmluZyhpdGVtLmNvbXBsZXRlZF9hdCA/PyBpdGVtLmNvbXBsZXRlZEF0ID8/IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSksXG4gICAgICB9KSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG5cbiAgcXVhbGl0eVdlaWdodHMoKTogUHJvdmlkZXJRdWFsaXR5V2VpZ2h0cyB8IHVuZGVmaW5lZCB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKTtcbiAgICAgIGNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG4gICAgICBjb25zdCB3ZWlnaHRzUGF0aCA9IHBhdGguam9pbihwYXRoLmRpcm5hbWUodGhpcy5maWxlUGF0aCksICdxdWFsaXR5LXdlaWdodHMuanNvbicpO1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHdlaWdodHNQYXRoKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyh3ZWlnaHRzUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZShyYXcpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdGFza0NvbXBsZXRpb246IE51bWJlcihkYXRhLnRhc2tfY29tcGxldGlvbiA/PyBkYXRhLnRhc2tDb21wbGV0aW9uID8/IDAuNSksXG4gICAgICAgIGNvZGVRdWFsaXR5OiBOdW1iZXIoZGF0YS5jb2RlX3F1YWxpdHkgPz8gZGF0YS5jb2RlUXVhbGl0eSA/PyAwLjMpLFxuICAgICAgICBwcm9jZXNzOiBOdW1iZXIoZGF0YS5wcm9jZXNzID8/IDAuMiksXG4gICAgICB9O1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFwUXVhbGl0eUZhY3RvcnMocmF3OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFF1YWxpdHlGYWN0b3JzIHtcbiAgcmV0dXJuIHtcbiAgICBhY2NlcHRhbmNlQ3JpdGVyaWFNZXQ6IHJhdy5hY2NlcHRhbmNlX2NyaXRlcmlhX21ldCBhcyBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgdGVzdHNQYXNzaW5nOiByYXcudGVzdHNfcGFzc2luZyBhcyBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgbm9SZWdyZXNzaW9uczogcmF3Lm5vX3JlZ3Jlc3Npb25zIGFzIG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICBsaW50Q2xlYW46IHJhdy5saW50X2NsZWFuIGFzIG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICB0eXBlQ2hlY2tDbGVhbjogcmF3LnR5cGVfY2hlY2tfY2xlYW4gYXMgbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIGZvbGxvd3NQYXR0ZXJuczogcmF3LmZvbGxvd3NfcGF0dGVybnMgYXMgbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIGNvbnRleHRSZWxldmFuY2U6IHJhdy5jb250ZXh0X3JlbGV2YW5jZSBhcyBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgcmVhc29uaW5nQ29oZXJlbmNlOiByYXcucmVhc29uaW5nX2NvaGVyZW5jZSBhcyBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgZXhlY3V0aW9uRWZmaWNpZW5jeTogcmF3LmV4ZWN1dGlvbl9lZmZpY2llbmN5IGFzIG51bWJlciB8IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBBZ2dyZWdhdGVzIHF1YWxpdHkgc2lnbmFscyBmcm9tIG11bHRpcGxlIHJlZ2lzdGVyZWQgcHJvdmlkZXJzLlxuICpcbiAqIElmIG5vIHByb3ZpZGVycyBhcmUgcmVnaXN0ZXJlZCwgbG9hZEFsbFNpZ25hbHMgcmV0dXJucyBlbXB0eSBhcnJheXNcbiAqIHdpdGggemVybyBvdmVyaGVhZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEludGVsbGlnZW5jZUxvYWRlciB7XG4gIHByaXZhdGUgcHJvdmlkZXJzOiBJbnRlbGxpZ2VuY2VQcm92aWRlcltdID0gW107XG5cbiAgLyoqIFJlZ2lzdGVyIGFuIGV4dGVybmFsIGludGVsbGlnZW5jZSBwcm92aWRlciAqL1xuICByZWdpc3RlclByb3ZpZGVyKHByb3ZpZGVyOiBJbnRlbGxpZ2VuY2VQcm92aWRlcik6IHZvaWQge1xuICAgIHRoaXMucHJvdmlkZXJzLnB1c2gocHJvdmlkZXIpO1xuICB9XG5cbiAgLyoqIFJldHVybnMgdGhlIG51bWJlciBvZiByZWdpc3RlcmVkIHByb3ZpZGVycyAqL1xuICBnZXQgcHJvdmlkZXJDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnByb3ZpZGVycy5sZW5ndGg7XG4gIH1cblxuICAvKiogUmV0dXJucyB0aGUgbmFtZXMgb2YgYWxsIHJlZ2lzdGVyZWQgcHJvdmlkZXJzICovXG4gIGdldCBwcm92aWRlck5hbWVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5wcm92aWRlcnMubWFwKHAgPT4gcC5uYW1lKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgc2lnbmFscyBmcm9tIGFsbCByZWdpc3RlcmVkIHByb3ZpZGVycy5cbiAgICpcbiAgICogTm9uLWZhdGFsOiBpZiBhIHByb3ZpZGVyIGZhaWxzLCBpdHMgZXJyb3IgaXMgY2FwdHVyZWQgYnV0XG4gICAqIG90aGVyIHByb3ZpZGVycyBjb250aW51ZSBsb2FkaW5nLlxuICAgKi9cbiAgbG9hZEFsbFNpZ25hbHMoKTogeyBzaWduYWxzOiBRdWFsaXR5U2lnbmFsW107IGVycm9yczogUHJvdmlkZXJFcnJvcltdIH0ge1xuICAgIGNvbnN0IHNpZ25hbHM6IFF1YWxpdHlTaWduYWxbXSA9IFtdO1xuICAgIGNvbnN0IGVycm9yczogUHJvdmlkZXJFcnJvcltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHByb3ZpZGVyIG9mIHRoaXMucHJvdmlkZXJzKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBwcm92aWRlclNpZ25hbHMgPSBwcm92aWRlci5sb2FkU2lnbmFscygpO1xuICAgICAgICBzaWduYWxzLnB1c2goLi4ucHJvdmlkZXJTaWduYWxzKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goe1xuICAgICAgICAgIHByb3ZpZGVyTmFtZTogcHJvdmlkZXIubmFtZSgpLFxuICAgICAgICAgIG1lc3NhZ2U6IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgc2lnbmFscywgZXJyb3JzIH07XG4gIH1cblxuICAvKiogTG9hZCBzaWduYWxzIGdyb3VwZWQgYnkgcHJvdmlkZXIgd2l0aCB3ZWlnaHQgb3ZlcnJpZGVzICovXG4gIGxvYWRHcm91cGVkKCk6IFByb3ZpZGVyUmVzdWx0W10ge1xuICAgIHJldHVybiB0aGlzLnByb3ZpZGVycy5tYXAocHJvdmlkZXIgPT4ge1xuICAgICAgbGV0IHByb3ZpZGVyU2lnbmFsczogUXVhbGl0eVNpZ25hbFtdID0gW107XG4gICAgICB0cnkge1xuICAgICAgICBwcm92aWRlclNpZ25hbHMgPSBwcm92aWRlci5sb2FkU2lnbmFscygpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIE5vbi1mYXRhbFxuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHJvdmlkZXJOYW1lOiBwcm92aWRlci5uYW1lKCksXG4gICAgICAgIHNpZ25hbHM6IHByb3ZpZGVyU2lnbmFscyxcbiAgICAgICAgd2VpZ2h0czogcHJvdmlkZXIucXVhbGl0eVdlaWdodHM/LigpLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxufVxuIl19 |
| /** | ||
| * External Intelligence Providers for SONA Learning (ADR-043) | ||
| * | ||
| * TypeScript bindings for the IntelligenceProvider trait, enabling | ||
| * external systems to feed quality signals into RuvLLM's learning loops. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { IntelligenceLoader, FileSignalProvider, QualitySignal } from '@ruvector/ruvllm'; | ||
| * | ||
| * const loader = new IntelligenceLoader(); | ||
| * loader.registerProvider(new FileSignalProvider('./signals.json')); | ||
| * | ||
| * const { signals, errors } = loader.loadAllSignals(); | ||
| * console.log(`Loaded ${signals.length} signals`); | ||
| * ``` | ||
| */ | ||
| /** | ||
| * A quality signal from an external system. | ||
| * | ||
| * Represents one completed task with quality assessment data | ||
| * that can feed into SONA trajectories, the embedding classifier, | ||
| * and model router calibration. | ||
| */ | ||
| export interface QualitySignal { | ||
| /** Unique identifier for this signal */ | ||
| id: string; | ||
| /** Human-readable task description (used for embedding generation) */ | ||
| taskDescription: string; | ||
| /** Execution outcome */ | ||
| outcome: 'success' | 'partial_success' | 'failure'; | ||
| /** Composite quality score (0.0 - 1.0) */ | ||
| qualityScore: number; | ||
| /** Optional human verdict */ | ||
| humanVerdict?: 'approved' | 'rejected'; | ||
| /** Optional structured quality factors for detailed analysis */ | ||
| qualityFactors?: QualityFactors; | ||
| /** ISO 8601 timestamp of task completion */ | ||
| completedAt: string; | ||
| } | ||
| /** | ||
| * Granular quality factor breakdown. | ||
| * | ||
| * Not all providers will have all factors. Undefined fields mean | ||
| * "not assessed" (distinct from 0.0, which means "assessed as zero"). | ||
| */ | ||
| export interface QualityFactors { | ||
| acceptanceCriteriaMet?: number; | ||
| testsPassing?: number; | ||
| noRegressions?: number; | ||
| lintClean?: number; | ||
| typeCheckClean?: number; | ||
| followsPatterns?: number; | ||
| contextRelevance?: number; | ||
| reasoningCoherence?: number; | ||
| executionEfficiency?: number; | ||
| } | ||
| /** | ||
| * Quality weight overrides from a provider. | ||
| * | ||
| * Weights should sum to approximately 1.0. | ||
| */ | ||
| export interface ProviderQualityWeights { | ||
| taskCompletion: number; | ||
| codeQuality: number; | ||
| process: number; | ||
| } | ||
| /** | ||
| * Error from a single provider during batch loading. | ||
| */ | ||
| export interface ProviderError { | ||
| providerName: string; | ||
| message: string; | ||
| } | ||
| /** | ||
| * Result from a single provider during grouped loading. | ||
| */ | ||
| export interface ProviderResult { | ||
| providerName: string; | ||
| signals: QualitySignal[]; | ||
| weights?: ProviderQualityWeights; | ||
| } | ||
| /** | ||
| * Interface for external systems that supply quality signals to RuvLLM. | ||
| * | ||
| * Implement this interface and register with IntelligenceLoader. | ||
| */ | ||
| export interface IntelligenceProvider { | ||
| /** Human-readable name for this provider */ | ||
| name(): string; | ||
| /** Load quality signals from this provider's data source */ | ||
| loadSignals(): QualitySignal[]; | ||
| /** Optional quality weight overrides */ | ||
| qualityWeights?(): ProviderQualityWeights | undefined; | ||
| } | ||
| /** | ||
| * Built-in file-based intelligence provider. | ||
| * | ||
| * Reads quality signals from a JSON file. This is the default provider | ||
| * for non-Rust integrations that write signal files. | ||
| */ | ||
| export declare class FileSignalProvider implements IntelligenceProvider { | ||
| private readonly filePath; | ||
| constructor(filePath: string); | ||
| name(): string; | ||
| loadSignals(): QualitySignal[]; | ||
| qualityWeights(): ProviderQualityWeights | undefined; | ||
| } | ||
| /** | ||
| * Aggregates quality signals from multiple registered providers. | ||
| * | ||
| * If no providers are registered, loadAllSignals returns empty arrays | ||
| * with zero overhead. | ||
| */ | ||
| export declare class IntelligenceLoader { | ||
| private providers; | ||
| /** Register an external intelligence provider */ | ||
| registerProvider(provider: IntelligenceProvider): void; | ||
| /** Returns the number of registered providers */ | ||
| get providerCount(): number; | ||
| /** Returns the names of all registered providers */ | ||
| get providerNames(): string[]; | ||
| /** | ||
| * Load signals from all registered providers. | ||
| * | ||
| * Non-fatal: if a provider fails, its error is captured but | ||
| * other providers continue loading. | ||
| */ | ||
| loadAllSignals(): { | ||
| signals: QualitySignal[]; | ||
| errors: ProviderError[]; | ||
| }; | ||
| /** Load signals grouped by provider with weight overrides */ | ||
| loadGrouped(): ProviderResult[]; | ||
| } | ||
| //# sourceMappingURL=intelligence.d.ts.map |
| {"version":3,"file":"intelligence.d.ts","sourceRoot":"","sources":["../../src/intelligence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,sEAAsE;IACtE,eAAe,EAAE,MAAM,CAAC;IACxB,wBAAwB;IACxB,OAAO,EAAE,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAC;IACnD,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,YAAY,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACvC,gEAAgE;IAChE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,IAAI,IAAI,MAAM,CAAC;IACf,4DAA4D;IAC5D,WAAW,IAAI,aAAa,EAAE,CAAC;IAC/B,wCAAwC;IACxC,cAAc,CAAC,IAAI,sBAAsB,GAAG,SAAS,CAAC;CACvD;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,EAAE,MAAM;IAI5B,IAAI,IAAI,MAAM;IAId,WAAW,IAAI,aAAa,EAAE;IA8B9B,cAAc,IAAI,sBAAsB,GAAG,SAAS;CAiBrD;AAgBD;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,SAAS,CAA8B;IAE/C,iDAAiD;IACjD,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAItD,iDAAiD;IACjD,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,oDAAoD;IACpD,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IAED;;;;;OAKG;IACH,cAAc,IAAI;QAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QAAC,MAAM,EAAE,aAAa,EAAE,CAAA;KAAE;IAmBvE,6DAA6D;IAC7D,WAAW,IAAI,cAAc,EAAE;CAehC"} |
| /** | ||
| * External Intelligence Providers for SONA Learning (ADR-043) | ||
| * | ||
| * TypeScript bindings for the IntelligenceProvider trait, enabling | ||
| * external systems to feed quality signals into RuvLLM's learning loops. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { IntelligenceLoader, FileSignalProvider, QualitySignal } from '@ruvector/ruvllm'; | ||
| * | ||
| * const loader = new IntelligenceLoader(); | ||
| * loader.registerProvider(new FileSignalProvider('./signals.json')); | ||
| * | ||
| * const { signals, errors } = loader.loadAllSignals(); | ||
| * console.log(`Loaded ${signals.length} signals`); | ||
| * ``` | ||
| */ | ||
| /** | ||
| * Built-in file-based intelligence provider. | ||
| * | ||
| * Reads quality signals from a JSON file. This is the default provider | ||
| * for non-Rust integrations that write signal files. | ||
| */ | ||
| export class FileSignalProvider { | ||
| constructor(filePath) { | ||
| this.filePath = filePath; | ||
| } | ||
| name() { | ||
| return 'file-signals'; | ||
| } | ||
| loadSignals() { | ||
| try { | ||
| // eslint-disable-next-line @typescript-eslint/no-var-requires | ||
| const fs = require('fs'); | ||
| if (!fs.existsSync(this.filePath)) { | ||
| return []; | ||
| } | ||
| const raw = fs.readFileSync(this.filePath, 'utf-8'); | ||
| const data = JSON.parse(raw); | ||
| if (!Array.isArray(data)) { | ||
| return []; | ||
| } | ||
| return data.map((item) => ({ | ||
| id: String(item.id ?? ''), | ||
| taskDescription: String(item.task_description ?? item.taskDescription ?? ''), | ||
| outcome: String(item.outcome ?? 'failure'), | ||
| qualityScore: Number(item.quality_score ?? item.qualityScore ?? 0), | ||
| humanVerdict: item.human_verdict ?? item.humanVerdict | ||
| ? String(item.human_verdict ?? item.humanVerdict) | ||
| : undefined, | ||
| qualityFactors: (item.quality_factors || item.qualityFactors) | ||
| ? mapQualityFactors((item.quality_factors ?? item.qualityFactors)) | ||
| : undefined, | ||
| completedAt: String(item.completed_at ?? item.completedAt ?? new Date().toISOString()), | ||
| })); | ||
| } | ||
| catch { | ||
| return []; | ||
| } | ||
| } | ||
| qualityWeights() { | ||
| try { | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| const weightsPath = path.join(path.dirname(this.filePath), 'quality-weights.json'); | ||
| if (!fs.existsSync(weightsPath)) | ||
| return undefined; | ||
| const raw = fs.readFileSync(weightsPath, 'utf-8'); | ||
| const data = JSON.parse(raw); | ||
| return { | ||
| taskCompletion: Number(data.task_completion ?? data.taskCompletion ?? 0.5), | ||
| codeQuality: Number(data.code_quality ?? data.codeQuality ?? 0.3), | ||
| process: Number(data.process ?? 0.2), | ||
| }; | ||
| } | ||
| catch { | ||
| return undefined; | ||
| } | ||
| } | ||
| } | ||
| function mapQualityFactors(raw) { | ||
| return { | ||
| acceptanceCriteriaMet: raw.acceptance_criteria_met, | ||
| testsPassing: raw.tests_passing, | ||
| noRegressions: raw.no_regressions, | ||
| lintClean: raw.lint_clean, | ||
| typeCheckClean: raw.type_check_clean, | ||
| followsPatterns: raw.follows_patterns, | ||
| contextRelevance: raw.context_relevance, | ||
| reasoningCoherence: raw.reasoning_coherence, | ||
| executionEfficiency: raw.execution_efficiency, | ||
| }; | ||
| } | ||
| /** | ||
| * Aggregates quality signals from multiple registered providers. | ||
| * | ||
| * If no providers are registered, loadAllSignals returns empty arrays | ||
| * with zero overhead. | ||
| */ | ||
| export class IntelligenceLoader { | ||
| constructor() { | ||
| this.providers = []; | ||
| } | ||
| /** Register an external intelligence provider */ | ||
| registerProvider(provider) { | ||
| this.providers.push(provider); | ||
| } | ||
| /** Returns the number of registered providers */ | ||
| get providerCount() { | ||
| return this.providers.length; | ||
| } | ||
| /** Returns the names of all registered providers */ | ||
| get providerNames() { | ||
| return this.providers.map(p => p.name()); | ||
| } | ||
| /** | ||
| * Load signals from all registered providers. | ||
| * | ||
| * Non-fatal: if a provider fails, its error is captured but | ||
| * other providers continue loading. | ||
| */ | ||
| loadAllSignals() { | ||
| const signals = []; | ||
| const errors = []; | ||
| for (const provider of this.providers) { | ||
| try { | ||
| const providerSignals = provider.loadSignals(); | ||
| signals.push(...providerSignals); | ||
| } | ||
| catch (e) { | ||
| errors.push({ | ||
| providerName: provider.name(), | ||
| message: e instanceof Error ? e.message : String(e), | ||
| }); | ||
| } | ||
| } | ||
| return { signals, errors }; | ||
| } | ||
| /** Load signals grouped by provider with weight overrides */ | ||
| loadGrouped() { | ||
| return this.providers.map(provider => { | ||
| let providerSignals = []; | ||
| try { | ||
| providerSignals = provider.loadSignals(); | ||
| } | ||
| catch { | ||
| // Non-fatal | ||
| } | ||
| return { | ||
| providerName: provider.name(), | ||
| signals: providerSignals, | ||
| weights: provider.qualityWeights?.(), | ||
| }; | ||
| }); | ||
| } | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWxsaWdlbmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludGVsbGlnZW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQXNGSDs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFHN0IsWUFBWSxRQUFnQjtRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDO0lBRUQsSUFBSTtRQUNGLE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDO1lBQ0gsOERBQThEO1lBQzlELE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDbEMsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDO1lBQ0QsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3BELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDekIsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBNkIsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDbEQsRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDekIsZUFBZSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUM7Z0JBQzVFLE9BQU8sRUFBRSxN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QUUsQ0FBQztZQUMxQyxJQUFJLENBQUM7Z0JBQ0gsZUFBZSxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQyxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLFlBQVk7WUFDZCxDQUFDO1lBQ0QsT0FBTztnQkFDTCxZQUFZLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRTtnQkFDN0IsT0FBTyxFQUFFLGVBQWU7Z0JBQ3hCLE9BQU8sRUFBRSxRQUFRLENBQUMsY0FBYyxFQUFFLEVBQUU7YUFDckMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFeHRlcm5hbCBJbnRlbGxpZ2VuY2UgUHJvdmlkZXJzIGZvciBTT05BIExlYXJuaW5nIChBRFItMDQzKVxuICpcbiAqIFR5cGVTY3JpcHQgYmluZGluZ3MgZm9yIHRoZSBJbnRlbGxpZ2VuY2VQcm92aWRlciB0cmFpdCwgZW5hYmxpbmdcbiAqIGV4dGVybmFsIHN5c3RlbXMgdG8gZmVlZCBxdWFsaXR5IHNpZ25hbHMgaW50byBSdXZMTE0ncyBsZWFybmluZyBsb29wcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgSW50ZWxsaWdlbmNlTG9hZGVyLCBGaWxlU2lnbmFsUHJvdmlkZXIsIFF1YWxpdHlTaWduYWwgfSBmcm9tICdAcnV2ZWN0b3IvcnV2bGxtJztcbiAqXG4gKiBjb25zdCBsb2FkZXIgPSBuZXcgSW50ZWxsaWdlbmNlTG9hZGVyKCk7XG4gKiBsb2FkZXIucmVnaXN0ZXJQcm92aWRlcihuZXcgRmlsZVNpZ25hbFByb3ZpZGVyKCcuL3NpZ25hbHMuanNvbicpKTtcbiAqXG4gKiBjb25zdCB7IHNpZ25hbHMsIGVycm9ycyB9ID0gbG9hZGVyLmxvYWRBbGxTaWduYWxzKCk7XG4gKiBjb25zb2xlLmxvZyhgTG9hZGVkICR7c2lnbmFscy5sZW5ndGh9IHNpZ25hbHNgKTtcbiAqIGBgYFxuICovXG5cbi8qKlxuICogQSBxdWFsaXR5IHNpZ25hbCBmcm9tIGFuIGV4dGVybmFsIHN5c3RlbS5cbiAqXG4gKiBSZXByZXNlbnRzIG9uZSBjb21wbGV0ZWQgdGFzayB3aXRoIHF1YWxpdHkgYXNzZXNzbWVudCBkYXRhXG4gKiB0aGF0IGNhbiBmZWVkIGludG8gU09OQSB0cmFqZWN0b3JpZXMsIHRoZSBlbWJlZGRpbmcgY2xhc3NpZmllcixcbiAqIGFuZCBtb2RlbCByb3V0ZXIgY2FsaWJyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVhbGl0eVNpZ25hbCB7XG4gIC8qKiBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhpcyBzaWduYWwgKi9cbiAgaWQ6IHN0cmluZztcbiAgLyoqIEh1bWFuLXJlYWRhYmxlIHRhc2sgZGVzY3JpcHRpb24gKHVzZWQgZm9yIGVtYmVkZGluZyBnZW5lcmF0aW9uKSAqL1xuICB0YXNrRGVzY3JpcHRpb246IHN0cmluZztcbiAgLyoqIEV4ZWN1dGlvbiBvdXRjb21lICovXG4gIG91dGNvbWU6ICdzdWNjZXNzJyB8ICdwYXJ0aWFsX3N1Y2Nlc3MnIHwgJ2ZhaWx1cmUnO1xuICAvKiogQ29tcG9zaXRlIHF1YWxpdHkgc2NvcmUgKDAuMCAtIDEuMCkgKi9cbiAgcXVhbGl0eVNjb3JlOiBudW1iZXI7XG4gIC8qKiBPcHRpb25hbCBodW1hbiB2ZXJkaWN0ICovXG4gIGh1bWFuVmVyZGljdD86ICdhcHByb3ZlZCcgfCAncmVqZWN0ZWQnO1xuICAvKiogT3B0aW9uYWwgc3RydWN0dXJlZCBxdWFsaXR5IGZhY3RvcnMgZm9yIGRldGFpbGVkIGFuYWx5c2lzICovXG4gIHF1YWxpdHlGYWN0b3JzPzogUXVhbGl0eUZhY3RvcnM7XG4gIC8qKiBJU08gODYwMSB0aW1lc3RhbXAgb2YgdGFzayBjb21wbGV0aW9uICovXG4gIGNvbXBsZXRlZEF0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogR3JhbnVsYXIgcXVhbGl0eSBmYWN0b3IgYnJlYWtkb3duLlxuICpcbiAqIE5vdCBhbGwgcHJvdmlkZXJzIHdpbGwgaGF2ZSBhbGwgZmFjdG9ycy4gVW5kZWZpbmVkIGZpZWxkcyBtZWFuXG4gKiBcIm5vdCBhc3Nlc3NlZFwiIChkaXN0aW5jdCBmcm9tIDAuMCwgd2hpY2ggbWVhbnMgXCJhc3Nlc3NlZCBhcyB6ZXJvXCIpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFF1YWxpdHlGYWN0b3JzIHtcbiAgYWNjZXB0YW5jZUNyaXRlcmlhTWV0PzogbnVtYmVyO1xuICB0ZXN0c1Bhc3Npbmc/OiBudW1iZXI7XG4gIG5vUmVncmVzc2lvbnM/OiBudW1iZXI7XG4gIGxpbnRDbGVhbj86IG51bWJlcjtcbiAgdHlwZUNoZWNrQ2xlYW4/OiBudW1iZXI7XG4gIGZvbGxvd3NQYXR0ZXJucz86IG51bWJlcjtcbiAgY29udGV4dFJlbGV2YW5jZT86IG51bWJlcjtcbiAgcmVhc29uaW5nQ29oZXJlbmNlPzogbnVtYmVyO1xuICBleGVjdXRpb25FZmZpY2llbmN5PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFF1YWxpdHkgd2VpZ2h0IG92ZXJyaWRlcyBmcm9tIGEgcHJvdmlkZXIuXG4gKlxuICogV2VpZ2h0cyBzaG91bGQgc3VtIHRvIGFwcHJveGltYXRlbHkgMS4wLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3ZpZGVyUXVhbGl0eVdlaWdodHMge1xuICB0YXNrQ29tcGxldGlvbjogbnVtYmVyO1xuICBjb2RlUXVhbGl0eTogbnVtYmVyO1xuICBwcm9jZXNzOiBudW1iZXI7XG59XG5cbi8qKlxuICogRXJyb3IgZnJvbSBhIHNpbmdsZSBwcm92aWRlciBkdXJpbmcgYmF0Y2ggbG9hZGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aWRlckVycm9yIHtcbiAgcHJvdmlkZXJOYW1lOiBzdHJpbmc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXN1bHQgZnJvbSBhIHNpbmdsZSBwcm92aWRlciBkdXJpbmcgZ3JvdXBlZCBsb2FkaW5nLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3ZpZGVyUmVzdWx0IHtcbiAgcHJvdmlkZXJOYW1lOiBzdHJpbmc7XG4gIHNpZ25hbHM6IFF1YWxpdHlTaWduYWxbXTtcbiAgd2VpZ2h0cz86IFByb3ZpZGVyUXVhbGl0eVdlaWdodHM7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBleHRlcm5hbCBzeXN0ZW1zIHRoYXQgc3VwcGx5IHF1YWxpdHkgc2lnbmFscyB0byBSdXZMTE0uXG4gKlxuICogSW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIGFuZCByZWdpc3RlciB3aXRoIEludGVsbGlnZW5jZUxvYWRlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnRlbGxpZ2VuY2VQcm92aWRlciB7XG4gIC8qKiBIdW1hbi1yZWFkYWJsZSBuYW1lIGZvciB0aGlzIHByb3ZpZGVyICovXG4gIG5hbWUoKTogc3RyaW5nO1xuICAvKiogTG9hZCBxdWFsaXR5IHNpZ25hbHMgZnJvbSB0aGlzIHByb3ZpZGVyJ3MgZGF0YSBzb3VyY2UgKi9cbiAgbG9hZFNpZ25hbHMoKTogUXVhbGl0eVNpZ25hbFtdO1xuICAvKiogT3B0aW9uYWwgcXVhbGl0eSB3ZWlnaHQgb3ZlcnJpZGVzICovXG4gIHF1YWxpdHlXZWlnaHRzPygpOiBQcm92aWRlclF1YWxpdHlXZWlnaHRzIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEJ1aWx0LWluIGZpbGUtYmFzZWQgaW50ZWxsaWdlbmNlIHByb3ZpZGVyLlxuICpcbiAqIFJlYWRzIHF1YWxpdHkgc2lnbmFscyBmcm9tIGEgSlNPTiBmaWxlLiBUaGlzIGlzIHRoZSBkZWZhdWx0IHByb3ZpZGVyXG4gKiBmb3Igbm9uLVJ1c3QgaW50ZWdyYXRpb25zIHRoYXQgd3JpdGUgc2lnbmFsIGZpbGVzLlxuICovXG5leHBvcnQgY2xhc3MgRmlsZVNpZ25hbFByb3ZpZGVyIGltcGxlbWVudHMgSW50ZWxsaWdlbmNlUHJvdmlkZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoZmlsZVBhdGg6IHN0cmluZykge1xuICAgIHRoaXMuZmlsZVBhdGggPSBmaWxlUGF0aDtcbiAgfVxuXG4gIG5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ2ZpbGUtc2lnbmFscyc7XG4gIH1cblxuICBsb2FkU2lnbmFscygpOiBRdWFsaXR5U2lnbmFsW10ge1xuICAgIHRyeSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICAgICAgY29uc3QgZnMgPSByZXF1aXJlKCdmcycpO1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRoaXMuZmlsZVBhdGgpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLmZpbGVQYXRoLCAndXRmLTgnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGEubWFwKChpdGVtOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gKHtcbiAgICAgICAgaWQ6IFN0cmluZyhpdGVtLmlkID8/ICcnKSxcbiAgICAgICAgdGFza0Rlc2NyaXB0aW9uOiBTdHJpbmcoaXRlbS50YXNrX2Rlc2NyaXB0aW9uID8/IGl0ZW0udGFza0Rlc2NyaXB0aW9uID8/ICcnKSxcbiAgICAgICAgb3V0Y29tZTogU3RyaW5nKGl0ZW0ub3V0Y29tZSA/PyAnZmFpbHVyZScpIGFzIFF1YWxpdHlTaWduYWxbJ291dGNvbWUnXSxcbiAgICAgICAgcXVhbGl0eVNjb3JlOiBOdW1iZXIoaXRlbS5xdWFsaXR5X3Njb3JlID8/IGl0ZW0ucXVhbGl0eVNjb3JlID8/IDApLFxuICAgICAgICBodW1hblZlcmRpY3Q6IGl0ZW0uaHVtYW5fdmVyZGljdCA/PyBpdGVtLmh1bWFuVmVyZGljdFxuICAgICAgICAgID8gU3RyaW5nKGl0ZW0uaHVtYW5fdmVyZGljdCA/PyBpdGVtLmh1bWFuVmVyZGljdCkgYXMgUXVhbGl0eVNpZ25hbFsnaHVtYW5WZXJkaWN0J11cbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgcXVhbGl0eUZhY3RvcnM6IChpdGVtLnF1YWxpdHlfZmFjdG9ycyB8fCBpdGVtLnF1YWxpdHlGYWN0b3JzKVxuICAgICAgICAgID8gbWFwUXVhbGl0eUZhY3RvcnMoKGl0ZW0ucXVhbGl0eV9mYWN0b3JzID8/IGl0ZW0ucXVhbGl0eUZhY3RvcnMpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVxuICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICBjb21wbGV0ZWRBdDogU3RyaW5nKGl0ZW0uY29tcGxldGVkX2F0ID8/IGl0ZW0uY29tcGxldGVkQXQgPz8gbmV3IERhdGUoKS50b0lTT1N0cmluZygpKSxcbiAgICAgIH0pKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cblxuICBxdWFsaXR5V2VpZ2h0cygpOiBQcm92aWRlclF1YWxpdHlXZWlnaHRzIHwgdW5kZWZpbmVkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZnMgPSByZXF1aXJlKCdmcycpO1xuICAgICAgY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbiAgICAgIGNvbnN0IHdlaWdodHNQYXRoID0gcGF0aC5qb2luKHBhdGguZGlybmFtZSh0aGlzLmZpbGVQYXRoKSwgJ3F1YWxpdHktd2VpZ2h0cy5qc29uJyk7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMod2VpZ2h0c1BhdGgpKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgcmF3ID0gZnMucmVhZEZpbGVTeW5jKHdlaWdodHNQYXRoLCAndXRmLTgnKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0YXNrQ29tcGxldGlvbjogTnVtYmVyKGRhdGEudGFza19jb21wbGV0aW9uID8/IGRhdGEudGFza0NvbXBsZXRpb24gPz8gMC41KSxcbiAgICAgICAgY29kZVF1YWxpdHk6IE51bWJlcihkYXRhLmNvZGVfcXVhbGl0eSA/PyBkYXRhLmNvZGVRdWFsaXR5ID8/IDAuMyksXG4gICAgICAgIHByb2Nlc3M6IE51bWJlcihkYXRhLnByb2Nlc3MgPz8gMC4yKSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtYXBRdWFsaXR5RmFjdG9ycyhyYXc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUXVhbGl0eUZhY3RvcnMge1xuICByZXR1cm4ge1xuICAgIGFjY2VwdGFuY2VDcml0ZXJpYU1ldDogcmF3LmFjY2VwdGFuY2VfY3JpdGVyaWFfbWV0IGFzIG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICB0ZXN0c1Bhc3Npbmc6IHJhdy50ZXN0c19wYXNzaW5nIGFzIG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICBub1JlZ3Jlc3Npb25zOiByYXcubm9fcmVncmVzc2lvbnMgYXMgbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIGxpbnRDbGVhbjogcmF3LmxpbnRfY2xlYW4gYXMgbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIHR5cGVDaGVja0NsZWFuOiByYXcudHlwZV9jaGVja19jbGVhbiBhcyBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgZm9sbG93c1BhdHRlcm5zOiByYXcuZm9sbG93c19wYXR0ZXJucyBhcyBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgY29udGV4dFJlbGV2YW5jZTogcmF3LmNvbnRleHRfcmVsZXZhbmNlIGFzIG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICByZWFzb25pbmdDb2hlcmVuY2U6IHJhdy5yZWFzb25pbmdfY29oZXJlbmNlIGFzIG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICBleGVjdXRpb25FZmZpY2llbmN5OiByYXcuZXhlY3V0aW9uX2VmZmljaWVuY3kgYXMgbnVtYmVyIHwgdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIEFnZ3JlZ2F0ZXMgcXVhbGl0eSBzaWduYWxzIGZyb20gbXVsdGlwbGUgcmVnaXN0ZXJlZCBwcm92aWRlcnMuXG4gKlxuICogSWYgbm8gcHJvdmlkZXJzIGFyZSByZWdpc3RlcmVkLCBsb2FkQWxsU2lnbmFscyByZXR1cm5zIGVtcHR5IGFycmF5c1xuICogd2l0aCB6ZXJvIG92ZXJoZWFkLlxuICovXG5leHBvcnQgY2xhc3MgSW50ZWxsaWdlbmNlTG9hZGVyIHtcbiAgcHJpdmF0ZSBwcm92aWRlcnM6IEludGVsbGlnZW5jZVByb3ZpZGVyW10gPSBbXTtcblxuICAvKiogUmVnaXN0ZXIgYW4gZXh0ZXJuYWwgaW50ZWxsaWdlbmNlIHByb3ZpZGVyICovXG4gIHJlZ2lzdGVyUHJvdmlkZXIocHJvdmlkZXI6IEludGVsbGlnZW5jZVByb3ZpZGVyKTogdm9pZCB7XG4gICAgdGhpcy5wcm92aWRlcnMucHVzaChwcm92aWRlcik7XG4gIH1cblxuICAvKiogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHJlZ2lzdGVyZWQgcHJvdmlkZXJzICovXG4gIGdldCBwcm92aWRlckNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucHJvdmlkZXJzLmxlbmd0aDtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBuYW1lcyBvZiBhbGwgcmVnaXN0ZXJlZCBwcm92aWRlcnMgKi9cbiAgZ2V0IHByb3ZpZGVyTmFtZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLnByb3ZpZGVycy5tYXAocCA9PiBwLm5hbWUoKSk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBzaWduYWxzIGZyb20gYWxsIHJlZ2lzdGVyZWQgcHJvdmlkZXJzLlxuICAgKlxuICAgKiBOb24tZmF0YWw6IGlmIGEgcHJvdmlkZXIgZmFpbHMsIGl0cyBlcnJvciBpcyBjYXB0dXJlZCBidXRcbiAgICogb3RoZXIgcHJvdmlkZXJzIGNvbnRpbnVlIGxvYWRpbmcuXG4gICAqL1xuICBsb2FkQWxsU2lnbmFscygpOiB7IHNpZ25hbHM6IFF1YWxpdHlTaWduYWxbXTsgZXJyb3JzOiBQcm92aWRlckVycm9yW10gfSB7XG4gICAgY29uc3Qgc2lnbmFsczogUXVhbGl0eVNpZ25hbFtdID0gW107XG4gICAgY29uc3QgZXJyb3JzOiBQcm92aWRlckVycm9yW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgcHJvdmlkZXIgb2YgdGhpcy5wcm92aWRlcnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyU2lnbmFscyA9IHByb3ZpZGVyLmxvYWRTaWduYWxzKCk7XG4gICAgICAgIHNpZ25hbHMucHVzaCguLi5wcm92aWRlclNpZ25hbHMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgICAgcHJvdmlkZXJOYW1lOiBwcm92aWRlci5uYW1lKCksXG4gICAgICAgICAgbWVzc2FnZTogZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogU3RyaW5nKGUpLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBzaWduYWxzLCBlcnJvcnMgfTtcbiAgfVxuXG4gIC8qKiBMb2FkIHNpZ25hbHMgZ3JvdXBlZCBieSBwcm92aWRlciB3aXRoIHdlaWdodCBvdmVycmlkZXMgKi9cbiAgbG9hZEdyb3VwZWQoKTogUHJvdmlkZXJSZXN1bHRbXSB7XG4gICAgcmV0dXJuIHRoaXMucHJvdmlkZXJzLm1hcChwcm92aWRlciA9PiB7XG4gICAgICBsZXQgcHJvdmlkZXJTaWduYWxzOiBRdWFsaXR5U2lnbmFsW10gPSBbXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHByb3ZpZGVyU2lnbmFscyA9IHByb3ZpZGVyLmxvYWRTaWduYWxzKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gTm9uLWZhdGFsXG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcm92aWRlck5hbWU6IHByb3ZpZGVyLm5hbWUoKSxcbiAgICAgICAgc2lnbmFsczogcHJvdmlkZXJTaWduYWxzLFxuICAgICAgICB3ZWlnaHRzOiBwcm92aWRlci5xdWFsaXR5V2VpZ2h0cz8uKCksXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59XG4iXX0= |
@@ -65,5 +65,5 @@ /** | ||
| export * from './benchmarks'; | ||
| export * from './rlm'; | ||
| export * from './intelligence'; | ||
| export { version, hasSimdSupport } from './native'; | ||
| export { RuvLLM as default } from './engine'; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,QAAQ,CAAC;AAGvB,cAAc,WAAW,CAAC;AAG1B,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,UAAU,CAAC;AAGzB,cAAc,YAAY,CAAC;AAG3B,cAAc,eAAe,CAAC;AAG9B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAG7B,cAAc,OAAO,CAAC;AAGtB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,QAAQ,CAAC;AAGvB,cAAc,WAAW,CAAC;AAG1B,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,UAAU,CAAC;AAGzB,cAAc,YAAY,CAAC;AAG3B,cAAc,eAAe,CAAC;AAG9B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC"} |
@@ -95,4 +95,4 @@ "use strict"; | ||
| __exportStar(require("./benchmarks"), exports); | ||
| // RLM - Retrieval Language Model | ||
| __exportStar(require("./rlm"), exports); | ||
| // External Intelligence Providers (ADR-043) | ||
| __exportStar(require("./intelligence"), exports); | ||
| // Native bindings utilities | ||
@@ -105,2 +105,2 @@ var native_1 = require("./native"); | ||
| Object.defineProperty(exports, "default", { enumerable: true, get: function () { return engine_1.RuvLLM; } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtERzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFSCxhQUFhO0FBQ2IsMENBQXdCO0FBRXhCLGNBQWM7QUFDZCwyQ0FBeUI7QUFFekIsa0JBQWtCO0FBQ2xCLHlDQUF1QjtBQUV2QixxQkFBcUI7QUFDckIsNENBQTBCO0FBRTFCLG9CQUFvQjtBQUNwQiw4Q0FBNEI7QUFFNUIsdUJBQXVCO0FBQ3ZCLHlDQUF1QjtBQUV2QixxQkFBcUI7QUFDckIsOENBQTRCO0FBRTVCLGdCQUFnQjtBQUNoQix5Q0FBdUI7QUFFdkIsdUJBQXVCO0FBQ3ZCLDJDQUF5QjtBQUV6QixvQkFBb0I7QUFDcEIsNkNBQTJCO0FBRTNCLDBCQUEwQjtBQUMxQixnREFBOEI7QUFFOUIsZ0NBQWdDO0FBQ2hDLDJDQUF5QjtBQUV6Qix1Q0FBdUM7QUFDdkMsK0NBQTZCO0FBRTdCLGlDQUFpQztBQUNqQyx3Q0FBc0I7QUFFdEIsNEJBQTRCO0FBQzVCLG1DQUFtRDtBQUExQyxpR0FBQSxPQUFPLE9BQUE7QUFBRSx3R0FBQSxjQUFjLE9BQUE7QUFFaEMsaUJBQWlCO0FBQ2pCLG1DQUE2QztBQUFwQyxpR0FBQSxNQUFNLE9BQVciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBydXZlY3Rvci9ydXZsbG0gLSBTZWxmLWxlYXJuaW5nIExMTSBvcmNoZXN0cmF0aW9uXG4gKlxuICogUnV2TExNIGNvbWJpbmVzIFNPTkEgYWRhcHRpdmUgbGVhcm5pbmcgd2l0aCBITlNXIG1lbW9yeSxcbiAqIEZhc3RHUk5OIHJvdXRpbmcsIGFuZCBTSU1ELW9wdGltaXplZCBpbmZlcmVuY2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFJ1dkxMTSwgU2Vzc2lvbk1hbmFnZXIsIFNvbmFDb29yZGluYXRvciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IGxsbSA9IG5ldyBSdXZMTE0oeyBsZWFybmluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gKiBjb25zdCBzZXNzaW9ucyA9IG5ldyBTZXNzaW9uTWFuYWdlcihsbG0pO1xuICogY29uc3Qgc29uYSA9IG5ldyBTb25hQ29vcmRpbmF0b3IoKTtcbiAqXG4gKiAvLyBRdWVyeSB3aXRoIHNlc3Npb24gY29udGV4dFxuICogY29uc3Qgc2Vzc2lvbiA9IHNlc3Npb25zLmNyZWF0ZSgpO1xuICogY29uc3QgcmVzcG9uc2UgPSBzZXNzaW9ucy5jaGF0KHNlc3Npb24uaWQsICdXaGF0IGlzIEFJPycpO1xuICpcbiAqIC8vIFRyYWNrIGxlYXJuaW5nIHRyYWplY3RvcnlcbiAqIGNvbnN0IHRyYWplY3RvcnkgPSBuZXcgVHJhamVjdG9yeUJ1aWxkZXIoKVxuICogICAuc3RhcnRTdGVwKCdxdWVyeScsICdXaGF0IGlzIEFJPycpXG4gKiAgIC5lbmRTdGVwKHJlc3BvbnNlLnRleHQsIHJlc3BvbnNlLmNvbmZpZGVuY2UpXG4gKiAgIC5jb21wbGV0ZSgnc3VjY2VzcycpO1xuICpcbiAqIHNvbmEucmVjb3JkVHJhamVjdG9yeSh0cmFqZWN0b3J5KTtcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIEZlZGVyYXRlZCBMZWFybmluZ1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgRXBoZW1lcmFsQWdlbnQsIEZlZGVyYXRlZENvb3JkaW5hdG9yIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogLy8gQ2VudHJhbCBjb29yZGluYXRvclxuICogY29uc3QgY29vcmRpbmF0b3IgPSBuZXcgRmVkZXJhdGVkQ29vcmRpbmF0b3IoJ2Nvb3JkLTEnKTtcbiAqXG4gKiAvLyBFcGhlbWVyYWwgYWdlbnRzIHByb2Nlc3MgdGFza3MgYW5kIGV4cG9ydFxuICogY29uc3QgYWdlbnQgPSBuZXcgRXBoZW1lcmFsQWdlbnQoJ2FnZW50LTEnKTtcbiAqIGFnZW50LnByb2Nlc3NUYXNrKGVtYmVkZGluZywgMC45KTtcbiAqIGNvbnN0IGV4cG9ydERhdGEgPSBhZ2VudC5leHBvcnRTdGF0ZSgpO1xuICpcbiAqIC8vIEFnZ3JlZ2F0ZSBsZWFybmluZ1xuICogY29vcmRpbmF0b3IuYWdncmVnYXRlKGV4cG9ydERhdGEpO1xuICogYGBgXG4gKlxuICogQGV4YW1wbGUgTG9SQSBBZGFwdGVyc1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgTG9yYUFkYXB0ZXIsIExvcmFNYW5hZ2VyIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogY29uc3QgYWRhcHRlciA9IG5ldyBMb3JhQWRhcHRlcih7IHJhbms6IDgsIGFscGhhOiAxNiB9KTtcbiAqIGNvbnN0IG91dHB1dCA9IGFkYXB0ZXIuZm9yd2FyZChpbnB1dCk7XG4gKiBgYGBcbiAqL1xuXG4vLyBDb3JlIHR5cGVzXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gTWFpbiBlbmdpbmVcbmV4cG9ydCAqIGZyb20gJy4vZW5naW5lJztcblxuLy8gU0lNRCBvcGVyYXRpb25zXG5leHBvcnQgKiBmcm9tICcuL3NpbWQnO1xuXG4vLyBTZXNzaW9uIG1hbmFnZW1lbnRcbmV4cG9ydCAqIGZyb20gJy4vc2Vzc2lvbic7XG5cbi8vIFN0cmVhbWluZyBzdXBwb3J0XG5leHBvcnQgKiBmcm9tICcuL3N0cmVhbWluZyc7XG5cbi8vIFNPTkEgbGVhcm5pbmcgc3lzdGVtXG5leHBvcnQgKiBmcm9tICcuL3NvbmEnO1xuXG4vLyBGZWRlcmF0ZWQgbGVhcm5pbmdcbmV4cG9ydCAqIGZyb20gJy4vZmVkZXJhdGVkJztcblxuLy8gTG9SQSBhZGFwdGVyc1xuZXhwb3J0ICogZnJvbSAnLi9sb3JhJztcblxuLy8gRXhwb3J0L3NlcmlhbGl6YXRpb25cbmV4cG9ydCAqIGZyb20gJy4vZXhwb3J0JztcblxuLy8gVHJhaW5pbmcgcGlwZWxpbmVcbmV4cG9ydCAqIGZyb20gJy4vdHJhaW5pbmcnO1xuXG4vLyBDb250cmFzdGl2ZSBmaW5lLXR1bmluZ1xuZXhwb3J0ICogZnJvbSAnLi9jb250cmFzdGl2ZSc7XG5cbi8vIE1vZGVsIGRvd25sb2FkZXIgYW5kIHJlZ2lzdHJ5XG5leHBvcnQgKiBmcm9tICcuL21vZGVscyc7XG5cbi8vIEJlbmNobWFya3MgZm9yIENsYXVkZSBDb2RlIHVzZSBjYXNlc1xuZXhwb3J0ICogZnJvbSAnLi9iZW5jaG1hcmtzJztcblxuLy8gUkxNIC0gUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsXG5leHBvcnQgKiBmcm9tICcuL3JsbSc7XG5cbi8vIE5hdGl2ZSBiaW5kaW5ncyB1dGlsaXRpZXNcbmV4cG9ydCB7IHZlcnNpb24sIGhhc1NpbWRTdXBwb3J0IH0gZnJvbSAnLi9uYXRpdmUnO1xuXG4vLyBEZWZhdWx0IGV4cG9ydFxuZXhwb3J0IHsgUnV2TExNIGFzIGRlZmF1bHQgfSBmcm9tICcuL2VuZ2luZSc7XG4iXX0= | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtERzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFSCxhQUFhO0FBQ2IsMENBQXdCO0FBRXhCLGNBQWM7QUFDZCwyQ0FBeUI7QUFFekIsa0JBQWtCO0FBQ2xCLHlDQUF1QjtBQUV2QixxQkFBcUI7QUFDckIsNENBQTBCO0FBRTFCLG9CQUFvQjtBQUNwQiw4Q0FBNEI7QUFFNUIsdUJBQXVCO0FBQ3ZCLHlDQUF1QjtBQUV2QixxQkFBcUI7QUFDckIsOENBQTRCO0FBRTVCLGdCQUFnQjtBQUNoQix5Q0FBdUI7QUFFdkIsdUJBQXVCO0FBQ3ZCLDJDQUF5QjtBQUV6QixvQkFBb0I7QUFDcEIsNkNBQTJCO0FBRTNCLDBCQUEwQjtBQUMxQixnREFBOEI7QUFFOUIsZ0NBQWdDO0FBQ2hDLDJDQUF5QjtBQUV6Qix1Q0FBdUM7QUFDdkMsK0NBQTZCO0FBRTdCLDRDQUE0QztBQUM1QyxpREFBK0I7QUFFL0IsNEJBQTRCO0FBQzVCLG1DQUFtRDtBQUExQyxpR0FBQSxPQUFPLE9BQUE7QUFBRSx3R0FBQSxjQUFjLE9BQUE7QUFFaEMsaUJBQWlCO0FBQ2pCLG1DQUE2QztBQUFwQyxpR0FBQSxNQUFNLE9BQVciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBydXZlY3Rvci9ydXZsbG0gLSBTZWxmLWxlYXJuaW5nIExMTSBvcmNoZXN0cmF0aW9uXG4gKlxuICogUnV2TExNIGNvbWJpbmVzIFNPTkEgYWRhcHRpdmUgbGVhcm5pbmcgd2l0aCBITlNXIG1lbW9yeSxcbiAqIEZhc3RHUk5OIHJvdXRpbmcsIGFuZCBTSU1ELW9wdGltaXplZCBpbmZlcmVuY2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFJ1dkxMTSwgU2Vzc2lvbk1hbmFnZXIsIFNvbmFDb29yZGluYXRvciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IGxsbSA9IG5ldyBSdXZMTE0oeyBsZWFybmluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gKiBjb25zdCBzZXNzaW9ucyA9IG5ldyBTZXNzaW9uTWFuYWdlcihsbG0pO1xuICogY29uc3Qgc29uYSA9IG5ldyBTb25hQ29vcmRpbmF0b3IoKTtcbiAqXG4gKiAvLyBRdWVyeSB3aXRoIHNlc3Npb24gY29udGV4dFxuICogY29uc3Qgc2Vzc2lvbiA9IHNlc3Npb25zLmNyZWF0ZSgpO1xuICogY29uc3QgcmVzcG9uc2UgPSBzZXNzaW9ucy5jaGF0KHNlc3Npb24uaWQsICdXaGF0IGlzIEFJPycpO1xuICpcbiAqIC8vIFRyYWNrIGxlYXJuaW5nIHRyYWplY3RvcnlcbiAqIGNvbnN0IHRyYWplY3RvcnkgPSBuZXcgVHJhamVjdG9yeUJ1aWxkZXIoKVxuICogICAuc3RhcnRTdGVwKCdxdWVyeScsICdXaGF0IGlzIEFJPycpXG4gKiAgIC5lbmRTdGVwKHJlc3BvbnNlLnRleHQsIHJlc3BvbnNlLmNvbmZpZGVuY2UpXG4gKiAgIC5jb21wbGV0ZSgnc3VjY2VzcycpO1xuICpcbiAqIHNvbmEucmVjb3JkVHJhamVjdG9yeSh0cmFqZWN0b3J5KTtcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIEZlZGVyYXRlZCBMZWFybmluZ1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgRXBoZW1lcmFsQWdlbnQsIEZlZGVyYXRlZENvb3JkaW5hdG9yIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogLy8gQ2VudHJhbCBjb29yZGluYXRvclxuICogY29uc3QgY29vcmRpbmF0b3IgPSBuZXcgRmVkZXJhdGVkQ29vcmRpbmF0b3IoJ2Nvb3JkLTEnKTtcbiAqXG4gKiAvLyBFcGhlbWVyYWwgYWdlbnRzIHByb2Nlc3MgdGFza3MgYW5kIGV4cG9ydFxuICogY29uc3QgYWdlbnQgPSBuZXcgRXBoZW1lcmFsQWdlbnQoJ2FnZW50LTEnKTtcbiAqIGFnZW50LnByb2Nlc3NUYXNrKGVtYmVkZGluZywgMC45KTtcbiAqIGNvbnN0IGV4cG9ydERhdGEgPSBhZ2VudC5leHBvcnRTdGF0ZSgpO1xuICpcbiAqIC8vIEFnZ3JlZ2F0ZSBsZWFybmluZ1xuICogY29vcmRpbmF0b3IuYWdncmVnYXRlKGV4cG9ydERhdGEpO1xuICogYGBgXG4gKlxuICogQGV4YW1wbGUgTG9SQSBBZGFwdGVyc1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgTG9yYUFkYXB0ZXIsIExvcmFNYW5hZ2VyIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogY29uc3QgYWRhcHRlciA9IG5ldyBMb3JhQWRhcHRlcih7IHJhbms6IDgsIGFscGhhOiAxNiB9KTtcbiAqIGNvbnN0IG91dHB1dCA9IGFkYXB0ZXIuZm9yd2FyZChpbnB1dCk7XG4gKiBgYGBcbiAqL1xuXG4vLyBDb3JlIHR5cGVzXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gTWFpbiBlbmdpbmVcbmV4cG9ydCAqIGZyb20gJy4vZW5naW5lJztcblxuLy8gU0lNRCBvcGVyYXRpb25zXG5leHBvcnQgKiBmcm9tICcuL3NpbWQnO1xuXG4vLyBTZXNzaW9uIG1hbmFnZW1lbnRcbmV4cG9ydCAqIGZyb20gJy4vc2Vzc2lvbic7XG5cbi8vIFN0cmVhbWluZyBzdXBwb3J0XG5leHBvcnQgKiBmcm9tICcuL3N0cmVhbWluZyc7XG5cbi8vIFNPTkEgbGVhcm5pbmcgc3lzdGVtXG5leHBvcnQgKiBmcm9tICcuL3NvbmEnO1xuXG4vLyBGZWRlcmF0ZWQgbGVhcm5pbmdcbmV4cG9ydCAqIGZyb20gJy4vZmVkZXJhdGVkJztcblxuLy8gTG9SQSBhZGFwdGVyc1xuZXhwb3J0ICogZnJvbSAnLi9sb3JhJztcblxuLy8gRXhwb3J0L3NlcmlhbGl6YXRpb25cbmV4cG9ydCAqIGZyb20gJy4vZXhwb3J0JztcblxuLy8gVHJhaW5pbmcgcGlwZWxpbmVcbmV4cG9ydCAqIGZyb20gJy4vdHJhaW5pbmcnO1xuXG4vLyBDb250cmFzdGl2ZSBmaW5lLXR1bmluZ1xuZXhwb3J0ICogZnJvbSAnLi9jb250cmFzdGl2ZSc7XG5cbi8vIE1vZGVsIGRvd25sb2FkZXIgYW5kIHJlZ2lzdHJ5XG5leHBvcnQgKiBmcm9tICcuL21vZGVscyc7XG5cbi8vIEJlbmNobWFya3MgZm9yIENsYXVkZSBDb2RlIHVzZSBjYXNlc1xuZXhwb3J0ICogZnJvbSAnLi9iZW5jaG1hcmtzJztcblxuLy8gRXh0ZXJuYWwgSW50ZWxsaWdlbmNlIFByb3ZpZGVycyAoQURSLTA0MylcbmV4cG9ydCAqIGZyb20gJy4vaW50ZWxsaWdlbmNlJztcblxuLy8gTmF0aXZlIGJpbmRpbmdzIHV0aWxpdGllc1xuZXhwb3J0IHsgdmVyc2lvbiwgaGFzU2ltZFN1cHBvcnQgfSBmcm9tICcuL25hdGl2ZSc7XG5cbi8vIERlZmF1bHQgZXhwb3J0XG5leHBvcnQgeyBSdXZMTE0gYXMgZGVmYXVsdCB9IGZyb20gJy4vZW5naW5lJztcbiJdfQ== |
@@ -65,5 +65,5 @@ /** | ||
| export * from './benchmarks'; | ||
| export * from './rlm'; | ||
| export * from './intelligence'; | ||
| export { version, hasSimdSupport } from './native'; | ||
| export { RuvLLM as default } from './engine'; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,QAAQ,CAAC;AAGvB,cAAc,WAAW,CAAC;AAG1B,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,UAAU,CAAC;AAGzB,cAAc,YAAY,CAAC;AAG3B,cAAc,eAAe,CAAC;AAG9B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAG7B,cAAc,OAAO,CAAC;AAGtB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,QAAQ,CAAC;AAGvB,cAAc,WAAW,CAAC;AAG1B,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,UAAU,CAAC;AAGzB,cAAc,YAAY,CAAC;AAG3B,cAAc,eAAe,CAAC;AAG9B,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC"} |
@@ -78,4 +78,4 @@ /** | ||
| export * from './benchmarks'; | ||
| // RLM - Retrieval Language Model | ||
| export * from './rlm'; | ||
| // External Intelligence Providers (ADR-043) | ||
| export * from './intelligence'; | ||
| // Native bindings utilities | ||
@@ -85,2 +85,2 @@ export { version, hasSimdSupport } from './native'; | ||
| export { RuvLLM as default } from './engine'; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0RHO0FBRUgsYUFBYTtBQUNiLGNBQWMsU0FBUyxDQUFDO0FBRXhCLGNBQWM7QUFDZCxjQUFjLFVBQVUsQ0FBQztBQUV6QixrQkFBa0I7QUFDbEIsY0FBYyxRQUFRLENBQUM7QUFFdkIscUJBQXFCO0FBQ3JCLGNBQWMsV0FBVyxDQUFDO0FBRTFCLG9CQUFvQjtBQUNwQixjQUFjLGFBQWEsQ0FBQztBQUU1Qix1QkFBdUI7QUFDdkIsY0FBYyxRQUFRLENBQUM7QUFFdkIscUJBQXFCO0FBQ3JCLGNBQWMsYUFBYSxDQUFDO0FBRTVCLGdCQUFnQjtBQUNoQixjQUFjLFFBQVEsQ0FBQztBQUV2Qix1QkFBdUI7QUFDdkIsY0FBYyxVQUFVLENBQUM7QUFFekIsb0JBQW9CO0FBQ3BCLGNBQWMsWUFBWSxDQUFDO0FBRTNCLDBCQUEwQjtBQUMxQixjQUFjLGVBQWUsQ0FBQztBQUU5QixnQ0FBZ0M7QUFDaEMsY0FBYyxVQUFVLENBQUM7QUFFekIsdUNBQXVDO0FBQ3ZDLGNBQWMsY0FBYyxDQUFDO0FBRTdCLGlDQUFpQztBQUNqQyxjQUFjLE9BQU8sQ0FBQztBQUV0Qiw0QkFBNEI7QUFDNUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFbkQsaUJBQWlCO0FBQ2pCLE9BQU8sRUFBRSxNQUFNLElBQUksT0FBTyxFQUFFLE1BQU0sVUFBVSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcnV2ZWN0b3IvcnV2bGxtIC0gU2VsZi1sZWFybmluZyBMTE0gb3JjaGVzdHJhdGlvblxuICpcbiAqIFJ1dkxMTSBjb21iaW5lcyBTT05BIGFkYXB0aXZlIGxlYXJuaW5nIHdpdGggSE5TVyBtZW1vcnksXG4gKiBGYXN0R1JOTiByb3V0aW5nLCBhbmQgU0lNRC1vcHRpbWl6ZWQgaW5mZXJlbmNlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBSdXZMTE0sIFNlc3Npb25NYW5hZ2VyLCBTb25hQ29vcmRpbmF0b3IgfSBmcm9tICdAcnV2ZWN0b3IvcnV2bGxtJztcbiAqXG4gKiBjb25zdCBsbG0gPSBuZXcgUnV2TExNKHsgbGVhcm5pbmdFbmFibGVkOiB0cnVlIH0pO1xuICogY29uc3Qgc2Vzc2lvbnMgPSBuZXcgU2Vzc2lvbk1hbmFnZXIobGxtKTtcbiAqIGNvbnN0IHNvbmEgPSBuZXcgU29uYUNvb3JkaW5hdG9yKCk7XG4gKlxuICogLy8gUXVlcnkgd2l0aCBzZXNzaW9uIGNvbnRleHRcbiAqIGNvbnN0IHNlc3Npb24gPSBzZXNzaW9ucy5jcmVhdGUoKTtcbiAqIGNvbnN0IHJlc3BvbnNlID0gc2Vzc2lvbnMuY2hhdChzZXNzaW9uLmlkLCAnV2hhdCBpcyBBST8nKTtcbiAqXG4gKiAvLyBUcmFjayBsZWFybmluZyB0cmFqZWN0b3J5XG4gKiBjb25zdCB0cmFqZWN0b3J5ID0gbmV3IFRyYWplY3RvcnlCdWlsZGVyKClcbiAqICAgLnN0YXJ0U3RlcCgncXVlcnknLCAnV2hhdCBpcyBBST8nKVxuICogICAuZW5kU3RlcChyZXNwb25zZS50ZXh0LCByZXNwb25zZS5jb25maWRlbmNlKVxuICogICAuY29tcGxldGUoJ3N1Y2Nlc3MnKTtcbiAqXG4gKiBzb25hLnJlY29yZFRyYWplY3RvcnkodHJhamVjdG9yeSk7XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZSBGZWRlcmF0ZWQgTGVhcm5pbmdcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IEVwaGVtZXJhbEFnZW50LCBGZWRlcmF0ZWRDb29yZGluYXRvciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIC8vIENlbnRyYWwgY29vcmRpbmF0b3JcbiAqIGNvbnN0IGNvb3JkaW5hdG9yID0gbmV3IEZlZGVyYXRlZENvb3JkaW5hdG9yKCdjb29yZC0xJyk7XG4gKlxuICogLy8gRXBoZW1lcmFsIGFnZW50cyBwcm9jZXNzIHRhc2tzIGFuZCBleHBvcnRcbiAqIGNvbnN0IGFnZW50ID0gbmV3IEVwaGVtZXJhbEFnZW50KCdhZ2VudC0xJyk7XG4gKiBhZ2VudC5wcm9jZXNzVGFzayhlbWJlZGRpbmcsIDAuOSk7XG4gKiBjb25zdCBleHBvcnREYXRhID0gYWdlbnQuZXhwb3J0U3RhdGUoKTtcbiAqXG4gKiAvLyBBZ2dyZWdhdGUgbGVhcm5pbmdcbiAqIGNvb3JkaW5hdG9yLmFnZ3JlZ2F0ZShleHBvcnREYXRhKTtcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIExvUkEgQWRhcHRlcnNcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IExvcmFBZGFwdGVyLCBMb3JhTWFuYWdlciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IGFkYXB0ZXIgPSBuZXcgTG9yYUFkYXB0ZXIoeyByYW5rOiA4LCBhbHBoYTogMTYgfSk7XG4gKiBjb25zdCBvdXRwdXQgPSBhZGFwdGVyLmZvcndhcmQoaW5wdXQpO1xuICogYGBgXG4gKi9cblxuLy8gQ29yZSB0eXBlc1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5cbi8vIE1haW4gZW5naW5lXG5leHBvcnQgKiBmcm9tICcuL2VuZ2luZSc7XG5cbi8vIFNJTUQgb3BlcmF0aW9uc1xuZXhwb3J0ICogZnJvbSAnLi9zaW1kJztcblxuLy8gU2Vzc2lvbiBtYW5hZ2VtZW50XG5leHBvcnQgKiBmcm9tICcuL3Nlc3Npb24nO1xuXG4vLyBTdHJlYW1pbmcgc3VwcG9ydFxuZXhwb3J0ICogZnJvbSAnLi9zdHJlYW1pbmcnO1xuXG4vLyBTT05BIGxlYXJuaW5nIHN5c3RlbVxuZXhwb3J0ICogZnJvbSAnLi9zb25hJztcblxuLy8gRmVkZXJhdGVkIGxlYXJuaW5nXG5leHBvcnQgKiBmcm9tICcuL2ZlZGVyYXRlZCc7XG5cbi8vIExvUkEgYWRhcHRlcnNcbmV4cG9ydCAqIGZyb20gJy4vbG9yYSc7XG5cbi8vIEV4cG9ydC9zZXJpYWxpemF0aW9uXG5leHBvcnQgKiBmcm9tICcuL2V4cG9ydCc7XG5cbi8vIFRyYWluaW5nIHBpcGVsaW5lXG5leHBvcnQgKiBmcm9tICcuL3RyYWluaW5nJztcblxuLy8gQ29udHJhc3RpdmUgZmluZS10dW5pbmdcbmV4cG9ydCAqIGZyb20gJy4vY29udHJhc3RpdmUnO1xuXG4vLyBNb2RlbCBkb3dubG9hZGVyIGFuZCByZWdpc3RyeVxuZXhwb3J0ICogZnJvbSAnLi9tb2RlbHMnO1xuXG4vLyBCZW5jaG1hcmtzIGZvciBDbGF1ZGUgQ29kZSB1c2UgY2FzZXNcbmV4cG9ydCAqIGZyb20gJy4vYmVuY2htYXJrcyc7XG5cbi8vIFJMTSAtIFJldHJpZXZhbCBMYW5ndWFnZSBNb2RlbFxuZXhwb3J0ICogZnJvbSAnLi9ybG0nO1xuXG4vLyBOYXRpdmUgYmluZGluZ3MgdXRpbGl0aWVzXG5leHBvcnQgeyB2ZXJzaW9uLCBoYXNTaW1kU3VwcG9ydCB9IGZyb20gJy4vbmF0aXZlJztcblxuLy8gRGVmYXVsdCBleHBvcnRcbmV4cG9ydCB7IFJ1dkxMTSBhcyBkZWZhdWx0IH0gZnJvbSAnLi9lbmdpbmUnO1xuIl19 | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0RHO0FBRUgsYUFBYTtBQUNiLGNBQWMsU0FBUyxDQUFDO0FBRXhCLGNBQWM7QUFDZCxjQUFjLFVBQVUsQ0FBQztBQUV6QixrQkFBa0I7QUFDbEIsY0FBYyxRQUFRLENBQUM7QUFFdkIscUJBQXFCO0FBQ3JCLGNBQWMsV0FBVyxDQUFDO0FBRTFCLG9CQUFvQjtBQUNwQixjQUFjLGFBQWEsQ0FBQztBQUU1Qix1QkFBdUI7QUFDdkIsY0FBYyxRQUFRLENBQUM7QUFFdkIscUJBQXFCO0FBQ3JCLGNBQWMsYUFBYSxDQUFDO0FBRTVCLGdCQUFnQjtBQUNoQixjQUFjLFFBQVEsQ0FBQztBQUV2Qix1QkFBdUI7QUFDdkIsY0FBYyxVQUFVLENBQUM7QUFFekIsb0JBQW9CO0FBQ3BCLGNBQWMsWUFBWSxDQUFDO0FBRTNCLDBCQUEwQjtBQUMxQixjQUFjLGVBQWUsQ0FBQztBQUU5QixnQ0FBZ0M7QUFDaEMsY0FBYyxVQUFVLENBQUM7QUFFekIsdUNBQXVDO0FBQ3ZDLGNBQWMsY0FBYyxDQUFDO0FBRTdCLDRDQUE0QztBQUM1QyxjQUFjLGdCQUFnQixDQUFDO0FBRS9CLDRCQUE0QjtBQUM1QixPQUFPLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUVuRCxpQkFBaUI7QUFDakIsT0FBTyxFQUFFLE1BQU0sSUFBSSxPQUFPLEVBQUUsTUFBTSxVQUFVLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBydXZlY3Rvci9ydXZsbG0gLSBTZWxmLWxlYXJuaW5nIExMTSBvcmNoZXN0cmF0aW9uXG4gKlxuICogUnV2TExNIGNvbWJpbmVzIFNPTkEgYWRhcHRpdmUgbGVhcm5pbmcgd2l0aCBITlNXIG1lbW9yeSxcbiAqIEZhc3RHUk5OIHJvdXRpbmcsIGFuZCBTSU1ELW9wdGltaXplZCBpbmZlcmVuY2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFJ1dkxMTSwgU2Vzc2lvbk1hbmFnZXIsIFNvbmFDb29yZGluYXRvciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IGxsbSA9IG5ldyBSdXZMTE0oeyBsZWFybmluZ0VuYWJsZWQ6IHRydWUgfSk7XG4gKiBjb25zdCBzZXNzaW9ucyA9IG5ldyBTZXNzaW9uTWFuYWdlcihsbG0pO1xuICogY29uc3Qgc29uYSA9IG5ldyBTb25hQ29vcmRpbmF0b3IoKTtcbiAqXG4gKiAvLyBRdWVyeSB3aXRoIHNlc3Npb24gY29udGV4dFxuICogY29uc3Qgc2Vzc2lvbiA9IHNlc3Npb25zLmNyZWF0ZSgpO1xuICogY29uc3QgcmVzcG9uc2UgPSBzZXNzaW9ucy5jaGF0KHNlc3Npb24uaWQsICdXaGF0IGlzIEFJPycpO1xuICpcbiAqIC8vIFRyYWNrIGxlYXJuaW5nIHRyYWplY3RvcnlcbiAqIGNvbnN0IHRyYWplY3RvcnkgPSBuZXcgVHJhamVjdG9yeUJ1aWxkZXIoKVxuICogICAuc3RhcnRTdGVwKCdxdWVyeScsICdXaGF0IGlzIEFJPycpXG4gKiAgIC5lbmRTdGVwKHJlc3BvbnNlLnRleHQsIHJlc3BvbnNlLmNvbmZpZGVuY2UpXG4gKiAgIC5jb21wbGV0ZSgnc3VjY2VzcycpO1xuICpcbiAqIHNvbmEucmVjb3JkVHJhamVjdG9yeSh0cmFqZWN0b3J5KTtcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIEZlZGVyYXRlZCBMZWFybmluZ1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgRXBoZW1lcmFsQWdlbnQsIEZlZGVyYXRlZENvb3JkaW5hdG9yIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogLy8gQ2VudHJhbCBjb29yZGluYXRvclxuICogY29uc3QgY29vcmRpbmF0b3IgPSBuZXcgRmVkZXJhdGVkQ29vcmRpbmF0b3IoJ2Nvb3JkLTEnKTtcbiAqXG4gKiAvLyBFcGhlbWVyYWwgYWdlbnRzIHByb2Nlc3MgdGFza3MgYW5kIGV4cG9ydFxuICogY29uc3QgYWdlbnQgPSBuZXcgRXBoZW1lcmFsQWdlbnQoJ2FnZW50LTEnKTtcbiAqIGFnZW50LnByb2Nlc3NUYXNrKGVtYmVkZGluZywgMC45KTtcbiAqIGNvbnN0IGV4cG9ydERhdGEgPSBhZ2VudC5leHBvcnRTdGF0ZSgpO1xuICpcbiAqIC8vIEFnZ3JlZ2F0ZSBsZWFybmluZ1xuICogY29vcmRpbmF0b3IuYWdncmVnYXRlKGV4cG9ydERhdGEpO1xuICogYGBgXG4gKlxuICogQGV4YW1wbGUgTG9SQSBBZGFwdGVyc1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgTG9yYUFkYXB0ZXIsIExvcmFNYW5hZ2VyIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogY29uc3QgYWRhcHRlciA9IG5ldyBMb3JhQWRhcHRlcih7IHJhbms6IDgsIGFscGhhOiAxNiB9KTtcbiAqIGNvbnN0IG91dHB1dCA9IGFkYXB0ZXIuZm9yd2FyZChpbnB1dCk7XG4gKiBgYGBcbiAqL1xuXG4vLyBDb3JlIHR5cGVzXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuLy8gTWFpbiBlbmdpbmVcbmV4cG9ydCAqIGZyb20gJy4vZW5naW5lJztcblxuLy8gU0lNRCBvcGVyYXRpb25zXG5leHBvcnQgKiBmcm9tICcuL3NpbWQnO1xuXG4vLyBTZXNzaW9uIG1hbmFnZW1lbnRcbmV4cG9ydCAqIGZyb20gJy4vc2Vzc2lvbic7XG5cbi8vIFN0cmVhbWluZyBzdXBwb3J0XG5leHBvcnQgKiBmcm9tICcuL3N0cmVhbWluZyc7XG5cbi8vIFNPTkEgbGVhcm5pbmcgc3lzdGVtXG5leHBvcnQgKiBmcm9tICcuL3NvbmEnO1xuXG4vLyBGZWRlcmF0ZWQgbGVhcm5pbmdcbmV4cG9ydCAqIGZyb20gJy4vZmVkZXJhdGVkJztcblxuLy8gTG9SQSBhZGFwdGVyc1xuZXhwb3J0ICogZnJvbSAnLi9sb3JhJztcblxuLy8gRXhwb3J0L3NlcmlhbGl6YXRpb25cbmV4cG9ydCAqIGZyb20gJy4vZXhwb3J0JztcblxuLy8gVHJhaW5pbmcgcGlwZWxpbmVcbmV4cG9ydCAqIGZyb20gJy4vdHJhaW5pbmcnO1xuXG4vLyBDb250cmFzdGl2ZSBmaW5lLXR1bmluZ1xuZXhwb3J0ICogZnJvbSAnLi9jb250cmFzdGl2ZSc7XG5cbi8vIE1vZGVsIGRvd25sb2FkZXIgYW5kIHJlZ2lzdHJ5XG5leHBvcnQgKiBmcm9tICcuL21vZGVscyc7XG5cbi8vIEJlbmNobWFya3MgZm9yIENsYXVkZSBDb2RlIHVzZSBjYXNlc1xuZXhwb3J0ICogZnJvbSAnLi9iZW5jaG1hcmtzJztcblxuLy8gRXh0ZXJuYWwgSW50ZWxsaWdlbmNlIFByb3ZpZGVycyAoQURSLTA0MylcbmV4cG9ydCAqIGZyb20gJy4vaW50ZWxsaWdlbmNlJztcblxuLy8gTmF0aXZlIGJpbmRpbmdzIHV0aWxpdGllc1xuZXhwb3J0IHsgdmVyc2lvbiwgaGFzU2ltZFN1cHBvcnQgfSBmcm9tICcuL25hdGl2ZSc7XG5cbi8vIERlZmF1bHQgZXhwb3J0XG5leHBvcnQgeyBSdXZMTE0gYXMgZGVmYXVsdCB9IGZyb20gJy4vZW5naW5lJztcbiJdfQ== |
+3
-7
| { | ||
| "name": "@ruvector/ruvllm", | ||
| "version": "2.4.1", | ||
| "description": "Self-learning LLM orchestration with SONA adaptive learning, HNSW memory, RLM recursive retrieval, FastGRNN routing, and SIMD inference", | ||
| "version": "2.5.0", | ||
| "description": "Self-learning LLM orchestration with SONA adaptive learning, HNSW memory, FastGRNN routing, and SIMD inference", | ||
| "main": "dist/cjs/index.js", | ||
@@ -77,4 +77,2 @@ "module": "dist/esm/index.js", | ||
| "llm", | ||
| "rlm", | ||
| "retrieval-language-model", | ||
| "self-learning", | ||
@@ -98,5 +96,3 @@ "adaptive-learning", | ||
| "rust", | ||
| "ruvector", | ||
| "rag", | ||
| "contrastive-learning" | ||
| "ruvector" | ||
| ], | ||
@@ -103,0 +99,0 @@ "author": "rUv Team <team@ruv.io>", |
+154
-394
@@ -1,41 +0,5 @@ | ||
| <div align="center"> | ||
| # @ruvector/ruvllm v2.3 | ||
| # @ruvector/ruvllm | ||
| Self-learning LLM orchestration with SONA adaptive learning, HNSW memory, and SIMD inference for Node.js. | ||
| ### The First Purpose-Built LLM Runtime for Claude Code Agent Orchestration | ||
| **100% Routing Accuracy | Sub-Millisecond Inference | Self-Learning** | ||
| [](https://www.npmjs.com/package/@ruvector/ruvllm) | ||
| [](https://www.npmjs.com/package/@ruvector/ruvllm) | ||
| [](LICENSE) | ||
| [](./test) | ||
| [Quick Start](#quick-start) | [RLM](#rlm-recursive-language-model) | [Training](#training) | [Models](#models) | [API](#api-reference) | ||
| </div> | ||
| --- | ||
| ## What is @ruvector/ruvllm? | ||
| **@ruvector/ruvllm** is a TypeScript/JavaScript SDK for intelligent LLM orchestration, specifically designed for **Claude Code** and multi-agent systems. It provides: | ||
| - **RLM (Recursive Language Model)** - Break complex queries into sub-queries, synthesize coherent answers | ||
| - **100% Routing Accuracy** - Hybrid keyword + embedding strategy for perfect agent selection | ||
| - **SONA Self-Learning** - Model improves with every successful interaction | ||
| - **SIMD Acceleration** - AVX2/NEON optimized inference | ||
| ### Why @ruvector/ruvllm? | ||
| | Challenge | Traditional Approach | @ruvector/ruvllm Solution | | ||
| |-----------|---------------------|---------------------------| | ||
| | Agent selection | Manual or keyword-based | Semantic + keyword hybrid = **100%** | | ||
| | Complex queries | Single-shot RAG | Recursive decomposition + synthesis | | ||
| | Response latency | 2-5 seconds | **<1ms** cache, 50-200ms full | | ||
| | Learning | Static models | **Self-improving** (SONA) | | ||
| | Cost per route | $0.01+ (API call) | **$0** (local inference) | | ||
| --- | ||
| ## Installation | ||
@@ -50,405 +14,214 @@ | ||
| ```typescript | ||
| import { RuvLLM, RlmController } from '@ruvector/ruvllm'; | ||
| import { RuvLLM, RuvLLMConfig } from '@ruvector/ruvllm'; | ||
| // Simple LLM inference | ||
| // Initialize with default configuration | ||
| const llm = new RuvLLM(); | ||
| // Or with custom configuration | ||
| const llm = new RuvLLM({ | ||
| modelPath: '~/.ruvllm/models/ruvltra-claude-code-0.5b-q4_k_m.gguf', | ||
| modelPath: './models/ruvltra-small-q4km.gguf', | ||
| sonaEnabled: true, | ||
| flashAttention: true, | ||
| maxTokens: 256, | ||
| }); | ||
| // Generate text | ||
| const response = await llm.query('Explain quantum computing'); | ||
| console.log(response.text); | ||
| // Recursive Language Model for complex queries | ||
| const rlm = new RlmController({ maxDepth: 5 }); | ||
| const answer = await rlm.query('What are the causes AND solutions for slow API responses?'); | ||
| // Automatically decomposes into sub-queries, retrieves context, synthesizes answer | ||
| // Stream generation | ||
| for await (const token of llm.stream('Write a haiku about Rust')) { | ||
| process.stdout.write(token); | ||
| } | ||
| ``` | ||
| --- | ||
| ## What's New in v2.3 | ||
| ## Core Features | ||
| | Feature | Description | | ||
| |---------|-------------| | ||
| | **RuvLTRA Models** | Purpose-built 0.5B & 3B models for Claude Flow | | ||
| | **Task-Specific LoRA** | 5 pre-trained adapters (coder, researcher, security, architect, reviewer) | | ||
| | **HuggingFace Hub** | Download/upload models directly | | ||
| | **Adapter Merging** | TIES, DARE, SLERP strategies | | ||
| | **HNSW Routing** | 150x faster semantic matching | | ||
| | **Evaluation Harness** | SWE-Bench testing with 5 ablation modes | | ||
| | **Auto-Dimension** | HNSW auto-detects model embedding size | | ||
| | **mistral-rs Backend** | Production serving with PagedAttention, X-LoRA, ISQ (5-10x concurrent users) | | ||
| ### 1. Claude Code Native Routing | ||
| ## CLI Usage | ||
| Built **by** Claude Code, **for** Claude Code. Routes tasks to 60+ agent types: | ||
| ```bash | ||
| # Query a model | ||
| ruvllm query "What is machine learning?" | ||
| ```typescript | ||
| import { RuvLLM } from '@ruvector/ruvllm'; | ||
| # Stream output | ||
| ruvllm query --stream "Write a poem" | ||
| const llm = new RuvLLM({ model: 'ruv/ruvltra' }); | ||
| # Download a model | ||
| ruvllm download ruvector/ruvltra-small-q4km | ||
| // Intelligent routing | ||
| const route = await llm.route('implement OAuth2 authentication'); | ||
| console.log(route.agent); // 'security-architect' | ||
| console.log(route.confidence); // 0.98 | ||
| console.log(route.tier); // 2 (Haiku-level complexity) | ||
| # Benchmark | ||
| ruvllm bench ./models/model.gguf | ||
| // Multi-agent teams for complex tasks | ||
| const team = await llm.routeComplex('build full-stack app with auth'); | ||
| // Returns: [system-architect, backend-dev, coder, security-architect, tester] | ||
| # Run evaluation (SWE-Bench) | ||
| ruvllm eval --model ./models/model.gguf --subset lite --max-tasks 50 | ||
| ``` | ||
| ### 2. 3-Tier Intelligent Routing | ||
| ## API Reference | ||
| ``` | ||
| ┌─────────────────────────────────────────────────────────┐ | ||
| │ User Request │ | ||
| └─────────────────────┬───────────────────────────────────┘ | ||
| ↓ | ||
| [RuvLTRA Routing] | ||
| ↓ | ||
| ┌─────────────┼─────────────┐ | ||
| ↓ ↓ ↓ | ||
| ┌───────────┐ ┌───────────┐ ┌───────────┐ | ||
| │ Tier 1 │ │ Tier 2 │ │ Tier 3 │ | ||
| │ Booster │ │ Haiku │ │ Opus │ | ||
| │ <1ms │ │ ~500ms │ │ 2-5s │ | ||
| │ $0 │ │ $0.0002 │ │ $0.015 │ | ||
| └───────────┘ └───────────┘ └───────────┘ | ||
| ``` | ||
| ### RuvLLM Class | ||
| ### 3. Self-Learning (SONA) | ||
| Every successful interaction improves the model: | ||
| ```typescript | ||
| // First routing: Full inference | ||
| llm.route('implement OAuth2') → security-architect (97%) | ||
| class RuvLLM { | ||
| constructor(config?: RuvLLMConfig); | ||
| // Later: Pattern hit in <25μs (learned from success) | ||
| llm.route('add OAuth2 flow') → security-architect (99%, cached pattern) | ||
| ``` | ||
| // Generate text | ||
| query(prompt: string, params?: GenerateParams): Promise<Response>; | ||
| --- | ||
| // Stream generation | ||
| stream(prompt: string, params?: GenerateParams): AsyncIterable<string>; | ||
| ## RLM (Recursive Language Model) | ||
| // Load a model | ||
| loadModel(path: string): Promise<void>; | ||
| RLM provides **recursive query decomposition** - unlike traditional RAG that retrieves once, RLM breaks complex questions into sub-queries and synthesizes coherent answers. | ||
| // Get SONA learning stats | ||
| sonaStats(): SonaStats | null; | ||
| ### How It Works | ||
| // Adapt on feedback | ||
| adapt(input: Float32Array, quality: number): void; | ||
| } | ||
| ``` | ||
| Query: "What are the causes AND solutions for slow API responses?" | ||
| ↓ | ||
| [Decomposition] | ||
| / \ | ||
| "Causes of slow API?" "Solutions for slow API?" | ||
| ↓ ↓ | ||
| [Sub-answers] [Sub-answers] | ||
| \ / | ||
| [Synthesis] | ||
| ↓ | ||
| Coherent combined answer with sources | ||
| ``` | ||
| ### Basic Usage | ||
| ### Configuration | ||
| ```typescript | ||
| import { RlmController } from '@ruvector/ruvllm'; | ||
| const rlm = new RlmController({ | ||
| maxDepth: 5, | ||
| retrievalTopK: 10, | ||
| enableCache: true, | ||
| }); | ||
| // Add knowledge to memory | ||
| await rlm.addMemory('TypeScript adds static typing to JavaScript.'); | ||
| await rlm.addMemory('React is a library for building user interfaces.'); | ||
| // Query with recursive retrieval | ||
| const answer = await rlm.query('What are causes and solutions for type errors in React?'); | ||
| console.log(answer.text); // Comprehensive synthesized answer | ||
| console.log(answer.sources); // Source attributions | ||
| console.log(answer.qualityScore); // 0.0-1.0 | ||
| console.log(answer.confidence); // Routing confidence | ||
| ``` | ||
| ### Streaming | ||
| ```typescript | ||
| for await (const event of rlm.queryStream('Explain machine learning')) { | ||
| if (event.type === 'token') { | ||
| process.stdout.write(event.text); | ||
| } else { | ||
| console.log('\n\nQuality:', event.answer.qualityScore); | ||
| } | ||
| interface RuvLLMConfig { | ||
| modelPath?: string; // Path to GGUF model | ||
| sonaEnabled?: boolean; // Enable SONA learning (default: true) | ||
| flashAttention?: boolean; // Use Flash Attention 2 (default: true) | ||
| maxTokens?: number; // Max generation tokens (default: 256) | ||
| temperature?: number; // Sampling temperature (default: 0.7) | ||
| topP?: number; // Top-p sampling (default: 0.9) | ||
| } | ||
| ``` | ||
| ### With Self-Reflection | ||
| ### Generate Parameters | ||
| ```typescript | ||
| const rlm = new RlmController({ | ||
| enableReflection: true, | ||
| maxReflectionIterations: 2, | ||
| minQualityScore: 0.8, | ||
| }); | ||
| // Answers are iteratively refined until quality >= 0.8 | ||
| const answer = await rlm.query('Complex multi-part technical question...'); | ||
| ``` | ||
| ### RLM Configuration | ||
| ```typescript | ||
| interface RlmConfig { | ||
| maxDepth?: number; // Max recursion depth (default: 3) | ||
| maxSubQueries?: number; // Max sub-queries per level (default: 5) | ||
| tokenBudget?: number; // Token budget (default: 4096) | ||
| enableCache?: boolean; // Enable caching (default: true) | ||
| cacheTtl?: number; // Cache TTL in ms (default: 300000) | ||
| retrievalTopK?: number; // Memory spans to retrieve (default: 10) | ||
| minQualityScore?: number; // Min quality threshold (default: 0.7) | ||
| enableReflection?: boolean; // Enable self-reflection (default: false) | ||
| maxReflectionIterations?: number; // Max reflection loops (default: 2) | ||
| interface GenerateParams { | ||
| maxTokens?: number; | ||
| temperature?: number; | ||
| topP?: number; | ||
| topK?: number; | ||
| repetitionPenalty?: number; | ||
| stopSequences?: string[]; | ||
| } | ||
| ``` | ||
| --- | ||
| ## SIMD Module | ||
| ## Unique Capabilities | ||
| For direct access to optimized SIMD kernels: | ||
| ### 1. Memory-Augmented Routing | ||
| Every successful routing is stored in HNSW-indexed memory for instant recall: | ||
| ```typescript | ||
| // First time: Full inference (~50ms) | ||
| route("implement OAuth2") → security-architect (97% confidence) | ||
| // Later: Memory hit (<25μs) | ||
| route("add OAuth2 flow") → security-architect (99% confidence, cached) | ||
| ``` | ||
| ### 2. Confidence-Aware Escalation | ||
| ```typescript | ||
| // Low confidence automatically escalates | ||
| Confidence > 0.9 → Use recommended agent | ||
| Confidence 0.7-0.9 → Use with human confirmation | ||
| Confidence < 0.7 → Escalate to higher tier | ||
| ``` | ||
| ### 3. Batch SIMD Operations | ||
| ```typescript | ||
| import { simd } from '@ruvector/ruvllm/simd'; | ||
| // 4x faster vector operations with AVX2/NEON | ||
| const similarity = simd.batchCosineSimilarity(query, targets); | ||
| const attended = simd.flashAttention(q, k, v, scale); | ||
| ``` | ||
| // Dot product | ||
| const result = simd.dotProduct(vecA, vecB); | ||
| ### 4. Zero-Copy Caching | ||
| // Matrix multiplication | ||
| const output = simd.matmul(matrix, vector); | ||
| Arc-based string interning for 100-1000x faster cache hits on large responses. | ||
| // Flash Attention | ||
| const attended = simd.flashAttention(query, key, value, scale); | ||
| --- | ||
| ## Performance | ||
| ### Benchmarks (M4 Pro) | ||
| | Operation | Latency | Throughput | | ||
| |-----------|---------|------------| | ||
| | Query decomposition | 340 ns | 2.9M/s | | ||
| | Cache lookup | 23.5 ns | 42.5M/s | | ||
| | Embedding (384d) | 293 ns | 3.4M/s | | ||
| | Memory search (10k) | 0.4 ms | 2.5K/s | | ||
| | End-to-end routing | <1 ms | 1K+/s | | ||
| | Full RLM query | 50-200 ms | 5-20/s | | ||
| ### Routing Accuracy | ||
| | Strategy | RuvLTRA | Qwen Base | OpenAI | | ||
| |----------|---------|-----------|--------| | ||
| | Embedding Only | 45% | 40% | 52% | | ||
| | Keyword Only | 78% | 78% | N/A | | ||
| | **Hybrid** | **100%** | 95% | N/A | | ||
| ### Test Results | ||
| // RMS Normalization | ||
| simd.rmsNorm(hidden, weights, epsilon); | ||
| ``` | ||
| 145 tests passing | ||
| - RLM Controller: 24 tests | ||
| - Routing Accuracy: 18 tests | ||
| - Contrastive Training: 15 tests | ||
| - SIMD Operations: 22 tests | ||
| - SONA Learning: 19 tests | ||
| - Memory/HNSW: 21 tests | ||
| - Benchmarks: 26 tests | ||
| ``` | ||
| --- | ||
| ## Performance (M4 Pro) | ||
| ## Models | ||
| | Operation | Performance | | ||
| |-----------|-------------| | ||
| | Inference | 88-135 tok/s | | ||
| | Flash Attention | 320µs (seq=2048) | | ||
| | HNSW Search | 17-62µs | | ||
| | SONA Adapt | <1ms | | ||
| | Evaluation | 5 ablation modes | | ||
| ### HuggingFace Repository | ||
| ## Evaluation Harness | ||
| **URL**: [https://huggingface.co/ruv/ruvltra](https://huggingface.co/ruv/ruvltra) | ||
| Run model evaluations with SWE-Bench integration: | ||
| ### Available Models | ||
| | Model | Size | Purpose | Accuracy | | ||
| |-------|------|---------|----------| | ||
| | **ruvltra-claude-code-0.5b-q4_k_m** | 398 MB | Agent routing | **100%** (hybrid) | | ||
| | ruvltra-small-0.5b-q4_k_m | ~400 MB | Embeddings | - | | ||
| | ruvltra-medium-1.1b-q4_k_m | ~1 GB | Full inference | - | | ||
| ### Download Models | ||
| ```typescript | ||
| // Programmatic | ||
| import { downloadModel } from '@ruvector/ruvllm'; | ||
| await downloadModel('ruv/ruvltra', { quantization: 'q4_k_m' }); | ||
| import { RuvLLM, EvaluationHarness, AblationMode } from '@ruvector/ruvllm'; | ||
| // CLI | ||
| ruvllm download ruv/ruvltra | ||
| ``` | ||
| ### Auto-Download | ||
| Models are automatically downloaded on first use: | ||
| ```typescript | ||
| const llm = new RuvLLM({ model: 'ruv/ruvltra' }); | ||
| // Downloads to ~/.ruvllm/models/ if not present | ||
| ``` | ||
| --- | ||
| ## Training | ||
| ### Generate Routing Dataset | ||
| ```bash | ||
| node scripts/training/routing-dataset.js | ||
| # Output: 381 examples, 793 contrastive pairs, 156 hard negatives | ||
| ``` | ||
| ### Contrastive Fine-tuning | ||
| ```typescript | ||
| import { ContrastiveTrainer } from '@ruvector/ruvllm'; | ||
| const trainer = new ContrastiveTrainer({ | ||
| modelPath: './models/base.gguf', | ||
| loraRank: 8, | ||
| loraAlpha: 16, | ||
| learningRate: 1e-4, | ||
| const harness = new EvaluationHarness({ | ||
| modelPath: './models/model.gguf', | ||
| enableHnsw: true, | ||
| enableSona: true, | ||
| }); | ||
| const pairs = [ | ||
| { anchor: 'Fix auth bug', positive: 'coder', negative: 'researcher' }, | ||
| // ... more pairs | ||
| ]; | ||
| // Run single evaluation | ||
| const result = await harness.evaluate( | ||
| 'Fix the null pointer exception', | ||
| 'def process(data): return data.split()', | ||
| AblationMode.Full | ||
| ); | ||
| await trainer.train(pairs, { epochs: 10 }); | ||
| await trainer.save('./adapters/routing-lora'); | ||
| ``` | ||
| console.log(`Success: ${result.success}, Quality: ${result.qualityScore}`); | ||
| ### Training Scripts | ||
| | Script | Description | | ||
| |--------|-------------| | ||
| | `routing-dataset.js` | Generate 381 routing examples | | ||
| | `claude-code-synth.js` | Synthetic data generation | | ||
| | `contrastive-finetune.js` | LoRA fine-tuning pipeline | | ||
| | `rlm-dataset.js` | RLM training data (500 examples) | | ||
| --- | ||
| ## API Reference | ||
| ### RuvLLM Class | ||
| ```typescript | ||
| class RuvLLM { | ||
| constructor(config?: RuvLLMConfig); | ||
| query(prompt: string, params?: GenerateParams): Promise<Response>; | ||
| stream(prompt: string, params?: GenerateParams): AsyncIterable<string>; | ||
| route(task: string): Promise<RoutingResult>; | ||
| routeComplex(task: string): Promise<AgentTeam[]>; | ||
| loadModel(path: string): Promise<void>; | ||
| addMemory(text: string, metadata?: object): number; | ||
| searchMemory(query: string, topK?: number): MemoryResult[]; | ||
| sonaStats(): SonaStats | null; | ||
| adapt(input: Float32Array, quality: number): void; | ||
| // Run ablation study (Baseline, RetrievalOnly, AdaptersOnly, R+A, Full) | ||
| const report = await harness.runAblationStudy(tasks); | ||
| for (const [mode, metrics] of Object.entries(report.modeMetrics)) { | ||
| console.log(`${mode}: ${metrics.successRate * 100}% success`); | ||
| } | ||
| ``` | ||
| ### RlmController Class | ||
| ## mistral-rs Backend (Production Serving) | ||
| ```typescript | ||
| class RlmController { | ||
| constructor(config?: RlmConfig, engine?: RuvLLM); | ||
| For production deployments with 10-100+ concurrent users, use the mistral-rs backend: | ||
| query(input: string): Promise<RlmAnswer>; | ||
| queryStream(input: string): AsyncGenerator<StreamToken>; | ||
| addMemory(text: string, metadata?: object): Promise<string>; | ||
| searchMemory(query: string, topK?: number): Promise<MemorySpan[]>; | ||
| clearCache(): void; | ||
| getCacheStats(): { size: number; entries: number }; | ||
| updateConfig(config: Partial<RlmConfig>): void; | ||
| getConfig(): Required<RlmConfig>; | ||
| } | ||
| ``` | ||
| ### All Exports | ||
| ```typescript | ||
| import { | ||
| // Core | ||
| RuvLLM, RuvLLMConfig, | ||
| import { RuvLLM, MistralBackend, PagedAttentionConfig } from '@ruvector/ruvllm'; | ||
| // RLM | ||
| RlmController, RlmConfig, RlmAnswer, MemorySpan, StreamToken, | ||
| // Configure for production serving | ||
| const backend = new MistralBackend({ | ||
| // PagedAttention: 5-10x more concurrent users | ||
| pagedAttention: { | ||
| blockSize: 16, | ||
| maxBlocks: 4096, | ||
| gpuMemoryFraction: 0.9, | ||
| prefixCaching: true, | ||
| }, | ||
| // X-LoRA: Per-token adapter routing | ||
| xlora: { | ||
| adapters: ['./adapters/coder', './adapters/researcher'], | ||
| topK: 2, | ||
| }, | ||
| // ISQ: Runtime quantization | ||
| isq: { | ||
| bits: 4, | ||
| method: 'awq', | ||
| }, | ||
| }); | ||
| // Training | ||
| RlmTrainer, ContrastiveTrainer, createRlmTrainer, | ||
| DEFAULT_RLM_CONFIG, FAST_RLM_CONFIG, THOROUGH_RLM_CONFIG, | ||
| const llm = new RuvLLM({ backend }); | ||
| await llm.loadModel('mistralai/Mistral-7B-Instruct-v0.2'); | ||
| // SONA Learning | ||
| SonaCoordinator, TrajectoryBuilder, | ||
| // LoRA | ||
| LoraAdapter, LoraManager, | ||
| // Benchmarks | ||
| ModelComparisonBenchmark, RoutingBenchmark, EmbeddingBenchmark, | ||
| } from '@ruvector/ruvllm'; | ||
| // Serve multiple concurrent requests | ||
| const response = await llm.query('Write production code'); | ||
| ``` | ||
| --- | ||
| > **Note**: mistral-rs features require the Rust backend with `mistral-rs` feature enabled. Native bindings will use mistral-rs when available. | ||
| ## CLI | ||
| ## Supported Models | ||
| ```bash | ||
| # Route a task | ||
| ruvllm route "add unit tests for auth module" | ||
| # → Agent: tester | Confidence: 0.96 | Tier: 2 | ||
| - **RuvLTRA-Small** (494M) - Q4K, Q5K, Q8 | ||
| - **RuvLTRA-Medium** (3B) - Q4K, Q5K, Q8 | ||
| - **Qwen 2.5** (0.5B-72B) | ||
| - **Llama 3.x** (8B-70B) | ||
| - **Mistral** (7B-22B) | ||
| - **Phi-3** (3.8B-14B) | ||
| - **Gemma-2** (2B-27B) | ||
| # Query with streaming | ||
| ruvllm query --stream "Explain machine learning" | ||
| # Download models | ||
| ruvllm download ruv/ruvltra | ||
| # Run benchmarks | ||
| ruvllm bench ./models/model.gguf | ||
| # Evaluate (SWE-Bench) | ||
| ruvllm eval --model ./models/model.gguf --subset lite | ||
| ``` | ||
| --- | ||
| ## Platform Support | ||
@@ -458,35 +231,22 @@ | ||
| |----------|--------------|--------| | ||
| | macOS | arm64 (M1-M4) | Full support | | ||
| | macOS | x64 | Supported | | ||
| | Linux | x64 | Supported | | ||
| | Linux | arm64 | Supported | | ||
| | Windows | x64 | Supported | | ||
| | macOS | arm64 (M1-M4) | ✅ Full support | | ||
| | macOS | x64 | ✅ Supported | | ||
| | Linux | x64 | ✅ Supported | | ||
| | Linux | arm64 | ✅ Supported | | ||
| | Windows | x64 | ✅ Supported | | ||
| --- | ||
| ## Related Packages | ||
| - [@ruvector/core](https://www.npmjs.com/package/@ruvector/core) - Vector operations | ||
| - [@ruvector/sona](https://www.npmjs.com/package/@ruvector/sona) - SONA learning engine | ||
| - [@ruvector/ruvector](https://www.npmjs.com/package/@ruvector/ruvector) - Full Ruvector SDK | ||
| ## Links | ||
| | Resource | URL | | ||
| |----------|-----| | ||
| | **npm** | [npmjs.com/package/@ruvector/ruvllm](https://www.npmjs.com/package/@ruvector/ruvllm) | | ||
| | **HuggingFace** | [huggingface.co/ruv/ruvltra](https://huggingface.co/ruv/ruvltra) | | ||
| | **Crate (Rust)** | [crates.io/crates/ruvllm](https://crates.io/crates/ruvllm) | | ||
| | **Documentation** | [docs.rs/ruvllm](https://docs.rs/ruvllm) | | ||
| | **GitHub** | [github.com/ruvnet/ruvector](https://github.com/ruvnet/ruvector) | | ||
| | **Claude Flow** | [github.com/ruvnet/claude-flow](https://github.com/ruvnet/claude-flow) | | ||
| - [GitHub Repository](https://github.com/ruvnet/ruvector) | ||
| - [API Documentation](https://docs.rs/ruvllm) | ||
| - [Crate (Rust)](https://crates.io/crates/ruvllm) | ||
| --- | ||
| ## License | ||
| MIT OR Apache-2.0 | ||
| --- | ||
| <div align="center"> | ||
| **Built for Claude Code. Optimized for agents. Designed for speed.** | ||
| [Get Started](#quick-start) | [View on GitHub](https://github.com/ruvnet/ruvector) | ||
| </div> |
| { | ||
| "timestamp": "2026-01-21T14:48:06.797Z", | ||
| "timestamp": "2026-01-21T00:21:04.044Z", | ||
| "totalAccuracy": 100, | ||
@@ -4,0 +4,0 @@ "results": { |
| /** | ||
| * RLM Controller - Recursive Retrieval Language Model | ||
| * | ||
| * Implements a recursive retrieval-augmented generation system that: | ||
| * 1. Breaks down complex queries into sub-queries | ||
| * 2. Retrieves relevant memory spans for each query | ||
| * 3. Synthesizes coherent answers from retrieved context | ||
| * 4. Optionally reflects on and refines answers | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * retrievalTopK: 10, | ||
| * enableCache: true, | ||
| * }); | ||
| * | ||
| * // Add knowledge to memory | ||
| * await rlm.addMemory('Machine learning is a subset of AI that enables systems to learn from data.'); | ||
| * await rlm.addMemory('Deep learning uses neural networks with many layers.'); | ||
| * | ||
| * // Query with recursive retrieval | ||
| * const answer = await rlm.query('Explain the relationship between ML and deep learning'); | ||
| * console.log(answer.text); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('What is AI?')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nDone! Quality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * const answer = await rlm.query('Complex multi-part question...'); | ||
| * // Answer will be iteratively refined until quality >= 0.8 | ||
| * ``` | ||
| */ | ||
| import { RlmConfig, RlmAnswer, MemorySpan, StreamToken } from './types'; | ||
| import { RuvLLM } from '../engine'; | ||
| /** | ||
| * RlmController - Recursive Retrieval Language Model Controller | ||
| * | ||
| * Orchestrates retrieval-augmented generation with recursive sub-query | ||
| * decomposition, memory search, and optional self-reflection. | ||
| */ | ||
| export declare class RlmController { | ||
| private config; | ||
| private cache; | ||
| private engine; | ||
| private memoryIdCounter; | ||
| /** | ||
| * Create a new RLM controller | ||
| * | ||
| * @param config - Configuration options | ||
| * @param engine - Optional RuvLLM engine instance (creates new if not provided) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // With default config | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * // With custom config | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 5, | ||
| * enableReflection: true, | ||
| * }); | ||
| * | ||
| * // With existing engine | ||
| * const engine = new RuvLLM({ learningEnabled: true }); | ||
| * const rlm = new RlmController({}, engine); | ||
| * ``` | ||
| */ | ||
| constructor(config?: RlmConfig, engine?: RuvLLM); | ||
| /** | ||
| * Query the RLM with recursive retrieval | ||
| * | ||
| * @param input - The query string | ||
| * @returns Promise resolving to the answer with sources and metadata | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const answer = await rlm.query('What is the capital of France?'); | ||
| * console.log(answer.text); // "The capital of France is Paris..." | ||
| * console.log(answer.confidence); // 0.95 | ||
| * console.log(answer.sources); // [{ id: '...', text: '...', similarityScore: 0.92 }] | ||
| * ``` | ||
| */ | ||
| query(input: string): Promise<RlmAnswer>; | ||
| /** | ||
| * Query with streaming response | ||
| * | ||
| * @param input - The query string | ||
| * @yields StreamToken events (either partial tokens or final answer) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * for await (const event of rlm.queryStream('Explain quantum computing')) { | ||
| * if (event.type === 'token') { | ||
| * // Partial token received | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * // Generation complete | ||
| * console.log('\n\nSources:', event.answer.sources.length); | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| queryStream(input: string): AsyncGenerator<StreamToken>; | ||
| /** | ||
| * Add content to memory for retrieval | ||
| * | ||
| * @param text - The text content to store | ||
| * @param metadata - Optional metadata to associate with the memory | ||
| * @returns Promise resolving to the memory span ID | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const id1 = await rlm.addMemory( | ||
| * 'TypeScript is a typed superset of JavaScript.', | ||
| * { source: 'documentation', category: 'programming' } | ||
| * ); | ||
| * | ||
| * const id2 = await rlm.addMemory( | ||
| * 'React is a JavaScript library for building UIs.' | ||
| * ); | ||
| * ``` | ||
| */ | ||
| addMemory(text: string, metadata?: Record<string, unknown>): Promise<string>; | ||
| /** | ||
| * Search memory for relevant spans | ||
| * | ||
| * @param query - The search query | ||
| * @param topK - Number of results to return (default: config.retrievalTopK) | ||
| * @returns Promise resolving to array of memory spans | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const spans = await rlm.searchMemory('JavaScript frameworks', 5); | ||
| * for (const span of spans) { | ||
| * console.log(`[${span.similarityScore.toFixed(2)}] ${span.text}`); | ||
| * } | ||
| * ``` | ||
| */ | ||
| searchMemory(query: string, topK?: number): Promise<MemorySpan[]>; | ||
| /** | ||
| * Clear the response cache | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * rlm.clearCache(); | ||
| * console.log('Cache cleared'); | ||
| * ``` | ||
| */ | ||
| clearCache(): void; | ||
| /** | ||
| * Get current cache statistics | ||
| * | ||
| * @returns Object with cache size and hit rate info | ||
| */ | ||
| getCacheStats(): { | ||
| size: number; | ||
| entries: number; | ||
| }; | ||
| /** | ||
| * Update configuration at runtime | ||
| * | ||
| * @param config - Partial configuration to merge | ||
| */ | ||
| updateConfig(config: Partial<RlmConfig>): void; | ||
| /** | ||
| * Get current configuration | ||
| */ | ||
| getConfig(): Required<RlmConfig>; | ||
| /** | ||
| * Generate sub-queries for complex questions | ||
| */ | ||
| private generateSubQueries; | ||
| /** | ||
| * Decompose a complex query into simpler parts | ||
| */ | ||
| private decomposeQuery; | ||
| /** | ||
| * Build context string from sources and sub-queries | ||
| */ | ||
| private buildContext; | ||
| /** | ||
| * Build the full prompt with context | ||
| */ | ||
| private buildPrompt; | ||
| /** | ||
| * Get generation config based on RLM settings | ||
| */ | ||
| private getGenerationConfig; | ||
| /** | ||
| * Estimate token usage | ||
| */ | ||
| private estimateTokenUsage; | ||
| /** | ||
| * Calculate quality score based on sources and confidence | ||
| */ | ||
| private calculateQualityScore; | ||
| /** | ||
| * Apply self-reflection to improve answer | ||
| */ | ||
| private applyReflection; | ||
| /** | ||
| * Get cached answer if valid | ||
| */ | ||
| private getCached; | ||
| /** | ||
| * Set cache entry | ||
| */ | ||
| private setCache; | ||
| /** | ||
| * Simple hash function for cache keys | ||
| */ | ||
| private hashQuery; | ||
| /** | ||
| * Prune expired cache entries | ||
| */ | ||
| private pruneCache; | ||
| /** | ||
| * Utility delay function for streaming simulation | ||
| */ | ||
| private delay; | ||
| } | ||
| //# sourceMappingURL=controller.d.ts.map |
| {"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"} |
| "use strict"; | ||
| /** | ||
| * RLM Controller - Recursive Retrieval Language Model | ||
| * | ||
| * Implements a recursive retrieval-augmented generation system that: | ||
| * 1. Breaks down complex queries into sub-queries | ||
| * 2. Retrieves relevant memory spans for each query | ||
| * 3. Synthesizes coherent answers from retrieved context | ||
| * 4. Optionally reflects on and refines answers | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * retrievalTopK: 10, | ||
| * enableCache: true, | ||
| * }); | ||
| * | ||
| * // Add knowledge to memory | ||
| * await rlm.addMemory('Machine learning is a subset of AI that enables systems to learn from data.'); | ||
| * await rlm.addMemory('Deep learning uses neural networks with many layers.'); | ||
| * | ||
| * // Query with recursive retrieval | ||
| * const answer = await rlm.query('Explain the relationship between ML and deep learning'); | ||
| * console.log(answer.text); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('What is AI?')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nDone! Quality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * const answer = await rlm.query('Complex multi-part question...'); | ||
| * // Answer will be iteratively refined until quality >= 0.8 | ||
| * ``` | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.RlmController = void 0; | ||
| const engine_1 = require("../engine"); | ||
| /** | ||
| * Default configuration values | ||
| */ | ||
| const DEFAULT_CONFIG = { | ||
| maxDepth: 3, | ||
| maxSubQueries: 5, | ||
| tokenBudget: 4096, | ||
| enableCache: true, | ||
| cacheTtl: 300000, // 5 minutes | ||
| retrievalTopK: 10, | ||
| minQualityScore: 0.7, | ||
| enableReflection: false, | ||
| maxReflectionIterations: 2, | ||
| }; | ||
| /** | ||
| * RlmController - Recursive Retrieval Language Model Controller | ||
| * | ||
| * Orchestrates retrieval-augmented generation with recursive sub-query | ||
| * decomposition, memory search, and optional self-reflection. | ||
| */ | ||
| class RlmController { | ||
| /** | ||
| * Create a new RLM controller | ||
| * | ||
| * @param config - Configuration options | ||
| * @param engine - Optional RuvLLM engine instance (creates new if not provided) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // With default config | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * // With custom config | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 5, | ||
| * enableReflection: true, | ||
| * }); | ||
| * | ||
| * // With existing engine | ||
| * const engine = new RuvLLM({ learningEnabled: true }); | ||
| * const rlm = new RlmController({}, engine); | ||
| * ``` | ||
| */ | ||
| constructor(config, engine) { | ||
| this.config = { ...DEFAULT_CONFIG, ...config }; | ||
| this.cache = new Map(); | ||
| this.engine = engine ?? new engine_1.RuvLLM({ learningEnabled: true }); | ||
| this.memoryIdCounter = 0; | ||
| } | ||
| /** | ||
| * Query the RLM with recursive retrieval | ||
| * | ||
| * @param input - The query string | ||
| * @returns Promise resolving to the answer with sources and metadata | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const answer = await rlm.query('What is the capital of France?'); | ||
| * console.log(answer.text); // "The capital of France is Paris..." | ||
| * console.log(answer.confidence); // 0.95 | ||
| * console.log(answer.sources); // [{ id: '...', text: '...', similarityScore: 0.92 }] | ||
| * ``` | ||
| */ | ||
| async query(input) { | ||
| // Check cache first | ||
| if (this.config.enableCache) { | ||
| const cached = this.getCached(input); | ||
| if (cached) { | ||
| return { ...cached, cached: true }; | ||
| } | ||
| } | ||
| // Retrieve relevant memory spans | ||
| const sources = await this.searchMemory(input, this.config.retrievalTopK); | ||
| // Generate sub-queries if needed and depth allows | ||
| const subQueries = await this.generateSubQueries(input, sources, 0); | ||
| // Build context from sources and sub-query answers | ||
| const context = this.buildContext(sources, subQueries); | ||
| // Generate the answer | ||
| const startTime = Date.now(); | ||
| const response = this.engine.query(this.buildPrompt(input, context), this.getGenerationConfig()); | ||
| // Calculate token usage (estimate if not provided by engine) | ||
| const tokenUsage = this.estimateTokenUsage(input, context, response.text); | ||
| // Calculate quality score | ||
| const qualityScore = this.calculateQualityScore(sources, response.confidence); | ||
| let answer = { | ||
| text: response.text, | ||
| confidence: response.confidence, | ||
| qualityScore, | ||
| sources, | ||
| subQueries: subQueries.length > 0 ? subQueries : undefined, | ||
| tokenUsage, | ||
| cached: false, | ||
| }; | ||
| // Apply reflection if enabled and quality is below threshold | ||
| if (this.config.enableReflection && qualityScore < this.config.minQualityScore) { | ||
| answer = await this.applyReflection(input, answer); | ||
| } | ||
| // Cache the result | ||
| if (this.config.enableCache) { | ||
| this.setCache(input, answer); | ||
| } | ||
| return answer; | ||
| } | ||
| /** | ||
| * Query with streaming response | ||
| * | ||
| * @param input - The query string | ||
| * @yields StreamToken events (either partial tokens or final answer) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * for await (const event of rlm.queryStream('Explain quantum computing')) { | ||
| * if (event.type === 'token') { | ||
| * // Partial token received | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * // Generation complete | ||
| * console.log('\n\nSources:', event.answer.sources.length); | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| async *queryStream(input) { | ||
| // Check cache first | ||
| if (this.config.enableCache) { | ||
| const cached = this.getCached(input); | ||
| if (cached) { | ||
| // Simulate streaming for cached response | ||
| const words = cached.text.split(' '); | ||
| for (const word of words) { | ||
| yield { type: 'token', text: word + ' ', done: false }; | ||
| await this.delay(10); // Small delay for realistic streaming | ||
| } | ||
| yield { type: 'done', answer: { ...cached, cached: true }, done: true }; | ||
| return; | ||
| } | ||
| } | ||
| // Retrieve sources | ||
| const sources = await this.searchMemory(input, this.config.retrievalTopK); | ||
| const subQueries = await this.generateSubQueries(input, sources, 0); | ||
| const context = this.buildContext(sources, subQueries); | ||
| // Generate with simulated streaming | ||
| const prompt = this.buildPrompt(input, context); | ||
| const response = this.engine.query(prompt, this.getGenerationConfig()); | ||
| // Stream the response word by word | ||
| const words = response.text.split(' '); | ||
| let streamedText = ''; | ||
| for (let i = 0; i < words.length; i++) { | ||
| const word = words[i]; | ||
| const text = i < words.length - 1 ? word + ' ' : word; | ||
| streamedText += text; | ||
| yield { type: 'token', text, done: false }; | ||
| await this.delay(20); // Simulate generation latency | ||
| } | ||
| const tokenUsage = this.estimateTokenUsage(input, context, streamedText); | ||
| const qualityScore = this.calculateQualityScore(sources, response.confidence); | ||
| const answer = { | ||
| text: streamedText, | ||
| confidence: response.confidence, | ||
| qualityScore, | ||
| sources, | ||
| subQueries: subQueries.length > 0 ? subQueries : undefined, | ||
| tokenUsage, | ||
| cached: false, | ||
| }; | ||
| // Cache the result | ||
| if (this.config.enableCache) { | ||
| this.setCache(input, answer); | ||
| } | ||
| yield { type: 'done', answer, done: true }; | ||
| } | ||
| /** | ||
| * Add content to memory for retrieval | ||
| * | ||
| * @param text - The text content to store | ||
| * @param metadata - Optional metadata to associate with the memory | ||
| * @returns Promise resolving to the memory span ID | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const id1 = await rlm.addMemory( | ||
| * 'TypeScript is a typed superset of JavaScript.', | ||
| * { source: 'documentation', category: 'programming' } | ||
| * ); | ||
| * | ||
| * const id2 = await rlm.addMemory( | ||
| * 'React is a JavaScript library for building UIs.' | ||
| * ); | ||
| * ``` | ||
| */ | ||
| async addMemory(text, metadata) { | ||
| const nodeId = this.engine.addMemory(text, metadata); | ||
| const id = `rlm-mem-${this.memoryIdCounter++}-${nodeId}`; | ||
| return id; | ||
| } | ||
| /** | ||
| * Search memory for relevant spans | ||
| * | ||
| * @param query - The search query | ||
| * @param topK - Number of results to return (default: config.retrievalTopK) | ||
| * @returns Promise resolving to array of memory spans | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const spans = await rlm.searchMemory('JavaScript frameworks', 5); | ||
| * for (const span of spans) { | ||
| * console.log(`[${span.similarityScore.toFixed(2)}] ${span.text}`); | ||
| * } | ||
| * ``` | ||
| */ | ||
| async searchMemory(query, topK) { | ||
| const k = topK ?? this.config.retrievalTopK; | ||
| const results = this.engine.searchMemory(query, k); | ||
| return results.map((result, index) => ({ | ||
| id: `rlm-span-${result.id}-${index}`, | ||
| text: result.content, | ||
| similarityScore: result.score, | ||
| source: result.metadata?.source, | ||
| metadata: result.metadata, | ||
| })); | ||
| } | ||
| /** | ||
| * Clear the response cache | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * rlm.clearCache(); | ||
| * console.log('Cache cleared'); | ||
| * ``` | ||
| */ | ||
| clearCache() { | ||
| this.cache.clear(); | ||
| } | ||
| /** | ||
| * Get current cache statistics | ||
| * | ||
| * @returns Object with cache size and hit rate info | ||
| */ | ||
| getCacheStats() { | ||
| return { | ||
| size: this.cache.size, | ||
| entries: this.cache.size, | ||
| }; | ||
| } | ||
| /** | ||
| * Update configuration at runtime | ||
| * | ||
| * @param config - Partial configuration to merge | ||
| */ | ||
| updateConfig(config) { | ||
| this.config = { ...this.config, ...config }; | ||
| } | ||
| /** | ||
| * Get current configuration | ||
| */ | ||
| getConfig() { | ||
| return { ...this.config }; | ||
| } | ||
| // ============================================ | ||
| // Private Methods | ||
| // ============================================ | ||
| /** | ||
| * Generate sub-queries for complex questions | ||
| */ | ||
| async generateSubQueries(query, sources, depth) { | ||
| if (depth >= this.config.maxDepth) { | ||
| return []; | ||
| } | ||
| // Simple heuristic: generate sub-queries for questions with multiple parts | ||
| const subQueries = []; | ||
| const parts = this.decomposeQuery(query); | ||
| for (const part of parts.slice(0, this.config.maxSubQueries)) { | ||
| if (part.trim().length < 10) | ||
| continue; | ||
| // Search for sub-query specific sources | ||
| const subSources = await this.searchMemory(part, Math.ceil(this.config.retrievalTopK / 2)); | ||
| const context = this.buildContext(subSources, []); | ||
| const response = this.engine.query(this.buildPrompt(part, context), { ...this.getGenerationConfig(), maxTokens: 256 }); | ||
| subQueries.push({ | ||
| query: part, | ||
| answer: response.text, | ||
| depth: depth + 1, | ||
| }); | ||
| } | ||
| return subQueries; | ||
| } | ||
| /** | ||
| * Decompose a complex query into simpler parts | ||
| */ | ||
| decomposeQuery(query) { | ||
| // Split on common conjunctions and question markers | ||
| const parts = []; | ||
| // Check for multi-part questions | ||
| const conjunctions = [' and ', ' or ', '. ', '? ', '; ']; | ||
| let current = query; | ||
| for (const conj of conjunctions) { | ||
| if (current.includes(conj)) { | ||
| const split = current.split(conj); | ||
| parts.push(...split.filter(p => p.trim().length > 10)); | ||
| current = ''; | ||
| break; | ||
| } | ||
| } | ||
| // If no decomposition happened, return original | ||
| if (parts.length === 0) { | ||
| return [query]; | ||
| } | ||
| return parts; | ||
| } | ||
| /** | ||
| * Build context string from sources and sub-queries | ||
| */ | ||
| buildContext(sources, subQueries) { | ||
| const parts = []; | ||
| // Add sources | ||
| if (sources.length > 0) { | ||
| parts.push('Relevant context:'); | ||
| for (const source of sources) { | ||
| parts.push(`- ${source.text}`); | ||
| } | ||
| } | ||
| // Add sub-query answers | ||
| if (subQueries.length > 0) { | ||
| parts.push('\nRelated information:'); | ||
| for (const sq of subQueries) { | ||
| parts.push(`Q: ${sq.query}`); | ||
| parts.push(`A: ${sq.answer}`); | ||
| } | ||
| } | ||
| return parts.join('\n'); | ||
| } | ||
| /** | ||
| * Build the full prompt with context | ||
| */ | ||
| buildPrompt(query, context) { | ||
| if (context.trim().length === 0) { | ||
| return query; | ||
| } | ||
| return `${context}\n\nBased on the above context, answer the following question:\n${query}`; | ||
| } | ||
| /** | ||
| * Get generation config based on RLM settings | ||
| */ | ||
| getGenerationConfig() { | ||
| return { | ||
| maxTokens: Math.min(this.config.tokenBudget, 2048), | ||
| temperature: 0.7, | ||
| topP: 0.9, | ||
| }; | ||
| } | ||
| /** | ||
| * Estimate token usage | ||
| */ | ||
| estimateTokenUsage(query, context, response) { | ||
| // Rough estimation: ~4 characters per token | ||
| const promptTokens = Math.ceil((query.length + context.length) / 4); | ||
| const completionTokens = Math.ceil(response.length / 4); | ||
| return { | ||
| prompt: promptTokens, | ||
| completion: completionTokens, | ||
| total: promptTokens + completionTokens, | ||
| }; | ||
| } | ||
| /** | ||
| * Calculate quality score based on sources and confidence | ||
| */ | ||
| calculateQualityScore(sources, confidence) { | ||
| if (sources.length === 0) { | ||
| return confidence * 0.5; // Penalize answers without sources | ||
| } | ||
| // Average source similarity | ||
| const avgSimilarity = sources.reduce((sum, s) => sum + s.similarityScore, 0) / sources.length; | ||
| // Weighted combination | ||
| return confidence * 0.6 + avgSimilarity * 0.4; | ||
| } | ||
| /** | ||
| * Apply self-reflection to improve answer | ||
| */ | ||
| async applyReflection(query, answer) { | ||
| let currentAnswer = answer; | ||
| let iterations = 0; | ||
| while (iterations < this.config.maxReflectionIterations && | ||
| currentAnswer.qualityScore < this.config.minQualityScore) { | ||
| iterations++; | ||
| // Generate critique | ||
| const critiquePrompt = `Evaluate this answer for accuracy and completeness: | ||
| Question: ${query} | ||
| Answer: ${currentAnswer.text} | ||
| Provide a brief critique and suggest improvements.`; | ||
| const critiqueResponse = this.engine.query(critiquePrompt, { | ||
| maxTokens: 256, | ||
| temperature: 0.5, | ||
| }); | ||
| // Generate improved answer | ||
| const improvePrompt = `Based on this feedback: "${critiqueResponse.text}" | ||
| Improve this answer: | ||
| Question: ${query} | ||
| Original: ${currentAnswer.text} | ||
| Provide an improved answer:`; | ||
| const improvedResponse = this.engine.query(improvePrompt, this.getGenerationConfig()); | ||
| // Update answer with reflection improvements | ||
| const newQualityScore = Math.min(1.0, currentAnswer.qualityScore + 0.1 * iterations); | ||
| currentAnswer = { | ||
| ...currentAnswer, | ||
| text: improvedResponse.text, | ||
| confidence: Math.max(currentAnswer.confidence, improvedResponse.confidence), | ||
| qualityScore: newQualityScore, | ||
| tokenUsage: { | ||
| prompt: currentAnswer.tokenUsage.prompt + 100, // Approximate additional tokens | ||
| completion: currentAnswer.tokenUsage.completion + 100, | ||
| total: currentAnswer.tokenUsage.total + 200, | ||
| }, | ||
| }; | ||
| } | ||
| return currentAnswer; | ||
| } | ||
| /** | ||
| * Get cached answer if valid | ||
| */ | ||
| getCached(query) { | ||
| const hash = this.hashQuery(query); | ||
| const entry = this.cache.get(hash); | ||
| if (!entry) { | ||
| return null; | ||
| } | ||
| // Check TTL | ||
| if (Date.now() - entry.timestamp > this.config.cacheTtl) { | ||
| this.cache.delete(hash); | ||
| return null; | ||
| } | ||
| return entry.answer; | ||
| } | ||
| /** | ||
| * Set cache entry | ||
| */ | ||
| setCache(query, answer) { | ||
| const hash = this.hashQuery(query); | ||
| this.cache.set(hash, { | ||
| answer, | ||
| timestamp: Date.now(), | ||
| queryHash: hash, | ||
| }); | ||
| // Prune old entries if cache gets too large | ||
| if (this.cache.size > 1000) { | ||
| this.pruneCache(); | ||
| } | ||
| } | ||
| /** | ||
| * Simple hash function for cache keys | ||
| */ | ||
| hashQuery(query) { | ||
| let hash = 0; | ||
| for (let i = 0; i < query.length; i++) { | ||
| const char = query.charCodeAt(i); | ||
| hash = ((hash << 5) - hash) + char; | ||
| hash = hash & hash; // Convert to 32-bit integer | ||
| } | ||
| return `rlm-cache-${hash.toString(16)}`; | ||
| } | ||
| /** | ||
| * Prune expired cache entries | ||
| */ | ||
| pruneCache() { | ||
| const now = Date.now(); | ||
| const toDelete = []; | ||
| for (const [key, entry] of this.cache.entries()) { | ||
| if (now - entry.timestamp > this.config.cacheTtl) { | ||
| toDelete.push(key); | ||
| } | ||
| } | ||
| // Delete oldest entries if still too large | ||
| if (this.cache.size - toDelete.length > 800) { | ||
| const entries = Array.from(this.cache.entries()) | ||
| .sort((a, b) => a[1].timestamp - b[1].timestamp); | ||
| const deleteCount = entries.length - 500; | ||
| for (let i = 0; i < deleteCount; i++) { | ||
| toDelete.push(entries[i][0]); | ||
| } | ||
| } | ||
| for (const key of toDelete) { | ||
| this.cache.delete(key); | ||
| } | ||
| } | ||
| /** | ||
| * Utility delay function for streaming simulation | ||
| */ | ||
| delay(ms) { | ||
| return new Promise(resolve => setTimeout(resolve, ms)); | ||
| } | ||
| } | ||
| exports.RlmController = RlmController; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ybG0vY29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNERzs7O0FBYUgsc0NBQW1DO0FBR25DOztHQUVHO0FBQ0gsTUFBTSxjQUFjLEdBQXdCO0lBQzFDLFFBQVEsRUFBRSxDQUFDO0lBQ1gsYUFBYSxFQUFFLENBQUM7SUFDaEIsV0FBVyxFQUFFLElBQUk7SUFDakIsV0FBVyxFQUFFLElBQUk7SUFDakIsUUFBUSxFQUFFLE1BQU0sRUFBRSxZQUFZO0lBQzlCLGFBQWEsRUFBRSxFQUFFO0lBQ2pCLGVBQWUsRUFBRSxHQUFHO0lBQ3BCLGdCQUFnQixFQUFFLEtBQUs7SUFDdkIsdUJBQXVCLEVBQUUsQ0FBQztDQUMzQixDQUFDO0FBRUY7Ozs7O0dBS0c7QUFDSCxNQUFhLGFBQWE7SUFNeEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFCRztJQUNILFlBQVksTUFBa0IsRUFBRSxNQUFlO1FBQzdDLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxHQUFHLGNBQWMsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sSUFBSSxJQUFJLGVBQU0sQ0FBQyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFhO1FBQ3ZCLG9CQUFvQjtRQUNwQixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDNUIsTUFBTSxN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QUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO2lCQUM3QyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUVuRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztZQUN6QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3JDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0IsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLE1BQU0sR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsRUFBVTtRQUN0QixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7Q0FDRjtBQXhqQkQsc0NBd2pCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUkxNIENvbnRyb2xsZXIgLSBSZWN1cnNpdmUgUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsXG4gKlxuICogSW1wbGVtZW50cyBhIHJlY3Vyc2l2ZSByZXRyaWV2YWwtYXVnbWVudGVkIGdlbmVyYXRpb24gc3lzdGVtIHRoYXQ6XG4gKiAxLiBCcmVha3MgZG93biBjb21wbGV4IHF1ZXJpZXMgaW50byBzdWItcXVlcmllc1xuICogMi4gUmV0cmlldmVzIHJlbGV2YW50IG1lbW9yeSBzcGFucyBmb3IgZWFjaCBxdWVyeVxuICogMy4gU3ludGhlc2l6ZXMgY29oZXJlbnQgYW5zd2VycyBmcm9tIHJldHJpZXZlZCBjb250ZXh0XG4gKiA0LiBPcHRpb25hbGx5IHJlZmxlY3RzIG9uIGFuZCByZWZpbmVzIGFuc3dlcnNcbiAqXG4gKiBAZXhhbXBsZSBCYXNpYyBVc2FnZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKHtcbiAqICAgbWF4RGVwdGg6IDMsXG4gKiAgIHJldHJpZXZhbFRvcEs6IDEwLFxuICogICBlbmFibGVDYWNoZTogdHJ1ZSxcbiAqIH0pO1xuICpcbiAqIC8vIEFkZCBrbm93bGVkZ2UgdG8gbWVtb3J5XG4gKiBhd2FpdCBybG0uYWRkTWVtb3J5KCdNYWNoaW5lIGxlYXJuaW5nIGlzIGEgc3Vic2V0IG9mIEFJIHRoYXQgZW5hYmxlcyBzeXN0ZW1zIHRvIGxlYXJuIGZyb20gZGF0YS4nKTtcbiAqIGF3YWl0IHJsbS5hZGRNZW1vcnkoJ0RlZXAgbGVhcm5pbmcgdXNlcyBuZXVyYWwgbmV0d29ya3Mgd2l0aCBtYW55IGxheWVycy4nKTtcbiAqXG4gKiAvLyBRdWVyeSB3aXRoIHJlY3Vyc2l2ZSByZXRyaWV2YWxcbiAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnRXhwbGFpbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTUwgYW5kIGRlZXAgbGVhcm5pbmcnKTtcbiAqIGNvbnNvbGUubG9nKGFuc3dlci50ZXh0KTtcbiAqIGNvbnNvbGUubG9nKCdTb3VyY2VzOicsIGFuc3dlci5zb3VyY2VzLmxlbmd0aCk7XG4gKiBjb25zb2xlLmxvZygnQ29uZmlkZW5jZTonLCBhbnN3ZXIuY29uZmlkZW5jZSk7XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZSBTdHJlYW1pbmdcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKCk7XG4gKlxuICogZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBybG0ucXVlcnlTdHJlYW0oJ1doYXQgaXMgQUk/JykpIHtcbiAqICAgaWYgKGV2ZW50LnR5cGUgPT09ICd0b2tlbicpIHtcbiAqICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShldmVudC50ZXh0KTtcbiAqICAgfSBlbHNlIHtcbiAqICAgICBjb25zb2xlLmxvZygnXFxuXFxuRG9uZSEgUXVhbGl0eTonLCBldmVudC5hbnN3ZXIucXVhbGl0eVNjb3JlKTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQGV4YW1wbGUgV2l0aCBSZWZsZWN0aW9uXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBybG0gPSBuZXcgUmxtQ29udHJvbGxlcih7XG4gKiAgIGVuYWJsZVJlZmxlY3Rpb246IHRydWUsXG4gKiAgIG1heFJlZmxlY3Rpb25JdGVyYXRpb25zOiAyLFxuICogICBtaW5RdWFsaXR5U2NvcmU6IDAuOCxcbiAqIH0pO1xuICpcbiAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnQ29tcGxleCBtdWx0aS1wYXJ0IHF1ZXN0aW9uLi4uJyk7XG4gKiAvLyBBbnN3ZXIgd2lsbCBiZSBpdGVyYXRpdmVseSByZWZpbmVkIHVudGlsIHF1YWxpdHkgPj0gMC44XG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQge1xuICBSbG1Db25maWcsXG4gIFJsbUFuc3dlcixcbiAgTWVtb3J5U3BhbixcbiAgU3ViUXVlcnksXG4gIFRva2VuVXNhZ2UsXG4gIFN0cmVhbVRva2VuLFxuICBSbG1DYWNoZUVudHJ5LFxuICBSZWZsZWN0aW9uUmVzdWx0LFxufSBmcm9tICcuL3R5cGVzJztcblxuaW1wb3J0IHsgUnV2TExNIH0gZnJvbSAnLi4vZW5naW5lJztcbmltcG9ydCB0eXBlIHsgR2VuZXJhdGlvbkNvbmZpZywgUXVlcnlSZXNwb25zZSB9IGZyb20gJy4uL3R5cGVzJztcblxuLyoqXG4gKiBEZWZhdWx0IGNvbmZpZ3VyYXRpb24gdmFsdWVzXG4gKi9cbmNvbnN0IERFRkFVTFRfQ09ORklHOiBSZXF1aXJlZDxSbG1Db25maWc+ID0ge1xuICBtYXhEZXB0aDogMyxcbiAgbWF4U3ViUXVlcmllczogNSxcbiAgdG9rZW5CdWRnZXQ6IDQwOTYsXG4gIGVuYWJsZUNhY2hlOiB0cnVlLFxuICBjYWNoZVR0bDogMzAwMDAwLCAvLyA1IG1pbnV0ZXNcbiAgcmV0cmlldmFsVG9wSzogMTAsXG4gIG1pblF1YWxpdHlTY29yZTogMC43LFxuICBlbmFibGVSZWZsZWN0aW9uOiBmYWxzZSxcbiAgbWF4UmVmbGVjdGlvbkl0ZXJhdGlvbnM6IDIsXG59O1xuXG4vKipcbiAqIFJsbUNvbnRyb2xsZXIgLSBSZWN1cnNpdmUgUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsIENvbnRyb2xsZXJcbiAqXG4gKiBPcmNoZXN0cmF0ZXMgcmV0cmlldmFsLWF1Z21lbnRlZCBnZW5lcmF0aW9uIHdpdGggcmVjdXJzaXZlIHN1Yi1xdWVyeVxuICogZGVjb21wb3NpdGlvbiwgbWVtb3J5IHNlYXJjaCwgYW5kIG9wdGlvbmFsIHNlbGYtcmVmbGVjdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFJsbUNvbnRyb2xsZXIge1xuICBwcml2YXRlIGNvbmZpZzogUmVxdWlyZWQ8UmxtQ29uZmlnPjtcbiAgcHJpdmF0ZSBjYWNoZTogTWFwPHN0cmluZywgUmxtQ2FjaGVFbnRyeT47XG4gIHByaXZhdGUgZW5naW5lOiBSdXZMTE07XG4gIHByaXZhdGUgbWVtb3J5SWRDb3VudGVyOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBSTE0gY29udHJvbGxlclxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSBlbmdpbmUgLSBPcHRpb25hbCBSdXZMTE0gZW5naW5lIGluc3RhbmNlIChjcmVhdGVzIG5ldyBpZiBub3QgcHJvdmlkZWQpXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogLy8gV2l0aCBkZWZhdWx0IGNvbmZpZ1xuICAgKiBjb25zdCBybG0gPSBuZXcgUmxtQ29udHJvbGxlcigpO1xuICAgKlxuICAgKiAvLyBXaXRoIGN1c3RvbSBjb25maWdcbiAgICogY29uc3QgcmxtID0gbmV3IFJsbUNvbnRyb2xsZXIoe1xuICAgKiAgIG1heERlcHRoOiA1LFxuICAgKiAgIGVuYWJsZVJlZmxlY3Rpb246IHRydWUsXG4gICAqIH0pO1xuICAgKlxuICAgKiAvLyBXaXRoIGV4aXN0aW5nIGVuZ2luZVxuICAgKiBjb25zdCBlbmdpbmUgPSBuZXcgUnV2TExNKHsgbGVhcm5pbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgKiBjb25zdCBybG0gPSBuZXcgUmxtQ29udHJvbGxlcih7fSwgZW5naW5lKTtcbiAgICogYGBgXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBSbG1Db25maWcsIGVuZ2luZT86IFJ1dkxMTSkge1xuICAgIHRoaXMuY29uZmlnID0geyAuLi5ERUZBVUxUX0NPTkZJRywgLi4uY29uZmlnIH07XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmVuZ2luZSA9IGVuZ2luZSA/PyBuZXcgUnV2TExNKHsgbGVhcm5pbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgIHRoaXMubWVtb3J5SWRDb3VudGVyID0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyeSB0aGUgUkxNIHdpdGggcmVjdXJzaXZlIHJldHJpZXZhbFxuICAgKlxuICAgKiBAcGFyYW0gaW5wdXQgLSBUaGUgcXVlcnkgc3RyaW5nXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBhbnN3ZXIgd2l0aCBzb3VyY2VzIGFuZCBtZXRhZGF0YVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnV2hhdCBpcyB0aGUgY2FwaXRhbCBvZiBGcmFuY2U/Jyk7XG4gICAqIGNvbnNvbGUubG9nKGFuc3dlci50ZXh0KTsgLy8gXCJUaGUgY2FwaXRhbCBvZiBGcmFuY2UgaXMgUGFyaXMuLi5cIlxuICAgKiBjb25zb2xlLmxvZyhhbnN3ZXIuY29uZmlkZW5jZSk7IC8vIDAuOTVcbiAgICogY29uc29sZS5sb2coYW5zd2VyLnNvdXJjZXMpOyAvLyBbeyBpZDogJy4uLicsIHRleHQ6ICcuLi4nLCBzaW1pbGFyaXR5U2NvcmU6IDAuOTIgfV1cbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBxdWVyeShpbnB1dDogc3RyaW5nKTogUHJvbWlzZTxSbG1BbnN3ZXI+IHtcbiAgICAvLyBDaGVjayBjYWNoZSBmaXJzdFxuICAgIGlmICh0aGlzLmNvbmZpZy5lbmFibGVDYWNoZSkge1xuICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy5nZXRDYWNoZWQoaW5wdXQpO1xuICAgICAgaWYgKGNhY2hlZCkge1xuICAgICAgICByZXR1cm4geyAuLi5jYWNoZWQsIGNhY2hlZDogdHJ1ZSB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHJpZXZlIHJlbGV2YW50IG1lbW9yeSBzcGFuc1xuICAgIGNvbnN0IHNvdXJjZXMgPSBhd2FpdCB0aGlzLnNlYXJjaE1lbW9yeShpbnB1dCwgdGhpcy5jb25maWcucmV0cmlldmFsVG9wSyk7XG5cbiAgICAvLyBHZW5lcmF0ZSBzdWItcXVlcmllcyBpZiBuZWVkZWQgYW5kIGRlcHRoIGFsbG93c1xuICAgIGNvbnN0IHN1YlF1ZXJpZXMgPSBhd2FpdCB0aGlzLmdlbmVyYXRlU3ViUXVlcmllcyhpbnB1dCwgc291cmNlcywgMCk7XG5cbiAgICAvLyBCdWlsZCBjb250ZXh0IGZyb20gc291cmNlcyBhbmQgc3ViLXF1ZXJ5IGFuc3dlcnNcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5idWlsZENvbnRleHQoc291cmNlcywgc3ViUXVlcmllcyk7XG5cbiAgICAvLyBHZW5lcmF0ZSB0aGUgYW5zd2VyXG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuZW5naW5lLnF1ZXJ5KFxuICAgICAgdGhpcy5idWlsZFByb21wdChpbnB1dCwgY29udGV4dCksXG4gICAgICB0aGlzLmdldEdlbmVyYXRpb25Db25maWcoKVxuICAgICk7XG5cbiAgICAvLyBDYWxjdWxhdGUgdG9rZW4gdXNhZ2UgKGVzdGltYXRlIGlmIG5vdCBwcm92aWRlZCBieSBlbmdpbmUpXG4gICAgY29uc3QgdG9rZW5Vc2FnZSA9IHRoaXMuZXN0aW1hdGVUb2tlblVzYWdlKGlucHV0LCBjb250ZXh0LCByZXNwb25zZS50ZXh0KTtcblxuICAgIC8vIENhbGN1bGF0ZSBxdWFsaXR5IHNjb3JlXG4gICAgY29uc3QgcXVhbGl0eVNjb3JlID0gdGhpcy5jYWxjdWxhdGVRdWFsaXR5U2NvcmUoc291cmNlcywgcmVzcG9uc2UuY29uZmlkZW5jZSk7XG5cbiAgICBsZXQgYW5zd2VyOiBSbG1BbnN3ZXIgPSB7XG4gICAgICB0ZXh0OiByZXNwb25zZS50ZXh0LFxuICAgICAgY29uZmlkZW5jZTogcmVzcG9uc2UuY29uZmlkZW5jZSxcbiAgICAgIHF1YWxpdHlTY29yZSxcbiAgICAgIHNvdXJjZXMsXG4gICAgICBzdWJRdWVyaWVzOiBzdWJRdWVyaWVzLmxlbmd0aCA+IDAgPyBzdWJRdWVyaWVzIDogdW5kZWZpbmVkLFxuICAgICAgdG9rZW5Vc2FnZSxcbiAgICAgIGNhY2hlZDogZmFsc2UsXG4gICAgfTtcblxuICAgIC8vIEFwcGx5IHJlZmxlY3Rpb24gaWYgZW5hYmxlZCBhbmQgcXVhbGl0eSBpcyBiZWxvdyB0aHJlc2hvbGRcbiAgICBpZiAodGhpcy5jb25maWcuZW5hYmxlUmVmbGVjdGlvbiAmJiBxdWFsaXR5U2NvcmUgPCB0aGlzLmNvbmZpZy5taW5RdWFsaXR5U2NvcmUpIHtcbiAgICAgIGFuc3dlciA9IGF3YWl0IHRoaXMuYXBwbHlSZWZsZWN0aW9uKGlucHV0LCBhbnN3ZXIpO1xuICAgIH1cblxuICAgIC8vIENhY2hlIHRoZSByZXN1bHRcbiAgICBpZiAodGhpcy5jb25maWcuZW5hYmxlQ2FjaGUpIHtcbiAgICAgIHRoaXMuc2V0Q2FjaGUoaW5wdXQsIGFuc3dlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFuc3dlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyeSB3aXRoIHN0cmVhbWluZyByZXNwb25zZVxuICAgKlxuICAgKiBAcGFyYW0gaW5wdXQgLSBUaGUgcXVlcnkgc3RyaW5nXG4gICAqIEB5aWVsZHMgU3RyZWFtVG9rZW4gZXZlbnRzIChlaXRoZXIgcGFydGlhbCB0b2tlbnMgb3IgZmluYWwgYW5zd2VyKVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgcmxtLnF1ZXJ5U3RyZWFtKCdFeHBsYWluIHF1YW50dW0gY29tcHV0aW5nJykpIHtcbiAgICogICBpZiAoZXZlbnQudHlwZSA9PT0gJ3Rva2VuJykge1xuICAgKiAgICAgLy8gUGFydGlhbCB0b2tlbiByZWNlaXZlZFxuICAgKiAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoZXZlbnQudGV4dCk7XG4gICAqICAgfSBlbHNlIHtcbiAgICogICAgIC8vIEdlbmVyYXRpb24gY29tcGxldGVcbiAgICogICAgIGNvbnNvbGUubG9nKCdcXG5cXG5Tb3VyY2VzOicsIGV2ZW50LmFuc3dlci5zb3VyY2VzLmxlbmd0aCk7XG4gICAqICAgfVxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgKnF1ZXJ5U3RyZWFtKGlucHV0OiBzdHJpbmcpOiBBc3luY0dlbmVyYXRvcjxTdHJlYW1Ub2tlbj4ge1xuICAgIC8vIENoZWNrIGNhY2hlIGZpcnN0XG4gICAgaWYgKHRoaXMuY29uZmlnLmVuYWJsZUNhY2hlKSB7XG4gICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLmdldENhY2hlZChpbnB1dCk7XG4gICAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAgIC8vIFNpbXVsYXRlIHN0cmVhbWluZyBmb3IgY2FjaGVkIHJlc3BvbnNlXG4gICAgICAgIGNvbnN0IHdvcmRzID0gY2FjaGVkLnRleHQuc3BsaXQoJyAnKTtcbiAgICAgICAgZm9yIChjb25zdCB3b3JkIG9mIHdvcmRzKSB7XG4gICAgICAgICAgeWllbGQgeyB0eXBlOiAndG9rZW4nLCB0ZXh0OiB3b3JkICsgJyAnLCBkb25lOiBmYWxzZSB9O1xuICAgICAgICAgIGF3YWl0IHRoaXMuZGVsYXkoMTApOyAvLyBTbWFsbCBkZWxheSBmb3IgcmVhbGlzdGljIHN0cmVhbWluZ1xuICAgICAgICB9XG4gICAgICAgIHlpZWxkIHsgdHlwZTogJ2RvbmUnLCBhbnN3ZXI6IHsgLi4uY2FjaGVkLCBjYWNoZWQ6IHRydWUgfSwgZG9uZTogdHJ1ZSB9O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0cmlldmUgc291cmNlc1xuICAgIGNvbnN0IHNvdXJjZXMgPSBhd2FpdCB0aGlzLnNlYXJjaE1lbW9yeShpbnB1dCwgdGhpcy5jb25maWcucmV0cmlldmFsVG9wSyk7XG4gICAgY29uc3Qgc3ViUXVlcmllcyA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVTdWJRdWVyaWVzKGlucHV0LCBzb3VyY2VzLCAwKTtcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5idWlsZENvbnRleHQoc291cmNlcywgc3ViUXVlcmllcyk7XG5cbiAgICAvLyBHZW5lcmF0ZSB3aXRoIHNpbXVsYXRlZCBzdHJlYW1pbmdcbiAgICBjb25zdCBwcm9tcHQgPSB0aGlzLmJ1aWxkUHJvbXB0KGlucHV0LCBjb250ZXh0KTtcbiAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuZW5naW5lLnF1ZXJ5KHByb21wdCwgdGhpcy5nZXRHZW5lcmF0aW9uQ29uZmlnKCkpO1xuXG4gICAgLy8gU3RyZWFtIHRoZSByZXNwb25zZSB3b3JkIGJ5IHdvcmRcbiAgICBjb25zdCB3b3JkcyA9IHJlc3BvbnNlLnRleHQuc3BsaXQoJyAnKTtcbiAgICBsZXQgc3RyZWFtZWRUZXh0ID0gJyc7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHdvcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB3b3JkID0gd29yZHNbaV07XG4gICAgICBjb25zdCB0ZXh0ID0gaSA8IHdvcmRzLmxlbmd0aCAtIDEgPyB3b3JkICsgJyAnIDogd29yZDtcbiAgICAgIHN0cmVhbWVkVGV4dCArPSB0ZXh0O1xuXG4gICAgICB5aWVsZCB7IHR5cGU6ICd0b2tlbicsIHRleHQsIGRvbmU6IGZhbHNlIH07XG4gICAgICBhd2FpdCB0aGlzLmRlbGF5KDIwKTsgLy8gU2ltdWxhdGUgZ2VuZXJhdGlvbiBsYXRlbmN5XG4gICAgfVxuXG4gICAgY29uc3QgdG9rZW5Vc2FnZSA9IHRoaXMuZXN0aW1hdGVUb2tlblVzYWdlKGlucHV0LCBjb250ZXh0LCBzdHJlYW1lZFRleHQpO1xuICAgIGNvbnN0IHF1YWxpdHlTY29yZSA9IHRoaXMuY2FsY3VsYXRlUXVhbGl0eVNjb3JlKHNvdXJjZXMsIHJlc3BvbnNlLmNvbmZpZGVuY2UpO1xuXG4gICAgY29uc3QgYW5zd2VyOiBSbG1BbnN3ZXIgPSB7XG4gICAgICB0ZXh0OiBzdHJlYW1lZFRleHQsXG4gICAgICBjb25maWRlbmNlOiByZXNwb25zZS5jb25maWRlbmNlLFxuICAgICAgcXVhbGl0eVNjb3JlLFxuICAgICAgc291cmNlcyxcbiAgICAgIHN1YlF1ZXJpZXM6IHN1YlF1ZXJpZXMubGVuZ3RoID4gMCA/IHN1YlF1ZXJpZXMgOiB1bmRlZmluZWQsXG4gICAgICB0b2tlblVzYWdlLFxuICAgICAgY2FjaGVkOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgLy8gQ2FjaGUgdGhlIHJlc3VsdFxuICAgIGlmICh0aGlzLmNvbmZpZy5lbmFibGVDYWNoZSkge1xuICAgICAgdGhpcy5zZXRDYWNoZShpbnB1dCwgYW5zd2VyKTtcbiAgICB9XG5cbiAgICB5aWVsZCB7IHR5cGU6ICdkb25lJywgYW5zd2VyLCBkb25lOiB0cnVlIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkIGNvbnRlbnQgdG8gbWVtb3J5IGZvciByZXRyaWV2YWxcbiAgICpcbiAgICogQHBhcmFtIHRleHQgLSBUaGUgdGV4dCBjb250ZW50IHRvIHN0b3JlXG4gICAqIEBwYXJhbSBtZXRhZGF0YSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBtZW1vcnlcbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIG1lbW9yeSBzcGFuIElEXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgaWQxID0gYXdhaXQgcmxtLmFkZE1lbW9yeShcbiAgICogICAnVHlwZVNjcmlwdCBpcyBhIHR5cGVkIHN1cGVyc2V0IG9mIEphdmFTY3JpcHQuJyxcbiAgICogICB7IHNvdXJjZTogJ2RvY3VtZW50YXRpb24nLCBjYXRlZ29yeTogJ3Byb2dyYW1taW5nJyB9XG4gICAqICk7XG4gICAqXG4gICAqIGNvbnN0IGlkMiA9IGF3YWl0IHJsbS5hZGRNZW1vcnkoXG4gICAqICAgJ1JlYWN0IGlzIGEgSmF2YVNjcmlwdCBsaWJyYXJ5IGZvciBidWlsZGluZyBVSXMuJ1xuICAgKiApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGFkZE1lbW9yeSh0ZXh0OiBzdHJpbmcsIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IG5vZGVJZCA9IHRoaXMuZW5naW5lLmFkZE1lbW9yeSh0ZXh0LCBtZXRhZGF0YSk7XG4gICAgY29uc3QgaWQgPSBgcmxtLW1lbS0ke3RoaXMubWVtb3J5SWRDb3VudGVyKyt9LSR7bm9kZUlkfWA7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlYXJjaCBtZW1vcnkgZm9yIHJlbGV2YW50IHNwYW5zXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeSAtIFRoZSBzZWFyY2ggcXVlcnlcbiAgICogQHBhcmFtIHRvcEsgLSBOdW1iZXIgb2YgcmVzdWx0cyB0byByZXR1cm4gKGRlZmF1bHQ6IGNvbmZpZy5yZXRyaWV2YWxUb3BLKVxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmluZyB0byBhcnJheSBvZiBtZW1vcnkgc3BhbnNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBzcGFucyA9IGF3YWl0IHJsbS5zZWFyY2hNZW1vcnkoJ0phdmFTY3JpcHQgZnJhbWV3b3JrcycsIDUpO1xuICAgKiBmb3IgKGNvbnN0IHNwYW4gb2Ygc3BhbnMpIHtcbiAgICogICBjb25zb2xlLmxvZyhgWyR7c3Bhbi5zaW1pbGFyaXR5U2NvcmUudG9GaXhlZCgyKX1dICR7c3Bhbi50ZXh0fWApO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgc2VhcmNoTWVtb3J5KHF1ZXJ5OiBzdHJpbmcsIHRvcEs/OiBudW1iZXIpOiBQcm9taXNlPE1lbW9yeVNwYW5bXT4ge1xuICAgIGNvbnN0IGsgPSB0b3BLID8/IHRoaXMuY29uZmlnLnJldHJpZXZhbFRvcEs7XG4gICAgY29uc3QgcmVzdWx0cyA9IHRoaXMuZW5naW5lLnNlYXJjaE1lbW9yeShxdWVyeSwgayk7XG5cbiAgICByZXR1cm4gcmVzdWx0cy5tYXAoKHJlc3VsdCwgaW5kZXgpID0+ICh7XG4gICAgICBpZDogYHJsbS1zcGFuLSR7cmVzdWx0LmlkfS0ke2luZGV4fWAsXG4gICAgICB0ZXh0OiByZXN1bHQuY29udGVudCxcbiAgICAgIHNpbWlsYXJpdHlTY29yZTogcmVzdWx0LnNjb3JlLFxuICAgICAgc291cmNlOiByZXN1bHQubWV0YWRhdGE/LnNvdXJjZSBhcyBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICBtZXRhZGF0YTogcmVzdWx0Lm1ldGFkYXRhLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciB0aGUgcmVzcG9uc2UgY2FjaGVcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBybG0uY2xlYXJDYWNoZSgpO1xuICAgKiBjb25zb2xlLmxvZygnQ2FjaGUgY2xlYXJlZCcpO1xuICAgKiBgYGBcbiAgICovXG4gIGNsZWFyQ2FjaGUoKTogdm9pZCB7XG4gICAgdGhpcy5jYWNoZS5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IGNhY2hlIHN0YXRpc3RpY3NcbiAgICpcbiAgICogQHJldHVybnMgT2JqZWN0IHdpdGggY2FjaGUgc2l6ZSBhbmQgaGl0IHJhdGUgaW5mb1xuICAgKi9cbiAgZ2V0Q2FjaGVTdGF0cygpOiB7IHNpemU6IG51bWJlcjsgZW50cmllczogbnVtYmVyIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBzaXplOiB0aGlzLmNhY2hlLnNpemUsXG4gICAgICBlbnRyaWVzOiB0aGlzLmNhY2hlLnNpemUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgY29uZmlndXJhdGlvbiBhdCBydW50aW1lXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBQYXJ0aWFsIGNvbmZpZ3VyYXRpb24gdG8gbWVyZ2VcbiAgICovXG4gIHVwZGF0ZUNvbmZpZyhjb25maWc6IFBhcnRpYWw8UmxtQ29uZmlnPik6IHZvaWQge1xuICAgIHRoaXMuY29uZmlnID0geyAuLi50aGlzLmNvbmZpZywgLi4uY29uZmlnIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgZ2V0Q29uZmlnKCk6IFJlcXVpcmVkPFJsbUNvbmZpZz4ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuY29uZmlnIH07XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBQcml2YXRlIE1ldGhvZHNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogR2VuZXJhdGUgc3ViLXF1ZXJpZXMgZm9yIGNvbXBsZXggcXVlc3Rpb25zXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlU3ViUXVlcmllcyhcbiAgICBxdWVyeTogc3RyaW5nLFxuICAgIHNvdXJjZXM6IE1lbW9yeVNwYW5bXSxcbiAgICBkZXB0aDogbnVtYmVyXG4gICk6IFByb21pc2U8U3ViUXVlcnlbXT4ge1xuICAgIGlmIChkZXB0aCA+PSB0aGlzLmNvbmZpZy5tYXhEZXB0aCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIFNpbXBsZSBoZXVyaXN0aWM6IGdlbmVyYXRlIHN1Yi1xdWVyaWVzIGZvciBxdWVzdGlvbnMgd2l0aCBtdWx0aXBsZSBwYXJ0c1xuICAgIGNvbnN0IHN1YlF1ZXJpZXM6IFN1YlF1ZXJ5W10gPSBbXTtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMuZGVjb21wb3NlUXVlcnkocXVlcnkpO1xuXG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzLnNsaWNlKDAsIHRoaXMuY29uZmlnLm1heFN1YlF1ZXJpZXMpKSB7XG4gICAgICBpZiAocGFydC50cmltKCkubGVuZ3RoIDwgMTApIGNvbnRpbnVlO1xuXG4gICAgICAvLyBTZWFyY2ggZm9yIHN1Yi1xdWVyeSBzcGVjaWZpYyBzb3VyY2VzXG4gICAgICBjb25zdCBzdWJTb3VyY2VzID0gYXdhaXQgdGhpcy5zZWFyY2hNZW1vcnkocGFydCwgTWF0aC5jZWlsKHRoaXMuY29uZmlnLnJldHJpZXZhbFRvcEsgLyAyKSk7XG4gICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5idWlsZENvbnRleHQoc3ViU291cmNlcywgW10pO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmVuZ2luZS5xdWVyeShcbiAgICAgICAgdGhpcy5idWlsZFByb21wdChwYXJ0LCBjb250ZXh0KSxcbiAgICAgICAgeyAuLi50aGlzLmdldEdlbmVyYXRpb25Db25maWcoKSwgbWF4VG9rZW5zOiAyNTYgfVxuICAgICAgKTtcblxuICAgICAgc3ViUXVlcmllcy5wdXNoKHtcbiAgICAgICAgcXVlcnk6IHBhcnQsXG4gICAgICAgIGFuc3dlcjogcmVzcG9uc2UudGV4dCxcbiAgICAgICAgZGVwdGg6IGRlcHRoICsgMSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBzdWJRdWVyaWVzO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY29tcG9zZSBhIGNvbXBsZXggcXVlcnkgaW50byBzaW1wbGVyIHBhcnRzXG4gICAqL1xuICBwcml2YXRlIGRlY29tcG9zZVF1ZXJ5KHF1ZXJ5OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgLy8gU3BsaXQgb24gY29tbW9uIGNvbmp1bmN0aW9ucyBhbmQgcXVlc3Rpb24gbWFya2Vyc1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gQ2hlY2sgZm9yIG11bHRpLXBhcnQgcXVlc3Rpb25zXG4gICAgY29uc3QgY29uanVuY3Rpb25zID0gWycgYW5kICcsICcgb3IgJywgJy4gJywgJz8gJywgJzsgJ107XG4gICAgbGV0IGN1cnJlbnQgPSBxdWVyeTtcblxuICAgIGZvciAoY29uc3QgY29uaiBvZiBjb25qdW5jdGlvbnMpIHtcbiAgICAgIGlmIChjdXJyZW50LmluY2x1ZGVzKGNvbmopKSB7XG4gICAgICAgIGNvbnN0IHNwbGl0ID0gY3VycmVudC5zcGxpdChjb25qKTtcbiAgICAgICAgcGFydHMucHVzaCguLi5zcGxpdC5maWx0ZXIocCA9PiBwLnRyaW0oKS5sZW5ndGggPiAxMCkpO1xuICAgICAgICBjdXJyZW50ID0gJyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vIGRlY29tcG9zaXRpb24gaGFwcGVuZWQsIHJldHVybiBvcmlnaW5hbFxuICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbcXVlcnldO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJ0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBjb250ZXh0IHN0cmluZyBmcm9tIHNvdXJjZXMgYW5kIHN1Yi1xdWVyaWVzXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQ29udGV4dChzb3VyY2VzOiBNZW1vcnlTcGFuW10sIHN1YlF1ZXJpZXM6IFN1YlF1ZXJ5W10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gQWRkIHNvdXJjZXNcbiAgICBpZiAoc291cmNlcy5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJ0cy5wdXNoKCdSZWxldmFudCBjb250ZXh0OicpO1xuICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICBwYXJ0cy5wdXNoKGAtICR7c291cmNlLnRleHR9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIHN1Yi1xdWVyeSBhbnN3ZXJzXG4gICAgaWYgKHN1YlF1ZXJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgcGFydHMucHVzaCgnXFxuUmVsYXRlZCBpbmZvcm1hdGlvbjonKTtcbiAgICAgIGZvciAoY29uc3Qgc3Egb2Ygc3ViUXVlcmllcykge1xuICAgICAgICBwYXJ0cy5wdXNoKGBROiAke3NxLnF1ZXJ5fWApO1xuICAgICAgICBwYXJ0cy5wdXNoKGBBOiAke3NxLmFuc3dlcn1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHMuam9pbignXFxuJyk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgdGhlIGZ1bGwgcHJvbXB0IHdpdGggY29udGV4dFxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFByb21wdChxdWVyeTogc3RyaW5nLCBjb250ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmIChjb250ZXh0LnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9XG5cbiAgICByZXR1cm4gYCR7Y29udGV4dH1cXG5cXG5CYXNlZCBvbiB0aGUgYWJvdmUgY29udGV4dCwgYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246XFxuJHtxdWVyeX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBnZW5lcmF0aW9uIGNvbmZpZyBiYXNlZCBvbiBSTE0gc2V0dGluZ3NcbiAgICovXG4gIHByaXZhdGUgZ2V0R2VuZXJhdGlvbkNvbmZpZygpOiBHZW5lcmF0aW9uQ29uZmlnIHtcbiAgICByZXR1cm4ge1xuICAgICAgbWF4VG9rZW5zOiBNYXRoLm1pbih0aGlzLmNvbmZpZy50b2tlbkJ1ZGdldCwgMjA0OCksXG4gICAgICB0ZW1wZXJhdHVyZTogMC43LFxuICAgICAgdG9wUDogMC45LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRXN0aW1hdGUgdG9rZW4gdXNhZ2VcbiAgICovXG4gIHByaXZhdGUgZXN0aW1hdGVUb2tlblVzYWdlKHF1ZXJ5OiBzdHJpbmcsIGNvbnRleHQ6IHN0cmluZywgcmVzcG9uc2U6IHN0cmluZyk6IFRva2VuVXNhZ2Uge1xuICAgIC8vIFJvdWdoIGVzdGltYXRpb246IH40IGNoYXJhY3RlcnMgcGVyIHRva2VuXG4gICAgY29uc3QgcHJvbXB0VG9rZW5zID0gTWF0aC5jZWlsKChxdWVyeS5sZW5ndGggKyBjb250ZXh0Lmxlbmd0aCkgLyA0KTtcbiAgICBjb25zdCBjb21wbGV0aW9uVG9rZW5zID0gTWF0aC5jZWlsKHJlc3BvbnNlLmxlbmd0aCAvIDQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByb21wdDogcHJvbXB0VG9rZW5zLFxuICAgICAgY29tcGxldGlvbjogY29tcGxldGlvblRva2VucyxcbiAgICAgIHRvdGFsOiBwcm9tcHRUb2tlbnMgKyBjb21wbGV0aW9uVG9rZW5zLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHF1YWxpdHkgc2NvcmUgYmFzZWQgb24gc291cmNlcyBhbmQgY29uZmlkZW5jZVxuICAgKi9cbiAgcHJpdmF0ZSBjYWxjdWxhdGVRdWFsaXR5U2NvcmUoc291cmNlczogTWVtb3J5U3BhbltdLCBjb25maWRlbmNlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChzb3VyY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbmZpZGVuY2UgKiAwLjU7IC8vIFBlbmFsaXplIGFuc3dlcnMgd2l0aG91dCBzb3VyY2VzXG4gICAgfVxuXG4gICAgLy8gQXZlcmFnZSBzb3VyY2Ugc2ltaWxhcml0eVxuICAgIGNvbnN0IGF2Z1NpbWlsYXJpdHkgPSBzb3VyY2VzLnJlZHVjZSgoc3VtLCBzKSA9PiBzdW0gKyBzLnNpbWlsYXJpdHlTY29yZSwgMCkgLyBzb3VyY2VzLmxlbmd0aDtcblxuICAgIC8vIFdlaWdodGVkIGNvbWJpbmF0aW9uXG4gICAgcmV0dXJuIGNvbmZpZGVuY2UgKiAwLjYgKyBhdmdTaW1pbGFyaXR5ICogMC40O1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IHNlbGYtcmVmbGVjdGlvbiB0byBpbXByb3ZlIGFuc3dlclxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhcHBseVJlZmxlY3Rpb24oXG4gICAgcXVlcnk6IHN0cmluZyxcbiAgICBhbnN3ZXI6IFJsbUFuc3dlclxuICApOiBQcm9taXNlPFJsbUFuc3dlcj4ge1xuICAgIGxldCBjdXJyZW50QW5zd2VyID0gYW5zd2VyO1xuICAgIGxldCBpdGVyYXRpb25zID0gMDtcblxuICAgIHdoaWxlIChcbiAgICAgIGl0ZXJhdGlvbnMgPCB0aGlzLmNvbmZpZy5tYXhSZWZsZWN0aW9uSXRlcmF0aW9ucyAmJlxuICAgICAgY3VycmVudEFuc3dlci5xdWFsaXR5U2NvcmUgPCB0aGlzLmNvbmZpZy5taW5RdWFsaXR5U2NvcmVcbiAgICApIHtcbiAgICAgIGl0ZXJhdGlvbnMrKztcblxuICAgICAgLy8gR2VuZXJhdGUgY3JpdGlxdWVcbiAgICAgIGNvbnN0IGNyaXRpcXVlUHJvbXB0ID0gYEV2YWx1YXRlIHRoaXMgYW5zd2VyIGZvciBhY2N1cmFjeSBhbmQgY29tcGxldGVuZXNzOlxuUXVlc3Rpb246ICR7cXVlcnl9XG5BbnN3ZXI6ICR7Y3VycmVudEFuc3dlci50ZXh0fVxuXG5Qcm92aWRlIGEgYnJpZWYgY3JpdGlxdWUgYW5kIHN1Z2dlc3QgaW1wcm92ZW1lbnRzLmA7XG5cbiAgICAgIGNvbnN0IGNyaXRpcXVlUmVzcG9uc2UgPSB0aGlzLmVuZ2luZS5xdWVyeShjcml0aXF1ZVByb21wdCwge1xuICAgICAgICBtYXhUb2tlbnM6IDI1NixcbiAgICAgICAgdGVtcGVyYXR1cmU6IDAuNSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBHZW5lcmF0ZSBpbXByb3ZlZCBhbnN3ZXJcbiAgICAgIGNvbnN0IGltcHJvdmVQcm9tcHQgPSBgQmFzZWQgb24gdGhpcyBmZWVkYmFjazogXCIke2NyaXRpcXVlUmVzcG9uc2UudGV4dH1cIlxuXG5JbXByb3ZlIHRoaXMgYW5zd2VyOlxuUXVlc3Rpb246ICR7cXVlcnl9XG5PcmlnaW5hbDogJHtjdXJyZW50QW5zd2VyLnRleHR9XG5cblByb3ZpZGUgYW4gaW1wcm92ZWQgYW5zd2VyOmA7XG5cbiAgICAgIGNvbnN0IGltcHJvdmVkUmVzcG9uc2UgPSB0aGlzLmVuZ2luZS5xdWVyeShpbXByb3ZlUHJvbXB0LCB0aGlzLmdldEdlbmVyYXRpb25Db25maWcoKSk7XG5cbiAgICAgIC8vIFVwZGF0ZSBhbnN3ZXIgd2l0aCByZWZsZWN0aW9uIGltcHJvdmVtZW50c1xuICAgICAgY29uc3QgbmV3UXVhbGl0eVNjb3JlID0gTWF0aC5taW4oXG4gICAgICAgIDEuMCxcbiAgICAgICAgY3VycmVudEFuc3dlci5xdWFsaXR5U2NvcmUgKyAwLjEgKiBpdGVyYXRpb25zXG4gICAgICApO1xuXG4gICAgICBjdXJyZW50QW5zd2VyID0ge1xuICAgICAgICAuLi5jdXJyZW50QW5zd2VyLFxuICAgICAgICB0ZXh0OiBpbXByb3ZlZFJlc3BvbnNlLnRleHQsXG4gICAgICAgIGNvbmZpZGVuY2U6IE1hdGgubWF4KGN1cnJlbnRBbnN3ZXIuY29uZmlkZW5jZSwgaW1wcm92ZWRSZXNwb25zZS5jb25maWRlbmNlKSxcbiAgICAgICAgcXVhbGl0eVNjb3JlOiBuZXdRdWFsaXR5U2NvcmUsXG4gICAgICAgIHRva2VuVXNhZ2U6IHtcbiAgICAgICAgICBwcm9tcHQ6IGN1cnJlbnRBbnN3ZXIudG9rZW5Vc2FnZS5wcm9tcHQgKyAxMDAsIC8vIEFwcHJveGltYXRlIGFkZGl0aW9uYWwgdG9rZW5zXG4gICAgICAgICAgY29tcGxldGlvbjogY3VycmVudEFuc3dlci50b2tlblVzYWdlLmNvbXBsZXRpb24gKyAxMDAsXG4gICAgICAgICAgdG90YWw6IGN1cnJlbnRBbnN3ZXIudG9rZW5Vc2FnZS50b3RhbCArIDIwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRBbnN3ZXI7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlZCBhbnN3ZXIgaWYgdmFsaWRcbiAgICovXG4gIHByaXZhdGUgZ2V0Q2FjaGVkKHF1ZXJ5OiBzdHJpbmcpOiBSbG1BbnN3ZXIgfCBudWxsIHtcbiAgICBjb25zdCBoYXNoID0gdGhpcy5oYXNoUXVlcnkocXVlcnkpO1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5jYWNoZS5nZXQoaGFzaCk7XG5cbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBUVExcbiAgICBpZiAoRGF0ZS5ub3coKSAtIGVudHJ5LnRpbWVzdGFtcCA+IHRoaXMuY29uZmlnLmNhY2hlVHRsKSB7XG4gICAgICB0aGlzLmNhY2hlLmRlbGV0ZShoYXNoKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBlbnRyeS5hbnN3ZXI7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGNhY2hlIGVudHJ5XG4gICAqL1xuICBwcml2YXRlIHNldENhY2hlKHF1ZXJ5OiBzdHJpbmcsIGFuc3dlcjogUmxtQW5zd2VyKTogdm9pZCB7XG4gICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaFF1ZXJ5KHF1ZXJ5KTtcbiAgICB0aGlzLmNhY2hlLnNldChoYXNoLCB7XG4gICAgICBhbnN3ZXIsXG4gICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICBxdWVyeUhhc2g6IGhhc2gsXG4gICAgfSk7XG5cbiAgICAvLyBQcnVuZSBvbGQgZW50cmllcyBpZiBjYWNoZSBnZXRzIHRvbyBsYXJnZVxuICAgIGlmICh0aGlzLmNhY2hlLnNpemUgPiAxMDAwKSB7XG4gICAgICB0aGlzLnBydW5lQ2FjaGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2ltcGxlIGhhc2ggZnVuY3Rpb24gZm9yIGNhY2hlIGtleXNcbiAgICovXG4gIHByaXZhdGUgaGFzaFF1ZXJ5KHF1ZXJ5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCBoYXNoID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjaGFyID0gcXVlcnkuY2hhckNvZGVBdChpKTtcbiAgICAgIGhhc2ggPSAoKGhhc2ggPDwgNSkgLSBoYXNoKSArIGNoYXI7XG4gICAgICBoYXNoID0gaGFzaCAmIGhhc2g7IC8vIENvbnZlcnQgdG8gMzItYml0IGludGVnZXJcbiAgICB9XG4gICAgcmV0dXJuIGBybG0tY2FjaGUtJHtoYXNoLnRvU3RyaW5nKDE2KX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFBydW5lIGV4cGlyZWQgY2FjaGUgZW50cmllc1xuICAgKi9cbiAgcHJpdmF0ZSBwcnVuZUNhY2hlKCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgdG9EZWxldGU6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIGVudHJ5XSBvZiB0aGlzLmNhY2hlLmVudHJpZXMoKSkge1xuICAgICAgaWYgKG5vdyAtIGVudHJ5LnRpbWVzdGFtcCA+IHRoaXMuY29uZmlnLmNhY2hlVHRsKSB7XG4gICAgICAgIHRvRGVsZXRlLnB1c2goa2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEZWxldGUgb2xkZXN0IGVudHJpZXMgaWYgc3RpbGwgdG9vIGxhcmdlXG4gICAgaWYgKHRoaXMuY2FjaGUuc2l6ZSAtIHRvRGVsZXRlLmxlbmd0aCA+IDgwMCkge1xuICAgICAgY29uc3QgZW50cmllcyA9IEFycmF5LmZyb20odGhpcy5jYWNoZS5lbnRyaWVzKCkpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhWzFdLnRpbWVzdGFtcCAtIGJbMV0udGltZXN0YW1wKTtcblxuICAgICAgY29uc3QgZGVsZXRlQ291bnQgPSBlbnRyaWVzLmxlbmd0aCAtIDUwMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVsZXRlQ291bnQ7IGkrKykge1xuICAgICAgICB0b0RlbGV0ZS5wdXNoKGVudHJpZXNbaV1bMF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIHRvRGVsZXRlKSB7XG4gICAgICB0aGlzLmNhY2hlLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVdGlsaXR5IGRlbGF5IGZ1bmN0aW9uIGZvciBzdHJlYW1pbmcgc2ltdWxhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBkZWxheShtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xuICB9XG59XG4iXX0= |
| /** | ||
| * RLM - Retrieval Language Model | ||
| * | ||
| * A recursive retrieval-augmented generation system that combines | ||
| * memory search with intelligent query decomposition and synthesis. | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * enableCache: true, | ||
| * retrievalTopK: 10, | ||
| * }); | ||
| * | ||
| * // Add knowledge | ||
| * await rlm.addMemory('TypeScript adds static typing to JavaScript.'); | ||
| * await rlm.addMemory('React is a library for building user interfaces.'); | ||
| * | ||
| * // Query with retrieval | ||
| * const answer = await rlm.query('Compare TypeScript and JavaScript'); | ||
| * console.log(answer.text); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('Explain machine learning')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nQuality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * // Answers will be iteratively refined until quality >= 0.8 | ||
| * const answer = await rlm.query('Complex technical question...'); | ||
| * ``` | ||
| * | ||
| * @module rlm | ||
| */ | ||
| export * from './types'; | ||
| export { RlmController } from './controller'; | ||
| export { type DecompositionStrategy, type SubQuery, type QueryDecomposition, type SubAnswer, type RlmTrajectoryMetadata, type RlmTrainingExample, type ContrastivePair, type RlmTrainingConfig, type TrainingResult as RlmTrainingResult, type EvaluationResult as RlmEvaluationResult, DEFAULT_RLM_CONFIG, FAST_RLM_CONFIG, THOROUGH_RLM_CONFIG, ROUTING_FOCUSED_CONFIG, AGENT_DEFINITIONS, HARD_NEGATIVE_PAIRS, RlmTrainer, createRlmTrainer, createEmptyExample, createSubQuery, createSubAnswer, } from './training'; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rlm/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,IAAI,iBAAiB,EACxC,KAAK,gBAAgB,IAAI,mBAAmB,EAG5C,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EAGnB,UAAU,EAGV,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC"} |
| "use strict"; | ||
| /** | ||
| * RLM - Retrieval Language Model | ||
| * | ||
| * A recursive retrieval-augmented generation system that combines | ||
| * memory search with intelligent query decomposition and synthesis. | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * enableCache: true, | ||
| * retrievalTopK: 10, | ||
| * }); | ||
| * | ||
| * // Add knowledge | ||
| * await rlm.addMemory('TypeScript adds static typing to JavaScript.'); | ||
| * await rlm.addMemory('React is a library for building user interfaces.'); | ||
| * | ||
| * // Query with retrieval | ||
| * const answer = await rlm.query('Compare TypeScript and JavaScript'); | ||
| * console.log(answer.text); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('Explain machine learning')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nQuality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * // Answers will be iteratively refined until quality >= 0.8 | ||
| * const answer = await rlm.query('Complex technical question...'); | ||
| * ``` | ||
| * | ||
| * @module rlm | ||
| */ | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.createSubAnswer = exports.createSubQuery = exports.createEmptyExample = exports.createRlmTrainer = exports.RlmTrainer = exports.HARD_NEGATIVE_PAIRS = exports.AGENT_DEFINITIONS = exports.ROUTING_FOCUSED_CONFIG = exports.THOROUGH_RLM_CONFIG = exports.FAST_RLM_CONFIG = exports.DEFAULT_RLM_CONFIG = exports.RlmController = void 0; | ||
| // Export all types | ||
| __exportStar(require("./types"), exports); | ||
| // Export the controller | ||
| var controller_1 = require("./controller"); | ||
| Object.defineProperty(exports, "RlmController", { enumerable: true, get: function () { return controller_1.RlmController; } }); | ||
| // Export training module | ||
| var training_1 = require("./training"); | ||
| // Constants | ||
| Object.defineProperty(exports, "DEFAULT_RLM_CONFIG", { enumerable: true, get: function () { return training_1.DEFAULT_RLM_CONFIG; } }); | ||
| Object.defineProperty(exports, "FAST_RLM_CONFIG", { enumerable: true, get: function () { return training_1.FAST_RLM_CONFIG; } }); | ||
| Object.defineProperty(exports, "THOROUGH_RLM_CONFIG", { enumerable: true, get: function () { return training_1.THOROUGH_RLM_CONFIG; } }); | ||
| Object.defineProperty(exports, "ROUTING_FOCUSED_CONFIG", { enumerable: true, get: function () { return training_1.ROUTING_FOCUSED_CONFIG; } }); | ||
| Object.defineProperty(exports, "AGENT_DEFINITIONS", { enumerable: true, get: function () { return training_1.AGENT_DEFINITIONS; } }); | ||
| Object.defineProperty(exports, "HARD_NEGATIVE_PAIRS", { enumerable: true, get: function () { return training_1.HARD_NEGATIVE_PAIRS; } }); | ||
| // Classes | ||
| Object.defineProperty(exports, "RlmTrainer", { enumerable: true, get: function () { return training_1.RlmTrainer; } }); | ||
| // Factory functions | ||
| Object.defineProperty(exports, "createRlmTrainer", { enumerable: true, get: function () { return training_1.createRlmTrainer; } }); | ||
| Object.defineProperty(exports, "createEmptyExample", { enumerable: true, get: function () { return training_1.createEmptyExample; } }); | ||
| Object.defineProperty(exports, "createSubQuery", { enumerable: true, get: function () { return training_1.createSubQuery; } }); | ||
| Object.defineProperty(exports, "createSubAnswer", { enumerable: true, get: function () { return training_1.createSubAnswer; } }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcmxtL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeURHOzs7Ozs7Ozs7Ozs7Ozs7OztBQUVILG1CQUFtQjtBQUNuQiwwQ0FBd0I7QUFFeEIsd0JBQXdCO0FBQ3hCLDJDQUE2QztBQUFwQywyR0FBQSxhQUFhLE9BQUE7QUFFdEIseUJBQXlCO0FBQ3pCLHVDQTZCb0I7QUFoQmxCLFlBQVk7QUFDWiw4R0FBQSxrQkFBa0IsT0FBQTtBQUNsQiwyR0FBQSxlQUFlLE9BQUE7QUFDZiwrR0FBQSxtQkFBbUIsT0FBQTtBQUNuQixrSEFBQSxzQkFBc0IsT0FBQTtBQUN0Qiw2R0FBQSxpQkFBaUIsT0FBQTtBQUNqQiwrR0FBQSxtQkFBbUIsT0FBQTtBQUVuQixVQUFVO0FBQ1Ysc0dBQUEsVUFBVSxPQUFBO0FBRVYsb0JBQW9CO0FBQ3BCLDRHQUFBLGdCQUFnQixPQUFBO0FBQ2hCLDhHQUFBLGtCQUFrQixPQUFBO0FBQ2xCLDBHQUFBLGNBQWMsT0FBQTtBQUNkLDJHQUFBLGVBQWUsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUkxNIC0gUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsXG4gKlxuICogQSByZWN1cnNpdmUgcmV0cmlldmFsLWF1Z21lbnRlZCBnZW5lcmF0aW9uIHN5c3RlbSB0aGF0IGNvbWJpbmVzXG4gKiBtZW1vcnkgc2VhcmNoIHdpdGggaW50ZWxsaWdlbnQgcXVlcnkgZGVjb21wb3NpdGlvbiBhbmQgc3ludGhlc2lzLlxuICpcbiAqIEBleGFtcGxlIEJhc2ljIFVzYWdlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBSbG1Db250cm9sbGVyIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogY29uc3QgcmxtID0gbmV3IFJsbUNvbnRyb2xsZXIoe1xuICogICBtYXhEZXB0aDogMyxcbiAqICAgZW5hYmxlQ2FjaGU6IHRydWUsXG4gKiAgIHJldHJpZXZhbFRvcEs6IDEwLFxuICogfSk7XG4gKlxuICogLy8gQWRkIGtub3dsZWRnZVxuICogYXdhaXQgcmxtLmFkZE1lbW9yeSgnVHlwZVNjcmlwdCBhZGRzIHN0YXRpYyB0eXBpbmcgdG8gSmF2YVNjcmlwdC4nKTtcbiAqIGF3YWl0IHJsbS5hZGRNZW1vcnkoJ1JlYWN0IGlzIGEgbGlicmFyeSBmb3IgYnVpbGRpbmcgdXNlciBpbnRlcmZhY2VzLicpO1xuICpcbiAqIC8vIFF1ZXJ5IHdpdGggcmV0cmlldmFsXG4gKiBjb25zdCBhbnN3ZXIgPSBhd2FpdCBybG0ucXVlcnkoJ0NvbXBhcmUgVHlwZVNjcmlwdCBhbmQgSmF2YVNjcmlwdCcpO1xuICogY29uc29sZS5sb2coYW5zd2VyLnRleHQpO1xuICogY29uc29sZS5sb2coJ0NvbmZpZGVuY2U6JywgYW5zd2VyLmNvbmZpZGVuY2UpO1xuICogY29uc29sZS5sb2coJ1NvdXJjZXM6JywgYW5zd2VyLnNvdXJjZXMubGVuZ3RoKTtcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFN0cmVhbWluZ1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKCk7XG4gKlxuICogZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBybG0ucXVlcnlTdHJlYW0oJ0V4cGxhaW4gbWFjaGluZSBsZWFybmluZycpKSB7XG4gKiAgIGlmIChldmVudC50eXBlID09PSAndG9rZW4nKSB7XG4gKiAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoZXZlbnQudGV4dCk7XG4gKiAgIH0gZWxzZSB7XG4gKiAgICAgY29uc29sZS5sb2coJ1xcblxcblF1YWxpdHk6JywgZXZlbnQuYW5zd2VyLnF1YWxpdHlTY29yZSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFdpdGggUmVmbGVjdGlvblxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKHtcbiAqICAgZW5hYmxlUmVmbGVjdGlvbjogdHJ1ZSxcbiAqICAgbWF4UmVmbGVjdGlvbkl0ZXJhdGlvbnM6IDIsXG4gKiAgIG1pblF1YWxpdHlTY29yZTogMC44LFxuICogfSk7XG4gKlxuICogLy8gQW5zd2VycyB3aWxsIGJlIGl0ZXJhdGl2ZWx5IHJlZmluZWQgdW50aWwgcXVhbGl0eSA+PSAwLjhcbiAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnQ29tcGxleCB0ZWNobmljYWwgcXVlc3Rpb24uLi4nKTtcbiAqIGBgYFxuICpcbiAqIEBtb2R1bGUgcmxtXG4gKi9cblxuLy8gRXhwb3J0IGFsbCB0eXBlc1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5cbi8vIEV4cG9ydCB0aGUgY29udHJvbGxlclxuZXhwb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJy4vY29udHJvbGxlcic7XG5cbi8vIEV4cG9ydCB0cmFpbmluZyBtb2R1bGVcbmV4cG9ydCB7XG4gIC8vIFR5cGVzXG4gIHR5cGUgRGVjb21wb3NpdGlvblN0cmF0ZWd5LFxuICB0eXBlIFN1YlF1ZXJ5LFxuICB0eXBlIFF1ZXJ5RGVjb21wb3NpdGlvbixcbiAgdHlwZSBTdWJBbnN3ZXIsXG4gIHR5cGUgUmxtVHJhamVjdG9yeU1ldGFkYXRhLFxuICB0eXBlIFJsbVRyYWluaW5nRXhhbXBsZSxcbiAgdHlwZSBDb250cmFzdGl2ZVBhaXIsXG4gIHR5cGUgUmxtVHJhaW5pbmdDb25maWcsXG4gIHR5cGUgVHJhaW5pbmdSZXN1bHQgYXMgUmxtVHJhaW5pbmdSZXN1bHQsXG4gIHR5cGUgRXZhbHVhdGlvblJlc3VsdCBhcyBSbG1FdmFsdWF0aW9uUmVzdWx0LFxuXG4gIC8vIENvbnN0YW50c1xuICBERUZBVUxUX1JMTV9DT05GSUcsXG4gIEZBU1RfUkxNX0NPTkZJRyxcbiAgVEhPUk9VR0hfUkxNX0NPTkZJRyxcbiAgUk9VVElOR19GT0NVU0VEX0NPTkZJRyxcbiAgQUdFTlRfREVGSU5JVElPTlMsXG4gIEhBUkRfTkVHQVRJVkVfUEFJUlMsXG5cbiAgLy8gQ2xhc3Nlc1xuICBSbG1UcmFpbmVyLFxuXG4gIC8vIEZhY3RvcnkgZnVuY3Rpb25zXG4gIGNyZWF0ZVJsbVRyYWluZXIsXG4gIGNyZWF0ZUVtcHR5RXhhbXBsZSxcbiAgY3JlYXRlU3ViUXVlcnksXG4gIGNyZWF0ZVN1YkFuc3dlcixcbn0gZnJvbSAnLi90cmFpbmluZyc7XG4iXX0= |
| /** | ||
| * RLM (Recursive Learning Machine) Training Module | ||
| * | ||
| * Provides training capabilities for RuvLTRA models on RLM task routing | ||
| * and decomposition, including query decomposition, answer synthesis, | ||
| * and agent routing optimization. | ||
| * | ||
| * @module rlm/training | ||
| */ | ||
| /** | ||
| * Strategy for decomposing a complex query | ||
| */ | ||
| export type DecompositionStrategy = 'sequential' | 'parallel' | 'hierarchical' | 'dag-based' | 'iterative' | 'none'; | ||
| /** | ||
| * A sub-query in the decomposition | ||
| */ | ||
| export interface SubQuery { | ||
| /** Unique identifier within the decomposition */ | ||
| id: number; | ||
| /** The sub-query text */ | ||
| query: string; | ||
| /** Expected output type (e.g., "code", "analysis", "data") */ | ||
| expectedType: string; | ||
| /** Dependencies (IDs of sub-queries that must complete first) */ | ||
| dependencies: number[]; | ||
| /** Recommended agent type for this sub-query */ | ||
| recommendedAgent?: string; | ||
| /** Estimated complexity (0.0-1.0) */ | ||
| complexity: number; | ||
| /** Optional context from parent query */ | ||
| context?: string; | ||
| } | ||
| /** | ||
| * Decomposition of a complex query into sub-queries | ||
| */ | ||
| export interface QueryDecomposition { | ||
| /** Sub-queries in execution order */ | ||
| subQueries: SubQuery[]; | ||
| /** Decomposition strategy used */ | ||
| strategy: DecompositionStrategy; | ||
| /** Reasoning for this decomposition */ | ||
| rationale: string; | ||
| /** Total estimated complexity */ | ||
| totalComplexity: number; | ||
| /** Whether decomposition was successful */ | ||
| success: boolean; | ||
| /** Error message if decomposition failed */ | ||
| error?: string; | ||
| } | ||
| /** | ||
| * Answer to a sub-query | ||
| */ | ||
| export interface SubAnswer { | ||
| /** ID of the sub-query this answers */ | ||
| subQueryId: number; | ||
| /** The answer content */ | ||
| content: string; | ||
| /** Confidence in this answer (0.0-1.0) */ | ||
| confidence: number; | ||
| /** Agent that produced this answer */ | ||
| agent: string; | ||
| /** Latency in milliseconds */ | ||
| latencyMs: number; | ||
| /** Quality score (0.0-1.0) */ | ||
| quality: number; | ||
| /** Whether this answer was successful */ | ||
| success: boolean; | ||
| /** Error message if failed */ | ||
| error?: string; | ||
| /** Intermediate reasoning/chain-of-thought */ | ||
| reasoning?: string; | ||
| } | ||
| /** | ||
| * Metadata about the RLM execution trajectory | ||
| */ | ||
| export interface RlmTrajectoryMetadata { | ||
| /** Session ID */ | ||
| sessionId?: string; | ||
| /** User ID */ | ||
| userId?: string; | ||
| /** Total latency in milliseconds */ | ||
| totalLatencyMs: number; | ||
| /** Number of retries */ | ||
| retries: number; | ||
| /** Maximum parallel branches executed */ | ||
| maxParallelism: number; | ||
| /** Models used during execution */ | ||
| modelsUsed: string[]; | ||
| /** Agents invoked */ | ||
| agentsInvoked: string[]; | ||
| /** Tools used */ | ||
| toolsUsed: string[]; | ||
| /** Custom attributes */ | ||
| attributes: Record<string, string>; | ||
| } | ||
| /** | ||
| * A complete RLM training example | ||
| */ | ||
| export interface RlmTrainingExample { | ||
| /** Unique identifier */ | ||
| id: string; | ||
| /** Original complex query */ | ||
| query: string; | ||
| /** Query embedding (optional) */ | ||
| queryEmbedding?: number[]; | ||
| /** How the query was decomposed */ | ||
| decomposition: QueryDecomposition; | ||
| /** Answers to each sub-query */ | ||
| subAnswers: SubAnswer[]; | ||
| /** Final synthesized answer */ | ||
| finalAnswer: string; | ||
| /** Final answer embedding (optional) */ | ||
| finalEmbedding?: number[]; | ||
| /** Overall quality score (0.0-1.0) */ | ||
| qualityScore: number; | ||
| /** Execution trajectory metadata */ | ||
| trajectory: RlmTrajectoryMetadata; | ||
| /** Whether this example was successful */ | ||
| success: boolean; | ||
| /** Lessons learned from this example */ | ||
| lessons: string[]; | ||
| /** Source of this example */ | ||
| source: string; | ||
| } | ||
| /** | ||
| * A contrastive pair for agent routing training | ||
| */ | ||
| export interface ContrastivePair { | ||
| /** Anchor query */ | ||
| anchor: string; | ||
| /** Anchor embedding (optional) */ | ||
| anchorEmbedding?: number[]; | ||
| /** Positive agent (correct routing) */ | ||
| positiveAgent: string; | ||
| /** Negative agent (incorrect routing) */ | ||
| negativeAgent: string; | ||
| /** Whether this is a hard negative */ | ||
| isHardNegative: boolean; | ||
| /** Quality score of the anchor example */ | ||
| quality: number; | ||
| /** Source example ID */ | ||
| sourceId: string; | ||
| } | ||
| /** | ||
| * Configuration for RLM training | ||
| */ | ||
| export interface RlmTrainingConfig { | ||
| /** Learning rate for decomposition training */ | ||
| decompositionLr: number; | ||
| /** Learning rate for synthesis training */ | ||
| synthesisLr: number; | ||
| /** Learning rate for contrastive fine-tuning */ | ||
| contrastiveLr: number; | ||
| /** Batch size */ | ||
| batchSize: number; | ||
| /** Number of epochs */ | ||
| epochs: number; | ||
| /** Contrastive margin for triplet loss */ | ||
| contrastiveMargin: number; | ||
| /** Temperature for InfoNCE loss */ | ||
| infonceTemperature: number; | ||
| /** Weight for decomposition loss */ | ||
| decompositionWeight: number; | ||
| /** Weight for synthesis loss */ | ||
| synthesisWeight: number; | ||
| /** Weight for routing loss */ | ||
| routingWeight: number; | ||
| /** Minimum quality for updates */ | ||
| qualityThreshold: number; | ||
| /** Evaluation interval (epochs) */ | ||
| evaluationInterval: number; | ||
| /** Warmup steps */ | ||
| warmupSteps: number; | ||
| /** Early stopping patience */ | ||
| earlyStoppingPatience: number; | ||
| /** Validation split ratio */ | ||
| validationSplit: number; | ||
| /** Random seed */ | ||
| seed: number; | ||
| } | ||
| /** | ||
| * Training result for a phase | ||
| */ | ||
| export interface TrainingResult { | ||
| /** Training phase name */ | ||
| phase: string; | ||
| /** Epochs completed */ | ||
| epochsCompleted: number; | ||
| /** Total steps */ | ||
| totalSteps: number; | ||
| /** Final training loss */ | ||
| finalLoss: number; | ||
| /** Best validation loss */ | ||
| bestValLoss: number; | ||
| /** Best epoch */ | ||
| bestEpoch: number; | ||
| /** Final accuracy (for classification tasks) */ | ||
| accuracy: number; | ||
| /** Loss history per epoch */ | ||
| lossHistory: number[]; | ||
| /** Validation loss history */ | ||
| valLossHistory: number[]; | ||
| /** Training duration in milliseconds */ | ||
| durationMs: number; | ||
| /** Whether early stopping was triggered */ | ||
| earlyStopped: boolean; | ||
| } | ||
| /** | ||
| * Evaluation result for the trained model | ||
| */ | ||
| export interface EvaluationResult { | ||
| /** Decomposition accuracy */ | ||
| decompositionAccuracy: number; | ||
| /** Synthesis quality */ | ||
| synthesisQuality: number; | ||
| /** Routing accuracy */ | ||
| routingAccuracy: number; | ||
| /** Hard negative accuracy */ | ||
| hardNegativeAccuracy: number; | ||
| /** Average latency in ms */ | ||
| avgLatencyMs: number; | ||
| /** Total examples evaluated */ | ||
| totalExamples: number; | ||
| /** Per-agent accuracy */ | ||
| perAgentAccuracy: Record<string, number>; | ||
| } | ||
| /** | ||
| * Default RLM training configuration | ||
| */ | ||
| export declare const DEFAULT_RLM_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Fast training configuration | ||
| */ | ||
| export declare const FAST_RLM_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Thorough training configuration | ||
| */ | ||
| export declare const THOROUGH_RLM_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Routing-focused training configuration | ||
| */ | ||
| export declare const ROUTING_FOCUSED_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Agent types with descriptions and keywords | ||
| */ | ||
| export declare const AGENT_DEFINITIONS: Record<string, { | ||
| description: string; | ||
| keywords: string[]; | ||
| }>; | ||
| /** | ||
| * Hard negative pairs (confusable agent combinations) | ||
| */ | ||
| export declare const HARD_NEGATIVE_PAIRS: [string, string][]; | ||
| /** | ||
| * RLM Trainer for RuvLTRA models | ||
| * | ||
| * Provides training capabilities for decomposition, synthesis, and routing tasks. | ||
| */ | ||
| export declare class RlmTrainer { | ||
| private config; | ||
| private currentEpoch; | ||
| private currentStep; | ||
| private bestValLoss; | ||
| private patienceCounter; | ||
| private lossHistory; | ||
| private valLossHistory; | ||
| /** | ||
| * Create a new RLM trainer | ||
| */ | ||
| constructor(config?: Partial<RlmTrainingConfig>); | ||
| /** | ||
| * Train on decomposition task | ||
| * | ||
| * Learns to break complex queries into manageable sub-queries. | ||
| */ | ||
| trainDecomposition(dataset: RlmTrainingExample[]): Promise<TrainingResult>; | ||
| /** | ||
| * Train on synthesis task | ||
| * | ||
| * Learns to combine sub-answers into coherent final responses. | ||
| */ | ||
| trainSynthesis(dataset: RlmTrainingExample[]): Promise<TrainingResult>; | ||
| /** | ||
| * Contrastive fine-tuning for agent routing | ||
| * | ||
| * Uses triplet loss and InfoNCE to improve routing accuracy. | ||
| */ | ||
| trainContrastive(pairs: ContrastivePair[]): Promise<TrainingResult>; | ||
| /** | ||
| * Evaluate trained model on test set | ||
| */ | ||
| evaluate(testSet: RlmTrainingExample[]): Promise<EvaluationResult>; | ||
| /** | ||
| * Generate contrastive pairs from dataset | ||
| */ | ||
| generateContrastivePairs(dataset: RlmTrainingExample[], hardNegativeRatio?: number): ContrastivePair[]; | ||
| private resetState; | ||
| private splitDataset; | ||
| private splitPairs; | ||
| private createBatches; | ||
| private createPairBatches; | ||
| private shuffle; | ||
| private trainDecompositionBatch; | ||
| private trainSynthesisBatch; | ||
| private trainContrastiveBatch; | ||
| private validateDecomposition; | ||
| private validateSynthesis; | ||
| private validateContrastive; | ||
| private computeTripletLoss; | ||
| private computeInfoNCELoss; | ||
| private agentDistance; | ||
| private predictAgent; | ||
| private isHardNegative; | ||
| private findBestEpoch; | ||
| } | ||
| /** | ||
| * Create an RLM trainer with default configuration | ||
| */ | ||
| export declare function createRlmTrainer(config?: Partial<RlmTrainingConfig>): RlmTrainer; | ||
| /** | ||
| * Create an empty RLM training example | ||
| */ | ||
| export declare function createEmptyExample(query: string): RlmTrainingExample; | ||
| /** | ||
| * Create a sub-query | ||
| */ | ||
| export declare function createSubQuery(id: number, query: string, options?: Partial<SubQuery>): SubQuery; | ||
| /** | ||
| * Create a sub-answer | ||
| */ | ||
| export declare function createSubAnswer(subQueryId: number, content: string, agent: string, options?: Partial<SubAnswer>): SubAnswer; | ||
| export default RlmTrainer; | ||
| //# sourceMappingURL=training.d.ts.map |
| {"version":3,"file":"training.d.ts","sourceRoot":"","sources":["../../../src/rlm/training.ts"],"names":[],"mappings":"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"} |
Sorry, the diff of this file is too big to display
| /** | ||
| * RLM (Retrieval Language Model) Type Definitions | ||
| * | ||
| * Types for the recursive retrieval-augmented generation system | ||
| * that breaks down complex queries into sub-queries and synthesizes | ||
| * answers from retrieved memory spans. | ||
| */ | ||
| /** | ||
| * Configuration for the RLM controller | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const config: RlmConfig = { | ||
| * maxDepth: 3, | ||
| * maxSubQueries: 5, | ||
| * tokenBudget: 4096, | ||
| * enableCache: true, | ||
| * cacheTtl: 300000, // 5 minutes | ||
| * retrievalTopK: 10, | ||
| * minQualityScore: 0.7, | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export interface RlmConfig { | ||
| /** Maximum recursion depth for sub-queries (default: 3) */ | ||
| maxDepth?: number; | ||
| /** Maximum number of sub-queries per level (default: 5) */ | ||
| maxSubQueries?: number; | ||
| /** Token budget for generation (default: 4096) */ | ||
| tokenBudget?: number; | ||
| /** Enable response caching (default: true) */ | ||
| enableCache?: boolean; | ||
| /** Cache TTL in milliseconds (default: 300000 = 5 minutes) */ | ||
| cacheTtl?: number; | ||
| /** Number of memory spans to retrieve (default: 10) */ | ||
| retrievalTopK?: number; | ||
| /** Minimum quality score to accept answer (default: 0.7) */ | ||
| minQualityScore?: number; | ||
| /** Enable self-reflection loop (default: false) */ | ||
| enableReflection?: boolean; | ||
| /** Maximum reflection iterations (default: 2) */ | ||
| maxReflectionIterations?: number; | ||
| } | ||
| /** | ||
| * Answer produced by the RLM controller | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const answer: RlmAnswer = { | ||
| * text: 'Machine learning is a subset of artificial intelligence...', | ||
| * confidence: 0.92, | ||
| * qualityScore: 0.88, | ||
| * sources: [ | ||
| * { id: 'mem-1', text: 'ML definition from textbook', similarityScore: 0.95, metadata: {} }, | ||
| * ], | ||
| * subQueries: [ | ||
| * { query: 'What is artificial intelligence?', answer: 'AI is...', depth: 1 }, | ||
| * ], | ||
| * tokenUsage: { prompt: 512, completion: 256, total: 768 }, | ||
| * cached: false, | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export interface RlmAnswer { | ||
| /** The generated answer text */ | ||
| text: string; | ||
| /** Overall confidence in the answer (0.0 - 1.0) */ | ||
| confidence: number; | ||
| /** Quality score based on source coverage and coherence (0.0 - 1.0) */ | ||
| qualityScore: number; | ||
| /** Memory spans used to generate the answer */ | ||
| sources: MemorySpan[]; | ||
| /** Sub-queries generated and answered (if recursive) */ | ||
| subQueries?: SubQuery[]; | ||
| /** Token usage statistics */ | ||
| tokenUsage: TokenUsage; | ||
| /** Whether this answer was served from cache */ | ||
| cached: boolean; | ||
| } | ||
| /** | ||
| * A span of memory retrieved for context | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const span: MemorySpan = { | ||
| * id: 'mem-abc123', | ||
| * text: 'Relevant context from memory...', | ||
| * similarityScore: 0.89, | ||
| * source: 'documentation', | ||
| * metadata: { timestamp: Date.now(), category: 'technical' }, | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export interface MemorySpan { | ||
| /** Unique identifier for the memory span */ | ||
| id: string; | ||
| /** The text content of the memory span */ | ||
| text: string; | ||
| /** Cosine similarity score to the query (0.0 - 1.0) */ | ||
| similarityScore: number; | ||
| /** Optional source identifier (e.g., document name, URL) */ | ||
| source?: string; | ||
| /** Additional metadata associated with this span */ | ||
| metadata: Record<string, unknown>; | ||
| } | ||
| /** | ||
| * A sub-query generated during recursive retrieval | ||
| */ | ||
| export interface SubQuery { | ||
| /** The generated sub-query text */ | ||
| query: string; | ||
| /** The answer to the sub-query */ | ||
| answer: string; | ||
| /** Recursion depth at which this sub-query was generated */ | ||
| depth: number; | ||
| } | ||
| /** | ||
| * Token usage statistics for a query | ||
| */ | ||
| export interface TokenUsage { | ||
| /** Tokens used in the prompt (including context) */ | ||
| prompt: number; | ||
| /** Tokens generated in the completion */ | ||
| completion: number; | ||
| /** Total tokens used (prompt + completion) */ | ||
| total: number; | ||
| } | ||
| /** | ||
| * Streaming token event | ||
| * | ||
| * Discriminated union for streaming responses: | ||
| * - `type: 'token'` - A partial token was generated | ||
| * - `type: 'done'` - Generation complete with final answer | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * for await (const event of controller.queryStream('What is AI?')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nFinal answer:', event.answer.text); | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| export type StreamToken = { | ||
| /** Token event type */ | ||
| type: 'token'; | ||
| /** The partial text token */ | ||
| text: string; | ||
| /** Always false for token events */ | ||
| done: false; | ||
| } | { | ||
| /** Done event type */ | ||
| type: 'done'; | ||
| /** The complete answer */ | ||
| answer: RlmAnswer; | ||
| /** Always true for done events */ | ||
| done: true; | ||
| }; | ||
| /** | ||
| * Internal cache entry for RLM answers | ||
| */ | ||
| export interface RlmCacheEntry { | ||
| /** The cached answer */ | ||
| answer: RlmAnswer; | ||
| /** Timestamp when the entry was cached */ | ||
| timestamp: number; | ||
| /** Query hash for cache key */ | ||
| queryHash: string; | ||
| } | ||
| /** | ||
| * Reflection result from self-evaluation loop | ||
| */ | ||
| export interface ReflectionResult { | ||
| /** Whether the answer passed reflection criteria */ | ||
| passed: boolean; | ||
| /** Critique of the current answer */ | ||
| critique?: string; | ||
| /** Suggested improvements */ | ||
| suggestions?: string[]; | ||
| /** Updated quality score after reflection */ | ||
| updatedScore: number; | ||
| /** Number of reflection iterations performed */ | ||
| iterations: number; | ||
| } | ||
| //# sourceMappingURL=types.d.ts.map |
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/rlm/types.ts"],"names":[],"mappings":"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"} |
| "use strict"; | ||
| /** | ||
| * RLM (Retrieval Language Model) Type Definitions | ||
| * | ||
| * Types for the recursive retrieval-augmented generation system | ||
| * that breaks down complex queries into sub-queries and synthesizes | ||
| * answers from retrieved memory spans. | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcmxtL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7O0dBTUciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJMTSAoUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsKSBUeXBlIERlZmluaXRpb25zXG4gKlxuICogVHlwZXMgZm9yIHRoZSByZWN1cnNpdmUgcmV0cmlldmFsLWF1Z21lbnRlZCBnZW5lcmF0aW9uIHN5c3RlbVxuICogdGhhdCBicmVha3MgZG93biBjb21wbGV4IHF1ZXJpZXMgaW50byBzdWItcXVlcmllcyBhbmQgc3ludGhlc2l6ZXNcbiAqIGFuc3dlcnMgZnJvbSByZXRyaWV2ZWQgbWVtb3J5IHNwYW5zLlxuICovXG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIFJMTSBjb250cm9sbGVyXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNvbmZpZzogUmxtQ29uZmlnID0ge1xuICogICBtYXhEZXB0aDogMyxcbiAqICAgbWF4U3ViUXVlcmllczogNSxcbiAqICAgdG9rZW5CdWRnZXQ6IDQwOTYsXG4gKiAgIGVuYWJsZUNhY2hlOiB0cnVlLFxuICogICBjYWNoZVR0bDogMzAwMDAwLCAvLyA1IG1pbnV0ZXNcbiAqICAgcmV0cmlldmFsVG9wSzogMTAsXG4gKiAgIG1pblF1YWxpdHlTY29yZTogMC43LFxuICogICBlbmFibGVSZWZsZWN0aW9uOiB0cnVlLFxuICogICBtYXhSZWZsZWN0aW9uSXRlcmF0aW9uczogMixcbiAqIH07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSbG1Db25maWcge1xuICAvKiogTWF4aW11bSByZWN1cnNpb24gZGVwdGggZm9yIHN1Yi1xdWVyaWVzIChkZWZhdWx0OiAzKSAqL1xuICBtYXhEZXB0aD86IG51bWJlcjtcblxuICAvKiogTWF4aW11bSBudW1iZXIgb2Ygc3ViLXF1ZXJpZXMgcGVyIGxldmVsIChkZWZhdWx0OiA1KSAqL1xuICBtYXhTdWJRdWVyaWVzPzogbnVtYmVyO1xuXG4gIC8qKiBUb2tlbiBidWRnZXQgZm9yIGdlbmVyYXRpb24gKGRlZmF1bHQ6IDQwOTYpICovXG4gIHRva2VuQnVkZ2V0PzogbnVtYmVyO1xuXG4gIC8qKiBFbmFibGUgcmVzcG9uc2UgY2FjaGluZyAoZGVmYXVsdDogdHJ1ZSkgKi9cbiAgZW5hYmxlQ2FjaGU/OiBib29sZWFuO1xuXG4gIC8qKiBDYWNoZSBUVEwgaW4gbWlsbGlzZWNvbmRzIChkZWZhdWx0OiAzMDAwMDAgPSA1IG1pbnV0ZXMpICovXG4gIGNhY2hlVHRsPzogbnVtYmVyO1xuXG4gIC8qKiBOdW1iZXIgb2YgbWVtb3J5IHNwYW5zIHRvIHJldHJpZXZlIChkZWZhdWx0OiAxMCkgKi9cbiAgcmV0cmlldmFsVG9wSz86IG51bWJlcjtcblxuICAvKiogTWluaW11bSBxdWFsaXR5IHNjb3JlIHRvIGFjY2VwdCBhbnN3ZXIgKGRlZmF1bHQ6IDAuNykgKi9cbiAgbWluUXVhbGl0eVNjb3JlPzogbnVtYmVyO1xuXG4gIC8qKiBFbmFibGUgc2VsZi1yZWZsZWN0aW9uIGxvb3AgKGRlZmF1bHQ6IGZhbHNlKSAqL1xuICBlbmFibGVSZWZsZWN0aW9uPzogYm9vbGVhbjtcblxuICAvKiogTWF4aW11bSByZWZsZWN0aW9uIGl0ZXJhdGlvbnMgKGRlZmF1bHQ6IDIpICovXG4gIG1heFJlZmxlY3Rpb25JdGVyYXRpb25zPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEFuc3dlciBwcm9kdWNlZCBieSB0aGUgUkxNIGNvbnRyb2xsZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgYW5zd2VyOiBSbG1BbnN3ZXIgPSB7XG4gKiAgIHRleHQ6ICdNYWNoaW5lIGxlYXJuaW5nIGlzIGEgc3Vic2V0IG9mIGFydGlmaWNpYWwgaW50ZWxsaWdlbmNlLi4uJyxcbiAqICAgY29uZmlkZW5jZTogMC45MixcbiAqICAgcXVhbGl0eVNjb3JlOiAwLjg4LFxuICogICBzb3VyY2VzOiBbXG4gKiAgICAgeyBpZDogJ21lbS0xJywgdGV4dDogJ01MIGRlZmluaXRpb24gZnJvbSB0ZXh0Ym9vaycsIHNpbWlsYXJpdHlTY29yZTogMC45NSwgbWV0YWRhdGE6IHt9IH0sXG4gKiAgIF0sXG4gKiAgIHN1YlF1ZXJpZXM6IFtcbiAqICAgICB7IHF1ZXJ5OiAnV2hhdCBpcyBhcnRpZmljaWFsIGludGVsbGlnZW5jZT8nLCBhbnN3ZXI6ICdBSSBpcy4uLicsIGRlcHRoOiAxIH0sXG4gKiAgIF0sXG4gKiAgIHRva2VuVXNhZ2U6IHsgcHJvbXB0OiA1MTIsIGNvbXBsZXRpb246IDI1NiwgdG90YWw6IDc2OCB9LFxuICogICBjYWNoZWQ6IGZhbHNlLFxuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJsbUFuc3dlciB7XG4gIC8qKiBUaGUgZ2VuZXJhdGVkIGFuc3dlciB0ZXh0ICovXG4gIHRleHQ6IHN0cmluZztcblxuICAvKiogT3ZlcmFsbCBjb25maWRlbmNlIGluIHRoZSBhbnN3ZXIgKDAuMCAtIDEuMCkgKi9cbiAgY29uZmlkZW5jZTogbnVtYmVyO1xuXG4gIC8qKiBRdWFsaXR5IHNjb3JlIGJhc2VkIG9uIHNvdXJjZSBjb3ZlcmFnZSBhbmQgY29oZXJlbmNlICgwLjAgLSAxLjApICovXG4gIHF1YWxpdHlTY29yZTogbnVtYmVyO1xuXG4gIC8qKiBNZW1vcnkgc3BhbnMgdXNlZCB0byBnZW5lcmF0ZSB0aGUgYW5zd2VyICovXG4gIHNvdXJjZXM6IE1lbW9yeVNwYW5bXTtcblxuICAvKiogU3ViLXF1ZXJpZXMgZ2VuZXJhdGVkIGFuZCBhbnN3ZXJlZCAoaWYgcmVjdXJzaXZlKSAqL1xuICBzdWJRdWVyaWVzPzogU3ViUXVlcnlbXTtcblxuICAvKiogVG9rZW4gdXNhZ2Ugc3RhdGlzdGljcyAqL1xuICB0b2tlblVzYWdlOiBUb2tlblVzYWdlO1xuXG4gIC8qKiBXaGV0aGVyIHRoaXMgYW5zd2VyIHdhcyBzZXJ2ZWQgZnJvbSBjYWNoZSAqL1xuICBjYWNoZWQ6IGJvb2xlYW47XG59XG5cbi8qKlxuICogQSBzcGFuIG9mIG1lbW9yeSByZXRyaWV2ZWQgZm9yIGNvbnRleHRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc3BhbjogTWVtb3J5U3BhbiA9IHtcbiAqICAgaWQ6ICdtZW0tYWJjMTIzJyxcbiAqICAgdGV4dDogJ1JlbGV2YW50IGNvbnRleHQgZnJvbSBtZW1vcnkuLi4nLFxuICogICBzaW1pbGFyaXR5U2NvcmU6IDAuODksXG4gKiAgIHNvdXJjZTogJ2RvY3VtZW50YXRpb24nLFxuICogICBtZXRhZGF0YTogeyB0aW1lc3RhbXA6IERhdGUubm93KCksIGNhdGVnb3J5OiAndGVjaG5pY2FsJyB9LFxuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lbW9yeVNwYW4ge1xuICAvKiogVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBtZW1vcnkgc3BhbiAqL1xuICBpZDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgdGV4dCBjb250ZW50IG9mIHRoZSBtZW1vcnkgc3BhbiAqL1xuICB0ZXh0OiBzdHJpbmc7XG5cbiAgLyoqIENvc2luZSBzaW1pbGFyaXR5IHNjb3JlIHRvIHRoZSBxdWVyeSAoMC4wIC0gMS4wKSAqL1xuICBzaW1pbGFyaXR5U2NvcmU6IG51bWJlcjtcblxuICAvKiogT3B0aW9uYWwgc291cmNlIGlkZW50aWZpZXIgKGUuZy4sIGRvY3VtZW50IG5hbWUsIFVSTCkgKi9cbiAgc291cmNlPzogc3RyaW5nO1xuXG4gIC8qKiBBZGRpdGlvbmFsIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHNwYW4gKi9cbiAgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG4vKipcbiAqIEEgc3ViLXF1ZXJ5IGdlbmVyYXRlZCBkdXJpbmcgcmVjdXJzaXZlIHJldHJpZXZhbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN1YlF1ZXJ5IHtcbiAgLyoqIFRoZSBnZW5lcmF0ZWQgc3ViLXF1ZXJ5IHRleHQgKi9cbiAgcXVlcnk6IHN0cmluZztcblxuICAvKiogVGhlIGFuc3dlciB0byB0aGUgc3ViLXF1ZXJ5ICovXG4gIGFuc3dlcjogc3RyaW5nO1xuXG4gIC8qKiBSZWN1cnNpb24gZGVwdGggYXQgd2hpY2ggdGhpcyBzdWItcXVlcnkgd2FzIGdlbmVyYXRlZCAqL1xuICBkZXB0aDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRva2VuIHVzYWdlIHN0YXRpc3RpY3MgZm9yIGEgcXVlcnlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUb2tlblVzYWdlIHtcbiAgLyoqIFRva2VucyB1c2VkIGluIHRoZSBwcm9tcHQgKGluY2x1ZGluZyBjb250ZXh0KSAqL1xuICBwcm9tcHQ6IG51bWJlcjtcblxuICAvKiogVG9rZW5zIGdlbmVyYXRlZCBpbiB0aGUgY29tcGxldGlvbiAqL1xuICBjb21wbGV0aW9uOiBudW1iZXI7XG5cbiAgLyoqIFRvdGFsIHRva2VucyB1c2VkIChwcm9tcHQgKyBjb21wbGV0aW9uKSAqL1xuICB0b3RhbDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFN0cmVhbWluZyB0b2tlbiBldmVudFxuICpcbiAqIERpc2NyaW1pbmF0ZWQgdW5pb24gZm9yIHN0cmVhbWluZyByZXNwb25zZXM6XG4gKiAtIGB0eXBlOiAndG9rZW4nYCAtIEEgcGFydGlhbCB0b2tlbiB3YXMgZ2VuZXJhdGVkXG4gKiAtIGB0eXBlOiAnZG9uZSdgIC0gR2VuZXJhdGlvbiBjb21wbGV0ZSB3aXRoIGZpbmFsIGFuc3dlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBmb3IgYXdhaXQgKGNvbnN0IGV2ZW50IG9mIGNvbnRyb2xsZXIucXVlcnlTdHJlYW0oJ1doYXQgaXMgQUk/JykpIHtcbiAqICAgaWYgKGV2ZW50LnR5cGUgPT09ICd0b2tlbicpIHtcbiAqICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShldmVudC50ZXh0KTtcbiAqICAgfSBlbHNlIHtcbiAqICAgICBjb25zb2xlLmxvZygnXFxuXFxuRmluYWwgYW5zd2VyOicsIGV2ZW50LmFuc3dlci50ZXh0KTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCB0eXBlIFN0cmVhbVRva2VuID1cbiAgfCB7XG4gICAgICAvKiogVG9rZW4gZXZlbnQgdHlwZSAqL1xuICAgICAgdHlwZTogJ3Rva2VuJztcbiAgICAgIC8qKiBUaGUgcGFydGlhbCB0ZXh0IHRva2VuICovXG4gICAgICB0ZXh0OiBzdHJpbmc7XG4gICAgICAvKiogQWx3YXlzIGZhbHNlIGZvciB0b2tlbiBldmVudHMgKi9cbiAgICAgIGRvbmU6IGZhbHNlO1xuICAgIH1cbiAgfCB7XG4gICAgICAvKiogRG9uZSBldmVudCB0eXBlICovXG4gICAgICB0eXBlOiAnZG9uZSc7XG4gICAgICAvKiogVGhlIGNvbXBsZXRlIGFuc3dlciAqL1xuICAgICAgYW5zd2VyOiBSbG1BbnN3ZXI7XG4gICAgICAvKiogQWx3YXlzIHRydWUgZm9yIGRvbmUgZXZlbnRzICovXG4gICAgICBkb25lOiB0cnVlO1xuICAgIH07XG5cbi8qKlxuICogSW50ZXJuYWwgY2FjaGUgZW50cnkgZm9yIFJMTSBhbnN3ZXJzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmxtQ2FjaGVFbnRyeSB7XG4gIC8qKiBUaGUgY2FjaGVkIGFuc3dlciAqL1xuICBhbnN3ZXI6IFJsbUFuc3dlcjtcblxuICAvKiogVGltZXN0YW1wIHdoZW4gdGhlIGVudHJ5IHdhcyBjYWNoZWQgKi9cbiAgdGltZXN0YW1wOiBudW1iZXI7XG5cbiAgLyoqIFF1ZXJ5IGhhc2ggZm9yIGNhY2hlIGtleSAqL1xuICBxdWVyeUhhc2g6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZWZsZWN0aW9uIHJlc3VsdCBmcm9tIHNlbGYtZXZhbHVhdGlvbiBsb29wXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVmbGVjdGlvblJlc3VsdCB7XG4gIC8qKiBXaGV0aGVyIHRoZSBhbnN3ZXIgcGFzc2VkIHJlZmxlY3Rpb24gY3JpdGVyaWEgKi9cbiAgcGFzc2VkOiBib29sZWFuO1xuXG4gIC8qKiBDcml0aXF1ZSBvZiB0aGUgY3VycmVudCBhbnN3ZXIgKi9cbiAgY3JpdGlxdWU/OiBzdHJpbmc7XG5cbiAgLyoqIFN1Z2dlc3RlZCBpbXByb3ZlbWVudHMgKi9cbiAgc3VnZ2VzdGlvbnM/OiBzdHJpbmdbXTtcblxuICAvKiogVXBkYXRlZCBxdWFsaXR5IHNjb3JlIGFmdGVyIHJlZmxlY3Rpb24gKi9cbiAgdXBkYXRlZFNjb3JlOiBudW1iZXI7XG5cbiAgLyoqIE51bWJlciBvZiByZWZsZWN0aW9uIGl0ZXJhdGlvbnMgcGVyZm9ybWVkICovXG4gIGl0ZXJhdGlvbnM6IG51bWJlcjtcbn1cbiJdfQ== |
| /** | ||
| * RLM Controller - Recursive Retrieval Language Model | ||
| * | ||
| * Implements a recursive retrieval-augmented generation system that: | ||
| * 1. Breaks down complex queries into sub-queries | ||
| * 2. Retrieves relevant memory spans for each query | ||
| * 3. Synthesizes coherent answers from retrieved context | ||
| * 4. Optionally reflects on and refines answers | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * retrievalTopK: 10, | ||
| * enableCache: true, | ||
| * }); | ||
| * | ||
| * // Add knowledge to memory | ||
| * await rlm.addMemory('Machine learning is a subset of AI that enables systems to learn from data.'); | ||
| * await rlm.addMemory('Deep learning uses neural networks with many layers.'); | ||
| * | ||
| * // Query with recursive retrieval | ||
| * const answer = await rlm.query('Explain the relationship between ML and deep learning'); | ||
| * console.log(answer.text); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('What is AI?')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nDone! Quality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * const answer = await rlm.query('Complex multi-part question...'); | ||
| * // Answer will be iteratively refined until quality >= 0.8 | ||
| * ``` | ||
| */ | ||
| import { RlmConfig, RlmAnswer, MemorySpan, StreamToken } from './types'; | ||
| import { RuvLLM } from '../engine'; | ||
| /** | ||
| * RlmController - Recursive Retrieval Language Model Controller | ||
| * | ||
| * Orchestrates retrieval-augmented generation with recursive sub-query | ||
| * decomposition, memory search, and optional self-reflection. | ||
| */ | ||
| export declare class RlmController { | ||
| private config; | ||
| private cache; | ||
| private engine; | ||
| private memoryIdCounter; | ||
| /** | ||
| * Create a new RLM controller | ||
| * | ||
| * @param config - Configuration options | ||
| * @param engine - Optional RuvLLM engine instance (creates new if not provided) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // With default config | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * // With custom config | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 5, | ||
| * enableReflection: true, | ||
| * }); | ||
| * | ||
| * // With existing engine | ||
| * const engine = new RuvLLM({ learningEnabled: true }); | ||
| * const rlm = new RlmController({}, engine); | ||
| * ``` | ||
| */ | ||
| constructor(config?: RlmConfig, engine?: RuvLLM); | ||
| /** | ||
| * Query the RLM with recursive retrieval | ||
| * | ||
| * @param input - The query string | ||
| * @returns Promise resolving to the answer with sources and metadata | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const answer = await rlm.query('What is the capital of France?'); | ||
| * console.log(answer.text); // "The capital of France is Paris..." | ||
| * console.log(answer.confidence); // 0.95 | ||
| * console.log(answer.sources); // [{ id: '...', text: '...', similarityScore: 0.92 }] | ||
| * ``` | ||
| */ | ||
| query(input: string): Promise<RlmAnswer>; | ||
| /** | ||
| * Query with streaming response | ||
| * | ||
| * @param input - The query string | ||
| * @yields StreamToken events (either partial tokens or final answer) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * for await (const event of rlm.queryStream('Explain quantum computing')) { | ||
| * if (event.type === 'token') { | ||
| * // Partial token received | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * // Generation complete | ||
| * console.log('\n\nSources:', event.answer.sources.length); | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| queryStream(input: string): AsyncGenerator<StreamToken>; | ||
| /** | ||
| * Add content to memory for retrieval | ||
| * | ||
| * @param text - The text content to store | ||
| * @param metadata - Optional metadata to associate with the memory | ||
| * @returns Promise resolving to the memory span ID | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const id1 = await rlm.addMemory( | ||
| * 'TypeScript is a typed superset of JavaScript.', | ||
| * { source: 'documentation', category: 'programming' } | ||
| * ); | ||
| * | ||
| * const id2 = await rlm.addMemory( | ||
| * 'React is a JavaScript library for building UIs.' | ||
| * ); | ||
| * ``` | ||
| */ | ||
| addMemory(text: string, metadata?: Record<string, unknown>): Promise<string>; | ||
| /** | ||
| * Search memory for relevant spans | ||
| * | ||
| * @param query - The search query | ||
| * @param topK - Number of results to return (default: config.retrievalTopK) | ||
| * @returns Promise resolving to array of memory spans | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const spans = await rlm.searchMemory('JavaScript frameworks', 5); | ||
| * for (const span of spans) { | ||
| * console.log(`[${span.similarityScore.toFixed(2)}] ${span.text}`); | ||
| * } | ||
| * ``` | ||
| */ | ||
| searchMemory(query: string, topK?: number): Promise<MemorySpan[]>; | ||
| /** | ||
| * Clear the response cache | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * rlm.clearCache(); | ||
| * console.log('Cache cleared'); | ||
| * ``` | ||
| */ | ||
| clearCache(): void; | ||
| /** | ||
| * Get current cache statistics | ||
| * | ||
| * @returns Object with cache size and hit rate info | ||
| */ | ||
| getCacheStats(): { | ||
| size: number; | ||
| entries: number; | ||
| }; | ||
| /** | ||
| * Update configuration at runtime | ||
| * | ||
| * @param config - Partial configuration to merge | ||
| */ | ||
| updateConfig(config: Partial<RlmConfig>): void; | ||
| /** | ||
| * Get current configuration | ||
| */ | ||
| getConfig(): Required<RlmConfig>; | ||
| /** | ||
| * Generate sub-queries for complex questions | ||
| */ | ||
| private generateSubQueries; | ||
| /** | ||
| * Decompose a complex query into simpler parts | ||
| */ | ||
| private decomposeQuery; | ||
| /** | ||
| * Build context string from sources and sub-queries | ||
| */ | ||
| private buildContext; | ||
| /** | ||
| * Build the full prompt with context | ||
| */ | ||
| private buildPrompt; | ||
| /** | ||
| * Get generation config based on RLM settings | ||
| */ | ||
| private getGenerationConfig; | ||
| /** | ||
| * Estimate token usage | ||
| */ | ||
| private estimateTokenUsage; | ||
| /** | ||
| * Calculate quality score based on sources and confidence | ||
| */ | ||
| private calculateQualityScore; | ||
| /** | ||
| * Apply self-reflection to improve answer | ||
| */ | ||
| private applyReflection; | ||
| /** | ||
| * Get cached answer if valid | ||
| */ | ||
| private getCached; | ||
| /** | ||
| * Set cache entry | ||
| */ | ||
| private setCache; | ||
| /** | ||
| * Simple hash function for cache keys | ||
| */ | ||
| private hashQuery; | ||
| /** | ||
| * Prune expired cache entries | ||
| */ | ||
| private pruneCache; | ||
| /** | ||
| * Utility delay function for streaming simulation | ||
| */ | ||
| private delay; | ||
| } | ||
| //# sourceMappingURL=controller.d.ts.map |
| {"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"} |
| /** | ||
| * RLM Controller - Recursive Retrieval Language Model | ||
| * | ||
| * Implements a recursive retrieval-augmented generation system that: | ||
| * 1. Breaks down complex queries into sub-queries | ||
| * 2. Retrieves relevant memory spans for each query | ||
| * 3. Synthesizes coherent answers from retrieved context | ||
| * 4. Optionally reflects on and refines answers | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * retrievalTopK: 10, | ||
| * enableCache: true, | ||
| * }); | ||
| * | ||
| * // Add knowledge to memory | ||
| * await rlm.addMemory('Machine learning is a subset of AI that enables systems to learn from data.'); | ||
| * await rlm.addMemory('Deep learning uses neural networks with many layers.'); | ||
| * | ||
| * // Query with recursive retrieval | ||
| * const answer = await rlm.query('Explain the relationship between ML and deep learning'); | ||
| * console.log(answer.text); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('What is AI?')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nDone! Quality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * const answer = await rlm.query('Complex multi-part question...'); | ||
| * // Answer will be iteratively refined until quality >= 0.8 | ||
| * ``` | ||
| */ | ||
| import { RuvLLM } from '../engine'; | ||
| /** | ||
| * Default configuration values | ||
| */ | ||
| const DEFAULT_CONFIG = { | ||
| maxDepth: 3, | ||
| maxSubQueries: 5, | ||
| tokenBudget: 4096, | ||
| enableCache: true, | ||
| cacheTtl: 300000, // 5 minutes | ||
| retrievalTopK: 10, | ||
| minQualityScore: 0.7, | ||
| enableReflection: false, | ||
| maxReflectionIterations: 2, | ||
| }; | ||
| /** | ||
| * RlmController - Recursive Retrieval Language Model Controller | ||
| * | ||
| * Orchestrates retrieval-augmented generation with recursive sub-query | ||
| * decomposition, memory search, and optional self-reflection. | ||
| */ | ||
| export class RlmController { | ||
| /** | ||
| * Create a new RLM controller | ||
| * | ||
| * @param config - Configuration options | ||
| * @param engine - Optional RuvLLM engine instance (creates new if not provided) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * // With default config | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * // With custom config | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 5, | ||
| * enableReflection: true, | ||
| * }); | ||
| * | ||
| * // With existing engine | ||
| * const engine = new RuvLLM({ learningEnabled: true }); | ||
| * const rlm = new RlmController({}, engine); | ||
| * ``` | ||
| */ | ||
| constructor(config, engine) { | ||
| this.config = { ...DEFAULT_CONFIG, ...config }; | ||
| this.cache = new Map(); | ||
| this.engine = engine ?? new RuvLLM({ learningEnabled: true }); | ||
| this.memoryIdCounter = 0; | ||
| } | ||
| /** | ||
| * Query the RLM with recursive retrieval | ||
| * | ||
| * @param input - The query string | ||
| * @returns Promise resolving to the answer with sources and metadata | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const answer = await rlm.query('What is the capital of France?'); | ||
| * console.log(answer.text); // "The capital of France is Paris..." | ||
| * console.log(answer.confidence); // 0.95 | ||
| * console.log(answer.sources); // [{ id: '...', text: '...', similarityScore: 0.92 }] | ||
| * ``` | ||
| */ | ||
| async query(input) { | ||
| // Check cache first | ||
| if (this.config.enableCache) { | ||
| const cached = this.getCached(input); | ||
| if (cached) { | ||
| return { ...cached, cached: true }; | ||
| } | ||
| } | ||
| // Retrieve relevant memory spans | ||
| const sources = await this.searchMemory(input, this.config.retrievalTopK); | ||
| // Generate sub-queries if needed and depth allows | ||
| const subQueries = await this.generateSubQueries(input, sources, 0); | ||
| // Build context from sources and sub-query answers | ||
| const context = this.buildContext(sources, subQueries); | ||
| // Generate the answer | ||
| const startTime = Date.now(); | ||
| const response = this.engine.query(this.buildPrompt(input, context), this.getGenerationConfig()); | ||
| // Calculate token usage (estimate if not provided by engine) | ||
| const tokenUsage = this.estimateTokenUsage(input, context, response.text); | ||
| // Calculate quality score | ||
| const qualityScore = this.calculateQualityScore(sources, response.confidence); | ||
| let answer = { | ||
| text: response.text, | ||
| confidence: response.confidence, | ||
| qualityScore, | ||
| sources, | ||
| subQueries: subQueries.length > 0 ? subQueries : undefined, | ||
| tokenUsage, | ||
| cached: false, | ||
| }; | ||
| // Apply reflection if enabled and quality is below threshold | ||
| if (this.config.enableReflection && qualityScore < this.config.minQualityScore) { | ||
| answer = await this.applyReflection(input, answer); | ||
| } | ||
| // Cache the result | ||
| if (this.config.enableCache) { | ||
| this.setCache(input, answer); | ||
| } | ||
| return answer; | ||
| } | ||
| /** | ||
| * Query with streaming response | ||
| * | ||
| * @param input - The query string | ||
| * @yields StreamToken events (either partial tokens or final answer) | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * for await (const event of rlm.queryStream('Explain quantum computing')) { | ||
| * if (event.type === 'token') { | ||
| * // Partial token received | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * // Generation complete | ||
| * console.log('\n\nSources:', event.answer.sources.length); | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| async *queryStream(input) { | ||
| // Check cache first | ||
| if (this.config.enableCache) { | ||
| const cached = this.getCached(input); | ||
| if (cached) { | ||
| // Simulate streaming for cached response | ||
| const words = cached.text.split(' '); | ||
| for (const word of words) { | ||
| yield { type: 'token', text: word + ' ', done: false }; | ||
| await this.delay(10); // Small delay for realistic streaming | ||
| } | ||
| yield { type: 'done', answer: { ...cached, cached: true }, done: true }; | ||
| return; | ||
| } | ||
| } | ||
| // Retrieve sources | ||
| const sources = await this.searchMemory(input, this.config.retrievalTopK); | ||
| const subQueries = await this.generateSubQueries(input, sources, 0); | ||
| const context = this.buildContext(sources, subQueries); | ||
| // Generate with simulated streaming | ||
| const prompt = this.buildPrompt(input, context); | ||
| const response = this.engine.query(prompt, this.getGenerationConfig()); | ||
| // Stream the response word by word | ||
| const words = response.text.split(' '); | ||
| let streamedText = ''; | ||
| for (let i = 0; i < words.length; i++) { | ||
| const word = words[i]; | ||
| const text = i < words.length - 1 ? word + ' ' : word; | ||
| streamedText += text; | ||
| yield { type: 'token', text, done: false }; | ||
| await this.delay(20); // Simulate generation latency | ||
| } | ||
| const tokenUsage = this.estimateTokenUsage(input, context, streamedText); | ||
| const qualityScore = this.calculateQualityScore(sources, response.confidence); | ||
| const answer = { | ||
| text: streamedText, | ||
| confidence: response.confidence, | ||
| qualityScore, | ||
| sources, | ||
| subQueries: subQueries.length > 0 ? subQueries : undefined, | ||
| tokenUsage, | ||
| cached: false, | ||
| }; | ||
| // Cache the result | ||
| if (this.config.enableCache) { | ||
| this.setCache(input, answer); | ||
| } | ||
| yield { type: 'done', answer, done: true }; | ||
| } | ||
| /** | ||
| * Add content to memory for retrieval | ||
| * | ||
| * @param text - The text content to store | ||
| * @param metadata - Optional metadata to associate with the memory | ||
| * @returns Promise resolving to the memory span ID | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const id1 = await rlm.addMemory( | ||
| * 'TypeScript is a typed superset of JavaScript.', | ||
| * { source: 'documentation', category: 'programming' } | ||
| * ); | ||
| * | ||
| * const id2 = await rlm.addMemory( | ||
| * 'React is a JavaScript library for building UIs.' | ||
| * ); | ||
| * ``` | ||
| */ | ||
| async addMemory(text, metadata) { | ||
| const nodeId = this.engine.addMemory(text, metadata); | ||
| const id = `rlm-mem-${this.memoryIdCounter++}-${nodeId}`; | ||
| return id; | ||
| } | ||
| /** | ||
| * Search memory for relevant spans | ||
| * | ||
| * @param query - The search query | ||
| * @param topK - Number of results to return (default: config.retrievalTopK) | ||
| * @returns Promise resolving to array of memory spans | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const spans = await rlm.searchMemory('JavaScript frameworks', 5); | ||
| * for (const span of spans) { | ||
| * console.log(`[${span.similarityScore.toFixed(2)}] ${span.text}`); | ||
| * } | ||
| * ``` | ||
| */ | ||
| async searchMemory(query, topK) { | ||
| const k = topK ?? this.config.retrievalTopK; | ||
| const results = this.engine.searchMemory(query, k); | ||
| return results.map((result, index) => ({ | ||
| id: `rlm-span-${result.id}-${index}`, | ||
| text: result.content, | ||
| similarityScore: result.score, | ||
| source: result.metadata?.source, | ||
| metadata: result.metadata, | ||
| })); | ||
| } | ||
| /** | ||
| * Clear the response cache | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * rlm.clearCache(); | ||
| * console.log('Cache cleared'); | ||
| * ``` | ||
| */ | ||
| clearCache() { | ||
| this.cache.clear(); | ||
| } | ||
| /** | ||
| * Get current cache statistics | ||
| * | ||
| * @returns Object with cache size and hit rate info | ||
| */ | ||
| getCacheStats() { | ||
| return { | ||
| size: this.cache.size, | ||
| entries: this.cache.size, | ||
| }; | ||
| } | ||
| /** | ||
| * Update configuration at runtime | ||
| * | ||
| * @param config - Partial configuration to merge | ||
| */ | ||
| updateConfig(config) { | ||
| this.config = { ...this.config, ...config }; | ||
| } | ||
| /** | ||
| * Get current configuration | ||
| */ | ||
| getConfig() { | ||
| return { ...this.config }; | ||
| } | ||
| // ============================================ | ||
| // Private Methods | ||
| // ============================================ | ||
| /** | ||
| * Generate sub-queries for complex questions | ||
| */ | ||
| async generateSubQueries(query, sources, depth) { | ||
| if (depth >= this.config.maxDepth) { | ||
| return []; | ||
| } | ||
| // Simple heuristic: generate sub-queries for questions with multiple parts | ||
| const subQueries = []; | ||
| const parts = this.decomposeQuery(query); | ||
| for (const part of parts.slice(0, this.config.maxSubQueries)) { | ||
| if (part.trim().length < 10) | ||
| continue; | ||
| // Search for sub-query specific sources | ||
| const subSources = await this.searchMemory(part, Math.ceil(this.config.retrievalTopK / 2)); | ||
| const context = this.buildContext(subSources, []); | ||
| const response = this.engine.query(this.buildPrompt(part, context), { ...this.getGenerationConfig(), maxTokens: 256 }); | ||
| subQueries.push({ | ||
| query: part, | ||
| answer: response.text, | ||
| depth: depth + 1, | ||
| }); | ||
| } | ||
| return subQueries; | ||
| } | ||
| /** | ||
| * Decompose a complex query into simpler parts | ||
| */ | ||
| decomposeQuery(query) { | ||
| // Split on common conjunctions and question markers | ||
| const parts = []; | ||
| // Check for multi-part questions | ||
| const conjunctions = [' and ', ' or ', '. ', '? ', '; ']; | ||
| let current = query; | ||
| for (const conj of conjunctions) { | ||
| if (current.includes(conj)) { | ||
| const split = current.split(conj); | ||
| parts.push(...split.filter(p => p.trim().length > 10)); | ||
| current = ''; | ||
| break; | ||
| } | ||
| } | ||
| // If no decomposition happened, return original | ||
| if (parts.length === 0) { | ||
| return [query]; | ||
| } | ||
| return parts; | ||
| } | ||
| /** | ||
| * Build context string from sources and sub-queries | ||
| */ | ||
| buildContext(sources, subQueries) { | ||
| const parts = []; | ||
| // Add sources | ||
| if (sources.length > 0) { | ||
| parts.push('Relevant context:'); | ||
| for (const source of sources) { | ||
| parts.push(`- ${source.text}`); | ||
| } | ||
| } | ||
| // Add sub-query answers | ||
| if (subQueries.length > 0) { | ||
| parts.push('\nRelated information:'); | ||
| for (const sq of subQueries) { | ||
| parts.push(`Q: ${sq.query}`); | ||
| parts.push(`A: ${sq.answer}`); | ||
| } | ||
| } | ||
| return parts.join('\n'); | ||
| } | ||
| /** | ||
| * Build the full prompt with context | ||
| */ | ||
| buildPrompt(query, context) { | ||
| if (context.trim().length === 0) { | ||
| return query; | ||
| } | ||
| return `${context}\n\nBased on the above context, answer the following question:\n${query}`; | ||
| } | ||
| /** | ||
| * Get generation config based on RLM settings | ||
| */ | ||
| getGenerationConfig() { | ||
| return { | ||
| maxTokens: Math.min(this.config.tokenBudget, 2048), | ||
| temperature: 0.7, | ||
| topP: 0.9, | ||
| }; | ||
| } | ||
| /** | ||
| * Estimate token usage | ||
| */ | ||
| estimateTokenUsage(query, context, response) { | ||
| // Rough estimation: ~4 characters per token | ||
| const promptTokens = Math.ceil((query.length + context.length) / 4); | ||
| const completionTokens = Math.ceil(response.length / 4); | ||
| return { | ||
| prompt: promptTokens, | ||
| completion: completionTokens, | ||
| total: promptTokens + completionTokens, | ||
| }; | ||
| } | ||
| /** | ||
| * Calculate quality score based on sources and confidence | ||
| */ | ||
| calculateQualityScore(sources, confidence) { | ||
| if (sources.length === 0) { | ||
| return confidence * 0.5; // Penalize answers without sources | ||
| } | ||
| // Average source similarity | ||
| const avgSimilarity = sources.reduce((sum, s) => sum + s.similarityScore, 0) / sources.length; | ||
| // Weighted combination | ||
| return confidence * 0.6 + avgSimilarity * 0.4; | ||
| } | ||
| /** | ||
| * Apply self-reflection to improve answer | ||
| */ | ||
| async applyReflection(query, answer) { | ||
| let currentAnswer = answer; | ||
| let iterations = 0; | ||
| while (iterations < this.config.maxReflectionIterations && | ||
| currentAnswer.qualityScore < this.config.minQualityScore) { | ||
| iterations++; | ||
| // Generate critique | ||
| const critiquePrompt = `Evaluate this answer for accuracy and completeness: | ||
| Question: ${query} | ||
| Answer: ${currentAnswer.text} | ||
| Provide a brief critique and suggest improvements.`; | ||
| const critiqueResponse = this.engine.query(critiquePrompt, { | ||
| maxTokens: 256, | ||
| temperature: 0.5, | ||
| }); | ||
| // Generate improved answer | ||
| const improvePrompt = `Based on this feedback: "${critiqueResponse.text}" | ||
| Improve this answer: | ||
| Question: ${query} | ||
| Original: ${currentAnswer.text} | ||
| Provide an improved answer:`; | ||
| const improvedResponse = this.engine.query(improvePrompt, this.getGenerationConfig()); | ||
| // Update answer with reflection improvements | ||
| const newQualityScore = Math.min(1.0, currentAnswer.qualityScore + 0.1 * iterations); | ||
| currentAnswer = { | ||
| ...currentAnswer, | ||
| text: improvedResponse.text, | ||
| confidence: Math.max(currentAnswer.confidence, improvedResponse.confidence), | ||
| qualityScore: newQualityScore, | ||
| tokenUsage: { | ||
| prompt: currentAnswer.tokenUsage.prompt + 100, // Approximate additional tokens | ||
| completion: currentAnswer.tokenUsage.completion + 100, | ||
| total: currentAnswer.tokenUsage.total + 200, | ||
| }, | ||
| }; | ||
| } | ||
| return currentAnswer; | ||
| } | ||
| /** | ||
| * Get cached answer if valid | ||
| */ | ||
| getCached(query) { | ||
| const hash = this.hashQuery(query); | ||
| const entry = this.cache.get(hash); | ||
| if (!entry) { | ||
| return null; | ||
| } | ||
| // Check TTL | ||
| if (Date.now() - entry.timestamp > this.config.cacheTtl) { | ||
| this.cache.delete(hash); | ||
| return null; | ||
| } | ||
| return entry.answer; | ||
| } | ||
| /** | ||
| * Set cache entry | ||
| */ | ||
| setCache(query, answer) { | ||
| const hash = this.hashQuery(query); | ||
| this.cache.set(hash, { | ||
| answer, | ||
| timestamp: Date.now(), | ||
| queryHash: hash, | ||
| }); | ||
| // Prune old entries if cache gets too large | ||
| if (this.cache.size > 1000) { | ||
| this.pruneCache(); | ||
| } | ||
| } | ||
| /** | ||
| * Simple hash function for cache keys | ||
| */ | ||
| hashQuery(query) { | ||
| let hash = 0; | ||
| for (let i = 0; i < query.length; i++) { | ||
| const char = query.charCodeAt(i); | ||
| hash = ((hash << 5) - hash) + char; | ||
| hash = hash & hash; // Convert to 32-bit integer | ||
| } | ||
| return `rlm-cache-${hash.toString(16)}`; | ||
| } | ||
| /** | ||
| * Prune expired cache entries | ||
| */ | ||
| pruneCache() { | ||
| const now = Date.now(); | ||
| const toDelete = []; | ||
| for (const [key, entry] of this.cache.entries()) { | ||
| if (now - entry.timestamp > this.config.cacheTtl) { | ||
| toDelete.push(key); | ||
| } | ||
| } | ||
| // Delete oldest entries if still too large | ||
| if (this.cache.size - toDelete.length > 800) { | ||
| const entries = Array.from(this.cache.entries()) | ||
| .sort((a, b) => a[1].timestamp - b[1].timestamp); | ||
| const deleteCount = entries.length - 500; | ||
| for (let i = 0; i < deleteCount; i++) { | ||
| toDelete.push(entries[i][0]); | ||
| } | ||
| } | ||
| for (const key of toDelete) { | ||
| this.cache.delete(key); | ||
| } | ||
| } | ||
| /** | ||
| * Utility delay function for streaming simulation | ||
| */ | ||
| delay(ms) { | ||
| return new Promise(resolve => setTimeout(resolve, ms)); | ||
| } | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ybG0vY29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0RHO0FBYUgsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUduQzs7R0FFRztBQUNILE1BQU0sY0FBYyxHQUF3QjtJQUMxQyxRQUFRLEVBQUUsQ0FBQztJQUNYLGFBQWEsRUFBRSxDQUFDO0lBQ2hCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLFFBQVEsRUFBRSxNQUFNLEVBQUUsWUFBWTtJQUM5QixhQUFhLEVBQUUsRUFBRTtJQUNqQixlQUFlLEVBQUUsR0FBRztJQUNwQixnQkFBZ0IsRUFBRSxLQUFLO0lBQ3ZCLHVCQUF1QixFQUFFLENBQUM7Q0FDM0IsQ0FBQztBQUVGOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUFNeEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFCRztJQUNILFlBQVksTUFBa0IsRUFBRSxNQUFlO1FBQzdDLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxHQUFHLGNBQWMsRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sSUFBSSxJQUFJLE1BQU0sQ0FBQyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFhO1FBQ3ZCLG9CQUFvQjtRQUNwQixJQUFJLElBQUksQ0FBQyxNQUFNLENB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QUcsR0FBRyxFQUFFLENBQUM7WUFDNUMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO2lCQUM3QyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUVuRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztZQUN6QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3JDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0IsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLE1BQU0sR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsRUFBVTtRQUN0QixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUkxNIENvbnRyb2xsZXIgLSBSZWN1cnNpdmUgUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsXG4gKlxuICogSW1wbGVtZW50cyBhIHJlY3Vyc2l2ZSByZXRyaWV2YWwtYXVnbWVudGVkIGdlbmVyYXRpb24gc3lzdGVtIHRoYXQ6XG4gKiAxLiBCcmVha3MgZG93biBjb21wbGV4IHF1ZXJpZXMgaW50byBzdWItcXVlcmllc1xuICogMi4gUmV0cmlldmVzIHJlbGV2YW50IG1lbW9yeSBzcGFucyBmb3IgZWFjaCBxdWVyeVxuICogMy4gU3ludGhlc2l6ZXMgY29oZXJlbnQgYW5zd2VycyBmcm9tIHJldHJpZXZlZCBjb250ZXh0XG4gKiA0LiBPcHRpb25hbGx5IHJlZmxlY3RzIG9uIGFuZCByZWZpbmVzIGFuc3dlcnNcbiAqXG4gKiBAZXhhbXBsZSBCYXNpYyBVc2FnZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKHtcbiAqICAgbWF4RGVwdGg6IDMsXG4gKiAgIHJldHJpZXZhbFRvcEs6IDEwLFxuICogICBlbmFibGVDYWNoZTogdHJ1ZSxcbiAqIH0pO1xuICpcbiAqIC8vIEFkZCBrbm93bGVkZ2UgdG8gbWVtb3J5XG4gKiBhd2FpdCBybG0uYWRkTWVtb3J5KCdNYWNoaW5lIGxlYXJuaW5nIGlzIGEgc3Vic2V0IG9mIEFJIHRoYXQgZW5hYmxlcyBzeXN0ZW1zIHRvIGxlYXJuIGZyb20gZGF0YS4nKTtcbiAqIGF3YWl0IHJsbS5hZGRNZW1vcnkoJ0RlZXAgbGVhcm5pbmcgdXNlcyBuZXVyYWwgbmV0d29ya3Mgd2l0aCBtYW55IGxheWVycy4nKTtcbiAqXG4gKiAvLyBRdWVyeSB3aXRoIHJlY3Vyc2l2ZSByZXRyaWV2YWxcbiAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnRXhwbGFpbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTUwgYW5kIGRlZXAgbGVhcm5pbmcnKTtcbiAqIGNvbnNvbGUubG9nKGFuc3dlci50ZXh0KTtcbiAqIGNvbnNvbGUubG9nKCdTb3VyY2VzOicsIGFuc3dlci5zb3VyY2VzLmxlbmd0aCk7XG4gKiBjb25zb2xlLmxvZygnQ29uZmlkZW5jZTonLCBhbnN3ZXIuY29uZmlkZW5jZSk7XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZSBTdHJlYW1pbmdcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKCk7XG4gKlxuICogZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBybG0ucXVlcnlTdHJlYW0oJ1doYXQgaXMgQUk/JykpIHtcbiAqICAgaWYgKGV2ZW50LnR5cGUgPT09ICd0b2tlbicpIHtcbiAqICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShldmVudC50ZXh0KTtcbiAqICAgfSBlbHNlIHtcbiAqICAgICBjb25zb2xlLmxvZygnXFxuXFxuRG9uZSEgUXVhbGl0eTonLCBldmVudC5hbnN3ZXIucXVhbGl0eVNjb3JlKTtcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQGV4YW1wbGUgV2l0aCBSZWZsZWN0aW9uXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBybG0gPSBuZXcgUmxtQ29udHJvbGxlcih7XG4gKiAgIGVuYWJsZVJlZmxlY3Rpb246IHRydWUsXG4gKiAgIG1heFJlZmxlY3Rpb25JdGVyYXRpb25zOiAyLFxuICogICBtaW5RdWFsaXR5U2NvcmU6IDAuOCxcbiAqIH0pO1xuICpcbiAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnQ29tcGxleCBtdWx0aS1wYXJ0IHF1ZXN0aW9uLi4uJyk7XG4gKiAvLyBBbnN3ZXIgd2lsbCBiZSBpdGVyYXRpdmVseSByZWZpbmVkIHVudGlsIHF1YWxpdHkgPj0gMC44XG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQge1xuICBSbG1Db25maWcsXG4gIFJsbUFuc3dlcixcbiAgTWVtb3J5U3BhbixcbiAgU3ViUXVlcnksXG4gIFRva2VuVXNhZ2UsXG4gIFN0cmVhbVRva2VuLFxuICBSbG1DYWNoZUVudHJ5LFxuICBSZWZsZWN0aW9uUmVzdWx0LFxufSBmcm9tICcuL3R5cGVzJztcblxuaW1wb3J0IHsgUnV2TExNIH0gZnJvbSAnLi4vZW5naW5lJztcbmltcG9ydCB0eXBlIHsgR2VuZXJhdGlvbkNvbmZpZywgUXVlcnlSZXNwb25zZSB9IGZyb20gJy4uL3R5cGVzJztcblxuLyoqXG4gKiBEZWZhdWx0IGNvbmZpZ3VyYXRpb24gdmFsdWVzXG4gKi9cbmNvbnN0IERFRkFVTFRfQ09ORklHOiBSZXF1aXJlZDxSbG1Db25maWc+ID0ge1xuICBtYXhEZXB0aDogMyxcbiAgbWF4U3ViUXVlcmllczogNSxcbiAgdG9rZW5CdWRnZXQ6IDQwOTYsXG4gIGVuYWJsZUNhY2hlOiB0cnVlLFxuICBjYWNoZVR0bDogMzAwMDAwLCAvLyA1IG1pbnV0ZXNcbiAgcmV0cmlldmFsVG9wSzogMTAsXG4gIG1pblF1YWxpdHlTY29yZTogMC43LFxuICBlbmFibGVSZWZsZWN0aW9uOiBmYWxzZSxcbiAgbWF4UmVmbGVjdGlvbkl0ZXJhdGlvbnM6IDIsXG59O1xuXG4vKipcbiAqIFJsbUNvbnRyb2xsZXIgLSBSZWN1cnNpdmUgUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsIENvbnRyb2xsZXJcbiAqXG4gKiBPcmNoZXN0cmF0ZXMgcmV0cmlldmFsLWF1Z21lbnRlZCBnZW5lcmF0aW9uIHdpdGggcmVjdXJzaXZlIHN1Yi1xdWVyeVxuICogZGVjb21wb3NpdGlvbiwgbWVtb3J5IHNlYXJjaCwgYW5kIG9wdGlvbmFsIHNlbGYtcmVmbGVjdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFJsbUNvbnRyb2xsZXIge1xuICBwcml2YXRlIGNvbmZpZzogUmVxdWlyZWQ8UmxtQ29uZmlnPjtcbiAgcHJpdmF0ZSBjYWNoZTogTWFwPHN0cmluZywgUmxtQ2FjaGVFbnRyeT47XG4gIHByaXZhdGUgZW5naW5lOiBSdXZMTE07XG4gIHByaXZhdGUgbWVtb3J5SWRDb3VudGVyOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBSTE0gY29udHJvbGxlclxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSBlbmdpbmUgLSBPcHRpb25hbCBSdXZMTE0gZW5naW5lIGluc3RhbmNlIChjcmVhdGVzIG5ldyBpZiBub3QgcHJvdmlkZWQpXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogLy8gV2l0aCBkZWZhdWx0IGNvbmZpZ1xuICAgKiBjb25zdCBybG0gPSBuZXcgUmxtQ29udHJvbGxlcigpO1xuICAgKlxuICAgKiAvLyBXaXRoIGN1c3RvbSBjb25maWdcbiAgICogY29uc3QgcmxtID0gbmV3IFJsbUNvbnRyb2xsZXIoe1xuICAgKiAgIG1heERlcHRoOiA1LFxuICAgKiAgIGVuYWJsZVJlZmxlY3Rpb246IHRydWUsXG4gICAqIH0pO1xuICAgKlxuICAgKiAvLyBXaXRoIGV4aXN0aW5nIGVuZ2luZVxuICAgKiBjb25zdCBlbmdpbmUgPSBuZXcgUnV2TExNKHsgbGVhcm5pbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgKiBjb25zdCBybG0gPSBuZXcgUmxtQ29udHJvbGxlcih7fSwgZW5naW5lKTtcbiAgICogYGBgXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc/OiBSbG1Db25maWcsIGVuZ2luZT86IFJ1dkxMTSkge1xuICAgIHRoaXMuY29uZmlnID0geyAuLi5ERUZBVUxUX0NPTkZJRywgLi4uY29uZmlnIH07XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmVuZ2luZSA9IGVuZ2luZSA/PyBuZXcgUnV2TExNKHsgbGVhcm5pbmdFbmFibGVkOiB0cnVlIH0pO1xuICAgIHRoaXMubWVtb3J5SWRDb3VudGVyID0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyeSB0aGUgUkxNIHdpdGggcmVjdXJzaXZlIHJldHJpZXZhbFxuICAgKlxuICAgKiBAcGFyYW0gaW5wdXQgLSBUaGUgcXVlcnkgc3RyaW5nXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBhbnN3ZXIgd2l0aCBzb3VyY2VzIGFuZCBtZXRhZGF0YVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnV2hhdCBpcyB0aGUgY2FwaXRhbCBvZiBGcmFuY2U/Jyk7XG4gICAqIGNvbnNvbGUubG9nKGFuc3dlci50ZXh0KTsgLy8gXCJUaGUgY2FwaXRhbCBvZiBGcmFuY2UgaXMgUGFyaXMuLi5cIlxuICAgKiBjb25zb2xlLmxvZyhhbnN3ZXIuY29uZmlkZW5jZSk7IC8vIDAuOTVcbiAgICogY29uc29sZS5sb2coYW5zd2VyLnNvdXJjZXMpOyAvLyBbeyBpZDogJy4uLicsIHRleHQ6ICcuLi4nLCBzaW1pbGFyaXR5U2NvcmU6IDAuOTIgfV1cbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBxdWVyeShpbnB1dDogc3RyaW5nKTogUHJvbWlzZTxSbG1BbnN3ZXI+IHtcbiAgICAvLyBDaGVjayBjYWNoZSBmaXJzdFxuICAgIGlmICh0aGlzLmNvbmZpZy5lbmFibGVDYWNoZSkge1xuICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy5nZXRDYWNoZWQoaW5wdXQpO1xuICAgICAgaWYgKGNhY2hlZCkge1xuICAgICAgICByZXR1cm4geyAuLi5jYWNoZWQsIGNhY2hlZDogdHJ1ZSB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHJpZXZlIHJlbGV2YW50IG1lbW9yeSBzcGFuc1xuICAgIGNvbnN0IHNvdXJjZXMgPSBhd2FpdCB0aGlzLnNlYXJjaE1lbW9yeShpbnB1dCwgdGhpcy5jb25maWcucmV0cmlldmFsVG9wSyk7XG5cbiAgICAvLyBHZW5lcmF0ZSBzdWItcXVlcmllcyBpZiBuZWVkZWQgYW5kIGRlcHRoIGFsbG93c1xuICAgIGNvbnN0IHN1YlF1ZXJpZXMgPSBhd2FpdCB0aGlzLmdlbmVyYXRlU3ViUXVlcmllcyhpbnB1dCwgc291cmNlcywgMCk7XG5cbiAgICAvLyBCdWlsZCBjb250ZXh0IGZyb20gc291cmNlcyBhbmQgc3ViLXF1ZXJ5IGFuc3dlcnNcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5idWlsZENvbnRleHQoc291cmNlcywgc3ViUXVlcmllcyk7XG5cbiAgICAvLyBHZW5lcmF0ZSB0aGUgYW5zd2VyXG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuZW5naW5lLnF1ZXJ5KFxuICAgICAgdGhpcy5idWlsZFByb21wdChpbnB1dCwgY29udGV4dCksXG4gICAgICB0aGlzLmdldEdlbmVyYXRpb25Db25maWcoKVxuICAgICk7XG5cbiAgICAvLyBDYWxjdWxhdGUgdG9rZW4gdXNhZ2UgKGVzdGltYXRlIGlmIG5vdCBwcm92aWRlZCBieSBlbmdpbmUpXG4gICAgY29uc3QgdG9rZW5Vc2FnZSA9IHRoaXMuZXN0aW1hdGVUb2tlblVzYWdlKGlucHV0LCBjb250ZXh0LCByZXNwb25zZS50ZXh0KTtcblxuICAgIC8vIENhbGN1bGF0ZSBxdWFsaXR5IHNjb3JlXG4gICAgY29uc3QgcXVhbGl0eVNjb3JlID0gdGhpcy5jYWxjdWxhdGVRdWFsaXR5U2NvcmUoc291cmNlcywgcmVzcG9uc2UuY29uZmlkZW5jZSk7XG5cbiAgICBsZXQgYW5zd2VyOiBSbG1BbnN3ZXIgPSB7XG4gICAgICB0ZXh0OiByZXNwb25zZS50ZXh0LFxuICAgICAgY29uZmlkZW5jZTogcmVzcG9uc2UuY29uZmlkZW5jZSxcbiAgICAgIHF1YWxpdHlTY29yZSxcbiAgICAgIHNvdXJjZXMsXG4gICAgICBzdWJRdWVyaWVzOiBzdWJRdWVyaWVzLmxlbmd0aCA+IDAgPyBzdWJRdWVyaWVzIDogdW5kZWZpbmVkLFxuICAgICAgdG9rZW5Vc2FnZSxcbiAgICAgIGNhY2hlZDogZmFsc2UsXG4gICAgfTtcblxuICAgIC8vIEFwcGx5IHJlZmxlY3Rpb24gaWYgZW5hYmxlZCBhbmQgcXVhbGl0eSBpcyBiZWxvdyB0aHJlc2hvbGRcbiAgICBpZiAodGhpcy5jb25maWcuZW5hYmxlUmVmbGVjdGlvbiAmJiBxdWFsaXR5U2NvcmUgPCB0aGlzLmNvbmZpZy5taW5RdWFsaXR5U2NvcmUpIHtcbiAgICAgIGFuc3dlciA9IGF3YWl0IHRoaXMuYXBwbHlSZWZsZWN0aW9uKGlucHV0LCBhbnN3ZXIpO1xuICAgIH1cblxuICAgIC8vIENhY2hlIHRoZSByZXN1bHRcbiAgICBpZiAodGhpcy5jb25maWcuZW5hYmxlQ2FjaGUpIHtcbiAgICAgIHRoaXMuc2V0Q2FjaGUoaW5wdXQsIGFuc3dlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFuc3dlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyeSB3aXRoIHN0cmVhbWluZyByZXNwb25zZVxuICAgKlxuICAgKiBAcGFyYW0gaW5wdXQgLSBUaGUgcXVlcnkgc3RyaW5nXG4gICAqIEB5aWVsZHMgU3RyZWFtVG9rZW4gZXZlbnRzIChlaXRoZXIgcGFydGlhbCB0b2tlbnMgb3IgZmluYWwgYW5zd2VyKVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgcmxtLnF1ZXJ5U3RyZWFtKCdFeHBsYWluIHF1YW50dW0gY29tcHV0aW5nJykpIHtcbiAgICogICBpZiAoZXZlbnQudHlwZSA9PT0gJ3Rva2VuJykge1xuICAgKiAgICAgLy8gUGFydGlhbCB0b2tlbiByZWNlaXZlZFxuICAgKiAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoZXZlbnQudGV4dCk7XG4gICAqICAgfSBlbHNlIHtcbiAgICogICAgIC8vIEdlbmVyYXRpb24gY29tcGxldGVcbiAgICogICAgIGNvbnNvbGUubG9nKCdcXG5cXG5Tb3VyY2VzOicsIGV2ZW50LmFuc3dlci5zb3VyY2VzLmxlbmd0aCk7XG4gICAqICAgfVxuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgKnF1ZXJ5U3RyZWFtKGlucHV0OiBzdHJpbmcpOiBBc3luY0dlbmVyYXRvcjxTdHJlYW1Ub2tlbj4ge1xuICAgIC8vIENoZWNrIGNhY2hlIGZpcnN0XG4gICAgaWYgKHRoaXMuY29uZmlnLmVuYWJsZUNhY2hlKSB7XG4gICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLmdldENhY2hlZChpbnB1dCk7XG4gICAgICBpZiAoY2FjaGVkKSB7XG4gICAgICAgIC8vIFNpbXVsYXRlIHN0cmVhbWluZyBmb3IgY2FjaGVkIHJlc3BvbnNlXG4gICAgICAgIGNvbnN0IHdvcmRzID0gY2FjaGVkLnRleHQuc3BsaXQoJyAnKTtcbiAgICAgICAgZm9yIChjb25zdCB3b3JkIG9mIHdvcmRzKSB7XG4gICAgICAgICAgeWllbGQgeyB0eXBlOiAndG9rZW4nLCB0ZXh0OiB3b3JkICsgJyAnLCBkb25lOiBmYWxzZSB9O1xuICAgICAgICAgIGF3YWl0IHRoaXMuZGVsYXkoMTApOyAvLyBTbWFsbCBkZWxheSBmb3IgcmVhbGlzdGljIHN0cmVhbWluZ1xuICAgICAgICB9XG4gICAgICAgIHlpZWxkIHsgdHlwZTogJ2RvbmUnLCBhbnN3ZXI6IHsgLi4uY2FjaGVkLCBjYWNoZWQ6IHRydWUgfSwgZG9uZTogdHJ1ZSB9O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0cmlldmUgc291cmNlc1xuICAgIGNvbnN0IHNvdXJjZXMgPSBhd2FpdCB0aGlzLnNlYXJjaE1lbW9yeShpbnB1dCwgdGhpcy5jb25maWcucmV0cmlldmFsVG9wSyk7XG4gICAgY29uc3Qgc3ViUXVlcmllcyA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVTdWJRdWVyaWVzKGlucHV0LCBzb3VyY2VzLCAwKTtcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5idWlsZENvbnRleHQoc291cmNlcywgc3ViUXVlcmllcyk7XG5cbiAgICAvLyBHZW5lcmF0ZSB3aXRoIHNpbXVsYXRlZCBzdHJlYW1pbmdcbiAgICBjb25zdCBwcm9tcHQgPSB0aGlzLmJ1aWxkUHJvbXB0KGlucHV0LCBjb250ZXh0KTtcbiAgICBjb25zdCByZXNwb25zZSA9IHRoaXMuZW5naW5lLnF1ZXJ5KHByb21wdCwgdGhpcy5nZXRHZW5lcmF0aW9uQ29uZmlnKCkpO1xuXG4gICAgLy8gU3RyZWFtIHRoZSByZXNwb25zZSB3b3JkIGJ5IHdvcmRcbiAgICBjb25zdCB3b3JkcyA9IHJlc3BvbnNlLnRleHQuc3BsaXQoJyAnKTtcbiAgICBsZXQgc3RyZWFtZWRUZXh0ID0gJyc7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHdvcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB3b3JkID0gd29yZHNbaV07XG4gICAgICBjb25zdCB0ZXh0ID0gaSA8IHdvcmRzLmxlbmd0aCAtIDEgPyB3b3JkICsgJyAnIDogd29yZDtcbiAgICAgIHN0cmVhbWVkVGV4dCArPSB0ZXh0O1xuXG4gICAgICB5aWVsZCB7IHR5cGU6ICd0b2tlbicsIHRleHQsIGRvbmU6IGZhbHNlIH07XG4gICAgICBhd2FpdCB0aGlzLmRlbGF5KDIwKTsgLy8gU2ltdWxhdGUgZ2VuZXJhdGlvbiBsYXRlbmN5XG4gICAgfVxuXG4gICAgY29uc3QgdG9rZW5Vc2FnZSA9IHRoaXMuZXN0aW1hdGVUb2tlblVzYWdlKGlucHV0LCBjb250ZXh0LCBzdHJlYW1lZFRleHQpO1xuICAgIGNvbnN0IHF1YWxpdHlTY29yZSA9IHRoaXMuY2FsY3VsYXRlUXVhbGl0eVNjb3JlKHNvdXJjZXMsIHJlc3BvbnNlLmNvbmZpZGVuY2UpO1xuXG4gICAgY29uc3QgYW5zd2VyOiBSbG1BbnN3ZXIgPSB7XG4gICAgICB0ZXh0OiBzdHJlYW1lZFRleHQsXG4gICAgICBjb25maWRlbmNlOiByZXNwb25zZS5jb25maWRlbmNlLFxuICAgICAgcXVhbGl0eVNjb3JlLFxuICAgICAgc291cmNlcyxcbiAgICAgIHN1YlF1ZXJpZXM6IHN1YlF1ZXJpZXMubGVuZ3RoID4gMCA/IHN1YlF1ZXJpZXMgOiB1bmRlZmluZWQsXG4gICAgICB0b2tlblVzYWdlLFxuICAgICAgY2FjaGVkOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgLy8gQ2FjaGUgdGhlIHJlc3VsdFxuICAgIGlmICh0aGlzLmNvbmZpZy5lbmFibGVDYWNoZSkge1xuICAgICAgdGhpcy5zZXRDYWNoZShpbnB1dCwgYW5zd2VyKTtcbiAgICB9XG5cbiAgICB5aWVsZCB7IHR5cGU6ICdkb25lJywgYW5zd2VyLCBkb25lOiB0cnVlIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkIGNvbnRlbnQgdG8gbWVtb3J5IGZvciByZXRyaWV2YWxcbiAgICpcbiAgICogQHBhcmFtIHRleHQgLSBUaGUgdGV4dCBjb250ZW50IHRvIHN0b3JlXG4gICAqIEBwYXJhbSBtZXRhZGF0YSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBtZW1vcnlcbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIG1lbW9yeSBzcGFuIElEXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgaWQxID0gYXdhaXQgcmxtLmFkZE1lbW9yeShcbiAgICogICAnVHlwZVNjcmlwdCBpcyBhIHR5cGVkIHN1cGVyc2V0IG9mIEphdmFTY3JpcHQuJyxcbiAgICogICB7IHNvdXJjZTogJ2RvY3VtZW50YXRpb24nLCBjYXRlZ29yeTogJ3Byb2dyYW1taW5nJyB9XG4gICAqICk7XG4gICAqXG4gICAqIGNvbnN0IGlkMiA9IGF3YWl0IHJsbS5hZGRNZW1vcnkoXG4gICAqICAgJ1JlYWN0IGlzIGEgSmF2YVNjcmlwdCBsaWJyYXJ5IGZvciBidWlsZGluZyBVSXMuJ1xuICAgKiApO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGFkZE1lbW9yeSh0ZXh0OiBzdHJpbmcsIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IG5vZGVJZCA9IHRoaXMuZW5naW5lLmFkZE1lbW9yeSh0ZXh0LCBtZXRhZGF0YSk7XG4gICAgY29uc3QgaWQgPSBgcmxtLW1lbS0ke3RoaXMubWVtb3J5SWRDb3VudGVyKyt9LSR7bm9kZUlkfWA7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlYXJjaCBtZW1vcnkgZm9yIHJlbGV2YW50IHNwYW5zXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeSAtIFRoZSBzZWFyY2ggcXVlcnlcbiAgICogQHBhcmFtIHRvcEsgLSBOdW1iZXIgb2YgcmVzdWx0cyB0byByZXR1cm4gKGRlZmF1bHQ6IGNvbmZpZy5yZXRyaWV2YWxUb3BLKVxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmluZyB0byBhcnJheSBvZiBtZW1vcnkgc3BhbnNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBzcGFucyA9IGF3YWl0IHJsbS5zZWFyY2hNZW1vcnkoJ0phdmFTY3JpcHQgZnJhbWV3b3JrcycsIDUpO1xuICAgKiBmb3IgKGNvbnN0IHNwYW4gb2Ygc3BhbnMpIHtcbiAgICogICBjb25zb2xlLmxvZyhgWyR7c3Bhbi5zaW1pbGFyaXR5U2NvcmUudG9GaXhlZCgyKX1dICR7c3Bhbi50ZXh0fWApO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgc2VhcmNoTWVtb3J5KHF1ZXJ5OiBzdHJpbmcsIHRvcEs/OiBudW1iZXIpOiBQcm9taXNlPE1lbW9yeVNwYW5bXT4ge1xuICAgIGNvbnN0IGsgPSB0b3BLID8/IHRoaXMuY29uZmlnLnJldHJpZXZhbFRvcEs7XG4gICAgY29uc3QgcmVzdWx0cyA9IHRoaXMuZW5naW5lLnNlYXJjaE1lbW9yeShxdWVyeSwgayk7XG5cbiAgICByZXR1cm4gcmVzdWx0cy5tYXAoKHJlc3VsdCwgaW5kZXgpID0+ICh7XG4gICAgICBpZDogYHJsbS1zcGFuLSR7cmVzdWx0LmlkfS0ke2luZGV4fWAsXG4gICAgICB0ZXh0OiByZXN1bHQuY29udGVudCxcbiAgICAgIHNpbWlsYXJpdHlTY29yZTogcmVzdWx0LnNjb3JlLFxuICAgICAgc291cmNlOiByZXN1bHQubWV0YWRhdGE/LnNvdXJjZSBhcyBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICBtZXRhZGF0YTogcmVzdWx0Lm1ldGFkYXRhLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciB0aGUgcmVzcG9uc2UgY2FjaGVcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBybG0uY2xlYXJDYWNoZSgpO1xuICAgKiBjb25zb2xlLmxvZygnQ2FjaGUgY2xlYXJlZCcpO1xuICAgKiBgYGBcbiAgICovXG4gIGNsZWFyQ2FjaGUoKTogdm9pZCB7XG4gICAgdGhpcy5jYWNoZS5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IGNhY2hlIHN0YXRpc3RpY3NcbiAgICpcbiAgICogQHJldHVybnMgT2JqZWN0IHdpdGggY2FjaGUgc2l6ZSBhbmQgaGl0IHJhdGUgaW5mb1xuICAgKi9cbiAgZ2V0Q2FjaGVTdGF0cygpOiB7IHNpemU6IG51bWJlcjsgZW50cmllczogbnVtYmVyIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBzaXplOiB0aGlzLmNhY2hlLnNpemUsXG4gICAgICBlbnRyaWVzOiB0aGlzLmNhY2hlLnNpemUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgY29uZmlndXJhdGlvbiBhdCBydW50aW1lXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBQYXJ0aWFsIGNvbmZpZ3VyYXRpb24gdG8gbWVyZ2VcbiAgICovXG4gIHVwZGF0ZUNvbmZpZyhjb25maWc6IFBhcnRpYWw8UmxtQ29uZmlnPik6IHZvaWQge1xuICAgIHRoaXMuY29uZmlnID0geyAuLi50aGlzLmNvbmZpZywgLi4uY29uZmlnIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1cnJlbnQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgZ2V0Q29uZmlnKCk6IFJlcXVpcmVkPFJsbUNvbmZpZz4ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuY29uZmlnIH07XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBQcml2YXRlIE1ldGhvZHNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogR2VuZXJhdGUgc3ViLXF1ZXJpZXMgZm9yIGNvbXBsZXggcXVlc3Rpb25zXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlU3ViUXVlcmllcyhcbiAgICBxdWVyeTogc3RyaW5nLFxuICAgIHNvdXJjZXM6IE1lbW9yeVNwYW5bXSxcbiAgICBkZXB0aDogbnVtYmVyXG4gICk6IFByb21pc2U8U3ViUXVlcnlbXT4ge1xuICAgIGlmIChkZXB0aCA+PSB0aGlzLmNvbmZpZy5tYXhEZXB0aCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIFNpbXBsZSBoZXVyaXN0aWM6IGdlbmVyYXRlIHN1Yi1xdWVyaWVzIGZvciBxdWVzdGlvbnMgd2l0aCBtdWx0aXBsZSBwYXJ0c1xuICAgIGNvbnN0IHN1YlF1ZXJpZXM6IFN1YlF1ZXJ5W10gPSBbXTtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMuZGVjb21wb3NlUXVlcnkocXVlcnkpO1xuXG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzLnNsaWNlKDAsIHRoaXMuY29uZmlnLm1heFN1YlF1ZXJpZXMpKSB7XG4gICAgICBpZiAocGFydC50cmltKCkubGVuZ3RoIDwgMTApIGNvbnRpbnVlO1xuXG4gICAgICAvLyBTZWFyY2ggZm9yIHN1Yi1xdWVyeSBzcGVjaWZpYyBzb3VyY2VzXG4gICAgICBjb25zdCBzdWJTb3VyY2VzID0gYXdhaXQgdGhpcy5zZWFyY2hNZW1vcnkocGFydCwgTWF0aC5jZWlsKHRoaXMuY29uZmlnLnJldHJpZXZhbFRvcEsgLyAyKSk7XG4gICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5idWlsZENvbnRleHQoc3ViU291cmNlcywgW10pO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmVuZ2luZS5xdWVyeShcbiAgICAgICAgdGhpcy5idWlsZFByb21wdChwYXJ0LCBjb250ZXh0KSxcbiAgICAgICAgeyAuLi50aGlzLmdldEdlbmVyYXRpb25Db25maWcoKSwgbWF4VG9rZW5zOiAyNTYgfVxuICAgICAgKTtcblxuICAgICAgc3ViUXVlcmllcy5wdXNoKHtcbiAgICAgICAgcXVlcnk6IHBhcnQsXG4gICAgICAgIGFuc3dlcjogcmVzcG9uc2UudGV4dCxcbiAgICAgICAgZGVwdGg6IGRlcHRoICsgMSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBzdWJRdWVyaWVzO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY29tcG9zZSBhIGNvbXBsZXggcXVlcnkgaW50byBzaW1wbGVyIHBhcnRzXG4gICAqL1xuICBwcml2YXRlIGRlY29tcG9zZVF1ZXJ5KHF1ZXJ5OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgLy8gU3BsaXQgb24gY29tbW9uIGNvbmp1bmN0aW9ucyBhbmQgcXVlc3Rpb24gbWFya2Vyc1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gQ2hlY2sgZm9yIG11bHRpLXBhcnQgcXVlc3Rpb25zXG4gICAgY29uc3QgY29uanVuY3Rpb25zID0gWycgYW5kICcsICcgb3IgJywgJy4gJywgJz8gJywgJzsgJ107XG4gICAgbGV0IGN1cnJlbnQgPSBxdWVyeTtcblxuICAgIGZvciAoY29uc3QgY29uaiBvZiBjb25qdW5jdGlvbnMpIHtcbiAgICAgIGlmIChjdXJyZW50LmluY2x1ZGVzKGNvbmopKSB7XG4gICAgICAgIGNvbnN0IHNwbGl0ID0gY3VycmVudC5zcGxpdChjb25qKTtcbiAgICAgICAgcGFydHMucHVzaCguLi5zcGxpdC5maWx0ZXIocCA9PiBwLnRyaW0oKS5sZW5ndGggPiAxMCkpO1xuICAgICAgICBjdXJyZW50ID0gJyc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vIGRlY29tcG9zaXRpb24gaGFwcGVuZWQsIHJldHVybiBvcmlnaW5hbFxuICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbcXVlcnldO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJ0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBjb250ZXh0IHN0cmluZyBmcm9tIHNvdXJjZXMgYW5kIHN1Yi1xdWVyaWVzXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQ29udGV4dChzb3VyY2VzOiBNZW1vcnlTcGFuW10sIHN1YlF1ZXJpZXM6IFN1YlF1ZXJ5W10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gQWRkIHNvdXJjZXNcbiAgICBpZiAoc291cmNlcy5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJ0cy5wdXNoKCdSZWxldmFudCBjb250ZXh0OicpO1xuICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICBwYXJ0cy5wdXNoKGAtICR7c291cmNlLnRleHR9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIHN1Yi1xdWVyeSBhbnN3ZXJzXG4gICAgaWYgKHN1YlF1ZXJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgcGFydHMucHVzaCgnXFxuUmVsYXRlZCBpbmZvcm1hdGlvbjonKTtcbiAgICAgIGZvciAoY29uc3Qgc3Egb2Ygc3ViUXVlcmllcykge1xuICAgICAgICBwYXJ0cy5wdXNoKGBROiAke3NxLnF1ZXJ5fWApO1xuICAgICAgICBwYXJ0cy5wdXNoKGBBOiAke3NxLmFuc3dlcn1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGFydHMuam9pbignXFxuJyk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgdGhlIGZ1bGwgcHJvbXB0IHdpdGggY29udGV4dFxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFByb21wdChxdWVyeTogc3RyaW5nLCBjb250ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmIChjb250ZXh0LnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9XG5cbiAgICByZXR1cm4gYCR7Y29udGV4dH1cXG5cXG5CYXNlZCBvbiB0aGUgYWJvdmUgY29udGV4dCwgYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb246XFxuJHtxdWVyeX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBnZW5lcmF0aW9uIGNvbmZpZyBiYXNlZCBvbiBSTE0gc2V0dGluZ3NcbiAgICovXG4gIHByaXZhdGUgZ2V0R2VuZXJhdGlvbkNvbmZpZygpOiBHZW5lcmF0aW9uQ29uZmlnIHtcbiAgICByZXR1cm4ge1xuICAgICAgbWF4VG9rZW5zOiBNYXRoLm1pbih0aGlzLmNvbmZpZy50b2tlbkJ1ZGdldCwgMjA0OCksXG4gICAgICB0ZW1wZXJhdHVyZTogMC43LFxuICAgICAgdG9wUDogMC45LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRXN0aW1hdGUgdG9rZW4gdXNhZ2VcbiAgICovXG4gIHByaXZhdGUgZXN0aW1hdGVUb2tlblVzYWdlKHF1ZXJ5OiBzdHJpbmcsIGNvbnRleHQ6IHN0cmluZywgcmVzcG9uc2U6IHN0cmluZyk6IFRva2VuVXNhZ2Uge1xuICAgIC8vIFJvdWdoIGVzdGltYXRpb246IH40IGNoYXJhY3RlcnMgcGVyIHRva2VuXG4gICAgY29uc3QgcHJvbXB0VG9rZW5zID0gTWF0aC5jZWlsKChxdWVyeS5sZW5ndGggKyBjb250ZXh0Lmxlbmd0aCkgLyA0KTtcbiAgICBjb25zdCBjb21wbGV0aW9uVG9rZW5zID0gTWF0aC5jZWlsKHJlc3BvbnNlLmxlbmd0aCAvIDQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByb21wdDogcHJvbXB0VG9rZW5zLFxuICAgICAgY29tcGxldGlvbjogY29tcGxldGlvblRva2VucyxcbiAgICAgIHRvdGFsOiBwcm9tcHRUb2tlbnMgKyBjb21wbGV0aW9uVG9rZW5zLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHF1YWxpdHkgc2NvcmUgYmFzZWQgb24gc291cmNlcyBhbmQgY29uZmlkZW5jZVxuICAgKi9cbiAgcHJpdmF0ZSBjYWxjdWxhdGVRdWFsaXR5U2NvcmUoc291cmNlczogTWVtb3J5U3BhbltdLCBjb25maWRlbmNlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChzb3VyY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbmZpZGVuY2UgKiAwLjU7IC8vIFBlbmFsaXplIGFuc3dlcnMgd2l0aG91dCBzb3VyY2VzXG4gICAgfVxuXG4gICAgLy8gQXZlcmFnZSBzb3VyY2Ugc2ltaWxhcml0eVxuICAgIGNvbnN0IGF2Z1NpbWlsYXJpdHkgPSBzb3VyY2VzLnJlZHVjZSgoc3VtLCBzKSA9PiBzdW0gKyBzLnNpbWlsYXJpdHlTY29yZSwgMCkgLyBzb3VyY2VzLmxlbmd0aDtcblxuICAgIC8vIFdlaWdodGVkIGNvbWJpbmF0aW9uXG4gICAgcmV0dXJuIGNvbmZpZGVuY2UgKiAwLjYgKyBhdmdTaW1pbGFyaXR5ICogMC40O1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IHNlbGYtcmVmbGVjdGlvbiB0byBpbXByb3ZlIGFuc3dlclxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhcHBseVJlZmxlY3Rpb24oXG4gICAgcXVlcnk6IHN0cmluZyxcbiAgICBhbnN3ZXI6IFJsbUFuc3dlclxuICApOiBQcm9taXNlPFJsbUFuc3dlcj4ge1xuICAgIGxldCBjdXJyZW50QW5zd2VyID0gYW5zd2VyO1xuICAgIGxldCBpdGVyYXRpb25zID0gMDtcblxuICAgIHdoaWxlIChcbiAgICAgIGl0ZXJhdGlvbnMgPCB0aGlzLmNvbmZpZy5tYXhSZWZsZWN0aW9uSXRlcmF0aW9ucyAmJlxuICAgICAgY3VycmVudEFuc3dlci5xdWFsaXR5U2NvcmUgPCB0aGlzLmNvbmZpZy5taW5RdWFsaXR5U2NvcmVcbiAgICApIHtcbiAgICAgIGl0ZXJhdGlvbnMrKztcblxuICAgICAgLy8gR2VuZXJhdGUgY3JpdGlxdWVcbiAgICAgIGNvbnN0IGNyaXRpcXVlUHJvbXB0ID0gYEV2YWx1YXRlIHRoaXMgYW5zd2VyIGZvciBhY2N1cmFjeSBhbmQgY29tcGxldGVuZXNzOlxuUXVlc3Rpb246ICR7cXVlcnl9XG5BbnN3ZXI6ICR7Y3VycmVudEFuc3dlci50ZXh0fVxuXG5Qcm92aWRlIGEgYnJpZWYgY3JpdGlxdWUgYW5kIHN1Z2dlc3QgaW1wcm92ZW1lbnRzLmA7XG5cbiAgICAgIGNvbnN0IGNyaXRpcXVlUmVzcG9uc2UgPSB0aGlzLmVuZ2luZS5xdWVyeShjcml0aXF1ZVByb21wdCwge1xuICAgICAgICBtYXhUb2tlbnM6IDI1NixcbiAgICAgICAgdGVtcGVyYXR1cmU6IDAuNSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBHZW5lcmF0ZSBpbXByb3ZlZCBhbnN3ZXJcbiAgICAgIGNvbnN0IGltcHJvdmVQcm9tcHQgPSBgQmFzZWQgb24gdGhpcyBmZWVkYmFjazogXCIke2NyaXRpcXVlUmVzcG9uc2UudGV4dH1cIlxuXG5JbXByb3ZlIHRoaXMgYW5zd2VyOlxuUXVlc3Rpb246ICR7cXVlcnl9XG5PcmlnaW5hbDogJHtjdXJyZW50QW5zd2VyLnRleHR9XG5cblByb3ZpZGUgYW4gaW1wcm92ZWQgYW5zd2VyOmA7XG5cbiAgICAgIGNvbnN0IGltcHJvdmVkUmVzcG9uc2UgPSB0aGlzLmVuZ2luZS5xdWVyeShpbXByb3ZlUHJvbXB0LCB0aGlzLmdldEdlbmVyYXRpb25Db25maWcoKSk7XG5cbiAgICAgIC8vIFVwZGF0ZSBhbnN3ZXIgd2l0aCByZWZsZWN0aW9uIGltcHJvdmVtZW50c1xuICAgICAgY29uc3QgbmV3UXVhbGl0eVNjb3JlID0gTWF0aC5taW4oXG4gICAgICAgIDEuMCxcbiAgICAgICAgY3VycmVudEFuc3dlci5xdWFsaXR5U2NvcmUgKyAwLjEgKiBpdGVyYXRpb25zXG4gICAgICApO1xuXG4gICAgICBjdXJyZW50QW5zd2VyID0ge1xuICAgICAgICAuLi5jdXJyZW50QW5zd2VyLFxuICAgICAgICB0ZXh0OiBpbXByb3ZlZFJlc3BvbnNlLnRleHQsXG4gICAgICAgIGNvbmZpZGVuY2U6IE1hdGgubWF4KGN1cnJlbnRBbnN3ZXIuY29uZmlkZW5jZSwgaW1wcm92ZWRSZXNwb25zZS5jb25maWRlbmNlKSxcbiAgICAgICAgcXVhbGl0eVNjb3JlOiBuZXdRdWFsaXR5U2NvcmUsXG4gICAgICAgIHRva2VuVXNhZ2U6IHtcbiAgICAgICAgICBwcm9tcHQ6IGN1cnJlbnRBbnN3ZXIudG9rZW5Vc2FnZS5wcm9tcHQgKyAxMDAsIC8vIEFwcHJveGltYXRlIGFkZGl0aW9uYWwgdG9rZW5zXG4gICAgICAgICAgY29tcGxldGlvbjogY3VycmVudEFuc3dlci50b2tlblVzYWdlLmNvbXBsZXRpb24gKyAxMDAsXG4gICAgICAgICAgdG90YWw6IGN1cnJlbnRBbnN3ZXIudG9rZW5Vc2FnZS50b3RhbCArIDIwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRBbnN3ZXI7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlZCBhbnN3ZXIgaWYgdmFsaWRcbiAgICovXG4gIHByaXZhdGUgZ2V0Q2FjaGVkKHF1ZXJ5OiBzdHJpbmcpOiBSbG1BbnN3ZXIgfCBudWxsIHtcbiAgICBjb25zdCBoYXNoID0gdGhpcy5oYXNoUXVlcnkocXVlcnkpO1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5jYWNoZS5nZXQoaGFzaCk7XG5cbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBUVExcbiAgICBpZiAoRGF0ZS5ub3coKSAtIGVudHJ5LnRpbWVzdGFtcCA+IHRoaXMuY29uZmlnLmNhY2hlVHRsKSB7XG4gICAgICB0aGlzLmNhY2hlLmRlbGV0ZShoYXNoKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBlbnRyeS5hbnN3ZXI7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGNhY2hlIGVudHJ5XG4gICAqL1xuICBwcml2YXRlIHNldENhY2hlKHF1ZXJ5OiBzdHJpbmcsIGFuc3dlcjogUmxtQW5zd2VyKTogdm9pZCB7XG4gICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaFF1ZXJ5KHF1ZXJ5KTtcbiAgICB0aGlzLmNhY2hlLnNldChoYXNoLCB7XG4gICAgICBhbnN3ZXIsXG4gICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICBxdWVyeUhhc2g6IGhhc2gsXG4gICAgfSk7XG5cbiAgICAvLyBQcnVuZSBvbGQgZW50cmllcyBpZiBjYWNoZSBnZXRzIHRvbyBsYXJnZVxuICAgIGlmICh0aGlzLmNhY2hlLnNpemUgPiAxMDAwKSB7XG4gICAgICB0aGlzLnBydW5lQ2FjaGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2ltcGxlIGhhc2ggZnVuY3Rpb24gZm9yIGNhY2hlIGtleXNcbiAgICovXG4gIHByaXZhdGUgaGFzaFF1ZXJ5KHF1ZXJ5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCBoYXNoID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjaGFyID0gcXVlcnkuY2hhckNvZGVBdChpKTtcbiAgICAgIGhhc2ggPSAoKGhhc2ggPDwgNSkgLSBoYXNoKSArIGNoYXI7XG4gICAgICBoYXNoID0gaGFzaCAmIGhhc2g7IC8vIENvbnZlcnQgdG8gMzItYml0IGludGVnZXJcbiAgICB9XG4gICAgcmV0dXJuIGBybG0tY2FjaGUtJHtoYXNoLnRvU3RyaW5nKDE2KX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFBydW5lIGV4cGlyZWQgY2FjaGUgZW50cmllc1xuICAgKi9cbiAgcHJpdmF0ZSBwcnVuZUNhY2hlKCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgdG9EZWxldGU6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIGVudHJ5XSBvZiB0aGlzLmNhY2hlLmVudHJpZXMoKSkge1xuICAgICAgaWYgKG5vdyAtIGVudHJ5LnRpbWVzdGFtcCA+IHRoaXMuY29uZmlnLmNhY2hlVHRsKSB7XG4gICAgICAgIHRvRGVsZXRlLnB1c2goa2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEZWxldGUgb2xkZXN0IGVudHJpZXMgaWYgc3RpbGwgdG9vIGxhcmdlXG4gICAgaWYgKHRoaXMuY2FjaGUuc2l6ZSAtIHRvRGVsZXRlLmxlbmd0aCA+IDgwMCkge1xuICAgICAgY29uc3QgZW50cmllcyA9IEFycmF5LmZyb20odGhpcy5jYWNoZS5lbnRyaWVzKCkpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhWzFdLnRpbWVzdGFtcCAtIGJbMV0udGltZXN0YW1wKTtcblxuICAgICAgY29uc3QgZGVsZXRlQ291bnQgPSBlbnRyaWVzLmxlbmd0aCAtIDUwMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVsZXRlQ291bnQ7IGkrKykge1xuICAgICAgICB0b0RlbGV0ZS5wdXNoKGVudHJpZXNbaV1bMF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIHRvRGVsZXRlKSB7XG4gICAgICB0aGlzLmNhY2hlLmRlbGV0ZShrZXkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVdGlsaXR5IGRlbGF5IGZ1bmN0aW9uIGZvciBzdHJlYW1pbmcgc2ltdWxhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBkZWxheShtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xuICB9XG59XG4iXX0= |
| /** | ||
| * RLM - Retrieval Language Model | ||
| * | ||
| * A recursive retrieval-augmented generation system that combines | ||
| * memory search with intelligent query decomposition and synthesis. | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * enableCache: true, | ||
| * retrievalTopK: 10, | ||
| * }); | ||
| * | ||
| * // Add knowledge | ||
| * await rlm.addMemory('TypeScript adds static typing to JavaScript.'); | ||
| * await rlm.addMemory('React is a library for building user interfaces.'); | ||
| * | ||
| * // Query with retrieval | ||
| * const answer = await rlm.query('Compare TypeScript and JavaScript'); | ||
| * console.log(answer.text); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('Explain machine learning')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nQuality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * // Answers will be iteratively refined until quality >= 0.8 | ||
| * const answer = await rlm.query('Complex technical question...'); | ||
| * ``` | ||
| * | ||
| * @module rlm | ||
| */ | ||
| export * from './types'; | ||
| export { RlmController } from './controller'; | ||
| export { type DecompositionStrategy, type SubQuery, type QueryDecomposition, type SubAnswer, type RlmTrajectoryMetadata, type RlmTrainingExample, type ContrastivePair, type RlmTrainingConfig, type TrainingResult as RlmTrainingResult, type EvaluationResult as RlmEvaluationResult, DEFAULT_RLM_CONFIG, FAST_RLM_CONFIG, THOROUGH_RLM_CONFIG, ROUTING_FOCUSED_CONFIG, AGENT_DEFINITIONS, HARD_NEGATIVE_PAIRS, RlmTrainer, createRlmTrainer, createEmptyExample, createSubQuery, createSubAnswer, } from './training'; | ||
| //# sourceMappingURL=index.d.ts.map |
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rlm/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,IAAI,iBAAiB,EACxC,KAAK,gBAAgB,IAAI,mBAAmB,EAG5C,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EAGnB,UAAU,EAGV,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC"} |
| /** | ||
| * RLM - Retrieval Language Model | ||
| * | ||
| * A recursive retrieval-augmented generation system that combines | ||
| * memory search with intelligent query decomposition and synthesis. | ||
| * | ||
| * @example Basic Usage | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * maxDepth: 3, | ||
| * enableCache: true, | ||
| * retrievalTopK: 10, | ||
| * }); | ||
| * | ||
| * // Add knowledge | ||
| * await rlm.addMemory('TypeScript adds static typing to JavaScript.'); | ||
| * await rlm.addMemory('React is a library for building user interfaces.'); | ||
| * | ||
| * // Query with retrieval | ||
| * const answer = await rlm.query('Compare TypeScript and JavaScript'); | ||
| * console.log(answer.text); | ||
| * console.log('Confidence:', answer.confidence); | ||
| * console.log('Sources:', answer.sources.length); | ||
| * ``` | ||
| * | ||
| * @example Streaming | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController(); | ||
| * | ||
| * for await (const event of rlm.queryStream('Explain machine learning')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nQuality:', event.answer.qualityScore); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * @example With Reflection | ||
| * ```typescript | ||
| * import { RlmController } from '@ruvector/ruvllm'; | ||
| * | ||
| * const rlm = new RlmController({ | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * minQualityScore: 0.8, | ||
| * }); | ||
| * | ||
| * // Answers will be iteratively refined until quality >= 0.8 | ||
| * const answer = await rlm.query('Complex technical question...'); | ||
| * ``` | ||
| * | ||
| * @module rlm | ||
| */ | ||
| // Export all types | ||
| export * from './types'; | ||
| // Export the controller | ||
| export { RlmController } from './controller'; | ||
| // Export training module | ||
| export { | ||
| // Constants | ||
| DEFAULT_RLM_CONFIG, FAST_RLM_CONFIG, THOROUGH_RLM_CONFIG, ROUTING_FOCUSED_CONFIG, AGENT_DEFINITIONS, HARD_NEGATIVE_PAIRS, | ||
| // Classes | ||
| RlmTrainer, | ||
| // Factory functions | ||
| createRlmTrainer, createEmptyExample, createSubQuery, createSubAnswer, } from './training'; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcmxtL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5REc7QUFFSCxtQkFBbUI7QUFDbkIsY0FBYyxTQUFTLENBQUM7QUFFeEIsd0JBQXdCO0FBQ3hCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFN0MseUJBQXlCO0FBQ3pCLE9BQU87QUFhTCxZQUFZO0FBQ1osa0JBQWtCLEVBQ2xCLGVBQWUsRUFDZixtQkFBbUIsRUFDbkIsc0JBQXNCLEVBQ3RCLGlCQUFpQixFQUNqQixtQkFBbUI7QUFFbkIsVUFBVTtBQUNWLFVBQVU7QUFFVixvQkFBb0I7QUFDcEIsZ0JBQWdCLEVBQ2hCLGtCQUFrQixFQUNsQixjQUFjLEVBQ2QsZUFBZSxHQUNoQixNQUFNLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUkxNIC0gUmV0cmlldmFsIExhbmd1YWdlIE1vZGVsXG4gKlxuICogQSByZWN1cnNpdmUgcmV0cmlldmFsLWF1Z21lbnRlZCBnZW5lcmF0aW9uIHN5c3RlbSB0aGF0IGNvbWJpbmVzXG4gKiBtZW1vcnkgc2VhcmNoIHdpdGggaW50ZWxsaWdlbnQgcXVlcnkgZGVjb21wb3NpdGlvbiBhbmQgc3ludGhlc2lzLlxuICpcbiAqIEBleGFtcGxlIEJhc2ljIFVzYWdlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBSbG1Db250cm9sbGVyIH0gZnJvbSAnQHJ1dmVjdG9yL3J1dmxsbSc7XG4gKlxuICogY29uc3QgcmxtID0gbmV3IFJsbUNvbnRyb2xsZXIoe1xuICogICBtYXhEZXB0aDogMyxcbiAqICAgZW5hYmxlQ2FjaGU6IHRydWUsXG4gKiAgIHJldHJpZXZhbFRvcEs6IDEwLFxuICogfSk7XG4gKlxuICogLy8gQWRkIGtub3dsZWRnZVxuICogYXdhaXQgcmxtLmFkZE1lbW9yeSgnVHlwZVNjcmlwdCBhZGRzIHN0YXRpYyB0eXBpbmcgdG8gSmF2YVNjcmlwdC4nKTtcbiAqIGF3YWl0IHJsbS5hZGRNZW1vcnkoJ1JlYWN0IGlzIGEgbGlicmFyeSBmb3IgYnVpbGRpbmcgdXNlciBpbnRlcmZhY2VzLicpO1xuICpcbiAqIC8vIFF1ZXJ5IHdpdGggcmV0cmlldmFsXG4gKiBjb25zdCBhbnN3ZXIgPSBhd2FpdCBybG0ucXVlcnkoJ0NvbXBhcmUgVHlwZVNjcmlwdCBhbmQgSmF2YVNjcmlwdCcpO1xuICogY29uc29sZS5sb2coYW5zd2VyLnRleHQpO1xuICogY29uc29sZS5sb2coJ0NvbmZpZGVuY2U6JywgYW5zd2VyLmNvbmZpZGVuY2UpO1xuICogY29uc29sZS5sb2coJ1NvdXJjZXM6JywgYW5zd2VyLnNvdXJjZXMubGVuZ3RoKTtcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFN0cmVhbWluZ1xuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKCk7XG4gKlxuICogZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBybG0ucXVlcnlTdHJlYW0oJ0V4cGxhaW4gbWFjaGluZSBsZWFybmluZycpKSB7XG4gKiAgIGlmIChldmVudC50eXBlID09PSAndG9rZW4nKSB7XG4gKiAgICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoZXZlbnQudGV4dCk7XG4gKiAgIH0gZWxzZSB7XG4gKiAgICAgY29uc29sZS5sb2coJ1xcblxcblF1YWxpdHk6JywgZXZlbnQuYW5zd2VyLnF1YWxpdHlTY29yZSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlIFdpdGggUmVmbGVjdGlvblxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJ0BydXZlY3Rvci9ydXZsbG0nO1xuICpcbiAqIGNvbnN0IHJsbSA9IG5ldyBSbG1Db250cm9sbGVyKHtcbiAqICAgZW5hYmxlUmVmbGVjdGlvbjogdHJ1ZSxcbiAqICAgbWF4UmVmbGVjdGlvbkl0ZXJhdGlvbnM6IDIsXG4gKiAgIG1pblF1YWxpdHlTY29yZTogMC44LFxuICogfSk7XG4gKlxuICogLy8gQW5zd2VycyB3aWxsIGJlIGl0ZXJhdGl2ZWx5IHJlZmluZWQgdW50aWwgcXVhbGl0eSA+PSAwLjhcbiAqIGNvbnN0IGFuc3dlciA9IGF3YWl0IHJsbS5xdWVyeSgnQ29tcGxleCB0ZWNobmljYWwgcXVlc3Rpb24uLi4nKTtcbiAqIGBgYFxuICpcbiAqIEBtb2R1bGUgcmxtXG4gKi9cblxuLy8gRXhwb3J0IGFsbCB0eXBlc1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5cbi8vIEV4cG9ydCB0aGUgY29udHJvbGxlclxuZXhwb3J0IHsgUmxtQ29udHJvbGxlciB9IGZyb20gJy4vY29udHJvbGxlcic7XG5cbi8vIEV4cG9ydCB0cmFpbmluZyBtb2R1bGVcbmV4cG9ydCB7XG4gIC8vIFR5cGVzXG4gIHR5cGUgRGVjb21wb3NpdGlvblN0cmF0ZWd5LFxuICB0eXBlIFN1YlF1ZXJ5LFxuICB0eXBlIFF1ZXJ5RGVjb21wb3NpdGlvbixcbiAgdHlwZSBTdWJBbnN3ZXIsXG4gIHR5cGUgUmxtVHJhamVjdG9yeU1ldGFkYXRhLFxuICB0eXBlIFJsbVRyYWluaW5nRXhhbXBsZSxcbiAgdHlwZSBDb250cmFzdGl2ZVBhaXIsXG4gIHR5cGUgUmxtVHJhaW5pbmdDb25maWcsXG4gIHR5cGUgVHJhaW5pbmdSZXN1bHQgYXMgUmxtVHJhaW5pbmdSZXN1bHQsXG4gIHR5cGUgRXZhbHVhdGlvblJlc3VsdCBhcyBSbG1FdmFsdWF0aW9uUmVzdWx0LFxuXG4gIC8vIENvbnN0YW50c1xuICBERUZBVUxUX1JMTV9DT05GSUcsXG4gIEZBU1RfUkxNX0NPTkZJRyxcbiAgVEhPUk9VR0hfUkxNX0NPTkZJRyxcbiAgUk9VVElOR19GT0NVU0VEX0NPTkZJRyxcbiAgQUdFTlRfREVGSU5JVElPTlMsXG4gIEhBUkRfTkVHQVRJVkVfUEFJUlMsXG5cbiAgLy8gQ2xhc3Nlc1xuICBSbG1UcmFpbmVyLFxuXG4gIC8vIEZhY3RvcnkgZnVuY3Rpb25zXG4gIGNyZWF0ZVJsbVRyYWluZXIsXG4gIGNyZWF0ZUVtcHR5RXhhbXBsZSxcbiAgY3JlYXRlU3ViUXVlcnksXG4gIGNyZWF0ZVN1YkFuc3dlcixcbn0gZnJvbSAnLi90cmFpbmluZyc7XG4iXX0= |
| /** | ||
| * RLM (Recursive Learning Machine) Training Module | ||
| * | ||
| * Provides training capabilities for RuvLTRA models on RLM task routing | ||
| * and decomposition, including query decomposition, answer synthesis, | ||
| * and agent routing optimization. | ||
| * | ||
| * @module rlm/training | ||
| */ | ||
| /** | ||
| * Strategy for decomposing a complex query | ||
| */ | ||
| export type DecompositionStrategy = 'sequential' | 'parallel' | 'hierarchical' | 'dag-based' | 'iterative' | 'none'; | ||
| /** | ||
| * A sub-query in the decomposition | ||
| */ | ||
| export interface SubQuery { | ||
| /** Unique identifier within the decomposition */ | ||
| id: number; | ||
| /** The sub-query text */ | ||
| query: string; | ||
| /** Expected output type (e.g., "code", "analysis", "data") */ | ||
| expectedType: string; | ||
| /** Dependencies (IDs of sub-queries that must complete first) */ | ||
| dependencies: number[]; | ||
| /** Recommended agent type for this sub-query */ | ||
| recommendedAgent?: string; | ||
| /** Estimated complexity (0.0-1.0) */ | ||
| complexity: number; | ||
| /** Optional context from parent query */ | ||
| context?: string; | ||
| } | ||
| /** | ||
| * Decomposition of a complex query into sub-queries | ||
| */ | ||
| export interface QueryDecomposition { | ||
| /** Sub-queries in execution order */ | ||
| subQueries: SubQuery[]; | ||
| /** Decomposition strategy used */ | ||
| strategy: DecompositionStrategy; | ||
| /** Reasoning for this decomposition */ | ||
| rationale: string; | ||
| /** Total estimated complexity */ | ||
| totalComplexity: number; | ||
| /** Whether decomposition was successful */ | ||
| success: boolean; | ||
| /** Error message if decomposition failed */ | ||
| error?: string; | ||
| } | ||
| /** | ||
| * Answer to a sub-query | ||
| */ | ||
| export interface SubAnswer { | ||
| /** ID of the sub-query this answers */ | ||
| subQueryId: number; | ||
| /** The answer content */ | ||
| content: string; | ||
| /** Confidence in this answer (0.0-1.0) */ | ||
| confidence: number; | ||
| /** Agent that produced this answer */ | ||
| agent: string; | ||
| /** Latency in milliseconds */ | ||
| latencyMs: number; | ||
| /** Quality score (0.0-1.0) */ | ||
| quality: number; | ||
| /** Whether this answer was successful */ | ||
| success: boolean; | ||
| /** Error message if failed */ | ||
| error?: string; | ||
| /** Intermediate reasoning/chain-of-thought */ | ||
| reasoning?: string; | ||
| } | ||
| /** | ||
| * Metadata about the RLM execution trajectory | ||
| */ | ||
| export interface RlmTrajectoryMetadata { | ||
| /** Session ID */ | ||
| sessionId?: string; | ||
| /** User ID */ | ||
| userId?: string; | ||
| /** Total latency in milliseconds */ | ||
| totalLatencyMs: number; | ||
| /** Number of retries */ | ||
| retries: number; | ||
| /** Maximum parallel branches executed */ | ||
| maxParallelism: number; | ||
| /** Models used during execution */ | ||
| modelsUsed: string[]; | ||
| /** Agents invoked */ | ||
| agentsInvoked: string[]; | ||
| /** Tools used */ | ||
| toolsUsed: string[]; | ||
| /** Custom attributes */ | ||
| attributes: Record<string, string>; | ||
| } | ||
| /** | ||
| * A complete RLM training example | ||
| */ | ||
| export interface RlmTrainingExample { | ||
| /** Unique identifier */ | ||
| id: string; | ||
| /** Original complex query */ | ||
| query: string; | ||
| /** Query embedding (optional) */ | ||
| queryEmbedding?: number[]; | ||
| /** How the query was decomposed */ | ||
| decomposition: QueryDecomposition; | ||
| /** Answers to each sub-query */ | ||
| subAnswers: SubAnswer[]; | ||
| /** Final synthesized answer */ | ||
| finalAnswer: string; | ||
| /** Final answer embedding (optional) */ | ||
| finalEmbedding?: number[]; | ||
| /** Overall quality score (0.0-1.0) */ | ||
| qualityScore: number; | ||
| /** Execution trajectory metadata */ | ||
| trajectory: RlmTrajectoryMetadata; | ||
| /** Whether this example was successful */ | ||
| success: boolean; | ||
| /** Lessons learned from this example */ | ||
| lessons: string[]; | ||
| /** Source of this example */ | ||
| source: string; | ||
| } | ||
| /** | ||
| * A contrastive pair for agent routing training | ||
| */ | ||
| export interface ContrastivePair { | ||
| /** Anchor query */ | ||
| anchor: string; | ||
| /** Anchor embedding (optional) */ | ||
| anchorEmbedding?: number[]; | ||
| /** Positive agent (correct routing) */ | ||
| positiveAgent: string; | ||
| /** Negative agent (incorrect routing) */ | ||
| negativeAgent: string; | ||
| /** Whether this is a hard negative */ | ||
| isHardNegative: boolean; | ||
| /** Quality score of the anchor example */ | ||
| quality: number; | ||
| /** Source example ID */ | ||
| sourceId: string; | ||
| } | ||
| /** | ||
| * Configuration for RLM training | ||
| */ | ||
| export interface RlmTrainingConfig { | ||
| /** Learning rate for decomposition training */ | ||
| decompositionLr: number; | ||
| /** Learning rate for synthesis training */ | ||
| synthesisLr: number; | ||
| /** Learning rate for contrastive fine-tuning */ | ||
| contrastiveLr: number; | ||
| /** Batch size */ | ||
| batchSize: number; | ||
| /** Number of epochs */ | ||
| epochs: number; | ||
| /** Contrastive margin for triplet loss */ | ||
| contrastiveMargin: number; | ||
| /** Temperature for InfoNCE loss */ | ||
| infonceTemperature: number; | ||
| /** Weight for decomposition loss */ | ||
| decompositionWeight: number; | ||
| /** Weight for synthesis loss */ | ||
| synthesisWeight: number; | ||
| /** Weight for routing loss */ | ||
| routingWeight: number; | ||
| /** Minimum quality for updates */ | ||
| qualityThreshold: number; | ||
| /** Evaluation interval (epochs) */ | ||
| evaluationInterval: number; | ||
| /** Warmup steps */ | ||
| warmupSteps: number; | ||
| /** Early stopping patience */ | ||
| earlyStoppingPatience: number; | ||
| /** Validation split ratio */ | ||
| validationSplit: number; | ||
| /** Random seed */ | ||
| seed: number; | ||
| } | ||
| /** | ||
| * Training result for a phase | ||
| */ | ||
| export interface TrainingResult { | ||
| /** Training phase name */ | ||
| phase: string; | ||
| /** Epochs completed */ | ||
| epochsCompleted: number; | ||
| /** Total steps */ | ||
| totalSteps: number; | ||
| /** Final training loss */ | ||
| finalLoss: number; | ||
| /** Best validation loss */ | ||
| bestValLoss: number; | ||
| /** Best epoch */ | ||
| bestEpoch: number; | ||
| /** Final accuracy (for classification tasks) */ | ||
| accuracy: number; | ||
| /** Loss history per epoch */ | ||
| lossHistory: number[]; | ||
| /** Validation loss history */ | ||
| valLossHistory: number[]; | ||
| /** Training duration in milliseconds */ | ||
| durationMs: number; | ||
| /** Whether early stopping was triggered */ | ||
| earlyStopped: boolean; | ||
| } | ||
| /** | ||
| * Evaluation result for the trained model | ||
| */ | ||
| export interface EvaluationResult { | ||
| /** Decomposition accuracy */ | ||
| decompositionAccuracy: number; | ||
| /** Synthesis quality */ | ||
| synthesisQuality: number; | ||
| /** Routing accuracy */ | ||
| routingAccuracy: number; | ||
| /** Hard negative accuracy */ | ||
| hardNegativeAccuracy: number; | ||
| /** Average latency in ms */ | ||
| avgLatencyMs: number; | ||
| /** Total examples evaluated */ | ||
| totalExamples: number; | ||
| /** Per-agent accuracy */ | ||
| perAgentAccuracy: Record<string, number>; | ||
| } | ||
| /** | ||
| * Default RLM training configuration | ||
| */ | ||
| export declare const DEFAULT_RLM_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Fast training configuration | ||
| */ | ||
| export declare const FAST_RLM_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Thorough training configuration | ||
| */ | ||
| export declare const THOROUGH_RLM_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Routing-focused training configuration | ||
| */ | ||
| export declare const ROUTING_FOCUSED_CONFIG: RlmTrainingConfig; | ||
| /** | ||
| * Agent types with descriptions and keywords | ||
| */ | ||
| export declare const AGENT_DEFINITIONS: Record<string, { | ||
| description: string; | ||
| keywords: string[]; | ||
| }>; | ||
| /** | ||
| * Hard negative pairs (confusable agent combinations) | ||
| */ | ||
| export declare const HARD_NEGATIVE_PAIRS: [string, string][]; | ||
| /** | ||
| * RLM Trainer for RuvLTRA models | ||
| * | ||
| * Provides training capabilities for decomposition, synthesis, and routing tasks. | ||
| */ | ||
| export declare class RlmTrainer { | ||
| private config; | ||
| private currentEpoch; | ||
| private currentStep; | ||
| private bestValLoss; | ||
| private patienceCounter; | ||
| private lossHistory; | ||
| private valLossHistory; | ||
| /** | ||
| * Create a new RLM trainer | ||
| */ | ||
| constructor(config?: Partial<RlmTrainingConfig>); | ||
| /** | ||
| * Train on decomposition task | ||
| * | ||
| * Learns to break complex queries into manageable sub-queries. | ||
| */ | ||
| trainDecomposition(dataset: RlmTrainingExample[]): Promise<TrainingResult>; | ||
| /** | ||
| * Train on synthesis task | ||
| * | ||
| * Learns to combine sub-answers into coherent final responses. | ||
| */ | ||
| trainSynthesis(dataset: RlmTrainingExample[]): Promise<TrainingResult>; | ||
| /** | ||
| * Contrastive fine-tuning for agent routing | ||
| * | ||
| * Uses triplet loss and InfoNCE to improve routing accuracy. | ||
| */ | ||
| trainContrastive(pairs: ContrastivePair[]): Promise<TrainingResult>; | ||
| /** | ||
| * Evaluate trained model on test set | ||
| */ | ||
| evaluate(testSet: RlmTrainingExample[]): Promise<EvaluationResult>; | ||
| /** | ||
| * Generate contrastive pairs from dataset | ||
| */ | ||
| generateContrastivePairs(dataset: RlmTrainingExample[], hardNegativeRatio?: number): ContrastivePair[]; | ||
| private resetState; | ||
| private splitDataset; | ||
| private splitPairs; | ||
| private createBatches; | ||
| private createPairBatches; | ||
| private shuffle; | ||
| private trainDecompositionBatch; | ||
| private trainSynthesisBatch; | ||
| private trainContrastiveBatch; | ||
| private validateDecomposition; | ||
| private validateSynthesis; | ||
| private validateContrastive; | ||
| private computeTripletLoss; | ||
| private computeInfoNCELoss; | ||
| private agentDistance; | ||
| private predictAgent; | ||
| private isHardNegative; | ||
| private findBestEpoch; | ||
| } | ||
| /** | ||
| * Create an RLM trainer with default configuration | ||
| */ | ||
| export declare function createRlmTrainer(config?: Partial<RlmTrainingConfig>): RlmTrainer; | ||
| /** | ||
| * Create an empty RLM training example | ||
| */ | ||
| export declare function createEmptyExample(query: string): RlmTrainingExample; | ||
| /** | ||
| * Create a sub-query | ||
| */ | ||
| export declare function createSubQuery(id: number, query: string, options?: Partial<SubQuery>): SubQuery; | ||
| /** | ||
| * Create a sub-answer | ||
| */ | ||
| export declare function createSubAnswer(subQueryId: number, content: string, agent: string, options?: Partial<SubAnswer>): SubAnswer; | ||
| export default RlmTrainer; | ||
| //# sourceMappingURL=training.d.ts.map |
| {"version":3,"file":"training.d.ts","sourceRoot":"","sources":["../../../src/rlm/training.ts"],"names":[],"mappings":"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"} |
Sorry, the diff of this file is too big to display
| /** | ||
| * RLM (Retrieval Language Model) Type Definitions | ||
| * | ||
| * Types for the recursive retrieval-augmented generation system | ||
| * that breaks down complex queries into sub-queries and synthesizes | ||
| * answers from retrieved memory spans. | ||
| */ | ||
| /** | ||
| * Configuration for the RLM controller | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const config: RlmConfig = { | ||
| * maxDepth: 3, | ||
| * maxSubQueries: 5, | ||
| * tokenBudget: 4096, | ||
| * enableCache: true, | ||
| * cacheTtl: 300000, // 5 minutes | ||
| * retrievalTopK: 10, | ||
| * minQualityScore: 0.7, | ||
| * enableReflection: true, | ||
| * maxReflectionIterations: 2, | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export interface RlmConfig { | ||
| /** Maximum recursion depth for sub-queries (default: 3) */ | ||
| maxDepth?: number; | ||
| /** Maximum number of sub-queries per level (default: 5) */ | ||
| maxSubQueries?: number; | ||
| /** Token budget for generation (default: 4096) */ | ||
| tokenBudget?: number; | ||
| /** Enable response caching (default: true) */ | ||
| enableCache?: boolean; | ||
| /** Cache TTL in milliseconds (default: 300000 = 5 minutes) */ | ||
| cacheTtl?: number; | ||
| /** Number of memory spans to retrieve (default: 10) */ | ||
| retrievalTopK?: number; | ||
| /** Minimum quality score to accept answer (default: 0.7) */ | ||
| minQualityScore?: number; | ||
| /** Enable self-reflection loop (default: false) */ | ||
| enableReflection?: boolean; | ||
| /** Maximum reflection iterations (default: 2) */ | ||
| maxReflectionIterations?: number; | ||
| } | ||
| /** | ||
| * Answer produced by the RLM controller | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const answer: RlmAnswer = { | ||
| * text: 'Machine learning is a subset of artificial intelligence...', | ||
| * confidence: 0.92, | ||
| * qualityScore: 0.88, | ||
| * sources: [ | ||
| * { id: 'mem-1', text: 'ML definition from textbook', similarityScore: 0.95, metadata: {} }, | ||
| * ], | ||
| * subQueries: [ | ||
| * { query: 'What is artificial intelligence?', answer: 'AI is...', depth: 1 }, | ||
| * ], | ||
| * tokenUsage: { prompt: 512, completion: 256, total: 768 }, | ||
| * cached: false, | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export interface RlmAnswer { | ||
| /** The generated answer text */ | ||
| text: string; | ||
| /** Overall confidence in the answer (0.0 - 1.0) */ | ||
| confidence: number; | ||
| /** Quality score based on source coverage and coherence (0.0 - 1.0) */ | ||
| qualityScore: number; | ||
| /** Memory spans used to generate the answer */ | ||
| sources: MemorySpan[]; | ||
| /** Sub-queries generated and answered (if recursive) */ | ||
| subQueries?: SubQuery[]; | ||
| /** Token usage statistics */ | ||
| tokenUsage: TokenUsage; | ||
| /** Whether this answer was served from cache */ | ||
| cached: boolean; | ||
| } | ||
| /** | ||
| * A span of memory retrieved for context | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const span: MemorySpan = { | ||
| * id: 'mem-abc123', | ||
| * text: 'Relevant context from memory...', | ||
| * similarityScore: 0.89, | ||
| * source: 'documentation', | ||
| * metadata: { timestamp: Date.now(), category: 'technical' }, | ||
| * }; | ||
| * ``` | ||
| */ | ||
| export interface MemorySpan { | ||
| /** Unique identifier for the memory span */ | ||
| id: string; | ||
| /** The text content of the memory span */ | ||
| text: string; | ||
| /** Cosine similarity score to the query (0.0 - 1.0) */ | ||
| similarityScore: number; | ||
| /** Optional source identifier (e.g., document name, URL) */ | ||
| source?: string; | ||
| /** Additional metadata associated with this span */ | ||
| metadata: Record<string, unknown>; | ||
| } | ||
| /** | ||
| * A sub-query generated during recursive retrieval | ||
| */ | ||
| export interface SubQuery { | ||
| /** The generated sub-query text */ | ||
| query: string; | ||
| /** The answer to the sub-query */ | ||
| answer: string; | ||
| /** Recursion depth at which this sub-query was generated */ | ||
| depth: number; | ||
| } | ||
| /** | ||
| * Token usage statistics for a query | ||
| */ | ||
| export interface TokenUsage { | ||
| /** Tokens used in the prompt (including context) */ | ||
| prompt: number; | ||
| /** Tokens generated in the completion */ | ||
| completion: number; | ||
| /** Total tokens used (prompt + completion) */ | ||
| total: number; | ||
| } | ||
| /** | ||
| * Streaming token event | ||
| * | ||
| * Discriminated union for streaming responses: | ||
| * - `type: 'token'` - A partial token was generated | ||
| * - `type: 'done'` - Generation complete with final answer | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * for await (const event of controller.queryStream('What is AI?')) { | ||
| * if (event.type === 'token') { | ||
| * process.stdout.write(event.text); | ||
| * } else { | ||
| * console.log('\n\nFinal answer:', event.answer.text); | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| export type StreamToken = { | ||
| /** Token event type */ | ||
| type: 'token'; | ||
| /** The partial text token */ | ||
| text: string; | ||
| /** Always false for token events */ | ||
| done: false; | ||
| } | { | ||
| /** Done event type */ | ||
| type: 'done'; | ||
| /** The complete answer */ | ||
| answer: RlmAnswer; | ||
| /** Always true for done events */ | ||
| done: true; | ||
| }; | ||
| /** | ||
| * Internal cache entry for RLM answers | ||
| */ | ||
| export interface RlmCacheEntry { | ||
| /** The cached answer */ | ||
| answer: RlmAnswer; | ||
| /** Timestamp when the entry was cached */ | ||
| timestamp: number; | ||
| /** Query hash for cache key */ | ||
| queryHash: string; | ||
| } | ||
| /** | ||
| * Reflection result from self-evaluation loop | ||
| */ | ||
| export interface ReflectionResult { | ||
| /** Whether the answer passed reflection criteria */ | ||
| passed: boolean; | ||
| /** Critique of the current answer */ | ||
| critique?: string; | ||
| /** Suggested improvements */ | ||
| suggestions?: string[]; | ||
| /** Updated quality score after reflection */ | ||
| updatedScore: number; | ||
| /** Number of reflection iterations performed */ | ||
| iterations: number; | ||
| } | ||
| //# sourceMappingURL=types.d.ts.map |
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/rlm/types.ts"],"names":[],"mappings":"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"} |
| /** | ||
| * RLM (Retrieval Language Model) Type Definitions | ||
| * | ||
| * Types for the recursive retrieval-augmented generation system | ||
| * that breaks down complex queries into sub-queries and synthesizes | ||
| * answers from retrieved memory spans. | ||
| */ | ||
| export {}; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcmxtL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUkxNIChSZXRyaWV2YWwgTGFuZ3VhZ2UgTW9kZWwpIFR5cGUgRGVmaW5pdGlvbnNcbiAqXG4gKiBUeXBlcyBmb3IgdGhlIHJlY3Vyc2l2ZSByZXRyaWV2YWwtYXVnbWVudGVkIGdlbmVyYXRpb24gc3lzdGVtXG4gKiB0aGF0IGJyZWFrcyBkb3duIGNvbXBsZXggcXVlcmllcyBpbnRvIHN1Yi1xdWVyaWVzIGFuZCBzeW50aGVzaXplc1xuICogYW5zd2VycyBmcm9tIHJldHJpZXZlZCBtZW1vcnkgc3BhbnMuXG4gKi9cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgUkxNIGNvbnRyb2xsZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY29uZmlnOiBSbG1Db25maWcgPSB7XG4gKiAgIG1heERlcHRoOiAzLFxuICogICBtYXhTdWJRdWVyaWVzOiA1LFxuICogICB0b2tlbkJ1ZGdldDogNDA5NixcbiAqICAgZW5hYmxlQ2FjaGU6IHRydWUsXG4gKiAgIGNhY2hlVHRsOiAzMDAwMDAsIC8vIDUgbWludXRlc1xuICogICByZXRyaWV2YWxUb3BLOiAxMCxcbiAqICAgbWluUXVhbGl0eVNjb3JlOiAwLjcsXG4gKiAgIGVuYWJsZVJlZmxlY3Rpb246IHRydWUsXG4gKiAgIG1heFJlZmxlY3Rpb25JdGVyYXRpb25zOiAyLFxuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJsbUNvbmZpZyB7XG4gIC8qKiBNYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aCBmb3Igc3ViLXF1ZXJpZXMgKGRlZmF1bHQ6IDMpICovXG4gIG1heERlcHRoPzogbnVtYmVyO1xuXG4gIC8qKiBNYXhpbXVtIG51bWJlciBvZiBzdWItcXVlcmllcyBwZXIgbGV2ZWwgKGRlZmF1bHQ6IDUpICovXG4gIG1heFN1YlF1ZXJpZXM/OiBudW1iZXI7XG5cbiAgLyoqIFRva2VuIGJ1ZGdldCBmb3IgZ2VuZXJhdGlvbiAoZGVmYXVsdDogNDA5NikgKi9cbiAgdG9rZW5CdWRnZXQ/OiBudW1iZXI7XG5cbiAgLyoqIEVuYWJsZSByZXNwb25zZSBjYWNoaW5nIChkZWZhdWx0OiB0cnVlKSAqL1xuICBlbmFibGVDYWNoZT86IGJvb2xlYW47XG5cbiAgLyoqIENhY2hlIFRUTCBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDMwMDAwMCA9IDUgbWludXRlcykgKi9cbiAgY2FjaGVUdGw/OiBudW1iZXI7XG5cbiAgLyoqIE51bWJlciBvZiBtZW1vcnkgc3BhbnMgdG8gcmV0cmlldmUgKGRlZmF1bHQ6IDEwKSAqL1xuICByZXRyaWV2YWxUb3BLPzogbnVtYmVyO1xuXG4gIC8qKiBNaW5pbXVtIHF1YWxpdHkgc2NvcmUgdG8gYWNjZXB0IGFuc3dlciAoZGVmYXVsdDogMC43KSAqL1xuICBtaW5RdWFsaXR5U2NvcmU/OiBudW1iZXI7XG5cbiAgLyoqIEVuYWJsZSBzZWxmLXJlZmxlY3Rpb24gbG9vcCAoZGVmYXVsdDogZmFsc2UpICovXG4gIGVuYWJsZVJlZmxlY3Rpb24/OiBib29sZWFuO1xuXG4gIC8qKiBNYXhpbXVtIHJlZmxlY3Rpb24gaXRlcmF0aW9ucyAoZGVmYXVsdDogMikgKi9cbiAgbWF4UmVmbGVjdGlvbkl0ZXJhdGlvbnM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQW5zd2VyIHByb2R1Y2VkIGJ5IHRoZSBSTE0gY29udHJvbGxlclxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBhbnN3ZXI6IFJsbUFuc3dlciA9IHtcbiAqICAgdGV4dDogJ01hY2hpbmUgbGVhcm5pbmcgaXMgYSBzdWJzZXQgb2YgYXJ0aWZpY2lhbCBpbnRlbGxpZ2VuY2UuLi4nLFxuICogICBjb25maWRlbmNlOiAwLjkyLFxuICogICBxdWFsaXR5U2NvcmU6IDAuODgsXG4gKiAgIHNvdXJjZXM6IFtcbiAqICAgICB7IGlkOiAnbWVtLTEnLCB0ZXh0OiAnTUwgZGVmaW5pdGlvbiBmcm9tIHRleHRib29rJywgc2ltaWxhcml0eVNjb3JlOiAwLjk1LCBtZXRhZGF0YToge30gfSxcbiAqICAgXSxcbiAqICAgc3ViUXVlcmllczogW1xuICogICAgIHsgcXVlcnk6ICdXaGF0IGlzIGFydGlmaWNpYWwgaW50ZWxsaWdlbmNlPycsIGFuc3dlcjogJ0FJIGlzLi4uJywgZGVwdGg6IDEgfSxcbiAqICAgXSxcbiAqICAgdG9rZW5Vc2FnZTogeyBwcm9tcHQ6IDUxMiwgY29tcGxldGlvbjogMjU2LCB0b3RhbDogNzY4IH0sXG4gKiAgIGNhY2hlZDogZmFsc2UsXG4gKiB9O1xuICogYGBgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmxtQW5zd2VyIHtcbiAgLyoqIFRoZSBnZW5lcmF0ZWQgYW5zd2VyIHRleHQgKi9cbiAgdGV4dDogc3RyaW5nO1xuXG4gIC8qKiBPdmVyYWxsIGNvbmZpZGVuY2UgaW4gdGhlIGFuc3dlciAoMC4wIC0gMS4wKSAqL1xuICBjb25maWRlbmNlOiBudW1iZXI7XG5cbiAgLyoqIFF1YWxpdHkgc2NvcmUgYmFzZWQgb24gc291cmNlIGNvdmVyYWdlIGFuZCBjb2hlcmVuY2UgKDAuMCAtIDEuMCkgKi9cbiAgcXVhbGl0eVNjb3JlOiBudW1iZXI7XG5cbiAgLyoqIE1lbW9yeSBzcGFucyB1c2VkIHRvIGdlbmVyYXRlIHRoZSBhbnN3ZXIgKi9cbiAgc291cmNlczogTWVtb3J5U3BhbltdO1xuXG4gIC8qKiBTdWItcXVlcmllcyBnZW5lcmF0ZWQgYW5kIGFuc3dlcmVkIChpZiByZWN1cnNpdmUpICovXG4gIHN1YlF1ZXJpZXM/OiBTdWJRdWVyeVtdO1xuXG4gIC8qKiBUb2tlbiB1c2FnZSBzdGF0aXN0aWNzICovXG4gIHRva2VuVXNhZ2U6IFRva2VuVXNhZ2U7XG5cbiAgLyoqIFdoZXRoZXIgdGhpcyBhbnN3ZXIgd2FzIHNlcnZlZCBmcm9tIGNhY2hlICovXG4gIGNhY2hlZDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBIHNwYW4gb2YgbWVtb3J5IHJldHJpZXZlZCBmb3IgY29udGV4dFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBzcGFuOiBNZW1vcnlTcGFuID0ge1xuICogICBpZDogJ21lbS1hYmMxMjMnLFxuICogICB0ZXh0OiAnUmVsZXZhbnQgY29udGV4dCBmcm9tIG1lbW9yeS4uLicsXG4gKiAgIHNpbWlsYXJpdHlTY29yZTogMC44OSxcbiAqICAgc291cmNlOiAnZG9jdW1lbnRhdGlvbicsXG4gKiAgIG1ldGFkYXRhOiB7IHRpbWVzdGFtcDogRGF0ZS5ub3coKSwgY2F0ZWdvcnk6ICd0ZWNobmljYWwnIH0sXG4gKiB9O1xuICogYGBgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVtb3J5U3BhbiB7XG4gIC8qKiBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIG1lbW9yeSBzcGFuICovXG4gIGlkOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIG1lbW9yeSBzcGFuICovXG4gIHRleHQ6IHN0cmluZztcblxuICAvKiogQ29zaW5lIHNpbWlsYXJpdHkgc2NvcmUgdG8gdGhlIHF1ZXJ5ICgwLjAgLSAxLjApICovXG4gIHNpbWlsYXJpdHlTY29yZTogbnVtYmVyO1xuXG4gIC8qKiBPcHRpb25hbCBzb3VyY2UgaWRlbnRpZmllciAoZS5nLiwgZG9jdW1lbnQgbmFtZSwgVVJMKSAqL1xuICBzb3VyY2U/OiBzdHJpbmc7XG5cbiAgLyoqIEFkZGl0aW9uYWwgbWV0YWRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc3BhbiAqL1xuICBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbi8qKlxuICogQSBzdWItcXVlcnkgZ2VuZXJhdGVkIGR1cmluZyByZWN1cnNpdmUgcmV0cmlldmFsXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3ViUXVlcnkge1xuICAvKiogVGhlIGdlbmVyYXRlZCBzdWItcXVlcnkgdGV4dCAqL1xuICBxdWVyeTogc3RyaW5nO1xuXG4gIC8qKiBUaGUgYW5zd2VyIHRvIHRoZSBzdWItcXVlcnkgKi9cbiAgYW5zd2VyOiBzdHJpbmc7XG5cbiAgLyoqIFJlY3Vyc2lvbiBkZXB0aCBhdCB3aGljaCB0aGlzIHN1Yi1xdWVyeSB3YXMgZ2VuZXJhdGVkICovXG4gIGRlcHRoOiBudW1iZXI7XG59XG5cbi8qKlxuICogVG9rZW4gdXNhZ2Ugc3RhdGlzdGljcyBmb3IgYSBxdWVyeVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuVXNhZ2Uge1xuICAvKiogVG9rZW5zIHVzZWQgaW4gdGhlIHByb21wdCAoaW5jbHVkaW5nIGNvbnRleHQpICovXG4gIHByb21wdDogbnVtYmVyO1xuXG4gIC8qKiBUb2tlbnMgZ2VuZXJhdGVkIGluIHRoZSBjb21wbGV0aW9uICovXG4gIGNvbXBsZXRpb246IG51bWJlcjtcblxuICAvKiogVG90YWwgdG9rZW5zIHVzZWQgKHByb21wdCArIGNvbXBsZXRpb24pICovXG4gIHRvdGFsOiBudW1iZXI7XG59XG5cbi8qKlxuICogU3RyZWFtaW5nIHRva2VuIGV2ZW50XG4gKlxuICogRGlzY3JpbWluYXRlZCB1bmlvbiBmb3Igc3RyZWFtaW5nIHJlc3BvbnNlczpcbiAqIC0gYHR5cGU6ICd0b2tlbidgIC0gQSBwYXJ0aWFsIHRva2VuIHdhcyBnZW5lcmF0ZWRcbiAqIC0gYHR5cGU6ICdkb25lJ2AgLSBHZW5lcmF0aW9uIGNvbXBsZXRlIHdpdGggZmluYWwgYW5zd2VyXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgY29udHJvbGxlci5xdWVyeVN0cmVhbSgnV2hhdCBpcyBBST8nKSkge1xuICogICBpZiAoZXZlbnQudHlwZSA9PT0gJ3Rva2VuJykge1xuICogICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGV2ZW50LnRleHQpO1xuICogICB9IGVsc2Uge1xuICogICAgIGNvbnNvbGUubG9nKCdcXG5cXG5GaW5hbCBhbnN3ZXI6JywgZXZlbnQuYW5zd2VyLnRleHQpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtVG9rZW4gPVxuICB8IHtcbiAgICAgIC8qKiBUb2tlbiBldmVudCB0eXBlICovXG4gICAgICB0eXBlOiAndG9rZW4nO1xuICAgICAgLyoqIFRoZSBwYXJ0aWFsIHRleHQgdG9rZW4gKi9cbiAgICAgIHRleHQ6IHN0cmluZztcbiAgICAgIC8qKiBBbHdheXMgZmFsc2UgZm9yIHRva2VuIGV2ZW50cyAqL1xuICAgICAgZG9uZTogZmFsc2U7XG4gICAgfVxuICB8IHtcbiAgICAgIC8qKiBEb25lIGV2ZW50IHR5cGUgKi9cbiAgICAgIHR5cGU6ICdkb25lJztcbiAgICAgIC8qKiBUaGUgY29tcGxldGUgYW5zd2VyICovXG4gICAgICBhbnN3ZXI6IFJsbUFuc3dlcjtcbiAgICAgIC8qKiBBbHdheXMgdHJ1ZSBmb3IgZG9uZSBldmVudHMgKi9cbiAgICAgIGRvbmU6IHRydWU7XG4gICAgfTtcblxuLyoqXG4gKiBJbnRlcm5hbCBjYWNoZSBlbnRyeSBmb3IgUkxNIGFuc3dlcnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSbG1DYWNoZUVudHJ5IHtcbiAgLyoqIFRoZSBjYWNoZWQgYW5zd2VyICovXG4gIGFuc3dlcjogUmxtQW5zd2VyO1xuXG4gIC8qKiBUaW1lc3RhbXAgd2hlbiB0aGUgZW50cnkgd2FzIGNhY2hlZCAqL1xuICB0aW1lc3RhbXA6IG51bWJlcjtcblxuICAvKiogUXVlcnkgaGFzaCBmb3IgY2FjaGUga2V5ICovXG4gIHF1ZXJ5SGFzaDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlZmxlY3Rpb24gcmVzdWx0IGZyb20gc2VsZi1ldmFsdWF0aW9uIGxvb3BcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWZsZWN0aW9uUmVzdWx0IHtcbiAgLyoqIFdoZXRoZXIgdGhlIGFuc3dlciBwYXNzZWQgcmVmbGVjdGlvbiBjcml0ZXJpYSAqL1xuICBwYXNzZWQ6IGJvb2xlYW47XG5cbiAgLyoqIENyaXRpcXVlIG9mIHRoZSBjdXJyZW50IGFuc3dlciAqL1xuICBjcml0aXF1ZT86IHN0cmluZztcblxuICAvKiogU3VnZ2VzdGVkIGltcHJvdmVtZW50cyAqL1xuICBzdWdnZXN0aW9ucz86IHN0cmluZ1tdO1xuXG4gIC8qKiBVcGRhdGVkIHF1YWxpdHkgc2NvcmUgYWZ0ZXIgcmVmbGVjdGlvbiAqL1xuICB1cGRhdGVkU2NvcmU6IG51bWJlcjtcblxuICAvKiogTnVtYmVyIG9mIHJlZmxlY3Rpb24gaXRlcmF0aW9ucyBwZXJmb3JtZWQgKi9cbiAgaXRlcmF0aW9uczogbnVtYmVyO1xufVxuIl19 |
| #!/usr/bin/env node | ||
| /** | ||
| * RLM Training Dataset Generator | ||
| * | ||
| * Generates synthetic RLM training examples for task decomposition, | ||
| * answer synthesis, and agent routing. Integrates with ReasoningBank | ||
| * patterns for realistic training data. | ||
| * | ||
| * Usage: | ||
| * node rlm-dataset.js [--output <file>] [--count <n>] [--quality <min>] | ||
| * | ||
| * Example: | ||
| * node rlm-dataset.js --output rlm-training.json --count 1000 --quality 0.7 | ||
| */ | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| const crypto = require('crypto'); | ||
| // Import routing dataset for agent definitions | ||
| const { AGENT_TRAINING_DATA, getDatasetStats } = require('./routing-dataset'); | ||
| // ============================================================================= | ||
| // Configuration | ||
| // ============================================================================= | ||
| const DEFAULT_CONFIG = { | ||
| outputFile: 'rlm-training-dataset.json', | ||
| exampleCount: 500, | ||
| minQuality: 0.6, | ||
| hardNegativeRatio: 0.3, | ||
| maxDecompositionDepth: 5, | ||
| embeddingDim: 768, | ||
| seed: 42, | ||
| }; | ||
| // ============================================================================= | ||
| // Decomposition Strategy Definitions | ||
| // ============================================================================= | ||
| const DECOMPOSITION_STRATEGIES = { | ||
| sequential: { | ||
| name: 'sequential', | ||
| description: 'Steps executed in order, each depending on the previous', | ||
| complexityWeight: 1.5, | ||
| }, | ||
| parallel: { | ||
| name: 'parallel', | ||
| description: 'Independent sub-queries that can run concurrently', | ||
| complexityWeight: 1.5, | ||
| }, | ||
| hierarchical: { | ||
| name: 'hierarchical', | ||
| description: 'Tree structure with parent-child dependencies', | ||
| complexityWeight: 2.0, | ||
| }, | ||
| 'dag-based': { | ||
| name: 'dag-based', | ||
| description: 'Complex DAG with arbitrary dependencies', | ||
| complexityWeight: 3.0, | ||
| }, | ||
| iterative: { | ||
| name: 'iterative', | ||
| description: 'Query -> result -> refined query cycles', | ||
| complexityWeight: 2.5, | ||
| }, | ||
| none: { | ||
| name: 'none', | ||
| description: 'Simple query needing no decomposition', | ||
| complexityWeight: 1.0, | ||
| }, | ||
| }; | ||
| // ============================================================================= | ||
| // Complex Query Templates | ||
| // ============================================================================= | ||
| const COMPLEX_QUERY_TEMPLATES = [ | ||
| // Multi-step development tasks | ||
| { | ||
| template: 'Build a {feature} for the {system} that includes {requirement1} and {requirement2}', | ||
| decomposition: ['research', 'design', 'implement', 'test', 'document'], | ||
| strategy: 'sequential', | ||
| agents: ['researcher', 'architect', 'coder', 'tester', 'documenter'], | ||
| quality: 0.9, | ||
| }, | ||
| { | ||
| template: 'Refactor the {component} to use {pattern} while maintaining backward compatibility', | ||
| decomposition: ['analyze', 'design_refactor', 'implement_changes', 'write_tests', 'review'], | ||
| strategy: 'sequential', | ||
| agents: ['researcher', 'architect', 'coder', 'tester', 'reviewer'], | ||
| quality: 0.85, | ||
| }, | ||
| { | ||
| template: 'Add {feature} support to the application with proper error handling and logging', | ||
| decomposition: ['requirements', 'implementation', 'error_handling', 'logging', 'testing'], | ||
| strategy: 'parallel', | ||
| agents: ['researcher', 'coder', 'coder', 'coder', 'tester'], | ||
| quality: 0.88, | ||
| }, | ||
| { | ||
| template: 'Investigate and fix the performance issue in {component} causing {symptom}', | ||
| decomposition: ['investigate', 'identify_cause', 'design_fix', 'implement_fix', 'verify'], | ||
| strategy: 'sequential', | ||
| agents: ['researcher', 'debugger', 'architect', 'coder', 'tester'], | ||
| quality: 0.82, | ||
| }, | ||
| { | ||
| template: 'Create a comprehensive API for {domain} with authentication, rate limiting, and documentation', | ||
| decomposition: ['design_api', 'implement_endpoints', 'add_auth', 'add_rate_limiting', 'write_docs'], | ||
| strategy: 'hierarchical', | ||
| agents: ['architect', 'coder', 'security-architect', 'coder', 'api-docs'], | ||
| quality: 0.9, | ||
| }, | ||
| { | ||
| template: 'Migrate the {system} from {old_tech} to {new_tech} with minimal downtime', | ||
| decomposition: ['plan_migration', 'prepare_infrastructure', 'migrate_data', 'switch_traffic', 'cleanup'], | ||
| strategy: 'sequential', | ||
| agents: ['planner', 'devops', 'coder', 'devops', 'devops'], | ||
| quality: 0.87, | ||
| }, | ||
| { | ||
| template: 'Implement a {algorithm} for {use_case} optimized for {constraint}', | ||
| decomposition: ['research_approaches', 'design_algorithm', 'implement', 'optimize', 'benchmark'], | ||
| strategy: 'sequential', | ||
| agents: ['researcher', 'architect', 'coder', 'optimizer', 'tester'], | ||
| quality: 0.85, | ||
| }, | ||
| { | ||
| template: 'Set up CI/CD pipeline for {project} with automated testing, security scanning, and deployment', | ||
| decomposition: ['design_pipeline', 'setup_tests', 'add_security', 'configure_deployment', 'document'], | ||
| strategy: 'dag-based', | ||
| agents: ['devops', 'tester', 'security-architect', 'devops', 'documenter'], | ||
| quality: 0.88, | ||
| }, | ||
| { | ||
| template: 'Review and improve the security of {component} following OWASP guidelines', | ||
| decomposition: ['audit_current', 'identify_vulnerabilities', 'plan_fixes', 'implement_fixes', 'verify'], | ||
| strategy: 'sequential', | ||
| agents: ['security-architect', 'security-architect', 'architect', 'coder', 'security-architect'], | ||
| quality: 0.9, | ||
| }, | ||
| { | ||
| template: 'Design and implement a {data_structure} optimized for {operation} operations', | ||
| decomposition: ['research_options', 'design_structure', 'implement', 'write_tests', 'benchmark'], | ||
| strategy: 'sequential', | ||
| agents: ['researcher', 'architect', 'coder', 'tester', 'optimizer'], | ||
| quality: 0.85, | ||
| }, | ||
| ]; | ||
| // Fill-in values for templates | ||
| const TEMPLATE_VALUES = { | ||
| feature: ['dark mode', 'real-time sync', 'offline support', 'multi-language', 'analytics dashboard', 'notification system', 'file upload', 'export functionality'], | ||
| system: ['web application', 'mobile app', 'backend service', 'CLI tool', 'browser extension', 'desktop app'], | ||
| requirement1: ['user authentication', 'data validation', 'error handling', 'caching', 'pagination', 'search'], | ||
| requirement2: ['logging', 'metrics', 'accessibility', 'responsive design', 'keyboard shortcuts', 'undo/redo'], | ||
| component: ['authentication module', 'payment service', 'user profile', 'notification system', 'search engine', 'data pipeline'], | ||
| pattern: ['async/await', 'event sourcing', 'CQRS', 'microservices', 'domain-driven design', 'hexagonal architecture'], | ||
| symptom: ['slow response times', 'high memory usage', 'database connection leaks', 'timeout errors', 'intermittent failures'], | ||
| domain: ['user management', 'inventory', 'payments', 'analytics', 'content management', 'scheduling'], | ||
| old_tech: ['MongoDB', 'Express.js', 'JavaScript', 'REST API', 'monolith', 'SQL Server'], | ||
| new_tech: ['PostgreSQL', 'NestJS', 'TypeScript', 'GraphQL', 'microservices', 'MongoDB'], | ||
| algorithm: ['search algorithm', 'sorting algorithm', 'caching strategy', 'load balancing', 'rate limiting', 'data compression'], | ||
| use_case: ['real-time search', 'batch processing', 'stream processing', 'recommendation engine', 'fraud detection'], | ||
| constraint: ['memory efficiency', 'low latency', 'high throughput', 'horizontal scaling', 'minimal dependencies'], | ||
| project: ['Node.js application', 'React frontend', 'Python service', 'Rust library', 'Go microservice'], | ||
| data_structure: ['priority queue', 'LRU cache', 'trie', 'bloom filter', 'skip list', 'B-tree'], | ||
| operation: ['insert', 'search', 'delete', 'range query', 'bulk update'], | ||
| }; | ||
| // ============================================================================= | ||
| // Hard Negative Pairs (Confusable Agent Combinations) | ||
| // ============================================================================= | ||
| const HARD_NEGATIVE_PAIRS = [ | ||
| ['coder', 'debugger'], | ||
| ['coder', 'refactorer'], | ||
| ['researcher', 'reviewer'], | ||
| ['tester', 'reviewer'], | ||
| ['architect', 'planner'], | ||
| ['documenter', 'api-docs'], | ||
| ['optimizer', 'debugger'], | ||
| ['devops', 'architect'], | ||
| ['security-architect', 'reviewer'], | ||
| ]; | ||
| // ============================================================================= | ||
| // Utility Functions | ||
| // ============================================================================= | ||
| function generateUUID() { | ||
| if (crypto.randomUUID) { | ||
| return crypto.randomUUID(); | ||
| } | ||
| // Fallback for older Node versions | ||
| return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { | ||
| const r = Math.random() * 16 | 0; | ||
| const v = c === 'x' ? r : (r & 0x3 | 0x8); | ||
| return v.toString(16); | ||
| }); | ||
| } | ||
| function seededRandom(seed) { | ||
| let state = seed; | ||
| return function() { | ||
| state = (state * 1103515245 + 12345) & 0x7fffffff; | ||
| return state / 0x7fffffff; | ||
| }; | ||
| } | ||
| function shuffle(array, rng) { | ||
| const shuffled = [...array]; | ||
| for (let i = shuffled.length - 1; i > 0; i--) { | ||
| const j = Math.floor(rng() * (i + 1)); | ||
| [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; | ||
| } | ||
| return shuffled; | ||
| } | ||
| function pickRandom(array, rng) { | ||
| return array[Math.floor(rng() * array.length)]; | ||
| } | ||
| function generateEmbedding(dim, rng) { | ||
| const embedding = []; | ||
| for (let i = 0; i < dim; i++) { | ||
| embedding.push(rng() * 2 - 1); | ||
| } | ||
| // Normalize | ||
| const norm = Math.sqrt(embedding.reduce((sum, v) => sum + v * v, 0)); | ||
| return embedding.map(v => v / norm); | ||
| } | ||
| function isHardNegative(agent1, agent2) { | ||
| return HARD_NEGATIVE_PAIRS.some( | ||
| ([a, b]) => (agent1 === a && agent2 === b) || (agent1 === b && agent2 === a) | ||
| ); | ||
| } | ||
| // ============================================================================= | ||
| // Dataset Generation Functions | ||
| // ============================================================================= | ||
| /** | ||
| * Fill a template with random values | ||
| */ | ||
| function fillTemplate(template, rng) { | ||
| let filled = template; | ||
| for (const [key, values] of Object.entries(TEMPLATE_VALUES)) { | ||
| const regex = new RegExp(`\\{${key}\\}`, 'g'); | ||
| filled = filled.replace(regex, () => pickRandom(values, rng)); | ||
| } | ||
| return filled; | ||
| } | ||
| /** | ||
| * Generate a sub-query from a decomposition step | ||
| */ | ||
| function generateSubQuery(id, step, agent, rng, dependencies = []) { | ||
| const stepDescriptions = { | ||
| research: 'Research best practices and options for', | ||
| design: 'Design the architecture for', | ||
| implement: 'Implement the functionality for', | ||
| test: 'Write comprehensive tests for', | ||
| document: 'Document the implementation of', | ||
| analyze: 'Analyze the current state of', | ||
| design_refactor: 'Design the refactoring approach for', | ||
| implement_changes: 'Implement the refactored code for', | ||
| write_tests: 'Write regression tests for', | ||
| review: 'Review the code quality of', | ||
| requirements: 'Gather and analyze requirements for', | ||
| implementation: 'Build the core implementation of', | ||
| error_handling: 'Add error handling to', | ||
| logging: 'Implement logging for', | ||
| testing: 'Create test suite for', | ||
| investigate: 'Investigate the root cause of', | ||
| identify_cause: 'Identify the specific cause of', | ||
| design_fix: 'Design a fix for', | ||
| implement_fix: 'Implement the fix for', | ||
| verify: 'Verify the fix works for', | ||
| design_api: 'Design the API structure for', | ||
| implement_endpoints: 'Implement API endpoints for', | ||
| add_auth: 'Add authentication to', | ||
| add_rate_limiting: 'Implement rate limiting for', | ||
| write_docs: 'Write API documentation for', | ||
| plan_migration: 'Create migration plan for', | ||
| prepare_infrastructure: 'Prepare infrastructure for', | ||
| migrate_data: 'Migrate data for', | ||
| switch_traffic: 'Switch traffic for', | ||
| cleanup: 'Clean up old resources for', | ||
| research_approaches: 'Research possible approaches for', | ||
| design_algorithm: 'Design the algorithm for', | ||
| optimize: 'Optimize performance of', | ||
| benchmark: 'Benchmark performance of', | ||
| design_pipeline: 'Design CI/CD pipeline for', | ||
| setup_tests: 'Set up automated testing for', | ||
| add_security: 'Add security scanning to', | ||
| configure_deployment: 'Configure deployment for', | ||
| audit_current: 'Audit current security of', | ||
| identify_vulnerabilities: 'Identify vulnerabilities in', | ||
| plan_fixes: 'Plan security fixes for', | ||
| implement_fixes: 'Implement security fixes for', | ||
| research_options: 'Research implementation options for', | ||
| design_structure: 'Design data structure for', | ||
| }; | ||
| const description = stepDescriptions[step] || `Process ${step} for`; | ||
| return { | ||
| id, | ||
| query: `${description} the component`, | ||
| expectedType: agent === 'coder' ? 'code' : agent === 'documenter' || agent === 'api-docs' ? 'documentation' : 'analysis', | ||
| dependencies, | ||
| recommendedAgent: agent, | ||
| complexity: 0.3 + rng() * 0.5, | ||
| context: null, | ||
| }; | ||
| } | ||
| /** | ||
| * Generate sub-answers for sub-queries | ||
| */ | ||
| function generateSubAnswers(subQueries, rng, successRate = 0.9) { | ||
| return subQueries.map(sq => ({ | ||
| subQueryId: sq.id, | ||
| content: `Completed ${sq.query}`, | ||
| confidence: 0.7 + rng() * 0.3, | ||
| agent: sq.recommendedAgent, | ||
| latencyMs: Math.floor(100 + rng() * 2000), | ||
| quality: rng() < successRate ? 0.7 + rng() * 0.3 : 0.3 + rng() * 0.4, | ||
| success: rng() < successRate, | ||
| error: rng() >= successRate ? 'Partial completion' : null, | ||
| reasoning: null, | ||
| })); | ||
| } | ||
| /** | ||
| * Generate dependencies based on strategy | ||
| */ | ||
| function generateDependencies(subQueries, strategy) { | ||
| switch (strategy) { | ||
| case 'sequential': | ||
| return subQueries.map((sq, i) => ({ | ||
| ...sq, | ||
| dependencies: i > 0 ? [i - 1] : [], | ||
| })); | ||
| case 'parallel': | ||
| return subQueries.map(sq => ({ | ||
| ...sq, | ||
| dependencies: [], | ||
| })); | ||
| case 'hierarchical': | ||
| // First query is root, others depend on it or previous | ||
| return subQueries.map((sq, i) => ({ | ||
| ...sq, | ||
| dependencies: i === 0 ? [] : i < 3 ? [0] : [Math.floor(i / 2)], | ||
| })); | ||
| case 'dag-based': | ||
| // Complex dependencies | ||
| return subQueries.map((sq, i) => { | ||
| const deps = []; | ||
| if (i > 0) deps.push(i - 1); | ||
| if (i > 2) deps.push(0); | ||
| return { ...sq, dependencies: deps }; | ||
| }); | ||
| case 'iterative': | ||
| return subQueries.map((sq, i) => ({ | ||
| ...sq, | ||
| dependencies: i > 0 ? [i - 1] : [], | ||
| })); | ||
| default: | ||
| return subQueries; | ||
| } | ||
| } | ||
| /** | ||
| * Generate a single RLM training example | ||
| */ | ||
| function generateExample(config, rng) { | ||
| const template = pickRandom(COMPLEX_QUERY_TEMPLATES, rng); | ||
| const query = fillTemplate(template.template, rng); | ||
| // Generate sub-queries | ||
| let subQueries = template.decomposition.map((step, i) => | ||
| generateSubQuery(i, step, template.agents[i], rng) | ||
| ); | ||
| // Add dependencies based on strategy | ||
| subQueries = generateDependencies(subQueries, template.strategy); | ||
| const strategyDef = DECOMPOSITION_STRATEGIES[template.strategy]; | ||
| const totalComplexity = subQueries.reduce((sum, sq) => sum + sq.complexity, 0) * strategyDef.complexityWeight; | ||
| // Generate decomposition | ||
| const decomposition = { | ||
| subQueries, | ||
| strategy: template.strategy, | ||
| rationale: `Using ${template.strategy} strategy for optimal execution`, | ||
| totalComplexity, | ||
| success: true, | ||
| error: null, | ||
| }; | ||
| // Generate sub-answers | ||
| const subAnswers = generateSubAnswers(subQueries, rng, template.quality); | ||
| // Calculate quality score | ||
| const avgSubAnswerQuality = subAnswers.length > 0 | ||
| ? subAnswers.reduce((sum, a) => sum + a.quality, 0) / subAnswers.length | ||
| : 0; | ||
| const success = subAnswers.every(a => a.success); | ||
| const qualityScore = success | ||
| ? template.quality * (0.9 + rng() * 0.1) | ||
| : template.quality * (0.5 + rng() * 0.3); | ||
| // Generate trajectory metadata | ||
| const trajectory = { | ||
| sessionId: generateUUID(), | ||
| userId: null, | ||
| totalLatencyMs: subAnswers.reduce((sum, a) => sum + a.latencyMs, 0), | ||
| retries: success ? 0 : Math.floor(rng() * 3), | ||
| maxParallelism: template.strategy === 'parallel' ? subQueries.length : 1, | ||
| modelsUsed: ['ruvltra-0.5b'], | ||
| agentsInvoked: [...new Set(subQueries.map(sq => sq.recommendedAgent))], | ||
| toolsUsed: [], | ||
| attributes: {}, | ||
| }; | ||
| return { | ||
| id: generateUUID(), | ||
| query, | ||
| queryEmbedding: generateEmbedding(config.embeddingDim, rng), | ||
| decomposition, | ||
| subAnswers, | ||
| finalAnswer: `Successfully completed: ${query}`, | ||
| finalEmbedding: generateEmbedding(config.embeddingDim, rng), | ||
| qualityScore, | ||
| trajectory, | ||
| success, | ||
| lessons: success ? [] : ['Encountered challenges during execution'], | ||
| source: 'synthetic', | ||
| }; | ||
| } | ||
| /** | ||
| * Generate contrastive pairs from examples | ||
| */ | ||
| function generateContrastivePairs(examples, config, rng) { | ||
| const pairs = []; | ||
| const agents = Object.keys(AGENT_TRAINING_DATA); | ||
| for (const example of examples) { | ||
| for (const subQuery of example.decomposition.subQueries) { | ||
| if (!subQuery.recommendedAgent) continue; | ||
| const positiveAgent = subQuery.recommendedAgent; | ||
| for (const negativeAgent of agents) { | ||
| if (negativeAgent === positiveAgent) continue; | ||
| const isHard = isHardNegative(positiveAgent, negativeAgent); | ||
| // Apply hard negative ratio | ||
| const include = isHard | ||
| ? rng() < config.hardNegativeRatio | ||
| : rng() < (1 - config.hardNegativeRatio) / agents.length; | ||
| if (include) { | ||
| pairs.push({ | ||
| anchor: subQuery.query, | ||
| anchorEmbedding: example.queryEmbedding, | ||
| positiveAgent, | ||
| negativeAgent, | ||
| isHardNegative: isHard, | ||
| quality: example.qualityScore, | ||
| sourceId: example.id, | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return pairs; | ||
| } | ||
| /** | ||
| * Generate the complete RLM dataset | ||
| */ | ||
| function generateRlmDataset(config = {}) { | ||
| const finalConfig = { ...DEFAULT_CONFIG, ...config }; | ||
| const rng = seededRandom(finalConfig.seed); | ||
| console.log('\n============================================================'); | ||
| console.log(' RLM TRAINING DATASET GENERATOR'); | ||
| console.log('============================================================\n'); | ||
| console.log('Configuration:'); | ||
| console.log(` Examples to generate: ${finalConfig.exampleCount}`); | ||
| console.log(` Minimum quality: ${finalConfig.minQuality}`); | ||
| console.log(` Hard negative ratio: ${finalConfig.hardNegativeRatio}`); | ||
| console.log(` Embedding dimension: ${finalConfig.embeddingDim}`); | ||
| console.log(` Random seed: ${finalConfig.seed}`); | ||
| console.log(''); | ||
| // Generate examples | ||
| console.log('Generating examples...'); | ||
| const examples = []; | ||
| let attempts = 0; | ||
| const maxAttempts = finalConfig.exampleCount * 2; | ||
| while (examples.length < finalConfig.exampleCount && attempts < maxAttempts) { | ||
| const example = generateExample(finalConfig, rng); | ||
| if (example.qualityScore >= finalConfig.minQuality) { | ||
| examples.push(example); | ||
| } | ||
| attempts++; | ||
| } | ||
| console.log(` Generated ${examples.length} examples (${attempts} attempts)`); | ||
| // Generate contrastive pairs | ||
| console.log('\nGenerating contrastive pairs...'); | ||
| const contrastivePairs = generateContrastivePairs(examples, finalConfig, rng); | ||
| console.log(` Generated ${contrastivePairs.length} contrastive pairs`); | ||
| // Calculate statistics | ||
| const stats = { | ||
| totalExamples: examples.length, | ||
| successfulExamples: examples.filter(e => e.success).length, | ||
| avgQuality: examples.reduce((sum, e) => sum + e.qualityScore, 0) / examples.length, | ||
| avgDecompositionDepth: examples.reduce((sum, e) => sum + e.decomposition.subQueries.length, 0) / examples.length, | ||
| strategyDistribution: {}, | ||
| agentDistribution: {}, | ||
| contrastivePairs: contrastivePairs.length, | ||
| hardNegativePairs: contrastivePairs.filter(p => p.isHardNegative).length, | ||
| }; | ||
| // Calculate strategy distribution | ||
| for (const example of examples) { | ||
| const strategy = example.decomposition.strategy; | ||
| stats.strategyDistribution[strategy] = (stats.strategyDistribution[strategy] || 0) + 1; | ||
| } | ||
| // Calculate agent distribution | ||
| for (const example of examples) { | ||
| for (const sq of example.decomposition.subQueries) { | ||
| const agent = sq.recommendedAgent; | ||
| stats.agentDistribution[agent] = (stats.agentDistribution[agent] || 0) + 1; | ||
| } | ||
| } | ||
| console.log('\n============================================================'); | ||
| console.log(' DATASET STATISTICS'); | ||
| console.log('============================================================\n'); | ||
| console.log(`Total Examples: ${stats.totalExamples}`); | ||
| console.log(`Successful Examples: ${stats.successfulExamples}`); | ||
| console.log(`Average Quality: ${(stats.avgQuality * 100).toFixed(1)}%`); | ||
| console.log(`Avg Decomposition Depth: ${stats.avgDecompositionDepth.toFixed(1)} steps`); | ||
| console.log(`Contrastive Pairs: ${stats.contrastivePairs}`); | ||
| console.log(`Hard Negative Pairs: ${stats.hardNegativePairs} (${((stats.hardNegativePairs / stats.contrastivePairs) * 100).toFixed(1)}%)`); | ||
| console.log('\nStrategy Distribution:'); | ||
| for (const [strategy, count] of Object.entries(stats.strategyDistribution)) { | ||
| console.log(` ${strategy.padEnd(15)} ${count} (${((count / stats.totalExamples) * 100).toFixed(1)}%)`); | ||
| } | ||
| console.log('\nAgent Distribution:'); | ||
| const sortedAgents = Object.entries(stats.agentDistribution).sort((a, b) => b[1] - a[1]); | ||
| for (const [agent, count] of sortedAgents) { | ||
| console.log(` ${agent.padEnd(20)} ${count}`); | ||
| } | ||
| return { | ||
| examples, | ||
| contrastivePairs, | ||
| stats, | ||
| config: finalConfig, | ||
| }; | ||
| } | ||
| /** | ||
| * Export dataset to JSON file | ||
| */ | ||
| function exportDataset(dataset, outputFile) { | ||
| const output = { | ||
| metadata: { | ||
| generatedAt: new Date().toISOString(), | ||
| version: '1.0.0', | ||
| config: dataset.config, | ||
| stats: dataset.stats, | ||
| }, | ||
| examples: dataset.examples, | ||
| contrastivePairs: dataset.contrastivePairs, | ||
| }; | ||
| fs.writeFileSync(outputFile, JSON.stringify(output, null, 2)); | ||
| console.log(`\nDataset exported to: ${outputFile}`); | ||
| console.log(`File size: ${(fs.statSync(outputFile).size / 1024 / 1024).toFixed(2)} MB`); | ||
| } | ||
| // ============================================================================= | ||
| // CLI Interface | ||
| // ============================================================================= | ||
| function parseArgs(args) { | ||
| const config = { ...DEFAULT_CONFIG }; | ||
| for (let i = 0; i < args.length; i++) { | ||
| const arg = args[i]; | ||
| if (arg === '--output' && args[i + 1]) { | ||
| config.outputFile = args[++i]; | ||
| } else if (arg === '--count' && args[i + 1]) { | ||
| config.exampleCount = parseInt(args[++i], 10); | ||
| } else if (arg === '--quality' && args[i + 1]) { | ||
| config.minQuality = parseFloat(args[++i]); | ||
| } else if (arg === '--seed' && args[i + 1]) { | ||
| config.seed = parseInt(args[++i], 10); | ||
| } else if (arg === '--hard-ratio' && args[i + 1]) { | ||
| config.hardNegativeRatio = parseFloat(args[++i]); | ||
| } else if (arg === '--help' || arg === '-h') { | ||
| console.log(` | ||
| RLM Training Dataset Generator | ||
| Usage: node rlm-dataset.js [options] | ||
| Options: | ||
| --output <file> Output file path (default: rlm-training-dataset.json) | ||
| --count <n> Number of examples to generate (default: 500) | ||
| --quality <min> Minimum quality threshold (default: 0.6) | ||
| --seed <n> Random seed (default: 42) | ||
| --hard-ratio <r> Hard negative pair ratio (default: 0.3) | ||
| --help, -h Show this help message | ||
| Example: | ||
| node rlm-dataset.js --output my-dataset.json --count 1000 --quality 0.7 | ||
| `); | ||
| process.exit(0); | ||
| } | ||
| } | ||
| return config; | ||
| } | ||
| // Main execution | ||
| if (require.main === module) { | ||
| const config = parseArgs(process.argv.slice(2)); | ||
| const dataset = generateRlmDataset(config); | ||
| exportDataset(dataset, config.outputFile); | ||
| } | ||
| // Module exports | ||
| module.exports = { | ||
| generateRlmDataset, | ||
| generateExample, | ||
| generateContrastivePairs, | ||
| exportDataset, | ||
| COMPLEX_QUERY_TEMPLATES, | ||
| DECOMPOSITION_STRATEGIES, | ||
| TEMPLATE_VALUES, | ||
| HARD_NEGATIVE_PAIRS, | ||
| DEFAULT_CONFIG, | ||
| }; |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
2392403
-13.88%135
-12.34%25327
-14.49%251
-48.88%34
9.68%