@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
@@ -21,6 +21,11 @@ function isTranscriptSummaryMessageEntry(x) {
21
21
  const role = x.role;
22
22
  return role === "branchSummary" || role === "compactionSummary";
23
23
  }
24
+ function isTranscriptCompactionEntry(x) {
25
+ if (!x || typeof x !== "object") return false;
26
+ const row = x;
27
+ return row.type === "compaction" && typeof row.at === "string" && typeof row.baseSeq === "number" && Number.isInteger(row.baseSeq) && typeof row.plannerVersion === "number" && Number.isInteger(row.plannerVersion) && typeof row.summaryModelRef === "string" && (row.qualityAudit === "passed" || row.qualityAudit === "disabled") && typeof row.summary === "string" && Array.isArray(row.messages) && typeof row.firstKeptIndex === "number" && typeof row.tokensBefore === "number" && typeof row.tokensAfter === "number";
28
+ }
24
29
  function isTranscriptLabelEntry(x) {
25
30
  if (!x || typeof x !== "object") return false;
26
31
  return x.type === "label";
@@ -37,13 +42,15 @@ const LLM_ROLES = new Set([
37
42
  "tool",
38
43
  "toolResult"
39
44
  ]);
40
- const CODING_CONTEXT_LOOKBACK = 80;
41
- const CODING_CONTEXT_MAX_LINES = 24;
42
45
  function isLikelyAgentMessage(x) {
43
46
  if (!x || typeof x !== "object") return false;
44
47
  const role = x.role;
45
48
  return typeof role === "string" && LLM_ROLES.has(role);
46
49
  }
50
+ /** Runtime-derived messages are never authoritative transcript rows. */
51
+ function isRuntimeOnlyTranscriptMessage(x) {
52
+ return isLikelyAgentMessage(x) && x.droppable === true;
53
+ }
47
54
  function parseTimestampValue(timestamp) {
48
55
  if (typeof timestamp === "number") return Number.isFinite(timestamp) ? timestamp : void 0;
49
56
  if (typeof timestamp !== "string") return;
@@ -93,33 +100,6 @@ function asRecord(value) {
93
100
  function stringValue(value) {
94
101
  return typeof value === "string" ? value : void 0;
95
102
  }
96
- function parseJsonRecord(value) {
97
- if (typeof value !== "string" || !value.trim()) return null;
98
- try {
99
- return asRecord(JSON.parse(value));
100
- } catch {
101
- return null;
102
- }
103
- }
104
- function textFromContent(content) {
105
- if (typeof content === "string") return content;
106
- if (!Array.isArray(content)) return "";
107
- return content.map((part) => {
108
- if (typeof part === "string") return part;
109
- const rec = asRecord(part);
110
- if (!rec) return "";
111
- if (rec.type === "text" && typeof rec.text === "string") return rec.text;
112
- return "";
113
- }).filter(Boolean).join("");
114
- }
115
- function toolNameFromBlock(block) {
116
- const fn = asRecord(block.function);
117
- return stringValue(block.name) ?? stringValue(block.toolName) ?? stringValue(fn?.name) ?? "tool";
118
- }
119
- function toolArgsFromBlock(block) {
120
- const fn = asRecord(block.function);
121
- return asRecord(block.arguments) ?? asRecord(block.args) ?? asRecord(block.input) ?? asRecord(fn?.arguments) ?? parseJsonRecord(block.arguments) ?? parseJsonRecord(block.args) ?? parseJsonRecord(block.input) ?? parseJsonRecord(fn?.arguments) ?? {};
122
- }
123
103
  function toolCallIdFromBlock(block) {
124
104
  return stringValue(block.id) ?? stringValue(block.toolCallId) ?? stringValue(block.tool_call_id) ?? stringValue(block.tool_call_id$);
125
105
  }
@@ -127,112 +107,84 @@ function toolResultId(row) {
127
107
  const rec = row;
128
108
  return stringValue(rec.toolCallId) ?? stringValue(rec.tool_call_id) ?? stringValue(rec.tool_call_id$);
129
109
  }
130
- function extractResultDetails(row) {
131
- if (!row) return null;
132
- const topLevelDetails = asRecord(row.details);
133
- if (topLevelDetails) return topLevelDetails;
134
- const contentText = textFromContent(row.content);
135
- if (!contentText.trim()) return null;
136
- try {
137
- const rec = asRecord(JSON.parse(contentText));
138
- return asRecord(rec?.details) ?? rec;
139
- } catch {
140
- return null;
141
- }
142
- }
143
- function collectToolResults(messages) {
144
- const results = /* @__PURE__ */ new Map();
145
- for (const message of messages) {
146
- const role = message.role;
147
- if (role !== "tool" && role !== "toolResult") continue;
148
- const id = toolResultId(message);
149
- if (id) results.set(id, message);
150
- }
151
- return results;
152
- }
153
- function extractToolCalls(message) {
110
+ function toolCallIds(message) {
111
+ if (message.role !== "assistant") return [];
112
+ const ids = [];
154
113
  const content = message.content;
155
- const calls = [];
156
114
  if (Array.isArray(content)) for (const block of content) {
157
115
  const rec = asRecord(block);
158
116
  const type = rec ? stringValue(rec.type) : void 0;
159
117
  if (!rec || type !== "toolCall" && type !== "tool_use" && type !== "tool_call") continue;
160
- calls.push({
161
- id: toolCallIdFromBlock(rec),
162
- name: toolNameFromBlock(rec),
163
- args: toolArgsFromBlock(rec)
164
- });
118
+ const id = toolCallIdFromBlock(rec);
119
+ if (id) ids.push(id);
165
120
  }
166
- const toolCalls = message.tool_calls;
167
- if (Array.isArray(toolCalls)) for (const call of toolCalls) {
168
- const rec = asRecord(call);
169
- const fn = asRecord(rec?.function);
170
- const name = stringValue(fn?.name) ?? stringValue(rec?.name);
171
- if (!rec || !name) continue;
172
- calls.push({
173
- id: stringValue(rec.id),
174
- name,
175
- args: parseJsonRecord(fn?.arguments) ?? asRecord(fn?.arguments) ?? {}
176
- });
121
+ const calls = message.tool_calls;
122
+ if (Array.isArray(calls)) for (const call of calls) {
123
+ const id = stringValue(asRecord(call)?.id);
124
+ if (id) ids.push(id);
177
125
  }
178
- return calls;
179
- }
180
- function summarizePlan(details) {
181
- const lines = (Array.isArray(details.plan) ? details.plan : []).map((item) => {
182
- const rec = asRecord(item);
183
- const step = stringValue(rec?.step)?.trim();
184
- const status = stringValue(rec?.status)?.trim();
185
- return step && status ? `${status}: ${step}` : "";
186
- }).filter(Boolean).slice(0, 8);
187
- if (lines.length === 0) return void 0;
188
- const explanation = stringValue(details.explanation)?.trim();
189
- return `Plan${explanation ? ` (${explanation})` : ""}: ${lines.join(" | ")}`;
190
- }
191
- function summarizeCommand(args, details) {
192
- const command = stringValue(details?.command) ?? stringValue(args.cmd) ?? stringValue(args.command) ?? "";
193
- const status = stringValue(details?.status) ?? (details?.exitCode === 0 ? "success" : "unknown");
194
- const exitCode = typeof details?.exitCode === "number" ? details.exitCode : void 0;
195
- const hint = stringValue(details?.failureHint);
196
- return [
197
- `Command ${status}: ${command || "(unknown command)"}`,
198
- exitCode !== void 0 ? `exit=${exitCode}` : "",
199
- hint ? `hint=${hint}` : ""
200
- ].filter(Boolean).join(" ");
126
+ return ids;
201
127
  }
202
- function summarizePatch(details) {
203
- if (!details) return void 0;
204
- const files = Array.isArray(details.files) ? details.files.filter((file) => typeof file === "string" && file.trim().length > 0) : [];
205
- const added = typeof details.added === "number" ? details.added : 0;
206
- const removed = typeof details.removed === "number" ? details.removed : 0;
207
- const summary = stringValue(details.summary)?.trim();
208
- return `Patch applied: ${files.length ? files.join(", ") : summary || "(files unknown)"} (+${added}/-${removed})`;
128
+ function filterAssistantToolCalls(message, pairedIds) {
129
+ const record = message;
130
+ const content = record.content;
131
+ const filteredContent = Array.isArray(content) ? content.filter((block) => {
132
+ const rec = asRecord(block);
133
+ const type = rec ? stringValue(rec.type) : void 0;
134
+ if (!rec || type !== "toolCall" && type !== "tool_use" && type !== "tool_call") return true;
135
+ const id = toolCallIdFromBlock(rec);
136
+ return id !== void 0 && pairedIds.has(id);
137
+ }) : content;
138
+ const toolCalls = record.tool_calls;
139
+ const filteredToolCalls = Array.isArray(toolCalls) ? toolCalls.filter((call) => {
140
+ const id = stringValue(asRecord(call)?.id);
141
+ return id !== void 0 && pairedIds.has(id);
142
+ }) : toolCalls;
143
+ const hadArrayContent = Array.isArray(content);
144
+ const hadToolCalls = Array.isArray(toolCalls);
145
+ const hasContent = Array.isArray(filteredContent) ? filteredContent.length > 0 : typeof filteredContent === "string" ? filteredContent.trim().length > 0 : filteredContent !== void 0 && filteredContent !== null;
146
+ const hasToolCalls = Array.isArray(filteredToolCalls) && filteredToolCalls.length > 0;
147
+ if (!hasContent && !hasToolCalls) return null;
148
+ return {
149
+ ...record,
150
+ ...hadArrayContent ? { content: filteredContent } : {},
151
+ ...hadToolCalls ? { tool_calls: filteredToolCalls } : {}
152
+ };
209
153
  }
210
- function buildCodingContextMessage(messages) {
211
- const recent = messages.slice(-CODING_CONTEXT_LOOKBACK);
212
- const results = collectToolResults(recent);
213
- const lines = [];
214
- for (const message of recent) {
215
- if (message.role !== "assistant") continue;
216
- for (const call of extractToolCalls(message)) {
217
- if (call.name !== "update_plan" && call.name !== "exec_command" && call.name !== "apply_patch") continue;
218
- const details = extractResultDetails(call.id ? results.get(call.id) : void 0);
219
- const line = call.name === "update_plan" ? summarizePlan(details ?? call.args) : call.name === "exec_command" ? summarizeCommand(call.args, details) : summarizePatch(details);
220
- if (line) lines.push(line);
154
+ /** Providers require every retained tool call and result to form an ordered pair. */
155
+ function sanitizeToolPairs(messages) {
156
+ const callIndex = /* @__PURE__ */ new Map();
157
+ const resultIndex = /* @__PURE__ */ new Map();
158
+ for (let index = 0; index < messages.length; index += 1) {
159
+ const message = messages[index];
160
+ for (const id of toolCallIds(message)) if (!callIndex.has(id)) callIndex.set(id, index);
161
+ const role = String(message.role ?? "");
162
+ if (role === "tool" || role === "toolResult") {
163
+ const id = toolResultId(message);
164
+ if (id && !resultIndex.has(id)) resultIndex.set(id, index);
221
165
  }
222
166
  }
223
- const uniqueLines = [...new Set(lines)].slice(-CODING_CONTEXT_MAX_LINES);
224
- if (uniqueLines.length === 0) return null;
225
- return {
226
- role: "user",
227
- content: [{
228
- type: "text",
229
- text: [
230
- "<coding_context>",
231
- ...uniqueLines.map((line) => `- ${line}`),
232
- "</coding_context>"
233
- ].join("\n")
234
- }]
235
- };
167
+ const pairedIds = /* @__PURE__ */ new Set();
168
+ for (const [id, callAt] of callIndex) {
169
+ const resultAt = resultIndex.get(id);
170
+ if (resultAt !== void 0 && resultAt > callAt) pairedIds.add(id);
171
+ }
172
+ const out = [];
173
+ for (const message of messages) {
174
+ const role = String(message.role ?? "");
175
+ if (role === "tool" || role === "toolResult") {
176
+ const id = toolResultId(message);
177
+ if (id && pairedIds.has(id)) out.push(message);
178
+ continue;
179
+ }
180
+ if (message.role === "assistant") {
181
+ const filtered = filterAssistantToolCalls(message, pairedIds);
182
+ if (filtered) out.push(filtered);
183
+ continue;
184
+ }
185
+ out.push(message);
186
+ }
187
+ return out;
236
188
  }
237
189
  /**
238
190
  * Normalize a JSON array from on-disk transcript into stored rows (drops unrecognized objects).
@@ -260,6 +212,10 @@ function transcriptRowsFromJsonArray(arr) {
260
212
  out.push(x);
261
213
  continue;
262
214
  }
215
+ if (isTranscriptCompactionEntry(x)) {
216
+ out.push(x);
217
+ continue;
218
+ }
263
219
  if (isTranscriptLabelEntry(x)) {
264
220
  out.push(x);
265
221
  continue;
@@ -276,8 +232,12 @@ function transcriptRowsFromJsonArray(arr) {
276
232
  function buildSessionContextForLlm(rows) {
277
233
  const out = [];
278
234
  for (const r of rows) {
235
+ if (isTranscriptCompactionEntry(r)) {
236
+ out.length = 0;
237
+ out.push(...r.messages);
238
+ continue;
239
+ }
279
240
  if (isTranscriptContextEntry(r)) continue;
280
- if (r.type === "compaction") continue;
281
241
  if (isTranscriptBashExecutionEntry(r)) {
282
242
  const msg = bashExecutionRowToLlmMessage(r);
283
243
  if (msg) out.push(msg);
@@ -289,9 +249,7 @@ function buildSessionContextForLlm(rows) {
289
249
  }
290
250
  if (isLikelyAgentMessage(r)) out.push(r);
291
251
  }
292
- const codingContext = buildCodingContextMessage(out);
293
- if (codingContext) out.push(codingContext);
294
- return out;
252
+ return sanitizeToolPairs(out);
295
253
  }
296
254
  /** Visible chat messages only - no LLM-only audit/context expansion. */
297
255
  function buildSessionDisplayMessages(rows) {
@@ -326,4 +284,4 @@ function mergeLlmMessagesPreservingContextRows(prevRows, llmMessages) {
326
284
  return out;
327
285
  }
328
286
  //#endregion
329
- export { buildSessionContextForLlm, buildSessionDisplayMessages, isTranscriptBashExecutionEntry, isTranscriptContextEntry, isTranscriptCustomMessageEntry, isTranscriptCustomStateEntry, isTranscriptLabelEntry, isTranscriptMetadataEntry, isTranscriptSummaryMessageEntry, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray };
287
+ export { buildSessionContextForLlm, buildSessionDisplayMessages, isRuntimeOnlyTranscriptMessage, isTranscriptBashExecutionEntry, isTranscriptCompactionEntry, isTranscriptContextEntry, isTranscriptCustomMessageEntry, isTranscriptCustomStateEntry, isTranscriptLabelEntry, isTranscriptMetadataEntry, isTranscriptSummaryMessageEntry, mergeLlmMessagesPreservingContextRows, transcriptRowsFromJsonArray };
@@ -1,22 +1,39 @@
1
1
  import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
+ import type { Api, Model } from '@earendil-works/pi-ai/compat';
2
3
  import type { Config } from '../config/schema.js';
3
- import { type CompactionConfig, type CompactionResult } from '../agent/memory/compaction.js';
4
+ import { type CompactionConfig, type CompactionExecutionOptions, type CompactionResult } from '../agent/memory/compaction.js';
4
5
  import { type WindowConfig } from '../agent/memory/window.js';
5
6
  import { type SessionMetadataSeed } from '../storage/sqlite/index.js';
6
7
  import type { XopcSessionTranscriptV1 } from './transcript-format.js';
7
8
  import { type TranscriptStoredRow, type XopcTranscriptContextEntry } from './session-context-for-llm.js';
8
- import type { SessionMetadata, SessionDetail, SessionListQuery, PaginatedResult, GlobalSessionStats, ExportFormat, CompactionCheckpointSummary, CompactionCheckpointDetail } from './types.js';
9
+ import type { SessionMetadata, SessionDetail, SessionListQuery, PaginatedResult, GlobalSessionStats, ExportFormat, CompactionBoundarySummary } from './types.js';
9
10
  import { SessionStatus } from './types.js';
10
11
  import type { Message } from './types.js';
11
12
  import type { SessionTranscriptUpdate } from './transcript-events.js';
12
13
  export interface SessionStoreOptions {
13
14
  config: Config;
14
15
  }
16
+ export interface SessionCompactionHooks {
17
+ before?: (event: {
18
+ sessionKey: string;
19
+ messageCount: number;
20
+ tokenCount: number;
21
+ }) => Promise<void> | void;
22
+ after?: (event: {
23
+ sessionKey: string;
24
+ messageCount: number;
25
+ tokenCount: number;
26
+ compactedCount: number;
27
+ }) => Promise<void> | void;
28
+ }
15
29
  export declare class SessionStore {
16
30
  private options;
17
31
  private window;
18
32
  private compactor;
33
+ private compactionHooks;
19
34
  constructor(options: SessionStoreOptions, windowConfig?: Partial<WindowConfig>, compactionConfig?: Partial<CompactionConfig>);
35
+ setCompactionHooks(hooks: SessionCompactionHooks): void;
36
+ private runCompactionHook;
20
37
  private resolveWorkspaceCwd;
21
38
  private runStoreMutation;
22
39
  initialize(): Promise<void>;
@@ -60,6 +77,7 @@ export declare class SessionStore {
60
77
  } | null>;
61
78
  private buildSessionDetail;
62
79
  loadTranscriptRows(key: string): Promise<TranscriptStoredRow[]>;
80
+ loadTranscriptHistoryRows(key: string): Promise<TranscriptStoredRow[]>;
63
81
  getMetadata(key: string): Promise<SessionMetadata | null>;
64
82
  resolveKeyBySessionId(sessionId: string): Promise<string | null>;
65
83
  updateMetadata(key: string, updates: Partial<SessionMetadata>): Promise<void>;
@@ -109,6 +127,11 @@ export declare class SessionStore {
109
127
  saveMessages(key: string, messages: AgentMessage[], options?: {
110
128
  metadata?: SessionMetadataSeed;
111
129
  }): Promise<void>;
130
+ deleteUserRound(key: string, userRoundIndex: number): Promise<{
131
+ deleted: number;
132
+ removedMessages: AgentMessage[];
133
+ remainingMessages: AgentMessage[];
134
+ } | null>;
112
135
  getWindowStats(messages: AgentMessage[]): {
113
136
  total: number;
114
137
  system: number;
@@ -117,31 +140,16 @@ export declare class SessionStore {
117
140
  tool: number;
118
141
  needsTrim: boolean;
119
142
  };
120
- needsCompaction(key: string, messages: AgentMessage[], contextWindow: number): {
121
- needed: boolean;
122
- reason: string;
123
- usagePercent?: number;
124
- };
125
- prepareCompaction(key: string, messages: AgentMessage[], contextWindow: number): {
126
- needsCompaction: boolean;
127
- messages: AgentMessage[];
128
- stats: {
129
- needed: boolean;
130
- reason: string;
131
- usagePercent?: number;
132
- };
133
- };
134
143
  applyCompaction(key: string, messages: AgentMessage[], result: CompactionResult): Promise<AgentMessage[]>;
135
- compact(key: string, messages: AgentMessage[], contextWindow: number, instructions?: string, force?: boolean): Promise<CompactionResult>;
144
+ compact(key: string, messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, executionOptions?: CompactionExecutionOptions): Promise<CompactionResult>;
136
145
  getCompactionStats(key: string): Promise<{
137
146
  compactionCount: number;
138
147
  totalTokensBefore: number;
139
148
  totalTokensAfter: number;
140
- lastCompactionAt: any;
149
+ lastCompactionAt: string;
141
150
  }>;
142
- listCompactionCheckpoints(key: string): Promise<CompactionCheckpointSummary[]>;
143
- getCompactionCheckpointDetail(key: string, checkpointId: string): Promise<CompactionCheckpointDetail | null>;
144
- restoreCompactionCheckpoint(key: string, checkpointId: string): Promise<void>;
151
+ listCompactionBoundaries(key: string): Promise<CompactionBoundarySummary[]>;
152
+ restoreBeforeCompactionBoundary(key: string, compactionId: string): Promise<void>;
145
153
  deleteSession(key: string): Promise<boolean>;
146
154
  load(key: string, options?: {
147
155
  fromArchive?: boolean;
@@ -168,9 +176,7 @@ export declare class SessionStore {
168
176
  estimateTokens(messages: AgentMessage[]): number;
169
177
  private loadDisplayMessages;
170
178
  private paginateDisplayMessages;
171
- private displayMessageIdentity;
172
179
  private messageContent;
173
- private isCompactionSummaryMessage;
174
180
  private extractTextContent;
175
181
  private injectPostCompactionContext;
176
182
  private convertMessages;