alvin-bot 5.7.0 → 5.8.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/CHANGELOG.md +13 -0
- 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 _0x240d32=_0xf16a,_0x8c9a74=_0xf16a;(function(_0x10f025,_0x4de497){const _0x475f0a=_0xf16a,_0x803524=_0xf16a,_0x507582=_0x10f025();while(!![]){try{const _0x244cf3=parseInt(_0x475f0a(0xa7))/(0x589+0x197a+-0x1f02)*(-parseInt(_0x475f0a(0xb5))/(0xf70+0x2*0xbc+0x7*-0x26a))+-parseInt(_0x475f0a(0xb8))/(0x1ffb+0x1f0b+-0x13*0x351)+-parseInt(_0x475f0a(0x117))/(-0x1*-0x851+-0x3*-0x3b+-0x47f*0x2)+-parseInt(_0x803524(0x114))/(0x38*-0x7+0x1ad+-0x20*0x1)*(-parseInt(_0x475f0a(0xe0))/(-0x23e9+0x127e+0x1171))+parseInt(_0x803524(0x116))/(0x12ec+-0x16f8+0x413)*(-parseInt(_0x475f0a(0x10a))/(-0xdb8+0x18b4+-0x1*0xaf4))+parseInt(_0x803524(0xc9))/(0x7ff*-0x3+-0x1cd3*0x1+-0xa3*-0x53)*(parseInt(_0x803524(0x9a))/(0x22e2+0x30e*0x9+-0x3e56))+parseInt(_0x475f0a(0x107))/(-0x187e+-0x2450+0x3cd9)*(parseInt(_0x803524(0xc2))/(-0x1*-0x12b9+0x158a+-0x5*0x80b));if(_0x244cf3===_0x4de497)break;else _0x507582['push'](_0x507582['shift']());}catch(_0x18c6f0){_0x507582['push'](_0x507582['shift']());}}}(_0x2d1b,-0xf*-0x1a72d+0x8a960+-0xa5f*0x1e8));const _0x20a094=(function(){let _0x3bce4f=!![];return function(_0x402309,_0x3d93dc){const _0x33f47c=_0x3bce4f?function(){const _0x3677a3=_0xf16a;if(_0x3d93dc){const _0x496304=_0x3d93dc[_0x3677a3(0xae)](_0x402309,arguments);return _0x3d93dc=null,_0x496304;}}:function(){};return _0x3bce4f=![],_0x33f47c;};}()),_0x2c8d89=_0x20a094(this,function(){const _0x51758c=_0xf16a,_0x527084=_0xf16a;return _0x2c8d89[_0x51758c(0x85)]()[_0x527084(0xdd)](_0x51758c(0xbb)+'+$')[_0x51758c(0x85)]()[_0x527084(0xe6)+'r'](_0x2c8d89)[_0x527084(0xdd)]('(((.+)+)+)'+'+$');});_0x2c8d89();import _0x5947a6 from'fs';import _0xd8a7f3 from'path';import{resolve}from'path';import _0x13ef4d from'os';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 _0x557341=_0xf16a,_0xe1add9=_0xf16a;if(sqliteLoadAttempted)return SqliteClass;sqliteLoadAttempted=!![];try{return SqliteClass=cjsRequire(_0x557341(0xf3)+_0x557341(0x102)),SqliteClass;}catch(_0x220f3e){return sqliteLoadError=_0x220f3e instanceof Error?_0x220f3e:new Error(String(_0x220f3e)),console[_0xe1add9(0x6b)](_0xe1add9(0x11c)+'\x20memory\x20(b'+_0x557341(0xfc)+_0xe1add9(0xd0)+_0x557341(0xb6)+_0x557341(0xf0)+_0xe1add9(0xf6)+_0xe1add9(0xda)+(_0xe1add9(0x8c)+_0x557341(0x8f)+_0x557341(0xd2)+_0x557341(0xf3)+_0x557341(0xfd)+_0xe1add9(0x73))),null;}}const HUB_MEMORY_DIR=resolve(_0x13ef4d[_0x240d32(0x119)](),_0x8c9a74(0xde),_0x240d32(0xd6),_0x240d32(0x10c)),SCHEMA_VERSION='2';function _0x2d1b(){const _0x61c32=['BwvTB3j5lW','oteZnZK3oxzsCuHqqG','tYbMAwXLx210Aq','CMvHzgrPCLn5BG','vvbeqvrfifnfva','EsWGDMfSDwuPia','CMvSyxrPDMu','Dw5RBM93BG','DguZksb1BMf2yq','zguGpsbxquW','BsbYzwj1AwXKia','id0Gtuvnt1jz','BgvUz3rO','BcbYDw4GB24GzG','AhvI','BgfZDfjLAw5Kzq','CM92AwrLCIbJAa','x21Ziezst00GzG','kezuuZuPlIa','vKfmvuvticG/la','BML0igrLzMvYCG','C2vHCMnO','lMnSyxvKzq','CNvU','nZaWmZiWEKLsB1HY','zxH0BMfTzq','zwqGka','Bw9KzwW','icburvHuifbssq','ignODw5RCYb2Aq','y29UC3rYDwn0BW','veuGvefcteuGsq','AgfZ','cIaGicbduKvbva','rvGUBwq','iokgKIa','igvUDhjPzxnFzG','4Os577Ipie1LBw9YEsbP','C2L6zuj5DgvZ','CYKGvKfmvuvtia','C2LUzYbRzxL3BW','icaGC291CMnLia','x1bst1zjrevs','yMv0DgvYlxnXBa','BMfTzq','z2v0','CMqGC2vHCMnOia','tuvnt1jzlM1K','DhjHBNnHy3rPBW','zgLT','8j+uJsbnzw1VCNKGAq','id8Pie9oienptG','zxr0zxiTC3fSAq','AxrLm2aGDg8Gzq','igvUDhjPzxm7ia','DgLLCG','tLvmtaOGicaGkq','zw52','AxrLmW','zwfYy2GGzMfPBa','C0zVCLnVDxjJzq','id0GzxHJBhvKzq','BxrPBwvFBxm','mJyYmtm3n21VuvjSrq','BwvZoW','ktOG','mJqWrNHLEuLs','BM93','tuvnt1jz','BwfW','CYa9ie5puK1bta','lM10Aw1Lx21Z','u0vmrunuihnVDq','C3bSAxq','BwvZC2fNzq','zwq6ia','nZbOAujRuKy','zxHLyW','mZy3nJmZBuP4y0Pe','ntG4mZKYnhDTtvzUtq','qvjzieTfwsWkia','Ag9TzwrPCG','4Os577Ipie1LBw9YEsbW','Bw1HCf9ZAxPLia','4Os577IpifnLBwfUDgLJ','DMvJDg9Y','Bg9N','lNrZ','DhjPBq','zw5KC1DPDgG','ru1cruresu5huW','yxnZzxrZlW','ig10Aw1Lx21Zia','zw1IzwrKAw5NxW','BMfIBguU','iezst00GzMLSzq','ChjHz21H','rIbot1qGrvHjuW','Aw5KzxHdAhvUAW','zxHPC3rZu3LUyW','C3LUy2HYB25VDq','zwfYy2GGDw5HDG','tK9uie5vteWkia','ifnfvcb2ywX1zq','ieLgievysvnuuW','kd8Sid8Pie9oia','Dg90ywW','C3rHCNrZv2L0Aa','y291BNrfBNrYAq','Aw1LCYaOcIaGia','ChjLCgfYzq','lMnZCW','Dg9tDhjPBMC','yxnZzxrZl0Lora','rKXjq1qOA2v5kq','ChvZAa','Dw5HDMfPBgfIBa','rMfPBgvKihrVia','AM91CM5HBf9TBW','uMvPBNn0ywXSia','y2XVC2u','Cgf0Aa','B3iGCNvUigbUCa','BM9Uzq','zc52ywX1zq','AwXLx210Aw1LCW','iezst00G','AxngAwXL','su5trvjuieLova','Aw5KzxHLza','zw50CMLLCW','zMLSzxm','BwTKAxjtEw5J','mtbxrKjsq04','psaYnJG0mZu0nq','BNrYAwvZieXjtq','icaGicb2ywX1zq','C3rHDfn5BMm','zxKGpsa/','tLqOkIKGqvmGyW','tYbTzxrHicHRzq','AxjZDcb1C2uU','zhjVCevUDhjPzq','AhvIlW','ihrVDgfSkq','lM1K','mteZnZGZmwPyruHjqG','BwvZicHZB3vYyW','y2nLC3mU','y2H1BMSG','ie5pvcbfweLtva','icaGicaGBxrPBq','uYbTzxrHicGkia','yxbWBhK','DMfSDwu','svqGmq','tsbMAwXLx210Aq','CMvSyxrPDMvqyq','ks4Gsw5PDgLHBa','zv9TCYbsrufmia','mLDmBxD2Ea','AwXHyMXLiokaLcb1','DgeGv0HfuKuGAW','mtK5oda1mwLnEgvbCG','revmrvrfiezstW','vfmGzMLSzv9TDa','kcGOlISPkYKRkq','C3DPDgnOzwq','BMrLEgvKoIa','C291CMnL','zxjYB3i','u0vmrunuihzLyW','ifrfwfqGtK9uia','mtu2Auzhuvbk','BxrPBwvnCW','lMH0BwW','ifrfwfqGufjjtq','AxneAxjLy3rVCG','psbLEgnSDwrLza'];_0x2d1b=function(){return _0x61c32;};return _0x2d1b();}let dbInstance=null,activeProvider=null,initialised=![],initInFlight=null;function openDb(){const _0x12f2c6=_0x240d32,_0x4f377f=_0x8c9a74;if(dbInstance)return dbInstance;const _0x3b18f0=loadSqlite();if(!_0x3b18f0)return null;return _0x5947a6[_0x12f2c6(0x99)](_0xd8a7f3['dirname'](EMBEDDINGS_DB),{'recursive':!![]}),dbInstance=new _0x3b18f0(EMBEDDINGS_DB),dbInstance[_0x12f2c6(0x75)](_0x4f377f(0x8b)+_0x12f2c6(0xd1)),dbInstance[_0x4f377f(0x75)](_0x12f2c6(0x79)+_0x4f377f(0x10e)),dbInstance[_0x12f2c6(0x75)]('temp_store'+_0x12f2c6(0xd3)),dbInstance[_0x12f2c6(0x75)](_0x12f2c6(0x11b)+_0x4f377f(0x9b)+'6'),dbInstance['exec'](_0x4f377f(0xe9)+'E\x20TABLE\x20IF'+_0x4f377f(0xab)+_0x4f377f(0xad)+'\x20\x20\x20\x20\x20key\x20\x20'+_0x12f2c6(0xc5)+_0x4f377f(0x118)+_0x4f377f(0x9d)+_0x4f377f(0xc1)+_0x12f2c6(0x100)+';\x0a\x20\x20\x20\x20CREA'+_0x12f2c6(0xe7)+_0x4f377f(0x76)+_0x12f2c6(0xba)+_0x4f377f(0x82)+_0x12f2c6(0xf1)+_0x4f377f(0xe4)+'MARY\x20KEY,\x0a'+_0x4f377f(0xac)+_0x12f2c6(0xb4)+_0x12f2c6(0x7b)+'\x20\x20\x20);\x0a\x20\x20'),dbInstance;}export function closeEmbeddingsDb(){const _0x591a88=_0x8c9a74;dbInstance&&(dbInstance[_0x591a88(0x8d)](),dbInstance=null),activeProvider=null,initialised=![],initInFlight=null;}function getMeta(_0x52c717,_0x57573c){const _0x5915fa=_0x240d32,_0x174e59=_0x240d32,_0x331e4f=_0x52c717[_0x5915fa(0x83)]('SELECT\x20val'+'ue\x20FROM\x20me'+_0x5915fa(0xb7)+_0x5915fa(0x9f))['get'](_0x57573c);return _0x331e4f?.[_0x5915fa(0xaf)]??null;}function setMeta(_0x4acfa9,_0x51189c,_0x46f08e){const _0x4d7e7c=_0x240d32,_0x49c465=_0x8c9a74;_0x4acfa9['prepare'](_0x4d7e7c(0x95)+_0x49c465(0xa1)+_0x49c465(0xcd)+_0x4d7e7c(0xdb)+_0x49c465(0xfb)+_0x49c465(0x87)+'\x20DO\x20UPDATE'+_0x49c465(0x7c)+_0x49c465(0x105)+_0x4d7e7c(0x91))[_0x4d7e7c(0xdf)](_0x51189c,_0x46f08e);}function clearAllProviderSchemas(_0x16cfeb){const _0xea3086=_0x240d32,_0x1c4cb0=_0x240d32;_0x16cfeb[_0xea3086(0x115)]('DROP\x20TABLE'+_0x1c4cb0(0x7d)+_0xea3086(0xfe)+'DROP\x20TABLE'+_0xea3086(0x7d)+_0x1c4cb0(0xec)+'ts;'),_0x16cfeb['exec'](_0x1c4cb0(0xb9)+_0xea3086(0xb1)+_0x1c4cb0(0x108));}function getFileMtimes(_0x30e5d8){const _0x3a7a7c=_0x8c9a74,_0x3f172b=_0x8c9a74,_0x1e4d45=_0x30e5d8['prepare'](_0x3a7a7c(0x110)+'rce,\x20mtime'+_0x3a7a7c(0xd9)+_0x3a7a7c(0x92))['all'](),_0x1d5665={};for(const _0x1583a0 of _0x1e4d45)_0x1d5665[_0x1583a0[_0x3f172b(0xbe)]]=_0x1583a0[_0x3f172b(0x106)];return _0x1d5665;}function setFileMtime(_0x3c520a,_0x29e1f3,_0x504a48){const _0x279d54=_0x8c9a74,_0x5c1ad1=_0x240d32;_0x3c520a[_0x279d54(0x83)](_0x279d54(0x95)+_0x5c1ad1(0xca)+_0x279d54(0xa8)+'e,\x20mtime_m'+_0x5c1ad1(0xef)+_0x279d54(0x7e)+'CONFLICT(s'+'ource)\x20DO\x20'+_0x279d54(0xcc)+_0x5c1ad1(0x71)+_0x5c1ad1(0xc7)+_0x279d54(0x10f))['run'](_0x29e1f3,_0x504a48);}const TEXT_EXTENSIONS=new Set([_0x8c9a74(0xa6),_0x8c9a74(0xc4),'.txt',_0x240d32(0x84),_0x240d32(0x6c)]);function walkAssetDir(_0x591548){const _0x4cc4a2=[];function _0x3032b2(_0x4f825e){const _0x11b820=_0xf16a,_0xe27a3f=_0xf16a;let _0x5dc4d2;try{_0x5dc4d2=_0x5947a6[_0x11b820(0xcb)+'c'](_0x4f825e,{'withFileTypes':!![]});}catch{return;}for(const _0x1805d5 of _0x5dc4d2){const _0x4017e7=resolve(_0x4f825e,_0x1805d5['name']);if(_0x1805d5[_0xe27a3f(0xc6)+'y']())_0x3032b2(_0x4017e7);else{if(_0x1805d5[_0x11b820(0x94)]()){if(_0x4f825e===_0x591548&&(_0x1805d5[_0xe27a3f(0xf4)]==='INDEX.json'||_0x1805d5['name']==='INDEX.md'))continue;_0x4cc4a2['push']({'name':_0x1805d5[_0xe27a3f(0xf4)],'path':_0x4017e7});}}}}return _0x3032b2(_0x591548),_0x4cc4a2;}function getIndexableFiles(){const _0x43619d=_0x240d32,_0x26c940=_0x240d32,_0x4bf087=[];_0x5947a6[_0x43619d(0x78)](MEMORY_FILE)&&_0x4bf087[_0x26c940(0x88)]({'path':MEMORY_FILE,'relativePath':_0x43619d(0xf7)});if(_0x5947a6[_0x43619d(0x78)](MEMORY_DIR)){const _0x4ac8ca=_0x5947a6['readdirSyn'+'c'](MEMORY_DIR);for(const _0x3b0a02 of _0x4ac8ca){_0x3b0a02[_0x26c940(0x6e)]('.md')&&!_0x3b0a02[_0x43619d(0x80)]('.')&&_0x4bf087[_0x43619d(0x88)]({'path':resolve(MEMORY_DIR,_0x3b0a02),'relativePath':_0x26c940(0xc8)+_0x3b0a02});}}if(_0x5947a6[_0x43619d(0x78)](HUB_MEMORY_DIR))try{const _0x3f7d33=_0x5947a6[_0x43619d(0xcb)+'c'](HUB_MEMORY_DIR);for(const _0x230143 of _0x3f7d33){_0x230143[_0x43619d(0x6e)](_0x43619d(0xa6))&&!_0x230143['startsWith']('.')&&_0x4bf087[_0x43619d(0x88)]({'path':resolve(HUB_MEMORY_DIR,_0x230143),'relativePath':_0x26c940(0xa4)+_0x230143});}}catch{}_0x5947a6[_0x26c940(0x78)](ASSETS_INDEX_MD)&&_0x4bf087['push']({'path':ASSETS_INDEX_MD,'relativePath':_0x26c940(0x86)+_0x26c940(0xea)});if(_0x5947a6[_0x43619d(0x78)](ASSETS_DIR))for(const _0x1d5076 of walkAssetDir(ASSETS_DIR)){TEXT_EXTENSIONS[_0x26c940(0xe8)](_0xd8a7f3[_0x43619d(0xe1)](_0x1d5076[_0x43619d(0xf4)]))&&_0x4bf087[_0x26c940(0x88)]({'path':_0x1d5076[_0x26c940(0x8e)],'relativePath':_0x26c940(0x70)+_0xd8a7f3[_0x43619d(0xce)](ASSETS_DIR,_0x1d5076[_0x43619d(0x8e)])});}return _0x4bf087;}function getStaleFiles(_0x1d77ae){const _0x402127=_0x8c9a74,_0xa14984=_0x240d32,_0x26da4f=getIndexableFiles(),_0x4a98bb=getFileMtimes(_0x1d77ae),_0x30b2b9=[];for(const _0x4e8a0f of _0x26da4f){try{const _0x308b4b=_0x5947a6['statSync'](_0x4e8a0f[_0x402127(0x8e)])['mtimeMs'];(!_0x4a98bb[_0x4e8a0f[_0xa14984(0xb2)+'th']]||_0x4a98bb[_0x4e8a0f[_0x402127(0xb2)+'th']]<_0x308b4b)&&_0x30b2b9[_0xa14984(0x88)](_0x4e8a0f);}catch{}}return _0x30b2b9;}function chunkMarkdown(_0x2cf5c6,_0x11d39b){const _0x58f3c3=_0x8c9a74,_0x2868a3=_0x240d32,_0x10b6a3=[],_0x1d4f57=_0x2cf5c6['split'](/^(?=## )/gm);for(let _0x30d7b2=-0x1*0xc44+0x22ba+-0x47e*0x5;_0x30d7b2<_0x1d4f57[_0x58f3c3(0xd4)];_0x30d7b2++){const _0x24c0b9=_0x1d4f57[_0x30d7b2][_0x58f3c3(0x6d)]();if(!_0x24c0b9||_0x24c0b9[_0x58f3c3(0xd4)]<0x2*-0x12e6+0x1bb6+0x1*0xa2a)continue;if(_0x24c0b9[_0x2868a3(0xd4)]>0x5a4*-0x1+-0x256*-0x9+-0xb7a){const _0x1c16f6=_0x24c0b9[_0x58f3c3(0x111)](/\n\n+/);let _0x14dc40='',_0x291074=-0x1048*0x1+-0x10da+0x2122;for(const _0x2ffbb6 of _0x1c16f6){_0x14dc40[_0x2868a3(0xd4)]+_0x2ffbb6[_0x2868a3(0xd4)]>0x2437+-0xc4a*-0x2+-0x39ab&&_0x14dc40['length']>-0x2f*-0x6f+0x3*0xf4+-0x16d9&&(_0x10b6a3['push']({'id':_0x11d39b+':'+_0x30d7b2+':'+_0x291074,'source':_0x11d39b,'text':_0x14dc40['trim']()}),_0x14dc40='',_0x291074++),_0x14dc40+=_0x2ffbb6+'\x0a\x0a';}_0x14dc40[_0x58f3c3(0x6d)]()['length']>0x6a8+-0x1c75+0x74b*0x3&&_0x10b6a3[_0x58f3c3(0x88)]({'id':_0x11d39b+':'+_0x30d7b2+':'+_0x291074,'source':_0x11d39b,'text':_0x14dc40[_0x58f3c3(0x6d)]()});}else _0x10b6a3[_0x2868a3(0x88)]({'id':_0x11d39b+':'+_0x30d7b2,'source':_0x11d39b,'text':_0x24c0b9});}return _0x10b6a3;}function syncProviderSchema(_0x32f6c6,_0x286e42){const _0x3e3513=_0x8c9a74,_0x10094d=_0x240d32,_0x17b04f=getMeta(_0x32f6c6,_0x3e3513(0x72)+_0x10094d(0xe3))??getMeta(_0x32f6c6,_0x10094d(0xe3)),_0x3f0f75=_0x17b04f!==null&&_0x17b04f!==_0x286e42[_0x3e3513(0xf4)];return _0x3f0f75&&clearAllProviderSchemas(_0x32f6c6),_0x286e42['initSchema'](_0x32f6c6),setMeta(_0x32f6c6,'embedding_'+_0x3e3513(0xe3),_0x286e42[_0x3e3513(0xf4)]),setMeta(_0x32f6c6,'embedding_'+_0x10094d(0xf9),String(_0x286e42[_0x10094d(0xf9)])),setMeta(_0x32f6c6,_0x10094d(0x72)+_0x10094d(0xff),_0x286e42[_0x3e3513(0xff)]),setMeta(_0x32f6c6,'schemaVers'+'ion',SCHEMA_VERSION),{'switched':_0x3f0f75,'previous':_0x17b04f};}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 _0x1301cf=_0xf16a,_0x2a2d75=_0xf16a,_0x221f9d=openDb();if(!_0x221f9d)return;const _0x5af4b2=parseProviderKey(process[_0x1301cf(0x101)][_0x2a2d75(0x6f)+_0x2a2d75(0xf2)]),_0x5ca573=await detectProvider(_0x5af4b2),_0x2ccaf8=syncProviderSchema(_0x221f9d,_0x5ca573);if(_0x2ccaf8[_0x2a2d75(0xbc)])console[_0x1301cf(0x6b)](_0x1301cf(0x11a)+_0x2a2d75(0xd8)+'anged:\x20'+(_0x2ccaf8['previous']??'none')+_0x2a2d75(0xeb)+_0x5ca573['name']+'\x20('+_0x5ca573[_0x2a2d75(0xff)]+(').\x20Reindex'+'\x20on\x20next\x20a'+_0x1301cf(0xa9)));else{const _0x2317bf=_0x5ca573['countEntri'+'es'](_0x221f9d);_0x2317bf===0x12dc+0x34*0x23+-0x19f8&&console[_0x1301cf(0x6b)](_0x2a2d75(0x11a)+'rovider:\x20'+_0x5ca573[_0x1301cf(0xf4)]+'\x20('+_0x5ca573[_0x2a2d75(0xff)]+(_0x1301cf(0xb3)+'\x20index\x20wil'+_0x2a2d75(0xd5)+_0x1301cf(0xa2)));}activeProvider=_0x5ca573,initialised=!![];})());try{await initInFlight;}finally{initInFlight=null;}return initialised&&dbInstance&&activeProvider?{'db':dbInstance,'provider':activeProvider}:null;}export async function reindexMemory(_0x4b5aa8=![]){const _0x246b5a=_0x8c9a74,_0x1066a9=_0x8c9a74,_0x586431=await ensureInit();if(!_0x586431)return{'indexed':0x0,'total':0x0};const {db:_0x375295,provider:_0x400bc5}=_0x586431,_0x550f87=_0x4b5aa8?getIndexableFiles():getStaleFiles(_0x375295);if(_0x550f87['length']===0x354+0x31*0x43+0x1027*-0x1)return{'indexed':0x0,'total':_0x400bc5[_0x246b5a(0x81)+'es'](_0x375295)};_0x400bc5[_0x246b5a(0xa3)+_0x1066a9(0x104)+'s'](_0x375295,_0x550f87[_0x1066a9(0x10d)](_0x57702f=>_0x57702f[_0x246b5a(0xb2)+'th']));const _0xc787b0=[],_0x34f4bd=[];for(const _0x5532d1 of _0x550f87){try{const _0x47f0f1=_0x5947a6['readFileSy'+'nc'](_0x5532d1[_0x1066a9(0x8e)],'utf-8'),_0x4590d2=chunkMarkdown(_0x47f0f1,_0x5532d1['relativePa'+'th']);for(const _0x2dabb6 of _0x4590d2)_0xc787b0[_0x1066a9(0x88)](_0x2dabb6);_0x34f4bd['push'](_0x5532d1);}catch(_0x498a94){console[_0x246b5a(0xbf)](_0x1066a9(0x8a)+_0x1066a9(0xaa)+_0x5532d1[_0x246b5a(0xb2)+'th']+':',_0x498a94);}}if(_0xc787b0[_0x246b5a(0xd4)]===0x11*0x29+-0x269f+0xa*0x397){const _0x4646ff=_0x375295[_0x246b5a(0xf8)+'n'](_0x551f0a=>{const _0x16984b=_0x1066a9,_0x2280d1=_0x246b5a;for(const _0x56c9c4 of _0x551f0a){try{setFileMtime(_0x375295,_0x56c9c4[_0x16984b(0xb2)+'th'],_0x5947a6[_0x16984b(0x9e)](_0x56c9c4['path'])[_0x2280d1(0xc3)]);}catch{}}});return _0x4646ff(_0x34f4bd),{'indexed':0x0,'total':_0x400bc5['countEntri'+'es'](_0x375295)};}await _0x400bc5[_0x246b5a(0x77)+'s'](_0x375295,_0xc787b0);const _0xe3a1d6=_0x375295[_0x246b5a(0xf8)+'n'](_0x2a99f5=>{const _0x2da64a=_0x246b5a,_0x58a084=_0x1066a9;for(const _0x4c1214 of _0x2a99f5){try{setFileMtime(_0x375295,_0x4c1214[_0x2da64a(0xb2)+'th'],_0x5947a6[_0x58a084(0x9e)](_0x4c1214[_0x2da64a(0x8e)])['mtimeMs']);}catch{}}});_0xe3a1d6(_0x34f4bd),setMeta(_0x375295,'lastReinde'+'x',String(Date[_0x246b5a(0x10b)]()));if(_0x400bc5[_0x246b5a(0xf9)]===-0x1*0x4ff+-0x34b*0x9+0x22a2)try{const _0x452c1f=_0x375295['prepare'](_0x246b5a(0xc0)+'tor\x20FROM\x20e'+_0x246b5a(0x9c)+_0x1066a9(0xb0))[_0x246b5a(0xf5)]();if(_0x452c1f?.[_0x1066a9(0x11d)]){const _0x49970e=_0x452c1f[_0x1066a9(0x11d)]['byteLength']/(0xa6*-0x35+-0x1f10+0x4172);setMeta(_0x375295,_0x1066a9(0x72)+_0x246b5a(0xf9),String(_0x49970e));}}catch{}return{'indexed':_0xc787b0[_0x246b5a(0xd4)],'total':_0x400bc5[_0x1066a9(0x81)+'es'](_0x375295)};}export async function searchMemory(_0x4f9406,_0x6ad0b1=-0x80*-0x42+0x3b5*-0x6+-0xabd,_0x5d4f7e=-0x263b+-0x1ab2+0x40ed*0x1+0.3){const _0x1a879a=_0x240d32,_0x268b39=_0x240d32,_0x4b1923=await ensureInit();if(!_0x4b1923)return[];const {db:_0x4a848c,provider:_0x2f3555}=_0x4b1923;if(_0x2f3555['countEntri'+'es'](_0x4a848c)===0x1f*0x91+-0x1*0x11e7+0x58){try{await reindexMemory();}catch(_0x4007d7){return console[_0x1a879a(0x6b)]('ℹ️\x20Memory\x20s'+_0x1a879a(0x7a)+'ailable:\x20'+(_0x4007d7 instanceof Error?_0x4007d7['message']:String(_0x4007d7))),[];}if(_0x2f3555[_0x1a879a(0x81)+'es'](_0x4a848c)===-0x12b*0x1+-0xa7*-0x1f+0x1*-0x130e)return[];}try{return await _0x2f3555['search'](_0x4a848c,_0x4f9406,_0x6ad0b1,_0x5d4f7e);}catch(_0x49f7e9){return console[_0x1a879a(0x6b)]('ℹ️\x20Memory\x20s'+_0x1a879a(0x103)+_0x1a879a(0xe2)+_0x2f3555[_0x268b39(0xf4)]+_0x1a879a(0x109)+(_0x49f7e9 instanceof Error?_0x49f7e9[_0x268b39(0x112)]:String(_0x49f7e9))),[];}}export async function initEmbeddings(){const _0x33664e=_0x240d32,_0xd7282f=_0x240d32,_0x409800=await ensureInit();if(!_0x409800)return;const {db:_0x111285,provider:_0x5d3777}=_0x409800;try{const _0x16ab67=getStaleFiles(_0x111285);if(_0x16ab67[_0x33664e(0xd4)]===-0xc6c+-0x3*0x1+0xc6f&&_0x5d3777[_0xd7282f(0x81)+'es'](_0x111285)>0x493+-0x4de+0x4b)return;const _0x18818a=await reindexMemory();_0x18818a[_0xd7282f(0x96)]>0x1362+-0x2d*-0x5d+-0x23bb&&console[_0xd7282f(0x6b)](_0xd7282f(0xfa)+_0x33664e(0xbd)+_0x18818a[_0xd7282f(0x96)]+(_0x33664e(0xe5)+'a\x20')+_0x5d3777[_0xd7282f(0xf4)]+'\x20('+_0x18818a[_0xd7282f(0x7f)]+_0x33664e(0xa5));}catch(_0x47f8d9){console['log'](_0x33664e(0xed)+_0xd7282f(0xdc)+_0xd7282f(0x113)+(_0x47f8d9 instanceof Error?_0x47f8d9[_0xd7282f(0x112)]:String(_0x47f8d9)));}}export function getIndexStats(){const _0x2fbb2d=_0x8c9a74,_0x4479f7=_0x240d32,_0x25e08b={'entries':0x0,'files':0x0,'lastReindex':0x0,'sizeBytes':0x0,'provider':_0x2fbb2d(0x89)+'e','tier':_0x2fbb2d(0x90),'dim':0x0};if(!loadSqlite())return _0x25e08b;const _0x174639=openDb();if(!_0x174639)return _0x25e08b;try{activeProvider?(_0x25e08b[_0x2fbb2d(0x97)]=activeProvider[_0x2fbb2d(0x81)+'es'](_0x174639),_0x25e08b['provider']=activeProvider['name'],_0x25e08b[_0x2fbb2d(0xff)]=activeProvider[_0x2fbb2d(0xff)],_0x25e08b['dim']=activeProvider[_0x4479f7(0xf9)]):(_0x25e08b['provider']=getMeta(_0x174639,_0x4479f7(0x72)+_0x2fbb2d(0xe3))??_0x2fbb2d(0xcf),_0x25e08b[_0x4479f7(0xff)]=getMeta(_0x174639,_0x2fbb2d(0x72)+_0x2fbb2d(0xff))??'unknown',_0x25e08b[_0x4479f7(0xf9)]=Number(getMeta(_0x174639,_0x2fbb2d(0x72)+_0x2fbb2d(0xf9))??0x1a81+0xe71*0x2+-0x3763));_0x25e08b[_0x4479f7(0x98)]=_0x174639[_0x4479f7(0x83)]('SELECT\x20COU'+_0x4479f7(0xa0)+_0x2fbb2d(0x74)+'_mtimes')[_0x2fbb2d(0xf5)]()['c'];const _0x1d234f=getMeta(_0x174639,_0x2fbb2d(0xd7)+'x');if(_0x1d234f)_0x25e08b[_0x2fbb2d(0xd7)+'x']=Number(_0x1d234f);if(_0x5947a6[_0x2fbb2d(0x78)](EMBEDDINGS_DB))_0x25e08b[_0x4479f7(0xee)]=_0x5947a6[_0x2fbb2d(0x9e)](EMBEDDINGS_DB)['size'];}catch{}return _0x25e08b;}function _0xf16a(_0x5947a6,_0xd8a7f3){_0x5947a6=_0x5947a6-(-0x20ab+-0x1f2f+0x4045);const _0x13ef4d=_0x2d1b();let _0x3bce4f=_0x13ef4d[_0x5947a6];if(_0xf16a['tZxpAK']===undefined){var _0x402309=function(_0x220f3e){const _0x3b18f0='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x52c717='',_0x57573c='',_0x331e4f=_0x52c717+_0x402309;for(let _0x4acfa9=-0x21e+-0x1ab6+0x1cd4,_0x51189c,_0x46f08e,_0x16cfeb=-0x3*0x493+0xa6*0x1+0xd13;_0x46f08e=_0x220f3e['charAt'](_0x16cfeb++);~_0x46f08e&&(_0x51189c=_0x4acfa9%(-0x42b+0x15bf+0x4*-0x464)?_0x51189c*(0x2*0x307+-0x126+0x95*-0x8)+_0x46f08e:_0x46f08e,_0x4acfa9++%(0x246a+0x50c+-0x2972))?_0x52c717+=_0x331e4f['charCodeAt'](_0x16cfeb+(-0x10da+0xe97+0x24d))-(0x2437+-0xc4a*-0x2+-0x3cc1)!==-0x2f*-0x6f+0x3*0xf4+-0x173d?String['fromCharCode'](0x6a8+-0x1c75+0x5b3*0x4&_0x51189c>>(-(0x12dc+0x34*0x23+-0x19f6)*_0x4acfa9&0x354+0x31*0x43+0x1021*-0x1)):_0x4acfa9:0x11*0x29+-0x269f+0xa*0x397){_0x46f08e=_0x3b18f0['indexOf'](_0x46f08e);}for(let _0x30e5d8=-0x1*0x4ff+-0x34b*0x9+0x22a2,_0x1e4d45=_0x52c717['length'];_0x30e5d8<_0x1e4d45;_0x30e5d8++){_0x57573c+='%'+('00'+_0x52c717['charCodeAt'](_0x30e5d8)['toString'](0xa6*-0x35+-0x1f10+0x417e))['slice'](-(-0x80*-0x42+0x3b5*-0x6+-0xac0));}return decodeURIComponent(_0x57573c);};_0xf16a['XYGzyL']=_0x402309,_0xf16a['iDLpAx']={},_0xf16a['tZxpAK']=!![];}const _0x3d93dc=_0x13ef4d[-0x263b+-0x1ab2+0x40ed*0x1],_0x33f47c=_0x5947a6+_0x3d93dc,_0x496304=_0xf16a['iDLpAx'][_0x33f47c];if(!_0x496304){const _0x1d5665=function(_0x1583a0){this['zAVnYp']=_0x1583a0,this['FmKQHl']=[0x1f*0x91+-0x1*0x11e7+0x59,-0x12b*0x1+-0xa7*-0x1f+0x1*-0x130e,-0xc6c+-0x3*0x1+0xc6f],this['XUjqFw']=function(){return'newState';},this['bULsTJ']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['uIbfKc']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x1d5665['prototype']['EbmDHO']=function(){const _0x3c520a=new RegExp(this['bULsTJ']+this['uIbfKc']),_0x29e1f3=_0x3c520a['test'](this['XUjqFw']['toString']())?--this['FmKQHl'][0x493+-0x4de+0x4c]:--this['FmKQHl'][0x1362+-0x2d*-0x5d+-0x23bb];return this['YaJCHm'](_0x29e1f3);},_0x1d5665['prototype']['YaJCHm']=function(_0x504a48){if(!Boolean(~_0x504a48))return _0x504a48;return this['PZXIGl'](this['zAVnYp']);},_0x1d5665['prototype']['PZXIGl']=function(_0x591548){for(let _0x4cc4a2=0x1a81+0xe71*0x2+-0x3763,_0x3032b2=this['FmKQHl']['length'];_0x4cc4a2<_0x3032b2;_0x4cc4a2++){this['FmKQHl']['push'](Math['round'](Math['random']())),_0x3032b2=this['FmKQHl']['length'];}return _0x591548(this['FmKQHl'][-0x20c0+0x11*-0x27+0x2357*0x1]);},new _0x1d5665(_0xf16a)['EbmDHO'](),_0x3bce4f=_0xf16a['XYGzyL'](_0x3bce4f),_0xf16a['iDLpAx'][_0x33f47c]=_0x3bce4f;}else _0x3bce4f=_0x496304;return _0x3bce4f;}export function getEmbeddingsBackendStatus(){const _0x1b861e=_0x8c9a74;return loadSqlite(),{'available':SqliteClass!==null,'error':sqliteLoadError?.[_0x1b861e(0x112)]??null};}export function isSqliteMemoryReady(){const _0x2354ee=_0x240d32,_0x43d802=_0x240d32;if(!loadSqlite())return![];const _0x1980b2=openDb();if(!_0x1980b2)return![];for(const _0xadd052 of[_0x2354ee(0x97),'entries_ft'+'s']){try{const _0x51765e=_0x1980b2['prepare']('SELECT\x20COU'+_0x43d802(0xa0)+_0x2354ee(0x93)+_0xadd052)[_0x43d802(0xf5)]();if(_0x51765e&&_0x51765e['c']>-0x20c0+0x11*-0x27+0x2357*0x1)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 _0x5802f2=_0x1374,_0x2bf8ab=_0x1374;(function(_0x41e38f,_0x58016d){const _0x4e1f03=_0x1374,_0x40620b=_0x1374,_0xef90cf=_0x41e38f();while(!![]){try{const _0x47143c=-parseInt(_0x4e1f03(0x126))/(0x16*-0xbe+-0x1736+-0xbf*-0x35)+parseInt(_0x40620b(0x136))/(0x6*0xc5+0x1aec+-0x1f88)+parseInt(_0x4e1f03(0x134))/(0x2430+-0x1ba8+-0x885)+-parseInt(_0x40620b(0x127))/(0x228e+-0x101d+-0x126d)+parseInt(_0x4e1f03(0x140))/(0x13bd+0xe51*0x1+0x1*-0x2209)*(-parseInt(_0x4e1f03(0x133))/(-0xdb0+-0x210c+0x2ec2))+parseInt(_0x4e1f03(0x125))/(0x14ea+0x1a8+-0x168b)+parseInt(_0x40620b(0x120))/(-0x2*-0x25c+0x1d*0x5b+0xb*-0x15d);if(_0x47143c===_0x58016d)break;else _0xef90cf['push'](_0xef90cf['shift']());}catch(_0x1593d6){_0xef90cf['push'](_0xef90cf['shift']());}}}(_0x521b,-0x2*-0x3079d+-0xb4c1*-0xd+-0x3c32d));const _0x321346=(function(){let _0x2a8999=!![];return function(_0x8071d9,_0x5a8973){const _0x3846ea=_0x2a8999?function(){if(_0x5a8973){const _0x2d89bf=_0x5a8973['apply'](_0x8071d9,arguments);return _0x5a8973=null,_0x2d89bf;}}:function(){};return _0x2a8999=![],_0x3846ea;};}()),_0x488d16=_0x321346(this,function(){const _0x3af25a=_0x1374,_0x38c46a=_0x1374;return _0x488d16[_0x3af25a(0x130)]()[_0x3af25a(0x11c)](_0x38c46a(0x11b)+'+$')[_0x38c46a(0x130)]()[_0x38c46a(0x128)+'r'](_0x488d16)[_0x3af25a(0x11c)](_0x38c46a(0x11b)+'+$');});_0x488d16();import{VectorProviderBase}from'./vector-base.js';function _0x521b(){const _0x42c937=['DgLTzw91Da','kcGOlISPkYKRkq','C2vHCMnO','BgvUz3rO','C3bSAxq','ue9tva','mtu5mJKXmZzOrNLTCwW','Ahr0CdOVl2XVyW','t2XSyw1HigvTyG','zxHWzwn0zwqG','B2XSyw1HoG','nZaYmZiZm1HjqvL1uW','nZe5ntaYDvb5C21Q','ntu5nJKWmgX1uwLztq','y29UC3rYDwn0BW','DMvJDg9YlwXVyW','yxbWBgLJyxrPBW','ywXOB3n0oJeXna','rv9vuKW','Dgv4Da','zc10zxH0','ANnVBG','Dg9tDhjPBMC','t0Xmqu1bx0jbuW','C29Tzq','otyYnfDgDNDIqq','mtyYnJCYmgXoCerVyW','Bw9KzwXZ','mtyWmZu1mNPIywHSEa','C3rYAw5NAwz5','zgLT','zw52','C3rHDhvZ','C3rHCNrZv2L0Aa','zw1Izwq','BMfTzq','zw1IzwrKAw5NCW','zwqGCMv0DxjUzq','ndu3nvjwyLDgtG','BI9QC29U','iokaLca','l2fWAs90ywDZ'];_0x521b=function(){return _0x42c937;};return _0x521b();}function _0x1374(_0x459755,_0x30b235){_0x459755=_0x459755-(0x7eb*-0x3+0x10e*0x15+0x2b3);const _0x1efc06=_0x521b();let _0x75ab75=_0x1efc06[_0x459755];if(_0x1374['jmafLU']===undefined){var _0x7dd48b=function(_0x31b5d1){const _0x21376b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2f9cf7='',_0x1d3c7e='',_0x357257=_0x2f9cf7+_0x7dd48b;for(let _0x3c4562=0x227f*-0x1+-0x11e4+0x1*0x3463,_0x5192a4,_0x28532f,_0x5bdfa2=0x107*0x1e+-0x1b7a*0x1+0xd6*-0x4;_0x28532f=_0x31b5d1['charAt'](_0x5bdfa2++);~_0x28532f&&(_0x5192a4=_0x3c4562%(0x2012+0xa6*-0x31+0x1*-0x48)?_0x5192a4*(-0x1*0x16dd+0x1e8c+-0x76f)+_0x28532f:_0x28532f,_0x3c4562++%(0x15af+-0x99*0x15+-0x91e))?_0x2f9cf7+=_0x357257['charCodeAt'](_0x5bdfa2+(0x21e5+-0x3*-0x381+-0x2c5e))-(0x6*-0xb4+-0x207f+0x24c1)!==-0x14*0x1c6+-0x26a7+0x4a1f?String['fromCharCode'](-0x3d*-0x13+0x2*-0x593+0x79e&_0x5192a4>>(-(0x14d3+0xe15+-0x3*0xba2)*_0x3c4562&-0x1354+0x1*-0x247d+0x37d7)):_0x3c4562:-0x2*0x380+-0x7be+0xebe){_0x28532f=_0x21376b['indexOf'](_0x28532f);}for(let _0x42ab39=-0x1946+-0x15+0x195b,_0x513be0=_0x2f9cf7['length'];_0x42ab39<_0x513be0;_0x42ab39++){_0x1d3c7e+='%'+('00'+_0x2f9cf7['charCodeAt'](_0x42ab39)['toString'](-0x15ae+-0x1*0x371+-0x15*-0x133))['slice'](-(-0x2300+-0x57a*0x4+0x5e*0x9b));}return decodeURIComponent(_0x1d3c7e);};_0x1374['kRRHPz']=_0x7dd48b,_0x1374['MvvKbL']={},_0x1374['jmafLU']=!![];}const _0x191d92=_0x1efc06[0x1995+0x1*0x20e7+0x1d3e*-0x2],_0x1d79ef=_0x459755+_0x191d92,_0x4936a9=_0x1374['MvvKbL'][_0x1d79ef];if(!_0x4936a9){const _0x4540f1=function(_0x3c46aa){this['EbGDpm']=_0x3c46aa,this['YyGkbI']=[0x81e+-0x734+0xe9*-0x1,-0x1*-0xd55+-0x61*-0x2+-0x1*0xe17,-0x140b+-0xe11+0x221c],this['KcvlXH']=function(){return'newState';},this['JjoTrW']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['uTLStj']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x4540f1['prototype']['EMDQcX']=function(){const _0x42c194=new RegExp(this['JjoTrW']+this['uTLStj']),_0x539b61=_0x42c194['test'](this['KcvlXH']['toString']())?--this['YyGkbI'][0x4c7+-0x56*-0x27+0xd0*-0x16]:--this['YyGkbI'][0xabc+0x1166+-0x22a*0xd];return this['HTkVbZ'](_0x539b61);},_0x4540f1['prototype']['HTkVbZ']=function(_0x292a39){if(!Boolean(~_0x292a39))return _0x292a39;return this['eOKodr'](this['EbGDpm']);},_0x4540f1['prototype']['eOKodr']=function(_0x558e95){for(let _0x1132ce=-0xe71+-0x20*0x52+0x18b1,_0x22ef7c=this['YyGkbI']['length'];_0x1132ce<_0x22ef7c;_0x1132ce++){this['YyGkbI']['push'](Math['round'](Math['random']())),_0x22ef7c=this['YyGkbI']['length'];}return _0x558e95(this['YyGkbI'][0xd*-0x2e3+-0x1601+0xbe8*0x5]);},new _0x4540f1(_0x1374)['EMDQcX'](),_0x75ab75=_0x1374['kRRHPz'](_0x75ab75),_0x1374['MvvKbL'][_0x1d79ef]=_0x75ab75;}else _0x75ab75=_0x4936a9;return _0x75ab75;}const DEFAULT_MODEL='nomic-embe'+_0x5802f2(0x12e),DEFAULT_HOST=_0x2bf8ab(0x121)+_0x2bf8ab(0x12b)+'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 _0x56f439=_0x2bf8ab,_0x4b61c5=_0x2bf8ab;return process[_0x56f439(0x139)]['OLLAMA_HOS'+'T']||process[_0x4b61c5(0x139)][_0x4b61c5(0x131)+_0x56f439(0x12c)]||DEFAULT_HOST;}function ollamaModel(){const _0x34d7d9=_0x2bf8ab;return process[_0x34d7d9(0x139)]['OLLAMA_EMB'+'EDDING_MOD'+'EL']||DEFAULT_MODEL;}export class OllamaProvider extends VectorProviderBase{['name'];['dim'];['tier']=_0x2bf8ab(0x129)+'al';constructor(){const _0x474ae3=_0x2bf8ab,_0x443da2=_0x5802f2;super();const _0x2f39a8=ollamaModel(),_0x465ea9=_0x2f39a8[_0x474ae3(0x11e)](':')[0x1345+0x107*0x1e+-0x3217*0x1];this['name']=_0x443da2(0x124)+_0x2f39a8,this[_0x443da2(0x138)]=KNOWN_DIMS[_0x465ea9]??-0xe1*-0x8+0x1c48+0x1c4*-0x14;}async['isAvailabl'+'e'](){const _0x51ebcb=_0x5802f2,_0x211033=_0x2bf8ab;try{const _0x83b15=await fetch(ollamaHost()+_0x51ebcb(0x119),{'signal':AbortSignal[_0x51ebcb(0x11a)](0x194c+0xf8*0x3+-0x1464)});if(!_0x83b15['ok'])return![];const _0x55ff93=await _0x83b15[_0x51ebcb(0x12f)](),_0x1c0c1b=ollamaModel(),_0xb339b4=_0x1c0c1b[_0x51ebcb(0x11e)](':')[-0x8*0x2a+-0x219+-0x61*-0x9];return Boolean(_0x55ff93[_0x51ebcb(0x135)]?.[_0x211033(0x132)](_0x3a650f=>_0x3a650f['name']===_0x1c0c1b||_0x3a650f[_0x51ebcb(0x13d)][_0x211033(0x13b)](_0xb339b4+':')));}catch{return![];}}async[_0x2bf8ab(0x13c)](_0x3536a7){const _0x15c338=_0x5802f2,_0x775912=_0x2bf8ab,_0x221510=await fetch(ollamaHost()+'/api/embed',{'method':_0x15c338(0x11f),'headers':{'Content-Type':_0x15c338(0x12a)+_0x775912(0x141)},'body':JSON[_0x15c338(0x137)]({'model':ollamaModel(),'input':_0x3536a7})});if(!_0x221510['ok'])throw new Error(_0x775912(0x122)+'ed\x20error:\x20'+_0x221510[_0x15c338(0x13a)]+_0x15c338(0x118)+await _0x221510[_0x15c338(0x12d)]());const _0x5a0939=await _0x221510[_0x775912(0x12f)]();if(!Array['isArray'](_0x5a0939[_0x15c338(0x13e)])||_0x5a0939['embeddings'][_0x15c338(0x11d)]!==_0x3536a7['length'])throw new Error('Ollama\x20emb'+_0x775912(0x13f)+'d\x20'+(_0x5a0939[_0x15c338(0x13e)]?.[_0x775912(0x11d)]??-0x1c*0x125+-0x1*-0x21e5+-0x1d9)+('\x20vectors,\x20'+_0x775912(0x123))+_0x3536a7['length']);return _0x5a0939['embeddings'];}async['embedQuery'](_0xeaa9e4){const [_0x358a69]=await this['embed']([_0xeaa9e4]);return _0x358a69;}}
|