@capybara-hq/kernel 0.1.0-rc.6 → 0.1.0-rc.7

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 (331) hide show
  1. package/bootstrap.json +27 -3
  2. package/dist/admin/admin.controller.d.ts +8 -72
  3. package/dist/admin/admin.controller.js +21 -46
  4. package/dist/admin/admin.schemas.d.ts +57 -0
  5. package/dist/admin/admin.schemas.js +50 -0
  6. package/dist/admin/extensions.controller.d.ts +10 -0
  7. package/dist/admin/extensions.controller.js +18 -0
  8. package/dist/admin/extensions.schemas.d.ts +7 -0
  9. package/dist/admin/extensions.schemas.js +10 -0
  10. package/dist/admin/limit-defaults.d.ts +20 -0
  11. package/dist/admin/limit-defaults.js +10 -0
  12. package/dist/agents/agent-profile.service.d.ts +7 -5
  13. package/dist/agents/agent-profile.service.js +14 -9
  14. package/dist/agents/agents.controller.d.ts +7 -287
  15. package/dist/agents/agents.controller.js +7 -67
  16. package/dist/agents/agents.schemas.d.ts +389 -0
  17. package/dist/agents/agents.schemas.js +126 -0
  18. package/dist/agents/agents.service.d.ts +13 -5
  19. package/dist/agents/agents.service.js +67 -13
  20. package/dist/agents/definition.d.ts +47 -19
  21. package/dist/agents/definition.js +119 -38
  22. package/dist/agents/from-template.d.ts +2 -2
  23. package/dist/agents/from-template.js +76 -45
  24. package/dist/agents/from-template.service.d.ts +12 -0
  25. package/dist/agents/from-template.service.js +20 -3
  26. package/dist/agents/models.controller.d.ts +1 -2
  27. package/dist/agents/models.controller.js +1 -1
  28. package/dist/agents/org-templates.d.ts +13 -3
  29. package/dist/agents/org-templates.js +69 -28
  30. package/dist/agents/pending-connector-requests.d.ts +2 -0
  31. package/dist/agents/pending-connector-requests.js +1 -1
  32. package/dist/agents/pending-connectors.controller.d.ts +1 -1
  33. package/dist/agents/pending-connectors.controller.js +2 -2
  34. package/dist/agents/pending-connectors.service.d.ts +2 -2
  35. package/dist/agents/pending-connectors.service.js +19 -19
  36. package/dist/agents/profile.d.ts +18 -0
  37. package/dist/agents/profile.js +5 -1
  38. package/dist/agents/templates.controller.d.ts +8 -17
  39. package/dist/agents/templates.controller.js +13 -31
  40. package/dist/agents/templates.schemas.d.ts +20 -0
  41. package/dist/agents/templates.schemas.js +45 -0
  42. package/dist/background/background.controller.js +3 -2
  43. package/dist/background/background.schemas.d.ts +10 -0
  44. package/dist/background/background.schemas.js +16 -0
  45. package/dist/background/tasks.service.d.ts +1 -1
  46. package/dist/background/tasks.service.js +7 -2
  47. package/dist/catalog/admin-catalog.controller.d.ts +4 -57
  48. package/dist/catalog/admin-catalog.controller.js +8 -45
  49. package/dist/catalog/admin-catalog.schemas.d.ts +72 -0
  50. package/dist/catalog/admin-catalog.schemas.js +92 -0
  51. package/dist/catalog/catalog-content.d.ts +12 -2
  52. package/dist/catalog/catalog-scope.service.js +8 -2
  53. package/dist/catalog/catalog.service.d.ts +2 -0
  54. package/dist/catalog/catalog.service.js +3 -0
  55. package/dist/catalog/component-scope.controller.d.ts +3 -65
  56. package/dist/catalog/component-scope.controller.js +3 -56
  57. package/dist/catalog/component-scope.schemas.d.ts +114 -0
  58. package/dist/catalog/component-scope.schemas.js +97 -0
  59. package/dist/catalog/component-scope.service.d.ts +28 -4
  60. package/dist/catalog/component-scope.service.js +55 -3
  61. package/dist/catalog/component-state.d.ts +9 -2
  62. package/dist/catalog/component-state.js +22 -13
  63. package/dist/catalog/marketplaces.controller.d.ts +5 -35
  64. package/dist/catalog/marketplaces.controller.js +6 -34
  65. package/dist/catalog/marketplaces.schemas.d.ts +48 -0
  66. package/dist/catalog/marketplaces.schemas.js +53 -0
  67. package/dist/catalog/marketplaces.service.d.ts +15 -1
  68. package/dist/catalog/marketplaces.service.js +22 -1
  69. package/dist/catalog/org-catalog.controller.d.ts +6 -62
  70. package/dist/catalog/org-catalog.controller.js +12 -66
  71. package/dist/catalog/org-catalog.schemas.d.ts +79 -0
  72. package/dist/catalog/org-catalog.schemas.js +82 -0
  73. package/dist/catalog/org-catalog.service.d.ts +9 -2
  74. package/dist/catalog/org-catalog.service.js +38 -5
  75. package/dist/catalog/org-extension.controller.d.ts +1 -12
  76. package/dist/catalog/org-extension.controller.js +1 -10
  77. package/dist/catalog/org-extension.schemas.d.ts +15 -0
  78. package/dist/catalog/org-extension.schemas.js +22 -0
  79. package/dist/catalog/org-plugin-uploads.controller.d.ts +2 -19
  80. package/dist/catalog/org-plugin-uploads.controller.js +15 -28
  81. package/dist/catalog/org-plugin-uploads.schemas.d.ts +20 -0
  82. package/dist/catalog/org-plugin-uploads.schemas.js +32 -0
  83. package/dist/catalog/owned-items.d.ts +6 -2
  84. package/dist/catalog/owned-items.js +16 -4
  85. package/dist/catalog/platform-components.d.ts +2 -0
  86. package/dist/catalog/platform-components.js +2 -0
  87. package/dist/catalog/plugin-import.js +1 -0
  88. package/dist/catalog/plugin-install.js +1 -1
  89. package/dist/catalog/requests.service.d.ts +2 -1
  90. package/dist/catalog/requests.service.js +6 -2
  91. package/dist/channels/channels.schemas.d.ts +33 -0
  92. package/dist/channels/channels.schemas.js +34 -0
  93. package/dist/channels/connections.controller.d.ts +2 -29
  94. package/dist/channels/connections.controller.js +1 -23
  95. package/dist/channels/connections.service.d.ts +8 -2
  96. package/dist/channels/connections.service.js +23 -5
  97. package/dist/channels/inbound.js +4 -0
  98. package/dist/conversations/conversations.controller.d.ts +16 -37
  99. package/dist/conversations/conversations.controller.js +16 -56
  100. package/dist/conversations/conversations.schemas.d.ts +52 -0
  101. package/dist/conversations/conversations.schemas.js +79 -0
  102. package/dist/conversations/conversations.service.d.ts +9 -1
  103. package/dist/conversations/conversations.service.js +23 -18
  104. package/dist/conversations/events.d.ts +80 -6
  105. package/dist/conversations/events.js +60 -5
  106. package/dist/conversations/message-context.d.ts +28 -0
  107. package/dist/conversations/message-context.js +56 -0
  108. package/dist/conversations/queue.d.ts +2 -1
  109. package/dist/conversations/queue.js +11 -2
  110. package/dist/db/kernel-schema.d.ts +20 -0
  111. package/dist/environments/environments.schemas.d.ts +3 -0
  112. package/dist/environments/environments.schemas.js +14 -0
  113. package/dist/environments/environments.service.d.ts +16 -4
  114. package/dist/environments/environments.service.js +58 -13
  115. package/dist/errors.d.ts +3 -0
  116. package/dist/errors.js +3 -0
  117. package/dist/evals/evals.schemas.d.ts +110 -0
  118. package/dist/evals/evals.schemas.js +107 -0
  119. package/dist/evals/reconstruct.js +18 -11
  120. package/dist/evals/recorded-tools.d.ts +2 -1
  121. package/dist/evals/recorded-tools.js +11 -3
  122. package/dist/evals/run-replay.d.ts +8 -1
  123. package/dist/evals/run-replay.js +13 -0
  124. package/dist/evals/runs.controller.d.ts +2 -57
  125. package/dist/evals/runs.controller.js +1 -42
  126. package/dist/evals/runs.service.d.ts +6 -6
  127. package/dist/evals/runs.service.js +32 -18
  128. package/dist/evals/sets.controller.d.ts +2 -28
  129. package/dist/evals/sets.controller.js +1 -31
  130. package/dist/evals/sets.service.d.ts +7 -7
  131. package/dist/evals/sets.service.js +23 -17
  132. package/dist/evals/snapshot.d.ts +3 -2
  133. package/dist/evals/snapshot.js +17 -4
  134. package/dist/extensions/admin-ops.d.ts +5 -3
  135. package/dist/extensions/admin-ops.js +17 -12
  136. package/dist/extensions/deployment-config.d.ts +16 -1
  137. package/dist/extensions/deployment-config.js +83 -0
  138. package/dist/extensions/extensions.module.js +3 -0
  139. package/dist/extensions/host.d.ts +33 -2
  140. package/dist/extensions/host.js +107 -1
  141. package/dist/extensions/installs.d.ts +5 -0
  142. package/dist/extensions/installs.js +12 -0
  143. package/dist/extensions/org-config.d.ts +17 -2
  144. package/dist/extensions/org-config.js +23 -4
  145. package/dist/extensions/point-defaults.controller.d.ts +2 -8
  146. package/dist/extensions/point-defaults.controller.js +1 -3
  147. package/dist/extensions/point-defaults.d.ts +3 -1
  148. package/dist/extensions/point-defaults.js +4 -2
  149. package/dist/extensions/point-defaults.schemas.d.ts +9 -0
  150. package/dist/extensions/point-defaults.schemas.js +14 -0
  151. package/dist/extensions/unavailable.d.ts +49 -0
  152. package/dist/extensions/unavailable.js +113 -0
  153. package/dist/files/previewers.controller.js +2 -3
  154. package/dist/files/previewers.d.ts +1 -1
  155. package/dist/files/previewers.js +4 -4
  156. package/dist/files/previewers.schemas.d.ts +10 -0
  157. package/dist/files/previewers.schemas.js +9 -0
  158. package/dist/http/api.module.js +2 -0
  159. package/dist/identity/accounts.d.ts +43 -4
  160. package/dist/identity/accounts.js +74 -6
  161. package/dist/identity/auth.guard.js +10 -1
  162. package/dist/identity/cookies.d.ts +6 -0
  163. package/dist/identity/cookies.js +14 -0
  164. package/dist/identity/identity.module.js +3 -0
  165. package/dist/identity/initial-passwords.controller.d.ts +22 -0
  166. package/dist/identity/initial-passwords.controller.js +49 -0
  167. package/dist/identity/initial-passwords.d.ts +61 -0
  168. package/dist/identity/initial-passwords.job.d.ts +16 -0
  169. package/dist/identity/initial-passwords.job.js +46 -0
  170. package/dist/identity/initial-passwords.js +159 -0
  171. package/dist/identity/me.controller.d.ts +14 -0
  172. package/dist/identity/me.controller.js +39 -1
  173. package/dist/identity/principal.d.ts +8 -0
  174. package/dist/identity/principal.js +8 -0
  175. package/dist/identity/settings.d.ts +3 -1
  176. package/dist/identity/settings.js +6 -4
  177. package/dist/inbox/inbox.schemas.d.ts +8 -0
  178. package/dist/inbox/inbox.schemas.js +11 -0
  179. package/dist/inbox/platform-inbox.controller.d.ts +1 -1
  180. package/dist/inbox/platform-inbox.controller.js +2 -2
  181. package/dist/index.d.ts +4 -0
  182. package/dist/index.js +6 -0
  183. package/dist/lifecycle/kernel-lifecycle.js +4 -0
  184. package/dist/models/enablement.d.ts +2 -0
  185. package/dist/models/enablement.js +1 -0
  186. package/dist/models/org-models.schemas.d.ts +8 -0
  187. package/dist/models/org-models.schemas.js +22 -0
  188. package/dist/models/prices.d.ts +3 -1
  189. package/dist/models/prices.js +7 -5
  190. package/dist/models/purposes.d.ts +12 -2
  191. package/dist/models/purposes.js +22 -8
  192. package/dist/orgs/orgs.controller.d.ts +2 -5
  193. package/dist/orgs/orgs.controller.js +3 -6
  194. package/dist/orgs/orgs.schemas.d.ts +8 -0
  195. package/dist/orgs/orgs.schemas.js +16 -0
  196. package/dist/orgs/orgs.service.d.ts +3 -1
  197. package/dist/orgs/orgs.service.js +6 -4
  198. package/dist/orgs/settings.service.d.ts +9 -1
  199. package/dist/orgs/settings.service.js +20 -5
  200. package/dist/overrides.d.ts +4 -0
  201. package/dist/overrides.js +2 -0
  202. package/dist/platform/errors.d.ts +21 -4
  203. package/dist/platform/errors.js +45 -6
  204. package/dist/platform/exclusions.d.ts +2 -3
  205. package/dist/platform/exclusions.js +68 -849
  206. package/dist/platform/method.js +1 -1
  207. package/dist/platform/operation.d.ts +82 -5
  208. package/dist/platform/operation.js +62 -7
  209. package/dist/platform/ops/accounts.ops.d.ts +32 -0
  210. package/dist/platform/ops/accounts.ops.js +291 -0
  211. package/dist/platform/ops/admin.ops.d.ts +36 -0
  212. package/dist/platform/ops/admin.ops.js +389 -0
  213. package/dist/platform/ops/agent-skills.ops.d.ts +24 -0
  214. package/dist/platform/ops/agent-skills.ops.js +226 -0
  215. package/dist/platform/ops/agent-templates.ops.d.ts +4 -1
  216. package/dist/platform/ops/agent-templates.ops.js +194 -14
  217. package/dist/platform/ops/agents.ops.d.ts +19 -1
  218. package/dist/platform/ops/agents.ops.js +481 -58
  219. package/dist/platform/ops/approvals.ops.d.ts +30 -0
  220. package/dist/platform/ops/approvals.ops.js +116 -0
  221. package/dist/platform/ops/background.ops.d.ts +14 -0
  222. package/dist/platform/ops/background.ops.js +134 -0
  223. package/dist/platform/ops/catalog-admin.ops.d.ts +74 -0
  224. package/dist/platform/ops/catalog-admin.ops.js +587 -0
  225. package/dist/platform/ops/channels.ops.d.ts +16 -0
  226. package/dist/platform/ops/channels.ops.js +195 -0
  227. package/dist/platform/ops/components.ops.d.ts +46 -0
  228. package/dist/platform/ops/components.ops.js +853 -0
  229. package/dist/platform/ops/connectors.ops.d.ts +4 -2
  230. package/dist/platform/ops/connectors.ops.js +68 -6
  231. package/dist/platform/ops/conversations.ops.d.ts +30 -0
  232. package/dist/platform/ops/conversations.ops.js +470 -0
  233. package/dist/platform/ops/environments.ops.d.ts +26 -0
  234. package/dist/platform/ops/environments.ops.js +289 -0
  235. package/dist/platform/ops/errors.d.ts +10 -5
  236. package/dist/platform/ops/errors.js +19 -11
  237. package/dist/platform/ops/evals.ops.d.ts +28 -0
  238. package/dist/platform/ops/evals.ops.js +783 -0
  239. package/dist/platform/ops/extensions-admin.ops.d.ts +25 -0
  240. package/dist/platform/ops/extensions-admin.ops.js +344 -0
  241. package/dist/platform/ops/extensions.ops.d.ts +7 -1
  242. package/dist/platform/ops/extensions.ops.js +248 -17
  243. package/dist/platform/ops/inbox.ops.d.ts +25 -0
  244. package/dist/platform/ops/inbox.ops.js +378 -0
  245. package/dist/platform/ops/marketplaces.ops.d.ts +7 -1
  246. package/dist/platform/ops/marketplaces.ops.js +326 -17
  247. package/dist/platform/ops/models.ops.d.ts +25 -0
  248. package/dist/platform/ops/models.ops.js +232 -0
  249. package/dist/platform/ops/org-plugins.ops.d.ts +29 -0
  250. package/dist/platform/ops/org-plugins.ops.js +329 -0
  251. package/dist/platform/ops/org-settings.ops.d.ts +16 -0
  252. package/dist/platform/ops/org-settings.ops.js +102 -0
  253. package/dist/platform/ops/orgs.ops.d.ts +28 -0
  254. package/dist/platform/ops/orgs.ops.js +295 -0
  255. package/dist/platform/ops/other-orgs.d.ts +20 -0
  256. package/dist/platform/ops/other-orgs.js +72 -0
  257. package/dist/platform/ops/platform.ops.d.ts +4 -4
  258. package/dist/platform/ops/platform.ops.js +23 -24
  259. package/dist/platform/ops/plugins.ops.d.ts +10 -8
  260. package/dist/platform/ops/plugins.ops.js +176 -77
  261. package/dist/platform/ops/previewers.ops.d.ts +14 -0
  262. package/dist/platform/ops/previewers.ops.js +109 -0
  263. package/dist/platform/ops/requests.ops.js +57 -19
  264. package/dist/platform/ops/skills.ops.d.ts +5 -1
  265. package/dist/platform/ops/skills.ops.js +129 -11
  266. package/dist/platform/ops/unavailable.d.ts +23 -0
  267. package/dist/platform/ops/unavailable.js +111 -0
  268. package/dist/platform/parity.d.ts +33 -0
  269. package/dist/platform/parity.js +272 -0
  270. package/dist/platform/platform-ops.module.d.ts +32 -0
  271. package/dist/platform/platform-ops.module.js +78 -11
  272. package/dist/platform/route-schemas.d.ts +18 -0
  273. package/dist/platform/route-schemas.js +60 -0
  274. package/dist/roles/worker.module.js +2 -0
  275. package/dist/runtime/context/build.d.ts +2 -0
  276. package/dist/runtime/context/build.js +28 -2
  277. package/dist/runtime/context/compaction.js +10 -1
  278. package/dist/runtime/context/run-context.d.ts +65 -0
  279. package/dist/runtime/context/run-context.js +215 -0
  280. package/dist/runtime/model-call.js +2 -1
  281. package/dist/runtime/providers.js +8 -1
  282. package/dist/runtime/run-context.service.d.ts +65 -0
  283. package/dist/runtime/run-context.service.js +220 -0
  284. package/dist/runtime/run-worker.d.ts +5 -0
  285. package/dist/runtime/run-worker.js +31 -6
  286. package/dist/runtime/runtime.module.js +2 -0
  287. package/dist/runtime/subagents/definition.d.ts +15 -15
  288. package/dist/runtime/subagents/definition.js +46 -115
  289. package/dist/skills/changes.controller.js +2 -1
  290. package/dist/skills/changes.service.d.ts +1 -1
  291. package/dist/skills/changes.service.js +4 -4
  292. package/dist/skills/invocable.controller.d.ts +1 -1
  293. package/dist/skills/invocable.controller.js +2 -2
  294. package/dist/skills/invoke.d.ts +2 -2
  295. package/dist/skills/invoke.js +8 -1
  296. package/dist/skills/skills.controller.d.ts +4 -13
  297. package/dist/skills/skills.controller.js +8 -24
  298. package/dist/skills/skills.schemas.d.ts +48 -0
  299. package/dist/skills/skills.schemas.js +61 -0
  300. package/dist/skills/skills.service.d.ts +11 -1
  301. package/dist/skills/skills.service.js +37 -14
  302. package/dist/time-zone.d.ts +5 -0
  303. package/dist/time-zone.js +19 -0
  304. package/dist/tools/approvals.controller.js +2 -3
  305. package/dist/tools/approvals.schemas.d.ts +21 -0
  306. package/dist/tools/approvals.schemas.js +15 -0
  307. package/dist/tools/builtin-names.d.ts +10 -8
  308. package/dist/tools/builtin-names.js +16 -11
  309. package/dist/tools/builtins/builtin-tools.d.ts +3 -1
  310. package/dist/tools/builtins/builtin-tools.js +15 -3
  311. package/dist/tools/builtins/current-time.d.ts +26 -0
  312. package/dist/tools/builtins/current-time.js +99 -0
  313. package/dist/tools/builtins/platform.d.ts +19 -2
  314. package/dist/tools/builtins/platform.js +105 -16
  315. package/dist/tools/connectors.controller.d.ts +1 -2
  316. package/dist/tools/connectors.controller.js +1 -4
  317. package/dist/tools/connectors.schemas.d.ts +12 -0
  318. package/dist/tools/connectors.schemas.js +19 -0
  319. package/dist/tools/connectors.service.d.ts +5 -2
  320. package/dist/tools/connectors.service.js +7 -5
  321. package/dist/tools/org-tool-switches.d.ts +16 -2
  322. package/dist/tools/org-tool-switches.js +26 -9
  323. package/dist/tools/pipeline.js +3 -1
  324. package/dist/tools/registry.d.ts +48 -51
  325. package/dist/tools/registry.js +222 -233
  326. package/package.json +3 -3
  327. package/src/migrations/0090_initial_passwords.sql +27 -0
  328. package/src/migrations/0091_account_time_zone.sql +4 -0
  329. package/src/migrations/0092_tools_default_on.sql +27 -0
  330. package/dist/platform/redact-orgs.d.ts +0 -7
  331. package/dist/platform/redact-orgs.js +0 -52
@@ -25,13 +25,22 @@ import { assertOrgSkills, assertPinnedSkills } from "../skills/skills.service.js
25
25
  import { legacyKeySaveText } from "../tools/legacy-keys.js";
26
26
  import { ToolRegistry } from "../tools/registry.js";
27
27
  import { AgentLookup, isAgentVisibleTo, visibleTo, } from "./agent-lookup.js";
28
- import { normalizeStoredDefinition, paramIssues, SUBAGENT_NAME_RE, SUBAGENT_ROSTER_MAX, } from "./definition.js";
28
+ import { canonicalDisabledTools, normalizeStoredDefinition, paramIssues, SUBAGENT_NAME_RE, SUBAGENT_ROSTER_MAX, } from "./definition.js";
29
29
  import { deriveInstructions } from "./instruction-files.js";
30
30
  import { PendingConnectorRequests } from "./pending-connector-requests.js";
31
31
  import { randomPreset } from "./profile.js";
32
32
  import { loadTemplates, templateTypeOf } from "./templates.js";
33
33
  export { AGENT_VISIBILITIES, isAgentVisibleTo, visibleTo, } from "./agent-lookup.js";
34
34
  export { paramIssues, SUBAGENT_ROSTER_MAX } from "./definition.js";
35
+ /**
36
+ * The definition with its description (run context spec §3.5): `given` when the save gives one
37
+ * (trimmed; empty removes it), else `kept` (the current version's).
38
+ */
39
+ function withDescription(definition, given, kept) {
40
+ const { description: _drop, ...rest } = definition;
41
+ const next = given !== undefined ? given.trim() : kept;
42
+ return next === undefined || next === "" ? rest : { ...rest, description: next };
43
+ }
35
44
  /** A new agent has no id to bind an upload to yet: a client can only choose a preset on create. */
36
45
  export function assertProfileWritable(profile) {
37
46
  if (profile?.avatar?.kind === "upload") {
@@ -86,6 +95,10 @@ export function keepPendingConnectors(definition, given, current) {
86
95
  }
87
96
  return next.length > 0 ? { ...rest, pendingConnectors: [...next] } : rest;
88
97
  }
98
+ /** `definition` with `disabledTools` in its canonical form (tools default-on spec §2). */
99
+ function withCanonicalTools(definition) {
100
+ return { ...definition, disabledTools: canonicalDisabledTools(definition.disabledTools ?? []) };
101
+ }
89
102
  /**
90
103
  * Checks `subagents` of an agent definition in the caller's transaction (spec §5.2); throws 400
91
104
  * `agent.subagents_invalid` with one detail per problem (`{ reason, path, value? }`):
@@ -282,13 +295,21 @@ let AgentsService = class AgentsService {
282
295
  this.setupRequests = setupRequests;
283
296
  }
284
297
  /**
285
- * 校验工具引用与工具策略:引用的内置 / 插件 / 连接器工具必须存在(见 `ToolRegistry.checkRefs`);
286
- * `toolPolicies` 的键必须是这些引用产生的工具 key(取值只能收紧,已由 schema 保证)。
287
- * 不合法 → `validation_failed`,path 为 `tools.<i>` / `toolPolicies.<key>`。
298
+ * Checks the turned-off tools and the policies (tools default-on spec §2): `disabledTools` must
299
+ * name existing builtins, extensions and connectors (`ToolRegistry.checkDisabled`); `toolPolicies`
300
+ * keys must be tools the agent could have, on or off (values only tighten, by the schema); a
301
+ * sub-agent's key filter is never saved. Invalid → `validation_failed` at `disabledTools.<i>` /
302
+ * `toolPolicies.<key>` / `subagentTools`. The list is stored in canonical form.
288
303
  */
289
- async checkTools(orgId, def) {
290
- const { keys, issues } = await this.tools.checkRefs(orgId, def.tools);
304
+ async checkTools(orgId, def, kept = []) {
305
+ const { keys, issues } = await this.tools.checkDisabled(orgId, def.disabledTools ?? [], kept);
291
306
  const details = [...issues];
307
+ if (def.subagentTools !== undefined) {
308
+ details.push({
309
+ path: "subagentTools",
310
+ message: "subagentTools is set only on a sub-agent's definition at dispatch",
311
+ });
312
+ }
292
313
  for (const key of Object.keys(def.toolPolicies)) {
293
314
  if (!isToolPolicyKey(key, keys)) {
294
315
  // an rc key (tool naming spec §8.3): saving writes current keys only, so name them
@@ -304,6 +325,23 @@ let AgentsService = class AgentsService {
304
325
  }
305
326
  return keys;
306
327
  }
328
+ /**
329
+ * The current version's `disabledTools` (empty for an agent that is not there: the update's own
330
+ * checks report that): entries kept from it are not re-checked, so a connector deleted or an
331
+ * extension uninstalled later never blocks other edits.
332
+ */
333
+ async keptDisabled(orgId, agentId) {
334
+ const row = await this.db.db
335
+ .selectFrom("agents")
336
+ .innerJoin("agent_versions", (j) => j
337
+ .onRef("agent_versions.agent_id", "=", "agents.id")
338
+ .onRef("agent_versions.version", "=", "agents.current_version"))
339
+ .select("agent_versions.definition")
340
+ .where("agents.id", "=", agentId)
341
+ .where("agents.org_id", "=", orgId)
342
+ .executeTakeFirst();
343
+ return row === undefined ? [] : (normalizeStoredDefinition(row.definition).disabledTools ?? []);
344
+ }
307
345
  /**
308
346
  * 校验主模型与兜底都可解析:enabled `chat` models in the org (`resolve`'s default kind; a model the
309
347
  * platform or the org disabled, or an embedding model → 400 `agent.model_unavailable`, spec B
@@ -369,7 +407,12 @@ let AgentsService = class AgentsService {
369
407
  return this.createChecked(orgId, actorAccountId, request, template, actorTokenId, auditDetail);
370
408
  }
371
409
  async createChecked(orgId, actorAccountId, request, template, actorTokenId, auditDetail) {
372
- const input = { ...request, definition: deriveInstructions(request.definition, null) };
410
+ const input = {
411
+ ...request,
412
+ // run context spec §3.5: version 1 carries the description (the profile's when the
413
+ // definition gives none)
414
+ definition: withCanonicalTools(withDescription(deriveInstructions(request.definition, null), request.definition.description ?? request.profile?.description, undefined)),
415
+ };
373
416
  // 先解析模型(可能访问供应商),不在持有组织行锁时做
374
417
  const warnings = await this.checkModels(orgId, input.definition);
375
418
  const toolKeys = await this.checkTools(orgId, input.definition);
@@ -409,7 +452,7 @@ let AgentsService = class AgentsService {
409
452
  visibility: input.visibility,
410
453
  current_version: 1,
411
454
  profile_avatar: JSON.stringify(input.profile?.avatar ?? { kind: "preset", id: randomPreset() }),
412
- profile_description: input.profile?.description ?? "",
455
+ profile_description: input.definition.description ?? "",
413
456
  profile_quick_actions: JSON.stringify(input.profile?.quickActions ?? []),
414
457
  ...(template !== null && {
415
458
  created_from_template_id: template.id,
@@ -481,7 +524,9 @@ let AgentsService = class AgentsService {
481
524
  async update(orgId, agentId, actorAccountId, request, actorTokenId, auditDetail) {
482
525
  const patch = request;
483
526
  const warnings = patch.definition ? await this.checkModels(orgId, patch.definition) : [];
484
- const toolKeys = patch.definition ? await this.checkTools(orgId, patch.definition) : null;
527
+ const toolKeys = patch.definition
528
+ ? await this.checkTools(orgId, patch.definition, await this.keptDisabled(orgId, agentId))
529
+ : null;
485
530
  const agent = await this.updateIn(orgId, agentId, actorAccountId, patch, toolKeys, actorTokenId, auditDetail);
486
531
  return { agent, warnings };
487
532
  }
@@ -505,7 +550,15 @@ let AgentsService = class AgentsService {
505
550
  .executeTakeFirstOrThrow();
506
551
  // the prompt: instructionFiles give instructions; a save given neither keeps the current one
507
552
  const currentDefinition = normalizeStoredDefinition(current.definition);
508
- const definition = keepPendingConnectors(deriveInstructions(patch.definition, currentDefinition), patch.definition.pendingConnectors, currentDefinition.pendingConnectors);
553
+ const definition = withCanonicalTools(withDescription(keepPendingConnectors(deriveInstructions(patch.definition, currentDefinition), patch.definition.pendingConnectors, currentDefinition.pendingConnectors), patch.definition.description, currentDefinition.description));
554
+ // the display copy follows every description the save gives (run context spec §3.5)
555
+ if (patch.definition.description !== undefined) {
556
+ await t
557
+ .updateTable("agents")
558
+ .set({ profile_description: definition.description ?? "" })
559
+ .where("id", "=", agentId)
560
+ .execute();
561
+ }
509
562
  // 当前版本已有的技能引用保存时合法,不再核对(被删的技能不挡住其他改动);新加的照常核对
510
563
  const kept = new Set(current.definition.skills?.orgSkills ?? []);
511
564
  await assertOrgSkills(t, orgId, definition.skills?.orgSkills ?? [], kept);
@@ -573,11 +626,11 @@ let AgentsService = class AgentsService {
573
626
  return this.lookup.view(agentId);
574
627
  }
575
628
  /** 软删除:权限同 update。待处理的技能改动与该 agent 评测集在执行的评测运行一并取消,提交后删除草稿(T15)。 */
576
- async softDelete(orgId, agentId, actorAccountId, actorTokenId) {
577
- const cancelled = await this.softDeleteIn(orgId, agentId, actorAccountId, actorTokenId);
629
+ async softDelete(orgId, agentId, actorAccountId, actorTokenId, auditDetail) {
630
+ const cancelled = await this.softDeleteIn(orgId, agentId, actorAccountId, actorTokenId, auditDetail);
578
631
  await this.skillChanges.finishCancel(orgId, cancelled);
579
632
  }
580
- async softDeleteIn(orgId, agentId, actorAccountId, actorTokenId) {
633
+ async softDeleteIn(orgId, agentId, actorAccountId, actorTokenId, auditDetail) {
581
634
  const t = this.db.db;
582
635
  await this.lockForWrite(orgId, agentId, actorAccountId);
583
636
  await t
@@ -598,6 +651,7 @@ let AgentsService = class AgentsService {
598
651
  orgId,
599
652
  action: "agent.deleted",
600
653
  target: agentId,
654
+ ...(auditDetail !== undefined && { detail: auditDetail }),
601
655
  });
602
656
  // the agent row stays (soft delete), so its setup request is closed here (P4-T6-3)
603
657
  await this.setupRequests.settleIn({
@@ -14,28 +14,48 @@ export type ModelRef = z.infer<typeof ModelRef>;
14
14
  export declare const ModelParams: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
15
15
  export type ModelParams = z.infer<typeof ModelParams>;
16
16
  /**
17
- * 改名前(D17)保存的连接器引用 `{ kind: "app", appId, tools }` 规范化为 `{ kind: "connector", connectorId, tools }`
18
- * (C27:已存 agent 版本不改写,读入时规范化;新保存只写 connector 形)。其余值原样返回。
17
+ * A tool an agent turns off (tools default-on spec §2): agents have every builtin, every tool of
18
+ * the extensions enabled in the org and every tool of the org's connectors, minus these. A builtin
19
+ * by name; an extension's or a connector's tools by name, or `"all"` to turn it off as a unit
20
+ * (tools it gains later included). Connectors by id, so a renamed connector stays off.
19
21
  */
20
- export declare function normalizeToolRef(v: unknown): unknown;
21
- /**
22
- * agent 定义里对工具的引用:内置工具按名字;插件工具按插件名 + 工具名;连接器工具按连接器 id,
23
- * `tools: "all"` = 该连接器当前所有启用的工具。旧形 `{ kind: "app", appId }` 仍可解析(见 {@link normalizeToolRef})。
24
- */
25
- export declare const AgentToolRef: z.ZodPreprocess<z.ZodDiscriminatedUnion<[z.ZodObject<{
22
+ export declare const DisabledToolRef: z.ZodDiscriminatedUnion<[z.ZodObject<{
26
23
  kind: z.ZodLiteral<"builtin">;
27
24
  name: z.ZodString;
28
25
  }, z.core.$strict>, z.ZodObject<{
29
26
  kind: z.ZodLiteral<"plugin">;
30
27
  plugin: z.ZodString;
31
- name: z.ZodString;
28
+ tools: z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>;
32
29
  }, z.core.$strict>, z.ZodObject<{
33
30
  kind: z.ZodLiteral<"connector">;
34
31
  connectorId: z.ZodString;
35
32
  tools: z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>;
36
- }, z.core.$strict>], "kind">, unknown>;
37
- export type AgentToolRef = z.output<typeof AgentToolRef>;
38
- export { DEFAULT_AGENT_TOOLS } from "../tools/builtin-names.js";
33
+ }, z.core.$strict>], "kind">;
34
+ export type DisabledToolRef = z.output<typeof DisabledToolRef>;
35
+ /** Is builtin `name` turned off by `disabled`? */
36
+ export declare const builtinDisabled: (disabled: readonly DisabledToolRef[] | undefined, name: string) => boolean;
37
+ /** Is tool `name` of extension `plugin` turned off by `disabled`? */
38
+ export declare const extensionToolDisabled: (disabled: readonly DisabledToolRef[] | undefined, plugin: string, name: string) => boolean;
39
+ /** Is tool `name` of connector `connectorId` turned off by `disabled`? */
40
+ export declare const connectorToolDisabled: (disabled: readonly DisabledToolRef[] | undefined, connectorId: string, name: string) => boolean;
41
+ /**
42
+ * `disabled` in its canonical form: one entry per builtin, extension and connector (in first-seen
43
+ * order), names deduplicated and sorted, `"all"` absorbing names. Saving stores this form, so two
44
+ * lists that turn off the same tools compare equal.
45
+ */
46
+ export declare function canonicalDisabledTools(disabled: readonly DisabledToolRef[]): DisabledToolRef[];
47
+ /**
48
+ * A sub-agent's tool filter by tool key (tools default-on spec §4): written only into a child's
49
+ * effective definition at dispatch (never accepted on save). `deny` removes keys (the child-removed
50
+ * tools, `Agent` at the depth limit, a template's `disallowedTools`); `allow`, when set, keeps only
51
+ * its keys (a template's `tools` allowlist). Registry-managed tools (`Skill`, `ToolSearch`,
52
+ * `SendMessage`, `SubagentHandback`) are not filtered.
53
+ */
54
+ export declare const SubagentToolsSchema: z.ZodObject<{
55
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
56
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
57
+ }, z.core.$strict>;
58
+ export type SubagentTools = z.infer<typeof SubagentToolsSchema>;
39
59
  /** Roster names of inline templates and allowlisted org agents (the template name rule). */
40
60
  export declare const SUBAGENT_NAME_RE: RegExp;
41
61
  /**
@@ -142,6 +162,7 @@ export type PendingConnector = z.infer<typeof PendingConnectorSchema>;
142
162
  /** Agent 定义:每次变化写一个新版本(`capybara.agent_versions`)。 */
143
163
  export declare const AgentDefinitionSchema: z.ZodObject<{
144
164
  name: z.ZodString;
165
+ description: z.ZodOptional<z.ZodString>;
145
166
  avatarUrl: z.ZodDefault<z.ZodNullable<z.ZodURL>>;
146
167
  instructions: z.ZodDefault<z.ZodString>;
147
168
  instructionFiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -158,18 +179,22 @@ export declare const AgentDefinitionSchema: z.ZodObject<{
158
179
  }, z.core.$strip>>>;
159
180
  modelParams: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
160
181
  fallbackParams: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
161
- tools: z.ZodDefault<z.ZodArray<z.ZodPreprocess<z.ZodDiscriminatedUnion<[z.ZodObject<{
182
+ disabledTools: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
162
183
  kind: z.ZodLiteral<"builtin">;
163
184
  name: z.ZodString;
164
185
  }, z.core.$strict>, z.ZodObject<{
165
186
  kind: z.ZodLiteral<"plugin">;
166
187
  plugin: z.ZodString;
167
- name: z.ZodString;
188
+ tools: z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>;
168
189
  }, z.core.$strict>, z.ZodObject<{
169
190
  kind: z.ZodLiteral<"connector">;
170
191
  connectorId: z.ZodString;
171
192
  tools: z.ZodUnion<readonly [z.ZodLiteral<"all">, z.ZodArray<z.ZodString>]>;
172
- }, z.core.$strict>], "kind">, unknown>>>;
193
+ }, z.core.$strict>], "kind">>>;
194
+ subagentTools: z.ZodOptional<z.ZodObject<{
195
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
196
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
197
+ }, z.core.$strict>>;
173
198
  toolPolicies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodEnum<{
174
199
  ask: "ask";
175
200
  deny: "deny";
@@ -267,10 +292,12 @@ export declare function normalizeToolKeys(definition: unknown, scope?: LegacySco
267
292
  */
268
293
  export declare function needsLegacyScope(definition: unknown): boolean;
269
294
  /**
270
- * 库里读出的定义(`agent_versions.definition`,不经 zod 解析):把改名前的 `{ kind: "app" }` 工具引用规范化为
271
- * connector 形(C27),and rc tool keys to current keys ({@link normalizeToolKeys}: builtins
272
- * always, `<x>__<tool>` keys with `scope`). Other fields are kept; without old forms the same
273
- * object is returned.
295
+ * A definition read from the database or from history (not parsed by zod): rc tool keys read as
296
+ * current keys ({@link normalizeToolKeys}: builtins always, `<x>__<tool>` keys with `scope`), and
297
+ * a definition from before tools were on by default (an enabled `tools` list, history only: the
298
+ * migration rewrote stored versions) reads as nothing turned off, which is what the migration
299
+ * writes (tools default-on spec §2, §3). Other fields are kept; without old forms the same object
300
+ * is returned.
274
301
  */
275
302
  export declare function normalizeStoredDefinition(def: unknown, scope?: LegacyScope): AgentDefinition;
276
303
  /** 按模型声明严格校验一组参数,返回 `{ path: "<field>.<key>", message }[]`(评测候选也用它)。 */
@@ -280,3 +307,4 @@ export declare function paramIssues(field: string, decl: ModelParameter[], param
280
307
  }[];
281
308
  /** Roster entries an agent may list (spec §4.3), general-purpose included. */
282
309
  export declare const SUBAGENT_ROSTER_MAX = 20;
310
+ export {};
@@ -10,36 +10,74 @@ export const ModelRef = z.object({ provider: z.string(), model: z.string() });
10
10
  */
11
11
  export const ModelParams = z.record(z.string(), z.union([z.string(), z.number(), z.boolean()]));
12
12
  /**
13
- * 改名前(D17)保存的连接器引用 `{ kind: "app", appId, tools }` 规范化为 `{ kind: "connector", connectorId, tools }`
14
- * (C27:已存 agent 版本不改写,读入时规范化;新保存只写 connector 形)。其余值原样返回。
13
+ * A tool an agent turns off (tools default-on spec §2): agents have every builtin, every tool of
14
+ * the extensions enabled in the org and every tool of the org's connectors, minus these. A builtin
15
+ * by name; an extension's or a connector's tools by name, or `"all"` to turn it off as a unit
16
+ * (tools it gains later included). Connectors by id, so a renamed connector stays off.
15
17
  */
16
- export function normalizeToolRef(v) {
17
- if (typeof v !== "object" || v === null || Array.isArray(v))
18
- return v;
19
- const r = v;
20
- if (r.kind !== "app")
21
- return v;
22
- const { kind: _kind, appId, ...rest } = r;
23
- return { kind: "connector", connectorId: appId, ...rest };
24
- }
25
- /**
26
- * agent 定义里对工具的引用:内置工具按名字;插件工具按插件名 + 工具名;连接器工具按连接器 id,
27
- * `tools: "all"` = 该连接器当前所有启用的工具。旧形 `{ kind: "app", appId }` 仍可解析(见 {@link normalizeToolRef})。
28
- */
29
- export const AgentToolRef = z.preprocess(normalizeToolRef, z.discriminatedUnion("kind", [
30
- z.object({ kind: z.literal("builtin"), name: z.string().min(1) }).strict(),
18
+ export const DisabledToolRef = z.discriminatedUnion("kind", [
19
+ z.object({ kind: z.literal("builtin"), name: z.string().min(1).max(200) }).strict(),
31
20
  z
32
- .object({ kind: z.literal("plugin"), plugin: z.string().min(1), name: z.string().min(1) })
21
+ .object({
22
+ kind: z.literal("plugin"),
23
+ plugin: z.string().min(1).max(200),
24
+ tools: z.union([z.literal("all"), z.array(z.string().min(1).max(256)).min(1).max(500)]),
25
+ })
33
26
  .strict(),
34
27
  z
35
28
  .object({
36
29
  kind: z.literal("connector"),
37
- connectorId: z.string().min(1),
38
- tools: z.union([z.literal("all"), z.array(z.string().min(1)).min(1)]),
30
+ connectorId: z.string().min(1).max(100),
31
+ tools: z.union([z.literal("all"), z.array(z.string().min(1).max(256)).min(1).max(500)]),
39
32
  })
40
33
  .strict(),
41
- ]));
42
- export { DEFAULT_AGENT_TOOLS } from "../tools/builtin-names.js";
34
+ ]);
35
+ /** Is builtin `name` turned off by `disabled`? */
36
+ export const builtinDisabled = (disabled, name) => (disabled ?? []).some((r) => r.kind === "builtin" && r.name === name);
37
+ /** Is tool `name` of extension `plugin` turned off by `disabled`? */
38
+ export const extensionToolDisabled = (disabled, plugin, name) => (disabled ?? []).some((r) => r.kind === "plugin" && r.plugin === plugin && (r.tools === "all" || r.tools.includes(name)));
39
+ /** Is tool `name` of connector `connectorId` turned off by `disabled`? */
40
+ export const connectorToolDisabled = (disabled, connectorId, name) => (disabled ?? []).some((r) => r.kind === "connector" &&
41
+ r.connectorId === connectorId &&
42
+ (r.tools === "all" || r.tools.includes(name)));
43
+ /**
44
+ * `disabled` in its canonical form: one entry per builtin, extension and connector (in first-seen
45
+ * order), names deduplicated and sorted, `"all"` absorbing names. Saving stores this form, so two
46
+ * lists that turn off the same tools compare equal.
47
+ */
48
+ export function canonicalDisabledTools(disabled) {
49
+ const out = [];
50
+ const merge = (cur, add) => cur === "all" || add === "all" ? "all" : [...new Set([...cur, ...add])].sort();
51
+ for (const r of disabled) {
52
+ if (r.kind === "builtin") {
53
+ if (!builtinDisabled(out, r.name))
54
+ out.push({ kind: "builtin", name: r.name });
55
+ continue;
56
+ }
57
+ const prev = out.find((x) => x.kind === r.kind &&
58
+ (r.kind === "plugin"
59
+ ? x.plugin === r.plugin
60
+ : x.connectorId === r.connectorId));
61
+ if (prev)
62
+ prev.tools = merge(prev.tools, r.tools);
63
+ else
64
+ out.push({ ...r, tools: r.tools === "all" ? "all" : [...new Set(r.tools)].sort() });
65
+ }
66
+ return out;
67
+ }
68
+ /**
69
+ * A sub-agent's tool filter by tool key (tools default-on spec §4): written only into a child's
70
+ * effective definition at dispatch (never accepted on save). `deny` removes keys (the child-removed
71
+ * tools, `Agent` at the depth limit, a template's `disallowedTools`); `allow`, when set, keeps only
72
+ * its keys (a template's `tools` allowlist). Registry-managed tools (`Skill`, `ToolSearch`,
73
+ * `SendMessage`, `SubagentHandback`) are not filtered.
74
+ */
75
+ export const SubagentToolsSchema = z
76
+ .object({
77
+ allow: z.array(z.string().min(1).max(300)).max(500).optional(),
78
+ deny: z.array(z.string().min(1).max(300)).max(500).optional(),
79
+ })
80
+ .strict();
43
81
  /** Roster names of inline templates and allowlisted org agents (the template name rule). */
44
82
  export const SUBAGENT_NAME_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
45
83
  /**
@@ -134,6 +172,13 @@ export const PendingConnectorSchema = z
134
172
  /** Agent 定义:每次变化写一个新版本(`capybara.agent_versions`)。 */
135
173
  export const AgentDefinitionSchema = z.object({
136
174
  name: z.string().min(1).max(80),
175
+ /**
176
+ * What the agent is for, one short paragraph (run context spec §3.5): shown on the agent's
177
+ * cards (copied to `agents.profile_description`) and given to the model in the run context. No
178
+ * default: older versions are unchanged and gain no version. A save without it keeps the
179
+ * current version's; `""` removes it.
180
+ */
181
+ description: z.string().max(500).optional(),
137
182
  avatarUrl: z.url().nullable().default(null),
138
183
  /**
139
184
  * The model-visible system prompt. Derived on save from `instructionFiles` when they are given
@@ -151,11 +196,19 @@ export const AgentDefinitionSchema = z.object({
151
196
  modelParams: ModelParams.default({}),
152
197
  /** 兜底模型自己的参数(按兜底模型的声明校验);兜底尝试只用这一份。 */
153
198
  fallbackParams: ModelParams.default({}),
154
- /** 引用的工具(M2 保存的 `tools: []` 仍然合法);保存时校验引用存在,运行时由注册表解析。 */
155
- tools: z.array(AgentToolRef).default([]),
156
199
  /**
157
- * 按工具 key 收紧策略(只能收紧:`ask` / `deny`,不接受 `allow`);键必须是该 agent 引用的工具的 key。
158
- * 较早保存的定义没有该字段,按空处理。
200
+ * The tools this agent turns off (tools default-on spec §2); everything else the org offers is
201
+ * on. Saved in canonical form ({@link canonicalDisabledTools}); checked on save.
202
+ */
203
+ disabledTools: z.array(DisabledToolRef).max(500).default([]),
204
+ /**
205
+ * A sub-agent's key filter, set only on a child's effective definition at dispatch (see
206
+ * {@link SubagentToolsSchema}); a save that carries it is refused.
207
+ */
208
+ subagentTools: SubagentToolsSchema.optional(),
209
+ /**
210
+ * Tightened policies by tool key (`ask` / `deny` only, never `allow`); keys are tools the agent
211
+ * could have (on or turned off). Older definitions without it read as empty.
159
212
  */
160
213
  toolPolicies: z.record(z.string(), z.enum(["ask", "deny"])).default({}),
161
214
  /**
@@ -180,7 +233,7 @@ export const AgentDefinitionSchema = z.object({
180
233
  })
181
234
  .strict()
182
235
  .optional(),
183
- /** Sub-agents (phase C); offered only when the builtin `Agent` tool is in `tools`. */
236
+ /** Sub-agents (phase C); offered unless the builtin `Agent` tool is turned off. */
184
237
  subagents: SubagentsSchema.optional(),
185
238
  /**
186
239
  * Connectors still to configure (ruling P4-6), written only by creating from a template. No
@@ -190,14 +243,18 @@ export const AgentDefinitionSchema = z.object({
190
243
  });
191
244
  const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
192
245
  /**
193
- * The connector slugs and extension names `definition`'s `tools` name: connector refs (through
194
- * `scope.connectorSlugById`), plugin refs, and current-format keys of a template's `tools`;
195
- * `inherited` (the parent agent's, for an inline template) is added.
246
+ * The connector slugs and extension names `definition` names: connector refs (through
247
+ * `scope.connectorSlugById`) and plugin refs of a frozen definition's `tools` or of
248
+ * `disabledTools`, and current-format keys of a template's `tools`; `inherited` (the parent
249
+ * agent's, for an inline template) is added.
196
250
  */
197
251
  function ownRefs(definition, scope, inherited) {
198
252
  const connectors = new Set(inherited?.connectors);
199
253
  const extensions = new Set(inherited?.extensions);
200
- const tools = Array.isArray(definition.tools) ? definition.tools : [];
254
+ const tools = [
255
+ ...(Array.isArray(definition.tools) ? definition.tools : []),
256
+ ...(Array.isArray(definition.disabledTools) ? definition.disabledTools : []),
257
+ ];
201
258
  for (const r of tools) {
202
259
  if (typeof r === "string") {
203
260
  const m = /^(mcp|plugin)__([^_].*?)__./.exec(r);
@@ -289,7 +346,10 @@ function policyKeys(v, scope, own) {
289
346
  }
290
347
  return out;
291
348
  }
292
- /** An agent definition's `tools`: builtin refs by their current names (connector and plugin refs name tools, not keys). */
349
+ /**
350
+ * A definition's `tools`: a template's allowlist of keys, or the refs of a definition frozen into
351
+ * history before tools were on by default (builtin refs by their current names).
352
+ */
293
353
  function toolRefs(v, scope, own) {
294
354
  if (!Array.isArray(v))
295
355
  return v;
@@ -369,18 +429,39 @@ export function needsLegacyScope(definition) {
369
429
  return isRecord(sub) && Array.isArray(sub.inline) && sub.inline.some(needsLegacyScope);
370
430
  }
371
431
  /**
372
- * 库里读出的定义(`agent_versions.definition`,不经 zod 解析):把改名前的 `{ kind: "app" }` 工具引用规范化为
373
- * connector 形(C27),and rc tool keys to current keys ({@link normalizeToolKeys}: builtins
374
- * always, `<x>__<tool>` keys with `scope`). Other fields are kept; without old forms the same
375
- * object is returned.
432
+ * A tool ref of a definition frozen into history (logs, eval case snapshots) before tools were on
433
+ * by default (tools default-on spec §2): `{ kind: "app", appId }` (before D17) reads as a
434
+ * connector ref. Other values are returned as they are.
435
+ */
436
+ function normalizeToolRef(v) {
437
+ if (!isRecord(v) || v.kind !== "app")
438
+ return v;
439
+ const { kind: _kind, appId, ...rest } = v;
440
+ return { kind: "connector", connectorId: appId, ...rest };
441
+ }
442
+ /**
443
+ * A definition read from the database or from history (not parsed by zod): rc tool keys read as
444
+ * current keys ({@link normalizeToolKeys}: builtins always, `<x>__<tool>` keys with `scope`), and
445
+ * a definition from before tools were on by default (an enabled `tools` list, history only: the
446
+ * migration rewrote stored versions) reads as nothing turned off, which is what the migration
447
+ * writes (tools default-on spec §2, §3). Other fields are kept; without old forms the same object
448
+ * is returned.
376
449
  */
377
450
  export function normalizeStoredDefinition(def, scope) {
378
451
  let d = def;
379
452
  const tools = d.tools;
380
- if (Array.isArray(tools) && tools.some((t) => t?.kind === "app")) {
453
+ if (Array.isArray(tools) && tools.some((t) => isRecord(t) && t.kind === "app")) {
381
454
  d = { ...d, tools: tools.map(normalizeToolRef) };
382
455
  }
383
- return normalizeToolKeys(d, scope);
456
+ d = normalizeToolKeys(d, scope);
457
+ if ("tools" in d) {
458
+ const { tools: _enabled, ...rest } = d;
459
+ d = { ...rest, disabledTools: Array.isArray(d.disabledTools) ? d.disabledTools : [] };
460
+ }
461
+ else if (!Array.isArray(d.disabledTools)) {
462
+ d = { ...d, disabledTools: [] };
463
+ }
464
+ return d;
384
465
  }
385
466
  /** 按模型声明严格校验一组参数,返回 `{ path: "<field>.<key>", message }[]`(评测候选也用它)。 */
386
467
  export function paramIssues(field, decl, params) {
@@ -12,8 +12,8 @@ export type PlanItemKind = "instruction_file" | "description" | "quick_action" |
12
12
  * qualifies some carried ones:
13
13
  * - instruction_file: unavailable `invalid_name`, `duplicate`, `too_many`, `too_long` (the joined
14
14
  * files exceed the agent's limit);
15
- * - tool: `default` (the template names no tools: the defaults of a new agent), `subagents`
16
- * (`Agent` added because the template describes sub-agents); unavailable `plugin_unavailable`
15
+ * - tool (the template's `tools` allowlist): `subagents` (`Agent` kept on because the template
16
+ * describes sub-agents, though its allowlist leaves it out); unavailable `plugin_unavailable`
17
17
  * (its plugin is not enabled in the org or not loaded), `unknown_tool`, `connector_key` (a
18
18
  * connector tool key: connectors carry over only through `connectors` entries);
19
19
  * - skill: `pinned`, `not_pinned_manual_only`, `not_pinned_too_large`, `subagent` (named only by an