vektor-slipstream 1.0.0 → 1.0.2
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 +19 -6
- package/slipstream-core.js +8 -3
- package/vektor-licence.js +191 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vektor-slipstream",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Hardware-accelerated persistent memory for AI agents. Local-first, zero cloud dependency, $0 embedding cost.",
|
|
5
5
|
"main": "slipstream-core.js",
|
|
6
6
|
"exports": {
|
|
@@ -9,9 +9,21 @@
|
|
|
9
9
|
"./embedder": "./slipstream-embedder.js"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
12
|
-
"ai",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
12
|
+
"ai",
|
|
13
|
+
"memory",
|
|
14
|
+
"agent",
|
|
15
|
+
"vector",
|
|
16
|
+
"sqlite",
|
|
17
|
+
"embeddings",
|
|
18
|
+
"langchain",
|
|
19
|
+
"openai",
|
|
20
|
+
"anthropic",
|
|
21
|
+
"claude",
|
|
22
|
+
"mcp",
|
|
23
|
+
"rag",
|
|
24
|
+
"persistent-memory",
|
|
25
|
+
"local-ai",
|
|
26
|
+
"onnx"
|
|
15
27
|
],
|
|
16
28
|
"author": "VEKTOR Memory <hello@vektormemory.com>",
|
|
17
29
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -28,15 +40,16 @@
|
|
|
28
40
|
"onnxruntime-node": "^1.17.3"
|
|
29
41
|
},
|
|
30
42
|
"optionalDependencies": {
|
|
31
|
-
"sqlite-vec-windows-x64": "^0.1.6",
|
|
32
43
|
"sqlite-vec-darwin-arm64": "^0.1.6",
|
|
33
|
-
"sqlite-vec-linux-x64": "^0.1.6"
|
|
44
|
+
"sqlite-vec-linux-x64": "^0.1.6",
|
|
45
|
+
"sqlite-vec-windows-x64": "^0.1.6"
|
|
34
46
|
},
|
|
35
47
|
"files": [
|
|
36
48
|
"slipstream-core.js",
|
|
37
49
|
"slipstream-db.js",
|
|
38
50
|
"slipstream-embedder.js",
|
|
39
51
|
"detect-hardware.js",
|
|
52
|
+
"vektor-licence.js",
|
|
40
53
|
"models/model_quantized.onnx",
|
|
41
54
|
"examples/",
|
|
42
55
|
"README.md",
|
package/slipstream-core.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
const { initSlipstreamDB, getDBStats } = require('./slipstream-db');
|
|
19
19
|
const { SlipstreamEmbedder } = require('./slipstream-embedder');
|
|
20
20
|
const { getEPLabel } = require('./detect-hardware');
|
|
21
|
+
const { validateLicence } = require('./vektor-licence');
|
|
21
22
|
|
|
22
23
|
// ─── Boot Banner ──────────────────────────────────────────────────────────────
|
|
23
24
|
|
|
@@ -305,11 +306,15 @@ async function createMemory(options = {}) {
|
|
|
305
306
|
const bootStart = Date.now();
|
|
306
307
|
|
|
307
308
|
const {
|
|
308
|
-
agentId
|
|
309
|
-
dbPath
|
|
310
|
-
silent
|
|
309
|
+
agentId = 'default',
|
|
310
|
+
dbPath = './slipstream-memory.db',
|
|
311
|
+
silent = false,
|
|
312
|
+
licenceKey = process.env.VEKTOR_LICENCE_KEY || '',
|
|
311
313
|
} = options;
|
|
312
314
|
|
|
315
|
+
// 0. Validate Polar licence key
|
|
316
|
+
await validateLicence(licenceKey);
|
|
317
|
+
|
|
313
318
|
// 1. Init embedder (hardware probe + ONNX load + pre-warmer)
|
|
314
319
|
const embedder = new SlipstreamEmbedder();
|
|
315
320
|
await embedder.init();
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* vektor-licence.js — Polar Licence Enforcement
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
* Validates a Polar licence key before allowing createMemory() to proceed.
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Customer calls createMemory({ licenceKey: 'VEKTOR-XXXX-...' })
|
|
9
|
+
* 2. We check ~/.vektor/licence.json for a cached validation (30-day TTL)
|
|
10
|
+
* 3. If cache miss or expired → call Polar validate API
|
|
11
|
+
* 4. Valid → cache result, proceed
|
|
12
|
+
* 5. Invalid/missing → throw with purchase link
|
|
13
|
+
*
|
|
14
|
+
* Polar validate endpoint requires no auth token — safe for client-side use.
|
|
15
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
const os = require('os');
|
|
21
|
+
const crypto = require('crypto');
|
|
22
|
+
|
|
23
|
+
// ── Config ────────────────────────────────────────────────────────────────────
|
|
24
|
+
// Replace POLAR_ORG_ID with your actual Polar organisation ID from
|
|
25
|
+
// polar.sh → Settings → Organisation ID
|
|
26
|
+
|
|
27
|
+
const POLAR_ORG_ID = 'a922049c-3049-41e8-9b20-b18890576b6f';
|
|
28
|
+
const POLAR_API = 'https://api.polar.sh/v1/customer-portal/license-keys/validate';
|
|
29
|
+
const CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
30
|
+
const CACHE_DIR = path.join(os.homedir(), '.vektor');
|
|
31
|
+
const CACHE_FILE = path.join(CACHE_DIR, 'licence.json');
|
|
32
|
+
const PURCHASE_URL = 'https://vektormemory.com/#pricing';
|
|
33
|
+
|
|
34
|
+
// ── Cache helpers ─────────────────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
function _cacheKey(licenceKey) {
|
|
37
|
+
// Hash the key so we don't store it in plaintext
|
|
38
|
+
return crypto.createHash('sha256').update(licenceKey).digest('hex').slice(0, 16);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function _readCache() {
|
|
42
|
+
try {
|
|
43
|
+
if (!fs.existsSync(CACHE_FILE)) return {};
|
|
44
|
+
return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
|
|
45
|
+
} catch(_) { return {}; }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function _writeCache(licenceKey, data) {
|
|
49
|
+
try {
|
|
50
|
+
if (!fs.existsSync(CACHE_DIR)) fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
51
|
+
const cache = _readCache();
|
|
52
|
+
cache[_cacheKey(licenceKey)] = { ...data, cached_at: Date.now() };
|
|
53
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
|
|
54
|
+
} catch(_) {}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function _getCached(licenceKey) {
|
|
58
|
+
const cache = _readCache();
|
|
59
|
+
const entry = cache[_cacheKey(licenceKey)];
|
|
60
|
+
if (!entry) return null;
|
|
61
|
+
if (Date.now() - entry.cached_at > CACHE_TTL_MS) return null; // expired
|
|
62
|
+
return entry;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ── Polar validation ──────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
async function _validateWithPolar(licenceKey) {
|
|
68
|
+
const body = JSON.stringify({
|
|
69
|
+
key: licenceKey,
|
|
70
|
+
organization_id: POLAR_ORG_ID,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const res = await fetch(POLAR_API, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: { 'Content-Type': 'application/json' },
|
|
76
|
+
body,
|
|
77
|
+
signal: AbortSignal.timeout(10000),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (res.status === 404) {
|
|
81
|
+
return { valid: false, reason: 'Key not found' };
|
|
82
|
+
}
|
|
83
|
+
if (res.status === 422) {
|
|
84
|
+
return { valid: false, reason: 'Invalid key format' };
|
|
85
|
+
}
|
|
86
|
+
if (!res.ok) {
|
|
87
|
+
// Network/server error — allow offline grace period
|
|
88
|
+
return { valid: null, reason: `Polar API error: ${res.status}` };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const data = await res.json();
|
|
92
|
+
|
|
93
|
+
// Polar returns status: 'granted' | 'revoked' | 'disabled'
|
|
94
|
+
if (data.status !== 'granted') {
|
|
95
|
+
return { valid: false, reason: `Licence ${data.status}` };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
valid: true,
|
|
100
|
+
status: data.status,
|
|
101
|
+
expires_at: data.expires_at || null,
|
|
102
|
+
key_id: data.id,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ── Main export ───────────────────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* validateLicence(licenceKey)
|
|
110
|
+
*
|
|
111
|
+
* Call before createMemory(). Throws if the key is invalid.
|
|
112
|
+
* Caches valid keys for 30 days so it doesn't call Polar on every run.
|
|
113
|
+
*
|
|
114
|
+
* @param {string} licenceKey — the customer's Polar licence key
|
|
115
|
+
* @returns {Promise<void>}
|
|
116
|
+
* @throws {Error} if key is invalid, revoked, or missing
|
|
117
|
+
*/
|
|
118
|
+
async function validateLicence(licenceKey) {
|
|
119
|
+
if (!licenceKey || typeof licenceKey !== 'string' || licenceKey.trim().length < 8) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
'\n' +
|
|
122
|
+
' ╔══════════════════════════════════════════════════════╗\n' +
|
|
123
|
+
' ║ VEKTOR SLIPSTREAM — LICENCE REQUIRED ║\n' +
|
|
124
|
+
' ╚══════════════════════════════════════════════════════╝\n' +
|
|
125
|
+
'\n' +
|
|
126
|
+
' A valid licence key is required to use Vektor Slipstream.\n' +
|
|
127
|
+
'\n' +
|
|
128
|
+
' Purchase at: ' + PURCHASE_URL + '\n' +
|
|
129
|
+
'\n' +
|
|
130
|
+
' Usage:\n' +
|
|
131
|
+
' const memory = await createMemory({\n' +
|
|
132
|
+
' agentId: \'my-agent\',\n' +
|
|
133
|
+
' licenceKey: \'VEKTOR-XXXX-XXXX-XXXX\',\n' +
|
|
134
|
+
' });\n'
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check cache first
|
|
139
|
+
const cached = _getCached(licenceKey);
|
|
140
|
+
if (cached?.valid === true) {
|
|
141
|
+
// Cache hit — valid, proceed silently
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Cache miss or expired — validate with Polar
|
|
146
|
+
let result;
|
|
147
|
+
try {
|
|
148
|
+
result = await _validateWithPolar(licenceKey.trim());
|
|
149
|
+
} catch(e) {
|
|
150
|
+
// Network failure — check if we have any cached entry (even expired) as grace period
|
|
151
|
+
const staleCache = _readCache()[_cacheKey(licenceKey)];
|
|
152
|
+
if (staleCache?.valid === true) {
|
|
153
|
+
console.warn('[SLIPSTREAM] Could not reach licence server — using cached validation (grace period).');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
throw new Error(
|
|
157
|
+
'[SLIPSTREAM] Licence validation failed — could not reach Polar.\n' +
|
|
158
|
+
'Check your internet connection and try again.\n' +
|
|
159
|
+
'Error: ' + e.message
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (result.valid === null) {
|
|
164
|
+
// Polar API error — use stale cache as grace period
|
|
165
|
+
const staleCache = _readCache()[_cacheKey(licenceKey)];
|
|
166
|
+
if (staleCache?.valid === true) {
|
|
167
|
+
console.warn('[SLIPSTREAM] Licence server error — using cached validation (grace period).');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
throw new Error('[SLIPSTREAM] Licence server temporarily unavailable. Try again in a moment.');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!result.valid) {
|
|
174
|
+
throw new Error(
|
|
175
|
+
'\n' +
|
|
176
|
+
' ╔══════════════════════════════════════════════════════╗\n' +
|
|
177
|
+
' ║ VEKTOR SLIPSTREAM — LICENCE INVALID ║\n' +
|
|
178
|
+
' ╚══════════════════════════════════════════════════════╝\n' +
|
|
179
|
+
'\n' +
|
|
180
|
+
' Reason: ' + result.reason + '\n' +
|
|
181
|
+
'\n' +
|
|
182
|
+
' Purchase a valid licence at: ' + PURCHASE_URL + '\n' +
|
|
183
|
+
' Already purchased? Check your email for the key.\n'
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Valid — cache it
|
|
188
|
+
_writeCache(licenceKey, result);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
module.exports = { validateLicence };
|