@xopcai/xopc 0.0.170 → 0.0.172

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 (242) 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-CkUp1qvf.js → activity-store-C3Y-bESI.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DDuem4HM.js → agent-avatar-dicebear-CPyev9P7.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-Bf_kK2Ay.js +2 -0
  6. package/dist/gateway/static/root/assets/{api-BnuPQhJW.js → api-B7qEr_Rw.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-DdZw8Hi1.js → app-management-settings-panel-Br_9-7fs.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-BN8Vk2bX.js → appearance-settings-uyLcRPai.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-DXFCP5-1.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-C82MaDQj.js → archive-plugin-B19REnR5.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-uilrwSdW.js → attachment-load-DLWCC4Yi.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automation-suggestion-card-CkDZjAmy.js → automation-suggestion-card-ky5S5lly.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-page-D8pT1o2O.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-B7NTL0_T.js → binary-plugins-CtPEzLlo.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-D_LDNlB-.js → block-editor-CQVR4Xij.js} +32 -32
  16. package/dist/gateway/static/root/assets/browser-settings-page-Bav_skKN.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-UFVUzn4v.js → browser-workflow-inputs-CimCGbhq.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-CGgC0N92.js → browser-workflows-page-DewuCw3p.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-BHaYYo9E.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-DUIorGUd.js → capability-presets-api-B5RTs-Az.js} +1 -1
  21. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-PTz00nR4.js → capability-presets-settings-panel-BgchTh81.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-BYwSB8c6.js → channel-recipient-api-Czu0YzIZ.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-BP0e62wt.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-DBWKfeGe.js +1 -0
  25. package/dist/gateway/static/root/assets/connector-logo-Di3gnR_D.js +1 -0
  26. package/dist/gateway/static/root/assets/connectors-page-CC5kh0de.js +2 -0
  27. package/dist/gateway/static/root/assets/{desktop-pet-CkT98fPT.js → desktop-pet-D-ZUNHhn.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-settings-DkbIzdA3.js → desktop-pet-settings-C3L6AI8_.js} +1 -1
  29. package/dist/gateway/static/root/assets/{directory-picker-path-field-dBQvj1sG.js → directory-picker-path-field-Dvq4iG6P.js} +1 -1
  30. package/dist/gateway/static/root/assets/dreaming-settings-D9i54kWO.js +3 -0
  31. package/dist/gateway/static/root/assets/{extension-debug-page-BfxoIiNo.js → extension-debug-page-BecQjU0J.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-EIJ3wIb7.js → extension-page-BeVkPSm-.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-DBBec51N.js → extension-settings-page-DMoo2mKx.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-api-4_u53Ufq.js → gateway-config-api-Bthb3_6v.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-v9kJM59H.js → gateway-settings-Bh8nPvJQ.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-CXITih5d.js → gateway-startup-retry-D3USVm9D.js} +1 -1
  37. package/dist/gateway/static/root/assets/goal-create-dialog-Dp0AyDHI.js +1 -0
  38. package/dist/gateway/static/root/assets/goal-detail-page-CNt7nrdS.js +4 -0
  39. package/dist/gateway/static/root/assets/{goals-config-api-D54YQPon.js → goals-config-api-C_2QWBtb.js} +1 -1
  40. package/dist/gateway/static/root/assets/goals-page-Bm_NZFiZ.js +2 -0
  41. package/dist/gateway/static/root/assets/{goals-settings-DDezXaVi.js → goals-settings-DhL643tc.js} +1 -1
  42. package/dist/gateway/static/root/assets/{heartbeat-settings-CRsIUeZN.js → heartbeat-settings-COVFwp7C.js} +1 -1
  43. package/dist/gateway/static/root/assets/{image-generation-api-CY6cQUHL.js → image-generation-api-BNQlnwpU.js} +1 -1
  44. package/dist/gateway/static/root/assets/index-C_XSKOH6.css +1 -0
  45. package/dist/gateway/static/root/assets/{index-Dfq2laZe.js → index-DUasAutC.js} +67 -67
  46. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D9k7EDdY.js → keyboard-shortcuts-settings-DfdJRJVy.js} +1 -1
  47. package/dist/gateway/static/root/assets/local-app-workbench-page-DZwkD1co.js +2 -0
  48. package/dist/gateway/static/root/assets/{local-apps-page-DbaiBolh.js → local-apps-page-BvCPOgoi.js} +1 -1
  49. package/dist/gateway/static/root/assets/{locale-store-Dqp9H2Uf.js → locale-store-BP0vD37A.js} +1 -1
  50. package/dist/gateway/static/root/assets/{logs-page-DoCY0Mm9.js → logs-page-dNL0Y1dA.js} +3 -3
  51. package/dist/gateway/static/root/assets/{markdown-split-BGlQR-Be.js → markdown-split-YO1rDk9m.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-BpaeV6f_.js → media-plugins-CU_RRf-q.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-BWtP5TFz.js +3 -0
  54. package/dist/gateway/static/root/assets/{notes-page-Cd2HpciM.js → notes-page-CeFiOK3S.js} +1 -1
  55. package/dist/gateway/static/root/assets/notes-workbench-B8MKxpZb.js +4 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-DyimBUp_.js → page-tabs-tiHmRJUA.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-BKZulEYr.js → preview-open-alternatives-CU6XgaCz.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-Bjz9BxBY.js → product-open-page-Dn4_qor4.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-CWBuuX-S.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-BJSsLsXH.js +1 -0
  61. package/dist/gateway/static/root/assets/remote-access-hub-DXJDb8vB.js +1 -0
  62. package/dist/gateway/static/root/assets/{save-bar-controls-BPTqb2_r.js → save-bar-controls-edDUIbXo.js} +1 -1
  63. package/dist/gateway/static/root/assets/{schedule-field-YN0D81Dk.js → schedule-field-DqJO_5Yb.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schema-form-BmY5PSS2.js → schema-form-CMh0jzy5.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-DeHpWgxM.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-Cf-TEYUd.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-B-RhgD_p.js → settings-form-section-Bb0Bc3nJ.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-loading-skeleton-DkPupX2B.js → settings-loading-skeleton-DQhADvz1.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-2QBMvaxj.js → settings-page-b0M5HukN.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-layout-CtrW-LD6.js → settings-page-layout-hvjtIjvh.js} +1 -1
  71. package/dist/gateway/static/root/assets/setup-status-panel-BFyfed_g.js +1 -0
  72. package/dist/gateway/static/root/assets/{share-preview-page-BezIW1n9.js → share-preview-page-rbeaOpTg.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-CYnH9sTt.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-Cr8_m-jS.js +1 -0
  75. package/dist/gateway/static/root/assets/skills-page-Chtc1xDO.js +2 -0
  76. package/dist/gateway/static/root/assets/{system-settings-panel-WAFhKyAu.js → system-settings-panel-BHo_hgnL.js} +1 -1
  77. package/dist/gateway/static/root/assets/{theme-store-BiC0gIBa.js → theme-store-C3KnnjcU.js} +1 -1
  78. package/dist/gateway/static/root/assets/time-picker-D-G-uwVJ.js +1 -0
  79. package/dist/gateway/static/root/assets/{typed-models-lib-WAQO3F_8.js → typed-models-lib-DtRnG-YI.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-channel-catalog-CKlfsSeU.js → use-channel-catalog-CWWItX2g.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-D7qMR26X.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-BAFHF0_v.js → voice-api-key-field-BTnltQHZ.js} +1 -1
  83. package/dist/gateway/static/root/assets/work-discovery-page-CpqFZze9.js +1 -0
  84. package/dist/gateway/static/root/assets/work-item-detail-page-t4dXpGC0.js +1 -0
  85. package/dist/gateway/static/root/assets/work-page-BXwDKiMZ.js +1 -0
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-1OP4HyvS.js → workflow-run-setup-panel-D7vKChFZ.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-Bos9HyqT.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/builtin-provider.js +4 -4
  95. package/dist/src/agent/memory/compaction-planner.d.ts +16 -0
  96. package/dist/src/agent/memory/compaction-planner.js +152 -0
  97. package/dist/src/agent/memory/compaction-policy.d.ts +10 -0
  98. package/dist/src/agent/memory/compaction-policy.js +24 -0
  99. package/dist/src/agent/memory/compaction.d.ts +21 -22
  100. package/dist/src/agent/memory/compaction.js +220 -194
  101. package/dist/src/agent/memory/context-budget.d.ts +40 -0
  102. package/dist/src/agent/memory/context-budget.js +106 -0
  103. package/dist/src/agent/memory/manager.d.ts +4 -1
  104. package/dist/src/agent/memory/manager.js +8 -3
  105. package/dist/src/agent/memory/understanding/service.d.ts +2 -0
  106. package/dist/src/agent/memory/understanding/service.js +11 -9
  107. package/dist/src/agent/orchestration/context-overflow.d.ts +1 -0
  108. package/dist/src/agent/orchestration/context-overflow.js +19 -0
  109. package/dist/src/agent/orchestration/loop-guard.js +13 -9
  110. package/dist/src/agent/reply/post-compaction-context.d.ts +4 -0
  111. package/dist/src/agent/reply/post-compaction-context.js +5 -3
  112. package/dist/src/agent/service/process-direct-one-shot.js +1 -2
  113. package/dist/src/agent/service/process-direct-streaming.js +1 -2
  114. package/dist/src/agent/service.d.ts +1 -2
  115. package/dist/src/agent/service.js +16 -44
  116. package/dist/src/agent/session/session-inspector.js +10 -2
  117. package/dist/src/automations/domain/validation.d.ts +8 -8
  118. package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -1
  119. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  120. package/dist/src/config/schema.d.ts +17 -1
  121. package/dist/src/connectors/composio-sessions.d.ts +1 -0
  122. package/dist/src/connectors/composio-sessions.js +14 -5
  123. package/dist/src/connectors/composio-triggers.d.ts +1 -1
  124. package/dist/src/connectors/composio-triggers.js +4 -3
  125. package/dist/src/connectors/composio.js +1 -0
  126. package/dist/src/connectors/{connector-memory-sync.d.ts → connected-source-ingestion.d.ts} +11 -4
  127. package/dist/src/connectors/{connector-memory-sync.js → connected-source-ingestion.js} +49 -101
  128. package/dist/src/connectors/connected-source-normalizers.d.ts +15 -0
  129. package/dist/src/connectors/connected-source-normalizers.js +186 -0
  130. package/dist/src/connectors/connector-identity.d.ts +2 -0
  131. package/dist/src/connectors/connector-identity.js +29 -0
  132. package/dist/src/connectors/learning-coordinator.d.ts +25 -0
  133. package/dist/src/connectors/learning-coordinator.js +214 -0
  134. package/dist/src/connectors/learning-recipes.d.ts +22 -0
  135. package/dist/src/connectors/learning-recipes.js +121 -0
  136. package/dist/src/connectors/runtime-status.d.ts +1 -8
  137. package/dist/src/connectors/runtime-status.js +4 -29
  138. package/dist/src/gateway/hono/lib/config-payload.d.ts +23 -0
  139. package/dist/src/gateway/hono/lib/config-payload.js +3 -0
  140. package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
  141. package/dist/src/gateway/hono/routes/config-patch/misc.js +28 -0
  142. package/dist/src/gateway/hono/routes/connectors.js +76 -118
  143. package/dist/src/gateway/hono/routes/models.js +24 -0
  144. package/dist/src/gateway/hono/routes/public-gateway.js +3 -2
  145. package/dist/src/gateway/hono/routes/sessions.js +17 -42
  146. package/dist/src/gateway/hono/routes/you.js +86 -5
  147. package/dist/src/gateway/service/sessions-api.d.ts +2 -3
  148. package/dist/src/gateway/service/sessions-api.js +4 -7
  149. package/dist/src/gateway/service.d.ts +5 -2
  150. package/dist/src/gateway/service.js +16 -11
  151. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +19 -0
  152. package/dist/src/knowledge/connected-understanding-pipeline.js +268 -0
  153. package/dist/src/knowledge/index.d.ts +1 -0
  154. package/dist/src/knowledge/index.js +2 -1
  155. package/dist/src/knowledge/ingestion-service.d.ts +6 -4
  156. package/dist/src/knowledge/ingestion-service.js +13 -10
  157. package/dist/src/knowledge/local-folder-adapter.js +1 -0
  158. package/dist/src/knowledge/people-graph.js +43 -110
  159. package/dist/src/knowledge/types.d.ts +3 -0
  160. package/dist/src/providers/xopc-cloud-account-service.d.ts +40 -0
  161. package/dist/src/providers/xopc-cloud-account-service.js +65 -0
  162. package/dist/src/session/index.d.ts +1 -2
  163. package/dist/src/session/index.js +1 -2
  164. package/dist/src/session/init-session-turn.d.ts +0 -1
  165. package/dist/src/session/init-session-turn.js +1 -2
  166. package/dist/src/session/manager.d.ts +11 -17
  167. package/dist/src/session/manager.js +11 -14
  168. package/dist/src/session/session-context-for-llm.d.ts +19 -1
  169. package/dist/src/session/session-context-for-llm.js +87 -129
  170. package/dist/src/session/store.d.ts +28 -23
  171. package/dist/src/session/store.js +94 -83
  172. package/dist/src/session/transcript-format.d.ts +2 -8
  173. package/dist/src/session/types.d.ts +8 -6
  174. package/dist/src/session/user-round-delete.d.ts +3 -6
  175. package/dist/src/session/user-round-delete.js +12 -16
  176. package/dist/src/storage/sqlite/connector-learning-repository.d.ts +47 -0
  177. package/dist/src/storage/sqlite/connector-learning-repository.js +110 -0
  178. package/dist/src/storage/sqlite/index.d.ts +4 -2
  179. package/dist/src/storage/sqlite/index.js +5 -3
  180. package/dist/src/storage/sqlite/knowledge-repository.d.ts +4 -2
  181. package/dist/src/storage/sqlite/knowledge-repository.js +24 -13
  182. package/dist/src/storage/sqlite/migrations/060_remove_runtime_transcript_messages.sql +45 -0
  183. package/dist/src/storage/sqlite/migrations/061_drop_compaction_checkpoints.sql +2 -0
  184. package/dist/src/storage/sqlite/migrations/062_connector_learning_jobs.sql +27 -0
  185. package/dist/src/storage/sqlite/migrations/063_knowledge_collection_scopes.sql +14 -0
  186. package/dist/src/storage/sqlite/migrations/064_user_claims.sql +60 -0
  187. package/dist/src/storage/sqlite/migrations/065_knowledge_item_scope_identity.sql +116 -0
  188. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  189. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  190. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  191. package/dist/src/storage/sqlite/schema.js +1 -1
  192. package/dist/src/storage/sqlite/schema.sql +0 -19
  193. package/dist/src/storage/sqlite/transcript-repository.d.ts +6 -11
  194. package/dist/src/storage/sqlite/transcript-repository.js +90 -84
  195. package/dist/src/storage/sqlite/user-claims-repository.d.ts +101 -0
  196. package/dist/src/storage/sqlite/user-claims-repository.js +241 -0
  197. package/dist/src/user-context/config.d.ts +67 -2
  198. package/dist/src/user-context/config.js +36 -3
  199. package/dist/src/user-context/projection.d.ts +36 -1
  200. package/dist/src/user-context/projection.js +84 -6
  201. package/dist/src/work-discovery/service.js +1 -0
  202. package/package.json +1 -1
  203. package/dist/gateway/static/root/assets/agents-BiaQhiQp.js +0 -2
  204. package/dist/gateway/static/root/assets/apps-page-CuL8Q4yF.js +0 -1
  205. package/dist/gateway/static/root/assets/automations-page-TZOluRNp.js +0 -6
  206. package/dist/gateway/static/root/assets/browser-settings-page-C-l6O68Z.js +0 -8
  207. package/dist/gateway/static/root/assets/capabilities-settings-panel-BW8c0xPp.js +0 -7
  208. package/dist/gateway/static/root/assets/channels-settings-h9CsE0GT.js +0 -1
  209. package/dist/gateway/static/root/assets/channels-status-swr-C058Mcfr.js +0 -1
  210. package/dist/gateway/static/root/assets/connector-logo-CsbegNqi.js +0 -1
  211. package/dist/gateway/static/root/assets/connectors-page-BWALafGW.js +0 -2
  212. package/dist/gateway/static/root/assets/dreaming-settings-DkdnKMZx.js +0 -3
  213. package/dist/gateway/static/root/assets/goal-create-dialog-y2Y3p7_k.js +0 -1
  214. package/dist/gateway/static/root/assets/goal-detail-page-DuzL-alv.js +0 -4
  215. package/dist/gateway/static/root/assets/goals-page-OeLtfKI2.js +0 -2
  216. package/dist/gateway/static/root/assets/index-o4uaOGKT.css +0 -1
  217. package/dist/gateway/static/root/assets/local-app-workbench-page-3ssYIEK6.js +0 -2
  218. package/dist/gateway/static/root/assets/messages-KEk-hTFt.js +0 -3
  219. package/dist/gateway/static/root/assets/notes-workbench-CatZNAPc.js +0 -4
  220. package/dist/gateway/static/root/assets/project-detail-page-DJUOgqm4.js +0 -1
  221. package/dist/gateway/static/root/assets/projects-page-BQQAD_nu.js +0 -1
  222. package/dist/gateway/static/root/assets/remote-access-hub-fIGXTTnA.js +0 -1
  223. package/dist/gateway/static/root/assets/sessions-page-BuU-8FCe.js +0 -1
  224. package/dist/gateway/static/root/assets/settings-advanced-gate-DlKoeZm3.js +0 -1
  225. package/dist/gateway/static/root/assets/setup-status-panel-BSUcDFnb.js +0 -1
  226. package/dist/gateway/static/root/assets/shares-settings-Bk2-SwGJ.js +0 -1
  227. package/dist/gateway/static/root/assets/skill-reload-api-e_Fx1kVC.js +0 -1
  228. package/dist/gateway/static/root/assets/skills-page-D_cCADfj.js +0 -2
  229. package/dist/gateway/static/root/assets/time-picker-fqRXpNJV.js +0 -1
  230. package/dist/gateway/static/root/assets/user-context-page-9Ov4htPW.js +0 -1
  231. package/dist/gateway/static/root/assets/work-discovery-page-DGN2FxWv.js +0 -1
  232. package/dist/gateway/static/root/assets/work-item-detail-page-HmyWSgUo.js +0 -1
  233. package/dist/gateway/static/root/assets/work-page-D3iKVjFq.js +0 -1
  234. package/dist/gateway/static/root/assets/workflows-page-B5L4SFw4.js +0 -11
  235. package/dist/src/agent/lifecycle/handlers/compaction.d.ts +0 -13
  236. package/dist/src/agent/lifecycle/handlers/compaction.js +0 -18
  237. package/dist/src/connectors/memory-sync-coordinator.d.ts +0 -28
  238. package/dist/src/connectors/memory-sync-coordinator.js +0 -162
  239. package/dist/src/connectors/memory-sync-profile.d.ts +0 -13
  240. package/dist/src/connectors/memory-sync-profile.js +0 -73
  241. package/dist/src/session/compaction-checkpoints.d.ts +0 -8
  242. package/dist/src/session/compaction-checkpoints.js +0 -19
@@ -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>;
@@ -110,6 +127,11 @@ export declare class SessionStore {
110
127
  saveMessages(key: string, messages: AgentMessage[], options?: {
111
128
  metadata?: SessionMetadataSeed;
112
129
  }): Promise<void>;
130
+ deleteUserRound(key: string, userRoundIndex: number): Promise<{
131
+ deleted: number;
132
+ removedMessages: AgentMessage[];
133
+ remainingMessages: AgentMessage[];
134
+ } | null>;
113
135
  getWindowStats(messages: AgentMessage[]): {
114
136
  total: number;
115
137
  system: number;
@@ -118,31 +140,16 @@ export declare class SessionStore {
118
140
  tool: number;
119
141
  needsTrim: boolean;
120
142
  };
121
- needsCompaction(key: string, messages: AgentMessage[], contextWindow: number): {
122
- needed: boolean;
123
- reason: string;
124
- usagePercent?: number;
125
- };
126
- prepareCompaction(key: string, messages: AgentMessage[], contextWindow: number): {
127
- needsCompaction: boolean;
128
- messages: AgentMessage[];
129
- stats: {
130
- needed: boolean;
131
- reason: string;
132
- usagePercent?: number;
133
- };
134
- };
135
143
  applyCompaction(key: string, messages: AgentMessage[], result: CompactionResult): Promise<AgentMessage[]>;
136
- 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>;
137
145
  getCompactionStats(key: string): Promise<{
138
146
  compactionCount: number;
139
147
  totalTokensBefore: number;
140
148
  totalTokensAfter: number;
141
- lastCompactionAt: any;
149
+ lastCompactionAt: string;
142
150
  }>;
143
- listCompactionCheckpoints(key: string): Promise<CompactionCheckpointSummary[]>;
144
- getCompactionCheckpointDetail(key: string, checkpointId: string): Promise<CompactionCheckpointDetail | null>;
145
- restoreCompactionCheckpoint(key: string, checkpointId: string): Promise<void>;
151
+ listCompactionBoundaries(key: string): Promise<CompactionBoundarySummary[]>;
152
+ restoreBeforeCompactionBoundary(key: string, compactionId: string): Promise<void>;
146
153
  deleteSession(key: string): Promise<boolean>;
147
154
  load(key: string, options?: {
148
155
  fromArchive?: boolean;
@@ -169,9 +176,7 @@ export declare class SessionStore {
169
176
  estimateTokens(messages: AgentMessage[]): number;
170
177
  private loadDisplayMessages;
171
178
  private paginateDisplayMessages;
172
- private displayMessageIdentity;
173
179
  private messageContent;
174
- private isCompactionSummaryMessage;
175
180
  private extractTextContent;
176
181
  private injectPostCompactionContext;
177
182
  private convertMessages;
@@ -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, loadTranscriptHistoryRowsForSession, 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
  }
@@ -94,8 +114,7 @@ var SessionStore = class {
94
114
  limit,
95
115
  offset: hasBeforeCursor ? void 0 : offset,
96
116
  beforeIndex: hasBeforeCursor ? parsedBefore : void 0,
97
- includeContext: true,
98
- includeArchived: true
117
+ includeContext: true
99
118
  });
100
119
  const messages = transcriptRowsToClientHistory(page.rows);
101
120
  const endIndex = hasBeforeCursor ? Math.min(page.total, Math.max(0, parsedBefore)) : Math.max(0, page.total - offset);
@@ -242,16 +261,19 @@ var SessionStore = class {
242
261
  if (!metadata?.sessionId) return null;
243
262
  const rows = await this.loadTranscriptRows(key);
244
263
  const compactions = [];
245
- for (const row of rows) if (row.type === "compaction") {
246
- const c = row;
247
- compactions.push({
248
- at: c.at ?? (/* @__PURE__ */ new Date()).toISOString(),
249
- summary: c.summary ?? "",
250
- firstKeptIndex: Number(c.firstKeptIndex ?? 0),
251
- tokensBefore: c.tokensBefore ?? 0,
252
- tokensAfter: c.tokensAfter ?? 0
253
- });
254
- }
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
+ });
255
277
  return {
256
278
  type: "xopc_session_transcript",
257
279
  version: 1,
@@ -346,34 +368,42 @@ var SessionStore = class {
346
368
  replaceTranscriptRows(key, mergeLlmMessagesPreservingContextRows(await this.loadTranscriptRows(key), messages));
347
369
  });
348
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
+ }
349
389
  getWindowStats(messages) {
350
390
  return this.window.getStats(messages);
351
391
  }
352
- needsCompaction(key, messages, contextWindow) {
353
- return this.compactor.needsCompaction(messages, contextWindow);
354
- }
355
- prepareCompaction(key, messages, contextWindow) {
356
- const result = this.compactor.needsCompaction(messages, contextWindow);
357
- return {
358
- needsCompaction: result.needed,
359
- messages,
360
- stats: result
361
- };
362
- }
363
392
  async applyCompaction(key, messages, result) {
364
393
  const compacted = this.compactor.applyCompaction(messages, result);
365
394
  return this.runStoreMutation(async () => {
366
- const merged = mergeLlmMessagesPreservingContextRows(await this.loadTranscriptRows(key), compacted);
367
- captureCompactionCheckpoint(key);
368
- replaceTranscriptRows(key, merged, { appendCompaction: {
395
+ appendCompactionBoundary(key, {
396
+ type: "compaction",
369
397
  at: (/* @__PURE__ */ new Date()).toISOString(),
398
+ plannerVersion: result.plannerVersion ?? 2,
399
+ summaryModelRef: result.summaryModelRef ?? "unknown",
400
+ qualityAudit: result.qualityAudit ?? "disabled",
370
401
  summary: result.summary,
402
+ messages: compacted,
371
403
  firstKeptIndex: result.firstKeptIndex,
372
404
  tokensBefore: result.tokensBefore,
373
405
  tokensAfter: result.tokensAfter
374
- } });
375
- const metadata = await this.getMetadata(key);
376
- if (metadata) await this.updateMetadata(key, { compactedCount: metadata.compactedCount + 1 });
406
+ });
377
407
  log.info({
378
408
  key,
379
409
  tokensBefore: result.tokensBefore,
@@ -384,37 +414,44 @@ var SessionStore = class {
384
414
  return compacted;
385
415
  });
386
416
  }
387
- async compact(key, messages, contextWindow, instructions, force) {
388
- const result = await this.compactor.compact(messages, instructions, force);
389
- 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
+ }
390
434
  return result;
391
435
  }
392
436
  async getCompactionStats(key) {
393
- const metadata = await this.getMetadata(key);
394
- if (!metadata) return;
437
+ if (!await this.getMetadata(key)) return void 0;
438
+ const boundaries = listCompactionBoundaries(key);
395
439
  return {
396
- compactionCount: metadata.compactedCount,
397
- totalTokensBefore: 0,
398
- totalTokensAfter: 0,
399
- 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
400
444
  };
401
445
  }
402
- async listCompactionCheckpoints(key) {
403
- requireXopcDatabase();
404
- return listCompactionCheckpoints(key);
405
- }
406
- async getCompactionCheckpointDetail(key, checkpointId) {
446
+ async listCompactionBoundaries(key) {
407
447
  requireXopcDatabase();
408
- const id = normalizeCompactionCheckpointId(checkpointId);
409
- if (!id) return null;
410
- return getCompactionCheckpointDetail(key, id);
448
+ return listCompactionBoundaries(key);
411
449
  }
412
- async restoreCompactionCheckpoint(key, checkpointId) {
450
+ async restoreBeforeCompactionBoundary(key, compactionId) {
413
451
  return this.runStoreMutation(async () => {
414
452
  requireXopcDatabase();
415
- const id = normalizeCompactionCheckpointId(checkpointId);
416
- if (!id) throw new Error(`Invalid checkpoint id: ${checkpointId}`);
417
- restoreCompactionCheckpoint(key, id);
453
+ if (!compactionId.trim()) throw new Error("compactionId is required");
454
+ restoreBeforeCompactionBoundary(key, compactionId);
418
455
  });
419
456
  }
420
457
  async deleteSession(key) {
@@ -553,20 +590,7 @@ var SessionStore = class {
553
590
  }
554
591
  async loadDisplayMessages(key) {
555
592
  requireXopcDatabase();
556
- const checkpoints = listCompactionCheckpoints(key);
557
- const rowSets = [];
558
- for (const checkpoint of [...checkpoints].reverse()) rowSets.push(loadCheckpointRows(key, checkpoint.id));
559
- rowSets.push(await this.loadTranscriptRows(key));
560
- const messages = [];
561
- const seen = /* @__PURE__ */ new Set();
562
- for (const rows of rowSets) for (const message of buildSessionDisplayMessages(rows)) {
563
- if (this.isCompactionSummaryMessage(message)) continue;
564
- const identity = this.displayMessageIdentity(message);
565
- if (seen.has(identity)) continue;
566
- seen.add(identity);
567
- messages.push(message);
568
- }
569
- return messages;
593
+ return buildSessionDisplayMessages(await this.loadTranscriptRows(key));
570
594
  }
571
595
  paginateDisplayMessages(messages, options = {}) {
572
596
  const total = messages.length;
@@ -588,24 +612,9 @@ var SessionStore = class {
588
612
  endIndex
589
613
  };
590
614
  }
591
- displayMessageIdentity(message) {
592
- const record = message;
593
- return JSON.stringify({
594
- role: message.role,
595
- timestamp: record.timestamp,
596
- toolCallId: record.toolCallId ?? record.tool_call_id,
597
- toolName: record.toolName,
598
- content: this.messageContent(message)
599
- });
600
- }
601
615
  messageContent(msg) {
602
616
  return msg.content;
603
617
  }
604
- isCompactionSummaryMessage(msg) {
605
- if (msg.role !== "user") return false;
606
- const text = this.extractTextContent(this.messageContent(msg)).trim();
607
- return /^\[Previous conversation summary\]/i.test(text);
608
- }
609
618
  extractTextContent(content) {
610
619
  if (typeof content === "string") return content;
611
620
  if (Array.isArray(content)) {
@@ -621,9 +630,11 @@ var SessionStore = class {
621
630
  return "";
622
631
  }
623
632
  async injectPostCompactionContext(key) {
633
+ const policy = resolveCompactionPolicy(this.options.config);
624
634
  const contextText = readPostCompactionContext({
625
635
  cfg: this.options.config,
626
- sessionKey: key
636
+ sessionKey: key,
637
+ sectionNames: policy.postCompactionSections
627
638
  });
628
639
  if (!contextText?.trim()) return;
629
640
  try {
@@ -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 };
@@ -0,0 +1,47 @@
1
+ export type ConnectorLearningMode = 'bootstrap' | 'incremental';
2
+ export type ConnectorLearningStatus = 'queued' | 'running' | 'completed' | 'failed' | 'paused';
3
+ export type ConnectorLearningPhase = 'queued' | 'fetching' | 'indexing' | 'deriving' | 'completed';
4
+ export type ConnectorLearningJob = {
5
+ id: string;
6
+ idempotencyKey: string;
7
+ connectorId: string;
8
+ connectionId: string;
9
+ sourceInstanceId: string;
10
+ agentId: string;
11
+ mode: ConnectorLearningMode;
12
+ status: ConnectorLearningStatus;
13
+ phase: ConnectorLearningPhase;
14
+ itemsDiscovered: number;
15
+ itemsIndexed: number;
16
+ candidatesCreated: number;
17
+ attemptCount: number;
18
+ error?: string;
19
+ nextRunAt?: string;
20
+ startedAt?: string;
21
+ finishedAt?: string;
22
+ createdAt: string;
23
+ updatedAt: string;
24
+ };
25
+ export declare function enqueueConnectorLearningJob(input: {
26
+ connectorId: string;
27
+ connectionId: string;
28
+ sourceInstanceId: string;
29
+ agentId: string;
30
+ mode: ConnectorLearningMode;
31
+ idempotencyKey: string;
32
+ nextRunAt?: number;
33
+ nowMs?: number;
34
+ }): ConnectorLearningJob;
35
+ export declare function claimNextConnectorLearningJob(nowMs?: number): ConnectorLearningJob | null;
36
+ export declare function recoverStaleConnectorLearningJobs(staleBeforeMs: number, nowMs?: number): number;
37
+ export declare function setConnectorLearningPaused(connectionId: string, paused: boolean, nowMs?: number): number;
38
+ export declare function updateConnectorLearningJob(id: string, patch: Partial<Pick<ConnectorLearningJob, 'status' | 'phase' | 'itemsDiscovered' | 'itemsIndexed' | 'candidatesCreated' | 'error'>> & {
39
+ nextRunAt?: number | null;
40
+ finished?: boolean;
41
+ nowMs?: number;
42
+ }): ConnectorLearningJob;
43
+ export declare function listConnectorLearningJobs(options?: {
44
+ sourceInstanceId?: string;
45
+ connectionId?: string;
46
+ limit?: number;
47
+ }): ConnectorLearningJob[];
@@ -0,0 +1,110 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
+ import { randomUUID } from "node:crypto";
3
+ //#region src/storage/sqlite/connector-learning-repository.ts
4
+ function iso(value) {
5
+ return value == null ? void 0 : new Date(value).toISOString();
6
+ }
7
+ function fromRow(row) {
8
+ return {
9
+ id: row.job_id,
10
+ idempotencyKey: row.idempotency_key,
11
+ connectorId: row.connector_id,
12
+ connectionId: row.connection_id,
13
+ sourceInstanceId: row.source_instance_id,
14
+ agentId: row.agent_id,
15
+ mode: row.mode,
16
+ status: row.status,
17
+ phase: row.phase,
18
+ itemsDiscovered: row.items_discovered,
19
+ itemsIndexed: row.items_indexed,
20
+ candidatesCreated: row.candidates_created,
21
+ attemptCount: row.attempt_count,
22
+ ...row.error ? { error: row.error } : {},
23
+ ...iso(row.next_run_at) ? { nextRunAt: iso(row.next_run_at) } : {},
24
+ ...iso(row.started_at) ? { startedAt: iso(row.started_at) } : {},
25
+ ...iso(row.finished_at) ? { finishedAt: iso(row.finished_at) } : {},
26
+ createdAt: new Date(row.created_at).toISOString(),
27
+ updatedAt: new Date(row.updated_at).toISOString()
28
+ };
29
+ }
30
+ function enqueueConnectorLearningJob(input) {
31
+ const now = input.nowMs ?? Date.now();
32
+ runSqliteWriteTransaction((db) => {
33
+ db.prepare(`INSERT INTO connector_learning_jobs (
34
+ job_id, idempotency_key, connector_id, connection_id, source_instance_id,
35
+ agent_id, mode, status, phase, next_run_at, created_at, updated_at
36
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, 'queued', 'queued', ?, ?, ?)
37
+ ON CONFLICT(idempotency_key) DO NOTHING`).run(randomUUID(), input.idempotencyKey, input.connectorId, input.connectionId, input.sourceInstanceId, input.agentId, input.mode, input.nextRunAt ?? now, now, now);
38
+ });
39
+ return fromRow(getSqliteDatabase().prepare("SELECT * FROM connector_learning_jobs WHERE idempotency_key = ?").get(input.idempotencyKey));
40
+ }
41
+ function claimNextConnectorLearningJob(nowMs = Date.now()) {
42
+ return runSqliteWriteTransaction((db) => {
43
+ const row = db.prepare(`SELECT * FROM connector_learning_jobs
44
+ WHERE status IN ('queued', 'failed') AND attempt_count < 5 AND COALESCE(next_run_at, 0) <= ?
45
+ ORDER BY next_run_at ASC, created_at ASC LIMIT 1`).get(nowMs);
46
+ if (!row) return null;
47
+ if (db.prepare(`UPDATE connector_learning_jobs SET
48
+ status = 'running', phase = 'fetching', attempt_count = attempt_count + 1,
49
+ error = NULL, started_at = COALESCE(started_at, ?), updated_at = ?
50
+ WHERE job_id = ? AND status IN ('queued', 'failed')`).run(nowMs, nowMs, row.job_id).changes !== 1) return null;
51
+ return fromRow(db.prepare("SELECT * FROM connector_learning_jobs WHERE job_id = ?").get(row.job_id));
52
+ });
53
+ }
54
+ function recoverStaleConnectorLearningJobs(staleBeforeMs, nowMs = Date.now()) {
55
+ return runSqliteWriteTransaction((db) => Number(db.prepare(`UPDATE connector_learning_jobs SET
56
+ status = CASE WHEN attempt_count >= 5 THEN 'paused' ELSE 'failed' END,
57
+ error = 'Interrupted while learning; queued for recovery.',
58
+ next_run_at = CASE WHEN attempt_count >= 5 THEN NULL ELSE ? END,
59
+ finished_at = ?, updated_at = ?
60
+ WHERE status = 'running' AND updated_at < ?`).run(nowMs, nowMs, nowMs, staleBeforeMs).changes));
61
+ }
62
+ function setConnectorLearningPaused(connectionId, paused, nowMs = Date.now()) {
63
+ return runSqliteWriteTransaction((db) => Number(db.prepare(paused ? `UPDATE connector_learning_jobs SET status = 'paused', next_run_at = NULL, updated_at = ?
64
+ WHERE connection_id = ? AND status IN ('queued', 'failed', 'running')` : `UPDATE connector_learning_jobs SET status = 'queued', next_run_at = ?, updated_at = ?
65
+ WHERE connection_id = ? AND status = 'paused'`).run(...paused ? [nowMs, connectionId] : [
66
+ nowMs,
67
+ nowMs,
68
+ connectionId
69
+ ]).changes));
70
+ }
71
+ function updateConnectorLearningJob(id, patch) {
72
+ const now = patch.nowMs ?? Date.now();
73
+ const fields = ["updated_at = ?"];
74
+ const values = [now];
75
+ const add = (column, value) => {
76
+ if (value === void 0) return;
77
+ fields.push(`${column} = ?`);
78
+ values.push(value);
79
+ };
80
+ add("status", patch.status);
81
+ add("phase", patch.phase);
82
+ add("items_discovered", patch.itemsDiscovered);
83
+ add("items_indexed", patch.itemsIndexed);
84
+ add("candidates_created", patch.candidatesCreated);
85
+ add("error", patch.error);
86
+ add("next_run_at", patch.nextRunAt);
87
+ if (patch.finished) add("finished_at", now);
88
+ values.push(id);
89
+ getSqliteDatabase().prepare(`UPDATE connector_learning_jobs SET ${fields.join(", ")} WHERE job_id = ?`).run(...values);
90
+ const row = getSqliteDatabase().prepare("SELECT * FROM connector_learning_jobs WHERE job_id = ?").get(id);
91
+ if (!row) throw new Error(`Connector learning job not found: ${id}`);
92
+ return fromRow(row);
93
+ }
94
+ function listConnectorLearningJobs(options = {}) {
95
+ const clauses = [];
96
+ const values = [];
97
+ if (options.sourceInstanceId) {
98
+ clauses.push("source_instance_id = ?");
99
+ values.push(options.sourceInstanceId);
100
+ }
101
+ if (options.connectionId) {
102
+ clauses.push("connection_id = ?");
103
+ values.push(options.connectionId);
104
+ }
105
+ const limit = Math.max(1, Math.min(options.limit ?? 100, 500));
106
+ return getSqliteDatabase().prepare(`SELECT * FROM connector_learning_jobs ${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""}
107
+ ORDER BY created_at DESC LIMIT ?`).all(...values, limit).map(fromRow);
108
+ }
109
+ //#endregion
110
+ export { claimNextConnectorLearningJob, enqueueConnectorLearningJob, listConnectorLearningJobs, recoverStaleConnectorLearningJobs, setConnectorLearningPaused, updateConnectorLearningJob };