@remnic/core 9.69.78 → 9.69.80

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 (105) hide show
  1. package/dist/access-admin-ops-surface.js +2 -2
  2. package/dist/access-authorization-probe.js +3 -3
  3. package/dist/access-boundary.js +2 -2
  4. package/dist/access-cli.js +21 -21
  5. package/dist/access-extraction-force-flush.js +2 -2
  6. package/dist/access-http-briefing.js +3 -3
  7. package/dist/access-http-lcm-compaction.d.ts +2 -1
  8. package/dist/access-http-lcm-compaction.d.ts.map +1 -1
  9. package/dist/access-http-lcm-compaction.js +1 -1
  10. package/dist/access-http-lifecycle-flush.d.ts.map +1 -1
  11. package/dist/access-http-lifecycle-flush.js +2 -2
  12. package/dist/access-http-query.js +2 -2
  13. package/dist/access-http.js +16 -16
  14. package/dist/access-identity-continuity-surface.js +2 -2
  15. package/dist/access-lcm-surface.js +2 -2
  16. package/dist/access-mcp.js +9 -9
  17. package/dist/access-namespace-preflight.js +2 -2
  18. package/dist/access-observe-write-surface.js +2 -2
  19. package/dist/access-operations-batch.js +3 -3
  20. package/dist/access-operations.js +8 -8
  21. package/dist/access-recall-concurrency.js +2 -2
  22. package/dist/access-recall-response.js +2 -2
  23. package/dist/access-recall-surface.js +2 -2
  24. package/dist/access-service-helpers.d.ts +1 -0
  25. package/dist/access-service-helpers.d.ts.map +1 -1
  26. package/dist/access-service-helpers.js +1 -1
  27. package/dist/access-service.js +2 -2
  28. package/dist/access-surface-catalog.js +4 -4
  29. package/dist/{chunk-TIDEL77O.js → chunk-2BPPGNAQ.js} +4 -3
  30. package/dist/chunk-2BPPGNAQ.js.map +1 -0
  31. package/dist/{chunk-JA64OVTE.js → chunk-3GN2PEOT.js} +2 -2
  32. package/dist/{chunk-TIVPGSGO.js → chunk-4V44AA7O.js} +2 -2
  33. package/dist/{chunk-2L5FSNPC.js → chunk-5FNZ3G6X.js} +40 -11
  34. package/dist/chunk-5FNZ3G6X.js.map +1 -0
  35. package/dist/{chunk-TS6WB2CL.js → chunk-7QK5TUTW.js} +2 -2
  36. package/dist/{chunk-WGXUEXSV.js → chunk-B47OHVFT.js} +3 -3
  37. package/dist/chunk-B47OHVFT.js.map +1 -0
  38. package/dist/{chunk-3QL24R5Y.js → chunk-C2WWQ4OR.js} +1 -1
  39. package/dist/chunk-C2WWQ4OR.js.map +1 -0
  40. package/dist/{chunk-DZQ734SM.js → chunk-C7JAUNFC.js} +2 -2
  41. package/dist/{chunk-GZ3R6XOE.js → chunk-DJSJ4ULL.js} +22 -12
  42. package/dist/chunk-DJSJ4ULL.js.map +1 -0
  43. package/dist/{chunk-7R4DKXKP.js → chunk-GEX5NI36.js} +2 -2
  44. package/dist/{chunk-MJQ3QF7Y.js → chunk-HKFJ3PF3.js} +2 -2
  45. package/dist/{chunk-P6GTQGGB.js → chunk-JXMECXMF.js} +2 -2
  46. package/dist/{chunk-2IAAJS3R.js → chunk-KERNN6BC.js} +2 -2
  47. package/dist/{chunk-TPDBFYEG.js → chunk-MMCO4SRG.js} +17 -6
  48. package/dist/chunk-MMCO4SRG.js.map +1 -0
  49. package/dist/{chunk-BIFFCC62.js → chunk-NMBX4D7P.js} +2 -2
  50. package/dist/{chunk-AFZWKVEX.js → chunk-Q5TRJ4BX.js} +5 -5
  51. package/dist/{chunk-H4USONK4.js → chunk-QB75LKQQ.js} +2 -2
  52. package/dist/{chunk-OXE7KNFJ.js → chunk-RDEUG2M2.js} +3 -3
  53. package/dist/{chunk-3NYCO5Q5.js → chunk-SVZWVZ7E.js} +4 -4
  54. package/dist/chunk-SVZWVZ7E.js.map +1 -0
  55. package/dist/{chunk-B5TUL5KO.js → chunk-TEV2JGU5.js} +10 -10
  56. package/dist/{chunk-54CG7SO6.js → chunk-X22B4KTI.js} +4 -4
  57. package/dist/cli.js +17 -17
  58. package/dist/external-wiki-access.js +3 -3
  59. package/dist/index.js +21 -21
  60. package/dist/lcm/engine.d.ts +2 -2
  61. package/dist/lcm/engine.d.ts.map +1 -1
  62. package/dist/lcm/engine.js +2 -2
  63. package/dist/lcm/index.js +2 -2
  64. package/dist/lcm/queue.d.ts +1 -1
  65. package/dist/lcm/queue.d.ts.map +1 -1
  66. package/dist/lcm/queue.js +1 -1
  67. package/dist/memory-browse-operations.js +3 -3
  68. package/dist/orchestrator.js +21 -21
  69. package/dist/recall-navigation-operations.js +3 -3
  70. package/dist/recall-navigation.js +2 -2
  71. package/dist/support-passport/index.js +5 -5
  72. package/package.json +2 -2
  73. package/src/access-http-extraction-force-flush.test.ts +6 -2
  74. package/src/access-http-lcm-compaction.abort.test.ts +60 -0
  75. package/src/access-http-lcm-compaction.ts +20 -9
  76. package/src/access-http-lifecycle-flush.ts +1 -0
  77. package/src/access-http.test.ts +4 -2
  78. package/src/access-operations-batch.ts +1 -1
  79. package/src/access-service-helpers.ts +1 -0
  80. package/src/access-service.ts +2 -2
  81. package/src/lcm/engine.ts +39 -9
  82. package/src/lcm/queue.test.ts +19 -0
  83. package/src/lcm/queue.ts +16 -5
  84. package/src/lcm-engine.test.ts +72 -0
  85. package/dist/chunk-2L5FSNPC.js.map +0 -1
  86. package/dist/chunk-3NYCO5Q5.js.map +0 -1
  87. package/dist/chunk-3QL24R5Y.js.map +0 -1
  88. package/dist/chunk-GZ3R6XOE.js.map +0 -1
  89. package/dist/chunk-TIDEL77O.js.map +0 -1
  90. package/dist/chunk-TPDBFYEG.js.map +0 -1
  91. package/dist/chunk-WGXUEXSV.js.map +0 -1
  92. /package/dist/{chunk-JA64OVTE.js.map → chunk-3GN2PEOT.js.map} +0 -0
  93. /package/dist/{chunk-TIVPGSGO.js.map → chunk-4V44AA7O.js.map} +0 -0
  94. /package/dist/{chunk-TS6WB2CL.js.map → chunk-7QK5TUTW.js.map} +0 -0
  95. /package/dist/{chunk-DZQ734SM.js.map → chunk-C7JAUNFC.js.map} +0 -0
  96. /package/dist/{chunk-7R4DKXKP.js.map → chunk-GEX5NI36.js.map} +0 -0
  97. /package/dist/{chunk-MJQ3QF7Y.js.map → chunk-HKFJ3PF3.js.map} +0 -0
  98. /package/dist/{chunk-P6GTQGGB.js.map → chunk-JXMECXMF.js.map} +0 -0
  99. /package/dist/{chunk-2IAAJS3R.js.map → chunk-KERNN6BC.js.map} +0 -0
  100. /package/dist/{chunk-BIFFCC62.js.map → chunk-NMBX4D7P.js.map} +0 -0
  101. /package/dist/{chunk-AFZWKVEX.js.map → chunk-Q5TRJ4BX.js.map} +0 -0
  102. /package/dist/{chunk-H4USONK4.js.map → chunk-QB75LKQQ.js.map} +0 -0
  103. /package/dist/{chunk-OXE7KNFJ.js.map → chunk-RDEUG2M2.js.map} +0 -0
  104. /package/dist/{chunk-B5TUL5KO.js.map → chunk-TEV2JGU5.js.map} +0 -0
  105. /package/dist/{chunk-54CG7SO6.js.map → chunk-X22B4KTI.js.map} +0 -0
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  SUPPORT_PASSPORT_OWNER_HTTP_ROUTES
3
- } from "./chunk-MJQ3QF7Y.js";
3
+ } from "./chunk-HKFJ3PF3.js";
4
4
  import {
5
5
  SUPPORT_PASSPORT_PUBLIC_HTTP_ROUTES
6
- } from "./chunk-TS6WB2CL.js";
7
- import "./chunk-3NYCO5Q5.js";
6
+ } from "./chunk-7QK5TUTW.js";
7
+ import "./chunk-SVZWVZ7E.js";
8
8
  import "./chunk-W4F3C7N7.js";
9
9
  import "./chunk-MPC7TYTZ.js";
10
10
  import "./chunk-H36X4NRH.js";
@@ -171,7 +171,7 @@ import "./chunk-W5BIQOAJ.js";
171
171
  import "./chunk-Z7L72ZHL.js";
172
172
  import "./chunk-4O4TKIXQ.js";
173
173
  import "./chunk-C5C7IJ4Q.js";
174
- import "./chunk-3QL24R5Y.js";
174
+ import "./chunk-C2WWQ4OR.js";
175
175
  import "./chunk-SYOIVK7K.js";
176
176
  import "./chunk-TY446V34.js";
177
177
  import "./chunk-BMYZTZ5D.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  runLcmCompactionFlushHttp,
3
3
  runLcmCompactionRecordHttp
4
- } from "./chunk-GZ3R6XOE.js";
4
+ } from "./chunk-DJSJ4ULL.js";
5
5
 
6
6
  // src/access-http-lifecycle-flush.ts
7
7
  async function maybeHandleLifecycleFlush(deps, method, pathname, abortSignal) {
@@ -16,7 +16,8 @@ async function maybeHandleLifecycleFlush(deps, method, pathname, abortSignal) {
16
16
  recordWriteRateLimitHit: deps.recordWriteRateLimitHit,
17
17
  resolveNamespace: deps.resolveNamespace,
18
18
  defaultNamespace: deps.defaultNamespace,
19
- resolveRequestPrincipal: deps.resolveRequestPrincipal
19
+ resolveRequestPrincipal: deps.resolveRequestPrincipal,
20
+ abortSignal
20
21
  });
21
22
  deps.respondJson(response);
22
23
  return true;
@@ -62,4 +63,4 @@ async function maybeHandleLifecycleFlush(deps, method, pathname, abortSignal) {
62
63
  export {
63
64
  maybeHandleLifecycleFlush
64
65
  };
65
- //# sourceMappingURL=chunk-TIDEL77O.js.map
66
+ //# sourceMappingURL=chunk-2BPPGNAQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/access-http-lifecycle-flush.ts"],"sourcesContent":["import type { OperationName } from \"./access-boundary.js\";\nimport { runLcmCompactionFlushHttp, runLcmCompactionRecordHttp } from \"./access-http-lcm-compaction.js\";\nimport type { LcmCompactionFlushRequest, LcmCompactionRecordRequest } from \"./access-schema.js\";\nimport type { EngramAccessExtractionForceFlushRequest, EngramAccessService } from \"./access-service.js\";\n\nexport interface LifecycleFlushHttpDeps {\n service: Pick<EngramAccessService, \"extractionForceFlush\" | \"lcmCompactionFlush\" | \"lcmCompactionRecord\">;\n enforceTokenOp(op: OperationName): void;\n defaultNamespace?: string;\n readValidatedBody(schemaName: \"lcmCompactionFlush\"): Promise<LcmCompactionFlushRequest>;\n readValidatedBody(schemaName: \"lcmCompactionRecord\"): Promise<LcmCompactionRecordRequest>;\n readValidatedBody(schemaName: \"extractionForceFlush\"): Promise<EngramAccessExtractionForceFlushRequest>;\n ensureWriteRateLimitAvailable(): void;\n resolveNamespace(namespace: string | undefined): string | undefined;\n resolveRequestPrincipal(): string | undefined;\n recordWriteRateLimitHit(): void;\n respondJson(payload: unknown): void;\n}\n\nexport async function maybeHandleLifecycleFlush(\n deps: LifecycleFlushHttpDeps,\n method: string | undefined,\n pathname: string,\n abortSignal: AbortSignal\n): Promise<boolean> {\n if (method !== \"POST\") return false;\n if (pathname === \"/engram/v1/lcm/compaction/flush\" || pathname === \"/remnic/v1/lcm/compaction/flush\") {\n deps.enforceTokenOp(\"lcm_compaction_flush\");\n const body = await deps.readValidatedBody(\"lcmCompactionFlush\");\n const response = await runLcmCompactionFlushHttp({\n body,\n service: deps.service,\n ensureWriteRateLimitAvailable: deps.ensureWriteRateLimitAvailable,\n recordWriteRateLimitHit: deps.recordWriteRateLimitHit,\n resolveNamespace: deps.resolveNamespace,\n defaultNamespace: deps.defaultNamespace,\n resolveRequestPrincipal: deps.resolveRequestPrincipal,\n abortSignal,\n });\n deps.respondJson(response);\n return true;\n }\n\n if (pathname === \"/engram/v1/lcm/compaction/record\" || pathname === \"/remnic/v1/lcm/compaction/record\") {\n deps.enforceTokenOp(\"lcm_compaction_record\");\n const body = await deps.readValidatedBody(\"lcmCompactionRecord\");\n const response = await runLcmCompactionRecordHttp({\n body,\n service: deps.service,\n ensureWriteRateLimitAvailable: deps.ensureWriteRateLimitAvailable,\n recordWriteRateLimitHit: deps.recordWriteRateLimitHit,\n resolveNamespace: deps.resolveNamespace,\n resolveRequestPrincipal: deps.resolveRequestPrincipal,\n });\n deps.respondJson(response);\n return true;\n }\n\n if (pathname === \"/engram/v1/extraction/flush\" || pathname === \"/remnic/v1/extraction/flush\") {\n deps.enforceTokenOp(\"extraction_force_flush\");\n const body = await deps.readValidatedBody(\"extractionForceFlush\");\n deps.ensureWriteRateLimitAvailable();\n let writeRateLimitRecorded = false;\n const recordCommittedWrite = (): void => {\n if (writeRateLimitRecorded) return;\n writeRateLimitRecorded = true;\n deps.recordWriteRateLimitHit();\n };\n const response = await deps.service.extractionForceFlush({\n ...body,\n namespace: deps.resolveNamespace(body.namespace),\n authenticatedPrincipal: deps.resolveRequestPrincipal(),\n abortSignal,\n onCommitted: recordCommittedWrite,\n });\n recordCommittedWrite();\n deps.respondJson(response);\n return true;\n }\n\n return false;\n}\n"],"mappings":";;;;;;AAmBA,eAAsB,0BACpB,MACA,QACA,UACA,aACkB;AAClB,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,aAAa,qCAAqC,aAAa,mCAAmC;AACpG,SAAK,eAAe,sBAAsB;AAC1C,UAAM,OAAO,MAAM,KAAK,kBAAkB,oBAAoB;AAC9D,UAAM,WAAW,MAAM,0BAA0B;AAAA,MAC/C;AAAA,MACA,SAAS,KAAK;AAAA,MACd,+BAA+B,KAAK;AAAA,MACpC,yBAAyB,KAAK;AAAA,MAC9B,kBAAkB,KAAK;AAAA,MACvB,kBAAkB,KAAK;AAAA,MACvB,yBAAyB,KAAK;AAAA,MAC9B;AAAA,IACF,CAAC;AACD,SAAK,YAAY,QAAQ;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,sCAAsC,aAAa,oCAAoC;AACtG,SAAK,eAAe,uBAAuB;AAC3C,UAAM,OAAO,MAAM,KAAK,kBAAkB,qBAAqB;AAC/D,UAAM,WAAW,MAAM,2BAA2B;AAAA,MAChD;AAAA,MACA,SAAS,KAAK;AAAA,MACd,+BAA+B,KAAK;AAAA,MACpC,yBAAyB,KAAK;AAAA,MAC9B,kBAAkB,KAAK;AAAA,MACvB,yBAAyB,KAAK;AAAA,IAChC,CAAC;AACD,SAAK,YAAY,QAAQ;AACzB,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,iCAAiC,aAAa,+BAA+B;AAC5F,SAAK,eAAe,wBAAwB;AAC5C,UAAM,OAAO,MAAM,KAAK,kBAAkB,sBAAsB;AAChE,SAAK,8BAA8B;AACnC,QAAI,yBAAyB;AAC7B,UAAM,uBAAuB,MAAY;AACvC,UAAI,uBAAwB;AAC5B,+BAAyB;AACzB,WAAK,wBAAwB;AAAA,IAC/B;AACA,UAAM,WAAW,MAAM,KAAK,QAAQ,qBAAqB;AAAA,MACvD,GAAG;AAAA,MACH,WAAW,KAAK,iBAAiB,KAAK,SAAS;AAAA,MAC/C,wBAAwB,KAAK,wBAAwB;AAAA,MACrD;AAAA,MACA,aAAa;AAAA,IACf,CAAC;AACD,yBAAqB;AACrB,SAAK,YAAY,QAAQ;AACzB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineOperation
3
- } from "./chunk-3NYCO5Q5.js";
3
+ } from "./chunk-SVZWVZ7E.js";
4
4
  import {
5
5
  EngramAccessInputError
6
6
  } from "./chunk-3MUKQQ7A.js";
@@ -71,4 +71,4 @@ defineOperation({
71
71
  })
72
72
  })
73
73
  });
74
- //# sourceMappingURL=chunk-JA64OVTE.js.map
74
+ //# sourceMappingURL=chunk-3GN2PEOT.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-7T4TOGMS.js";
4
4
  import {
5
5
  defineOperation
6
- } from "./chunk-3NYCO5Q5.js";
6
+ } from "./chunk-SVZWVZ7E.js";
7
7
 
8
8
  // src/external-wiki-access.ts
9
9
  import { z } from "zod";
@@ -26,4 +26,4 @@ var externalWikiSearchOperation = defineOperation({
26
26
  export {
27
27
  externalWikiSearchOperation
28
28
  };
29
- //# sourceMappingURL=chunk-TIVPGSGO.js.map
29
+ //# sourceMappingURL=chunk-4V44AA7O.js.map
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-7N4KAIGN.js";
14
14
  import {
15
15
  LcmWorkQueue
16
- } from "./chunk-TPDBFYEG.js";
16
+ } from "./chunk-MMCO4SRG.js";
17
17
  import {
18
18
  assembleCompressedHistoryWithTrace
19
19
  } from "./chunk-UXPUUL3G.js";
@@ -32,6 +32,17 @@ function positiveInteger(value, fallback, min = 1) {
32
32
  if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
33
33
  return Math.max(min, Math.floor(value));
34
34
  }
35
+ function abortOnSignal(abortSignal, work) {
36
+ if (abortSignal === void 0) return work;
37
+ abortSignal.throwIfAborted();
38
+ return new Promise((resolve, reject) => {
39
+ const onAbort = () => {
40
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new DOMException("Aborted", "AbortError"));
41
+ };
42
+ abortSignal.addEventListener("abort", onAbort, { once: true });
43
+ work.then(resolve, reject).finally(() => abortSignal.removeEventListener("abort", onAbort));
44
+ });
45
+ }
35
46
  function extractLcmConfig(cfg) {
36
47
  return {
37
48
  enabled: cfg.lcmEnabled === true,
@@ -228,14 +239,16 @@ var LcmEngine = class {
228
239
  await this.waitForPendingObserveInitIdle();
229
240
  await this.observeQueue?.whenIdle();
230
241
  }
231
- async waitForSessionObserveIdle(sessionId) {
242
+ async waitForSessionObserveIdle(sessionId, abortSignal) {
243
+ abortSignal?.throwIfAborted();
232
244
  if (!this.config.enabled || this.closed) return;
233
245
  const normalizedSessionId = normalizeLcmSessionId(sessionId);
234
246
  if (!normalizedSessionId) return;
235
247
  await this.ensureInitialized();
248
+ abortSignal?.throwIfAborted();
236
249
  if (this.closed) return;
237
- await this.waitForPendingObserveInitIdle(normalizedSessionId);
238
- await this.observeQueue?.whenSessionIdle(normalizedSessionId);
250
+ await this.waitForPendingObserveInitIdle(normalizedSessionId, abortSignal);
251
+ await this.observeQueue?.whenSessionIdle(normalizedSessionId, abortSignal) ?? Promise.resolve();
239
252
  }
240
253
  reservePendingObserveInit(sessionId) {
241
254
  const count = this.pendingObserveInitCounts.get(sessionId) ?? 0;
@@ -260,13 +273,25 @@ var LcmEngine = class {
260
273
  }
261
274
  this.pendingObserveInitCounts.set(sessionId, count - 1);
262
275
  }
263
- async waitForPendingObserveInitIdle(sessionId) {
276
+ async waitForPendingObserveInitIdle(sessionId, abortSignal) {
277
+ abortSignal?.throwIfAborted();
264
278
  if (sessionId) {
265
279
  if (!this.pendingObserveInitCounts.has(sessionId)) return;
266
- await new Promise((resolve) => {
280
+ await new Promise((resolve, reject) => {
281
+ const finish = () => {
282
+ abortSignal?.removeEventListener("abort", onAbort);
283
+ resolve();
284
+ };
285
+ const onAbort = () => {
286
+ const remaining = (this.pendingObserveInitWaiters.get(sessionId) ?? []).filter((waiter) => waiter !== finish);
287
+ if (remaining.length === 0) this.pendingObserveInitWaiters.delete(sessionId);
288
+ else this.pendingObserveInitWaiters.set(sessionId, remaining);
289
+ reject(abortSignal?.reason instanceof Error ? abortSignal.reason : new DOMException("Aborted", "AbortError"));
290
+ };
267
291
  const waiters = this.pendingObserveInitWaiters.get(sessionId) ?? [];
268
- waiters.push(resolve);
292
+ waiters.push(finish);
269
293
  this.pendingObserveInitWaiters.set(sessionId, waiters);
294
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
270
295
  });
271
296
  return;
272
297
  }
@@ -320,15 +345,19 @@ var LcmEngine = class {
320
345
  ${lines.join("\n")}` : "";
321
346
  }
322
347
  /** Flush pending summaries before compaction (called from before_compaction hook). */
323
- async preCompactionFlush(sessionId) {
348
+ async preCompactionFlush(sessionId, abortSignal) {
349
+ abortSignal?.throwIfAborted();
324
350
  if (!this.config.enabled) return;
325
351
  const normalizedSessionId = normalizeLcmSessionId(sessionId);
326
352
  if (!normalizedSessionId) return;
327
353
  await this.ensureInitialized();
328
- await this.waitForSessionObserveIdle(normalizedSessionId);
354
+ abortSignal?.throwIfAborted();
355
+ await this.waitForSessionObserveIdle(normalizedSessionId, abortSignal);
356
+ abortSignal?.throwIfAborted();
329
357
  try {
330
- await this.summarizer.summarizeIncremental(normalizedSessionId);
358
+ await abortOnSignal(abortSignal, this.summarizer.summarizeIncremental(normalizedSessionId));
331
359
  } catch (err) {
360
+ if (abortSignal?.aborted) throw err;
332
361
  log.debug(`LCM pre-compaction flush error: ${err}`);
333
362
  }
334
363
  }
@@ -573,4 +602,4 @@ export {
573
602
  extractLcmConfig,
574
603
  LcmEngine
575
604
  };
576
- //# sourceMappingURL=chunk-2L5FSNPC.js.map
605
+ //# sourceMappingURL=chunk-5FNZ3G6X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lcm/engine.ts"],"sourcesContent":["import type Database from \"better-sqlite3\";\nimport { openLcmDatabase, ensureLcmStateDir } from \"./schema.js\";\nimport { LcmArchive, type LcmMessage, type LcmStructuredRecallMatch } from \"./archive.js\";\nimport { LcmDag } from \"./dag.js\";\nimport { LcmSummarizer, type SummarizeFn } from \"./summarizer.js\";\nimport {\n assembleCompressedHistoryWithTrace,\n type LcmRecallConfig,\n type LcmRecallWithTraceResult,\n} from \"./recall.js\";\nimport { LcmWorkQueue, type LcmObserveMessage } from \"./queue.js\";\nimport type { PluginConfig } from \"../types.js\";\nimport { estimateTokenCount } from \"../token-estimate.js\";\nimport { log } from \"../logger.js\";\nimport { nativeBindingRecoveryHint } from \"../native-binding-hint.js\";\nexport interface LcmEngineConfig {\n enabled: boolean;\n leafBatchSize: number;\n rollupFanIn: number;\n freshTailTurns: number;\n maxDepth: number;\n deterministicMaxTokens: number;\n archiveRetentionDays: number;\n recallBudgetShare: number;\n observeConcurrency: number;\n telemetryPrefilterEnabled: boolean;\n messagePartsEnabled: boolean;\n messagePartsRecallMaxResults: number;\n}\n\n/** An expanded archive row with stable lineage identity; content may be budget-truncated. */\nexport interface LcmExpandedMessage {\n id: number;\n session_id: string;\n turn_index: number;\n role: string;\n content: string;\n}\n\nfunction positiveInteger(value: unknown, fallback: number, min = 1): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n return Math.max(min, Math.floor(value));\n}\n\nfunction abortOnSignal<T>(abortSignal: AbortSignal | undefined, work: Promise<T>): Promise<T> {\n if (abortSignal === undefined) return work;\n abortSignal.throwIfAborted();\n return new Promise((resolve, reject) => {\n const onAbort = (): void => {\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new DOMException(\"Aborted\", \"AbortError\"));\n };\n abortSignal.addEventListener(\"abort\", onAbort, { once: true });\n work.then(resolve, reject).finally(() => abortSignal.removeEventListener(\"abort\", onAbort));\n });\n}\n\nexport function extractLcmConfig(cfg: PluginConfig): LcmEngineConfig {\n return {\n enabled: (cfg as any).lcmEnabled === true,\n leafBatchSize: positiveInteger((cfg as any).lcmLeafBatchSize, 8),\n rollupFanIn: positiveInteger((cfg as any).lcmRollupFanIn, 4, 2),\n freshTailTurns: positiveInteger((cfg as any).lcmFreshTailTurns, 16),\n maxDepth: positiveInteger((cfg as any).lcmMaxDepth, 5),\n deterministicMaxTokens: positiveInteger((cfg as any).lcmDeterministicMaxTokens, 512),\n archiveRetentionDays: positiveInteger((cfg as any).lcmArchiveRetentionDays, 90, 0),\n recallBudgetShare: (cfg as any).lcmRecallBudgetShare ?? 0.15,\n observeConcurrency:\n typeof (cfg as any).lcmObserveConcurrency === \"number\" &&\n Number.isFinite((cfg as any).lcmObserveConcurrency)\n ? Math.max(1, Math.floor((cfg as any).lcmObserveConcurrency))\n : 1,\n telemetryPrefilterEnabled: (cfg as any).lcmTelemetryPrefilterEnabled !== false,\n messagePartsEnabled: (cfg as any).messagePartsEnabled === true,\n messagePartsRecallMaxResults:\n typeof (cfg as any).messagePartsRecallMaxResults === \"number\"\n ? Math.max(0, Math.floor((cfg as any).messagePartsRecallMaxResults))\n : 6,\n };\n}\n\nfunction normalizeLcmSessionId(sessionId: string): string {\n return sessionId.trim();\n}\n\nfunction normalizeOptionalLcmSessionId(sessionId?: string): string | undefined {\n if (sessionId === undefined) {\n return undefined;\n }\n const normalized = normalizeLcmSessionId(sessionId);\n return normalized.length > 0 ? normalized : undefined;\n}\n\nconst EMPTY_LCM_STATS = {\n totalMessages: 0,\n totalSummaryNodes: 0,\n maxDepth: -1,\n} as const;\n\nexport class LcmEngine {\n private db: Database.Database | null = null;\n private archive: LcmArchive | null = null;\n private dag: LcmDag | null = null;\n private summarizer: LcmSummarizer | null = null;\n private observeQueue: LcmWorkQueue | null = null;\n private closed = false;\n private readonly config: LcmEngineConfig;\n private readonly memoryDir: string;\n private initPromise: Promise<void> | null = null;\n private readonly pendingObserveInitCounts = new Map<string, number>();\n private readonly pendingObserveInitWaiters = new Map<string, Array<() => void>>();\n private readonly pendingObserveInitIdleWaiters: Array<() => void> = [];\n\n constructor(\n pluginConfig: PluginConfig,\n private readonly summarizeFn: SummarizeFn,\n ) {\n this.config = extractLcmConfig(pluginConfig);\n this.memoryDir = pluginConfig.memoryDir;\n }\n\n get enabled(): boolean {\n return this.config.enabled;\n }\n\n /** Lazy init — open database on first use. */\n async ensureInitialized(): Promise<void> {\n if (this.closed) return;\n if (this.db) return;\n if (this.initPromise) {\n await this.initPromise;\n return;\n }\n this.initPromise = this.doInit().catch((err) => {\n // Reset so next call retries instead of caching the failure\n this.initPromise = null;\n throw err;\n });\n await this.initPromise;\n }\n\n private async doInit(): Promise<void> {\n await ensureLcmStateDir(this.memoryDir);\n const db = openLcmDatabase(this.memoryDir);\n const archive = new LcmArchive(db);\n const dag = new LcmDag(db);\n const { telemetryPrefilterEnabled } = this.config;\n const summarizer = new LcmSummarizer(\n archive,\n dag,\n this.summarizeFn,\n {\n leafBatchSize: this.config.leafBatchSize,\n rollupFanIn: this.config.rollupFanIn,\n maxDepth: this.config.maxDepth,\n deterministicMaxTokens: this.config.deterministicMaxTokens,\n telemetryPrefilterEnabled,\n },\n );\n const observeQueue = new LcmWorkQueue({\n concurrency: this.config.observeConcurrency,\n worker: async (sessionId, messages) => {\n await this.processObserveMessages(sessionId, messages);\n },\n hooks: {\n onJobStart: ({ sessionId, depth, inFlight, waitMs }) => {\n log.debug(\n `LCM observe queue start: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms`,\n );\n },\n onJobFinish: ({\n sessionId,\n depth,\n inFlight,\n waitMs,\n runMs,\n totalMs,\n error,\n }) => {\n if (error) {\n log.error(\n `LCM observe queue failure: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms, run=${runMs}ms, total=${totalMs}ms, error=${error}`,\n );\n return;\n }\n\n log.debug(\n `LCM observe queue finish: session=${sessionId}, depth=${depth}, inFlight=${inFlight}, wait=${waitMs}ms, run=${runMs}ms, total=${totalMs}ms`,\n );\n },\n },\n });\n\n if (this.closed) {\n db.close();\n return;\n }\n\n this.db = db;\n this.archive = archive;\n this.dag = dag;\n this.summarizer = summarizer;\n this.observeQueue = observeQueue;\n log.info(\"LCM engine initialized\");\n }\n\n /**\n * Enqueue messages from agent_end hook.\n * The queue worker performs the archive append and incremental summarization.\n */\n async observeMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): Promise<void> {\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n this.enqueueObserveMessages(normalizedSessionId, messages);\n }\n\n /** Enqueue an observe job without waiting for worker completion. */\n enqueueObserveMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): void {\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n if (messages.length === 0) return;\n\n this.reservePendingObserveInit(normalizedSessionId);\n\n void this.ensureInitialized()\n .then(() => {\n if (this.closed || !this.observeQueue) return;\n this.observeQueue.enqueue(normalizedSessionId, messages);\n log.debug(\n `LCM observe enqueued: session=${normalizedSessionId}, depth=${this.observeQueue.depth}, inFlight=${this.observeQueue.inFlightCount}`,\n );\n })\n .catch((err) => {\n if (this.closed) return;\n log.error(\n `LCM observe enqueue initialization error: ${err}${nativeBindingRecoveryHint(err)}`,\n );\n })\n .finally(() => {\n this.releasePendingObserveInit(normalizedSessionId);\n });\n }\n\n private async processObserveMessages(\n sessionId: string,\n messages: LcmObserveMessage[],\n ): Promise<void> {\n if (this.closed) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.summarizer) return;\n\n if (messages.length === 0) return;\n\n const currentMax = this.archive.getMaxTurnIndex(sessionId);\n const { messagePartsEnabled } = this.config;\n const newMessages = messages.map((m, i) => ({\n turnIndex: currentMax + 1 + i,\n role: m.role,\n content: m.content,\n parts: messagePartsEnabled ? m.parts : undefined,\n rawContent: messagePartsEnabled ? m.rawContent : undefined,\n sourceFormat: messagePartsEnabled ? m.sourceFormat : undefined,\n }));\n\n this.archive.appendMessages(sessionId, newMessages, {\n messagePartsEnabled,\n });\n\n // Trigger incremental summarization inside the worker, after append.\n try {\n await this.summarizer.summarizeIncremental(sessionId);\n } catch (err) {\n log.debug(`LCM incremental summarization error: ${err}`);\n }\n }\n\n get observeQueueDepth(): number {\n return this.observeQueue?.depth ?? 0;\n }\n\n get observeQueueInFlightCount(): number {\n return this.observeQueue?.inFlightCount ?? 0;\n }\n\n async waitForObserveQueueIdle(): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n await this.ensureInitialized();\n if (this.closed) return;\n await this.waitForPendingObserveInitIdle();\n await this.observeQueue?.whenIdle();\n }\n\n async waitForSessionObserveIdle(sessionId: string, abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n abortSignal?.throwIfAborted();\n if (this.closed) return;\n await this.waitForPendingObserveInitIdle(normalizedSessionId, abortSignal);\n await this.observeQueue?.whenSessionIdle(normalizedSessionId, abortSignal) ?? Promise.resolve();\n }\n\n private reservePendingObserveInit(sessionId: string): void {\n const count = this.pendingObserveInitCounts.get(sessionId) ?? 0;\n this.pendingObserveInitCounts.set(sessionId, count + 1);\n }\n\n private releasePendingObserveInit(sessionId: string): void {\n const count = this.pendingObserveInitCounts.get(sessionId);\n if (!count) return;\n\n if (count === 1) {\n this.pendingObserveInitCounts.delete(sessionId);\n const waiters = this.pendingObserveInitWaiters.get(sessionId) ?? [];\n this.pendingObserveInitWaiters.delete(sessionId);\n for (const resolve of waiters) resolve();\n if (this.pendingObserveInitCounts.size === 0) {\n const idleWaiters = this.pendingObserveInitIdleWaiters.splice(\n 0,\n this.pendingObserveInitIdleWaiters.length,\n );\n for (const resolve of idleWaiters) resolve();\n }\n return;\n }\n\n this.pendingObserveInitCounts.set(sessionId, count - 1);\n }\n\n private async waitForPendingObserveInitIdle(sessionId?: string, abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n if (sessionId) {\n if (!this.pendingObserveInitCounts.has(sessionId)) return;\n await new Promise<void>((resolve, reject) => {\n const finish = (): void => {\n abortSignal?.removeEventListener(\"abort\", onAbort);\n resolve();\n };\n const onAbort = (): void => {\n const remaining = (this.pendingObserveInitWaiters.get(sessionId) ?? []).filter((waiter) => waiter !== finish);\n if (remaining.length === 0) this.pendingObserveInitWaiters.delete(sessionId);\n else this.pendingObserveInitWaiters.set(sessionId, remaining);\n reject(abortSignal?.reason instanceof Error ? abortSignal.reason : new DOMException(\"Aborted\", \"AbortError\"));\n };\n const waiters = this.pendingObserveInitWaiters.get(sessionId) ?? [];\n waiters.push(finish);\n this.pendingObserveInitWaiters.set(sessionId, waiters);\n abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n return;\n }\n\n if (this.pendingObserveInitCounts.size === 0) return;\n await new Promise<void>((resolve) => {\n this.pendingObserveInitIdleWaiters.push(resolve);\n });\n }\n\n /** Build the compressed history recall section for a session. */\n async assembleRecall(\n sessionId: string,\n budgetChars: number,\n ): Promise<string> {\n return (await this.assembleRecallWithTrace(sessionId, budgetChars)).text;\n }\n\n /** Build compressed recall plus content-free selected-summary receipts. */\n async assembleRecallWithTrace(\n sessionId: string,\n budgetChars: number,\n ): Promise<LcmRecallWithTraceResult> {\n if (!this.config.enabled) return { text: \"\", selectedSummaries: [] };\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return { text: \"\", selectedSummaries: [] };\n await this.ensureInitialized();\n\n const effectiveBudget = Math.ceil(\n budgetChars * this.config.recallBudgetShare,\n );\n if (effectiveBudget <= 0) return { text: \"\", selectedSummaries: [] };\n\n return assembleCompressedHistoryWithTrace(this.dag!, this.archive!, normalizedSessionId, {\n freshTailTurns: this.config.freshTailTurns,\n budgetChars: effectiveBudget,\n });\n }\n\n async searchStructuredParts(\n sessionId: string,\n query: string,\n limit = this.config.messagePartsRecallMaxResults,\n ): Promise<LcmStructuredRecallMatch[]> {\n const { messagePartsEnabled } = this.config;\n if (!this.config.enabled || !messagePartsEnabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n if (!this.archive) return [];\n return this.archive.searchStructuredParts(query, limit, normalizedSessionId);\n }\n\n formatStructuredRecall(\n matches: LcmStructuredRecallMatch[],\n budgetChars: number,\n ): string {\n if (matches.length === 0 || budgetChars <= 0) return \"\";\n const lines: string[] = [];\n let used = \"## Structured Session Matches\\n\\n\".length;\n for (const match of matches) {\n const label = match.file_path\n ? `${match.kind} ${match.file_path}`\n : match.tool_name\n ? `${match.kind} ${match.tool_name}`\n : match.kind;\n const excerpt = match.content.replace(/\\s+/g, \" \").slice(0, 220);\n const line = `- turn ${match.turn_index} (${match.role}): ${label} — ${excerpt}`;\n if (used + line.length + 1 > budgetChars) break;\n lines.push(line);\n used += line.length + 1;\n }\n return lines.length > 0 ? `## Structured Session Matches\\n\\n${lines.join(\"\\n\")}` : \"\";\n }\n\n /** Flush pending summaries before compaction (called from before_compaction hook). */\n async preCompactionFlush(sessionId: string, abortSignal?: AbortSignal): Promise<void> {\n abortSignal?.throwIfAborted();\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n abortSignal?.throwIfAborted();\n await this.waitForSessionObserveIdle(normalizedSessionId, abortSignal);\n abortSignal?.throwIfAborted();\n\n try {\n await abortOnSignal(abortSignal, this.summarizer!.summarizeIncremental(normalizedSessionId));\n } catch (err) {\n if (abortSignal?.aborted) throw err;\n log.debug(`LCM pre-compaction flush error: ${err}`);\n }\n }\n\n /** Record a compaction event with real token counts (called from after_compaction hook). */\n async recordCompaction(\n sessionId: string,\n tokensBefore: number,\n tokensAfter: number,\n ): Promise<void> {\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n await this.waitForSessionObserveIdle(normalizedSessionId);\n\n const maxTurn = this.archive!.getMaxTurnIndex(normalizedSessionId);\n\n this.dag!.recordCompaction(normalizedSessionId, maxTurn, tokensBefore, tokensAfter);\n log.info(\n `LCM compaction recorded: session=${normalizedSessionId}, turn=${maxTurn}, tokens ${tokensBefore}→${tokensAfter}`,\n );\n }\n\n /** Verify archive coverage after compaction. */\n async verifyPostCompaction(sessionId: string): Promise<void> {\n if (!this.config.enabled) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n\n const msgCount = this.archive!.getMessageCount(normalizedSessionId);\n const nodeCount = this.dag!.getNodeCount(normalizedSessionId);\n log.debug(\n `LCM post-compaction verify: session=${normalizedSessionId}, messages=${msgCount}, summaryNodes=${nodeCount}`,\n );\n }\n\n // ── MCP Tool implementations ──\n\n /** Search across all conversation history via FTS (snippet mode). */\n async searchContext(\n query: string,\n limit: number,\n sessionId?: string,\n sessionPrefix?: string,\n ): Promise<\n Array<{\n turn_index: number;\n role: string;\n snippet: string;\n session_id: string;\n }>\n > {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) return [];\n const normalizedSessionPrefix = normalizeOptionalLcmSessionId(sessionPrefix);\n if (sessionPrefix !== undefined && !normalizedSessionPrefix) return [];\n await this.ensureInitialized();\n return this.archive!.search(query, limit, normalizedSessionId, normalizedSessionPrefix);\n }\n\n /** Search via FTS returning full message content (not snippets). */\n async searchContextFull(\n query: string,\n limit: number,\n sessionId?: string,\n sessionPrefix?: string,\n ): Promise<\n Array<{\n id: number;\n turn_index: number;\n role: string;\n content: string;\n session_id: string;\n score: number;\n }>\n > {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) return [];\n const normalizedSessionPrefix = normalizeOptionalLcmSessionId(sessionPrefix);\n if (sessionPrefix !== undefined && !normalizedSessionPrefix) return [];\n await this.ensureInitialized();\n return this.archive!.searchWithContent(\n query,\n limit,\n normalizedSessionId,\n 1000,\n normalizedSessionPrefix,\n );\n }\n\n /** Get a compressed summary of a turn range. */\n async describeContext(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n ): Promise<{ summary: string; turn_count: number; depth: number } | null> {\n if (!this.config.enabled) return null;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return null;\n await this.ensureInitialized();\n\n const nodes = this.dag!.getCoveringNodes(normalizedSessionId, fromTurn, toTurn);\n if (nodes.length === 0) {\n // No summary exists — build a description from raw messages\n const messages = this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n if (messages.length === 0) return null;\n const preview = messages\n .slice(0, 5)\n .map((m) => `[${m.role}] ${m.content.slice(0, 100)}`)\n .join(\"\\n\");\n return {\n summary: `No summary available for this range. Preview of ${messages.length} messages:\\n${preview}`,\n turn_count: messages.length,\n depth: -1,\n };\n }\n\n // Use the deepest covering node\n const best = nodes[0]; // Already sorted by depth DESC\n return {\n summary: best.summary_text,\n turn_count: best.msg_end - best.msg_start + 1,\n depth: best.depth,\n };\n }\n\n /**\n * Retrieve raw archived messages for a turn range (inclusive bounds),\n * read-only and unshaped — no token-budget trimming (issue #2331\n * episodic-context). Callers own truncation and cleaning.\n */\n async getTurnRange(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n ): Promise<LcmMessage[]> {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n return this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n }\n\n /** Retrieve raw messages for a turn range (lossless expansion). */\n async expandContext(\n sessionId: string,\n fromTurn: number,\n toTurn: number,\n maxTokens: number,\n ): Promise<LcmExpandedMessage[]> {\n if (!this.config.enabled) return [];\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return [];\n await this.ensureInitialized();\n\n const messages = this.archive!.getMessages(normalizedSessionId, fromTurn, toTurn);\n if (messages.length === 0) return [];\n\n // Enforce the token budget while keeping the existing first/last shape.\n const tokenBudget = Math.max(0, Math.floor(maxTokens));\n if (tokenBudget === 0) return [];\n const totalTokens = messages.reduce(\n (sum, message) => sum + estimateTokenCount(message.content),\n 0,\n );\n if (totalTokens <= tokenBudget) {\n return messages.map((m) => ({\n id: m.id,\n session_id: m.session_id,\n turn_index: m.turn_index,\n role: m.role,\n content: m.content,\n }));\n }\n\n const result: LcmExpandedMessage[] = [];\n const lastMsg = messages[messages.length - 1];\n const reservedLastTokens = Math.min(\n estimateTokenCount(lastMsg.content),\n Math.max(1, Math.floor(tokenBudget * 0.3)),\n );\n let remainingTokens = tokenBudget - reservedLastTokens;\n\n for (let i = 0; i < messages.length - 1; i++) {\n if (remainingTokens <= 0) break;\n const content = truncateToTokenBudget(\n messages[i].content,\n remainingTokens,\n );\n if (!content) continue;\n result.push({\n id: messages[i].id,\n session_id: messages[i].session_id,\n turn_index: messages[i].turn_index,\n role: messages[i].role,\n content,\n });\n remainingTokens -= estimateTokenCount(content);\n }\n\n const lastContent = truncateToTokenBudget(\n lastMsg.content,\n reservedLastTokens + remainingTokens,\n );\n if (lastContent) {\n result.push({\n id: lastMsg.id,\n session_id: lastMsg.session_id,\n turn_index: lastMsg.turn_index,\n role: lastMsg.role,\n content: lastContent,\n });\n }\n return result;\n }\n\n\n /** Get statistics about the LCM archive. */\n async getStats(sessionId?: string): Promise<{\n totalMessages: number;\n totalSummaryNodes: number;\n maxDepth: number;\n maxTurnIndex?: number;\n }> {\n if (!this.config.enabled)\n return { totalMessages: 0, totalSummaryNodes: 0, maxDepth: -1 };\n const normalizedSessionId = normalizeOptionalLcmSessionId(sessionId);\n if (sessionId !== undefined && !normalizedSessionId) {\n return { ...EMPTY_LCM_STATS };\n }\n await this.ensureInitialized();\n\n if (normalizedSessionId) {\n return {\n totalMessages: this.archive!.getMessageCount(normalizedSessionId),\n totalSummaryNodes: this.dag!.getNodeCount(normalizedSessionId),\n maxDepth: this.dag!.getMaxDepth(normalizedSessionId),\n maxTurnIndex: this.archive!.getMaxTurnIndex(normalizedSessionId),\n };\n }\n\n return {\n totalMessages: this.archive!.getTotalMessageCount(),\n totalSummaryNodes: 0, // Would need a global count query\n maxDepth: -1,\n };\n }\n\n /** Clear all LCM archive and summary state for one session. */\n async clearSession(sessionId: string): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n const normalizedSessionId = normalizeLcmSessionId(sessionId);\n if (!normalizedSessionId) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.dag) return;\n await this.waitForSessionObserveIdle(normalizedSessionId);\n this.dag.deleteSession(normalizedSessionId);\n this.archive.deleteSession(normalizedSessionId);\n }\n\n /** Clear all LCM archive and summary state without closing the engine. */\n async clearAll(): Promise<void> {\n if (!this.config.enabled || this.closed) return;\n await this.ensureInitialized();\n if (this.closed || !this.archive || !this.dag) return;\n await this.waitForObserveQueueIdle();\n this.dag.deleteAll();\n this.archive.deleteAll();\n }\n\n /** Prune old data beyond retention period. */\n async prune(): Promise<{ messagesPruned: number; nodesPruned: number }> {\n if (!this.config.enabled) return { messagesPruned: 0, nodesPruned: 0 };\n await this.ensureInitialized();\n\n const messagesPruned = this.archive!.pruneOldMessages(\n this.config.archiveRetentionDays,\n );\n const nodesPruned = this.dag!.pruneOldNodes(\n this.config.archiveRetentionDays,\n );\n return { messagesPruned, nodesPruned };\n }\n\n /** Close the database connection. */\n close(): void {\n this.closed = true;\n if (this.db) {\n this.db.close();\n }\n this.db = null;\n this.archive = null;\n this.dag = null;\n this.summarizer = null;\n this.observeQueue = null;\n this.initPromise = null;\n }\n}\nfunction truncateToTokenBudget(text: string, maxTokens: number): string {\n if (maxTokens <= 0) return \"\";\n if (estimateTokenCount(text) <= maxTokens) return text;\n const codePoints = [...text];\n let low = 0;\n let high = codePoints.length;\n while (low < high) {\n const mid = Math.ceil((low + high) / 2);\n if (estimateTokenCount(codePoints.slice(0, mid).join(\"\")) <= maxTokens) {\n low = mid;\n } else {\n high = mid - 1;\n }\n }\n return codePoints.slice(0, low).join(\"\");\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SupportPassportError,
3
3
  getOperation
4
- } from "./chunk-3NYCO5Q5.js";
4
+ } from "./chunk-SVZWVZ7E.js";
5
5
  import {
6
6
  abortError,
7
7
  isAbortError
@@ -499,4 +499,4 @@ export {
499
499
  buildSupportPassportPublicRequestHandler,
500
500
  composeSupportPassportExternalRequestHandlers
501
501
  };
502
- //# sourceMappingURL=chunk-TS6WB2CL.js.map
502
+ //# sourceMappingURL=chunk-7QK5TUTW.js.map
@@ -21,7 +21,7 @@ import {
21
21
  defineOperation,
22
22
  parseNamespacePreflightWriteOp,
23
23
  resolveAuthorizedNamespaceWritablePreflight
24
- } from "./chunk-3NYCO5Q5.js";
24
+ } from "./chunk-SVZWVZ7E.js";
25
25
  import {
26
26
  parseSharedWriteOutputControls
27
27
  } from "./chunk-IFBSZGW3.js";
@@ -379,7 +379,7 @@ defineOperation({
379
379
  })
380
380
  });
381
381
  defineOperation({ name: "lcm_search", description: "Search LCM.", schema: strictSchema({ query: S.str, sessionKey: S.str, sessionPrefix: S.str, namespace: S.str, limit: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.lcmSearch({ query: defStr(input.query, ""), sessionKey: optStr(input.sessionKey), sessionPrefix: optStr(input.sessionPrefix), namespace: optStr(input.namespace), limit: optNum(input.limit), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
382
- defineOperation({ name: "lcm_compaction_flush", description: "Flush LCM compaction.", schema: strictSchema({ sessionKey: S.str, namespace: S.str, cwd: S.str, projectTag: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.lcmCompactionFlush({ sessionKey: optStr(input.sessionKey) ?? "", namespace: optStr(input.namespace), cwd: optStr(input.cwd), projectTag: optStr(input.projectTag), authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
382
+ defineOperation({ name: "lcm_compaction_flush", description: "Flush LCM compaction.", schema: strictSchema({ sessionKey: S.str, namespace: S.str, cwd: S.str, projectTag: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.lcmCompactionFlush({ sessionKey: optStr(input.sessionKey) ?? "", namespace: optStr(input.namespace), cwd: optStr(input.cwd), projectTag: optStr(input.projectTag), authenticatedPrincipal: ctx.authenticatedPrincipal, ...ctx.abortSignal ? { abortSignal: ctx.abortSignal } : {} }) }) });
383
383
  defineOperation({ name: "extraction_force_flush", description: "Force-drain a session extraction buffer.", schema: strictSchema({ sessionKey: S.str, namespace: S.str, cwd: S.str, projectTag: S.str, deadlineMs: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.extractionForceFlush({ sessionKey: optStr(input.sessionKey) ?? "", namespace: optStr(input.namespace), cwd: optStr(input.cwd), projectTag: optStr(input.projectTag), deadlineMs: optNum(input.deadlineMs), authenticatedPrincipal: ctx.authenticatedPrincipal, onCommitted: ctx.hooks?.recordWriteCommit, ...ctx.abortSignal ? { abortSignal: ctx.abortSignal } : {} }) }) });
384
384
  defineOperation({ name: "lcm_compaction_record", description: "Record LCM compaction.", schema: strictSchema({ sessionKey: S.str, namespace: S.str, tokensBefore: S.num, tokensAfter: S.num }), handler: async (input, ctx) => ({ result: await ctx.service.lcmCompactionRecord({ sessionKey: optStr(input.sessionKey) ?? "", namespace: optStr(input.namespace), tokensBefore: optNum(input.tokensBefore) ?? 0, tokensAfter: optNum(input.tokensAfter) ?? 0, authenticatedPrincipal: ctx.authenticatedPrincipal }) }) });
385
385
  defineOperation({ name: "continuity_audit_generate", description: "Continuity audit.", fleetWide: true, schema: strictSchema({ period: S.str, key: S.str }), handler: async (input, ctx) => ({ result: await ctx.service.continuityAuditGenerate({ period: optStr(input.period) === "monthly" ? "monthly" : optStr(input.period) === "weekly" ? "weekly" : void 0, key: optStr(input.key) }) }) });
@@ -603,4 +603,4 @@ defineOperation({ name: "graph_events", description: "SSE graph events.", schema
603
603
  defineOperation({ name: "chat_message", description: "Chat message.", schema: strictSchema({ message: S.str, chatSessionId: S.str }), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
604
604
  defineOperation({ name: "chat_events", description: "SSE chat events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });
605
605
  defineOperation({ name: "adapters_status", description: "Adapter registry metadata (issue #1850 round 5). Marker op: the HTTP transport builds the response from its own adapterRegistry, but the op still must be registered so it appears in listRegisteredOperations and enforceTokenOp can gate it for scoped tokens.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
606
- //# sourceMappingURL=chunk-WGXUEXSV.js.map
606
+ //# sourceMappingURL=chunk-B47OHVFT.js.map