@capybara-hq/kernel 0.1.0-rc.21 → 0.1.0-rc.23

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 (263) hide show
  1. package/dist/admin/admin.controller.d.ts +3 -3
  2. package/dist/admin/admin.controller.js +6 -2
  3. package/dist/admin/admin.schemas.d.ts +13 -0
  4. package/dist/agents/admin-agents.d.ts +16 -3
  5. package/dist/agents/admin-agents.js +65 -7
  6. package/dist/agents/agents.schemas.d.ts +24 -6
  7. package/dist/agents/agents.service.d.ts +4 -3
  8. package/dist/agents/agents.service.js +39 -26
  9. package/dist/agents/definition.d.ts +44 -6
  10. package/dist/agents/definition.js +86 -18
  11. package/dist/agents/from-template.d.ts +6 -3
  12. package/dist/agents/from-template.js +57 -44
  13. package/dist/agents/org-templates.js +97 -41
  14. package/dist/agents/templates.d.ts +6 -0
  15. package/dist/agents/templates.js +15 -1
  16. package/dist/background/launch.d.ts +43 -5
  17. package/dist/background/launch.js +88 -8
  18. package/dist/background/session.d.ts +14 -2
  19. package/dist/background/session.js +26 -4
  20. package/dist/background/status.d.ts +1 -1
  21. package/dist/background/status.js +3 -3
  22. package/dist/background/stop.d.ts +0 -2
  23. package/dist/background/stop.js +1 -21
  24. package/dist/catalog/admin-catalog.controller.d.ts +2 -4
  25. package/dist/catalog/admin-catalog.controller.js +2 -6
  26. package/dist/catalog/catalog-content.d.ts +5 -0
  27. package/dist/catalog/catalog-content.js +1 -0
  28. package/dist/catalog/catalog.module.js +3 -0
  29. package/dist/catalog/claude/report.d.ts +9 -2
  30. package/dist/catalog/claude/report.js +1 -0
  31. package/dist/catalog/claude/translate.js +1 -1
  32. package/dist/catalog/component-promotion.js +1 -2
  33. package/dist/catalog/component-state.d.ts +13 -1
  34. package/dist/catalog/component-state.js +14 -5
  35. package/dist/catalog/marketplaces.service.d.ts +1 -1
  36. package/dist/catalog/marketplaces.service.js +2 -1
  37. package/dist/catalog/org-catalog.controller.d.ts +13 -3
  38. package/dist/catalog/org-catalog.controller.js +26 -4
  39. package/dist/catalog/org-catalog.schemas.d.ts +13 -0
  40. package/dist/catalog/org-catalog.schemas.js +34 -0
  41. package/dist/catalog/org-plugin-uploads.controller.js +0 -1
  42. package/dist/catalog/org-plugin-uploads.d.ts +0 -1
  43. package/dist/catalog/org-plugin-uploads.js +0 -3
  44. package/dist/catalog/org-plugin-uploads.schemas.d.ts +0 -1
  45. package/dist/catalog/org-plugin-uploads.schemas.js +0 -2
  46. package/dist/catalog/platform-components.d.ts +0 -1
  47. package/dist/catalog/platform-components.js +3 -8
  48. package/dist/catalog/plugin-import.d.ts +0 -8
  49. package/dist/catalog/plugin-import.js +4 -35
  50. package/dist/catalog/plugin-install.d.ts +2 -2
  51. package/dist/catalog/plugin-install.js +2 -2
  52. package/dist/catalog/plugin-package.d.ts +7 -0
  53. package/dist/catalog/plugin-package.js +27 -1
  54. package/dist/catalog/plugin-upgrade.d.ts +5 -6
  55. package/dist/catalog/plugin-upgrade.js +5 -23
  56. package/dist/catalog/requests.service.d.ts +66 -10
  57. package/dist/catalog/requests.service.js +196 -15
  58. package/dist/channels/actions.d.ts +2 -0
  59. package/dist/channels/actions.js +19 -4
  60. package/dist/channels/cards.d.ts +16 -2
  61. package/dist/channels/cards.js +40 -7
  62. package/dist/channels/channels.module.js +3 -0
  63. package/dist/channels/outbound.d.ts +22 -1
  64. package/dist/channels/outbound.js +116 -7
  65. package/dist/channels/phrases.d.ts +25 -0
  66. package/dist/channels/phrases.js +19 -0
  67. package/dist/channels/threads.d.ts +12 -0
  68. package/dist/channels/threads.js +34 -0
  69. package/dist/config/schema.d.ts +23 -1
  70. package/dist/config/schema.js +107 -5
  71. package/dist/conversations/conversations.service.d.ts +42 -9
  72. package/dist/conversations/conversations.service.js +57 -25
  73. package/dist/conversations/events.d.ts +106 -11
  74. package/dist/conversations/events.js +121 -18
  75. package/dist/conversations/message-context.d.ts +6 -3
  76. package/dist/conversations/message-context.js +14 -10
  77. package/dist/conversations/queue.d.ts +15 -2
  78. package/dist/conversations/queue.js +22 -3
  79. package/dist/conversations/queue.service.d.ts +12 -6
  80. package/dist/conversations/queue.service.js +36 -13
  81. package/dist/db/kernel-schema.d.ts +105 -3
  82. package/dist/devices/conversation-devices.d.ts +8 -1
  83. package/dist/devices/conversation-devices.js +8 -0
  84. package/dist/devices/devices.controller.d.ts +21 -4
  85. package/dist/devices/devices.controller.js +46 -8
  86. package/dist/devices/devices.schemas.d.ts +9 -1
  87. package/dist/devices/devices.schemas.js +11 -3
  88. package/dist/devices/devices.service.d.ts +176 -4
  89. package/dist/devices/devices.service.js +347 -6
  90. package/dist/devices/dto.d.ts +56 -3
  91. package/dist/devices/dto.js +51 -1
  92. package/dist/devices/public-suffix.d.ts +6 -0
  93. package/dist/devices/public-suffix.js +79 -0
  94. package/dist/errors.d.ts +50 -5
  95. package/dist/errors.js +50 -5
  96. package/dist/evals/reconstruct.d.ts +18 -13
  97. package/dist/evals/reconstruct.js +50 -36
  98. package/dist/evals/recorded-tools.d.ts +7 -7
  99. package/dist/evals/recorded-tools.js +4 -3
  100. package/dist/evals/trajectory.d.ts +6 -1
  101. package/dist/evals/trajectory.js +7 -0
  102. package/dist/extensions/package.js +2 -2
  103. package/dist/http/api.module.js +5 -0
  104. package/dist/identity/settings.d.ts +53 -3
  105. package/dist/identity/settings.js +92 -9
  106. package/dist/inbox/inbox.module.js +2 -1
  107. package/dist/inbox/inbox.service.d.ts +19 -4
  108. package/dist/inbox/inbox.service.js +14 -3
  109. package/dist/infra/config/kernel-config.service.d.ts +7 -0
  110. package/dist/infra/config/kernel-config.service.js +31 -0
  111. package/dist/infra/events/kernel-events.d.ts +2 -1
  112. package/dist/local-devices/device-policy.service.d.ts +65 -0
  113. package/dist/local-devices/device-policy.service.js +217 -0
  114. package/dist/local-devices/local-device-gateway.d.ts +4 -2
  115. package/dist/local-devices/local-device-gateway.js +39 -11
  116. package/dist/local-devices/local-device-provider.d.ts +40 -3
  117. package/dist/local-devices/local-device-provider.js +109 -7
  118. package/dist/local-devices/local-devices.module.d.ts +2 -1
  119. package/dist/local-devices/local-devices.module.js +19 -3
  120. package/dist/local-devices/machines.d.ts +30 -3
  121. package/dist/local-devices/machines.js +79 -3
  122. package/dist/local-devices/network-grants.d.ts +104 -0
  123. package/dist/local-devices/network-grants.js +288 -0
  124. package/dist/local-devices/policy-summary.d.ts +20 -0
  125. package/dist/local-devices/policy-summary.js +63 -0
  126. package/dist/orgs/orgs.module.js +4 -10
  127. package/dist/orgs/roles.d.ts +1 -1
  128. package/dist/orgs/roles.js +4 -0
  129. package/dist/orgs/settings.controller.js +4 -3
  130. package/dist/orgs/settings.service.d.ts +172 -14
  131. package/dist/orgs/settings.service.js +229 -27
  132. package/dist/platform/exclusions.js +11 -1
  133. package/dist/platform/operation.js +4 -0
  134. package/dist/platform/ops/admin-items.ops.js +1 -1
  135. package/dist/platform/ops/admin.ops.js +32 -7
  136. package/dist/platform/ops/agent-skills.ops.js +2 -2
  137. package/dist/platform/ops/agent-templates.ops.js +2 -2
  138. package/dist/platform/ops/agents.ops.js +11 -15
  139. package/dist/platform/ops/devices.ops.js +3 -1
  140. package/dist/platform/ops/inbox.ops.js +19 -0
  141. package/dist/platform/ops/org-settings.ops.js +15 -6
  142. package/dist/platform/ops/orgs.ops.js +1 -0
  143. package/dist/platform/ops/platform.ops.d.ts +9 -1
  144. package/dist/platform/ops/platform.ops.js +34 -12
  145. package/dist/platform/ops/requests.ops.js +3 -2
  146. package/dist/platform/ops/schedules.ops.d.ts +21 -0
  147. package/dist/platform/ops/schedules.ops.js +470 -0
  148. package/dist/platform/ops/skills.ops.js +3 -3
  149. package/dist/platform/platform-ops.module.d.ts +2 -1
  150. package/dist/platform/platform-ops.module.js +5 -0
  151. package/dist/platform/route-schemas.js +3 -0
  152. package/dist/roles/worker.module.js +3 -0
  153. package/dist/runtime/context/build.js +13 -4
  154. package/dist/runtime/context/compaction.js +6 -3
  155. package/dist/runtime/context/device-paths.d.ts +43 -21
  156. package/dist/runtime/context/device-paths.js +104 -21
  157. package/dist/runtime/context/run-context.d.ts +9 -0
  158. package/dist/runtime/context/run-context.js +8 -0
  159. package/dist/runtime/context/skills.d.ts +14 -1
  160. package/dist/runtime/context/skills.js +36 -5
  161. package/dist/runtime/maintenance.d.ts +4 -2
  162. package/dist/runtime/maintenance.js +16 -5
  163. package/dist/runtime/run-finish.d.ts +6 -1
  164. package/dist/runtime/run-finish.js +16 -2
  165. package/dist/runtime/run-queue.js +21 -2
  166. package/dist/runtime/run-worker.js +14 -33
  167. package/dist/runtime/runtime.module.js +3 -0
  168. package/dist/runtime/subagents/definition.d.ts +32 -14
  169. package/dist/runtime/subagents/definition.js +106 -109
  170. package/dist/runtime/subagents/dispatch.js +4 -3
  171. package/dist/runtime/subagents/preamble.d.ts +2 -1
  172. package/dist/runtime/subagents/preamble.js +2 -1
  173. package/dist/runtime/waits.js +14 -4
  174. package/dist/sandbox/platform-tiers.d.ts +86 -0
  175. package/dist/sandbox/platform-tiers.js +97 -0
  176. package/dist/sandbox/sandbox.service.d.ts +121 -11
  177. package/dist/sandbox/sandbox.service.js +351 -30
  178. package/dist/sandbox/tiers.d.ts +98 -0
  179. package/dist/sandbox/tiers.js +104 -0
  180. package/dist/schedules/effective-settings.d.ts +16 -0
  181. package/dist/schedules/effective-settings.js +17 -0
  182. package/dist/schedules/errors.d.ts +8 -0
  183. package/dist/schedules/errors.js +8 -0
  184. package/dist/schedules/fire.d.ts +118 -0
  185. package/dist/schedules/fire.js +625 -0
  186. package/dist/schedules/grant-rules.d.ts +94 -0
  187. package/dist/schedules/grant-rules.js +126 -0
  188. package/dist/schedules/job-ids.d.ts +32 -0
  189. package/dist/schedules/job-ids.js +27 -0
  190. package/dist/schedules/pause.d.ts +9 -0
  191. package/dist/schedules/pause.js +33 -0
  192. package/dist/schedules/run-tracker.d.ts +81 -0
  193. package/dist/schedules/run-tracker.js +333 -0
  194. package/dist/schedules/scan.job.d.ts +64 -0
  195. package/dist/schedules/scan.job.js +303 -0
  196. package/dist/schedules/schedule-math.d.ts +31 -0
  197. package/dist/schedules/schedule-math.js +223 -0
  198. package/dist/schedules/scheduled-tasks.service.d.ts +351 -0
  199. package/dist/schedules/scheduled-tasks.service.js +1193 -0
  200. package/dist/schedules/schedules.controller.d.ts +68 -0
  201. package/dist/schedules/schedules.controller.js +242 -0
  202. package/dist/schedules/schedules.module.d.ts +16 -0
  203. package/dist/schedules/schedules.module.js +65 -0
  204. package/dist/schedules/schedules.schemas.d.ts +316 -0
  205. package/dist/schedules/schedules.schemas.js +186 -0
  206. package/dist/schedules/store.d.ts +81 -0
  207. package/dist/schedules/store.js +390 -0
  208. package/dist/schedules/store.module.d.ts +6 -0
  209. package/dist/schedules/store.module.js +21 -0
  210. package/dist/schedules/types.d.ts +108 -0
  211. package/dist/schedules/types.js +1 -0
  212. package/dist/schedules/unattended.d.ts +117 -0
  213. package/dist/schedules/unattended.js +228 -0
  214. package/dist/setup/oauth-token-probe.js +8 -4
  215. package/dist/skills/agent-skills.service.d.ts +4 -8
  216. package/dist/skills/agent-skills.service.js +18 -53
  217. package/dist/skills/catalog.d.ts +65 -62
  218. package/dist/skills/catalog.js +109 -206
  219. package/dist/skills/conversation-catalog.d.ts +3 -3
  220. package/dist/skills/conversation-catalog.js +5 -12
  221. package/dist/skills/invoke.d.ts +2 -2
  222. package/dist/skills/skills.controller.d.ts +3 -1
  223. package/dist/skills/skills.service.d.ts +38 -37
  224. package/dist/skills/skills.service.js +168 -107
  225. package/dist/skills/usable.d.ts +57 -8
  226. package/dist/skills/usable.js +172 -38
  227. package/dist/tools/approvals.controller.d.ts +4 -2
  228. package/dist/tools/approvals.controller.js +17 -2
  229. package/dist/tools/approvals.schemas.d.ts +1 -0
  230. package/dist/tools/approvals.schemas.js +3 -1
  231. package/dist/tools/approvals.service.d.ts +182 -7
  232. package/dist/tools/approvals.service.js +597 -13
  233. package/dist/tools/builtin-names.d.ts +25 -4
  234. package/dist/tools/builtin-names.js +45 -4
  235. package/dist/tools/builtins/builtin-tools.d.ts +8 -0
  236. package/dist/tools/builtins/builtin-tools.js +23 -2
  237. package/dist/tools/builtins/sandbox/bash.js +16 -7
  238. package/dist/tools/builtins/sandbox/common.d.ts +1 -1
  239. package/dist/tools/builtins/sandbox/common.js +33 -10
  240. package/dist/tools/builtins/sandbox/edit.js +7 -3
  241. package/dist/tools/builtins/sandbox/file-state.d.ts +31 -1
  242. package/dist/tools/builtins/sandbox/file-state.js +33 -3
  243. package/dist/tools/builtins/sandbox/write.js +8 -4
  244. package/dist/tools/builtins/schedules.d.ts +107 -0
  245. package/dist/tools/builtins/schedules.js +789 -0
  246. package/dist/tools/elicitation.d.ts +2 -0
  247. package/dist/tools/elicitation.js +1 -1
  248. package/dist/tools/fixed-ask.d.ts +7 -0
  249. package/dist/tools/fixed-ask.js +9 -0
  250. package/dist/tools/network-asks.d.ts +109 -0
  251. package/dist/tools/network-asks.js +221 -0
  252. package/dist/tools/pipeline.d.ts +53 -6
  253. package/dist/tools/pipeline.js +202 -13
  254. package/dist/tools/policy.d.ts +21 -8
  255. package/dist/tools/policy.js +63 -9
  256. package/dist/tools/registry.d.ts +10 -1
  257. package/dist/tools/tools.module.js +12 -0
  258. package/package.json +2 -2
  259. package/src/migrations/0113_scheduled_tasks.sql +108 -0
  260. package/src/migrations/0114_network_asks.sql +23 -0
  261. package/src/migrations/0115_network_requests.sql +28 -0
  262. package/src/migrations/0116_skills_default_on.sql +37 -0
  263. package/src/migrations/0117_sandbox_tiers.sql +11 -0
@@ -35,11 +35,6 @@ const Def = AgentCreateDefinition.shape;
35
35
  /** Every string the model sends is bounded (the route's tool refs and model strings are not). */
36
36
  const Short = z.string().min(1).max(200);
37
37
  const Model = Def.model.extend({ provider: Short, model: Short }).strict();
38
- const RouteSkills = Def.skills.unwrap();
39
- /** `writePolicy` stays the web's; `orgSkills` is required here (the route defaults it to []). */
40
- const Skills = RouteSkills.pick({ pinned: true })
41
- .extend({ orgSkills: RouteSkills.shape.orgSkills.unwrap() })
42
- .strict();
43
38
  /**
44
39
  * Whether `next` sets an `allow` that `current` does not have (decision 2026-11-09: `allow` on a
45
40
  * connector tool lets an agent call it without asking). Such a change is confirmed every time and
@@ -61,7 +56,8 @@ const Fields = {
61
56
  */
62
57
  disabledTools: Def.disabledTools.unwrap(),
63
58
  toolPolicies: z.record(Short, Def.toolPolicies.unwrap().valueType),
64
- skills: Skills,
59
+ /** Skills turned off (skills default-on spec §4); `skills.writePolicy` stays the web's. */
60
+ disabledSkills: Def.disabledSkills.unwrap(),
65
61
  subagents: Def.subagents.unwrap(),
66
62
  };
67
63
  /**
@@ -189,7 +185,7 @@ let AgentsOperations = class AgentsOperations {
189
185
  }),
190
186
  defineOperation({
191
187
  id: "agents.get",
192
- description: "Read one agent you can see with its full definition (description, instructions, model, the tools it turns off (disabledTools: an agent has every tool the org offers except these), tool policies, skills and sub-agents) and its profile (avatar, description, quick actions). Takes the agent id from agents.list.",
188
+ description: "Read one agent you can see with its full definition (description, instructions, model, the tools it turns off (disabledTools: an agent has every tool the org offers except these), tool policies, the skills it turns off (disabledSkills: an agent has every skill on in the org except these), skills.writePolicy and sub-agents) and its profile (avatar, description, quick actions). Takes the agent id from agents.list.",
193
189
  input: z.object({ agentId: AgentId }).strict(),
194
190
  example: { agentId: "7c1a5b0e-9a53-4c6b-8d64-2f5a1b0c3e77" },
195
191
  authz: { orgAction: "agents.use" },
@@ -201,7 +197,7 @@ let AgentsOperations = class AgentsOperations {
201
197
  }),
202
198
  defineOperation({
203
199
  id: "agents.create",
204
- description: 'Create a new private agent owned by you, with a name, a model and optionally instructions, disabledTools, tool policies, skills and sub-agents. An agent has every tool the org offers (all built-in tools, the tools of the extensions on in the org and of the org\'s connectors) unless disabledTools turns it off: { kind: "builtin", name }, { kind: "plugin", plugin, tools: "all" | [names] } or { kind: "connector", connectorId, tools: "all" | [names] }. Agents created with the Platform tool are private; sharing an agent with the org or with members is done on the agents page of the web app.',
200
+ description: 'Create a new private agent owned by you, with a name, a model and optionally instructions, disabledTools, tool policies, disabledSkills and sub-agents. An agent has every tool the org offers (all built-in tools, the tools of the extensions on in the org and of the org\'s connectors) unless disabledTools turns it off: { kind: "builtin", name }, { kind: "plugin", plugin, tools: "all" | [names] } or { kind: "connector", connectorId, tools: "all" | [names] }. Likewise, an agent has every skill on in the org unless disabledSkills turns it off: { kind: "plugin", plugin, skills: "all" | [names] } for skills of a plugin (skills.list gives the plugin of each), or { kind: "skill", skillId } for a skill without a plugin; the skills of builtin plugins (builtin in skills.list) and the own skills of the agent cannot be turned off. Agents created with the Platform tool are private; sharing an agent with the org or with members is done on the agents page of the web app.',
205
201
  input: z
206
202
  .object({
207
203
  definition: z
@@ -211,7 +207,7 @@ let AgentsOperations = class AgentsOperations {
211
207
  model: Fields.model,
212
208
  disabledTools: Fields.disabledTools.optional(),
213
209
  toolPolicies: Fields.toolPolicies.optional(),
214
- skills: Fields.skills.optional(),
210
+ disabledSkills: Fields.disabledSkills.optional(),
215
211
  subagents: Fields.subagents.optional(),
216
212
  })
217
213
  .strict(),
@@ -248,7 +244,7 @@ let AgentsOperations = class AgentsOperations {
248
244
  model: d.model,
249
245
  ...(d.disabledTools !== undefined && { disabledTools: d.disabledTools }),
250
246
  ...(d.toolPolicies !== undefined && { toolPolicies: d.toolPolicies }),
251
- ...(d.skills !== undefined && { skills: d.skills }),
247
+ ...(d.disabledSkills !== undefined && { disabledSkills: d.disabledSkills }),
252
248
  ...(d.subagents !== undefined && { subagents: d.subagents }),
253
249
  });
254
250
  return this.agents.create(ctx.orgId, ctx.actorAccountId, {
@@ -259,7 +255,7 @@ let AgentsOperations = class AgentsOperations {
259
255
  }),
260
256
  defineOperation({
261
257
  id: "agents.update",
262
- description: 'Change an agent you may edit: your own, private or shared, and as an org admin any agent of the org. Send the version you read from agents.get and only the fields to change; the others keep their value. The description (one short paragraph, "" removes it) is saved with the definition; the avatar and quick actions are changed with agents.update-profile. disabledTools replaces the whole list of turned-off tools (send [] to turn every tool on). A version that is no longer current is refused, so read the agent again first. The visibility cannot be changed here (that is done on the agents page of the web app). A change to your own private agent may be remembered by the person; a change to a shared agent, or one that sets a tool policy to allow, is confirmed every time.',
258
+ description: 'Change an agent you may edit: your own, private or shared, and as an org admin any agent of the org. Send the version you read from agents.get and only the fields to change; the others keep their value. The description (one short paragraph, "" removes it) is saved with the definition; the avatar and quick actions are changed with agents.update-profile. disabledTools replaces the whole list of turned-off tools (send [] to turn every tool on). disabledSkills replaces the whole list of turned-off skills (send [] to turn every skill on); an agent has every skill on in the org unless disabledSkills turns it off: { kind: "plugin", plugin, skills: "all" | [names] } for skills of a plugin (skills.list gives the plugin of each), or { kind: "skill", skillId } for a skill without a plugin; the skills of builtin plugins (builtin in skills.list) and the own skills of the agent cannot be turned off. A version that is no longer current is refused, so read the agent again first. The visibility cannot be changed here (that is done on the agents page of the web app). A change to your own private agent may be remembered by the person; a change to a shared agent, or one that sets a tool policy to allow, is confirmed every time.',
263
259
  input: z
264
260
  .object({
265
261
  agentId: AgentId,
@@ -270,7 +266,7 @@ let AgentsOperations = class AgentsOperations {
270
266
  model: Fields.model.optional(),
271
267
  disabledTools: Fields.disabledTools.optional(),
272
268
  toolPolicies: Fields.toolPolicies.optional(),
273
- skills: Fields.skills.optional(),
269
+ disabledSkills: Fields.disabledSkills.optional(),
274
270
  subagents: Fields.subagents.optional(),
275
271
  })
276
272
  .strict(),
@@ -292,7 +288,7 @@ let AgentsOperations = class AgentsOperations {
292
288
  model: "definition.model",
293
289
  disabledTools: "definition.disabledTools",
294
290
  toolPolicies: "definition.toolPolicies",
295
- skills: "definition.skills",
291
+ disabledSkills: "definition.disabledSkills",
296
292
  subagents: "definition.subagents",
297
293
  },
298
294
  confirm: "personal",
@@ -332,7 +328,7 @@ let AgentsOperations = class AgentsOperations {
332
328
  ...(patch.model !== undefined && { model: patch.model }),
333
329
  ...(patch.disabledTools !== undefined && { disabledTools: patch.disabledTools }),
334
330
  ...(patch.toolPolicies !== undefined && { toolPolicies: patch.toolPolicies }),
335
- ...(patch.skills !== undefined && { skills: patch.skills }),
331
+ ...(patch.disabledSkills !== undefined && { disabledSkills: patch.disabledSkills }),
336
332
  ...(patch.subagents !== undefined && { subagents: patch.subagents }),
337
333
  };
338
334
  return this.agents.update(ctx.orgId, agentId, ctx.actorAccountId, { definition, expectedVersion: version }, undefined, viaAgent("agents.update", ctx));
@@ -414,7 +410,7 @@ let AgentsOperations = class AgentsOperations {
414
410
  }),
415
411
  defineOperation({
416
412
  id: "agents.preview-from-template",
417
- description: "Preview creating an agent from an agent template: what carries over, what is pending (connectors the org has not set up) or unavailable, the model that would be used, and a previewHash. agents.create-from-template needs that hash.",
413
+ description: "Preview creating an agent from an agent template: what carries over, what is pending (connectors the org has not set up) or unavailable, the model that would be used, and a previewHash. Each skill the template names is carried when the org has it and unavailable otherwise; the new agent has every skill on in the org except those the template's disallowedSkills turns off. agents.create-from-template needs that hash.",
418
414
  input: AgentFromTemplatePreviewBody,
419
415
  example: { templateId: "5d0c7a52-3a0e-4f0a-bd0a-0f8c3d2a9e10" },
420
416
  authz: { orgAction: "agents.create" },
@@ -131,7 +131,7 @@ let DevicesOperations = class DevicesOperations {
131
131
  }),
132
132
  defineOperation({
133
133
  id: "devices.get",
134
- description: "Read one of your devices with its source (cloud or local), provider, state, instance, the machine of a local one and whether it is online, limits and creation time. Takes the id from devices.list.",
134
+ description: "Read one of your devices with its source (cloud or local), provider, state, instance, the machine of a local one and whether it is online, limits, sandbox level (the tier chosen and the one in effect, the highest allowed and why it is lower, whether it runs without a sandbox) and creation time. Takes the id from devices.list. Only the person changes a device's sandbox level, on the web.",
135
135
  input: DeviceId,
136
136
  example: { deviceId: "4e8a0c1d-6b2f-4a37-8d19-3c5e7f9a1b20" },
137
137
  authz: { orgAction: "agents.use" },
@@ -276,6 +276,8 @@ let DevicesOperations = class DevicesOperations {
276
276
  authz: { orgAction: "agents.use" },
277
277
  mirrors: ["PATCH /api/v1/orgs/:orgId/devices/:id"],
278
278
  renames: { deviceId: "id" },
279
+ // a person decides their device's sandbox level (sandbox dev tiers spec §7.2)
280
+ omits: ["tier"],
279
281
  confirm: "personal",
280
282
  errors: [
281
283
  {
@@ -109,6 +109,25 @@ function orgRow(i) {
109
109
  summary: `Your ${r.kind} request was ${r.status}${r.reason ? `: ${r.reason}` : ""}.`,
110
110
  };
111
111
  }
112
+ case "schedule_attention": {
113
+ const a = i.attention;
114
+ const summary = a.reason === "missing_grants"
115
+ ? `Scheduled task "${a.name}" ran without: ${a.missing.join(", ")}.${a.needsRole.length > 0 ? ` Needing a higher role than the owner has (cannot be pre-approved): ${a.needsRole.join(", ")}.` : ""}${a.needsAdmin.length > 0 ? ` Outside the organization's network allowlist (only an org admin can add them): ${a.needsAdmin.join(", ")}.` : ""}${a.deviceRefuses ? " The task's device does not accept network grants; its owner allows domains locally (capybara-device policy add allowedDomains <host>)." : ""}`
116
+ : a.reason === "failed"
117
+ ? `Scheduled task "${a.name}"'s latest run failed${a.error ? `: ${a.error}` : ""}.`
118
+ : `Scheduled task "${a.name}" is paused (${a.reason}${a.pausedBy ? ` by ${a.pausedBy.name || a.pausedBy.id}` : ""}).`;
119
+ return {
120
+ ...base,
121
+ name: a.name,
122
+ state: a.reason,
123
+ summary,
124
+ next: a.reason === "missing_grants"
125
+ ? "Add the missing tools to the task's approved tools and connect the missing connectors on the web; tools that need a higher role cannot be pre-approved; network domains (network:<host>) are approved only by the person on the task page."
126
+ : a.reason === "failed"
127
+ ? "Check the run's error and the task's settings; the next good run clears this, and repeated failures pause the task."
128
+ : "Resume the task once the cause is fixed.",
129
+ };
130
+ }
112
131
  default: {
113
132
  const n = i.notice;
114
133
  return {
@@ -39,7 +39,7 @@ let OrgSettingsOperations = class OrgSettingsOperations {
39
39
  this.registry.register([
40
40
  defineOperation({
41
41
  id: "org-settings.get",
42
- description: "Read this org's settings: toolSearch, locale, sandboxToolPolicy, platformTool (on, read-only or off), sandboxEgress and wakeOnBackgroundTask (absent means it follows the deployment), theme (the org's default theme id, null or absent following the platform, and personal: allowed or locked), uiArrangement (per list slot, the extension contributions the org hides and their order; per single slot, the contribution that replaces the built-in as use, null for the built-in; a slot not listed follows the platform), the deployment's sandbox egress default and the sandbox cpu / memory limits in effect.",
42
+ description: "Read this org's settings: toolSearch, locale, sandboxToolPolicy, platformTool (on, read-only or off), sandboxEgress, sandboxTier ({ max, default, allowUnsandboxed }: the org's sandbox levels strict < dev < open) and wakeOnBackgroundTask (absent means it follows the deployment), theme (the org's default theme id, null or absent following the platform, and personal: allowed or locked), uiArrangement (per list slot, the extension contributions the org hides and their order; per single slot, the contribution that replaces the built-in as use, null for the built-in; a slot not listed follows the platform), the deployment's sandbox egress default and sandbox tiers, and the sandbox cpu / memory limits in effect.",
43
43
  input: z.object({}).strict(),
44
44
  example: {},
45
45
  authz: { orgAction: "org.read" },
@@ -47,13 +47,13 @@ let OrgSettingsOperations = class OrgSettingsOperations {
47
47
  confirm: "read",
48
48
  run: async (_input, ctx) => ({
49
49
  settings: await this.settings.get(ctx.orgId),
50
- deployment: this.settings.deployment(),
50
+ deployment: await this.settings.deployment(),
51
51
  sandboxLimits: await this.settings.sandboxLimits(ctx.orgId),
52
52
  }),
53
53
  }),
54
54
  defineOperation({
55
55
  id: "org-settings.update",
56
- description: "Change this org's settings (org admins). Give only the settings to change; null clears sandboxEgress or wakeOnBackgroundTask so they follow the deployment again. theme: { id, personal } sets the org's default theme (a theme id from themes.list, or null to follow the platform) and whether members may pick their own (allowed) or not (locked); null clears it. uiArrangement: { <slot>: { hidden, order } } (a list slot) or { <slot>: { use } } (a single slot: shell.brand, conversation.empty, conversation.composer.frame) replaces that slot's entry, where hidden, order and use name contribution keys <extension>/<contribution> (hidden ones are not listed in the web UI but their pages still open by URL; use null is the built-in); null for a slot makes it follow the platform again; platform.page is refused. Setting platformTool to off or read-only takes effect from the next call and cuts this Platform tool off in the org, so say so before asking; an org admin switches it back on in the web settings.",
56
+ description: "Change this org's settings (org admins). Give only the settings to change; null clears sandboxEgress, sandboxTier or wakeOnBackgroundTask so they follow the deployment again. sandboxTier ({ max, default, allowUnsandboxed }, replaced whole) and sandboxEgress may only narrow the org's sandbox here: raising or clearing a tier cap, allowing unsandboxed devices, or adding network hosts is refused and needs a person in the organization settings on the web. theme: { id, personal } sets the org's default theme (a theme id from themes.list, or null to follow the platform) and whether members may pick their own (allowed) or not (locked); null clears it. uiArrangement: { <slot>: { hidden, order } } (a list slot) or { <slot>: { use } } (a single slot: shell.brand, conversation.empty, conversation.composer.frame) replaces that slot's entry, where hidden, order and use name contribution keys <extension>/<contribution> (hidden ones are not listed in the web UI but their pages still open by URL; use null is the built-in); null for a slot makes it follow the platform again; platform.page is refused. Setting platformTool to off or read-only takes effect from the next call and cuts this Platform tool off in the org, so say so before asking; an org admin switches it back on in the web settings.",
57
57
  input: OrgSettingsPatchSchema.refine((i) => Object.values(i).some((v) => v !== undefined), {
58
58
  message: "give at least one setting",
59
59
  }),
@@ -64,7 +64,11 @@ let OrgSettingsOperations = class OrgSettingsOperations {
64
64
  errors: [
65
65
  {
66
66
  code: "org.sandbox_egress_not_allowed",
67
- next: "This deployment disables sandbox network access, so the org can only set sandboxEgress to none; ask the super admin to change sandbox.limits.egress.",
67
+ next: "Through this tool the org's sandbox network may only be narrowed (no new hosts, not back from none); if the deployment disables sandbox network access, sandboxEgress can only be none. To widen it, ask an org admin to change it in the organization settings on the web.",
68
+ },
69
+ {
70
+ code: "org.sandbox_tier_not_allowed",
71
+ next: "Through this tool the org's sandbox level may only be lowered, never above the platform's sandbox.tiers (org-settings.get shows both); to raise it, ask an org admin to change it in the organization settings on the web.",
68
72
  },
69
73
  {
70
74
  code: "theme.not_available",
@@ -75,7 +79,10 @@ let OrgSettingsOperations = class OrgSettingsOperations {
75
79
  next: "Fix the setting as the message says (org-settings.get shows the current values).",
76
80
  },
77
81
  ],
78
- precheck: (i) => precheckBy(async () => this.settings.check(i)),
82
+ precheck: (i, ctx) => precheckBy(async () => {
83
+ await this.settings.check(i);
84
+ await this.settings.assertOnlyNarrows(await this.settings.get(ctx.orgId), i);
85
+ }),
79
86
  summary: async (i, ctx) => {
80
87
  const { theme, ...rest } = i;
81
88
  const parts = Object.entries(rest)
@@ -108,7 +115,9 @@ let OrgSettingsOperations = class OrgSettingsOperations {
108
115
  };
109
116
  },
110
117
  run: async (input, ctx) => {
111
- const settings = await this.settings.update(ctx.orgId, input, ctx.actorAccountId, undefined, viaAgent("org-settings.update", ctx));
118
+ const settings = await this.settings.update(ctx.orgId, input, ctx.actorAccountId, undefined, viaAgent("org-settings.update", ctx),
119
+ // a person widens the sandbox, never an agent (sandbox dev tiers spec §7.2)
120
+ { onlyNarrows: true });
112
121
  const note = input.platformTool === undefined
113
122
  ? undefined
114
123
  : PLATFORM_TOOL_NOTE[settings.platformTool];
@@ -161,6 +161,7 @@ let OrgsOperations = class OrgsOperations {
161
161
  "uiTheme",
162
162
  "uiArrangement",
163
163
  "clientExtensions",
164
+ "sandboxTiers",
164
165
  ],
165
166
  extras: ["orgId", "runConcurrency", "sandbox", "subagents"],
166
167
  confirm: "platform",
@@ -1,6 +1,7 @@
1
1
  import { type OnModuleInit } from "@nestjs/common";
2
2
  import { AgentsService } from "../../agents/agents.service.js";
3
3
  import { AccountsService } from "../../identity/accounts.js";
4
+ import { KernelDb } from "../../infra/database/kernel-db.js";
4
5
  import { OrgSettingsService } from "../../orgs/settings.service.js";
5
6
  import { ThemesService } from "../../themes/themes.service.js";
6
7
  import { ToolRegistry } from "../../tools/registry.js";
@@ -18,7 +19,14 @@ export declare class PlatformOperationsProvider implements OnModuleInit {
18
19
  private readonly tools;
19
20
  private readonly accounts;
20
21
  private readonly themes;
21
- constructor(registry: PlatformOperations, actor: PlatformActor, agents: AgentsService, settings: OrgSettingsService, tools: ToolRegistry, accounts: AccountsService, themes: ThemesService);
22
+ private readonly db;
23
+ constructor(registry: PlatformOperations, actor: PlatformActor, agents: AgentsService, settings: OrgSettingsService, tools: ToolRegistry, accounts: AccountsService, themes: ThemesService, db: KernelDb);
24
+ /**
25
+ * The skills in the agent's catalog now, by the names a run's catalog lists them, each with its
26
+ * plugin (skills default-on spec §11): the resolver's result for this conversation, as the next
27
+ * run start would snapshot it (manual-only skills are not in the catalog).
28
+ */
29
+ private skillNames;
22
30
  /**
23
31
  * The agent's tools by the keys the model sees, as the registry resolves them for a run (tools
24
32
  * default-on spec §8): every tool the org offers that the definition does not turn off, builtins
@@ -12,8 +12,10 @@ import { z } from "zod";
12
12
  import { AgentsService } from "../../agents/agents.service.js";
13
13
  import { AccountsService } from "../../identity/accounts.js";
14
14
  import { PreferencesSchema } from "../../identity/me.schemas.js";
15
+ import { KernelDb } from "../../infra/database/kernel-db.js";
15
16
  import { can } from "../../orgs/roles.js";
16
- import { effectiveSandboxEgress, OrgSettingsService } from "../../orgs/settings.service.js";
17
+ import { OrgSettingsService } from "../../orgs/settings.service.js";
18
+ import { resolveEffectiveSkills } from "../../skills/catalog.js";
17
19
  import { ThemesService } from "../../themes/themes.service.js";
18
20
  import { SANDBOX_TOOL_NAMES } from "../../tools/builtin-names.js";
19
21
  import { ToolRegistry } from "../../tools/registry.js";
@@ -49,7 +51,8 @@ let PlatformOperationsProvider = class PlatformOperationsProvider {
49
51
  tools;
50
52
  accounts;
51
53
  themes;
52
- constructor(registry, actor, agents, settings, tools, accounts, themes) {
54
+ db;
55
+ constructor(registry, actor, agents, settings, tools, accounts, themes, db) {
53
56
  this.registry = registry;
54
57
  this.actor = actor;
55
58
  this.agents = agents;
@@ -57,6 +60,21 @@ let PlatformOperationsProvider = class PlatformOperationsProvider {
57
60
  this.tools = tools;
58
61
  this.accounts = accounts;
59
62
  this.themes = themes;
63
+ this.db = db;
64
+ }
65
+ /**
66
+ * The skills in the agent's catalog now, by the names a run's catalog lists them, each with its
67
+ * plugin (skills default-on spec §11): the resolver's result for this conversation, as the next
68
+ * run start would snapshot it (manual-only skills are not in the catalog).
69
+ */
70
+ async skillNames(ctx, d) {
71
+ const skills = await resolveEffectiveSkills(this.db.db, {
72
+ orgId: ctx.orgId,
73
+ agentId: ctx.agentId,
74
+ agent: { disabledSkills: d.disabledSkills ?? [] },
75
+ conversationId: ctx.conversationId,
76
+ });
77
+ return skills.map((s) => ({ name: s.name, plugin: s.plugin ?? null }));
60
78
  }
61
79
  /**
62
80
  * The agent's tools by the keys the model sees, as the registry resolves them for a run (tools
@@ -114,7 +132,7 @@ let PlatformOperationsProvider = class PlatformOperationsProvider {
114
132
  }),
115
133
  defineOperation({
116
134
  id: "platform.me",
117
- description: "Show this agent as configured: its model, the tools it has now by the keys you call them by (every tool the org offers unless the agent turns it off; connector tools as mcp__<connector>__<tool>, with those that cannot load now and why), the tools it turns off (disabledTools), skills (org and pinned), sub-agents, whether it runs in a sandbox, the sandbox network mode, and its profile (avatar, description, quick actions). Secrets are never shown.",
135
+ description: "Show this agent as configured: its model, the tools it has now by the keys you call them by (every tool the org offers unless the agent turns it off; connector tools as mcp__<connector>__<tool>, with those that cannot load now and why), the tools it turns off (disabledTools), the skills in its catalog now by name with their plugin (every skill on in the org unless the agent turns it off, its own and builtin plugins' skills always; manual-only skills are not in the catalog), the skills it turns off (disabledSkills), sub-agents, whether it runs in a sandbox, the sandbox level (tier) and network mode of a new device, and its profile (avatar, description, quick actions). Secrets are never shown.",
118
136
  input: EMPTY,
119
137
  example: {},
120
138
  authz: { orgAction: "agents.use" },
@@ -123,11 +141,14 @@ let PlatformOperationsProvider = class PlatformOperationsProvider {
123
141
  run: async (_input, ctx) => {
124
142
  const agent = await this.agents.get(ctx.orgId, ctx.agentId, ctx.actorAccountId);
125
143
  const d = agent.definition;
126
- const { keys: toolKeys, unavailable } = await this.toolKeys(ctx.orgId, d);
144
+ const [{ keys: toolKeys, unavailable }, skills] = await Promise.all([
145
+ this.toolKeys(ctx.orgId, d),
146
+ this.skillNames(ctx, d),
147
+ ]);
127
148
  const sandbox = toolKeys.some((k) => SANDBOX_TOOL_NAMES.includes(k));
128
149
  const org = await this.settings.get(ctx.orgId);
129
- const dep = this.settings.deployment().sandboxEgress;
130
- const egress = effectiveSandboxEgress({ egress: dep.mode, allowHosts: dep.allowHosts }, org.sandboxEgress);
150
+ // a new device's level: the org's default tier and its network
151
+ const policy = await this.settings.sandboxPolicy(org, null);
131
152
  return {
132
153
  id: agent.id,
133
154
  name: d.name,
@@ -139,12 +160,12 @@ let PlatformOperationsProvider = class PlatformOperationsProvider {
139
160
  ...(unavailable.length > 0 && { unavailableTools: unavailable }),
140
161
  disabledTools: d.disabledTools ?? [],
141
162
  toolPolicies: d.toolPolicies,
142
- skills: {
143
- orgSkills: d.skills?.orgSkills ?? [],
144
- pinned: d.skills?.pinned ?? [],
145
- },
163
+ skills,
164
+ disabledSkills: d.disabledSkills ?? [],
146
165
  subagents: d.subagents ?? null,
147
- sandbox: sandbox ? { enabled: true, egress: egress.egress } : { enabled: false },
166
+ sandbox: sandbox
167
+ ? { enabled: true, tier: policy.tier, egress: policy.egress }
168
+ : { enabled: false },
148
169
  profile: {
149
170
  avatar: agent.profile.avatar,
150
171
  description: agent.profile.description,
@@ -226,6 +247,7 @@ PlatformOperationsProvider = __decorate([
226
247
  __param(3, Inject(OrgSettingsService)),
227
248
  __param(4, Inject(ToolRegistry)),
228
249
  __param(5, Inject(AccountsService)),
229
- __param(6, Inject(ThemesService))
250
+ __param(6, Inject(ThemesService)),
251
+ __param(7, Inject(KernelDb))
230
252
  ], PlatformOperationsProvider);
231
253
  export { PlatformOperationsProvider };
@@ -23,6 +23,7 @@ const view = (r) => ({
23
23
  item: r.item,
24
24
  entry: r.entry,
25
25
  agent: r.agent,
26
+ network: r.network,
26
27
  note: r.note,
27
28
  reason: r.reason,
28
29
  decidedAt: r.decidedAt,
@@ -40,7 +41,7 @@ const platformRow = (r) => ({
40
41
  /** A member's pending request as the org admins' list shows it: a compact row (the inbox's). */
41
42
  const pendingRow = (r) => ({
42
43
  id: r.id,
43
- name: r.item?.name ?? r.entry?.name ?? r.agent?.name ?? r.kind,
44
+ name: r.item?.name ?? r.entry?.name ?? r.agent?.name ?? r.network?.hosts.join(", ") ?? r.kind,
44
45
  state: r.status,
45
46
  kind: r.kind,
46
47
  requestedBy: r.requestedByName,
@@ -153,7 +154,7 @@ let RequestsOperations = class RequestsOperations {
153
154
  }),
154
155
  defineOperation({
155
156
  id: "requests.pending",
156
- description: "List the requests members sent this org's admins that wait for a decision (org admins), as the inbox shows them, newest first: kind enable (switch a plugin on) or connector_setup (set up an agent's connectors), what it is about (the plugin or the agent), who asked and their note. Deciding them is done on the web. Pages by 50: pass the returned next as params.cursor.",
157
+ description: "List the requests members sent this org's admins that wait for a decision (org admins), as the inbox shows them, newest first: kind enable (switch a plugin on), connector_setup (set up an agent's connectors) or network_allowlist (allow hosts in the org's sandbox network), what it is about (the plugin, the agent or the hosts), who asked and their note. Deciding them is done on the web. Pages by 50: pass the returned next as params.cursor.",
157
158
  input: z.object({ cursor: Cursor.optional() }).strict(),
158
159
  example: {},
159
160
  authz: { orgAction: "catalog.decide" },
@@ -0,0 +1,21 @@
1
+ import { type OnModuleInit } from "@nestjs/common";
2
+ import { ScheduledTasksService } from "../../schedules/scheduled-tasks.service.js";
3
+ import { PlatformOperations } from "../registry.js";
4
+ /**
5
+ * Scheduled-task operations of the `Platform` tool (scheduled tasks spec §10): the same service
6
+ * as the HTTP routes. Writes are `personal`. Creating or changing a task and its approved tools
7
+ * are never remembered (`rememberable: false`): an approval, remembered or granted to a task,
8
+ * must never let an unattended run create or widen a task. Delete, run and resume are never
9
+ * remembered either. List, pause and delete are `org.read` like their routes: a creator demoted
10
+ * to guest can still see and stop their own tasks (the service decides by ownership).
11
+ */
12
+ export declare class SchedulesOperations implements OnModuleInit {
13
+ private readonly registry;
14
+ private readonly tasks;
15
+ constructor(registry: PlatformOperations, tasks: ScheduledTasksService);
16
+ /** The caller as the service expects (it reads the live role itself). */
17
+ private actor;
18
+ /** The task's name for a card; its id when it cannot be read. */
19
+ private label;
20
+ onModuleInit(): void;
21
+ }