@xopcai/xopc 0.0.123 → 0.0.125

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 (436) hide show
  1. package/README.md +28 -11
  2. package/README.zh-CN.md +28 -11
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +41 -0
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Bicr3ZBg.js → agent-avatar-dicebear-BKDKICZV.js} +1 -1
  7. package/dist/gateway/static/root/assets/agents-BnTB7-c5.js +2 -0
  8. package/dist/gateway/static/root/assets/app-management-settings-panel-DI4BqHKW.js +1 -0
  9. package/dist/gateway/static/root/assets/appearance-settings-6_ie3NQ4.js +1 -0
  10. package/dist/gateway/static/root/assets/apps-page-B6bG65SW.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-Bpy64GjU.js → archive-plugin-kUHEJ1HK.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-DMkp4xSb.js → attachment-load-Dm-9prpU.js} +1 -1
  13. package/dist/gateway/static/root/assets/automation-suggestion-card-OTxQTPnC.js +1 -0
  14. package/dist/gateway/static/root/assets/automations-page-1lVbo0dS.js +1 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-DA9C5mCw.js → binary-plugins-DllA_jQ0.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-CiSXk_YC.js → block-editor-Cm6CWNj1.js} +5 -5
  17. package/dist/gateway/static/root/assets/browser-settings-page-CzDBlOK0.js +8 -0
  18. package/dist/gateway/static/root/assets/capability-presets-api-VJ89b6I2.js +1 -0
  19. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BaPj8wC2.js +1 -0
  20. package/dist/gateway/static/root/assets/{channel-recipient-api-CDhrhfhN.js → channel-recipient-api-B5PwBEUx.js} +1 -1
  21. package/dist/gateway/static/root/assets/channels-settings-Df4m7p1k.js +1 -0
  22. package/dist/gateway/static/root/assets/code-editor-gbRgS14t.js +1 -0
  23. package/dist/gateway/static/root/assets/connectors-page-BMTphmHS.js +2 -0
  24. package/dist/gateway/static/root/assets/{directory-picker-path-field-7jKfbH0J.js → directory-picker-path-field-DySMzOF6.js} +1 -1
  25. package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +1 -0
  26. package/dist/gateway/static/root/assets/dist-CkobR7mk.js +1 -0
  27. package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +1 -0
  28. package/dist/gateway/static/root/assets/dreaming-settings-D_AjSnV_.js +3 -0
  29. package/dist/gateway/static/root/assets/extension-debug-page-BaM0FpW7.js +1 -0
  30. package/dist/gateway/static/root/assets/extension-page-DuZWVOGA.js +1 -0
  31. package/dist/gateway/static/root/assets/extension-settings-page-DarVtbmJ.js +1 -0
  32. package/dist/gateway/static/root/assets/{fetch-Dtpbbe0s.js → fetch-NFKfkqrd.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-BN6pyX2c.js → gateway-config-api-CFEm9rgy.js} +1 -1
  34. package/dist/gateway/static/root/assets/gateway-settings-BMk2S5td.js +1 -0
  35. package/dist/gateway/static/root/assets/{gateway-startup-retry-BIET2x3y.js → gateway-startup-retry-Dtwh_yGg.js} +1 -1
  36. package/dist/gateway/static/root/assets/goal-create-dialog-BKP7ylcG.js +1 -0
  37. package/dist/gateway/static/root/assets/goal-detail-page-C2cTxf71.js +1 -0
  38. package/dist/gateway/static/root/assets/{goals-config-api-CQm2r1Ty.js → goals-config-api-DTWZNA_Y.js} +1 -1
  39. package/dist/gateway/static/root/assets/goals-page-CTmA3hWK.js +2 -0
  40. package/dist/gateway/static/root/assets/goals-settings-Bhct0ZT-.js +1 -0
  41. package/dist/gateway/static/root/assets/heartbeat-settings-C-UxSU4a.js +1 -0
  42. package/dist/gateway/static/root/assets/{html-workspace-editor-CQLWDiwE.js → html-workspace-editor-DV90ddkE.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-BNHDd2j1.css +1 -0
  44. package/dist/gateway/static/root/assets/index-BPXLPMuY.js +193 -0
  45. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-DCjy2y4d.js +1 -0
  46. package/dist/gateway/static/root/assets/logs-page-CGc3_CQU.js +2 -0
  47. package/dist/gateway/static/root/assets/{markdown-editor-AssmZFx4.js → markdown-editor-BFOjBBla.js} +2 -2
  48. package/dist/gateway/static/root/assets/markdown-split-BaqxP-GQ.js +1 -0
  49. package/dist/gateway/static/root/assets/{media-plugins-DS44pJzr.js → media-plugins-DQ_EXloK.js} +1 -1
  50. package/dist/gateway/static/root/assets/messages-CjuIJcZl.js +3 -0
  51. package/dist/gateway/static/root/assets/models-hub-panel-Drz4UQMb.js +2 -0
  52. package/dist/gateway/static/root/assets/notes-page-CY1ylng1.js +1 -0
  53. package/dist/gateway/static/root/assets/notes-workbench-X7IaD--t.js +2 -0
  54. package/dist/gateway/static/root/assets/page-tabs-EIZhLppK.js +1 -0
  55. package/dist/gateway/static/root/assets/{preview-open-alternatives-Dej6zHnr.js → preview-open-alternatives-r_uB4Epr.js} +1 -1
  56. package/dist/gateway/static/root/assets/project-detail-page-DE5adRBE.js +1 -0
  57. package/dist/gateway/static/root/assets/projects-page-CuOb1k6F.js +1 -0
  58. package/dist/gateway/static/root/assets/remote-access-hub-BOxNrUVA.js +1 -0
  59. package/dist/gateway/static/root/assets/{save-bar-controls-Zu1FzH6z.js → save-bar-controls-B132Uf-2.js} +1 -1
  60. package/dist/gateway/static/root/assets/{schedule-field-BW78mKc0.js → schedule-field-B5qshALm.js} +1 -1
  61. package/dist/gateway/static/root/assets/{schema-form-Cc-IOydE.js → schema-form-CvLmkdS9.js} +1 -1
  62. package/dist/gateway/static/root/assets/sessions-page-CY0IQcGW.js +1 -0
  63. package/dist/gateway/static/root/assets/settings-advanced-gate-D4NBNVCB.js +1 -0
  64. package/dist/gateway/static/root/assets/{settings-collapsible-section-DIpIYht_.js → settings-collapsible-section-pRlvqsAf.js} +1 -1
  65. package/dist/gateway/static/root/assets/{settings-form-section-BFxBNxOG.js → settings-form-section-BBYUDLVd.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-page-C4fivemT.js → settings-page-DaO7zYZM.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-page-layout-CLx4o2PN.js → settings-page-layout-D8g9PAek.js} +1 -1
  68. package/dist/gateway/static/root/assets/setup-status-panel-Bks0CLLT.js +1 -0
  69. package/dist/gateway/static/root/assets/{share-preview-page-ZswWCrDu.js → share-preview-page-v6-IOp8t.js} +1 -1
  70. package/dist/gateway/static/root/assets/shares-settings-CEZsKm9r.js +1 -0
  71. package/dist/gateway/static/root/assets/skill-reload-api-oTkHbb9W.js +1 -0
  72. package/dist/gateway/static/root/assets/skills-page-DigsbZ6K.js +2 -0
  73. package/dist/gateway/static/root/assets/{system-settings-panel-3ZNcGRhS.js → system-settings-panel-HUU2FFjM.js} +1 -1
  74. package/dist/gateway/static/root/assets/{typed-models-lib-bpzZjiVF.js → typed-models-lib-AH160QHh.js} +1 -1
  75. package/dist/gateway/static/root/assets/{use-channel-catalog-BCjZLZ3O.js → use-channel-catalog-BXzDmjCQ.js} +1 -1
  76. package/dist/gateway/static/root/assets/{user-profile-settings-panel-CIXafITi.js → user-profile-settings-panel-DxwnQvQ3.js} +1 -1
  77. package/dist/gateway/static/root/assets/{utils-DXMtz5j_.js → utils-i5POEtqd.js} +1 -1
  78. package/dist/gateway/static/root/assets/{vendor-codemirror-CNP1wPe7.js → vendor-codemirror-BvNgyE1Q.js} +1 -1
  79. package/dist/gateway/static/root/assets/voice-api-key-field-CEJklEgb.js +1 -0
  80. package/dist/gateway/static/root/assets/work-item-detail-page-CD6FL_Rs.js +1 -0
  81. package/dist/gateway/static/root/assets/workflow-run-setup-panel-ClVVMgN-.js +3 -0
  82. package/dist/gateway/static/root/assets/{workflow-start-dialog-B4sZpTDQ.js → workflow-start-dialog-Dv4ZA1T0.js} +1 -1
  83. package/dist/gateway/static/root/assets/workflows-page-OLQiUpoW.js +18 -0
  84. package/dist/gateway/static/root/index.html +8 -7
  85. package/dist/package.js +1 -1
  86. package/dist/src/agent/agent-manager.d.ts +6 -1
  87. package/dist/src/agent/agent-manager.js +34 -14
  88. package/dist/src/agent/agent-manager.js.map +1 -1
  89. package/dist/src/agent/child-agent-factory.d.ts +2 -0
  90. package/dist/src/agent/child-agent-factory.js +2 -0
  91. package/dist/src/agent/child-agent-factory.js.map +1 -1
  92. package/dist/src/agent/coding/index.d.ts +1 -0
  93. package/dist/src/agent/coding/index.js +2 -0
  94. package/dist/src/agent/coding/turn-diff-tracker.d.ts +67 -0
  95. package/dist/src/agent/coding/turn-diff-tracker.js +233 -0
  96. package/dist/src/agent/coding/turn-diff-tracker.js.map +1 -0
  97. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  98. package/dist/src/agent/embedded/xopc-tools-bridge.js +11 -7
  99. package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
  100. package/dist/src/agent/lifecycle/progress.js +3 -1
  101. package/dist/src/agent/lifecycle/progress.js.map +1 -1
  102. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +2 -2
  103. package/dist/src/agent/lifecycle/timeout-wrapper.js +4 -4
  104. package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
  105. package/dist/src/agent/memory/dreaming/config.d.ts +2 -2
  106. package/dist/src/agent/memory/dreaming/config.js +3 -3
  107. package/dist/src/agent/memory/dreaming/config.js.map +1 -1
  108. package/dist/src/agent/memory/dreaming/constants.d.ts +1 -1
  109. package/dist/src/agent/memory/dreaming/constants.js +1 -1
  110. package/dist/src/agent/memory/dreaming/constants.js.map +1 -1
  111. package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +1 -0
  112. package/dist/src/agent/memory/dreaming/deep-promotion.js +11 -20
  113. package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
  114. package/dist/src/agent/memory/dreaming/events.d.ts +3 -3
  115. package/dist/src/agent/memory/dreaming/events.js +6 -6
  116. package/dist/src/agent/memory/dreaming/events.js.map +1 -1
  117. package/dist/src/agent/memory/dreaming/last-run.d.ts +2 -2
  118. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  119. package/dist/src/agent/memory/dreaming/last-run.js.map +1 -1
  120. package/dist/src/agent/memory/dreaming/light-sweep.d.ts +1 -1
  121. package/dist/src/agent/memory/dreaming/light-sweep.js +3 -3
  122. package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
  123. package/dist/src/agent/memory/dreaming/preview.d.ts +1 -0
  124. package/dist/src/agent/memory/dreaming/preview.js +2 -2
  125. package/dist/src/agent/memory/dreaming/preview.js.map +1 -1
  126. package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +1 -1
  127. package/dist/src/agent/memory/dreaming/rem-patterns.js +13 -13
  128. package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
  129. package/dist/src/agent/memory/dreaming/scope.d.ts +14 -0
  130. package/dist/src/agent/memory/dreaming/scope.js +27 -0
  131. package/dist/src/agent/memory/dreaming/scope.js.map +1 -0
  132. package/dist/src/agent/memory/dreaming/short-term-store.d.ts +4 -4
  133. package/dist/src/agent/memory/dreaming/short-term-store.js +17 -17
  134. package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
  135. package/dist/src/agent/memory/summary-generator.d.ts +1 -1
  136. package/dist/src/agent/memory/summary-generator.js +1 -2
  137. package/dist/src/agent/memory/summary-generator.js.map +1 -1
  138. package/dist/src/agent/middleware/index.d.ts +1 -1
  139. package/dist/src/agent/middleware/self-verify.d.ts +44 -14
  140. package/dist/src/agent/middleware/self-verify.js +214 -44
  141. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  142. package/dist/src/agent/orchestration/agent-event-handler.d.ts +2 -0
  143. package/dist/src/agent/orchestration/agent-event-handler.js +69 -14
  144. package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
  145. package/dist/src/agent/orchestration/agent-orchestrator.js +22 -12
  146. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  147. package/dist/src/agent/prompt/sections/tooling.js +18 -13
  148. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  149. package/dist/src/agent/prompt/system-reminder.js +2 -2
  150. package/dist/src/agent/prompt/system-reminder.js.map +1 -1
  151. package/dist/src/agent/sandbox/command-validator.js +12 -0
  152. package/dist/src/agent/sandbox/command-validator.js.map +1 -1
  153. package/dist/src/agent/sandbox/sanitize-env-vars.d.ts +2 -2
  154. package/dist/src/agent/sandbox/sanitize-env-vars.js +2 -2
  155. package/dist/src/agent/sandbox/sanitize-env-vars.js.map +1 -1
  156. package/dist/src/agent/sandbox/types.d.ts +2 -2
  157. package/dist/src/agent/sandbox/types.js.map +1 -1
  158. package/dist/src/agent/service/btw-query.js +1 -1
  159. package/dist/src/agent/service/btw-query.js.map +1 -1
  160. package/dist/src/agent/service/process-direct-one-shot.js +6 -2
  161. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  162. package/dist/src/agent/service/process-direct-streaming.js +12 -7
  163. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  164. package/dist/src/agent/service.d.ts +2 -1
  165. package/dist/src/agent/service.js +19 -6
  166. package/dist/src/agent/service.js.map +1 -1
  167. package/dist/src/agent/session/session-inspector.d.ts +5 -3
  168. package/dist/src/agent/session/session-inspector.js +16 -7
  169. package/dist/src/agent/session/session-inspector.js.map +1 -1
  170. package/dist/src/agent/skills/skill-tool-gating.js +1 -1
  171. package/dist/src/agent/skills/skill-tool-gating.js.map +1 -1
  172. package/dist/src/agent/source-context/types.d.ts +1 -1
  173. package/dist/src/agent/source-context/types.js +1 -1
  174. package/dist/src/agent/source-context/types.js.map +1 -1
  175. package/dist/src/agent/starter-agents.js +9 -9
  176. package/dist/src/agent/starter-agents.js.map +1 -1
  177. package/dist/src/agent/tools/apply-patch.d.ts +25 -0
  178. package/dist/src/agent/tools/apply-patch.js +310 -0
  179. package/dist/src/agent/tools/apply-patch.js.map +1 -0
  180. package/dist/src/agent/tools/concurrency.d.ts +8 -0
  181. package/dist/src/agent/tools/concurrency.js +31 -0
  182. package/dist/src/agent/tools/concurrency.js.map +1 -0
  183. package/dist/src/agent/tools/delegate-tool.d.ts +1 -1
  184. package/dist/src/agent/tools/delegate-tool.js +3 -3
  185. package/dist/src/agent/tools/delegate-tool.js.map +1 -1
  186. package/dist/src/agent/tools/dreaming-tool.d.ts +2 -0
  187. package/dist/src/agent/tools/dreaming-tool.js +13 -10
  188. package/dist/src/agent/tools/dreaming-tool.js.map +1 -1
  189. package/dist/src/agent/tools/exec-command.d.ts +30 -0
  190. package/dist/src/agent/tools/exec-command.js +228 -0
  191. package/dist/src/agent/tools/exec-command.js.map +1 -0
  192. package/dist/src/agent/tools/execute-code-tool.js +7 -4
  193. package/dist/src/agent/tools/execute-code-tool.js.map +1 -1
  194. package/dist/src/agent/tools/executor.d.ts +6 -4
  195. package/dist/src/agent/tools/executor.js +7 -4
  196. package/dist/src/agent/tools/executor.js.map +1 -1
  197. package/dist/src/agent/tools/factory.d.ts +6 -3
  198. package/dist/src/agent/tools/factory.js +14 -9
  199. package/dist/src/agent/tools/factory.js.map +1 -1
  200. package/dist/src/agent/tools/find.js +2 -0
  201. package/dist/src/agent/tools/find.js.map +1 -1
  202. package/dist/src/agent/tools/grep.js +2 -0
  203. package/dist/src/agent/tools/grep.js.map +1 -1
  204. package/dist/src/agent/tools/index.d.ts +5 -2
  205. package/dist/src/agent/tools/index.js +7 -4
  206. package/dist/src/agent/tools/list-dir.js +2 -0
  207. package/dist/src/agent/tools/list-dir.js.map +1 -1
  208. package/dist/src/agent/tools/memory-tool.d.ts +1 -0
  209. package/dist/src/agent/tools/memory-tool.js +2 -2
  210. package/dist/src/agent/tools/memory-tool.js.map +1 -1
  211. package/dist/src/agent/tools/metadata.d.ts +15 -0
  212. package/dist/src/agent/tools/metadata.js +26 -0
  213. package/dist/src/agent/tools/metadata.js.map +1 -0
  214. package/dist/src/agent/tools/read.js +2 -0
  215. package/dist/src/agent/tools/read.js.map +1 -1
  216. package/dist/src/agent/tools/skills-tools.d.ts +1 -1
  217. package/dist/src/agent/tools/skills-tools.js.map +1 -1
  218. package/dist/src/agent/tools/update-plan-tool.d.ts +11 -0
  219. package/dist/src/agent/tools/update-plan-tool.js +72 -0
  220. package/dist/src/agent/tools/update-plan-tool.js.map +1 -0
  221. package/dist/src/agent/tools/write.js +6 -0
  222. package/dist/src/agent/tools/write.js.map +1 -1
  223. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
  224. package/dist/src/agent/workflow/builtins/debug-incident.js +1 -1
  225. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
  226. package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
  227. package/dist/src/agent/workflow/builtins/pr-review.js +1 -1
  228. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
  229. package/dist/src/agent/workflow/builtins/release-check.d.ts +1 -1
  230. package/dist/src/agent/workflow/builtins/release-check.js +1 -1
  231. package/dist/src/agent/workflow/builtins/release-check.js.map +1 -1
  232. package/dist/src/agent/workflow/step-labels.js +7 -3
  233. package/dist/src/agent/workflow/step-labels.js.map +1 -1
  234. package/dist/src/agent/workflow/subagent-runner.d.ts +1 -0
  235. package/dist/src/agent/workflow/subagent-runner.js +5 -1
  236. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  237. package/dist/src/agent/workflow/workflow-child-tools.js +5 -0
  238. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -1
  239. package/dist/src/chat-commands/agent-edit.js +1 -1
  240. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  241. package/dist/src/chat-commands/builtins/review.d.ts +1 -0
  242. package/dist/src/chat-commands/builtins/review.js +167 -0
  243. package/dist/src/chat-commands/builtins/review.js.map +1 -0
  244. package/dist/src/chat-commands/index.d.ts +1 -0
  245. package/dist/src/chat-commands/index.js +3 -1
  246. package/dist/src/chat-commands/index.js.map +1 -1
  247. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  248. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  249. package/dist/src/connectors/health.d.ts +2 -1
  250. package/dist/src/connectors/health.js +59 -1
  251. package/dist/src/connectors/health.js.map +1 -1
  252. package/dist/src/connectors/install.d.ts +1 -0
  253. package/dist/src/connectors/install.js +28 -1
  254. package/dist/src/connectors/install.js.map +1 -1
  255. package/dist/src/connectors/instances.js +7 -0
  256. package/dist/src/connectors/instances.js.map +1 -1
  257. package/dist/src/connectors/materialize.js +2 -1
  258. package/dist/src/connectors/materialize.js.map +1 -1
  259. package/dist/src/connectors/registries/modelscope.js +38 -13
  260. package/dist/src/connectors/registries/modelscope.js.map +1 -1
  261. package/dist/src/connectors/types.d.ts +2 -0
  262. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  263. package/dist/src/gateway/agent-builtin-tools.js +3 -2
  264. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  265. package/dist/src/gateway/chat-stream/mapper.d.ts +6 -0
  266. package/dist/src/gateway/chat-stream/mapper.js +149 -6
  267. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  268. package/dist/src/gateway/chat-stream/protocol.d.ts +51 -1
  269. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +1 -0
  270. package/dist/src/gateway/dreaming-automation-reconciler.js +62 -42
  271. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -1
  272. package/dist/src/gateway/hono/app.js +7 -1
  273. package/dist/src/gateway/hono/app.js.map +1 -1
  274. package/dist/src/gateway/hono/routes/commands-skills.js +21 -0
  275. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  276. package/dist/src/gateway/hono/routes/connectors.js +46 -2
  277. package/dist/src/gateway/hono/routes/connectors.js.map +1 -1
  278. package/dist/src/gateway/hono/routes/dreaming.js +111 -66
  279. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  280. package/dist/src/gateway/hono/routes/index.js +2 -0
  281. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  282. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
  283. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  284. package/dist/src/gateway/hono/routes/projects.js +886 -45
  285. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  286. package/dist/src/gateway/hono/routes/search.d.ts +3 -0
  287. package/dist/src/gateway/hono/routes/search.js +47 -0
  288. package/dist/src/gateway/hono/routes/search.js.map +1 -0
  289. package/dist/src/gateway/hono/routes/sessions.js +1 -0
  290. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  291. package/dist/src/gateway/security/dangerous-tools.js +1 -1
  292. package/dist/src/gateway/security/dangerous-tools.js.map +1 -1
  293. package/dist/src/gateway/service.js +17 -8
  294. package/dist/src/gateway/service.js.map +1 -1
  295. package/dist/src/infra/update-restart.js +1 -1
  296. package/dist/src/mcp/channel-bridge.js +1 -1
  297. package/dist/src/media/store.js +1 -1
  298. package/dist/src/media/store.js.map +1 -1
  299. package/dist/src/media/types.d.ts +1 -1
  300. package/dist/src/media/uri.js +2 -1
  301. package/dist/src/media/uri.js.map +1 -1
  302. package/dist/src/projects/index.d.ts +2 -0
  303. package/dist/src/projects/index.js +3 -1
  304. package/dist/src/projects/project-agent-suggestion.d.ts +14 -0
  305. package/dist/src/projects/project-agent-suggestion.js +19 -0
  306. package/dist/src/projects/project-agent-suggestion.js.map +1 -0
  307. package/dist/src/projects/project-kind.d.ts +13 -0
  308. package/dist/src/projects/project-kind.js +147 -0
  309. package/dist/src/projects/project-kind.js.map +1 -0
  310. package/dist/src/projects/project-service.d.ts +1 -0
  311. package/dist/src/projects/project-service.js +1 -1
  312. package/dist/src/projects/project-service.js.map +1 -1
  313. package/dist/src/projects/project-store.js +32 -8
  314. package/dist/src/projects/project-store.js.map +1 -1
  315. package/dist/src/projects/types.d.ts +1 -0
  316. package/dist/src/review/review-git.d.ts +48 -0
  317. package/dist/src/review/review-git.js +333 -0
  318. package/dist/src/review/review-git.js.map +1 -0
  319. package/dist/src/review/review-types.d.ts +22 -0
  320. package/dist/src/review/review-types.js +29 -0
  321. package/dist/src/review/review-types.js.map +1 -0
  322. package/dist/src/session/session-context-for-llm.d.ts +2 -0
  323. package/dist/src/session/session-context-for-llm.js +165 -1
  324. package/dist/src/session/session-context-for-llm.js.map +1 -1
  325. package/dist/src/session/store.js +2 -2
  326. package/dist/src/session/store.js.map +1 -1
  327. package/dist/src/storage/sqlite/migrations/021_projects_fts.sql +21 -0
  328. package/dist/src/storage/sqlite/migrations/022_work_items.sql +61 -0
  329. package/dist/src/storage/sqlite/migrations/023_work_item_attachments.sql +15 -0
  330. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  331. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  332. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  333. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  334. package/dist/src/storage/sqlite/schema.js +1 -1
  335. package/dist/src/storage/sqlite/schema.sql +78 -0
  336. package/dist/src/tui/backends/embedded-backend.d.ts +1 -0
  337. package/dist/src/tui/backends/embedded-backend.js +20 -0
  338. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  339. package/dist/src/tui/backends/gateway-sse-backend.d.ts +2 -0
  340. package/dist/src/tui/backends/gateway-sse-backend.js +7 -0
  341. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  342. package/dist/src/tui/components/assistant-message.js +47 -2
  343. package/dist/src/tui/components/assistant-message.js.map +1 -1
  344. package/dist/src/tui/components/tool-execution.d.ts +8 -0
  345. package/dist/src/tui/components/tool-execution.js +87 -77
  346. package/dist/src/tui/components/tool-execution.js.map +1 -1
  347. package/dist/src/tui/components/visual-truncate.d.ts +1 -0
  348. package/dist/src/tui/components/visual-truncate.js +28 -1
  349. package/dist/src/tui/components/visual-truncate.js.map +1 -1
  350. package/dist/src/tui/tool-summary.d.ts +22 -0
  351. package/dist/src/tui/tool-summary.js +212 -0
  352. package/dist/src/tui/tool-summary.js.map +1 -0
  353. package/dist/src/tui/tui-agent-events.js +25 -0
  354. package/dist/src/tui/tui-agent-events.js.map +1 -1
  355. package/dist/src/tui/tui-backend.d.ts +4 -0
  356. package/dist/src/tui/tui-commands.d.ts +1 -0
  357. package/dist/src/tui/tui-commands.js +110 -4
  358. package/dist/src/tui/tui-commands.js.map +1 -1
  359. package/dist/src/tui/tui-picker-overlay.d.ts +2 -0
  360. package/dist/src/tui/tui-picker-overlay.js +153 -1
  361. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  362. package/dist/src/tui/tui-tool-diff.d.ts +15 -0
  363. package/dist/src/tui/tui-tool-diff.js +178 -7
  364. package/dist/src/tui/tui-tool-diff.js.map +1 -1
  365. package/dist/src/tui/tui.js +16 -3
  366. package/dist/src/tui/tui.js.map +1 -1
  367. package/dist/src/work-items/agent-context.d.ts +3 -0
  368. package/dist/src/work-items/agent-context.js +39 -0
  369. package/dist/src/work-items/agent-context.js.map +1 -0
  370. package/dist/src/work-items/index.d.ts +4 -0
  371. package/dist/src/work-items/index.js +4 -0
  372. package/dist/src/work-items/types.d.ts +112 -0
  373. package/dist/src/work-items/types.js +1 -0
  374. package/dist/src/work-items/work-item-service.d.ts +33 -0
  375. package/dist/src/work-items/work-item-service.js +180 -0
  376. package/dist/src/work-items/work-item-service.js.map +1 -0
  377. package/dist/src/work-items/work-item-store.d.ts +21 -0
  378. package/dist/src/work-items/work-item-store.js +302 -0
  379. package/dist/src/work-items/work-item-store.js.map +1 -0
  380. package/dist/src/workflows/service/workflow-run-service.js +4 -3
  381. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  382. package/dist/src/workflows/service/workflow-session-bridge.js +3 -0
  383. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  384. package/package.json +1 -1
  385. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +0 -41
  386. package/dist/gateway/static/root/assets/agents-CxDSFHGx.js +0 -2
  387. package/dist/gateway/static/root/assets/app-management-settings-panel-CbEy9sR1.js +0 -1
  388. package/dist/gateway/static/root/assets/appearance-settings-CTHja6n9.js +0 -1
  389. package/dist/gateway/static/root/assets/apps-page-CyZdgqvm.js +0 -1
  390. package/dist/gateway/static/root/assets/automation-suggestion-card-KnYaP7NT.js +0 -1
  391. package/dist/gateway/static/root/assets/automations-page-8VLKM4au.js +0 -1
  392. package/dist/gateway/static/root/assets/browser-settings-page-5tPg0DcP.js +0 -8
  393. package/dist/gateway/static/root/assets/capability-presets-api-CEJ44WCU.js +0 -1
  394. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BJW3aVST.js +0 -1
  395. package/dist/gateway/static/root/assets/channels-settings-CorUCTrs.js +0 -1
  396. package/dist/gateway/static/root/assets/code-editor-dZTY2dRW.js +0 -1
  397. package/dist/gateway/static/root/assets/connectors-page-VKstC3sP.js +0 -2
  398. package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +0 -1
  399. package/dist/gateway/static/root/assets/dist-wO9a2_ID.js +0 -1
  400. package/dist/gateway/static/root/assets/dreaming-settings-m1-wmz4o.js +0 -1
  401. package/dist/gateway/static/root/assets/extension-debug-page-C9qQQrBS.js +0 -1
  402. package/dist/gateway/static/root/assets/extension-page-DcBBMEGl.js +0 -1
  403. package/dist/gateway/static/root/assets/extension-settings-page-BQ-jMMP9.js +0 -1
  404. package/dist/gateway/static/root/assets/gateway-settings-hQtgVmSR.js +0 -1
  405. package/dist/gateway/static/root/assets/goal-create-dialog-BuIMDx6C.js +0 -1
  406. package/dist/gateway/static/root/assets/goal-detail-page-FEypCq74.js +0 -1
  407. package/dist/gateway/static/root/assets/goals-page-C4-2_MLG.js +0 -2
  408. package/dist/gateway/static/root/assets/goals-settings-DDrdRMxB.js +0 -1
  409. package/dist/gateway/static/root/assets/heartbeat-settings-BJVok3Sl.js +0 -1
  410. package/dist/gateway/static/root/assets/index-CBDr5xjB.css +0 -1
  411. package/dist/gateway/static/root/assets/index-T0SaNd5a.js +0 -191
  412. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-C2TuQppb.js +0 -1
  413. package/dist/gateway/static/root/assets/logs-page-DwkwPgid.js +0 -2
  414. package/dist/gateway/static/root/assets/markdown-split-DhONQ81k.js +0 -1
  415. package/dist/gateway/static/root/assets/messages-avfvyZuQ.js +0 -3
  416. package/dist/gateway/static/root/assets/models-hub-panel-huNY4A1G.js +0 -2
  417. package/dist/gateway/static/root/assets/notes-page-DdfGuEZ1.js +0 -1
  418. package/dist/gateway/static/root/assets/notes-workbench-B0bT9Hqa.js +0 -2
  419. package/dist/gateway/static/root/assets/project-detail-page-CjxhPorG.js +0 -1
  420. package/dist/gateway/static/root/assets/projects-page-C4Z5OJMF.js +0 -1
  421. package/dist/gateway/static/root/assets/remote-access-hub-CVCOPUVd.js +0 -1
  422. package/dist/gateway/static/root/assets/sessions-page-B4qExXHC.js +0 -1
  423. package/dist/gateway/static/root/assets/settings-advanced-gate-Ce8yLTBi.js +0 -1
  424. package/dist/gateway/static/root/assets/setup-status-panel-Kyc4eUf0.js +0 -1
  425. package/dist/gateway/static/root/assets/shares-settings-Bu76CMiC.js +0 -1
  426. package/dist/gateway/static/root/assets/skill-reload-api-D-CFg86j.js +0 -1
  427. package/dist/gateway/static/root/assets/skills-page-CUU4f6Ss.js +0 -2
  428. package/dist/gateway/static/root/assets/voice-api-key-field-C1MrQD8R.js +0 -1
  429. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DqizIcY5.js +0 -3
  430. package/dist/gateway/static/root/assets/workflows-page-B3sVNPFk.js +0 -18
  431. package/dist/src/agent/tools/edit.d.ts +0 -14
  432. package/dist/src/agent/tools/edit.js +0 -132
  433. package/dist/src/agent/tools/edit.js.map +0 -1
  434. package/dist/src/agent/tools/shell.d.ts +0 -15
  435. package/dist/src/agent/tools/shell.js +0 -158
  436. package/dist/src/agent/tools/shell.js.map +0 -1
@@ -51,21 +51,24 @@ export interface ToolFactoryDeps {
51
51
  } | undefined;
52
52
  /** After skill_manage mutates disk, reload skills + refresh agent prompts (optional). */
53
53
  onSkillsFilesystemMutate?: () => void;
54
- /** Names registered via skill_view for shell env passthrough. */
54
+ /** Names registered via skill_view for command env passthrough. */
55
55
  getSkillPassthroughEnvVarNames?: () => string[];
56
56
  /** Add declared env names for the current session (no values stored). */
57
57
  registerSkillEnvPassthrough?: (names: string[]) => void;
58
58
  }
59
59
  export interface CreateCoreToolsOptions {
60
- /** Workspace root for file/shell tools (defaults to factory workspace). */
60
+ /** Workspace root for file/command tools (defaults to factory workspace). */
61
61
  workspace?: string;
62
62
  /** Canonical `agents/<id>/profile/`: bare SOUL.md / IDENTITY.md resolve here after the workspace. */
63
63
  profileMarkdownRoot?: string;
64
- /** Tool `name` values to omit (e.g. `shell`, `extensions` for extension tools). */
64
+ /** Tool `name` values to omit (e.g. `exec_command`, `extensions` for extension tools). */
65
65
  disabledTools?: Set<string>;
66
66
  /** Optional primary model for image tool heuristics. */
67
67
  getPrimaryModel?: () => Model<Api>;
68
68
  getMemoryManager?: () => MemoryManager;
69
+ /** Agent-scoped memories directory used for dreaming state (`agents/<id>/memories`). */
70
+ dreamingRoot?: string;
71
+ agentId?: string;
69
72
  /** When set, registers `skills_list` and `skill_view` bound to this workspace\'s skills. */
70
73
  getSkillManager?: () => SkillManager;
71
74
  }
@@ -2,9 +2,9 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { createReadFileTool } from "./read.js";
4
4
  import { createWriteFileTool } from "./write.js";
5
- import { createEditFileTool } from "./edit.js";
6
5
  import { createListDirTool } from "./list-dir.js";
7
- import { createShellTool } from "./shell.js";
6
+ import { createExecCommandTool } from "./exec-command.js";
7
+ import { createApplyPatchTool } from "./apply-patch.js";
8
8
  import { createMemoryGetTool, createMemorySearchTool } from "./memory-tool.js";
9
9
  import { createCuratedMemoryTool } from "./curated-memory-tool.js";
10
10
  import { createSessionSearchTool } from "./session-search-tool.js";
@@ -18,6 +18,7 @@ import { createSendMediaTool } from "./send-media.js";
18
18
  import { createReadMediaTool } from "./media-read-tool.js";
19
19
  import { createCreateShareTool, isShareToolAvailable } from "./create-share-tool.js";
20
20
  import { createTodoTool } from "./todo-tool.js";
21
+ import { createUpdatePlanTool } from "./update-plan-tool.js";
21
22
  import { createSessionStatusTool } from "./session-status-tool.js";
22
23
  import { createDreamingTool } from "./dreaming-tool.js";
23
24
  import { createClarifyTool } from "./clarify-tool.js";
@@ -40,6 +41,7 @@ import { createImageGenerateTool } from "./image-generate-tool.js";
40
41
  import "./index.js";
41
42
  import { shouldRegisterCuratedMemoryTool } from "../memory/memory-config.js";
42
43
  import { createBrowserUseTool } from "./browser/tool/browser-use-tool.js";
44
+ import { resolveDreamingRootForAgent } from "../memory/dreaming/scope.js";
43
45
  import { wrapToolsWithProtection } from "./executor.js";
44
46
  import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
45
47
  import { createTextToSpeechTool } from "./tts-tool.js";
@@ -151,6 +153,7 @@ var AgentToolsFactory = class {
151
153
  const primary = getPrimary?.();
152
154
  const modelHasVision = primary?.input?.includes("image") ?? false;
153
155
  const cfg = this.deps.getConfig?.();
156
+ const dreamingRoot = options?.dreamingRoot ?? (cfg ? resolveDreamingRootForAgent(cfg, options?.agentId) : workspace);
154
157
  const browserEnabled = cfg?.browser?.enabled !== false;
155
158
  const recordGoalEvidence = createGoalEvidenceRecorder({ getSessionKey: () => this.deps.getCurrentContext()?.sessionKey });
156
159
  const optionalTools = [
@@ -170,10 +173,7 @@ var AgentToolsFactory = class {
170
173
  profileMarkdownRoot: options?.profileMarkdownRoot,
171
174
  recordGoalEvidence
172
175
  });
173
- const editTool = createEditFileTool(workspace, {
174
- profileMarkdownRoot: options?.profileMarkdownRoot,
175
- recordGoalEvidence
176
- });
176
+ const applyPatchTool = createApplyPatchTool(workspace, { recordGoalEvidence });
177
177
  const listDir = createListDirTool(workspace);
178
178
  const grep = createGrepTool(workspace);
179
179
  const find = createFindTool(workspace);
@@ -181,7 +181,9 @@ var AgentToolsFactory = class {
181
181
  createSessionStatusTool(),
182
182
  createDreamingTool({
183
183
  getWorkspace: () => workspace,
184
- getConfig: () => this.deps.getConfig?.()
184
+ getDreamingRoot: () => dreamingRoot,
185
+ getConfig: () => this.deps.getConfig?.(),
186
+ getAgentId: () => options?.agentId
185
187
  }),
186
188
  createToolManualTool(),
187
189
  createClarifyTool({ resolveAskUser: () => {
@@ -193,6 +195,7 @@ var AgentToolsFactory = class {
193
195
  return (r) => req(ctx.sessionKey, r);
194
196
  } }),
195
197
  createTodoTool({ getSessionKey: () => this.deps.getCurrentContext()?.sessionKey }),
198
+ createUpdatePlanTool(),
196
199
  ...getSkillMgr ? [
197
200
  createSkillsListTool({
198
201
  getSkillManager: getSkillMgr,
@@ -211,11 +214,11 @@ var AgentToolsFactory = class {
211
214
  ] : [],
212
215
  readTool,
213
216
  writeTool,
214
- editTool,
217
+ applyPatchTool,
215
218
  listDir,
216
219
  grep,
217
220
  find,
218
- createShellTool(workspace, {
221
+ createExecCommandTool(workspace, {
219
222
  getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,
220
223
  recordGoalEvidence
221
224
  }),
@@ -236,9 +239,11 @@ var AgentToolsFactory = class {
236
239
  })] : [],
237
240
  ...getMemMgr ? [createMemorySearchTool({
238
241
  workspaceDir: workspace,
242
+ dreamingRoot,
239
243
  getMemoryManager: () => getMemMgr()
240
244
  }), createMemoryGetTool({
241
245
  workspaceDir: workspace,
246
+ dreamingRoot,
242
247
  getMemoryManager: () => getMemMgr()
243
248
  })] : [],
244
249
  ...getMemMgr && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.()) ? [createCuratedMemoryTool(() => getMemMgr())] : [],
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","names":[],"sources":["../../../../src/agent/tools/factory.ts"],"sourcesContent":["/**\n * Agent Tools Factory - Creates and configures agent tools\n *\n * Centralizes tool creation logic to keep service.ts focused on orchestration.\n *\n * TTS: auto TTS is applied at the ChannelManager via maybeApplyTtsToPayload().\n * Optional \\`text_to_speech\\` tool sends explicit voice when TTS is enabled.\n */\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { Page } from 'playwright-core';\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport {\n createReadFileTool,\n createWriteFileTool,\n createEditFileTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createShellTool,\n createWebSearchTool,\n createWebFetchTool,\n createWebExtractTool,\n createMessageTool,\n createComposioExecuteTool,\n createSendMediaTool,\n createReadMediaTool,\n createCreateShareTool,\n isShareToolAvailable,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n createToolManualTool,\n createGoalTool,\n createAutomationTool,\n} from './index.js';\nimport { createCuratedMemoryTool } from './curated-memory-tool.js';\nimport { createSessionSearchTool } from './session-search-tool.js';\nimport type { MemoryManager } from '../memory/manager.js';\nimport { shouldRegisterCuratedMemoryTool } from '../memory/memory-config.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { GatewayClarifyRequestFn } from './clarify-tool.js';\nimport { createImageTool } from './image-tool.js';\nimport { createImageGenerateTool } from './image-generate-tool.js';\nimport {\n BrowserManager,\n BrowserNotReadyError,\n CdpSupervisor,\n checkBrowserReadiness,\n resolveBrowserBackendFromConfig,\n} from '../../browser/index.js';\nimport { createBrowserUseTool } from './browser/tool/browser-use-tool.js';\nimport { createDelegateTool } from './delegate-tool.js';\nimport { createWorkflowTool } from './workflow-tool.js';\nimport { createWorkflowCatalog } from '../workflow/catalog.js';\nimport { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport type { AutomationService } from '../../automations/index.js';\nimport type { WorkflowRunServiceLike } from '../../workflows/service/workflow-run-service.types.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { wrapToolsWithProtection, type ToolExecutorConfig } from './executor.js';\nimport { createSkillsListTool, createSkillViewTool } from './skills-tools.js';\nimport { createSkillManageTool } from './skill-manage-tool.js';\nimport { createTextToSpeechTool } from './tts-tool.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\nimport { createGoalEvidenceRecorder } from './goal-evidence-recorder.js';\n\nconst log = createLogger('AgentToolsFactory');\n\n/** Channels where `clarify` can block for a user answer (web UI, Telegram, CLI readline). */\nconst CLARIFY_SUPPORTED_CHANNELS = new Set(['webchat', 'telegram', 'cli']);\n\nexport interface ToolFactoryDeps {\n workspace: string;\n extensionRegistry?: any;\n getCurrentContext: () => { channel: string; chatId: string; sessionKey: string } | null;\n hookRunner?: import('../../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n toolExecutorConfig?: Partial<ToolExecutorConfig>;\n /** Agent defaults (image tools, etc.); use getter so hot-reloaded config applies. */\n getConfig?: () => Config | undefined;\n /** Session / default chat model for vision tool description. */\n getPrimaryModel?: () => Model<Api>;\n /** Memory orchestration (prefetch/sync + external tools). */\n getMemoryManager?: () => MemoryManager;\n /** Session store for `session_search`. */\n getSessionStore?: () => SessionStore;\n /** When set (gateway webchat), enables the `clarify` tool. */\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: enables the `automation` tool. */\n getAutomationService?: () => AutomationService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => WorkflowRunServiceLike | undefined;\n /** Current session skill indexing (tool gating + allowlist); used by skills_list / skill_view. */\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** After skill_manage mutates disk, reload skills + refresh agent prompts (optional). */\n onSkillsFilesystemMutate?: () => void;\n /** Names registered via skill_view for shell env passthrough. */\n getSkillPassthroughEnvVarNames?: () => string[];\n /** Add declared env names for the current session (no values stored). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n}\n\nexport interface CreateCoreToolsOptions {\n /** Workspace root for file/shell tools (defaults to factory workspace). */\n workspace?: string;\n /** Canonical `agents/<id>/profile/`: bare SOUL.md / IDENTITY.md resolve here after the workspace. */\n profileMarkdownRoot?: string;\n /** Tool `name` values to omit (e.g. `shell`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getMemoryManager?: () => MemoryManager;\n /** When set, registers `skills_list` and `skill_view` bound to this workspace\\'s skills. */\n getSkillManager?: () => SkillManager;\n}\n\nexport class AgentToolsFactory {\n private browserManager: BrowserManager | null = null;\n /** One dialog/console supervisor per chat session (browser tab). */\n private readonly browserTaskSupervisors = new Map<string, CdpSupervisor>();\n /** Cached readiness probe — keyed by backend mode + extension host:port. */\n private browserReadinessCache: {\n key: string;\n expiresAt: number;\n inflight?: Promise<BrowserNotReadyError | null>;\n result?: BrowserNotReadyError | null;\n } | null = null;\n\n constructor(private deps: ToolFactoryDeps) {}\n\n private browserReadinessKey(): string {\n const cfg = this.deps.getConfig?.();\n const backend = resolveBrowserBackendFromConfig(cfg);\n const host = '127.0.0.1';\n const port = 19820;\n const cdpUrl = backend.mode === 'cdp' ? backend.config.wsEndpoint : '';\n const cloudKind = backend.mode === 'cloud' ? backend.config.type : '';\n return `${backend.mode}@${host}:${port}|${cdpUrl}|${cloudKind}`;\n }\n\n private async checkBrowserReadinessCached(): Promise<BrowserNotReadyError | null> {\n const key = this.browserReadinessKey();\n const now = Date.now();\n const cached = this.browserReadinessCache;\n if (cached && cached.key === key && cached.expiresAt > now && cached.inflight === undefined) {\n return cached.result ?? null;\n }\n if (cached && cached.key === key && cached.inflight) {\n return cached.inflight;\n }\n const inflight = checkBrowserReadiness(this.deps.getConfig?.());\n this.browserReadinessCache = { key, expiresAt: now + 30_000, inflight };\n try {\n const result = await inflight;\n this.browserReadinessCache = { key, expiresAt: Date.now() + 30_000, result };\n return result;\n } catch (e) {\n // Probe should never throw, but if it does we just bypass the cache.\n this.browserReadinessCache = null;\n log.warn({ err: e }, 'browserReadiness probe failed');\n return null;\n }\n }\n\n /** Invalidate the readiness cache (config hot-reload, settings-page save, etc.). */\n invalidateBrowserReadinessCache(): void {\n this.browserReadinessCache = null;\n }\n\n private browserSupervisorForTask(taskId: string): CdpSupervisor {\n let s = this.browserTaskSupervisors.get(taskId);\n if (!s) {\n s = new CdpSupervisor({ dialogPolicy: 'auto_dismiss', dialogTimeoutSeconds: 300 });\n this.browserTaskSupervisors.set(taskId, s);\n }\n return s;\n }\n\n private async acquireBrowserPage(): Promise<Page> {\n const taskId = this.deps.getCurrentContext()?.sessionKey ?? 'default';\n const mgr = this.ensureBrowserManager();\n await mgr.ensureConnected();\n if (mgr.getExtensionProvider()) {\n return null as unknown as Page;\n }\n const page = await mgr.getPage(taskId);\n this.browserSupervisorForTask(taskId).attach(page);\n return page;\n }\n\n private ensureBrowserManager(): BrowserManager {\n if (!this.browserManager) {\n this.browserManager = new BrowserManager({\n getHeadless: () => false,\n getBackend: () => resolveBrowserBackendFromConfig(this.deps.getConfig?.()),\n });\n }\n return this.browserManager;\n }\n\n /** Close Playwright and all pages (gateway stop, agent manager dispose, or config hot-reload). */\n async shutdownBrowser(): Promise<void> {\n this.browserReadinessCache = null;\n if (!this.browserManager) {\n return;\n }\n await this.browserManager.shutdown();\n this.browserManager = null;\n this.browserTaskSupervisors.clear();\n }\n\n /** Drop the tab for a session when its agent instance is removed. */\n async closeBrowserPageForSession(sessionKey: string): Promise<void> {\n this.browserTaskSupervisors.delete(sessionKey);\n await this.browserManager?.closePage(sessionKey);\n }\n\n createCoreTools(options?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const workspace = options?.workspace ?? this.deps.workspace;\n const { bus } = this.deps;\n const getPrimary = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const getMemMgr = options?.getMemoryManager ?? this.deps.getMemoryManager;\n const getSkillMgr = options?.getSkillManager;\n const disabled = options?.disabledTools;\n\n const primary = getPrimary?.();\n const modelHasVision = primary?.input?.includes('image') ?? false;\n const cfg = this.deps.getConfig?.();\n const browserEnabled = cfg?.browser?.enabled !== false;\n const recordGoalEvidence = createGoalEvidenceRecorder({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n });\n const imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const composioTool = createComposioExecuteTool(() => this.deps.getConfig?.());\n const optionalTools = [imageTool, imageGenerateTool, composioTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n recordGoalEvidence,\n });\n const editTool = createEditFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n recordGoalEvidence,\n });\n const listDir = createListDirTool(workspace);\n const grep = createGrepTool(workspace);\n const find = createFindTool(workspace);\n\n const core: AgentTool<any, any>[] = [\n createSessionStatusTool(),\n createDreamingTool({\n getWorkspace: () => workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n createToolManualTool(),\n createClarifyTool({\n resolveAskUser: () => {\n const req = this.deps.gatewayClarify?.requestClarification;\n if (!req) return null;\n const ctx = this.deps.getCurrentContext();\n if (!ctx?.sessionKey) return null;\n if (!CLARIFY_SUPPORTED_CHANNELS.has(ctx.channel)) return null;\n return (r) => req(ctx.sessionKey, r);\n },\n }),\n createTodoTool({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ...(getSkillMgr\n ? [\n createSkillsListTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n }),\n createSkillViewTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n registerSkillEnvPassthrough: this.deps.registerSkillEnvPassthrough,\n }),\n createSkillManageTool({\n getSkillManager: getSkillMgr,\n getWorkspace: () => workspace,\n onSkillsFilesystemMutate: this.deps.onSkillsFilesystemMutate,\n }),\n ]\n : []),\n readTool,\n writeTool,\n editTool,\n listDir,\n grep,\n find,\n createShellTool(workspace, {\n getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,\n recordGoalEvidence,\n }),\n createWebSearchTool(() => this.deps.getConfig?.()),\n createWebFetchTool(() => this.deps.getConfig?.()),\n createWebExtractTool({ getConfig: () => this.deps.getConfig?.() }),\n // Note: TTS is NOT handled by send_message tool anymore\n // TTS is applied at the ChannelManager dispatch layer\n createMessageTool(bus, () => this.deps.getCurrentContext()),\n ...(mergeTtsConfigFromAppConfig(cfg?.messages?.tts).enabled\n ? [\n createTextToSpeechTool({\n bus,\n getContext: () => this.deps.getCurrentContext(),\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n createSendMediaTool(workspace, bus, () => this.deps.getCurrentContext()),\n createReadMediaTool(),\n ...(isShareToolAvailable(cfg)\n ? [\n createCreateShareTool({\n workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n ...(getMemMgr\n ? [\n createMemorySearchTool({ workspaceDir: workspace, getMemoryManager: () => getMemMgr() }),\n createMemoryGetTool({ workspaceDir: workspace, getMemoryManager: () => getMemMgr() }),\n ]\n : []),\n ...(getMemMgr && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.())\n ? [\n createCuratedMemoryTool(() => getMemMgr()),\n ]\n : []),\n ...(getMemMgr?.().getAdditionalTools() ?? []),\n ...(this.deps.getSessionStore\n ? [\n createSessionSearchTool({\n getSessionStore: this.deps.getSessionStore,\n getConfig: this.deps.getConfig,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ]\n : []),\n ...(this.deps.getAutomationService\n ? [\n createAutomationTool({\n getAutomationService: this.deps.getAutomationService,\n }),\n ]\n : []),\n createGoalTool({\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ...(browserEnabled\n ? [\n createBrowserUseTool({\n getManager: () => this.ensureBrowserManager(),\n getPageForTask: () => this.acquireBrowserPage(),\n getTaskId: () => this.deps.getCurrentContext()?.sessionKey ?? 'default',\n getConfig: () => this.deps.getConfig?.(),\n getReadiness: () => this.checkBrowserReadinessCached(),\n getSupervisor: () =>\n this.browserSupervisorForTask(this.deps.getCurrentContext()?.sessionKey ?? 'default'),\n notifyBrowserPageClosed: (taskId) => {\n this.browserTaskSupervisors.delete(taskId);\n },\n }),\n ]\n : []),\n ...(primary\n ? [\n createWorkflowTool({\n catalog: createWorkflowCatalog(),\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n getConfig: () => this.deps.getConfig?.(),\n startWorkflowRun: this.deps.getWorkflowRunService\n ? (params) => this.deps.getWorkflowRunService!().startWorkflowRun(params)\n : undefined,\n }),\n ]\n : []),\n ...(false && primary\n ? [\n createDelegateTool({\n workspace,\n getSubagentModel: () => {\n const gp = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const m = gp?.();\n if (!m) {\n throw new Error('No primary model configured for delegate_task');\n }\n return m;\n },\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,\n hookRunner: this.deps.hookRunner,\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `child-agent-factory.ts` does not need to import\n // `AgentToolsFactory` directly (which would form a cycle).\n buildChildTools: (childOpts) => {\n const childFactory = new AgentToolsFactory({\n workspace: childOpts.workspace,\n bus: childOpts.bus,\n getCurrentContext: () => null,\n getConfig: childOpts.getConfig,\n getPrimaryModel: () => childOpts.model,\n toolExecutorConfig: childOpts.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOpts.workspace,\n getPrimaryModel: () => childOpts.model,\n disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\n }\n\n createAllTools(coreOptions?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const coreTools = this.createCoreTools(coreOptions);\n const disableExtensions = coreOptions?.disabledTools?.has('extensions');\n\n let bundled: AgentTool<any, any>[];\n if (!this.deps.extensionRegistry || disableExtensions) {\n bundled = coreTools;\n } else {\n const extensionTools = this.deps.extensionRegistry.getAllTools();\n log.info({ count: extensionTools.length }, 'Loaded extension tools');\n bundled = [...coreTools, ...extensionTools];\n }\n\n const wrapped = wrapToolsWithProtection(bundled, this.deps.toolExecutorConfig);\n\n const executeEnabled = false && !coreOptions?.disabledTools?.has('execute_code');\n\n if (executeEnabled) {\n const sandboxMap = buildSandboxToolMap(wrapped);\n const executeTool = createExecuteCodeTool({ getSandboxToolMap: () => sandboxMap });\n const wrappedExecute = wrapToolsWithProtection([executeTool as any], this.deps.toolExecutorConfig);\n return [...wrapped, ...wrappedExecute];\n }\n\n return wrapped;\n }\n}\n\nfunction filterToolsByDisabledSet(\n tools: any[],\n disabled: Set<string> | undefined,\n): any[] {\n if (!disabled || disabled.size === 0) {\n return tools;\n }\n return tools.filter((t) => !disabled.has(t.name));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA+DqD;AASrD,MAAM,MAAM,aAAa,oBAAoB;;AAG7C,MAAM,6BAA6B,IAAI,IAAI;CAAC;CAAW;CAAY;CAAM,CAAC;AAiD1E,IAAa,oBAAb,MAA+B;CAC7B,iBAAgD;;CAEhD,yCAA0C,IAAI,KAA4B;;CAE1E,wBAKW;CAEX,YAAY,MAA+B;AAAvB,OAAA,OAAA;;CAEpB,sBAAsC;EACpC,MAAM,MAAM,KAAK,KAAK,aAAa;EACnC,MAAM,UAAU,gCAAgC,IAAI;EACpD,MAAM,OAAO;EACb,MAAM,OAAO;EACb,MAAM,SAAS,QAAQ,SAAS,QAAQ,QAAQ,OAAO,aAAa;EACpE,MAAM,YAAY,QAAQ,SAAS,UAAU,QAAQ,OAAO,OAAO;AACnE,SAAO,GAAG,QAAQ,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG;;CAGtD,MAAc,8BAAoE;EAChF,MAAM,MAAM,KAAK,qBAAqB;EACtC,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,SAAS,KAAK;AACpB,MAAI,UAAU,OAAO,QAAQ,OAAO,OAAO,YAAY,OAAO,OAAO,aAAa,KAAA,EAChF,QAAO,OAAO,UAAU;AAE1B,MAAI,UAAU,OAAO,QAAQ,OAAO,OAAO,SACzC,QAAO,OAAO;EAEhB,MAAM,WAAW,sBAAsB,KAAK,KAAK,aAAa,CAAC;AAC/D,OAAK,wBAAwB;GAAE;GAAK,WAAW,MAAM;GAAQ;GAAU;AACvE,MAAI;GACF,MAAM,SAAS,MAAM;AACrB,QAAK,wBAAwB;IAAE;IAAK,WAAW,KAAK,KAAK,GAAG;IAAQ;IAAQ;AAC5E,UAAO;WACA,GAAG;AAEV,QAAK,wBAAwB;AAC7B,OAAI,KAAK,EAAE,KAAK,GAAG,EAAE,gCAAgC;AACrD,UAAO;;;;CAKX,kCAAwC;AACtC,OAAK,wBAAwB;;CAG/B,yBAAiC,QAA+B;EAC9D,IAAI,IAAI,KAAK,uBAAuB,IAAI,OAAO;AAC/C,MAAI,CAAC,GAAG;AACN,OAAI,IAAI,cAAc;IAAE,cAAc;IAAgB,sBAAsB;IAAK,CAAC;AAClF,QAAK,uBAAuB,IAAI,QAAQ,EAAE;;AAE5C,SAAO;;CAGT,MAAc,qBAAoC;EAChD,MAAM,SAAS,KAAK,KAAK,mBAAmB,EAAE,cAAc;EAC5D,MAAM,MAAM,KAAK,sBAAsB;AACvC,QAAM,IAAI,iBAAiB;AAC3B,MAAI,IAAI,sBAAsB,CAC5B,QAAO;EAET,MAAM,OAAO,MAAM,IAAI,QAAQ,OAAO;AACtC,OAAK,yBAAyB,OAAO,CAAC,OAAO,KAAK;AAClD,SAAO;;CAGT,uBAA+C;AAC7C,MAAI,CAAC,KAAK,eACR,MAAK,iBAAiB,IAAI,eAAe;GACvC,mBAAmB;GACnB,kBAAkB,gCAAgC,KAAK,KAAK,aAAa,CAAC;GAC3E,CAAC;AAEJ,SAAO,KAAK;;;CAId,MAAM,kBAAiC;AACrC,OAAK,wBAAwB;AAC7B,MAAI,CAAC,KAAK,eACR;AAEF,QAAM,KAAK,eAAe,UAAU;AACpC,OAAK,iBAAiB;AACtB,OAAK,uBAAuB,OAAO;;;CAIrC,MAAM,2BAA2B,YAAmC;AAClE,OAAK,uBAAuB,OAAO,WAAW;AAC9C,QAAM,KAAK,gBAAgB,UAAU,WAAW;;CAGlD,gBAAgB,SAAyD;EACvE,MAAM,YAAY,SAAS,aAAa,KAAK,KAAK;EAClD,MAAM,EAAE,QAAQ,KAAK;EACrB,MAAM,aAAa,SAAS,mBAAmB,KAAK,KAAK;EACzD,MAAM,YAAY,SAAS,oBAAoB,KAAK,KAAK;EACzD,MAAM,cAAc,SAAS;EAC7B,MAAM,WAAW,SAAS;EAE1B,MAAM,UAAU,cAAc;EAC9B,MAAM,iBAAiB,SAAS,OAAO,SAAS,QAAQ,IAAI;EAC5D,MAAM,MAAM,KAAK,KAAK,aAAa;EACnC,MAAM,iBAAiB,KAAK,SAAS,YAAY;EACjD,MAAM,qBAAqB,2BAA2B,EACpD,qBAAqB,KAAK,KAAK,mBAAmB,EAAE,YACrD,CAAC;EAYF,MAAM,gBAAgB;GAXJ,gBAAgB;IAChC,QAAQ;IACR;IACA;IACD,CAO+B;GANN,wBAAwB;IAChD,QAAQ;IACR;IACD,CAGkD;GAD9B,gCAAgC,KAAK,KAAK,aAAa,CACX;GAAC,CAAC,QAAQ,MAAM,KAAK,KAAK;EAE3F,MAAM,WAAW,mBAAmB,WAAW,EAC7C,qBAAqB,SAAS,qBAC/B,CAAC;EACF,MAAM,YAAY,oBAAoB,WAAW;GAC/C,qBAAqB,SAAS;GAC9B;GACD,CAAC;EACF,MAAM,WAAW,mBAAmB,WAAW;GAC7C,qBAAqB,SAAS;GAC9B;GACD,CAAC;EACF,MAAM,UAAU,kBAAkB,UAAU;EAC5C,MAAM,OAAO,eAAe,UAAU;EACtC,MAAM,OAAO,eAAe,UAAU;AA8KtC,SAAO,yBAAyB;GA3K9B,yBAAyB;GACzB,mBAAmB;IACjB,oBAAoB;IACpB,iBAAiB,KAAK,KAAK,aAAa;IACzC,CAAC;GACF,sBAAsB;GACtB,kBAAkB,EAChB,sBAAsB;IACpB,MAAM,MAAM,KAAK,KAAK,gBAAgB;AACtC,QAAI,CAAC,IAAK,QAAO;IACjB,MAAM,MAAM,KAAK,KAAK,mBAAmB;AACzC,QAAI,CAAC,KAAK,WAAY,QAAO;AAC7B,QAAI,CAAC,2BAA2B,IAAI,IAAI,QAAQ,CAAE,QAAO;AACzD,YAAQ,MAAM,IAAI,IAAI,YAAY,EAAE;MAEvC,CAAC;GACF,eAAe,EACb,qBAAqB,KAAK,KAAK,mBAAmB,EAAE,YACrD,CAAC;GACF,GAAI,cACA;IACE,qBAAqB;KACnB,iBAAiB;KACjB,yBAAyB,KAAK,KAAK;KACpC,CAAC;IACF,oBAAoB;KAClB,iBAAiB;KACjB,yBAAyB,KAAK,KAAK;KACnC,6BAA6B,KAAK,KAAK;KACxC,CAAC;IACF,sBAAsB;KACpB,iBAAiB;KACjB,oBAAoB;KACpB,0BAA0B,KAAK,KAAK;KACrC,CAAC;IACH,GACD,EAAE;GACN;GACA;GACA;GACA;GACA;GACA;GACA,gBAAgB,WAAW;IACzB,gCAAgC,KAAK,KAAK;IAC1C;IACD,CAAC;GACF,0BAA0B,KAAK,KAAK,aAAa,CAAC;GAClD,yBAAyB,KAAK,KAAK,aAAa,CAAC;GACjD,qBAAqB,EAAE,iBAAiB,KAAK,KAAK,aAAa,EAAE,CAAC;GAGlE,kBAAkB,WAAW,KAAK,KAAK,mBAAmB,CAAC;GAC3D,GAAI,4BAA4B,KAAK,UAAU,IAAI,CAAC,UAChD,CACE,uBAAuB;IACrB;IACA,kBAAkB,KAAK,KAAK,mBAAmB;IAC/C,iBAAiB,KAAK,KAAK,aAAa;IACzC,CAAC,CACH,GACD,EAAE;GACN,oBAAoB,WAAW,WAAW,KAAK,KAAK,mBAAmB,CAAC;GACxE,qBAAqB;GACrB,GAAI,qBAAqB,IAAI,GACzB,CACE,sBAAsB;IACpB;IACA,iBAAiB,KAAK,KAAK,aAAa;IACzC,CAAC,CACH,GACD,EAAE;GACN,GAAI,YACA,CACE,uBAAuB;IAAE,cAAc;IAAW,wBAAwB,WAAW;IAAE,CAAC,EACxF,oBAAoB;IAAE,cAAc;IAAW,wBAAwB,WAAW;IAAE,CAAC,CACtF,GACD,EAAE;GACN,GAAI,aAAa,gCAAgC,KAAK,KAAK,aAAa,CAAC,GACrE,CACE,8BAA8B,WAAW,CAAC,CAC3C,GACD,EAAE;GACN,GAAI,aAAa,CAAC,oBAAoB,IAAI,EAAE;GAC5C,GAAI,KAAK,KAAK,kBACV,CACE,wBAAwB;IACtB,iBAAiB,KAAK,KAAK;IAC3B,WAAW,KAAK,KAAK;IACrB,4BAA4B,KAAK,KAAK,mBAAmB,EAAE;IAC5D,CAAC,CACH,GACD,EAAE;GACN,GAAI,KAAK,KAAK,uBACV,CACE,qBAAqB,EACnB,sBAAsB,KAAK,KAAK,sBACjC,CAAC,CACH,GACD,EAAE;GACN,eAAe,EACb,4BAA4B,KAAK,KAAK,mBAAmB,EAAE,YAC5D,CAAC;GACF,GAAI,iBACA,CACE,qBAAqB;IACnB,kBAAkB,KAAK,sBAAsB;IAC7C,sBAAsB,KAAK,oBAAoB;IAC/C,iBAAiB,KAAK,KAAK,mBAAmB,EAAE,cAAc;IAC9D,iBAAiB,KAAK,KAAK,aAAa;IACxC,oBAAoB,KAAK,6BAA6B;IACtD,qBACE,KAAK,yBAAyB,KAAK,KAAK,mBAAmB,EAAE,cAAc,UAAU;IACvF,0BAA0B,WAAW;AACnC,UAAK,uBAAuB,OAAO,OAAO;;IAE7C,CAAC,CACH,GACD,EAAE;GACN,GAAI,UACA,CACE,mBAAmB;IACjB,SAAS,uBAAuB;IAChC,4BAA4B,KAAK,KAAK,mBAAmB,EAAE;IAC3D,iBAAiB,KAAK,KAAK,aAAa;IACxC,kBAAkB,KAAK,KAAK,yBACvB,WAAW,KAAK,KAAK,uBAAwB,CAAC,iBAAiB,OAAO,GACvE,KAAA;IACL,CAAC,CACH,GACD,EAAE;GACN,GAoCI,EAAE;GACN,GAAG;GAG+B,EAAE,SAAS;;CAGjD,eAAe,aAA6D;EAC1E,MAAM,YAAY,KAAK,gBAAgB,YAAY;EACnD,MAAM,oBAAoB,aAAa,eAAe,IAAI,aAAa;EAEvE,IAAI;AACJ,MAAI,CAAC,KAAK,KAAK,qBAAqB,kBAClC,WAAU;OACL;GACL,MAAM,iBAAiB,KAAK,KAAK,kBAAkB,aAAa;AAChE,OAAI,KAAK,EAAE,OAAO,eAAe,QAAQ,EAAE,yBAAyB;AACpE,aAAU,CAAC,GAAG,WAAW,GAAG,eAAe;;AAc7C,SAXgB,wBAAwB,SAAS,KAAK,KAAK,mBAW7C;;;AAIlB,SAAS,yBACP,OACA,UACO;AACP,KAAI,CAAC,YAAY,SAAS,SAAS,EACjC,QAAO;AAET,QAAO,MAAM,QAAQ,MAAM,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC"}
1
+ {"version":3,"file":"factory.js","names":[],"sources":["../../../../src/agent/tools/factory.ts"],"sourcesContent":["/**\n * Agent Tools Factory - Creates and configures agent tools\n *\n * Centralizes tool creation logic to keep service.ts focused on orchestration.\n *\n * TTS: auto TTS is applied at the ChannelManager via maybeApplyTtsToPayload().\n * Optional \\`text_to_speech\\` tool sends explicit voice when TTS is enabled.\n */\n\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\nimport type { Model, Api } from '@earendil-works/pi-ai';\nimport type { Page } from 'playwright-core';\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport {\n createReadFileTool,\n createWriteFileTool,\n createApplyPatchTool,\n createListDirTool,\n createGrepTool,\n createFindTool,\n createExecCommandTool,\n createWebSearchTool,\n createWebFetchTool,\n createWebExtractTool,\n createMessageTool,\n createComposioExecuteTool,\n createSendMediaTool,\n createReadMediaTool,\n createCreateShareTool,\n isShareToolAvailable,\n createMemorySearchTool,\n createMemoryGetTool,\n createTodoTool,\n createUpdatePlanTool,\n createSessionStatusTool,\n createDreamingTool,\n createClarifyTool,\n createToolManualTool,\n createGoalTool,\n createAutomationTool,\n} from './index.js';\nimport { createCuratedMemoryTool } from './curated-memory-tool.js';\nimport { createSessionSearchTool } from './session-search-tool.js';\nimport type { MemoryManager } from '../memory/manager.js';\nimport { shouldRegisterCuratedMemoryTool } from '../memory/memory-config.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { GatewayClarifyRequestFn } from './clarify-tool.js';\nimport { createImageTool } from './image-tool.js';\nimport { createImageGenerateTool } from './image-generate-tool.js';\nimport {\n BrowserManager,\n BrowserNotReadyError,\n CdpSupervisor,\n checkBrowserReadiness,\n resolveBrowserBackendFromConfig,\n} from '../../browser/index.js';\nimport { createBrowserUseTool } from './browser/tool/browser-use-tool.js';\nimport { createDelegateTool } from './delegate-tool.js';\nimport { createWorkflowTool } from './workflow-tool.js';\nimport { createWorkflowCatalog } from '../workflow/catalog.js';\nimport { resolveDreamingRootForAgent } from '../memory/dreaming/scope.js';\nimport { buildSandboxToolMap, createExecuteCodeTool } from './execute-code-tool.js';\nimport type { AutomationService } from '../../automations/index.js';\nimport type { WorkflowRunServiceLike } from '../../workflows/service/workflow-run-service.types.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { wrapToolsWithProtection, type ToolExecutorConfig } from './executor.js';\nimport { createSkillsListTool, createSkillViewTool } from './skills-tools.js';\nimport { createSkillManageTool } from './skill-manage-tool.js';\nimport { createTextToSpeechTool } from './tts-tool.js';\nimport { mergeTtsConfigFromAppConfig } from '../../voice/tts/merge-config.js';\nimport { createGoalEvidenceRecorder } from './goal-evidence-recorder.js';\n\nconst log = createLogger('AgentToolsFactory');\n\n/** Channels where `clarify` can block for a user answer (web UI, Telegram, CLI readline). */\nconst CLARIFY_SUPPORTED_CHANNELS = new Set(['webchat', 'telegram', 'cli']);\n\nexport interface ToolFactoryDeps {\n workspace: string;\n extensionRegistry?: any;\n getCurrentContext: () => { channel: string; chatId: string; sessionKey: string } | null;\n hookRunner?: import('../../extensions/index.js').ExtensionHookRunner;\n bus: MessageBus;\n toolExecutorConfig?: Partial<ToolExecutorConfig>;\n /** Agent defaults (image tools, etc.); use getter so hot-reloaded config applies. */\n getConfig?: () => Config | undefined;\n /** Session / default chat model for vision tool description. */\n getPrimaryModel?: () => Model<Api>;\n /** Memory orchestration (prefetch/sync + external tools). */\n getMemoryManager?: () => MemoryManager;\n /** Session store for `session_search`. */\n getSessionStore?: () => SessionStore;\n /** When set (gateway webchat), enables the `clarify` tool. */\n gatewayClarify?: { requestClarification: GatewayClarifyRequestFn };\n /** Gateway: enables the `automation` tool. */\n getAutomationService?: () => AutomationService | undefined;\n /** Gateway: starts persisted workflow runs (dedicated chat session per run). */\n getWorkflowRunService?: () => WorkflowRunServiceLike | undefined;\n /** Current session skill indexing (tool gating + allowlist); used by skills_list / skill_view. */\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** After skill_manage mutates disk, reload skills + refresh agent prompts (optional). */\n onSkillsFilesystemMutate?: () => void;\n /** Names registered via skill_view for command env passthrough. */\n getSkillPassthroughEnvVarNames?: () => string[];\n /** Add declared env names for the current session (no values stored). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n}\n\nexport interface CreateCoreToolsOptions {\n /** Workspace root for file/command tools (defaults to factory workspace). */\n workspace?: string;\n /** Canonical `agents/<id>/profile/`: bare SOUL.md / IDENTITY.md resolve here after the workspace. */\n profileMarkdownRoot?: string;\n /** Tool `name` values to omit (e.g. `exec_command`, `extensions` for extension tools). */\n disabledTools?: Set<string>;\n /** Optional primary model for image tool heuristics. */\n getPrimaryModel?: () => Model<Api>;\n getMemoryManager?: () => MemoryManager;\n /** Agent-scoped memories directory used for dreaming state (`agents/<id>/memories`). */\n dreamingRoot?: string;\n agentId?: string;\n /** When set, registers `skills_list` and `skill_view` bound to this workspace\\'s skills. */\n getSkillManager?: () => SkillManager;\n}\n\nexport class AgentToolsFactory {\n private browserManager: BrowserManager | null = null;\n /** One dialog/console supervisor per chat session (browser tab). */\n private readonly browserTaskSupervisors = new Map<string, CdpSupervisor>();\n /** Cached readiness probe — keyed by backend mode + extension host:port. */\n private browserReadinessCache: {\n key: string;\n expiresAt: number;\n inflight?: Promise<BrowserNotReadyError | null>;\n result?: BrowserNotReadyError | null;\n } | null = null;\n\n constructor(private deps: ToolFactoryDeps) {}\n\n private browserReadinessKey(): string {\n const cfg = this.deps.getConfig?.();\n const backend = resolveBrowserBackendFromConfig(cfg);\n const host = '127.0.0.1';\n const port = 19820;\n const cdpUrl = backend.mode === 'cdp' ? backend.config.wsEndpoint : '';\n const cloudKind = backend.mode === 'cloud' ? backend.config.type : '';\n return `${backend.mode}@${host}:${port}|${cdpUrl}|${cloudKind}`;\n }\n\n private async checkBrowserReadinessCached(): Promise<BrowserNotReadyError | null> {\n const key = this.browserReadinessKey();\n const now = Date.now();\n const cached = this.browserReadinessCache;\n if (cached && cached.key === key && cached.expiresAt > now && cached.inflight === undefined) {\n return cached.result ?? null;\n }\n if (cached && cached.key === key && cached.inflight) {\n return cached.inflight;\n }\n const inflight = checkBrowserReadiness(this.deps.getConfig?.());\n this.browserReadinessCache = { key, expiresAt: now + 30_000, inflight };\n try {\n const result = await inflight;\n this.browserReadinessCache = { key, expiresAt: Date.now() + 30_000, result };\n return result;\n } catch (e) {\n // Probe should never throw, but if it does we just bypass the cache.\n this.browserReadinessCache = null;\n log.warn({ err: e }, 'browserReadiness probe failed');\n return null;\n }\n }\n\n /** Invalidate the readiness cache (config hot-reload, settings-page save, etc.). */\n invalidateBrowserReadinessCache(): void {\n this.browserReadinessCache = null;\n }\n\n private browserSupervisorForTask(taskId: string): CdpSupervisor {\n let s = this.browserTaskSupervisors.get(taskId);\n if (!s) {\n s = new CdpSupervisor({ dialogPolicy: 'auto_dismiss', dialogTimeoutSeconds: 300 });\n this.browserTaskSupervisors.set(taskId, s);\n }\n return s;\n }\n\n private async acquireBrowserPage(): Promise<Page> {\n const taskId = this.deps.getCurrentContext()?.sessionKey ?? 'default';\n const mgr = this.ensureBrowserManager();\n await mgr.ensureConnected();\n if (mgr.getExtensionProvider()) {\n return null as unknown as Page;\n }\n const page = await mgr.getPage(taskId);\n this.browserSupervisorForTask(taskId).attach(page);\n return page;\n }\n\n private ensureBrowserManager(): BrowserManager {\n if (!this.browserManager) {\n this.browserManager = new BrowserManager({\n getHeadless: () => false,\n getBackend: () => resolveBrowserBackendFromConfig(this.deps.getConfig?.()),\n });\n }\n return this.browserManager;\n }\n\n /** Close Playwright and all pages (gateway stop, agent manager dispose, or config hot-reload). */\n async shutdownBrowser(): Promise<void> {\n this.browserReadinessCache = null;\n if (!this.browserManager) {\n return;\n }\n await this.browserManager.shutdown();\n this.browserManager = null;\n this.browserTaskSupervisors.clear();\n }\n\n /** Drop the tab for a session when its agent instance is removed. */\n async closeBrowserPageForSession(sessionKey: string): Promise<void> {\n this.browserTaskSupervisors.delete(sessionKey);\n await this.browserManager?.closePage(sessionKey);\n }\n\n createCoreTools(options?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const workspace = options?.workspace ?? this.deps.workspace;\n const { bus } = this.deps;\n const getPrimary = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const getMemMgr = options?.getMemoryManager ?? this.deps.getMemoryManager;\n const getSkillMgr = options?.getSkillManager;\n const disabled = options?.disabledTools;\n\n const primary = getPrimary?.();\n const modelHasVision = primary?.input?.includes('image') ?? false;\n const cfg = this.deps.getConfig?.();\n const dreamingRoot = options?.dreamingRoot ?? (cfg ? resolveDreamingRootForAgent(cfg, options?.agentId) : workspace);\n const browserEnabled = cfg?.browser?.enabled !== false;\n const recordGoalEvidence = createGoalEvidenceRecorder({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n });\n const imageTool = createImageTool({\n config: cfg,\n workspace,\n modelHasVision,\n });\n const imageGenerateTool = createImageGenerateTool({\n config: cfg,\n workspace,\n });\n\n const composioTool = createComposioExecuteTool(() => this.deps.getConfig?.());\n const optionalTools = [imageTool, imageGenerateTool, composioTool].filter((t) => t != null) as any[];\n\n const readTool = createReadFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n });\n const writeTool = createWriteFileTool(workspace, {\n profileMarkdownRoot: options?.profileMarkdownRoot,\n recordGoalEvidence,\n });\n const applyPatchTool = createApplyPatchTool(workspace, { recordGoalEvidence });\n const listDir = createListDirTool(workspace);\n const grep = createGrepTool(workspace);\n const find = createFindTool(workspace);\n\n const core: AgentTool<any, any>[] = [\n createSessionStatusTool(),\n createDreamingTool({\n getWorkspace: () => workspace,\n getDreamingRoot: () => dreamingRoot,\n getConfig: () => this.deps.getConfig?.(),\n getAgentId: () => options?.agentId,\n }),\n createToolManualTool(),\n createClarifyTool({\n resolveAskUser: () => {\n const req = this.deps.gatewayClarify?.requestClarification;\n if (!req) return null;\n const ctx = this.deps.getCurrentContext();\n if (!ctx?.sessionKey) return null;\n if (!CLARIFY_SUPPORTED_CHANNELS.has(ctx.channel)) return null;\n return (r) => req(ctx.sessionKey, r);\n },\n }),\n createTodoTool({\n getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n createUpdatePlanTool(),\n ...(getSkillMgr\n ? [\n createSkillsListTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n }),\n createSkillViewTool({\n getSkillManager: getSkillMgr,\n getSkillIndexingContext: this.deps.getSkillIndexingContext,\n registerSkillEnvPassthrough: this.deps.registerSkillEnvPassthrough,\n }),\n createSkillManageTool({\n getSkillManager: getSkillMgr,\n getWorkspace: () => workspace,\n onSkillsFilesystemMutate: this.deps.onSkillsFilesystemMutate,\n }),\n ]\n : []),\n readTool,\n writeTool,\n applyPatchTool,\n listDir,\n grep,\n find,\n createExecCommandTool(workspace, {\n getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,\n recordGoalEvidence,\n }),\n createWebSearchTool(() => this.deps.getConfig?.()),\n createWebFetchTool(() => this.deps.getConfig?.()),\n createWebExtractTool({ getConfig: () => this.deps.getConfig?.() }),\n // Note: TTS is NOT handled by send_message tool anymore\n // TTS is applied at the ChannelManager dispatch layer\n createMessageTool(bus, () => this.deps.getCurrentContext()),\n ...(mergeTtsConfigFromAppConfig(cfg?.messages?.tts).enabled\n ? [\n createTextToSpeechTool({\n bus,\n getContext: () => this.deps.getCurrentContext(),\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n createSendMediaTool(workspace, bus, () => this.deps.getCurrentContext()),\n createReadMediaTool(),\n ...(isShareToolAvailable(cfg)\n ? [\n createCreateShareTool({\n workspace,\n getConfig: () => this.deps.getConfig?.(),\n }),\n ]\n : []),\n ...(getMemMgr\n ? [\n createMemorySearchTool({ workspaceDir: workspace, dreamingRoot, getMemoryManager: () => getMemMgr() }),\n createMemoryGetTool({ workspaceDir: workspace, dreamingRoot, getMemoryManager: () => getMemMgr() }),\n ]\n : []),\n ...(getMemMgr && shouldRegisterCuratedMemoryTool(this.deps.getConfig?.())\n ? [\n createCuratedMemoryTool(() => getMemMgr()),\n ]\n : []),\n ...(getMemMgr?.().getAdditionalTools() ?? []),\n ...(this.deps.getSessionStore\n ? [\n createSessionSearchTool({\n getSessionStore: this.deps.getSessionStore,\n getConfig: this.deps.getConfig,\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ]\n : []),\n ...(this.deps.getAutomationService\n ? [\n createAutomationTool({\n getAutomationService: this.deps.getAutomationService,\n }),\n ]\n : []),\n createGoalTool({\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n }),\n ...(browserEnabled\n ? [\n createBrowserUseTool({\n getManager: () => this.ensureBrowserManager(),\n getPageForTask: () => this.acquireBrowserPage(),\n getTaskId: () => this.deps.getCurrentContext()?.sessionKey ?? 'default',\n getConfig: () => this.deps.getConfig?.(),\n getReadiness: () => this.checkBrowserReadinessCached(),\n getSupervisor: () =>\n this.browserSupervisorForTask(this.deps.getCurrentContext()?.sessionKey ?? 'default'),\n notifyBrowserPageClosed: (taskId) => {\n this.browserTaskSupervisors.delete(taskId);\n },\n }),\n ]\n : []),\n ...(primary\n ? [\n createWorkflowTool({\n catalog: createWorkflowCatalog(),\n getCurrentSessionKey: () => this.deps.getCurrentContext()?.sessionKey,\n getConfig: () => this.deps.getConfig?.(),\n startWorkflowRun: this.deps.getWorkflowRunService\n ? (params) => this.deps.getWorkflowRunService!().startWorkflowRun(params)\n : undefined,\n }),\n ]\n : []),\n ...(false && primary\n ? [\n createDelegateTool({\n workspace,\n getSubagentModel: () => {\n const gp = options?.getPrimaryModel ?? this.deps.getPrimaryModel;\n const m = gp?.();\n if (!m) {\n throw new Error('No primary model configured for delegate_task');\n }\n return m;\n },\n bus: this.deps.bus,\n getConfig: () => this.deps.getConfig?.(),\n getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,\n hookRunner: this.deps.hookRunner,\n toolExecutorConfig: this.deps.toolExecutorConfig,\n // Injected so `child-agent-factory.ts` does not need to import\n // `AgentToolsFactory` directly (which would form a cycle).\n buildChildTools: (childOpts) => {\n const childFactory = new AgentToolsFactory({\n workspace: childOpts.workspace,\n bus: childOpts.bus,\n getCurrentContext: () => null,\n getConfig: childOpts.getConfig,\n getPrimaryModel: () => childOpts.model,\n toolExecutorConfig: childOpts.toolExecutorConfig,\n });\n return childFactory.createAllTools({\n workspace: childOpts.workspace,\n getPrimaryModel: () => childOpts.model,\n agentId: options?.agentId ?? childOpts.agentId,\n dreamingRoot: options?.dreamingRoot,\n disabledTools: new Set(['extensions']),\n });\n },\n }),\n ]\n : []),\n ...optionalTools,\n ];\n\n return filterToolsByDisabledSet(core, disabled);\n }\n\n createAllTools(coreOptions?: CreateCoreToolsOptions): AgentTool<any, any>[] {\n const coreTools = this.createCoreTools(coreOptions);\n const disableExtensions = coreOptions?.disabledTools?.has('extensions');\n\n let bundled: AgentTool<any, any>[];\n if (!this.deps.extensionRegistry || disableExtensions) {\n bundled = coreTools;\n } else {\n const extensionTools = this.deps.extensionRegistry.getAllTools();\n log.info({ count: extensionTools.length }, 'Loaded extension tools');\n bundled = [...coreTools, ...extensionTools];\n }\n\n const wrapped = wrapToolsWithProtection(bundled, this.deps.toolExecutorConfig);\n\n const executeEnabled = false && !coreOptions?.disabledTools?.has('execute_code');\n\n if (executeEnabled) {\n const sandboxMap = buildSandboxToolMap(wrapped);\n const executeTool = createExecuteCodeTool({ getSandboxToolMap: () => sandboxMap });\n const wrappedExecute = wrapToolsWithProtection([executeTool as any], this.deps.toolExecutorConfig);\n return [...wrapped, ...wrappedExecute];\n }\n\n return wrapped;\n }\n}\n\nfunction filterToolsByDisabledSet(\n tools: any[],\n disabled: Set<string> | undefined,\n): any[] {\n if (!disabled || disabled.size === 0) {\n return tools;\n }\n return tools.filter((t) => !disabled.has(t.name));\n}\n"],"mappings":"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"}
@@ -20,6 +20,8 @@ function createFindTool(cwd) {
20
20
  label: "📁 find",
21
21
  description: "Find files by glob pattern (e.g., *.ts, **/*.json).",
22
22
  parameters: findSchema,
23
+ supportsParallel: true,
24
+ idempotent: true,
23
25
  execute: async (_toolCallId, params, signal) => {
24
26
  try {
25
27
  const p = params;
@@ -1 +1 @@
1
- {"version":3,"file":"find.js","names":[],"sources":["../../../../src/agent/tools/find.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { existsSync } from 'fs';\nimport { globSync } from 'glob';\nimport path from 'path';\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from './truncate.js';\nimport { resolveToCwd } from '../../utils/helpers.js';\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: 'Directory to search in (default: current directory)' })),\n\tlimit: Type.Optional(Type.Number({ description: 'Maximum number of results (default: 1000)' })),\n});\n\nexport type FindToolInput = { pattern: string; path?: string; limit?: number };\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\n/**\n * Find tool - Search for files by glob pattern\n */\nexport function createFindTool(cwd: string): AgentTool {\n\treturn {\n\t\tname: 'find',\n\t\tlabel: '📁 find',\n\t\tdescription: 'Find files by glob pattern (e.g., *.ts, **/*.json).',\n\t\tparameters: findSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\tparams: any,\n\t\t\tsignal?: AbortSignal\n\t\t): Promise<AgentToolResult<FindToolDetails>> => {\n\t\t\ttry {\n\t\t\t\tconst p = params as FindToolInput;\n\t\t\t\tconst searchPath = resolveToCwd(p.path || '.', cwd);\n\t\t\t\tconst effectiveLimit = p.limit || DEFAULT_LIMIT;\n\n\t\t\t\tif (!existsSync(searchPath)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: `Error: Path not found: ${searchPath}` }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: 'Operation aborted' }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst filePaths = globSync(p.pattern, {\n\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\tdot: true,\n\t\t\t\t\tignore: ['**/node_modules/**', '**/.git/**'],\n\t\t\t\t});\n\n\t\t\t\tif (filePaths.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: 'No files found matching pattern' }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Relativize paths\n\t\t\t\tconst relativized = filePaths.map((p) => {\n\t\t\t\t\tif (p.startsWith(searchPath)) {\n\t\t\t\t\t\treturn p.slice(searchPath.length + 1);\n\t\t\t\t\t}\n\t\t\t\t\treturn path.relative(searchPath, p);\n\t\t\t\t});\n\n\t\t\t\t// Sort results\n\t\t\t\trelativized.sort();\n\n\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\tconst outputLines = resultLimitReached ? relativized.slice(0, effectiveLimit) : relativized;\n\t\t\t\tconst rawOutput = outputLines.join('\\n');\n\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\n\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\tconst notices: string[] = [];\n\n\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\tnotices.push(`${effectiveLimit} results limit reached`);\n\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t}\n\n\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t}\n\n\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\tresultOutput += `\\n\\n[${notices.join('. ')}]`;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: 'text', text: resultOutput }],\n\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\ttext: `Error during find: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t} as any;\n}\n\n/** Default find tool using process.cwd() */\nexport const findTool: AgentTool = createFindTool(process.cwd());\n"],"mappings":";;;;;;;AAQA,MAAM,aAAa,KAAK,OAAO;CAC9B,SAAS,KAAK,OAAO,EACpB,aAAa,gFACb,CAAC;CACF,MAAM,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,uDAAuD,CAAC,CAAC;CACxG,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,6CAA6C,CAAC,CAAC;CAC/F,CAAC;AAIF,MAAM,gBAAgB;;;;AAUtB,SAAgB,eAAe,KAAwB;AACtD,QAAO;EACN,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY;EACZ,SAAS,OACR,aACA,QACA,WAC+C;AAC/C,OAAI;IACH,MAAM,IAAI;IACV,MAAM,aAAa,aAAa,EAAE,QAAQ,KAAK,IAAI;IACnD,MAAM,iBAAiB,EAAE,SAAS;AAElC,QAAI,CAAC,WAAW,WAAW,CAC1B,QAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,0BAA0B;MAAc,CAAC;KACzE,SAAS,EAAE;KACX;AAGF,QAAI,QAAQ,QACX,QAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAqB,CAAC;KACtD,SAAS,EAAE;KACX;IAGF,MAAM,YAAY,SAAS,EAAE,SAAS;KACrC,KAAK;KACL,KAAK;KACL,QAAQ,CAAC,sBAAsB,aAAa;KAC5C,CAAC;AAEF,QAAI,UAAU,WAAW,EACxB,QAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAmC,CAAC;KACpE,SAAS,EAAE;KACX;IAIF,MAAM,cAAc,UAAU,KAAK,MAAM;AACxC,SAAI,EAAE,WAAW,WAAW,CAC3B,QAAO,EAAE,MAAM,WAAW,SAAS,EAAE;AAEtC,YAAO,KAAK,SAAS,YAAY,EAAE;MAClC;AAGF,gBAAY,MAAM;IAElB,MAAM,qBAAqB,YAAY,UAAU;IAGjD,MAAM,aAAa,cAFC,qBAAqB,YAAY,MAAM,GAAG,eAAe,GAAG,aAClD,KAAK,KACM,EAAE,EAAE,UAAU,OAAO,kBAAkB,CAAC;IAEjF,IAAI,eAAe,WAAW;IAC9B,MAAM,UAA2B,EAAE;IACnC,MAAM,UAAoB,EAAE;AAE5B,QAAI,oBAAoB;AACvB,aAAQ,KAAK,GAAG,eAAe,wBAAwB;AACvD,aAAQ,qBAAqB;;AAG9B,QAAI,WAAW,WAAW;AACzB,aAAQ,KAAK,GAAG,WAAW,kBAAkB,CAAC,gBAAgB;AAC9D,aAAQ,aAAa;;AAGtB,QAAI,QAAQ,SAAS,EACpB,iBAAgB,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAG5C,WAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAc,CAAC;KAC/C,SAAS,OAAO,KAAK,QAAQ,CAAC,SAAS,IAAI,UAAU,KAAA;KACrD;YACO,OAAO;AACf,WAAO;KACN,SAAS,CACR;MACC,MAAM;MACN,MAAM,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;MAClF,CACD;KACD,SAAS,EAAE;KACX;;;EAGH;;;AAIF,MAAa,WAAsB,eAAe,QAAQ,KAAK,CAAC"}
1
+ {"version":3,"file":"find.js","names":[],"sources":["../../../../src/agent/tools/find.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { existsSync } from 'fs';\nimport { globSync } from 'glob';\nimport path from 'path';\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from './truncate.js';\nimport { resolveToCwd } from '../../utils/helpers.js';\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: 'Directory to search in (default: current directory)' })),\n\tlimit: Type.Optional(Type.Number({ description: 'Maximum number of results (default: 1000)' })),\n});\n\nexport type FindToolInput = { pattern: string; path?: string; limit?: number };\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\n/**\n * Find tool - Search for files by glob pattern\n */\nexport function createFindTool(cwd: string): AgentTool {\n\treturn {\n\t\tname: 'find',\n\t\tlabel: '📁 find',\n\t\tdescription: 'Find files by glob pattern (e.g., *.ts, **/*.json).',\n\t\tparameters: findSchema,\n\t\tsupportsParallel: true,\n\t\tidempotent: true,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\tparams: any,\n\t\t\tsignal?: AbortSignal\n\t\t): Promise<AgentToolResult<FindToolDetails>> => {\n\t\t\ttry {\n\t\t\t\tconst p = params as FindToolInput;\n\t\t\t\tconst searchPath = resolveToCwd(p.path || '.', cwd);\n\t\t\t\tconst effectiveLimit = p.limit || DEFAULT_LIMIT;\n\n\t\t\t\tif (!existsSync(searchPath)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: `Error: Path not found: ${searchPath}` }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: 'Operation aborted' }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst filePaths = globSync(p.pattern, {\n\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\tdot: true,\n\t\t\t\t\tignore: ['**/node_modules/**', '**/.git/**'],\n\t\t\t\t});\n\n\t\t\t\tif (filePaths.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: 'No files found matching pattern' }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Relativize paths\n\t\t\t\tconst relativized = filePaths.map((p) => {\n\t\t\t\t\tif (p.startsWith(searchPath)) {\n\t\t\t\t\t\treturn p.slice(searchPath.length + 1);\n\t\t\t\t\t}\n\t\t\t\t\treturn path.relative(searchPath, p);\n\t\t\t\t});\n\n\t\t\t\t// Sort results\n\t\t\t\trelativized.sort();\n\n\t\t\t\tconst resultLimitReached = relativized.length >= effectiveLimit;\n\t\t\t\tconst outputLines = resultLimitReached ? relativized.slice(0, effectiveLimit) : relativized;\n\t\t\t\tconst rawOutput = outputLines.join('\\n');\n\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\n\t\t\t\tlet resultOutput = truncation.content;\n\t\t\t\tconst details: FindToolDetails = {};\n\t\t\t\tconst notices: string[] = [];\n\n\t\t\t\tif (resultLimitReached) {\n\t\t\t\t\tnotices.push(`${effectiveLimit} results limit reached`);\n\t\t\t\t\tdetails.resultLimitReached = effectiveLimit;\n\t\t\t\t}\n\n\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t}\n\n\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\tresultOutput += `\\n\\n[${notices.join('. ')}]`;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: 'text', text: resultOutput }],\n\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\ttext: `Error during find: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t} as any;\n}\n\n/** Default find tool using process.cwd() */\nexport const findTool: AgentTool = createFindTool(process.cwd());\n"],"mappings":";;;;;;;AAQA,MAAM,aAAa,KAAK,OAAO;CAC9B,SAAS,KAAK,OAAO,EACpB,aAAa,gFACb,CAAC;CACF,MAAM,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,uDAAuD,CAAC,CAAC;CACxG,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,6CAA6C,CAAC,CAAC;CAC/F,CAAC;AAIF,MAAM,gBAAgB;;;;AAUtB,SAAgB,eAAe,KAAwB;AACtD,QAAO;EACN,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY;EACZ,kBAAkB;EAClB,YAAY;EACZ,SAAS,OACR,aACA,QACA,WAC+C;AAC/C,OAAI;IACH,MAAM,IAAI;IACV,MAAM,aAAa,aAAa,EAAE,QAAQ,KAAK,IAAI;IACnD,MAAM,iBAAiB,EAAE,SAAS;AAElC,QAAI,CAAC,WAAW,WAAW,CAC1B,QAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,0BAA0B;MAAc,CAAC;KACzE,SAAS,EAAE;KACX;AAGF,QAAI,QAAQ,QACX,QAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAqB,CAAC;KACtD,SAAS,EAAE;KACX;IAGF,MAAM,YAAY,SAAS,EAAE,SAAS;KACrC,KAAK;KACL,KAAK;KACL,QAAQ,CAAC,sBAAsB,aAAa;KAC5C,CAAC;AAEF,QAAI,UAAU,WAAW,EACxB,QAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAmC,CAAC;KACpE,SAAS,EAAE;KACX;IAIF,MAAM,cAAc,UAAU,KAAK,MAAM;AACxC,SAAI,EAAE,WAAW,WAAW,CAC3B,QAAO,EAAE,MAAM,WAAW,SAAS,EAAE;AAEtC,YAAO,KAAK,SAAS,YAAY,EAAE;MAClC;AAGF,gBAAY,MAAM;IAElB,MAAM,qBAAqB,YAAY,UAAU;IAGjD,MAAM,aAAa,cAFC,qBAAqB,YAAY,MAAM,GAAG,eAAe,GAAG,aAClD,KAAK,KACM,EAAE,EAAE,UAAU,OAAO,kBAAkB,CAAC;IAEjF,IAAI,eAAe,WAAW;IAC9B,MAAM,UAA2B,EAAE;IACnC,MAAM,UAAoB,EAAE;AAE5B,QAAI,oBAAoB;AACvB,aAAQ,KAAK,GAAG,eAAe,wBAAwB;AACvD,aAAQ,qBAAqB;;AAG9B,QAAI,WAAW,WAAW;AACzB,aAAQ,KAAK,GAAG,WAAW,kBAAkB,CAAC,gBAAgB;AAC9D,aAAQ,aAAa;;AAGtB,QAAI,QAAQ,SAAS,EACpB,iBAAgB,QAAQ,QAAQ,KAAK,KAAK,CAAC;AAG5C,WAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAc,CAAC;KAC/C,SAAS,OAAO,KAAK,QAAQ,CAAC,SAAS,IAAI,UAAU,KAAA;KACrD;YACO,OAAO;AACf,WAAO;KACN,SAAS,CACR;MACC,MAAM;MACN,MAAM,sBAAsB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;MAClF,CACD;KACD,SAAS,EAAE;KACX;;;EAGH;;;AAIF,MAAa,WAAsB,eAAe,QAAQ,KAAK,CAAC"}
@@ -39,6 +39,8 @@ function createGrepTool(cwd) {
39
39
  label: "🔍 grep",
40
40
  description: "Search file contents for a pattern (regex or literal).",
41
41
  parameters: grepSchema,
42
+ supportsParallel: true,
43
+ idempotent: true,
42
44
  execute: async (_toolCallId, params, signal) => {
43
45
  try {
44
46
  const p = params;
@@ -1 +1 @@
1
- {"version":3,"file":"grep.js","names":[],"sources":["../../../../src/agent/tools/grep.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { readFileSync, existsSync, statSync } from 'fs';\nimport { globSync } from 'glob';\nimport path from 'path';\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from './truncate.js';\nimport { resolveToCwd } from '../../utils/helpers.js';\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: 'Search pattern (regex or literal string)' }),\n\tpath: Type.Optional(Type.String({ description: 'Directory or file to search (default: current directory)' })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: 'Case-insensitive search (default: false)' })),\n\tliteral: Type.Optional(Type.Boolean({ description: 'Treat pattern as literal string instead of regex (default: false)' })),\n\tcontext: Type.Optional(Type.Number({ description: 'Number of lines to show before and after each match (default: 0)' })),\n\tlimit: Type.Optional(Type.Number({ description: 'Maximum number of matches to return (default: 100)' })),\n});\n\nexport type GrepToolInput = {\n\tpattern: string;\n\tpath?: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontext?: number;\n\tlimit?: number;\n};\n\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\n/**\n * Simple grep implementation using Node.js regex\n */\nfunction simpleGrep(\n\tcontent: string,\n\tpattern: string,\n\toptions: { ignoreCase: boolean; literal: boolean }\n): Array<{ lineNumber: number; line: string }> {\n\tconst matches: Array<{ lineNumber: number; line: string }> = [];\n\tconst lines = content.split('\\n');\n\tconst regexPattern = options.literal\n\t\t? pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\t\t: pattern;\n\tconst flags = options.ignoreCase ? 'i' : '';\n\tconst regex = new RegExp(regexPattern, flags);\n\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tif (regex.test(lines[i])) {\n\t\t\tmatches.push({ lineNumber: i + 1, line: lines[i] });\n\t\t}\n\t}\n\n\treturn matches;\n}\n\n/**\n * Grep tool - Search file contents for a pattern\n */\nexport function createGrepTool(cwd: string): AgentTool {\n\treturn {\n\t\tname: 'grep',\n\t\tlabel: '🔍 grep',\n\t\tdescription: 'Search file contents for a pattern (regex or literal).',\n\t\tparameters: grepSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\tparams: any,\n\t\t\tsignal?: AbortSignal\n\t\t): Promise<AgentToolResult<GrepToolDetails>> => {\n\t\t\ttry {\n\t\t\t\tconst p = params as GrepToolInput;\n\t\t\t\tconst searchPath = resolveToCwd(p.path || '.', cwd);\n\t\t\t\t\n\t\t\t\tif (!existsSync(searchPath)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: `Error: Path not found: ${searchPath}` }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst isDirectory = statSync(searchPath).isDirectory();\n\t\t\t\tconst context = p.context || 0;\n\t\t\t\tconst effectiveLimit = p.limit || DEFAULT_LIMIT;\n\t\t\t\tconst files: string[] = [];\n\n\t\t\t\t// Collect files to search\n\t\t\t\tif (isDirectory) {\n\t\t\t\t\tconst globPattern = p.glob || '**/*';\n\t\t\t\t\tconst filePaths = globSync(globPattern, {\n\t\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\t\tdot: true,\n\t\t\t\t\t\tignore: ['**/node_modules/**', '**/.git/**'],\n\t\t\t\t\t});\n\t\t\t\t\tfiles.push(...filePaths.map(f => path.join(searchPath, f)));\n\t\t\t\t} else {\n\t\t\t\t\tfiles.push(searchPath);\n\t\t\t\t}\n\n\t\t\t\tconst matches: Array<{ file: string; lineNumber: number; line: string }> = [];\n\t\t\t\tlet matchCount = 0;\n\t\t\t\tlet linesTruncated = false;\n\n\t\t\t\t// Search each file\n\t\t\t\tfor (const filePath of files) {\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: 'text', text: 'Operation aborted' }],\n\t\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!existsSync(filePath)) continue;\n\t\t\t\t\t\tconst content = readFileSync(filePath, 'utf-8');\n\t\t\t\t\t\tconst fileMatches = simpleGrep(content, p.pattern, {\n\t\t\t\t\t\t\tignoreCase: p.ignoreCase || false,\n\t\t\t\t\t\t\tliteral: p.literal || false,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tfor (const match of fileMatches) {\n\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) break;\n\t\t\t\t\t\t\tmatches.push({ file: filePath, ...match });\n\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Skip files that can't be read\n\t\t\t\t\t}\n\n\t\t\t\t\tif (matchCount >= effectiveLimit) break;\n\t\t\t\t}\n\n\t\t\t\tif (matches.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: 'No matches found' }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Format output\n\t\t\t\tconst outputLines: string[] = [];\n\t\t\t\tconst basePath = isDirectory ? searchPath : path.dirname(searchPath);\n\n\t\t\t\tfor (const match of matches) {\n\t\t\t\t\tconst relativePath = path.relative(basePath, match.file);\n\t\t\t\t\tconst { text: truncatedLine, wasTruncated } = truncateLine(match.line);\n\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\n\t\t\t\t\tif (context > 0) {\n\t\t\t\t\t\t// Add context lines\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst content = readFileSync(match.file, 'utf-8');\n\t\t\t\t\t\t\tconst allLines = content.split('\\n');\n\t\t\t\t\t\t\tconst start = Math.max(1, match.lineNumber - context);\n\t\t\t\t\t\t\tconst end = Math.min(allLines.length, match.lineNumber + context);\n\n\t\t\t\t\t\t\tfor (let i = start; i <= end; i++) {\n\t\t\t\t\t\t\t\tconst lineText = allLines[i - 1] || '';\n\t\t\t\t\t\t\t\tconst { text: truncatedContextLine } = truncateLine(lineText);\n\t\t\t\t\t\t\t\tif (i === match.lineNumber) {\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${i}: ${truncatedContextLine}`);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}-${i}- ${truncatedContextLine}`);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedLine}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedLine}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst rawOutput = outputLines.join('\\n');\n\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\n\t\t\t\tlet output = truncation.content;\n\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\tconst notices: string[] = [];\n\n\t\t\t\tif (matches.length >= effectiveLimit) {\n\t\t\t\t\tnotices.push(`${effectiveLimit} matches limit reached`);\n\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t}\n\n\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t}\n\n\t\t\t\tif (linesTruncated) {\n\t\t\t\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars`);\n\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t}\n\n\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\toutput += `\\n\\n[${notices.join('. ')}]`;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: 'text', text: output }],\n\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\ttext: `Error during grep: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t} as any;\n}\n\n/** Default grep tool using process.cwd() */\nexport const grepTool: AgentTool = createGrepTool(process.cwd());\n"],"mappings":"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"}
1
+ {"version":3,"file":"grep.js","names":[],"sources":["../../../../src/agent/tools/grep.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { readFileSync, existsSync, statSync } from 'fs';\nimport { globSync } from 'glob';\nimport path from 'path';\nimport {\n\tDEFAULT_MAX_BYTES,\n\tformatSize,\n\tGREP_MAX_LINE_LENGTH,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n} from './truncate.js';\nimport { resolveToCwd } from '../../utils/helpers.js';\n\nconst grepSchema = Type.Object({\n\tpattern: Type.String({ description: 'Search pattern (regex or literal string)' }),\n\tpath: Type.Optional(Type.String({ description: 'Directory or file to search (default: current directory)' })),\n\tglob: Type.Optional(Type.String({ description: \"Filter files by glob pattern, e.g. '*.ts'\" })),\n\tignoreCase: Type.Optional(Type.Boolean({ description: 'Case-insensitive search (default: false)' })),\n\tliteral: Type.Optional(Type.Boolean({ description: 'Treat pattern as literal string instead of regex (default: false)' })),\n\tcontext: Type.Optional(Type.Number({ description: 'Number of lines to show before and after each match (default: 0)' })),\n\tlimit: Type.Optional(Type.Number({ description: 'Maximum number of matches to return (default: 100)' })),\n});\n\nexport type GrepToolInput = {\n\tpattern: string;\n\tpath?: string;\n\tglob?: string;\n\tignoreCase?: boolean;\n\tliteral?: boolean;\n\tcontext?: number;\n\tlimit?: number;\n};\n\nconst DEFAULT_LIMIT = 100;\n\nexport interface GrepToolDetails {\n\ttruncation?: TruncationResult;\n\tmatchLimitReached?: number;\n\tlinesTruncated?: boolean;\n}\n\n/**\n * Simple grep implementation using Node.js regex\n */\nfunction simpleGrep(\n\tcontent: string,\n\tpattern: string,\n\toptions: { ignoreCase: boolean; literal: boolean }\n): Array<{ lineNumber: number; line: string }> {\n\tconst matches: Array<{ lineNumber: number; line: string }> = [];\n\tconst lines = content.split('\\n');\n\tconst regexPattern = options.literal\n\t\t? pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\t\t: pattern;\n\tconst flags = options.ignoreCase ? 'i' : '';\n\tconst regex = new RegExp(regexPattern, flags);\n\n\tfor (let i = 0; i < lines.length; i++) {\n\t\tif (regex.test(lines[i])) {\n\t\t\tmatches.push({ lineNumber: i + 1, line: lines[i] });\n\t\t}\n\t}\n\n\treturn matches;\n}\n\n/**\n * Grep tool - Search file contents for a pattern\n */\nexport function createGrepTool(cwd: string): AgentTool {\n\treturn {\n\t\tname: 'grep',\n\t\tlabel: '🔍 grep',\n\t\tdescription: 'Search file contents for a pattern (regex or literal).',\n\t\tparameters: grepSchema,\n\t\tsupportsParallel: true,\n\t\tidempotent: true,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\tparams: any,\n\t\t\tsignal?: AbortSignal\n\t\t): Promise<AgentToolResult<GrepToolDetails>> => {\n\t\t\ttry {\n\t\t\t\tconst p = params as GrepToolInput;\n\t\t\t\tconst searchPath = resolveToCwd(p.path || '.', cwd);\n\t\t\t\t\n\t\t\t\tif (!existsSync(searchPath)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: `Error: Path not found: ${searchPath}` }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst isDirectory = statSync(searchPath).isDirectory();\n\t\t\t\tconst context = p.context || 0;\n\t\t\t\tconst effectiveLimit = p.limit || DEFAULT_LIMIT;\n\t\t\t\tconst files: string[] = [];\n\n\t\t\t\t// Collect files to search\n\t\t\t\tif (isDirectory) {\n\t\t\t\t\tconst globPattern = p.glob || '**/*';\n\t\t\t\t\tconst filePaths = globSync(globPattern, {\n\t\t\t\t\t\tcwd: searchPath,\n\t\t\t\t\t\tdot: true,\n\t\t\t\t\t\tignore: ['**/node_modules/**', '**/.git/**'],\n\t\t\t\t\t});\n\t\t\t\t\tfiles.push(...filePaths.map(f => path.join(searchPath, f)));\n\t\t\t\t} else {\n\t\t\t\t\tfiles.push(searchPath);\n\t\t\t\t}\n\n\t\t\t\tconst matches: Array<{ file: string; lineNumber: number; line: string }> = [];\n\t\t\t\tlet matchCount = 0;\n\t\t\t\tlet linesTruncated = false;\n\n\t\t\t\t// Search each file\n\t\t\t\tfor (const filePath of files) {\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: 'text', text: 'Operation aborted' }],\n\t\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!existsSync(filePath)) continue;\n\t\t\t\t\t\tconst content = readFileSync(filePath, 'utf-8');\n\t\t\t\t\t\tconst fileMatches = simpleGrep(content, p.pattern, {\n\t\t\t\t\t\t\tignoreCase: p.ignoreCase || false,\n\t\t\t\t\t\t\tliteral: p.literal || false,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tfor (const match of fileMatches) {\n\t\t\t\t\t\t\tif (matchCount >= effectiveLimit) break;\n\t\t\t\t\t\t\tmatches.push({ file: filePath, ...match });\n\t\t\t\t\t\t\tmatchCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Skip files that can't be read\n\t\t\t\t\t}\n\n\t\t\t\t\tif (matchCount >= effectiveLimit) break;\n\t\t\t\t}\n\n\t\t\t\tif (matches.length === 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: 'text', text: 'No matches found' }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Format output\n\t\t\t\tconst outputLines: string[] = [];\n\t\t\t\tconst basePath = isDirectory ? searchPath : path.dirname(searchPath);\n\n\t\t\t\tfor (const match of matches) {\n\t\t\t\t\tconst relativePath = path.relative(basePath, match.file);\n\t\t\t\t\tconst { text: truncatedLine, wasTruncated } = truncateLine(match.line);\n\t\t\t\t\tif (wasTruncated) linesTruncated = true;\n\n\t\t\t\t\tif (context > 0) {\n\t\t\t\t\t\t// Add context lines\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst content = readFileSync(match.file, 'utf-8');\n\t\t\t\t\t\t\tconst allLines = content.split('\\n');\n\t\t\t\t\t\t\tconst start = Math.max(1, match.lineNumber - context);\n\t\t\t\t\t\t\tconst end = Math.min(allLines.length, match.lineNumber + context);\n\n\t\t\t\t\t\t\tfor (let i = start; i <= end; i++) {\n\t\t\t\t\t\t\t\tconst lineText = allLines[i - 1] || '';\n\t\t\t\t\t\t\t\tconst { text: truncatedContextLine } = truncateLine(lineText);\n\t\t\t\t\t\t\t\tif (i === match.lineNumber) {\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${i}: ${truncatedContextLine}`);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\toutputLines.push(`${relativePath}-${i}- ${truncatedContextLine}`);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedLine}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutputLines.push(`${relativePath}:${match.lineNumber}: ${truncatedLine}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst rawOutput = outputLines.join('\\n');\n\t\t\t\tconst truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });\n\n\t\t\t\tlet output = truncation.content;\n\t\t\t\tconst details: GrepToolDetails = {};\n\t\t\t\tconst notices: string[] = [];\n\n\t\t\t\tif (matches.length >= effectiveLimit) {\n\t\t\t\t\tnotices.push(`${effectiveLimit} matches limit reached`);\n\t\t\t\t\tdetails.matchLimitReached = effectiveLimit;\n\t\t\t\t}\n\n\t\t\t\tif (truncation.truncated) {\n\t\t\t\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\t\t\t\tdetails.truncation = truncation;\n\t\t\t\t}\n\n\t\t\t\tif (linesTruncated) {\n\t\t\t\t\tnotices.push(`Some lines truncated to ${GREP_MAX_LINE_LENGTH} chars`);\n\t\t\t\t\tdetails.linesTruncated = true;\n\t\t\t\t}\n\n\t\t\t\tif (notices.length > 0) {\n\t\t\t\t\toutput += `\\n\\n[${notices.join('. ')}]`;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: 'text', text: output }],\n\t\t\t\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\ttext: `Error during grep: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t} as any;\n}\n\n/** Default grep tool using process.cwd() */\nexport const grepTool: AgentTool = createGrepTool(process.cwd());\n"],"mappings":"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"}
@@ -1,8 +1,10 @@
1
+ export { getToolMetadata, DEFAULT_TOOL_METADATA, type AgentToolWithMetadata, type ToolMutationScope, type ToolVerificationKind, type XopcToolMetadata, } from './metadata.js';
2
+ export { ToolConcurrencyController, resolveToolLockMode, type ToolLockMode, } from './concurrency.js';
1
3
  export { createReadFileTool, type CreateReadFileToolOptions } from './read.js';
2
4
  export { createWriteFileTool, writeFileTool } from './write.js';
3
- export { createEditFileTool, editFileTool, type EditToolDetails } from './edit.js';
4
5
  export { createListDirTool, listDirTool } from './list-dir.js';
5
- export { createShellTool } from './shell.js';
6
+ export { createExecCommandTool, type ExecCommandDetails, type ExecCommandUpdateDetails, } from './exec-command.js';
7
+ export { createApplyPatchTool, type AppliedPatchChange, type ApplyPatchDetails, } from './apply-patch.js';
6
8
  export { createMemorySearchTool, createMemoryGetTool, type MemoryToolOptions, } from './memory-tool.js';
7
9
  export { createCuratedMemoryTool } from './curated-memory-tool.js';
8
10
  export { createSessionSearchTool } from './session-search-tool.js';
@@ -16,6 +18,7 @@ export { createSendMediaTool } from './send-media.js';
16
18
  export { createReadMediaTool } from './media-read-tool.js';
17
19
  export { createCreateShareTool, isShareToolAvailable, type CreateShareToolDeps, } from './create-share-tool.js';
18
20
  export { createTodoTool, TodoStore, type TodoItem, type TodoStatus } from './todo-tool.js';
21
+ export { createUpdatePlanTool, type TurnPlanDetails, type TurnPlanStatus, type TurnPlanStep, } from './update-plan-tool.js';
19
22
  export { createSessionStatusTool } from './session-status-tool.js';
20
23
  export { createDreamingTool, type DreamingToolDeps } from './dreaming-tool.js';
21
24
  export { createClarifyTool, type ClarifyRequestPayload, type GatewayClarifyRequestFn, } from './clarify-tool.js';
@@ -1,10 +1,12 @@
1
+ import { DEFAULT_TOOL_METADATA, getToolMetadata } from "./metadata.js";
2
+ import { ToolConcurrencyController, resolveToolLockMode } from "./concurrency.js";
1
3
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, GREP_MAX_LINE_LENGTH, formatSize, truncateHead, truncateLine, truncateTail } from "./truncate.js";
2
4
  import { createReadFileTool } from "./read.js";
3
5
  import { createWriteFileTool, writeFileTool } from "./write.js";
4
- import { fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom } from "./edit-diff.js";
5
- import { createEditFileTool, editFileTool } from "./edit.js";
6
6
  import { createListDirTool, listDirTool } from "./list-dir.js";
7
- import { createShellTool } from "./shell.js";
7
+ import { createExecCommandTool } from "./exec-command.js";
8
+ import { fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom } from "./edit-diff.js";
9
+ import { createApplyPatchTool } from "./apply-patch.js";
8
10
  import { createMemoryGetTool, createMemorySearchTool } from "./memory-tool.js";
9
11
  import { createCuratedMemoryTool } from "./curated-memory-tool.js";
10
12
  import { createSessionSearchTool } from "./session-search-tool.js";
@@ -18,6 +20,7 @@ import { createSendMediaTool } from "./send-media.js";
18
20
  import { createReadMediaTool } from "./media-read-tool.js";
19
21
  import { createCreateShareTool, isShareToolAvailable } from "./create-share-tool.js";
20
22
  import { TodoStore, createTodoTool } from "./todo-tool.js";
23
+ import { createUpdatePlanTool } from "./update-plan-tool.js";
21
24
  import { createSessionStatusTool } from "./session-status-tool.js";
22
25
  import { createDreamingTool } from "./dreaming-tool.js";
23
26
  import { createClarifyTool } from "./clarify-tool.js";
@@ -35,4 +38,4 @@ import { createToolManualTool } from "./tool-manual-tool.js";
35
38
  import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
36
39
  import { createImageTool } from "./image-tool.js";
37
40
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
38
- export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, assertBrowserUrlAllowed, buildSandboxToolMap, createAutomationTool, createClarifyTool, createComposioExecuteTool, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createEditFileTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createShellTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createToolManualTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, editFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
41
+ export { BrowserManager, 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, SANDBOX_ALLOWED_TOOLS, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createClarifyTool, createComposioExecuteTool, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -9,6 +9,8 @@ function createListDirTool(workspace) {
9
9
  description: "List the contents of a directory. Relative paths are under the current agent workspace.",
10
10
  parameters: ListDirSchema,
11
11
  label: "📁 List Directory",
12
+ supportsParallel: true,
13
+ idempotent: true,
12
14
  async execute(_toolCallId, params, _signal) {
13
15
  try {
14
16
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"list-dir.js","names":["p"],"sources":["../../../../src/agent/tools/list-dir.ts"],"sourcesContent":["// List Directory Tool\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { readdir } from 'fs/promises';\nimport { resolvePathUnderWorkspace } from './tool-paths.js';\n\nconst ListDirSchema = Type.Object({\n path: Type.String({ description: 'The directory path to list' }),\n});\n\ntype ListDirParams = { path: string };\n\nexport function createListDirTool(workspace: string): AgentTool {\n return {\n name: 'list_dir',\n description: 'List the contents of a directory. Relative paths are under the current agent workspace.',\n parameters: ListDirSchema,\n label: '📁 List Directory',\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n try {\n const p = params as ListDirParams;\n const target = resolvePathUnderWorkspace(p.path, workspace);\n const entries = await readdir(target, { withFileTypes: true });\n const lines = entries.map((e) => {\n const type = e.isDirectory() ? 'd' : e.isFile() ? 'f' : '?';\n return `${type} ${e.name}`;\n });\n return {\n content: [{ type: 'text', text: lines.join('\\n') || '(empty)' }],\n details: {},\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Error listing directory: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: {},\n };\n }\n },\n } as any;\n}\n\nexport const listDirTool: AgentTool = createListDirTool(process.cwd());\n"],"mappings":";;;;AAMA,MAAM,gBAAgB,KAAK,OAAO,EAChC,MAAM,KAAK,OAAO,EAAE,aAAa,8BAA8B,CAAC,EACjE,CAAC;AAIF,SAAgB,kBAAkB,WAA8B;AAC9D,QAAO;EACL,MAAM;EACN,aAAa;EACb,YAAY;EACZ,OAAO;EAEP,MAAM,QACJ,aACA,QACA,SAC8B;AAC9B,OAAI;AAQF,WAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,OALd,MADQ,QADP,0BAA0BA,OAAE,MAAM,UACb,EAAE,EAAE,eAAe,MAAM,CAAC,EACxC,KAAK,MAAM;AAE/B,cAAO,GADM,EAAE,aAAa,GAAG,MAAM,EAAE,QAAQ,GAAG,MAAM,IACzC,GAAG,EAAE;QAGiB,CAAC,KAAK,KAAK,IAAI;MAAW,CAAC;KAChE,SAAS,EAAE;KACZ;YACM,OAAO;AACd,WAAO;KACL,SAAS,CACP;MACE,MAAM;MACN,MAAM,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;MACzF,CACF;KACD,SAAS,EAAE;KACZ;;;EAGN;;AAGH,MAAa,cAAyB,kBAAkB,QAAQ,KAAK,CAAC"}
1
+ {"version":3,"file":"list-dir.js","names":["p"],"sources":["../../../../src/agent/tools/list-dir.ts"],"sourcesContent":["// List Directory Tool\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { readdir } from 'fs/promises';\nimport { resolvePathUnderWorkspace } from './tool-paths.js';\n\nconst ListDirSchema = Type.Object({\n path: Type.String({ description: 'The directory path to list' }),\n});\n\ntype ListDirParams = { path: string };\n\nexport function createListDirTool(workspace: string): AgentTool {\n return {\n name: 'list_dir',\n description: 'List the contents of a directory. Relative paths are under the current agent workspace.',\n parameters: ListDirSchema,\n label: '📁 List Directory',\n supportsParallel: true,\n idempotent: true,\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n try {\n const p = params as ListDirParams;\n const target = resolvePathUnderWorkspace(p.path, workspace);\n const entries = await readdir(target, { withFileTypes: true });\n const lines = entries.map((e) => {\n const type = e.isDirectory() ? 'd' : e.isFile() ? 'f' : '?';\n return `${type} ${e.name}`;\n });\n return {\n content: [{ type: 'text', text: lines.join('\\n') || '(empty)' }],\n details: {},\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Error listing directory: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: {},\n };\n }\n },\n } as any;\n}\n\nexport const listDirTool: AgentTool = createListDirTool(process.cwd());\n"],"mappings":";;;;AAMA,MAAM,gBAAgB,KAAK,OAAO,EAChC,MAAM,KAAK,OAAO,EAAE,aAAa,8BAA8B,CAAC,EACjE,CAAC;AAIF,SAAgB,kBAAkB,WAA8B;AAC9D,QAAO;EACL,MAAM;EACN,aAAa;EACb,YAAY;EACZ,OAAO;EACP,kBAAkB;EAClB,YAAY;EAEZ,MAAM,QACJ,aACA,QACA,SAC8B;AAC9B,OAAI;AAQF,WAAO;KACL,SAAS,CAAC;MAAE,MAAM;MAAQ,OALd,MADQ,QADP,0BAA0BA,OAAE,MAAM,UACb,EAAE,EAAE,eAAe,MAAM,CAAC,EACxC,KAAK,MAAM;AAE/B,cAAO,GADM,EAAE,aAAa,GAAG,MAAM,EAAE,QAAQ,GAAG,MAAM,IACzC,GAAG,EAAE;QAGiB,CAAC,KAAK,KAAK,IAAI;MAAW,CAAC;KAChE,SAAS,EAAE;KACZ;YACM,OAAO;AACd,WAAO;KACL,SAAS,CACP;MACE,MAAM;MACN,MAAM,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;MACzF,CACF;KACD,SAAS,EAAE;KACZ;;;EAGN;;AAGH,MAAa,cAAyB,kBAAkB,QAAQ,KAAK,CAAC"}
@@ -2,6 +2,7 @@ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
2
  import type { MemoryManager } from '../memory/manager.js';
3
3
  export interface MemoryToolOptions {
4
4
  workspaceDir: string;
5
+ dreamingRoot: string;
5
6
  getMemoryManager: () => MemoryManager;
6
7
  }
7
8
  export declare function createMemorySearchTool(options: MemoryToolOptions): AgentTool;
@@ -7,7 +7,7 @@ const MemorySearchSchema = Type.Object({
7
7
  minScore: Type.Optional(Type.Number())
8
8
  });
9
9
  function createMemorySearchTool(options) {
10
- const { workspaceDir, getMemoryManager } = options;
10
+ const { dreamingRoot, getMemoryManager } = options;
11
11
  return {
12
12
  name: "memory_search",
13
13
  label: "🔍 Memory Search",
@@ -34,7 +34,7 @@ function createMemorySearchTool(options) {
34
34
  }
35
35
  });
36
36
  recordDreamingRecalls({
37
- workspaceDir,
37
+ dreamingRoot,
38
38
  query,
39
39
  matches: results.map((entry) => ({
40
40
  file: entry.citation.path ?? entry.record.source.path ?? entry.record.id,
@@ -1 +1 @@
1
- {"version":3,"file":"memory-tool.js","names":[],"sources":["../../../../src/agent/tools/memory-tool.ts"],"sourcesContent":["// Memory search tools for xopc agent\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { recordDreamingRecalls } from '../memory/dreaming/short-term-store.js';\nimport type { MemoryManager } from '../memory/manager.js';\n\n// =============================================================================\n// Memory Search Tool\n// =============================================================================\nconst MemorySearchSchema = Type.Object({\n query: Type.String(),\n maxResults: Type.Optional(Type.Number()),\n minScore: Type.Optional(Type.Number()),\n});\n\ntype MemorySearchParams = { query: string; maxResults?: number; minScore?: number };\n\nexport interface MemoryToolOptions {\n workspaceDir: string;\n getMemoryManager: () => MemoryManager;\n}\n\nexport function createMemorySearchTool(options: MemoryToolOptions): AgentTool {\n const { workspaceDir, getMemoryManager } = options;\n return {\n name: 'memory_search',\n label: '🔍 Memory Search',\n description:\n 'Mandatory recall step: search indexed profile, curated, and session memory sources before answering questions about prior work, decisions, dates, people, preferences, or todos; returns top snippets with source path + lines.',\n parameters: MemorySearchSchema,\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n const { query, maxResults, minScore } = params as MemorySearchParams;\n\n try {\n const results = await getMemoryManager().search({ query, maxResults, minScore });\n for (const result of results) {\n getMemoryManager().recordSignal({\n source: 'search_recall',\n recordId: result.record.id,\n score: result.score,\n content: result.snippet,\n metadata: {\n providerId: result.citation.providerId,\n path: result.citation.path,\n lineStart: result.citation.lineStart,\n lineEnd: result.citation.lineEnd,\n },\n });\n }\n // Dreaming: record short-term recall evidence from memory_search.\n void recordDreamingRecalls({\n workspaceDir,\n query,\n matches: results.map((entry) => ({\n file: entry.citation.path ?? entry.record.source.path ?? entry.record.id,\n lines: entry.snippet,\n score: entry.score,\n lineNumbers:\n entry.citation.lineStart != null\n ? [entry.citation.lineStart, entry.citation.lineEnd ?? entry.citation.lineStart]\n : [],\n })),\n }).catch(() => {});\n const withCitations = results.map((entry) => ({\n id: entry.record.id,\n kind: entry.record.kind,\n file: entry.citation.path ?? entry.record.source.path,\n lines: entry.snippet,\n score: entry.score,\n lineNumbers:\n entry.citation.lineStart != null\n ? [entry.citation.lineStart, entry.citation.lineEnd ?? entry.citation.lineStart]\n : [],\n citation: `${entry.citation.path ?? entry.record.id}${entry.citation.lineStart != null ? `#L${entry.citation.lineStart}${entry.citation.lineEnd && entry.citation.lineEnd !== entry.citation.lineStart ? `-L${entry.citation.lineEnd}` : ''}` : ''}`,\n snippet: `${entry.snippet.trim()}\\n\\nSource: ${entry.citation.path ?? entry.record.id}${entry.citation.lineStart != null ? `#L${entry.citation.lineStart}${entry.citation.lineEnd && entry.citation.lineEnd !== entry.citation.lineStart ? `-L${entry.citation.lineEnd}` : ''}` : ''}`,\n }));\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ results: withCitations, provider: 'memory-manager' }, null, 2) }],\n details: { results: withCitations },\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Search error: ${message}` }],\n details: { error: message },\n };\n }\n },\n } as any;\n}\n\n// =============================================================================\n// Memory Get Tool\n// =============================================================================\nconst MemoryGetSchema = Type.Object({\n path: Type.String(),\n from: Type.Optional(Type.Number()),\n lines: Type.Optional(Type.Number()),\n});\n\ntype MemoryGetParams = { path: string; from?: number; lines?: number };\n\nexport function createMemoryGetTool(options: MemoryToolOptions): AgentTool {\n const { getMemoryManager } = options;\n return {\n name: 'memory_get',\n label: '📄 Memory Get',\n description: 'Safe snippet read from a source path returned by memory_search, with optional from/lines; pull only the needed lines and keep context small.',\n parameters: MemoryGetSchema,\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n const { path, from, lines } = params as MemoryGetParams;\n\n try {\n const result = await getMemoryManager().read({ path, from, lines });\n if (!result) {\n return {\n content: [{ type: 'text', text: `File not found: ${path}` }],\n details: { path, text: '' },\n };\n }\n return {\n content: [{ type: 'text', text: result.record.content }],\n details: { path, text: result.record.content, lineNumbers: result.lineNumbers },\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Read error: ${message}` }],\n details: { error: message },\n };\n }\n },\n } as any;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"memory-tool.js","names":[],"sources":["../../../../src/agent/tools/memory-tool.ts"],"sourcesContent":["// Memory search tools for xopc agent\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { recordDreamingRecalls } from '../memory/dreaming/short-term-store.js';\nimport type { MemoryManager } from '../memory/manager.js';\n\n// =============================================================================\n// Memory Search Tool\n// =============================================================================\nconst MemorySearchSchema = Type.Object({\n query: Type.String(),\n maxResults: Type.Optional(Type.Number()),\n minScore: Type.Optional(Type.Number()),\n});\n\ntype MemorySearchParams = { query: string; maxResults?: number; minScore?: number };\n\nexport interface MemoryToolOptions {\n workspaceDir: string;\n dreamingRoot: string;\n getMemoryManager: () => MemoryManager;\n}\n\nexport function createMemorySearchTool(options: MemoryToolOptions): AgentTool {\n const { dreamingRoot, getMemoryManager } = options;\n return {\n name: 'memory_search',\n label: '🔍 Memory Search',\n description:\n 'Mandatory recall step: search indexed profile, curated, and session memory sources before answering questions about prior work, decisions, dates, people, preferences, or todos; returns top snippets with source path + lines.',\n parameters: MemorySearchSchema,\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n const { query, maxResults, minScore } = params as MemorySearchParams;\n\n try {\n const results = await getMemoryManager().search({ query, maxResults, minScore });\n for (const result of results) {\n getMemoryManager().recordSignal({\n source: 'search_recall',\n recordId: result.record.id,\n score: result.score,\n content: result.snippet,\n metadata: {\n providerId: result.citation.providerId,\n path: result.citation.path,\n lineStart: result.citation.lineStart,\n lineEnd: result.citation.lineEnd,\n },\n });\n }\n // Dreaming: record short-term recall evidence from memory_search.\n void recordDreamingRecalls({\n dreamingRoot,\n query,\n matches: results.map((entry) => ({\n file: entry.citation.path ?? entry.record.source.path ?? entry.record.id,\n lines: entry.snippet,\n score: entry.score,\n lineNumbers:\n entry.citation.lineStart != null\n ? [entry.citation.lineStart, entry.citation.lineEnd ?? entry.citation.lineStart]\n : [],\n })),\n }).catch(() => {});\n const withCitations = results.map((entry) => ({\n id: entry.record.id,\n kind: entry.record.kind,\n file: entry.citation.path ?? entry.record.source.path,\n lines: entry.snippet,\n score: entry.score,\n lineNumbers:\n entry.citation.lineStart != null\n ? [entry.citation.lineStart, entry.citation.lineEnd ?? entry.citation.lineStart]\n : [],\n citation: `${entry.citation.path ?? entry.record.id}${entry.citation.lineStart != null ? `#L${entry.citation.lineStart}${entry.citation.lineEnd && entry.citation.lineEnd !== entry.citation.lineStart ? `-L${entry.citation.lineEnd}` : ''}` : ''}`,\n snippet: `${entry.snippet.trim()}\\n\\nSource: ${entry.citation.path ?? entry.record.id}${entry.citation.lineStart != null ? `#L${entry.citation.lineStart}${entry.citation.lineEnd && entry.citation.lineEnd !== entry.citation.lineStart ? `-L${entry.citation.lineEnd}` : ''}` : ''}`,\n }));\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ results: withCitations, provider: 'memory-manager' }, null, 2) }],\n details: { results: withCitations },\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Search error: ${message}` }],\n details: { error: message },\n };\n }\n },\n } as any;\n}\n\n// =============================================================================\n// Memory Get Tool\n// =============================================================================\nconst MemoryGetSchema = Type.Object({\n path: Type.String(),\n from: Type.Optional(Type.Number()),\n lines: Type.Optional(Type.Number()),\n});\n\ntype MemoryGetParams = { path: string; from?: number; lines?: number };\n\nexport function createMemoryGetTool(options: MemoryToolOptions): AgentTool {\n const { getMemoryManager } = options;\n return {\n name: 'memory_get',\n label: '📄 Memory Get',\n description: 'Safe snippet read from a source path returned by memory_search, with optional from/lines; pull only the needed lines and keep context small.',\n parameters: MemoryGetSchema,\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n const { path, from, lines } = params as MemoryGetParams;\n\n try {\n const result = await getMemoryManager().read({ path, from, lines });\n if (!result) {\n return {\n content: [{ type: 'text', text: `File not found: ${path}` }],\n details: { path, text: '' },\n };\n }\n return {\n content: [{ type: 'text', text: result.record.content }],\n details: { path, text: result.record.content, lineNumbers: result.lineNumbers },\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: [{ type: 'text', text: `Read error: ${message}` }],\n details: { error: message },\n };\n }\n },\n } as any;\n}\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ export type ToolMutationScope = 'none' | 'workspace' | 'external' | 'unknown';
3
+ export type ToolVerificationKind = 'none' | 'diff-review' | 'test' | 'build' | 'lint' | 'typecheck';
4
+ export interface XopcToolMetadata {
5
+ mutatesWorkspace?: boolean;
6
+ mutationScope?: ToolMutationScope;
7
+ supportsParallel?: boolean;
8
+ idempotent?: boolean;
9
+ verificationKind?: ToolVerificationKind;
10
+ requiresExclusiveWorkspaceLock?: boolean;
11
+ finalGuardRelevant?: boolean;
12
+ }
13
+ export type AgentToolWithMetadata<TParams = any, TDetails = any> = AgentTool<TParams, TDetails> & XopcToolMetadata;
14
+ export declare const DEFAULT_TOOL_METADATA: Required<XopcToolMetadata>;
15
+ export declare function getToolMetadata(tool: AgentTool<any, any>): Required<XopcToolMetadata>;
@@ -0,0 +1,26 @@
1
+ //#region src/agent/tools/metadata.ts
2
+ const DEFAULT_TOOL_METADATA = {
3
+ mutatesWorkspace: false,
4
+ mutationScope: "none",
5
+ supportsParallel: false,
6
+ idempotent: false,
7
+ verificationKind: "none",
8
+ requiresExclusiveWorkspaceLock: false,
9
+ finalGuardRelevant: false
10
+ };
11
+ function getToolMetadata(tool) {
12
+ const t = tool;
13
+ return {
14
+ mutatesWorkspace: t.mutatesWorkspace === true,
15
+ mutationScope: t.mutationScope ?? DEFAULT_TOOL_METADATA.mutationScope,
16
+ supportsParallel: t.supportsParallel === true,
17
+ idempotent: t.idempotent === true,
18
+ verificationKind: t.verificationKind ?? DEFAULT_TOOL_METADATA.verificationKind,
19
+ requiresExclusiveWorkspaceLock: t.requiresExclusiveWorkspaceLock === true,
20
+ finalGuardRelevant: t.finalGuardRelevant === true
21
+ };
22
+ }
23
+ //#endregion
24
+ export { DEFAULT_TOOL_METADATA, getToolMetadata };
25
+
26
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","names":[],"sources":["../../../../src/agent/tools/metadata.ts"],"sourcesContent":["import type { AgentTool } from '@earendil-works/pi-agent-core';\n\nexport type ToolMutationScope = 'none' | 'workspace' | 'external' | 'unknown';\n\nexport type ToolVerificationKind = 'none' | 'diff-review' | 'test' | 'build' | 'lint' | 'typecheck';\n\nexport interface XopcToolMetadata {\n mutatesWorkspace?: boolean;\n mutationScope?: ToolMutationScope;\n supportsParallel?: boolean;\n idempotent?: boolean;\n verificationKind?: ToolVerificationKind;\n requiresExclusiveWorkspaceLock?: boolean;\n finalGuardRelevant?: boolean;\n}\n\nexport type AgentToolWithMetadata<TParams = any, TDetails = any> = AgentTool<TParams, TDetails> & XopcToolMetadata;\n\nexport const DEFAULT_TOOL_METADATA: Required<XopcToolMetadata> = {\n mutatesWorkspace: false,\n mutationScope: 'none',\n supportsParallel: false,\n idempotent: false,\n verificationKind: 'none',\n requiresExclusiveWorkspaceLock: false,\n finalGuardRelevant: false,\n};\n\nexport function getToolMetadata(tool: AgentTool<any, any>): Required<XopcToolMetadata> {\n const t = tool as AgentToolWithMetadata;\n return {\n mutatesWorkspace: t.mutatesWorkspace === true,\n mutationScope: t.mutationScope ?? DEFAULT_TOOL_METADATA.mutationScope,\n supportsParallel: t.supportsParallel === true,\n idempotent: t.idempotent === true,\n verificationKind: t.verificationKind ?? DEFAULT_TOOL_METADATA.verificationKind,\n requiresExclusiveWorkspaceLock: t.requiresExclusiveWorkspaceLock === true,\n finalGuardRelevant: t.finalGuardRelevant === true,\n };\n}\n"],"mappings":";AAkBA,MAAa,wBAAoD;CAC/D,kBAAkB;CAClB,eAAe;CACf,kBAAkB;CAClB,YAAY;CACZ,kBAAkB;CAClB,gCAAgC;CAChC,oBAAoB;CACrB;AAED,SAAgB,gBAAgB,MAAuD;CACrF,MAAM,IAAI;AACV,QAAO;EACL,kBAAkB,EAAE,qBAAqB;EACzC,eAAe,EAAE,iBAAiB,sBAAsB;EACxD,kBAAkB,EAAE,qBAAqB;EACzC,YAAY,EAAE,eAAe;EAC7B,kBAAkB,EAAE,oBAAoB,sBAAsB;EAC9D,gCAAgC,EAAE,mCAAmC;EACrE,oBAAoB,EAAE,uBAAuB;EAC9C"}
@@ -16,6 +16,8 @@ function createReadFileTool(workspace, options) {
16
16
  description: "Read file contents. Relative paths are from the current agent workspace; profile Markdown (SOUL.md, etc.) is found automatically when given by filename.",
17
17
  parameters: ReadFileSchema,
18
18
  label: "📄 Read",
19
+ supportsParallel: true,
20
+ idempotent: true,
19
21
  async execute(_toolCallId, params, _signal) {
20
22
  return executeReadFile(workspace, options?.profileMarkdownRoot, params);
21
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"read.js","names":[],"sources":["../../../../src/agent/tools/read.ts"],"sourcesContent":["// Read file tool\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { readFile, stat } from 'fs/promises';\nimport { checkFileSafety } from '../prompt/safety.js';\nimport { truncateHead, formatSize, DEFAULT_MAX_BYTES } from './truncate.js';\nimport {\n isBareProfileMarkdownFileName,\n resolveProfileMarkdownPathIfBareName,\n resolvePathUnderWorkspace,\n} from './tool-paths.js';\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024;\nconst DEFAULT_MAX_LINES = 500;\n\nconst ReadFileSchema = Type.Object({\n path: Type.String({ description: 'File path to read' }),\n limit: Type.Optional(Type.Number({ description: 'Max lines (default: 500)' })),\n});\n\nexport interface CreateReadFileToolOptions {\n /** When set and the path is a bare profile filename (e.g. SOUL.md), try this root if not in workspace. */\n profileMarkdownRoot?: string;\n}\n\ntype ReadFileParams = {\n path: string;\n limit?: number;\n};\n\nexport function createReadFileTool(\n workspace: string,\n options?: CreateReadFileToolOptions,\n): AgentTool {\n return {\n name: 'read_file',\n description:\n 'Read file contents. Relative paths are from the current agent workspace; profile Markdown (SOUL.md, etc.) is found automatically when given by filename.',\n parameters: ReadFileSchema,\n label: '📄 Read',\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n return executeReadFile(workspace, options?.profileMarkdownRoot, params as ReadFileParams);\n },\n } as any;\n}\n\nasync function executeReadFile(\n workspace: string,\n profileMarkdownRoot: string | undefined,\n params: ReadFileParams,\n): Promise<AgentToolResult<{}>> {\n try {\n const safety = checkFileSafety('read', params.path);\n if (!safety.allowed) {\n return { content: [{ type: 'text', text: `🚫 ${safety.message}` }], details: {} };\n }\n\n let normalized = resolvePathUnderWorkspace(params.path, workspace);\n let stats;\n try {\n stats = await stat(normalized);\n } catch (e) {\n const code = (e as NodeJS.ErrnoException)?.code;\n if (\n code === 'ENOENT' &&\n profileMarkdownRoot &&\n isBareProfileMarkdownFileName(params.path)\n ) {\n const alt = resolveProfileMarkdownPathIfBareName(params.path, profileMarkdownRoot);\n try {\n stats = await stat(alt);\n normalized = alt;\n } catch {\n throw e;\n }\n } else {\n throw e;\n }\n }\n\n if (stats.size > MAX_FILE_SIZE) {\n return { content: [{ type: 'text', text: `🚫 File too large: ${formatSize(stats.size)}` }], details: {} };\n }\n\n const content = await readFile(normalized, 'utf-8');\n const truncation = truncateHead(content, { maxLines: params.limit || DEFAULT_MAX_LINES, maxBytes: DEFAULT_MAX_BYTES });\n\n let outputText = truncation.content;\n if (truncation.truncated) {\n if (truncation.firstLineExceedsLimit) {\n outputText = `(Line exceeds ${formatSize(DEFAULT_MAX_BYTES)})`;\n } else {\n outputText += `\\n\\n[${truncation.outputLines}/${truncation.totalLines} lines]`;\n }\n }\n\n return { content: [{ type: 'text', text: outputText }], details: {} };\n } catch (error) {\n return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], details: {} };\n }\n}\n"],"mappings":";;;;;;AAYA,MAAM,gBAAgB,KAAK,OAAO;AAClC,MAAM,oBAAoB;AAE1B,MAAM,iBAAiB,KAAK,OAAO;CACjC,MAAM,KAAK,OAAO,EAAE,aAAa,qBAAqB,CAAC;CACvD,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,4BAA4B,CAAC,CAAC;CAC/E,CAAC;AAYF,SAAgB,mBACd,WACA,SACW;AACX,QAAO;EACL,MAAM;EACN,aACE;EACF,YAAY;EACZ,OAAO;EAEP,MAAM,QACJ,aACA,QACA,SAC8B;AAC9B,UAAO,gBAAgB,WAAW,SAAS,qBAAqB,OAAyB;;EAE5F;;AAGH,eAAe,gBACb,WACA,qBACA,QAC8B;AAC9B,KAAI;EACF,MAAM,SAAS,gBAAgB,QAAQ,OAAO,KAAK;AACnD,MAAI,CAAC,OAAO,QACV,QAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,MAAM,OAAO;IAAW,CAAC;GAAE,SAAS,EAAE;GAAE;EAGnF,IAAI,aAAa,0BAA0B,OAAO,MAAM,UAAU;EAClE,IAAI;AACJ,MAAI;AACF,WAAQ,MAAM,KAAK,WAAW;WACvB,GAAG;AAEV,OADc,GAA6B,SAEhC,YACT,uBACA,8BAA8B,OAAO,KAAK,EAC1C;IACA,MAAM,MAAM,qCAAqC,OAAO,MAAM,oBAAoB;AAClF,QAAI;AACF,aAAQ,MAAM,KAAK,IAAI;AACvB,kBAAa;YACP;AACN,WAAM;;SAGR,OAAM;;AAIV,MAAI,MAAM,OAAO,cACf,QAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,sBAAsB,WAAW,MAAM,KAAK;IAAI,CAAC;GAAE,SAAS,EAAE;GAAE;EAI3G,MAAM,aAAa,aAAa,MADV,SAAS,YAAY,QAAQ,EACV;GAAE,UAAU,OAAO,SAAS;GAAmB,UAAU;GAAmB,CAAC;EAEtH,IAAI,aAAa,WAAW;AAC5B,MAAI,WAAW,UACb,KAAI,WAAW,sBACb,cAAa,iBAAiB,WAAW,kBAAkB,CAAC;MAE5D,eAAc,QAAQ,WAAW,YAAY,GAAG,WAAW,WAAW;AAI1E,SAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;IAAY,CAAC;GAAE,SAAS,EAAE;GAAE;UAC9D,OAAO;AACd,SAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAAI,CAAC;GAAE,SAAS,EAAE;GAAE"}
1
+ {"version":3,"file":"read.js","names":[],"sources":["../../../../src/agent/tools/read.ts"],"sourcesContent":["// Read file tool\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { readFile, stat } from 'fs/promises';\nimport { checkFileSafety } from '../prompt/safety.js';\nimport { truncateHead, formatSize, DEFAULT_MAX_BYTES } from './truncate.js';\nimport {\n isBareProfileMarkdownFileName,\n resolveProfileMarkdownPathIfBareName,\n resolvePathUnderWorkspace,\n} from './tool-paths.js';\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024;\nconst DEFAULT_MAX_LINES = 500;\n\nconst ReadFileSchema = Type.Object({\n path: Type.String({ description: 'File path to read' }),\n limit: Type.Optional(Type.Number({ description: 'Max lines (default: 500)' })),\n});\n\nexport interface CreateReadFileToolOptions {\n /** When set and the path is a bare profile filename (e.g. SOUL.md), try this root if not in workspace. */\n profileMarkdownRoot?: string;\n}\n\ntype ReadFileParams = {\n path: string;\n limit?: number;\n};\n\nexport function createReadFileTool(\n workspace: string,\n options?: CreateReadFileToolOptions,\n): AgentTool {\n return {\n name: 'read_file',\n description:\n 'Read file contents. Relative paths are from the current agent workspace; profile Markdown (SOUL.md, etc.) is found automatically when given by filename.',\n parameters: ReadFileSchema,\n label: '📄 Read',\n supportsParallel: true,\n idempotent: true,\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n return executeReadFile(workspace, options?.profileMarkdownRoot, params as ReadFileParams);\n },\n } as any;\n}\n\nasync function executeReadFile(\n workspace: string,\n profileMarkdownRoot: string | undefined,\n params: ReadFileParams,\n): Promise<AgentToolResult<{}>> {\n try {\n const safety = checkFileSafety('read', params.path);\n if (!safety.allowed) {\n return { content: [{ type: 'text', text: `🚫 ${safety.message}` }], details: {} };\n }\n\n let normalized = resolvePathUnderWorkspace(params.path, workspace);\n let stats;\n try {\n stats = await stat(normalized);\n } catch (e) {\n const code = (e as NodeJS.ErrnoException)?.code;\n if (\n code === 'ENOENT' &&\n profileMarkdownRoot &&\n isBareProfileMarkdownFileName(params.path)\n ) {\n const alt = resolveProfileMarkdownPathIfBareName(params.path, profileMarkdownRoot);\n try {\n stats = await stat(alt);\n normalized = alt;\n } catch {\n throw e;\n }\n } else {\n throw e;\n }\n }\n\n if (stats.size > MAX_FILE_SIZE) {\n return { content: [{ type: 'text', text: `🚫 File too large: ${formatSize(stats.size)}` }], details: {} };\n }\n\n const content = await readFile(normalized, 'utf-8');\n const truncation = truncateHead(content, { maxLines: params.limit || DEFAULT_MAX_LINES, maxBytes: DEFAULT_MAX_BYTES });\n\n let outputText = truncation.content;\n if (truncation.truncated) {\n if (truncation.firstLineExceedsLimit) {\n outputText = `(Line exceeds ${formatSize(DEFAULT_MAX_BYTES)})`;\n } else {\n outputText += `\\n\\n[${truncation.outputLines}/${truncation.totalLines} lines]`;\n }\n }\n\n return { content: [{ type: 'text', text: outputText }], details: {} };\n } catch (error) {\n return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], details: {} };\n }\n}\n"],"mappings":";;;;;;AAYA,MAAM,gBAAgB,KAAK,OAAO;AAClC,MAAM,oBAAoB;AAE1B,MAAM,iBAAiB,KAAK,OAAO;CACjC,MAAM,KAAK,OAAO,EAAE,aAAa,qBAAqB,CAAC;CACvD,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,4BAA4B,CAAC,CAAC;CAC/E,CAAC;AAYF,SAAgB,mBACd,WACA,SACW;AACX,QAAO;EACL,MAAM;EACN,aACE;EACF,YAAY;EACZ,OAAO;EACP,kBAAkB;EAClB,YAAY;EAEZ,MAAM,QACJ,aACA,QACA,SAC8B;AAC9B,UAAO,gBAAgB,WAAW,SAAS,qBAAqB,OAAyB;;EAE5F;;AAGH,eAAe,gBACb,WACA,qBACA,QAC8B;AAC9B,KAAI;EACF,MAAM,SAAS,gBAAgB,QAAQ,OAAO,KAAK;AACnD,MAAI,CAAC,OAAO,QACV,QAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,MAAM,OAAO;IAAW,CAAC;GAAE,SAAS,EAAE;GAAE;EAGnF,IAAI,aAAa,0BAA0B,OAAO,MAAM,UAAU;EAClE,IAAI;AACJ,MAAI;AACF,WAAQ,MAAM,KAAK,WAAW;WACvB,GAAG;AAEV,OADc,GAA6B,SAEhC,YACT,uBACA,8BAA8B,OAAO,KAAK,EAC1C;IACA,MAAM,MAAM,qCAAqC,OAAO,MAAM,oBAAoB;AAClF,QAAI;AACF,aAAQ,MAAM,KAAK,IAAI;AACvB,kBAAa;YACP;AACN,WAAM;;SAGR,OAAM;;AAIV,MAAI,MAAM,OAAO,cACf,QAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,sBAAsB,WAAW,MAAM,KAAK;IAAI,CAAC;GAAE,SAAS,EAAE;GAAE;EAI3G,MAAM,aAAa,aAAa,MADV,SAAS,YAAY,QAAQ,EACV;GAAE,UAAU,OAAO,SAAS;GAAmB,UAAU;GAAmB,CAAC;EAEtH,IAAI,aAAa,WAAW;AAC5B,MAAI,WAAW,UACb,KAAI,WAAW,sBACb,cAAa,iBAAiB,WAAW,kBAAkB,CAAC;MAE5D,eAAc,QAAQ,WAAW,YAAY,GAAG,WAAW,WAAW;AAI1E,SAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM;IAAY,CAAC;GAAE,SAAS,EAAE;GAAE;UAC9D,OAAO;AACd,SAAO;GAAE,SAAS,CAAC;IAAE,MAAM;IAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAAI,CAAC;GAAE,SAAS,EAAE;GAAE"}