@vpxa/aikit 0.1.289 → 0.1.291
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/cli/dist/index.js +1 -1
- package/packages/server/dist/bin.js +1 -1
- package/packages/server/dist/config-BkWFC9ah.js +1 -0
- package/packages/server/dist/config-DK_lqZRv.js +2 -0
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/proxy.js +10 -6
- package/packages/server/dist/{server-b09Z9fpn.js → server-BRinO5Fx.js} +146 -145
- package/packages/server/dist/{server-VemkXO_E.js → server-CyERdqK0.js} +145 -146
- package/packages/store/dist/index.d.ts +27 -1
- package/packages/store/dist/index.js +75 -32
- package/packages/store/package.json +5 -2
- package/scaffold/dist/definitions/flows.mjs +2 -2
- package/scaffold/dist/definitions/skills/present.mjs +1 -1
- package/packages/server/dist/config--q4iaq8F.js +0 -1
- package/packages/server/dist/config-BJuTGi8e.js +0 -2
- package/packages/server/dist/retention-B4ITAs7F.js +0 -1
- package/packages/server/dist/retention-C3tsarCT.js +0 -2
|
@@ -161,8 +161,15 @@ interface IGraphStore {
|
|
|
161
161
|
close(): Promise<void>;
|
|
162
162
|
}
|
|
163
163
|
//#endregion
|
|
164
|
-
//#region packages/store/src/sqlite-adapter.d.ts
|
|
164
|
+
//#region packages/store/src/sqlite-adapter.types.d.ts
|
|
165
|
+
/** Which legacy adapter implementation is active */
|
|
165
166
|
type SqliteAdapterType = 'better-sqlite3' | 'sql.js';
|
|
167
|
+
/**
|
|
168
|
+
* Legacy SQLite adapter interface.
|
|
169
|
+
*
|
|
170
|
+
* Prefer SqlDatabase for new code. ISqliteAdapter exists for backward
|
|
171
|
+
* compatibility with consumers that were written before SqlDatabase.
|
|
172
|
+
*/
|
|
166
173
|
interface ISqliteAdapter {
|
|
167
174
|
/** Which adapter implementation is active */
|
|
168
175
|
readonly type: SqliteAdapterType;
|
|
@@ -187,6 +194,8 @@ interface ISqliteAdapter {
|
|
|
187
194
|
/** Close the database connection */
|
|
188
195
|
close(): void;
|
|
189
196
|
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region packages/store/src/sqlite-adapter.d.ts
|
|
190
199
|
/**
|
|
191
200
|
* Create the project's SQLite adapter.
|
|
192
201
|
*
|
|
@@ -389,6 +398,7 @@ interface IKnowledgeStore {
|
|
|
389
398
|
//#region packages/store/src/sqlite-vec-store.d.ts
|
|
390
399
|
interface EmbeddingProfile$1 {
|
|
391
400
|
model: string;
|
|
401
|
+
version?: string;
|
|
392
402
|
nativeDim: number;
|
|
393
403
|
dimensions: number;
|
|
394
404
|
queryPrefix: string;
|
|
@@ -448,6 +458,12 @@ declare class SqliteVecStore implements IKnowledgeStore {
|
|
|
448
458
|
private saveEmbeddingProfile;
|
|
449
459
|
private dropVectorTables;
|
|
450
460
|
private ensureVecTable;
|
|
461
|
+
/**
|
|
462
|
+
* Backfill canonical memory_embeddings from existing vec0 tables.
|
|
463
|
+
* Runs only when memory_embeddings is empty and vec0 tables exist.
|
|
464
|
+
* Updates vector_index_metadata after successful backfill.
|
|
465
|
+
*/
|
|
466
|
+
private backfillCanonicalEmbeddingsIfNeeded;
|
|
451
467
|
private enqueueWrite;
|
|
452
468
|
private _drain;
|
|
453
469
|
upsert(records: KnowledgeRecord[], vectors: Float32Array[]): Promise<void>;
|
|
@@ -639,6 +655,16 @@ interface StoreConfig {
|
|
|
639
655
|
embeddingProfile?: EmbeddingProfile;
|
|
640
656
|
/** Optional control/content partition config for sqlite-backed stores. */
|
|
641
657
|
partition?: StatePartitionConfig;
|
|
658
|
+
/**
|
|
659
|
+
* SQLite driver mode: auto (default) or forced.
|
|
660
|
+
* When unset, reads AI_KIT_SQLITE_DRIVER env var.
|
|
661
|
+
*/
|
|
662
|
+
sqliteDriver?: 'auto' | 'node-sqlite' | 'better-sqlite3' | 'sqljs';
|
|
663
|
+
/**
|
|
664
|
+
* Allow fallback chain when a forced mode fails (default: true).
|
|
665
|
+
* When unset, reads AI_KIT_SQLITE_ALLOW_FALLBACK env var.
|
|
666
|
+
*/
|
|
667
|
+
allowFallback?: boolean;
|
|
642
668
|
}
|
|
643
669
|
declare function createStore(config: StoreConfig): Promise<IKnowledgeStore>;
|
|
644
670
|
//#endregion
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as n,readFileSync as r,renameSync as i,unlinkSync as a,writeFileSync as o}from"node:fs";import{basename as s,dirname as c,extname as l,join as u}from"node:path";import{
|
|
1
|
+
import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as n,readFileSync as r,renameSync as i,unlinkSync as a,writeFileSync as o}from"node:fs";import{basename as s,dirname as c,extname as l,join as u}from"node:path";import{AIKIT_PATHS as d,EMBEDDING_DEFAULTS as f,SEARCH_DEFAULTS as p,STORE_DEFAULTS as m,createLogger as h,serializeError as g,sourceTypeContentTypes as ee}from"../../core/dist/index.js";import{homedir as te}from"node:os";var ne=e(import.meta.url);function re(e){e.exec(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS _migrations (
|
|
3
3
|
version INTEGER PRIMARY KEY,
|
|
4
4
|
name TEXT NOT NULL,
|
|
5
5
|
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
6
6
|
)
|
|
7
|
-
`)}function
|
|
7
|
+
`)}function _(e,t){re(e);let n=new Set(e.queryAll(`SELECT version FROM _migrations`).map(e=>e.version)),r=[...t].sort((e,t)=>e.version-t.version).filter(e=>!n.has(e.version));for(let t of r){e.exec(`BEGIN`);try{t.up(e),e.run(`INSERT INTO _migrations (version, name) VALUES (?, ?)`,[t.version,t.name]),e.exec(`COMMIT`)}catch(t){try{e.exec(`ROLLBACK`)}catch{}throw t}}}const v=[{version:1,name:`create state store tables`,up(e){e.exec(`
|
|
8
8
|
CREATE TABLE IF NOT EXISTS stash (
|
|
9
9
|
key TEXT PRIMARY KEY,
|
|
10
10
|
value TEXT NOT NULL,
|
|
@@ -79,17 +79,49 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
79
79
|
FROM leases_legacy;
|
|
80
80
|
|
|
81
81
|
DROP TABLE leases_legacy;
|
|
82
|
-
`)}}],v=te(`sqlite-adapter`),y=e(import.meta.url),b=`better-sqlite3`;function ae(e){return e.replace(/\\/g,`/`)}function x(){return y.resolve(`@vpxa/aikit/package.json`).replace(/[\\/]package\.json$/,``)}function S(){return x().replace(/[\\/]node_modules[\\/]@vpxa[\\/]aikit$/,``)}function oe(e){return ae(e).includes(`/_npx/`)}function C(){try{return JSON.parse(r(u(x(),`package.json`),`utf8`)).optionalDependencies?.[b]??`latest`}catch{return`latest`}}function se(e){return e.replace(/[^a-zA-Z0-9._-]+/g,`_`)}function ce(){let e=`${se(C())}-${process.platform}-${process.arch}-abi${process.versions.modules}`;return u(d(),`.aikit`,`cache`,`native-modules`,b,e)}function w(e){n(e,{recursive:!0});let r=u(e,`package.json`);t(r)||o(r,`${JSON.stringify({name:`aikit-native-runtime-cache`,private:!0},null,2)}\n`,`utf8`)}function T(e){let t=k(e);if(!t)return null;try{return JSON.parse(r(u(t,`package.json`),`utf8`)).version??null}catch{return null}}function E(e,t){try{let n={packageName:b,packageSpec:C(),packageVersion:T(e),platform:process.platform,arch:process.arch,nodeAbi:process.versions.modules,installedAt:new Date().toISOString(),source:t};o(u(e,`.aikit-native-module.json`),`${JSON.stringify(n,null,2)}\n`,`utf8`)}catch(e){v.debug(`Failed to write better-sqlite3 runtime marker`,h(e))}}var D=class{runtimeRoot;type=`better-sqlite3`;vectorCapable=!1;db=null;stmtCache=new Map;dbPath=``;DatabaseCtor=null;recovering=!1;constructor(e){this.runtimeRoot=e}async open(t){let n;try{let t=y;this.runtimeRoot!=null&&(w(this.runtimeRoot),t=e(u(this.runtimeRoot,`package.json`))),n=t(b)}catch(e){throw Error(`better-sqlite3 native binding unavailable: ${e instanceof Error?e.message:String(e)}`)}this.db=new n(t),this.dbPath=t,this.DatabaseCtor=n,this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`),this.runIntegrityCheck(t,n)||(this.db?.pragma(`journal_mode = WAL`),this.db?.pragma(`foreign_keys = ON`),this.db?.pragma(`synchronous = NORMAL`));try{y(`sqlite-vec`).load(this.db),this.vectorCapable=!0,v.debug(`sqlite-vec extension loaded`)}catch(e){this.vectorCapable=!1,v.warn(`sqlite-vec extension failed to load; vector search disabled`,h(e))}}exec(e){try{this.getDb().exec(e)}catch(t){if(this.isCorruptionError(t)){this.recover(),this.getDb().exec(e);return}throw t}}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){try{let n=this.prepareCached(e);return t.length>0?n.all(...t):n.all()}catch(n){if(this.isCorruptionError(n))return this.recover(),this.queryAll(e,t);throw n}}run(e,t=[]){try{let n=this.prepareCached(e);t.length>0?n.run(...t):n.run()}catch(n){if(this.isCorruptionError(n)){this.recover(),this.run(e,t);return}throw n}}flush(){}close(){this.db&&=(this.stmtCache.clear(),this.db.close(),null)}runIntegrityCheck(e,t){try{let t=this.db?.pragma(`integrity_check`);if(t.length===1&&t[0]?.integrity_check===`ok`)return!0;let n=t.map(e=>e.integrity_check).slice(0,5).join(`; `);v.warn(`Database integrity check failed — recreating`,{dbPath:e,issues:n})}catch(t){v.warn(`Integrity check query failed — recreating database`,{dbPath:e,error:h(t)})}try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(e)}catch{}try{a(`${e}-wal`)}catch{}try{a(`${e}-shm`)}catch{}return this.db=new t(e),v.info(`Database recreated successfully — full reindex required`,{dbPath:e}),!1}isCorruptionError(e){if(this.recovering)return!1;let t=e instanceof Error?e.message:String(e);return/database disk image is malformed|file is not a database|database or disk is full/.test(t)}recover(){if(this.recovering)throw Error(`BetterSqlite3Adapter: recovery already in progress`);this.recovering=!0;try{v.warn(`Runtime corruption detected — recovering database`,{dbPath:this.dbPath});try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(this.dbPath)}catch{}try{a(`${this.dbPath}-wal`)}catch{}try{a(`${this.dbPath}-shm`)}catch{}if(!this.DatabaseCtor)throw Error(`DatabaseCtor is not initialized`);this.db=this.DatabaseCtor(this.dbPath),this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`);try{y(`sqlite-vec`).load(this.db),this.vectorCapable=!0}catch{this.vectorCapable=!1}v.info(`Database recovered — full reindex required`,{dbPath:this.dbPath})}finally{this.recovering=!1}}getDb(){if(!this.db)throw Error(`BetterSqlite3Adapter: database not opened`);return this.db}prepareCached(e){let t=this.stmtCache.get(e);if(t)return t;let n=this.getDb().prepare(e);return this.stmtCache.set(e,n),n}};function le(e){return y.resolve(`sql.js/dist/${e}`)}function ue(e){return e.match(/^\s*(?:INSERT(?:\s+OR\s+\w+)?\s+INTO|UPDATE)\s+([A-Za-z_][A-Za-z0-9_]*)/i)?.[1]??null}var O=class{type=`sql.js`;vectorCapable=!1;db=null;dbPath=``;dirty=!1;inTransaction=!1;foreignKeysEnabled=!1;async open(e){this.dbPath=e;let n=(await import(`sql.js`)).default,i=await n({locateFile:e=>le(e)});if(t(e)){let t=r(e);this.db=new i.Database(t)}else this.db=new i.Database}exec(e){let t=e.trimStart().toUpperCase();this.getDb().run(e),t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.dirty=!0}pragma(e){let t=e.trim().toLowerCase();t===`foreign_keys = on`||t===`foreign_keys=on`?this.foreignKeysEnabled=!0:(t===`foreign_keys = off`||t===`foreign_keys=off`)&&(this.foreignKeysEnabled=!1),this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);try{t.length>0&&n.bind(t);let e=[];for(;n.step();)e.push(n.getAsObject());return e}finally{n.free()}}run(e,t=[]){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=ue(e),a=this.foreignKeysEnabled&&!this.inTransaction&&i!==null&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));a&&n.run(`SAVEPOINT fk_check`);try{if(t.length>0){let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}else n.run(e);if(a){if(n.exec(`PRAGMA foreign_key_check(${i})`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}}catch(e){if(a)try{n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`)}catch{}throw e}this.dirty=!0}flush(){if(!this.dirty||!this.db)return;let e=this.db.export(),r=`${this.dbPath}.tmp`,a=c(this.dbPath);a&&!t(a)&&n(a,{recursive:!0}),o(r,Buffer.from(e)),i(r,this.dbPath),this.dirty=!1}close(){if(this.db){let e=this.db,t;try{this.flush()}catch(e){t=e;try{a(`${this.dbPath}.tmp`)}catch{}}try{e.close()}finally{this.db=null}if(t)throw t}}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};function k(e){if(e){let n=u(e,`node_modules`,b);return t(u(n,`package.json`))?n:null}try{return y.resolve(`${b}/package.json`).replace(/[\\/]package\.json$/,``)}catch{return null}}function de(e){let n=k(e);if(!n)return null;let r=u(n,`build`,`Release`,`better_sqlite3.node`);return t(r)?r:null}async function fe(e){let n=k(e);if(!n)return`package-missing`;if(!t(u(n,`build`,`Release`,`better_sqlite3.node`)))return`binding-missing`;try{let{execFileSync:t}=await import(`node:child_process`),n=e??S();return e&&w(e),t(process.execPath,[`-e`,`require('${b}')`],{cwd:n,stdio:`pipe`,timeout:15e3,windowsHide:!0}),`ok`}catch(e){let t=e instanceof Error&&`stderr`in e?String(e.stderr):``;return/NODE_MODULE_VERSION/.test(t)?`abi-mismatch`:/Could not locate the bindings file|no native build was found/.test(t)?`binding-missing`:`error`}}async function pe(e,n=!1){let r=k(e);if(!r)return v.info(`better-sqlite3 package is not installed — skipping native rebuild`),!1;try{let{execFileSync:i}=await import(`node:child_process`),o=e??r.replace(/[\\/]node_modules[\\/]better-sqlite3$/,``),s=process.platform===`win32`?`npm.cmd`:`npm`;if(e&&w(e),n){let e=u(r,`build`,`Release`,`better_sqlite3.node`);if(t(e))try{a(e),v.info(`Deleted stale native binding before rebuild`,{path:e})}catch(t){v.warn(`Cannot delete stale native binding — file may be locked by another process`,{path:e,error:t instanceof Error?t.message:String(t)})}}return v.info(`Attempting native module rebuild for better-sqlite3`,{cwd:o}),i(s,[`rebuild`,b],{cwd:o,stdio:`pipe`,timeout:6e4,windowsHide:!0}),v.info(`Native module rebuild completed successfully`),E(o,`rebuild`),!0}catch(e){return v.warn(`Native module rebuild failed — continuing with sql.js fallback`,h(e)),!1}}async function me(e){try{let{execFileSync:t}=await import(`node:child_process`),n=e??S(),r=process.platform===`win32`?`npm.cmd`:`npm`,i=C();return w(n),v.info(`Attempting to install better-sqlite3 for native adapter recovery`,{cwd:n,packageSpec:i}),t(r,[`install`,`--no-save`,`--package-lock=false`,`--no-audit`,`--no-fund`,`--omit=dev`,`${b}@${i}`],{cwd:n,stdio:`pipe`,timeout:12e4,windowsHide:!0}),v.info(`better-sqlite3 install completed successfully`),E(n,`install`),!0}catch(e){return v.warn(`better-sqlite3 install failed — continuing with sql.js fallback`,h(e)),!1}}let A=!1;function he(){return!!process.env.VITEST||process.argv.some(e=>e.includes(`vitest`))}async function ge(){let e=M.resolveAikitRuntimeRoot(),t=await M.probeNativeModuleAbi(e);if(t===`ok`)return e;if(M.isNpxRuntimeRoot(e)){let e=M.resolvePersistentNativeRuntimeRoot(),t=await M.probeNativeModuleAbi(e);if(t===`ok`)return v.info(`Using cached better-sqlite3 native runtime`,{runtimeRoot:e,version:M.resolveNativeModuleVersion(e)}),e;let n=!1;if(t===`abi-mismatch`?(v.info(`Persistent better-sqlite3 cache ABI mismatch — rebuilding cached binding`),n=await M.tryRebuildNativeModule(e,!0)):t===`binding-missing`?(v.info(`Persistent better-sqlite3 cache missing binding — rebuilding cache`),n=await M.tryRebuildNativeModule(e,!1)):(v.info(`Persistent better-sqlite3 cache missing — installing cached runtime`,{runtimeRoot:e,packageSpec:M.readAikitPackageSpec()}),n=await M.tryInstallNativeModule(e)),n&&await M.probeNativeModuleAbi(e)===`ok`)return v.info(`Persistent better-sqlite3 cache ready`,{runtimeRoot:e,version:M.resolveNativeModuleVersion(e)}),e}if(t===`abi-mismatch`){if(v.info(`Detected NODE_MODULE_VERSION mismatch via pre-flight probe — rebuilding before load`),await M.tryRebuildNativeModule(e,!0)&&await M.probeNativeModuleAbi(e)===`ok`)return v.info(`Pre-flight rebuild succeeded — proceeding with native adapter`),e}else if(t===`binding-missing`){if(v.info(`No native binding found — attempting rebuild before load`),await M.tryRebuildNativeModule(e,!1)&&await M.probeNativeModuleAbi(e)===`ok`)return e}else if(t===`package-missing`&&(v.info(`better-sqlite3 package is not installed — attempting install before load`),await M.tryInstallNativeModule(e)&&await M.probeNativeModuleAbi(e)===`ok`))return e;return null}async function j(e){let t=null;M.isVitestRuntime()||(t=await M.preparePreferredNativeRuntime());{let n=M.createNativeAdapter(t??void 0);try{return await n.open(e),n}catch(n){let r=n instanceof Error?n.message:String(n);if(!M.isVitestRuntime()&&/NODE_MODULE_VERSION|Could not locate the bindings file|no native build was found/.test(r)){let n=t??M.resolveAikitRuntimeRoot();if(await M.tryRebuildNativeModule(n,!1)){let t=M.createNativeAdapter(n);try{return await t.open(e),v.info(`better-sqlite3 recovered after native module rebuild`),t}catch{}}}A||(A=!0,v.warn(`[aikit] better-sqlite3 unavailable — falling back to sql.js (vector search disabled). Reinstall with prebuild support or rebuild from source to enable vector search.`,h(n)))}}let n=M.createFallbackAdapter();try{return await n.open(e),n}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[aikit] SQLite adapter "sql.js" failed to load: ${t}`)}}async function _e(e){let t=new O;return await t.open(e),t}const M={BetterSqlite3Adapter:D,SqlJsAdapter:O,isVitestRuntime:he,resolveAikitPackageRoot:x,resolveAikitRuntimeRoot:S,isNpxRuntimeRoot:oe,readAikitPackageSpec:C,resolvePersistentNativeRuntimeRoot:ce,ensureRuntimeRootPackageJson:w,resolveNativeModulePackageDir:k,resolveNativeBindingPath:de,resolveNativeModuleVersion:T,probeNativeModuleAbi:fe,tryRebuildNativeModule:pe,tryInstallNativeModule:me,preparePreferredNativeRuntime:ge,createNativeAdapter:e=>new D(e),createFallbackAdapter:()=>new O},N=new Set([`sessions`,`stash`,`checkpoints`,`leases`,`signals`,`audit_log`,`replay_entries`,`session_metadata`]);function ve(e){let t=l(e)||`.db`,n=s(e,t);return u(c(e),`${n}-control${t}`)}function ye(e){return N.has(e)?`control`:`content`}function P(e,t={}){let n=t.splitEnabled??!1;return{splitEnabled:n,contentDbPath:t.contentDbPath??e,controlDbPath:t.controlDbPath??(n?ve(e):e)}}function be(e,t=process.env){let n=t.AIKIT_SPLIT_STATE?.trim().toLowerCase();return P(e,{splitEnabled:n===`1`||n===`true`||n===`yes`||n===`on`})}const F=`_state_partition_meta`;function I(e){return`"${e.replaceAll(`"`,`""`)}"`}function xe(e){let r=c(e);t(r)||n(r,{recursive:!0})}async function Se(e){return xe(e),j(e)}function L(e,t){return e.queryAll(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`,[t]).length>0}function Ce(e,t){return e.queryAll(`SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`,[t])[0]?.sql??void 0}function we(e,t){return e.queryAll(`PRAGMA table_info(${I(t)})`).map(e=>e.name)}function R(e,t){return e.queryAll(`SELECT COUNT(*) AS count FROM ${I(t)}`)[0]?.count??0}function Te(e,t,n){if(!L(e,n))return;if(!L(t,n)){let r=Ce(e,n);if(!r)return;t.exec(r)}let r=we(t,n);if(r.length===0)return;let i=r.map(I).join(`, `),a=r.map(()=>`?`).join(`, `),o=e.queryAll(`SELECT ${i} FROM ${I(n)}`);if(o.length===0)return;let s=`INSERT OR REPLACE INTO ${I(n)} (${i}) VALUES (${a})`;for(let e of o)t.run(s,r.map(t=>e[t]??null))}function Ee(e){e.exec(`
|
|
83
|
-
|
|
82
|
+
`)}},{version:3,name:`canonical embedding and vector index metadata`,up(e){e.exec(`
|
|
83
|
+
CREATE TABLE IF NOT EXISTS storage_metadata (
|
|
84
|
+
key TEXT PRIMARY KEY,
|
|
85
|
+
value TEXT NOT NULL,
|
|
86
|
+
updated_at INTEGER NOT NULL
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
90
|
+
memory_id TEXT NOT NULL,
|
|
91
|
+
embedding_model TEXT NOT NULL,
|
|
92
|
+
embedding_version TEXT NOT NULL,
|
|
93
|
+
dimensions INTEGER NOT NULL,
|
|
94
|
+
element_type TEXT NOT NULL,
|
|
95
|
+
embedding BLOB NOT NULL,
|
|
96
|
+
created_at INTEGER NOT NULL,
|
|
97
|
+
PRIMARY KEY (memory_id, embedding_model, embedding_version),
|
|
98
|
+
FOREIGN KEY (memory_id) REFERENCES knowledge(id) ON DELETE CASCADE
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
CREATE TABLE IF NOT EXISTS vector_index_metadata (
|
|
102
|
+
index_name TEXT PRIMARY KEY,
|
|
103
|
+
generation INTEGER NOT NULL,
|
|
104
|
+
embedding_model TEXT NOT NULL,
|
|
105
|
+
embedding_version TEXT NOT NULL,
|
|
106
|
+
dimensions INTEGER NOT NULL,
|
|
107
|
+
canonical_count INTEGER NOT NULL,
|
|
108
|
+
indexed_count INTEGER NOT NULL,
|
|
109
|
+
built_at INTEGER NOT NULL
|
|
110
|
+
);
|
|
111
|
+
`)}},{version:4,name:`backfill vec0 embeddings into memory_embeddings`,up(e){let t=e.queryAll(`SELECT COUNT(*) AS cnt FROM memory_embeddings`);if(t[0]?.cnt&&t[0].cnt>0)return;let n=e.queryAll(`SELECT name, sql FROM sqlite_master WHERE type = 'table' AND sql LIKE '%vec0%'`);if(n.length===0)return;let r=Date.now(),i=0;for(let t of n){let n=t.sql.match(/(?:int8|float)\[(\d+)\]/i);if(!n)continue;let a=Number(n[1]),o=e.queryAll(`SELECT COUNT(*) AS cnt FROM memory_embeddings`)[0]?.cnt??0;e.run(`INSERT OR IGNORE INTO memory_embeddings
|
|
112
|
+
(memory_id, embedding_model, embedding_version, dimensions, element_type, embedding, created_at)
|
|
113
|
+
SELECT knowledge_id, 'default', '1', ?, 'float32', embedding, ?
|
|
114
|
+
FROM ${t.name}`,[a,r]);let s=e.queryAll(`SELECT COUNT(*) AS cnt FROM memory_embeddings`)[0]?.cnt??0;i+=s-o}i>0&&console.log(`[migration v4] backfilled ${i} embeddings into memory_embeddings`)}}],y=h(`sqlite-adapter`),b=e(import.meta.url),x=`better-sqlite3`;function ie(e){return e.replace(/\\/g,`/`)}function S(){return b.resolve(`@vpxa/aikit/package.json`).replace(/[\\/]package\.json$/,``)}function C(){return S().replace(/[\\/]node_modules[\\/]@vpxa[\\/]aikit$/,``)}function ae(e){return ie(e).includes(`/_npx/`)}function w(){try{return JSON.parse(r(u(S(),`package.json`),`utf8`)).optionalDependencies?.[x]??`latest`}catch{return`latest`}}function oe(e){return e.replace(/[^a-zA-Z0-9._-]+/g,`_`)}function se(){let e=`${oe(w())}-${process.platform}-${process.arch}-abi${process.versions.modules}`;return u(te(),`.aikit`,`cache`,`native-modules`,x,e)}function T(e){n(e,{recursive:!0});let r=u(e,`package.json`);t(r)||o(r,`${JSON.stringify({name:`aikit-native-runtime-cache`,private:!0},null,2)}\n`,`utf8`)}function E(e){let t=k(e);if(!t)return null;try{return JSON.parse(r(u(t,`package.json`),`utf8`)).version??null}catch{return null}}function D(e,t){try{let n={packageName:x,packageSpec:w(),packageVersion:E(e),platform:process.platform,arch:process.arch,nodeAbi:process.versions.modules,installedAt:new Date().toISOString(),source:t};o(u(e,`.aikit-native-module.json`),`${JSON.stringify(n,null,2)}\n`,`utf8`)}catch(e){y.debug(`Failed to write better-sqlite3 runtime marker`,g(e))}}var O=class{runtimeRoot;type=`better-sqlite3`;kind=`better-sqlite3`;vectorCapable=!1;get capabilities(){return{vectorCapable:this.vectorCapable,persistentFile:!0,concurrentReaders:!0}}db=null;stmtCache=new Map;dbPath=``;DatabaseCtor=null;recovering=!1;constructor(e){this.runtimeRoot=e}async open(t){let n;try{let t=b;this.runtimeRoot!=null&&(T(this.runtimeRoot),t=e(u(this.runtimeRoot,`package.json`))),n=t(x)}catch(e){throw Error(`better-sqlite3 native binding unavailable: ${e instanceof Error?e.message:String(e)}`)}this.db=new n(t),this.dbPath=t,this.DatabaseCtor=n,this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`),this.runIntegrityCheck(t,n)||(this.db?.pragma(`journal_mode = WAL`),this.db?.pragma(`foreign_keys = ON`),this.db?.pragma(`synchronous = NORMAL`));try{b(`sqlite-vec`).load(this.db),this.vectorCapable=!0,y.debug(`sqlite-vec extension loaded`)}catch(e){this.vectorCapable=!1,y.warn(`sqlite-vec extension failed to load; vector search disabled`,g(e))}}exec(e){try{this.getDb().exec(e)}catch(t){if(this.isCorruptionError(t)){this.recover(),this.getDb().exec(e);return}throw t}}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){try{let n=this.prepareCached(e);return t.length>0?n.all(...t):n.all()}catch(n){if(this.isCorruptionError(n))return this.recover(),this.queryAll(e,t);throw n}}run(e,t){try{let n=this.prepareCached(e);return t===void 0?n.run():Array.isArray(t)?t.length===0?n.run():n.run(...t):n.run(t)}catch(n){if(this.isCorruptionError(n))return this.recover(),this.run(e,t);throw n}}get(e,t){try{let n=this.prepareCached(e);return t===void 0?n.get():Array.isArray(t)?t.length>0?n.get(...t):n.get():n.get(t)}catch(n){if(this.isCorruptionError(n))return this.recover(),this.get(e,t);throw n}}all(e,t){try{let n=this.prepareCached(e);return t===void 0?n.all():Array.isArray(t)?t.length>0?n.all(...t):n.all():n.all(t)}catch(n){if(this.isCorruptionError(n))return this.recover(),this.all(e,t);throw n}}transaction(e){return this.getDb().transaction(()=>e(this.createTransactionHandle()))()}createTransactionHandle(){return{exec:e=>this.exec(e),get:(e,t)=>this.get(e,t),all:(e,t)=>this.all(e,t),run:(e,t)=>this.run(e,t)}}flush(){}async close(){this.db&&=(this.stmtCache.clear(),this.db.close(),null)}runIntegrityCheck(e,t){try{let t=this.db?.pragma(`integrity_check`);if(t.length===1&&t[0]?.integrity_check===`ok`)return!0;let n=t.map(e=>e.integrity_check).slice(0,5).join(`; `);y.warn(`Database integrity check failed — recreating`,{dbPath:e,issues:n})}catch(t){y.warn(`Integrity check query failed — recreating database`,{dbPath:e,error:g(t)})}try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(e)}catch{}try{a(`${e}-wal`)}catch{}try{a(`${e}-shm`)}catch{}return this.db=new t(e),y.info(`Database recreated successfully — full reindex required`,{dbPath:e}),!1}isCorruptionError(e){if(this.recovering)return!1;let t=e instanceof Error?e.message:String(e);return/database disk image is malformed|file is not a database|database or disk is full/.test(t)}recover(){if(this.recovering)throw Error(`BetterSqlite3Adapter: recovery already in progress`);this.recovering=!0;try{y.warn(`Runtime corruption detected — recovering database`,{dbPath:this.dbPath});try{this.db?.close()}catch{}this.db=null,this.stmtCache.clear();try{a(this.dbPath)}catch{}try{a(`${this.dbPath}-wal`)}catch{}try{a(`${this.dbPath}-shm`)}catch{}if(!this.DatabaseCtor)throw Error(`DatabaseCtor is not initialized`);this.db=this.DatabaseCtor(this.dbPath),this.db.pragma(`journal_mode = WAL`),this.db.pragma(`foreign_keys = ON`),this.db.pragma(`synchronous = NORMAL`);try{b(`sqlite-vec`).load(this.db),this.vectorCapable=!0}catch{this.vectorCapable=!1}y.info(`Database recovered — full reindex required`,{dbPath:this.dbPath})}finally{this.recovering=!1}}getDb(){if(!this.db)throw Error(`BetterSqlite3Adapter: database not opened`);return this.db}prepareCached(e){let t=this.stmtCache.get(e);if(t)return t;let n=this.getDb().prepare(e);return this.stmtCache.set(e,n),n}};function k(e){if(e){let n=u(e,`node_modules`,x);return t(u(n,`package.json`))?n:null}try{return b.resolve(`${x}/package.json`).replace(/[\\/]package\.json$/,``)}catch{return null}}function ce(e){let n=k(e);if(!n)return null;let r=u(n,`build`,`Release`,`better_sqlite3.node`);return t(r)?r:null}async function le(e){let n=k(e);if(!n)return`package-missing`;if(!t(u(n,`build`,`Release`,`better_sqlite3.node`)))return`binding-missing`;try{let{execFileSync:t}=await import(`node:child_process`),n=e??C();return e&&T(e),t(process.execPath,[`-e`,`require('${x}')`],{cwd:n,stdio:`pipe`,timeout:15e3,windowsHide:!0}),`ok`}catch(e){let t=e instanceof Error&&`stderr`in e?String(e.stderr):``;return/NODE_MODULE_VERSION/.test(t)?`abi-mismatch`:/Could not locate the bindings file|no native build was found/.test(t)?`binding-missing`:`error`}}async function ue(e,n=!1){let r=k(e);if(!r)return y.info(`better-sqlite3 package is not installed — skipping native rebuild`),!1;try{let{execFileSync:i}=await import(`node:child_process`),o=e??r.replace(/[\\/]node_modules[\\/]better-sqlite3$/,``),s=process.platform===`win32`?`npm.cmd`:`npm`;if(e&&T(e),n){let e=u(r,`build`,`Release`,`better_sqlite3.node`);if(t(e))try{a(e),y.info(`Deleted stale native binding before rebuild`,{path:e})}catch(t){y.warn(`Cannot delete stale native binding — file may be locked by another process`,{path:e,error:t instanceof Error?t.message:String(t)})}}return y.info(`Attempting native module rebuild for better-sqlite3`,{cwd:o}),i(s,[`rebuild`,x],{cwd:o,stdio:`pipe`,timeout:6e4,windowsHide:!0}),y.info(`Native module rebuild completed successfully`),D(o,`rebuild`),!0}catch(e){return y.warn(`Native module rebuild failed — continuing with sql.js fallback`,g(e)),!1}}async function de(e){try{let{execFileSync:t}=await import(`node:child_process`),n=e??C(),r=process.platform===`win32`?`npm.cmd`:`npm`,i=w();return T(n),y.info(`Attempting to install better-sqlite3 for native adapter recovery`,{cwd:n,packageSpec:i}),t(r,[`install`,`--no-save`,`--package-lock=false`,`--no-audit`,`--no-fund`,`--omit=dev`,`${x}@${i}`],{cwd:n,stdio:`pipe`,timeout:12e4,windowsHide:!0}),y.info(`better-sqlite3 install completed successfully`),D(n,`install`),!0}catch(e){return y.warn(`better-sqlite3 install failed — continuing with sql.js fallback`,g(e)),!1}}const fe=e(import.meta.url),pe=h(`sqljs-adapter`);function me(e){return fe.resolve(`sql.js/dist/${e}`)}function he(e){return e.match(/^\s*(?:INSERT(?:\s+OR\s+\w+)?\s+INTO|UPDATE)\s+([A-Za-z_][A-Za-z0-9_]*)/i)?.[1]??null}var A=class{type=`sql.js`;kind=`sqljs`;vectorCapable=!1;capabilities={vectorCapable:!1,persistentFile:!0,concurrentReaders:!1};db=null;dbPath=``;dirty=!1;flushTimer=null;DEBOUNCE_MS=1e3;MAX_DB_SIZE_BYTES=500*1024*1024;inTransaction=!1;foreignKeysEnabled=!1;async open(e){this.dbPath=e;let n=(await import(`sql.js`)).default,i=await n({locateFile:e=>me(e)});if(t(e)){let t=r(e);this.db=new i.Database(t)}else this.db=new i.Database}exec(e){let t=e.trimStart().toUpperCase();this.getDb().run(e),t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.markDirty()}pragma(e){let t=e.trim().toLowerCase();t===`foreign_keys = on`||t===`foreign_keys=on`?this.foreignKeysEnabled=!0:(t===`foreign_keys = off`||t===`foreign_keys=off`)&&(this.foreignKeysEnabled=!1),this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);try{t.length>0&&n.bind(t);let e=[];for(;n.step();)e.push(n.getAsObject());return e}finally{n.free()}}execWrite(e,t){let n=this.getDb();if(t===void 0){n.run(e);return}let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}toBindParams(e){if(e!==void 0)return Array.isArray(e)&&e.length===0?void 0:e}run(e,t){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=he(e),a=this.foreignKeysEnabled&&!this.inTransaction&&i!==null&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));a&&n.run(`SAVEPOINT fk_check`);try{if(this.execWrite(e,this.toBindParams(t)),a){if(n.exec(`PRAGMA foreign_key_check(${i})`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}}catch(e){if(a)try{n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`)}catch{}throw e}return this.markDirty(),this.getChangesResult(n)}getChangesResult(e){let t=e.exec(`SELECT changes() AS changes, last_insert_rowid() AS rowid`),n=t[0]?.values[0]?.[0]??0,r=t[0]?.values[0]?.[1];return{changes:Number(n),lastInsertRowid:r===void 0?void 0:Number(r)}}get(e,t){let n=this.getDb().prepare(e);try{return t!==void 0&&(Array.isArray(t)?t.length>0&&n.bind(t):n.bind(t)),n.step()?n.getAsObject():void 0}finally{n.free()}}all(e,t){let n=this.getDb().prepare(e);try{t!==void 0&&(Array.isArray(t)?t.length>0&&n.bind(t):n.bind(t));let e=[];for(;n.step();)e.push(n.getAsObject());return e}finally{n.free()}}transaction(e){this.exec(`BEGIN IMMEDIATE`);try{let t=e(this.createTransactionHandle());return this.exec(`COMMIT`),t}catch(e){throw this.exec(`ROLLBACK`),e}}createTransactionHandle(){return{exec:e=>this.exec(e),get:(e,t)=>this.get(e,t),all:(e,t)=>this.all(e,t),run:(e,t)=>this.run(e,t)}}markDirty(e=!1){this.dirty=!0,e?this.flushImmediate():this.scheduleFlush()}scheduleFlush(){this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=setTimeout(()=>{this.flush()},this.DEBOUNCE_MS),this.flushTimer&&typeof this.flushTimer==`object`&&`unref`in this.flushTimer&&this.flushTimer.unref()}flushImmediate(){this.flushTimer&&=(clearTimeout(this.flushTimer),null),this.flush()}notifyCriticalWrite(){this.flushImmediate()}flush(){if(!this.dirty||!this.db)return;let e=this.db.export();e.byteLength>this.MAX_DB_SIZE_BYTES&&pe.warn(`Database size ${e.byteLength} bytes exceeds guardrail ${this.MAX_DB_SIZE_BYTES} bytes`);let r=`${this.dbPath}.tmp`,s=c(this.dbPath);s&&!t(s)&&n(s,{recursive:!0}),o(r,Buffer.from(e));try{a(this.dbPath)}catch{}i(r,this.dbPath),this.dirty=!1}async close(){if(this.flushTimer&&=(clearTimeout(this.flushTimer),null),this.db){let e=this.db,t;if(this.dirty)try{this.flush()}catch(e){t=e;try{a(`${this.dbPath}.tmp`)}catch{}}try{e.close()}finally{this.db=null}if(t)throw t}}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};const j=h(`sqlite-adapter`);e(import.meta.url);let M=!1;function ge(){return!!process.env.VITEST||process.argv.some(e=>e.includes(`vitest`))}async function _e(){let e=P.resolveAikitRuntimeRoot(),t=await P.probeNativeModuleAbi(e);if(t===`ok`)return e;if(P.isNpxRuntimeRoot(e)){let e=P.resolvePersistentNativeRuntimeRoot(),t=await P.probeNativeModuleAbi(e);if(t===`ok`)return j.info(`Using cached better-sqlite3 native runtime`,{runtimeRoot:e,version:P.resolveNativeModuleVersion(e)}),e;let n=!1;if(t===`abi-mismatch`?(j.info(`Persistent better-sqlite3 cache ABI mismatch — rebuilding cached binding`),n=await P.tryRebuildNativeModule(e,!0)):t===`binding-missing`?(j.info(`Persistent better-sqlite3 cache missing binding — rebuilding cache`),n=await P.tryRebuildNativeModule(e,!1)):(j.info(`Persistent better-sqlite3 cache missing — installing cached runtime`,{runtimeRoot:e,packageSpec:P.readAikitPackageSpec()}),n=await P.tryInstallNativeModule(e)),n&&await P.probeNativeModuleAbi(e)===`ok`)return j.info(`Persistent better-sqlite3 cache ready`,{runtimeRoot:e,version:P.resolveNativeModuleVersion(e)}),e}if(t===`abi-mismatch`){if(j.info(`Detected NODE_MODULE_VERSION mismatch via pre-flight probe — rebuilding before load`),await P.tryRebuildNativeModule(e,!0)&&await P.probeNativeModuleAbi(e)===`ok`)return j.info(`Pre-flight rebuild succeeded — proceeding with native adapter`),e}else if(t===`binding-missing`){if(j.info(`No native binding found — attempting rebuild before load`),await P.tryRebuildNativeModule(e,!1)&&await P.probeNativeModuleAbi(e)===`ok`)return e}else if(t===`package-missing`&&(j.info(`better-sqlite3 package is not installed — attempting install before load`),await P.tryInstallNativeModule(e)&&await P.probeNativeModuleAbi(e)===`ok`))return e;return null}async function N(e){let t=null;P.isVitestRuntime()||(t=await P.preparePreferredNativeRuntime());{let n=P.createNativeAdapter(t??void 0);try{return await n.open(e),n}catch(n){let r=n instanceof Error?n.message:String(n);if(!P.isVitestRuntime()&&/NODE_MODULE_VERSION|Could not locate the bindings file|no native build was found/.test(r)){let n=t??P.resolveAikitRuntimeRoot();if(await P.tryRebuildNativeModule(n,!1)){let t=P.createNativeAdapter(n);try{return await t.open(e),j.info(`better-sqlite3 recovered after native module rebuild`),t}catch{}}}M||(M=!0,j.warn(`[aikit] better-sqlite3 unavailable — falling back to sql.js (vector search disabled). Reinstall with prebuild support or rebuild from source to enable vector search.`,g(n)))}}let n=P.createFallbackAdapter();try{return await n.open(e),n}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`[aikit] SQLite adapter "sql.js" failed to load: ${t}`)}}async function ve(e){let t=new A;return await t.open(e),t}const P={BetterSqlite3Adapter:O,SqlJsAdapter:A,isVitestRuntime:ge,resolveAikitPackageRoot:S,resolveAikitRuntimeRoot:C,isNpxRuntimeRoot:ae,readAikitPackageSpec:w,resolvePersistentNativeRuntimeRoot:se,ensureRuntimeRootPackageJson:T,resolveNativeModulePackageDir:k,resolveNativeBindingPath:ce,resolveNativeModuleVersion:E,probeNativeModuleAbi:le,tryRebuildNativeModule:ue,tryInstallNativeModule:de,preparePreferredNativeRuntime:_e,createNativeAdapter:e=>new O(e),createFallbackAdapter:()=>new A},F=new Set([`sessions`,`stash`,`checkpoints`,`leases`,`signals`,`audit_log`,`replay_entries`,`session_metadata`]);function ye(e){let t=l(e)||`.db`,n=s(e,t);return u(c(e),`${n}-control${t}`)}function be(e){return F.has(e)?`control`:`content`}function I(e,t={}){let n=t.splitEnabled??!1;return{splitEnabled:n,contentDbPath:t.contentDbPath??e,controlDbPath:t.controlDbPath??(n?ye(e):e)}}function xe(e,t=process.env){let n=t.AIKIT_SPLIT_STATE?.trim().toLowerCase();return I(e,{splitEnabled:n===`1`||n===`true`||n===`yes`||n===`on`})}const L=`_state_partition_meta`;function R(e){return`"${e.replaceAll(`"`,`""`)}"`}function Se(e){let r=c(e);t(r)||n(r,{recursive:!0})}async function z(e){return Se(e),N(e)}function B(e,t){return e.queryAll(`SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?`,[t]).length>0}function Ce(e,t){return e.queryAll(`SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?`,[t])[0]?.sql??void 0}function we(e,t){return e.queryAll(`PRAGMA table_info(${R(t)})`).map(e=>e.name)}function Te(e,t){return e.queryAll(`SELECT COUNT(*) AS count FROM ${R(t)}`)[0]?.count??0}function Ee(e,t,n){if(!B(e,n))return;if(!B(t,n)){let r=Ce(e,n);if(!r)return;t.exec(r)}let r=we(t,n);if(r.length===0)return;let i=r.map(R).join(`, `),a=r.map(()=>`?`).join(`, `),o=e.queryAll(`SELECT ${i} FROM ${R(n)}`);if(o.length===0)return;let s=`INSERT OR REPLACE INTO ${R(n)} (${i}) VALUES (${a})`;for(let e of o)t.run(s,r.map(t=>e[t]??null))}function De(e){e.exec(`
|
|
115
|
+
CREATE TABLE IF NOT EXISTS ${L} (
|
|
84
116
|
key TEXT PRIMARY KEY,
|
|
85
117
|
value TEXT NOT NULL,
|
|
86
118
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
87
119
|
)
|
|
88
|
-
`)}function
|
|
120
|
+
`)}function Oe(e,t,n){De(e),e.run(`INSERT INTO ${L} (key, value, updated_at)
|
|
89
121
|
VALUES (?, ?, datetime('now'))
|
|
90
122
|
ON CONFLICT(key) DO UPDATE SET
|
|
91
123
|
value = excluded.value,
|
|
92
|
-
updated_at = datetime('now')`,[`split-state`,JSON.stringify({splitEnabled:t.splitEnabled,contentDbPath:t.contentDbPath,controlDbPath:t.controlDbPath,migratedTables:n})])}async function
|
|
124
|
+
updated_at = datetime('now')`,[`split-state`,JSON.stringify({splitEnabled:t.splitEnabled,contentDbPath:t.contentDbPath,controlDbPath:t.controlDbPath,migratedTables:n})])}async function ke(e){let t=e.contentDbPath??e.controlDbPath;if(!t)throw Error(`migrateToSplitState requires at least one database path in config`);let n=I(t,e);if(!n.splitEnabled||n.controlDbPath===n.contentDbPath)return;let r=await z(n.contentDbPath),i=await z(n.controlDbPath);try{_(i,v);let e=[];for(let t of F){if(!B(r,t))continue;Ee(r,i,t);let n=Te(r,t),a=Te(i,t);if(a<n)throw Error(`Split-state migration verification failed for ${t}: source=${n} target=${a}`);e.push(t)}Oe(i,n,e)}finally{r.close(),i.close()}}var Ae=class{adapter=null;reopenPromise=null;dbPath;externalAdapter;constructor(e={}){if(e.adapter)this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``;else{let t=e.path??d.data;this.dbPath=u(t,`graph.db`),this.externalAdapter=!1}}async initialize(){if(this.externalAdapter){let e=this.getAdapter();this.createTables(e),this.migrateSchema(e),e.flush();return}let e=c(this.dbPath);t(e)||n(e,{recursive:!0}),this.adapter=await N(this.dbPath),this.configureAdapter(this.adapter),this.createTables(this.adapter),this.migrateSchema(this.adapter),this.adapter.flush()}configureAdapter(e){e.pragma(`journal_mode = WAL`),e.pragma(`foreign_keys = ON`)}createTables(e){e.exec(`
|
|
93
125
|
CREATE TABLE IF NOT EXISTS nodes (
|
|
94
126
|
id TEXT PRIMARY KEY,
|
|
95
127
|
type TEXT NOT NULL,
|
|
@@ -130,7 +162,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
130
162
|
FOREIGN KEY (process_id) REFERENCES processes(id) ON DELETE CASCADE,
|
|
131
163
|
FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
|
132
164
|
)
|
|
133
|
-
`),e.exec(`CREATE INDEX IF NOT EXISTS idx_process_steps_node ON process_steps(node_id)`)}migrateSchema(e){for(let t of[`ALTER TABLE edges ADD COLUMN confidence REAL DEFAULT 1.0`,`ALTER TABLE nodes ADD COLUMN community TEXT`])try{e.exec(t)}catch{}e.exec(`CREATE INDEX IF NOT EXISTS idx_nodes_community ON nodes(community)`)}getAdapter(){if(!this.adapter)throw Error(`SqliteGraphStore not initialized — call initialize() first`);return this.adapter}async ensureOpen(){if(this.adapter)return;if(this.externalAdapter)throw Error(`SqliteGraphStore: external adapter has been closed by its owner; cannot reopen`);if(this.reopenPromise)return this.reopenPromise;let e=this.reopenAdapter();this.reopenPromise=e;try{await e}finally{this.reopenPromise===e&&(this.reopenPromise=null)}}async reopenAdapter(){let e=await
|
|
165
|
+
`),e.exec(`CREATE INDEX IF NOT EXISTS idx_process_steps_node ON process_steps(node_id)`)}migrateSchema(e){for(let t of[`ALTER TABLE edges ADD COLUMN confidence REAL DEFAULT 1.0`,`ALTER TABLE nodes ADD COLUMN community TEXT`])try{e.exec(t)}catch{}e.exec(`CREATE INDEX IF NOT EXISTS idx_nodes_community ON nodes(community)`)}getAdapter(){if(!this.adapter)throw Error(`SqliteGraphStore not initialized — call initialize() first`);return this.adapter}async ensureOpen(){if(this.adapter)return;if(this.externalAdapter)throw Error(`SqliteGraphStore: external adapter has been closed by its owner; cannot reopen`);if(this.reopenPromise)return this.reopenPromise;let e=this.reopenAdapter();this.reopenPromise=e;try{await e}finally{this.reopenPromise===e&&(this.reopenPromise=null)}}async reopenAdapter(){let e=await N(this.dbPath);this.configureAdapter(e),this.adapter=e}query(e,t=[]){return this.getAdapter().queryAll(e,t)}run(e,t=[]){this.getAdapter().run(e,t)}async upsertNode(e){await this.ensureOpen(),this.run(`INSERT INTO nodes (id, type, name, properties, source_record_id, source_path, created_at, community)
|
|
134
166
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
135
167
|
ON CONFLICT(id) DO UPDATE SET
|
|
136
168
|
type = excluded.type, name = excluded.name, properties = excluded.properties,
|
|
@@ -148,19 +180,19 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
148
180
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
149
181
|
ON CONFLICT(id) DO UPDATE SET
|
|
150
182
|
from_id = excluded.from_id, to_id = excluded.to_id,
|
|
151
|
-
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[t.id,t.fromId,t.toId,t.type,t.weight??1,t.confidence??1,JSON.stringify(t.properties??{})]);t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}finally{t.pragma(`foreign_keys = ON`)}}async getNode(e){await this.ensureOpen();let t=this.query(`SELECT * FROM nodes WHERE id = ?`,[e]);return t.length>0?
|
|
183
|
+
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[t.id,t.fromId,t.toId,t.type,t.weight??1,t.confidence??1,JSON.stringify(t.properties??{})]);t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}finally{t.pragma(`foreign_keys = ON`)}}async getNode(e){await this.ensureOpen();let t=this.query(`SELECT * FROM nodes WHERE id = ?`,[e]);return t.length>0?je(t[0]):null}async getNeighbors(e,t){await this.ensureOpen();let n=t?.direction??`both`,r=t?.edgeType,i=t?.limit??50,a=[],o=[],s=new Set;if(n===`outgoing`||n===`both`){let t=`
|
|
152
184
|
SELECT e.id AS edge_id, e.from_id, e.to_id, e.type AS edge_type, e.weight,
|
|
153
185
|
e.confidence AS edge_confidence, e.properties AS edge_props,
|
|
154
186
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
155
187
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
156
188
|
n.created_at AS node_created, n.community AS node_community
|
|
157
|
-
FROM edges e JOIN nodes n ON e.to_id = n.id WHERE e.from_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(
|
|
189
|
+
FROM edges e JOIN nodes n ON e.to_id = n.id WHERE e.from_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(H(e)),s.has(e.node_id)||(s.add(e.node_id),a.push(Ne(e)))}if(n===`incoming`||n===`both`){let t=`
|
|
158
190
|
SELECT e.id AS edge_id, e.from_id, e.to_id, e.type AS edge_type, e.weight,
|
|
159
191
|
e.confidence AS edge_confidence, e.properties AS edge_props,
|
|
160
192
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
161
193
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
162
194
|
n.created_at AS node_created, n.community AS node_community
|
|
163
|
-
FROM edges e JOIN nodes n ON e.from_id = n.id WHERE e.to_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(
|
|
195
|
+
FROM edges e JOIN nodes n ON e.from_id = n.id WHERE e.to_id = ?`,n=[e];r&&(t+=` AND e.type = ?`,n.push(r)),t+=` LIMIT ?`,n.push(i);let c=this.query(t,n);for(let e of c)o.push(H(e)),s.has(e.node_id)||(s.add(e.node_id),a.push(Ne(e)))}return{nodes:a,edges:o}}async traverse(e,t){await this.ensureOpen();let n=t?.maxDepth??2,r=t?.direction??`both`,i=t?.edgeType,a=t?.limit??50,o=new Map,s=new Map,c=new Set,l=[{nodeId:e,depth:0}];for(;l.length>0&&o.size<a;){let e=l.shift();if(!e||c.has(e.nodeId)||e.depth>n)continue;c.add(e.nodeId);let t=await this.getNeighbors(e.nodeId,{direction:r,edgeType:i,limit:a-o.size});for(let r of t.nodes)o.has(r.id)||(o.set(r.id,r),e.depth+1<n&&l.push({nodeId:r.id,depth:e.depth+1}));for(let e of t.edges)s.set(e.id,e)}return{nodes:[...o.values()],edges:[...s.values()]}}async findNodes(e){await this.ensureOpen();let t=[],n=[];e.type&&(t.push(`type = ?`),n.push(e.type)),e.namePattern&&(t.push(`name LIKE ?`),n.push(`%${e.namePattern}%`)),e.sourcePath&&(t.push(`source_path = ?`),n.push(e.sourcePath));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit??100;return this.query(`SELECT * FROM nodes ${r} LIMIT ?`,[...n,i]).map(e=>je(e))}async findEdges(e){await this.ensureOpen();let t=[],n=[];e.type&&(t.push(`type = ?`),n.push(e.type)),e.fromId&&(t.push(`from_id = ?`),n.push(e.fromId)),e.toId&&(t.push(`to_id = ?`),n.push(e.toId));let r=t.length>0?`WHERE ${t.join(` AND `)}`:``,i=e.limit??100;return this.query(`SELECT * FROM edges ${r} LIMIT ?`,[...n,i]).map(e=>Me(e))}async deleteNode(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM edges WHERE from_id = ? OR to_id = ?`,[e,e]),this.run(`DELETE FROM nodes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async deleteBySourcePath(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE source_path = ?`,[e]);if(t.length===0)return 0;let n=this.getAdapter();n.exec(`BEGIN TRANSACTION`);try{for(let e of t)this.run(`DELETE FROM edges WHERE from_id = ? OR to_id = ?`,[e.id,e.id]);this.run(`DELETE FROM nodes WHERE source_path = ?`,[e]),n.exec(`COMMIT`),n.flush()}catch(e){throw n.exec(`ROLLBACK`),e}return t.length}async clear(){await this.ensureOpen();let e=this.getAdapter();e.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps`),this.run(`DELETE FROM processes`),this.run(`DELETE FROM edges`),this.run(`DELETE FROM nodes`),e.exec(`COMMIT`)}catch(t){throw e.exec(`ROLLBACK`),t}e.flush()}async getStats(){await this.ensureOpen();let e=this.query(`SELECT COUNT(*) as count FROM nodes`)[0]?.count??0,t=this.query(`SELECT COUNT(*) as count FROM edges`)[0]?.count??0,n=this.query(`SELECT type, COUNT(*) as count FROM nodes GROUP BY type`),r={};for(let e of n)r[e.type]=e.count;let i=this.query(`SELECT type, COUNT(*) as count FROM edges GROUP BY type`),a={};for(let e of i)a[e.type]=e.count;return{nodeCount:e,edgeCount:t,nodeTypes:r,edgeTypes:a}}async validate(){await this.ensureOpen();let e=await this.getStats(),t=this.query(`SELECT e.id AS edgeId,
|
|
164
196
|
CASE
|
|
165
197
|
WHEN n1.id IS NULL THEN e.from_id
|
|
166
198
|
WHEN n2.id IS NULL THEN e.to_id
|
|
@@ -178,7 +210,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
178
210
|
VALUES (?, ?, ?, '{}', ?)`,[a,e,t,o]);for(let e=0;e<n.length;e++)this.run(`INSERT INTO process_steps (process_id, node_id, step_order) VALUES (?, ?, ?)`,[a,n[e],e]);s.exec(`COMMIT`),s.flush()}catch(e){throw s.exec(`ROLLBACK`),e}return{id:a,entryNodeId:e,label:t,properties:{},steps:n,createdAt:o}}async getProcesses(e){await this.ensureOpen();let t;t=e?this.query(`SELECT DISTINCT p.id, p.entry_node_id, p.label, p.properties, p.created_at
|
|
179
211
|
FROM processes p
|
|
180
212
|
JOIN process_steps ps ON p.id = ps.process_id
|
|
181
|
-
WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:
|
|
213
|
+
WHERE ps.node_id = ?`,[e]):this.query(`SELECT * FROM processes`);let n=[];for(let e of t){let t=this.query(`SELECT node_id FROM process_steps WHERE process_id = ? ORDER BY step_order`,[e.id]);n.push({id:e.id,entryNodeId:e.entry_node_id,label:e.label,properties:V(e.properties),steps:t.map(e=>e.node_id),createdAt:e.created_at})}return n}async deleteProcess(e){await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{this.run(`DELETE FROM process_steps WHERE process_id = ?`,[e]),this.run(`DELETE FROM processes WHERE id = ?`,[e]),t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async depthGroupedTraversal(e,t=3,n){await this.ensureOpen();let r=n?.direction??`both`,i=n?.edgeType,a=n?.limit??100,o={},s=new Set;s.add(e);let c=[e];for(let e=1;e<=t;e++){let t=[],n=[];for(let e of c){let o=await this.getNeighbors(e,{direction:r,edgeType:i,limit:a});for(let e of o.nodes)s.has(e.id)||(s.add(e.id),t.push(e.id),n.push(e))}if(n.length>0&&(o[e]=n),c=t,c.length===0||s.size>=a)break}return o}async getCohesionScore(e){await this.ensureOpen();let t=this.query(`SELECT id FROM nodes WHERE community = ?`,[e]);if(t.length===0)return 0;let n=new Set(t.map(e=>e.id)),r=t.map(()=>`?`).join(`,`),i=t.map(e=>e.id),a=this.query(`SELECT from_id, to_id FROM edges WHERE from_id IN (${r}) OR to_id IN (${r})`,[...i,...i]);if(a.length===0)return 0;let o=0;for(let e of a)n.has(e.from_id)&&n.has(e.to_id)&&o++;return o/a.length}async getSymbol360(e){let t=await this.getNode(e);if(!t)throw Error(`Node '${e}' not found`);let n=await this.findEdges({toId:e}),r=await this.findEdges({fromId:e}),i=await this.getProcesses(e);return{node:t,incoming:n,outgoing:r,community:t.community??null,processes:i}}releaseMemory(){if(this.adapter)try{this.adapter.exec(`PRAGMA shrink_memory`),this.adapter.exec(`PRAGMA wal_checkpoint(TRUNCATE)`)}catch{}}async close(){this.adapter&&=(this.externalAdapter||this.adapter.close(),null)}};function V(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function je(e){return{id:e.id,type:e.type,name:e.name,properties:V(e.properties),sourceRecordId:e.source_record_id??void 0,sourcePath:e.source_path??void 0,createdAt:e.created_at,community:e.community??void 0}}function Me(e){return{id:e.id,fromId:e.from_id,toId:e.to_id,type:e.type,weight:e.weight??1,confidence:e.confidence??1,properties:V(e.properties)}}function H(e){return{id:e.edge_id,fromId:e.from_id,toId:e.to_id,type:e.edge_type,weight:e.weight??1,confidence:e.edge_confidence??1,properties:V(e.edge_props??`{}`)}}function Ne(e){return{id:e.node_id,type:e.node_type,name:e.node_name,properties:V(e.node_props??`{}`),sourceRecordId:e.node_src_rec??void 0,sourcePath:e.node_src_path??void 0,createdAt:e.node_created,community:e.node_community??void 0}}function U(e){let t=0;for(let n=0;n<e.length;n++){let r=e[n]<0?-e[n]:e[n];r>t&&(t=r)}let n=new Int8Array(e.length);if(t===0)return Buffer.from(n.buffer,n.byteOffset,n.byteLength);let r=127/t;for(let t=0;t<e.length;t++){let i=Math.round(e[t]*r);n[t]=i<-127?-127:i>127?127:i}return Buffer.from(n.buffer,n.byteOffset,n.byteLength)}const W=h(`sqlite-vec-store`);function Pe(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function Fe(e){return!e||e.length===0?[]:[...new Set(e.filter(e=>typeof e==`string`&&e.length>0))]}const G=`knowledge_meta`,Ie=`embedding_profile`,K=Object.freeze({additionalFilterMultiplier:4,baseOverfetchMultiplier:4,filteredOverfetchMultiplier:8,filteredRetryMultiplier:2,maxCandidateLimit:512,maxExpansionFactor:4,minFilteredCandidateLimit:16,tagFilterMultiplier:4});function Le(e){return{model:e.model,nativeDim:e.nativeDim,dimensions:e.dimensions,queryPrefix:e.queryPrefix}}function Re(e){return JSON.stringify(Le(e))}function ze(e){return new Uint8Array(e.buffer,e.byteOffset,e.byteLength)}var Be=class{adapter=null;externalAdapter;dbPath;embeddingDim;embeddingProfile;coarseDim;vectorEnabled=!1;ftsEnabled=!1;warnedVectorDisabled=!1;_draining=!1;_priorityQueue=[];_normalQueue=[];_closeWaiter=null;_onCloseHooks=[];constructor(e={}){let t=e.embeddingProfile?.dimensions??e.embeddingDim??f.dimensions;if(this.embeddingDim=t,this.embeddingProfile=Le(e.embeddingProfile??{model:f.model,nativeDim:f.nativeDim,dimensions:t,queryPrefix:f.queryPrefix}),this.coarseDim=Math.min(128,this.embeddingDim),e.adapter)this.adapter=e.adapter,this.externalAdapter=!0,this.dbPath=``;else{let t=I(e.path??`${m.path}/aikit.db`,e.partition);this.dbPath=t.contentDbPath,this.externalAdapter=!1}}async initialize(){if(!this.adapter){let e=c(this.dbPath);t(e)||n(e,{recursive:!0}),this.adapter=await N(this.dbPath)}this.configureConnectionPragmas(),this.vectorEnabled=this.adapter.vectorCapable,_(this.adapter,v),this.createKnowledgeTable(),this.createKnowledgeTagsTable(),this.createFtsTable(),this.vectorEnabled?(this.ensureVecTable(),this.backfillCanonicalEmbeddingsIfNeeded()):this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,W.warn(`SqliteVecStore: vector search disabled (sqlite-vec extension not loaded). Hybrid search will return FTS-only results.`))}configureConnectionPragmas(){let e=this.getAdapter();e.pragma(`journal_mode = WAL`),e.pragma(`busy_timeout = 5000`)}getDiagnostics(){let e=this.adapter,t=e?e.constructor.name:`unknown`,n=null,r=this.externalAdapter?``:this.dbPath;if(r)try{let{statSync:e}=ne(`node:fs`);n=e(r).size}catch{n=null}return{adapterType:t,vectorSearchEnabled:this.vectorEnabled,ftsEnabled:this.ftsEnabled,degradedMode:!this.vectorEnabled,dbPath:r,dbSizeBytes:n,embeddingDim:this.embeddingDim,vectorDtype:`int8`,embeddingModel:this.embeddingProfile.model,embeddingProfile:this.embeddingProfile}}createKnowledgeTable(){let e=this.getAdapter();e.exec(`
|
|
182
214
|
CREATE TABLE IF NOT EXISTS knowledge (
|
|
183
215
|
id TEXT PRIMARY KEY,
|
|
184
216
|
content TEXT NOT NULL,
|
|
@@ -209,14 +241,14 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
209
241
|
content,
|
|
210
242
|
tokenize = 'unicode61 remove_diacritics 2'
|
|
211
243
|
)
|
|
212
|
-
`),this.ftsEnabled=!0}catch(e){this.ftsEnabled=!1,W.warn(`FTS5 unavailable — keyword search disabled`,
|
|
213
|
-
CREATE TABLE IF NOT EXISTS ${
|
|
244
|
+
`),this.ftsEnabled=!0}catch(e){this.ftsEnabled=!1,W.warn(`FTS5 unavailable — keyword search disabled`,g(e))}}createEmbeddingProfileTable(){this.getAdapter().exec(`
|
|
245
|
+
CREATE TABLE IF NOT EXISTS ${G} (
|
|
214
246
|
key TEXT PRIMARY KEY,
|
|
215
247
|
value TEXT NOT NULL
|
|
216
248
|
)
|
|
217
|
-
`)}getStoredEmbeddingProfile(){return this.getAdapter().queryAll(`SELECT value FROM ${
|
|
249
|
+
`)}getStoredEmbeddingProfile(){return this.getAdapter().queryAll(`SELECT value FROM ${G} WHERE key = ? LIMIT 1`,[Ie])[0]?.value??null}saveEmbeddingProfile(){this.getAdapter().run(`INSERT INTO ${G} (key, value)
|
|
218
250
|
VALUES (?, ?)
|
|
219
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value`,[
|
|
251
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`,[Ie,Re(this.embeddingProfile)])}dropVectorTables(){let e=this.getAdapter();e.exec(`DROP TABLE IF EXISTS vec_knowledge_coarse`),e.exec(`DROP TABLE IF EXISTS vec_knowledge`)}ensureVecTable(){let e=this.getAdapter();this.createEmbeddingProfileTable();let t=Re(this.embeddingProfile),n=this.getStoredEmbeddingProfile(),r=!1;n!==null&&n!==t&&(r=!0,W.warn(`Vec profile mismatch — dropping vector tables for recreation`,{storedProfile:n,activeProfile:t}));let i=e.queryAll(`SELECT name, sql FROM sqlite_master WHERE type='table' AND name='vec_knowledge'`);if(!r&&i.length>0){let e=i[0].sql??``,t=e.match(/(?:float|int8)\[(\d+)\]/i),n=t?Number(t[1]):null,a=/int8\[/i.test(e);(n!==null&&n!==this.embeddingDim||!a)&&(r=!0,W.warn(`Vec table schema mismatch — dropping for recreation`,{existingDim:n,newDim:this.embeddingDim,wasInt8:a}))}r&&this.dropVectorTables(),e.exec(`
|
|
220
252
|
CREATE VIRTUAL TABLE IF NOT EXISTS vec_knowledge USING vec0(
|
|
221
253
|
embedding int8[${this.embeddingDim}] distance_metric=cosine,
|
|
222
254
|
+knowledge_id TEXT
|
|
@@ -226,7 +258,14 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
226
258
|
embedding int8[${this.coarseDim}] distance_metric=cosine,
|
|
227
259
|
+knowledge_id TEXT
|
|
228
260
|
)
|
|
229
|
-
`),this.saveEmbeddingProfile()}
|
|
261
|
+
`),this.saveEmbeddingProfile()}backfillCanonicalEmbeddingsIfNeeded(){let e=this.getAdapter();if((e.queryAll(`SELECT COUNT(*) AS cnt FROM memory_embeddings`)[0]?.cnt??0)>0)return;let t=e.queryAll(`SELECT name, sql FROM sqlite_master WHERE type = 'table' AND sql LIKE '%vec0%'`);if(t.length===0)return;let n=Date.now(),r=0;for(let i of t){let t=i.sql.match(/(?:int8|float)\[(\d+)\]/i);if(!t)continue;let a=Number(t[1]),o=e.queryAll(`SELECT COUNT(*) AS cnt FROM memory_embeddings`)[0]?.cnt??0;try{e.run(`INSERT OR IGNORE INTO memory_embeddings
|
|
262
|
+
(memory_id, embedding_model, embedding_version, dimensions, element_type, embedding, created_at)
|
|
263
|
+
SELECT knowledge_id, 'default', '1', ?, 'float32', embedding, ?
|
|
264
|
+
FROM ${i.name}`,[a,n])}catch(e){W.warn(`backfillCanonicalEmbeddings: failed for vec0 table`,{table:i.name,error:g(e)});continue}let s=e.queryAll(`SELECT COUNT(*) AS cnt FROM memory_embeddings`)[0]?.cnt??0;r+=s-o}if(r>0){W.info(`backfilled canonical embeddings from vec0`,{count:r});try{let t=this.embeddingProfile?.model??`default`,i=this.embeddingProfile?.version??`1`;e.run(`INSERT INTO vector_index_metadata (index_name, generation, embedding_model, embedding_version, dimensions, canonical_count, indexed_count, built_at)
|
|
265
|
+
VALUES ('vec_knowledge', 0, ?, ?, ?, ?, 0, ?)
|
|
266
|
+
ON CONFLICT(index_name) DO UPDATE SET
|
|
267
|
+
canonical_count = excluded.canonical_count,
|
|
268
|
+
generation = excluded.generation`,[t,i,this.embeddingDim,r,n])}catch(e){W.warn(`backfillCanonicalEmbeddings: failed to update vector_index_metadata`,{error:g(e)})}}}enqueueWrite(e,t=!1){return new Promise((n,r)=>{let i=async()=>{try{n(await e())}catch(e){r(e)}};t?this._priorityQueue.push(i):this._normalQueue.push(i),this._drain()})}async _drain(){if(!this._draining){this._draining=!0;try{for(;this._priorityQueue.length>0||this._normalQueue.length>0;){let e=this._priorityQueue.shift()??this._normalQueue.shift();e&&await e()}}finally{if(this._draining=!1,this._closeWaiter){let e=this._closeWaiter;this._closeWaiter=null,e.resolve()}}}}async upsert(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);for(let n=0;n<t.length;n++)if(t[n].length===0)throw Error(`Zero-length vector at index ${n} for record ${e[n].sourcePath}`);return this.enqueueWrite(()=>this._upsertImpl(e,t))}}async upsertInteractive(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);for(let n=0;n<t.length;n++)if(t[n].length===0)throw Error(`Zero-length vector at index ${n} for record ${e[n].sourcePath}`);return this.enqueueWrite(()=>this._upsertImpl(e,t),!0)}}async upsertWithoutVector(e,t){return this.enqueueWrite(async()=>{let n=this.getAdapter(),r=e;n.exec(`BEGIN`);try{if(this.upsertKnowledgeRow(r),this.ftsEnabled&&(n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[r.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[r.id,r.content])),this.vectorEnabled){let e=n.queryAll(`SELECT embedding FROM vec_knowledge WHERE knowledge_id = ?`,[t]);if(e.length>0){if(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]),this.coarseDim<this.embeddingDim){let e=n.queryAll(`SELECT embedding FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[t]);e.length>0&&(n.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[r.id]),n.run(`INSERT INTO vec_knowledge_coarse (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[e[0].embedding,r.id]))}}else W.warn(`upsertWithoutVector: source vector not found, record will lack vector`,{recordId:r.id,sourceRecordId:t})}n.exec(`COMMIT`)}catch(e){try{n.exec(`ROLLBACK`)}catch{}throw e}n.flush()})}upsertKnowledgeRow(e){this.getAdapter().run(`INSERT INTO knowledge (id, content, sourcePath, contentType, headingPath, chunkIndex,
|
|
230
269
|
totalChunks, startLine, endLine, fileHash, content_hash, indexedAt, origin, tags, category, version)
|
|
231
270
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
232
271
|
ON CONFLICT(id) DO UPDATE SET
|
|
@@ -244,7 +283,9 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
244
283
|
origin = excluded.origin,
|
|
245
284
|
tags = excluded.tags,
|
|
246
285
|
category = excluded.category,
|
|
247
|
-
version = excluded.version`,[e.id,e.content,e.sourcePath,e.contentType,e.headingPath??``,e.chunkIndex,e.totalChunks,e.startLine,e.endLine,e.fileHash,e.contentHash??``,e.indexedAt,e.origin,JSON.stringify(
|
|
286
|
+
version = excluded.version`,[e.id,e.content,e.sourcePath,e.contentType,e.headingPath??``,e.chunkIndex,e.totalChunks,e.startLine,e.endLine,e.fileHash,e.contentHash??``,e.indexedAt,e.origin,JSON.stringify(Fe(e.tags)),e.category??``,e.version])}replaceKnowledgeTags(e,t){let n=this.getAdapter(),r=Fe(t);if(n.run(`DELETE FROM knowledge_tags WHERE knowledge_id = ?`,[e]),r.length===0)return;let i=r.map(()=>`(?, ?)`).join(`, `),a=[];for(let t of r)a.push(e,t);n.run(`INSERT INTO knowledge_tags (knowledge_id, tag) VALUES ${i}`,a)}async _upsertImpl(e,t){let n=this.getAdapter();n.transaction(()=>{for(let r=0;r<e.length;r++){let i=e[r];if(this.upsertKnowledgeRow(i),this.replaceKnowledgeTags(i.id,i.tags),this.ftsEnabled&&(n.run(`DELETE FROM knowledge_fts WHERE id = ?`,[i.id]),n.run(`INSERT INTO knowledge_fts (id, content) VALUES (?, ?)`,[i.id,i.content])),this.vectorEnabled){if(n.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[U(t[r]),i.id]),this.coarseDim<this.embeddingDim){let e=t[r].subarray(0,this.coarseDim);n.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[i.id]),n.run(`INSERT INTO vec_knowledge_coarse (embedding, knowledge_id) VALUES (vec_int8(?), ?)`,[U(e),i.id])}let e=ze(t[r]);n.run(`INSERT OR REPLACE INTO memory_embeddings
|
|
287
|
+
(memory_id, embedding_model, embedding_version, dimensions, element_type, embedding, created_at)
|
|
288
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,[i.id,this.embeddingProfile?.model??`default`,this.embeddingProfile?.version??`1`,t[r].length,`float32`,e,Date.now()])}}}),n.flush()}async search(e,t){if(e.length===0)return[];if(!this.vectorEnabled)return this.warnedVectorDisabled||(this.warnedVectorDisabled=!0,W.warn(`search() called but vector backend is disabled — returning []`)),[];let n=t?.limit??p.maxResults,r=t?.minScore??p.minScore,i;try{i=this.runAdaptiveVectorSearch(`vec_knowledge`,U(e),t)}catch(e){return W.warn(`vector search failed`,g(e)),[]}return this.rowsToSearchResults(i,r,n)}async coarseSearch(e,t){if(!this.vectorEnabled||this.coarseDim>=this.embeddingDim)return this.search(e,t);let n=t?.limit??p.maxResults,r=t?.minScore??p.minScore,i=e.subarray(0,this.coarseDim),a;try{a=this.runAdaptiveVectorSearch(`vec_knowledge_coarse`,U(i),t)}catch(n){return W.warn(`coarse vector search failed, falling back to full search`,g(n)),this.search(e,t)}return a.length===0?this.search(e,t):this.rowsToSearchResults(a,r,n)}async ftsSearch(e,t){if(!e||e.trim().length===0||!this.ftsEnabled)return[];let n=this.getAdapter(),r=t?.limit??p.maxResults,i=this.buildFilterSqlSuffix(t,!0),a=`
|
|
248
289
|
SELECT k.*, bm25(knowledge_fts) AS _bm25
|
|
249
290
|
FROM knowledge_fts
|
|
250
291
|
JOIN knowledge k ON k.id = knowledge_fts.id
|
|
@@ -252,7 +293,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
252
293
|
${i.sql}
|
|
253
294
|
ORDER BY _bm25 ASC
|
|
254
295
|
LIMIT ?
|
|
255
|
-
`,o;try{let t=
|
|
296
|
+
`,o;try{let t=Ve(e);o=n.queryAll(a,[t,...i.params,r])}catch(e){return W.warn(`fts search failed`,g(e)),[]}return o.map(e=>({record:this.fromRow(e),score:He(e._bm25)}))}async getById(e){let t=this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE id = ? LIMIT 1`,[e]);return t.length===0?null:this.fromRow(t[0])}async deleteBySourcePath(e){return this.enqueueWrite(()=>this._deleteBySourcePathImpl(e))}async _deleteBySourcePathImpl(e){let t=this.getAdapter(),n=t.queryAll(`SELECT id FROM knowledge WHERE sourcePath = ?`,[e]);if(n.length===0)return 0;t.exec(`BEGIN`);try{for(let{id:e}of n)this.vectorEnabled&&(t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),this.coarseDim<this.embeddingDim&&t.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[e])),t.run(`DELETE FROM memory_embeddings WHERE memory_id = ?`,[e]),t.run(`DELETE FROM knowledge_tags WHERE knowledge_id = ?`,[e]),this.ftsEnabled&&t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]);t.run(`DELETE FROM knowledge WHERE sourcePath = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),n.length}async deleteById(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e))}async deleteByIdInteractive(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e),!0)}async _deleteByIdImpl(e){let t=this.getAdapter();if(t.queryAll(`SELECT id FROM knowledge WHERE id = ? LIMIT 1`,[e]).length===0)return!1;t.exec(`BEGIN`);try{this.vectorEnabled&&(t.run(`DELETE FROM vec_knowledge WHERE knowledge_id = ?`,[e]),this.coarseDim<this.embeddingDim&&t.run(`DELETE FROM vec_knowledge_coarse WHERE knowledge_id = ?`,[e])),t.run(`DELETE FROM memory_embeddings WHERE memory_id = ?`,[e]),t.run(`DELETE FROM knowledge_tags WHERE knowledge_id = ?`,[e]),this.ftsEnabled&&t.run(`DELETE FROM knowledge_fts WHERE id = ?`,[e]),t.run(`DELETE FROM knowledge WHERE id = ?`,[e]),t.exec(`COMMIT`)}catch(e){try{t.exec(`ROLLBACK`)}catch{}throw e}return t.flush(),!0}async getBySourcePath(e){return this.getAdapter().queryAll(`SELECT * FROM knowledge WHERE sourcePath = ? ORDER BY chunkIndex ASC`,[e]).map(e=>this.fromRow(e))}async getStats(){let e=this.getAdapter(),t=e.queryAll(`SELECT COUNT(*) AS n FROM knowledge`)[0]?.n??0;if(t===0)return{totalRecords:0,totalFiles:0,contentTypeBreakdown:{},lastIndexedAt:null,storeBackend:`sqlite-vec`,embeddingModel:this.embeddingProfile.model};let n=e.queryAll(`SELECT COUNT(DISTINCT sourcePath) AS n FROM knowledge`),r=e.queryAll(`SELECT contentType, COUNT(*) AS n FROM knowledge GROUP BY contentType`),i=e.queryAll(`SELECT MAX(indexedAt) AS ts FROM knowledge`),a={};for(let e of r)a[e.contentType]=e.n;return{totalRecords:t,totalFiles:n[0]?.n??0,contentTypeBreakdown:a,lastIndexedAt:i[0]?.ts??null,storeBackend:`sqlite-vec`,embeddingModel:this.embeddingProfile.model}}async listSourcePaths(){return this.getAdapter().queryAll(`SELECT DISTINCT sourcePath FROM knowledge ORDER BY sourcePath`).map(e=>e.sourcePath)}async createFtsIndex(){this.createFtsTable()}async dropTable(){return this.enqueueWrite(()=>this._dropTableImpl())}async _dropTableImpl(){let e=this.getAdapter();this.ftsEnabled&&e.exec(`DROP TABLE IF EXISTS knowledge_fts`),this.vectorEnabled&&this.dropVectorTables(),e.exec(`DROP TABLE IF EXISTS ${G}`),e.exec(`DROP TABLE IF EXISTS knowledge_tags`),e.exec(`DROP TABLE IF EXISTS knowledge`),e.flush(),this.createKnowledgeTable(),this.createKnowledgeTagsTable(),this.createFtsTable(),this.vectorEnabled&&this.ensureVecTable()}releaseMemory(){if(this.adapter)try{this.adapter.exec(`PRAGMA shrink_memory`),this.adapter.exec(`PRAGMA wal_checkpoint(TRUNCATE)`)}catch{}}onBeforeClose(e){this._onCloseHooks.push(e)}async close(e=5e3){for(let e of this._onCloseHooks)try{e()}catch{}this._onCloseHooks.length=0,(this._priorityQueue.length>0||this._normalQueue.length>0||this._draining)&&(this._drain(),await new Promise(t=>{let n=setTimeout(()=>{W.warn(`SqliteVecStore.close() timed out waiting for queue drain — force closing`),t(!0)},e);this._closeWaiter={resolve:()=>{clearTimeout(n),t(!1)},reject:()=>{clearTimeout(n),t(!1)}}})&&(this._priorityQueue.length=0,this._normalQueue.length=0)),this.adapter&&!this.externalAdapter&&this.adapter.close(),this.adapter=null}getAdapter(){if(!this.adapter)throw Error(`SqliteVecStore: not initialized — call initialize() first`);return this.adapter}runAdaptiveVectorSearch(e,t,n){let r=n?.limit??p.maxResults;if(r<=0)return[];let i=this.buildFilterSqlSuffix(n),a=this.buildVectorSearchPlan(r,i.profile),o=a.initialCandidateLimit,s=this.queryVectorRows(e,t,i,o,r);for(;a.hasFilters&&s.length<r&&o<a.maxCandidateLimit;)o=Math.min(a.maxCandidateLimit,Math.max(o+r,o*K.filteredRetryMultiplier)),s=this.queryVectorRows(e,t,i,o,r);return s}queryVectorRows(e,t,n,r,i){let a=this.getAdapter(),o=`
|
|
256
297
|
SELECT k.*, v.distance AS _distance
|
|
257
298
|
FROM (
|
|
258
299
|
SELECT knowledge_id, distance
|
|
@@ -265,11 +306,11 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
265
306
|
${n.sql}
|
|
266
307
|
ORDER BY v.distance ASC
|
|
267
308
|
LIMIT ?
|
|
268
|
-
`;return a.queryAll(o,[t,r,...n.params,i])}buildVectorSearchPlan(e,t){let n=Math.max(1,e*
|
|
309
|
+
`;return a.queryAll(o,[t,r,...n.params,i])}buildVectorSearchPlan(e,t){let n=Math.max(1,e*K.baseOverfetchMultiplier);if(!t.hasFilters)return{hasFilters:!1,initialCandidateLimit:n,maxCandidateLimit:n};let r=Math.max(0,t.filterCount-1),i=K.filteredOverfetchMultiplier+r*K.additionalFilterMultiplier+(t.tagCount>0?K.tagFilterMultiplier:0),a=Math.min(K.maxCandidateLimit,Math.max(e*i,K.minFilteredCandidateLimit));return{hasFilters:!0,initialCandidateLimit:a,maxCandidateLimit:Math.min(K.maxCandidateLimit,Math.max(a*K.maxExpansionFactor,e*K.filteredOverfetchMultiplier))}}rowsToSearchResults(e,t,n){return e.map(e=>({record:this.fromRow(e),score:1-(e._distance??1)})).filter(e=>e.score>=t).slice(0,n)}buildFilterSqlSuffix(e,t=!1){if(!e)return{sql:``,params:[],profile:{filterCount:0,hasFilters:!1,tagCount:0}};let n=[],r=[],i=0,a=0;if(e.contentType&&(n.push(`k.contentType = ?`),r.push(e.contentType),i++),e.sourceType){let t=ee(e.sourceType);t.length>0&&(n.push(`k.contentType IN (${t.map(()=>`?`).join(`, `)})`),r.push(...t),i++)}if(e.origin&&(n.push(`k.origin = ?`),r.push(e.origin),i++),e.category&&(n.push(`k.category = ?`),r.push(e.category),i++),e.tags&&e.tags.length>0){let t=e.tags.map(()=>`?`).join(`, `);n.push(`EXISTS (SELECT 1 FROM knowledge_tags kt WHERE kt.knowledge_id = k.id AND kt.tag IN (${t}))`),r.push(...e.tags),i++,a=e.tags.length}if(n.length===0)return{sql:``,params:[],profile:{filterCount:0,hasFilters:!1,tagCount:0}};let o=n.join(` AND `);return{sql:t?`AND ${o}`:`WHERE ${o}`,params:r,profile:{filterCount:i,hasFilters:!0,tagCount:a}}}fromRow(e){return{id:e.id,content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath||void 0,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,contentHash:e.content_hash||void 0,indexedAt:e.indexedAt,origin:e.origin,tags:Pe(e.tags),category:e.category||void 0,version:e.version}}};function Ve(e){let t=e.replace(/["'()*:^-]/g,` `).trim();return t?t.split(/\s+/).filter(e=>e.length>0).map(e=>`"${e}"`).join(` OR `):`""`}function He(e){return e==null||Number.isNaN(e)?0:1-Math.exp(-Math.abs(e)/5)}function q(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`,n=new Date(t);return Number.isNaN(n.getTime())?t:n.toISOString()}function J(e){return`queryAll`in e&&`run`in e}function Ue(e){return{get(t){return e.queryAll(`SELECT key, value, updated_at AS updatedAt FROM stash WHERE key = ?`,[t])[0]},set(t,n){e.run(`INSERT INTO stash (key, value)
|
|
269
310
|
VALUES (?, ?)
|
|
270
311
|
ON CONFLICT(key) DO UPDATE SET
|
|
271
312
|
value = excluded.value,
|
|
272
|
-
updated_at = datetime('now')`,[t,n])},list(){return e.queryAll(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`)},has(t){return e.queryAll(`SELECT 1 AS present FROM stash WHERE key = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM stash WHERE key = ?`,[t])},clear(){e.run(`DELETE FROM stash`)}}}function
|
|
313
|
+
updated_at = datetime('now')`,[t,n])},list(){return e.queryAll(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`)},has(t){return e.queryAll(`SELECT 1 AS present FROM stash WHERE key = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM stash WHERE key = ?`,[t])},clear(){e.run(`DELETE FROM stash`)}}}function We(e){return{save(t,n,r,i){e.run(`INSERT INTO checkpoints (id, label, data, notes)
|
|
273
314
|
VALUES (?, ?, ?, ?)
|
|
274
315
|
ON CONFLICT(id) DO UPDATE SET
|
|
275
316
|
label = excluded.label,
|
|
@@ -296,7 +337,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
296
337
|
ORDER BY created_at DESC, id DESC
|
|
297
338
|
LIMIT 1`;return e.queryAll(r,n)[0]},has(t){return e.queryAll(`SELECT 1 AS present FROM checkpoints WHERE id = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM checkpoints WHERE id = ?`,[t])},gc(t=10,n){let r=e.queryAll(`SELECT id, label, notes, created_at AS createdAt
|
|
298
339
|
FROM checkpoints
|
|
299
|
-
ORDER BY label, created_at DESC, id DESC`),i=n===void 0?void 0:Date.now()-n*864e5,a=new Map;for(let e of r){let t=a.get(e.label);t?t.push(e):a.set(e.label,[e])}let o=[];for(let e of a.values())e.forEach((e,n)=>{let r=Date.parse(e.createdAt);n<t&&!(i!==void 0&&!Number.isNaN(r)&&r<i)||o.push(e.id)});for(let t of o)e.run(`DELETE FROM checkpoints WHERE id = ?`,[t]);return o.length}}}function
|
|
340
|
+
ORDER BY label, created_at DESC, id DESC`),i=n===void 0?void 0:Date.now()-n*864e5,a=new Map;for(let e of r){let t=a.get(e.label);t?t.push(e):a.set(e.label,[e])}let o=[];for(let e of a.values())e.forEach((e,n)=>{let r=Date.parse(e.createdAt);n<t&&!(i!==void 0&&!Number.isNaN(r)&&r<i)||o.push(e.id)});for(let t of o)e.run(`DELETE FROM checkpoints WHERE id = ?`,[t]);return o.length}}}function Ge(e){return{create(t,n){e.run(`INSERT INTO sessions (session_id, metadata)
|
|
300
341
|
VALUES (?, ?)
|
|
301
342
|
ON CONFLICT(session_id) DO UPDATE SET
|
|
302
343
|
last_activity = datetime('now'),
|
|
@@ -312,7 +353,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
312
353
|
ORDER BY created_at, session_id`)},has(t){return e.queryAll(`SELECT 1 AS present FROM sessions WHERE session_id = ?`,[t]).length>0},delete(t){e.run(`DELETE FROM sessions WHERE session_id = ?`,[t])},deleteStale(t){let n=`-${Math.max(0,t)} minutes`,r=e.queryAll(`SELECT COUNT(*) AS count
|
|
313
354
|
FROM sessions
|
|
314
355
|
WHERE last_activity < datetime('now', ?)`,[n])[0]?.count??0;return r>0&&e.run(`DELETE FROM sessions
|
|
315
|
-
WHERE last_activity < datetime('now', ?)`,[n]),r}}}function
|
|
356
|
+
WHERE last_activity < datetime('now', ?)`,[n]),r}}}function Ke(e){return{post(t,n,r,i,a=300){return e.run(`INSERT INTO signals (workspace, key, value, agent, ttl_seconds, expires_at)
|
|
316
357
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' seconds'))`,[t,n,r,i??null,a,a]),e.queryAll(`SELECT last_insert_rowid() AS id`)[0]?.id??0},get(t,n){return e.queryAll(`SELECT id,
|
|
317
358
|
workspace,
|
|
318
359
|
key,
|
|
@@ -334,7 +375,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
334
375
|
WHERE workspace = ?
|
|
335
376
|
ORDER BY created_at ASC, id ASC`,[t])},clear(t,n){let r=n===void 0?e.queryAll(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ?`,[t])[0]?.count??0:e.queryAll(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ? AND key = ?`,[t,n])[0]?.count??0;return r>0&&(n===void 0?e.run(`DELETE FROM signals WHERE workspace = ?`,[t]):e.run(`DELETE FROM signals WHERE workspace = ? AND key = ?`,[t,n])),r},cleanExpired(){let t=e.queryAll(`SELECT COUNT(*) AS count
|
|
336
377
|
FROM signals
|
|
337
|
-
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM signals WHERE expires_at <= datetime('now')`),t}}}function
|
|
378
|
+
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM signals WHERE expires_at <= datetime('now')`),t}}}function qe(e){return{upsert(t,n,r,i,a=10){e.run(`INSERT INTO leases (resource, holder, intent, workspace, ttl_minutes, expires_at)
|
|
338
379
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' minutes'))
|
|
339
380
|
ON CONFLICT(workspace, resource) DO UPDATE SET
|
|
340
381
|
holder = excluded.holder,
|
|
@@ -359,7 +400,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
359
400
|
WHERE workspace = ?
|
|
360
401
|
ORDER BY acquired_at ASC, resource ASC`,[t])},delete(t,n){e.run(`DELETE FROM leases WHERE resource = ? AND workspace = ?`,[t,n])},cleanExpired(){let t=e.queryAll(`SELECT COUNT(*) AS count
|
|
361
402
|
FROM leases
|
|
362
|
-
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM leases WHERE expires_at <= datetime('now')`),t}}}function
|
|
403
|
+
WHERE expires_at <= datetime('now')`)[0]?.count??0;return t>0&&e.run(`DELETE FROM leases WHERE expires_at <= datetime('now')`),t}}}function Je(e){return{create(t,n){e.run(`INSERT INTO memory_meta (entry_id, tier)
|
|
363
404
|
VALUES (?, ?)
|
|
364
405
|
ON CONFLICT(entry_id) DO NOTHING`,[t,n??`working`])},get(t){return e.queryAll(`SELECT entry_id AS entryId,
|
|
365
406
|
tier,
|
|
@@ -395,11 +436,11 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
395
436
|
ORDER BY retention_score ASC,
|
|
396
437
|
COALESCE(last_accessed_at, created_at) ASC,
|
|
397
438
|
entry_id ASC
|
|
398
|
-
${a}`,r)}}}function
|
|
439
|
+
${a}`,r)}}}function Ye(e){let t=e.prepare(`SELECT key, value, updated_at AS updatedAt FROM stash WHERE key = ?`),n=e.prepare(`INSERT INTO stash (key, value)
|
|
399
440
|
VALUES (?, ?)
|
|
400
441
|
ON CONFLICT(key) DO UPDATE SET
|
|
401
442
|
value = excluded.value,
|
|
402
|
-
updated_at = datetime('now')`),r=e.prepare(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`),i=e.prepare(`SELECT 1 AS present FROM stash WHERE key = ?`),a=e.prepare(`DELETE FROM stash WHERE key = ?`),o=e.prepare(`DELETE FROM stash`);return{get(e){return t.get(e)},set(e,t){n.run(e,t)},list(){return r.all()},has(e){return i.get(e)!==void 0},delete(e){a.run(e)},clear(){o.run()}}}function
|
|
443
|
+
updated_at = datetime('now')`),r=e.prepare(`SELECT key, value, updated_at AS updatedAt FROM stash ORDER BY key`),i=e.prepare(`SELECT 1 AS present FROM stash WHERE key = ?`),a=e.prepare(`DELETE FROM stash WHERE key = ?`),o=e.prepare(`DELETE FROM stash`);return{get(e){return t.get(e)},set(e,t){n.run(e,t)},list(){return r.all()},has(e){return i.get(e)!==void 0},delete(e){a.run(e)},clear(){o.run()}}}function Xe(e){let t=e.prepare(`INSERT INTO checkpoints (id, label, data, notes)
|
|
403
444
|
VALUES (?, ?, ?, ?)
|
|
404
445
|
ON CONFLICT(id) DO UPDATE SET
|
|
405
446
|
label = excluded.label,
|
|
@@ -426,7 +467,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
426
467
|
ORDER BY created_at DESC, id DESC
|
|
427
468
|
LIMIT 1`),l=e.prepare(`SELECT 1 AS present FROM checkpoints WHERE id = ?`),u=e.prepare(`DELETE FROM checkpoints WHERE id = ?`),d=e.prepare(`SELECT id, label, notes, created_at AS createdAt
|
|
428
469
|
FROM checkpoints
|
|
429
|
-
ORDER BY label, created_at DESC, id DESC`);return{save(e,n,r,i){t.run(e,n,r,i??null)},get(e){return n.get(e)},list(e,t){return e!==void 0&&t!==void 0?o.all(e,t):e===void 0?t===void 0?r.all():i.all(t):a.all(e)},latest(e){return e===void 0?s.get():c.get(e)},has(e){return l.get(e)!==void 0},delete(e){u.run(e)},gc(e=10,t){let n=d.all(),r=t===void 0?void 0:Date.now()-t*864e5,i=new Map;for(let e of n){let t=i.get(e.label);t?t.push(e):i.set(e.label,[e])}let a=[];for(let t of i.values())t.forEach((t,n)=>{let i=Date.parse(t.createdAt);n<e&&!(r!==void 0&&!Number.isNaN(i)&&i<r)||a.push(t.id)});for(let e of a)u.run(e);return a.length}}}function
|
|
470
|
+
ORDER BY label, created_at DESC, id DESC`);return{save(e,n,r,i){t.run(e,n,r,i??null)},get(e){return n.get(e)},list(e,t){return e!==void 0&&t!==void 0?o.all(e,t):e===void 0?t===void 0?r.all():i.all(t):a.all(e)},latest(e){return e===void 0?s.get():c.get(e)},has(e){return l.get(e)!==void 0},delete(e){u.run(e)},gc(e=10,t){let n=d.all(),r=t===void 0?void 0:Date.now()-t*864e5,i=new Map;for(let e of n){let t=i.get(e.label);t?t.push(e):i.set(e.label,[e])}let a=[];for(let t of i.values())t.forEach((t,n)=>{let i=Date.parse(t.createdAt);n<e&&!(r!==void 0&&!Number.isNaN(i)&&i<r)||a.push(t.id)});for(let e of a)u.run(e);return a.length}}}function Ze(e){let t=e.prepare(`INSERT INTO sessions (session_id, metadata)
|
|
430
471
|
VALUES (?, ?)
|
|
431
472
|
ON CONFLICT(session_id) DO UPDATE SET
|
|
432
473
|
last_activity = datetime('now'),
|
|
@@ -442,7 +483,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
442
483
|
ORDER BY created_at, session_id`),a=e.prepare(`SELECT 1 AS present FROM sessions WHERE session_id = ?`),o=e.prepare(`DELETE FROM sessions WHERE session_id = ?`),s=e.prepare(`SELECT COUNT(*) AS count
|
|
443
484
|
FROM sessions
|
|
444
485
|
WHERE last_activity < datetime('now', ?)`),c=e.prepare(`DELETE FROM sessions
|
|
445
|
-
WHERE last_activity < datetime('now', ?)`);return{create(e,n){t.run(e,n??null)},touch(e){n.run(e)},get(e){return r.get(e)},list(){return i.all()},has(e){return a.get(e)!==void 0},delete(e){o.run(e)},deleteStale(e){let t=`-${Math.max(0,e)} minutes`,n=s.get(t)?.count??0;return n>0&&c.run(t),n}}}function
|
|
486
|
+
WHERE last_activity < datetime('now', ?)`);return{create(e,n){t.run(e,n??null)},touch(e){n.run(e)},get(e){return r.get(e)},list(){return i.all()},has(e){return a.get(e)!==void 0},delete(e){o.run(e)},deleteStale(e){let t=`-${Math.max(0,e)} minutes`,n=s.get(t)?.count??0;return n>0&&c.run(t),n}}}function Qe(e){let t=e.prepare(`INSERT INTO signals (workspace, key, value, agent, ttl_seconds, expires_at)
|
|
446
487
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' seconds'))`),n=e.prepare(`SELECT id,
|
|
447
488
|
workspace,
|
|
448
489
|
key,
|
|
@@ -464,7 +505,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
464
505
|
WHERE workspace = ?
|
|
465
506
|
ORDER BY created_at ASC, id ASC`),i=e.prepare(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ?`),a=e.prepare(`SELECT COUNT(*) AS count FROM signals WHERE workspace = ? AND key = ?`),o=e.prepare(`DELETE FROM signals WHERE workspace = ?`),s=e.prepare(`DELETE FROM signals WHERE workspace = ? AND key = ?`),c=e.prepare(`SELECT COUNT(*) AS count
|
|
466
507
|
FROM signals
|
|
467
|
-
WHERE expires_at <= datetime('now')`),l=e.prepare(`DELETE FROM signals WHERE expires_at <= datetime('now')`);return{post(e,n,r,i,a=300){let o=t.run(e,n,r,i??null,a,a);return Number(o.lastInsertRowid)},get(e,t){return n.all(e,t)},list(e){return r.all(e)},clear(e,t){let n=t===void 0?i.get(e)?.count??0:a.get(e,t)?.count??0;return n>0&&(t===void 0?o.run(e):s.run(e,t)),n},cleanExpired(){let e=c.get()?.count??0;return e>0&&l.run(),e}}}function
|
|
508
|
+
WHERE expires_at <= datetime('now')`),l=e.prepare(`DELETE FROM signals WHERE expires_at <= datetime('now')`);return{post(e,n,r,i,a=300){let o=t.run(e,n,r,i??null,a,a);return Number(o.lastInsertRowid)},get(e,t){return n.all(e,t)},list(e){return r.all(e)},clear(e,t){let n=t===void 0?i.get(e)?.count??0:a.get(e,t)?.count??0;return n>0&&(t===void 0?o.run(e):s.run(e,t)),n},cleanExpired(){let e=c.get()?.count??0;return e>0&&l.run(),e}}}function $e(e){let t=e.prepare(`INSERT INTO leases (resource, holder, intent, workspace, ttl_minutes, expires_at)
|
|
468
509
|
VALUES (?, ?, ?, ?, ?, datetime('now', '+' || ? || ' minutes'))
|
|
469
510
|
ON CONFLICT(workspace, resource) DO UPDATE SET
|
|
470
511
|
holder = excluded.holder,
|
|
@@ -489,7 +530,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
489
530
|
WHERE workspace = ?
|
|
490
531
|
ORDER BY acquired_at ASC, resource ASC`),i=e.prepare(`DELETE FROM leases WHERE resource = ? AND workspace = ?`),a=e.prepare(`SELECT COUNT(*) AS count
|
|
491
532
|
FROM leases
|
|
492
|
-
WHERE expires_at <= datetime('now')`),o=e.prepare(`DELETE FROM leases WHERE expires_at <= datetime('now')`);return{upsert(e,n,r,i,a=10){t.run(e,n,i??null,r,a,a)},get(e,t){return n.get(e,t)},list(e){return r.all(e)},delete(e,t){i.run(e,t)},cleanExpired(){let e=a.get()?.count??0;return e>0&&o.run(),e}}}function
|
|
533
|
+
WHERE expires_at <= datetime('now')`),o=e.prepare(`DELETE FROM leases WHERE expires_at <= datetime('now')`);return{upsert(e,n,r,i,a=10){t.run(e,n,i??null,r,a,a)},get(e,t){return n.get(e,t)},list(e){return r.all(e)},delete(e,t){i.run(e,t)},cleanExpired(){let e=a.get()?.count??0;return e>0&&o.run(),e}}}function et(e){let t=e.prepare(`INSERT INTO memory_meta (entry_id, tier)
|
|
493
534
|
VALUES (?, ?)
|
|
494
535
|
ON CONFLICT(entry_id) DO NOTHING`),n=e.prepare(`SELECT entry_id AS entryId,
|
|
495
536
|
tier,
|
|
@@ -604,7 +645,7 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
604
645
|
AND retention_score < ?
|
|
605
646
|
ORDER BY retention_score ASC,
|
|
606
647
|
COALESCE(last_accessed_at, created_at) ASC,
|
|
607
|
-
entry_id ASC`),
|
|
648
|
+
entry_id ASC`),h=e.prepare(`SELECT entry_id AS entryId,
|
|
608
649
|
tier,
|
|
609
650
|
retention_score AS retentionScore,
|
|
610
651
|
access_count AS accessCount,
|
|
@@ -619,4 +660,6 @@ import{createRequire as e}from"node:module";import{existsSync as t,mkdirSync as
|
|
|
619
660
|
ORDER BY retention_score ASC,
|
|
620
661
|
COALESCE(last_accessed_at, created_at) ASC,
|
|
621
662
|
entry_id ASC
|
|
622
|
-
LIMIT ?`);return{create(e,n){t.run(e,n??`working`)},get(e){return n.get(e)},touch(e){r.run(e)},updateScore(e,t){i.run(t,e)},updateConfidence(e,t){a.run(t,e)},updateTier(e,t){o.run(t,t,t,e)},setSuperseded(e,t){s.run(t,e)},list(e){return e?.tier!==void 0&&e?.belowScore!==void 0&&e?.limit!==void 0?
|
|
663
|
+
LIMIT ?`);return{create(e,n){t.run(e,n??`working`)},get(e){return n.get(e)},touch(e){r.run(e)},updateScore(e,t){i.run(t,e)},updateConfidence(e,t){a.run(t,e)},updateTier(e,t){o.run(t,t,t,e)},setSuperseded(e,t){s.run(t,e)},list(e){return e?.tier!==void 0&&e?.belowScore!==void 0&&e?.limit!==void 0?h.all(e.tier,e.belowScore,e.limit):e?.tier!==void 0&&e?.belowScore!==void 0?m.all(e.tier,e.belowScore):e?.tier!==void 0&&e?.limit!==void 0?d.all(e.tier,e.limit):e?.tier===void 0?e?.belowScore!==void 0&&e?.limit!==void 0?p.all(e.belowScore,e.limit):e?.belowScore===void 0?e?.limit===void 0?c.all():l.all(e.limit):f.all(e.belowScore):u.all(e.tier)}}}function tt(e){let t=J(e)?Ue(e):Ye(e),n=J(e)?Ke(e):Qe(e),r=J(e)?qe(e):$e(e),i=J(e)?Ge(e):Ze(e),a=J(e)?We(e):Xe(e),o=J(e)?Je(e):et(e);return{stashGet(e){return t.get(e)?.value},stashSet(e,n){t.set(e,n)},stashList(){return t.list()},stashDelete(e){return t.has(e)?(t.delete(e),!0):!1},stashClear(){t.clear()},signalPost(e,t,r,i,a){return n.post(e,t,r,i,a)},signalGet(e,t){return n.cleanExpired(),n.get(e,t).map(e=>({id:e.id,value:e.value,createdAt:q(e.createdAt),expiresAt:q(e.expiresAt),...e.agent?{agent:e.agent}:{}}))},signalList(e){return n.cleanExpired(),n.list(e).map(e=>({id:e.id,key:e.key,value:e.value,createdAt:q(e.createdAt),...e.agent?{agent:e.agent}:{}}))},signalClear(e,t){return n.cleanExpired(),n.clear(e,t)},signalCleanExpired(){return n.cleanExpired()},leaseAcquire(e,t,n,i,a){r.cleanExpired();let o=r.get(e,n);return o&&o.holder!==t?!1:(r.upsert(e,t,n,i??o?.intent??void 0,a),!0)},leaseRelease(e,t,n){r.cleanExpired();let i=r.get(e,n);return!i||i.holder!==t?!1:(r.delete(e,n),!0)},leaseGet(e,t){r.cleanExpired();let n=r.get(e,t);if(n)return{resource:n.resource,holder:n.holder,workspace:n.workspace,acquiredAt:q(n.acquiredAt),expiresAt:q(n.expiresAt),...n.intent?{intent:n.intent}:{}}},leaseList(e){return r.cleanExpired(),r.list(e).map(e=>({resource:e.resource,holder:e.holder,acquiredAt:q(e.acquiredAt),expiresAt:q(e.expiresAt),...e.intent?{intent:e.intent}:{}}))},leaseCleanExpired(){return r.cleanExpired()},sessionCreate(e,t){i.create(e,t?JSON.stringify(t):void 0)},sessionTouch(e){i.touch(e)},sessionGet(e){let t=i.get(e);if(t)return{sessionId:t.sessionId,createdAt:t.createdAt,lastActivity:t.lastActivity,...t.metadata?{metadata:t.metadata}:{}}},sessionList(){return i.list().map(e=>({sessionId:e.sessionId,createdAt:e.createdAt,lastActivity:e.lastActivity}))},sessionDelete(e){return i.has(e)?(i.delete(e),!0):!1},sessionDeleteStale(e){return i.deleteStale(e)},checkpointSave(e,t,n,r){a.save(e,t,n,r)},checkpointLoad(e){let t=a.get(e);if(t)return{id:t.id,label:t.label,data:t.data,createdAt:t.createdAt,...t.notes?{notes:t.notes}:{}}},checkpointList(e,t){return a.list(e,t).map(e=>({id:e.id,label:e.label,createdAt:e.createdAt,...e.notes?{notes:e.notes}:{}}))},checkpointLatest(e){let t=a.latest(e);if(t)return{id:t.id,label:t.label,data:t.data,createdAt:t.createdAt,...t.notes?{notes:t.notes}:{}}},checkpointDelete(e){return a.has(e)?(a.delete(e),!0):!1},checkpointDiff(e,t){let n=a.get(e),r=a.get(t);if(!(!n||!r))return{from:n.data,to:r.data}},checkpointHistory(e,t){return a.list(e,t).map(e=>({id:e.id,label:e.label,createdAt:e.createdAt,...e.notes?{notes:e.notes}:{}}))},checkpointGc(e,t){return a.gc(e,t)},memoryMetaCreate(e,t){o.create(e,t)},memoryMetaGet(e){return o.get(e)},memoryMetaTouch(e){o.touch(e)},memoryMetaUpdateScore(e,t){o.updateScore(e,t)},memoryMetaUpdateConfidence(e,t){o.updateConfidence(e,t)},memoryMetaUpdateTier(e,t){o.updateTier(e,t)},memoryMetaSetSuperseded(e,t){o.setSuperseded(e,t)},memoryMetaList(e){return o.list(e)}}}const Y=h(`driver-selector`),X=e(import.meta.url);var nt=class extends Error{code=`STORAGE_INITIALIZATION_FAILED`;failures;constructor(e){let t=e.map(e=>`[${e.code}] ${e.driver}: ${e.message}`).join(`; `);super(`All SQLite drivers failed to initialise (${e.length}): ${t}`),this.name=`StorageInitializationError`,this.failures=e}};function rt(e){let[t,n]=(e??process.versions.node).split(`.`),r=Number.parseInt(t??`0`,10);return r>22||r===22&&Number.parseInt(n??`0`,10)>=13}function Z(e,t,n){return{available:!1,failure:{driver:e,code:t,message:n}}}function Q(e){return{available:!0,capabilities:e}}function it(){try{try{let e=X(`sqlite-vec`);if(e.loadablePath&&typeof e.loadablePath==`string`&&t(e.loadablePath))return e.loadablePath}catch{}let e=c(X.resolve(`sqlite-vec/package.json`)),n={"win32-x64":`sqlite-vec-win32-x64.node`,"win32-arm64":`sqlite-vec-win32-arm64.node`,"darwin-x64":`sqlite-vec-darwin-x64.node`,"darwin-arm64":`sqlite-vec-darwin-arm64.node`,"linux-x64":`sqlite-vec-linux-x64.node`,"linux-arm64":`sqlite-vec-linux-arm64.node`}[`${process.platform}-${process.arch}`];if(n){let r=u(e,n);if(t(r))return r}let r=u(e,`sqlite-vec.node`);if(t(r))return r;let i=u(c(X.resolve(`sqlite-vec`)),`sqlite-vec.node`);return t(i)?i:null}catch{return null}}async function at(){if(!rt())return Z(`node-sqlite`,`NODE_VERSION_UNSUPPORTED`,`Node.js ${process.versions.node} < 22.13 — node:sqlite extension loading unavailable`);let e;try{e=(await import(`node:sqlite`)).DatabaseSync}catch(e){return Z(`node-sqlite`,`MODULE_NOT_AVAILABLE`,`node:sqlite not available: ${e instanceof Error?e.message:String(e)}`)}let t=new e(`:memory:`,{allowExtension:!0});try{try{t.enableLoadExtension(!0)}catch(e){return Z(`node-sqlite`,`EXTENSION_LOADING_DISABLED`,`enableLoadExtension failed: ${e instanceof Error?e.message:String(e)}`)}let e=it();if(!e)return Z(`node-sqlite`,`NATIVE_BINARY_UNAVAILABLE`,`Could not resolve sqlite-vec native binary path`);try{t.loadExtension(e)}catch(e){return Z(`node-sqlite`,`SQLITE_VEC_LOAD_FAILED`,`sqlite-vec loadExtension failed: ${e instanceof Error?e.message:String(e)}`)}try{let e=t.prepare(`SELECT vec_version() AS v`).get();if(!e||typeof e.v!=`string`)return Z(`node-sqlite`,`SQLITE_VEC_PROBE_FAILED`,`vec_version() returned empty result`);Y.debug(`node-sqlite: sqlite-vec ${e.v}`)}catch(e){return Z(`node-sqlite`,`SQLITE_VEC_PROBE_FAILED`,`vec_version() failed: ${e instanceof Error?e.message:String(e)}`)}try{if(t.exec(`CREATE TEMP TABLE _probe_v(v float32(3));
|
|
664
|
+
INSERT INTO _probe_v VALUES ('[1.0,2.0,3.0]'), ('[4.0,5.0,6.0]');`),t.prepare(`SELECT vec_distance_cosine(v, CAST(? AS float32(3))) AS d FROM _probe_v`).all([`[1.0,2.0,3.0]`]).length===0)return Z(`node-sqlite`,`SQLITE_VEC_PROBE_FAILED`,`Vector smoke test returned no rows`);Y.debug(`node-sqlite: vector smoke test passed`)}catch(e){return Z(`node-sqlite`,`SQLITE_VEC_PROBE_FAILED`,`Vector smoke test failed: ${e instanceof Error?e.message:String(e)}`)}}finally{try{t.enableLoadExtension(!1)}catch{}t.close()}return Y.info(`node:sqlite driver ready (sqlite-vec enabled)`),Q({vectorCapable:!0,persistentFile:!0,concurrentReaders:!0})}async function ot(){let e;try{e=X(`better-sqlite3`)}catch(e){return Z(`better-sqlite3`,`MODULE_NOT_AVAILABLE`,`better-sqlite3 not available: ${e instanceof Error?e.message:String(e)}`)}let t;try{t=new e(`:memory:`,{memory:!0})}catch(e){return Z(`better-sqlite3`,`DATABASE_OPEN_FAILED`,`Failed to open in-memory database: ${e instanceof Error?e.message:String(e)}`)}try{try{X(`sqlite-vec`).load(t)}catch(e){return Z(`better-sqlite3`,`SQLITE_VEC_LOAD_FAILED`,`sqlite-vec load failed: ${e instanceof Error?e.message:String(e)}`)}try{let e=t.prepare(`SELECT vec_version() AS v`).get();if(!e||typeof e.v!=`string`)return Z(`better-sqlite3`,`SQLITE_VEC_PROBE_FAILED`,`vec_version() returned empty result`);Y.debug(`better-sqlite3: sqlite-vec ${e.v}`)}catch(e){return Z(`better-sqlite3`,`SQLITE_VEC_PROBE_FAILED`,`vec_version() failed: ${e instanceof Error?e.message:String(e)}`)}try{if(t.exec(`CREATE TEMP TABLE _probe_v(v float32(3));
|
|
665
|
+
INSERT INTO _probe_v VALUES ('[1.0,2.0,3.0]'), ('[4.0,5.0,6.0]');`),t.prepare(`SELECT vec_distance_cosine(v, CAST(? AS float32(3))) AS d FROM _probe_v`).all([`[1.0,2.0,3.0]`]).length===0)return Z(`better-sqlite3`,`SQLITE_VEC_PROBE_FAILED`,`Vector smoke test returned no rows`);Y.debug(`better-sqlite3: vector smoke test passed`)}catch(e){return Z(`better-sqlite3`,`SQLITE_VEC_PROBE_FAILED`,`Vector smoke test failed: ${e instanceof Error?e.message:String(e)}`)}}finally{t.close()}return Y.info(`better-sqlite3 driver ready (sqlite-vec enabled)`),Q({vectorCapable:!0,persistentFile:!0,concurrentReaders:!0})}async function st(){let e;try{let t=await import(`sql.js`);e=t.default??t}catch(e){return Z(`sqljs`,`MODULE_NOT_AVAILABLE`,`sql.js module not available: ${e instanceof Error?e.message:String(e)}`)}let n;try{let e=c(X.resolve(`sql.js/package.json`)),r=u(e,`dist`,`sql-wasm.wasm`);t(r)&&(n=t=>t.endsWith(`.wasm`)?r:u(e,`dist`,t))}catch{}let r;try{r=await e(n?{locateFile:n}:void 0)}catch(e){let t=e instanceof Error?e.message:String(e);return t.includes(`wasm`)||t.includes(`WASM`)||t.includes(`WebAssembly`)?Z(`sqljs`,`WASM_INITIALIZATION_FAILED`,`sql.js WASM initialisation failed: ${t}`):Z(`sqljs`,`WASM_ASSET_NOT_FOUND`,`sql.js initialisation failed (WASM asset may be missing): ${t}`)}try{new r.Database().close()}catch(e){return Z(`sqljs`,`DATABASE_OPEN_FAILED`,`sql.js in-memory database failed: ${e instanceof Error?e.message:String(e)}`)}return Y.info(`sql.js driver ready (vector search disabled)`),Q({vectorCapable:!1,persistentFile:!0,concurrentReaders:!1})}async function ct(e){let t=e.driver??`auto`;if(t!==`auto`)return lt(t);let n=[];{let e=await at();if(e.available)return{kind:`node-sqlite`,capabilities:e.capabilities,failures:[]};e.failure&&n.push(e.failure)}{let e=await ot();if(e.available)return{kind:`better-sqlite3`,capabilities:e.capabilities,failures:n};e.failure&&n.push(e.failure)}{let e=await st();if(e.available)return{kind:`sqljs`,capabilities:e.capabilities,failures:n};e.failure&&n.push(e.failure)}throw new nt(n)}async function lt(e){let{kind:t,capabilities:n,failures:r}=await ut(e);if(!n)throw new nt(r);return{kind:t,capabilities:n,failures:r}}async function ut(e){let t=e;switch(e){case`node-sqlite`:{let e=await at();if(e.available)return{kind:t,capabilities:e.capabilities,failures:[]};let n=[];return e.failure&&n.push(e.failure),{kind:t,capabilities:null,failures:n}}case`better-sqlite3`:{let e=await ot();if(e.available)return{kind:t,capabilities:e.capabilities,failures:[]};let n=[];return e.failure&&n.push(e.failure),{kind:t,capabilities:null,failures:n}}case`sqljs`:{let e=await st();if(e.available)return{kind:t,capabilities:e.capabilities,failures:[]};let n=[];return e.failure&&n.push(e.failure),{kind:t,capabilities:null,failures:n}}default:throw Error(`Unreachable: unknown driver mode "${e}"`)}}const dt=e(import.meta.url);var ft=class{kind=`node-sqlite`;capabilities={vectorCapable:!0,persistentFile:!0,concurrentReaders:!0};db=null;getDb(){if(!this.db)throw Error(`NodeSqliteAdapter: database not opened`);return this.db}ensureOpen(){this.getDb()}async open(e){let r=c(e);r&&!t(r)&&n(r,{recursive:!0});let i;try{i=(await import(`node:sqlite`)).DatabaseSync}catch(e){throw Error(`node:sqlite unavailable (requires Node ≥22.13): ${e instanceof Error?e.message:String(e)}`)}this.db=new i(e,{allowExtension:!0,timeout:5e3});try{this.loadSqliteVec(),this.getDb().exec(`PRAGMA foreign_keys = ON`),this.getDb().exec(`PRAGMA journal_mode = WAL`),this.getDb().exec(`PRAGMA synchronous = NORMAL`),this.getDb().exec(`PRAGMA busy_timeout = 5000`)}finally{this.getDb().enableLoadExtension(!1)}}exec(e){this.ensureOpen(),this.getDb().exec(e)}pragma(e){this.ensureOpen(),this.getDb().exec(`PRAGMA ${e}`)}bindArgs(e){return e===void 0?[]:Array.isArray(e)?e:[e]}queryAll(e,t){return this.all(e,t)}get(e,t){this.ensureOpen();let n=this.getDb().prepare(e),r=this.bindArgs(t),i=r.length>0?n.get(...r):n.get();if(i!=null)return this.normalizeRow(i)}all(e,t){this.ensureOpen();let n=this.getDb().prepare(e),r=this.bindArgs(t);return(r.length>0?n.all(...r):n.all()).map(e=>this.normalizeRow(e))}run(e,t){this.ensureOpen();let n=this.getDb().prepare(e),r=this.bindArgs(t),i=r.length>0?n.run(...r):n.run();return{changes:i.changes,lastInsertRowid:i.lastInsertRowid}}transaction(e){this.ensureOpen(),this.getDb().exec(`BEGIN IMMEDIATE`);let t={exec:e=>{this.ensureOpen(),this.getDb().exec(e)},get:(e,t)=>{this.ensureOpen();let n=this.getDb().prepare(e),r=this.bindArgs(t),i=r.length>0?n.get(...r):n.get();if(i!=null)return this.normalizeRow(i)},all:(e,t)=>{this.ensureOpen();let n=this.getDb().prepare(e),r=this.bindArgs(t);return(r.length>0?n.all(...r):n.all()).map(e=>this.normalizeRow(e))},run:(e,t)=>{this.ensureOpen();let n=this.getDb().prepare(e),r=this.bindArgs(t),i=r.length>0?n.run(...r):n.run();return{changes:i.changes,lastInsertRowid:i.lastInsertRowid}}};try{let n=e(t);return this.getDb().exec(`COMMIT`),n}catch(e){try{this.getDb().exec(`ROLLBACK`)}catch{}throw e}}flush(){}async close(){this.db&&=(this.getDb().close(),null)}normalizeRow(e){if(typeof e!=`object`||!e||Array.isArray(e))return e;let t=e;for(let e of Object.keys(t)){let n=t[e];Buffer.isBuffer(n)&&(t[e]=new Uint8Array(n.buffer,n.byteOffset,n.byteLength))}return e}loadSqliteVec(){try{let e=c(dt.resolve(`sqlite-vec`)),t;try{t=dt(`sqlite-vec`).loadablePath}catch{}if(t||=this.probeExtensionBinary(e),!t)throw Error(`Could not locate sqlite-vec extension binary`);if(this.getDb().enableLoadExtension(!0),this.getDb().loadExtension(t),!this.getDb().prepare(`SELECT vec_version() AS version`).get()?.version)throw Error(`sqlite-vec loaded but vec_version() returned no data`);let n=new Float32Array([1,0,0]),r=new Float32Array([0,1,0]),i=this.db?.prepare(`SELECT vec_distance_cosine(?, ?) AS d`).get([n,r]);if(!i||typeof i.d!=`number`)throw Error(`sqlite-vec smoke test failed: unexpected result ${JSON.stringify(i)}`)}catch(e){console.warn(`[NodeSqliteAdapter] sqlite-vec loading failed, vector search disabled:`,e instanceof Error?e.message:String(e))}}probeExtensionBinary(e){let n=process.platform===`win32`?`.dll`:process.platform===`darwin`?`.dylib`:`.so`,r=[u(e,`vec0${n}`),u(e,`sqlite-vec${n}`),u(e,`libsqlite-vec${n}`)];for(let e of r)if(t(e))return e}};const $=h(`store-factory`);async function pt(e){if(e.adapter)return{adapter:e.adapter,selection:null};let t=e.sqliteDriver??process.env.AI_KIT_SQLITE_DRIVER??`auto`,n=e.allowFallback??process.env.AI_KIT_SQLITE_ALLOW_FALLBACK!==`false`,r;try{r=await ct({driver:t,databasePath:e.path})}catch(i){if(n&&t!==`auto`)$.warn(`Forced driver "${t}" failed — falling back to auto selection`),r=await ct({databasePath:e.path});else throw i}let i;switch(r.kind){case`node-sqlite`:i=new ft;break;case`better-sqlite3`:i=new O;break;case`sqljs`:i=new A;break;default:{let e=r.kind;throw Error(`Unknown driver kind: ${e}`)}}if($.info(`Storage backend: ${r.kind}`),r.failures.length>0){$.warn(`Fallback reasons:`);for(let e of r.failures)$.warn(` ${e.driver}: ${e.code} — ${e.message}`)}return{adapter:i,selection:r}}async function mt(e){switch(e.backend){case`lancedb`:{let{LanceStore:t}=await import(`./lance-store-B1Gim3h9.js`);return new t({path:e.path})}case`sqlite-vec`:{let{adapter:t}=await pt(e);return new Be({path:e.path,adapter:t,embeddingDim:e.embeddingDim,embeddingProfile:e.embeddingProfile,partition:e.partition})}default:{let t=e.backend;throw Error(`Unknown store backend: "${t}". Supported: lancedb, sqlite-vec`)}}}export{F as CONTROL_TABLES,Ae as SqliteGraphStore,Be as SqliteVecStore,v as allMigrations,ve as createSqlJsAdapter,N as createSqliteAdapter,tt as createStateStore,mt as createStore,be as getTablePartition,ke as migrateToSplitState,xe as readStatePartitionConfigFromEnv,I as resolveStatePartitionConfig,_ as runMigrations};
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"description": "Knowledge + vector + graph store (SQLite + sqlite-vec, LanceDB legacy)",
|
|
5
5
|
"private": true,
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=18.20.0"
|
|
8
|
+
},
|
|
6
9
|
"type": "module",
|
|
7
10
|
"main": "./dist/index.js",
|
|
8
11
|
"types": "./dist/index.d.ts",
|
|
@@ -18,8 +21,8 @@
|
|
|
18
21
|
},
|
|
19
22
|
"dependencies": {
|
|
20
23
|
"@lancedb/lancedb": "^0.x",
|
|
21
|
-
"sql.js": "^1.
|
|
22
|
-
"sqlite-vec": "
|
|
24
|
+
"sql.js": "^1.10.0",
|
|
25
|
+
"sqlite-vec": "0.1.9"
|
|
23
26
|
},
|
|
24
27
|
"optionalDependencies": {
|
|
25
28
|
"better-sqlite3": "^12.x"
|