ruvector 0.1.65 → 0.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cli.js CHANGED
@@ -3916,6 +3916,449 @@ hooksCmd.command('route-enhanced')
3916
3916
  }));
3917
3917
  });
3918
3918
 
3919
+ // ============================================
3920
+ // LEARNING & COMPRESSION COMMANDS (v2.1)
3921
+ // ============================================
3922
+
3923
+ let TensorCompressClass = null;
3924
+ let LearningEngineClass = null;
3925
+
3926
+ function loadLearningModules() {
3927
+ if (LearningEngineClass) return true;
3928
+ try {
3929
+ const core = require('../dist/core/index.js');
3930
+ TensorCompressClass = core.TensorCompress;
3931
+ LearningEngineClass = core.LearningEngine;
3932
+ return true;
3933
+ } catch (e) {
3934
+ return false;
3935
+ }
3936
+ }
3937
+
3938
+ // Learning algorithm configuration
3939
+ hooksCmd.command('learning-config')
3940
+ .description('Configure learning algorithms for different tasks')
3941
+ .option('-t, --task <type>', 'Task type (agent-routing, error-avoidance, confidence-scoring, trajectory-learning, context-ranking, memory-recall)')
3942
+ .option('-a, --algorithm <alg>', 'Algorithm (q-learning, sarsa, double-q, actor-critic, ppo, decision-transformer, monte-carlo, td-lambda, dqn)')
3943
+ .option('-l, --learning-rate <rate>', 'Learning rate (0.0-1.0)', parseFloat)
3944
+ .option('-g, --gamma <gamma>', 'Discount factor (0.0-1.0)', parseFloat)
3945
+ .option('-e, --epsilon <epsilon>', 'Exploration rate (0.0-1.0)', parseFloat)
3946
+ .option('--lambda <lambda>', 'Lambda for TD(λ)', parseFloat)
3947
+ .option('--list', 'List all algorithms and their descriptions')
3948
+ .option('--show', 'Show current configuration')
3949
+ .action(async (opts) => {
3950
+ if (!loadLearningModules()) {
3951
+ console.log(JSON.stringify({ success: false, error: 'Learning modules not available. Run npm run build.' }));
3952
+ return;
3953
+ }
3954
+
3955
+ if (opts.list) {
3956
+ const algorithms = LearningEngineClass.getAlgorithms();
3957
+ console.log(JSON.stringify({
3958
+ success: true,
3959
+ algorithms: algorithms.map(a => ({
3960
+ name: a.algorithm,
3961
+ description: a.description,
3962
+ bestFor: a.bestFor
3963
+ }))
3964
+ }));
3965
+ return;
3966
+ }
3967
+
3968
+ // Load existing intelligence data
3969
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
3970
+ let data = {};
3971
+ try {
3972
+ if (fs.existsSync(dataPath)) {
3973
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
3974
+ }
3975
+ } catch (e) {}
3976
+
3977
+ const engine = new LearningEngineClass();
3978
+ if (data.learning) {
3979
+ engine.import(data.learning);
3980
+ }
3981
+
3982
+ if (opts.show) {
3983
+ const tasks = ['agent-routing', 'error-avoidance', 'confidence-scoring', 'trajectory-learning', 'context-ranking', 'memory-recall'];
3984
+ const configs = {};
3985
+ for (const task of tasks) {
3986
+ configs[task] = engine.getConfig(task);
3987
+ }
3988
+ console.log(JSON.stringify({ success: true, configs }));
3989
+ return;
3990
+ }
3991
+
3992
+ if (!opts.task) {
3993
+ console.log(JSON.stringify({ success: false, error: 'Specify --task or use --list/--show' }));
3994
+ return;
3995
+ }
3996
+
3997
+ const config = {};
3998
+ if (opts.algorithm) config.algorithm = opts.algorithm;
3999
+ if (opts.learningRate !== undefined) config.learningRate = opts.learningRate;
4000
+ if (opts.gamma !== undefined) config.discountFactor = opts.gamma;
4001
+ if (opts.epsilon !== undefined) config.epsilon = opts.epsilon;
4002
+ if (opts.lambda !== undefined) config.lambda = opts.lambda;
4003
+
4004
+ engine.configure(opts.task, config);
4005
+
4006
+ // Save
4007
+ data.learning = engine.export();
4008
+ fs.mkdirSync(path.dirname(dataPath), { recursive: true });
4009
+ fs.writeFileSync(dataPath, JSON.stringify(data, null, 2));
4010
+
4011
+ console.log(JSON.stringify({
4012
+ success: true,
4013
+ task: opts.task,
4014
+ config: engine.getConfig(opts.task)
4015
+ }));
4016
+ });
4017
+
4018
+ // Learning statistics
4019
+ hooksCmd.command('learning-stats')
4020
+ .description('Show learning algorithm statistics and performance')
4021
+ .option('--json', 'Output as JSON')
4022
+ .action(async (opts) => {
4023
+ if (!loadLearningModules()) {
4024
+ console.log(JSON.stringify({ success: false, error: 'Learning modules not available' }));
4025
+ return;
4026
+ }
4027
+
4028
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
4029
+ let data = {};
4030
+ try {
4031
+ if (fs.existsSync(dataPath)) {
4032
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
4033
+ }
4034
+ } catch (e) {}
4035
+
4036
+ const engine = new LearningEngineClass();
4037
+ if (data.learning) {
4038
+ engine.import(data.learning);
4039
+ }
4040
+
4041
+ const summary = engine.getStatsSummary();
4042
+
4043
+ if (opts.json) {
4044
+ console.log(JSON.stringify({ success: true, ...summary }));
4045
+ } else {
4046
+ console.log(chalk.bold.cyan('\n📊 Learning Statistics\n'));
4047
+ console.log(` Best Algorithm: ${chalk.green(summary.bestAlgorithm)}`);
4048
+ console.log(` Total Updates: ${summary.totalUpdates}`);
4049
+ console.log(` Avg Reward: ${summary.avgReward.toFixed(4)}`);
4050
+
4051
+ if (summary.algorithms.length > 0) {
4052
+ console.log(chalk.bold('\n Algorithm Performance:'));
4053
+ for (const alg of summary.algorithms) {
4054
+ console.log(` ${alg.algorithm.padEnd(20)} updates: ${String(alg.updates).padStart(6)} avgReward: ${alg.avgReward.toFixed(3).padStart(8)} convergence: ${alg.convergenceScore.toFixed(3)}`);
4055
+ }
4056
+ }
4057
+ console.log('');
4058
+ }
4059
+ });
4060
+
4061
+ // Manual learning update
4062
+ hooksCmd.command('learning-update')
4063
+ .description('Manually record a learning experience')
4064
+ .requiredOption('-t, --task <type>', 'Task type')
4065
+ .requiredOption('-s, --state <state>', 'Current state')
4066
+ .requiredOption('-a, --action <action>', 'Action taken')
4067
+ .requiredOption('-r, --reward <reward>', 'Reward received', parseFloat)
4068
+ .option('-n, --next-state <state>', 'Next state')
4069
+ .option('-d, --done', 'Episode is done')
4070
+ .action(async (opts) => {
4071
+ if (!loadLearningModules()) {
4072
+ console.log(JSON.stringify({ success: false, error: 'Learning modules not available' }));
4073
+ return;
4074
+ }
4075
+
4076
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
4077
+ let data = {};
4078
+ try {
4079
+ if (fs.existsSync(dataPath)) {
4080
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
4081
+ }
4082
+ } catch (e) {}
4083
+
4084
+ const engine = new LearningEngineClass();
4085
+ if (data.learning) {
4086
+ engine.import(data.learning);
4087
+ }
4088
+
4089
+ const experience = {
4090
+ state: opts.state,
4091
+ action: opts.action,
4092
+ reward: opts.reward,
4093
+ nextState: opts.nextState || opts.state,
4094
+ done: opts.done || false,
4095
+ timestamp: Date.now()
4096
+ };
4097
+
4098
+ const delta = engine.update(opts.task, experience);
4099
+
4100
+ // Save
4101
+ data.learning = engine.export();
4102
+ fs.writeFileSync(dataPath, JSON.stringify(data, null, 2));
4103
+
4104
+ console.log(JSON.stringify({
4105
+ success: true,
4106
+ task: opts.task,
4107
+ experience,
4108
+ delta,
4109
+ algorithm: engine.getConfig(opts.task).algorithm
4110
+ }));
4111
+ });
4112
+
4113
+ // TensorCompress commands
4114
+ hooksCmd.command('compress')
4115
+ .description('Compress pattern storage using TensorCompress')
4116
+ .option('--force', 'Force recompression of all patterns')
4117
+ .option('--stats', 'Show compression statistics only')
4118
+ .action(async (opts) => {
4119
+ if (!loadLearningModules()) {
4120
+ console.log(JSON.stringify({ success: false, error: 'Compression modules not available' }));
4121
+ return;
4122
+ }
4123
+
4124
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
4125
+ let data = {};
4126
+ try {
4127
+ if (fs.existsSync(dataPath)) {
4128
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
4129
+ }
4130
+ } catch (e) {}
4131
+
4132
+ const compress = new TensorCompressClass({
4133
+ autoCompress: false,
4134
+ hotThreshold: 0.8,
4135
+ warmThreshold: 0.4,
4136
+ coolThreshold: 0.1,
4137
+ coldThreshold: 0.01
4138
+ });
4139
+
4140
+ // Import existing compressed data
4141
+ if (data.compressedPatterns) {
4142
+ compress.import(data.compressedPatterns);
4143
+ }
4144
+
4145
+ // Also compress any uncompressed patterns from the regular patterns
4146
+ if (data.patterns && !data.compressedPatterns) {
4147
+ for (const [key, value] of Object.entries(data.patterns)) {
4148
+ if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'number') {
4149
+ compress.store(key, value);
4150
+ }
4151
+ }
4152
+ }
4153
+
4154
+ if (opts.stats) {
4155
+ const stats = compress.getStats();
4156
+ console.log(JSON.stringify({ success: true, ...stats }));
4157
+ return;
4158
+ }
4159
+
4160
+ // Recompress based on access patterns
4161
+ const stats = compress.recompressAll();
4162
+
4163
+ // Save compressed data
4164
+ data.compressedPatterns = compress.export();
4165
+ fs.writeFileSync(dataPath, JSON.stringify(data, null, 2));
4166
+
4167
+ console.log(JSON.stringify({
4168
+ success: true,
4169
+ message: 'Compression complete',
4170
+ ...stats
4171
+ }));
4172
+ });
4173
+
4174
+ hooksCmd.command('compress-stats')
4175
+ .description('Show TensorCompress statistics')
4176
+ .option('--json', 'Output as JSON')
4177
+ .action(async (opts) => {
4178
+ if (!loadLearningModules()) {
4179
+ console.log(JSON.stringify({ success: false, error: 'Compression modules not available' }));
4180
+ return;
4181
+ }
4182
+
4183
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
4184
+ let data = {};
4185
+ try {
4186
+ if (fs.existsSync(dataPath)) {
4187
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
4188
+ }
4189
+ } catch (e) {}
4190
+
4191
+ const compress = new TensorCompressClass({ autoCompress: false });
4192
+ if (data.compressedPatterns) {
4193
+ compress.import(data.compressedPatterns);
4194
+ }
4195
+
4196
+ const stats = compress.getStats();
4197
+
4198
+ if (opts.json) {
4199
+ console.log(JSON.stringify({ success: true, ...stats }));
4200
+ } else {
4201
+ console.log(chalk.bold.cyan('\n📦 TensorCompress Statistics\n'));
4202
+ console.log(` Total Tensors: ${stats.totalTensors}`);
4203
+ console.log(` Original Size: ${(stats.originalBytes / 1024).toFixed(2)} KB`);
4204
+ console.log(` Compressed Size: ${(stats.compressedBytes / 1024).toFixed(2)} KB`);
4205
+ console.log(` Savings: ${chalk.green(stats.savingsPercent.toFixed(1) + '%')}`);
4206
+
4207
+ console.log(chalk.bold('\n By Compression Level:'));
4208
+ console.log(` none (hot): ${stats.byLevel.none}`);
4209
+ console.log(` half (warm): ${stats.byLevel.half}`);
4210
+ console.log(` pq8 (cool): ${stats.byLevel.pq8}`);
4211
+ console.log(` pq4 (cold): ${stats.byLevel.pq4}`);
4212
+ console.log(` binary (archive): ${stats.byLevel.binary}`);
4213
+ console.log('');
4214
+ }
4215
+ });
4216
+
4217
+ // Store embedding with compression
4218
+ hooksCmd.command('compress-store')
4219
+ .description('Store an embedding with adaptive compression')
4220
+ .requiredOption('-k, --key <key>', 'Storage key')
4221
+ .requiredOption('-v, --vector <vector>', 'Vector as JSON array')
4222
+ .option('-l, --level <level>', 'Compression level (none, half, pq8, pq4, binary)')
4223
+ .action(async (opts) => {
4224
+ if (!loadLearningModules()) {
4225
+ console.log(JSON.stringify({ success: false, error: 'Compression modules not available' }));
4226
+ return;
4227
+ }
4228
+
4229
+ let vector;
4230
+ try {
4231
+ vector = JSON.parse(opts.vector);
4232
+ } catch (e) {
4233
+ console.log(JSON.stringify({ success: false, error: 'Invalid vector JSON' }));
4234
+ return;
4235
+ }
4236
+
4237
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
4238
+ let data = {};
4239
+ try {
4240
+ if (fs.existsSync(dataPath)) {
4241
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
4242
+ }
4243
+ } catch (e) {}
4244
+
4245
+ const compress = new TensorCompressClass({ autoCompress: false });
4246
+ if (data.compressedPatterns) {
4247
+ compress.import(data.compressedPatterns);
4248
+ }
4249
+
4250
+ compress.store(opts.key, vector, opts.level);
4251
+
4252
+ data.compressedPatterns = compress.export();
4253
+ fs.mkdirSync(path.dirname(dataPath), { recursive: true });
4254
+ fs.writeFileSync(dataPath, JSON.stringify(data, null, 2));
4255
+
4256
+ const stats = compress.getStats();
4257
+ console.log(JSON.stringify({
4258
+ success: true,
4259
+ key: opts.key,
4260
+ level: opts.level || 'auto',
4261
+ originalDim: vector.length,
4262
+ totalTensors: stats.totalTensors
4263
+ }));
4264
+ });
4265
+
4266
+ // Retrieve compressed embedding
4267
+ hooksCmd.command('compress-get')
4268
+ .description('Retrieve a compressed embedding')
4269
+ .requiredOption('-k, --key <key>', 'Storage key')
4270
+ .action(async (opts) => {
4271
+ if (!loadLearningModules()) {
4272
+ console.log(JSON.stringify({ success: false, error: 'Compression modules not available' }));
4273
+ return;
4274
+ }
4275
+
4276
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
4277
+ let data = {};
4278
+ try {
4279
+ if (fs.existsSync(dataPath)) {
4280
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
4281
+ }
4282
+ } catch (e) {}
4283
+
4284
+ const compress = new TensorCompressClass({ autoCompress: false });
4285
+ if (data.compressedPatterns) {
4286
+ compress.import(data.compressedPatterns);
4287
+ }
4288
+
4289
+ const vector = compress.get(opts.key);
4290
+ if (!vector) {
4291
+ console.log(JSON.stringify({ success: false, error: 'Key not found' }));
4292
+ return;
4293
+ }
4294
+
4295
+ console.log(JSON.stringify({
4296
+ success: true,
4297
+ key: opts.key,
4298
+ vector: Array.from(vector),
4299
+ dimension: vector.length
4300
+ }));
4301
+ });
4302
+
4303
+ // Combined learning action with best algorithm
4304
+ hooksCmd.command('learn')
4305
+ .description('Record learning outcome and get best action recommendation')
4306
+ .requiredOption('-s, --state <state>', 'Current state (e.g., file extension, task type)')
4307
+ .option('-a, --action <action>', 'Action taken')
4308
+ .option('-r, --reward <reward>', 'Reward (-1 to 1)', parseFloat)
4309
+ .option('--actions <actions>', 'Available actions (comma-separated)')
4310
+ .option('-t, --task <type>', 'Task type', 'agent-routing')
4311
+ .action(async (opts) => {
4312
+ if (!loadLearningModules()) {
4313
+ console.log(JSON.stringify({ success: false, error: 'Learning modules not available' }));
4314
+ return;
4315
+ }
4316
+
4317
+ const dataPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
4318
+ let data = {};
4319
+ try {
4320
+ if (fs.existsSync(dataPath)) {
4321
+ data = JSON.parse(fs.readFileSync(dataPath, 'utf-8'));
4322
+ }
4323
+ } catch (e) {}
4324
+
4325
+ const engine = new LearningEngineClass();
4326
+ if (data.learning) {
4327
+ engine.import(data.learning);
4328
+ }
4329
+
4330
+ let result = { success: true };
4331
+
4332
+ // If action and reward provided, record the experience
4333
+ if (opts.action && opts.reward !== undefined) {
4334
+ const experience = {
4335
+ state: opts.state,
4336
+ action: opts.action,
4337
+ reward: opts.reward,
4338
+ nextState: opts.state,
4339
+ done: true,
4340
+ timestamp: Date.now()
4341
+ };
4342
+
4343
+ const delta = engine.update(opts.task, experience);
4344
+ result.recorded = { experience, delta, algorithm: engine.getConfig(opts.task).algorithm };
4345
+ }
4346
+
4347
+ // Get best action recommendation
4348
+ if (opts.actions) {
4349
+ const actions = opts.actions.split(',').map(a => a.trim());
4350
+ const best = engine.getBestAction(opts.task, opts.state, actions);
4351
+ result.recommendation = best;
4352
+ }
4353
+
4354
+ // Save
4355
+ data.learning = engine.export();
4356
+ fs.mkdirSync(path.dirname(dataPath), { recursive: true });
4357
+ fs.writeFileSync(dataPath, JSON.stringify(data, null, 2));
4358
+
4359
+ console.log(JSON.stringify(result));
4360
+ });
4361
+
3919
4362
  // ============================================
3920
4363
  // END NEW CAPABILITY COMMANDS
3921
4364
  // ============================================