@capybara-hq/kernel 0.1.0-rc.4 → 0.1.0-rc.5

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 (507) hide show
  1. package/bootstrap.json +61 -5
  2. package/dist/admin/admin.controller.d.ts +39 -13
  3. package/dist/admin/admin.controller.js +33 -17
  4. package/dist/admin/extensions.controller.d.ts +16 -2
  5. package/dist/admin/extensions.controller.js +26 -6
  6. package/dist/admin/setup-lock.d.ts +1 -1
  7. package/dist/admin/setup-lock.js +1 -1
  8. package/dist/admin/setup.controller.d.ts +1 -1
  9. package/dist/admin/setup.controller.js +1 -1
  10. package/dist/admin/setup.service.d.ts +4 -4
  11. package/dist/admin/setup.service.js +8 -8
  12. package/dist/agents/agent-lookup.d.ts +16 -0
  13. package/dist/agents/agent-lookup.js +11 -0
  14. package/dist/agents/agents.controller.d.ts +76 -1
  15. package/dist/agents/agents.controller.js +90 -11
  16. package/dist/agents/agents.module.d.ts +4 -1
  17. package/dist/agents/agents.module.js +32 -6
  18. package/dist/agents/agents.service.d.ts +51 -22
  19. package/dist/agents/agents.service.js +172 -70
  20. package/dist/agents/definition.d.ts +49 -0
  21. package/dist/agents/definition.js +45 -0
  22. package/dist/agents/from-template.d.ts +106 -0
  23. package/dist/agents/from-template.js +649 -0
  24. package/dist/agents/from-template.service.d.ts +60 -0
  25. package/dist/agents/from-template.service.js +161 -0
  26. package/dist/agents/org-templates.d.ts +176 -0
  27. package/dist/agents/org-templates.js +827 -0
  28. package/dist/agents/pending-connector-requests.d.ts +77 -0
  29. package/dist/agents/pending-connector-requests.js +215 -0
  30. package/dist/agents/pending-connectors.controller.d.ts +39 -0
  31. package/dist/agents/pending-connectors.controller.js +91 -0
  32. package/dist/agents/pending-connectors.service.d.ts +62 -0
  33. package/dist/agents/pending-connectors.service.js +282 -0
  34. package/dist/agents/templates.controller.d.ts +86 -5
  35. package/dist/agents/templates.controller.js +171 -7
  36. package/dist/agents/templates.d.ts +127 -23
  37. package/dist/agents/templates.js +475 -52
  38. package/dist/background/background.module.js +8 -1
  39. package/dist/background/finish.d.ts +3 -2
  40. package/dist/background/launch-lock.d.ts +4 -3
  41. package/dist/background/launch-lock.js +4 -3
  42. package/dist/background/poll.job.d.ts +9 -6
  43. package/dist/background/poll.job.js +30 -22
  44. package/dist/background/session.d.ts +13 -2
  45. package/dist/background/session.js +13 -0
  46. package/dist/background/stop.d.ts +12 -6
  47. package/dist/background/stop.js +57 -39
  48. package/dist/background/store.d.ts +18 -6
  49. package/dist/background/store.js +12 -6
  50. package/dist/background/tasks.service.d.ts +15 -5
  51. package/dist/background/tasks.service.js +42 -17
  52. package/dist/background/wake-rules.d.ts +27 -18
  53. package/dist/background/wake-rules.js +52 -22
  54. package/dist/background/wake.d.ts +13 -11
  55. package/dist/background/wake.js +20 -14
  56. package/dist/catalog/admin-catalog.controller.d.ts +129 -30
  57. package/dist/catalog/admin-catalog.controller.js +213 -42
  58. package/dist/catalog/catalog-content.d.ts +58 -32
  59. package/dist/catalog/catalog-content.js +34 -8
  60. package/dist/catalog/catalog-import.module.d.ts +7 -0
  61. package/dist/catalog/catalog-import.module.js +60 -0
  62. package/dist/catalog/catalog-items.d.ts +111 -7
  63. package/dist/catalog/catalog-items.js +279 -13
  64. package/dist/catalog/catalog-scope.service.d.ts +260 -0
  65. package/dist/catalog/catalog-scope.service.js +1116 -0
  66. package/dist/catalog/catalog.module.d.ts +7 -9
  67. package/dist/catalog/catalog.module.js +41 -31
  68. package/dist/catalog/catalog.service.d.ts +101 -29
  69. package/dist/catalog/catalog.service.js +104 -106
  70. package/dist/catalog/cli.d.ts +11 -1
  71. package/dist/catalog/cli.js +26 -1
  72. package/dist/catalog/component-promotion.d.ts +96 -0
  73. package/dist/catalog/component-promotion.js +395 -0
  74. package/dist/catalog/component-scope.controller.d.ts +152 -0
  75. package/dist/catalog/component-scope.controller.js +287 -0
  76. package/dist/catalog/component-scope.service.d.ts +303 -0
  77. package/dist/catalog/component-scope.service.js +936 -0
  78. package/dist/catalog/component-state.d.ts +174 -0
  79. package/dist/catalog/component-state.js +437 -0
  80. package/dist/catalog/job-ids.d.ts +30 -0
  81. package/dist/catalog/job-ids.js +25 -0
  82. package/dist/catalog/marketplace-fetch.d.ts +1 -1
  83. package/dist/catalog/marketplaces.controller.d.ts +22 -5
  84. package/dist/catalog/marketplaces.controller.js +56 -7
  85. package/dist/catalog/marketplaces.service.d.ts +54 -14
  86. package/dist/catalog/marketplaces.service.js +71 -22
  87. package/dist/catalog/org-catalog.controller.d.ts +125 -34
  88. package/dist/catalog/org-catalog.controller.js +181 -65
  89. package/dist/catalog/org-catalog.service.d.ts +65 -33
  90. package/dist/catalog/org-catalog.service.js +324 -157
  91. package/dist/catalog/org-extension-switch.d.ts +41 -0
  92. package/dist/catalog/org-extension-switch.js +115 -0
  93. package/dist/catalog/org-extension.controller.d.ts +119 -0
  94. package/dist/catalog/org-extension.controller.js +266 -0
  95. package/dist/catalog/org-plugin-uploads.controller.d.ts +98 -0
  96. package/dist/catalog/org-plugin-uploads.controller.js +213 -0
  97. package/dist/catalog/org-plugin-uploads.d.ts +63 -0
  98. package/dist/catalog/org-plugin-uploads.js +116 -0
  99. package/dist/catalog/owned-items.d.ts +184 -0
  100. package/dist/catalog/owned-items.js +789 -0
  101. package/dist/catalog/owned-plugin-cleanup.d.ts +56 -0
  102. package/dist/catalog/owned-plugin-cleanup.js +194 -0
  103. package/dist/catalog/ownership.d.ts +172 -0
  104. package/dist/catalog/ownership.js +326 -0
  105. package/dist/catalog/platform-components.d.ts +221 -0
  106. package/dist/catalog/platform-components.js +761 -0
  107. package/dist/catalog/platform-migration.d.ts +115 -0
  108. package/dist/catalog/platform-migration.js +582 -0
  109. package/dist/catalog/plugin-import.d.ts +178 -34
  110. package/dist/catalog/plugin-import.js +622 -82
  111. package/dist/catalog/plugin-install.d.ts +185 -41
  112. package/dist/catalog/plugin-install.js +758 -126
  113. package/dist/catalog/plugin-upgrade.d.ts +260 -225
  114. package/dist/catalog/plugin-upgrade.js +1147 -1136
  115. package/dist/catalog/request-rules.d.ts +65 -0
  116. package/dist/catalog/request-rules.js +217 -0
  117. package/dist/catalog/requests.service.d.ts +193 -118
  118. package/dist/catalog/requests.service.js +526 -343
  119. package/dist/catalog/reserved-names.d.ts +8 -0
  120. package/dist/catalog/reserved-names.js +42 -0
  121. package/dist/catalog/scope-orgs.d.ts +21 -0
  122. package/dist/catalog/scope-orgs.js +67 -0
  123. package/dist/catalog/scope-state.d.ts +35 -0
  124. package/dist/catalog/scope-state.js +87 -0
  125. package/dist/catalog/scope-sync-workers.d.ts +7 -0
  126. package/dist/catalog/scope-sync-workers.js +29 -0
  127. package/dist/catalog/scope-sync.d.ts +176 -0
  128. package/dist/catalog/scope-sync.js +576 -0
  129. package/dist/catalog/scope.d.ts +42 -0
  130. package/dist/catalog/scope.js +42 -0
  131. package/dist/catalog/unshare.d.ts +22 -0
  132. package/dist/catalog/unshare.js +118 -0
  133. package/dist/channels/actions.js +1 -0
  134. package/dist/channels/cards.js +20 -2
  135. package/dist/channels/channels.module.js +2 -0
  136. package/dist/channels/inbound.d.ts +9 -1
  137. package/dist/channels/inbound.js +67 -5
  138. package/dist/channels/phrases.d.ts +35 -0
  139. package/dist/channels/phrases.js +29 -0
  140. package/dist/config/docs.js +3 -1
  141. package/dist/config/schema.d.ts +6 -2
  142. package/dist/config/schema.js +46 -22
  143. package/dist/conversations/access.d.ts +6 -4
  144. package/dist/conversations/access.js +27 -5
  145. package/dist/conversations/agent-tree.d.ts +46 -0
  146. package/dist/conversations/agent-tree.js +92 -0
  147. package/dist/conversations/conversations.controller.d.ts +43 -18
  148. package/dist/conversations/conversations.controller.js +79 -38
  149. package/dist/conversations/conversations.module.d.ts +1 -1
  150. package/dist/conversations/conversations.module.js +7 -7
  151. package/dist/conversations/conversations.service.d.ts +69 -12
  152. package/dist/conversations/conversations.service.js +106 -27
  153. package/dist/conversations/environment-status.d.ts +24 -0
  154. package/dist/conversations/environment-status.js +71 -0
  155. package/dist/conversations/event-log.d.ts +20 -5
  156. package/dist/conversations/event-log.js +60 -0
  157. package/dist/conversations/events.d.ts +84 -2
  158. package/dist/conversations/events.js +91 -17
  159. package/dist/conversations/queue.service.d.ts +1 -1
  160. package/dist/conversations/queue.service.js +5 -0
  161. package/dist/conversations/titles.d.ts +5 -3
  162. package/dist/conversations/titles.js +21 -8
  163. package/dist/conversations/tree.d.ts +17 -0
  164. package/dist/conversations/tree.js +42 -0
  165. package/dist/ctx/create-ctx.d.ts +5 -0
  166. package/dist/ctx/create-ctx.js +15 -5
  167. package/dist/db/kernel-schema.d.ts +362 -18
  168. package/dist/environments/access.d.ts +41 -0
  169. package/dist/environments/access.js +77 -0
  170. package/dist/environments/conversation-environments.d.ts +61 -0
  171. package/dist/environments/conversation-environments.js +170 -0
  172. package/dist/environments/dto.d.ts +25 -0
  173. package/dist/environments/dto.js +12 -0
  174. package/dist/environments/environments.controller.d.ts +33 -0
  175. package/dist/environments/environments.controller.js +110 -0
  176. package/dist/environments/environments.module.d.ts +8 -0
  177. package/dist/environments/environments.module.js +27 -0
  178. package/dist/environments/environments.service.d.ts +153 -0
  179. package/dist/environments/environments.service.js +541 -0
  180. package/dist/environments/legacy-cleanup.job.d.ts +34 -0
  181. package/dist/environments/legacy-cleanup.job.js +141 -0
  182. package/dist/errors.d.ts +82 -2
  183. package/dist/errors.js +82 -2
  184. package/dist/evals/reconstruct.d.ts +18 -9
  185. package/dist/evals/reconstruct.js +26 -7
  186. package/dist/evals/run-replay.d.ts +4 -2
  187. package/dist/evals/run-replay.js +16 -4
  188. package/dist/evals/step-replay.d.ts +2 -5
  189. package/dist/evals/step-replay.js +1 -1
  190. package/dist/evals/trajectory.service.d.ts +8 -3
  191. package/dist/evals/trajectory.service.js +26 -14
  192. package/dist/evals/worker.d.ts +5 -5
  193. package/dist/evals/worker.js +9 -3
  194. package/dist/extensions/admin-ops.d.ts +36 -10
  195. package/dist/extensions/admin-ops.js +65 -42
  196. package/dist/extensions/admin-view.d.ts +37 -10
  197. package/dist/extensions/admin-view.js +103 -20
  198. package/dist/extensions/bootstrap.d.ts +17 -4
  199. package/dist/extensions/bootstrap.js +70 -9
  200. package/dist/extensions/cli.d.ts +12 -0
  201. package/dist/extensions/cli.js +11 -2
  202. package/dist/extensions/deployment-config.d.ts +28 -5
  203. package/dist/extensions/deployment-config.js +48 -7
  204. package/dist/extensions/effective-config.d.ts +127 -0
  205. package/dist/extensions/effective-config.js +368 -0
  206. package/dist/extensions/extensions.module.js +8 -2
  207. package/dist/extensions/hooks.d.ts +37 -4
  208. package/dist/extensions/hooks.js +82 -16
  209. package/dist/extensions/host.d.ts +19 -1
  210. package/dist/extensions/host.js +30 -7
  211. package/dist/extensions/installs.d.ts +20 -8
  212. package/dist/extensions/installs.js +37 -15
  213. package/dist/extensions/org-config.d.ts +75 -6
  214. package/dist/extensions/org-config.js +184 -32
  215. package/dist/extensions/org-levels.d.ts +37 -0
  216. package/dist/extensions/org-levels.js +71 -0
  217. package/dist/extensions/org-overrides.d.ts +151 -0
  218. package/dist/extensions/org-overrides.js +524 -0
  219. package/dist/extensions/permission-view.d.ts +16 -4
  220. package/dist/extensions/permission-view.js +4 -4
  221. package/dist/extensions/plugin-items.d.ts +21 -0
  222. package/dist/extensions/plugin-items.js +42 -0
  223. package/dist/extensions/point-defaults.d.ts +12 -5
  224. package/dist/extensions/point-defaults.js +37 -9
  225. package/dist/extensions/resolve.d.ts +5 -1
  226. package/dist/extensions/resolve.js +15 -2
  227. package/dist/files/previewers.d.ts +8 -1
  228. package/dist/files/previewers.js +35 -6
  229. package/dist/http/api.module.js +23 -3
  230. package/dist/http/app.d.ts +11 -2
  231. package/dist/http/app.js +31 -5
  232. package/dist/identity/accounts.d.ts +29 -29
  233. package/dist/identity/accounts.js +47 -47
  234. package/dist/identity/audit.d.ts +2 -1
  235. package/dist/identity/auth.guard.d.ts +13 -5
  236. package/dist/identity/auth.guard.js +26 -9
  237. package/dist/identity/identity.module.d.ts +1 -1
  238. package/dist/identity/identity.module.js +4 -4
  239. package/dist/identity/me.controller.js +1 -1
  240. package/dist/identity/principal.d.ts +3 -3
  241. package/dist/identity/principal.js +3 -3
  242. package/dist/identity/settings.d.ts +22 -11
  243. package/dist/identity/settings.js +53 -18
  244. package/dist/identity/{enterprise-admin.d.ts → super-admin.d.ts} +5 -5
  245. package/dist/identity/{enterprise-admin.js → super-admin.js} +24 -24
  246. package/dist/inbox/inbox.module.d.ts +4 -1
  247. package/dist/inbox/inbox.module.js +7 -3
  248. package/dist/inbox/inbox.service.d.ts +62 -3
  249. package/dist/inbox/inbox.service.js +74 -4
  250. package/dist/inbox/org-notices.d.ts +63 -0
  251. package/dist/inbox/org-notices.js +91 -0
  252. package/dist/inbox/platform-inbox.controller.d.ts +23 -0
  253. package/dist/inbox/platform-inbox.controller.js +58 -0
  254. package/dist/inbox/platform-inbox.service.d.ts +151 -0
  255. package/dist/inbox/platform-inbox.service.js +263 -0
  256. package/dist/inbox/platform-notices.d.ts +19 -0
  257. package/dist/inbox/platform-notices.js +9 -0
  258. package/dist/index.d.ts +1 -1
  259. package/dist/index.js +1 -1
  260. package/dist/infra/cli/kernel-cli.module.js +9 -1
  261. package/dist/infra/config/kernel-config.service.js +21 -1
  262. package/dist/infra/database/xact-lock.d.ts +1 -1
  263. package/dist/infra/database/xact-lock.js +1 -1
  264. package/dist/infra/events/kernel-events.d.ts +11 -2
  265. package/dist/infra/queue/add-job-once.d.ts +14 -0
  266. package/dist/infra/queue/add-job-once.js +16 -0
  267. package/dist/kernel.module.js +6 -0
  268. package/dist/lifecycle/kernel-lifecycle.d.ts +1 -1
  269. package/dist/lifecycle/kernel-lifecycle.js +4 -4
  270. package/dist/models/prices.d.ts +5 -5
  271. package/dist/models/prices.js +4 -4
  272. package/dist/models/purposes.controller.d.ts +6 -4
  273. package/dist/models/purposes.controller.js +13 -7
  274. package/dist/models/purposes.d.ts +20 -9
  275. package/dist/models/purposes.js +17 -8
  276. package/dist/orgs/directory-sync.d.ts +14 -5
  277. package/dist/orgs/directory-sync.js +41 -17
  278. package/dist/orgs/offboarding.d.ts +9 -7
  279. package/dist/orgs/offboarding.js +28 -17
  280. package/dist/orgs/org-lock.d.ts +5 -0
  281. package/dist/orgs/org-lock.js +13 -0
  282. package/dist/orgs/org.guard.d.ts +10 -0
  283. package/dist/orgs/org.guard.js +43 -32
  284. package/dist/orgs/orgs.module.js +3 -0
  285. package/dist/orgs/orgs.service.d.ts +20 -7
  286. package/dist/orgs/orgs.service.js +32 -12
  287. package/dist/orgs/roles.d.ts +1 -1
  288. package/dist/orgs/roles.js +5 -1
  289. package/dist/orgs/settings.controller.d.ts +1 -1
  290. package/dist/orgs/settings.service.d.ts +15 -3
  291. package/dist/orgs/settings.service.js +6 -2
  292. package/dist/overrides.d.ts +3 -0
  293. package/dist/overrides.js +2 -0
  294. package/dist/platform/actor.d.ts +48 -0
  295. package/dist/platform/actor.js +100 -0
  296. package/dist/platform/agent-docs.d.ts +18 -0
  297. package/dist/platform/agent-docs.js +59 -0
  298. package/dist/platform/availability.d.ts +14 -0
  299. package/dist/platform/availability.js +43 -0
  300. package/dist/platform/errors.d.ts +11 -0
  301. package/dist/platform/errors.js +26 -0
  302. package/dist/platform/exclusions.d.ts +12 -0
  303. package/dist/platform/exclusions.js +1387 -0
  304. package/dist/platform/method.d.ts +6 -0
  305. package/dist/platform/method.js +15 -0
  306. package/dist/platform/operation.d.ts +92 -0
  307. package/dist/platform/operation.js +35 -0
  308. package/dist/platform/ops/agent-templates.ops.d.ts +14 -0
  309. package/dist/platform/ops/agent-templates.ops.js +92 -0
  310. package/dist/platform/ops/agents.ops.d.ts +19 -0
  311. package/dist/platform/ops/agents.ops.js +294 -0
  312. package/dist/platform/ops/connectors.ops.d.ts +15 -0
  313. package/dist/platform/ops/connectors.ops.js +126 -0
  314. package/dist/platform/ops/errors.d.ts +11 -0
  315. package/dist/platform/ops/errors.js +22 -0
  316. package/dist/platform/ops/extensions.ops.d.ts +19 -0
  317. package/dist/platform/ops/extensions.ops.js +116 -0
  318. package/dist/platform/ops/marketplaces.ops.d.ts +16 -0
  319. package/dist/platform/ops/marketplaces.ops.js +157 -0
  320. package/dist/platform/ops/paging.d.ts +14 -0
  321. package/dist/platform/ops/paging.js +20 -0
  322. package/dist/platform/ops/platform.ops.d.ts +23 -0
  323. package/dist/platform/ops/platform.ops.js +158 -0
  324. package/dist/platform/ops/plugins.ops.d.ts +33 -0
  325. package/dist/platform/ops/plugins.ops.js +377 -0
  326. package/dist/platform/ops/requests.ops.d.ts +14 -0
  327. package/dist/platform/ops/requests.ops.js +153 -0
  328. package/dist/platform/ops/role.d.ts +4 -0
  329. package/dist/platform/ops/role.js +10 -0
  330. package/dist/platform/ops/skills.ops.d.ts +13 -0
  331. package/dist/platform/ops/skills.ops.js +98 -0
  332. package/dist/platform/ops/summary.d.ts +10 -0
  333. package/dist/platform/ops/summary.js +18 -0
  334. package/dist/platform/platform-ops.module.d.ts +7 -0
  335. package/dist/platform/platform-ops.module.js +55 -0
  336. package/dist/platform/platform.module.d.ts +8 -0
  337. package/dist/platform/platform.module.js +25 -0
  338. package/dist/platform/redact-orgs.d.ts +7 -0
  339. package/dist/platform/redact-orgs.js +52 -0
  340. package/dist/platform/registry.d.ts +30 -0
  341. package/dist/platform/registry.js +111 -0
  342. package/dist/roles/worker-role.d.ts +6 -4
  343. package/dist/roles/worker-role.js +14 -7
  344. package/dist/roles/worker.module.d.ts +1 -1
  345. package/dist/roles/worker.module.js +9 -1
  346. package/dist/runtime/context/build.d.ts +6 -4
  347. package/dist/runtime/context/build.js +26 -7
  348. package/dist/runtime/context/claude-tools.d.ts +2 -1
  349. package/dist/runtime/context/claude-tools.js +5 -4
  350. package/dist/runtime/context/compaction.js +9 -0
  351. package/dist/runtime/context/reminders.d.ts +2 -0
  352. package/dist/runtime/context/reminders.js +2 -0
  353. package/dist/runtime/context/skills.js +9 -2
  354. package/dist/runtime/context/tool-changes.d.ts +27 -0
  355. package/dist/runtime/context/tool-changes.js +60 -0
  356. package/dist/runtime/hook-calls.js +2 -0
  357. package/dist/runtime/langgraph-loop.d.ts +3 -1
  358. package/dist/runtime/langgraph-loop.js +35 -17
  359. package/dist/runtime/loop.d.ts +32 -4
  360. package/dist/runtime/maintenance.d.ts +7 -4
  361. package/dist/runtime/maintenance.js +23 -8
  362. package/dist/runtime/model-call.d.ts +30 -8
  363. package/dist/runtime/model-call.js +69 -19
  364. package/dist/runtime/run-control.d.ts +11 -1
  365. package/dist/runtime/run-control.js +12 -0
  366. package/dist/runtime/run-drafts.d.ts +85 -0
  367. package/dist/runtime/run-drafts.js +230 -0
  368. package/dist/runtime/run-jobs.d.ts +3 -5
  369. package/dist/runtime/run-jobs.js +3 -7
  370. package/dist/runtime/run-queue.d.ts +37 -3
  371. package/dist/runtime/run-queue.js +188 -11
  372. package/dist/runtime/run-worker.d.ts +11 -5
  373. package/dist/runtime/run-worker.js +54 -31
  374. package/dist/runtime/runtime.module.js +3 -0
  375. package/dist/runtime/step-log.d.ts +9 -4
  376. package/dist/runtime/step-log.js +8 -5
  377. package/dist/runtime/stream.controller.d.ts +23 -1
  378. package/dist/runtime/stream.controller.js +60 -3
  379. package/dist/runtime/stream.d.ts +4 -1
  380. package/dist/runtime/stream.js +27 -3
  381. package/dist/runtime/subagents/child.d.ts +55 -7
  382. package/dist/runtime/subagents/child.js +105 -7
  383. package/dist/runtime/subagents/definition.d.ts +12 -3
  384. package/dist/runtime/subagents/definition.js +43 -29
  385. package/dist/runtime/subagents/deliveries.d.ts +71 -0
  386. package/dist/runtime/subagents/deliveries.js +228 -0
  387. package/dist/runtime/subagents/dispatch.d.ts +115 -26
  388. package/dist/runtime/subagents/dispatch.js +212 -141
  389. package/dist/runtime/subagents/limits.d.ts +24 -5
  390. package/dist/runtime/subagents/limits.js +40 -6
  391. package/dist/runtime/subagents/messages.d.ts +95 -0
  392. package/dist/runtime/subagents/messages.js +328 -0
  393. package/dist/runtime/subagents/preamble.d.ts +4 -4
  394. package/dist/runtime/subagents/preamble.js +9 -7
  395. package/dist/runtime/subagents/progress.d.ts +8 -6
  396. package/dist/runtime/subagents/progress.js +11 -6
  397. package/dist/runtime/subagents/render.d.ts +30 -0
  398. package/dist/runtime/subagents/render.js +53 -0
  399. package/dist/runtime/subagents/roster.d.ts +24 -7
  400. package/dist/runtime/subagents/roster.js +47 -11
  401. package/dist/runtime/subagents/skill-fork.d.ts +3 -2
  402. package/dist/runtime/subagents/skill-fork.js +8 -4
  403. package/dist/runtime/subagents/status.d.ts +14 -0
  404. package/dist/runtime/subagents/status.js +23 -0
  405. package/dist/runtime/subagents/subagents.service.d.ts +7 -4
  406. package/dist/runtime/subagents/subagents.service.js +11 -6
  407. package/dist/runtime/usage-report.js +17 -12
  408. package/dist/runtime/waits.d.ts +140 -37
  409. package/dist/runtime/waits.js +394 -106
  410. package/dist/sandbox/jobs.d.ts +40 -13
  411. package/dist/sandbox/jobs.js +57 -20
  412. package/dist/sandbox/leases.d.ts +37 -54
  413. package/dist/sandbox/leases.js +71 -115
  414. package/dist/sandbox/providers.d.ts +2 -2
  415. package/dist/sandbox/providers.js +1 -1
  416. package/dist/sandbox/sandbox.module.d.ts +3 -2
  417. package/dist/sandbox/sandbox.module.js +4 -3
  418. package/dist/sandbox/sandbox.service.d.ts +229 -134
  419. package/dist/sandbox/sandbox.service.js +630 -409
  420. package/dist/skills/catalog.d.ts +3 -2
  421. package/dist/skills/catalog.js +21 -43
  422. package/dist/skills/changes.controller.d.ts +7 -0
  423. package/dist/skills/changes.controller.js +19 -1
  424. package/dist/skills/invoke.js +8 -3
  425. package/dist/skills/package.d.ts +20 -1
  426. package/dist/skills/package.js +28 -1
  427. package/dist/skills/skills.controller.d.ts +39 -4
  428. package/dist/skills/skills.controller.js +88 -10
  429. package/dist/skills/skills.module.js +10 -1
  430. package/dist/skills/skills.service.d.ts +106 -26
  431. package/dist/skills/skills.service.js +421 -75
  432. package/dist/skills/usable.d.ts +81 -0
  433. package/dist/skills/usable.js +379 -0
  434. package/dist/tools/approvals.service.d.ts +20 -2
  435. package/dist/tools/approvals.service.js +23 -4
  436. package/dist/tools/builtin-names.d.ts +21 -5
  437. package/dist/tools/builtin-names.js +30 -5
  438. package/dist/tools/builtins/agent.d.ts +23 -21
  439. package/dist/tools/builtins/agent.js +62 -55
  440. package/dist/tools/builtins/builtin-tools.d.ts +6 -2
  441. package/dist/tools/builtins/builtin-tools.js +37 -12
  442. package/dist/tools/builtins/handback.d.ts +28 -0
  443. package/dist/tools/builtins/handback.js +53 -0
  444. package/dist/tools/builtins/platform.d.ts +34 -0
  445. package/dist/tools/builtins/platform.js +362 -0
  446. package/dist/tools/builtins/sandbox/bash.js +13 -3
  447. package/dist/tools/builtins/sandbox/common.d.ts +43 -24
  448. package/dist/tools/builtins/sandbox/common.js +80 -45
  449. package/dist/tools/builtins/sandbox/edit.js +2 -2
  450. package/dist/tools/builtins/sandbox/glob.js +2 -2
  451. package/dist/tools/builtins/sandbox/grep.js +2 -4
  452. package/dist/tools/builtins/sandbox/index.d.ts +1 -1
  453. package/dist/tools/builtins/sandbox/index.js +1 -1
  454. package/dist/tools/builtins/sandbox/read.js +1 -1
  455. package/dist/tools/builtins/sandbox/task-output.d.ts +14 -3
  456. package/dist/tools/builtins/sandbox/task-output.js +30 -5
  457. package/dist/tools/builtins/sandbox/task-stop.js +2 -1
  458. package/dist/tools/builtins/sandbox/write.js +2 -2
  459. package/dist/tools/builtins/send-message.d.ts +56 -0
  460. package/dist/tools/builtins/send-message.js +100 -0
  461. package/dist/tools/builtins/skill-load.d.ts +22 -14
  462. package/dist/tools/builtins/skill-load.js +86 -57
  463. package/dist/tools/builtins/skill-write.js +1 -1
  464. package/dist/tools/builtins/web/extract.js +5 -1
  465. package/dist/tools/builtins/web/fetch.js +1 -0
  466. package/dist/tools/builtins/web/search.js +1 -0
  467. package/dist/tools/connectors.controller.d.ts +10 -0
  468. package/dist/tools/connectors.controller.js +12 -0
  469. package/dist/tools/connectors.service.d.ts +46 -5
  470. package/dist/tools/connectors.service.js +94 -15
  471. package/dist/tools/extension-tools.controller.d.ts +14 -0
  472. package/dist/tools/extension-tools.controller.js +37 -0
  473. package/dist/tools/info.d.ts +42 -1
  474. package/dist/tools/info.js +64 -1
  475. package/dist/tools/org-tool-switches.d.ts +74 -0
  476. package/dist/tools/org-tool-switches.js +184 -0
  477. package/dist/tools/pipeline.d.ts +46 -40
  478. package/dist/tools/pipeline.js +187 -364
  479. package/dist/tools/policy.d.ts +1 -1
  480. package/dist/tools/policy.js +36 -16
  481. package/dist/tools/registry.d.ts +98 -5
  482. package/dist/tools/registry.js +87 -9
  483. package/dist/tools/tools.module.js +12 -2
  484. package/dist/ui/views.d.ts +2 -1
  485. package/dist/ui/views.js +17 -3
  486. package/package.json +3 -3
  487. package/src/migrations/0074_subagent_tree.sql +50 -0
  488. package/src/migrations/0075_plugin_scope.sql +61 -0
  489. package/src/migrations/0076_skills_created_by_nullable.sql +6 -0
  490. package/src/migrations/0077_scope_requests.sql +52 -0
  491. package/src/migrations/0078_scope_grant_switches.sql +18 -0
  492. package/src/migrations/0079_scope_live_install_switches.sql +19 -0
  493. package/src/migrations/0080_rename_enterprise_admin.sql +18 -0
  494. package/src/migrations/0081_platform_components.sql +129 -0
  495. package/src/migrations/0082_platform_migration.sql +33 -0
  496. package/src/migrations/0083_plugin_scope_sync_failures.sql +15 -0
  497. package/src/migrations/0084_org_owned_items.sql +85 -0
  498. package/src/migrations/0085_agent_templates_phase4.sql +45 -0
  499. package/src/migrations/0086_org_layering.sql +30 -0
  500. package/src/migrations/0087_approval_summary.sql +6 -0
  501. package/src/migrations/0088_environments.sql +80 -0
  502. package/dist/catalog/upgrade-targets.d.ts +0 -56
  503. package/dist/catalog/upgrade-targets.js +0 -90
  504. package/dist/conversations/sandbox-status.d.ts +0 -24
  505. package/dist/conversations/sandbox-status.js +0 -52
  506. package/dist/extensions/org-config.controller.d.ts +0 -32
  507. package/dist/extensions/org-config.controller.js +0 -70
@@ -1,14 +1,15 @@
1
1
  import { isSandboxGoneError, ToolError, validateSandboxPath, } from "@capybara-hq/plugin-sdk";
2
+ import { ANONYMOUS_NO_ENVIRONMENT, } from "../../../environments/conversation-environments.js";
2
3
  import { ApiError } from "../../../errors.js";
3
4
  import { SandboxPathBusyError } from "../../../sandbox/leases.js";
4
- import { SandboxLockLostError } from "../../../sandbox/sandbox.service.js";
5
+ import { SandboxLockLostError, } from "../../../sandbox/sandbox.service.js";
5
6
  // ---- 模型可见文案(英文) ----
6
7
  /** 没有沙箱提供方时「工具不可用」的原因(进提醒与调用结果)。 */
7
- /** 本对话第一次用沙箱。 */
8
- export const SANDBOX_STARTED_NOTICE = "Sandbox started for this conversation (first use); the working directory is /workspace.";
9
- /** 沙箱被重建(之前的实例已销毁或不在了)。 */
10
- export const SANDBOX_RECREATED_NOTICE = "Sandbox was recreated; previous files are gone.";
11
- const BUSY_TEXT = "The sandbox is busy with another command in this conversation; wait for it to finish and retry.";
8
+ /** This conversation's first use of its environment. */
9
+ export const SANDBOX_STARTED_NOTICE = "Environment started (first use in this conversation); the working directory is /workspace, shared with the environment's other conversations.";
10
+ /** A new instance came up on the environment's kept files. */
11
+ export const SANDBOX_RESTARTED_NOTICE = "The environment's instance was restarted; files are kept, running processes and /tmp are gone.";
12
+ const BUSY_TEXT = "The environment is busy: all its command slots are taken by commands of this or another conversation sharing it; wait for one to finish and retry.";
12
13
  const NO_SANDBOX_TEXT = "No sandbox is configured in this deployment; ask an administrator to install a sandbox plugin, or do the task without the sandbox.";
13
14
  /** 没有沙箱提供方时「工具不可用」的原因(进提醒,内核在后面补句号):与调用时的错误同一句话。 */
14
15
  export const SANDBOX_UNAVAILABLE_REASON = NO_SANDBOX_TEXT.slice(0, -1);
@@ -16,12 +17,26 @@ export const SANDBOX_UNAVAILABLE_REASON = NO_SANDBOX_TEXT.slice(0, -1);
16
17
  export function noSandboxError() {
17
18
  return new ToolError(NO_SANDBOX_TEXT);
18
19
  }
19
- const PATH_BUSY_TEXT = "Another sub-agent is writing this file; wait a moment and retry.";
20
+ const PATH_BUSY_TEXT = "Another sub-agent or another conversation in this environment is writing this file; wait a moment and retry.";
21
+ const ANONYMOUS_TEXT = "The sandbox is not available to anonymous IM senders; do the task without the sandbox, or ask the person to link their account and start a new conversation.";
22
+ const ENV_NOT_FOUND_TEXT = "This conversation's environment was deleted or its owner can no longer use it; ask the user to start a new conversation in another environment.";
23
+ const ENV_FORBIDDEN_TEXT = "This conversation's owner may no longer use its environment; ask the user to start a new conversation in an environment they can use.";
24
+ const ENV_UNAVAILABLE_TEXT = "This conversation's environment is kept by a sandbox provider that is not active in this deployment; ask the user to start a new conversation in another environment, or an administrator to re-enable that provider.";
25
+ const ENV_FILES_LOST_TEXT = "This environment's files are gone. Ask the user to reset its files on the environments page, then retry.";
20
26
  const LOCK_LOST_TEXT = "The sandbox operation was interrupted because the sandbox lock was lost; check the sandbox state and retry.";
21
- /** 沙箱里附件所在目录。 */
22
- export const ATTACHMENTS_DIR = "/workspace/attachments";
23
- /** 已同步附件的标记文件:`{ <附件 id>: <文件名> }`。 */
24
- export const SYNC_MARKER = `${ATTACHMENTS_DIR}/.capybara-sync.json`;
27
+ /** The directory of attachments in the environment (each conversation has a subdirectory). */
28
+ export const ATTACHMENTS_ROOT = "/workspace/attachments";
29
+ /**
30
+ * One conversation's attachment directory: the first 12 hex digits of the root conversation's
31
+ * UUID, so conversations sharing an environment do not overwrite each other's files.
32
+ */
33
+ export const attachmentsDir = (rootConversationId) => `${ATTACHMENTS_ROOT}/${rootConversationId.replaceAll("-", "").slice(0, 12)}`;
34
+ /** The conversation's marker of synced attachments: `{ <attachment id>: <file name> }`. */
35
+ export const syncMarkerPath = (rootConversationId) => `${attachmentsDir(rootConversationId)}/.capybara-sync.json`;
36
+ const SYNC_MARKER_NAME = ".capybara-sync.json";
37
+ const SYNC_MARKER_RE = new RegExp(`^${ATTACHMENTS_ROOT}/[^/]+/${SYNC_MARKER_NAME.replaceAll(".", "\\.")}(?=$|[:-])`);
38
+ /** Whether a path, or a Grep output line starting with one, belongs to a sync marker (hidden from Glob / Grep). */
39
+ export const isSyncMarkerEntry = (pathOrLine) => SYNC_MARKER_RE.test(pathOrLine);
25
40
  const MARKER_MAX_BYTES = 1024 * 1024;
26
41
  /** 附件文件名的上限(UTF-8 字节,常见文件系统单个文件名上限 255 字节,留出 `-N` 后缀的余量)。 */
27
42
  export const ATTACHMENT_NAME_MAX_BYTES = 200;
@@ -133,11 +148,11 @@ function sanitizeName(raw) {
133
148
  */
134
149
  export function assignAttachmentNames(items, used) {
135
150
  const taken = new Set(used);
136
- taken.add(SYNC_MARKER.slice(ATTACHMENTS_DIR.length + 1));
151
+ taken.add(SYNC_MARKER_NAME);
137
152
  const out = new Map();
138
153
  for (const a of items) {
139
154
  let base = sanitizeName(a.name);
140
- if (validateSandboxPath(`${ATTACHMENTS_DIR}/${base}`).length > 0) {
155
+ if (validateSandboxPath(`${ATTACHMENTS_ROOT}/${base}`).length > 0) {
141
156
  base = `attachment-${a.id.slice(0, 8)}`;
142
157
  }
143
158
  let name = base;
@@ -171,35 +186,36 @@ function copyFailureReason(e) {
171
186
  return "a temporary error occurred; it will be retried on the next sandbox call";
172
187
  }
173
188
  /**
174
- * 把本对话已 ready 的附件复制到 `/workspace/attachments/<name>`,标记文件记下已复制的(不重复复制)。
175
- * `reset`(新建 / 重建的沙箱,文件已不在)时忽略标记文件全部重新复制。对象已不在的附件跳过(下次再试)。
189
+ * 把本对话已 ready 的附件复制到 `/workspace/attachments/<conversation>/<name>`({@link attachmentsDir}),
190
+ * 标记文件记下已复制的(不重复复制)。对象已不在的附件跳过(下次再试)。
176
191
  * 每复制一个就更新标记文件:中途超时 / 中止,下次从停下的地方继续。
177
192
  * 单个附件失败(存储故障等)只跳过它并给出说明,不让工具调用失败;signal 已中止或实例已不在时照常抛出。
178
193
  * 返回本次复制的沙箱路径与失败说明。
179
194
  */
180
- async function syncAttachments(deps, ctx, s, reset) {
195
+ async function syncAttachments(deps, ctx, s) {
181
196
  const none = { copied: [], failures: [] };
182
197
  const conv = sandboxConversationOf(ctx);
183
198
  const list = await deps.attachments.listForConversation(ctx.orgId, conv);
184
199
  if (list.length === 0)
185
200
  return none;
186
201
  // nothing to copy (the usual case): no path lease, so calls do not queue on the marker
187
- if (!reset) {
188
- const marker = await readSyncMarker(s);
189
- if (list.every((a) => Object.hasOwn(marker, a.id)))
190
- return none;
191
- }
202
+ const marker = await readSyncMarker(s, conv);
203
+ if (list.every((a) => Object.hasOwn(marker, a.id)))
204
+ return none;
192
205
  // the sync marker is read, changed and written: one holder at a time
193
- return withPathLease(deps, ctx, SYNC_MARKER, s.signal, (signal) => copyAttachments(deps, ctx, { ...s, signal }, reset, conv, list));
206
+ return withPathLease(deps, s, syncMarkerPath(conv), s.signal, (signal) => copyAttachments(deps, ctx, { ...s, signal }, conv, list));
194
207
  }
195
208
  /** The sync marker's entries (`{}` when it is missing, too large or unreadable). */
196
- async function readSyncMarker(s) {
197
- const m = await s.p.readFile(s.h, SYNC_MARKER, { maxBytes: MARKER_MAX_BYTES, signal: s.signal });
209
+ async function readSyncMarker(s, conv) {
210
+ const m = await s.p.readFile(s.h, syncMarkerPath(conv), {
211
+ maxBytes: MARKER_MAX_BYTES,
212
+ signal: s.signal,
213
+ });
198
214
  return m && !m.truncated ? parseMarker(m.data) : {};
199
215
  }
200
- async function copyAttachments(deps, ctx, s, reset, conv, list) {
216
+ async function copyAttachments(deps, ctx, s, conv, list) {
201
217
  const none = { copied: [], failures: [] };
202
- let marker = reset ? {} : await readSyncMarker(s);
218
+ let marker = await readSyncMarker(s, conv);
203
219
  const pending = list.filter((a) => !Object.hasOwn(marker, a.id));
204
220
  if (pending.length === 0)
205
221
  return none;
@@ -208,7 +224,7 @@ async function copyAttachments(deps, ctx, s, reset, conv, list) {
208
224
  const failures = [];
209
225
  for (const a of pending) {
210
226
  const name = names.get(a.id);
211
- const path = `${ATTACHMENTS_DIR}/${name}`;
227
+ const path = `${attachmentsDir(conv)}/${name}`;
212
228
  try {
213
229
  const opened = await deps.attachments.openForConversation(ctx.orgId, conv, a.id);
214
230
  if (!opened)
@@ -228,7 +244,7 @@ async function copyAttachments(deps, ctx, s, reset, conv, list) {
228
244
  copied.push(path);
229
245
  const next = { ...marker, [a.id]: name };
230
246
  try {
231
- await s.p.writeFile(s.h, SYNC_MARKER, utf8.encode(JSON.stringify(next)), s.signal);
247
+ await s.p.writeFile(s.h, syncMarkerPath(conv), utf8.encode(JSON.stringify(next)), s.signal);
232
248
  marker = next;
233
249
  }
234
250
  catch (e) {
@@ -243,8 +259,20 @@ export function mapSandboxError(e) {
243
259
  if (e instanceof ApiError) {
244
260
  if (e.code === "sandbox.busy")
245
261
  return new ToolError(BUSY_TEXT);
246
- if (e.code === "sandbox.unavailable")
262
+ if (e.code === "sandbox.unavailable") {
263
+ const reason = e.details?.[0]?.reason;
264
+ if (reason === ANONYMOUS_NO_ENVIRONMENT)
265
+ return new ToolError(ANONYMOUS_TEXT);
247
266
  return new ToolError(NO_SANDBOX_TEXT);
267
+ }
268
+ if (e.code === "environment.not_found")
269
+ return new ToolError(ENV_NOT_FOUND_TEXT);
270
+ if (e.code === "environment.forbidden")
271
+ return new ToolError(ENV_FORBIDDEN_TEXT);
272
+ if (e.code === "environment.unavailable")
273
+ return new ToolError(ENV_UNAVAILABLE_TEXT);
274
+ if (e.code === "environment.files_lost")
275
+ return new ToolError(ENV_FILES_LOST_TEXT);
248
276
  }
249
277
  if (e instanceof SandboxLockLostError)
250
278
  return new ToolError(LOCK_LOST_TEXT);
@@ -253,25 +281,31 @@ export function mapSandboxError(e) {
253
281
  return e;
254
282
  }
255
283
  /**
256
- * 在本对话的沙箱上执行 `fn`(`SandboxService.withSandbox`:懒创建、恢复、重建):先同步附件,
257
- * 再执行;返回结果与要加在结果开头的状态说明(首次使用 / 重建 / 新复制的附件)。
258
- * `withSandbox` 遇到实例不在时会重建并再调用一次回调,说明按最后一次调用的为准。
284
+ * Runs `fn` in the environment of the call's conversation (a sub-agent: its root's): resolves and
285
+ * checks the environment for the conversation's owner (binding an unbound conversation to the
286
+ * owner's default first), then `SandboxService.withSandbox` (the instance created, resumed or
287
+ * rebuilt on the kept files as needed, every `exec` carrying the call's actor). Attachments are
288
+ * synced first. Returns the value and the notices to put before the result (first use, a new
289
+ * instance, newly copied attachments). When `withSandbox` rebuilds a gone instance and calls
290
+ * `fn` again, the notices are the last call's.
259
291
  */
260
292
  export async function inSandbox(deps, ctx, fn) {
261
293
  try {
294
+ const environmentId = await deps.environments.forTool(ctx.orgId, sandboxConversationOf(ctx));
262
295
  return await deps.sandbox.withSandbox({
263
296
  orgId: ctx.orgId,
264
- conversationId: sandboxConversationOf(ctx),
265
- // a sub-agent is told when another holder rebuilt the shared sandbox (final review m5)
297
+ environmentId,
298
+ // a sub-agent is told when another holder rebuilt the shared instance (final review m5)
266
299
  holderConversationId: ctx.conversationId,
300
+ actor: { accountId: ctx.accountId, conversationId: ctx.conversationId },
267
301
  }, async (h, p, info, signal) => {
268
- const s = { h, p, signal, reset: info.fresh || info.recreated };
302
+ const s = { environmentId, h, p, signal };
269
303
  const notices = [];
270
- if (info.recreated)
271
- notices.push(SANDBOX_RECREATED_NOTICE);
304
+ if (info.restarted)
305
+ notices.push(SANDBOX_RESTARTED_NOTICE);
272
306
  else if (info.fresh)
273
307
  notices.push(SANDBOX_STARTED_NOTICE);
274
- const { copied, failures } = await syncAttachments(deps, ctx, s, s.reset);
308
+ const { copied, failures } = await syncAttachments(deps, ctx, s);
275
309
  if (copied.length > 0) {
276
310
  notices.push(`Attachments copied into the sandbox: ${copied.join(", ")}.`);
277
311
  }
@@ -283,18 +317,19 @@ export async function inSandbox(deps, ctx, fn) {
283
317
  throw mapSandboxError(e);
284
318
  }
285
319
  }
286
- /** The conversation whose sandbox a call uses (the parent's for a sub-agent). */
320
+ /** The conversation whose environment a call uses (the root conversation's for a sub-agent). */
287
321
  export const sandboxConversationOf = (ctx) => ctx.sandboxConversationId ?? ctx.conversationId;
288
322
  /**
289
- * Runs `fn` under the per-path lease of `path` in the call's sandbox (spec §10.4: the kernel's own
290
- * read-modify-write of one file never loses another holder's update). `fn` gets `signal` combined
291
- * with the path lease's: pass it to every provider call, so a lost path lease stops the write.
292
- * Without `pathLease` (test stubs) it just runs `fn` with `signal`.
323
+ * Runs `fn` under the per-path lease of `path` in the session's environment (spec §10.4: the
324
+ * kernel's own read-modify-write of one file never loses another holder's update, from any
325
+ * conversation sharing the environment). `fn` gets `signal` combined with the path lease's: pass
326
+ * it to every provider call, so a lost path lease stops the write. Without `pathLease` (test
327
+ * stubs) it just runs `fn` with `signal`.
293
328
  */
294
- export async function withPathLease(deps, ctx, path, signal, fn) {
329
+ export async function withPathLease(deps, s, path, signal, fn) {
295
330
  if (!deps.sandbox.pathLease)
296
331
  return fn(signal);
297
- const lease = await deps.sandbox.pathLease(sandboxConversationOf(ctx), path, signal);
332
+ const lease = await deps.sandbox.pathLease(s.environmentId, path, signal);
298
333
  try {
299
334
  return await fn(AbortSignal.any([signal, lease.signal]));
300
335
  }
@@ -56,9 +56,9 @@ export function sandboxEditTool(deps) {
56
56
  const path = checkWritable(input.file_path);
57
57
  if (old_string === new_string)
58
58
  throw new ToolError(SAME_TEXT);
59
- const { value: edit, notices } = await inSandbox(deps, ctx, ({ h, p, signal }) =>
59
+ const { value: edit, notices } = await inSandbox(deps, ctx, ({ environmentId, h, p, signal }) =>
60
60
  // read, replace, write: one holder at a time per file
61
- withPathLease(deps, ctx, path, signal, async (signal) => {
61
+ withPathLease(deps, { environmentId }, path, signal, async (signal) => {
62
62
  const st = await p.stat(h, path, signal);
63
63
  if (st === null)
64
64
  throw new ToolError(notFound(path));
@@ -1,5 +1,5 @@
1
1
  import { ToolError } from "@capybara-hq/plugin-sdk";
2
- import { checkPath, clip, display, inSandbox, SYNC_MARKER, sandboxBaseTimeoutMs, searchTimeoutMs, unavailableWhenNoSandbox, withNotices, } from "./common.js";
2
+ import { checkPath, clip, display, inSandbox, isSyncMarkerEntry, sandboxBaseTimeoutMs, searchTimeoutMs, unavailableWhenNoSandbox, withNotices, } from "./common.js";
3
3
  import { compileGlob, GlobPatternError } from "./glob-match.js";
4
4
  /** 最多列出的文件数。 */
5
5
  const MAX_RESULTS = 1000;
@@ -82,7 +82,7 @@ export function sandboxGlobTool(deps) {
82
82
  .map((l) => l.slice(2))
83
83
  .filter((rel) => matches(rel))
84
84
  .map((rel) => `${base}/${rel}`)
85
- .filter((abs) => abs !== SYNC_MARKER)
85
+ .filter((abs) => !isSyncMarkerEntry(abs))
86
86
  .sort()
87
87
  // 文件名里的换行显示为 `\n`(与 Grep 一致),一行一个文件
88
88
  .map((abs) => abs.replace(/\n/g, "\\n")));
@@ -1,5 +1,5 @@
1
1
  import { ToolError } from "@capybara-hq/plugin-sdk";
2
- import { checkPath, clip, display, inSandbox, SYNC_MARKER, sandboxBaseTimeoutMs, searchTimeoutMs, shellQuote, unavailableWhenNoSandbox, withNotices, } from "./common.js";
2
+ import { checkPath, clip, display, inSandbox, isSyncMarkerEntry, sandboxBaseTimeoutMs, searchTimeoutMs, shellQuote, unavailableWhenNoSandbox, withNotices, } from "./common.js";
3
3
  /** The most output entries (lines, files or counts) returned in one call, whatever `head_limit` says. */
4
4
  const MAX_MATCHES = 500;
5
5
  /** `head_limit` when the model gives none. */
@@ -207,9 +207,7 @@ export function sandboxGrepTool(deps) {
207
207
  : mode === "count"
208
208
  ? parseCounts(r.stdout, base)
209
209
  : parseGrepNull(r.stdout, base, numbered);
210
- const entries = all.filter((l) => l !== SYNC_MARKER &&
211
- !l.startsWith(`${SYNC_MARKER}:`) &&
212
- !l.startsWith(`${SYNC_MARKER}-`));
210
+ const entries = all.filter((l) => !isSyncMarkerEntry(l));
213
211
  // 退出码 2 = 有错误(如个别文件不可读);有输出时照常返回(可能为空:只匹配到隐藏的标记文件)并附上说明
214
212
  if (r.exitCode !== 0 && all.length === 0)
215
213
  throw new ToolError(failed(r.stderr));
@@ -2,7 +2,7 @@ import type { BuiltinTool } from "../../registry.js";
2
2
  import type { SandboxToolDeps } from "./common.js";
3
3
  export { SANDBOX_ASK_TOOL_NAMES, SANDBOX_TOOL_NAMES } from "../../builtin-names.js";
4
4
  export { BASH_SPILL_CHARS, formatExec } from "./bash.js";
5
- export { assignAttachmentNames, RUN_DEADLINE_MARGIN_MS, runTimeLeftMs, SANDBOX_RECREATED_NOTICE, SANDBOX_SETUP_MARGIN_MS, SANDBOX_STARTED_NOTICE, SANDBOX_UNAVAILABLE_REASON, type SandboxToolDeps, sandboxBaseTimeoutMs, searchTimeoutMs, shellQuote, } from "./common.js";
5
+ export { assignAttachmentNames, RUN_DEADLINE_MARGIN_MS, runTimeLeftMs, SANDBOX_RESTARTED_NOTICE, SANDBOX_SETUP_MARGIN_MS, SANDBOX_STARTED_NOTICE, SANDBOX_UNAVAILABLE_REASON, type SandboxToolDeps, sandboxBaseTimeoutMs, searchTimeoutMs, shellQuote, } from "./common.js";
6
6
  export { compileGlob, GlobPatternError, MAX_GLOB_STARS } from "./glob-match.js";
7
7
  /**
8
8
  * 沙箱内置工具(M5 T8):bash / read / write / edit / glob / grep / deliver,都在本对话的沙箱上执行
@@ -9,7 +9,7 @@ import { taskStopTool } from "./task-stop.js";
9
9
  import { sandboxWriteTool } from "./write.js";
10
10
  export { SANDBOX_ASK_TOOL_NAMES, SANDBOX_TOOL_NAMES } from "../../builtin-names.js";
11
11
  export { BASH_SPILL_CHARS, formatExec } from "./bash.js";
12
- export { assignAttachmentNames, RUN_DEADLINE_MARGIN_MS, runTimeLeftMs, SANDBOX_RECREATED_NOTICE, SANDBOX_SETUP_MARGIN_MS, SANDBOX_STARTED_NOTICE, SANDBOX_UNAVAILABLE_REASON, sandboxBaseTimeoutMs, searchTimeoutMs, shellQuote, } from "./common.js";
12
+ export { assignAttachmentNames, RUN_DEADLINE_MARGIN_MS, runTimeLeftMs, SANDBOX_RESTARTED_NOTICE, SANDBOX_SETUP_MARGIN_MS, SANDBOX_STARTED_NOTICE, SANDBOX_UNAVAILABLE_REASON, sandboxBaseTimeoutMs, searchTimeoutMs, shellQuote, } from "./common.js";
13
13
  export { compileGlob, GlobPatternError, MAX_GLOB_STARS } from "./glob-match.js";
14
14
  /**
15
15
  * 沙箱内置工具(M5 T8):bash / read / write / edit / glob / grep / deliver,都在本对话的沙箱上执行
@@ -13,7 +13,7 @@ const SPEC = {
13
13
  // Display only (the tool row; not in the fingerprint, never sent to the model).
14
14
  keyArgs: ["file_path"],
15
15
  description: "Read a text file from this conversation's sandbox, with line numbers. Use it to look at " +
16
- "source code, data files, logs and files the user attached (under /workspace/attachments). " +
16
+ "source code, data files, logs and files the user attached (under /workspace/attachments/<conversation>/). " +
17
17
  "Paths are absolute, under /workspace, /skills or /tmp. Lines are numbered from 1; pass " +
18
18
  "offset and limit to read part of a long file. Binary files are not shown; use Bash " +
19
19
  "to inspect them. Do not use it to list directories; use Glob instead. Read a file before you " +
@@ -1,6 +1,6 @@
1
1
  import { type SandboxHandle } from "@capybara-hq/plugin-sdk";
2
2
  import type { BackgroundTaskRow } from "../../../background/store.js";
3
- import type { IfRunningResult, SandboxService, TaggedProvider } from "../../../sandbox/sandbox.service.js";
3
+ import type { HeldProvider, IfRunningResult, SandboxService } from "../../../sandbox/sandbox.service.js";
4
4
  import type { BuiltinCallContext, BuiltinTool } from "../../registry.js";
5
5
  import { type SandboxToolDeps } from "./common.js";
6
6
  /** How long `TaskOutput` waits with `block` when `timeout` is not given (ms). */
@@ -14,6 +14,7 @@ export interface TaskEnv {
14
14
  store: NonNullable<SandboxToolDeps["background"]>;
15
15
  tasks: NonNullable<SandboxToolDeps["tasks"]>;
16
16
  ifRunning: SandboxService["ifRunning"];
17
+ environments: SandboxToolDeps["environments"];
17
18
  }
18
19
  /** The task tools' dependencies; throws the tool's error when they are missing. */
19
20
  export declare function taskEnv(deps: SandboxToolDeps): TaskEnv;
@@ -22,8 +23,18 @@ export declare function taskEnv(deps: SandboxToolDeps): TaskEnv;
22
23
  * sub-agent's, when called from its parent) is not found, the same as an unknown id.
23
24
  */
24
25
  export declare function ownedTask(env: TaskEnv, ctx: BuiltinCallContext, id: string): Promise<BackgroundTaskRow>;
25
- /** `ifRunning` on the task's own sandbox instance; sandbox errors become the tools' errors. */
26
- export declare function onTaskInstance<T>(env: TaskEnv, task: BackgroundTaskRow, fn: (p: TaggedProvider, h: SandboxHandle, signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<IfRunningResult<T>>;
26
+ /**
27
+ * The per-call access re-check of every sandbox tool (`inSandbox`): the conversation's environment
28
+ * may still be used by its owner. The task tools read a task's own instance without `inSandbox`,
29
+ * so they check here first; errors become the tools' errors.
30
+ */
31
+ export declare function recheckEnvironment(env: TaskEnv, ctx: BuiltinCallContext): Promise<void>;
32
+ /**
33
+ * `ifRunning` on the task's own environment instance (its execs act for the task's trigger in its
34
+ * conversation); sandbox errors become the tools' errors. A task from before environments has no
35
+ * instance (`not_running`).
36
+ */
37
+ export declare function onTaskInstance<T>(env: TaskEnv, task: BackgroundTaskRow, fn: (p: HeldProvider, h: SandboxHandle, signal: AbortSignal) => Promise<T>, signal: AbortSignal): Promise<IfRunningResult<T>>;
27
38
  /**
28
39
  * The task's status line: `Status: running (2m05s)`, `Status: failed, exit code 3, after 4m12s`,
29
40
  * `Status: stopped after 1m00s`, `Status: lost (the sandbox was suspended) after 3s`.
@@ -2,10 +2,10 @@ import { setTimeout as sleep } from "node:timers/promises";
2
2
  import { isSandboxGoneError, ToolError, } from "@capybara-hq/plugin-sdk";
3
3
  import { TASK_ID_RE, TASKS_DIR } from "../../../background/launch.js";
4
4
  import { formatElapsed, lostReasonText } from "../../../background/render.js";
5
- import { SID_RE } from "../../../background/session.js";
5
+ import { actingAs, SID_RE, taskActor } from "../../../background/session.js";
6
6
  import { parsePollOutput, polledAs, pollScript, } from "../../../background/status.js";
7
7
  import { notRunningAs, RECREATED } from "../../../background/stop.js";
8
- import { clip, display, mapSandboxError, noSandboxError, runTimeLeftMs, sandboxBaseTimeoutMs, unavailableWhenNoSandbox, } from "./common.js";
8
+ import { clip, display, mapSandboxError, noSandboxError, runTimeLeftMs, sandboxBaseTimeoutMs, sandboxConversationOf, unavailableWhenNoSandbox, } from "./common.js";
9
9
  /** How long `TaskOutput` waits with `block` when `timeout` is not given (ms). */
10
10
  export const TASK_OUTPUT_DEFAULT_TIMEOUT_MS = 30_000;
11
11
  /** The longest `TaskOutput` wait (ms). */
@@ -57,7 +57,12 @@ export function taskEnv(deps) {
57
57
  if (!background || !tasks || !deps.sandbox.ifRunning) {
58
58
  throw new ToolError("Background tasks are not available here; use Bash without run_in_background instead.");
59
59
  }
60
- return { store: background, tasks, ifRunning: deps.sandbox.ifRunning.bind(deps.sandbox) };
60
+ return {
61
+ store: background,
62
+ tasks,
63
+ ifRunning: deps.sandbox.ifRunning.bind(deps.sandbox),
64
+ environments: deps.environments,
65
+ };
61
66
  }
62
67
  const notFound = (id) => new ToolError(`No background task ${clip(id, 40)} in this conversation. Pass a task id that Bash with run_in_background returned in this conversation.`);
63
68
  /**
@@ -72,10 +77,29 @@ export async function ownedTask(env, ctx, id) {
72
77
  throw notFound(id);
73
78
  return task;
74
79
  }
75
- /** `ifRunning` on the task's own sandbox instance; sandbox errors become the tools' errors. */
80
+ /**
81
+ * The per-call access re-check of every sandbox tool (`inSandbox`): the conversation's environment
82
+ * may still be used by its owner. The task tools read a task's own instance without `inSandbox`,
83
+ * so they check here first; errors become the tools' errors.
84
+ */
85
+ export async function recheckEnvironment(env, ctx) {
86
+ try {
87
+ await env.environments.forTool(ctx.orgId, sandboxConversationOf(ctx));
88
+ }
89
+ catch (e) {
90
+ throw mapSandboxError(e);
91
+ }
92
+ }
93
+ /**
94
+ * `ifRunning` on the task's own environment instance (its execs act for the task's trigger in its
95
+ * conversation); sandbox errors become the tools' errors. A task from before environments has no
96
+ * instance (`not_running`).
97
+ */
76
98
  export async function onTaskInstance(env, task, fn, signal) {
99
+ if (task.environmentId === null)
100
+ return { kind: "not_running", status: "gone" };
77
101
  try {
78
- return await env.ifRunning(task.sandboxConversationId, { createdAt: task.sandboxCreatedAt }, fn, signal);
102
+ return await env.ifRunning(task.environmentId, { createdAt: task.sandboxCreatedAt }, (p, h, sig) => fn(actingAs(p, taskActor(task)), h, sig), signal);
79
103
  }
80
104
  catch (e) {
81
105
  throw mapSandboxError(e);
@@ -240,6 +264,7 @@ export function taskOutputTool(deps) {
240
264
  const { task_id, block = true, timeout } = input;
241
265
  const env = taskEnv(deps);
242
266
  let task = await ownedTask(env, ctx, task_id);
267
+ await recheckEnvironment(env, ctx);
243
268
  if (block && task.status === "running") {
244
269
  const wait = Math.max(0, Math.min(timeout ?? TASK_OUTPUT_DEFAULT_TIMEOUT_MS, TASK_OUTPUT_MAX_TIMEOUT_MS, runTimeLeftMs(ctx.runDeadline)));
245
270
  const until = Date.now() + wait;
@@ -1,7 +1,7 @@
1
1
  import { ToolError } from "@capybara-hq/plugin-sdk";
2
2
  import { decodeTail, tailCommand } from "../../../background/session.js";
3
3
  import { clip, display, mapSandboxError, sandboxBaseTimeoutMs, unavailableWhenNoSandbox, } from "./common.js";
4
- import { onTaskInstance, ownedTask, statusLine, taskEnv } from "./task-output.js";
4
+ import { onTaskInstance, ownedTask, recheckEnvironment, statusLine, taskEnv, } from "./task-output.js";
5
5
  /** The time limit of reading a stopped task's last lines. */
6
6
  const TAIL_EXEC_TIMEOUT_MS = 10_000;
7
7
  const SPEC = {
@@ -84,6 +84,7 @@ export function taskStopTool(deps) {
84
84
  const { task_id } = input;
85
85
  const env = taskEnv(deps);
86
86
  const task = await ownedTask(env, ctx, task_id);
87
+ await recheckEnvironment(env, ctx);
87
88
  if (task.status !== "running") {
88
89
  return ended(env, task, "had already finished", ctx.signal);
89
90
  }
@@ -45,9 +45,9 @@ export function sandboxWriteTool(deps) {
45
45
  async run(input, ctx) {
46
46
  const path = checkWritable(input.file_path);
47
47
  const data = new TextEncoder().encode(input.content);
48
- const { value, notices } = await inSandbox(deps, ctx, ({ h, p, signal }) =>
48
+ const { value, notices } = await inSandbox(deps, ctx, ({ environmentId, h, p, signal }) =>
49
49
  // stat, read the previous content, write: one holder at a time per file
50
- withPathLease(deps, ctx, path, signal, async (signal) => {
50
+ withPathLease(deps, { environmentId }, path, signal, async (signal) => {
51
51
  const st = await p.stat(h, path, signal);
52
52
  if (st?.isDir)
53
53
  throw new ToolError(isDirectory(path));
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ import type { BuiltinTool } from "../registry.js";
3
+ export { SEND_MESSAGE } from "../builtin-names.js";
4
+ /**
5
+ * The `SendMessage` builtin tool (agent map spec §4.2, §5.1, §5.2): moves text between the agents
6
+ * of one tree. An agent sends to one of its own sub-agents by agentId (a running one reads it at its
7
+ * next step, an idle one starts again with its earlier context), and a sub-agent to `"parent"`.
8
+ * The result says the message was delivered, never the target's reply. The tool pipeline handles
9
+ * the call itself (`SubagentMessages`), so {@link sendMessageTool}'s `run` is only a guard.
10
+ */
11
+ /** The input of a `SendMessage` call. */
12
+ export declare const SendMessageInput: z.ZodObject<{
13
+ to: z.ZodString;
14
+ message: z.ZodString;
15
+ }, z.core.$strict>;
16
+ export type SendMessageInputT = z.infer<typeof SendMessageInput>;
17
+ /** The target a sub-agent uses for the agent that dispatched it. */
18
+ export declare const PARENT_TARGET = "parent";
19
+ /** One valid target of a caller: a sub-agent of its own, by agentId and task label. */
20
+ export interface SendTarget {
21
+ id: string;
22
+ description: string;
23
+ }
24
+ /** Refusals: `isError` results written without delivering anything (model-visible). */
25
+ export declare const SEND_MESSAGE_REFUSALS: {
26
+ /**
27
+ * `to` is none of the caller's own sub-agents (nor `"parent"` in a sub-agent): lists the valid
28
+ * targets, at most the newest {@link SEND_TARGETS_LISTED} sub-agents.
29
+ */
30
+ readonly unknownTarget: (to: string, targets: readonly SendTarget[], opts: {
31
+ hasParent: boolean;
32
+ more: number;
33
+ }) => string;
34
+ /** The sub-agent's type or org agent is no longer available to the caller (its gates). */
35
+ readonly notAvailable: (id: string, type: string) => string;
36
+ /** The limits of a send that would start an idle sub-agent again (agent map spec §6). */
37
+ readonly tooManyConcurrent: (n: number) => string;
38
+ readonly tooManyDispatches: (n: number) => string;
39
+ readonly budget: (n: number) => string;
40
+ readonly depthLimit: (maxDepth: number) => string;
41
+ readonly notAvailableHere: "Messages between agents are not available in this conversation.";
42
+ };
43
+ /** How many of the caller's sub-agents an unknown-target refusal lists (the newest). */
44
+ export declare const SEND_TARGETS_LISTED = 20;
45
+ /** The result of a message to a sub-agent whose run was active (agent map spec §5.1). */
46
+ export declare const sentToRunningText: (t: SendTarget) => string;
47
+ /** The result of a message that started an idle sub-agent again (agent map spec §5.1, §6). */
48
+ export declare const sentToIdleText: (t: SendTarget) => string;
49
+ /** The result of a sub-agent's note to its parent (agent map spec §5.2). */
50
+ export declare const SENT_TO_PARENT_TEXT = "Message delivered to the agent that dispatched you. Keep working; its reply, if any, arrives as a message in this conversation.";
51
+ /**
52
+ * The builtin. `defaultPolicy: "allow"` (agent map spec §4.2): it only moves text inside one tree
53
+ * the person already started. The tool pipeline handles `SendMessage` calls itself; `run` answers
54
+ * only when a call reaches it anyway.
55
+ */
56
+ export declare const sendMessageTool: BuiltinTool;
@@ -0,0 +1,100 @@
1
+ import { z } from "zod";
2
+ export { SEND_MESSAGE } from "../builtin-names.js";
3
+ /**
4
+ * The `SendMessage` builtin tool (agent map spec §4.2, §5.1, §5.2): moves text between the agents
5
+ * of one tree. An agent sends to one of its own sub-agents by agentId (a running one reads it at its
6
+ * next step, an idle one starts again with its earlier context), and a sub-agent to `"parent"`.
7
+ * The result says the message was delivered, never the target's reply. The tool pipeline handles
8
+ * the call itself (`SubagentMessages`), so {@link sendMessageTool}'s `run` is only a guard.
9
+ */
10
+ /** The input of a `SendMessage` call. */
11
+ export const SendMessageInput = z
12
+ .object({
13
+ to: z.string().min(1).max(64),
14
+ message: z.string().min(1).max(100_000),
15
+ })
16
+ .strict();
17
+ /** The target a sub-agent uses for the agent that dispatched it. */
18
+ export const PARENT_TARGET = "parent";
19
+ const SPEC = {
20
+ name: "SendMessage",
21
+ description: "Send a message to another agent of this conversation. To reach one of your sub-agents, pass " +
22
+ "its agentId (from the Agent result) as to: a sub-agent that is working reads the message at " +
23
+ "its next step, and one that already finished starts working again with its earlier context. " +
24
+ 'A sub-agent can pass "parent" as to, to send a note to the agent that dispatched it. This ' +
25
+ "tool only delivers the message and returns at once; it never waits for a reply. Replies, " +
26
+ "reports and finishes arrive later in this conversation as notifications. A sub-agent hands " +
27
+ "back its final report with SubagentHandback, not with this tool.",
28
+ inputSchema: {
29
+ type: "object",
30
+ properties: {
31
+ to: {
32
+ type: "string",
33
+ minLength: 1,
34
+ maxLength: 64,
35
+ description: 'The agentId of one of your sub-agents, or "parent" in a sub-agent.',
36
+ },
37
+ message: {
38
+ type: "string",
39
+ minLength: 1,
40
+ maxLength: 100000,
41
+ description: "The message. The receiving agent sees only this text, so include everything it needs.",
42
+ },
43
+ },
44
+ required: ["to", "message"],
45
+ additionalProperties: false,
46
+ },
47
+ // display only (UI refresh B): who the message goes to; never sent to the model
48
+ keyArgs: ["to"],
49
+ };
50
+ /** `12345` → `12,345` (no locale data involved, so the text is the same on every replica). */
51
+ const count = (n) => String(Math.round(n)).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
52
+ /** How a target is listed in a refusal. */
53
+ const targetLine = (t) => `${t.id} (${JSON.stringify(t.description)})`;
54
+ /** Refusals: `isError` results written without delivering anything (model-visible). */
55
+ export const SEND_MESSAGE_REFUSALS = {
56
+ /**
57
+ * `to` is none of the caller's own sub-agents (nor `"parent"` in a sub-agent): lists the valid
58
+ * targets, at most the newest {@link SEND_TARGETS_LISTED} sub-agents.
59
+ */
60
+ unknownTarget: (to, targets, opts) => {
61
+ const lines = [
62
+ ...targets.map(targetLine),
63
+ ...(opts.hasParent ? [`"${PARENT_TARGET}" (the agent that dispatched you)`] : []),
64
+ ];
65
+ if (lines.length === 0) {
66
+ return `There is no agent "${to}" to send to: you have no sub-agents yet. Use Agent to dispatch one.`;
67
+ }
68
+ const more = opts.more > 0 ? `, and ${opts.more} older sub-agents` : "";
69
+ return `There is no agent "${to}" you can send to. Pass one of these as to: ${lines.join(", ")}${more}.`;
70
+ },
71
+ /** The sub-agent's type or org agent is no longer available to the caller (its gates). */
72
+ notAvailable: (id, type) => `Sub-agent ${id} can no longer receive messages: its agent type "${type}" is not available to you any more. Use Agent to dispatch another sub-agent instead.`,
73
+ /** The limits of a send that would start an idle sub-agent again (agent map spec §6). */
74
+ tooManyConcurrent: (n) => `At most ${n} of your sub-agents can run at once in this conversation, and this one has finished; send the message again after one of the running sub-agents finishes.`,
75
+ tooManyDispatches: (n) => `${n} sub-agents have been dispatched or restarted since the user's latest message, counted across all levels of sub-agents; that is the limit, so this finished sub-agent cannot start again. Do the remaining work yourself.`,
76
+ budget: (n) => `Sub-agents have used their token budget since the user's latest message (${count(n)} tokens, counted across all levels of sub-agents), so this finished sub-agent cannot start again. Do the remaining work yourself.`,
77
+ depthLimit: (maxDepth) => `Sub-agents can be nested at most ${maxDepth} levels deep and you are at the deepest level, so this finished sub-agent cannot start again. Do the remaining work yourself.`,
78
+ notAvailableHere: "Messages between agents are not available in this conversation.",
79
+ };
80
+ /** How many of the caller's sub-agents an unknown-target refusal lists (the newest). */
81
+ export const SEND_TARGETS_LISTED = 20;
82
+ /** The result of a message to a sub-agent whose run was active (agent map spec §5.1). */
83
+ export const sentToRunningText = (t) => `Message delivered to sub-agent ${targetLine(t)}, which is working; it reads the message at its next step. Its reply or report arrives later as a notification; keep working or end your turn.`;
84
+ /** The result of a message that started an idle sub-agent again (agent map spec §5.1, §6). */
85
+ export const sentToIdleText = (t) => `Message delivered to sub-agent ${targetLine(t)}, which had finished; it is working again with its earlier context. Its reply or report arrives later as a notification; keep working or end your turn.`;
86
+ /** The result of a sub-agent's note to its parent (agent map spec §5.2). */
87
+ export const SENT_TO_PARENT_TEXT = "Message delivered to the agent that dispatched you. Keep working; its reply, if any, arrives as a message in this conversation.";
88
+ /**
89
+ * The builtin. `defaultPolicy: "allow"` (agent map spec §4.2): it only moves text inside one tree
90
+ * the person already started. The tool pipeline handles `SendMessage` calls itself; `run` answers
91
+ * only when a call reaches it anyway.
92
+ */
93
+ export const sendMessageTool = {
94
+ spec: SPEC,
95
+ defaultPolicy: "allow",
96
+ run: async () => ({
97
+ content: [{ type: "text", text: SEND_MESSAGE_REFUSALS.notAvailableHere }],
98
+ isError: true,
99
+ }),
100
+ };