@vpxa/aikit 0.1.82 → 0.1.84
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/core/dist/index.d.ts +13 -1
- package/packages/core/dist/index.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{server-DyCYX0nU.js → server-CRBcgUPU.js} +138 -138
- package/packages/store/dist/index.d.ts +50 -4
- package/packages/store/dist/index.js +12 -12
- package/packages/tools/dist/index.d.ts +8 -10
- package/packages/tools/dist/index.js +70 -62
- package/scaffold/dist/definitions/bodies.mjs +1 -1
- package/scaffold/dist/definitions/skills.mjs +1 -1
|
@@ -251,18 +251,64 @@ declare class LanceStore implements IKnowledgeStore {
|
|
|
251
251
|
private fromLanceRecord;
|
|
252
252
|
}
|
|
253
253
|
//#endregion
|
|
254
|
+
//#region packages/store/src/sqlite-adapter.d.ts
|
|
255
|
+
/**
|
|
256
|
+
* SQLite adapter abstraction — allows swapping between better-sqlite3 (native)
|
|
257
|
+
* and sql.js (WASM) without changing consumer code.
|
|
258
|
+
*
|
|
259
|
+
* Primary adapter is configurable; the other serves as automatic fallback
|
|
260
|
+
* when the primary fails to load (e.g. native binary missing on the platform).
|
|
261
|
+
*/
|
|
262
|
+
type SqliteAdapterType = 'better-sqlite3' | 'sql.js';
|
|
263
|
+
interface ISqliteAdapter {
|
|
264
|
+
/** Which adapter implementation is active */
|
|
265
|
+
readonly type: SqliteAdapterType;
|
|
266
|
+
/** Open or create the database at the given file path */
|
|
267
|
+
open(dbPath: string): Promise<void>;
|
|
268
|
+
/** Execute DDL or multi-statement SQL (CREATE TABLE, BEGIN, COMMIT, etc.) */
|
|
269
|
+
exec(sql: string): void;
|
|
270
|
+
/** Set a PRAGMA value */
|
|
271
|
+
pragma(pragma: string): void;
|
|
272
|
+
/** Run a parameterized SELECT, return all rows */
|
|
273
|
+
queryAll<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
|
|
274
|
+
/** Run a parameterized INSERT/UPDATE/DELETE */
|
|
275
|
+
run(sql: string, params?: unknown[]): void;
|
|
276
|
+
/** Flush to disk — no-op for file-backed engines, required for in-memory engines */
|
|
277
|
+
flush(): void;
|
|
278
|
+
/** Close the database connection */
|
|
279
|
+
close(): void;
|
|
280
|
+
}
|
|
281
|
+
interface SqliteAdapterOptions {
|
|
282
|
+
/** Which adapter to try first. Default: 'better-sqlite3' (lower memory usage) */
|
|
283
|
+
primary?: SqliteAdapterType;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Create a SQLite adapter with automatic fallback.
|
|
287
|
+
*
|
|
288
|
+
* Tries the primary adapter first; if it fails to load (missing native binary,
|
|
289
|
+
* unsupported platform, etc.), falls back to the other adapter transparently.
|
|
290
|
+
*/
|
|
291
|
+
declare function createSqliteAdapter(dbPath: string, options?: SqliteAdapterOptions): Promise<ISqliteAdapter>;
|
|
292
|
+
//#endregion
|
|
254
293
|
//#region packages/store/src/sqlite-graph-store.d.ts
|
|
255
294
|
declare class SqliteGraphStore implements IGraphStore {
|
|
256
|
-
private
|
|
295
|
+
private adapter;
|
|
257
296
|
private readonly dbPath;
|
|
297
|
+
private readonly adapterOptions?;
|
|
258
298
|
constructor(options?: {
|
|
259
299
|
path?: string;
|
|
300
|
+
sqliteAdapter?: SqliteAdapterOptions;
|
|
260
301
|
});
|
|
261
302
|
initialize(): Promise<void>;
|
|
262
|
-
private
|
|
303
|
+
private configureAdapter;
|
|
263
304
|
private createTables;
|
|
264
305
|
private migrateSchema;
|
|
265
|
-
private
|
|
306
|
+
private getAdapter;
|
|
307
|
+
/**
|
|
308
|
+
* Ensure the adapter is open, lazily re-opening after close().
|
|
309
|
+
* Must be called from any public async method that may be invoked after close().
|
|
310
|
+
*/
|
|
311
|
+
private ensureOpen;
|
|
266
312
|
private query;
|
|
267
313
|
private run;
|
|
268
314
|
upsertNode(node: GraphNode): Promise<void>;
|
|
@@ -309,4 +355,4 @@ interface StoreConfig {
|
|
|
309
355
|
}
|
|
310
356
|
declare function createStore(config: StoreConfig): Promise<IKnowledgeStore>;
|
|
311
357
|
//#endregion
|
|
312
|
-
export { type DepthGroupedResult, type GraphEdge, type GraphNode, type GraphStats, type GraphTraversalOptions, type GraphTraversalResult, type GraphValidationResult, type IGraphStore, type IKnowledgeStore, LanceStore, type ProcessInfo, type SearchOptions, SqliteGraphStore, type StoreBackend, type StoreConfig, type Symbol360, createStore };
|
|
358
|
+
export { type DepthGroupedResult, type GraphEdge, type GraphNode, type GraphStats, type GraphTraversalOptions, type GraphTraversalResult, type GraphValidationResult, type IGraphStore, type IKnowledgeStore, type ISqliteAdapter, LanceStore, type ProcessInfo, type SearchOptions, type SqliteAdapterOptions, type SqliteAdapterType, SqliteGraphStore, type StoreBackend, type StoreConfig, type Symbol360, createSqliteAdapter, createStore };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../../core/dist/index.js";import{existsSync as n,mkdirSync as r}from"node:fs";import{dirname as
|
|
1
|
+
import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../../core/dist/index.js";import{existsSync as n,mkdirSync as r,readFileSync as i,writeFileSync as a}from"node:fs";import{dirname as o,join as s}from"node:path";var c=class{type=`better-sqlite3`;db=null;async open(e){let t=(await import(`better-sqlite3`)).default;this.db=new t(e)}exec(e){this.getDb().exec(e)}pragma(e){this.getDb().pragma(e)}queryAll(e,t=[]){return this.getDb().prepare(e).all(...t)}run(e,t=[]){this.getDb().prepare(e).run(...t)}flush(){}close(){this.db&&=(this.db.close(),null)}getDb(){if(!this.db)throw Error(`BetterSqliteAdapter: database not opened`);return this.db}},l=class{type=`sql.js`;db=null;dbPath=``;dirty=!1;inTransaction=!1;async open(e){this.dbPath=e;let t=(await import(`sql.js`)).default,r=await t();if(n(e)){let t=i(e);this.db=new r.Database(t)}else this.db=new r.Database}exec(e){let t=e.trimStart().toUpperCase();t.startsWith(`BEGIN`)?this.inTransaction=!0:(t.startsWith(`COMMIT`)||t.startsWith(`ROLLBACK`))&&(this.inTransaction=!1),this.getDb().run(e),this.dirty=!0}pragma(e){this.getDb().exec(`PRAGMA ${e}`)}queryAll(e,t=[]){let n=this.getDb().prepare(e);t.length>0&&n.bind(t);let r=[];for(;n.step();)r.push(n.getAsObject());return n.free(),r}run(e,t=[]){let n=this.getDb(),r=e.trimStart().toUpperCase(),i=!this.inTransaction&&(r.startsWith(`INSERT`)||r.startsWith(`UPDATE`));if(i&&n.run(`SAVEPOINT fk_check`),t.length>0){let r=n.prepare(e);try{r.bind(t),r.step()}finally{r.free()}}else n.run(e);if(i){if(n.exec(`PRAGMA foreign_key_check`).length>0)throw n.run(`ROLLBACK TO fk_check`),n.run(`RELEASE fk_check`),Error(`FOREIGN KEY constraint failed`);n.run(`RELEASE fk_check`)}this.dirty=!0}flush(){if(!this.dirty||!this.db)return;let e=this.db.export();a(this.dbPath,Buffer.from(e)),this.dirty=!1}close(){this.db&&=(this.flush(),this.db.close(),null)}getDb(){if(!this.db)throw Error(`SqlJsAdapter: database not opened`);return this.db}};async function u(e,t){let n=t?.primary??`better-sqlite3`,r=[n,n===`better-sqlite3`?`sql.js`:`better-sqlite3`];for(let t of r)try{let r=t===`better-sqlite3`?new c:new l;return await r.open(e),t!==n&&console.error(`[aikit] SQLite adapter: primary "${n}" unavailable, using fallback "${t}"`),r}catch(e){let n=e instanceof Error?e.message:String(e);console.error(`[aikit] SQLite adapter "${t}" failed to load: ${n}`)}throw Error(`[aikit] No SQLite adapter available. Tried: ${r.join(`, `)}. Install either better-sqlite3 or sql.js.`)}var d=class{adapter=null;dbPath;adapterOptions;constructor(e){let n=e?.path??t.data;this.dbPath=s(n,`graph.db`),this.adapterOptions=e?.sqliteAdapter}async initialize(){let e=o(this.dbPath);n(e)||r(e,{recursive:!0}),this.adapter=await u(this.dbPath,this.adapterOptions),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(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS nodes (
|
|
3
3
|
id TEXT PRIMARY KEY,
|
|
4
4
|
type TEXT NOT NULL,
|
|
@@ -39,37 +39,37 @@ import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../..
|
|
|
39
39
|
FOREIGN KEY (process_id) REFERENCES processes(id) ON DELETE CASCADE,
|
|
40
40
|
FOREIGN KEY (node_id) REFERENCES nodes(id) ON DELETE CASCADE
|
|
41
41
|
)
|
|
42
|
-
`),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)`)}
|
|
42
|
+
`),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(){this.adapter||(this.adapter=await u(this.dbPath,this.adapterOptions),this.configureAdapter(this.adapter))}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)
|
|
43
43
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
44
44
|
ON CONFLICT(id) DO UPDATE SET
|
|
45
45
|
type = excluded.type, name = excluded.name, properties = excluded.properties,
|
|
46
46
|
source_record_id = excluded.source_record_id, source_path = excluded.source_path,
|
|
47
|
-
community = excluded.community`,[e.id,e.type,e.name,JSON.stringify(e.properties),e.sourceRecordId??null,e.sourcePath??null,e.createdAt??new Date().toISOString(),e.community??null])}async upsertEdge(e){this.run(`INSERT INTO edges (id, from_id, to_id, type, weight, confidence, properties)
|
|
47
|
+
community = excluded.community`,[e.id,e.type,e.name,JSON.stringify(e.properties),e.sourceRecordId??null,e.sourcePath??null,e.createdAt??new Date().toISOString(),e.community??null]),this.getAdapter().flush()}async upsertEdge(e){await this.ensureOpen(),this.run(`INSERT INTO edges (id, from_id, to_id, type, weight, confidence, properties)
|
|
48
48
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
49
49
|
ON CONFLICT(id) DO UPDATE SET
|
|
50
50
|
from_id = excluded.from_id, to_id = excluded.to_id,
|
|
51
|
-
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[e.id,e.fromId,e.toId,e.type,e.weight??1,e.confidence??1,JSON.stringify(e.properties??{})])}async upsertNodes(e){if(e.length===0)return;let t=this.
|
|
51
|
+
type = excluded.type, weight = excluded.weight, confidence = excluded.confidence, properties = excluded.properties`,[e.id,e.fromId,e.toId,e.type,e.weight??1,e.confidence??1,JSON.stringify(e.properties??{})]),this.getAdapter().flush()}async upsertNodes(e){if(e.length===0)return;await this.ensureOpen();let t=this.getAdapter();t.exec(`BEGIN TRANSACTION`);try{for(let t of e)this.run(`INSERT INTO nodes (id, type, name, properties, source_record_id, source_path, created_at, community)
|
|
52
52
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
53
53
|
ON CONFLICT(id) DO UPDATE SET
|
|
54
54
|
type = excluded.type, name = excluded.name, properties = excluded.properties,
|
|
55
55
|
source_record_id = excluded.source_record_id, source_path = excluded.source_path,
|
|
56
|
-
community = excluded.community`,[t.id,t.type,t.name,JSON.stringify(t.properties),t.sourceRecordId??null,t.sourcePath??null,t.createdAt??new Date().toISOString(),t.community??null]);t.exec(`COMMIT`)}catch(e){throw t.exec(`ROLLBACK`),e}}async upsertEdges(e){if(e.length===0)return;let t=this.
|
|
56
|
+
community = excluded.community`,[t.id,t.type,t.name,JSON.stringify(t.properties),t.sourceRecordId??null,t.sourcePath??null,t.createdAt??new Date().toISOString(),t.community??null]);t.exec(`COMMIT`),t.flush()}catch(e){throw t.exec(`ROLLBACK`),e}}async upsertEdges(e){if(e.length===0)return;await this.ensureOpen();let t=this.getAdapter();t.pragma(`foreign_keys = OFF`),t.exec(`BEGIN TRANSACTION`);try{for(let t of e)this.run(`INSERT INTO edges (id, from_id, to_id, type, weight, confidence, properties)
|
|
57
57
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
58
58
|
ON CONFLICT(id) DO UPDATE SET
|
|
59
59
|
from_id = excluded.from_id, to_id = excluded.to_id,
|
|
60
|
-
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`)}catch(e){throw t.exec(`ROLLBACK`),e}finally{t.pragma(`foreign_keys = ON`)}}async getNode(e){let t=this.query(`SELECT * FROM nodes WHERE id = ?`,[e]);return t.length>0?
|
|
60
|
+
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?p(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=`
|
|
61
61
|
SELECT e.id AS edge_id, e.from_id, e.to_id, e.type AS edge_type, e.weight,
|
|
62
62
|
e.confidence AS edge_confidence, e.properties AS edge_props,
|
|
63
63
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
64
64
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
65
65
|
n.created_at AS node_created, n.community AS node_community
|
|
66
|
-
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(
|
|
66
|
+
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(g(e)))}if(n===`incoming`||n===`both`){let t=`
|
|
67
67
|
SELECT e.id AS edge_id, e.from_id, e.to_id, e.type AS edge_type, e.weight,
|
|
68
68
|
e.confidence AS edge_confidence, e.properties AS edge_props,
|
|
69
69
|
n.id AS node_id, n.type AS node_type, n.name AS node_name, n.properties AS node_props,
|
|
70
70
|
n.source_record_id AS node_src_rec, n.source_path AS node_src_path,
|
|
71
71
|
n.created_at AS node_created, n.community AS node_community
|
|
72
|
-
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(
|
|
72
|
+
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(g(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=>p(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=>m(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(),this.run(`DELETE FROM process_steps`),this.run(`DELETE FROM processes`),this.run(`DELETE FROM edges`),this.run(`DELETE FROM nodes`),this.getAdapter().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,
|
|
73
73
|
CASE
|
|
74
74
|
WHEN n1.id IS NULL THEN e.from_id
|
|
75
75
|
WHEN n2.id IS NULL THEN e.to_id
|
|
@@ -81,10 +81,10 @@ import{t as e}from"./lance-store-jdHZp-V4.js";import{AIKIT_PATHS as t}from"../..
|
|
|
81
81
|
FROM nodes n
|
|
82
82
|
LEFT JOIN edges e1 ON n.id = e1.from_id
|
|
83
83
|
LEFT JOIN edges e2 ON n.id = e2.to_id
|
|
84
|
-
WHERE e1.id IS NULL AND e2.id IS NULL`).map(e=>e.id);return{valid:t.length===0,orphanNodes:n,danglingEdges:t,stats:e}}async setNodeCommunity(e,t){this.run(`UPDATE nodes SET community = ? WHERE id = ?`,[t,e])}async detectCommunities(){let e=this.query(`SELECT id FROM nodes`),t=new Map;for(let n of e)t.set(n.id,n.id);for(let n=0;n<10;n++){let n=!1,r=new Map(t);for(let i of e){let e=this.query(`SELECT to_id AS neighbor_id FROM edges WHERE from_id = ?
|
|
84
|
+
WHERE e1.id IS NULL AND e2.id IS NULL`).map(e=>e.id);return{valid:t.length===0,orphanNodes:n,danglingEdges:t,stats:e}}async setNodeCommunity(e,t){await this.ensureOpen(),this.run(`UPDATE nodes SET community = ? WHERE id = ?`,[t,e]),this.getAdapter().flush()}async detectCommunities(){await this.ensureOpen();let e=this.query(`SELECT id FROM nodes`),t=new Map;for(let n of e)t.set(n.id,n.id);for(let n=0;n<10;n++){let n=!1,r=new Map(t);for(let i of e){let e=this.query(`SELECT to_id AS neighbor_id FROM edges WHERE from_id = ?
|
|
85
85
|
UNION
|
|
86
|
-
SELECT from_id AS neighbor_id FROM edges WHERE to_id = ?`,[i.id,i.id]),a=new Map,o=t.get(i.id)??i.id;a.set(o,1);for(let n of e){let e=t.get(n.neighbor_id)??n.neighbor_id;a.set(e,(a.get(e)??0)+1)}let s=o,c=0;for(let[e,t]of a)(t>c||t===c&&e<s)&&(c=t,s=e);o!==s&&(r.set(i.id,s),n=!0)}t.clear();for(let[e,n]of r)t.set(e,n);if(!n)break}let n=this.
|
|
87
|
-
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`)}catch(e){throw s.exec(`ROLLBACK`),e}return{id:a,entryNodeId:e,label:t,properties:{},steps:n,createdAt:o}}async getProcesses(e){let t;t=e?this.query(`SELECT DISTINCT p.id, p.entry_node_id, p.label, p.properties, p.created_at
|
|
86
|
+
SELECT from_id AS neighbor_id FROM edges WHERE to_id = ?`,[i.id,i.id]),a=new Map,o=t.get(i.id)??i.id;a.set(o,1);for(let n of e){let e=t.get(n.neighbor_id)??n.neighbor_id;a.set(e,(a.get(e)??0)+1)}let s=o,c=0;for(let[e,t]of a)(t>c||t===c&&e<s)&&(c=t,s=e);o!==s&&(r.set(i.id,s),n=!0)}t.clear();for(let[e,n]of r)t.set(e,n);if(!n)break}let n=this.getAdapter();n.exec(`BEGIN TRANSACTION`);try{for(let[e,n]of t)this.run(`UPDATE nodes SET community = ? WHERE id = ?`,[n,e]);n.exec(`COMMIT`),n.flush()}catch(e){throw n.exec(`ROLLBACK`),e}let r={};for(let[e,n]of t)r[n]||(r[n]=[]),r[n].push(e);return r}async traceProcess(e,t){await this.ensureOpen();let n=[],r=new Set,i=[e];for(;i.length>0;){let e=i.shift();if(!e||r.has(e))continue;r.add(e),n.push(e);let t=this.query(`SELECT to_id FROM edges WHERE from_id = ? AND type = 'calls'`,[e]);for(let e of t)r.has(e.to_id)||i.push(e.to_id)}let a=`proc_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,o=new Date().toISOString(),s=this.getAdapter();s.exec(`BEGIN TRANSACTION`);try{this.run(`INSERT INTO processes (id, entry_node_id, label, properties, created_at)
|
|
87
|
+
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
|
|
88
88
|
FROM processes p
|
|
89
89
|
JOIN process_steps ps ON p.id = ps.process_id
|
|
90
|
-
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:
|
|
90
|
+
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:f(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){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}}async close(){this.adapter&&=(this.adapter.close(),null)}};function f(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}function p(e){return{id:e.id,type:e.type,name:e.name,properties:f(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 m(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:f(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:f(e.edge_props??`{}`)}}function g(e){return{id:e.node_id,type:e.node_type,name:e.node_name,properties:f(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}}async function _(e){switch(e.backend){case`lancedb`:{let{LanceStore:t}=await import(`./lance-store-jdHZp-V4.js`).then(e=>e.n);return new t({path:e.path})}default:throw Error(`Unknown store backend: "${e.backend}". Supported: lancedb`)}}export{e as LanceStore,d as SqliteGraphStore,u as createSqliteAdapter,_ as createStore};
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { ContentType, KnowledgeOrigin } from "../../core/dist/index.js";
|
|
1
|
+
import { ContentType, KnowledgeOrigin, TokenBudget } from "../../core/dist/index.js";
|
|
2
2
|
import { IEmbedder } from "../../embeddings/dist/index.js";
|
|
3
3
|
import { DepthGroupedResult, GraphEdge, GraphNode, GraphStats, GraphTraversalResult, GraphValidationResult, IGraphStore, IKnowledgeStore, ProcessInfo, Symbol360 } from "../../store/dist/index.js";
|
|
4
4
|
|
|
5
5
|
//#region packages/tools/src/response-envelope.d.ts
|
|
6
|
-
/**
|
|
7
|
-
* Standardized response envelope for AI Kit tools (E-009).
|
|
8
|
-
* New tools should return KBResponse<T>. Existing tools can adopt gradually.
|
|
9
|
-
*/
|
|
10
6
|
interface KBNextHint {
|
|
11
7
|
tool: string;
|
|
12
8
|
reason: string;
|
|
@@ -23,7 +19,7 @@ type KBErrorCode = 'SYMBOL_NOT_FOUND' | 'INDEX_STALE' | 'TREE_SITTER_UNAVAILABLE
|
|
|
23
19
|
interface KBResponseMeta {
|
|
24
20
|
durationMs: number;
|
|
25
21
|
tokensEstimate: number;
|
|
26
|
-
detail:
|
|
22
|
+
detail: TokenBudget;
|
|
27
23
|
cached: boolean;
|
|
28
24
|
truncated: boolean;
|
|
29
25
|
caveats?: string[];
|
|
@@ -51,8 +47,8 @@ interface AuditOptions {
|
|
|
51
47
|
path?: string;
|
|
52
48
|
/** Which checks to run (default: all) */
|
|
53
49
|
checks?: AuditCheck[];
|
|
54
|
-
/** Detail level (default: '
|
|
55
|
-
detail?:
|
|
50
|
+
/** Detail level (default: 'efficient') */
|
|
51
|
+
detail?: TokenBudget;
|
|
56
52
|
}
|
|
57
53
|
interface AuditRecommendation {
|
|
58
54
|
priority: 'high' | 'medium' | 'low';
|
|
@@ -252,8 +248,8 @@ interface CheckOptions {
|
|
|
252
248
|
skipTypes?: boolean;
|
|
253
249
|
/** Skip lint */
|
|
254
250
|
skipLint?: boolean;
|
|
255
|
-
/** Detail level:
|
|
256
|
-
detail?:
|
|
251
|
+
/** Detail level: efficient (default, minimal), normal (parsed errors), full (includes raw) */
|
|
252
|
+
detail?: TokenBudget;
|
|
257
253
|
}
|
|
258
254
|
interface CheckSummaryResult {
|
|
259
255
|
passed: boolean;
|
|
@@ -1331,6 +1327,8 @@ interface GuideRecommendation {
|
|
|
1331
1327
|
reason: string;
|
|
1332
1328
|
order: number;
|
|
1333
1329
|
suggestedArgs?: Record<string, unknown>;
|
|
1330
|
+
/** Optional token-saving tip shown alongside the recommendation */
|
|
1331
|
+
tokenTip?: string;
|
|
1334
1332
|
}
|
|
1335
1333
|
interface GuideResult {
|
|
1336
1334
|
workflow: string;
|