trellis 3.2.0 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +61 -171
  3. package/dist/browser/index.d.ts +18 -0
  4. package/dist/browser/index.d.ts.map +1 -0
  5. package/dist/browser/index.js +95 -0
  6. package/dist/{chunk-3ETIIPPB.js → chunk-2W3MHTMG.js} +190 -27
  7. package/dist/{chunk-MBNBTJCR.js → chunk-6GEZ6DN5.js} +2 -2
  8. package/dist/chunk-7ZFRVCUE.js +211 -0
  9. package/dist/chunk-CAG4FULI.js +121 -0
  10. package/dist/{chunk-GD5QJXSS.js → chunk-FWRS4CSC.js} +2 -2
  11. package/dist/{chunk-36VSSTL7.js → chunk-GU374KWZ.js} +1 -1
  12. package/dist/{chunk-3GDRZTAW.js → chunk-H6JB3PZ3.js} +1 -1
  13. package/dist/{chunk-ZHVI7BQN.js → chunk-IZX2PLIB.js} +191 -28
  14. package/dist/chunk-J2TXUFCZ.js +289 -0
  15. package/dist/{chunk-BJ7EZ7FP.js → chunk-JHHEXEDM.js} +17 -0
  16. package/dist/{chunk-X762XWVC.js → chunk-KIJITUZB.js} +1 -1
  17. package/dist/{chunk-7WQGTFVJ.js → chunk-L5N5PR2S.js} +130 -75
  18. package/dist/{chunk-BXSTJVE3.js → chunk-N6MYZT4O.js} +2 -1
  19. package/dist/{chunk-KKDRMIV6.js → chunk-QB5ISE47.js} +1 -1
  20. package/dist/{chunk-HO4TURXW.js → chunk-S3XLFZ27.js} +28 -11
  21. package/dist/{chunk-BQBUVMRN.js → chunk-S6GBJ2ZB.js} +25 -14
  22. package/dist/{chunk-IUWVEEOX.js → chunk-SGMDTWJJ.js} +4 -0
  23. package/dist/{chunk-FZVCXDYW.js → chunk-UQISRW6T.js} +65 -12
  24. package/dist/{chunk-B3ZIFA2O.js → chunk-VBYUTRXX.js} +1 -1
  25. package/dist/cli/deploy-cli.d.ts +18 -0
  26. package/dist/cli/deploy-cli.d.ts.map +1 -0
  27. package/dist/cli/index.d.ts +1 -1
  28. package/dist/cli/index.d.ts.map +1 -1
  29. package/dist/cli/index.js +153 -100
  30. package/dist/client/index.browser.d.ts +29 -0
  31. package/dist/client/index.browser.d.ts.map +1 -0
  32. package/dist/client/index.browser.js +64 -0
  33. package/dist/client/index.js +10 -10
  34. package/dist/client/sdk.browser.d.ts +104 -0
  35. package/dist/client/sdk.browser.d.ts.map +1 -0
  36. package/dist/{sdk-LZ7W3EEY.js → client/sdk.browser.js} +2 -2
  37. package/dist/client/sdk.js +1 -1
  38. package/dist/core/index.js +6 -6
  39. package/dist/db/index.js +18 -18
  40. package/dist/db/inspector.js +6 -6
  41. package/dist/db/trellis.css +1 -1
  42. package/dist/decisions/index.js +2 -2
  43. package/dist/deploy-LQ7GUGJ5.js +9 -0
  44. package/dist/{deploy-66EC752W.js → deploy-YNVG5E4E.js} +1 -1
  45. package/dist/deploy-cli-24BCHAXY.js +67 -0
  46. package/dist/deploy-cli-C35HTITO.js +67 -0
  47. package/dist/embeddings/auto-embed.d.ts.map +1 -1
  48. package/dist/embeddings/index.js +1 -1
  49. package/dist/embeddings/store.d.ts.map +1 -1
  50. package/dist/engine.d.ts +27 -7
  51. package/dist/engine.d.ts.map +1 -1
  52. package/dist/index.js +6 -6
  53. package/dist/mcp/server.d.ts.map +1 -1
  54. package/dist/react/index.js +2 -2
  55. package/dist/react/schema-hooks.js +7 -7
  56. package/dist/{remote-manager-SG545WNY.js → remote-manager-ODE3T2KR.js} +5 -5
  57. package/dist/scaffold/seed.d.ts.map +1 -1
  58. package/dist/scaffold/write.d.ts +1 -1
  59. package/dist/scaffold/write.d.ts.map +1 -1
  60. package/dist/schema/index.js +4 -3
  61. package/dist/server/deploy-meta.d.ts +25 -0
  62. package/dist/server/deploy-meta.d.ts.map +1 -0
  63. package/dist/server/deploy.d.ts +7 -2
  64. package/dist/server/deploy.d.ts.map +1 -1
  65. package/dist/server/index.d.ts +5 -2
  66. package/dist/server/index.d.ts.map +1 -1
  67. package/dist/server/index.js +52 -18
  68. package/dist/server/realtime.d.ts +4 -1
  69. package/dist/server/realtime.d.ts.map +1 -1
  70. package/dist/server/server.d.ts +1 -0
  71. package/dist/server/server.d.ts.map +1 -1
  72. package/dist/server/sprites.d.ts +18 -1
  73. package/dist/server/sprites.d.ts.map +1 -1
  74. package/dist/server/tenancy.d.ts +4 -0
  75. package/dist/server/tenancy.d.ts.map +1 -1
  76. package/dist/server/usage-meter.d.ts +53 -0
  77. package/dist/server/usage-meter.d.ts.map +1 -0
  78. package/dist/{server-IGBIIJSF.js → server-MB3OPSPI.js} +6 -1
  79. package/dist/{server-BOH7M4TT.js → server-ZVWGLLRF.js} +7 -2
  80. package/dist/sprites-KQGTGM6W.js +27 -0
  81. package/dist/{tenancy-S676GLID.js → tenancy-NBLLGCNJ.js} +1 -1
  82. package/dist/{tenancy-OP34NFFS.js → tenancy-POMWQP6M.js} +5 -3
  83. package/dist/vcs/index.js +3 -3
  84. package/dist/vcs/types.d.ts +2 -0
  85. package/dist/vcs/types.d.ts.map +1 -1
  86. package/package.json +17 -6
  87. package/dist/better-sqlite-backend-PII64VE6.js +0 -159
  88. package/dist/better-sqlite-backend-VUBVQ7SN.js +0 -209
  89. package/dist/better-sqlite-backend-Y3AQN65E.js +0 -159
  90. package/dist/better-sqlite-backend-Y3M7DXOX.js +0 -159
  91. package/dist/boot-middleware-FJDGVUM4.js +0 -9
  92. package/dist/boot-middleware-MLJUTLUM.js +0 -9
  93. package/dist/boot-middleware-ZZPDZNYR.js +0 -9
  94. package/dist/chunk-276LKLZR.js +0 -359
  95. package/dist/chunk-2CX5UCRV.js +0 -111
  96. package/dist/chunk-2ESYSVXG.js +0 -48
  97. package/dist/chunk-2I5JU73Y.js +0 -340
  98. package/dist/chunk-2UNSRRNB.js +0 -171
  99. package/dist/chunk-335UEHQR.js +0 -907
  100. package/dist/chunk-4CF2L46N.js +0 -29
  101. package/dist/chunk-5CINODKT.js +0 -41
  102. package/dist/chunk-5ESGWJ5L.js +0 -45
  103. package/dist/chunk-5FGLQGMF.js +0 -1676
  104. package/dist/chunk-5IQZFITY.js +0 -357
  105. package/dist/chunk-5JWFAQDW.js +0 -150
  106. package/dist/chunk-62UHTVU3.js +0 -141
  107. package/dist/chunk-66UJQT2I.js +0 -35
  108. package/dist/chunk-6RNNVOAS.js +0 -355
  109. package/dist/chunk-6X23PZ6H.js +0 -969
  110. package/dist/chunk-7C7LL6MB.js +0 -315
  111. package/dist/chunk-7F4HM3JG.js +0 -394
  112. package/dist/chunk-7KJ7T4D3.js +0 -910
  113. package/dist/chunk-7QQQNUB5.js +0 -92
  114. package/dist/chunk-7QWJBS72.js +0 -946
  115. package/dist/chunk-7R36OZK3.js +0 -957
  116. package/dist/chunk-7UPKCOHE.js +0 -946
  117. package/dist/chunk-A3BONW34.js +0 -35
  118. package/dist/chunk-AHMDVHBL.js +0 -141
  119. package/dist/chunk-AW6A4OZY.js +0 -171
  120. package/dist/chunk-BJ5EKCJ5.js +0 -458
  121. package/dist/chunk-BRGYDO7D.js +0 -223
  122. package/dist/chunk-C5KPSEDN.js +0 -359
  123. package/dist/chunk-CCTNYTUC.js +0 -940
  124. package/dist/chunk-CYQ2OVD2.js +0 -35
  125. package/dist/chunk-DDAK7YOE.js +0 -299
  126. package/dist/chunk-DRILKBY6.js +0 -965
  127. package/dist/chunk-DXE24HNN.js +0 -45
  128. package/dist/chunk-E7ICUNW7.js +0 -945
  129. package/dist/chunk-EAL2PUOE.js +0 -10022
  130. package/dist/chunk-ELT7MLZB.js +0 -109
  131. package/dist/chunk-EWEIRF6G.js +0 -171
  132. package/dist/chunk-F5VDGQJC.js +0 -120
  133. package/dist/chunk-FCPL3IEQ.js +0 -98
  134. package/dist/chunk-FDPKYSV7.js +0 -96
  135. package/dist/chunk-FES3TC24.js +0 -171
  136. package/dist/chunk-FOWKR5TW.js +0 -129
  137. package/dist/chunk-G3XIHPSQ.js +0 -361
  138. package/dist/chunk-GKJLYLVU.js +0 -359
  139. package/dist/chunk-GNXHXNVQ.js +0 -113
  140. package/dist/chunk-GSR6ILTM.js +0 -277
  141. package/dist/chunk-GWRIMRSX.js +0 -45
  142. package/dist/chunk-H72UW2HJ.js +0 -45
  143. package/dist/chunk-HGI74PXB.js +0 -7417
  144. package/dist/chunk-HGRA37LO.js +0 -145
  145. package/dist/chunk-HXSRQO3L.js +0 -145
  146. package/dist/chunk-IG2X2BVO.js +0 -373
  147. package/dist/chunk-IIJVDD54.js +0 -373
  148. package/dist/chunk-IX4BBOIT.js +0 -394
  149. package/dist/chunk-IXU4RMQM.js +0 -349
  150. package/dist/chunk-J6OUIION.js +0 -857
  151. package/dist/chunk-K46RNFDE.js +0 -171
  152. package/dist/chunk-KAGU2XMY.js +0 -359
  153. package/dist/chunk-KCVYJNVX.js +0 -394
  154. package/dist/chunk-KYLIQ3YI.js +0 -399
  155. package/dist/chunk-KZYJJIRN.js +0 -946
  156. package/dist/chunk-LFOX744K.js +0 -96
  157. package/dist/chunk-LHOVJEWR.js +0 -7403
  158. package/dist/chunk-LOPXTPF3.js +0 -120
  159. package/dist/chunk-LZR3VIFU.js +0 -907
  160. package/dist/chunk-MCKGQKYU.js +0 -15
  161. package/dist/chunk-MU6EOS6F.js +0 -0
  162. package/dist/chunk-MWRQ2TXT.js +0 -357
  163. package/dist/chunk-NO73OK2I.js +0 -102
  164. package/dist/chunk-NPE2YJHK.js +0 -394
  165. package/dist/chunk-NSDXU6QX.js +0 -2213
  166. package/dist/chunk-NXIRDSZ6.js +0 -145
  167. package/dist/chunk-NZWFNHCS.js +0 -407
  168. package/dist/chunk-OB4CMMX6.js +0 -260
  169. package/dist/chunk-OBKU74FU.js +0 -7411
  170. package/dist/chunk-OQNDWRDE.js +0 -145
  171. package/dist/chunk-OVWAJMB6.js +0 -394
  172. package/dist/chunk-PDHLBTTD.js +0 -45
  173. package/dist/chunk-PEQNRKLG.js +0 -210
  174. package/dist/chunk-QERIS7QY.js +0 -7403
  175. package/dist/chunk-QHA2DM3C.js +0 -373
  176. package/dist/chunk-QLM4HSYC.js +0 -45
  177. package/dist/chunk-S2OT3TQJ.js +0 -283
  178. package/dist/chunk-S5PHSN5K.js +0 -907
  179. package/dist/chunk-SIAA4J6H.js +0 -21
  180. package/dist/chunk-SQBNLUIA.js +0 -171
  181. package/dist/chunk-STLN6A6B.js +0 -355
  182. package/dist/chunk-U7HV7GU2.js +0 -17
  183. package/dist/chunk-UGZHOGRA.js +0 -39
  184. package/dist/chunk-UICF66FS.js +0 -359
  185. package/dist/chunk-UK3EQREE.js +0 -1078
  186. package/dist/chunk-UPKPURVY.js +0 -394
  187. package/dist/chunk-URC74VCN.js +0 -959
  188. package/dist/chunk-V3G7Q3QQ.js +0 -102
  189. package/dist/chunk-VUJ6SA55.js +0 -303
  190. package/dist/chunk-VUJQLIML.js +0 -141
  191. package/dist/chunk-VWKLKLYB.js +0 -267
  192. package/dist/chunk-VYC3RZMK.js +0 -277
  193. package/dist/chunk-WMERMSWI.js +0 -154
  194. package/dist/chunk-WMR777PO.js +0 -2213
  195. package/dist/chunk-X46IECAC.js +0 -517
  196. package/dist/chunk-XEN3OEYY.js +0 -2234
  197. package/dist/chunk-XZQ66K7A.js +0 -124
  198. package/dist/chunk-YY3GF7DH.js +0 -7411
  199. package/dist/chunk-ZE5R3H4C.js +0 -907
  200. package/dist/chunk-ZMN5LUB7.js +0 -7411
  201. package/dist/chunk-ZUV4MD5U.js +0 -94
  202. package/dist/config-KMY6RRK3.js +0 -19
  203. package/dist/config-VDMK2DUJ.js +0 -19
  204. package/dist/deploy-SO7AFK6L.js +0 -9
  205. package/dist/engine-7GXBM4IT.js +0 -7
  206. package/dist/engine-NSR6BIF7.js +0 -7
  207. package/dist/factory-2P64OC7M.js +0 -34
  208. package/dist/factory-YP4ZZK5K.js +0 -34
  209. package/dist/import-AJLYHFIA.js +0 -10
  210. package/dist/launch-explorer-AI6L2AWJ.js +0 -91
  211. package/dist/query-GJL3CVGN.js +0 -31
  212. package/dist/query-MBJSK3EB.js +0 -31
  213. package/dist/query-TJHEVSKL.js +0 -31
  214. package/dist/query-WUIKOHPE.js +0 -524
  215. package/dist/remote-manager-BLJZ6KF6.js +0 -224
  216. package/dist/remote-manager-BPYE46SI.js +0 -223
  217. package/dist/remote-manager-FMESEAFA.js +0 -224
  218. package/dist/remote-manager-K2WZ5RHY.js +0 -223
  219. package/dist/remote-manager-SG5PQKCH.js +0 -224
  220. package/dist/remote-manager-WGP6MIQZ.js +0 -224
  221. package/dist/sdk-3KBB3E6V.js +0 -16
  222. package/dist/sdk-4ZQO6UTU.js +0 -16
  223. package/dist/sdk-6JA6GV3G.js +0 -16
  224. package/dist/sdk-6VTP5UTZ.js +0 -16
  225. package/dist/sdk-7VS6TYCD.js +0 -16
  226. package/dist/sdk-HQ3FTLRT.js +0 -16
  227. package/dist/sdk-HZ7NU3XE.js +0 -15
  228. package/dist/sdk-KBQE2OXT.js +0 -16
  229. package/dist/sdk-MSCDZ7JU.js +0 -15
  230. package/dist/sdk-WNZOGO3S.js +0 -15
  231. package/dist/sdk-YLV33ZCW.js +0 -9
  232. package/dist/sdk-ZSUD2LLJ.js +0 -16
  233. package/dist/server-AFXFFBWA.js +0 -11
  234. package/dist/server-AGHC4VUL.js +0 -11
  235. package/dist/server-DBUY2KY5.js +0 -11
  236. package/dist/server-GWBQJPRG.js +0 -11
  237. package/dist/server-JZZFULVU.js +0 -11
  238. package/dist/server-L5XAF4M5.js +0 -11
  239. package/dist/server-NYFUHANA.js +0 -12
  240. package/dist/server-OABUB2LO.js +0 -12
  241. package/dist/server-P2CKZWWV.js +0 -12
  242. package/dist/sprites-XVSMQLSI.js +0 -15
  243. package/dist/sql-wasm-FORCZFHZ.js +0 -2148
  244. package/dist/sql-wasm-JZH76RLO.js +0 -2148
  245. package/dist/sqljs-backend-CJQOIQYE.js +0 -266
  246. package/dist/sqljs-backend-KWXBUDUO.js +0 -266
  247. package/dist/state-demo.bundle.js +0 -1033
  248. package/dist/tenancy-CBWYEVUB.js +0 -11
  249. package/dist/tenancy-FO6WVYFN.js +0 -13
  250. package/dist/tenancy-FWDBESMX.js +0 -14
  251. package/dist/tenancy-HGPIS5QA.js +0 -13
  252. package/dist/tenancy-HXFALA37.js +0 -14
  253. package/dist/tenancy-V7ARWNNV.js +0 -14
  254. package/dist/tenancy-ZDN4GXK5.js +0 -13
  255. package/dist/tenancy-ZT5VMY7B.js +0 -14
  256. package/dist/vm-config-YZRJ3KUB.js +0 -21
  257. /package/dist/{chunk-2BRTCEHB.js → chunk-PZ4XYZ4J.js} +0 -0
  258. /package/dist/{chunk-EO3J7GRP.js → chunk-WXSWA3MV.js} +0 -0
@@ -1,1078 +0,0 @@
1
- import {
2
- __esm,
3
- __export,
4
- __require
5
- } from "./chunk-2ESYSVXG.js";
6
-
7
- // src/embeddings/types.ts
8
- var DEFAULT_MODEL_CONFIG;
9
- var init_types = __esm({
10
- "src/embeddings/types.ts"() {
11
- "use strict";
12
- DEFAULT_MODEL_CONFIG = {
13
- modelName: "Xenova/all-MiniLM-L6-v2",
14
- dimension: 384
15
- };
16
- }
17
- });
18
-
19
- // src/embeddings/model.ts
20
- async function importTransformers() {
21
- try {
22
- return await import("@huggingface/transformers");
23
- } catch {
24
- try {
25
- return await import("@xenova/transformers");
26
- } catch {
27
- throw new Error(
28
- "No transformers library found. Install @huggingface/transformers (recommended) or @xenova/transformers."
29
- );
30
- }
31
- }
32
- }
33
- async function loadModel(config = DEFAULT_MODEL_CONFIG) {
34
- if (pipeline) return pipeline;
35
- if (!loadPromise) {
36
- loadPromise = (async () => {
37
- const { pipeline: createPipeline } = await importTransformers();
38
- const opts = {};
39
- if (config.cacheDir) {
40
- opts.cache_dir = config.cacheDir;
41
- }
42
- pipeline = await createPipeline(
43
- "feature-extraction",
44
- config.modelName,
45
- opts
46
- );
47
- return pipeline;
48
- })();
49
- }
50
- return loadPromise;
51
- }
52
- async function embed(text, config = DEFAULT_MODEL_CONFIG) {
53
- const pipe = await loadModel(config);
54
- const output = await pipe(text, { pooling: "mean", normalize: true });
55
- return new Float32Array(output.data);
56
- }
57
- async function embedBatch(texts, config = DEFAULT_MODEL_CONFIG) {
58
- if (texts.length === 0) return [];
59
- const pipe = await loadModel(config);
60
- const results = [];
61
- const batchSize = 32;
62
- for (let i = 0; i < texts.length; i += batchSize) {
63
- const batch = texts.slice(i, i + batchSize);
64
- for (const text of batch) {
65
- const output = await pipe(text, { pooling: "mean", normalize: true });
66
- results.push(new Float32Array(output.data));
67
- }
68
- }
69
- return results;
70
- }
71
- function resetModel() {
72
- pipeline = null;
73
- loadPromise = null;
74
- }
75
- var pipeline, loadPromise;
76
- var init_model = __esm({
77
- "src/embeddings/model.ts"() {
78
- "use strict";
79
- init_types();
80
- pipeline = null;
81
- loadPromise = null;
82
- }
83
- });
84
-
85
- // src/embeddings/store.ts
86
- function rowToChunkMeta(row) {
87
- return {
88
- id: row.id,
89
- entityId: row.entity_id,
90
- content: row.content,
91
- chunkType: row.chunk_type,
92
- filePath: row.file_path ?? void 0,
93
- updatedAt: row.updated_at
94
- };
95
- }
96
- function cosineSimilarity(a, b) {
97
- if (a.length !== b.length) return 0;
98
- let dot = 0;
99
- let normA = 0;
100
- let normB = 0;
101
- for (let i = 0; i < a.length; i++) {
102
- dot += a[i] * b[i];
103
- normA += a[i] * a[i];
104
- normB += b[i] * b[i];
105
- }
106
- const denom = Math.sqrt(normA) * Math.sqrt(normB);
107
- return denom === 0 ? 0 : dot / denom;
108
- }
109
- var SCHEMA_SQL, VectorStore;
110
- var init_store = __esm({
111
- "src/embeddings/store.ts"() {
112
- "use strict";
113
- SCHEMA_SQL = `
114
- CREATE TABLE IF NOT EXISTS chunks (
115
- id TEXT PRIMARY KEY,
116
- entity_id TEXT NOT NULL,
117
- content TEXT NOT NULL,
118
- chunk_type TEXT NOT NULL,
119
- file_path TEXT,
120
- updated_at TEXT NOT NULL
121
- );
122
-
123
- CREATE TABLE IF NOT EXISTS vectors (
124
- id TEXT PRIMARY KEY,
125
- embedding BLOB NOT NULL,
126
- FOREIGN KEY (id) REFERENCES chunks(id) ON DELETE CASCADE
127
- );
128
-
129
- CREATE INDEX IF NOT EXISTS idx_chunks_entity ON chunks(entity_id);
130
- CREATE INDEX IF NOT EXISTS idx_chunks_type ON chunks(chunk_type);
131
- CREATE INDEX IF NOT EXISTS idx_chunks_file ON chunks(file_path);
132
- `;
133
- VectorStore = class _VectorStore {
134
- constructor(dbPath) {
135
- this.dbPath = dbPath;
136
- }
137
- db;
138
- stmts;
139
- writes = 0;
140
- /**
141
- * Async factory — sql.js WASM init is async, but after bootstrap the store
142
- * exposes a synchronous-style public API.
143
- */
144
- static async create(dbPath) {
145
- const store = new _VectorStore(dbPath);
146
- await store.bootstrap();
147
- return store;
148
- }
149
- async bootstrap() {
150
- let initSqlJs;
151
- try {
152
- const mod = await import("sql.js");
153
- initSqlJs = mod.default ?? mod;
154
- } catch {
155
- throw new Error(
156
- 'VectorStore requires the optional dependency "sql.js". Install it: npm install sql.js'
157
- );
158
- }
159
- let sqljsDistDir = null;
160
- if (typeof window === "undefined") {
161
- try {
162
- const moduleMod = await import("module");
163
- const pathMod = await import("path");
164
- const req = moduleMod.createRequire(import.meta.url);
165
- const sqlJsEntry = req.resolve("sql.js");
166
- sqljsDistDir = pathMod.dirname(sqlJsEntry);
167
- } catch {
168
- sqljsDistDir = null;
169
- }
170
- }
171
- const SQL = await initSqlJs({
172
- locateFile: (file) => {
173
- if (typeof window !== "undefined") return `/sql-wasm/${file}`;
174
- if (sqljsDistDir) return `${sqljsDistDir}/${file}`;
175
- return file;
176
- }
177
- });
178
- const existing = this.loadFromDisk();
179
- this.db = existing ? new SQL.Database(existing) : new SQL.Database();
180
- this.db.run("PRAGMA foreign_keys = ON;");
181
- this.db.run(SCHEMA_SQL);
182
- this.prepareStatements();
183
- }
184
- loadFromDisk() {
185
- if (this.dbPath === ":memory:") return null;
186
- try {
187
- const fs = __require("fs");
188
- if (!fs.existsSync(this.dbPath)) return null;
189
- return new Uint8Array(fs.readFileSync(this.dbPath));
190
- } catch {
191
- return null;
192
- }
193
- }
194
- flushToDisk() {
195
- if (this.dbPath === ":memory:") return;
196
- try {
197
- const fs = __require("fs");
198
- const path = __require("path");
199
- const data = this.db.export();
200
- fs.mkdirSync(path.dirname(this.dbPath), { recursive: true });
201
- const tmp = `${this.dbPath}.tmp`;
202
- fs.writeFileSync(tmp, Buffer.from(data));
203
- fs.renameSync(tmp, this.dbPath);
204
- } catch {
205
- }
206
- }
207
- prepareStatements() {
208
- this.stmts = {
209
- upsertChunk: this.db.prepare(`
210
- INSERT OR REPLACE INTO chunks (id, entity_id, content, chunk_type, file_path, updated_at)
211
- VALUES ($id, $entityId, $content, $chunkType, $filePath, $updatedAt)
212
- `),
213
- upsertVector: this.db.prepare(`
214
- INSERT OR REPLACE INTO vectors (id, embedding)
215
- VALUES ($id, $embedding)
216
- `),
217
- deleteVector: this.db.prepare("DELETE FROM vectors WHERE id = $id"),
218
- deleteChunk: this.db.prepare("DELETE FROM chunks WHERE id = $id"),
219
- getChunkById: this.db.prepare("SELECT * FROM chunks WHERE id = $id"),
220
- getChunkIdsByEntity: this.db.prepare(
221
- "SELECT id FROM chunks WHERE entity_id = $entityId"
222
- ),
223
- getChunkIdsByFile: this.db.prepare(
224
- "SELECT id FROM chunks WHERE file_path = $filePath"
225
- ),
226
- count: this.db.prepare("SELECT COUNT(*) AS cnt FROM chunks"),
227
- countByType: this.db.prepare(
228
- "SELECT chunk_type, COUNT(*) AS cnt FROM chunks GROUP BY chunk_type"
229
- )
230
- };
231
- }
232
- /**
233
- * Insert or update a chunk with its embedding vector.
234
- */
235
- upsert(record) {
236
- const embeddingBlob = new Uint8Array(record.embedding.buffer);
237
- this.db.run("BEGIN");
238
- try {
239
- this.stmts.upsertChunk.run({
240
- $id: record.id,
241
- $entityId: record.entityId,
242
- $content: record.content,
243
- $chunkType: record.chunkType,
244
- $filePath: record.filePath ?? null,
245
- $updatedAt: record.updatedAt
246
- });
247
- this.stmts.upsertChunk.reset();
248
- this.stmts.upsertVector.run({ $id: record.id, $embedding: embeddingBlob });
249
- this.stmts.upsertVector.reset();
250
- this.db.run("COMMIT");
251
- } catch (e) {
252
- this.db.run("ROLLBACK");
253
- throw e;
254
- }
255
- this.tickFlush();
256
- }
257
- /**
258
- * Batch upsert multiple records.
259
- */
260
- upsertBatch(records) {
261
- if (records.length === 0) return;
262
- this.db.run("BEGIN");
263
- try {
264
- for (const record of records) {
265
- const embeddingBlob = new Uint8Array(record.embedding.buffer);
266
- this.stmts.upsertChunk.run({
267
- $id: record.id,
268
- $entityId: record.entityId,
269
- $content: record.content,
270
- $chunkType: record.chunkType,
271
- $filePath: record.filePath ?? null,
272
- $updatedAt: record.updatedAt
273
- });
274
- this.stmts.upsertChunk.reset();
275
- this.stmts.upsertVector.run({ $id: record.id, $embedding: embeddingBlob });
276
- this.stmts.upsertVector.reset();
277
- }
278
- this.db.run("COMMIT");
279
- } catch (e) {
280
- this.db.run("ROLLBACK");
281
- throw e;
282
- }
283
- this.tickFlush();
284
- }
285
- /**
286
- * Delete a chunk and its vector by ID.
287
- */
288
- delete(id) {
289
- this.stmts.deleteVector.run({ $id: id });
290
- this.stmts.deleteVector.reset();
291
- this.stmts.deleteChunk.run({ $id: id });
292
- this.stmts.deleteChunk.reset();
293
- this.tickFlush();
294
- }
295
- /**
296
- * Delete all chunks for an entity.
297
- */
298
- deleteByEntity(entityId) {
299
- const ids = this.runAll(this.stmts.getChunkIdsByEntity, {
300
- $entityId: entityId
301
- }).map((r) => r.id);
302
- if (ids.length === 0) return;
303
- this.db.run("BEGIN");
304
- try {
305
- for (const id of ids) {
306
- this.stmts.deleteVector.run({ $id: id });
307
- this.stmts.deleteVector.reset();
308
- this.stmts.deleteChunk.run({ $id: id });
309
- this.stmts.deleteChunk.reset();
310
- }
311
- this.db.run("COMMIT");
312
- } catch (e) {
313
- this.db.run("ROLLBACK");
314
- throw e;
315
- }
316
- this.tickFlush();
317
- }
318
- /**
319
- * Delete all chunks associated with a file path.
320
- */
321
- deleteByFile(filePath) {
322
- const ids = this.runAll(this.stmts.getChunkIdsByFile, {
323
- $filePath: filePath
324
- }).map((r) => r.id);
325
- if (ids.length === 0) return;
326
- this.db.run("BEGIN");
327
- try {
328
- for (const id of ids) {
329
- this.stmts.deleteVector.run({ $id: id });
330
- this.stmts.deleteVector.reset();
331
- this.stmts.deleteChunk.run({ $id: id });
332
- this.stmts.deleteChunk.reset();
333
- }
334
- this.db.run("COMMIT");
335
- } catch (e) {
336
- this.db.run("ROLLBACK");
337
- throw e;
338
- }
339
- this.tickFlush();
340
- }
341
- /**
342
- * Get a chunk by ID (without vector).
343
- */
344
- getChunk(id) {
345
- const row = this.runOne(this.stmts.getChunkById, { $id: id });
346
- return row ? rowToChunkMeta(row) : null;
347
- }
348
- /**
349
- * Search for chunks similar to the query vector.
350
- * Uses brute-force cosine similarity scan.
351
- */
352
- search(queryVector, opts = {}) {
353
- const limit = opts.limit ?? 10;
354
- const minScore = opts.minScore ?? 0;
355
- const conditions = [];
356
- const params = {};
357
- if (opts.types && opts.types.length > 0) {
358
- const placeholders = opts.types.map((_, i) => `$type${i}`).join(", ");
359
- conditions.push(`c.chunk_type IN (${placeholders})`);
360
- opts.types.forEach((t, i) => {
361
- params[`$type${i}`] = t;
362
- });
363
- }
364
- if (opts.filePrefix) {
365
- conditions.push("c.file_path LIKE $filePrefix");
366
- params.$filePrefix = `${opts.filePrefix}%`;
367
- }
368
- const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
369
- const sql = `
370
- SELECT c.id, c.entity_id, c.content, c.chunk_type, c.file_path, c.updated_at,
371
- v.embedding
372
- FROM chunks c
373
- JOIN vectors v ON c.id = v.id
374
- ${where}
375
- `;
376
- const stmt = this.db.prepare(sql);
377
- const rows = this.runAll(stmt, params);
378
- stmt.free();
379
- const scored = [];
380
- for (const row of rows) {
381
- const embeddingBytes = row.embedding;
382
- const ownedBuf = embeddingBytes.buffer.slice(
383
- embeddingBytes.byteOffset,
384
- embeddingBytes.byteOffset + embeddingBytes.byteLength
385
- );
386
- const storedVec = new Float32Array(ownedBuf);
387
- const score = cosineSimilarity(queryVector, storedVec);
388
- if (score >= minScore) {
389
- scored.push({ chunk: rowToChunkMeta(row), score });
390
- }
391
- }
392
- scored.sort((a, b) => b.score - a.score);
393
- return scored.slice(0, limit);
394
- }
395
- /**
396
- * Get total count of chunks in the store.
397
- */
398
- count() {
399
- const row = this.runOne(this.stmts.count);
400
- return Number(row?.cnt ?? 0);
401
- }
402
- /**
403
- * Get count by chunk type.
404
- */
405
- countByType() {
406
- const rows = this.runAll(this.stmts.countByType);
407
- const result = {};
408
- for (const row of rows) {
409
- result[row.chunk_type] = row.cnt;
410
- }
411
- return result;
412
- }
413
- /**
414
- * Clear all data from the store.
415
- */
416
- clear() {
417
- this.db.run("DELETE FROM vectors");
418
- this.db.run("DELETE FROM chunks");
419
- this.tickFlush();
420
- }
421
- /**
422
- * Force a write of the in-memory DB image to disk.
423
- */
424
- flush() {
425
- this.flushToDisk();
426
- }
427
- /**
428
- * Close the database connection.
429
- */
430
- close() {
431
- try {
432
- this.flushToDisk();
433
- } finally {
434
- for (const s of Object.values(this.stmts ?? {})) s?.free?.();
435
- this.db?.close?.();
436
- }
437
- }
438
- // ---------------------------------------------------------------------------
439
- // Helpers
440
- // ---------------------------------------------------------------------------
441
- runAll(stmt, params = {}) {
442
- stmt.bind(params);
443
- const rows = [];
444
- while (stmt.step()) rows.push(stmt.getAsObject());
445
- stmt.reset();
446
- return rows;
447
- }
448
- runOne(stmt, params = {}) {
449
- stmt.bind(params);
450
- const has = stmt.step();
451
- const row = has ? stmt.getAsObject() : void 0;
452
- stmt.reset();
453
- return row;
454
- }
455
- tickFlush() {
456
- if (++this.writes % 50 === 0) this.flushToDisk();
457
- }
458
- };
459
- }
460
- });
461
-
462
- // src/embeddings/chunker.ts
463
- function chunkIssue(issue) {
464
- const now = (/* @__PURE__ */ new Date()).toISOString();
465
- const chunks = [];
466
- if (issue.title) {
467
- chunks.push({
468
- id: `issue:${issue.id}:title`,
469
- entityId: `issue:${issue.id}`,
470
- content: issue.title,
471
- chunkType: "issue_title",
472
- updatedAt: now
473
- });
474
- }
475
- if (issue.description) {
476
- chunks.push({
477
- id: `issue:${issue.id}:desc`,
478
- entityId: `issue:${issue.id}`,
479
- content: issue.description,
480
- chunkType: "issue_desc",
481
- updatedAt: now
482
- });
483
- }
484
- return chunks;
485
- }
486
- function chunkDecision(decision) {
487
- const parts = [];
488
- parts.push(`Decision ${decision.id}: ${decision.toolName}`);
489
- if (decision.rationale) parts.push(`Rationale: ${decision.rationale}`);
490
- if (decision.context) parts.push(`Context: ${decision.context}`);
491
- if (decision.outputSummary) parts.push(`Output: ${decision.outputSummary}`);
492
- const content = parts.join("\n");
493
- if (!content.trim()) return [];
494
- return [
495
- {
496
- id: `decision:${decision.id}:rationale`,
497
- entityId: `decision:${decision.id}`,
498
- content,
499
- chunkType: "decision_rationale",
500
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
501
- }
502
- ];
503
- }
504
- function chunkMilestone(milestone) {
505
- if (!milestone.message) return [];
506
- return [
507
- {
508
- id: `milestone:${milestone.id}:msg`,
509
- entityId: `milestone:${milestone.id}`,
510
- content: milestone.message,
511
- chunkType: "milestone_msg",
512
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
513
- }
514
- ];
515
- }
516
- function chunkMarkdown(filePath, content) {
517
- if (!content.trim()) return [];
518
- const entityId = `file:${filePath}`;
519
- const now = (/* @__PURE__ */ new Date()).toISOString();
520
- const sections = splitByHeadings(content);
521
- const chunks = [];
522
- for (let i = 0; i < sections.length; i++) {
523
- const section = sections[i];
524
- if (!section.text.trim()) continue;
525
- if (section.text.length <= MAX_CHUNK_CHARS) {
526
- chunks.push({
527
- id: `${entityId}:section:${i}`,
528
- entityId,
529
- content: section.text,
530
- chunkType: "markdown",
531
- filePath,
532
- updatedAt: now
533
- });
534
- } else {
535
- const windows = slidingWindow(section.text);
536
- for (let w = 0; w < windows.length; w++) {
537
- chunks.push({
538
- id: `${entityId}:section:${i}:w${w}`,
539
- entityId,
540
- content: windows[w],
541
- chunkType: "markdown",
542
- filePath,
543
- updatedAt: now
544
- });
545
- }
546
- }
547
- }
548
- return chunks;
549
- }
550
- function chunkCodeEntities(filePath, declarations) {
551
- const now = (/* @__PURE__ */ new Date()).toISOString();
552
- const chunks = [];
553
- for (const decl of declarations) {
554
- const parts = [];
555
- if (decl.docComment) parts.push(decl.docComment);
556
- parts.push(`${decl.kind} ${decl.name}`);
557
- parts.push(decl.signature);
558
- const content = parts.join("\n").slice(0, MAX_CHUNK_CHARS);
559
- chunks.push({
560
- id: `symbol:${filePath}#${decl.name}`,
561
- entityId: `symbol:${filePath}#${decl.name}`,
562
- content,
563
- chunkType: "code_entity",
564
- filePath,
565
- updatedAt: now
566
- });
567
- }
568
- return chunks;
569
- }
570
- function chunkDocComments(filePath, comments) {
571
- if (comments.length === 0) return [];
572
- const entityId = `file:${filePath}`;
573
- const now = (/* @__PURE__ */ new Date()).toISOString();
574
- const chunks = [];
575
- for (let i = 0; i < comments.length; i++) {
576
- const comment = comments[i];
577
- if (!comment.text.trim()) continue;
578
- chunks.push({
579
- id: `${entityId}:doc:${i}`,
580
- entityId,
581
- content: comment.text.slice(0, MAX_CHUNK_CHARS),
582
- chunkType: "doc_comment",
583
- filePath,
584
- updatedAt: now
585
- });
586
- }
587
- return chunks;
588
- }
589
- function chunkSummary(filePath, content) {
590
- if (!content.trim()) return [];
591
- const entityId = `file:${filePath}`;
592
- const now = (/* @__PURE__ */ new Date()).toISOString();
593
- if (content.length <= MAX_CHUNK_CHARS) {
594
- return [
595
- {
596
- id: `${entityId}:summary`,
597
- entityId,
598
- content,
599
- chunkType: "summary_md",
600
- filePath,
601
- updatedAt: now
602
- }
603
- ];
604
- }
605
- return chunkMarkdown(filePath, content).map((c) => ({
606
- ...c,
607
- chunkType: "summary_md"
608
- }));
609
- }
610
- function chunkFile(filePath, content) {
611
- if (!content.trim()) return [];
612
- const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
613
- if (filePath.endsWith("summary.md")) {
614
- return chunkSummary(filePath, content);
615
- }
616
- if (ext === "md") {
617
- return chunkMarkdown(filePath, content);
618
- }
619
- return [];
620
- }
621
- function splitByHeadings(content) {
622
- const lines = content.split("\n");
623
- const sections = [];
624
- let currentSection = { text: "" };
625
- for (const line of lines) {
626
- if (/^#{1,3}\s/.test(line)) {
627
- if (currentSection.text.trim()) {
628
- sections.push(currentSection);
629
- }
630
- currentSection = { heading: line, text: line + "\n" };
631
- } else {
632
- currentSection.text += line + "\n";
633
- }
634
- }
635
- if (currentSection.text.trim()) {
636
- sections.push(currentSection);
637
- }
638
- return sections;
639
- }
640
- function slidingWindow(text) {
641
- const windows = [];
642
- let start = 0;
643
- while (start < text.length) {
644
- const end = Math.min(start + MAX_CHUNK_CHARS, text.length);
645
- windows.push(text.slice(start, end));
646
- if (end >= text.length) break;
647
- start += MAX_CHUNK_CHARS - OVERLAP_CHARS;
648
- }
649
- return windows;
650
- }
651
- var MAX_CHUNK_CHARS, OVERLAP_CHARS;
652
- var init_chunker = __esm({
653
- "src/embeddings/chunker.ts"() {
654
- "use strict";
655
- MAX_CHUNK_CHARS = 512;
656
- OVERLAP_CHARS = 64;
657
- }
658
- });
659
-
660
- // src/embeddings/search.ts
661
- import { join } from "path";
662
- import { readFileSync, existsSync } from "fs";
663
- var EmbeddingManager;
664
- var init_search = __esm({
665
- "src/embeddings/search.ts"() {
666
- "use strict";
667
- init_store();
668
- init_model();
669
- init_chunker();
670
- EmbeddingManager = class _EmbeddingManager {
671
- store;
672
- embedFn;
673
- constructor(store, embedFn) {
674
- this.store = store;
675
- this.embedFn = embedFn;
676
- }
677
- static async create(dbPath, embedFn) {
678
- const store = await VectorStore.create(dbPath);
679
- return new _EmbeddingManager(store, embedFn ?? embed);
680
- }
681
- /**
682
- * Full reindex: clear store, re-chunk all entities, embed, and insert.
683
- */
684
- async reindex(engine) {
685
- this.store.clear();
686
- const allChunks = [];
687
- const issues = engine.listIssues();
688
- for (const issue of issues) {
689
- allChunks.push(...chunkIssue(issue));
690
- }
691
- const milestones = engine.listMilestones();
692
- for (const ms of milestones) {
693
- allChunks.push(...chunkMilestone(ms));
694
- }
695
- if (engine.queryDecisions) {
696
- const decisions = engine.queryDecisions();
697
- for (const dec of decisions) {
698
- allChunks.push(...chunkDecision(dec));
699
- }
700
- }
701
- const rootPath = engine.getRootPath();
702
- const trackedFiles = engine.trackedFiles();
703
- for (const tf of trackedFiles) {
704
- try {
705
- const absPath = join(rootPath, tf.path);
706
- if (!existsSync(absPath)) continue;
707
- const content = readFileSync(absPath, "utf-8");
708
- allChunks.push(...chunkFile(tf.path, content));
709
- } catch {
710
- }
711
- }
712
- if (engine.parseFile) {
713
- for (const tf of trackedFiles) {
714
- const ext = tf.path.split(".").pop()?.toLowerCase() ?? "";
715
- if (![
716
- "ts",
717
- "js",
718
- "tsx",
719
- "jsx",
720
- "py",
721
- "go",
722
- "rs",
723
- "rb",
724
- "java",
725
- "cs"
726
- ].includes(ext)) {
727
- continue;
728
- }
729
- try {
730
- const parsed = engine.parseFile(tf.path);
731
- if (parsed && Array.isArray(parsed.entities)) {
732
- const declarations = parsed.entities.map((e) => ({
733
- id: e.id ?? e.name,
734
- name: e.name,
735
- kind: e.kind,
736
- signature: e.signature ?? e.rawText?.split("\n")[0] ?? "",
737
- docComment: e.docComment
738
- }));
739
- allChunks.push(...chunkCodeEntities(tf.path, declarations));
740
- }
741
- } catch {
742
- }
743
- }
744
- }
745
- const records = [];
746
- for (const chunk of allChunks) {
747
- try {
748
- const vector = await this.embedFn(chunk.content);
749
- records.push({ ...chunk, embedding: vector });
750
- } catch {
751
- }
752
- }
753
- this.store.upsertBatch(records);
754
- return { chunks: records.length };
755
- }
756
- /**
757
- * Incrementally index a single file (on file change).
758
- */
759
- async indexFile(filePath, content, engine) {
760
- this.store.deleteByFile(filePath);
761
- const chunks = chunkFile(filePath, content);
762
- if (engine?.parseFile) {
763
- const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
764
- if ([
765
- "ts",
766
- "js",
767
- "tsx",
768
- "jsx",
769
- "py",
770
- "go",
771
- "rs",
772
- "rb",
773
- "java",
774
- "cs"
775
- ].includes(ext)) {
776
- try {
777
- const parsed = engine.parseFile(filePath);
778
- if (parsed && Array.isArray(parsed.entities)) {
779
- const declarations = parsed.entities.map((e) => ({
780
- id: e.id ?? e.name,
781
- name: e.name,
782
- kind: e.kind,
783
- signature: e.signature ?? e.rawText?.split("\n")[0] ?? "",
784
- docComment: e.docComment
785
- }));
786
- chunks.push(...chunkCodeEntities(filePath, declarations));
787
- }
788
- } catch {
789
- }
790
- }
791
- }
792
- const records = [];
793
- for (const chunk of chunks) {
794
- try {
795
- const vector = await this.embedFn(chunk.content);
796
- records.push({ ...chunk, embedding: vector });
797
- } catch {
798
- }
799
- }
800
- if (records.length > 0) {
801
- this.store.upsertBatch(records);
802
- }
803
- return records.length;
804
- }
805
- /**
806
- * Index an issue (on create/update).
807
- */
808
- async indexIssue(issue) {
809
- this.store.deleteByEntity(`issue:${issue.id}`);
810
- const chunks = chunkIssue(issue);
811
- const records = [];
812
- for (const chunk of chunks) {
813
- try {
814
- const vector = await this.embedFn(chunk.content);
815
- records.push({ ...chunk, embedding: vector });
816
- } catch {
817
- }
818
- }
819
- if (records.length > 0) {
820
- this.store.upsertBatch(records);
821
- }
822
- return records.length;
823
- }
824
- /**
825
- * Index a milestone (on create).
826
- */
827
- async indexMilestone(milestone) {
828
- this.store.deleteByEntity(`milestone:${milestone.id}`);
829
- const chunks = chunkMilestone(milestone);
830
- const records = [];
831
- for (const chunk of chunks) {
832
- try {
833
- const vector = await this.embedFn(chunk.content);
834
- records.push({ ...chunk, embedding: vector });
835
- } catch {
836
- }
837
- }
838
- if (records.length > 0) {
839
- this.store.upsertBatch(records);
840
- }
841
- return records.length;
842
- }
843
- /**
844
- * Semantic search: embed query → vector search → ranked results.
845
- */
846
- async search(query, opts) {
847
- const queryVector = await this.embedFn(query);
848
- return this.store.search(queryVector, opts);
849
- }
850
- /**
851
- * Remove all data for a file.
852
- */
853
- removeFile(filePath) {
854
- this.store.deleteByFile(filePath);
855
- }
856
- /**
857
- * Get store statistics.
858
- */
859
- stats() {
860
- return {
861
- total: this.store.count(),
862
- byType: this.store.countByType()
863
- };
864
- }
865
- /**
866
- * Close the store.
867
- */
868
- close() {
869
- this.store.close();
870
- }
871
- };
872
- }
873
- });
874
-
875
- // src/embeddings/auto-embed.ts
876
- function entitySummaryText(entityId, facts, links) {
877
- const type = facts.find((f) => f.a === "type")?.v ?? "Entity";
878
- const name = facts.find((f) => f.a === "name" || f.a === "title")?.v ?? entityId;
879
- const parts = [`${type}: ${name} (${entityId})`];
880
- const attrs = facts.filter((f) => !["type", "name", "title", "createdAt", "updatedAt"].includes(f.a));
881
- if (attrs.length > 0) {
882
- parts.push(attrs.map((f) => ` ${f.a} = ${f.v}`).join("\n"));
883
- }
884
- if (links.length > 0) {
885
- parts.push("Relations:");
886
- parts.push(links.map((l) => ` ${l.a} \u2192 ${l.e2}`).join("\n"));
887
- }
888
- return parts.join("\n");
889
- }
890
- async function createAutoEmbedMiddleware(options) {
891
- const store = await VectorStore.create(options.dbPath);
892
- const embedFn = options.embedFn ?? embed;
893
- const embedIndividual = options.embedIndividualFacts ?? false;
894
- return {
895
- name: "auto-embed",
896
- handleOp: async (op, ctx, next) => {
897
- await next(op, ctx);
898
- try {
899
- await _processOp(op, store, embedFn, embedIndividual);
900
- } catch {
901
- }
902
- },
903
- close: () => {
904
- store.close();
905
- }
906
- };
907
- }
908
- async function _processOp(op, store, embedFn, embedIndividual) {
909
- const now = (/* @__PURE__ */ new Date()).toISOString();
910
- const entityIds = /* @__PURE__ */ new Set();
911
- if (op.facts) for (const f of op.facts) entityIds.add(f.e);
912
- if (op.links) for (const l of op.links) {
913
- entityIds.add(l.e1);
914
- entityIds.add(l.e2);
915
- }
916
- if (op.deleteFacts) for (const f of op.deleteFacts) entityIds.add(f.e);
917
- if (op.deleteLinks) for (const l of op.deleteLinks) {
918
- entityIds.add(l.e1);
919
- entityIds.add(l.e2);
920
- }
921
- if (op.deleteFacts || op.deleteLinks) {
922
- for (const eid of entityIds) {
923
- store.deleteByEntity(eid);
924
- }
925
- }
926
- if (op.facts && op.facts.length > 0) {
927
- const factsByEntity = /* @__PURE__ */ new Map();
928
- for (const f of op.facts) {
929
- const existing = factsByEntity.get(f.e) ?? [];
930
- existing.push(f);
931
- factsByEntity.set(f.e, existing);
932
- }
933
- const linksByEntity = /* @__PURE__ */ new Map();
934
- if (op.links) {
935
- for (const l of op.links) {
936
- const existing = linksByEntity.get(l.e1) ?? [];
937
- existing.push(l);
938
- linksByEntity.set(l.e1, existing);
939
- }
940
- }
941
- const records = [];
942
- for (const [eid, facts] of factsByEntity) {
943
- const links = linksByEntity.get(eid) ?? [];
944
- const summaryText = entitySummaryText(eid, facts, links);
945
- if (summaryText.trim()) {
946
- try {
947
- const vector = await embedFn(summaryText);
948
- records.push({
949
- id: `entity:${eid}:summary`,
950
- entityId: eid,
951
- content: summaryText,
952
- chunkType: "summary_md",
953
- updatedAt: now,
954
- embedding: vector
955
- });
956
- } catch {
957
- }
958
- }
959
- if (embedIndividual) {
960
- for (const fact of facts) {
961
- if (["type", "createdAt", "updatedAt"].includes(fact.a)) continue;
962
- const text = `${fact.a}: ${fact.v}`;
963
- try {
964
- const vector = await embedFn(text);
965
- records.push({
966
- id: `entity:${eid}:fact:${fact.a}`,
967
- entityId: eid,
968
- content: text,
969
- chunkType: "doc_comment",
970
- updatedAt: now,
971
- embedding: vector
972
- });
973
- } catch {
974
- }
975
- }
976
- }
977
- }
978
- if (records.length > 0) {
979
- store.upsertBatch(records);
980
- }
981
- }
982
- }
983
- async function buildRAGContext(query, vectorStore, embedFn = embed, options) {
984
- const maxChunks = options?.maxChunks ?? 10;
985
- const maxTokens = options?.maxTokens ?? 4e3;
986
- const minScore = options?.minScore ?? 0.1;
987
- const queryVector = await embedFn(query);
988
- const results = vectorStore.search(queryVector, {
989
- limit: maxChunks * 2,
990
- minScore
991
- });
992
- const chunks = [];
993
- let totalChars = 0;
994
- for (const r of results) {
995
- if (chunks.length >= maxChunks) break;
996
- if (totalChars + r.chunk.content.length > maxTokens * 4) break;
997
- chunks.push({
998
- content: r.chunk.content,
999
- entityId: r.chunk.entityId,
1000
- score: r.score,
1001
- chunkType: r.chunk.chunkType
1002
- });
1003
- totalChars += r.chunk.content.length;
1004
- }
1005
- return {
1006
- query,
1007
- chunks,
1008
- estimatedTokens: Math.ceil(totalChars / 4)
1009
- };
1010
- }
1011
- var init_auto_embed = __esm({
1012
- "src/embeddings/auto-embed.ts"() {
1013
- "use strict";
1014
- init_store();
1015
- init_model();
1016
- }
1017
- });
1018
-
1019
- // src/embeddings/index.ts
1020
- var embeddings_exports = {};
1021
- __export(embeddings_exports, {
1022
- DEFAULT_MODEL_CONFIG: () => DEFAULT_MODEL_CONFIG,
1023
- EmbeddingManager: () => EmbeddingManager,
1024
- VectorStore: () => VectorStore,
1025
- buildRAGContext: () => buildRAGContext,
1026
- chunkCodeEntities: () => chunkCodeEntities,
1027
- chunkDecision: () => chunkDecision,
1028
- chunkDocComments: () => chunkDocComments,
1029
- chunkFile: () => chunkFile,
1030
- chunkIssue: () => chunkIssue,
1031
- chunkMarkdown: () => chunkMarkdown,
1032
- chunkMilestone: () => chunkMilestone,
1033
- chunkSummary: () => chunkSummary,
1034
- cosineSimilarity: () => cosineSimilarity,
1035
- createAutoEmbedMiddleware: () => createAutoEmbedMiddleware,
1036
- embed: () => embed,
1037
- embedBatch: () => embedBatch,
1038
- loadModel: () => loadModel,
1039
- resetModel: () => resetModel,
1040
- slidingWindow: () => slidingWindow
1041
- });
1042
- var init_embeddings = __esm({
1043
- "src/embeddings/index.ts"() {
1044
- init_types();
1045
- init_model();
1046
- init_store();
1047
- init_search();
1048
- init_auto_embed();
1049
- init_chunker();
1050
- }
1051
- });
1052
-
1053
- export {
1054
- DEFAULT_MODEL_CONFIG,
1055
- loadModel,
1056
- embed,
1057
- embedBatch,
1058
- resetModel,
1059
- init_model,
1060
- VectorStore,
1061
- cosineSimilarity,
1062
- init_store,
1063
- chunkIssue,
1064
- chunkDecision,
1065
- chunkMilestone,
1066
- chunkMarkdown,
1067
- chunkCodeEntities,
1068
- chunkDocComments,
1069
- chunkSummary,
1070
- chunkFile,
1071
- slidingWindow,
1072
- EmbeddingManager,
1073
- createAutoEmbedMiddleware,
1074
- buildRAGContext,
1075
- init_auto_embed,
1076
- embeddings_exports,
1077
- init_embeddings
1078
- };