@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
@@ -1,26 +1,24 @@
1
1
  import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
- import type { CompactionCheckpointDetail, CompactionCheckpointSummary } from '../../session/types.js';
3
- import type { TranscriptCompactionRecord } from '../../session/transcript-format.js';
4
- import { type TranscriptStoredRow } from '../../session/session-context-for-llm.js';
2
+ import type { CompactionBoundarySummary } from '../../session/types.js';
3
+ import { type TranscriptStoredRow, type XopcTranscriptCompactionEntry } from '../../session/session-context-for-llm.js';
5
4
  import { type TranscriptEntryRow } from './row-mappers.js';
6
5
  export declare function appendTranscriptEntry(sessionKey: string, row: TranscriptStoredRow, opts?: {
7
6
  sessionId?: string;
8
7
  tokenDelta?: number;
9
8
  }): TranscriptEntryRow;
9
+ export declare function appendCompactionBoundary(sessionKey: string, row: Omit<XopcTranscriptCompactionEntry, 'baseSeq'>): TranscriptEntryRow;
10
10
  export declare function loadTranscriptRowsForSession(sessionKey: string): TranscriptStoredRow[];
11
+ export declare function loadTranscriptHistoryRowsForSession(sessionKey: string): TranscriptStoredRow[];
11
12
  export declare function loadTranscriptRows(sessionId: string): TranscriptStoredRow[];
12
13
  export declare function loadLlmMessagesForSession(sessionKey: string): AgentMessage[];
13
- export declare function replaceTranscriptRows(sessionKey: string, rows: TranscriptStoredRow[], opts?: {
14
- appendCompaction?: TranscriptCompactionRecord;
15
- }): void;
16
- export declare function loadCheckpointRows(sessionKey: string, checkpointId: string): TranscriptStoredRow[];
14
+ export declare function replaceTranscriptRows(sessionKey: string, rows: TranscriptStoredRow[]): void;
17
15
  export declare function paginateTranscriptMessages(sessionKey: string, options?: {
18
16
  offset?: number;
19
17
  limit?: number;
20
- beforeSeq?: number;
21
- /** 0-based exclusive end index (legacy cursor from gateway UI). */
22
- beforeEndIndex?: number;
18
+ beforeIndex?: number;
23
19
  includeContext?: boolean;
20
+ /** Include reset/rollover transcripts for read-only conversation history. */
21
+ includeArchived?: boolean;
24
22
  }): {
25
23
  rows: TranscriptStoredRow[];
26
24
  messages: AgentMessage[];
@@ -28,7 +26,5 @@ export declare function paginateTranscriptMessages(sessionKey: string, options?:
28
26
  startSeq: number;
29
27
  endSeq: number;
30
28
  };
31
- export declare function captureCompactionCheckpoint(sessionKey: string): string | null;
32
- export declare function listCompactionCheckpoints(sessionKey: string): CompactionCheckpointSummary[];
33
- export declare function getCompactionCheckpointDetail(sessionKey: string, checkpointId: string): CompactionCheckpointDetail | null;
34
- export declare function restoreCompactionCheckpoint(sessionKey: string, checkpointId: string): void;
29
+ export declare function listCompactionBoundaries(sessionKey: string): CompactionBoundarySummary[];
30
+ export declare function restoreBeforeCompactionBoundary(sessionKey: string, compactionId: string): void;
@@ -1,10 +1,9 @@
1
1
  import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
- import { buildSessionContextForLlm } from "../../session/session-context-for-llm.js";
2
+ import { buildSessionContextForLlm, isRuntimeOnlyTranscriptMessage } from "../../session/session-context-for-llm.js";
3
3
  import { classifyStoredRow, estimateTokensFromMessages, extractFtsContent, transcriptEntryRowToStoredRow } from "./row-mappers.js";
4
4
  import { getCurrentSessionId, readCurrentSessionId } from "./session-repository.js";
5
5
  import { randomUUID } from "node:crypto";
6
6
  //#region src/storage/sqlite/transcript-repository.ts
7
- const MAX_CHECKPOINTS_PER_TRANSCRIPT = 15;
8
7
  function nextSeq(db, sessionId) {
9
8
  return (db.prepare(`SELECT COALESCE(MAX(seq), 0) AS max_seq FROM transcript_entries WHERE session_id = ?`).get(sessionId).max_seq ?? 0) + 1;
10
9
  }
@@ -34,6 +33,7 @@ function isUserMessageRow(row) {
34
33
  return classified.entryKind === "message" && classified.role === "user";
35
34
  }
36
35
  function appendTranscriptEntry(sessionKey, row, opts) {
36
+ if (isRuntimeOnlyTranscriptMessage(row)) throw new Error("Runtime-only messages cannot be persisted in a session transcript");
37
37
  return runSqliteWriteTransaction((db) => {
38
38
  const sessionId = opts?.sessionId ?? readCurrentSessionId(db, sessionKey);
39
39
  if (!sessionId) throw new Error(`Session not found: ${sessionKey}`);
@@ -58,11 +58,45 @@ function appendTranscriptEntry(sessionKey, row, opts) {
58
58
  return inserted;
59
59
  });
60
60
  }
61
+ function appendCompactionBoundary(sessionKey, row) {
62
+ return runSqliteWriteTransaction((db) => {
63
+ const sessionId = readCurrentSessionId(db, sessionKey);
64
+ if (!sessionId) throw new Error(`Session not found: ${sessionKey}`);
65
+ const boundary = {
66
+ ...row,
67
+ baseSeq: nextSeq(db, sessionId) - 1
68
+ };
69
+ const inserted = insertEntry(db, {
70
+ sessionId,
71
+ sessionKey,
72
+ row: boundary
73
+ });
74
+ const now = Date.now();
75
+ db.prepare(`UPDATE sessions SET
76
+ message_count = ?,
77
+ estimated_tokens = ?,
78
+ compacted_count = compacted_count + 1,
79
+ updated_at = ?,
80
+ last_accessed_at = ?,
81
+ last_interaction_at = ?
82
+ WHERE session_key = ?`).run(boundary.messages.length, boundary.tokensAfter, now, now, now, sessionKey);
83
+ return inserted;
84
+ });
85
+ }
61
86
  function loadTranscriptRowsForSession(sessionKey) {
62
87
  const sessionId = getCurrentSessionId(sessionKey);
63
88
  if (!sessionId) return [];
64
89
  return loadTranscriptRows(sessionId);
65
90
  }
91
+ function loadTranscriptHistoryRowsForSession(sessionKey) {
92
+ if (!getCurrentSessionId(sessionKey)) return [];
93
+ return getSqliteDatabase().prepare(`SELECT e.entry_id, e.session_id, e.seq, e.entry_kind, e.role, e.payload_json, e.created_at
94
+ FROM transcript_entries e
95
+ JOIN transcripts t ON t.session_id = e.session_id
96
+ WHERE t.session_key = ?
97
+ AND (t.status = 'active' OR t.archive_reason IN ('reset', 'stale'))
98
+ ORDER BY t.created_at ASC, t.rowid ASC, e.seq ASC`).all(sessionKey).map(transcriptEntryRowToStoredRow);
99
+ }
66
100
  function loadTranscriptRows(sessionId) {
67
101
  return getSqliteDatabase().prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
68
102
  FROM transcript_entries
@@ -70,25 +104,30 @@ function loadTranscriptRows(sessionId) {
70
104
  ORDER BY seq ASC`).all(sessionId).map(transcriptEntryRowToStoredRow);
71
105
  }
72
106
  function loadLlmMessagesForSession(sessionKey) {
73
- return buildSessionContextForLlm(loadTranscriptRowsForSession(sessionKey));
107
+ const sessionId = getCurrentSessionId(sessionKey);
108
+ if (!sessionId) return [];
109
+ return buildSessionContextForLlm(getSqliteDatabase().prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
110
+ FROM transcript_entries
111
+ WHERE session_id = ?
112
+ AND seq >= COALESCE(
113
+ (SELECT MAX(seq) FROM transcript_entries WHERE session_id = ? AND entry_kind = 'compaction'),
114
+ 1
115
+ )
116
+ ORDER BY seq ASC`).all(sessionId, sessionId).map(transcriptEntryRowToStoredRow));
74
117
  }
75
- function replaceTranscriptRows(sessionKey, rows, opts) {
118
+ function replaceTranscriptRows(sessionKey, rows) {
119
+ if (rows.some(isRuntimeOnlyTranscriptMessage)) throw new Error("Runtime-only messages cannot be persisted in a session transcript");
76
120
  runSqliteWriteTransaction((db) => {
77
121
  const sessionId = readCurrentSessionId(db, sessionKey);
78
122
  if (!sessionId) throw new Error(`Session not found: ${sessionKey}`);
79
123
  db.prepare(`DELETE FROM transcript_fts WHERE session_id = ?`).run(sessionId);
80
124
  db.prepare(`DELETE FROM transcript_entries WHERE session_id = ?`).run(sessionId);
81
- const toWrite = [...rows];
82
- if (opts?.appendCompaction) toWrite.push({
83
- type: "compaction",
84
- ...opts.appendCompaction
85
- });
86
- for (const row of toWrite) insertEntry(db, {
125
+ for (const row of rows) insertEntry(db, {
87
126
  sessionId,
88
127
  sessionKey,
89
128
  row
90
129
  });
91
- const llm = buildSessionContextForLlm(toWrite);
130
+ const llm = buildSessionContextForLlm(rows);
92
131
  const now = Date.now();
93
132
  const hiddenUpdate = llm.some((message) => message.role === "user") ? `hidden_from_session_list = 0,` : "";
94
133
  db.prepare(`UPDATE sessions SET
@@ -101,14 +140,6 @@ function replaceTranscriptRows(sessionKey, rows, opts) {
101
140
  WHERE session_key = ?`).run(llm.length, estimateTokensFromMessages(llm), now, now, now, sessionKey);
102
141
  });
103
142
  }
104
- function loadCheckpointRows(sessionKey, checkpointId) {
105
- const db = getSqliteDatabase();
106
- if (!db.prepare(`SELECT checkpoint_id FROM compaction_checkpoints
107
- WHERE session_key = ? AND checkpoint_id = ?`).get(sessionKey, checkpointId)) return [];
108
- return db.prepare(`SELECT payload_json FROM checkpoint_entries
109
- WHERE checkpoint_id = ?
110
- ORDER BY seq ASC`).all(checkpointId).map((entry) => JSON.parse(entry.payload_json));
111
- }
112
143
  function paginateTranscriptMessages(sessionKey, options = {}) {
113
144
  const sessionId = getCurrentSessionId(sessionKey);
114
145
  if (!sessionId) return {
@@ -121,36 +152,36 @@ function paginateTranscriptMessages(sessionKey, options = {}) {
121
152
  const db = getSqliteDatabase();
122
153
  const kinds = options.includeContext ? ["message", "context"] : ["message"];
123
154
  const kindPlaceholders = kinds.map(() => "?").join(", ");
124
- const total = db.prepare(`SELECT COUNT(*) AS total FROM transcript_entries
125
- WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})`).get(sessionId, ...kinds).total;
155
+ const includeArchived = options.includeArchived === true;
156
+ const transcriptWhere = includeArchived ? `t.session_key = ? AND (t.status = 'active' OR t.archive_reason IN ('reset', 'stale'))` : "e.session_id = ?";
157
+ const transcriptArg = includeArchived ? sessionKey : sessionId;
158
+ const total = db.prepare(`SELECT COUNT(*) AS total
159
+ FROM transcript_entries e
160
+ JOIN transcripts t ON t.session_id = e.session_id
161
+ WHERE ${transcriptWhere} AND e.entry_kind IN (${kindPlaceholders})`).get(transcriptArg, ...kinds).total;
126
162
  const limit = Math.min(200, Math.max(1, Math.trunc(options.limit ?? 50)));
127
163
  const offset = Math.max(0, Math.trunc(options.offset ?? 0));
128
164
  let rows;
129
- if (options.beforeEndIndex !== void 0 && Number.isFinite(options.beforeEndIndex)) {
130
- const endExclusive = Math.min(total, Math.max(0, Math.trunc(options.beforeEndIndex)));
165
+ if (options.beforeIndex !== void 0 && Number.isFinite(options.beforeIndex)) {
166
+ const endExclusive = Math.min(total, Math.max(0, Math.trunc(options.beforeIndex)));
131
167
  const startInclusive = Math.max(0, endExclusive - limit);
132
168
  rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
133
169
  FROM (
134
- SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at,
135
- ROW_NUMBER() OVER (ORDER BY seq ASC) - 1 AS idx
136
- FROM transcript_entries
137
- WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})
170
+ SELECT e.entry_id, e.session_id, e.seq, e.entry_kind, e.role, e.payload_json, e.created_at,
171
+ ROW_NUMBER() OVER (ORDER BY t.created_at ASC, t.rowid ASC, e.seq ASC) - 1 AS idx
172
+ FROM transcript_entries e
173
+ JOIN transcripts t ON t.session_id = e.session_id
174
+ WHERE ${transcriptWhere} AND e.entry_kind IN (${kindPlaceholders})
138
175
  )
139
176
  WHERE idx >= ? AND idx < ?
140
- ORDER BY seq ASC`).all(sessionId, ...kinds, startInclusive, endExclusive);
141
- } else if (options.beforeSeq !== void 0 && Number.isFinite(options.beforeSeq)) {
142
- rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
143
- FROM transcript_entries
144
- WHERE session_id = ? AND entry_kind IN (${kindPlaceholders}) AND seq < ?
145
- ORDER BY seq DESC
146
- LIMIT ?`).all(sessionId, ...kinds, options.beforeSeq, limit);
147
- rows.reverse();
177
+ ORDER BY idx ASC`).all(transcriptArg, ...kinds, startInclusive, endExclusive);
148
178
  } else {
149
- rows = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
150
- FROM transcript_entries
151
- WHERE session_id = ? AND entry_kind IN (${kindPlaceholders})
152
- ORDER BY seq DESC
153
- LIMIT ? OFFSET ?`).all(sessionId, ...kinds, limit, offset);
179
+ rows = db.prepare(`SELECT e.entry_id, e.session_id, e.seq, e.entry_kind, e.role, e.payload_json, e.created_at
180
+ FROM transcript_entries e
181
+ JOIN transcripts t ON t.session_id = e.session_id
182
+ WHERE ${transcriptWhere} AND e.entry_kind IN (${kindPlaceholders})
183
+ ORDER BY t.created_at DESC, t.rowid DESC, e.seq DESC
184
+ LIMIT ? OFFSET ?`).all(transcriptArg, ...kinds, limit, offset);
154
185
  rows.reverse();
155
186
  }
156
187
  const storedRows = rows.map(transcriptEntryRowToStoredRow);
@@ -162,86 +193,70 @@ function paginateTranscriptMessages(sessionKey, options = {}) {
162
193
  endSeq: rows[rows.length - 1]?.seq ?? 0
163
194
  };
164
195
  }
165
- function captureCompactionCheckpoint(sessionKey) {
166
- return runSqliteWriteTransaction((db) => {
167
- const sessionId = readCurrentSessionId(db, sessionKey);
168
- if (!sessionId) return null;
169
- const entries = db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
170
- FROM transcript_entries WHERE session_id = ? ORDER BY seq ASC`).all(sessionId);
171
- if (entries.length === 0) return null;
172
- const checkpointId = randomUUID();
173
- const now = Date.now();
174
- const messageCount = entries.filter((e) => e.entry_kind === "message").length;
175
- const sizeBytes = entries.reduce((sum, e) => sum + e.payload_json.length, 0);
176
- db.prepare(`INSERT INTO compaction_checkpoints
177
- (checkpoint_id, session_id, session_key, created_at, message_count, size_bytes)
178
- VALUES (?, ?, ?, ?, ?, ?)`).run(checkpointId, sessionId, sessionKey, now, messageCount, sizeBytes);
179
- const insertCheckpointEntry = db.prepare(`INSERT INTO checkpoint_entries (checkpoint_id, seq, entry_kind, role, payload_json)
180
- VALUES (?, ?, ?, ?, ?)`);
181
- for (const entry of entries) insertCheckpointEntry.run(checkpointId, entry.seq, entry.entry_kind, entry.role, entry.payload_json);
182
- pruneCompactionCheckpoints(db, sessionId);
183
- return checkpointId;
196
+ function listCompactionBoundaries(sessionKey) {
197
+ const db = getSqliteDatabase();
198
+ const sessionId = getCurrentSessionId(sessionKey);
199
+ if (!sessionId) return [];
200
+ return db.prepare(`SELECT entry_id, seq, payload_json, created_at
201
+ FROM transcript_entries
202
+ WHERE session_id = ? AND entry_kind = 'compaction'
203
+ ORDER BY seq DESC`).all(sessionId).map((row) => {
204
+ const payload = JSON.parse(row.payload_json);
205
+ return {
206
+ id: row.entry_id,
207
+ seq: row.seq,
208
+ createdAt: new Date(row.created_at).toISOString(),
209
+ messageCount: payload.messages.length,
210
+ tokensBefore: payload.tokensBefore,
211
+ tokensAfter: payload.tokensAfter,
212
+ summaryPreview: payload.summary.slice(0, 500),
213
+ restoredFromCompactionId: payload.restoredFromCompactionId
214
+ };
184
215
  });
185
216
  }
186
- function pruneCompactionCheckpoints(db, sessionId) {
187
- const rows = db.prepare(`SELECT checkpoint_id FROM compaction_checkpoints
188
- WHERE session_id = ?
189
- ORDER BY created_at ASC`).all(sessionId);
190
- if (rows.length <= MAX_CHECKPOINTS_PER_TRANSCRIPT) return;
191
- const toDelete = rows.slice(0, rows.length - MAX_CHECKPOINTS_PER_TRANSCRIPT);
192
- const del = db.prepare(`DELETE FROM compaction_checkpoints WHERE checkpoint_id = ?`);
193
- for (const row of toDelete) del.run(row.checkpoint_id);
194
- }
195
- function listCompactionCheckpoints(sessionKey) {
196
- return getSqliteDatabase().prepare(`SELECT checkpoint_id, created_at, message_count, size_bytes
197
- FROM compaction_checkpoints
198
- WHERE session_key = ?
199
- ORDER BY created_at DESC`).all(sessionKey).map((row) => ({
200
- id: row.checkpoint_id,
201
- sizeBytes: row.size_bytes,
202
- modifiedAt: new Date(row.created_at).toISOString()
203
- }));
204
- }
205
- function getCompactionCheckpointDetail(sessionKey, checkpointId) {
206
- const row = getSqliteDatabase().prepare(`SELECT checkpoint_id, created_at, message_count, size_bytes
207
- FROM compaction_checkpoints
208
- WHERE session_key = ? AND checkpoint_id = ?`).get(sessionKey, checkpointId);
209
- if (!row) return null;
210
- return {
211
- id: row.checkpoint_id,
212
- sizeBytes: row.size_bytes,
213
- modifiedAt: new Date(row.created_at).toISOString(),
214
- messageCount: row.message_count
215
- };
216
- }
217
- function restoreCompactionCheckpoint(sessionKey, checkpointId) {
217
+ function restoreBeforeCompactionBoundary(sessionKey, compactionId) {
218
218
  runSqliteWriteTransaction((db) => {
219
219
  const sessionId = readCurrentSessionId(db, sessionKey);
220
220
  if (!sessionId) throw new Error(`Session not found: ${sessionKey}`);
221
- if (!db.prepare(`SELECT checkpoint_id FROM compaction_checkpoints
222
- WHERE session_key = ? AND checkpoint_id = ?`).get(sessionKey, checkpointId)) throw new Error(`Checkpoint not found: ${checkpointId}`);
223
- const entries = db.prepare(`SELECT seq, entry_kind, role, payload_json
224
- FROM checkpoint_entries
225
- WHERE checkpoint_id = ?
226
- ORDER BY seq ASC`).all(checkpointId);
227
- db.prepare(`DELETE FROM transcript_fts WHERE session_id = ?`).run(sessionId);
228
- db.prepare(`DELETE FROM transcript_entries WHERE session_id = ?`).run(sessionId);
229
- for (const entry of entries) insertEntry(db, {
221
+ const boundary = db.prepare(`SELECT seq FROM transcript_entries
222
+ WHERE session_id = ? AND entry_id = ? AND entry_kind = 'compaction'`).get(sessionId, compactionId);
223
+ if (!boundary) throw new Error(`Compaction boundary not found: ${compactionId}`);
224
+ const restoredMessages = buildSessionContextForLlm(db.prepare(`SELECT entry_id, session_id, seq, entry_kind, role, payload_json, created_at
225
+ FROM transcript_entries
226
+ WHERE session_id = ? AND seq < ?
227
+ ORDER BY seq ASC`).all(sessionId, boundary.seq).map(transcriptEntryRowToStoredRow));
228
+ if (restoredMessages.length === 0) throw new Error(`No restorable context exists before compaction boundary: ${compactionId}`);
229
+ const current = db.prepare(`SELECT estimated_tokens FROM sessions WHERE session_key = ?`).get(sessionKey);
230
+ const tokensAfter = estimateTokensFromMessages(restoredMessages);
231
+ const baseSeq = nextSeq(db, sessionId) - 1;
232
+ insertEntry(db, {
230
233
  sessionId,
231
234
  sessionKey,
232
- row: JSON.parse(entry.payload_json),
233
- createdAt: Date.now()
235
+ row: {
236
+ type: "compaction",
237
+ at: (/* @__PURE__ */ new Date()).toISOString(),
238
+ baseSeq,
239
+ plannerVersion: 2,
240
+ summaryModelRef: "logical-restore",
241
+ qualityAudit: "disabled",
242
+ summary: `Restored the effective context that existed before compaction boundary ${compactionId}.`,
243
+ messages: restoredMessages,
244
+ firstKeptIndex: 0,
245
+ tokensBefore: current.estimated_tokens,
246
+ tokensAfter,
247
+ restoredFromCompactionId: compactionId
248
+ }
234
249
  });
235
- const llm = buildSessionContextForLlm(entries.map((e) => JSON.parse(e.payload_json)));
236
250
  const now = Date.now();
237
251
  db.prepare(`UPDATE sessions SET
238
252
  message_count = ?,
239
253
  estimated_tokens = ?,
254
+ compacted_count = compacted_count + 1,
240
255
  updated_at = ?,
241
256
  last_accessed_at = ?,
242
257
  last_interaction_at = ?
243
- WHERE session_key = ?`).run(llm.length, estimateTokensFromMessages(llm), now, now, now, sessionKey);
258
+ WHERE session_key = ?`).run(restoredMessages.length, tokensAfter, now, now, now, sessionKey);
244
259
  });
245
260
  }
246
261
  //#endregion
247
- export { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint };
262
+ export { appendCompactionBoundary, appendTranscriptEntry, listCompactionBoundaries, loadLlmMessagesForSession, loadTranscriptHistoryRowsForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreBeforeCompactionBoundary };
@@ -5,6 +5,39 @@ export declare const UserMemoryModeSchema: z.ZodEnum<{
5
5
  readOnly: "readOnly";
6
6
  confirmWrite: "confirmWrite";
7
7
  }>;
8
+ export declare const DEFAULT_CONTEXT_COMPACTION_POLICY: {
9
+ enabled: boolean;
10
+ triggerThreshold: number;
11
+ reserveTokens: number;
12
+ minMessagesBeforeCompact: number;
13
+ keepRecentTokens: number;
14
+ recentTurnsPreserve: number;
15
+ summaryMaxTokens: number;
16
+ summaryChunkTokens: number;
17
+ summaryTimeoutMs: number;
18
+ summaryRetries: number;
19
+ qualityGuard: boolean;
20
+ minToolResultKeepChars: number;
21
+ maxActiveTranscriptBytes: number;
22
+ postCompactionSections: string[];
23
+ };
24
+ export declare const ContextCompactionPolicySchema: z.ZodDefault<z.ZodObject<{
25
+ enabled: z.ZodDefault<z.ZodBoolean>;
26
+ triggerThreshold: z.ZodDefault<z.ZodNumber>;
27
+ reserveTokens: z.ZodDefault<z.ZodNumber>;
28
+ minMessagesBeforeCompact: z.ZodDefault<z.ZodNumber>;
29
+ keepRecentTokens: z.ZodDefault<z.ZodNumber>;
30
+ recentTurnsPreserve: z.ZodDefault<z.ZodNumber>;
31
+ summaryMaxTokens: z.ZodDefault<z.ZodNumber>;
32
+ summaryChunkTokens: z.ZodDefault<z.ZodNumber>;
33
+ summaryTimeoutMs: z.ZodDefault<z.ZodNumber>;
34
+ summaryRetries: z.ZodDefault<z.ZodNumber>;
35
+ qualityGuard: z.ZodDefault<z.ZodBoolean>;
36
+ model: z.ZodOptional<z.ZodString>;
37
+ minToolResultKeepChars: z.ZodDefault<z.ZodNumber>;
38
+ maxActiveTranscriptBytes: z.ZodDefault<z.ZodNumber>;
39
+ postCompactionSections: z.ZodDefault<z.ZodArray<z.ZodString>>;
40
+ }, z.core.$strict>>;
8
41
  export declare const UserMemoryConfigSchema: z.ZodDefault<z.ZodObject<{
9
42
  mode: z.ZodDefault<z.ZodEnum<{
10
43
  off: "off";
@@ -43,7 +76,23 @@ export declare const UserMemoryConfigSchema: z.ZodDefault<z.ZodObject<{
43
76
  }>>;
44
77
  }, z.core.$strict>>;
45
78
  retention: z.ZodOptional<z.ZodObject<{
46
- compaction: z.ZodDefault<z.ZodBoolean>;
79
+ compaction: z.ZodDefault<z.ZodObject<{
80
+ enabled: z.ZodDefault<z.ZodBoolean>;
81
+ triggerThreshold: z.ZodDefault<z.ZodNumber>;
82
+ reserveTokens: z.ZodDefault<z.ZodNumber>;
83
+ minMessagesBeforeCompact: z.ZodDefault<z.ZodNumber>;
84
+ keepRecentTokens: z.ZodDefault<z.ZodNumber>;
85
+ recentTurnsPreserve: z.ZodDefault<z.ZodNumber>;
86
+ summaryMaxTokens: z.ZodDefault<z.ZodNumber>;
87
+ summaryChunkTokens: z.ZodDefault<z.ZodNumber>;
88
+ summaryTimeoutMs: z.ZodDefault<z.ZodNumber>;
89
+ summaryRetries: z.ZodDefault<z.ZodNumber>;
90
+ qualityGuard: z.ZodDefault<z.ZodBoolean>;
91
+ model: z.ZodOptional<z.ZodString>;
92
+ minToolResultKeepChars: z.ZodDefault<z.ZodNumber>;
93
+ maxActiveTranscriptBytes: z.ZodDefault<z.ZodNumber>;
94
+ postCompactionSections: z.ZodDefault<z.ZodArray<z.ZodString>>;
95
+ }, z.core.$strict>>;
47
96
  maxAgeDays: z.ZodOptional<z.ZodNumber>;
48
97
  maxItems: z.ZodOptional<z.ZodNumber>;
49
98
  maxChars: z.ZodOptional<z.ZodNumber>;
@@ -153,7 +202,23 @@ export declare const UserContextConfigSchema: z.ZodDefault<z.ZodObject<{
153
202
  }>>;
154
203
  }, z.core.$strict>>;
155
204
  retention: z.ZodOptional<z.ZodObject<{
156
- compaction: z.ZodDefault<z.ZodBoolean>;
205
+ compaction: z.ZodDefault<z.ZodObject<{
206
+ enabled: z.ZodDefault<z.ZodBoolean>;
207
+ triggerThreshold: z.ZodDefault<z.ZodNumber>;
208
+ reserveTokens: z.ZodDefault<z.ZodNumber>;
209
+ minMessagesBeforeCompact: z.ZodDefault<z.ZodNumber>;
210
+ keepRecentTokens: z.ZodDefault<z.ZodNumber>;
211
+ recentTurnsPreserve: z.ZodDefault<z.ZodNumber>;
212
+ summaryMaxTokens: z.ZodDefault<z.ZodNumber>;
213
+ summaryChunkTokens: z.ZodDefault<z.ZodNumber>;
214
+ summaryTimeoutMs: z.ZodDefault<z.ZodNumber>;
215
+ summaryRetries: z.ZodDefault<z.ZodNumber>;
216
+ qualityGuard: z.ZodDefault<z.ZodBoolean>;
217
+ model: z.ZodOptional<z.ZodString>;
218
+ minToolResultKeepChars: z.ZodDefault<z.ZodNumber>;
219
+ maxActiveTranscriptBytes: z.ZodDefault<z.ZodNumber>;
220
+ postCompactionSections: z.ZodDefault<z.ZodArray<z.ZodString>>;
221
+ }, z.core.$strict>>;
157
222
  maxAgeDays: z.ZodOptional<z.ZodNumber>;
158
223
  maxItems: z.ZodOptional<z.ZodNumber>;
159
224
  maxChars: z.ZodOptional<z.ZodNumber>;
@@ -1,7 +1,7 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { z } from "zod";
3
3
  //#region src/user-context/config.ts
4
- var UserMemoryModeSchema, UserMemoryConfigSchema, UserUnderstandingConfigSchema, UserContextPrivacySchema, UserContextProviderRoutingSchema, DreamingPhaseSchema, UserContextDreamingSchema, UserContextConfigSchema;
4
+ var UserMemoryModeSchema, DEFAULT_CONTEXT_COMPACTION_POLICY, ContextCompactionPolicySchema, UserMemoryConfigSchema, UserUnderstandingConfigSchema, UserContextPrivacySchema, UserContextProviderRoutingSchema, DreamingPhaseSchema, UserContextDreamingSchema, UserContextConfigSchema;
5
5
  var init_config = __esmMin((() => {
6
6
  UserMemoryModeSchema = z.enum([
7
7
  "off",
@@ -9,6 +9,39 @@ var init_config = __esmMin((() => {
9
9
  "confirmWrite",
10
10
  "auto"
11
11
  ]);
12
+ DEFAULT_CONTEXT_COMPACTION_POLICY = {
13
+ enabled: true,
14
+ triggerThreshold: .8,
15
+ reserveTokens: 8192,
16
+ minMessagesBeforeCompact: 10,
17
+ keepRecentTokens: 2e4,
18
+ recentTurnsPreserve: 3,
19
+ summaryMaxTokens: 2e3,
20
+ summaryChunkTokens: 24e3,
21
+ summaryTimeoutMs: 18e4,
22
+ summaryRetries: 2,
23
+ qualityGuard: true,
24
+ minToolResultKeepChars: 1e3,
25
+ maxActiveTranscriptBytes: 2e6,
26
+ postCompactionSections: ["Session Startup", "Red Lines"]
27
+ };
28
+ ContextCompactionPolicySchema = z.object({
29
+ enabled: z.boolean().default(true),
30
+ triggerThreshold: z.number().min(.1).max(.98).default(.8),
31
+ reserveTokens: z.number().int().min(1024).default(8192),
32
+ minMessagesBeforeCompact: z.number().int().min(2).default(10),
33
+ keepRecentTokens: z.number().int().min(1e3).default(2e4),
34
+ recentTurnsPreserve: z.number().int().min(1).max(12).default(3),
35
+ summaryMaxTokens: z.number().int().min(256).default(2e3),
36
+ summaryChunkTokens: z.number().int().min(1e3).default(24e3),
37
+ summaryTimeoutMs: z.number().int().min(1e3).max(6e5).default(18e4),
38
+ summaryRetries: z.number().int().min(0).max(5).default(2),
39
+ qualityGuard: z.boolean().default(true),
40
+ model: z.string().min(1).optional(),
41
+ minToolResultKeepChars: z.number().int().min(200).default(1e3),
42
+ maxActiveTranscriptBytes: z.number().int().min(64e3).default(2e6),
43
+ postCompactionSections: z.array(z.string().min(1)).max(12).default(["Session Startup", "Red Lines"])
44
+ }).strict().default(DEFAULT_CONTEXT_COMPACTION_POLICY);
12
45
  UserMemoryConfigSchema = z.object({
13
46
  mode: UserMemoryModeSchema.default("off"),
14
47
  sources: z.array(z.enum([
@@ -42,7 +75,7 @@ var init_config = __esmMin((() => {
42
75
  ]).optional()
43
76
  }).strict().optional(),
44
77
  retention: z.object({
45
- compaction: z.boolean().default(true),
78
+ compaction: ContextCompactionPolicySchema,
46
79
  maxAgeDays: z.number().int().positive().optional(),
47
80
  maxItems: z.number().int().positive().optional(),
48
81
  maxChars: z.number().int().positive().optional()
@@ -153,4 +186,4 @@ var init_config = __esmMin((() => {
153
186
  }));
154
187
  //#endregion
155
188
  init_config();
156
- export { UserContextConfigSchema, UserContextDreamingSchema, UserContextPrivacySchema, UserContextProviderRoutingSchema, UserMemoryConfigSchema, UserMemoryModeSchema, UserUnderstandingConfigSchema, init_config };
189
+ export { ContextCompactionPolicySchema, DEFAULT_CONTEXT_COMPACTION_POLICY, UserContextConfigSchema, UserContextDreamingSchema, UserContextPrivacySchema, UserContextProviderRoutingSchema, UserMemoryConfigSchema, UserMemoryModeSchema, UserUnderstandingConfigSchema, init_config };
@@ -1,18 +1,12 @@
1
1
  export interface WorkflowResultEnvelope {
2
2
  title?: string;
3
3
  summary: string;
4
- sections: WorkflowResultSection[];
4
+ sections?: WorkflowResultSection[];
5
5
  actions?: WorkflowNextAction[];
6
6
  artifacts?: WorkflowArtifactRef[];
7
7
  followUps?: WorkflowFollowUp[];
8
- structuredOutput?: unknown;
9
- }
10
- /** Product-level outcome contract for reusable workflow deliverables. */
11
- export interface WorkflowOutcome {
12
- summary: string;
13
- artifacts?: WorkflowArtifactRef[];
14
- followUps?: WorkflowFollowUp[];
15
- structuredOutput?: unknown;
8
+ /** Machine-readable workflow output. It is intentionally not rendered as user-facing content. */
9
+ data?: unknown;
16
10
  }
17
11
  export interface WorkflowFollowUp {
18
12
  id: string;
@@ -20,7 +14,7 @@ export interface WorkflowFollowUp {
20
14
  prompt?: string;
21
15
  priority?: 'low' | 'medium' | 'high';
22
16
  }
23
- export type WorkflowResultSection = WorkflowTextSection | WorkflowFindingsSection | WorkflowRisksSection | WorkflowQuestionsSection | WorkflowJsonSection;
17
+ export type WorkflowResultSection = WorkflowTextSection | WorkflowFindingsSection | WorkflowRisksSection | WorkflowQuestionsSection;
24
18
  export interface WorkflowTextSection {
25
19
  kind: 'text';
26
20
  title: string;
@@ -41,11 +35,6 @@ export interface WorkflowQuestionsSection {
41
35
  title: string;
42
36
  items: string[];
43
37
  }
44
- export interface WorkflowJsonSection {
45
- kind: 'json';
46
- title: string;
47
- value: unknown;
48
- }
49
38
  export interface WorkflowFinding {
50
39
  title: string;
51
40
  severity?: WorkflowSeverity;
@@ -177,7 +177,7 @@ var WorkflowEngine = class {
177
177
  await eventQueue;
178
178
  if (currentPhaseId) await appendEvent("phase_completed", { phaseId: currentPhaseId });
179
179
  const result = requireWorkflowResultEnvelope(runtimeResult.result);
180
- assertWorkflowOutput(definition, result);
180
+ assertWorkflowOutput(definition, result.data === void 0 ? result.summary : result.data);
181
181
  await appendEvent("run_completed", { result });
182
182
  await this.callHooks((hook) => hook.afterRun?.({
183
183
  runId,
@@ -622,16 +622,7 @@ function groupReplayTargetsByPhase(targets) {
622
622
  function buildReplayResultEnvelope(options, results) {
623
623
  return {
624
624
  summary: `Replay completed for ${results.filter((item) => item.status === "done").length}/${results.length} target${results.length === 1 ? "" : "s"}.`,
625
- sections: [{
626
- kind: "json",
627
- title: "Replay targets",
628
- value: {
629
- sourceRunId: options.sourceRunId,
630
- scope: options.replayScope,
631
- targets: results
632
- }
633
- }],
634
- structuredOutput: { replay: {
625
+ data: { replay: {
635
626
  sourceRunId: options.sourceRunId,
636
627
  scope: options.replayScope,
637
628
  targets: results
@@ -669,6 +660,7 @@ function normalizeCompletedAgentStatus(status) {
669
660
  function previewWorkflowValue(value) {
670
661
  if (value === null || value === void 0) return;
671
662
  if (typeof value === "string") return truncate(value, 300);
663
+ if (isWorkflowResultEnvelope(value)) return truncate(value.summary, 1200);
672
664
  try {
673
665
  return truncate(JSON.stringify(value), 300);
674
666
  } catch {
@@ -687,12 +679,11 @@ function assertWorkflowOutput(definition, value) {
687
679
  }
688
680
  function isWorkflowResultEnvelope(value) {
689
681
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
690
- const record = value;
691
- return typeof record.summary === "string" && Array.isArray(record.sections);
682
+ return typeof value.summary === "string";
692
683
  }
693
684
  function requireWorkflowResultEnvelope(value) {
694
685
  if (isWorkflowResultEnvelope(value)) return value;
695
- throw new WorkflowEngineRunError("result_validation_failed", "Workflow output node must return a result envelope with summary and sections.", false);
686
+ throw new WorkflowEngineRunError("result_validation_failed", "Workflow output node must return a result envelope with summary.", false);
696
687
  }
697
688
  function toWorkflowRunError(err, wasAborted, abortReason) {
698
689
  if (err instanceof WorkflowEngineRunError) return {
@@ -95,15 +95,10 @@ var GraphWorkflowRuntime = class {
95
95
  };
96
96
  } else if (node.kind === "merge") value = node.config.mode === "array" ? predecessors.map((entry) => entry.value) : Object.fromEntries(predecessors.map((entry) => [entry.id, entry.value]));
97
97
  else {
98
- const structuredOutput = predecessors.length === 1 ? predecessors[0].value : Object.fromEntries(predecessors.map((entry) => [entry.id, entry.value]));
98
+ const outputData = predecessors.length === 1 ? predecessors[0].value : Object.fromEntries(predecessors.map((entry) => [entry.id, entry.value]));
99
99
  value = {
100
- summary: node.config.summary ? renderTemplate(node.config.summary, options.args, outputs, predecessors, options.goal) : summarizeValue(structuredOutput),
101
- sections: [{
102
- kind: "json",
103
- title: node.config.title ?? "Workflow result",
104
- value: structuredOutput
105
- }],
106
- structuredOutput
100
+ summary: node.config.summary ? renderTemplate(node.config.summary, options.args, outputs, predecessors, options.goal) : renderResultContent(outputData),
101
+ ...typeof outputData === "string" ? {} : { data: outputData }
107
102
  };
108
103
  }
109
104
  outputs.set(node.id, value);
@@ -276,16 +271,17 @@ function createLimiter(limit) {
276
271
  }
277
272
  };
278
273
  }
279
- function summarizeValue(value) {
280
- if (typeof value === "string") return value.slice(0, 500);
274
+ function renderResultContent(value) {
275
+ if (typeof value === "string") return value.trim();
281
276
  if (value && typeof value === "object") {
282
277
  const record = value;
283
278
  for (const key of [
279
+ "content",
284
280
  "summary",
285
281
  "executiveSummary",
286
282
  "result",
287
283
  "answer"
288
- ]) if (typeof record[key] === "string") return record[key].slice(0, 500);
284
+ ]) if (typeof record[key] === "string") return record[key].trim();
289
285
  }
290
286
  return "Workflow completed.";
291
287
  }