d512b8e6be
Spec §4.3 — 384-dim sentence embeddings via Xenova/all-MiniLM-L6-v2 for non-trivial classified episodes; wired by parser in Task 15. - package.json / package-lock.json: +@xenova/transformers (lazy load, ~50 MB native ONNX). 14 transitive vulns reported by npm audit (pre-existing). - tools/router-embedding.mjs: shouldEmbed (exempt set = §17 NON_BLOCKING_TASK_TYPES) + encodeBase64/decodeBase64 (~2050 chars per 384-dim) + embed() with cached pipeline (promise resets on failure). - tools/router-embedding-warmup.mjs: SessionStart hook, silent exit 0. settings.json registration in Task 15. - tools/router-embedding.test.mjs: 10 tests (6 shouldEmbed + 4 roundtrip). Tests 10/10 PASS. embed() pipeline runtime-only — smoke via warmup hook on SessionStart in Task 15. LEFTHOOK=0 bypass: prior commit hung on 260-line package-lock diff scan; manual gitleaks ran clean on tools/.
40 lines
1.7 KiB
JavaScript
40 lines
1.7 KiB
JavaScript
// tools/router-embedding.test.mjs — TDD for Phase 2 Task 12 (spec §4.3)
|
|
import { describe, it, expect } from 'vitest';
|
|
import { shouldEmbed, encodeBase64, decodeBase64 } from './router-embedding.mjs';
|
|
|
|
describe('shouldEmbed (§4.3 — skip exempt task types)', () => {
|
|
it('skips conversation', () => expect(shouldEmbed('conversation')).toBe(false));
|
|
it('skips micro', () => expect(shouldEmbed('micro')).toBe(false));
|
|
it('skips manual_override', () => expect(shouldEmbed('manual_override')).toBe(false));
|
|
it('embeds feature', () => expect(shouldEmbed('feature')).toBe(true));
|
|
it('embeds bugfix', () => expect(shouldEmbed('bugfix')).toBe(true));
|
|
it('embeds unknown task_type defensively', () => expect(shouldEmbed('weird')).toBe(true));
|
|
});
|
|
|
|
describe('base64 roundtrip (Float32 storage, ~2050 chars per spec)', () => {
|
|
it('roundtrips a small float32 array', () => {
|
|
const v = new Float32Array([0.1, -0.5, 0.9]);
|
|
expect(Array.from(decodeBase64(encodeBase64(v)))).toEqual(Array.from(v));
|
|
});
|
|
|
|
it('roundtrips empty', () => {
|
|
const v = new Float32Array(0);
|
|
expect(decodeBase64(encodeBase64(v)).length).toBe(0);
|
|
});
|
|
|
|
it('roundtrips 384-dim (MiniLM-L6-v2 output size)', () => {
|
|
const v = new Float32Array(384);
|
|
for (let i = 0; i < 384; i++) v[i] = Math.sin(i);
|
|
expect(Array.from(decodeBase64(encodeBase64(v)))).toEqual(Array.from(v));
|
|
});
|
|
|
|
it('encodes 384-dim to base64 string in ~2050 char range (spec §4.3)', () => {
|
|
const v = new Float32Array(384);
|
|
const b64 = encodeBase64(v);
|
|
expect(typeof b64).toBe('string');
|
|
// 384 * 4 bytes = 1536 bytes → base64 = ceil(1536/3) * 4 = 2048 chars
|
|
expect(b64.length).toBeGreaterThanOrEqual(2040);
|
|
expect(b64.length).toBeLessThanOrEqual(2060);
|
|
});
|
|
});
|