alvin-bot 5.7.0 → 5.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/CHANGELOG.md +25 -0
- package/README.md +25 -31
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -174
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -583
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -86
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1902
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,496 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Embeddings Facade — provider-agnostic memory search.
|
|
3
|
-
*
|
|
4
|
-
* Manages the SQLite DB, picks an active provider via auto-detect, handles
|
|
5
|
-
* schema migrations on provider switch, and exposes the legacy public API
|
|
6
|
-
* (initEmbeddings, searchMemory, reindexMemory, getIndexStats) so callers
|
|
7
|
-
* outside this module don't need to know which backend is running.
|
|
8
|
-
*
|
|
9
|
-
* Provider tiers (auto-detected in this order, override via EMBEDDINGS_PROVIDER):
|
|
10
|
-
* 1. Gemini (3072-dim, GOOGLE_API_KEY) — free tier
|
|
11
|
-
* 2. OpenAI (1536-dim, OPENAI_API_KEY) — ~$0.02/1M tokens
|
|
12
|
-
* 3. Ollama (768-dim default, local) — free, private
|
|
13
|
-
* 4. FTS5 (BM25 keyword, no key needed) — universal fallback
|
|
14
|
-
*
|
|
15
|
-
* Schema-mismatch handling: when meta.embedding_model differs from the active
|
|
16
|
-
* provider's name (e.g. user added GOOGLE_API_KEY after running on FTS5), we
|
|
17
|
-
* drop the previous provider's tables, clear file_mtimes, and initialise the
|
|
18
|
-
* new provider's schema. The next reindexMemory() call repopulates everything
|
|
19
|
-
* from disk. This is what makes the "user adds key later" flow seamless.
|
|
20
|
-
*/
|
|
21
|
-
import fs from "fs";
|
|
22
|
-
import path from "path";
|
|
23
|
-
import { resolve } from "path";
|
|
24
|
-
import os from "os";
|
|
25
|
-
import { createRequire } from "module";
|
|
26
|
-
import { MEMORY_DIR, MEMORY_FILE, EMBEDDINGS_DB } from "../../paths.js";
|
|
27
|
-
import { ASSETS_DIR, ASSETS_INDEX_MD } from "../../paths.js";
|
|
28
|
-
import { detectProvider, parseProviderKey } from "./auto-detect.js";
|
|
29
|
-
let SqliteClass = null;
|
|
30
|
-
let sqliteLoadAttempted = false;
|
|
31
|
-
let sqliteLoadError = null;
|
|
32
|
-
const cjsRequire = createRequire(import.meta.url);
|
|
33
|
-
function loadSqlite() {
|
|
34
|
-
if (sqliteLoadAttempted)
|
|
35
|
-
return SqliteClass;
|
|
36
|
-
sqliteLoadAttempted = true;
|
|
37
|
-
try {
|
|
38
|
-
SqliteClass = cjsRequire("better-sqlite3");
|
|
39
|
-
return SqliteClass;
|
|
40
|
-
}
|
|
41
|
-
catch (err) {
|
|
42
|
-
sqliteLoadError = err instanceof Error ? err : new Error(String(err));
|
|
43
|
-
console.log("ℹ️ Semantic memory (better-sqlite3) unavailable — using keyword search (FTS5). " +
|
|
44
|
-
"Reinstall or run `npm rebuild better-sqlite3` to enable.");
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// ── State ────────────────────────────────────────────────
|
|
49
|
-
const HUB_MEMORY_DIR = resolve(os.homedir(), ".claude", "hub", "MEMORY");
|
|
50
|
-
const SCHEMA_VERSION = "2"; // bumped from 1 when introducing multi-provider
|
|
51
|
-
let dbInstance = null;
|
|
52
|
-
let activeProvider = null;
|
|
53
|
-
let initialised = false;
|
|
54
|
-
let initInFlight = null;
|
|
55
|
-
// ── DB lifecycle ────────────────────────────────────────
|
|
56
|
-
function openDb() {
|
|
57
|
-
if (dbInstance)
|
|
58
|
-
return dbInstance;
|
|
59
|
-
const Database = loadSqlite();
|
|
60
|
-
if (!Database)
|
|
61
|
-
return null;
|
|
62
|
-
fs.mkdirSync(path.dirname(EMBEDDINGS_DB), { recursive: true });
|
|
63
|
-
dbInstance = new Database(EMBEDDINGS_DB);
|
|
64
|
-
dbInstance.pragma("journal_mode = WAL");
|
|
65
|
-
dbInstance.pragma("synchronous = NORMAL");
|
|
66
|
-
dbInstance.pragma("temp_store = MEMORY");
|
|
67
|
-
dbInstance.pragma("mmap_size = 268435456"); // 256 MB
|
|
68
|
-
// Shared tables — owned by the facade, not by any single provider.
|
|
69
|
-
dbInstance.exec(`
|
|
70
|
-
CREATE TABLE IF NOT EXISTS meta (
|
|
71
|
-
key TEXT PRIMARY KEY,
|
|
72
|
-
value TEXT NOT NULL
|
|
73
|
-
);
|
|
74
|
-
CREATE TABLE IF NOT EXISTS file_mtimes (
|
|
75
|
-
source TEXT PRIMARY KEY,
|
|
76
|
-
mtime_ms REAL NOT NULL
|
|
77
|
-
);
|
|
78
|
-
`);
|
|
79
|
-
return dbInstance;
|
|
80
|
-
}
|
|
81
|
-
export function closeEmbeddingsDb() {
|
|
82
|
-
if (dbInstance) {
|
|
83
|
-
dbInstance.close();
|
|
84
|
-
dbInstance = null;
|
|
85
|
-
}
|
|
86
|
-
activeProvider = null;
|
|
87
|
-
initialised = false;
|
|
88
|
-
initInFlight = null;
|
|
89
|
-
}
|
|
90
|
-
// ── Meta helpers ────────────────────────────────────────
|
|
91
|
-
function getMeta(db, key) {
|
|
92
|
-
const row = db.prepare("SELECT value FROM meta WHERE key = ?").get(key);
|
|
93
|
-
return row?.value ?? null;
|
|
94
|
-
}
|
|
95
|
-
function setMeta(db, key, value) {
|
|
96
|
-
db.prepare("INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(key, value);
|
|
97
|
-
}
|
|
98
|
-
function clearAllProviderSchemas(db) {
|
|
99
|
-
// Drop both possible provider-owned tables. Defensive — covers any past
|
|
100
|
-
// schema regardless of which provider wrote it.
|
|
101
|
-
db.exec("DROP TABLE IF EXISTS entries; DROP TABLE IF EXISTS entries_fts;");
|
|
102
|
-
db.exec("DELETE FROM file_mtimes;");
|
|
103
|
-
}
|
|
104
|
-
// ── File mtime tracking ─────────────────────────────────
|
|
105
|
-
function getFileMtimes(db) {
|
|
106
|
-
const rows = db.prepare("SELECT source, mtime_ms FROM file_mtimes").all();
|
|
107
|
-
const out = {};
|
|
108
|
-
for (const r of rows)
|
|
109
|
-
out[r.source] = r.mtime_ms;
|
|
110
|
-
return out;
|
|
111
|
-
}
|
|
112
|
-
function setFileMtime(db, source, mtimeMs) {
|
|
113
|
-
db.prepare("INSERT INTO file_mtimes (source, mtime_ms) VALUES (?, ?) ON CONFLICT(source) DO UPDATE SET mtime_ms = excluded.mtime_ms").run(source, mtimeMs);
|
|
114
|
-
}
|
|
115
|
-
// ── File discovery ──────────────────────────────────────
|
|
116
|
-
const TEXT_EXTENSIONS = new Set([".md", ".html", ".txt", ".css", ".ts"]);
|
|
117
|
-
function walkAssetDir(dir) {
|
|
118
|
-
const results = [];
|
|
119
|
-
function walk(currentDir) {
|
|
120
|
-
let entries;
|
|
121
|
-
try {
|
|
122
|
-
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
for (const entry of entries) {
|
|
128
|
-
const fullPath = resolve(currentDir, entry.name);
|
|
129
|
-
if (entry.isDirectory()) {
|
|
130
|
-
walk(fullPath);
|
|
131
|
-
}
|
|
132
|
-
else if (entry.isFile()) {
|
|
133
|
-
if (currentDir === dir && (entry.name === "INDEX.json" || entry.name === "INDEX.md"))
|
|
134
|
-
continue;
|
|
135
|
-
results.push({ name: entry.name, path: fullPath });
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
walk(dir);
|
|
140
|
-
return results;
|
|
141
|
-
}
|
|
142
|
-
function getIndexableFiles() {
|
|
143
|
-
const files = [];
|
|
144
|
-
if (fs.existsSync(MEMORY_FILE)) {
|
|
145
|
-
files.push({ path: MEMORY_FILE, relativePath: "MEMORY.md" });
|
|
146
|
-
}
|
|
147
|
-
if (fs.existsSync(MEMORY_DIR)) {
|
|
148
|
-
const entries = fs.readdirSync(MEMORY_DIR);
|
|
149
|
-
for (const entry of entries) {
|
|
150
|
-
if (entry.endsWith(".md") && !entry.startsWith(".")) {
|
|
151
|
-
files.push({
|
|
152
|
-
path: resolve(MEMORY_DIR, entry),
|
|
153
|
-
relativePath: `memory/${entry}`,
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (fs.existsSync(HUB_MEMORY_DIR)) {
|
|
159
|
-
try {
|
|
160
|
-
const entries = fs.readdirSync(HUB_MEMORY_DIR);
|
|
161
|
-
for (const entry of entries) {
|
|
162
|
-
if (entry.endsWith(".md") && !entry.startsWith(".")) {
|
|
163
|
-
files.push({
|
|
164
|
-
path: resolve(HUB_MEMORY_DIR, entry),
|
|
165
|
-
relativePath: `hub/${entry}`,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
catch {
|
|
171
|
-
/* hub dir not available */
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (fs.existsSync(ASSETS_INDEX_MD)) {
|
|
175
|
-
files.push({ path: ASSETS_INDEX_MD, relativePath: "assets/INDEX.md" });
|
|
176
|
-
}
|
|
177
|
-
if (fs.existsSync(ASSETS_DIR)) {
|
|
178
|
-
for (const entry of walkAssetDir(ASSETS_DIR)) {
|
|
179
|
-
if (TEXT_EXTENSIONS.has(path.extname(entry.name))) {
|
|
180
|
-
files.push({
|
|
181
|
-
path: entry.path,
|
|
182
|
-
relativePath: `assets/${path.relative(ASSETS_DIR, entry.path)}`,
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return files;
|
|
188
|
-
}
|
|
189
|
-
function getStaleFiles(db) {
|
|
190
|
-
const all = getIndexableFiles();
|
|
191
|
-
const known = getFileMtimes(db);
|
|
192
|
-
const stale = [];
|
|
193
|
-
for (const f of all) {
|
|
194
|
-
try {
|
|
195
|
-
const mtime = fs.statSync(f.path).mtimeMs;
|
|
196
|
-
if (!known[f.relativePath] || known[f.relativePath] < mtime) {
|
|
197
|
-
stale.push(f);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
/* file disappeared */
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return stale;
|
|
205
|
-
}
|
|
206
|
-
// ── Chunking ────────────────────────────────────────────
|
|
207
|
-
function chunkMarkdown(content, source) {
|
|
208
|
-
const chunks = [];
|
|
209
|
-
const sections = content.split(/^(?=## )/gm);
|
|
210
|
-
for (let i = 0; i < sections.length; i++) {
|
|
211
|
-
const section = sections[i].trim();
|
|
212
|
-
if (!section || section.length < 20)
|
|
213
|
-
continue;
|
|
214
|
-
if (section.length > 1000) {
|
|
215
|
-
const paragraphs = section.split(/\n\n+/);
|
|
216
|
-
let cur = "";
|
|
217
|
-
let chunkIdx = 0;
|
|
218
|
-
for (const p of paragraphs) {
|
|
219
|
-
if (cur.length + p.length > 800 && cur.length > 100) {
|
|
220
|
-
chunks.push({ id: `${source}:${i}:${chunkIdx}`, source, text: cur.trim() });
|
|
221
|
-
cur = "";
|
|
222
|
-
chunkIdx++;
|
|
223
|
-
}
|
|
224
|
-
cur += p + "\n\n";
|
|
225
|
-
}
|
|
226
|
-
if (cur.trim().length > 20) {
|
|
227
|
-
chunks.push({ id: `${source}:${i}:${chunkIdx}`, source, text: cur.trim() });
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
chunks.push({ id: `${source}:${i}`, source, text: section });
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return chunks;
|
|
235
|
-
}
|
|
236
|
-
// ── Provider sync ───────────────────────────────────────
|
|
237
|
-
/**
|
|
238
|
-
* Ensure the DB schema matches the active provider. If the stored model name
|
|
239
|
-
* differs from the active provider's, wipe provider-owned tables + file_mtimes
|
|
240
|
-
* so the next reindex repopulates from disk against the new schema. Idempotent.
|
|
241
|
-
*/
|
|
242
|
-
function syncProviderSchema(db, provider) {
|
|
243
|
-
// Legacy v4.20 DBs only have meta.model (set by embeddings-migration.ts).
|
|
244
|
-
// Treat that as the previous embedding_model so we don't accidentally
|
|
245
|
-
// wipe a 49 MB vector store just because the meta key was renamed.
|
|
246
|
-
const storedModel = getMeta(db, "embedding_model") ?? getMeta(db, "model");
|
|
247
|
-
// Schema mismatch is detected by provider-name change ONLY. Bumping
|
|
248
|
-
// SCHEMA_VERSION alone must NOT trigger a drop — vector providers (Gemini,
|
|
249
|
-
// OpenAI, Ollama) all share the same `entries` table layout, so a refactor
|
|
250
|
-
// version bump shouldn't cost users a full re-embed against the API.
|
|
251
|
-
const switched = storedModel !== null && storedModel !== provider.name;
|
|
252
|
-
if (switched) {
|
|
253
|
-
clearAllProviderSchemas(db);
|
|
254
|
-
}
|
|
255
|
-
// Initialise the active provider's schema (idempotent — IF NOT EXISTS guards).
|
|
256
|
-
provider.initSchema(db);
|
|
257
|
-
setMeta(db, "embedding_model", provider.name);
|
|
258
|
-
setMeta(db, "embedding_dim", String(provider.dim));
|
|
259
|
-
setMeta(db, "embedding_tier", provider.tier);
|
|
260
|
-
setMeta(db, "schemaVersion", SCHEMA_VERSION);
|
|
261
|
-
return { switched, previous: storedModel };
|
|
262
|
-
}
|
|
263
|
-
// ── Internal init ───────────────────────────────────────
|
|
264
|
-
async function ensureInit() {
|
|
265
|
-
if (initialised && dbInstance && activeProvider) {
|
|
266
|
-
return { db: dbInstance, provider: activeProvider };
|
|
267
|
-
}
|
|
268
|
-
if (initInFlight) {
|
|
269
|
-
await initInFlight;
|
|
270
|
-
return initialised && dbInstance && activeProvider
|
|
271
|
-
? { db: dbInstance, provider: activeProvider }
|
|
272
|
-
: null;
|
|
273
|
-
}
|
|
274
|
-
initInFlight = (async () => {
|
|
275
|
-
const db = openDb();
|
|
276
|
-
if (!db)
|
|
277
|
-
return; // sqlite unavailable — leave initialised=false
|
|
278
|
-
const overrideKey = parseProviderKey(process.env.EMBEDDINGS_PROVIDER);
|
|
279
|
-
const provider = await detectProvider(overrideKey);
|
|
280
|
-
const sync = syncProviderSchema(db, provider);
|
|
281
|
-
if (sync.switched) {
|
|
282
|
-
console.log(`ℹ️ Memory provider changed: ${sync.previous ?? "none"} → ${provider.name} (${provider.tier}). Reindex on next access.`);
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
// Quiet info log on first startup of a new install.
|
|
286
|
-
const total = provider.countEntries(db);
|
|
287
|
-
if (total === 0) {
|
|
288
|
-
console.log(`ℹ️ Memory provider: ${provider.name} (${provider.tier}). Initial index will run on first use.`);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
activeProvider = provider;
|
|
292
|
-
initialised = true;
|
|
293
|
-
})();
|
|
294
|
-
try {
|
|
295
|
-
await initInFlight;
|
|
296
|
-
}
|
|
297
|
-
finally {
|
|
298
|
-
initInFlight = null;
|
|
299
|
-
}
|
|
300
|
-
return initialised && dbInstance && activeProvider
|
|
301
|
-
? { db: dbInstance, provider: activeProvider }
|
|
302
|
-
: null;
|
|
303
|
-
}
|
|
304
|
-
// ── Public API ──────────────────────────────────────────
|
|
305
|
-
export async function reindexMemory(force = false) {
|
|
306
|
-
const ctx = await ensureInit();
|
|
307
|
-
if (!ctx)
|
|
308
|
-
return { indexed: 0, total: 0 };
|
|
309
|
-
const { db, provider } = ctx;
|
|
310
|
-
const filesToIndex = force ? getIndexableFiles() : getStaleFiles(db);
|
|
311
|
-
if (filesToIndex.length === 0) {
|
|
312
|
-
return { indexed: 0, total: provider.countEntries(db) };
|
|
313
|
-
}
|
|
314
|
-
// Drop existing entries for these files (per-source DELETE).
|
|
315
|
-
provider.dropEntriesForSources(db, filesToIndex.map(f => f.relativePath));
|
|
316
|
-
// Chunk all files.
|
|
317
|
-
const allChunks = [];
|
|
318
|
-
const fileMtimeMap = [];
|
|
319
|
-
for (const file of filesToIndex) {
|
|
320
|
-
try {
|
|
321
|
-
const content = fs.readFileSync(file.path, "utf-8");
|
|
322
|
-
const chunks = chunkMarkdown(content, file.relativePath);
|
|
323
|
-
for (const c of chunks)
|
|
324
|
-
allChunks.push(c);
|
|
325
|
-
fileMtimeMap.push(file);
|
|
326
|
-
}
|
|
327
|
-
catch (err) {
|
|
328
|
-
console.error(`Failed to chunk ${file.relativePath}:`, err);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
if (allChunks.length === 0) {
|
|
332
|
-
// No content to embed — but DO update mtimes so we don't re-walk these
|
|
333
|
-
// files every startup.
|
|
334
|
-
const updMtime = db.transaction((files) => {
|
|
335
|
-
for (const f of files) {
|
|
336
|
-
try {
|
|
337
|
-
setFileMtime(db, f.relativePath, fs.statSync(f.path).mtimeMs);
|
|
338
|
-
}
|
|
339
|
-
catch {
|
|
340
|
-
/* file vanished */
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
updMtime(fileMtimeMap);
|
|
345
|
-
return { indexed: 0, total: provider.countEntries(db) };
|
|
346
|
-
}
|
|
347
|
-
await provider.indexChunks(db, allChunks);
|
|
348
|
-
// Update mtimes for indexed files.
|
|
349
|
-
const updMtime = db.transaction((files) => {
|
|
350
|
-
for (const f of files) {
|
|
351
|
-
try {
|
|
352
|
-
setFileMtime(db, f.relativePath, fs.statSync(f.path).mtimeMs);
|
|
353
|
-
}
|
|
354
|
-
catch {
|
|
355
|
-
/* file vanished */
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
updMtime(fileMtimeMap);
|
|
360
|
-
setMeta(db, "lastReindex", String(Date.now()));
|
|
361
|
-
// For Ollama with unknown dim, set it now from the actual vector size.
|
|
362
|
-
if (provider.dim === 0) {
|
|
363
|
-
// Probe one entry; vector providers store as BLOB, FTS5 doesn't have one.
|
|
364
|
-
try {
|
|
365
|
-
const row = db.prepare("SELECT vector FROM entries LIMIT 1").get();
|
|
366
|
-
if (row?.vector) {
|
|
367
|
-
const detectedDim = row.vector.byteLength / 4;
|
|
368
|
-
setMeta(db, "embedding_dim", String(detectedDim));
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
catch {
|
|
372
|
-
/* not a vector provider */
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
return { indexed: allChunks.length, total: provider.countEntries(db) };
|
|
376
|
-
}
|
|
377
|
-
export async function searchMemory(query, topK = 5, minScore = 0.3) {
|
|
378
|
-
const ctx = await ensureInit();
|
|
379
|
-
if (!ctx)
|
|
380
|
-
return [];
|
|
381
|
-
const { db, provider } = ctx;
|
|
382
|
-
// Lazy first-time index if empty.
|
|
383
|
-
if (provider.countEntries(db) === 0) {
|
|
384
|
-
try {
|
|
385
|
-
await reindexMemory();
|
|
386
|
-
}
|
|
387
|
-
catch (err) {
|
|
388
|
-
// Reindex failure (e.g. API key missing for vector provider) — return
|
|
389
|
-
// empty so the caller can degrade gracefully.
|
|
390
|
-
console.log(`ℹ️ Memory search unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
391
|
-
return [];
|
|
392
|
-
}
|
|
393
|
-
if (provider.countEntries(db) === 0)
|
|
394
|
-
return [];
|
|
395
|
-
}
|
|
396
|
-
try {
|
|
397
|
-
return await provider.search(db, query, topK, minScore);
|
|
398
|
-
}
|
|
399
|
-
catch (err) {
|
|
400
|
-
console.log(`ℹ️ Memory search failed (${provider.name}): ${err instanceof Error ? err.message : String(err)}`);
|
|
401
|
-
return [];
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
export async function initEmbeddings() {
|
|
405
|
-
const ctx = await ensureInit();
|
|
406
|
-
if (!ctx)
|
|
407
|
-
return; // sqlite unavailable — already warned in loadSqlite
|
|
408
|
-
const { db, provider } = ctx;
|
|
409
|
-
try {
|
|
410
|
-
const stale = getStaleFiles(db);
|
|
411
|
-
if (stale.length === 0 && provider.countEntries(db) > 0) {
|
|
412
|
-
return; // already up to date
|
|
413
|
-
}
|
|
414
|
-
const result = await reindexMemory();
|
|
415
|
-
if (result.indexed > 0) {
|
|
416
|
-
console.log(`🔍 Memory indexed: ${result.indexed} chunks via ${provider.name} (${result.total} total)`);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
catch (err) {
|
|
420
|
-
// Don't crash the bot if reindexing fails (e.g. API down). Log INFO not
|
|
421
|
-
// WARN — bot keeps running, search just returns empty until conditions
|
|
422
|
-
// recover. Public users without keys hit the FTS5 path which never throws.
|
|
423
|
-
console.log(`ℹ️ Memory init deferred: ${err instanceof Error ? err.message : String(err)}`);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
export function getIndexStats() {
|
|
427
|
-
const stats = {
|
|
428
|
-
entries: 0,
|
|
429
|
-
files: 0,
|
|
430
|
-
lastReindex: 0,
|
|
431
|
-
sizeBytes: 0,
|
|
432
|
-
provider: "unavailable",
|
|
433
|
-
tier: "none",
|
|
434
|
-
dim: 0,
|
|
435
|
-
};
|
|
436
|
-
if (!loadSqlite())
|
|
437
|
-
return stats;
|
|
438
|
-
const db = openDb();
|
|
439
|
-
if (!db)
|
|
440
|
-
return stats;
|
|
441
|
-
try {
|
|
442
|
-
if (activeProvider) {
|
|
443
|
-
stats.entries = activeProvider.countEntries(db);
|
|
444
|
-
stats.provider = activeProvider.name;
|
|
445
|
-
stats.tier = activeProvider.tier;
|
|
446
|
-
stats.dim = activeProvider.dim;
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
// Fall back to stored meta if init never ran.
|
|
450
|
-
stats.provider = getMeta(db, "embedding_model") ?? "unknown";
|
|
451
|
-
stats.tier = getMeta(db, "embedding_tier") ?? "unknown";
|
|
452
|
-
stats.dim = Number(getMeta(db, "embedding_dim") ?? 0);
|
|
453
|
-
}
|
|
454
|
-
stats.files = db.prepare("SELECT COUNT(*) AS c FROM file_mtimes").get().c;
|
|
455
|
-
const lr = getMeta(db, "lastReindex");
|
|
456
|
-
if (lr)
|
|
457
|
-
stats.lastReindex = Number(lr);
|
|
458
|
-
if (fs.existsSync(EMBEDDINGS_DB))
|
|
459
|
-
stats.sizeBytes = fs.statSync(EMBEDDINGS_DB).size;
|
|
460
|
-
}
|
|
461
|
-
catch {
|
|
462
|
-
/* DB not initialised or partial */
|
|
463
|
-
}
|
|
464
|
-
return stats;
|
|
465
|
-
}
|
|
466
|
-
export function getEmbeddingsBackendStatus() {
|
|
467
|
-
loadSqlite();
|
|
468
|
-
return { available: SqliteClass !== null, error: sqliteLoadError?.message ?? null };
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Synchronous probe: does the SQLite memory store have at least one indexed
|
|
472
|
-
* entry, regardless of which provider wrote it? Used by the inject-mode
|
|
473
|
-
* resolver to decide between legacy plain-text and SQLite-backed search at
|
|
474
|
-
* system-prompt build time (which is sync).
|
|
475
|
-
*
|
|
476
|
-
* Cheap: opens the DB if needed (idempotent), runs a single COUNT on whichever
|
|
477
|
-
* provider table exists. Does NOT call out to embedding APIs.
|
|
478
|
-
*/
|
|
479
|
-
export function isSqliteMemoryReady() {
|
|
480
|
-
if (!loadSqlite())
|
|
481
|
-
return false;
|
|
482
|
-
const db = openDb();
|
|
483
|
-
if (!db)
|
|
484
|
-
return false;
|
|
485
|
-
for (const tbl of ["entries", "entries_fts"]) {
|
|
486
|
-
try {
|
|
487
|
-
const r = db.prepare(`SELECT COUNT(*) AS c FROM ${tbl}`).get();
|
|
488
|
-
if (r && r.c > 0)
|
|
489
|
-
return true;
|
|
490
|
-
}
|
|
491
|
-
catch {
|
|
492
|
-
/* table missing — try next */
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
return false;
|
|
496
|
-
}
|
|
1
|
+
const _0x2cb525=_0x55b4,_0x4b9ae7=_0x55b4;(function(_0x311ea2,_0x3331fb){const _0x2642ed=_0x55b4,_0x5eb324=_0x55b4,_0x4aba66=_0x311ea2();while(!![]){try{const _0x29ea3e=-parseInt(_0x2642ed(0xc7))/(-0xbd7+0x1*-0xeaf+-0x1a87*-0x1)*(parseInt(_0x5eb324(0xef))/(-0xd51+-0x1915*-0x1+0x25a*-0x5))+parseInt(_0x2642ed(0x79))/(-0x341*-0x5+-0x4a*0x29+-0x468)*(-parseInt(_0x5eb324(0xfb))/(0x226c+-0xb32+-0x1736))+-parseInt(_0x5eb324(0x87))/(0x31*-0x84+0x1f*-0x1+-0x10f*-0x18)*(-parseInt(_0x5eb324(0xb1))/(0x37*-0x5+-0x1ecf+0x1fe8))+-parseInt(_0x5eb324(0x10a))/(-0x1*0x265+-0x565*-0x1+-0x2f9)+parseInt(_0x5eb324(0xa5))/(0x109*-0x19+-0x6b*0x18+0x23f1)+-parseInt(_0x2642ed(0x83))/(0x23db+-0x1876+-0xb5c)+-parseInt(_0x2642ed(0x93))/(0x1d68+-0x127*0x1+-0xe9*0x1f)*(-parseInt(_0x5eb324(0x98))/(0x85*-0xc+-0x1d47*0x1+-0x52*-0x6f));if(_0x29ea3e===_0x3331fb)break;else _0x4aba66['push'](_0x4aba66['shift']());}catch(_0x35df5a){_0x4aba66['push'](_0x4aba66['shift']());}}}(_0x207e,-0x4d3fb*0x1+-0xcbf6*-0x8+0x3ad52));const _0x4f37ec=(function(){let _0x5a063e=!![];return function(_0x3176f7,_0x32feed){const _0x2834a3=_0x5a063e?function(){const _0x330c25=_0x55b4;if(_0x32feed){const _0x44bf00=_0x32feed[_0x330c25(0x11f)](_0x3176f7,arguments);return _0x32feed=null,_0x44bf00;}}:function(){};return _0x5a063e=![],_0x2834a3;};}()),_0x2bad56=_0x4f37ec(this,function(){const _0x45ab7e=_0x55b4,_0x435b7e=_0x55b4;return _0x2bad56[_0x45ab7e(0x8d)]()[_0x435b7e(0x122)](_0x45ab7e(0xbc)+'+$')[_0x435b7e(0x8d)]()[_0x435b7e(0xf6)+'r'](_0x2bad56)[_0x435b7e(0x122)]('(((.+)+)+)'+'+$');});_0x2bad56();import _0x50d532 from'fs';import _0x276de7 from'path';import{resolve}from'path';import _0x1125c1 from'os';function _0x55b4(_0x44bf00,_0xf0a605){_0x44bf00=_0x44bf00-(-0x1*0xb25+-0x7*-0x8b+0x39*0x23);const _0x133d45=_0x207e();let _0x88113c=_0x133d45[_0x44bf00];if(_0x55b4['vtKmdA']===undefined){var _0x597acb=function(_0x5d5d56){const _0x4ded4f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4e6339='',_0x4e2666='',_0x32bb7a=_0x4e6339+_0x597acb;for(let _0x358ebc=0xc3f+-0x130f+0x6d0,_0x555d17,_0x87109b,_0x2b3e7e=-0x22b3+0x1*0x2693+0x3e0*-0x1;_0x87109b=_0x5d5d56['charAt'](_0x2b3e7e++);~_0x87109b&&(_0x555d17=_0x358ebc%(0xa63*0x3+0x3*-0x3d8+0x139d*-0x1)?_0x555d17*(0x1075+0x26a7+-0x1*0x36dc)+_0x87109b:_0x87109b,_0x358ebc++%(-0x1*0x581+-0xa1b+0xfa0))?_0x4e6339+=_0x32bb7a['charCodeAt'](_0x2b3e7e+(0x1fa1*-0x1+-0xa*-0x2cf+-0x1*-0x395))-(0x4f*-0x54+0x23e+-0x2f7*-0x8)!==0x1dc6+-0x241*0x8+-0x6*0x1f5?String['fromCharCode'](0x1*-0x1cba+-0x19*0xb0+0xfa3*0x3&_0x555d17>>(-(0x106*0x4+-0x1*-0x25b5+-0x29cb*0x1)*_0x358ebc&0x2*0xe27+0x31*-0xc1+0x3*0x2e3)):_0x358ebc:-0x8*0x193+-0x1b7e+0xe*0x2dd){_0x87109b=_0x4ded4f['indexOf'](_0x87109b);}for(let _0x4ab261=-0xb03*-0x1+-0x13af+-0x25*-0x3c,_0x1bf0de=_0x4e6339['length'];_0x4ab261<_0x1bf0de;_0x4ab261++){_0x4e2666+='%'+('00'+_0x4e6339['charCodeAt'](_0x4ab261)['toString'](-0x1b5a+-0x1c29+-0x1*-0x3793))['slice'](-(0x118d+0x3c2*-0x1+-0xdc9));}return decodeURIComponent(_0x4e2666);};_0x55b4['MdfAjr']=_0x597acb,_0x55b4['RbOSWv']={},_0x55b4['vtKmdA']=!![];}const _0x40e937=_0x133d45[0x1884*-0x1+0x1b94+-0x7*0x70],_0x48e6fa=_0x44bf00+_0x40e937,_0x326ce0=_0x55b4['RbOSWv'][_0x48e6fa];if(!_0x326ce0){const _0x3a259e=function(_0x419f32){this['KkjKEe']=_0x419f32,this['dmzeda']=[-0x10a5+-0x1*0x677+0x171d,-0xd69+0x1*-0x1882+0x1*0x25eb,0x1*0x1781+-0x2060+-0x2f5*-0x3],this['jeEwtz']=function(){return'newState';},this['dOGguf']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['EmJePH']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x3a259e['prototype']['cbucdO']=function(){const _0x4daff5=new RegExp(this['dOGguf']+this['EmJePH']),_0x4610aa=_0x4daff5['test'](this['jeEwtz']['toString']())?--this['dmzeda'][-0x14d5+-0x2375+0x384b]:--this['dmzeda'][-0x173*-0x1+-0x1*0x208b+0x8*0x3e3];return this['njQviT'](_0x4610aa);},_0x3a259e['prototype']['njQviT']=function(_0x3af8b4){if(!Boolean(~_0x3af8b4))return _0x3af8b4;return this['EmLVxD'](this['KkjKEe']);},_0x3a259e['prototype']['EmLVxD']=function(_0xeccd53){for(let _0x59fe5a=-0x23*-0x3e+-0x2*-0x79a+-0x17ae,_0x2f4c2e=this['dmzeda']['length'];_0x59fe5a<_0x2f4c2e;_0x59fe5a++){this['dmzeda']['push'](Math['round'](Math['random']())),_0x2f4c2e=this['dmzeda']['length'];}return _0xeccd53(this['dmzeda'][0x1b28+0x1*-0x6c4+-0x6*0x366]);},new _0x3a259e(_0x55b4)['cbucdO'](),_0x88113c=_0x55b4['MdfAjr'](_0x88113c),_0x55b4['RbOSWv'][_0x48e6fa]=_0x88113c;}else _0x88113c=_0x326ce0;return _0x88113c;}import{createRequire}from'module';import{MEMORY_DIR,MEMORY_FILE,EMBEDDINGS_DB}from'../../paths.js';import{ASSETS_DIR,ASSETS_INDEX_MD}from'../../paths.js';import{detectProvider,parseProviderKey}from'./auto-detect.js';let SqliteClass=null,sqliteLoadAttempted=![],sqliteLoadError=null;const cjsRequire=createRequire(import.meta.url);function loadSqlite(){const _0x4010ca=_0x55b4,_0x5b2d23=_0x55b4;if(sqliteLoadAttempted)return SqliteClass;sqliteLoadAttempted=!![];try{return SqliteClass=cjsRequire(_0x4010ca(0xb8)+_0x4010ca(0xdc)),SqliteClass;}catch(_0xf0a605){return sqliteLoadError=_0xf0a605 instanceof Error?_0xf0a605:new Error(String(_0xf0a605)),console['log']('ℹ️\x20Semantic'+_0x4010ca(0xfc)+_0x5b2d23(0xa7)+_0x4010ca(0x11b)+_0x5b2d23(0x78)+_0x4010ca(0xca)+_0x4010ca(0xe5)+_0x4010ca(0xf9)+('Reinstall\x20'+_0x4010ca(0xec)+'m\x20rebuild\x20'+_0x4010ca(0xb8)+_0x5b2d23(0xc1)+'nable.')),null;}}const HUB_MEMORY_DIR=resolve(_0x1125c1[_0x2cb525(0xd2)](),_0x2cb525(0xd6),'hub',_0x4b9ae7(0x97)),SCHEMA_VERSION='2';let dbInstance=null,activeProvider=null,initialised=![],initInFlight=null;function openDb(){const _0xef6c4=_0x4b9ae7,_0x2ddf45=_0x4b9ae7;if(dbInstance)return dbInstance;const _0x133d45=loadSqlite();if(!_0x133d45)return null;return _0x50d532['mkdirSync'](_0x276de7[_0xef6c4(0x10f)](EMBEDDINGS_DB),{'recursive':!![]}),dbInstance=new _0x133d45(EMBEDDINGS_DB),dbInstance[_0xef6c4(0x105)](_0xef6c4(0xc3)+'de\x20=\x20WAL'),dbInstance[_0x2ddf45(0x105)](_0xef6c4(0x123)+'s\x20=\x20NORMAL'),dbInstance[_0xef6c4(0x105)](_0xef6c4(0xaa)+_0xef6c4(0xce)),dbInstance['pragma'](_0x2ddf45(0xb9)+'=\x2026843545'+'6'),dbInstance[_0xef6c4(0xa1)](_0x2ddf45(0xc9)+'E\x20TABLE\x20IF'+_0x2ddf45(0xfd)+_0x2ddf45(0xf0)+_0xef6c4(0xc8)+_0x2ddf45(0x8a)+_0x2ddf45(0xf7)+_0x2ddf45(0xe9)+_0x2ddf45(0xb6)+_0xef6c4(0x8f)+_0x2ddf45(0xff)+_0xef6c4(0xc4)+'F\x20NOT\x20EXIS'+_0xef6c4(0x103)+_0xef6c4(0xad)+_0x2ddf45(0x119)+_0xef6c4(0xe8)+_0x2ddf45(0xc6)+_0x2ddf45(0x9d)+_0xef6c4(0xaf)+_0x2ddf45(0x7a)+'\x20\x20\x20);\x0a\x20\x20'),dbInstance;}export function closeEmbeddingsDb(){const _0x2fbc06=_0x4b9ae7;dbInstance&&(dbInstance[_0x2fbc06(0x110)](),dbInstance=null),activeProvider=null,initialised=![],initInFlight=null;}function getMeta(_0x88113c,_0x597acb){const _0x2c9cc8=_0x2cb525,_0x41f18d=_0x2cb525,_0x40e937=_0x88113c[_0x2c9cc8(0xf2)](_0x41f18d(0xea)+_0x41f18d(0xae)+'ta\x20WHERE\x20k'+_0x41f18d(0xb0))[_0x2c9cc8(0xe3)](_0x597acb);return _0x40e937?.[_0x41f18d(0x73)]??null;}function setMeta(_0x48e6fa,_0x326ce0,_0x5d5d56){const _0x25cdaf=_0x2cb525,_0x5c501d=_0x2cb525;_0x48e6fa[_0x25cdaf(0xf2)]('INSERT\x20INT'+'O\x20meta\x20(ke'+_0x5c501d(0xfe)+'VALUES\x20(?,'+_0x25cdaf(0x80)+_0x25cdaf(0x8c)+_0x5c501d(0x90)+_0x5c501d(0x10b)+_0x5c501d(0x120)+_0x5c501d(0x121))[_0x5c501d(0xc0)](_0x326ce0,_0x5d5d56);}function clearAllProviderSchemas(_0x4ded4f){const _0x535af3=_0x4b9ae7,_0x3d5bbe=_0x4b9ae7;_0x4ded4f[_0x535af3(0xa1)]('DROP\x20TABLE'+_0x3d5bbe(0xb2)+'\x20entries;\x20'+'DROP\x20TABLE'+_0x3d5bbe(0xb2)+_0x535af3(0x9e)+_0x3d5bbe(0xbb)),_0x4ded4f[_0x3d5bbe(0xa1)](_0x3d5bbe(0xed)+_0x535af3(0x7c)+_0x535af3(0xd7));}function _0x207e(){const _0x5bf311=['DwuGrLjptsbTzq','zv9TCYbsrufmia','zxKGpsa/','otyXoe9XAMvnvq','ieLgievysvnuuW','C2nOzw1HvMvYCW','BxrPBwvnCW','lM10Aw1Lx21Z','ifrfwfqGtK9uia','4Os577Ipie1LBw9YEsbW','yMv0DgvYlxnXBa','Bw1HCf9ZAxPLia','ks4Gsw5PDgLHBa','Dhm7','kcGOlISPkYKRkq','DhjHBNnHy3rPBW','yxnZzxrZlW','BcbYDw4GB24GzG','CNvU','AxrLm2aGDg8Gzq','Cgf0Aa','AM91CM5HBf9TBW','veuGvefcteuGsq','ChvZAa','tufswsblrvKScG','mZHWEMXHAxa','icaGicbRzxKGia','cIaGicbduKvbva','C2LUzYbRzxL3BW','zwq6ia','Dw5HDMfPBgfIBa','zw5KC1DPDgG','id0Gtuvnt1jz','lM1K','ks4GuMvPBMrLEa','zhjVCevUDhjPzq','Ag9TzwrPCG','rvGUBwq','ChjVDMLKzxi','BNrYAwvZieXjtq','lMnSyxvKzq','BwvZoW','C3rHDfn5BMm','DgLLCG','su5ervGUBwq','x21Ziezst00GzG','AxrLmW','C0zVCLnVDxjJzq','zMLSzxm','ihrVDgfSkq','lNr4Da','CM92AwrLCIbJAa','Dg90ywW','z2v0','Aw5PDfnJAgvTyq','CMqGC2vHCMnOia','C3bSAxq','zwfYy2GGzMfPBa','icburvHuifbssq','icaGicb2ywX1zq','u0vmrunuihzHBa','ywXS','B3iGCNvUigbUCa','revmrvrfiezstW','AxjZDcb1C2uU','mta4mJzbEKjhB20','uYbTzxrHicGkia','CMvHzgrPCLn5BG','ChjLCgfYzq','iezst00G','CYKGvKfmvuvtia','Bg9N','y29UC3rYDwn0BW','qvjzieTfwsWkia','Aw9U','kezuuZuPlIa','zw50CMLLCW','mtjMB2Lorhy','ig1LBw9YEsaOyG','ie5pvcbfweLtva','EsWGDMfSDwuPia','oWOGicaGq1jfqq','C2L6zq','AxngAwXL','ignODw5RCYb2Aq','vfmGzMLSzv9TDa','zw52','ChjHz21H','ktOG','BM9Uzq','yw5Nzwq6ia','zwfYy2GGDw5HDG','nda1odC5nMrRrgTtBG','ifnfvcb2ywX1zq','CMvHzezPBgvtEq','DhjPBq','ig9Uig5LEhqGyq','zgLYBMfTzq','y2XVC2u','BML0igrLzMvYCG','DMvJDg9Y','AhvIlW','u0vmrunuihnVDq','Aw5KzxHdAhvUAW','BgfZDfjLAw5Kzq','Dw5RBM93BG','su5ervGUANnVBG','icaGC291CMnLia','yNL0zuXLBMD0Aa','DguZksb1BMf2yq','ig10Aw1Lx21Zia','tYbMAwXLx210Aq','iokgKIa','yxbWBhK','id0GzxHJBhvKzq','zc52ywX1zq','C2vHCMnO','C3LUy2HYB25VDq','DMfSDwu','vvbeqvrfifnfva','BgvUz3rO','AwXLx210Aw1LCW','lMnZCW','AwXHyMXLiokaLcb1','mZi2odqXu0XTzwrL','tK9uie5vteWkia','ywLSywjSztOG','tsbMAwXLx210Aq','BMrLEgvKoIa','C2L6zuj5DgvZ','BM93','id8Pie9oienptG','zgLT','ru1cruresu5huW','ntC5mJmWmuDfwLPgtW','8j+uJsbnzw1VCNKGAq','u0vmrunuihzLyW','y291BNrfBNrYAq','odqWALH3Bu1M','svqGmq','BMfTzq','ifrfwfqGufjjtq','psbLEgnSDwrLza','rKXjq1qOA2v5kq','Dg9tDhjPBMC','CM92AwrLCJOG','tLvmtaOGicaGkq','ierpifvqrefurq','Aw5KzxHLza','rMfPBgvKihrVia','nty2mhzvwLPlqG','zw1IzwrKAw5NxW','igLUzgv4ihDPBa','DxrMltG','tuvnt1jz','mJuYmtjpEwzxtxC','BwvZC2fNzq','Bw9KzwW','4Os577Ipie1LBw9YEsbZ','zw50CMLLC19MDa','icaGicaGBxrPBq','igvUDhjPzxnFzG','CMvSyxrPDMvqyq','zxHPC3rZu3LUyW','zxHLyW','CMnLlcbTDgLTzq','zwqGka','BwvTB3j5lW','ndi1mZi0mgPlB1fUyW','yxnZzxrZl0Lora','zxr0zxiTC3fSAq','u0vmrunuienpvq','CMvSyxrPDMu','DgvTCf9ZDg9Yzq','BwvZicHZB3vYyW','zsWGBxrPBwvFBq','Aw1LCYaOcIaGia'];_0x207e=function(){return _0x5bf311;};return _0x207e();}function getFileMtimes(_0x4e6339){const _0x979b02=_0x2cb525,_0x51d318=_0x2cb525,_0x4e2666=_0x4e6339['prepare'](_0x979b02(0x114)+_0x979b02(0xa2)+_0x51d318(0xdb)+_0x979b02(0x76))[_0x51d318(0xeb)](),_0x32bb7a={};for(const _0x358ebc of _0x4e2666)_0x32bb7a[_0x358ebc['source']]=_0x358ebc['mtime_ms'];return _0x32bb7a;}function setFileMtime(_0x555d17,_0x87109b,_0x2b3e7e){const _0xaa2aef=_0x2cb525,_0x2aad0b=_0x4b9ae7;_0x555d17[_0xaa2aef(0xf2)]('INSERT\x20INT'+_0x2aad0b(0x11d)+_0xaa2aef(0xab)+_0x2aad0b(0xac)+_0xaa2aef(0xf4)+'(?,\x20?)\x20ON\x20'+'CONFLICT(s'+'ource)\x20DO\x20'+_0x2aad0b(0x74)+_0x2aad0b(0x11c)+_0xaa2aef(0x8b)+_0x2aad0b(0xb5))[_0xaa2aef(0xc0)](_0x87109b,_0x2b3e7e);}const TEXT_EXTENSIONS=new Set(['.md','.html',_0x4b9ae7(0xe0),_0x2cb525(0x77),'.ts']);function walkAssetDir(_0x4ab261){const _0x1bf0de=[];function _0x3a259e(_0x419f32){const _0x52f6e8=_0x55b4,_0x257a40=_0x55b4;let _0x4daff5;try{_0x4daff5=_0x50d532[_0x52f6e8(0xf1)+'c'](_0x419f32,{'withFileTypes':!![]});}catch{return;}for(const _0x4610aa of _0x4daff5){const _0x3af8b4=resolve(_0x419f32,_0x4610aa[_0x52f6e8(0x89)]);if(_0x4610aa['isDirector'+'y']())_0x3a259e(_0x3af8b4);else{if(_0x4610aa[_0x52f6e8(0x101)]()){if(_0x419f32===_0x4ab261&&(_0x4610aa[_0x257a40(0x89)]===_0x52f6e8(0x118)||_0x4610aa[_0x257a40(0x89)]===_0x52f6e8(0xda)))continue;_0x1bf0de[_0x52f6e8(0xc5)]({'name':_0x4610aa[_0x257a40(0x89)],'path':_0x3af8b4});}}}}return _0x3a259e(_0x4ab261),_0x1bf0de;}function getIndexableFiles(){const _0x50f992=_0x2cb525,_0x3b7476=_0x4b9ae7,_0xeccd53=[];_0x50d532[_0x50f992(0xa0)](MEMORY_FILE)&&_0xeccd53['push']({'path':MEMORY_FILE,'relativePath':'MEMORY.md'});if(_0x50d532[_0x3b7476(0xa0)](MEMORY_DIR)){const _0x59fe5a=_0x50d532[_0x50f992(0xf1)+'c'](MEMORY_DIR);for(const _0x2f4c2e of _0x59fe5a){_0x2f4c2e[_0x50f992(0xcd)](_0x50f992(0xcf))&&!_0x2f4c2e['startsWith']('.')&&_0xeccd53[_0x50f992(0xc5)]({'path':resolve(MEMORY_DIR,_0x2f4c2e),'relativePath':_0x3b7476(0xa4)+_0x2f4c2e});}}if(_0x50d532[_0x3b7476(0xa0)](HUB_MEMORY_DIR))try{const _0x137185=_0x50d532['readdirSyn'+'c'](HUB_MEMORY_DIR);for(const _0x3ae1b6 of _0x137185){_0x3ae1b6[_0x50f992(0xcd)](_0x50f992(0xcf))&&!_0x3ae1b6['startsWith']('.')&&_0xeccd53[_0x50f992(0xc5)]({'path':resolve(HUB_MEMORY_DIR,_0x3ae1b6),'relativePath':_0x3b7476(0x113)+_0x3ae1b6});}}catch{}_0x50d532[_0x50f992(0xa0)](ASSETS_INDEX_MD)&&_0xeccd53[_0x3b7476(0xc5)]({'path':ASSETS_INDEX_MD,'relativePath':_0x3b7476(0xa6)+_0x3b7476(0xd3)});if(_0x50d532[_0x3b7476(0xa0)](ASSETS_DIR))for(const _0x145e5d of walkAssetDir(ASSETS_DIR)){TEXT_EXTENSIONS['has'](_0x276de7['extname'](_0x145e5d['name']))&&_0xeccd53[_0x50f992(0xc5)]({'path':_0x145e5d[_0x3b7476(0xc2)],'relativePath':_0x50f992(0xbe)+_0x276de7[_0x3b7476(0xa9)](ASSETS_DIR,_0x145e5d[_0x50f992(0xc2)])});}return _0xeccd53;}function getStaleFiles(_0x31ad99){const _0x458d2b=_0x2cb525,_0x513117=_0x2cb525,_0x4e0014=getIndexableFiles(),_0x5f3065=getFileMtimes(_0x31ad99),_0x1a6d79=[];for(const _0x1115d5 of _0x4e0014){try{const _0x23682d=_0x50d532[_0x458d2b(0xd8)](_0x1115d5[_0x513117(0xc2)])[_0x458d2b(0xb4)];(!_0x5f3065[_0x1115d5[_0x513117(0x9f)+'th']]||_0x5f3065[_0x1115d5['relativePa'+'th']]<_0x23682d)&&_0x1a6d79[_0x513117(0xc5)](_0x1115d5);}catch{}}return _0x1a6d79;}function chunkMarkdown(_0x4ca914,_0x3ffd87){const _0x30fbb2=_0x2cb525,_0x278d7a=_0x2cb525,_0x400ca3=[],_0x1504ad=_0x4ca914[_0x30fbb2(0xe6)](/^(?=## )/gm);for(let _0x58271d=-0x22b3+0x1*0x2693+0x3e0*-0x1;_0x58271d<_0x1504ad[_0x30fbb2(0x75)];_0x58271d++){const _0xd25dd4=_0x1504ad[_0x58271d][_0x278d7a(0x10d)]();if(!_0xd25dd4||_0xd25dd4[_0x278d7a(0x75)]<0xa63*0x3+0x3*-0x3d8+0x5b*-0x37)continue;if(_0xd25dd4[_0x30fbb2(0x75)]>0x1075+0x26a7+-0x2*0x199a){const _0x2a07de=_0xd25dd4['split'](/\n\n+/);let _0x138a1f='',_0xb5054e=-0x1*0x581+-0xa1b+0xf9c;for(const _0x1379f2 of _0x2a07de){_0x138a1f[_0x278d7a(0x75)]+_0x1379f2[_0x278d7a(0x75)]>0x1fa1*-0x1+-0xa*-0x2cf+-0x1*-0x6ab&&_0x138a1f[_0x30fbb2(0x75)]>0x4f*-0x54+0x23e+-0x806*-0x3&&(_0x400ca3[_0x30fbb2(0xc5)]({'id':_0x3ffd87+':'+_0x58271d+':'+_0xb5054e,'source':_0x3ffd87,'text':_0x138a1f['trim']()}),_0x138a1f='',_0xb5054e++),_0x138a1f+=_0x1379f2+'\x0a\x0a';}_0x138a1f[_0x278d7a(0x10d)]()[_0x30fbb2(0x75)]>0x1dc6+-0x241*0x8+-0x2*0x5d5&&_0x400ca3[_0x278d7a(0xc5)]({'id':_0x3ffd87+':'+_0x58271d+':'+_0xb5054e,'source':_0x3ffd87,'text':_0x138a1f[_0x30fbb2(0x10d)]()});}else _0x400ca3[_0x278d7a(0xc5)]({'id':_0x3ffd87+':'+_0x58271d,'source':_0x3ffd87,'text':_0xd25dd4});}return _0x400ca3;}function syncProviderSchema(_0x5edd1a,_0x53d3f3){const _0x26931c=_0x4b9ae7,_0x51531d=_0x2cb525,_0x55a13a=getMeta(_0x5edd1a,'embedding_'+_0x26931c(0x9a))??getMeta(_0x5edd1a,_0x26931c(0x9a)),_0x167a17=_0x55a13a!==null&&_0x55a13a!==_0x53d3f3['name'];return _0x167a17&&clearAllProviderSchemas(_0x5edd1a),_0x53d3f3[_0x51531d(0xe4)](_0x5edd1a),setMeta(_0x5edd1a,_0x51531d(0x94)+_0x51531d(0x9a),_0x53d3f3['name']),setMeta(_0x5edd1a,'embedding_'+'dim',String(_0x53d3f3[_0x51531d(0x81)])),setMeta(_0x5edd1a,_0x51531d(0x94)+_0x26931c(0xd9),_0x53d3f3['tier']),setMeta(_0x5edd1a,_0x26931c(0xb3)+_0x26931c(0xf8),SCHEMA_VERSION),{'switched':_0x167a17,'previous':_0x55a13a};}async function ensureInit(){if(initialised&&dbInstance&&activeProvider)return{'db':dbInstance,'provider':activeProvider};if(initInFlight)return await initInFlight,initialised&&dbInstance&&activeProvider?{'db':dbInstance,'provider':activeProvider}:null;initInFlight=((async()=>{const _0x4f0a7c=_0x55b4,_0x15b7a2=_0x55b4,_0x4a1782=openDb();if(!_0x4a1782)return;const _0x34796b=parseProviderKey(process[_0x4f0a7c(0x104)][_0x15b7a2(0x82)+'_PROVIDER']),_0x378c89=await detectProvider(_0x34796b),_0x399afd=syncProviderSchema(_0x4a1782,_0x378c89);if(_0x399afd['switched'])console[_0x15b7a2(0xf5)]('ℹ️\x20Memory\x20p'+_0x15b7a2(0xe1)+_0x15b7a2(0x108)+(_0x399afd['previous']??_0x4f0a7c(0x107))+_0x4f0a7c(0x11e)+_0x378c89['name']+'\x20('+_0x378c89['tier']+(_0x4f0a7c(0xd0)+_0x4f0a7c(0x10e)+'ccess.'));else{const _0x54aa8e=_0x378c89[_0x4f0a7c(0x86)+'es'](_0x4a1782);_0x54aa8e===0x1*-0x1cba+-0x19*0xb0+0x51a*0x9&&console[_0x4f0a7c(0xf5)](_0x4f0a7c(0xb7)+_0x15b7a2(0x8e)+_0x378c89[_0x4f0a7c(0x89)]+'\x20('+_0x378c89[_0x4f0a7c(0xd9)]+(_0x4f0a7c(0xba)+_0x15b7a2(0x95)+_0x15b7a2(0xbf)+_0x4f0a7c(0xee)));}activeProvider=_0x378c89,initialised=!![];})());try{await initInFlight;}finally{initInFlight=null;}return initialised&&dbInstance&&activeProvider?{'db':dbInstance,'provider':activeProvider}:null;}export async function reindexMemory(_0x265aed=![]){const _0x59663e=_0x2cb525,_0x3a10f2=_0x4b9ae7,_0xd5b826=await ensureInit();if(!_0xd5b826)return{'indexed':0x0,'total':0x0};const {db:_0x441653,provider:_0x39e377}=_0xd5b826,_0x43bb69=_0x265aed?getIndexableFiles():getStaleFiles(_0x441653);if(_0x43bb69[_0x59663e(0x75)]===0x106*0x4+-0x1*-0x25b5+-0xdef*0x3)return{'indexed':0x0,'total':_0x39e377['countEntri'+'es'](_0x441653)};_0x39e377[_0x3a10f2(0xd1)+_0x59663e(0xdd)+'s'](_0x441653,_0x43bb69['map'](_0x187b2b=>_0x187b2b[_0x59663e(0x9f)+'th']));const _0x3f4c2d=[],_0x1375b4=[];for(const _0x44f536 of _0x43bb69){try{const _0x17034d=_0x50d532[_0x3a10f2(0x10c)+'nc'](_0x44f536['path'],_0x59663e(0x96)),_0x34492f=chunkMarkdown(_0x17034d,_0x44f536[_0x3a10f2(0x9f)+'th']);for(const _0x318b08 of _0x34492f)_0x3f4c2d[_0x3a10f2(0xc5)](_0x318b08);_0x1375b4[_0x3a10f2(0xc5)](_0x44f536);}catch(_0x38af85){console['error'](_0x3a10f2(0x92)+'chunk\x20'+_0x44f536['relativePa'+'th']+':',_0x38af85);}}if(_0x3f4c2d['length']===0x2*0xe27+0x31*-0xc1+0x21*0x43){const _0x55f14f=_0x441653[_0x59663e(0xbd)+'n'](_0x2caa38=>{const _0x1efd41=_0x59663e,_0x299f7b=_0x3a10f2;for(const _0x5ac799 of _0x2caa38){try{setFileMtime(_0x441653,_0x5ac799['relativePa'+'th'],_0x50d532[_0x1efd41(0xd8)](_0x5ac799[_0x1efd41(0xc2)])[_0x1efd41(0xb4)]);}catch{}}});return _0x55f14f(_0x1375b4),{'indexed':0x0,'total':_0x39e377[_0x3a10f2(0x86)+'es'](_0x441653)};}await _0x39e377[_0x3a10f2(0x115)+'s'](_0x441653,_0x3f4c2d);const _0x469081=_0x441653['transactio'+'n'](_0x4e4eec=>{const _0x58ffda=_0x3a10f2,_0x4cfa67=_0x3a10f2;for(const _0x3d9d3d of _0x4e4eec){try{setFileMtime(_0x441653,_0x3d9d3d[_0x58ffda(0x9f)+'th'],_0x50d532[_0x58ffda(0xd8)](_0x3d9d3d[_0x58ffda(0xc2)])[_0x4cfa67(0xb4)]);}catch{}}});_0x469081(_0x1375b4),setMeta(_0x441653,_0x59663e(0x116)+'x',String(Date[_0x3a10f2(0x7f)]()));if(_0x39e377[_0x59663e(0x81)]===-0x8*0x193+-0x1b7e+0xe*0x2dd)try{const _0x454ba3=_0x441653[_0x59663e(0xf2)](_0x59663e(0x85)+'tor\x20FROM\x20e'+_0x3a10f2(0xd5)+_0x59663e(0x88))['get']();if(_0x454ba3?.['vector']){const _0x4441b2=_0x454ba3[_0x3a10f2(0x112)][_0x3a10f2(0x11a)]/(-0xb03*-0x1+-0x13af+-0x10*-0x8b);setMeta(_0x441653,_0x3a10f2(0x94)+_0x59663e(0x81),String(_0x4441b2));}}catch{}return{'indexed':_0x3f4c2d[_0x3a10f2(0x75)],'total':_0x39e377['countEntri'+'es'](_0x441653)};}export async function searchMemory(_0x1be35e,_0x4a8eb8=-0x1b5a+-0x1c29+-0x1*-0x3788,_0x116852=0x118d+0x3c2*-0x1+-0xdcb+0.3){const _0x1573eb=_0x2cb525,_0x4b7d32=_0x2cb525,_0x1e1fb3=await ensureInit();if(!_0x1e1fb3)return[];const {db:_0x3cf375,provider:_0x286ad8}=_0x1e1fb3;if(_0x286ad8['countEntri'+'es'](_0x3cf375)===0x1884*-0x1+0x1b94+-0x7*0x70){try{await reindexMemory();}catch(_0x46e8ec){return console[_0x1573eb(0xf5)]('ℹ️\x20Memory\x20s'+_0x1573eb(0x109)+_0x1573eb(0x7b)+(_0x46e8ec instanceof Error?_0x46e8ec['message']:String(_0x46e8ec))),[];}if(_0x286ad8['countEntri'+'es'](_0x3cf375)===-0x10a5+-0x1*0x677+0x171c)return[];}try{return await _0x286ad8['search'](_0x3cf375,_0x1be35e,_0x4a8eb8,_0x116852);}catch(_0x5ecf65){return console[_0x4b7d32(0xf5)](_0x1573eb(0x9b)+_0x1573eb(0xe7)+_0x4b7d32(0xa3)+_0x286ad8[_0x4b7d32(0x89)]+_0x1573eb(0x106)+(_0x5ecf65 instanceof Error?_0x5ecf65[_0x4b7d32(0x99)]:String(_0x5ecf65))),[];}}export async function initEmbeddings(){const _0x121c4f=_0x2cb525,_0x5626e7=_0x4b9ae7,_0x214c20=await ensureInit();if(!_0x214c20)return;const {db:_0x488670,provider:_0x48f6b8}=_0x214c20;try{const _0x31128a=getStaleFiles(_0x488670);if(_0x31128a[_0x121c4f(0x75)]===-0xd69+0x1*-0x1882+0x1*0x25eb&&_0x48f6b8[_0x121c4f(0x86)+'es'](_0x488670)>0x1*0x1781+-0x2060+-0x2f5*-0x3)return;const _0x174fc1=await reindexMemory();_0x174fc1[_0x5626e7(0x91)]>-0x14d5+-0x2375+0x384a&&console['log'](_0x121c4f(0x84)+_0x121c4f(0x7d)+_0x174fc1[_0x5626e7(0x91)]+(_0x121c4f(0x102)+'a\x20')+_0x48f6b8[_0x121c4f(0x89)]+'\x20('+_0x174fc1[_0x5626e7(0xe2)]+_0x5626e7(0xdf));}catch(_0x497855){console[_0x5626e7(0xf5)]('ℹ️\x20Memory\x20i'+_0x5626e7(0x111)+_0x121c4f(0xcb)+(_0x497855 instanceof Error?_0x497855[_0x5626e7(0x99)]:String(_0x497855)));}}export function getIndexStats(){const _0x5d521b=_0x2cb525,_0x1260e2=_0x4b9ae7,_0xfdb762={'entries':0x0,'files':0x0,'lastReindex':0x0,'sizeBytes':0x0,'provider':_0x5d521b(0xcc)+'e','tier':'none','dim':0x0};if(!loadSqlite())return _0xfdb762;const _0x57c362=openDb();if(!_0x57c362)return _0xfdb762;try{activeProvider?(_0xfdb762[_0x1260e2(0xfa)]=activeProvider[_0x5d521b(0x86)+'es'](_0x57c362),_0xfdb762['provider']=activeProvider[_0x1260e2(0x89)],_0xfdb762[_0x5d521b(0xd9)]=activeProvider[_0x5d521b(0xd9)],_0xfdb762[_0x5d521b(0x81)]=activeProvider['dim']):(_0xfdb762[_0x5d521b(0xd4)]=getMeta(_0x57c362,_0x5d521b(0x94)+_0x1260e2(0x9a))??_0x5d521b(0x117),_0xfdb762['tier']=getMeta(_0x57c362,_0x5d521b(0x94)+_0x1260e2(0xd9))??_0x1260e2(0x117),_0xfdb762[_0x5d521b(0x81)]=Number(getMeta(_0x57c362,'embedding_'+_0x5d521b(0x81))??-0x173*-0x1+-0x1*0x208b+0x8*0x3e3));_0xfdb762[_0x5d521b(0xde)]=_0x57c362[_0x5d521b(0xf2)](_0x1260e2(0xa8)+'NT(*)\x20AS\x20c'+'\x20FROM\x20file'+'_mtimes')[_0x5d521b(0xe3)]()['c'];const _0x5094ed=getMeta(_0x57c362,_0x1260e2(0x116)+'x');if(_0x5094ed)_0xfdb762[_0x5d521b(0x116)+'x']=Number(_0x5094ed);if(_0x50d532[_0x1260e2(0xa0)](EMBEDDINGS_DB))_0xfdb762[_0x1260e2(0x7e)]=_0x50d532['statSync'](EMBEDDINGS_DB)[_0x1260e2(0x100)];}catch{}return _0xfdb762;}export function getEmbeddingsBackendStatus(){return loadSqlite(),{'available':SqliteClass!==null,'error':sqliteLoadError?.['message']??null};}export function isSqliteMemoryReady(){const _0x2e2d39=_0x4b9ae7,_0x55d123=_0x2cb525;if(!loadSqlite())return![];const _0x7d9c93=openDb();if(!_0x7d9c93)return![];for(const _0x5e9189 of['entries',_0x2e2d39(0x9c)+'s']){try{const _0x5a5732=_0x7d9c93[_0x55d123(0xf2)](_0x55d123(0xa8)+'NT(*)\x20AS\x20c'+_0x55d123(0xf3)+_0x5e9189)[_0x55d123(0xe3)]();if(_0x5a5732&&_0x5a5732['c']>-0x23*-0x3e+-0x2*-0x79a+-0x17ae)return!![];}catch{}}return![];}
|
|
@@ -1,78 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Ollama Memory Provider — local, private, free embeddings via Ollama.
|
|
3
|
-
*
|
|
4
|
-
* Default model: nomic-embed-text (768-dim, ~270 MB pull).
|
|
5
|
-
* Alternatives via OLLAMA_EMBEDDING_MODEL: mxbai-embed-large (1024-dim),
|
|
6
|
-
* all-minilm (384-dim, fast), bge-large (1024-dim).
|
|
7
|
-
*
|
|
8
|
-
* Uses /api/embed (newer batched endpoint). Detects host via OLLAMA_HOST or
|
|
9
|
-
* OLLAMA_BASE_URL env, defaults to http://localhost:11434.
|
|
10
|
-
*/
|
|
11
|
-
import { VectorProviderBase } from "./vector-base.js";
|
|
12
|
-
const DEFAULT_MODEL = "nomic-embed-text";
|
|
13
|
-
const DEFAULT_HOST = "http://localhost:11434";
|
|
14
|
-
// Hardcoded dims for common models — saves a probe call. Unknown models fall
|
|
15
|
-
// through to dynamic detection on first embed().
|
|
16
|
-
const KNOWN_DIMS = {
|
|
17
|
-
"nomic-embed-text": 768,
|
|
18
|
-
"mxbai-embed-large": 1024,
|
|
19
|
-
"all-minilm": 384,
|
|
20
|
-
"bge-large": 1024,
|
|
21
|
-
"bge-small-en-v1.5": 384,
|
|
22
|
-
"snowflake-arctic-embed": 1024,
|
|
23
|
-
};
|
|
24
|
-
function ollamaHost() {
|
|
25
|
-
return process.env.OLLAMA_HOST || process.env.OLLAMA_BASE_URL || DEFAULT_HOST;
|
|
26
|
-
}
|
|
27
|
-
function ollamaModel() {
|
|
28
|
-
return process.env.OLLAMA_EMBEDDING_MODEL || DEFAULT_MODEL;
|
|
29
|
-
}
|
|
30
|
-
export class OllamaProvider extends VectorProviderBase {
|
|
31
|
-
name;
|
|
32
|
-
dim;
|
|
33
|
-
tier = "vector-local";
|
|
34
|
-
constructor() {
|
|
35
|
-
super();
|
|
36
|
-
const model = ollamaModel();
|
|
37
|
-
// Strip any tag like `:latest` for the dim lookup.
|
|
38
|
-
const baseModel = model.split(":")[0];
|
|
39
|
-
this.name = `ollama:${model}`;
|
|
40
|
-
this.dim = KNOWN_DIMS[baseModel] ?? 0; // 0 means "discover dynamically on first embed"
|
|
41
|
-
}
|
|
42
|
-
async isAvailable() {
|
|
43
|
-
try {
|
|
44
|
-
const res = await fetch(`${ollamaHost()}/api/tags`, {
|
|
45
|
-
signal: AbortSignal.timeout(2000),
|
|
46
|
-
});
|
|
47
|
-
if (!res.ok)
|
|
48
|
-
return false;
|
|
49
|
-
const data = (await res.json());
|
|
50
|
-
const wanted = ollamaModel();
|
|
51
|
-
const wantedBase = wanted.split(":")[0];
|
|
52
|
-
// Match either the exact tag or the base name.
|
|
53
|
-
return Boolean(data.models?.some(m => m.name === wanted || m.name.startsWith(`${wantedBase}:`)));
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async embed(texts) {
|
|
60
|
-
const res = await fetch(`${ollamaHost()}/api/embed`, {
|
|
61
|
-
method: "POST",
|
|
62
|
-
headers: { "Content-Type": "application/json" },
|
|
63
|
-
body: JSON.stringify({ model: ollamaModel(), input: texts }),
|
|
64
|
-
});
|
|
65
|
-
if (!res.ok) {
|
|
66
|
-
throw new Error(`Ollama embed error: ${res.status} — ${await res.text()}`);
|
|
67
|
-
}
|
|
68
|
-
const data = (await res.json());
|
|
69
|
-
if (!Array.isArray(data.embeddings) || data.embeddings.length !== texts.length) {
|
|
70
|
-
throw new Error(`Ollama embed returned ${data.embeddings?.length ?? 0} vectors, expected ${texts.length}`);
|
|
71
|
-
}
|
|
72
|
-
return data.embeddings;
|
|
73
|
-
}
|
|
74
|
-
async embedQuery(text) {
|
|
75
|
-
const [v] = await this.embed([text]);
|
|
76
|
-
return v;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
1
|
+
const _0x248139=_0x12f5,_0x3bfe97=_0x12f5;function _0x12f5(_0x38ede0,_0x2dc0e8){_0x38ede0=_0x38ede0-(0x23c5+0x9ee+-0x2bc2);const _0x40e61f=_0xc038();let _0xce8a5=_0x40e61f[_0x38ede0];if(_0x12f5['WZXkdb']===undefined){var _0x128131=function(_0x27d996){const _0x61b8ab='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1ee881='',_0x3f47d4='',_0x56df2f=_0x1ee881+_0x128131;for(let _0x10ad42=-0x42d*0x7+-0x178a+0x34c5,_0x92ca0a,_0x383c4e,_0x506d54=-0x1110+0x2611+0x1*-0x1501;_0x383c4e=_0x27d996['charAt'](_0x506d54++);~_0x383c4e&&(_0x92ca0a=_0x10ad42%(-0x18a9+-0x12af+0xb9*0x3c)?_0x92ca0a*(0x21fe+0x7*0x25c+-0x3242)+_0x383c4e:_0x383c4e,_0x10ad42++%(0x12c7+0x3b3+0x1676*-0x1))?_0x1ee881+=_0x56df2f['charCodeAt'](_0x506d54+(0x14f*0x1+-0x21f1+-0x1056*-0x2))-(0x5fa+-0x51*-0x6+-0x7d6)!==-0x1e71+0x1*0x2095+0x89*-0x4?String['fromCharCode'](-0x52*-0x6a+-0x21cf+0xda&_0x92ca0a>>(-(-0x1*-0x1f7b+0xc14+-0x2b8d)*_0x10ad42&-0x1*0x1a5d+0x1bd3+-0x170)):_0x10ad42:-0x1*-0x74f+0x933*-0x1+-0x79*-0x4){_0x383c4e=_0x61b8ab['indexOf'](_0x383c4e);}for(let _0x225c48=0x1751+-0x6*0xf1+0x11ab*-0x1,_0x5c008d=_0x1ee881['length'];_0x225c48<_0x5c008d;_0x225c48++){_0x3f47d4+='%'+('00'+_0x1ee881['charCodeAt'](_0x225c48)['toString'](-0x1*-0x499+0x5d4*-0x1+-0x1*-0x14b))['slice'](-(-0x739+-0x1a2f*-0x1+0x1*-0x12f4));}return decodeURIComponent(_0x3f47d4);};_0x12f5['eLxvTS']=_0x128131,_0x12f5['CSoAIi']={},_0x12f5['WZXkdb']=!![];}const _0x859b7a=_0x40e61f[-0x5*0x527+-0xde2+0x27a5],_0x3a7ae2=_0x38ede0+_0x859b7a,_0x494215=_0x12f5['CSoAIi'][_0x3a7ae2];if(!_0x494215){const _0x4f1caa=function(_0x4ac855){this['tavPXc']=_0x4ac855,this['TVRRcf']=[0xa24*-0x2+0x4*0x4e1+0xc5*0x1,-0xdd*-0x8+0x197*-0x9+0x767,0x25f*0x3+0x2*-0x163+-0x457],this['SKUvKG']=function(){return'newState';},this['zaRTRc']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['xTKCCh']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x4f1caa['prototype']['XXtVKh']=function(){const _0x41a762=new RegExp(this['zaRTRc']+this['xTKCCh']),_0x31a4ac=_0x41a762['test'](this['SKUvKG']['toString']())?--this['TVRRcf'][0xb0e+0x1*0x1c9+-0xcd6]:--this['TVRRcf'][0x1*-0x9e8+0x153b+-0xb53];return this['bGzidW'](_0x31a4ac);},_0x4f1caa['prototype']['bGzidW']=function(_0x4a7bf0){if(!Boolean(~_0x4a7bf0))return _0x4a7bf0;return this['fkUEcv'](this['tavPXc']);},_0x4f1caa['prototype']['fkUEcv']=function(_0x5850ae){for(let _0x15cf9b=-0xfc7+0x1*0x65f+-0x4b4*-0x2,_0x58a2fd=this['TVRRcf']['length'];_0x15cf9b<_0x58a2fd;_0x15cf9b++){this['TVRRcf']['push'](Math['round'](Math['random']())),_0x58a2fd=this['TVRRcf']['length'];}return _0x5850ae(this['TVRRcf'][-0xfdd*0x2+0x466*-0x2+0x2886]);},new _0x4f1caa(_0x12f5)['XXtVKh'](),_0xce8a5=_0x12f5['eLxvTS'](_0xce8a5),_0x12f5['CSoAIi'][_0x3a7ae2]=_0xce8a5;}else _0xce8a5=_0x494215;return _0xce8a5;}(function(_0x146a49,_0x4d0068){const _0xb9525e=_0x12f5,_0x48020b=_0x12f5,_0x5eb311=_0x146a49();while(!![]){try{const _0x13fe94=-parseInt(_0xb9525e(0x210))/(-0x2b7*0xb+-0x1*-0x931+-0x14ad*-0x1)*(-parseInt(_0xb9525e(0x1f7))/(0x17e9*-0x1+-0x203b+0x3826))+-parseInt(_0xb9525e(0x20c))/(-0xa0*0x16+0xcc6+0x17*0xb)+-parseInt(_0x48020b(0x216))/(0xe9*-0xc+0x1*0x244f+0x875*-0x3)+-parseInt(_0xb9525e(0x20a))/(0x5c*-0x3b+0x218d+0x6*-0x20e)*(parseInt(_0x48020b(0x21b))/(0x870+-0x1b9d+0x1333))+-parseInt(_0xb9525e(0x1fc))/(-0xfbc+-0x1d22*0x1+0x2ce5)*(parseInt(_0xb9525e(0x21c))/(0x504*-0x1+0x597*-0x2+-0x3e*-0x43))+parseInt(_0xb9525e(0x1f3))/(-0xe82+0x3a1*-0x1+-0x48b*-0x4)*(parseInt(_0xb9525e(0x1f2))/(0x479*0x2+0x101*0x24+0x1*-0x2d0c))+-parseInt(_0x48020b(0x205))/(0x2586+0x19b4+0x1*-0x3f2f)*(-parseInt(_0xb9525e(0x211))/(-0x1*-0x569+-0x1618+-0x10bb*-0x1));if(_0x13fe94===_0x4d0068)break;else _0x5eb311['push'](_0x5eb311['shift']());}catch(_0xb52d4e){_0x5eb311['push'](_0x5eb311['shift']());}}}(_0xc038,0x9*-0x13302+-0x5d2e*-0x2+0x1*0x1494a5));const _0x20dddf=(function(){let _0x5a90eb=!![];return function(_0xcb265f,_0x19d1c1){const _0xa88c93=_0x5a90eb?function(){const _0x4d0a4b=_0x12f5;if(_0x19d1c1){const _0x5774d5=_0x19d1c1[_0x4d0a4b(0x1f1)](_0xcb265f,arguments);return _0x19d1c1=null,_0x5774d5;}}:function(){};return _0x5a90eb=![],_0xa88c93;};}()),_0xf6b082=_0x20dddf(this,function(){const _0x2cb37b=_0x12f5,_0x117e55=_0x12f5;return _0xf6b082[_0x2cb37b(0x217)]()[_0x2cb37b(0x20d)](_0x117e55(0x1fe)+'+$')['toString']()['constructo'+'r'](_0xf6b082)[_0x117e55(0x20d)](_0x2cb37b(0x1fe)+'+$');});_0xf6b082();function _0xc038(){const _0x2c19d3=['DgLLCG','mJbqD2DyBK0','otK2q1jJzxvl','C3rHCNrZv2L0Aa','BM9TAwmTzw1Izq','zgLT','zxHWzwn0zwqG','mZu4mdG3mLfJvefPCq','Dg9tDhjPBMC','AxnbDMfPBgfIBa','C29Tzq','DMvJDg9YlwXVyW','mZyXodzfweXmqvG','mZCYmdCYogzfEuPtsG','yxbWBhK','mtbcBhrpsue','odGZntaWm0z5sejOrq','Ahr0CdOVl2XVyW','Dgv4Da','zw52','mteXmde0uer3wxLq','zwqGCMv0DxjUzq','t0Xmqu1bx0HpuW','zw1Izwq','BgvUz3rO','mtrfCuLMv1u','BMfTzq','kcGOlISPkYKRkq','ANnVBG','l2fWAs90ywDZ','zw1IzwrKAw5NCW','ue9tva','zwqGzxjYB3i6ia','l2fWAs9LBwjLza','mta1nZqZDM5Wrxjc','yxbWBgLJyxrPBW','AxnbCNjHEq','zc10zxH0','t2XSyw1HigvTyG','mti1vw5NyM1n','DgLTzw91Da','nJCZmti4wfn2DLj0','C2vHCMnO','C3rHDhvZ'];_0xc038=function(){return _0x2c19d3;};return _0xc038();}import{VectorProviderBase}from'./vector-base.js';const DEFAULT_MODEL=_0x248139(0x213)+_0x248139(0x208),DEFAULT_HOST=_0x3bfe97(0x1f4)+'alhost:114'+'34',KNOWN_DIMS={'nomic-embed-text':0x300,'mxbai-embed-large':0x400,'all-minilm':0x180,'bge-large':0x400,'bge-small-en-v1.5':0x180,'snowflake-arctic-embed':0x400};function ollamaHost(){const _0x312285=_0x248139,_0x58f8c9=_0x3bfe97;return process['env'][_0x312285(0x1f9)+'T']||process[_0x58f8c9(0x1f6)]['OLLAMA_BAS'+'E_URL']||DEFAULT_HOST;}function ollamaModel(){return process['env']['OLLAMA_EMB'+'EDDING_MOD'+'EL']||DEFAULT_MODEL;}export class OllamaProvider extends VectorProviderBase{[_0x3bfe97(0x1fd)];[_0x3bfe97(0x214)];[_0x248139(0x20f)]=_0x248139(0x21a)+'al';constructor(){const _0x324591=_0x3bfe97;super();const _0x2f9244=ollamaModel(),_0x32c362=_0x2f9244['split'](':')[0xb*-0x231+-0x190e+0x3129];this['name']='ollama:'+_0x2f9244,this[_0x324591(0x214)]=KNOWN_DIMS[_0x32c362]??0x2335*-0x1+0x14*-0x92+0x2e9d;}async[_0x3bfe97(0x218)+'e'](){const _0x47576a=_0x248139,_0x2cc849=_0x248139;try{const _0x397333=await fetch(ollamaHost()+_0x47576a(0x200),{'signal':AbortSignal[_0x2cc849(0x20b)](0x192f+0x1*0xbc3+-0x1d22)});if(!_0x397333['ok'])return![];const _0x4ded18=await _0x397333[_0x2cc849(0x1ff)](),_0x4a14c7=ollamaModel(),_0x5920e1=_0x4a14c7['split'](':')[0x1*-0x1cbf+0xc27+0x84c*0x2];return Boolean(_0x4ded18['models']?.[_0x2cc849(0x219)](_0x66c411=>_0x66c411[_0x2cc849(0x1fd)]===_0x4a14c7||_0x66c411[_0x47576a(0x1fd)][_0x2cc849(0x212)](_0x5920e1+':')));}catch{return![];}}async[_0x248139(0x1fa)](_0x533425){const _0x2071dd=_0x248139,_0x57d7d9=_0x248139,_0x19d77a=await fetch(ollamaHost()+_0x2071dd(0x204),{'method':_0x2071dd(0x202),'headers':{'Content-Type':_0x2071dd(0x206)+'n/json'},'body':JSON['stringify']({'model':ollamaModel(),'input':_0x533425})});if(!_0x19d77a['ok'])throw new Error(_0x2071dd(0x209)+_0x57d7d9(0x203)+_0x19d77a[_0x57d7d9(0x20e)]+'\x20—\x20'+await _0x19d77a[_0x57d7d9(0x1f5)]());const _0x8774a1=await _0x19d77a[_0x57d7d9(0x1ff)]();if(!Array[_0x57d7d9(0x207)](_0x8774a1[_0x57d7d9(0x201)])||_0x8774a1['embeddings'][_0x57d7d9(0x1fb)]!==_0x533425[_0x57d7d9(0x1fb)])throw new Error('Ollama\x20emb'+_0x57d7d9(0x1f8)+'d\x20'+(_0x8774a1['embeddings']?.[_0x2071dd(0x1fb)]??-0x1fc3+0x1*0x10f7+0xecc)+('\x20vectors,\x20'+_0x57d7d9(0x215))+_0x533425[_0x2071dd(0x1fb)]);return _0x8774a1[_0x2071dd(0x201)];}async['embedQuery'](_0x369e69){const _0x4487e9=_0x3bfe97,[_0x561c7f]=await this[_0x4487e9(0x1fa)]([_0x369e69]);return _0x561c7f;}}
|