@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
@@ -11,7 +11,7 @@
11
11
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
12
12
  <link rel="manifest" href="/site.webmanifest?v=20260713-1" />
13
13
  <title>XOPC — Turn goals into loops. Keep what matters moving.</title>
14
- <script type="module" crossorigin src="/assets/index-Dfq2laZe.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-DUasAutC.js"></script>
15
15
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
17
17
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
@@ -24,17 +24,17 @@
24
24
  <link rel="modulepreload" crossorigin href="/assets/check-DUBLcKHA.js">
25
25
  <link rel="modulepreload" crossorigin href="/assets/circle-alert-BEjgurr2.js">
26
26
  <link rel="modulepreload" crossorigin href="/assets/middleware-Pd0e8Igk.js">
27
- <link rel="modulepreload" crossorigin href="/assets/messages-KEk-hTFt.js">
28
- <link rel="modulepreload" crossorigin href="/assets/locale-store-Dqp9H2Uf.js">
27
+ <link rel="modulepreload" crossorigin href="/assets/messages-BWtP5TFz.js">
28
+ <link rel="modulepreload" crossorigin href="/assets/locale-store-BP0vD37A.js">
29
29
  <link rel="modulepreload" crossorigin href="/assets/cn-JdwAhgNB.js">
30
30
  <link rel="modulepreload" crossorigin href="/assets/schemas-DgQq6Z5S.js">
31
31
  <link rel="modulepreload" crossorigin href="/assets/product-delivery-BTRT9kCS.js">
32
32
  <link rel="modulepreload" crossorigin href="/assets/config-reload-event-Bjh2zoKp.js">
33
33
  <link rel="modulepreload" crossorigin href="/assets/copy-to-clipboard-HOJ79TWv.js">
34
- <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-CXITih5d.js">
35
- <link rel="modulepreload" crossorigin href="/assets/activity-store-CkUp1qvf.js">
36
- <link rel="modulepreload" crossorigin href="/assets/theme-store-BiC0gIBa.js">
37
- <link rel="stylesheet" crossorigin href="/assets/index-o4uaOGKT.css">
34
+ <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-D3USVm9D.js">
35
+ <link rel="modulepreload" crossorigin href="/assets/activity-store-C3Y-bESI.js">
36
+ <link rel="modulepreload" crossorigin href="/assets/theme-store-C3KnnjcU.js">
37
+ <link rel="stylesheet" crossorigin href="/assets/index-C_XSKOH6.css">
38
38
  </head>
39
39
  <body>
40
40
  <div id="root"></div>
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.0.170";
2
+ var version = "0.0.172";
3
3
  //#endregion
4
4
  export { version };
@@ -2,6 +2,8 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { init_providers, resolveModel } from "../../providers/index.js";
4
4
  import { resolveAgentTurnTimeoutMs } from "../orchestration/run-agent-turn-with-timeout.js";
5
+ import { evaluateContextBudget } from "../memory/context-budget.js";
6
+ import { resolveCompactionPolicy } from "../memory/compaction-policy.js";
5
7
  import { runXopcEmbeddedTurn } from "./run-turn.js";
6
8
  import { applyStartupContextToUserMessage } from "../reply/apply-turn-user-enrichment.js";
7
9
  import { mergeTurnTools, resolveEmbeddedMcpToolsForTurn } from "../mcp/resolve-embedded-mcp-tools.js";
@@ -46,14 +48,6 @@ async function runEmbeddedTurnForSession(params) {
46
48
  const thinkingLevel = params.thinkingOverride ?? agent.state.thinkingLevel;
47
49
  const workspaceDir = agentManager.getResolvedWorkspaceForSession(sessionKey);
48
50
  const config = params.getConfig?.();
49
- await maybeAutoCompactBeforeTurn({
50
- sessionKey,
51
- sessionStore,
52
- agentManager,
53
- model,
54
- config,
55
- onEvent: params.onEvent
56
- });
57
51
  let userMessageForTurn = userMessage;
58
52
  if (params.applyStartupContext !== false) userMessageForTurn = await applyStartupContextToUserMessage({
59
53
  userMessage,
@@ -74,6 +68,20 @@ async function runEmbeddedTurnForSession(params) {
74
68
  });
75
69
  const turnTools = mergeTurnTools(tools, mcpResolved.tools);
76
70
  try {
71
+ await maybeAutoCompactBeforeTurn({
72
+ sessionKey,
73
+ sessionStore,
74
+ agentManager,
75
+ model,
76
+ config,
77
+ systemPrompt,
78
+ userMessage: userMessageForTurn,
79
+ tools: turnTools,
80
+ imageCount: params.llmImages?.length ?? 0,
81
+ fallbackModels: resolvedCandidates.slice(1).map((candidate) => candidate.model),
82
+ abortSignal: params.abortSignal,
83
+ onEvent: params.onEvent
84
+ });
77
85
  log.info({
78
86
  sessionKey,
79
87
  runId,
@@ -167,28 +175,61 @@ async function runEmbeddedTurnForSession(params) {
167
175
  }
168
176
  })();
169
177
  }
178
+ function serializedTranscriptBytes(messages) {
179
+ return Buffer.byteLength(JSON.stringify(messages), "utf8");
180
+ }
170
181
  async function maybeAutoCompactBeforeTurn(opts) {
171
- const { sessionKey, sessionStore, agentManager, model, config, onEvent } = opts;
172
- if (config) try {
173
- if (config.userContext.memory.retention?.compaction === false) return;
174
- } catch {}
182
+ const { sessionKey, sessionStore, agentManager, model, config, systemPrompt, userMessage, tools, imageCount, fallbackModels, abortSignal, onEvent } = opts;
183
+ const policy = resolveCompactionPolicy(config);
175
184
  const contextWindow = model.contextWindow ?? 128e3;
176
185
  const messages = await sessionStore.load(sessionKey);
177
- const prep = sessionStore.prepareCompaction(sessionKey, messages, contextWindow);
178
- if (!prep.needsCompaction) return;
186
+ const activeTranscriptBytes = serializedTranscriptBytes(messages);
187
+ const byteLimitExceeded = policy.enabled && activeTranscriptBytes > policy.maxActiveTranscriptBytes;
188
+ const budget = evaluateContextBudget({
189
+ messages,
190
+ contextWindow,
191
+ systemPrompt,
192
+ currentUserMessage: userMessage,
193
+ tools,
194
+ imageCount,
195
+ triggerThreshold: policy.triggerThreshold,
196
+ reserveTokens: policy.reserveTokens,
197
+ minToolResultKeepChars: policy.minToolResultKeepChars,
198
+ canCompact: messages.length >= policy.minMessagesBeforeCompact
199
+ });
200
+ if (!byteLimitExceeded && (budget.route === "fits" || budget.route === "truncate_tool_results_only")) return;
201
+ if (!policy.enabled) {
202
+ if (budget.estimatedTokens <= budget.hardLimitTokens) return;
203
+ if (budget.estimatedTokens - budget.reducibleToolResultTokens <= budget.hardLimitTokens) return;
204
+ throw new Error(`Context budget exceeded (${budget.estimatedTokens}/${budget.hardLimitTokens} tokens) and compaction is disabled`);
205
+ }
179
206
  log.info({
180
207
  sessionKey,
181
- reason: prep.stats?.reason,
182
- usagePercent: prep.stats?.usagePercent,
183
- contextWindow
208
+ route: budget.route,
209
+ estimatedTokens: budget.estimatedTokens,
210
+ usagePercent: budget.usagePercent,
211
+ contextWindow,
212
+ activeTranscriptBytes,
213
+ maxActiveTranscriptBytes: policy.maxActiveTranscriptBytes,
214
+ byteLimitExceeded
184
215
  }, "Pre-turn auto-compaction triggered");
185
216
  onEvent?.({
186
217
  type: "compaction",
187
218
  status: "started",
188
- tokensBefore: prep.stats?.usagePercent != null ? Math.round(prep.stats.usagePercent * contextWindow) : void 0
219
+ tokensBefore: budget.estimatedTokens
189
220
  });
190
221
  try {
191
- const result = await sessionStore.compact(sessionKey, messages, contextWindow);
222
+ let summaryModel = model;
223
+ let summaryFallbackModels = fallbackModels;
224
+ if (policy.model) {
225
+ summaryModel = resolveModel(policy.model);
226
+ const summaryRef = `${summaryModel.provider}/${summaryModel.id}`;
227
+ summaryFallbackModels = [model, ...fallbackModels].filter((candidate) => `${candidate.provider}/${candidate.id}` !== summaryRef);
228
+ }
229
+ const result = await sessionStore.compact(sessionKey, messages, summaryModel, void 0, byteLimitExceeded || budget.estimatedTokens > budget.hardLimitTokens, {
230
+ fallbackModels: summaryFallbackModels,
231
+ signal: abortSignal
232
+ });
192
233
  if (result.compacted) {
193
234
  agentManager.removeAgent(sessionKey);
194
235
  log.info({
@@ -203,20 +244,26 @@ async function maybeAutoCompactBeforeTurn(opts) {
203
244
  tokensAfter: result.tokensAfter,
204
245
  summary: result.summary.length > 200 ? `${result.summary.slice(0, 200)}…` : result.summary
205
246
  });
206
- } else onEvent?.({
207
- type: "compaction",
208
- status: "skipped"
209
- });
247
+ } else {
248
+ if (byteLimitExceeded || budget.estimatedTokens > budget.hardLimitTokens) throw new Error(byteLimitExceeded ? `Active transcript size exceeded (${activeTranscriptBytes}/${policy.maxActiveTranscriptBytes} bytes) but no safe compaction range was available` : `Context budget exceeded (${budget.estimatedTokens}/${budget.hardLimitTokens} tokens) but no safe compaction range was available`);
249
+ onEvent?.({
250
+ type: "compaction",
251
+ status: "skipped"
252
+ });
253
+ }
210
254
  } catch (err) {
211
255
  const errorMessage = err instanceof Error ? err.message : String(err);
212
256
  log.warn({
213
257
  err,
214
- sessionKey
258
+ sessionKey,
259
+ estimatedTokens: budget.estimatedTokens,
260
+ activeTranscriptBytes
215
261
  }, `Pre-turn auto-compaction failed: ${errorMessage}`);
216
262
  onEvent?.({
217
263
  type: "compaction",
218
264
  status: "skipped"
219
265
  });
266
+ if (byteLimitExceeded || budget.estimatedTokens > budget.hardLimitTokens) throw err;
220
267
  }
221
268
  }
222
269
  //#endregion
@@ -3,11 +3,13 @@ import { init_logger } from "../../utils/logger.js";
3
3
  import { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
4
4
  import { wrapStreamFnForXopcExtensions } from "./xopc-stream-bridge.js";
5
5
  import { acquireEmbeddedSessionRunner, resolveEmbeddedTranscriptInputs } from "./session-runner.js";
6
- import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure } from "../orchestration/llm-turn-retry.js";
6
+ import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure, stripTrailingErrorAssistantMessages } from "../orchestration/llm-turn-retry.js";
7
+ import { pruneToolResultsToFit } from "../memory/context-budget.js";
7
8
  import { abortEmbeddedRun, queueEmbeddedSteer, registerEmbeddedRun, unregisterEmbeddedRun } from "./runs.js";
8
9
  import { lastAssistantPlainText, subscribeEmbeddedSessionEvents } from "./subscribe-session.js";
9
10
  import { detectToolLoops } from "../orchestration/loop-guard.js";
10
11
  import { tryApplySessionTranscriptHygiene } from "../transcript/transcript-hygiene.js";
12
+ import { isContextOverflowError } from "../orchestration/context-overflow.js";
11
13
  //#region src/agent/embedded/run-turn.ts
12
14
  init_logger();
13
15
  const log = createLogger("EmbeddedRun");
@@ -23,6 +25,13 @@ function extractTextFromContent(content) {
23
25
  }).map((block) => block.text).join("");
24
26
  }
25
27
  function extractRecentToolCalls(messages) {
28
+ const resultByToolCallId = /* @__PURE__ */ new Map();
29
+ for (const message of messages) {
30
+ if (message.role !== "toolResult") continue;
31
+ const toolCallId = message.toolCallId;
32
+ if (typeof toolCallId !== "string" || !toolCallId) continue;
33
+ resultByToolCallId.set(toolCallId, truncateForLog(extractTextFromContent(message.content)));
34
+ }
26
35
  const calls = [];
27
36
  for (const message of messages) {
28
37
  if (message.role !== "assistant" || !Array.isArray(message.content)) continue;
@@ -30,7 +39,8 @@ function extractRecentToolCalls(messages) {
30
39
  const toolCall = block;
31
40
  calls.push({
32
41
  name: toolCall.name,
33
- params: toolCall.arguments
42
+ params: toolCall.arguments,
43
+ ...toolCall.id && resultByToolCallId.has(toolCall.id) ? { resultPreview: resultByToolCallId.get(toolCall.id) } : {}
34
44
  });
35
45
  }
36
46
  }
@@ -56,6 +66,33 @@ function userMessageToPromptText(message) {
56
66
  }).map((block) => block.text).join("");
57
67
  return "";
58
68
  }
69
+ async function maybeRecoverContextOverflow(params) {
70
+ const errorMessage = getAssistantTurnErrorMessage(params.agent);
71
+ if (!errorMessage || !isContextOverflowError(errorMessage)) return false;
72
+ const messages = stripTrailingErrorAssistantMessages(params.agent.state.messages);
73
+ log.warn({
74
+ sessionKey: params.sessionKey,
75
+ errorMessage,
76
+ messageCount: messages.length
77
+ }, "Provider rejected the context window; compacting and retrying the same turn");
78
+ params.onEvent?.({
79
+ type: "compaction",
80
+ status: "started"
81
+ });
82
+ const result = await params.sessionStore.compact(params.sessionKey, messages, params.model, "Preserve the current pending user request verbatim and retain every fact needed to answer it.", true);
83
+ if (!result.compacted) throw new Error(`Context overflow recovery could not find a safe compaction range: ${errorMessage}`);
84
+ params.agent.state.messages = await params.sessionStore.load(params.sessionKey);
85
+ params.onEvent?.({
86
+ type: "compaction",
87
+ status: "completed",
88
+ tokensBefore: result.tokensBefore,
89
+ tokensAfter: result.tokensAfter,
90
+ summary: result.summary.length > 200 ? `${result.summary.slice(0, 200)}…` : result.summary
91
+ });
92
+ await params.agent.continue();
93
+ await params.agent.waitForIdle();
94
+ return true;
95
+ }
59
96
  async function runXopcEmbeddedTurn(params) {
60
97
  const { sessionKey, runId, userMessage, model, tools, systemPrompt, thinkingLevel, workspaceDir, sessionStore, onEvent } = params;
61
98
  const timeoutMs = params.timeoutMs || resolveAgentTurnTimeoutMs();
@@ -85,11 +122,11 @@ async function runXopcEmbeddedTurn(params) {
85
122
  messages: hygienicMessages
86
123
  };
87
124
  if (loopGuard.injection || loopGuard.hiddenTools.size > 0) {
88
- const messages = loopGuard.injection ? [...context.messages, {
125
+ const messages = loopGuard.injection ? [...hygienicMessages, {
89
126
  role: "user",
90
127
  content: loopGuard.injection,
91
128
  timestamp: Date.now()
92
- }] : context.messages;
129
+ }] : hygienicMessages;
93
130
  const contextTools = loopGuard.hiddenTools.size > 0 && context.tools ? context.tools.filter((t) => !loopGuard.hiddenTools.has(t.name)) : context.tools;
94
131
  effectiveContext = {
95
132
  ...context,
@@ -97,6 +134,26 @@ async function runXopcEmbeddedTurn(params) {
97
134
  tools: contextTools
98
135
  };
99
136
  }
137
+ const pruned = pruneToolResultsToFit({
138
+ messages: effectiveContext.messages,
139
+ contextWindow: streamModel.contextWindow ?? 128e3,
140
+ systemPrompt: effectiveContext.systemPrompt,
141
+ tools: effectiveContext.tools,
142
+ canCompact: false
143
+ });
144
+ if (pruned.prunedToolResults > 0) {
145
+ effectiveContext = {
146
+ ...effectiveContext,
147
+ messages: pruned.messages
148
+ };
149
+ log.warn({
150
+ sessionKey,
151
+ runId,
152
+ prunedToolResults: pruned.prunedToolResults,
153
+ estimatedTokens: pruned.evaluation.estimatedTokens,
154
+ hardLimitTokens: pruned.evaluation.hardLimitTokens
155
+ }, "Pruned old tool results to fit the model context window");
156
+ }
100
157
  log.debug({
101
158
  sessionKey,
102
159
  runId,
@@ -157,6 +214,13 @@ async function runXopcEmbeddedTurn(params) {
157
214
  sessionKey,
158
215
  log
159
216
  });
217
+ await maybeRecoverContextOverflow({
218
+ agent: session.agent,
219
+ model: resolvedModel,
220
+ sessionKey,
221
+ sessionStore,
222
+ onEvent
223
+ });
160
224
  }, timeoutMs);
161
225
  if (isAssistantTurnAborted(session.agent)) return {
162
226
  ok: true,
@@ -13,7 +13,6 @@
13
13
  * dependencies are injected so this class is unit-testable and the inbound
14
14
  * pipeline can evolve without touching `AgentService`.
15
15
  */
16
- import type { AgentMessage } from '@earendil-works/pi-agent-core';
17
16
  import type { MessageBus } from '../../infra/bus/index.js';
18
17
  import type { Config } from '../../config/schema.js';
19
18
  import type { ChannelManager } from '../../channels/manager.js';
@@ -52,7 +51,6 @@ export interface InboundLoopConfig {
52
51
  /** Returns the visible last assistant text used for outbound + persistent-goal hook. */
53
52
  getLastAssistantPlainText: (sessionKey: string) => string;
54
53
  /** Pre-turn auto-compaction (only used by system messages). */
55
- checkAndCompact: (sessionKey: string, messages: AgentMessage[]) => Promise<void>;
56
54
  /** Fire-and-forget auto-title (no-ops for cron/heartbeat keys). */
57
55
  enqueueMaybeAutoTitleAfterPersist: (sessionKey: string) => void;
58
56
  /** Effective merged config snapshot. */
@@ -206,8 +206,6 @@ var InboundLoop = class {
206
206
  this.log.debug({ sessionKey: context.sessionKey }, "Processing system message");
207
207
  await this.cfg.sessionHydrator.workspace(context.sessionKey);
208
208
  await this.cfg.sessionHydrator.model(context.sessionKey);
209
- const messages = await this.cfg.sessionStore.load(context.sessionKey);
210
- await this.cfg.checkAndCompact(context.sessionKey, messages);
211
209
  const systemMessage = {
212
210
  role: "user",
213
211
  content: [{
@@ -170,8 +170,8 @@ var BuiltinMemoryProvider = class {
170
170
  projectId: request.scope?.projectId,
171
171
  content: request.content,
172
172
  source: {
173
- ...request.source ?? {},
174
- provider: this.id
173
+ provider: this.id,
174
+ ...request.source ?? {}
175
175
  },
176
176
  confidence: request.confidence,
177
177
  tags: request.tags,
@@ -208,9 +208,9 @@ var BuiltinMemoryProvider = class {
208
208
  sessionKey: request.scope?.sessionKey,
209
209
  content: request.content,
210
210
  source: {
211
- ...request.source ?? {},
212
211
  provider: this.id,
213
- path: sourcePathForTarget(target)
212
+ path: sourcePathForTarget(target),
213
+ ...request.source ?? {}
214
214
  },
215
215
  tags: request.tags,
216
216
  canonicalKey: request.canonicalKey,
@@ -0,0 +1,16 @@
1
+ import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
+ export interface CompactionUnit {
3
+ messages: AgentMessage[];
4
+ text: string;
5
+ estimatedTokens: number;
6
+ }
7
+ export interface CompactionChunk {
8
+ text: string;
9
+ estimatedTokens: number;
10
+ messageCount: number;
11
+ oversized: boolean;
12
+ }
13
+ export declare function serializeMessageForCompaction(message: AgentMessage): string;
14
+ export declare function buildCompactionUnits(messages: readonly AgentMessage[]): CompactionUnit[];
15
+ export declare function planCompactionChunks(messages: readonly AgentMessage[], maxChunkTokens: number): CompactionChunk[];
16
+ export declare function extractExactIdentifiers(messages: readonly AgentMessage[], limit?: number): string[];
@@ -0,0 +1,152 @@
1
+ import { readAgentMessageContent } from "./agent-message-access.js";
2
+ import { estimateTextTokens } from "./context-budget.js";
3
+ //#region src/agent/memory/compaction-planner.ts
4
+ function safeJson(value, maxChars = 8e3) {
5
+ let text;
6
+ try {
7
+ text = JSON.stringify(value, (_key, nested) => {
8
+ if (typeof nested === "string" && nested.length > 4e3) return `${nested.slice(0, 2e3)}\n… [${nested.length - 4e3} chars omitted] …\n${nested.slice(-2e3)}`;
9
+ return nested;
10
+ });
11
+ } catch {
12
+ text = String(value);
13
+ }
14
+ if (text.length <= maxChars) return text;
15
+ const half = Math.floor((maxChars - 80) / 2);
16
+ return `${text.slice(0, half)}\n… [structured value truncated] …\n${text.slice(-half)}`;
17
+ }
18
+ function valueRecord(value) {
19
+ return value && typeof value === "object" ? value : void 0;
20
+ }
21
+ function serializeContentBlock(block) {
22
+ const record = valueRecord(block);
23
+ if (!record) return safeJson(block);
24
+ const type = String(record.type ?? "unknown");
25
+ if (type === "text") return String(record.text ?? "");
26
+ if (type === "toolCall") return [
27
+ "[Tool call]",
28
+ `name: ${String(record.name ?? "unknown")}`,
29
+ `id: ${String(record.id ?? record.toolCallId ?? "unknown")}`,
30
+ `arguments: ${safeJson(record.arguments ?? record.args ?? {})}`
31
+ ].join("\n");
32
+ if (type === "image" || type === "audio" || type === "video" || type === "file") {
33
+ const metadata = { ...record };
34
+ delete metadata.data;
35
+ delete metadata.bytes;
36
+ delete metadata.base64;
37
+ return `[${type} content]\nmetadata: ${safeJson(metadata, 2e3)}`;
38
+ }
39
+ if (type === "thinking" || type === "reasoning" || type === "reasoning_details") return "[Assistant private reasoning omitted from compaction input]";
40
+ return `[${type} block]\n${safeJson(record)}`;
41
+ }
42
+ function serializeMessageForCompaction(message) {
43
+ const record = message;
44
+ const raw = readAgentMessageContent(message);
45
+ const content = typeof raw === "string" ? raw : Array.isArray(raw) ? raw.map(serializeContentBlock).filter(Boolean).join("\n\n") : safeJson(raw);
46
+ const metadata = [];
47
+ if (message.role === "toolResult") {
48
+ metadata.push(`tool: ${String(record.toolName ?? "unknown")}`);
49
+ metadata.push(`toolCallId: ${String(record.toolCallId ?? "unknown")}`);
50
+ metadata.push(`status: ${record.isError === true ? "error" : "success"}`);
51
+ if (record.details != null) metadata.push(`details: ${safeJson(record.details, 4e3)}`);
52
+ }
53
+ return [
54
+ `### ${message.role}`,
55
+ ...metadata,
56
+ content
57
+ ].filter(Boolean).join("\n");
58
+ }
59
+ function toolCallIds(message) {
60
+ if (message.role !== "assistant") return /* @__PURE__ */ new Set();
61
+ const raw = readAgentMessageContent(message);
62
+ if (!Array.isArray(raw)) return /* @__PURE__ */ new Set();
63
+ const ids = /* @__PURE__ */ new Set();
64
+ for (const block of raw) {
65
+ const record = valueRecord(block);
66
+ if (record?.type !== "toolCall") continue;
67
+ const id = record.id ?? record.toolCallId;
68
+ if (typeof id === "string" && id) ids.add(id);
69
+ }
70
+ return ids;
71
+ }
72
+ function isMatchingToolResult(message, ids) {
73
+ if (message.role !== "toolResult") return false;
74
+ const id = message.toolCallId;
75
+ return typeof id === "string" && ids.has(id);
76
+ }
77
+ function buildCompactionUnits(messages) {
78
+ const units = [];
79
+ for (let index = 0; index < messages.length; index += 1) {
80
+ const group = [messages[index]];
81
+ const ids = toolCallIds(messages[index]);
82
+ if (ids.size > 0) while (index + 1 < messages.length && isMatchingToolResult(messages[index + 1], ids)) {
83
+ index += 1;
84
+ group.push(messages[index]);
85
+ }
86
+ const text = group.map(serializeMessageForCompaction).join("\n\n");
87
+ units.push({
88
+ messages: group,
89
+ text,
90
+ estimatedTokens: estimateTextTokens(text) + 16
91
+ });
92
+ }
93
+ return units;
94
+ }
95
+ function truncateOversizedUnit(text, maxTokens) {
96
+ const maxChars = Math.max(800, maxTokens * 4);
97
+ if (text.length <= maxChars) return text;
98
+ const marker = `\n\n[Oversized atomic message group: ${text.length - maxChars} characters omitted from the middle]\n\n`;
99
+ const side = Math.max(200, Math.floor((maxChars - marker.length) / 2));
100
+ return `${text.slice(0, side)}${marker}${text.slice(-side)}`;
101
+ }
102
+ function planCompactionChunks(messages, maxChunkTokens) {
103
+ const chunks = [];
104
+ let parts = [];
105
+ let tokens = 0;
106
+ let messageCount = 0;
107
+ const flush = () => {
108
+ if (parts.length === 0) return;
109
+ chunks.push({
110
+ text: parts.join("\n\n"),
111
+ estimatedTokens: tokens,
112
+ messageCount,
113
+ oversized: false
114
+ });
115
+ parts = [];
116
+ tokens = 0;
117
+ messageCount = 0;
118
+ };
119
+ for (const unit of buildCompactionUnits(messages)) {
120
+ if (unit.estimatedTokens > maxChunkTokens) {
121
+ flush();
122
+ const text = truncateOversizedUnit(unit.text, maxChunkTokens);
123
+ chunks.push({
124
+ text,
125
+ estimatedTokens: estimateTextTokens(text),
126
+ messageCount: unit.messages.length,
127
+ oversized: true
128
+ });
129
+ continue;
130
+ }
131
+ if (tokens > 0 && tokens + unit.estimatedTokens > maxChunkTokens) flush();
132
+ parts.push(unit.text);
133
+ tokens += unit.estimatedTokens;
134
+ messageCount += unit.messages.length;
135
+ }
136
+ flush();
137
+ return chunks;
138
+ }
139
+ const IDENTIFIER_PATTERN = /(?:\/?[\w.-]+\/)+(?:[\w.@-]+)|https?:\/\/[^\s)>]+|\b[0-9a-f]{8,64}\b|\b\d{4}-\d{2}-\d{2}\b|\bport\s+\d{2,5}\b/gi;
140
+ function extractExactIdentifiers(messages, limit = 12) {
141
+ const text = messages.map(serializeMessageForCompaction).join("\n");
142
+ const found = /* @__PURE__ */ new Set();
143
+ for (const match of text.matchAll(IDENTIFIER_PATTERN)) {
144
+ const identifier = match[0].trim();
145
+ if (identifier.length < 4) continue;
146
+ found.add(identifier);
147
+ if (found.size >= limit) break;
148
+ }
149
+ return [...found];
150
+ }
151
+ //#endregion
152
+ export { buildCompactionUnits, extractExactIdentifiers, planCompactionChunks, serializeMessageForCompaction };
@@ -0,0 +1,10 @@
1
+ import type { Config } from '../../config/schema.js';
2
+ import { type CompactionConfig } from './compaction.js';
3
+ export interface ResolvedCompactionPolicy extends CompactionConfig {
4
+ reserveTokens: number;
5
+ model?: string;
6
+ minToolResultKeepChars: number;
7
+ maxActiveTranscriptBytes: number;
8
+ postCompactionSections: string[];
9
+ }
10
+ export declare function resolveCompactionPolicy(config?: Config): ResolvedCompactionPolicy;
@@ -0,0 +1,24 @@
1
+ import { DEFAULT_COMPACTION_CONFIG } from "./compaction.js";
2
+ //#region src/agent/memory/compaction-policy.ts
3
+ const POLICY_DEFAULTS = {
4
+ ...DEFAULT_COMPACTION_CONFIG,
5
+ reserveTokens: 8192,
6
+ minToolResultKeepChars: 1e3,
7
+ maxActiveTranscriptBytes: 2e6,
8
+ postCompactionSections: ["Session Startup", "Red Lines"]
9
+ };
10
+ function resolveCompactionPolicy(config) {
11
+ const configured = config?.userContext.memory.retention?.compaction;
12
+ if (!configured) return {
13
+ ...POLICY_DEFAULTS,
14
+ postCompactionSections: [...POLICY_DEFAULTS.postCompactionSections]
15
+ };
16
+ return {
17
+ ...POLICY_DEFAULTS,
18
+ ...configured,
19
+ accumulateUsage: true,
20
+ postCompactionSections: [...configured.postCompactionSections]
21
+ };
22
+ }
23
+ //#endregion
24
+ export { resolveCompactionPolicy };
@@ -1,13 +1,14 @@
1
1
  import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
- import { type Model, type Api } from '@earendil-works/pi-ai/compat';
3
- import { type ConversationSummary } from './summary-generator.js';
2
+ import { type Api, type Model } from '@earendil-works/pi-ai/compat';
4
3
  export interface CompactionResult {
5
4
  summary: string;
6
5
  firstKeptIndex: number;
7
6
  tokensBefore: number;
8
7
  tokensAfter: number;
9
8
  compacted: boolean;
10
- structuredSummary?: ConversationSummary;
9
+ plannerVersion?: number;
10
+ summaryModelRef?: string;
11
+ qualityAudit?: 'passed' | 'disabled';
11
12
  compactedUsage?: {
12
13
  input: number;
13
14
  output: number;
@@ -17,17 +18,22 @@ export interface CompactionResult {
17
18
  }
18
19
  export interface CompactionConfig {
19
20
  enabled: boolean;
20
- mode: 'extractive' | 'abstractive' | 'structured';
21
- reserveTokens: number;
22
21
  triggerThreshold: number;
23
22
  minMessagesBeforeCompact: number;
24
- keepRecentMessages: number;
23
+ keepRecentTokens: number;
24
+ recentTurnsPreserve: number;
25
25
  summaryMaxTokens: number;
26
- evictionWindow: number;
27
- retentionWindow: number;
28
- preserveReasoning: boolean;
26
+ summaryChunkTokens: number;
27
+ summaryTimeoutMs: number;
28
+ summaryRetries: number;
29
+ qualityGuard: boolean;
29
30
  accumulateUsage: boolean;
30
31
  }
32
+ export interface CompactionExecutionOptions {
33
+ fallbackModels?: Array<Model<Api>>;
34
+ signal?: AbortSignal;
35
+ }
36
+ export declare const DEFAULT_COMPACTION_CONFIG: CompactionConfig;
31
37
  interface MessageUsage {
32
38
  input: number;
33
39
  output: number;
@@ -36,20 +42,13 @@ interface MessageUsage {
36
42
  }
37
43
  export declare function accumulateUsage(messages: AgentMessage[]): MessageUsage | undefined;
38
44
  export declare class SessionCompactor {
39
- private model?;
40
- private config;
41
- constructor(config?: Partial<CompactionConfig>, model?: Model<Api>);
42
- needsCompaction(messages: AgentMessage[], contextWindow: number): {
43
- needed: boolean;
44
- reason: string;
45
- usagePercent?: number;
46
- };
47
- compact(messages: AgentMessage[], instructions?: string, force?: boolean): Promise<CompactionResult>;
45
+ private readonly config;
46
+ constructor(config?: Partial<CompactionConfig>);
47
+ getConfig(): Readonly<CompactionConfig>;
48
+ compact(messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
48
49
  private generateSummary;
49
- private llmAbstractiveSummary;
50
- private formatMessages;
51
- private extractiveSummary;
52
- estimateTotalTokens(messages: AgentMessage[]): number;
50
+ private callSummaryModels;
53
51
  applyCompaction(messages: AgentMessage[], result: CompactionResult): AgentMessage[];
52
+ estimateTotalTokens(messages: AgentMessage[]): number;
54
53
  }
55
54
  export {};