@xopcai/xopc 0.0.360 → 0.0.362

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 (251) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-CnmHVy1D.js → activity-store-_2aJ4ozN.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CQTERenW.js → agent-avatar-dicebear-CSIn4ghK.js} +1 -1
  5. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DBNFaHYa.js +1 -0
  6. package/dist/gateway/static/root/assets/agent-plugin-dialog-DJkGbMVg.js +1 -0
  7. package/dist/gateway/static/root/assets/agents-CuQayYYr.js +66 -0
  8. package/dist/gateway/static/root/assets/{agents-admin-api-BtnYiq7O.js → agents-admin-api-Dl0V7UQq.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-V5QVeMvW.js → app-management-settings-panel-CSczq9QV.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-BDkRcoI6.js → appearance-settings-W0vc1J1Q.js} +1 -1
  11. package/dist/gateway/static/root/assets/{apps-page-DzCyL89L.js → apps-page-esnvb3hh.js} +1 -1
  12. package/dist/gateway/static/root/assets/{archive-plugin-DZCN9m71.js → archive-plugin-CBR91gHK.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-DOu1wMOV.js → automations-page-B9RdzKUS.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-workspace-U9TEZd_t.js +7 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-U63xxRgh.js → binary-plugins-C9KIjPph.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-K6is5GrS.js → block-editor-C0bammwh.js} +3 -3
  17. package/dist/gateway/static/root/assets/{browser-automation-inputs-MmkUGn9W.js → browser-automation-inputs-D2E0co_S.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-automations-page-B8IiXEBs.js → browser-automations-page-8kqdhAOz.js} +2 -2
  19. package/dist/gateway/static/root/assets/browser-settings-page-Dl4idi13.js +3 -0
  20. package/dist/gateway/static/root/assets/{capabilities-BXG_5wIg.js → capabilities-Bfktn_7E.js} +1 -1
  21. package/dist/gateway/static/root/assets/{capabilities-Bigu28Z6.js → capabilities-BmMMlNmY.js} +1 -1
  22. package/dist/gateway/static/root/assets/capabilities-page-3ImhKPBx.js +2 -0
  23. package/dist/gateway/static/root/assets/capabilities-settings-panel-4VDEB_ob.js +8 -0
  24. package/dist/gateway/static/root/assets/{capability-header-actions-wh3Nr0qS.js → capability-header-actions-D1gxCGi8.js} +1 -1
  25. package/dist/gateway/static/root/assets/channels-Drbr2JR-.js +1 -0
  26. package/dist/gateway/static/root/assets/{chat-terminal-dock-BU-X9nu1.js → chat-terminal-dock-CSkksCaa.js} +2 -2
  27. package/dist/gateway/static/root/assets/{computer-settings-page-MyXsSqFJ.js → computer-settings-page-BIXpOJAk.js} +1 -1
  28. package/dist/gateway/static/root/assets/{connector-service-page-DyxPM_MZ.js → connector-service-page-CTnlVEE1.js} +1 -1
  29. package/dist/gateway/static/root/assets/connectors-page-BluT2l4d.js +2 -0
  30. package/dist/gateway/static/root/assets/{date-picker-WRFvi7Pu.js → date-picker-Bw-CydDe.js} +1 -1
  31. package/dist/gateway/static/root/assets/dependency-picker-CgHzhtAc.js +1 -0
  32. package/dist/gateway/static/root/assets/{desktop-pet-iaVa9vVM.js → desktop-pet-YahEnyfd.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-settings-0RS3sP3Z.js → desktop-pet-settings-47Z4bqJr.js} +1 -1
  34. package/dist/gateway/static/root/assets/device-pairing-wizard-C3aPEEaM.js +1 -0
  35. package/dist/gateway/static/root/assets/{directory-picker-path-field-Btlldlt3.js → directory-picker-path-field-DH_ok92y.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-debug-page-BImQT4PU.js → extension-debug-page-t1TiLQrR.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-BmuLv-ET.js → extension-page-BeV-7G1h.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-provider-Dg7cRxDX.js → extension-provider-CFCxzqna.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-settings-page-7Kr8UJK4.js → extension-settings-page-DCODJHOu.js} +1 -1
  40. package/dist/gateway/static/root/assets/{fallback-models-B0w1lumZ.js → fallback-models-CJzvASNV.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-config-swr-EZxaKXdC.js → gateway-config-swr-B3LfyXpc.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-realtime-DBRa17u3.js → gateway-realtime-CWxXXAe_.js} +1 -1
  43. package/dist/gateway/static/root/assets/gateway-realtime-store-DS4WzQyF.js +1 -0
  44. package/dist/gateway/static/root/assets/gateway-settings-Q5NFzAJ_.js +1 -0
  45. package/dist/gateway/static/root/assets/{gateway-startup-retry-Wtxq_y2f.js → gateway-startup-retry-BzQP02wp.js} +1 -1
  46. package/dist/gateway/static/root/assets/home-page-DndTkAw8.js +1 -0
  47. package/dist/gateway/static/root/assets/{image-generation-api-Bnl0CH4n.js → image-generation-api-BO-Xs__S.js} +1 -1
  48. package/dist/gateway/static/root/assets/{imports-page-BLOJY67-.js → imports-page-Bb6Gm30L.js} +1 -1
  49. package/dist/gateway/static/root/assets/index-Byk2QKIS.css +1 -0
  50. package/dist/gateway/static/root/assets/index-qOHWhsEK.js +106 -0
  51. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Dlbsip2R.js → keyboard-shortcuts-settings-D2u6sk5l.js} +1 -1
  52. package/dist/gateway/static/root/assets/{local-app-workbench-page-nyWeTK0r.js → local-app-workbench-page-CHeMfXrB.js} +1 -1
  53. package/dist/gateway/static/root/assets/{local-apps-page-CfEpFLs0.js → local-apps-page-BanU1SLr.js} +1 -1
  54. package/dist/gateway/static/root/assets/{local-session-drafts-CeHhcudO.js → local-session-drafts-DLZQBcZY.js} +1 -1
  55. package/dist/gateway/static/root/assets/{locale-store-ChN_vjs2.js → locale-store-BbwWB0ra.js} +1 -1
  56. package/dist/gateway/static/root/assets/{logs-page-A38cawkA.js → logs-page-CQdHKCL0.js} +2 -2
  57. package/dist/gateway/static/root/assets/management-settings-D0V5kCx0.js +1 -0
  58. package/dist/gateway/static/root/assets/{markdown-view-DKlJx4eo.js → markdown-view-DIBLXsPm.js} +1 -1
  59. package/dist/gateway/static/root/assets/{media-plugins-JWzrPQwt.js → media-plugins-XPzvDZPz.js} +1 -1
  60. package/dist/gateway/static/root/assets/{messages-CnM6Qfr7.js → messages-B4AhAW4B.js} +2 -2
  61. package/dist/gateway/static/root/assets/models-hub-cache-DN5MnhL8.js +1 -0
  62. package/dist/gateway/static/root/assets/{note-detail-panel-CUGVyo2V.js → note-detail-panel-CodeKI_W.js} +3 -3
  63. package/dist/gateway/static/root/assets/{notes-api-D8nvWMMC.js → notes-api-CLn4r03Z.js} +1 -1
  64. package/dist/gateway/static/root/assets/notes-page-liRQoHbF.js +8 -0
  65. package/dist/gateway/static/root/assets/{oauth-api-BXn1a9qx.js → oauth-api-D9zkd42J.js} +1 -1
  66. package/dist/gateway/static/root/assets/{page-context-capture-button-C72qIgBg.js → page-context-capture-button-DO6DB9pi.js} +1 -1
  67. package/dist/gateway/static/root/assets/personal-page-DdfdwOv5.js +1 -0
  68. package/dist/gateway/static/root/assets/{product-open-page-CT98FsVl.js → product-open-page-C9a3sm6Z.js} +1 -1
  69. package/dist/gateway/static/root/assets/{project-detail-page-BlqOVwKP.js → project-detail-page-BVe5R-Nj.js} +1 -1
  70. package/dist/gateway/static/root/assets/projects-page-D_rCwi7w.js +1 -0
  71. package/dist/gateway/static/root/assets/{registry-api-BM_81rLe.js → registry-api-BFxQTbXQ.js} +1 -1
  72. package/dist/gateway/static/root/assets/remote-access-hub-B3imt2du.js +1 -0
  73. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-ry0jprz7.js → runtime-tools-settings-panel-C9WC8hJM.js} +1 -1
  74. package/dist/gateway/static/root/assets/{scenes-page-CV1GkOj6.js → scenes-page-DL95V1UP.js} +2 -2
  75. package/dist/gateway/static/root/assets/{schema-form-C5zMrxgR.js → schema-form-CDgGmgrq.js} +1 -1
  76. package/dist/gateway/static/root/assets/{send-session-input-Dt0t5SoR.js → send-session-input-tkAQXGBG.js} +1 -1
  77. package/dist/gateway/static/root/assets/{session-api-UkGomZfv.js → session-api-9X7qep91.js} +1 -1
  78. package/dist/gateway/static/root/assets/{session-manager-DDR-gv_e.js → session-manager-Dy22bbJT.js} +2 -2
  79. package/dist/gateway/static/root/assets/sessions-page-CeeKIVsM.js +1 -0
  80. package/dist/gateway/static/root/assets/settings-advanced-gate-DuvJrDU2.js +1 -0
  81. package/dist/gateway/static/root/assets/{settings-page-C88fsfZF.js → settings-page-xmUGYSOG.js} +1 -1
  82. package/dist/gateway/static/root/assets/{setup-status-panel-DESlRgZS.js → setup-status-panel-CmjT9Q4P.js} +1 -1
  83. package/dist/gateway/static/root/assets/{share-link-dialog-BvSRHs1P.js → share-link-dialog-DeOe9qfQ.js} +1 -1
  84. package/dist/gateway/static/root/assets/{share-preview-page-D5Gey-6E.js → share-preview-page-Ck27gozJ.js} +1 -1
  85. package/dist/gateway/static/root/assets/{shares-api-DwqLga5H.js → shares-api-D-GuMkPu.js} +1 -1
  86. package/dist/gateway/static/root/assets/shares-settings-DpvM2OyO.js +1 -0
  87. package/dist/gateway/static/root/assets/{skill-api-1hbX3qDC.js → skill-api-BpD02td8.js} +1 -1
  88. package/dist/gateway/static/root/assets/{skill-reload-api-C1hzIawD.js → skill-reload-api-CezAwYxM.js} +1 -1
  89. package/dist/gateway/static/root/assets/skills-page-BCgbVI-P.js +2 -0
  90. package/dist/gateway/static/root/assets/{system-settings-panel-DbNk-Jwq.js → system-settings-panel-UODcpzsP.js} +1 -1
  91. package/dist/gateway/static/root/assets/task-detail-page-BbqQnNes.js +2 -0
  92. package/dist/gateway/static/root/assets/{theme-store-DTYk7Gll.js → theme-store-6IK2Ik2J.js} +1 -1
  93. package/dist/gateway/static/root/assets/{tunnel-api-H3FheXYH.js → tunnel-api-Eey2aZIz.js} +1 -1
  94. package/dist/gateway/static/root/assets/{usage-page-DGbqcsV6.js → usage-page-BrWj5mk3.js} +1 -1
  95. package/dist/gateway/static/root/assets/{use-autosave-R3hEHQQq.js → use-autosave-B-3BJbnn.js} +1 -1
  96. package/dist/gateway/static/root/assets/{use-composer-attachments-pzPAUV_o.js → use-composer-attachments-ByAHuR8v.js} +1 -1
  97. package/dist/gateway/static/root/assets/{use-file-preview-expanded-DNhXjL0W.js → use-file-preview-expanded-CXVwWJeP.js} +2 -2
  98. package/dist/gateway/static/root/assets/user-model-page-Cg-oM8nY.js +2 -0
  99. package/dist/gateway/static/root/assets/{voice-api-key-field-C-AF-IcO.js → voice-api-key-field-BtffIKZD.js} +1 -1
  100. package/dist/gateway/static/root/assets/{voice-config-api-CxGsCDoW.js → voice-config-api-BMm9dSKX.js} +1 -1
  101. package/dist/gateway/static/root/assets/{work-discovery-overlay-DfyI9kVf.js → work-discovery-overlay-ByHhF_4r.js} +1 -1
  102. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-De80GODZ.js → workflow-run-setup-panel-DfNn5VTy.js} +2 -2
  103. package/dist/gateway/static/root/assets/workflows-page-B67D-7Wt.js +6 -0
  104. package/dist/gateway/static/root/assets/{workspace-api-Dwa8kHdY.js → workspace-api-TAD7LYsc.js} +2 -2
  105. package/dist/gateway/static/root/connector-icons/README.md +5 -2
  106. package/dist/gateway/static/root/connector-icons/SOURCES.md +15 -1
  107. package/dist/gateway/static/root/connector-icons/amap.ico +0 -0
  108. package/dist/gateway/static/root/connector-icons/antv-chart.png +0 -0
  109. package/dist/gateway/static/root/connector-icons/bailian.png +0 -0
  110. package/dist/gateway/static/root/connector-icons/dida365.png +0 -0
  111. package/dist/gateway/static/root/connector-icons/flomo.png +0 -0
  112. package/dist/gateway/static/root/connector-icons/gmail.svg +1 -3
  113. package/dist/gateway/static/root/connector-icons/jira.svg +3 -14
  114. package/dist/gateway/static/root/connector-icons/railway-12306.jpg +0 -0
  115. package/dist/gateway/static/root/connector-icons/railway-query.svg +1 -0
  116. package/dist/gateway/static/root/connector-icons/tencent-docs.ico +0 -0
  117. package/dist/gateway/static/root/connector-icons/yuque.png +0 -0
  118. package/dist/gateway/static/root/index.html +28 -29
  119. package/dist/package.js +1 -1
  120. package/dist/packages/gateway-contract/src/task-result-delivery.js +2 -2
  121. package/dist/src/agent/agent-manager.js +3 -3
  122. package/dist/src/agent/background-review/run-background-review.js +1 -1
  123. package/dist/src/agent/embedded/run-for-session.js +70 -4
  124. package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
  125. package/dist/src/agent/image/tool-model-config.js +1 -1
  126. package/dist/src/agent/inbound/attachment-pipeline.js +13 -0
  127. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  128. package/dist/src/agent/memory/compaction-policy.d.ts +4 -0
  129. package/dist/src/agent/memory/compaction-policy.js +3 -0
  130. package/dist/src/agent/memory/idle-compaction-scheduler.d.ts +28 -0
  131. package/dist/src/agent/memory/idle-compaction-scheduler.js +127 -0
  132. package/dist/src/agent/service/process-direct-one-shot.js +1 -0
  133. package/dist/src/agent/service/process-direct-streaming.js +1 -0
  134. package/dist/src/agent/service.js +3 -2
  135. package/dist/src/agent/session/session-config-service.js +1 -1
  136. package/dist/src/agent/skills/hub-lock.js +1 -1
  137. package/dist/src/agent/skills/index.js +1 -1
  138. package/dist/src/agent/skills/managed-store.js +1 -1
  139. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  140. package/dist/src/agent/tasks/task-judge-service.js +1 -1
  141. package/dist/src/agent/tools/delegation-policy.js +1 -0
  142. package/dist/src/agent/tools/factory.js +16 -2
  143. package/dist/src/agent/tools/index.d.ts +1 -0
  144. package/dist/src/agent/tools/index.js +2 -1
  145. package/dist/src/agent/tools/media-read-tool.d.ts +5 -1
  146. package/dist/src/agent/tools/media-read-tool.js +44 -5
  147. package/dist/src/agent/tools/personal-read-tool.d.ts +3 -0
  148. package/dist/src/agent/tools/personal-read-tool.js +155 -0
  149. package/dist/src/agent/tools/personal-task-tool.js +1 -1
  150. package/dist/src/agent/tools/read.d.ts +3 -0
  151. package/dist/src/agent/tools/read.js +26 -8
  152. package/dist/src/agent/tools/session-search-tool.d.ts +1 -0
  153. package/dist/src/agent/tools/session-search-tool.js +39 -5
  154. package/dist/src/agent/tools/xopc-use-tool.js +2 -2
  155. package/dist/src/agent-catalog/capabilities.js +2 -2
  156. package/dist/src/auth/credentials.js +1 -1
  157. package/dist/src/auth/oauth-provider-lock.js +1 -1
  158. package/dist/src/auth/profiles/store.js +1 -1
  159. package/dist/src/automations/capabilities/drafts.js +1 -1
  160. package/dist/src/bootstrap/application-state.js +1 -1
  161. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  162. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  163. package/dist/src/capabilities/runtime/product.js +1 -1
  164. package/dist/src/cli/commands/agent.js +1 -1
  165. package/dist/src/cli/commands/agents.js +1 -1
  166. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  167. package/dist/src/cli/commands/models.js +1 -1
  168. package/dist/src/cli/commands/onboard/model.js +1 -1
  169. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  170. package/dist/src/config/index.js +3 -3
  171. package/dist/src/config/loader.js +1 -1
  172. package/dist/src/config/models-json.js +1 -1
  173. package/dist/src/config/schema.d.ts +10 -0
  174. package/dist/src/config/schema.js +1 -1
  175. package/dist/src/connectors/china-catalog.js +572 -0
  176. package/dist/src/connectors/cli/authorization.js +3 -2
  177. package/dist/src/connectors/cli/installer.js +3 -1
  178. package/dist/src/extensions/agent-plugins/validation.js +1 -1
  179. package/dist/src/extensions/lockfile.js +1 -1
  180. package/dist/src/gateway/agents-admin.js +2 -2
  181. package/dist/src/gateway/hono/lib/config-payload.d.ts +10 -0
  182. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  183. package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
  184. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  185. package/dist/src/gateway/hono/routes/notes.js +2 -2
  186. package/dist/src/gateway/hono/routes/personal-agent.js +1 -1
  187. package/dist/src/gateway/hono/routes/projects.js +2 -2
  188. package/dist/src/gateway/hono/routes/session-input-handler.js +1 -1
  189. package/dist/src/gateway/hono/routes/sessions.js +1 -1
  190. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  191. package/dist/src/gateway/hono/routes/voice.js +1 -1
  192. package/dist/src/gateway/image-generation-setup.js +2 -2
  193. package/dist/src/gateway/lock.js +1 -1
  194. package/dist/src/gateway/service/agent-runner.js +1 -0
  195. package/dist/src/gateway/service/session-command-service.js +1 -1
  196. package/dist/src/gateway/service/session-input-coordinator.d.ts +1 -0
  197. package/dist/src/gateway/service/session-input-coordinator.js +2 -0
  198. package/dist/src/gateway/service.js +1 -1
  199. package/dist/src/gateway/side-chat/manager.js +3 -2
  200. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  201. package/dist/src/infra/update-restart.js +1 -1
  202. package/dist/src/local-apps/service.js +1 -1
  203. package/dist/src/media/store.js +5 -1
  204. package/dist/src/personal-agent/policy.d.ts +1 -1
  205. package/dist/src/personal-agent/policy.js +4 -0
  206. package/dist/src/personal-agent/request-service.js +1 -1
  207. package/dist/src/personal-agent/service.js +9 -7
  208. package/dist/src/providers/model-catalog-persistence.js +1 -1
  209. package/dist/src/session/store.d.ts +12 -1
  210. package/dist/src/session/store.js +33 -0
  211. package/dist/src/storage/sqlite/transcript-repository.d.ts +4 -1
  212. package/dist/src/storage/sqlite/transcript-repository.js +15 -1
  213. package/dist/src/tasks/capabilities/read.js +2 -2
  214. package/dist/src/tasks/task-main-update-decision-service.js +1 -1
  215. package/dist/src/tasks/task-result-delivery-repository.js +4 -5
  216. package/dist/src/tui/backends/embedded-backend.js +2 -2
  217. package/dist/src/user-context/config.d.ts +48 -0
  218. package/dist/src/user-context/config.js +23 -3
  219. package/dist/src/voice/realtime/persona-context.js +1 -1
  220. package/dist/src/voice/realtime/runtime.js +1 -1
  221. package/package.json +2 -2
  222. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CPF0lunJ.js +0 -1
  223. package/dist/gateway/static/root/assets/agent-plugin-dialog-BjDaZlKy.js +0 -1
  224. package/dist/gateway/static/root/assets/agents-XopBILLB.js +0 -66
  225. package/dist/gateway/static/root/assets/automations-workspace-CiY_2otj.js +0 -7
  226. package/dist/gateway/static/root/assets/browser-settings-page-Cms2Bu3Q.js +0 -3
  227. package/dist/gateway/static/root/assets/capabilities-page-BAFRNHQv.js +0 -2
  228. package/dist/gateway/static/root/assets/capabilities-settings-panel-Cws6od1d.js +0 -8
  229. package/dist/gateway/static/root/assets/channels-DxwismTc.js +0 -1
  230. package/dist/gateway/static/root/assets/connectors-page-C7-OC3MW.js +0 -2
  231. package/dist/gateway/static/root/assets/dependency-picker-CLun5Tst.js +0 -1
  232. package/dist/gateway/static/root/assets/device-pairing-wizard-DVAGb04L.js +0 -1
  233. package/dist/gateway/static/root/assets/gateway-realtime-store-7glMlD2l.js +0 -1
  234. package/dist/gateway/static/root/assets/gateway-settings-DmPvmwYp.js +0 -1
  235. package/dist/gateway/static/root/assets/home-page-N0Mp-eTJ.js +0 -1
  236. package/dist/gateway/static/root/assets/index-B7AHDHSO.css +0 -1
  237. package/dist/gateway/static/root/assets/index-BXrBL_Hb.js +0 -106
  238. package/dist/gateway/static/root/assets/management-settings-Cse9K61x.js +0 -1
  239. package/dist/gateway/static/root/assets/model-display-name-DXhO9rcM.js +0 -1
  240. package/dist/gateway/static/root/assets/models-hub-cache-DnIOzcvn.js +0 -1
  241. package/dist/gateway/static/root/assets/notes-page-Dk89l5dC.js +0 -8
  242. package/dist/gateway/static/root/assets/personal-page-DCtduzh8.js +0 -1
  243. package/dist/gateway/static/root/assets/projects-page-DVN2q_yR.js +0 -1
  244. package/dist/gateway/static/root/assets/remote-access-hub-BP5kUgIN.js +0 -1
  245. package/dist/gateway/static/root/assets/sessions-page-BXtGeOsR.js +0 -1
  246. package/dist/gateway/static/root/assets/settings-advanced-gate-CvFVkELy.js +0 -1
  247. package/dist/gateway/static/root/assets/shares-settings-btoP07Fx.js +0 -1
  248. package/dist/gateway/static/root/assets/skills-page-DYJbwwBT.js +0 -2
  249. package/dist/gateway/static/root/assets/task-detail-page-DoLKOJrE.js +0 -1
  250. package/dist/gateway/static/root/assets/user-model-page-7pW4Pazn.js +0 -2
  251. package/dist/gateway/static/root/assets/workflows-page-BuH3pC1C.js +0 -6
@@ -0,0 +1,127 @@
1
+ import { createLogger } from "../../utils/logger/index.js";
2
+ import { init_logger } from "../../utils/logger.js";
3
+ //#region src/agent/memory/idle-compaction-scheduler.ts
4
+ init_logger();
5
+ const log = createLogger("IdleCompaction");
6
+ /** Generation checks protect commits even when a provider ignores cancellation. */
7
+ var IdleCompactionScheduler = class {
8
+ states = /* @__PURE__ */ new Map();
9
+ running = false;
10
+ disposed = false;
11
+ metrics = {
12
+ committed: 0,
13
+ skipped: 0,
14
+ stale: 0,
15
+ cancelled: 0,
16
+ failed: 0
17
+ };
18
+ getMetrics() {
19
+ return { ...this.metrics };
20
+ }
21
+ interrupt(conversationId) {
22
+ const state = this.states.get(conversationId);
23
+ if (!state) return;
24
+ state.generation++;
25
+ if (state.timer) clearTimeout(state.timer);
26
+ state.timer = void 0;
27
+ state.job = void 0;
28
+ if (state.controller && !state.controller.signal.aborted) {
29
+ this.metrics.cancelled++;
30
+ state.controller.abort();
31
+ }
32
+ }
33
+ beginTurn(conversationId) {
34
+ this.interrupt(conversationId);
35
+ const state = this.states.get(conversationId) ?? {
36
+ generation: 0,
37
+ active: 0,
38
+ eligibleAt: 0
39
+ };
40
+ state.active++;
41
+ this.states.set(conversationId, state);
42
+ return state.generation;
43
+ }
44
+ endTurn(conversationId, generation, job, options) {
45
+ const state = this.states.get(conversationId);
46
+ if (!state) return;
47
+ state.active = Math.max(0, state.active - 1);
48
+ if (this.disposed || state.active || state.generation !== generation || !job || !options) return;
49
+ state.job = job;
50
+ state.queuedAt = Date.now();
51
+ state.options = options;
52
+ const delay = Math.max(options.idleMs, state.eligibleAt - Date.now());
53
+ state.timer = setTimeout(() => {
54
+ state.timer = void 0;
55
+ this.drain();
56
+ }, delay);
57
+ state.timer.unref?.();
58
+ }
59
+ cancelAll() {
60
+ for (const id of this.states.keys()) this.interrupt(id);
61
+ }
62
+ dispose() {
63
+ this.disposed = true;
64
+ this.cancelAll();
65
+ for (const state of this.states.values()) if (state.deadline) clearTimeout(state.deadline);
66
+ this.states.clear();
67
+ }
68
+ drain() {
69
+ if (this.running || this.disposed) return;
70
+ const entry = [...this.states.entries()].find(([, state]) => state.job && !state.timer && !state.active);
71
+ if (!entry) return;
72
+ const [conversationId, state] = entry;
73
+ const job = state.job;
74
+ const options = state.options;
75
+ state.job = void 0;
76
+ const generation = state.generation;
77
+ const controller = new AbortController();
78
+ state.controller = controller;
79
+ const startedAt = Date.now();
80
+ const waitMs = startedAt - (state.queuedAt ?? startedAt);
81
+ const isCurrent = () => !this.disposed && !controller.signal.aborted && state.generation === generation && !state.active;
82
+ this.running = true;
83
+ let timeout;
84
+ const deadline = new Promise((_, reject) => {
85
+ timeout = setTimeout(() => {
86
+ controller.abort();
87
+ reject(/* @__PURE__ */ new Error("Idle compaction deadline exceeded"));
88
+ }, options.timeoutMs);
89
+ state.deadline = timeout;
90
+ timeout.unref?.();
91
+ });
92
+ const operation = Promise.resolve().then(() => job(controller.signal, isCurrent));
93
+ Promise.race([operation, deadline]).then((outcome) => {
94
+ this.metrics[outcome]++;
95
+ if (outcome === "committed") state.eligibleAt = Date.now() + options.cooldownMs;
96
+ const fields = {
97
+ conversationId,
98
+ outcome,
99
+ waitMs,
100
+ durationMs: Date.now() - startedAt
101
+ };
102
+ if (outcome === "skipped") log.debug(fields, "Idle compaction skipped");
103
+ else log.info(fields, "Idle compaction finished");
104
+ }).catch((err) => {
105
+ if (state.generation === generation) {
106
+ this.metrics.failed++;
107
+ state.eligibleAt = Date.now() + options.cooldownMs;
108
+ log.warn({
109
+ err,
110
+ conversationId,
111
+ durationMs: Date.now() - startedAt
112
+ }, "Idle compaction failed; retry deferred");
113
+ }
114
+ }).finally(() => {
115
+ clearTimeout(timeout);
116
+ if (state.deadline === timeout) state.deadline = void 0;
117
+ if (state.controller === controller) state.controller = void 0;
118
+ });
119
+ const release = () => {
120
+ this.running = false;
121
+ this.drain();
122
+ };
123
+ operation.then(release, release);
124
+ }
125
+ };
126
+ //#endregion
127
+ export { IdleCompactionScheduler };
@@ -8,6 +8,7 @@ function isReviewOutput(value) {
8
8
  return !!value && typeof value === "object" && !Array.isArray(value) && value.type === "review";
9
9
  }
10
10
  async function runProcessDirect(deps, input) {
11
+ deps.sessionStore?.idleCompaction?.interrupt(input.conversationId);
11
12
  const { channel, chatId } = await deps.resolveSessionEndpoint(input.conversationId);
12
13
  deps.initSessionContext(input.conversationId, channel, chatId, input.origin);
13
14
  try {
@@ -138,6 +138,7 @@ function pushAssistantReceipt(queue, text, runId, metadata) {
138
138
  }
139
139
  async function* runProcessDirectStreaming(deps, input) {
140
140
  const conversationId = input.conversationId ?? resolveAgentMainConversationId({ agentId: resolveDefaultAgentId() });
141
+ deps.sessionStore?.idleCompaction?.interrupt(conversationId);
141
142
  const isConnectionResume = Boolean(input.runId && getConnectionResumeInput(conversationId, input.runId));
142
143
  const isClarificationResume = Boolean(input.runId && getClarificationResumeInput(conversationId, input.runId));
143
144
  const isInternalResume = isConnectionResume || isClarificationResume;
@@ -1,13 +1,13 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { init_attachment_ref, parseNoteAttachmentTarget } from "../notes/attachment-ref.js";
4
- import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "./agent-scope.js";
5
- import { extractTextContent } from "./context/workspace.js";
6
4
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
7
5
  import { applyConfigOverrides } from "../config/runtime-overrides.js";
6
+ import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "./agent-scope.js";
8
7
  import { init_agent_session_key, resolveAgentIdFromConversationId } from "../routing/agent-session-key.js";
9
8
  import { extractProfileAgentId, resolveEffectiveAgentConfigForSession } from "../config/agent-profile.js";
10
9
  import { init_providers, resolveModel } from "../providers/index.js";
10
+ import { extractTextContent } from "./context/workspace.js";
11
11
  import { effectiveWorkspacePathForSession } from "../session/session-workspace.js";
12
12
  import { getProjectForSession } from "../projects/workspace.js";
13
13
  import { runWithEmbeddedExecutionSession } from "./embedded/execution-context.js";
@@ -878,6 +878,7 @@ var AgentService = class {
878
878
  }
879
879
  }
880
880
  dispose() {
881
+ this.sessionStore.idleCompaction.dispose();
881
882
  this.sessionTracker.dispose();
882
883
  this.sessionState.disposeAll();
883
884
  this.agentManager.dispose();
@@ -6,8 +6,8 @@ import { ResponseLanguageSchema, init_response_language } from "../../i18n/respo
6
6
  import { resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
7
7
  import { normalizeWorkingDirectoryInput } from "../../session/session-workspace.js";
8
8
  import { getProjectWorkspacePathForSession } from "../../projects/workspace.js";
9
- import { getModelThinking } from "../../providers/model-thinking.js";
10
9
  import { isPersonalConversation } from "../../personal-agent/repository.js";
10
+ import { getModelThinking } from "../../providers/model-thinking.js";
11
11
  import { savePersonalModelConfig } from "../../personal-agent/model-config.js";
12
12
  import { normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel } from "../transcript/thinking-types.js";
13
13
  import "../../session/index.js";
@@ -1,5 +1,5 @@
1
- import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
2
1
  import { init_paths, resolveSkillsLockPath } from "../../config/paths.js";
2
+ import { init_write_file_atomic, writeTextAtomicSync } from "../../infra/write-file-atomic.js";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  //#region src/agent/skills/hub-lock.ts
5
5
  /**
@@ -1,8 +1,8 @@
1
1
  import { resolveStateDir } from "../../config/paths-state.js";
2
2
  import { createLogger } from "../../utils/logger/index.js";
3
3
  import { init_logger } from "../../utils/logger.js";
4
- import { parseFrontmatter } from "../../markdown/frontmatter.js";
5
4
  import { init_paths } from "../../config/paths.js";
5
+ import { parseFrontmatter } from "../../markdown/frontmatter.js";
6
6
  import { findInstallSpec, hasBinary, installSkill } from "./installer.js";
7
7
  import { applySkillEnvOverrides, createSkillConfigManager, getSkillEnvironment, isSkillEnabled, resolveSkillConfig, validateSkillConfig } from "./config.js";
8
8
  import { parseSkillToolConditions } from "./skill-tool-gating.js";
@@ -1,5 +1,5 @@
1
- import { parseFrontmatter } from "../../markdown/frontmatter.js";
2
1
  import { init_paths, resolveSkillsDir } from "../../config/paths.js";
2
+ import { parseFrontmatter } from "../../markdown/frontmatter.js";
3
3
  import { loadSkillsLock } from "./hub-lock.js";
4
4
  import { dirname, join, resolve, sep } from "node:path";
5
5
  import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
@@ -1,5 +1,5 @@
1
- import { parseFrontmatter } from "../../markdown/frontmatter.js";
2
1
  import { init_paths, resolveSkillsDir } from "../../config/paths.js";
2
+ import { parseFrontmatter } from "../../markdown/frontmatter.js";
3
3
  import { resolveWorkspaceSkillsDir } from "./workspace-skills-dir.js";
4
4
  import { formatScanSummary, scanSkillDirectory } from "./scanner.js";
5
5
  import { fuzzyFindText, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings } from "../tools/edit-diff.js";
@@ -207,7 +207,7 @@ var TaskJudgeService = class {
207
207
  expectedRunVersion: run.version,
208
208
  receipt: {
209
209
  status: "succeeded",
210
- summary: payload.assistantPlainText.slice(-2e3) || "Agent run completed",
210
+ summary: payload.assistantPlainText || "Agent run completed",
211
211
  changes: [],
212
212
  evidence,
213
213
  verification: {
@@ -16,6 +16,7 @@ const DELEGATION_TOOL_CAPABILITIES = {
16
16
  find: "local_read",
17
17
  list_dir: "local_read",
18
18
  review_workspace: "local_read",
19
+ personal_read: "local_read",
19
20
  read_media: "local_read",
20
21
  image: "local_read",
21
22
  tool_manual: "local_read",
@@ -62,6 +62,7 @@ import { createDesktopPetTool } from "./desktop-pet-tool.js";
62
62
  import { createManagedJobTool } from "./managed-job-tool.js";
63
63
  import { createImageTool } from "./image-tool.js";
64
64
  import { createImageGenerateTool } from "./image-generate-tool.js";
65
+ import { createPersonalReadTool } from "./personal-read-tool.js";
65
66
  import "./index.js";
66
67
  import { createPersonalTaskTool } from "./personal-task-tool.js";
67
68
  import { createPersonalRequestTools } from "./personal-request-tool.js";
@@ -279,7 +280,14 @@ var AgentToolsFactory = class AgentToolsFactory {
279
280
  canAccessMemory: () => currentAccess().knowledge
280
281
  });
281
282
  const optionalTools = [imageTool, imageGenerateTool].filter((t) => t != null);
282
- const readTool = createReadFileTool(workspace, { profileMarkdownRoot: options?.profileMarkdownRoot });
283
+ const readTool = createReadFileTool(workspace, {
284
+ profileMarkdownRoot: options?.profileMarkdownRoot,
285
+ ...personalToolsConfigured ? {
286
+ defaultMaxLines: 150,
287
+ maxOutputBytes: 8e3,
288
+ maxReadBytes: 12e3
289
+ } : {}
290
+ });
283
291
  const writeTool = createWriteFileTool(workspace, { profileMarkdownRoot: options?.profileMarkdownRoot });
284
292
  const applyPatchTool = createApplyPatchTool(workspace);
285
293
  const listDir = createListDirTool(workspace);
@@ -395,7 +403,11 @@ var AgentToolsFactory = class AgentToolsFactory {
395
403
  })] : [],
396
404
  createSendMediaTool(workspace, bus, deliveryContext),
397
405
  createPublishArtifactsTool(workspace),
398
- createReadMediaTool(),
406
+ createReadMediaTool(personalToolsConfigured ? {
407
+ textOnly: true,
408
+ maxChars: 8e3,
409
+ maxReadBytes: 12e3
410
+ } : void 0),
399
411
  ...isShareToolAvailable(cfg) ? [createCreateShareTool({
400
412
  workspace,
401
413
  getConfig: () => this.deps.getConfig?.()
@@ -461,6 +473,7 @@ var AgentToolsFactory = class AgentToolsFactory {
461
473
  getCurrentConversationId: () => this.deps.getCurrentContext()?.conversationId
462
474
  })] : [],
463
475
  ...this.deps.getSessionStore && getPrimary ? [createSessionSearchTool({
476
+ localOnly: personalToolsConfigured,
464
477
  getSessionStore: this.deps.getSessionStore,
465
478
  getPrimaryModel: getPrimary,
466
479
  getCurrentConversationId: () => this.deps.getCurrentContext()?.conversationId,
@@ -474,6 +487,7 @@ var AgentToolsFactory = class AgentToolsFactory {
474
487
  ...browserEnabled && this.deps.getBrowserAutomationService ? [createBrowserAutomationTool({ getBrowserAutomationService: this.deps.getBrowserAutomationService })] : [],
475
488
  ...this.deps.getAutomationService || this.deps.getSceneAccess || this.deps.getProjectService || this.deps.getNotesService || this.deps.getLocalAppService || this.deps.getChatPreviewService || this.deps.dispatchTaskEvents || this.deps.dispatchTaskRuns ? [createXopcUseTool(productToolDeps), ...personalToolsConfigured ? [
476
489
  createPersonalTaskTool(productToolDeps),
490
+ createPersonalReadTool(productToolDeps),
477
491
  ...createPersonalRequestTools(productToolDeps),
478
492
  createPersonalPreferenceTool({
479
493
  getCurrentConversationId: () => this.deps.getCurrentContext()?.conversationId,
@@ -42,3 +42,4 @@ export { createImageTool, resolveImageModelConfigForTool } from './image-tool.js
42
42
  export { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from './image-generate-tool.js';
43
43
  export { truncateHead, truncateTail, truncateLine, formatSize, type TruncationResult, type TruncationOptions, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES, GREP_MAX_LINE_LENGTH, } from './truncate.js';
44
44
  export { normalizeToLF, restoreLineEndings, normalizeForFuzzyMatch, fuzzyFindText, stripBom, generateDiffString, type FuzzyMatchResult, } from './edit-diff.js';
45
+ export { createPersonalReadTool } from './personal-read-tool.js';
@@ -45,4 +45,5 @@ import { createDesktopPetTool } from "./desktop-pet-tool.js";
45
45
  import { createManagedJobTool } from "./managed-job-tool.js";
46
46
  import { createImageTool } from "./image-tool.js";
47
47
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
48
- export { BrowserRuntime, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, createApplyPatchTool, createAutomationTool, createBrowserAutomationTool, createClarifyTool, createCreateShareTool, createDataBatchTool, createDelegateTool, createDesktopPetTool, createExecCommandTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool, createListDirTool, createManagedJobTool, createMemoryMaintenanceTool, createMessageTool, createPublishArtifactsTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowManageTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
48
+ import { createPersonalReadTool } from "./personal-read-tool.js";
49
+ export { BrowserRuntime, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, createApplyPatchTool, createAutomationTool, createBrowserAutomationTool, createClarifyTool, createCreateShareTool, createDataBatchTool, createDelegateTool, createDesktopPetTool, createExecCommandTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool, createListDirTool, createManagedJobTool, createMemoryMaintenanceTool, createMessageTool, createPersonalReadTool, createPublishArtifactsTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowManageTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -1,2 +1,6 @@
1
1
  import type { AgentTool } from '@earendil-works/pi-agent-core';
2
- export declare function createReadMediaTool(): AgentTool;
2
+ export declare function createReadMediaTool(options?: {
3
+ textOnly?: boolean;
4
+ maxChars?: number;
5
+ maxReadBytes?: number;
6
+ }): AgentTool;
@@ -15,12 +15,14 @@ function clampMaxBytes(raw) {
15
15
  if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return DEFAULT_MAX_BYTES;
16
16
  return Math.min(Math.floor(raw), HARD_MAX_BYTES);
17
17
  }
18
- function createReadMediaTool() {
18
+ function createReadMediaTool(options) {
19
19
  return {
20
20
  name: "read_media",
21
21
  label: "Read Media Attachment",
22
22
  description: "Read an attachment by media:// URI. Use this for xopc-media-uri attachments in user messages.",
23
23
  parameters: ReadMediaSchema,
24
+ supportsParallel: true,
25
+ idempotent: true,
24
26
  async execute(_toolCallId, params, _signal) {
25
27
  const uri = typeof params.uri === "string" ? params.uri.trim() : "";
26
28
  if (!uri) return {
@@ -34,7 +36,7 @@ function createReadMediaTool() {
34
36
  }
35
37
  };
36
38
  try {
37
- const { buffer, path } = await readMediaReference(uri, clampMaxBytes(params.maxBytes));
39
+ const { buffer, path } = await readMediaReference(uri, Math.min(clampMaxBytes(params.maxBytes), options?.maxReadBytes ?? HARD_MAX_BYTES));
38
40
  const mimeType = mimeTypeFromMediaPath(path);
39
41
  const metadata = {
40
42
  ok: true,
@@ -43,14 +45,35 @@ function createReadMediaTool() {
43
45
  size: buffer.byteLength,
44
46
  path
45
47
  };
46
- if (isLikelyText(mimeType)) return {
48
+ if (isLikelyText(mimeType)) {
49
+ const fullText = buffer.toString("utf8");
50
+ const maxChars = options?.maxChars ?? fullText.length;
51
+ const truncated = fullText.length > maxChars;
52
+ return {
53
+ content: [{
54
+ type: "text",
55
+ text: fullText.slice(0, maxChars) + (truncated ? "\n[Attachment truncated; delegate full analysis to a specialist.]" : "")
56
+ }],
57
+ details: {
58
+ ...metadata,
59
+ kind: "text",
60
+ truncated,
61
+ ...truncated && options?.textOnly ? {
62
+ requiresSpecialist: true,
63
+ reason: "large_attachment"
64
+ } : {}
65
+ }
66
+ };
67
+ }
68
+ if (options?.textOnly) return {
47
69
  content: [{
48
70
  type: "text",
49
- text: buffer.toString("utf8")
71
+ text: "Binary attachment: delegate document parsing or media analysis to a specialist."
50
72
  }],
51
73
  details: {
52
74
  ...metadata,
53
- kind: "text"
75
+ kind: "binary",
76
+ requiresSpecialist: true
54
77
  }
55
78
  };
56
79
  return {
@@ -68,6 +91,22 @@ function createReadMediaTool() {
68
91
  }
69
92
  };
70
93
  } catch (err) {
94
+ if (options?.textOnly && err?.code === "MEDIA_READ_LIMIT") {
95
+ const size = err.size;
96
+ return {
97
+ content: [{
98
+ type: "text",
99
+ text: `Attachment is large (${size} bytes; local read limit ${options.maxReadBytes ?? HARD_MAX_BYTES} bytes). Tell the user briefly, then delegate reading and processing with this URI: ${uri}`
100
+ }],
101
+ details: {
102
+ ok: true,
103
+ uri,
104
+ size,
105
+ requiresSpecialist: true,
106
+ reason: "large_attachment"
107
+ }
108
+ };
109
+ }
71
110
  const message = err instanceof Error ? err.message : String(err);
72
111
  return {
73
112
  content: [{
@@ -0,0 +1,3 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ import type { XopcUseToolDeps } from './xopc-use-tool.js';
3
+ export declare function createPersonalReadTool(deps: XopcUseToolDeps): AgentTool;
@@ -0,0 +1,155 @@
1
+ import { CapabilityDispatcher } from "../../capabilities/runtime/dispatcher.js";
2
+ import { registerNoteReadCapabilities } from "../../notes/capabilities/read.js";
3
+ import { registerProjectReadCapabilities } from "../../projects/capabilities/read.js";
4
+ import { registerAutomationReadCapabilities } from "../../automations/capabilities/read.js";
5
+ import { Type } from "@sinclair/typebox";
6
+ //#region src/agent/tools/personal-read-tool.ts
7
+ const schema = Type.Object({
8
+ kind: Type.Union([
9
+ Type.Literal("note"),
10
+ Type.Literal("project"),
11
+ Type.Literal("automation")
12
+ ]),
13
+ command: Type.Union([Type.Literal("list"), Type.Literal("get")]),
14
+ id: Type.Optional(Type.String()),
15
+ search: Type.Optional(Type.String({ maxLength: 500 })),
16
+ projectId: Type.Optional(Type.String()),
17
+ offset: Type.Optional(Type.Integer({ minimum: 0 })),
18
+ limit: Type.Optional(Type.Integer({
19
+ minimum: 1,
20
+ maximum: 10
21
+ }))
22
+ });
23
+ const fields = [
24
+ "id",
25
+ "name",
26
+ "title",
27
+ "status",
28
+ "kind",
29
+ "projectId",
30
+ "description",
31
+ "markdown",
32
+ "objective",
33
+ "enabled",
34
+ "createdAt",
35
+ "updatedAt",
36
+ "createdAtMs",
37
+ "updatedAtMs",
38
+ "trigger",
39
+ "action",
40
+ "state"
41
+ ];
42
+ /** Small projections keep local reads from expanding the next model request. */
43
+ function compact(value, textLimit) {
44
+ if (!value || typeof value !== "object") return {};
45
+ const source = value;
46
+ const result = {};
47
+ const truncatedFields = [];
48
+ for (const key of fields) {
49
+ const entry = source[key];
50
+ if (typeof entry === "string") {
51
+ result[key] = entry.slice(0, textLimit);
52
+ if (entry.length > textLimit) truncatedFields.push(key);
53
+ } else if (typeof entry === "number" || typeof entry === "boolean" || entry === null) result[key] = entry;
54
+ else if (entry && typeof entry === "object" && !Array.isArray(entry)) result[key] = Object.fromEntries(Object.entries(entry).slice(0, 12).filter(([, item]) => [
55
+ "string",
56
+ "number",
57
+ "boolean"
58
+ ].includes(typeof item) || item === null).map(([field, item]) => [field, typeof item === "string" ? item.slice(0, 200) : item]));
59
+ }
60
+ if (truncatedFields.length) result.truncatedFields = truncatedFields;
61
+ return result;
62
+ }
63
+ function createPersonalReadTool(deps) {
64
+ const dispatcher = new CapabilityDispatcher();
65
+ if (deps.getNotesService) registerNoteReadCapabilities(dispatcher, () => {
66
+ const notes = deps.getNotesService();
67
+ if (!notes) throw new Error("Notes service unavailable");
68
+ return notes;
69
+ });
70
+ const projects = deps.getProjectService?.();
71
+ if (projects) registerProjectReadCapabilities(dispatcher, projects);
72
+ const automations = deps.getAutomationService?.();
73
+ if (automations) registerAutomationReadCapabilities(dispatcher, automations, projects);
74
+ return {
75
+ name: "personal_read",
76
+ label: "Read local objects",
77
+ description: "Read local notes, projects or automation state. Only list/get; bounded excerpts, no network or model calls. Use personal_task for delegated tasks.",
78
+ parameters: schema,
79
+ supportsParallel: true,
80
+ idempotent: true,
81
+ async execute(_id, raw, signal) {
82
+ const input = raw;
83
+ if (![
84
+ "note",
85
+ "project",
86
+ "automation"
87
+ ].includes(input.kind) || !["list", "get"].includes(input.command)) throw new Error("Only local note/project/automation list/get is supported");
88
+ if (input.command === "get" && !input.id?.trim()) throw new Error("id is required");
89
+ if (input.kind === "automation" && input.search) throw new Error("Automation search is unsupported; use list");
90
+ const operation = `xopc.${input.kind === "note" ? "notes" : input.kind === "project" ? "projects" : "automations"}.${input.command}`;
91
+ const limit = Math.min(10, Math.max(1, input.limit ?? 5));
92
+ const offset = Math.max(0, input.offset ?? 0);
93
+ const args = input.command === "get" ? { id: input.id } : input.kind === "automation" ? { ...input.projectId ? { projectId: input.projectId } : {} } : {
94
+ limit,
95
+ offset,
96
+ ...input.search ? { search: input.search } : {},
97
+ ...input.kind === "note" && input.projectId ? { projectId: input.projectId } : {}
98
+ };
99
+ const result = await dispatcher.call(operation, args, {
100
+ principalId: `agent:${deps.getCurrentAgentId?.() ?? "main"}`,
101
+ surface: "agent",
102
+ scopes: ["workspace.read", "automations.read"],
103
+ allowedCapabilities: [operation],
104
+ authorize: deps.authorizeCapability ?? (() => true),
105
+ signal
106
+ });
107
+ let payload;
108
+ if (input.command === "get") payload = {
109
+ kind: input.kind,
110
+ item: compact(result[input.kind], 6e3),
111
+ excerpts: true
112
+ };
113
+ else {
114
+ const rows = result.items ?? [];
115
+ const selected = input.kind === "automation" ? rows.slice(offset, offset + limit) : rows;
116
+ payload = {
117
+ kind: input.kind,
118
+ items: selected.map((row) => compact(row, 200)),
119
+ offset,
120
+ total: result.total ?? rows.length,
121
+ nextOffset: selected.length === limit ? offset + selected.length : void 0,
122
+ excerpts: true
123
+ };
124
+ }
125
+ const serialized = JSON.stringify(payload);
126
+ const requiresSpecialist = input.command === "get" && (serialized.length > 12e3 || Boolean(payload.item?.truncatedFields));
127
+ if (requiresSpecialist) payload = {
128
+ ...payload,
129
+ requiresSpecialist: true,
130
+ reason: "large_object",
131
+ id: input.id,
132
+ guidance: "Briefly tell the user the material is large, then delegate full reading and processing using this object kind and ID."
133
+ };
134
+ const output = JSON.stringify(payload);
135
+ return {
136
+ content: [{
137
+ type: "text",
138
+ text: output.length <= 12e3 ? output : JSON.stringify({
139
+ kind: input.kind,
140
+ excerpt: output.slice(0, 1e4),
141
+ truncated: true,
142
+ requiresSpecialist: true,
143
+ id: input.id
144
+ })
145
+ }],
146
+ details: {
147
+ localOnly: true,
148
+ requiresSpecialist: requiresSpecialist || output.length > 12e3
149
+ }
150
+ };
151
+ }
152
+ };
153
+ }
154
+ //#endregion
155
+ export { createPersonalReadTool };
@@ -3,9 +3,9 @@ import { init_agent_config } from "../../agent-config/index.js";
3
3
  import { AgentCatalogRepository, init_repository } from "../../agent-catalog/repository.js";
4
4
  import { resolveEffectiveAgentConfigForAgent } from "../../config/agent-profile.js";
5
5
  import { init_providers, isProviderConfiguredSync, resolveModel } from "../../providers/index.js";
6
+ import { isPersonalConversation } from "../../personal-agent/repository.js";
6
7
  import { TaskOriginRepository } from "../../tasks/task-origin-repository.js";
7
8
  import { createXopcUseTool } from "./xopc-use-tool.js";
8
- import { isPersonalConversation } from "../../personal-agent/repository.js";
9
9
  import { PERSONAL_WORKER_RESULT_GUIDANCE } from "../../personal-agent/communication.js";
10
10
  import { randomUUID } from "node:crypto";
11
11
  import { Type } from "@sinclair/typebox";
@@ -2,5 +2,8 @@ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
2
  export interface CreateReadFileToolOptions {
3
3
  /** When set and the path is a bare profile filename (e.g. SOUL.md), try this root if not in workspace. */
4
4
  profileMarkdownRoot?: string;
5
+ defaultMaxLines?: number;
6
+ maxOutputBytes?: number;
7
+ maxReadBytes?: number;
5
8
  }
6
9
  export declare function createReadFileTool(workspace: string, options?: CreateReadFileToolOptions): AgentTool;
@@ -1,7 +1,7 @@
1
1
  import { checkedFilePath, readWorkspaceFileAsync } from "../sandbox/fileAccess.js";
2
2
  import { dataScheduler } from "../data-acquisition/scheduler.js";
3
3
  import { checkFileSafety } from "../prompt/safety.js";
4
- import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
4
+ import { formatSize, truncateHead } from "./truncate.js";
5
5
  import { isBareProfileMarkdownFileName, resolvePathUnderWorkspace, resolveProfileMarkdownPathIfBareName } from "./tool-paths.js";
6
6
  import { stat } from "fs/promises";
7
7
  import { Type } from "@sinclair/typebox";
@@ -29,11 +29,13 @@ function createReadFileTool(workspace, options) {
29
29
  supportsParallel: true,
30
30
  idempotent: true,
31
31
  async execute(_toolCallId, params, signal) {
32
- return dataScheduler.run(workspace, signal, () => executeReadFile(workspace, options?.profileMarkdownRoot, params, signal));
32
+ return dataScheduler.run(workspace, signal, () => executeReadFile(workspace, options, params, signal));
33
33
  }
34
34
  };
35
35
  }
36
- async function executeReadFile(workspace, profileMarkdownRoot, params, signal) {
36
+ async function executeReadFile(workspace, options, params, signal) {
37
+ const profileMarkdownRoot = options?.profileMarkdownRoot;
38
+ const maxOutputBytes = options?.maxOutputBytes ?? 51200;
37
39
  try {
38
40
  const safety = checkFileSafety("read", params.path);
39
41
  if (!safety.allowed) return {
@@ -60,6 +62,18 @@ async function executeReadFile(workspace, profileMarkdownRoot, params, signal) {
60
62
  }
61
63
  } else throw e;
62
64
  }
65
+ if (options?.maxReadBytes && stats.size > options.maxReadBytes) return {
66
+ content: [{
67
+ type: "text",
68
+ text: `File is large (${formatSize(stats.size)}; local read limit ${formatSize(options.maxReadBytes)}). Tell the user briefly, then delegate reading and processing. Path: ${normalized}`
69
+ }],
70
+ details: {
71
+ path: normalized,
72
+ size: stats.size,
73
+ requiresSpecialist: true,
74
+ reason: "large_file"
75
+ }
76
+ };
63
77
  if (stats.size > MAX_FILE_SIZE) return {
64
78
  content: [{
65
79
  type: "text",
@@ -72,12 +86,12 @@ async function executeReadFile(workspace, profileMarkdownRoot, params, signal) {
72
86
  const lines = content.split("\n");
73
87
  if (offset > lines.length) throw new Error(`Offset ${offset} exceeds ${lines.length} lines`);
74
88
  const truncation = truncateHead(lines.slice(offset - 1).join("\n"), {
75
- maxLines: params.limit || DEFAULT_MAX_LINES,
76
- maxBytes: DEFAULT_MAX_BYTES
89
+ maxLines: params.limit || options?.defaultMaxLines || DEFAULT_MAX_LINES,
90
+ maxBytes: maxOutputBytes
77
91
  });
78
92
  let outputText = truncation.content;
79
- if (truncation.truncated) if (truncation.firstLineExceedsLimit) outputText = `(Line exceeds ${formatSize(DEFAULT_MAX_BYTES)})`;
80
- else outputText += `\n\n[Lines ${offset}-${offset + truncation.outputLines - 1} of ${lines.length}; continue with offset=${offset + truncation.outputLines}]`;
93
+ if (truncation.truncated) if (truncation.firstLineExceedsLimit) outputText = `(Line exceeds ${formatSize(maxOutputBytes)})`;
94
+ else outputText += options?.maxReadBytes ? `\n\n[File excerpt only. Tell the user briefly and delegate full reading and processing. Path: ${normalized}]` : `\n\n[Lines ${offset}-${offset + truncation.outputLines - 1} of ${lines.length}; continue with offset=${offset + truncation.outputLines}]`;
81
95
  return {
82
96
  content: [{
83
97
  type: "text",
@@ -87,7 +101,11 @@ async function executeReadFile(workspace, profileMarkdownRoot, params, signal) {
87
101
  path: normalized,
88
102
  offset,
89
103
  totalLines: lines.length,
90
- truncated: truncation.truncated
104
+ truncated: truncation.truncated,
105
+ ...options?.maxReadBytes && truncation.truncated ? {
106
+ requiresSpecialist: true,
107
+ reason: "large_file"
108
+ } : {}
91
109
  }
92
110
  };
93
111
  } catch (error) {