vektor-slipstream 1.2.2 → 1.3.0

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/package.json CHANGED
@@ -1,90 +1,114 @@
1
- {
2
- "name": "vektor-slipstream",
3
- "version": "1.2.2",
4
- "description": "Hardware-accelerated persistent memory for AI agents. Local-first, zero cloud dependency, $0 embedding cost.",
5
- "main": "slipstream-core.js",
6
- "bin": {
7
- "vektor": "./vektor-cli.js"
8
- },
9
- "exports": {
10
- ".": "./slipstream-core.js",
11
- "./cloak": "./cloak-index.js",
12
- "./cloak-warmup": "./cloak-warmup.js",
13
- "./db": "./slipstream-db.js",
14
- "./embedder": "./slipstream-embedder.js",
15
- "./cloak-behaviour": "./cloak-behaviour.js",
16
- "./cloak-pattern-store": "./cloak-pattern-store.js",
17
- "./cloak-recorder-auto": "./cloak-recorder-auto.js",
18
- "./cloak-recorder-snippet": "./cloak-recorder-snippet.js",
19
- "./cloak-turbo-quant": "./cloak-turbo-quant.js"
20
- },
21
- "keywords": [
22
- "ai", "memory", "agent", "vector", "sqlite", "embeddings",
23
- "langchain", "openai", "anthropic", "claude", "mcp",
24
- "rag", "persistent-memory", "local-ai", "onnx", "mistral", "cloak"
25
- ],
26
- "author": "VEKTOR Memory <hello@vektormemory.com>",
27
- "license": "SEE LICENSE IN LICENSE",
28
- "homepage": "https://vektormemory.com",
29
- "repository": {
30
- "type": "git",
31
- "url": "https://github.com/Vektor-Memory/Vektor-memory"
32
- },
33
- "engines": {
34
- "node": ">=18.0.0"
35
- },
36
- "dependencies": {
37
- "better-sqlite3": "^12.8.0",
38
- "onnxruntime-node": "^1.17.3"
39
- },
40
- "optionalDependencies": {
41
- "@anthropic-ai/sdk": "^0.82.0",
42
- "@xenova/transformers": "^2.17.2",
43
- "playwright": "^1.44.0",
44
- "blessed": "^0.1.81",
45
- "blessed-contrib": "^4.11.0",
46
- "sqlite-vec-darwin-arm64": "^0.1.6",
47
- "sqlite-vec-linux-x64": "^0.1.6",
48
- "sqlite-vec-windows-x64": "^0.1.6"
49
- },
50
- "files": [
51
- "slipstream-core.js",
52
- "slipstream-db.js",
53
- "slipstream-embedder.js",
54
- "detect-hardware.js",
55
- "vektor-licence.js",
56
- "vektor-licence-prompt.js",
57
- "vektor-cli.js",
58
- "vektor-setup.js",
59
- "vektor-banner-loader.js",
60
- "vektor-tui.js",
61
- "boot-screen.html",
62
- "cloak-core.js",
63
- "cloak-index.js",
64
- "cloak-identity.js",
65
- "cloak-captcha.js",
66
- "cloak-llms.js",
67
- "cloak-turbo-quant.js",
68
- "cloak-warmup.js",
69
- "cloak-behaviour.js",
70
- "cloak-recorder-snippet.js",
71
- "cloak-pattern-store.js",
72
- "cloak-recorder-auto.js",
73
- "sovereign.js",
74
- "visualize.js",
75
- "TENETS.md",
76
- "README.md",
77
- "LICENSE",
78
- "models/model_quantized.onnx",
79
- "models/vocab.json",
80
- "examples/",
81
- "mistral/"
82
- ],
83
- "publishConfig": {
84
- "access": "public"
85
- },
86
- "devDependencies": {
87
- "javascript-obfuscator": "^5.4.1"
88
- }
89
- }
90
-
1
+ {
2
+ "name": "vektor-slipstream",
3
+ "version": "1.3.0",
4
+ "description": "Hardware-accelerated persistent memory for AI agents. Local-first, zero cloud dependency, $0 embedding cost.",
5
+ "main": "slipstream-core.js",
6
+ "bin": {
7
+ "vektor": "./vektor-cli.js"
8
+ },
9
+ "exports": {
10
+ ".": "./slipstream-core.js",
11
+ "./cloak": "./cloak-index.js",
12
+ "./cloak-warmup": "./cloak-warmup.js",
13
+ "./db": "./slipstream-db.js",
14
+ "./embedder": "./slipstream-embedder.js",
15
+ "./cloak-behaviour": "./cloak-behaviour.js",
16
+ "./cloak-pattern-store": "./cloak-pattern-store.js",
17
+ "./cloak-recorder-auto": "./cloak-recorder-auto.js",
18
+ "./cloak-recorder-snippet": "./cloak-recorder-snippet.js",
19
+ "./cloak-turbo-quant": "./cloak-turbo-quant.js",
20
+ "./cloak/cortex": "./cortex.js",
21
+ "./cloak/axon": "./axon.js",
22
+ "./cloak/cerebellum": "./cerebellum.js",
23
+ "./cloak/token": "./token.js",
24
+ "./cloak/mcp": "./index.js"
25
+ },
26
+ "keywords": [
27
+ "ai",
28
+ "memory",
29
+ "agent",
30
+ "vector",
31
+ "sqlite",
32
+ "embeddings",
33
+ "langchain",
34
+ "openai",
35
+ "anthropic",
36
+ "claude",
37
+ "mcp",
38
+ "rag",
39
+ "persistent-memory",
40
+ "local-ai",
41
+ "onnx",
42
+ "mistral",
43
+ "cloak"
44
+ ],
45
+ "author": "VEKTOR Memory <hello@vektormemory.com>",
46
+ "license": "SEE LICENSE IN LICENSE",
47
+ "homepage": "https://vektormemory.com",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/Vektor-Memory/Vektor-memory"
51
+ },
52
+ "engines": {
53
+ "node": ">=18.0.0"
54
+ },
55
+ "dependencies": {
56
+ "better-sqlite3": "^12.8.0",
57
+ "onnxruntime-node": "^1.17.3"
58
+ },
59
+ "optionalDependencies": {
60
+ "@anthropic-ai/sdk": "^0.82.0",
61
+ "@xenova/transformers": "^2.17.2",
62
+ "playwright": "^1.44.0",
63
+ "blessed": "^0.1.81",
64
+ "blessed-contrib": "^4.11.0",
65
+ "sqlite-vec-darwin-arm64": "^0.1.6",
66
+ "sqlite-vec-linux-x64": "^0.1.6",
67
+ "sqlite-vec-windows-x64": "^0.1.6"
68
+ },
69
+ "files": [
70
+ "slipstream-core.js",
71
+ "slipstream-db.js",
72
+ "slipstream-embedder.js",
73
+ "detect-hardware.js",
74
+ "vektor-licence.js",
75
+ "vektor-licence-prompt.js",
76
+ "vektor-cli.js",
77
+ "vektor-setup.js",
78
+ "vektor-banner-loader.js",
79
+ "vektor-tui.js",
80
+ "boot-screen.html",
81
+ "cloak-core.js",
82
+ "cloak-index.js",
83
+ "cloak-identity.js",
84
+ "cloak-captcha.js",
85
+ "cloak-llms.js",
86
+ "cloak-turbo-quant.js",
87
+ "cloak-warmup.js",
88
+ "cloak-behaviour.js",
89
+ "cloak-recorder-snippet.js",
90
+ "cloak-pattern-store.js",
91
+ "cloak-recorder-auto.js",
92
+ "sovereign.js",
93
+ "visualize.js",
94
+ "TENETS.md",
95
+ "README.md",
96
+ "LICENSE",
97
+ "cortex.js",
98
+ "axon.js",
99
+ "cerebellum.js",
100
+ "token.js",
101
+ "index.js",
102
+ "models/model_quantized.onnx",
103
+ "models/vocab.json",
104
+ "examples/",
105
+ "mistral/",
106
+ "vektor-slipstream.dxt"
107
+ ],
108
+ "publishConfig": {
109
+ "access": "public"
110
+ },
111
+ "devDependencies": {
112
+ "javascript-obfuscator": "^5.4.1"
113
+ }
114
+ }
package/token.js ADDED
@@ -0,0 +1,322 @@
1
+ /**
2
+ * cloak_token.js
3
+ * Token ledger — aggregates context budget consumption per session.
4
+ * Writes ONE summary node per session end (via cloak_axon integration).
5
+ * Detects waste patterns: repeated reads, oversized context injections.
6
+ *
7
+ * Design principles:
8
+ * - Aggregated, not per-operation. Never writes on every read/write.
9
+ * - Session total written ONCE at Stop (passed to cloak_axon's tokenCount).
10
+ * - Waste patterns flagged at session end, not in real time.
11
+ * - Uses character-to-token ratios (OpenWolf method, ±15% accurate).
12
+ *
13
+ * Architecture: CLOAK layer → Vektor temporal graph
14
+ * Research: OpenWolf token-ledger pattern
15
+ */
16
+
17
+ 'use strict';
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // Token estimation ratios (same as cortex.js for consistency)
21
+ // ---------------------------------------------------------------------------
22
+ const TOKEN_RATIOS = {
23
+ code : 3.5,
24
+ prose: 4.0,
25
+ mixed: 3.75,
26
+ };
27
+
28
+ const CODE_EXTS = new Set(['.js','.ts','.jsx','.tsx','.py','.go','.rs','.rb','.java','.c','.cpp']);
29
+
30
+ function estimateTokens(content, filePath = '') {
31
+ if (!content) return 0;
32
+ const ext = (filePath.match(/\.[^.]+$/) || [''])[0].toLowerCase();
33
+ const bytes = Buffer.byteLength(String(content), 'utf8');
34
+ if (CODE_EXTS.has(ext)) return Math.round(bytes / TOKEN_RATIOS.code);
35
+ return Math.round(bytes / TOKEN_RATIOS.mixed);
36
+ }
37
+
38
+ // ---------------------------------------------------------------------------
39
+ // In-RAM session ledger
40
+ // ---------------------------------------------------------------------------
41
+ const _ledger = {
42
+ sessionId : null,
43
+ reads : [], // { file, tokens, ts }
44
+ writes : [], // { file, tokens, ts }
45
+ wasteEvents : [], // { type, description, tokens_wasted }
46
+ totalReadTokens : 0,
47
+ totalWriteTokens: 0,
48
+ };
49
+
50
+ function _resetLedger() {
51
+ _ledger.sessionId = null;
52
+ _ledger.reads = [];
53
+ _ledger.writes = [];
54
+ _ledger.wasteEvents = [];
55
+ _ledger.totalReadTokens = 0;
56
+ _ledger.totalWriteTokens = 0;
57
+ }
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // Waste detection thresholds
61
+ // ---------------------------------------------------------------------------
62
+ const WASTE_RULES = {
63
+ REPEATED_READ_THRESHOLD : 2, // same file read > 2x = waste
64
+ LARGE_READ_THRESHOLD : 2000, // reading >2000 tokens when anatomy would suffice
65
+ REPEATED_READ_PENALTY : 0.8, // assume 80% of repeated read tokens are wasted
66
+ };
67
+
68
+ // ---------------------------------------------------------------------------
69
+ // Session lifecycle
70
+ // ---------------------------------------------------------------------------
71
+
72
+ /**
73
+ * startSession(sessionId)
74
+ * Called from cloak_axon onSessionStart. Resets ledger for new session.
75
+ */
76
+ function startSession(sessionId) {
77
+ _resetLedger();
78
+ _ledger.sessionId = sessionId;
79
+ }
80
+
81
+ // ---------------------------------------------------------------------------
82
+ // Event tracking — called from hook integration
83
+ // ---------------------------------------------------------------------------
84
+
85
+ /**
86
+ * trackRead({ filePath, content })
87
+ * Record a file read. Detects repeated reads and large reads.
88
+ */
89
+ function trackRead({ filePath, content } = {}) {
90
+ if (!_ledger.sessionId) return;
91
+
92
+ const tokens = estimateTokens(content, filePath);
93
+ const file = filePath || 'unknown';
94
+ const ts = Date.now();
95
+
96
+ _ledger.reads.push({ file, tokens, ts });
97
+ _ledger.totalReadTokens += tokens;
98
+
99
+ // Detect repeated reads of same file this session
100
+ const readCount = _ledger.reads.filter(r => r.file === file).length;
101
+ if (readCount > WASTE_RULES.REPEATED_READ_THRESHOLD) {
102
+ const wastedTokens = Math.round(tokens * WASTE_RULES.REPEATED_READ_PENALTY);
103
+ _ledger.wasteEvents.push({
104
+ type : 'repeated_read',
105
+ description : `${file} read ${readCount}x this session`,
106
+ tokens_wasted : wastedTokens,
107
+ recommendation : 'Use cloak_cortex anatomy to check file before re-reading',
108
+ });
109
+ }
110
+
111
+ // Detect large reads that cortex anatomy could have avoided
112
+ if (tokens > WASTE_RULES.LARGE_READ_THRESHOLD) {
113
+ _ledger.wasteEvents.push({
114
+ type : 'large_read',
115
+ description : `${file} read at ~${tokens} tokens`,
116
+ tokens_wasted : Math.round(tokens * 0.5), // assume 50% avoidable
117
+ recommendation : 'Check cloak_cortex anatomy description first',
118
+ });
119
+ }
120
+ }
121
+
122
+ /**
123
+ * trackWrite({ filePath, content })
124
+ * Record a file write.
125
+ */
126
+ function trackWrite({ filePath, content } = {}) {
127
+ if (!_ledger.sessionId) return;
128
+
129
+ const tokens = estimateTokens(content, filePath);
130
+ _ledger.writes.push({ file: filePath || 'unknown', tokens, ts: Date.now() });
131
+ _ledger.totalWriteTokens += tokens;
132
+ }
133
+
134
+ // ---------------------------------------------------------------------------
135
+ // Session summary — called at session end, returns total for cloak_axon
136
+ // ---------------------------------------------------------------------------
137
+
138
+ /**
139
+ * getSessionSummary()
140
+ * Returns aggregated stats for the current session.
141
+ * This is passed as tokenCount to cloak_axon.onSessionStop().
142
+ */
143
+ function getSessionSummary() {
144
+ if (!_ledger.sessionId) return null;
145
+
146
+ const totalTokens = _ledger.totalReadTokens + _ledger.totalWriteTokens;
147
+ const totalWasted = _ledger.wasteEvents.reduce((sum, e) => sum + (e.tokens_wasted || 0), 0);
148
+ const wasteRate = totalTokens > 0 ? Math.round((totalWasted / totalTokens) * 100) : 0;
149
+
150
+ // Top files by token consumption
151
+ const fileTotals = {};
152
+ [..._ledger.reads, ..._ledger.writes].forEach(({ file, tokens }) => {
153
+ fileTotals[file] = (fileTotals[file] || 0) + tokens;
154
+ });
155
+ const topFiles = Object.entries(fileTotals)
156
+ .sort((a, b) => b[1] - a[1])
157
+ .slice(0, 5)
158
+ .map(([file, tokens]) => `${file}:~${tokens}t`);
159
+
160
+ return {
161
+ sessionId : _ledger.sessionId,
162
+ totalTokens,
163
+ readTokens : _ledger.totalReadTokens,
164
+ writeTokens : _ledger.totalWriteTokens,
165
+ wastedTokens : totalWasted,
166
+ wasteRate : `${wasteRate}%`,
167
+ wasteEvents : _ledger.wasteEvents.length,
168
+ topFiles,
169
+ readCount : _ledger.reads.length,
170
+ writeCount : _ledger.writes.length,
171
+ uniqueFilesRead : new Set(_ledger.reads.map(r => r.file)).size,
172
+ uniqueFilesWritten: new Set(_ledger.writes.map(w => w.file)).size,
173
+ };
174
+ }
175
+
176
+ // ---------------------------------------------------------------------------
177
+ // Temporal graph node builder — ONE write per session
178
+ // This is called by cloak_axon at session stop, not by token.js directly.
179
+ // ---------------------------------------------------------------------------
180
+
181
+ /**
182
+ * buildTokenNode(summary)
183
+ * Builds the Vektor memory string for the temporal graph.
184
+ * cloak_axon calls this and includes it in the MemCell, OR it can be
185
+ * written as a standalone temporal node. Either way: one write per session.
186
+ */
187
+ function buildTokenNode(summary) {
188
+ if (!summary) return null;
189
+
190
+ return [
191
+ `[CLOAK_TOKEN_LEDGER]`,
192
+ `session:${summary.sessionId}`,
193
+ `total_tokens:~${summary.totalTokens}`,
194
+ `read_tokens:~${summary.readTokens}`,
195
+ `write_tokens:~${summary.writeTokens}`,
196
+ `wasted_tokens:~${summary.wastedTokens}`,
197
+ `waste_rate:${summary.wasteRate}`,
198
+ `waste_events:${summary.wasteEvents}`,
199
+ `top_files:${summary.topFiles.join(',')}`,
200
+ `logged_at:${new Date().toISOString()}`,
201
+ ].join(' | ');
202
+ }
203
+
204
+ // ---------------------------------------------------------------------------
205
+ // Lifetime waste report — queries Vektor for historical patterns
206
+ // ---------------------------------------------------------------------------
207
+
208
+ /**
209
+ * getWasteReport({ memory, days })
210
+ * Queries Vektor temporal graph for token waste patterns over N days.
211
+ * Returns actionable recommendations. Read-only — no writes.
212
+ *
213
+ * @param {object} memory - Vektor memory instance
214
+ * @param {number} days - Lookback window (default: 30)
215
+ */
216
+ async function getWasteReport({ memory, days = 30 } = {}) {
217
+ if (!memory) throw new Error('cloak_token: memory instance is required');
218
+
219
+ let nodes;
220
+ try {
221
+ nodes = await memory.recall(
222
+ `[CLOAK_TOKEN_LEDGER]`,
223
+ { limit: days }
224
+ );
225
+ } catch (err) {
226
+ return { error: err.message, sessions: [] };
227
+ }
228
+
229
+ if (!nodes || nodes.length === 0) {
230
+ return { sessions: [], totalTokens: 0, totalWasted: 0, recommendations: [] };
231
+ }
232
+
233
+ // Parse historical nodes
234
+ const sessions = nodes.map(n => {
235
+ const parts = n.content.split(' | ');
236
+ const get = key => {
237
+ const p = parts.find(p => p.startsWith(`${key}:`));
238
+ return p ? p.slice(key.length + 1) : null;
239
+ };
240
+ return {
241
+ sessionId : get('session'),
242
+ totalTokens : parseInt(get('total_tokens')?.replace('~','') || '0'),
243
+ wastedTokens : parseInt(get('wasted_tokens')?.replace('~','') || '0'),
244
+ wasteRate : get('waste_rate'),
245
+ wasteEvents : parseInt(get('waste_events') || '0'),
246
+ };
247
+ });
248
+
249
+ const totalTokens = sessions.reduce((s, n) => s + n.totalTokens, 0);
250
+ const totalWasted = sessions.reduce((s, n) => s + n.wastedTokens, 0);
251
+ const avgWasteRate = totalTokens > 0 ? Math.round((totalWasted / totalTokens) * 100) : 0;
252
+
253
+ const recommendations = [];
254
+ if (avgWasteRate > 30) {
255
+ recommendations.push(`High waste rate (${avgWasteRate}%) — run cloak_cortex scan to refresh anatomy index`);
256
+ }
257
+ if (sessions.filter(s => s.wasteEvents > 3).length > 3) {
258
+ recommendations.push('Repeated waste events — check most-read files and add to anatomy');
259
+ }
260
+
261
+ return {
262
+ sessions : sessions.slice(0, 10),
263
+ totalTokens,
264
+ totalWasted,
265
+ avgWasteRate : `${avgWasteRate}%`,
266
+ recommendations,
267
+ };
268
+ }
269
+
270
+ // ---------------------------------------------------------------------------
271
+ // Claude Code hook integration
272
+ // ---------------------------------------------------------------------------
273
+
274
+ /**
275
+ * handleHookPayload({ payload, sessionId })
276
+ * Routes Claude Code hook events to trackRead / trackWrite.
277
+ * Called from the main MCP server hook handler.
278
+ */
279
+ function handleHookPayload({ payload, sessionId } = {}) {
280
+ if (!payload) return null;
281
+
282
+ const hookName = payload?.hook_event_name || payload?.event;
283
+ const tool = payload?.tool_name;
284
+ const input = payload?.tool_input;
285
+
286
+ // Start ledger if we receive a session ID and haven't started yet
287
+ if (sessionId && !_ledger.sessionId) {
288
+ startSession(sessionId);
289
+ }
290
+
291
+ switch (hookName) {
292
+ case 'PostToolUse':
293
+ case 'post_tool_use': {
294
+ if (tool === 'Read') {
295
+ trackRead({
296
+ filePath: input?.file_path || input?.path,
297
+ content : payload?.tool_response?.content || '',
298
+ });
299
+ } else if (['Write','Edit','MultiEdit'].includes(tool)) {
300
+ trackWrite({
301
+ filePath: input?.file_path || input?.path,
302
+ content : input?.new_string || input?.content || '',
303
+ });
304
+ }
305
+ break;
306
+ }
307
+ }
308
+
309
+ return null; // token tracking never returns hook responses
310
+ }
311
+
312
+ module.exports = {
313
+ startSession,
314
+ trackRead,
315
+ trackWrite,
316
+ getSessionSummary,
317
+ buildTokenNode,
318
+ getWasteReport,
319
+ handleHookPayload,
320
+ estimateTokens,
321
+ _ledger, // exported for testing and cloak_axon integration
322
+ };
Binary file