@xopcai/xopc 0.0.169 → 0.0.171

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 (198) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-DumQD8EX.js → activity-store-BLz30jWq.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CNI1HQdV.js → agent-avatar-dicebear-BKZO0EFn.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-ZCIC8mhO.js +2 -0
  6. package/dist/gateway/static/root/assets/{api-D7eNcGmE.js → api-N2qKY-WI.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-BPbnbnFn.js → app-management-settings-panel-CNZkpXCD.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-WWFCDver.js → appearance-settings-Drf5a563.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-B27faKqW.js → apps-page-DJmgBaAm.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-Cu2dsFtI.js → archive-plugin-ChVwOXE5.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-C9mycbtr.js → attachment-load-BVK3Y2d9.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automation-suggestion-card-DtHqVViI.js → automation-suggestion-card-DH4N0SYR.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-page-Ddot8-Md.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-DqrPRyjm.js → binary-plugins-CeHY6VVP.js} +1 -1
  15. package/dist/gateway/static/root/assets/block-editor-D3GIllO3.js +184 -0
  16. package/dist/gateway/static/root/assets/browser-settings-page-DvETvRcg.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-70k5yvTc.js → browser-workflow-inputs-femCtfpo.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-DBNuaWwR.js → browser-workflows-page-o0GVE_aF.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-ChXIYbys.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-CvV4M4Oe.js → capability-presets-api-Bx-JJC0R.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CUekXsJy.js +1 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-BnLOBd7v.js → channel-recipient-api-CTw3ibx4.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-CkhveNsQ.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-DRTb8DBk.js +1 -0
  25. package/dist/gateway/static/root/assets/{connector-logo-CYQPu4Nn.js → connector-logo-CQznQcd4.js} +1 -1
  26. package/dist/gateway/static/root/assets/connectors-page-DkSGIxWP.js +2 -0
  27. package/dist/gateway/static/root/assets/desktop-pet-BtP-xUQ9.js +1 -0
  28. package/dist/gateway/static/root/assets/{desktop-pet-settings-DHTY5Ku1.js → desktop-pet-settings-CIeH4VyP.js} +1 -1
  29. package/dist/gateway/static/root/assets/{directory-picker-path-field-cGL2aEB6.js → directory-picker-path-field-Ddgt6c3K.js} +1 -1
  30. package/dist/gateway/static/root/assets/{dreaming-settings-C2XF2wL4.js → dreaming-settings-gd9W6SLj.js} +3 -3
  31. package/dist/gateway/static/root/assets/{extension-debug-page-F8AzDx0d.js → extension-debug-page-CJGwUaQX.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-ZrX_Ge87.js → extension-page-B3zHKJAB.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-VypAD6ok.js → extension-settings-page-Cj9rrSr1.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-api-C-UsxEKi.js → gateway-config-api-BdmtlJRP.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-ChG26Coy.js → gateway-settings-C2RwKIsl.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-D73V3EVy.js → gateway-startup-retry-mcMq_uu_.js} +1 -1
  37. package/dist/gateway/static/root/assets/goal-create-dialog-5Ryd_rx4.js +1 -0
  38. package/dist/gateway/static/root/assets/goal-detail-page-DizZ6Cpl.js +4 -0
  39. package/dist/gateway/static/root/assets/{goals-config-api-fv7JLhjy.js → goals-config-api-CAO1J4jn.js} +1 -1
  40. package/dist/gateway/static/root/assets/goals-page-Dqry_hi2.js +2 -0
  41. package/dist/gateway/static/root/assets/{goals-settings-DlfyneMz.js → goals-settings-Boj2izKZ.js} +1 -1
  42. package/dist/gateway/static/root/assets/{heartbeat-settings-BPyFbSbh.js → heartbeat-settings-DbPC9a_y.js} +1 -1
  43. package/dist/gateway/static/root/assets/{image-generation-api-CSKX7PsM.js → image-generation-api-DrLCLTXn.js} +1 -1
  44. package/dist/gateway/static/root/assets/index-DEdyUjxM.css +1 -0
  45. package/dist/gateway/static/root/assets/{index-DJtuKve9.js → index-vHb2z7VS.js} +83 -70
  46. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BUxrnWH_.js → keyboard-shortcuts-settings-BrxfptgY.js} +1 -1
  47. package/dist/gateway/static/root/assets/local-app-workbench-page-BP0_Ih0e.js +2 -0
  48. package/dist/gateway/static/root/assets/{local-apps-page-BsZMeDnS.js → local-apps-page-DNCRlfFs.js} +1 -1
  49. package/dist/gateway/static/root/assets/{locale-store-DXq-Y8Bi.js → locale-store-CzIfXqm8.js} +1 -1
  50. package/dist/gateway/static/root/assets/logs-page-mT48mcF4.js +7 -0
  51. package/dist/gateway/static/root/assets/{markdown-split-Cmaw70yM.js → markdown-split-CIUH9Lor.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-Blqj_oJD.js → media-plugins-DX4AgkCs.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-CKZuaOeG.js +3 -0
  54. package/dist/gateway/static/root/assets/{notes-page-B6Fdlf_s.js → notes-page-D1KprtxL.js} +1 -1
  55. package/dist/gateway/static/root/assets/notes-workbench-wgt2Osyk.js +4 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-D6zFoyJY.js → page-tabs-DjZPJGf6.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-BLoo7Ad8.js → preview-open-alternatives-DNiJTpwZ.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-0-tt2dp7.js → product-open-page-CNfR17-g.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-CDjHvxJm.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-kJZwQXfC.js +1 -0
  61. package/dist/gateway/static/root/assets/remote-access-hub-MJdI9ek_.js +1 -0
  62. package/dist/gateway/static/root/assets/{save-bar-controls-9ujl7LRy.js → save-bar-controls-BGZFVO9S.js} +1 -1
  63. package/dist/gateway/static/root/assets/{schedule-field-e80Mj-0z.js → schedule-field-BAZiHtds.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schema-form-DYZQD-PL.js → schema-form-CesBcwJH.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-BqC7GDC_.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-CYwz8MfF.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-Clt3p-mk.js → settings-form-section-Bxc54BLj.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-loading-skeleton-CTuS66nC.js → settings-loading-skeleton-CYrho7Db.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-CMP_owwc.js → settings-page-C03X5fkh.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-layout-BWUV_wx6.js → settings-page-layout-CZAJbv4E.js} +1 -1
  71. package/dist/gateway/static/root/assets/setup-status-panel-Jv8_bcOD.js +1 -0
  72. package/dist/gateway/static/root/assets/{share-preview-page-tISZJtRK.js → share-preview-page-DSC7tKKG.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-h8tGDkA3.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-D2DGvRUn.js +1 -0
  75. package/dist/gateway/static/root/assets/skills-page-vqhjSMhZ.js +2 -0
  76. package/dist/gateway/static/root/assets/{system-settings-panel-6u0k0wJi.js → system-settings-panel-BO89zw5H.js} +1 -1
  77. package/dist/gateway/static/root/assets/{theme-store-DSpAOJ9G.js → theme-store-1OkdVC8l.js} +1 -1
  78. package/dist/gateway/static/root/assets/time-picker-mtD64kFB.js +1 -0
  79. package/dist/gateway/static/root/assets/{typed-models-lib-CyRCjjGS.js → typed-models-lib-D-_vct_y.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-channel-catalog-B_Igd7ec.js → use-channel-catalog-VlFtjlET.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-BgF0WxjM.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-BanJk_cf.js → voice-api-key-field-BhDk-UV_.js} +1 -1
  83. package/dist/gateway/static/root/assets/work-discovery-page-CP0Daig-.js +1 -0
  84. package/dist/gateway/static/root/assets/work-item-detail-page-NEWZPKB_.js +1 -0
  85. package/dist/gateway/static/root/assets/work-page-BkWntcQh.js +1 -0
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DCXTQx7p.js → workflow-run-setup-panel-uVw4Yoej.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-DRvhNQGe.js +11 -0
  88. package/dist/gateway/static/root/index.html +7 -7
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/embedded/run-for-session.js +71 -24
  91. package/dist/src/agent/embedded/run-turn.js +68 -4
  92. package/dist/src/agent/inbound/inbound-loop.d.ts +0 -2
  93. package/dist/src/agent/inbound/inbound-loop.js +0 -2
  94. package/dist/src/agent/memory/compaction-planner.d.ts +16 -0
  95. package/dist/src/agent/memory/compaction-planner.js +152 -0
  96. package/dist/src/agent/memory/compaction-policy.d.ts +10 -0
  97. package/dist/src/agent/memory/compaction-policy.js +24 -0
  98. package/dist/src/agent/memory/compaction.d.ts +21 -22
  99. package/dist/src/agent/memory/compaction.js +220 -194
  100. package/dist/src/agent/memory/context-budget.d.ts +40 -0
  101. package/dist/src/agent/memory/context-budget.js +106 -0
  102. package/dist/src/agent/memory/dreaming/config.js +1 -1
  103. package/dist/src/agent/orchestration/context-overflow.d.ts +1 -0
  104. package/dist/src/agent/orchestration/context-overflow.js +19 -0
  105. package/dist/src/agent/orchestration/loop-guard.js +13 -9
  106. package/dist/src/agent/reply/post-compaction-context.d.ts +4 -0
  107. package/dist/src/agent/reply/post-compaction-context.js +5 -3
  108. package/dist/src/agent/service.d.ts +0 -2
  109. package/dist/src/agent/service.js +13 -44
  110. package/dist/src/agent/session/session-inspector.js +10 -2
  111. package/dist/src/agent/workflow/builtins/index.js +2 -2
  112. package/dist/src/agent-runtime/index.js +1 -1
  113. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  114. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  115. package/dist/src/cli/commands/onboard/model.d.ts +2 -0
  116. package/dist/src/cli/commands/onboard/model.js +16 -3
  117. package/dist/src/config/agent-profile.js +1 -1
  118. package/dist/src/config/schema.d.ts +19 -5
  119. package/dist/src/config/schema.js +1 -2
  120. package/dist/src/gateway/agents-admin.js +1 -1
  121. package/dist/src/gateway/hono/lib/config-payload.d.ts +23 -0
  122. package/dist/src/gateway/hono/lib/config-payload.js +3 -0
  123. package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
  124. package/dist/src/gateway/hono/routes/config-patch/misc.js +28 -0
  125. package/dist/src/gateway/hono/routes/sessions.js +30 -44
  126. package/dist/src/gateway/service/sessions-api.d.ts +2 -3
  127. package/dist/src/gateway/service/sessions-api.js +6 -9
  128. package/dist/src/session/index.d.ts +1 -2
  129. package/dist/src/session/index.js +1 -2
  130. package/dist/src/session/init-session-turn.d.ts +0 -1
  131. package/dist/src/session/init-session-turn.js +1 -2
  132. package/dist/src/session/manager.d.ts +11 -17
  133. package/dist/src/session/manager.js +11 -14
  134. package/dist/src/session/reset-policy.js +3 -5
  135. package/dist/src/session/session-context-for-llm.d.ts +19 -1
  136. package/dist/src/session/session-context-for-llm.js +87 -129
  137. package/dist/src/session/store.d.ts +29 -23
  138. package/dist/src/session/store.js +109 -87
  139. package/dist/src/session/transcript-format.d.ts +2 -8
  140. package/dist/src/session/types.d.ts +8 -6
  141. package/dist/src/session/user-round-delete.d.ts +3 -6
  142. package/dist/src/session/user-round-delete.js +12 -16
  143. package/dist/src/storage/sqlite/index.d.ts +1 -1
  144. package/dist/src/storage/sqlite/index.js +2 -2
  145. package/dist/src/storage/sqlite/migrations/060_remove_runtime_transcript_messages.sql +45 -0
  146. package/dist/src/storage/sqlite/migrations/061_drop_compaction_checkpoints.sql +2 -0
  147. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  148. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  149. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  150. package/dist/src/storage/sqlite/schema.js +1 -1
  151. package/dist/src/storage/sqlite/schema.sql +0 -19
  152. package/dist/src/storage/sqlite/transcript-repository.d.ts +10 -14
  153. package/dist/src/storage/sqlite/transcript-repository.js +120 -105
  154. package/dist/src/user-context/config.d.ts +67 -2
  155. package/dist/src/user-context/config.js +36 -3
  156. package/dist/src/workflows/domain/result.d.ts +4 -15
  157. package/dist/src/workflows/engine/workflow-engine.js +5 -14
  158. package/dist/src/workflows/runtime/graph-workflow-runtime.js +7 -11
  159. package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
  160. package/dist/src/workflows/store/run-index-store.js +1 -6
  161. package/package.json +1 -1
  162. package/dist/gateway/static/root/assets/agents-DfpeWAnu.js +0 -2
  163. package/dist/gateway/static/root/assets/automations-page-BoH5grBX.js +0 -6
  164. package/dist/gateway/static/root/assets/block-editor-B9dc3pqc.js +0 -184
  165. package/dist/gateway/static/root/assets/browser-settings-page-CK2fnxHY.js +0 -8
  166. package/dist/gateway/static/root/assets/capabilities-settings-panel-gg9GXU00.js +0 -7
  167. package/dist/gateway/static/root/assets/capability-presets-settings-panel-A1qGVyll.js +0 -1
  168. package/dist/gateway/static/root/assets/channels-settings-H4vCzqiD.js +0 -1
  169. package/dist/gateway/static/root/assets/channels-status-swr-DtswVkDX.js +0 -1
  170. package/dist/gateway/static/root/assets/connectors-page-DphVkloc.js +0 -2
  171. package/dist/gateway/static/root/assets/desktop-pet-Deb8fsr-.js +0 -1
  172. package/dist/gateway/static/root/assets/goal-create-dialog-B6aBG2KK.js +0 -1
  173. package/dist/gateway/static/root/assets/goal-detail-page-B_G9oVL1.js +0 -4
  174. package/dist/gateway/static/root/assets/goals-page-BQmg_7aD.js +0 -2
  175. package/dist/gateway/static/root/assets/index-DfE2j0g8.css +0 -1
  176. package/dist/gateway/static/root/assets/local-app-workbench-page-Dzlj4fH8.js +0 -2
  177. package/dist/gateway/static/root/assets/logs-page-Bg1B-cKU.js +0 -7
  178. package/dist/gateway/static/root/assets/messages-Cj_n7gUv.js +0 -3
  179. package/dist/gateway/static/root/assets/notes-workbench-4HYPR6Hb.js +0 -4
  180. package/dist/gateway/static/root/assets/project-detail-page-CGa68F1d.js +0 -1
  181. package/dist/gateway/static/root/assets/projects-page-BXmIeErj.js +0 -1
  182. package/dist/gateway/static/root/assets/remote-access-hub-bxrIHaRt.js +0 -1
  183. package/dist/gateway/static/root/assets/sessions-page-D_7ms_LG.js +0 -1
  184. package/dist/gateway/static/root/assets/settings-advanced-gate-VLuu9WHc.js +0 -1
  185. package/dist/gateway/static/root/assets/setup-status-panel-CAClgrxi.js +0 -1
  186. package/dist/gateway/static/root/assets/shares-settings-t-hP0QDv.js +0 -1
  187. package/dist/gateway/static/root/assets/skill-reload-api-CYRaxTqs.js +0 -1
  188. package/dist/gateway/static/root/assets/skills-page-C6CXLWnN.js +0 -2
  189. package/dist/gateway/static/root/assets/time-picker-BF3f8el1.js +0 -1
  190. package/dist/gateway/static/root/assets/user-context-page-B3zeQLeM.js +0 -1
  191. package/dist/gateway/static/root/assets/work-discovery-page-BCANmOUS.js +0 -1
  192. package/dist/gateway/static/root/assets/work-item-detail-page-t5xiIEFv.js +0 -1
  193. package/dist/gateway/static/root/assets/work-page-CEI3zs-y.js +0 -1
  194. package/dist/gateway/static/root/assets/workflows-page-B8FRLCHp.js +0 -11
  195. package/dist/src/agent/lifecycle/handlers/compaction.d.ts +0 -13
  196. package/dist/src/agent/lifecycle/handlers/compaction.js +0 -18
  197. package/dist/src/session/compaction-checkpoints.d.ts +0 -8
  198. package/dist/src/session/compaction-checkpoints.js +0 -19
@@ -3,18 +3,19 @@ import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
4
  import { requireXopcDatabase } from "../storage/sqlite/connection.js";
5
5
  import "./types.js";
6
- import { buildSessionContextForLlm, buildSessionDisplayMessages, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray } from "./session-context-for-llm.js";
6
+ import { buildSessionContextForLlm, buildSessionDisplayMessages, isRuntimeOnlyTranscriptMessage, isTranscriptCompactionEntry, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray } from "./session-context-for-llm.js";
7
7
  import { estimateTokensFromMessages } from "../storage/sqlite/row-mappers.js";
8
8
  import { deleteSessionRecord, ensureSessionRecord, findSessionKeyBySessionId, getGlobalSessionStats, getSessionMetadata, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord } from "../storage/sqlite/session-repository.js";
9
- import { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint } from "../storage/sqlite/transcript-repository.js";
9
+ import { appendCompactionBoundary, appendTranscriptEntry, listCompactionBoundaries, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreBeforeCompactionBoundary } from "../storage/sqlite/transcript-repository.js";
10
10
  import "../storage/sqlite/index.js";
11
11
  import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
12
12
  import { readPostCompactionContext } from "../agent/reply/post-compaction-context.js";
13
13
  import { SessionCompactor } from "../agent/memory/compaction.js";
14
+ import { resolveCompactionPolicy } from "../agent/memory/compaction-policy.js";
14
15
  import { SlidingWindow } from "../agent/memory/window.js";
15
- import { normalizeCompactionCheckpointId } from "./compaction-checkpoints.js";
16
16
  import { isAppendOnlyLlmTranscriptMessage } from "./transcript-stats.js";
17
17
  import { transcriptRowsToClientHistory } from "./client-history.js";
18
+ import { computeTranscriptUserRoundDeleteRange } from "./user-round-delete.js";
18
19
  //#region src/session/store.ts
19
20
  init_paths_state();
20
21
  init_logger();
@@ -23,11 +24,30 @@ const INDEX_VERSION = "1.0";
23
24
  var SessionStore = class {
24
25
  window;
25
26
  compactor;
27
+ compactionHooks = {};
26
28
  constructor(options, windowConfig, compactionConfig) {
27
29
  this.options = options;
28
30
  this.window = new SlidingWindow(windowConfig);
29
31
  this.compactor = new SessionCompactor(compactionConfig);
30
32
  }
33
+ setCompactionHooks(hooks) {
34
+ this.compactionHooks = hooks;
35
+ }
36
+ async runCompactionHook(phase, event) {
37
+ try {
38
+ if (phase === "before") await this.compactionHooks.before?.(event);
39
+ else await this.compactionHooks.after?.({
40
+ ...event,
41
+ compactedCount: event.compactedCount ?? 0
42
+ });
43
+ } catch (err) {
44
+ log.warn({
45
+ err,
46
+ phase,
47
+ sessionKey: event.sessionKey
48
+ }, `Session compaction ${phase} hook failed`);
49
+ }
50
+ }
31
51
  resolveWorkspaceCwd(sessionKey) {
32
52
  return resolveEffectiveAgentProfileForSession(this.options.config, sessionKey).resolvedWorkspacePath;
33
53
  }
@@ -87,13 +107,13 @@ var SessionStore = class {
87
107
  if (!metadata) return null;
88
108
  const limit = Math.min(200, Math.max(1, Math.trunc(options.limit ?? 50)));
89
109
  const offset = Math.max(0, Math.trunc(options.offset ?? 0));
90
- const parsedBefore = options.before ? Number.parseInt(options.before, 10) : void 0;
91
- const hasBeforeCursor = parsedBefore !== void 0 && Number.isFinite(parsedBefore);
110
+ const parsedBefore = options.before === void 0 ? void 0 : parseHistoryBeforeIndex(options.before);
111
+ const hasBeforeCursor = parsedBefore !== void 0;
92
112
  if (options.includeContextRows) {
93
113
  const page = paginateTranscriptMessages(key, {
94
114
  limit,
95
115
  offset: hasBeforeCursor ? void 0 : offset,
96
- beforeEndIndex: hasBeforeCursor ? parsedBefore : void 0,
116
+ beforeIndex: hasBeforeCursor ? parsedBefore : void 0,
97
117
  includeContext: true
98
118
  });
99
119
  const messages = transcriptRowsToClientHistory(page.rows);
@@ -121,7 +141,7 @@ var SessionStore = class {
121
141
  const page = this.paginateDisplayMessages(displayMessages, {
122
142
  limit,
123
143
  offset: hasBeforeCursor ? void 0 : offset,
124
- beforeEndIndex: hasBeforeCursor ? parsedBefore : void 0
144
+ beforeIndex: hasBeforeCursor ? parsedBefore : void 0
125
145
  });
126
146
  const session = await this.buildSessionDetail(key, metadata, page.messages, options);
127
147
  const nextBeforeCursor = page.startIndex > 0 ? String(page.startIndex) : void 0;
@@ -162,6 +182,10 @@ var SessionStore = class {
162
182
  requireXopcDatabase();
163
183
  return loadTranscriptRowsForSession(key);
164
184
  }
185
+ async loadTranscriptHistoryRows(key) {
186
+ requireXopcDatabase();
187
+ return loadTranscriptHistoryRowsForSession(key);
188
+ }
165
189
  async getMetadata(key) {
166
190
  requireXopcDatabase();
167
191
  return getSessionMetadata(key);
@@ -237,16 +261,19 @@ var SessionStore = class {
237
261
  if (!metadata?.sessionId) return null;
238
262
  const rows = await this.loadTranscriptRows(key);
239
263
  const compactions = [];
240
- for (const row of rows) if (row.type === "compaction") {
241
- const c = row;
242
- compactions.push({
243
- at: c.at ?? (/* @__PURE__ */ new Date()).toISOString(),
244
- summary: c.summary ?? "",
245
- firstKeptIndex: Number(c.firstKeptIndex ?? 0),
246
- tokensBefore: c.tokensBefore ?? 0,
247
- tokensAfter: c.tokensAfter ?? 0
248
- });
249
- }
264
+ for (const row of rows) if (isTranscriptCompactionEntry(row)) compactions.push({
265
+ at: row.at,
266
+ baseSeq: row.baseSeq,
267
+ plannerVersion: row.plannerVersion,
268
+ summaryModelRef: row.summaryModelRef,
269
+ qualityAudit: row.qualityAudit,
270
+ summary: row.summary,
271
+ messages: row.messages,
272
+ firstKeptIndex: row.firstKeptIndex,
273
+ tokensBefore: row.tokensBefore,
274
+ tokensAfter: row.tokensAfter,
275
+ restoredFromCompactionId: row.restoredFromCompactionId
276
+ });
250
277
  return {
251
278
  type: "xopc_session_transcript",
252
279
  version: 1,
@@ -341,34 +368,42 @@ var SessionStore = class {
341
368
  replaceTranscriptRows(key, mergeLlmMessagesPreservingContextRows(await this.loadTranscriptRows(key), messages));
342
369
  });
343
370
  }
371
+ async deleteUserRound(key, userRoundIndex) {
372
+ return this.runStoreMutation(async () => {
373
+ requireXopcDatabase();
374
+ const canonicalRows = (await this.loadTranscriptRows(key)).filter((row) => !isTranscriptCompactionEntry(row) && !isRuntimeOnlyTranscriptMessage(row));
375
+ const range = computeTranscriptUserRoundDeleteRange(canonicalRows, userRoundIndex);
376
+ if (!range) return null;
377
+ const removedRows = canonicalRows.slice(range.startIndex, range.startIndex + range.count);
378
+ const remainingRows = canonicalRows.slice(0, range.startIndex).concat(canonicalRows.slice(range.startIndex + range.count));
379
+ const removedMessages = buildSessionDisplayMessages(removedRows);
380
+ const remainingMessages = buildSessionDisplayMessages(remainingRows);
381
+ replaceTranscriptRows(key, remainingRows);
382
+ return {
383
+ deleted: removedMessages.length,
384
+ removedMessages,
385
+ remainingMessages
386
+ };
387
+ });
388
+ }
344
389
  getWindowStats(messages) {
345
390
  return this.window.getStats(messages);
346
391
  }
347
- needsCompaction(key, messages, contextWindow) {
348
- return this.compactor.needsCompaction(messages, contextWindow);
349
- }
350
- prepareCompaction(key, messages, contextWindow) {
351
- const result = this.compactor.needsCompaction(messages, contextWindow);
352
- return {
353
- needsCompaction: result.needed,
354
- messages,
355
- stats: result
356
- };
357
- }
358
392
  async applyCompaction(key, messages, result) {
359
393
  const compacted = this.compactor.applyCompaction(messages, result);
360
394
  return this.runStoreMutation(async () => {
361
- const merged = mergeLlmMessagesPreservingContextRows(await this.loadTranscriptRows(key), compacted);
362
- captureCompactionCheckpoint(key);
363
- replaceTranscriptRows(key, merged, { appendCompaction: {
395
+ appendCompactionBoundary(key, {
396
+ type: "compaction",
364
397
  at: (/* @__PURE__ */ new Date()).toISOString(),
398
+ plannerVersion: result.plannerVersion ?? 2,
399
+ summaryModelRef: result.summaryModelRef ?? "unknown",
400
+ qualityAudit: result.qualityAudit ?? "disabled",
365
401
  summary: result.summary,
402
+ messages: compacted,
366
403
  firstKeptIndex: result.firstKeptIndex,
367
404
  tokensBefore: result.tokensBefore,
368
405
  tokensAfter: result.tokensAfter
369
- } });
370
- const metadata = await this.getMetadata(key);
371
- if (metadata) await this.updateMetadata(key, { compactedCount: metadata.compactedCount + 1 });
406
+ });
372
407
  log.info({
373
408
  key,
374
409
  tokensBefore: result.tokensBefore,
@@ -379,37 +414,44 @@ var SessionStore = class {
379
414
  return compacted;
380
415
  });
381
416
  }
382
- async compact(key, messages, contextWindow, instructions, force) {
383
- const result = await this.compactor.compact(messages, instructions, force);
384
- if (result.compacted) await this.applyCompaction(key, messages, result);
417
+ async compact(key, messages, model, instructions, force, executionOptions) {
418
+ const tokenCount = this.estimateTokens(messages);
419
+ await this.runCompactionHook("before", {
420
+ sessionKey: key,
421
+ messageCount: messages.length,
422
+ tokenCount
423
+ });
424
+ const result = await this.compactor.compact(messages, model, instructions, force, executionOptions);
425
+ if (result.compacted) {
426
+ const compacted = await this.applyCompaction(key, messages, result);
427
+ await this.runCompactionHook("after", {
428
+ sessionKey: key,
429
+ messageCount: compacted.length,
430
+ tokenCount: result.tokensAfter,
431
+ compactedCount: Math.max(0, Math.min(messages.length, result.firstKeptIndex))
432
+ });
433
+ }
385
434
  return result;
386
435
  }
387
436
  async getCompactionStats(key) {
388
- const metadata = await this.getMetadata(key);
389
- if (!metadata) return;
437
+ if (!await this.getMetadata(key)) return void 0;
438
+ const boundaries = listCompactionBoundaries(key);
390
439
  return {
391
- compactionCount: metadata.compactedCount,
392
- totalTokensBefore: 0,
393
- totalTokensAfter: 0,
394
- lastCompactionAt: void 0
440
+ compactionCount: boundaries.length,
441
+ totalTokensBefore: boundaries.reduce((sum, boundary) => sum + boundary.tokensBefore, 0),
442
+ totalTokensAfter: boundaries.reduce((sum, boundary) => sum + boundary.tokensAfter, 0),
443
+ lastCompactionAt: boundaries[0]?.createdAt
395
444
  };
396
445
  }
397
- async listCompactionCheckpoints(key) {
398
- requireXopcDatabase();
399
- return listCompactionCheckpoints(key);
400
- }
401
- async getCompactionCheckpointDetail(key, checkpointId) {
446
+ async listCompactionBoundaries(key) {
402
447
  requireXopcDatabase();
403
- const id = normalizeCompactionCheckpointId(checkpointId);
404
- if (!id) return null;
405
- return getCompactionCheckpointDetail(key, id);
448
+ return listCompactionBoundaries(key);
406
449
  }
407
- async restoreCompactionCheckpoint(key, checkpointId) {
450
+ async restoreBeforeCompactionBoundary(key, compactionId) {
408
451
  return this.runStoreMutation(async () => {
409
452
  requireXopcDatabase();
410
- const id = normalizeCompactionCheckpointId(checkpointId);
411
- if (!id) throw new Error(`Invalid checkpoint id: ${checkpointId}`);
412
- restoreCompactionCheckpoint(key, id);
453
+ if (!compactionId.trim()) throw new Error("compactionId is required");
454
+ restoreBeforeCompactionBoundary(key, compactionId);
413
455
  });
414
456
  }
415
457
  async deleteSession(key) {
@@ -548,20 +590,7 @@ var SessionStore = class {
548
590
  }
549
591
  async loadDisplayMessages(key) {
550
592
  requireXopcDatabase();
551
- const checkpoints = listCompactionCheckpoints(key);
552
- const rowSets = [];
553
- for (const checkpoint of [...checkpoints].reverse()) rowSets.push(loadCheckpointRows(key, checkpoint.id));
554
- rowSets.push(await this.loadTranscriptRows(key));
555
- const messages = [];
556
- const seen = /* @__PURE__ */ new Set();
557
- for (const rows of rowSets) for (const message of buildSessionDisplayMessages(rows)) {
558
- if (this.isCompactionSummaryMessage(message)) continue;
559
- const identity = this.displayMessageIdentity(message);
560
- if (seen.has(identity)) continue;
561
- seen.add(identity);
562
- messages.push(message);
563
- }
564
- return messages;
593
+ return buildSessionDisplayMessages(await this.loadTranscriptRows(key));
565
594
  }
566
595
  paginateDisplayMessages(messages, options = {}) {
567
596
  const total = messages.length;
@@ -569,8 +598,8 @@ var SessionStore = class {
569
598
  const offset = Math.max(0, Math.trunc(options.offset ?? 0));
570
599
  let startIndex;
571
600
  let endIndex;
572
- if (options.beforeEndIndex !== void 0 && Number.isFinite(options.beforeEndIndex)) {
573
- endIndex = Math.min(total, Math.max(0, Math.trunc(options.beforeEndIndex)));
601
+ if (options.beforeIndex !== void 0 && Number.isFinite(options.beforeIndex)) {
602
+ endIndex = Math.min(total, Math.max(0, Math.trunc(options.beforeIndex)));
574
603
  startIndex = Math.max(0, endIndex - limit);
575
604
  } else {
576
605
  endIndex = Math.max(0, total - offset);
@@ -583,24 +612,9 @@ var SessionStore = class {
583
612
  endIndex
584
613
  };
585
614
  }
586
- displayMessageIdentity(message) {
587
- const record = message;
588
- return JSON.stringify({
589
- role: message.role,
590
- timestamp: record.timestamp,
591
- toolCallId: record.toolCallId ?? record.tool_call_id,
592
- toolName: record.toolName,
593
- content: this.messageContent(message)
594
- });
595
- }
596
615
  messageContent(msg) {
597
616
  return msg.content;
598
617
  }
599
- isCompactionSummaryMessage(msg) {
600
- if (msg.role !== "user") return false;
601
- const text = this.extractTextContent(this.messageContent(msg)).trim();
602
- return /^\[Previous conversation summary\]/i.test(text);
603
- }
604
618
  extractTextContent(content) {
605
619
  if (typeof content === "string") return content;
606
620
  if (Array.isArray(content)) {
@@ -616,9 +630,11 @@ var SessionStore = class {
616
630
  return "";
617
631
  }
618
632
  async injectPostCompactionContext(key) {
633
+ const policy = resolveCompactionPolicy(this.options.config);
619
634
  const contextText = readPostCompactionContext({
620
635
  cfg: this.options.config,
621
- sessionKey: key
636
+ sessionKey: key,
637
+ sectionNames: policy.postCompactionSections
622
638
  });
623
639
  if (!contextText?.trim()) return;
624
640
  try {
@@ -666,5 +682,11 @@ var SessionStore = class {
666
682
  });
667
683
  }
668
684
  };
685
+ function parseHistoryBeforeIndex(value) {
686
+ if (!/^(0|[1-9]\d*)$/.test(value)) throw new Error("Invalid session history cursor");
687
+ const parsed = Number(value);
688
+ if (!Number.isSafeInteger(parsed)) throw new Error("Invalid session history cursor");
689
+ return parsed;
690
+ }
669
691
  //#endregion
670
692
  export { SessionStore };
@@ -1,17 +1,11 @@
1
1
  /**
2
2
  * API-level transcript summary types (authoritative storage is SQLite `transcript_entries`).
3
3
  */
4
- import type { TranscriptStoredRow } from './session-context-for-llm.js';
4
+ import type { TranscriptStoredRow, XopcTranscriptCompactionEntry } from './session-context-for-llm.js';
5
5
  export declare const XOPC_SESSION_TRANSCRIPT_TYPE: "xopc_session_transcript";
6
6
  export declare const CURRENT_SESSION_TRANSCRIPT_VERSION = 1;
7
7
  /** Record appended when context compaction runs (mirrors pi `CompactionEntry` audit fields). */
8
- export interface TranscriptCompactionRecord {
9
- at: string;
10
- summary: string;
11
- firstKeptIndex: number;
12
- tokensBefore: number;
13
- tokensAfter: number;
14
- }
8
+ export type TranscriptCompactionRecord = Omit<XopcTranscriptCompactionEntry, 'type'>;
15
9
  /** Synthetic document shape returned by {@link SessionStore.loadTranscriptDocument} for API parity. */
16
10
  export interface XopcSessionTranscriptV1 {
17
11
  type: typeof XOPC_SESSION_TRANSCRIPT_TYPE;
@@ -179,12 +179,14 @@ export interface SessionExport {
179
179
  /** Full on-disk rows (LLM + `kind: 'context'`) for audit / round-trip. */
180
180
  transcriptRows: TranscriptStoredRow[];
181
181
  }
182
- /** On-disk pre-compaction snapshot (OpenClaw-style checkpoint list). */
183
- export interface CompactionCheckpointSummary {
182
+ /** Append-only context boundary produced by compaction or logical restoration. */
183
+ export interface CompactionBoundarySummary {
184
184
  id: string;
185
- sizeBytes: number;
186
- modifiedAt: string;
187
- }
188
- export interface CompactionCheckpointDetail extends CompactionCheckpointSummary {
185
+ seq: number;
186
+ createdAt: string;
189
187
  messageCount: number;
188
+ tokensBefore: number;
189
+ tokensAfter: number;
190
+ summaryPreview: string;
191
+ restoredFromCompactionId?: string;
190
192
  }
@@ -1,9 +1,6 @@
1
- import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
- /**
3
- * LLM transcript range for one user turn: the user row plus every following
4
- * assistant / tool / toolResult row until the next user (or EOF).
5
- */
6
- export declare function computeUserRoundDeleteRange(messages: readonly AgentMessage[], userRoundIndex: number): {
1
+ import { type TranscriptStoredRow } from './session-context-for-llm.js';
2
+ /** Raw transcript range for one UI-visible user turn. */
3
+ export declare function computeTranscriptUserRoundDeleteRange(rows: readonly TranscriptStoredRow[], userRoundIndex: number): {
7
4
  startIndex: number;
8
5
  count: number;
9
6
  } | null;
@@ -1,33 +1,29 @@
1
+ import { isTranscriptCustomMessageEntry } from "./session-context-for-llm.js";
1
2
  //#region src/session/user-round-delete.ts
2
- function isUserRole(role) {
3
- return role === "user";
3
+ function isVisibleUserRow(row) {
4
+ if (isTranscriptCustomMessageEntry(row)) return row.display !== false;
5
+ return row.role === "user";
4
6
  }
5
- /**
6
- * LLM transcript range for one user turn: the user row plus every following
7
- * assistant / tool / toolResult row until the next user (or EOF).
8
- */
9
- function computeUserRoundDeleteRange(messages, userRoundIndex) {
10
- if (userRoundIndex < 0 || messages.length === 0) return null;
7
+ /** Raw transcript range for one UI-visible user turn. */
8
+ function computeTranscriptUserRoundDeleteRange(rows, userRoundIndex) {
9
+ if (!Number.isInteger(userRoundIndex) || userRoundIndex < 0 || rows.length === 0) return null;
11
10
  let userCount = 0;
12
11
  let startIndex = -1;
13
- for (let i = 0; i < messages.length; i++) {
14
- if (!isUserRole(String(messages[i]?.role ?? ""))) continue;
12
+ for (let index = 0; index < rows.length; index += 1) {
13
+ if (!isVisibleUserRow(rows[index])) continue;
15
14
  if (userCount === userRoundIndex) {
16
- startIndex = i;
15
+ startIndex = index;
17
16
  break;
18
17
  }
19
18
  userCount += 1;
20
19
  }
21
20
  if (startIndex < 0) return null;
22
21
  let end = startIndex + 1;
23
- while (end < messages.length) {
24
- if (isUserRole(String(messages[end]?.role ?? ""))) break;
25
- end += 1;
26
- }
22
+ while (end < rows.length && !isVisibleUserRow(rows[end])) end += 1;
27
23
  return {
28
24
  startIndex,
29
25
  count: end - startIndex
30
26
  };
31
27
  }
32
28
  //#endregion
33
- export { computeUserRoundDeleteRange };
29
+ export { computeTranscriptUserRoundDeleteRange };
@@ -12,7 +12,7 @@ export { completeTaskOutcome, findTaskOutcomeForAssistant, getTaskOutcome, listT
12
12
  export { buildDefaultSessionMetadata, type SessionMetadataSeed, } from './session-metadata.js';
13
13
  export { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages, extractFtsContent, metadataToSessionInsert, sessionConfigRowToConfig, sessionRowToMetadata, transcriptEntryRowToStoredRow, type SessionConfigRow, type SessionRow, type TranscriptEntryRow, } from './row-mappers.js';
14
14
  export { deleteSessionRecord, ensureSessionRecord, getCurrentSessionId, getGlobalSessionStats, findSessionKeyBySessionId, getSessionPersistedLevels, getSessionMetadata, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats, } from './session-repository.js';
15
- export { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint, } from './transcript-repository.js';
15
+ export { appendCompactionBoundary, appendTranscriptEntry, listCompactionBoundaries, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreBeforeCompactionBoundary, } from './transcript-repository.js';
16
16
  export { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord, } from './notes-repository.js';
17
17
  export { deleteNoteAgentContextRecord, getNoteAgentContextRecord, upsertNoteAgentContextRecord, type NoteAgentContextRecord, } from './note-agent-context-repository.js';
18
18
  export { searchMemoryIndex, syncMemoryIndex, type MemorySearchHit, } from './memory-index-repository.js';
@@ -13,7 +13,7 @@ import { completeTaskOutcome, findTaskOutcomeForAssistant, getTaskOutcome, listT
13
13
  import { buildDefaultSessionMetadata } from "./session-metadata.js";
14
14
  import { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages, extractFtsContent, metadataToSessionInsert, sessionConfigRowToConfig, sessionRowToMetadata, transcriptEntryRowToStoredRow } from "./row-mappers.js";
15
15
  import { deleteSessionRecord, ensureSessionRecord, findSessionKeyBySessionId, getCurrentSessionId, getGlobalSessionStats, getSessionMetadata, getSessionPersistedLevels, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats } from "./session-repository.js";
16
- import { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint } from "./transcript-repository.js";
16
+ import { appendCompactionBoundary, appendTranscriptEntry, listCompactionBoundaries, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreBeforeCompactionBoundary } from "./transcript-repository.js";
17
17
  import { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord } from "./notes-repository.js";
18
18
  import { deleteNoteAgentContextRecord, getNoteAgentContextRecord, upsertNoteAgentContextRecord } from "./note-agent-context-repository.js";
19
19
  import { searchMemoryIndex, syncMemoryIndex } from "./memory-index-repository.js";
@@ -25,4 +25,4 @@ import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeC
25
25
  import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
26
26
  import { consumeMemoryReferenceConsent, decideMemoryReferenceConsent, ensureMemoryReferenceConsentRequest, hasMemoryReferenceConsent, listMemoryReferenceConsents, revokeMemoryReferenceConsent } from "./memory-reference-consent-repository.js";
27
27
  import { getUserProfilePromptState, setUserProfilePromptState } from "./user-profile-setup-repository.js";
28
- export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendComposerInputHistory, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, captureCompactionCheckpoint, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, clearComposerInputHistory, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, completeTaskOutcome, consumeConnectorApproval, consumeMemoryReferenceConsent, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, decideMemoryReferenceConsent, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureMemoryReferenceConsentRequest, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, findTaskOutcomeForAssistant, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCompactionCheckpointDetail, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getTaskOutcome, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasMemoryReferenceConsent, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isProactiveSupportAllowed, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionCheckpoints, listComposerInputHistory, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemoryReferenceConsents, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTaskOutcomes, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, revokeMemoryReferenceConsent, runSqliteWriteTransaction, searchMemoryIndex, searchMemoryRecords, sessionConfigRowToConfig, sessionRowToMetadata, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, setSessionConfig, setTaskOutcomeFeedback, setUserProfilePromptState, setUserTrustPolicy, startKnowledgeSyncRun, startTaskOutcome, summarizeMemoryRecallFeedback, summarizeTaskOutcomes, summarizeUserUnderstandingQuality, syncMemoryIndex, transcriptEntryRowToStoredRow, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateTaskOutcome, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord };
28
+ export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendCompactionBoundary, appendComposerInputHistory, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, clearComposerInputHistory, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, completeTaskOutcome, consumeConnectorApproval, consumeMemoryReferenceConsent, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, decideMemoryReferenceConsent, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureMemoryReferenceConsentRequest, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, findTaskOutcomeForAssistant, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getTaskOutcome, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasMemoryReferenceConsent, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isProactiveSupportAllowed, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionBoundaries, listComposerInputHistory, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemoryReferenceConsents, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTaskOutcomes, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreBeforeCompactionBoundary, revokeMemoryReferenceConsent, runSqliteWriteTransaction, searchMemoryIndex, searchMemoryRecords, sessionConfigRowToConfig, sessionRowToMetadata, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, setSessionConfig, setTaskOutcomeFeedback, setUserProfilePromptState, setUserTrustPolicy, startKnowledgeSyncRun, startTaskOutcome, summarizeMemoryRecallFeedback, summarizeTaskOutcomes, summarizeUserUnderstandingQuality, syncMemoryIndex, transcriptEntryRowToStoredRow, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateTaskOutcome, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord };
@@ -0,0 +1,45 @@
1
+ CREATE TEMP TABLE xopc_runtime_transcript_cleanup_sessions (
2
+ session_id TEXT PRIMARY KEY
3
+ );
4
+
5
+ INSERT INTO xopc_runtime_transcript_cleanup_sessions (session_id)
6
+ SELECT DISTINCT session_id
7
+ FROM transcript_entries
8
+ WHERE entry_kind = 'message'
9
+ AND json_extract(payload_json, '$.droppable') = 1;
10
+
11
+ DELETE FROM transcript_fts
12
+ WHERE entry_id IN (
13
+ SELECT entry_id
14
+ FROM transcript_entries
15
+ WHERE session_id IN (SELECT session_id FROM xopc_runtime_transcript_cleanup_sessions)
16
+ AND (
17
+ json_extract(payload_json, '$.droppable') = 1
18
+ OR json_extract(payload_json, '$.type') = 'compaction'
19
+ )
20
+ );
21
+
22
+ DELETE FROM transcript_entries
23
+ WHERE session_id IN (SELECT session_id FROM xopc_runtime_transcript_cleanup_sessions)
24
+ AND (
25
+ json_extract(payload_json, '$.droppable') = 1
26
+ OR json_extract(payload_json, '$.type') = 'compaction'
27
+ );
28
+
29
+ UPDATE sessions
30
+ SET
31
+ message_count = (
32
+ SELECT COUNT(*)
33
+ FROM transcript_entries e
34
+ WHERE e.session_id = sessions.session_id
35
+ AND e.entry_kind = 'message'
36
+ ),
37
+ estimated_tokens = (
38
+ SELECT COALESCE(SUM((length(COALESCE(json_extract(e.payload_json, '$.content'), '')) + 3) / 4), 0)
39
+ FROM transcript_entries e
40
+ WHERE e.session_id = sessions.session_id
41
+ AND e.entry_kind = 'message'
42
+ )
43
+ WHERE session_id IN (SELECT session_id FROM xopc_runtime_transcript_cleanup_sessions);
44
+
45
+ DROP TABLE xopc_runtime_transcript_cleanup_sessions;
@@ -0,0 +1,2 @@
1
+ DROP TABLE IF EXISTS checkpoint_entries;
2
+ DROP TABLE IF EXISTS compaction_checkpoints;
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
3
3
  /** Baseline schema version applied from schema.sql on first open. */
4
4
  export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 59;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 61;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
12
12
  /** Baseline schema version applied from schema.sql on first open. */
13
13
  const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
14
14
  /** Latest schema version this release supports (increment when adding migrations). */
15
- const XOPC_DB_SCHEMA_VERSION = 59;
15
+ const XOPC_DB_SCHEMA_VERSION = 61;
16
16
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
17
17
  function resolveMigrationsDir(override) {
18
18
  if (override) return override;
@@ -46,7 +46,7 @@ function applySingleMigration(db, migration) {
46
46
  * Each step runs in its own transaction and updates schema_meta on success.
47
47
  */
48
48
  function applyPendingMigrations(db, options = {}) {
49
- const targetVersion = options.targetVersion ?? 59;
49
+ const targetVersion = options.targetVersion ?? 61;
50
50
  let currentVersion = readSchemaVersion(db);
51
51
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
52
52
  if (currentVersion >= targetVersion) return currentVersion;
@@ -62,7 +62,7 @@ function applyPendingMigrations(db, options = {}) {
62
62
  }
63
63
  /** Inspect schema version without mutating the database. */
64
64
  function inspectSchemaMigrationStatus(db, options = {}) {
65
- const appVersion = options.targetVersion ?? 59;
65
+ const appVersion = options.targetVersion ?? 61;
66
66
  const dbVersion = readSchemaVersion(db);
67
67
  if (dbVersion > appVersion) return {
68
68
  dbVersion,
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
19
19
  export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
20
20
 
21
21
  /** Latest schema version this release supports (increment when adding migrations). */
22
- export const XOPC_DB_SCHEMA_VERSION = 59;
22
+ export const XOPC_DB_SCHEMA_VERSION = 61;
23
23
 
24
24
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -31,7 +31,7 @@ function ensureXopcDatabaseSchema(db) {
31
31
  bootstrapFreshDatabase(db);
32
32
  currentVersion = 11;
33
33
  }
34
- applyPendingMigrations(db, { targetVersion: 59 });
34
+ applyPendingMigrations(db, { targetVersion: 61 });
35
35
  }
36
36
  //#endregion
37
37
  export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, ensureSchemaMetaTable, ensureXopcDatabaseSchema, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion };
@@ -91,25 +91,6 @@ CREATE INDEX IF NOT EXISTS idx_entries_session_seq
91
91
  CREATE INDEX IF NOT EXISTS idx_entries_kind
92
92
  ON transcript_entries(session_id, entry_kind);
93
93
 
94
- CREATE TABLE IF NOT EXISTS compaction_checkpoints (
95
- checkpoint_id TEXT PRIMARY KEY,
96
- session_id TEXT NOT NULL,
97
- session_key TEXT NOT NULL,
98
- created_at INTEGER NOT NULL,
99
- message_count INTEGER NOT NULL,
100
- size_bytes INTEGER NOT NULL
101
- );
102
-
103
- CREATE TABLE IF NOT EXISTS checkpoint_entries (
104
- checkpoint_id TEXT NOT NULL,
105
- seq INTEGER NOT NULL,
106
- entry_kind TEXT NOT NULL,
107
- role TEXT,
108
- payload_json TEXT NOT NULL,
109
- PRIMARY KEY (checkpoint_id, seq),
110
- FOREIGN KEY (checkpoint_id) REFERENCES compaction_checkpoints(checkpoint_id) ON DELETE CASCADE
111
- );
112
-
113
94
  CREATE VIRTUAL TABLE IF NOT EXISTS transcript_fts USING fts5(
114
95
  content,
115
96
  session_key UNINDEXED,