agentic-qe 3.7.22 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/v3/qe-message-broker-tester.md +3 -3
- package/.claude/agents/v3/qe-middleware-validator.md +3 -3
- package/.claude/agents/v3/qe-odata-contract-tester.md +3 -3
- package/.claude/agents/v3/qe-qx-partner.md +1 -1
- package/.claude/agents/v3/qe-sap-idoc-tester.md +3 -3
- package/.claude/agents/v3/qe-sap-rfc-tester.md +3 -3
- package/.claude/agents/v3/qe-soap-tester.md +3 -3
- package/.claude/agents/v3/qe-sod-analyzer.md +3 -3
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +42 -0
- package/README.md +2 -2
- package/assets/agents/v3/qe-message-broker-tester.md +3 -3
- package/assets/agents/v3/qe-middleware-validator.md +3 -3
- package/assets/agents/v3/qe-odata-contract-tester.md +3 -3
- package/assets/agents/v3/qe-qx-partner.md +1 -1
- package/assets/agents/v3/qe-sap-idoc-tester.md +3 -3
- package/assets/agents/v3/qe-sap-rfc-tester.md +3 -3
- package/assets/agents/v3/qe-soap-tester.md +3 -3
- package/assets/agents/v3/qe-sod-analyzer.md +3 -3
- package/dist/cli/bundle.js +5689 -1244
- package/dist/cli/commands/audit.d.ts +43 -0
- package/dist/cli/commands/audit.js +125 -0
- package/dist/cli/commands/learning.js +106 -1
- package/dist/cli/commands/ruvector-commands.d.ts +15 -0
- package/dist/cli/commands/ruvector-commands.js +271 -0
- package/dist/cli/index.js +4 -0
- package/dist/coordination/behavior-tree/decorators.d.ts +108 -0
- package/dist/coordination/behavior-tree/decorators.js +251 -0
- package/dist/coordination/behavior-tree/index.d.ts +12 -0
- package/dist/coordination/behavior-tree/index.js +15 -0
- package/dist/coordination/behavior-tree/nodes.d.ts +165 -0
- package/dist/coordination/behavior-tree/nodes.js +338 -0
- package/dist/coordination/behavior-tree/qe-trees.d.ts +105 -0
- package/dist/coordination/behavior-tree/qe-trees.js +181 -0
- package/dist/coordination/coherence-action-gate.d.ts +284 -0
- package/dist/coordination/coherence-action-gate.js +512 -0
- package/dist/coordination/index.d.ts +4 -0
- package/dist/coordination/index.js +8 -0
- package/dist/coordination/reasoning-qec.d.ts +315 -0
- package/dist/coordination/reasoning-qec.js +585 -0
- package/dist/coordination/task-executor.d.ts +16 -0
- package/dist/coordination/task-executor.js +99 -0
- package/dist/coordination/workflow-orchestrator.d.ts +29 -0
- package/dist/coordination/workflow-orchestrator.js +42 -0
- package/dist/domains/visual-accessibility/cnn-visual-regression.d.ts +135 -0
- package/dist/domains/visual-accessibility/cnn-visual-regression.js +327 -0
- package/dist/domains/visual-accessibility/index.d.ts +1 -0
- package/dist/domains/visual-accessibility/index.js +4 -0
- package/dist/governance/coherence-validator.d.ts +112 -0
- package/dist/governance/coherence-validator.js +180 -0
- package/dist/governance/index.d.ts +1 -0
- package/dist/governance/index.js +2 -0
- package/dist/governance/witness-chain.d.ts +311 -0
- package/dist/governance/witness-chain.js +509 -0
- package/dist/init/settings-merge.js +1 -1
- package/dist/integrations/browser/qe-dashboard/clustering.d.ts +48 -0
- package/dist/integrations/browser/qe-dashboard/clustering.js +183 -0
- package/dist/integrations/browser/qe-dashboard/index.d.ts +12 -0
- package/dist/integrations/browser/qe-dashboard/index.js +15 -0
- package/dist/integrations/browser/qe-dashboard/pattern-explorer.d.ts +165 -0
- package/dist/integrations/browser/qe-dashboard/pattern-explorer.js +260 -0
- package/dist/integrations/browser/qe-dashboard/wasm-vector-store.d.ts +144 -0
- package/dist/integrations/browser/qe-dashboard/wasm-vector-store.js +277 -0
- package/dist/integrations/ruvector/cognitive-container-codec.d.ts +51 -0
- package/dist/integrations/ruvector/cognitive-container-codec.js +180 -0
- package/dist/integrations/ruvector/cognitive-container.d.ts +125 -0
- package/dist/integrations/ruvector/cognitive-container.js +306 -0
- package/dist/integrations/ruvector/coherence-gate.d.ts +309 -0
- package/dist/integrations/ruvector/coherence-gate.js +631 -0
- package/dist/integrations/ruvector/compressed-hnsw-integration.d.ts +176 -0
- package/dist/integrations/ruvector/compressed-hnsw-integration.js +301 -0
- package/dist/integrations/ruvector/dither-adapter.d.ts +122 -0
- package/dist/integrations/ruvector/dither-adapter.js +295 -0
- package/dist/integrations/ruvector/domain-transfer.d.ts +129 -0
- package/dist/integrations/ruvector/domain-transfer.js +220 -0
- package/dist/integrations/ruvector/feature-flags.d.ts +214 -2
- package/dist/integrations/ruvector/feature-flags.js +167 -2
- package/dist/integrations/ruvector/filter-adapter.d.ts +71 -0
- package/dist/integrations/ruvector/filter-adapter.js +285 -0
- package/dist/integrations/ruvector/gnn-wrapper.d.ts +20 -0
- package/dist/integrations/ruvector/gnn-wrapper.js +40 -0
- package/dist/integrations/ruvector/hnsw-health-monitor.d.ts +237 -0
- package/dist/integrations/ruvector/hnsw-health-monitor.js +394 -0
- package/dist/integrations/ruvector/index.d.ts +8 -2
- package/dist/integrations/ruvector/index.js +18 -2
- package/dist/integrations/ruvector/interfaces.d.ts +40 -0
- package/dist/integrations/ruvector/sona-persistence.d.ts +54 -0
- package/dist/integrations/ruvector/sona-persistence.js +162 -0
- package/dist/integrations/ruvector/sona-three-loop.d.ts +392 -0
- package/dist/integrations/ruvector/sona-three-loop.js +814 -0
- package/dist/integrations/ruvector/sona-wrapper.d.ts +97 -0
- package/dist/integrations/ruvector/sona-wrapper.js +147 -3
- package/dist/integrations/ruvector/spectral-math.d.ts +101 -0
- package/dist/integrations/ruvector/spectral-math.js +254 -0
- package/dist/integrations/ruvector/temporal-compression.d.ts +163 -0
- package/dist/integrations/ruvector/temporal-compression.js +318 -0
- package/dist/integrations/ruvector/thompson-sampler.d.ts +61 -0
- package/dist/integrations/ruvector/thompson-sampler.js +118 -0
- package/dist/integrations/ruvector/transfer-coherence-stub.d.ts +80 -0
- package/dist/integrations/ruvector/transfer-coherence-stub.js +63 -0
- package/dist/integrations/ruvector/transfer-verification.d.ts +119 -0
- package/dist/integrations/ruvector/transfer-verification.js +115 -0
- package/dist/kernel/hnsw-adapter.d.ts +52 -1
- package/dist/kernel/hnsw-adapter.js +139 -4
- package/dist/kernel/hnsw-index-provider.d.ts +5 -0
- package/dist/kernel/native-hnsw-backend.d.ts +110 -0
- package/dist/kernel/native-hnsw-backend.js +408 -0
- package/dist/learning/aqe-learning-engine.d.ts +2 -0
- package/dist/learning/aqe-learning-engine.js +65 -0
- package/dist/learning/experience-capture.d.ts +10 -0
- package/dist/learning/experience-capture.js +34 -0
- package/dist/learning/index.d.ts +2 -0
- package/dist/learning/index.js +4 -0
- package/dist/learning/metrics-tracker.d.ts +11 -0
- package/dist/learning/metrics-tracker.js +14 -0
- package/dist/learning/pattern-lifecycle.d.ts +29 -0
- package/dist/learning/pattern-lifecycle.js +74 -0
- package/dist/learning/pattern-store.d.ts +8 -0
- package/dist/learning/pattern-store.js +8 -2
- package/dist/learning/regret-tracker.d.ts +201 -0
- package/dist/learning/regret-tracker.js +361 -0
- package/dist/mcp/bundle.js +5834 -398
- package/dist/routing/index.d.ts +4 -2
- package/dist/routing/index.js +3 -1
- package/dist/routing/neural-tiny-dancer-router.d.ts +268 -0
- package/dist/routing/neural-tiny-dancer-router.js +514 -0
- package/dist/routing/queen-integration.js +5 -5
- package/dist/routing/routing-config.d.ts +6 -0
- package/dist/routing/routing-config.js +1 -0
- package/dist/routing/simple-neural-router.d.ts +76 -0
- package/dist/routing/simple-neural-router.js +202 -0
- package/dist/routing/tiny-dancer-router.d.ts +20 -1
- package/dist/routing/tiny-dancer-router.js +21 -2
- package/dist/test-scheduling/dag-attention-scheduler.d.ts +81 -0
- package/dist/test-scheduling/dag-attention-scheduler.js +358 -0
- package/dist/test-scheduling/dag-attention-types.d.ts +81 -0
- package/dist/test-scheduling/dag-attention-types.js +10 -0
- package/dist/test-scheduling/index.d.ts +1 -0
- package/dist/test-scheduling/index.js +4 -0
- package/dist/test-scheduling/pipeline.d.ts +8 -0
- package/dist/test-scheduling/pipeline.js +28 -0
- package/package.json +6 -2
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-side WASM Vector Store for QE Dashboard (Task 4.6)
|
|
3
|
+
*
|
|
4
|
+
* Provides a vector store that attempts to load `rvlite` for WASM-based
|
|
5
|
+
* vector search. When unavailable, falls back to a lightweight in-memory
|
|
6
|
+
* vector store with cosine similarity search and namespace support.
|
|
7
|
+
*
|
|
8
|
+
* Design Goals:
|
|
9
|
+
* - No browser-specific APIs (must work in Node.js for testing)
|
|
10
|
+
* - All WASM imports are optional with TypeScript fallback
|
|
11
|
+
* - Efficient cosine similarity computation
|
|
12
|
+
* - Namespace-scoped vector storage
|
|
13
|
+
*
|
|
14
|
+
* @module integrations/browser/qe-dashboard/wasm-vector-store
|
|
15
|
+
*/
|
|
16
|
+
/** Result of a similarity search */
|
|
17
|
+
export interface SearchResult {
|
|
18
|
+
/** Unique identifier for the matched vector */
|
|
19
|
+
id: string;
|
|
20
|
+
/** Cosine similarity score (0..1 for normalized vectors, -1..1 otherwise) */
|
|
21
|
+
similarity: number;
|
|
22
|
+
/** Metadata associated with the vector */
|
|
23
|
+
metadata: Record<string, unknown>;
|
|
24
|
+
/** Namespace the vector belongs to */
|
|
25
|
+
namespace?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Statistics about the vector store */
|
|
28
|
+
export interface StoreStats {
|
|
29
|
+
/** Total number of vectors stored */
|
|
30
|
+
totalVectors: number;
|
|
31
|
+
/** Number of distinct namespaces */
|
|
32
|
+
namespaceCount: number;
|
|
33
|
+
/** Vectors per namespace */
|
|
34
|
+
namespaceSizes: Record<string, number>;
|
|
35
|
+
/** Dimensionality of stored vectors (0 if empty) */
|
|
36
|
+
dimensions: number;
|
|
37
|
+
/** Whether the WASM backend is active */
|
|
38
|
+
wasmActive: boolean;
|
|
39
|
+
/** Approximate memory usage in bytes */
|
|
40
|
+
memoryBytes: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute cosine similarity between two vectors
|
|
44
|
+
*
|
|
45
|
+
* cosine_similarity = dot(a, b) / (||a|| * ||b||)
|
|
46
|
+
*
|
|
47
|
+
* Optimized to accept pre-computed norms for repeated queries.
|
|
48
|
+
*/
|
|
49
|
+
export declare function cosineSimilarity(a: Float32Array, b: Float32Array, normA?: number, normB?: number): number;
|
|
50
|
+
/**
|
|
51
|
+
* Browser-side vector store with optional WASM acceleration.
|
|
52
|
+
*
|
|
53
|
+
* Tries to load `rvlite` for WASM-based vector search. When unavailable,
|
|
54
|
+
* uses a pure TypeScript in-memory implementation with cosine similarity.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const store = new WasmVectorStore();
|
|
59
|
+
* await store.initialize();
|
|
60
|
+
*
|
|
61
|
+
* // Add vectors
|
|
62
|
+
* store.add('pattern-1', new Float32Array([0.1, 0.2, 0.3]), { domain: 'testing' });
|
|
63
|
+
* store.add('pattern-2', new Float32Array([0.4, 0.5, 0.6]), { domain: 'coverage' });
|
|
64
|
+
*
|
|
65
|
+
* // Search
|
|
66
|
+
* const results = store.search(new Float32Array([0.1, 0.2, 0.3]), 5);
|
|
67
|
+
* console.log(results[0].id); // 'pattern-1'
|
|
68
|
+
* console.log(results[0].similarity); // ~1.0
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare class WasmVectorStore {
|
|
72
|
+
private vectors;
|
|
73
|
+
private wasmModule;
|
|
74
|
+
private dimensions;
|
|
75
|
+
private initialized;
|
|
76
|
+
/**
|
|
77
|
+
* Initialize the vector store
|
|
78
|
+
*
|
|
79
|
+
* Attempts to load the WASM backend. Falls back to TypeScript if unavailable.
|
|
80
|
+
* Safe to call multiple times (idempotent).
|
|
81
|
+
*/
|
|
82
|
+
initialize(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Add a vector with optional metadata and namespace
|
|
85
|
+
*
|
|
86
|
+
* @param id - Unique identifier for the vector
|
|
87
|
+
* @param vector - The vector data as Float32Array
|
|
88
|
+
* @param metadata - Optional key-value metadata
|
|
89
|
+
* @param namespace - Optional namespace for scoped queries (default: 'default')
|
|
90
|
+
* @throws Error if vector dimensions are inconsistent
|
|
91
|
+
*/
|
|
92
|
+
add(id: string, vector: Float32Array, metadata?: Record<string, unknown>, namespace?: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Search for the k most similar vectors to a query
|
|
95
|
+
*
|
|
96
|
+
* @param query - The query vector
|
|
97
|
+
* @param k - Number of results to return
|
|
98
|
+
* @param namespace - Optional namespace filter (searches all if omitted)
|
|
99
|
+
* @returns Array of SearchResult sorted by descending similarity
|
|
100
|
+
*/
|
|
101
|
+
search(query: Float32Array, k: number, namespace?: string): SearchResult[];
|
|
102
|
+
/**
|
|
103
|
+
* Remove a vector by id
|
|
104
|
+
*
|
|
105
|
+
* @param id - The vector id to remove
|
|
106
|
+
* @returns true if the vector was found and removed, false otherwise
|
|
107
|
+
*/
|
|
108
|
+
remove(id: string): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Check if a vector exists
|
|
111
|
+
*
|
|
112
|
+
* @param id - The vector id to check
|
|
113
|
+
* @returns true if a vector with this id exists
|
|
114
|
+
*/
|
|
115
|
+
has(id: string): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Get the number of stored vectors
|
|
118
|
+
*/
|
|
119
|
+
get size(): number;
|
|
120
|
+
/**
|
|
121
|
+
* Clear all vectors, optionally within a specific namespace
|
|
122
|
+
*
|
|
123
|
+
* @param namespace - If provided, only clear vectors in this namespace
|
|
124
|
+
*/
|
|
125
|
+
clear(namespace?: string): void;
|
|
126
|
+
/**
|
|
127
|
+
* Get store statistics
|
|
128
|
+
*
|
|
129
|
+
* @returns StoreStats with counts, dimensions, memory usage, etc.
|
|
130
|
+
*/
|
|
131
|
+
getStats(): StoreStats;
|
|
132
|
+
/**
|
|
133
|
+
* Get all vector ids, optionally filtered by namespace
|
|
134
|
+
*
|
|
135
|
+
* @param namespace - Optional namespace filter
|
|
136
|
+
* @returns Array of vector ids
|
|
137
|
+
*/
|
|
138
|
+
getIds(namespace?: string): string[];
|
|
139
|
+
/**
|
|
140
|
+
* Whether the WASM backend is loaded
|
|
141
|
+
*/
|
|
142
|
+
get isWasmActive(): boolean;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=wasm-vector-store.d.ts.map
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-side WASM Vector Store for QE Dashboard (Task 4.6)
|
|
3
|
+
*
|
|
4
|
+
* Provides a vector store that attempts to load `rvlite` for WASM-based
|
|
5
|
+
* vector search. When unavailable, falls back to a lightweight in-memory
|
|
6
|
+
* vector store with cosine similarity search and namespace support.
|
|
7
|
+
*
|
|
8
|
+
* Design Goals:
|
|
9
|
+
* - No browser-specific APIs (must work in Node.js for testing)
|
|
10
|
+
* - All WASM imports are optional with TypeScript fallback
|
|
11
|
+
* - Efficient cosine similarity computation
|
|
12
|
+
* - Namespace-scoped vector storage
|
|
13
|
+
*
|
|
14
|
+
* @module integrations/browser/qe-dashboard/wasm-vector-store
|
|
15
|
+
*/
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Math Utilities
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Compute the L2 norm of a vector
|
|
21
|
+
*/
|
|
22
|
+
function l2Norm(v) {
|
|
23
|
+
let sum = 0;
|
|
24
|
+
for (let i = 0; i < v.length; i++) {
|
|
25
|
+
sum += v[i] * v[i];
|
|
26
|
+
}
|
|
27
|
+
return Math.sqrt(sum);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Compute cosine similarity between two vectors
|
|
31
|
+
*
|
|
32
|
+
* cosine_similarity = dot(a, b) / (||a|| * ||b||)
|
|
33
|
+
*
|
|
34
|
+
* Optimized to accept pre-computed norms for repeated queries.
|
|
35
|
+
*/
|
|
36
|
+
export function cosineSimilarity(a, b, normA, normB) {
|
|
37
|
+
if (a.length !== b.length) {
|
|
38
|
+
throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);
|
|
39
|
+
}
|
|
40
|
+
let dot = 0;
|
|
41
|
+
for (let i = 0; i < a.length; i++) {
|
|
42
|
+
dot += a[i] * b[i];
|
|
43
|
+
}
|
|
44
|
+
const na = normA ?? l2Norm(a);
|
|
45
|
+
const nb = normB ?? l2Norm(b);
|
|
46
|
+
if (na === 0 || nb === 0) {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
return dot / (na * nb);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Attempt to load the rvlite WASM module
|
|
53
|
+
* Returns null if unavailable (expected in most environments)
|
|
54
|
+
*/
|
|
55
|
+
async function tryLoadRvlite() {
|
|
56
|
+
try {
|
|
57
|
+
// Dynamic import - will fail gracefully if rvlite is not installed
|
|
58
|
+
const rvlite = await import('rvlite');
|
|
59
|
+
if (rvlite && typeof rvlite.add === 'function') {
|
|
60
|
+
return rvlite;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Expected: rvlite is not installed in most environments
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// WasmVectorStore
|
|
71
|
+
// ============================================================================
|
|
72
|
+
/**
|
|
73
|
+
* Browser-side vector store with optional WASM acceleration.
|
|
74
|
+
*
|
|
75
|
+
* Tries to load `rvlite` for WASM-based vector search. When unavailable,
|
|
76
|
+
* uses a pure TypeScript in-memory implementation with cosine similarity.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const store = new WasmVectorStore();
|
|
81
|
+
* await store.initialize();
|
|
82
|
+
*
|
|
83
|
+
* // Add vectors
|
|
84
|
+
* store.add('pattern-1', new Float32Array([0.1, 0.2, 0.3]), { domain: 'testing' });
|
|
85
|
+
* store.add('pattern-2', new Float32Array([0.4, 0.5, 0.6]), { domain: 'coverage' });
|
|
86
|
+
*
|
|
87
|
+
* // Search
|
|
88
|
+
* const results = store.search(new Float32Array([0.1, 0.2, 0.3]), 5);
|
|
89
|
+
* console.log(results[0].id); // 'pattern-1'
|
|
90
|
+
* console.log(results[0].similarity); // ~1.0
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export class WasmVectorStore {
|
|
94
|
+
vectors = new Map();
|
|
95
|
+
wasmModule = null;
|
|
96
|
+
dimensions = 0;
|
|
97
|
+
initialized = false;
|
|
98
|
+
/**
|
|
99
|
+
* Initialize the vector store
|
|
100
|
+
*
|
|
101
|
+
* Attempts to load the WASM backend. Falls back to TypeScript if unavailable.
|
|
102
|
+
* Safe to call multiple times (idempotent).
|
|
103
|
+
*/
|
|
104
|
+
async initialize() {
|
|
105
|
+
if (this.initialized)
|
|
106
|
+
return;
|
|
107
|
+
this.wasmModule = await tryLoadRvlite();
|
|
108
|
+
this.initialized = true;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Add a vector with optional metadata and namespace
|
|
112
|
+
*
|
|
113
|
+
* @param id - Unique identifier for the vector
|
|
114
|
+
* @param vector - The vector data as Float32Array
|
|
115
|
+
* @param metadata - Optional key-value metadata
|
|
116
|
+
* @param namespace - Optional namespace for scoped queries (default: 'default')
|
|
117
|
+
* @throws Error if vector dimensions are inconsistent
|
|
118
|
+
*/
|
|
119
|
+
add(id, vector, metadata = {}, namespace = 'default') {
|
|
120
|
+
if (vector.length === 0) {
|
|
121
|
+
throw new Error('Cannot add zero-length vector');
|
|
122
|
+
}
|
|
123
|
+
// Enforce consistent dimensionality
|
|
124
|
+
if (this.dimensions === 0) {
|
|
125
|
+
this.dimensions = vector.length;
|
|
126
|
+
}
|
|
127
|
+
else if (vector.length !== this.dimensions) {
|
|
128
|
+
throw new Error(`Dimension mismatch: expected ${this.dimensions}, got ${vector.length}`);
|
|
129
|
+
}
|
|
130
|
+
// Delegate to WASM if available
|
|
131
|
+
if (this.wasmModule) {
|
|
132
|
+
this.wasmModule.add(id, vector, namespace);
|
|
133
|
+
// Still keep in JS map for metadata lookups
|
|
134
|
+
}
|
|
135
|
+
const norm = l2Norm(vector);
|
|
136
|
+
this.vectors.set(id, { vector, metadata, namespace, norm });
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Search for the k most similar vectors to a query
|
|
140
|
+
*
|
|
141
|
+
* @param query - The query vector
|
|
142
|
+
* @param k - Number of results to return
|
|
143
|
+
* @param namespace - Optional namespace filter (searches all if omitted)
|
|
144
|
+
* @returns Array of SearchResult sorted by descending similarity
|
|
145
|
+
*/
|
|
146
|
+
search(query, k, namespace) {
|
|
147
|
+
if (query.length === 0) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
if (this.vectors.size === 0) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
// Dimension check for query
|
|
154
|
+
if (this.dimensions > 0 && query.length !== this.dimensions) {
|
|
155
|
+
throw new Error(`Query dimension mismatch: expected ${this.dimensions}, got ${query.length}`);
|
|
156
|
+
}
|
|
157
|
+
const queryNorm = l2Norm(query);
|
|
158
|
+
const results = [];
|
|
159
|
+
for (const [id, entry] of this.vectors) {
|
|
160
|
+
// Namespace filter
|
|
161
|
+
if (namespace !== undefined && entry.namespace !== namespace) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const similarity = cosineSimilarity(query, entry.vector, queryNorm, entry.norm);
|
|
165
|
+
results.push({
|
|
166
|
+
id,
|
|
167
|
+
similarity,
|
|
168
|
+
metadata: { ...entry.metadata },
|
|
169
|
+
namespace: entry.namespace,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// Sort by descending similarity
|
|
173
|
+
results.sort((a, b) => b.similarity - a.similarity);
|
|
174
|
+
return results.slice(0, Math.max(0, k));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Remove a vector by id
|
|
178
|
+
*
|
|
179
|
+
* @param id - The vector id to remove
|
|
180
|
+
* @returns true if the vector was found and removed, false otherwise
|
|
181
|
+
*/
|
|
182
|
+
remove(id) {
|
|
183
|
+
if (this.wasmModule) {
|
|
184
|
+
this.wasmModule.remove(id);
|
|
185
|
+
}
|
|
186
|
+
const existed = this.vectors.delete(id);
|
|
187
|
+
// Reset dimensions if store is now empty
|
|
188
|
+
if (this.vectors.size === 0) {
|
|
189
|
+
this.dimensions = 0;
|
|
190
|
+
}
|
|
191
|
+
return existed;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if a vector exists
|
|
195
|
+
*
|
|
196
|
+
* @param id - The vector id to check
|
|
197
|
+
* @returns true if a vector with this id exists
|
|
198
|
+
*/
|
|
199
|
+
has(id) {
|
|
200
|
+
return this.vectors.has(id);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Get the number of stored vectors
|
|
204
|
+
*/
|
|
205
|
+
get size() {
|
|
206
|
+
return this.vectors.size;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Clear all vectors, optionally within a specific namespace
|
|
210
|
+
*
|
|
211
|
+
* @param namespace - If provided, only clear vectors in this namespace
|
|
212
|
+
*/
|
|
213
|
+
clear(namespace) {
|
|
214
|
+
if (namespace === undefined) {
|
|
215
|
+
this.vectors.clear();
|
|
216
|
+
this.dimensions = 0;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
for (const [id, entry] of this.vectors) {
|
|
220
|
+
if (entry.namespace === namespace) {
|
|
221
|
+
this.vectors.delete(id);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (this.vectors.size === 0) {
|
|
225
|
+
this.dimensions = 0;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Get store statistics
|
|
231
|
+
*
|
|
232
|
+
* @returns StoreStats with counts, dimensions, memory usage, etc.
|
|
233
|
+
*/
|
|
234
|
+
getStats() {
|
|
235
|
+
const namespaceSizes = {};
|
|
236
|
+
let memoryBytes = 0;
|
|
237
|
+
for (const [, entry] of this.vectors) {
|
|
238
|
+
const ns = entry.namespace;
|
|
239
|
+
namespaceSizes[ns] = (namespaceSizes[ns] || 0) + 1;
|
|
240
|
+
// Approximate: Float32Array bytes + metadata overhead
|
|
241
|
+
memoryBytes += entry.vector.byteLength + 128;
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
totalVectors: this.vectors.size,
|
|
245
|
+
namespaceCount: Object.keys(namespaceSizes).length,
|
|
246
|
+
namespaceSizes,
|
|
247
|
+
dimensions: this.dimensions,
|
|
248
|
+
wasmActive: this.wasmModule !== null,
|
|
249
|
+
memoryBytes,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get all vector ids, optionally filtered by namespace
|
|
254
|
+
*
|
|
255
|
+
* @param namespace - Optional namespace filter
|
|
256
|
+
* @returns Array of vector ids
|
|
257
|
+
*/
|
|
258
|
+
getIds(namespace) {
|
|
259
|
+
if (namespace === undefined) {
|
|
260
|
+
return Array.from(this.vectors.keys());
|
|
261
|
+
}
|
|
262
|
+
const ids = [];
|
|
263
|
+
for (const [id, entry] of this.vectors) {
|
|
264
|
+
if (entry.namespace === namespace) {
|
|
265
|
+
ids.push(id);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return ids;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Whether the WASM backend is loaded
|
|
272
|
+
*/
|
|
273
|
+
get isWasmActive() {
|
|
274
|
+
return this.wasmModule !== null;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=wasm-vector-store.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cognitive Container Binary Codec (Task 4.1)
|
|
3
|
+
*
|
|
4
|
+
* Binary pack/unpack helpers for the cognitive container format.
|
|
5
|
+
* Separated from cognitive-container.ts to keep each file under 500 lines.
|
|
6
|
+
*
|
|
7
|
+
* Binary layout:
|
|
8
|
+
* [MAGIC 8B][VERSION 4B][MANIFEST_LEN 4B][MANIFEST JSON][SEGMENT DATA...]
|
|
9
|
+
*
|
|
10
|
+
* @module integrations/ruvector/cognitive-container-codec
|
|
11
|
+
*/
|
|
12
|
+
import { Buffer } from 'buffer';
|
|
13
|
+
import Database from 'better-sqlite3';
|
|
14
|
+
import type { ContainerManifest, ContainerSegment } from './cognitive-container.js';
|
|
15
|
+
/** 8-byte magic header: "COGCNTNR" */
|
|
16
|
+
export declare const MAGIC: Buffer<ArrayBuffer>;
|
|
17
|
+
/** Current container format version */
|
|
18
|
+
export declare const FORMAT_VERSION = 2;
|
|
19
|
+
/** Segment names in canonical order */
|
|
20
|
+
export declare const SEGMENT_NAMES: readonly ["patterns", "embeddings", "q-values", "lora-weights", "graph", "witness-chain"];
|
|
21
|
+
export type SegmentName = (typeof SEGMENT_NAMES)[number];
|
|
22
|
+
/** SHA-256 hash of a Buffer, returned as hex. */
|
|
23
|
+
export declare function sha256buf(data: Buffer): string;
|
|
24
|
+
/**
|
|
25
|
+
* Collect all table data from the database, grouped by segment.
|
|
26
|
+
*/
|
|
27
|
+
export declare function collectSegmentData(db: Database.Database, domains?: readonly string[]): Record<SegmentName, Record<string, unknown[]>>;
|
|
28
|
+
/**
|
|
29
|
+
* Serialize a segment's data map to a Buffer, optionally compressed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function serializeSegment(data: Record<string, unknown[]>, compress: boolean): Buffer;
|
|
32
|
+
/**
|
|
33
|
+
* Deserialize a segment Buffer back to its data map.
|
|
34
|
+
*/
|
|
35
|
+
export declare function deserializeSegment(buf: Buffer, compressed: boolean): Record<string, unknown[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Write the container binary from a manifest and segment buffers.
|
|
38
|
+
*/
|
|
39
|
+
export declare function packContainer(manifest: ContainerManifest, segmentBuffers: Buffer[]): Buffer;
|
|
40
|
+
/**
|
|
41
|
+
* Parse the header from container data and return manifest + data offset.
|
|
42
|
+
*/
|
|
43
|
+
export declare function unpackHeader(data: Buffer): {
|
|
44
|
+
manifest: ContainerManifest;
|
|
45
|
+
dataOffset: number;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Extract segment buffers from container data using manifest offsets.
|
|
49
|
+
*/
|
|
50
|
+
export declare function extractSegments(data: Buffer, dataOffset: number, segments: ContainerSegment[]): Map<string, Buffer>;
|
|
51
|
+
//# sourceMappingURL=cognitive-container-codec.d.ts.map
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cognitive Container Binary Codec (Task 4.1)
|
|
3
|
+
*
|
|
4
|
+
* Binary pack/unpack helpers for the cognitive container format.
|
|
5
|
+
* Separated from cognitive-container.ts to keep each file under 500 lines.
|
|
6
|
+
*
|
|
7
|
+
* Binary layout:
|
|
8
|
+
* [MAGIC 8B][VERSION 4B][MANIFEST_LEN 4B][MANIFEST JSON][SEGMENT DATA...]
|
|
9
|
+
*
|
|
10
|
+
* @module integrations/ruvector/cognitive-container-codec
|
|
11
|
+
*/
|
|
12
|
+
import { createHash } from 'crypto';
|
|
13
|
+
import { Buffer } from 'buffer';
|
|
14
|
+
import { gunzipSync, gzipSync } from 'zlib';
|
|
15
|
+
import { queryAll, domainFilterForColumn, serializeRowBlobs, TABLE_CONFIGS, TABLE_BLOB_COLUMNS, } from './brain-shared.js';
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Constants
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/** 8-byte magic header: "COGCNTNR" */
|
|
20
|
+
export const MAGIC = Buffer.from('COGCNTNR', 'ascii');
|
|
21
|
+
/** Current container format version */
|
|
22
|
+
export const FORMAT_VERSION = 2;
|
|
23
|
+
/** Segment names in canonical order */
|
|
24
|
+
export const SEGMENT_NAMES = [
|
|
25
|
+
'patterns',
|
|
26
|
+
'embeddings',
|
|
27
|
+
'q-values',
|
|
28
|
+
'lora-weights',
|
|
29
|
+
'graph',
|
|
30
|
+
'witness-chain',
|
|
31
|
+
];
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Helpers
|
|
34
|
+
// ============================================================================
|
|
35
|
+
/** SHA-256 hash of a Buffer, returned as hex. */
|
|
36
|
+
export function sha256buf(data) {
|
|
37
|
+
return createHash('sha256').update(data).digest('hex');
|
|
38
|
+
}
|
|
39
|
+
/** Table name to segment name mapping. */
|
|
40
|
+
const TABLE_TO_SEGMENT = {
|
|
41
|
+
qe_patterns: 'patterns',
|
|
42
|
+
qe_pattern_embeddings: 'embeddings',
|
|
43
|
+
captured_experiences: 'embeddings',
|
|
44
|
+
sona_patterns: 'embeddings',
|
|
45
|
+
rl_q_values: 'q-values',
|
|
46
|
+
dream_cycles: 'lora-weights',
|
|
47
|
+
dream_insights: 'lora-weights',
|
|
48
|
+
concept_nodes: 'graph',
|
|
49
|
+
concept_edges: 'graph',
|
|
50
|
+
witness_chain: 'witness-chain',
|
|
51
|
+
};
|
|
52
|
+
/** Assign a segment name for a given table. Defaults to 'patterns'. */
|
|
53
|
+
function segmentForTable(tableName) {
|
|
54
|
+
return TABLE_TO_SEGMENT[tableName] ?? 'patterns';
|
|
55
|
+
}
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Data Collection
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Collect all table data from the database, grouped by segment.
|
|
61
|
+
*/
|
|
62
|
+
export function collectSegmentData(db, domains) {
|
|
63
|
+
const segments = {
|
|
64
|
+
'patterns': {},
|
|
65
|
+
'embeddings': {},
|
|
66
|
+
'q-values': {},
|
|
67
|
+
'lora-weights': {},
|
|
68
|
+
'graph': {},
|
|
69
|
+
'witness-chain': {},
|
|
70
|
+
};
|
|
71
|
+
for (const config of TABLE_CONFIGS) {
|
|
72
|
+
const [where, params] = config.domainColumn
|
|
73
|
+
? domainFilterForColumn(domains, config.domainColumn)
|
|
74
|
+
: [undefined, []];
|
|
75
|
+
let rows = queryAll(db, config.tableName, where, params);
|
|
76
|
+
const blobCols = TABLE_BLOB_COLUMNS[config.tableName];
|
|
77
|
+
if (blobCols && blobCols.length > 0) {
|
|
78
|
+
rows = rows.map(r => serializeRowBlobs(r, blobCols));
|
|
79
|
+
}
|
|
80
|
+
const seg = segmentForTable(config.tableName);
|
|
81
|
+
segments[seg][config.tableName] = rows;
|
|
82
|
+
}
|
|
83
|
+
return segments;
|
|
84
|
+
}
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// Segment Serialization
|
|
87
|
+
// ============================================================================
|
|
88
|
+
/**
|
|
89
|
+
* Serialize a segment's data map to a Buffer, optionally compressed.
|
|
90
|
+
*/
|
|
91
|
+
export function serializeSegment(data, compress) {
|
|
92
|
+
const json = JSON.stringify(data);
|
|
93
|
+
const raw = Buffer.from(json, 'utf-8');
|
|
94
|
+
if (compress) {
|
|
95
|
+
return gzipSync(raw);
|
|
96
|
+
}
|
|
97
|
+
return raw;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Deserialize a segment Buffer back to its data map.
|
|
101
|
+
*/
|
|
102
|
+
export function deserializeSegment(buf, compressed) {
|
|
103
|
+
const raw = compressed ? gunzipSync(buf) : buf;
|
|
104
|
+
return JSON.parse(raw.toString('utf-8'));
|
|
105
|
+
}
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// Binary Packing
|
|
108
|
+
// ============================================================================
|
|
109
|
+
/**
|
|
110
|
+
* Write the container binary from a manifest and segment buffers.
|
|
111
|
+
*/
|
|
112
|
+
export function packContainer(manifest, segmentBuffers) {
|
|
113
|
+
const manifestJson = JSON.stringify(manifest);
|
|
114
|
+
const manifestBuf = Buffer.from(manifestJson, 'utf-8');
|
|
115
|
+
const headerLen = MAGIC.length + 4 + 4; // MAGIC(8) + VERSION(4) + MANIFEST_LEN(4)
|
|
116
|
+
const totalDataLen = segmentBuffers.reduce((sum, b) => sum + b.length, 0);
|
|
117
|
+
const totalLen = headerLen + manifestBuf.length + totalDataLen;
|
|
118
|
+
const out = Buffer.alloc(totalLen);
|
|
119
|
+
let pos = 0;
|
|
120
|
+
MAGIC.copy(out, pos);
|
|
121
|
+
pos += MAGIC.length;
|
|
122
|
+
out.writeUInt32BE(FORMAT_VERSION, pos);
|
|
123
|
+
pos += 4;
|
|
124
|
+
out.writeUInt32BE(manifestBuf.length, pos);
|
|
125
|
+
pos += 4;
|
|
126
|
+
manifestBuf.copy(out, pos);
|
|
127
|
+
pos += manifestBuf.length;
|
|
128
|
+
for (const buf of segmentBuffers) {
|
|
129
|
+
buf.copy(out, pos);
|
|
130
|
+
pos += buf.length;
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Parse the header from container data and return manifest + data offset.
|
|
136
|
+
*/
|
|
137
|
+
export function unpackHeader(data) {
|
|
138
|
+
if (data.length < 16) {
|
|
139
|
+
throw new Error('Container too small: missing header');
|
|
140
|
+
}
|
|
141
|
+
const magic = data.subarray(0, MAGIC.length);
|
|
142
|
+
if (!magic.equals(MAGIC)) {
|
|
143
|
+
throw new Error('Invalid container: bad magic bytes');
|
|
144
|
+
}
|
|
145
|
+
const version = data.readUInt32BE(MAGIC.length);
|
|
146
|
+
if (version !== FORMAT_VERSION) {
|
|
147
|
+
throw new Error(`Unsupported container version: ${version}`);
|
|
148
|
+
}
|
|
149
|
+
const manifestLen = data.readUInt32BE(MAGIC.length + 4);
|
|
150
|
+
const manifestStart = MAGIC.length + 8;
|
|
151
|
+
const manifestEnd = manifestStart + manifestLen;
|
|
152
|
+
if (data.length < manifestEnd) {
|
|
153
|
+
throw new Error('Container truncated: manifest extends beyond data');
|
|
154
|
+
}
|
|
155
|
+
const manifestJson = data.subarray(manifestStart, manifestEnd).toString('utf-8');
|
|
156
|
+
let manifest;
|
|
157
|
+
try {
|
|
158
|
+
manifest = JSON.parse(manifestJson);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
throw new Error('Container corrupt: manifest JSON parse failed');
|
|
162
|
+
}
|
|
163
|
+
return { manifest, dataOffset: manifestEnd };
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Extract segment buffers from container data using manifest offsets.
|
|
167
|
+
*/
|
|
168
|
+
export function extractSegments(data, dataOffset, segments) {
|
|
169
|
+
const result = new Map();
|
|
170
|
+
for (const seg of segments) {
|
|
171
|
+
const start = dataOffset + seg.offset;
|
|
172
|
+
const end = start + seg.length;
|
|
173
|
+
if (end > data.length) {
|
|
174
|
+
throw new Error(`Segment '${seg.name}' extends beyond container data`);
|
|
175
|
+
}
|
|
176
|
+
result.set(seg.name, data.subarray(start, end));
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=cognitive-container-codec.js.map
|