123 lines
3.5 KiB
JavaScript
123 lines
3.5 KiB
JavaScript
/**
|
|
* Basic NAPI tests for SONA
|
|
*/
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert');
|
|
const { SonaEngine } = require('../index.js');
|
|
|
|
test('SonaEngine creation', () => {
|
|
const engine = new SonaEngine(128);
|
|
assert.ok(engine, 'Engine should be created');
|
|
assert.strictEqual(engine.isEnabled(), true, 'Engine should be enabled by default');
|
|
});
|
|
|
|
test('SonaEngine with custom config', () => {
|
|
const engine = SonaEngine.withConfig({
|
|
hiddenDim: 256,
|
|
microLoraRank: 2,
|
|
baseLoraRank: 8,
|
|
});
|
|
assert.ok(engine, 'Engine should be created with custom config');
|
|
});
|
|
|
|
test('Trajectory recording', () => {
|
|
const engine = new SonaEngine(64);
|
|
const queryEmbedding = Array(64).fill(0.1);
|
|
|
|
const builder = engine.beginTrajectory(queryEmbedding);
|
|
assert.ok(builder, 'TrajectoryBuilder should be created');
|
|
|
|
builder.addStep(Array(64).fill(0.5), Array(32).fill(0.4), 0.8);
|
|
builder.setRoute('test_route');
|
|
builder.addContext('test_context');
|
|
|
|
engine.endTrajectory(builder, 0.85);
|
|
});
|
|
|
|
test('Micro-LoRA application', () => {
|
|
const engine = new SonaEngine(64);
|
|
const input = Array(64).fill(1.0);
|
|
|
|
const output = engine.applyMicroLora(input);
|
|
assert.ok(Array.isArray(output), 'Output should be an array');
|
|
assert.strictEqual(output.length, 64, 'Output should have same dimension as input');
|
|
});
|
|
|
|
test('Base-LoRA application', () => {
|
|
const engine = new SonaEngine(64);
|
|
const input = Array(64).fill(1.0);
|
|
|
|
const output = engine.applyBaseLora(0, input);
|
|
assert.ok(Array.isArray(output), 'Output should be an array');
|
|
assert.strictEqual(output.length, 64, 'Output should have same dimension as input');
|
|
});
|
|
|
|
test('Pattern finding', () => {
|
|
const engine = new SonaEngine(64);
|
|
|
|
// Record some trajectories first
|
|
for (let i = 0; i < 10; i++) {
|
|
const builder = engine.beginTrajectory(Array(64).fill(Math.random()));
|
|
builder.addStep(Array(64).fill(0.5), Array(32).fill(0.4), 0.8);
|
|
engine.endTrajectory(builder, 0.8);
|
|
}
|
|
|
|
// Force learning to extract patterns
|
|
engine.forceLearn();
|
|
|
|
// Find patterns
|
|
const patterns = engine.findPatterns(Array(64).fill(0.5), 5);
|
|
assert.ok(Array.isArray(patterns), 'Patterns should be an array');
|
|
});
|
|
|
|
test('Enable/disable engine', () => {
|
|
const engine = new SonaEngine(64);
|
|
|
|
assert.strictEqual(engine.isEnabled(), true);
|
|
engine.setEnabled(false);
|
|
assert.strictEqual(engine.isEnabled(), false);
|
|
engine.setEnabled(true);
|
|
assert.strictEqual(engine.isEnabled(), true);
|
|
});
|
|
|
|
test('Force learning', () => {
|
|
const engine = new SonaEngine(64);
|
|
|
|
// Record trajectories
|
|
for (let i = 0; i < 5; i++) {
|
|
const builder = engine.beginTrajectory(Array(64).fill(Math.random()));
|
|
builder.addStep(Array(64).fill(0.5), Array(32).fill(0.4), 0.8);
|
|
engine.endTrajectory(builder, 0.8);
|
|
}
|
|
|
|
const result = engine.forceLearn();
|
|
assert.ok(typeof result === 'string', 'Result should be a string');
|
|
assert.ok(result.length > 0, 'Result should not be empty');
|
|
});
|
|
|
|
test('Get statistics', () => {
|
|
const engine = new SonaEngine(64);
|
|
|
|
const stats = engine.getStats();
|
|
assert.ok(typeof stats === 'string', 'Stats should be a string');
|
|
assert.ok(stats.length > 0, 'Stats should not be empty');
|
|
});
|
|
|
|
test('Flush instant updates', () => {
|
|
const engine = new SonaEngine(64);
|
|
|
|
// Should not throw
|
|
assert.doesNotThrow(() => {
|
|
engine.flush();
|
|
});
|
|
});
|
|
|
|
test('Tick background learning', () => {
|
|
const engine = new SonaEngine(64);
|
|
|
|
// May or may not return a message depending on timing
|
|
const result = engine.tick();
|
|
assert.ok(result === null || typeof result === 'string');
|
|
});
|