@xopcai/xopc 0.0.142 → 0.0.144

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 (622) hide show
  1. package/README.md +1 -1
  2. package/dist/browser-ext/manifest.json +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
  5. package/dist/extensions/telegram/src/inbound-processor.js +1 -1
  6. package/dist/extensions/telegram/src/plugin.js +1 -1
  7. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  8. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/extensions/weixin/src/api/api.js +1 -1
  11. package/dist/extensions/weixin/src/plugin.js +1 -1
  12. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  13. package/dist/gateway/static/root/assets/activity-center-store-jITiX2vJ.js +1 -0
  14. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BawPxiu5.js → agent-avatar-dicebear-EAVnrCAs.js} +1 -1
  15. package/dist/gateway/static/root/assets/agents-5rTuJOtT.js +2 -0
  16. package/dist/gateway/static/root/assets/{app-management-settings-panel-81xd1p9R.js → app-management-settings-panel-Bu568NpC.js} +1 -1
  17. package/dist/gateway/static/root/assets/{appearance-settings-DYeQsYU8.js → appearance-settings-DSkm9bp_.js} +1 -1
  18. package/dist/gateway/static/root/assets/apps-page-DWetalKp.js +1 -0
  19. package/dist/gateway/static/root/assets/{archive-plugin-D_oa7oti.js → archive-plugin-C99N0vV6.js} +1 -1
  20. package/dist/gateway/static/root/assets/{attachment-load-Cd-bwI2N.js → attachment-load-CHTDqME5.js} +1 -1
  21. package/dist/gateway/static/root/assets/automation-suggestion-card-CBt6U3-S.js +1 -0
  22. package/dist/gateway/static/root/assets/automations-page-ICUfxeOz.js +4 -0
  23. package/dist/gateway/static/root/assets/{binary-plugins-O8svLKWw.js → binary-plugins-BRtxOLlM.js} +1 -1
  24. package/dist/gateway/static/root/assets/block-editor-CUlXfgXd.js +184 -0
  25. package/dist/gateway/static/root/assets/browser-settings-page-D7Bj4MKi.js +8 -0
  26. package/dist/gateway/static/root/assets/{capability-presets-api-dJy1Eqgx.js → capability-presets-api-Bg1ntFSD.js} +1 -1
  27. package/dist/gateway/static/root/assets/capability-presets-settings-panel-C-8I-Ktn.js +2 -0
  28. package/dist/gateway/static/root/assets/{channel-recipient-api-Bfuhp2ty.js → channel-recipient-api-DuulnhIj.js} +1 -1
  29. package/dist/gateway/static/root/assets/channels-settings-Dm5EqQyK.js +1 -0
  30. package/dist/gateway/static/root/assets/channels-status-swr-B5lVrUsN.js +1 -0
  31. package/dist/gateway/static/root/assets/check-BODqo66o.js +1 -0
  32. package/dist/gateway/static/root/assets/chunk-QUQL4437-DXsxWP7r.js +4 -0
  33. package/dist/gateway/static/root/assets/circle-alert-RzVebuX2.js +1 -0
  34. package/dist/gateway/static/root/assets/connectors-page-BOzjh-OK.js +2 -0
  35. package/dist/gateway/static/root/assets/{desktop-pet-DFMfIb5F.js → desktop-pet-C-Drhqyk.js} +1 -1
  36. package/dist/gateway/static/root/assets/desktop-pet-settings-CRGiolqF.js +1 -0
  37. package/dist/gateway/static/root/assets/{directory-picker-path-field-BrYt1gAr.js → directory-picker-path-field-Dw1L3M84.js} +1 -1
  38. package/dist/gateway/static/root/assets/dist-SwiI0Xu3.js +1 -0
  39. package/dist/gateway/static/root/assets/dreaming-settings-CF21cbjo.js +3 -0
  40. package/dist/gateway/static/root/assets/{extension-debug-page-Bh630pLD.js → extension-debug-page-Dcl8LJG_.js} +1 -1
  41. package/dist/gateway/static/root/assets/extension-page-i_BXmO_x.js +1 -0
  42. package/dist/gateway/static/root/assets/extension-settings-page-CWIi7xsn.js +1 -0
  43. package/dist/gateway/static/root/assets/{fetch-B1WtuprY.js → fetch-8QNN25Sh.js} +1 -1
  44. package/dist/gateway/static/root/assets/{gateway-config-api-De2N821l.js → gateway-config-api-2sLP2kkA.js} +1 -1
  45. package/dist/gateway/static/root/assets/gateway-settings-DMHiZc-2.js +1 -0
  46. package/dist/gateway/static/root/assets/{gateway-startup-retry-nEujFSDj.js → gateway-startup-retry-5YBnS9Fj.js} +1 -1
  47. package/dist/gateway/static/root/assets/goal-create-dialog-CAODVDiA.js +1 -0
  48. package/dist/gateway/static/root/assets/goal-detail-page-_d4DjmeX.js +4 -0
  49. package/dist/gateway/static/root/assets/{goals-config-api-DUy3eEse.js → goals-config-api-B4qeLKQS.js} +1 -1
  50. package/dist/gateway/static/root/assets/goals-page-lgsop664.js +2 -0
  51. package/dist/gateway/static/root/assets/goals-settings-Dx_1ZNgb.js +1 -0
  52. package/dist/gateway/static/root/assets/heartbeat-settings-DeTseEk_.js +1 -0
  53. package/dist/gateway/static/root/assets/index-CphxClbs.css +1 -0
  54. package/dist/gateway/static/root/assets/index-VWvztcst.js +257 -0
  55. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CVIwwM15.js → keyboard-shortcuts-settings-BpwpMmlk.js} +1 -1
  56. package/dist/gateway/static/root/assets/logs-page-9_hbTg3j.js +7 -0
  57. package/dist/gateway/static/root/assets/{markdown-split-B_6us9j7.js → markdown-split-BTRFTK0w.js} +1 -1
  58. package/dist/gateway/static/root/assets/{media-plugins-D_fryIyj.js → media-plugins-BABfIZPU.js} +1 -1
  59. package/dist/gateway/static/root/assets/messages-CzKxM6I4.js +5 -0
  60. package/dist/gateway/static/root/assets/models-hub-panel-B1CUvZxh.js +2 -0
  61. package/dist/gateway/static/root/assets/notes-page-88QBHW9a.js +1 -0
  62. package/dist/gateway/static/root/assets/notes-workbench-CerZOeLW.js +2 -0
  63. package/dist/gateway/static/root/assets/{page-tabs-D_8jGlqx.js → page-tabs-je95DZOf.js} +1 -1
  64. package/dist/gateway/static/root/assets/{preview-open-alternatives-BBLMK8Mp.js → preview-open-alternatives-BJbwi7Rc.js} +1 -1
  65. package/dist/gateway/static/root/assets/project-detail-page-BmrApldl.js +1 -0
  66. package/dist/gateway/static/root/assets/projects-page-tTn-k76N.js +1 -0
  67. package/dist/gateway/static/root/assets/remote-access-hub-DeA2-pOi.js +1 -0
  68. package/dist/gateway/static/root/assets/{save-bar-controls-DVS3FR5r.js → save-bar-controls-qWMQ9mod.js} +1 -1
  69. package/dist/gateway/static/root/assets/{schedule-field-D6vKd6-T.js → schedule-field-kxd270Gs.js} +1 -1
  70. package/dist/gateway/static/root/assets/{schema-form-BPy4lbIh.js → schema-form-DLnD-MuD.js} +1 -1
  71. package/dist/gateway/static/root/assets/sessions-page-D4kvvcL1.js +1 -0
  72. package/dist/gateway/static/root/assets/settings-advanced-gate-CI1OG4gq.js +1 -0
  73. package/dist/gateway/static/root/assets/{settings-collapsible-section-WzdikxPt.js → settings-collapsible-section-DQprvu5J.js} +1 -1
  74. package/dist/gateway/static/root/assets/{settings-form-section-CvfzhBV-.js → settings-form-section-Cqq7Y98y.js} +1 -1
  75. package/dist/gateway/static/root/assets/{settings-loading-skeleton-BxR-Ulhi.js → settings-loading-skeleton-b6rXULL5.js} +1 -1
  76. package/dist/gateway/static/root/assets/settings-page-BtBVz3cX.js +1 -0
  77. package/dist/gateway/static/root/assets/{settings-page-layout-CKefvbYi.js → settings-page-layout-BNJbtklV.js} +1 -1
  78. package/dist/gateway/static/root/assets/setup-status-panel-cmclUJzS.js +1 -0
  79. package/dist/gateway/static/root/assets/share-preview-page--zO-A1W1.js +2 -0
  80. package/dist/gateway/static/root/assets/shares-settings-DNJvqA67.js +1 -0
  81. package/dist/gateway/static/root/assets/skill-reload-api-DWr_0Xgn.js +1 -0
  82. package/dist/gateway/static/root/assets/skills-page-DEGsTbJx.js +2 -0
  83. package/dist/gateway/static/root/assets/{system-settings-panel-BokgAgf7.js → system-settings-panel-Cq9J7i7v.js} +1 -1
  84. package/dist/gateway/static/root/assets/{typed-models-lib-BwHlNL3L.js → typed-models-lib-CdSwi1gT.js} +1 -1
  85. package/dist/gateway/static/root/assets/{use-channel-catalog-DR11ap3A.js → use-channel-catalog-COXIfXcl.js} +1 -1
  86. package/dist/gateway/static/root/assets/user-context-page-C-V73ZaJ.js +1 -0
  87. package/dist/gateway/static/root/assets/user-profile-fields-editor-B1cxoGkh.js +1 -0
  88. package/dist/gateway/static/root/assets/user-profile-settings-panel-B8hlamVB.js +1 -0
  89. package/dist/gateway/static/root/assets/{utils-BKUWB-TT.js → utils-Dx01V8qF.js} +1 -1
  90. package/dist/gateway/static/root/assets/voice-api-key-field-DGpIUelZ.js +1 -0
  91. package/dist/gateway/static/root/assets/with-selector-aYPsXwdl.js +1 -0
  92. package/dist/gateway/static/root/assets/work-item-detail-page-fzWTxF26.js +1 -0
  93. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CL_rnAUB.js → workflow-run-setup-panel-Dt_x8LGg.js} +2 -2
  94. package/dist/gateway/static/root/assets/workflows-page-Bg02zEUh.js +11 -0
  95. package/dist/gateway/static/root/assets/workflows-page-DLioOiRN.css +1 -0
  96. package/dist/gateway/static/root/connector-icons/README.md +11 -0
  97. package/dist/gateway/static/root/connector-icons/airtable.svg +13 -0
  98. package/dist/gateway/static/root/connector-icons/asana.svg +15 -0
  99. package/dist/gateway/static/root/connector-icons/brave-search.svg +1 -0
  100. package/dist/gateway/static/root/connector-icons/clickup.svg +19 -0
  101. package/dist/gateway/static/root/connector-icons/composio.svg +266 -0
  102. package/dist/gateway/static/root/connector-icons/discord.svg +15 -0
  103. package/dist/gateway/static/root/connector-icons/dropbox.svg +152 -0
  104. package/dist/gateway/static/root/connector-icons/excel.svg +56 -0
  105. package/dist/gateway/static/root/connector-icons/fetch.svg +6 -0
  106. package/dist/gateway/static/root/connector-icons/figma.svg +178 -0
  107. package/dist/gateway/static/root/connector-icons/filesystem.svg +6 -0
  108. package/dist/gateway/static/root/connector-icons/github.svg +10 -0
  109. package/dist/gateway/static/root/connector-icons/gmail.svg +3 -0
  110. package/dist/gateway/static/root/connector-icons/google-calendar.svg +3 -0
  111. package/dist/gateway/static/root/connector-icons/google-docs.svg +25 -0
  112. package/dist/gateway/static/root/connector-icons/google-drive.svg +25 -0
  113. package/dist/gateway/static/root/connector-icons/google-sheets.svg +1 -0
  114. package/dist/gateway/static/root/connector-icons/hubspot.svg +142 -0
  115. package/dist/gateway/static/root/connector-icons/jira.svg +15 -0
  116. package/dist/gateway/static/root/connector-icons/linear.svg +5 -0
  117. package/dist/gateway/static/root/connector-icons/memory.svg +5 -0
  118. package/dist/gateway/static/root/connector-icons/microsoft-teams.svg +33 -0
  119. package/dist/gateway/static/root/connector-icons/notion.svg +5 -0
  120. package/dist/gateway/static/root/connector-icons/one-drive.svg +13 -0
  121. package/dist/gateway/static/root/connector-icons/outlook.svg +76 -0
  122. package/dist/gateway/static/root/connector-icons/playwright.svg +9 -0
  123. package/dist/gateway/static/root/connector-icons/salesforce.svg +17 -0
  124. package/dist/gateway/static/root/connector-icons/sequential-thinking.svg +8 -0
  125. package/dist/gateway/static/root/connector-icons/shopify.svg +5 -0
  126. package/dist/gateway/static/root/connector-icons/slack.svg +9 -0
  127. package/dist/gateway/static/root/connector-icons/spotify.svg +43 -0
  128. package/dist/gateway/static/root/connector-icons/stripe.svg +11 -0
  129. package/dist/gateway/static/root/connector-icons/telegram.svg +130 -0
  130. package/dist/gateway/static/root/connector-icons/time.svg +6 -0
  131. package/dist/gateway/static/root/connector-icons/todoist.svg +277 -0
  132. package/dist/gateway/static/root/connector-icons/trello.svg +19 -0
  133. package/dist/gateway/static/root/connector-icons/twitter.svg +128 -0
  134. package/dist/gateway/static/root/connector-icons/whatsapp.svg +61 -0
  135. package/dist/gateway/static/root/connector-icons/youtube.svg +11 -0
  136. package/dist/gateway/static/root/index.html +10 -7
  137. package/dist/package.js +1 -1
  138. package/dist/src/activity/emitter.js +1 -1
  139. package/dist/src/agent/agent-manager.d.ts +2 -0
  140. package/dist/src/agent/agent-manager.js +12 -4
  141. package/dist/src/agent/agent-manager.js.map +1 -1
  142. package/dist/src/agent/background-review/prompts.d.ts +1 -1
  143. package/dist/src/agent/background-review/prompts.js +3 -2
  144. package/dist/src/agent/background-review/prompts.js.map +1 -1
  145. package/dist/src/agent/code-intelligence/binary.js +1 -1
  146. package/dist/src/agent/context/project-context.js +2 -2
  147. package/dist/src/agent/context/workspace-seed.js +2 -2
  148. package/dist/src/agent/embedded/run-for-session.js +1 -1
  149. package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
  150. package/dist/src/agent/embedded/xopc-tools-bridge.d.ts +9 -0
  151. package/dist/src/agent/embedded/xopc-tools-bridge.js +71 -3
  152. package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
  153. package/dist/src/agent/goals/post-turn.js +7 -6
  154. package/dist/src/agent/goals/post-turn.js.map +1 -1
  155. package/dist/src/agent/ipc/bus.js +1 -1
  156. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  157. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  158. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  159. package/dist/src/agent/mcp/mcp-transport.js +5 -2
  160. package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
  161. package/dist/src/agent/memory/context/planner.d.ts +1 -0
  162. package/dist/src/agent/memory/context/planner.js +60 -14
  163. package/dist/src/agent/memory/context/planner.js.map +1 -1
  164. package/dist/src/agent/memory/context/types.d.ts +3 -1
  165. package/dist/src/agent/memory/lifecycle.d.ts +11 -0
  166. package/dist/src/agent/memory/lifecycle.js +50 -0
  167. package/dist/src/agent/memory/lifecycle.js.map +1 -0
  168. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  169. package/dist/src/agent/memory/source-origin.d.ts +3 -0
  170. package/dist/src/agent/memory/source-origin.js +19 -0
  171. package/dist/src/agent/memory/source-origin.js.map +1 -0
  172. package/dist/src/agent/memory/understanding/service.js +5 -0
  173. package/dist/src/agent/memory/understanding/service.js.map +1 -1
  174. package/dist/src/agent/memory/user-context-coordinator.js +7 -2
  175. package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
  176. package/dist/src/agent/models/manager.js +1 -1
  177. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
  178. package/dist/src/agent/prompt/sections/behavior.d.ts +2 -0
  179. package/dist/src/agent/prompt/sections/behavior.js +30 -1
  180. package/dist/src/agent/prompt/sections/behavior.js.map +1 -1
  181. package/dist/src/agent/prompt/sections/tooling.js +1 -1
  182. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  183. package/dist/src/agent/prompt/service-prompt-builder.js +8 -1
  184. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  185. package/dist/src/agent/prompt/system-prompt.d.ts +2 -0
  186. package/dist/src/agent/prompt/system-prompt.js +6 -3
  187. package/dist/src/agent/prompt/system-prompt.js.map +1 -1
  188. package/dist/src/agent/service/process-direct-streaming.js +22 -0
  189. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  190. package/dist/src/agent/service.d.ts +2 -0
  191. package/dist/src/agent/service.js +12 -6
  192. package/dist/src/agent/service.js.map +1 -1
  193. package/dist/src/agent/session/session-inspector.js +2 -2
  194. package/dist/src/agent/skills/hub-pull.js +1 -1
  195. package/dist/src/agent/starter-agents.js +1 -1
  196. package/dist/src/agent/starter-agents.js.map +1 -1
  197. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  198. package/dist/src/agent/tool-manuals/xopc-use.js +1 -1
  199. package/dist/src/agent/tool-manuals/xopc-use.js.map +1 -1
  200. package/dist/src/agent/tools/composio-tool.d.ts +18 -5
  201. package/dist/src/agent/tools/composio-tool.js +252 -35
  202. package/dist/src/agent/tools/composio-tool.js.map +1 -1
  203. package/dist/src/agent/tools/factory.js +7 -3
  204. package/dist/src/agent/tools/factory.js.map +1 -1
  205. package/dist/src/agent/tools/goal-tool.js +2 -2
  206. package/dist/src/agent/tools/index.d.ts +1 -1
  207. package/dist/src/agent/tools/index.js +2 -2
  208. package/dist/src/agent/tools/workflow-tool.d.ts +0 -1
  209. package/dist/src/agent/tools/workflow-tool.js +4 -17
  210. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  211. package/dist/src/agent/tools/xopc-use-tool.js +1 -1
  212. package/dist/src/agent/workflow/builtins/index.d.ts +2 -28
  213. package/dist/src/agent/workflow/builtins/index.js +226 -41
  214. package/dist/src/agent/workflow/builtins/index.js.map +1 -1
  215. package/dist/src/agent/workflow/catalog.d.ts +32 -34
  216. package/dist/src/agent/workflow/catalog.js +158 -154
  217. package/dist/src/agent/workflow/catalog.js.map +1 -1
  218. package/dist/src/agent/workflow/index.d.ts +4 -6
  219. package/dist/src/agent/workflow/index.js +2 -5
  220. package/dist/src/agent/workflow/snapshot.d.ts +2 -2
  221. package/dist/src/agent/workflow/snapshot.js +2 -2
  222. package/dist/src/agent/workflow/snapshot.js.map +1 -1
  223. package/dist/src/agent/workflow/structured-output-tool.d.ts +2 -2
  224. package/dist/src/agent/workflow/structured-output-tool.js +2 -2
  225. package/dist/src/agent/workflow/structured-output-tool.js.map +1 -1
  226. package/dist/src/agent/workflow/subagent-runner.js +1 -1
  227. package/dist/src/agent/workflow/types.d.ts +31 -26
  228. package/dist/src/agent/workspace-runtime/registry.js +2 -2
  229. package/dist/src/agent-manifest/index.d.ts +1 -0
  230. package/dist/src/agent-manifest/index.js +3 -1
  231. package/dist/src/agent-manifest/index.js.map +1 -1
  232. package/dist/src/agent-manifest/preset-chain.d.ts +10 -0
  233. package/dist/src/agent-manifest/preset-chain.js +32 -0
  234. package/dist/src/agent-manifest/preset-chain.js.map +1 -0
  235. package/dist/src/agent-manifest/resolver.js +3 -10
  236. package/dist/src/agent-manifest/resolver.js.map +1 -1
  237. package/dist/src/agent-manifest/schema.d.ts +4 -4
  238. package/dist/src/automations/api/routes.js +14 -2
  239. package/dist/src/automations/api/routes.js.map +1 -1
  240. package/dist/src/automations/domain/validation.d.ts +14 -14
  241. package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -3
  242. package/dist/src/automations/service/action-executor.js +2 -2
  243. package/dist/src/browser/cdp-local-launcher.js +1 -1
  244. package/dist/src/browser/providers/browser-ext-install.d.ts +11 -1
  245. package/dist/src/browser/providers/browser-ext-install.js +42 -17
  246. package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
  247. package/dist/src/browser/providers/cloakbrowser.js +2 -2
  248. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  249. package/dist/src/browser/stealth.js +1 -1
  250. package/dist/src/capabilities/store-connector.d.ts +0 -1
  251. package/dist/src/capabilities/store-connector.js +4 -6
  252. package/dist/src/capabilities/store-connector.js.map +1 -1
  253. package/dist/src/chat-commands/agent-edit.js +1 -1
  254. package/dist/src/chat-commands/builtins/config.js +1 -1
  255. package/dist/src/chat-commands/builtins/goal.js +2 -2
  256. package/dist/src/chat-commands/builtins/review.js +72 -73
  257. package/dist/src/chat-commands/builtins/review.js.map +1 -1
  258. package/dist/src/chat-commands/builtins/workflow.js +9 -54
  259. package/dist/src/chat-commands/builtins/workflow.js.map +1 -1
  260. package/dist/src/chat-commands/context.js +1 -1
  261. package/dist/src/cli/commands/agent.js +1 -1
  262. package/dist/src/cli/commands/doctor/checks/database-schema.js +2 -2
  263. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  264. package/dist/src/cli/commands/extension-create.js +2 -2
  265. package/dist/src/cli/commands/extension-create.js.map +1 -1
  266. package/dist/src/cli/commands/extension-marketplace.js +43 -37
  267. package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
  268. package/dist/src/cli/commands/extension-pack.d.ts +6 -0
  269. package/dist/src/cli/commands/extension-pack.js +4 -3
  270. package/dist/src/cli/commands/extension-pack.js.map +1 -1
  271. package/dist/src/cli/commands/goal.js +2 -2
  272. package/dist/src/cli/commands/init.js +1 -1
  273. package/dist/src/cli/commands/project.js +3 -3
  274. package/dist/src/commands/agents.config.d.ts +1 -0
  275. package/dist/src/commands/agents.config.js +1 -0
  276. package/dist/src/commands/agents.config.js.map +1 -1
  277. package/dist/src/config/gateway-bind.js +1 -1
  278. package/dist/src/config/index.js +1 -1
  279. package/dist/src/config/loader.js +1 -1
  280. package/dist/src/config/models-json.js +1 -1
  281. package/dist/src/config/schema.d.ts +6 -6
  282. package/dist/src/config/schema.js +6 -22
  283. package/dist/src/config/schema.js.map +1 -1
  284. package/dist/src/config/web-patch.d.ts +1 -1
  285. package/dist/src/connectors/approval.d.ts +2 -0
  286. package/dist/src/connectors/approval.js +33 -0
  287. package/dist/src/connectors/approval.js.map +1 -0
  288. package/dist/src/connectors/auth-provider-registry.d.ts +9 -0
  289. package/dist/src/connectors/auth-provider-registry.js +17 -0
  290. package/dist/src/connectors/auth-provider-registry.js.map +1 -0
  291. package/dist/src/connectors/builtin-catalog.js +55 -116
  292. package/dist/src/connectors/builtin-catalog.js.map +1 -1
  293. package/dist/src/connectors/catalog.js +7 -2
  294. package/dist/src/connectors/catalog.js.map +1 -1
  295. package/dist/src/connectors/composio-catalog.d.ts +19 -0
  296. package/dist/src/connectors/composio-catalog.js +237 -0
  297. package/dist/src/connectors/composio-catalog.js.map +1 -0
  298. package/dist/src/connectors/composio-logo.d.ts +1 -0
  299. package/dist/src/connectors/composio-logo.js +51 -0
  300. package/dist/src/connectors/composio-logo.js.map +1 -0
  301. package/dist/src/connectors/composio-sessions.d.ts +116 -0
  302. package/dist/src/connectors/composio-sessions.js +296 -0
  303. package/dist/src/connectors/composio-sessions.js.map +1 -0
  304. package/dist/src/connectors/composio-triggers.d.ts +17 -0
  305. package/dist/src/connectors/composio-triggers.js +48 -5
  306. package/dist/src/connectors/composio-triggers.js.map +1 -1
  307. package/dist/src/connectors/composio.d.ts +31 -2
  308. package/dist/src/connectors/composio.js +374 -151
  309. package/dist/src/connectors/composio.js.map +1 -1
  310. package/dist/src/connectors/connector-memory-sync.d.ts +15 -0
  311. package/dist/src/connectors/connector-memory-sync.js +90 -0
  312. package/dist/src/connectors/connector-memory-sync.js.map +1 -0
  313. package/dist/src/connectors/install.js +35 -92
  314. package/dist/src/connectors/install.js.map +1 -1
  315. package/dist/src/connectors/instances.js +6 -2
  316. package/dist/src/connectors/instances.js.map +1 -1
  317. package/dist/src/connectors/integration-strategy.d.ts +3 -0
  318. package/dist/src/connectors/integration-strategy.js +29 -0
  319. package/dist/src/connectors/integration-strategy.js.map +1 -0
  320. package/dist/src/connectors/policy.d.ts +13 -0
  321. package/dist/src/connectors/policy.js +48 -0
  322. package/dist/src/connectors/policy.js.map +1 -0
  323. package/dist/src/connectors/providers.js +1 -1
  324. package/dist/src/connectors/runtime-adapter-registry.d.ts +25 -0
  325. package/dist/src/connectors/runtime-adapter-registry.js +154 -0
  326. package/dist/src/connectors/runtime-adapter-registry.js.map +1 -0
  327. package/dist/src/connectors/types.d.ts +113 -4
  328. package/dist/src/connectors/workflow-preflight.d.ts +20 -0
  329. package/dist/src/connectors/workflow-preflight.js +70 -0
  330. package/dist/src/connectors/workflow-preflight.js.map +1 -0
  331. package/dist/src/daemon/launchd.js +1 -1
  332. package/dist/src/daemon/systemd.js +1 -1
  333. package/dist/src/extensions/discover-extensions.js +1 -1
  334. package/dist/src/extensions/install-transaction.d.ts +16 -0
  335. package/dist/src/extensions/install-transaction.js +76 -0
  336. package/dist/src/extensions/install-transaction.js.map +1 -0
  337. package/dist/src/extensions/install.d.ts +2 -0
  338. package/dist/src/extensions/install.js +23 -1
  339. package/dist/src/extensions/install.js.map +1 -1
  340. package/dist/src/extensions/loader.js +2 -2
  341. package/dist/src/gateway/agents-admin.d.ts +2 -0
  342. package/dist/src/gateway/agents-admin.js +7 -0
  343. package/dist/src/gateway/agents-admin.js.map +1 -1
  344. package/dist/src/gateway/capability-presets-admin.d.ts +11 -0
  345. package/dist/src/gateway/capability-presets-admin.js +11 -4
  346. package/dist/src/gateway/capability-presets-admin.js.map +1 -1
  347. package/dist/src/gateway/chat-stream/mapper.js +17 -0
  348. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  349. package/dist/src/gateway/chat-stream/protocol.d.ts +18 -1
  350. package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -3
  351. package/dist/src/gateway/hono/lib/static-ui.js +1 -1
  352. package/dist/src/gateway/hono/routes/agents.js +3 -0
  353. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  354. package/dist/src/gateway/hono/routes/capability-presets.js +19 -1
  355. package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -1
  356. package/dist/src/gateway/hono/routes/connectors.js +188 -25
  357. package/dist/src/gateway/hono/routes/connectors.js.map +1 -1
  358. package/dist/src/gateway/hono/routes/goals.js +22 -3
  359. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  360. package/dist/src/gateway/hono/routes/home.d.ts +60 -1
  361. package/dist/src/gateway/hono/routes/home.js +244 -18
  362. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  363. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  364. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  365. package/dist/src/gateway/hono/routes/memory.js +17 -4
  366. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  367. package/dist/src/gateway/hono/routes/projects.js +106 -5
  368. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  369. package/dist/src/gateway/hono/routes/public-gateway.js +93 -0
  370. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  371. package/dist/src/gateway/hono/routes/workflows.js +137 -22
  372. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  373. package/dist/src/gateway/hono/routes/you.d.ts +23 -0
  374. package/dist/src/gateway/hono/routes/you.js +538 -0
  375. package/dist/src/gateway/hono/routes/you.js.map +1 -0
  376. package/dist/src/gateway/hono/sse.d.ts +2 -1
  377. package/dist/src/gateway/hono/sse.js +2 -1
  378. package/dist/src/gateway/hono/sse.js.map +1 -1
  379. package/dist/src/gateway/lock.js +1 -1
  380. package/dist/src/gateway/ports.js +1 -1
  381. package/dist/src/gateway/service/marketplace-service.d.ts +13 -1
  382. package/dist/src/gateway/service/marketplace-service.js +96 -40
  383. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  384. package/dist/src/gateway/service.d.ts +2 -0
  385. package/dist/src/gateway/service.js +13 -7
  386. package/dist/src/gateway/service.js.map +1 -1
  387. package/dist/src/goals/goal-service.d.ts +7 -5
  388. package/dist/src/goals/goal-service.js +25 -13
  389. package/dist/src/goals/goal-service.js.map +1 -1
  390. package/dist/src/goals/goal-store.js +46 -7
  391. package/dist/src/goals/goal-store.js.map +1 -1
  392. package/dist/src/goals/goal-workflow-judge.js +1 -1
  393. package/dist/src/goals/types.d.ts +24 -0
  394. package/dist/src/infra/ports.js +1 -1
  395. package/dist/src/infra/ssh-tunnel.js +1 -1
  396. package/dist/src/infra/update-check.js +1 -1
  397. package/dist/src/migrations/runner.js +1 -1
  398. package/dist/src/notes/service.js +3 -3
  399. package/dist/src/notes/store.js +1 -1
  400. package/dist/src/projects/project-service.js +1 -1
  401. package/dist/src/projects/workspace.js +1 -1
  402. package/dist/src/routing/agent-session-key.js +1 -1
  403. package/dist/src/routing/resolve-route.js +1 -1
  404. package/dist/src/routing/resolve-tui-session-key.js +1 -1
  405. package/dist/src/session/init-session-turn.js +1 -1
  406. package/dist/src/session/resolve-session.js +1 -1
  407. package/dist/src/session/session-title.js +2 -2
  408. package/dist/src/session/store.js +1 -1
  409. package/dist/src/storage/sqlite/connection.js +1 -1
  410. package/dist/src/storage/sqlite/connector-repository.d.ts +49 -0
  411. package/dist/src/storage/sqlite/connector-repository.js +385 -0
  412. package/dist/src/storage/sqlite/connector-repository.js.map +1 -0
  413. package/dist/src/storage/sqlite/index.d.ts +3 -0
  414. package/dist/src/storage/sqlite/index.js +4 -1
  415. package/dist/src/storage/sqlite/migrations/030_connectors.sql +94 -0
  416. package/dist/src/storage/sqlite/migrations/031_connector_approvals.sql +24 -0
  417. package/dist/src/storage/sqlite/migrations/032_connector_webhook_deliveries.sql +15 -0
  418. package/dist/src/storage/sqlite/migrations/033_user_trust_policies.sql +6 -0
  419. package/dist/src/storage/sqlite/migrations/034_allow_global_auto_trust.sql +14 -0
  420. package/dist/src/storage/sqlite/migrations/035_user_profile_prompt_state.sql +7 -0
  421. package/dist/src/storage/sqlite/migrations/036_goal_outcome_metric.sql +12 -0
  422. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  423. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  424. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  425. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  426. package/dist/src/storage/sqlite/row-mappers.js +1 -1
  427. package/dist/src/storage/sqlite/schema.js +1 -1
  428. package/dist/src/storage/sqlite/user-profile-setup-repository.d.ts +3 -0
  429. package/dist/src/storage/sqlite/user-profile-setup-repository.js +34 -0
  430. package/dist/src/storage/sqlite/user-profile-setup-repository.js.map +1 -0
  431. package/dist/src/storage/sqlite/user-trust-repository.d.ts +3 -0
  432. package/dist/src/storage/sqlite/user-trust-repository.js +34 -0
  433. package/dist/src/storage/sqlite/user-trust-repository.js.map +1 -0
  434. package/dist/src/tui/backends/embedded-backend.js +4 -4
  435. package/dist/src/tui/clipboard-image.js +1 -1
  436. package/dist/src/tui/components/assistant-message.js +15 -0
  437. package/dist/src/tui/components/assistant-message.js.map +1 -1
  438. package/dist/src/tui/tui-agent-events.js +85 -1
  439. package/dist/src/tui/tui-agent-events.js.map +1 -1
  440. package/dist/src/tui/tui-command-formatters.js +9 -9
  441. package/dist/src/tui/tui-command-formatters.js.map +1 -1
  442. package/dist/src/tui/tui-commands.js +4 -4
  443. package/dist/src/tui/tui-startup-resources.js +1 -1
  444. package/dist/src/tui/tui.js +1 -1
  445. package/dist/src/user-context/import.d.ts +12 -0
  446. package/dist/src/user-context/import.js +48 -0
  447. package/dist/src/user-context/import.js.map +1 -0
  448. package/dist/src/user-context/profile.d.ts +37 -0
  449. package/dist/src/user-context/profile.js +165 -0
  450. package/dist/src/user-context/profile.js.map +1 -0
  451. package/dist/src/user-context/projection.d.ts +54 -0
  452. package/dist/src/user-context/projection.js +121 -0
  453. package/dist/src/user-context/projection.js.map +1 -0
  454. package/dist/src/user-context/source-recommendations.d.ts +13 -0
  455. package/dist/src/user-context/source-recommendations.js +86 -0
  456. package/dist/src/user-context/source-recommendations.js.map +1 -0
  457. package/dist/src/user-context/trust-policy.d.ts +11 -0
  458. package/dist/src/user-context/trust-policy.js +31 -0
  459. package/dist/src/user-context/trust-policy.js.map +1 -0
  460. package/dist/src/utils/index.js +1 -1
  461. package/dist/src/utils/logger/index.js +1 -1
  462. package/dist/src/utils/logger.js +1 -1
  463. package/dist/src/work-items/work-item-service.js +1 -1
  464. package/dist/src/workflows/authoring/index.d.ts +1 -0
  465. package/dist/src/workflows/authoring/index.js +2 -0
  466. package/dist/src/workflows/authoring/workflow-draft-store.d.ts +33 -0
  467. package/dist/src/workflows/authoring/workflow-draft-store.js +74 -0
  468. package/dist/src/workflows/authoring/workflow-draft-store.js.map +1 -0
  469. package/dist/src/workflows/domain/definition-utils.d.ts +6 -4
  470. package/dist/src/workflows/domain/definition-utils.js +28 -26
  471. package/dist/src/workflows/domain/definition-utils.js.map +1 -1
  472. package/dist/src/workflows/domain/definition.d.ts +79 -6
  473. package/dist/src/workflows/domain/event.d.ts +18 -2
  474. package/dist/src/workflows/domain/index.js +3 -3
  475. package/dist/src/workflows/domain/run.d.ts +16 -2
  476. package/dist/src/workflows/domain/run.js.map +1 -1
  477. package/dist/src/workflows/domain/validation.d.ts +9 -5
  478. package/dist/src/workflows/domain/validation.js +183 -40
  479. package/dist/src/workflows/domain/validation.js.map +1 -1
  480. package/dist/src/workflows/draft/workflow-draft-prompt.d.ts +2 -3
  481. package/dist/src/workflows/draft/workflow-draft-prompt.js +31 -73
  482. package/dist/src/workflows/draft/workflow-draft-prompt.js.map +1 -1
  483. package/dist/src/workflows/draft/workflow-draft-service.js +5 -9
  484. package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -1
  485. package/dist/src/workflows/draft/workflow-draft-validator.js +29 -37
  486. package/dist/src/workflows/draft/workflow-draft-validator.js.map +1 -1
  487. package/dist/src/workflows/draft/workflow-draft.types.d.ts +4 -4
  488. package/dist/src/workflows/engine/projector.js +43 -1
  489. package/dist/src/workflows/engine/projector.js.map +1 -1
  490. package/dist/src/workflows/engine/workflow-engine.d.ts +2 -3
  491. package/dist/src/workflows/engine/workflow-engine.js +24 -4
  492. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  493. package/dist/src/workflows/index.js +4 -7
  494. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +1 -9
  495. package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -1
  496. package/dist/src/workflows/runtime/graph-workflow-runtime.d.ts +10 -0
  497. package/dist/src/workflows/runtime/graph-workflow-runtime.js +295 -0
  498. package/dist/src/workflows/runtime/graph-workflow-runtime.js.map +1 -0
  499. package/dist/src/workflows/runtime/index.d.ts +1 -2
  500. package/dist/src/workflows/runtime/index.js +2 -5
  501. package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +5 -8
  502. package/dist/src/workflows/service/workflow-run-service.js +15 -1
  503. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  504. package/dist/src/workflows/service/workflow-run-service.types.d.ts +2 -1
  505. package/dist/src/workflows/service/workflow-session-bridge.js +3 -3
  506. package/package.json +5 -4
  507. package/dist/gateway/static/root/assets/agents-CyvCIHnB.js +0 -2
  508. package/dist/gateway/static/root/assets/apps-page-DK_Vx6nl.js +0 -1
  509. package/dist/gateway/static/root/assets/automation-suggestion-card-B1LV3YYv.js +0 -1
  510. package/dist/gateway/static/root/assets/automations-page-fzrovqhv.js +0 -4
  511. package/dist/gateway/static/root/assets/block-editor-Dhj5f4Bx.js +0 -184
  512. package/dist/gateway/static/root/assets/browser-settings-page-BDn-n-UB.js +0 -8
  513. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Co5ipo_Q.js +0 -1
  514. package/dist/gateway/static/root/assets/channels-settings-BWlpaxg9.js +0 -1
  515. package/dist/gateway/static/root/assets/channels-status-swr-D_jkIZLV.js +0 -1
  516. package/dist/gateway/static/root/assets/connectors-page-BcekbW4q.js +0 -2
  517. package/dist/gateway/static/root/assets/desktop-pet-settings-BJCUuL8Y.js +0 -1
  518. package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +0 -1
  519. package/dist/gateway/static/root/assets/dreaming-settings-BN1Z2mIo.js +0 -3
  520. package/dist/gateway/static/root/assets/extension-page-B-1KxvVy.js +0 -1
  521. package/dist/gateway/static/root/assets/extension-settings-page-BF9NACI3.js +0 -1
  522. package/dist/gateway/static/root/assets/gateway-settings-DN9sNREz.js +0 -1
  523. package/dist/gateway/static/root/assets/goal-create-dialog-BpoQW8cD.js +0 -1
  524. package/dist/gateway/static/root/assets/goal-detail-page-CBRSPd0b.js +0 -4
  525. package/dist/gateway/static/root/assets/goals-page-BCcBi407.js +0 -2
  526. package/dist/gateway/static/root/assets/goals-settings-pkTXzXkh.js +0 -1
  527. package/dist/gateway/static/root/assets/heartbeat-settings-ezsufgLQ.js +0 -1
  528. package/dist/gateway/static/root/assets/index-B8s8Pq5U.css +0 -1
  529. package/dist/gateway/static/root/assets/index-DcUaXYeb.js +0 -262
  530. package/dist/gateway/static/root/assets/logs-page-DQtTRXtj.js +0 -7
  531. package/dist/gateway/static/root/assets/messages-BXNELNBa.js +0 -3
  532. package/dist/gateway/static/root/assets/models-hub-panel-BP2M9n6Q.js +0 -2
  533. package/dist/gateway/static/root/assets/notes-page-CspveYaO.js +0 -1
  534. package/dist/gateway/static/root/assets/notes-workbench-BHwzJ0OC.js +0 -2
  535. package/dist/gateway/static/root/assets/project-detail-page-Dy3rsobs.js +0 -1
  536. package/dist/gateway/static/root/assets/projects-page-CWKpPE0L.js +0 -1
  537. package/dist/gateway/static/root/assets/remote-access-hub-CqNRyXEo.js +0 -1
  538. package/dist/gateway/static/root/assets/sessions-page-MEME7ivF.js +0 -1
  539. package/dist/gateway/static/root/assets/settings-advanced-gate-JVd0qaSF.js +0 -1
  540. package/dist/gateway/static/root/assets/settings-page-DYEbB1EV.js +0 -1
  541. package/dist/gateway/static/root/assets/setup-status-panel-dWN8BJ3z.js +0 -1
  542. package/dist/gateway/static/root/assets/share-preview-page-D8foINzP.js +0 -2
  543. package/dist/gateway/static/root/assets/shares-settings-Tgbv1s7G.js +0 -1
  544. package/dist/gateway/static/root/assets/skill-reload-api-D_YK0b_Z.js +0 -1
  545. package/dist/gateway/static/root/assets/skills-page-DGytfoZK.js +0 -2
  546. package/dist/gateway/static/root/assets/toast-z0toXu32.js +0 -1
  547. package/dist/gateway/static/root/assets/user-profile-settings-panel-8YtygcJp.js +0 -1
  548. package/dist/gateway/static/root/assets/voice-api-key-field-BVH71EFf.js +0 -1
  549. package/dist/gateway/static/root/assets/work-item-detail-page-JeTE7XNM.js +0 -1
  550. package/dist/gateway/static/root/assets/workflow-start-dialog-_u8Uc1ze.js +0 -1
  551. package/dist/gateway/static/root/assets/workflows-page-ixgk_y1l.js +0 -18
  552. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +0 -13
  553. package/dist/src/agent/workflow/builtins/audit-repo.js +0 -183
  554. package/dist/src/agent/workflow/builtins/audit-repo.js.map +0 -1
  555. package/dist/src/agent/workflow/builtins/client-proposal.d.ts +0 -12
  556. package/dist/src/agent/workflow/builtins/client-proposal.js +0 -164
  557. package/dist/src/agent/workflow/builtins/client-proposal.js.map +0 -1
  558. package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +0 -12
  559. package/dist/src/agent/workflow/builtins/competitor-scan.js +0 -164
  560. package/dist/src/agent/workflow/builtins/competitor-scan.js.map +0 -1
  561. package/dist/src/agent/workflow/builtins/content-draft.d.ts +0 -13
  562. package/dist/src/agent/workflow/builtins/content-draft.js +0 -159
  563. package/dist/src/agent/workflow/builtins/content-draft.js.map +0 -1
  564. package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +0 -11
  565. package/dist/src/agent/workflow/builtins/content-repurpose.js +0 -146
  566. package/dist/src/agent/workflow/builtins/content-repurpose.js.map +0 -1
  567. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +0 -13
  568. package/dist/src/agent/workflow/builtins/debug-incident.js +0 -177
  569. package/dist/src/agent/workflow/builtins/debug-incident.js.map +0 -1
  570. package/dist/src/agent/workflow/builtins/decision-compare.d.ts +0 -13
  571. package/dist/src/agent/workflow/builtins/decision-compare.js +0 -187
  572. package/dist/src/agent/workflow/builtins/decision-compare.js.map +0 -1
  573. package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +0 -12
  574. package/dist/src/agent/workflow/builtins/implementation-plan.js +0 -185
  575. package/dist/src/agent/workflow/builtins/implementation-plan.js.map +0 -1
  576. package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +0 -11
  577. package/dist/src/agent/workflow/builtins/inbox-triage.js +0 -158
  578. package/dist/src/agent/workflow/builtins/inbox-triage.js.map +0 -1
  579. package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +0 -12
  580. package/dist/src/agent/workflow/builtins/meeting-prep.js +0 -152
  581. package/dist/src/agent/workflow/builtins/meeting-prep.js.map +0 -1
  582. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +0 -14
  583. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +0 -171
  584. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +0 -1
  585. package/dist/src/agent/workflow/builtins/offer-design.d.ts +0 -12
  586. package/dist/src/agent/workflow/builtins/offer-design.js +0 -170
  587. package/dist/src/agent/workflow/builtins/offer-design.js.map +0 -1
  588. package/dist/src/agent/workflow/builtins/pr-review.d.ts +0 -12
  589. package/dist/src/agent/workflow/builtins/pr-review.js +0 -178
  590. package/dist/src/agent/workflow/builtins/pr-review.js.map +0 -1
  591. package/dist/src/agent/workflow/builtins/release-check.d.ts +0 -11
  592. package/dist/src/agent/workflow/builtins/release-check.js +0 -174
  593. package/dist/src/agent/workflow/builtins/release-check.js.map +0 -1
  594. package/dist/src/agent/workflow/builtins/research.d.ts +0 -13
  595. package/dist/src/agent/workflow/builtins/research.js +0 -188
  596. package/dist/src/agent/workflow/builtins/research.js.map +0 -1
  597. package/dist/src/agent/workflow/builtins/weekly-review.d.ts +0 -12
  598. package/dist/src/agent/workflow/builtins/weekly-review.js +0 -139
  599. package/dist/src/agent/workflow/builtins/weekly-review.js.map +0 -1
  600. package/dist/src/agent/workflow/last-run-memory.d.ts +0 -42
  601. package/dist/src/agent/workflow/last-run-memory.js +0 -60
  602. package/dist/src/agent/workflow/last-run-memory.js.map +0 -1
  603. package/dist/src/agent/workflow/lint.d.ts +0 -38
  604. package/dist/src/agent/workflow/lint.js +0 -74
  605. package/dist/src/agent/workflow/lint.js.map +0 -1
  606. package/dist/src/agent/workflow/meta-locale.d.ts +0 -12
  607. package/dist/src/agent/workflow/meta-locale.js +0 -62
  608. package/dist/src/agent/workflow/meta-locale.js.map +0 -1
  609. package/dist/src/agent/workflow/parser.d.ts +0 -20
  610. package/dist/src/agent/workflow/parser.js +0 -152
  611. package/dist/src/agent/workflow/parser.js.map +0 -1
  612. package/dist/src/agent/workflow/runtime.d.ts +0 -34
  613. package/dist/src/agent/workflow/runtime.js +0 -402
  614. package/dist/src/agent/workflow/runtime.js.map +0 -1
  615. package/dist/src/connectors/oauth.d.ts +0 -22
  616. package/dist/src/connectors/oauth.js +0 -99
  617. package/dist/src/connectors/oauth.js.map +0 -1
  618. package/dist/src/workflows/runtime/script-runtime.d.ts +0 -3
  619. package/dist/src/workflows/runtime/script-runtime.js +0 -3
  620. package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +0 -5
  621. package/dist/src/workflows/runtime/script-workflow-runtime.js +0 -15
  622. package/dist/src/workflows/runtime/script-workflow-runtime.js.map +0 -1
@@ -1,4 +1,6 @@
1
1
  //#region src/agent/embedded/xopc-tools-bridge.ts
2
+ const APPLY_PATCH_BEGIN_MARKER = "*** Begin Patch";
3
+ const APPLY_PATCH_END_MARKER = "*** End Patch";
2
4
  const TOOL_PROMPT_HINTS = {
3
5
  read_file: {
4
6
  promptSnippet: "Read targeted file contents",
@@ -9,8 +11,14 @@ const TOOL_PROMPT_HINTS = {
9
11
  promptGuidelines: ["Prefer apply_patch for code changes. Use write_file only for non-code artifacts or deliberate full-file rewrites."]
10
12
  },
11
13
  apply_patch: {
12
- promptSnippet: "Apply strict multi-file patches for code edits",
13
- promptGuidelines: ["Use apply_patch for all source edits. Keep patches small and verify with exec_command."]
14
+ promptSnippet: "Apply patches using the exact apply_patch envelope",
15
+ promptGuidelines: [
16
+ "Use apply_patch for source edits. Keep patches small and verify with exec_command.",
17
+ "The patch must start exactly with `*** Begin Patch` and end exactly with `*** End Patch`.",
18
+ "Patch control lines must not end in ` ***`; do not wrap the patch in a Markdown code fence or add prose.",
19
+ "Use this shape: `*** Begin Patch\\n*** Update File: path\\n@@\\n-old\\n+new\\n*** End Patch`.",
20
+ "If apply_patch rejects the envelope, regenerate the complete patch from this exact shape instead of repeating it."
21
+ ]
14
22
  },
15
23
  exec_command: {
16
24
  promptSnippet: "Run tests, type checks, builds, package scripts, and safe inspection commands",
@@ -23,6 +31,62 @@ const TOOL_PROMPT_HINTS = {
23
31
  grep: { promptSnippet: "Search file contents for literals, errors, config values, and docs" },
24
32
  find: { promptSnippet: "Find files by glob pattern" }
25
33
  };
34
+ function validateApplyPatchEnvelope(params) {
35
+ if (!params || typeof params !== "object" || Array.isArray(params)) return {
36
+ code: "invalid_patch_envelope",
37
+ field: "patch",
38
+ issue: "missing_patch",
39
+ expected: APPLY_PATCH_BEGIN_MARKER,
40
+ retryHint: "Pass a patch string beginning with the exact marker `*** Begin Patch`."
41
+ };
42
+ const patch = params.patch;
43
+ if (typeof patch !== "string") return {
44
+ code: "invalid_patch_envelope",
45
+ field: "patch",
46
+ issue: "missing_patch",
47
+ expected: APPLY_PATCH_BEGIN_MARKER,
48
+ retryHint: "Pass a patch string beginning with the exact marker `*** Begin Patch`."
49
+ };
50
+ const lines = patch.split(/\r?\n/);
51
+ const firstLine = lines[0] ?? "";
52
+ if (firstLine !== APPLY_PATCH_BEGIN_MARKER) return {
53
+ code: "invalid_patch_envelope",
54
+ field: "patch",
55
+ issue: "first_line",
56
+ expected: APPLY_PATCH_BEGIN_MARKER,
57
+ received: firstLine,
58
+ retryHint: "Use `*** Begin Patch` exactly. Do not add trailing ` ***`, prose, or a Markdown code fence."
59
+ };
60
+ const malformedControlLine = lines.slice(1, -1).find((line) => line.startsWith("*** ") && line.endsWith(" ***"));
61
+ if (malformedControlLine) return {
62
+ code: "invalid_patch_envelope",
63
+ field: "patch",
64
+ issue: "control_line",
65
+ expected: malformedControlLine.slice(0, -4),
66
+ received: malformedControlLine,
67
+ retryHint: "Patch control lines must not end in ` ***`. Remove the trailing stars from this control line."
68
+ };
69
+ const lastLine = lines.at(-1) ?? "";
70
+ if (lastLine !== APPLY_PATCH_END_MARKER) return {
71
+ code: "invalid_patch_envelope",
72
+ field: "patch",
73
+ issue: "last_line",
74
+ expected: APPLY_PATCH_END_MARKER,
75
+ received: lastLine,
76
+ retryHint: "End the patch with `*** End Patch` exactly. Do not add trailing ` ***` or prose."
77
+ };
78
+ return null;
79
+ }
80
+ function invalidApplyPatchEnvelopeResult(error) {
81
+ const received = error.received === void 0 ? "" : ` Received: ${JSON.stringify(error.received)}.`;
82
+ return {
83
+ content: [{
84
+ type: "text",
85
+ text: `apply_patch input rejected (${error.issue}). Expected: ${error.expected}.${received} ${error.retryHint} Use this exact envelope:\n${APPLY_PATCH_BEGIN_MARKER}\n*** Update File: path\n@@\n-old\n+new\n${APPLY_PATCH_END_MARKER}`
86
+ }],
87
+ details: error
88
+ };
89
+ }
26
90
  /** Map xopc {@link AgentTool} instances to pi-coding-agent {@link ToolDefinition}s for `createAgentSession`. */
27
91
  function xopcToolsToDefinitions(tools) {
28
92
  return tools.map((tool) => {
@@ -35,12 +99,16 @@ function xopcToolsToDefinitions(tools) {
35
99
  ...promptHints?.promptGuidelines ? { promptGuidelines: promptHints.promptGuidelines } : {},
36
100
  parameters: tool.parameters,
37
101
  async execute(toolCallId, params, signal, onUpdate) {
102
+ if (tool.name === "apply_patch") {
103
+ const envelopeError = validateApplyPatchEnvelope(params);
104
+ if (envelopeError) return invalidApplyPatchEnvelopeResult(envelopeError);
105
+ }
38
106
  return tool.execute(toolCallId, params, signal, onUpdate);
39
107
  }
40
108
  };
41
109
  });
42
110
  }
43
111
  //#endregion
44
- export { xopcToolsToDefinitions };
112
+ export { validateApplyPatchEnvelope, xopcToolsToDefinitions };
45
113
 
46
114
  //# sourceMappingURL=xopc-tools-bridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"xopc-tools-bridge.js","names":[],"sources":["../../../../src/agent/embedded/xopc-tools-bridge.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nconst TOOL_PROMPT_HINTS: Record<string, { promptSnippet?: string; promptGuidelines?: string[] }> = {\n read_file: {\n promptSnippet: 'Read targeted file contents',\n promptGuidelines: ['Use read_file to inspect source files before editing.'],\n },\n write_file: {\n promptSnippet: 'Create new files or intentional complete rewrites',\n promptGuidelines: ['Prefer apply_patch for code changes. Use write_file only for non-code artifacts or deliberate full-file rewrites.'],\n },\n apply_patch: {\n promptSnippet: 'Apply strict multi-file patches for code edits',\n promptGuidelines: ['Use apply_patch for all source edits. Keep patches small and verify with exec_command.'],\n },\n exec_command: {\n promptSnippet: 'Run tests, type checks, builds, package scripts, and safe inspection commands',\n promptGuidelines: ['Use exec_command for verification and safe inspection, not routine file editing.'],\n },\n update_plan: {\n promptSnippet: 'Update the visible multi-step coding plan',\n promptGuidelines: ['Use update_plan for multi-step coding work and keep the active step current.'],\n },\n grep: {\n promptSnippet: 'Search file contents for literals, errors, config values, and docs',\n },\n find: {\n promptSnippet: 'Find files by glob pattern',\n },\n};\n\n/** Map xopc {@link AgentTool} instances to pi-coding-agent {@link ToolDefinition}s for `createAgentSession`. */\nexport function xopcToolsToDefinitions(tools: AgentTool[]): ToolDefinition[] {\n return tools.map((tool) => {\n const promptHints = TOOL_PROMPT_HINTS[tool.name];\n const def = {\n name: tool.name,\n label: tool.label ?? tool.name,\n description: tool.description ?? tool.name,\n ...(promptHints?.promptSnippet ? { promptSnippet: promptHints.promptSnippet } : {}),\n ...(promptHints?.promptGuidelines ? { promptGuidelines: promptHints.promptGuidelines } : {}),\n parameters: tool.parameters,\n async execute(\n toolCallId: string,\n params: unknown,\n signal: AbortSignal | undefined,\n onUpdate: unknown,\n ) {\n return (tool as { execute: (...a: never[]) => unknown }).execute(\n toolCallId as never,\n params as never,\n signal as never,\n onUpdate as never,\n ) as never;\n },\n };\n return def as unknown as ToolDefinition;\n });\n}\n"],"mappings":";AAGA,MAAM,oBAA6F;CACjG,WAAW;EACT,eAAe;EACf,kBAAkB,CAAC,wDAAwD;EAC5E;CACD,YAAY;EACV,eAAe;EACf,kBAAkB,CAAC,oHAAoH;EACxI;CACD,aAAa;EACX,eAAe;EACf,kBAAkB,CAAC,yFAAyF;EAC7G;CACD,cAAc;EACZ,eAAe;EACf,kBAAkB,CAAC,mFAAmF;EACvG;CACD,aAAa;EACX,eAAe;EACf,kBAAkB,CAAC,+EAA+E;EACnG;CACD,MAAM,EACJ,eAAe,sEAChB;CACD,MAAM,EACJ,eAAe,8BAChB;CACF;;AAGD,SAAgB,uBAAuB,OAAsC;AAC3E,QAAO,MAAM,KAAK,SAAS;EACzB,MAAM,cAAc,kBAAkB,KAAK;AAsB3C,SAAO;GApBL,MAAM,KAAK;GACX,OAAO,KAAK,SAAS,KAAK;GAC1B,aAAa,KAAK,eAAe,KAAK;GACtC,GAAI,aAAa,gBAAgB,EAAE,eAAe,YAAY,eAAe,GAAG,EAAE;GAClF,GAAI,aAAa,mBAAmB,EAAE,kBAAkB,YAAY,kBAAkB,GAAG,EAAE;GAC3F,YAAY,KAAK;GACjB,MAAM,QACJ,YACA,QACA,QACA,UACA;AACA,WAAQ,KAAiD,QACvD,YACA,QACA,QACA,SACD;;GAGK;GACV"}
1
+ {"version":3,"file":"xopc-tools-bridge.js","names":[],"sources":["../../../../src/agent/embedded/xopc-tools-bridge.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { ToolDefinition } from '@earendil-works/pi-coding-agent';\n\nconst APPLY_PATCH_BEGIN_MARKER = '*** Begin Patch';\nconst APPLY_PATCH_END_MARKER = '*** End Patch';\n\nexport type ApplyPatchEnvelopeError = {\n code: 'invalid_patch_envelope';\n field: 'patch';\n issue: 'missing_patch' | 'first_line' | 'control_line' | 'last_line';\n expected: string;\n received?: string;\n retryHint: string;\n};\n\nconst TOOL_PROMPT_HINTS: Record<string, { promptSnippet?: string; promptGuidelines?: string[] }> = {\n read_file: {\n promptSnippet: 'Read targeted file contents',\n promptGuidelines: ['Use read_file to inspect source files before editing.'],\n },\n write_file: {\n promptSnippet: 'Create new files or intentional complete rewrites',\n promptGuidelines: ['Prefer apply_patch for code changes. Use write_file only for non-code artifacts or deliberate full-file rewrites.'],\n },\n apply_patch: {\n promptSnippet: 'Apply patches using the exact apply_patch envelope',\n promptGuidelines: [\n 'Use apply_patch for source edits. Keep patches small and verify with exec_command.',\n 'The patch must start exactly with `*** Begin Patch` and end exactly with `*** End Patch`.',\n 'Patch control lines must not end in ` ***`; do not wrap the patch in a Markdown code fence or add prose.',\n 'Use this shape: `*** Begin Patch\\\\n*** Update File: path\\\\n@@\\\\n-old\\\\n+new\\\\n*** End Patch`.',\n 'If apply_patch rejects the envelope, regenerate the complete patch from this exact shape instead of repeating it.',\n ],\n },\n exec_command: {\n promptSnippet: 'Run tests, type checks, builds, package scripts, and safe inspection commands',\n promptGuidelines: ['Use exec_command for verification and safe inspection, not routine file editing.'],\n },\n update_plan: {\n promptSnippet: 'Update the visible multi-step coding plan',\n promptGuidelines: ['Use update_plan for multi-step coding work and keep the active step current.'],\n },\n grep: {\n promptSnippet: 'Search file contents for literals, errors, config values, and docs',\n },\n find: {\n promptSnippet: 'Find files by glob pattern',\n },\n};\n\nexport function validateApplyPatchEnvelope(params: unknown): ApplyPatchEnvelopeError | null {\n if (!params || typeof params !== 'object' || Array.isArray(params)) {\n return {\n code: 'invalid_patch_envelope',\n field: 'patch',\n issue: 'missing_patch',\n expected: APPLY_PATCH_BEGIN_MARKER,\n retryHint: 'Pass a patch string beginning with the exact marker `*** Begin Patch`.',\n };\n }\n\n const patch = (params as { patch?: unknown }).patch;\n if (typeof patch !== 'string') {\n return {\n code: 'invalid_patch_envelope',\n field: 'patch',\n issue: 'missing_patch',\n expected: APPLY_PATCH_BEGIN_MARKER,\n retryHint: 'Pass a patch string beginning with the exact marker `*** Begin Patch`.',\n };\n }\n\n const lines = patch.split(/\\r?\\n/);\n const firstLine = lines[0] ?? '';\n if (firstLine !== APPLY_PATCH_BEGIN_MARKER) {\n return {\n code: 'invalid_patch_envelope',\n field: 'patch',\n issue: 'first_line',\n expected: APPLY_PATCH_BEGIN_MARKER,\n received: firstLine,\n retryHint: 'Use `*** Begin Patch` exactly. Do not add trailing ` ***`, prose, or a Markdown code fence.',\n };\n }\n\n const malformedControlLine = lines.slice(1, -1).find((line) => line.startsWith('*** ') && line.endsWith(' ***'));\n if (malformedControlLine) {\n return {\n code: 'invalid_patch_envelope',\n field: 'patch',\n issue: 'control_line',\n expected: malformedControlLine.slice(0, -4),\n received: malformedControlLine,\n retryHint: 'Patch control lines must not end in ` ***`. Remove the trailing stars from this control line.',\n };\n }\n\n const lastLine = lines.at(-1) ?? '';\n if (lastLine !== APPLY_PATCH_END_MARKER) {\n return {\n code: 'invalid_patch_envelope',\n field: 'patch',\n issue: 'last_line',\n expected: APPLY_PATCH_END_MARKER,\n received: lastLine,\n retryHint: 'End the patch with `*** End Patch` exactly. Do not add trailing ` ***` or prose.',\n };\n }\n\n return null;\n}\n\nfunction invalidApplyPatchEnvelopeResult(error: ApplyPatchEnvelopeError) {\n const received = error.received === undefined ? '' : ` Received: ${JSON.stringify(error.received)}.`;\n return {\n content: [{\n type: 'text' as const,\n text: `apply_patch input rejected (${error.issue}). Expected: ${error.expected}.${received} ${error.retryHint} Use this exact envelope:\\n${APPLY_PATCH_BEGIN_MARKER}\\n*** Update File: path\\n@@\\n-old\\n+new\\n${APPLY_PATCH_END_MARKER}`,\n }],\n details: error,\n };\n}\n\n/** Map xopc {@link AgentTool} instances to pi-coding-agent {@link ToolDefinition}s for `createAgentSession`. */\nexport function xopcToolsToDefinitions(tools: AgentTool[]): ToolDefinition[] {\n return tools.map((tool) => {\n const promptHints = TOOL_PROMPT_HINTS[tool.name];\n const def = {\n name: tool.name,\n label: tool.label ?? tool.name,\n description: tool.description ?? tool.name,\n ...(promptHints?.promptSnippet ? { promptSnippet: promptHints.promptSnippet } : {}),\n ...(promptHints?.promptGuidelines ? { promptGuidelines: promptHints.promptGuidelines } : {}),\n parameters: tool.parameters,\n async execute(\n toolCallId: string,\n params: unknown,\n signal: AbortSignal | undefined,\n onUpdate: unknown,\n ) {\n if (tool.name === 'apply_patch') {\n const envelopeError = validateApplyPatchEnvelope(params);\n if (envelopeError) {\n return invalidApplyPatchEnvelopeResult(envelopeError) as never;\n }\n }\n\n return (tool as { execute: (...a: never[]) => unknown }).execute(\n toolCallId as never,\n params as never,\n signal as never,\n onUpdate as never,\n ) as never;\n },\n };\n return def as unknown as ToolDefinition;\n });\n}\n"],"mappings":";AAGA,MAAM,2BAA2B;AACjC,MAAM,yBAAyB;AAW/B,MAAM,oBAA6F;CACjG,WAAW;EACT,eAAe;EACf,kBAAkB,CAAC,wDAAwD;EAC5E;CACD,YAAY;EACV,eAAe;EACf,kBAAkB,CAAC,oHAAoH;EACxI;CACD,aAAa;EACX,eAAe;EACf,kBAAkB;GAChB;GACA;GACA;GACA;GACA;GACD;EACF;CACD,cAAc;EACZ,eAAe;EACf,kBAAkB,CAAC,mFAAmF;EACvG;CACD,aAAa;EACX,eAAe;EACf,kBAAkB,CAAC,+EAA+E;EACnG;CACD,MAAM,EACJ,eAAe,sEAChB;CACD,MAAM,EACJ,eAAe,8BAChB;CACF;AAED,SAAgB,2BAA2B,QAAiD;AAC1F,KAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAChE,QAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO;EACP,UAAU;EACV,WAAW;EACZ;CAGH,MAAM,QAAS,OAA+B;AAC9C,KAAI,OAAO,UAAU,SACnB,QAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO;EACP,UAAU;EACV,WAAW;EACZ;CAGH,MAAM,QAAQ,MAAM,MAAM,QAAQ;CAClC,MAAM,YAAY,MAAM,MAAM;AAC9B,KAAI,cAAc,yBAChB,QAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO;EACP,UAAU;EACV,UAAU;EACV,WAAW;EACZ;CAGH,MAAM,uBAAuB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,SAAS,KAAK,WAAW,OAAO,IAAI,KAAK,SAAS,OAAO,CAAC;AAChH,KAAI,qBACF,QAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO;EACP,UAAU,qBAAqB,MAAM,GAAG,GAAG;EAC3C,UAAU;EACV,WAAW;EACZ;CAGH,MAAM,WAAW,MAAM,GAAG,GAAG,IAAI;AACjC,KAAI,aAAa,uBACf,QAAO;EACL,MAAM;EACN,OAAO;EACP,OAAO;EACP,UAAU;EACV,UAAU;EACV,WAAW;EACZ;AAGH,QAAO;;AAGT,SAAS,gCAAgC,OAAgC;CACvE,MAAM,WAAW,MAAM,aAAa,KAAA,IAAY,KAAK,cAAc,KAAK,UAAU,MAAM,SAAS,CAAC;AAClG,QAAO;EACL,SAAS,CAAC;GACR,MAAM;GACN,MAAM,+BAA+B,MAAM,MAAM,eAAe,MAAM,SAAS,GAAG,SAAS,GAAG,MAAM,UAAU,6BAA6B,yBAAyB,2CAA2C;GAChN,CAAC;EACF,SAAS;EACV;;;AAIH,SAAgB,uBAAuB,OAAsC;AAC3E,QAAO,MAAM,KAAK,SAAS;EACzB,MAAM,cAAc,kBAAkB,KAAK;AA6B3C,SAAO;GA3BL,MAAM,KAAK;GACX,OAAO,KAAK,SAAS,KAAK;GAC1B,aAAa,KAAK,eAAe,KAAK;GACtC,GAAI,aAAa,gBAAgB,EAAE,eAAe,YAAY,eAAe,GAAG,EAAE;GAClF,GAAI,aAAa,mBAAmB,EAAE,kBAAkB,YAAY,kBAAkB,GAAG,EAAE;GAC3F,YAAY,KAAK;GACjB,MAAM,QACJ,YACA,QACA,QACA,UACA;AACA,QAAI,KAAK,SAAS,eAAe;KAC/B,MAAM,gBAAgB,2BAA2B,OAAO;AACxD,SAAI,cACF,QAAO,gCAAgC,cAAc;;AAIzD,WAAQ,KAAiD,QACvD,YACA,QACA,QACA,SACD;;GAGK;GACV"}
@@ -1,7 +1,7 @@
1
- import { createLogger } from "../../utils/logger/index.js";
2
- import { init_logger } from "../../utils/logger.js";
3
1
  import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
4
2
  import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
+ import { createLogger } from "../../utils/logger/index.js";
4
+ import { init_logger } from "../../utils/logger.js";
5
5
  import { GoalService } from "../../goals/goal-service.js";
6
6
  import { resolveGoalUiLocale } from "./goal-locale.js";
7
7
  import { evaluateAfterTurnHermesLike } from "./evaluate-turn.js";
@@ -102,8 +102,9 @@ async function handlePersistentGoalPostTurn(opts) {
102
102
  uiLocale: resolveGoalUiLocale(state)
103
103
  });
104
104
  const completionReadiness = goalService.getCompletionReadiness(goal.id);
105
- if (decision.verdict === "done" && completionReadiness && !completionReadiness.ready && decision.newState) {
106
- const reason = `Completion evidence still needed: ${completionReadiness.missingEvidence.join("; ")}`;
105
+ const executionGaps = completionReadiness ? [...completionReadiness.missingEvidence, ...completionReadiness.pendingOutcome] : [];
106
+ if (decision.verdict === "done" && executionGaps.length > 0 && decision.newState) {
107
+ const reason = `Completion evidence or outcome still needed: ${executionGaps.join("; ")}`;
107
108
  decision = {
108
109
  ...decision,
109
110
  newState: {
@@ -113,11 +114,11 @@ async function handlePersistentGoalPostTurn(opts) {
113
114
  lastReason: reason
114
115
  },
115
116
  shouldContinue: true,
116
- continuationPrompt: `Before declaring the goal complete, collect this evidence:\n${completionReadiness.missingEvidence.map((item) => `- ${item}`).join("\n")}`,
117
+ continuationPrompt: `Before declaring the goal complete, address these gaps:\n${executionGaps.map((item) => `- ${item}`).join("\n")}`,
117
118
  verdict: "continue",
118
119
  reason,
119
120
  message: reason,
120
- missingEvidence: completionReadiness.missingEvidence
121
+ missingEvidence: executionGaps
121
122
  };
122
123
  }
123
124
  if (decision.newState) {
@@ -1 +1 @@
1
- {"version":3,"file":"post-turn.js","names":[],"sources":["../../../../src/agent/goals/post-turn.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config, GoalsConfig } from '../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport { GoalService } from '../../goals/index.js';\nimport { createLogger } from '../../utils/logger.js';\n\nimport { evaluateAfterTurnHermesLike } from './evaluate-turn.js';\nimport { resolveGoalUiLocale } from './goal-locale.js';\nimport type { PersistentGoalApis } from './persistent-goal-apis.js';\nimport type { PersistentGoalState } from './state.js';\n\nconst log = createLogger('PersistentGoal');\nconst goalService = new GoalService();\n\nfunction buildHistoryExcerpt(messages: AgentMessage[], maxChars: number): string {\n if (maxChars <= 0) return '';\n try {\n const raw = JSON.stringify(messages);\n if (raw.length <= maxChars) return raw;\n return raw.slice(-maxChars);\n } catch {\n return '';\n }\n}\n\nfunction buildGoalContextText(goal: NonNullable<ReturnType<GoalService['get']>>): string {\n const lines = [`Title: ${goal.contract?.objective || goal.title}`];\n if (goal.contract?.scopeBoundary) {\n lines.push(`Scope boundary:\\n${goal.contract.scopeBoundary}`);\n }\n if (goal.contract?.evidencePlan.length) {\n lines.push(`Expected completion evidence:\\n${goal.contract.evidencePlan.map((item) => `- ${item}`).join('\\n')}`);\n }\n if (goal.contextMessage?.text.trim()) {\n lines.push(`Context:\\n${goal.contextMessage.text.trim()}`);\n }\n if (goal.contextMessage?.attachments.length) {\n lines.push(\n [\n 'Attachments:',\n ...goal.contextMessage.attachments.map((attachment) =>\n `- ${attachment.name} (${attachment.mimeType}, ${attachment.size} bytes) ${attachment.uri}`,\n ),\n ].join('\\n'),\n );\n }\n return lines.join('\\n\\n');\n}\n\nfunction resolveJudgeModelRef(\n config: Config | undefined,\n sessionKey: string,\n storedJudge?: string,\n runtimeSessionModelRef?: string,\n): string | undefined {\n const fromCfg = config?.goals?.judgeModelRef?.trim();\n if (fromCfg) return fromCfg;\n if (storedJudge?.trim()) return storedJudge.trim();\n if (config) {\n const profile = resolveEffectiveAgentProfileForSession(config, sessionKey);\n if (profile.primaryModelRef?.trim()) return profile.primaryModelRef.trim();\n }\n if (runtimeSessionModelRef?.trim()) return runtimeSessionModelRef.trim();\n if (config) return getAgentDefaultModelRef(config);\n return undefined;\n}\n\nexport function shouldRunInitialChecklistDecomposition(input: {\n checklistLength: number;\n turnsUsed: number;\n checklistDecomposePolicy?: GoalsConfig['checklistDecomposePolicy'];\n}): boolean {\n if (input.checklistLength === 0) return true;\n return input.checklistDecomposePolicy === 'supplement_existing' && input.turnsUsed === 0;\n}\n\nasync function appendAssistantLine(apis: PersistentGoalApis, sessionKey: string, text: string): Promise<void> {\n await apis.appendAssistantReceipt(sessionKey, text);\n}\n\nexport async function handlePersistentGoalPostTurn(opts: {\n apis: PersistentGoalApis;\n sessionKey: string;\n assistantPlainText: string;\n aborted: boolean;\n streamError?: string;\n skipPersistentGoalPostTurn: boolean;\n config: Config | undefined;\n /** Active session model (overrides, per-agent defaults) when goals/global defaults are unset. */\n runtimeSessionModelRef?: string;\n signal?: AbortSignal;\n /** Hermes-style: verdict line also sent as a normal outbound message (non-webchat). */\n publishVerdictToChannel?: (text: string) => Promise<void>;\n onGoalStatusUpdated?: (payload: {\n goalId: string;\n sessionKey: string;\n previousStatus: string;\n status: string;\n goal: import('../../goals/types.js').GoalWithDetails;\n }) => void;\n}): Promise<void> {\n const {\n apis,\n sessionKey,\n assistantPlainText,\n aborted,\n streamError,\n skipPersistentGoalPostTurn,\n config,\n runtimeSessionModelRef,\n signal,\n publishVerdictToChannel,\n onGoalStatusUpdated,\n } = opts;\n\n if (skipPersistentGoalPostTurn) return;\n if (aborted || streamError) return;\n\n const meta = await apis.getSessionMetadata(sessionKey);\n if (!meta) return;\n\n const goal = goalService.getActiveForSession(sessionKey);\n if (!goal || goal.status !== 'active') return;\n\n const goalsCfg = config?.goals;\n const shouldDecomposeChecklist = shouldRunInitialChecklistDecomposition({\n checklistLength: goal.checklist.length,\n turnsUsed: goal.turnsUsed,\n checklistDecomposePolicy: goalsCfg?.checklistDecomposePolicy,\n });\n const state: PersistentGoalState = {\n goal: buildGoalContextText(goal),\n status: 'active',\n turnsUsed: goal.turnsUsed,\n maxTurns: goal.maxTurns,\n createdAt: goal.createdAt,\n lastTurnAt: goal.updatedAt,\n lastReason: goal.blockedReason,\n judgeModelRef: goal.judgeModelRef,\n decomposed: shouldDecomposeChecklist ? undefined : true,\n uiLocale: goal.uiLocale,\n checklist: goal.checklist.map((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n completedAt: it.completedAt,\n evidence: it.evidenceSummary,\n })),\n };\n\n const judgeRef = resolveJudgeModelRef(config, sessionKey, state.judgeModelRef, runtimeSessionModelRef);\n if (!judgeRef) {\n log.warn({ sessionKey }, 'Persistent goal: no judge model ref; skipping post-turn');\n return;\n }\n\n const historyCap = goalsCfg?.checklistHistoryChars ?? 24_000;\n let historyExcerpt = '';\n try {\n const msgs = await apis.loadMessages(sessionKey);\n historyExcerpt = buildHistoryExcerpt(msgs, historyCap);\n } catch (err) {\n log.debug(\n { err, sessionKey },\n `Persistent goal: could not load messages for judge context: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n let decision = await evaluateAfterTurnHermesLike(state, assistantPlainText, judgeRef, signal, {\n goalsSlice: goalsCfg,\n historyExcerpt,\n goalContextExcerpt: buildGoalContextText(goal),\n uiLocale: resolveGoalUiLocale(state),\n });\n\n const completionReadiness = goalService.getCompletionReadiness(goal.id);\n if (decision.verdict === 'done' && completionReadiness && !completionReadiness.ready && decision.newState) {\n const reason = `Completion evidence still needed: ${completionReadiness.missingEvidence.join('; ')}`;\n decision = {\n ...decision,\n newState: {\n ...decision.newState,\n status: 'active',\n lastVerdict: 'continue',\n lastReason: reason,\n },\n shouldContinue: true,\n continuationPrompt: `Before declaring the goal complete, collect this evidence:\\n${completionReadiness.missingEvidence.map((item) => `- ${item}`).join('\\n')}`,\n verdict: 'continue',\n reason,\n message: reason,\n missingEvidence: completionReadiness.missingEvidence,\n };\n }\n\n if (decision.newState) {\n const ns = decision.newState;\n const completedChecklistItemIds = decision.completedChecklistItemIndexes\n ?.map((index) => goal.checklist[index]?.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0);\n try {\n const updatedGoal = goalService.syncPostTurnState({\n goalId: goal.id,\n sessionKey,\n source: 'chat',\n status: ns.status === 'done'\n ? 'done'\n : decision.verdict === 'blocked'\n ? 'blocked'\n : decision.verdict === 'needs_input'\n ? 'needs_input'\n : ns.status === 'paused'\n ? 'paused'\n : 'active',\n turnsUsed: ns.turnsUsed,\n maxTurns: ns.maxTurns,\n reason: ns.pausedReason ?? decision.reason,\n nextAction: decision.continuationPrompt ?? undefined,\n assistantPreview: assistantPlainText,\n verdict: decision.verdict === 'done'\n ? 'done'\n : decision.verdict === 'decompose'\n ? 'decompose'\n : decision.verdict === 'blocked'\n ? 'blocked'\n : decision.verdict === 'needs_input'\n ? 'needs_input'\n : 'continue',\n confidence: decision.confidence,\n missingEvidence: decision.missingEvidence,\n userQuestion: decision.userQuestion,\n completedChecklistItemIds,\n checklist: ns.checklist?.map((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n completedAt: it.completedAt,\n evidenceSummary: it.evidence,\n })),\n });\n if (updatedGoal && updatedGoal.status !== goal.status) {\n onGoalStatusUpdated?.({\n goalId: goal.id,\n sessionKey,\n previousStatus: goal.status,\n status: updatedGoal.status,\n goal: updatedGoal,\n });\n }\n } catch (err) {\n log.warn(\n { err, sessionKey, goalId: goal.id },\n `Persistent goal: SQLite goal update failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n if (decision.message) {\n if (publishVerdictToChannel) {\n try {\n await publishVerdictToChannel(decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: channel verdict send failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n } else {\n try {\n await appendAssistantLine(apis, sessionKey, decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: failed to append status message: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n if (decision.shouldContinue && decision.continuationPrompt) {\n apis.scheduleContinuation(sessionKey, decision.continuationPrompt);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"post-turn.js","names":[],"sources":["../../../../src/agent/goals/post-turn.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config, GoalsConfig } from '../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport { GoalService } from '../../goals/index.js';\nimport { createLogger } from '../../utils/logger.js';\n\nimport { evaluateAfterTurnHermesLike } from './evaluate-turn.js';\nimport { resolveGoalUiLocale } from './goal-locale.js';\nimport type { PersistentGoalApis } from './persistent-goal-apis.js';\nimport type { PersistentGoalState } from './state.js';\n\nconst log = createLogger('PersistentGoal');\nconst goalService = new GoalService();\n\nfunction buildHistoryExcerpt(messages: AgentMessage[], maxChars: number): string {\n if (maxChars <= 0) return '';\n try {\n const raw = JSON.stringify(messages);\n if (raw.length <= maxChars) return raw;\n return raw.slice(-maxChars);\n } catch {\n return '';\n }\n}\n\nfunction buildGoalContextText(goal: NonNullable<ReturnType<GoalService['get']>>): string {\n const lines = [`Title: ${goal.contract?.objective || goal.title}`];\n if (goal.contract?.scopeBoundary) {\n lines.push(`Scope boundary:\\n${goal.contract.scopeBoundary}`);\n }\n if (goal.contract?.evidencePlan.length) {\n lines.push(`Expected completion evidence:\\n${goal.contract.evidencePlan.map((item) => `- ${item}`).join('\\n')}`);\n }\n if (goal.contextMessage?.text.trim()) {\n lines.push(`Context:\\n${goal.contextMessage.text.trim()}`);\n }\n if (goal.contextMessage?.attachments.length) {\n lines.push(\n [\n 'Attachments:',\n ...goal.contextMessage.attachments.map((attachment) =>\n `- ${attachment.name} (${attachment.mimeType}, ${attachment.size} bytes) ${attachment.uri}`,\n ),\n ].join('\\n'),\n );\n }\n return lines.join('\\n\\n');\n}\n\nfunction resolveJudgeModelRef(\n config: Config | undefined,\n sessionKey: string,\n storedJudge?: string,\n runtimeSessionModelRef?: string,\n): string | undefined {\n const fromCfg = config?.goals?.judgeModelRef?.trim();\n if (fromCfg) return fromCfg;\n if (storedJudge?.trim()) return storedJudge.trim();\n if (config) {\n const profile = resolveEffectiveAgentProfileForSession(config, sessionKey);\n if (profile.primaryModelRef?.trim()) return profile.primaryModelRef.trim();\n }\n if (runtimeSessionModelRef?.trim()) return runtimeSessionModelRef.trim();\n if (config) return getAgentDefaultModelRef(config);\n return undefined;\n}\n\nexport function shouldRunInitialChecklistDecomposition(input: {\n checklistLength: number;\n turnsUsed: number;\n checklistDecomposePolicy?: GoalsConfig['checklistDecomposePolicy'];\n}): boolean {\n if (input.checklistLength === 0) return true;\n return input.checklistDecomposePolicy === 'supplement_existing' && input.turnsUsed === 0;\n}\n\nasync function appendAssistantLine(apis: PersistentGoalApis, sessionKey: string, text: string): Promise<void> {\n await apis.appendAssistantReceipt(sessionKey, text);\n}\n\nexport async function handlePersistentGoalPostTurn(opts: {\n apis: PersistentGoalApis;\n sessionKey: string;\n assistantPlainText: string;\n aborted: boolean;\n streamError?: string;\n skipPersistentGoalPostTurn: boolean;\n config: Config | undefined;\n /** Active session model (overrides, per-agent defaults) when goals/global defaults are unset. */\n runtimeSessionModelRef?: string;\n signal?: AbortSignal;\n /** Hermes-style: verdict line also sent as a normal outbound message (non-webchat). */\n publishVerdictToChannel?: (text: string) => Promise<void>;\n onGoalStatusUpdated?: (payload: {\n goalId: string;\n sessionKey: string;\n previousStatus: string;\n status: string;\n goal: import('../../goals/types.js').GoalWithDetails;\n }) => void;\n}): Promise<void> {\n const {\n apis,\n sessionKey,\n assistantPlainText,\n aborted,\n streamError,\n skipPersistentGoalPostTurn,\n config,\n runtimeSessionModelRef,\n signal,\n publishVerdictToChannel,\n onGoalStatusUpdated,\n } = opts;\n\n if (skipPersistentGoalPostTurn) return;\n if (aborted || streamError) return;\n\n const meta = await apis.getSessionMetadata(sessionKey);\n if (!meta) return;\n\n const goal = goalService.getActiveForSession(sessionKey);\n if (!goal || goal.status !== 'active') return;\n\n const goalsCfg = config?.goals;\n const shouldDecomposeChecklist = shouldRunInitialChecklistDecomposition({\n checklistLength: goal.checklist.length,\n turnsUsed: goal.turnsUsed,\n checklistDecomposePolicy: goalsCfg?.checklistDecomposePolicy,\n });\n const state: PersistentGoalState = {\n goal: buildGoalContextText(goal),\n status: 'active',\n turnsUsed: goal.turnsUsed,\n maxTurns: goal.maxTurns,\n createdAt: goal.createdAt,\n lastTurnAt: goal.updatedAt,\n lastReason: goal.blockedReason,\n judgeModelRef: goal.judgeModelRef,\n decomposed: shouldDecomposeChecklist ? undefined : true,\n uiLocale: goal.uiLocale,\n checklist: goal.checklist.map((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n completedAt: it.completedAt,\n evidence: it.evidenceSummary,\n })),\n };\n\n const judgeRef = resolveJudgeModelRef(config, sessionKey, state.judgeModelRef, runtimeSessionModelRef);\n if (!judgeRef) {\n log.warn({ sessionKey }, 'Persistent goal: no judge model ref; skipping post-turn');\n return;\n }\n\n const historyCap = goalsCfg?.checklistHistoryChars ?? 24_000;\n let historyExcerpt = '';\n try {\n const msgs = await apis.loadMessages(sessionKey);\n historyExcerpt = buildHistoryExcerpt(msgs, historyCap);\n } catch (err) {\n log.debug(\n { err, sessionKey },\n `Persistent goal: could not load messages for judge context: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n let decision = await evaluateAfterTurnHermesLike(state, assistantPlainText, judgeRef, signal, {\n goalsSlice: goalsCfg,\n historyExcerpt,\n goalContextExcerpt: buildGoalContextText(goal),\n uiLocale: resolveGoalUiLocale(state),\n });\n\n const completionReadiness = goalService.getCompletionReadiness(goal.id);\n const executionGaps = completionReadiness\n ? [...completionReadiness.missingEvidence, ...completionReadiness.pendingOutcome]\n : [];\n if (decision.verdict === 'done' && executionGaps.length > 0 && decision.newState) {\n const reason = `Completion evidence or outcome still needed: ${executionGaps.join('; ')}`;\n decision = {\n ...decision,\n newState: {\n ...decision.newState,\n status: 'active',\n lastVerdict: 'continue',\n lastReason: reason,\n },\n shouldContinue: true,\n continuationPrompt: `Before declaring the goal complete, address these gaps:\\n${executionGaps.map((item) => `- ${item}`).join('\\n')}`,\n verdict: 'continue',\n reason,\n message: reason,\n missingEvidence: executionGaps,\n };\n }\n\n if (decision.newState) {\n const ns = decision.newState;\n const completedChecklistItemIds = decision.completedChecklistItemIndexes\n ?.map((index) => goal.checklist[index]?.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0);\n try {\n const updatedGoal = goalService.syncPostTurnState({\n goalId: goal.id,\n sessionKey,\n source: 'chat',\n status: ns.status === 'done'\n ? 'done'\n : decision.verdict === 'blocked'\n ? 'blocked'\n : decision.verdict === 'needs_input'\n ? 'needs_input'\n : ns.status === 'paused'\n ? 'paused'\n : 'active',\n turnsUsed: ns.turnsUsed,\n maxTurns: ns.maxTurns,\n reason: ns.pausedReason ?? decision.reason,\n nextAction: decision.continuationPrompt ?? undefined,\n assistantPreview: assistantPlainText,\n verdict: decision.verdict === 'done'\n ? 'done'\n : decision.verdict === 'decompose'\n ? 'decompose'\n : decision.verdict === 'blocked'\n ? 'blocked'\n : decision.verdict === 'needs_input'\n ? 'needs_input'\n : 'continue',\n confidence: decision.confidence,\n missingEvidence: decision.missingEvidence,\n userQuestion: decision.userQuestion,\n completedChecklistItemIds,\n checklist: ns.checklist?.map((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n completedAt: it.completedAt,\n evidenceSummary: it.evidence,\n })),\n });\n if (updatedGoal && updatedGoal.status !== goal.status) {\n onGoalStatusUpdated?.({\n goalId: goal.id,\n sessionKey,\n previousStatus: goal.status,\n status: updatedGoal.status,\n goal: updatedGoal,\n });\n }\n } catch (err) {\n log.warn(\n { err, sessionKey, goalId: goal.id },\n `Persistent goal: SQLite goal update failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n if (decision.message) {\n if (publishVerdictToChannel) {\n try {\n await publishVerdictToChannel(decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: channel verdict send failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n } else {\n try {\n await appendAssistantLine(apis, sessionKey, decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: failed to append status message: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n if (decision.shouldContinue && decision.continuationPrompt) {\n apis.scheduleContinuation(sessionKey, decision.continuationPrompt);\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
4
4
  import { createResponseMessage, createSignalMessage, createTaskMessage } from "./types.js";
5
5
  import { AgentInbox } from "./inbox.js";
6
6
  //#region src/agent/ipc/bus.ts
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { buildSafeToolName, normalizeReservedToolNames } from "./bundle-mcp-names.js";
5
5
  import { setPluginToolMeta } from "./mcp-tool-meta.js";
6
6
  import crypto from "node:crypto";
@@ -1,7 +1,7 @@
1
+ import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
4
  import { resolveGlobalSingleton } from "../../utils/global-singleton.js";
4
- import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
5
5
  import { sanitizeServerName } from "./bundle-mcp-names.js";
6
6
  import { redactSensitiveUrlLikeString } from "../../utils/redact-sensitive-url.js";
7
7
  import { loadEmbeddedMcpConfig } from "./embedded-mcp.js";
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeLowercaseStringOrEmpty } from "../../utils/string-coerce.js";
4
4
  import { resolveXopcMcpTransportAlias } from "../../config/mcp-config-normalize.js";
5
5
  import { sanitizeForLog } from "../../utils/sanitize-log.js";
6
6
  import { describeHttpMcpServerLaunchConfig, resolveHttpMcpServerLaunchConfig } from "./mcp-http.js";
@@ -1,6 +1,6 @@
1
+ import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
1
2
  import { createLogger } from "../../utils/logger/index.js";
2
3
  import { init_logger } from "../../utils/logger.js";
3
- import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
4
4
  import { XopcStdioClientTransport } from "./mcp-stdio-transport.js";
5
5
  import { resolveMcpTransportConfig } from "./mcp-transport-config.js";
6
6
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
@@ -64,7 +64,10 @@ function resolveMcpTransport(serverName, rawServer) {
64
64
  };
65
65
  }
66
66
  if (resolved.transportType === "streamable-http") return {
67
- transport: new StreamableHTTPClientTransport(new URL(resolved.url), { requestInit: resolved.headers ? { headers: resolved.headers } : void 0 }),
67
+ transport: new StreamableHTTPClientTransport(new URL(resolved.url), {
68
+ requestInit: resolved.headers ? { headers: resolved.headers } : void 0,
69
+ fetch: fetchWithUndici
70
+ }),
68
71
  description: resolved.description,
69
72
  transportType: "streamable-http",
70
73
  connectionTimeoutMs: resolved.connectionTimeoutMs
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-transport.js","names":["undiciFetch"],"sources":["../../../../src/agent/mcp/mcp-transport.ts"],"sourcesContent":["import {\n SSEClientTransport,\n type SSEClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { FetchLike, Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { fetch as undiciFetch } from \"undici\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Transport\");\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { XopcStdioClientTransport } from \"./mcp-stdio-transport.js\";\nimport { resolveMcpTransportConfig } from \"./mcp-transport-config.js\";\n\nexport type ResolvedMcpTransport = {\n transport: Transport;\n description: string;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n connectionTimeoutMs: number;\n detachStderr?: () => void;\n};\n\nfunction attachStderrLogging(serverName: string, transport: XopcStdioClientTransport) {\n const stderr = transport.stderr;\n if (!stderr || typeof stderr.on !== \"function\") {\n return undefined;\n }\n const onData = (chunk: Buffer | string) => {\n const message =\n normalizeOptionalString(typeof chunk === \"string\" ? chunk : String(chunk)) ?? \"\";\n if (!message) {\n return;\n }\n for (const line of message.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed) {\n log.debug(`bundle-mcp:${serverName}: ${trimmed}`);\n }\n }\n };\n stderr.on(\"data\", onData);\n return () => {\n if (typeof stderr.off === \"function\") {\n stderr.off(\"data\", onData);\n } else if (typeof stderr.removeListener === \"function\") {\n stderr.removeListener(\"data\", onData);\n }\n };\n}\n\ntype SseEventSourceFetch = NonNullable<\n NonNullable<SSEClientTransportOptions[\"eventSourceInit\"]>[\"fetch\"]\n>;\n\nconst fetchWithUndici: FetchLike = async (url, init) =>\n (await undiciFetch(url, init as unknown as Parameters<typeof undiciFetch>[1])) as unknown as Response;\n\nfunction buildSseEventSourceFetch(headers: Record<string, string>): SseEventSourceFetch {\n return (url: string | URL, init?: RequestInit) => {\n const sdkHeaders: Record<string, string> = {};\n if (init?.headers) {\n if (init.headers instanceof Headers) {\n init.headers.forEach((value, key) => {\n sdkHeaders[key] = value;\n });\n } else {\n Object.assign(sdkHeaders, init.headers);\n }\n }\n return fetchWithUndici(url, {\n ...(init as RequestInit),\n headers: { ...sdkHeaders, ...headers },\n }) as ReturnType<SseEventSourceFetch>;\n };\n}\n\nexport function resolveMcpTransport(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransport | null {\n const resolved = resolveMcpTransportConfig(serverName, rawServer);\n if (!resolved) {\n return null;\n }\n if (resolved.kind === \"stdio\") {\n const transport = new XopcStdioClientTransport({\n command: resolved.command,\n args: resolved.args,\n env: resolved.env,\n cwd: resolved.cwd,\n stderr: \"pipe\",\n });\n return {\n transport,\n description: resolved.description,\n transportType: \"stdio\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n detachStderr: attachStderrLogging(serverName, transport),\n };\n }\n if (resolved.transportType === \"streamable-http\") {\n return {\n transport: new StreamableHTTPClientTransport(new URL(resolved.url), {\n requestInit: resolved.headers ? { headers: resolved.headers } : undefined,\n }),\n description: resolved.description,\n transportType: \"streamable-http\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n }\n const headers: Record<string, string> = {\n ...resolved.headers,\n };\n const hasHeaders = Object.keys(headers).length > 0;\n return {\n transport: new SSEClientTransport(new URL(resolved.url), {\n requestInit: hasHeaders ? { headers } : undefined,\n fetch: fetchWithUndici,\n eventSourceInit: { fetch: buildSseEventSourceFetch(headers) },\n }),\n description: resolved.description,\n transportType: \"sse\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n}\n"],"mappings":";;;;;;;;;aAOqD;oBAEkB;AADvE,MAAM,MAAM,aAAa,gBAAgB;AAazC,SAAS,oBAAoB,YAAoB,WAAqC;CACpF,MAAM,SAAS,UAAU;AACzB,KAAI,CAAC,UAAU,OAAO,OAAO,OAAO,WAClC;CAEF,MAAM,UAAU,UAA2B;EACzC,MAAM,UACJ,wBAAwB,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM,CAAC,IAAI;AAChF,MAAI,CAAC,QACH;AAEF,OAAK,MAAM,QAAQ,QAAQ,MAAM,QAAQ,EAAE;GACzC,MAAM,UAAU,KAAK,MAAM;AAC3B,OAAI,QACF,KAAI,MAAM,cAAc,WAAW,IAAI,UAAU;;;AAIvD,QAAO,GAAG,QAAQ,OAAO;AACzB,cAAa;AACX,MAAI,OAAO,OAAO,QAAQ,WACxB,QAAO,IAAI,QAAQ,OAAO;WACjB,OAAO,OAAO,mBAAmB,WAC1C,QAAO,eAAe,QAAQ,OAAO;;;AAS3C,MAAM,kBAA6B,OAAO,KAAK,SAC5C,MAAMA,MAAY,KAAK,KAAqD;AAE/E,SAAS,yBAAyB,SAAsD;AACtF,SAAQ,KAAmB,SAAuB;EAChD,MAAM,aAAqC,EAAE;AAC7C,MAAI,MAAM,QACR,KAAI,KAAK,mBAAmB,QAC1B,MAAK,QAAQ,SAAS,OAAO,QAAQ;AACnC,cAAW,OAAO;IAClB;MAEF,QAAO,OAAO,YAAY,KAAK,QAAQ;AAG3C,SAAO,gBAAgB,KAAK;GAC1B,GAAI;GACJ,SAAS;IAAE,GAAG;IAAY,GAAG;IAAS;GACvC,CAAC;;;AAIN,SAAgB,oBACd,YACA,WAC6B;CAC7B,MAAM,WAAW,0BAA0B,YAAY,UAAU;AACjE,KAAI,CAAC,SACH,QAAO;AAET,KAAI,SAAS,SAAS,SAAS;EAC7B,MAAM,YAAY,IAAI,yBAAyB;GAC7C,SAAS,SAAS;GAClB,MAAM,SAAS;GACf,KAAK,SAAS;GACd,KAAK,SAAS;GACd,QAAQ;GACT,CAAC;AACF,SAAO;GACL;GACA,aAAa,SAAS;GACtB,eAAe;GACf,qBAAqB,SAAS;GAC9B,cAAc,oBAAoB,YAAY,UAAU;GACzD;;AAEH,KAAI,SAAS,kBAAkB,kBAC7B,QAAO;EACL,WAAW,IAAI,8BAA8B,IAAI,IAAI,SAAS,IAAI,EAAE,EAClE,aAAa,SAAS,UAAU,EAAE,SAAS,SAAS,SAAS,GAAG,KAAA,GACjE,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B;CAEH,MAAM,UAAkC,EACtC,GAAG,SAAS,SACb;CACD,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,SAAS;AACjD,QAAO;EACL,WAAW,IAAI,mBAAmB,IAAI,IAAI,SAAS,IAAI,EAAE;GACvD,aAAa,aAAa,EAAE,SAAS,GAAG,KAAA;GACxC,OAAO;GACP,iBAAiB,EAAE,OAAO,yBAAyB,QAAQ,EAAE;GAC9D,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B"}
1
+ {"version":3,"file":"mcp-transport.js","names":["undiciFetch"],"sources":["../../../../src/agent/mcp/mcp-transport.ts"],"sourcesContent":["import {\n SSEClientTransport,\n type SSEClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { FetchLike, Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { fetch as undiciFetch } from \"undici\";\nimport { createLogger } from \"../../utils/logger.js\";\nconst log = createLogger(\"Mcp:Transport\");\nimport { normalizeOptionalString } from \"../../utils/string-coerce.js\";\nimport { XopcStdioClientTransport } from \"./mcp-stdio-transport.js\";\nimport { resolveMcpTransportConfig } from \"./mcp-transport-config.js\";\n\nexport type ResolvedMcpTransport = {\n transport: Transport;\n description: string;\n transportType: \"stdio\" | \"sse\" | \"streamable-http\";\n connectionTimeoutMs: number;\n detachStderr?: () => void;\n};\n\nfunction attachStderrLogging(serverName: string, transport: XopcStdioClientTransport) {\n const stderr = transport.stderr;\n if (!stderr || typeof stderr.on !== \"function\") {\n return undefined;\n }\n const onData = (chunk: Buffer | string) => {\n const message =\n normalizeOptionalString(typeof chunk === \"string\" ? chunk : String(chunk)) ?? \"\";\n if (!message) {\n return;\n }\n for (const line of message.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed) {\n log.debug(`bundle-mcp:${serverName}: ${trimmed}`);\n }\n }\n };\n stderr.on(\"data\", onData);\n return () => {\n if (typeof stderr.off === \"function\") {\n stderr.off(\"data\", onData);\n } else if (typeof stderr.removeListener === \"function\") {\n stderr.removeListener(\"data\", onData);\n }\n };\n}\n\ntype SseEventSourceFetch = NonNullable<\n NonNullable<SSEClientTransportOptions[\"eventSourceInit\"]>[\"fetch\"]\n>;\n\nconst fetchWithUndici: FetchLike = async (url, init) =>\n (await undiciFetch(url, init as unknown as Parameters<typeof undiciFetch>[1])) as unknown as Response;\n\nfunction buildSseEventSourceFetch(headers: Record<string, string>): SseEventSourceFetch {\n return (url: string | URL, init?: RequestInit) => {\n const sdkHeaders: Record<string, string> = {};\n if (init?.headers) {\n if (init.headers instanceof Headers) {\n init.headers.forEach((value, key) => {\n sdkHeaders[key] = value;\n });\n } else {\n Object.assign(sdkHeaders, init.headers);\n }\n }\n return fetchWithUndici(url, {\n ...(init as RequestInit),\n headers: { ...sdkHeaders, ...headers },\n }) as ReturnType<SseEventSourceFetch>;\n };\n}\n\nexport function resolveMcpTransport(\n serverName: string,\n rawServer: unknown,\n): ResolvedMcpTransport | null {\n const resolved = resolveMcpTransportConfig(serverName, rawServer);\n if (!resolved) {\n return null;\n }\n if (resolved.kind === \"stdio\") {\n const transport = new XopcStdioClientTransport({\n command: resolved.command,\n args: resolved.args,\n env: resolved.env,\n cwd: resolved.cwd,\n stderr: \"pipe\",\n });\n return {\n transport,\n description: resolved.description,\n transportType: \"stdio\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n detachStderr: attachStderrLogging(serverName, transport),\n };\n }\n if (resolved.transportType === \"streamable-http\") {\n return {\n transport: new StreamableHTTPClientTransport(new URL(resolved.url), {\n requestInit: resolved.headers ? { headers: resolved.headers } : undefined,\n fetch: fetchWithUndici,\n }),\n description: resolved.description,\n transportType: \"streamable-http\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n }\n const headers: Record<string, string> = {\n ...resolved.headers,\n };\n const hasHeaders = Object.keys(headers).length > 0;\n return {\n transport: new SSEClientTransport(new URL(resolved.url), {\n requestInit: hasHeaders ? { headers } : undefined,\n fetch: fetchWithUndici,\n eventSourceInit: { fetch: buildSseEventSourceFetch(headers) },\n }),\n description: resolved.description,\n transportType: \"sse\",\n connectionTimeoutMs: resolved.connectionTimeoutMs,\n };\n}\n"],"mappings":";;;;;;;;;aAOqD;oBAEkB;AADvE,MAAM,MAAM,aAAa,gBAAgB;AAazC,SAAS,oBAAoB,YAAoB,WAAqC;CACpF,MAAM,SAAS,UAAU;AACzB,KAAI,CAAC,UAAU,OAAO,OAAO,OAAO,WAClC;CAEF,MAAM,UAAU,UAA2B;EACzC,MAAM,UACJ,wBAAwB,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM,CAAC,IAAI;AAChF,MAAI,CAAC,QACH;AAEF,OAAK,MAAM,QAAQ,QAAQ,MAAM,QAAQ,EAAE;GACzC,MAAM,UAAU,KAAK,MAAM;AAC3B,OAAI,QACF,KAAI,MAAM,cAAc,WAAW,IAAI,UAAU;;;AAIvD,QAAO,GAAG,QAAQ,OAAO;AACzB,cAAa;AACX,MAAI,OAAO,OAAO,QAAQ,WACxB,QAAO,IAAI,QAAQ,OAAO;WACjB,OAAO,OAAO,mBAAmB,WAC1C,QAAO,eAAe,QAAQ,OAAO;;;AAS3C,MAAM,kBAA6B,OAAO,KAAK,SAC5C,MAAMA,MAAY,KAAK,KAAqD;AAE/E,SAAS,yBAAyB,SAAsD;AACtF,SAAQ,KAAmB,SAAuB;EAChD,MAAM,aAAqC,EAAE;AAC7C,MAAI,MAAM,QACR,KAAI,KAAK,mBAAmB,QAC1B,MAAK,QAAQ,SAAS,OAAO,QAAQ;AACnC,cAAW,OAAO;IAClB;MAEF,QAAO,OAAO,YAAY,KAAK,QAAQ;AAG3C,SAAO,gBAAgB,KAAK;GAC1B,GAAI;GACJ,SAAS;IAAE,GAAG;IAAY,GAAG;IAAS;GACvC,CAAC;;;AAIN,SAAgB,oBACd,YACA,WAC6B;CAC7B,MAAM,WAAW,0BAA0B,YAAY,UAAU;AACjE,KAAI,CAAC,SACH,QAAO;AAET,KAAI,SAAS,SAAS,SAAS;EAC7B,MAAM,YAAY,IAAI,yBAAyB;GAC7C,SAAS,SAAS;GAClB,MAAM,SAAS;GACf,KAAK,SAAS;GACd,KAAK,SAAS;GACd,QAAQ;GACT,CAAC;AACF,SAAO;GACL;GACA,aAAa,SAAS;GACtB,eAAe;GACf,qBAAqB,SAAS;GAC9B,cAAc,oBAAoB,YAAY,UAAU;GACzD;;AAEH,KAAI,SAAS,kBAAkB,kBAC7B,QAAO;EACL,WAAW,IAAI,8BAA8B,IAAI,IAAI,SAAS,IAAI,EAAE;GAClE,aAAa,SAAS,UAAU,EAAE,SAAS,SAAS,SAAS,GAAG,KAAA;GAChE,OAAO;GACR,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B;CAEH,MAAM,UAAkC,EACtC,GAAG,SAAS,SACb;CACD,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,SAAS;AACjD,QAAO;EACL,WAAW,IAAI,mBAAmB,IAAI,IAAI,SAAS,IAAI,EAAE;GACvD,aAAa,aAAa,EAAE,SAAS,GAAG,KAAA;GACxC,OAAO;GACP,iBAAiB,EAAE,OAAO,yBAAyB,QAAQ,EAAE;GAC9D,CAAC;EACF,aAAa,SAAS;EACtB,eAAe;EACf,qBAAqB,SAAS;EAC/B"}
@@ -8,5 +8,6 @@ export declare class UserContextPlanner {
8
8
  sessionKey: string;
9
9
  query: string;
10
10
  userMessage: AgentMessage;
11
+ excludedRecordIds?: string[];
11
12
  }): Promise<UserContextPlan>;
12
13
  }
@@ -4,11 +4,21 @@ import { appendMemoryTraceEvent } from "../../../storage/sqlite/memory-records-r
4
4
  import "../../../storage/sqlite/index.js";
5
5
  import { readAgentMessageContent } from "../agent-message-access.js";
6
6
  import { buildUserContextBlock } from "../context-fence.js";
7
+ import { resolveMemoryStability } from "../lifecycle.js";
8
+ import { classifyMemoryContextOrigin } from "../source-origin.js";
7
9
  import { randomUUID } from "node:crypto";
8
10
  //#region src/agent/memory/context/planner.ts
9
11
  init_logger();
10
12
  const MAX_CONTEXT_CHARS = 6e3;
11
13
  const MAX_RESULTS = 8;
14
+ const BASELINE_KINDS = [
15
+ "boundary",
16
+ "preference",
17
+ "tool_preference",
18
+ "routine",
19
+ "user_profile",
20
+ "personal_logistics"
21
+ ];
12
22
  const log = createLogger("UserContextPlanner");
13
23
  function sectionFor(record) {
14
24
  if (record.kind === "boundary") return "safety";
@@ -20,13 +30,13 @@ function rejectReason(record, now) {
20
30
  if (record.validTo && Date.parse(record.validTo) < now || record.expiresAt && Date.parse(record.expiresAt) < now) return "expired";
21
31
  if (record.sensitivity === "secret" || record.sensitivity === "regulated") return "sensitive";
22
32
  if (record.disclosurePolicy === "ask_before_reference") return "requires_consent";
33
+ if (record.status === "needs_review" || record.status === "stale" || resolveMemoryStability(record, now).reviewDue) return "needs_review";
23
34
  }
24
35
  function scoreResult(result, now) {
25
36
  const confidence = result.record.confidence ?? .5;
26
37
  const explicitness = result.record.explicitness === "explicit" ? 1 : result.record.explicitness === "observed" ? .65 : .4;
27
- const ageDays = Math.max(0, (now - Date.parse(result.record.updatedAt)) / 864e5);
28
- const freshness = Math.exp(-ageDays / 180);
29
- return Math.max(0, Math.min(1, result.score * .5 + confidence * .15 + result.record.importance * .2 + explicitness * .1 + freshness * .05));
38
+ const stability = resolveMemoryStability(result.record, now).score;
39
+ return Math.max(0, Math.min(1, result.score * .45 + confidence * .1 + result.record.importance * .2 + explicitness * .1 + stability * .15));
30
40
  }
31
41
  function citationFor(result, requesterAgentId) {
32
42
  const base = result.citation.path ?? `${result.citation.providerId}:${result.citation.recordId}`;
@@ -35,6 +45,12 @@ function citationFor(result, requesterAgentId) {
35
45
  const end = result.citation.lineEnd && result.citation.lineEnd !== result.citation.lineStart ? `-L${result.citation.lineEnd}` : "";
36
46
  return `${ownerPrefix}${base}#L${result.citation.lineStart}${end}`;
37
47
  }
48
+ function evidenceLabel(item) {
49
+ if (item.origin === "told_by_user") return "The user explicitly shared this";
50
+ if (item.origin === "observed") return "Observed across prior work";
51
+ if (item.origin === "connected_source") return "A connected source provided this";
52
+ return "An inference that may be wrong";
53
+ }
38
54
  function prependContext(message, block) {
39
55
  if (!block) return message;
40
56
  const prefix = `${block}\n\n`;
@@ -78,21 +94,42 @@ var UserContextPlanner = class {
78
94
  estimatedTokens: 0
79
95
  };
80
96
  const started = Date.now();
81
- const results = await params.memoryManager.search({
97
+ const scope = {
98
+ agentId: params.agentId,
99
+ sessionKey: params.sessionKey
100
+ };
101
+ const [taskResults, baselineLists] = await Promise.all([params.memoryManager.search({
82
102
  query,
83
- scope: {
84
- agentId: params.agentId,
85
- sessionKey: params.sessionKey
86
- },
103
+ scope,
87
104
  maxResults: MAX_RESULTS,
88
105
  minScore: .15
89
- }).catch(() => []);
106
+ }).catch(() => []), Promise.all(BASELINE_KINDS.map((kind) => params.memoryManager.list({
107
+ kind,
108
+ status: "active",
109
+ scope
110
+ }).catch(() => [])))]);
111
+ const taskIds = new Set(taskResults.map((result) => result.record.id));
112
+ const baselineResults = baselineLists.flat().filter((record) => !taskIds.has(record.id)).filter((record) => record.kind === "boundary" || record.explicitness === "explicit" || record.importance >= .7).map((record) => ({
113
+ record,
114
+ score: record.kind === "boundary" ? .7 : .42,
115
+ snippet: record.content,
116
+ citation: {
117
+ providerId: record.source.provider ?? "local",
118
+ recordId: record.id,
119
+ path: record.source.path,
120
+ lineStart: record.source.lineStart,
121
+ lineEnd: record.source.lineEnd,
122
+ createdAt: record.createdAt
123
+ }
124
+ }));
125
+ const results = [...taskResults, ...baselineResults];
90
126
  const now = Date.now();
127
+ const excluded = new Set(params.excludedRecordIds ?? []);
91
128
  const rejected = [];
92
- const ranked = results.map((result) => ({
129
+ const ranked = results.filter((result) => !excluded.has(result.record.id)).map((result) => ({
93
130
  result,
94
131
  score: scoreResult(result, now)
95
- })).sort((a, b) => b.score - a.score);
132
+ })).sort((a, b) => b.score - a.score).filter((entry, index, all) => all.findIndex((candidate) => candidate.result.record.id === entry.result.record.id) === index).slice(0, MAX_RESULTS);
96
133
  const items = [];
97
134
  let usedChars = 0;
98
135
  for (const { result, score } of ranked) {
@@ -118,7 +155,9 @@ var UserContextPlanner = class {
118
155
  content,
119
156
  score,
120
157
  section: sectionFor(result.record),
121
- citation: citationFor(result, params.agentId)
158
+ citation: citationFor(result, params.agentId),
159
+ origin: classifyMemoryContextOrigin(result.record),
160
+ stability: resolveMemoryStability(result.record, now).score
122
161
  });
123
162
  }
124
163
  const sections = [];
@@ -128,7 +167,7 @@ var UserContextPlanner = class {
128
167
  ["interaction", "Interaction preferences"]
129
168
  ]) {
130
169
  const sectionItems = items.filter((item) => item.section === section);
131
- if (sectionItems.length > 0) sections.push(`${title}:\n${sectionItems.map((item) => `- ${item.content}\n Source: ${item.citation}`).join("\n")}`);
170
+ if (sectionItems.length > 0) sections.push(`${title}:\n${sectionItems.map((item) => `- ${item.content}\n Evidence: ${evidenceLabel(item)}`).join("\n")}`);
132
171
  }
133
172
  const block = buildUserContextBlock(sections.join("\n\n"));
134
173
  try {
@@ -139,7 +178,14 @@ var UserContextPlanner = class {
139
178
  sessionKey: params.sessionKey,
140
179
  request: {
141
180
  query,
142
- rejected
181
+ rejected,
182
+ contextItems: items.map((item) => ({
183
+ recordId: item.recordId,
184
+ section: item.section,
185
+ origin: item.origin,
186
+ stability: item.stability,
187
+ citation: item.citation
188
+ }))
143
189
  },
144
190
  resultCount: items.length,
145
191
  selectedRecordIds: items.map((item) => item.recordId),
@@ -1 +1 @@
1
- {"version":3,"file":"planner.js","names":[],"sources":["../../../../../src/agent/memory/context/planner.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport { appendMemoryTraceEvent } from '../../../storage/sqlite/index.js';\nimport { createLogger } from '../../../utils/logger.js';\nimport { readAgentMessageContent } from '../agent-message-access.js';\nimport { buildUserContextBlock } from '../context-fence.js';\nimport type { MemoryManager } from '../manager.js';\nimport type { MemoryRecord, MemorySearchResult } from '../types.js';\nimport type {\n PlannedUserContextItem,\n UserContextPlan,\n UserContextRejectionReason,\n} from './types.js';\n\nconst MAX_CONTEXT_CHARS = 6_000;\nconst MAX_RESULTS = 8;\nconst log = createLogger('UserContextPlanner');\n\nfunction sectionFor(record: MemoryRecord): PlannedUserContextItem['section'] {\n if (record.kind === 'boundary') return 'safety';\n if (\n record.kind === 'preference' ||\n record.kind === 'user_profile' ||\n record.kind === 'relationship' ||\n record.kind === 'routine' ||\n record.kind === 'personal_logistics' ||\n record.kind === 'tool_preference'\n ) return 'interaction';\n return 'task';\n}\n\nfunction rejectReason(record: MemoryRecord, now: number): UserContextRejectionReason | undefined {\n if (record.validFrom && Date.parse(record.validFrom) > now) return 'not_yet_valid';\n if (\n (record.validTo && Date.parse(record.validTo) < now) ||\n (record.expiresAt && Date.parse(record.expiresAt) < now)\n ) return 'expired';\n if (record.sensitivity === 'secret' || record.sensitivity === 'regulated') return 'sensitive';\n if (record.disclosurePolicy === 'ask_before_reference') return 'requires_consent';\n return undefined;\n}\n\nfunction scoreResult(result: MemorySearchResult, now: number): number {\n const confidence = result.record.confidence ?? 0.5;\n const explicitness = result.record.explicitness === 'explicit'\n ? 1\n : result.record.explicitness === 'observed' ? 0.65 : 0.4;\n const ageDays = Math.max(0, (now - Date.parse(result.record.updatedAt)) / 86_400_000);\n const freshness = Math.exp(-ageDays / 180);\n return Math.max(0, Math.min(1,\n result.score * 0.5 + confidence * 0.15 + result.record.importance * 0.2 + explicitness * 0.1 + freshness * 0.05,\n ));\n}\n\nfunction citationFor(result: MemorySearchResult, requesterAgentId: string): string {\n const base = result.citation.path ?? `${result.citation.providerId}:${result.citation.recordId}`;\n const ownerPrefix = result.record.scope.agentId !== requesterAgentId\n ? `shared-from-agent:${result.record.scope.agentId} `\n : '';\n if (result.citation.lineStart == null) return `${ownerPrefix}${base}`;\n const end = result.citation.lineEnd && result.citation.lineEnd !== result.citation.lineStart\n ? `-L${result.citation.lineEnd}`\n : '';\n return `${ownerPrefix}${base}#L${result.citation.lineStart}${end}`;\n}\n\nfunction prependContext(message: AgentMessage, block: string): AgentMessage {\n if (!block) return message;\n const prefix = `${block}\\n\\n`;\n const content = readAgentMessageContent(message);\n if (typeof content === 'string') return { ...message, content: prefix + content } as AgentMessage;\n if (Array.isArray(content) && content.length > 0) {\n const first = content[0] as { type?: string; text?: string };\n if (first.type === 'text' && typeof first.text === 'string') {\n const copy = [...content];\n copy[0] = { type: 'text', text: prefix + first.text };\n return { ...message, content: copy } as AgentMessage;\n }\n return { ...message, content: [{ type: 'text' as const, text: prefix }, ...content] } as AgentMessage;\n }\n return message;\n}\n\nexport class UserContextPlanner {\n async plan(params: {\n memoryManager: MemoryManager;\n agentId: string;\n sessionKey: string;\n query: string;\n userMessage: AgentMessage;\n }): Promise<UserContextPlan> {\n const traceId = randomUUID();\n const query = params.query.trim();\n if (!query) {\n return { traceId, modelMessage: params.userMessage, items: [], rejected: [], estimatedTokens: 0 };\n }\n const started = Date.now();\n const results = await params.memoryManager.search({\n query,\n scope: { agentId: params.agentId, sessionKey: params.sessionKey },\n maxResults: MAX_RESULTS,\n minScore: 0.15,\n }).catch(() => []);\n const now = Date.now();\n const rejected: UserContextPlan['rejected'] = [];\n const ranked = results\n .map((result) => ({ result, score: scoreResult(result, now) }))\n .sort((a, b) => b.score - a.score);\n const items: PlannedUserContextItem[] = [];\n let usedChars = 0;\n for (const { result, score } of ranked) {\n const reason = rejectReason(result.record, now) ?? (score < 0.25 ? 'low_score' : undefined);\n if (reason) {\n rejected.push({ recordId: result.record.id, reason });\n continue;\n }\n const content = result.snippet.trim();\n if (usedChars + content.length > MAX_CONTEXT_CHARS) {\n rejected.push({ recordId: result.record.id, reason: 'budget' });\n continue;\n }\n usedChars += content.length;\n items.push({\n recordId: result.record.id,\n content,\n score,\n section: sectionFor(result.record),\n citation: citationFor(result, params.agentId),\n });\n }\n const sections: string[] = [];\n for (const [section, title] of [['safety', 'Boundaries'], ['task', 'Relevant facts'], ['interaction', 'Interaction preferences']] as const) {\n const sectionItems = items.filter((item) => item.section === section);\n if (sectionItems.length > 0) {\n sections.push(`${title}:\\n${sectionItems.map((item) => `- ${item.content}\\n Source: ${item.citation}`).join('\\n')}`);\n }\n }\n const block = buildUserContextBlock(sections.join('\\n\\n'));\n try {\n appendMemoryTraceEvent({\n traceId,\n phase: 'inject',\n providerId: 'user-understanding',\n sessionKey: params.sessionKey,\n request: { query, rejected },\n resultCount: items.length,\n selectedRecordIds: items.map((item) => item.recordId),\n durationMs: Date.now() - started,\n });\n } catch (err) {\n log.debug({ err, traceId, sessionKey: params.sessionKey }, 'Context plan trace was not persisted');\n }\n return {\n traceId,\n modelMessage: prependContext(params.userMessage, block),\n items,\n rejected,\n estimatedTokens: Math.ceil(block.length / 4),\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"planner.js","names":[],"sources":["../../../../../src/agent/memory/context/planner.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport { appendMemoryTraceEvent } from '../../../storage/sqlite/index.js';\nimport { createLogger } from '../../../utils/logger.js';\nimport { readAgentMessageContent } from '../agent-message-access.js';\nimport { buildUserContextBlock } from '../context-fence.js';\nimport type { MemoryManager } from '../manager.js';\nimport { resolveMemoryStability } from '../lifecycle.js';\nimport { classifyMemoryContextOrigin } from '../source-origin.js';\nimport type { MemoryRecord, MemorySearchResult } from '../types.js';\nimport type {\n PlannedUserContextItem,\n UserContextPlan,\n UserContextRejectionReason,\n} from './types.js';\n\nconst MAX_CONTEXT_CHARS = 6_000;\nconst MAX_RESULTS = 8;\nconst BASELINE_KINDS = [\n 'boundary',\n 'preference',\n 'tool_preference',\n 'routine',\n 'user_profile',\n 'personal_logistics',\n] as const;\nconst log = createLogger('UserContextPlanner');\n\nfunction sectionFor(record: MemoryRecord): PlannedUserContextItem['section'] {\n if (record.kind === 'boundary') return 'safety';\n if (\n record.kind === 'preference' ||\n record.kind === 'user_profile' ||\n record.kind === 'relationship' ||\n record.kind === 'routine' ||\n record.kind === 'personal_logistics' ||\n record.kind === 'tool_preference'\n ) return 'interaction';\n return 'task';\n}\n\nfunction rejectReason(record: MemoryRecord, now: number): UserContextRejectionReason | undefined {\n if (record.validFrom && Date.parse(record.validFrom) > now) return 'not_yet_valid';\n if (\n (record.validTo && Date.parse(record.validTo) < now) ||\n (record.expiresAt && Date.parse(record.expiresAt) < now)\n ) return 'expired';\n if (record.sensitivity === 'secret' || record.sensitivity === 'regulated') return 'sensitive';\n if (record.disclosurePolicy === 'ask_before_reference') return 'requires_consent';\n if (record.status === 'needs_review' || record.status === 'stale' || resolveMemoryStability(record, now).reviewDue) return 'needs_review';\n return undefined;\n}\n\nfunction scoreResult(result: MemorySearchResult, now: number): number {\n const confidence = result.record.confidence ?? 0.5;\n const explicitness = result.record.explicitness === 'explicit'\n ? 1\n : result.record.explicitness === 'observed' ? 0.65 : 0.4;\n const stability = resolveMemoryStability(result.record, now).score;\n return Math.max(0, Math.min(1,\n result.score * 0.45 + confidence * 0.1 + result.record.importance * 0.2 + explicitness * 0.1 + stability * 0.15,\n ));\n}\n\nfunction citationFor(result: MemorySearchResult, requesterAgentId: string): string {\n const base = result.citation.path ?? `${result.citation.providerId}:${result.citation.recordId}`;\n const ownerPrefix = result.record.scope.agentId !== requesterAgentId\n ? `shared-from-agent:${result.record.scope.agentId} `\n : '';\n if (result.citation.lineStart == null) return `${ownerPrefix}${base}`;\n const end = result.citation.lineEnd && result.citation.lineEnd !== result.citation.lineStart\n ? `-L${result.citation.lineEnd}`\n : '';\n return `${ownerPrefix}${base}#L${result.citation.lineStart}${end}`;\n}\n\nfunction evidenceLabel(item: PlannedUserContextItem): string {\n if (item.origin === 'told_by_user') return 'The user explicitly shared this';\n if (item.origin === 'observed') return 'Observed across prior work';\n if (item.origin === 'connected_source') return 'A connected source provided this';\n return 'An inference that may be wrong';\n}\n\nfunction prependContext(message: AgentMessage, block: string): AgentMessage {\n if (!block) return message;\n const prefix = `${block}\\n\\n`;\n const content = readAgentMessageContent(message);\n if (typeof content === 'string') return { ...message, content: prefix + content } as AgentMessage;\n if (Array.isArray(content) && content.length > 0) {\n const first = content[0] as { type?: string; text?: string };\n if (first.type === 'text' && typeof first.text === 'string') {\n const copy = [...content];\n copy[0] = { type: 'text', text: prefix + first.text };\n return { ...message, content: copy } as AgentMessage;\n }\n return { ...message, content: [{ type: 'text' as const, text: prefix }, ...content] } as AgentMessage;\n }\n return message;\n}\n\nexport class UserContextPlanner {\n async plan(params: {\n memoryManager: MemoryManager;\n agentId: string;\n sessionKey: string;\n query: string;\n userMessage: AgentMessage;\n excludedRecordIds?: string[];\n }): Promise<UserContextPlan> {\n const traceId = randomUUID();\n const query = params.query.trim();\n if (!query) {\n return { traceId, modelMessage: params.userMessage, items: [], rejected: [], estimatedTokens: 0 };\n }\n const started = Date.now();\n const scope = { agentId: params.agentId, sessionKey: params.sessionKey };\n const [taskResults, baselineLists] = await Promise.all([\n params.memoryManager.search({\n query,\n scope,\n maxResults: MAX_RESULTS,\n minScore: 0.15,\n }).catch(() => []),\n Promise.all(BASELINE_KINDS.map((kind) => (\n params.memoryManager.list({ kind, status: 'active', scope }).catch(() => [])\n ))),\n ]);\n const taskIds = new Set(taskResults.map((result) => result.record.id));\n const baselineResults: MemorySearchResult[] = baselineLists\n .flat()\n .filter((record) => !taskIds.has(record.id))\n .filter((record) => record.kind === 'boundary' || record.explicitness === 'explicit' || record.importance >= 0.7)\n .map((record) => ({\n record,\n score: record.kind === 'boundary' ? 0.7 : 0.42,\n snippet: record.content,\n citation: {\n providerId: record.source.provider ?? 'local',\n recordId: record.id,\n path: record.source.path,\n lineStart: record.source.lineStart,\n lineEnd: record.source.lineEnd,\n createdAt: record.createdAt,\n },\n }));\n const results = [...taskResults, ...baselineResults];\n const now = Date.now();\n const excluded = new Set(params.excludedRecordIds ?? []);\n const rejected: UserContextPlan['rejected'] = [];\n const ranked = results\n .filter((result) => !excluded.has(result.record.id))\n .map((result) => ({ result, score: scoreResult(result, now) }))\n .sort((a, b) => b.score - a.score)\n .filter((entry, index, all) => all.findIndex((candidate) => candidate.result.record.id === entry.result.record.id) === index)\n .slice(0, MAX_RESULTS);\n const items: PlannedUserContextItem[] = [];\n let usedChars = 0;\n for (const { result, score } of ranked) {\n const reason = rejectReason(result.record, now) ?? (score < 0.25 ? 'low_score' : undefined);\n if (reason) {\n rejected.push({ recordId: result.record.id, reason });\n continue;\n }\n const content = result.snippet.trim();\n if (usedChars + content.length > MAX_CONTEXT_CHARS) {\n rejected.push({ recordId: result.record.id, reason: 'budget' });\n continue;\n }\n usedChars += content.length;\n items.push({\n recordId: result.record.id,\n content,\n score,\n section: sectionFor(result.record),\n citation: citationFor(result, params.agentId),\n origin: classifyMemoryContextOrigin(result.record),\n stability: resolveMemoryStability(result.record, now).score,\n });\n }\n const sections: string[] = [];\n for (const [section, title] of [['safety', 'Boundaries'], ['task', 'Relevant facts'], ['interaction', 'Interaction preferences']] as const) {\n const sectionItems = items.filter((item) => item.section === section);\n if (sectionItems.length > 0) {\n sections.push(`${title}:\\n${sectionItems.map((item) => `- ${item.content}\\n Evidence: ${evidenceLabel(item)}`).join('\\n')}`);\n }\n }\n const block = buildUserContextBlock(sections.join('\\n\\n'));\n try {\n appendMemoryTraceEvent({\n traceId,\n phase: 'inject',\n providerId: 'user-understanding',\n sessionKey: params.sessionKey,\n request: {\n query,\n rejected,\n contextItems: items.map((item) => ({\n recordId: item.recordId,\n section: item.section,\n origin: item.origin,\n stability: item.stability,\n citation: item.citation,\n })),\n },\n resultCount: items.length,\n selectedRecordIds: items.map((item) => item.recordId),\n durationMs: Date.now() - started,\n });\n } catch (err) {\n log.debug({ err, traceId, sessionKey: params.sessionKey }, 'Context plan trace was not persisted');\n }\n return {\n traceId,\n modelMessage: prependContext(params.userMessage, block),\n items,\n rejected,\n estimatedTokens: Math.ceil(block.length / 4),\n };\n }\n}\n"],"mappings":"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"}
@@ -1,11 +1,13 @@
1
1
  import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
- export type UserContextRejectionReason = 'expired' | 'not_yet_valid' | 'sensitive' | 'requires_consent' | 'low_score' | 'budget';
2
+ export type UserContextRejectionReason = 'expired' | 'not_yet_valid' | 'sensitive' | 'requires_consent' | 'needs_review' | 'low_score' | 'budget';
3
3
  export interface PlannedUserContextItem {
4
4
  recordId: string;
5
5
  content: string;
6
6
  score: number;
7
7
  section: 'task' | 'interaction' | 'safety';
8
8
  citation: string;
9
+ origin: 'told_by_user' | 'observed' | 'inferred' | 'connected_source';
10
+ stability: number;
9
11
  }
10
12
  export interface UserContextPlan {
11
13
  traceId: string;
@@ -0,0 +1,11 @@
1
+ import type { MemoryRecord, MemoryStatus } from './types.js';
2
+ export type MemoryStabilityBand = 'strong' | 'working' | 'fragile';
3
+ export declare function nextMemoryReviewAt(record: Pick<MemoryRecord, 'durability' | 'explicitness'>, fromMs?: number): string;
4
+ export declare function resolveMemoryStability(record: MemoryRecord, nowMs?: number): {
5
+ score: number;
6
+ band: MemoryStabilityBand;
7
+ reviewAt: string;
8
+ reviewDue: boolean;
9
+ expired: boolean;
10
+ };
11
+ export declare function effectiveMemoryStatus(record: MemoryRecord, nowMs?: number): MemoryStatus;
@@ -0,0 +1,50 @@
1
+ //#region src/agent/memory/lifecycle.ts
2
+ const DAY_MS = 864e5;
3
+ function clamp01(value) {
4
+ return Math.max(0, Math.min(1, value));
5
+ }
6
+ function reviewIntervalDays(record) {
7
+ if (record.durability === "ephemeral") return 14;
8
+ if (record.durability === "recurring") return record.explicitness === "explicit" ? 120 : 60;
9
+ if (record.explicitness === "explicit") return 365;
10
+ if (record.explicitness === "observed") return 180;
11
+ return 90;
12
+ }
13
+ function nextMemoryReviewAt(record, fromMs = Date.now()) {
14
+ return new Date(fromMs + reviewIntervalDays(record) * DAY_MS).toISOString();
15
+ }
16
+ function resolveMemoryStability(record, nowMs = Date.now()) {
17
+ const confidence = clamp01(record.confidence ?? .5);
18
+ const explicitness = record.explicitness === "explicit" ? 1 : record.explicitness === "observed" ? .7 : .45;
19
+ const durability = record.durability === "durable" ? 1 : record.durability === "recurring" ? .85 : .55;
20
+ const evidence = record.evidence ?? [];
21
+ const evidenceStrength = clamp01((evidence.length > 0 ? evidence.reduce((sum, item) => sum + clamp01(item.confidence ?? confidence), 0) / evidence.length : confidence * .8) * .75 + Math.min(evidence.length, 4) * .0625);
22
+ const updatedAtMs = Date.parse(record.updatedAt);
23
+ const ageDays = Number.isFinite(updatedAtMs) ? Math.max(0, (nowMs - updatedAtMs) / DAY_MS) : 0;
24
+ const halfLifeDays = record.durability === "ephemeral" ? 21 : record.durability === "recurring" ? 120 : 365;
25
+ const freshnessFloor = record.explicitness === "explicit" ? .72 : record.explicitness === "observed" ? .48 : .28;
26
+ const freshness = freshnessFloor + (1 - freshnessFloor) * Math.pow(.5, ageDays / halfLifeDays);
27
+ const raw = confidence * .32 + explicitness * .2 + clamp01(record.importance) * .16 + durability * .14 + evidenceStrength * .18;
28
+ const score = Math.round(clamp01(raw * freshness) * 1e3) / 1e3;
29
+ const band = score >= .75 ? "strong" : score >= .5 ? "working" : "fragile";
30
+ const inferredReviewAt = nextMemoryReviewAt(record, Number.isFinite(updatedAtMs) ? updatedAtMs : nowMs);
31
+ const reviewAt = record.reviewAfter && Number.isFinite(Date.parse(record.reviewAfter)) ? record.reviewAfter : inferredReviewAt;
32
+ const expired = Boolean(record.expiresAt && Date.parse(record.expiresAt) <= nowMs || record.validTo && Date.parse(record.validTo) <= nowMs);
33
+ return {
34
+ score,
35
+ band,
36
+ reviewAt,
37
+ reviewDue: record.status === "candidate" || record.status === "needs_review" || record.status === "stale" || Date.parse(reviewAt) <= nowMs,
38
+ expired
39
+ };
40
+ }
41
+ function effectiveMemoryStatus(record, nowMs = Date.now()) {
42
+ const lifecycle = resolveMemoryStability(record, nowMs);
43
+ if (lifecycle.expired && record.status === "active") return "stale";
44
+ if (lifecycle.reviewDue && record.status === "active") return "needs_review";
45
+ return record.status ?? "active";
46
+ }
47
+ //#endregion
48
+ export { effectiveMemoryStatus, nextMemoryReviewAt, resolveMemoryStability };
49
+
50
+ //# sourceMappingURL=lifecycle.js.map