@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
@@ -10,6 +10,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
10
10
  import { createHash } from "node:crypto";
11
11
  import { connectorToolKey, extensionToolKey } from "@capybara-hq/plugin-sdk";
12
12
  import { Inject, Injectable } from "@nestjs/common";
13
+ import { builtinDisabled, connectorToolDisabled, extensionToolDisabled, } from "../agents/definition.js";
13
14
  import { EffectiveConfigs, NEEDS_CONFIG_REASON } from "../extensions/effective-config.js";
14
15
  import { ExtensionHost } from "../extensions/host.js";
15
16
  import { ExtensionRegistry } from "../extensions/registry.js";
@@ -19,7 +20,7 @@ import { readOrgSettings } from "../orgs/settings.service.js";
19
20
  import { estimateTokens } from "../runtime/context/tokens.js";
20
21
  import { SUBAGENT_LIMIT_DEFAULTS, subagentLimits } from "../runtime/subagents/limits.js";
21
22
  import { resolveRoster } from "../runtime/subagents/roster.js";
22
- import { AGENT_TOOL, BASH_COMPANION_TOOLS, BUILTIN, BUILTIN_TOOL_NAMES, SEND_MESSAGE, SKILL_LOAD, SUBAGENT_HANDBACK, SUBAGENT_MESSAGE_TOOLS, TOOL_SEARCH, } from "./builtin-names.js";
23
+ import { AGENT_BUILTIN_NAMES, AGENT_TOOL, BASH_COMPANION_TOOLS, BUILTIN, SEND_MESSAGE, SKILL_LOAD, SUBAGENT_HANDBACK, TOOL_SEARCH, } from "./builtin-names.js";
23
24
  import { agentToolSpec } from "./builtins/agent.js";
24
25
  import { BuiltinTools } from "./builtins/builtin-tools.js";
25
26
  import { canonicalJson } from "./canonical-json.js";
@@ -85,23 +86,21 @@ const builtinTool = (b, spec) => ({
85
86
  ...(b.callPolicy !== undefined && { callPolicy: b.callPolicy }),
86
87
  });
87
88
  /**
88
- * Tool registry: resolves the references in an agent definition into the tools available for this
89
- * run. Not cached (reads PG and the host live every time), so changes take effect right away across
90
- * replicas.
89
+ * Tool registry: resolves what an agent has for this run (tools default-on spec §4): everything
90
+ * the org offers minus the definition's `disabledTools`. Not cached (reads PG and the host live
91
+ * every time), so changes take effect right away across replicas.
91
92
  *
92
- * Availability:
93
- * - builtin: in `builtins`;
94
- * - extension tools: the extension is loaded and registered the tool, this org enabled the
95
- * extension (`extension_org_configs.enabled`, spec 2.2 "installed at deployment level, enabled at
96
- * org level"; required bootstrap plugins are enabled in every org, `enabled.ts`), and the
97
- * extension's effective config for the org is valid (layering spec A §6) and the org did not
98
- * turn the tool off (§7);
99
- * - connector tools: the connector belongs to this org, is not deleted or disabled, the connector is
100
- * installed, the tool status is `enabled` and the key is valid.
101
- * `tools: "all"` takes only enabled tools; disabled / pending-review ones count as deliberately
102
- * turned off by an admin and are not reported; named tools report their reason one by one.
103
- * Only the first of a key is kept; the same source referenced twice is deduplicated silently,
104
- * different sources with the same key report a duplicate.
93
+ * What is offered:
94
+ * - builtins: every {@link AGENT_BUILTIN_NAMES} entry registered here that can run (`unavailable`
95
+ * says why not), `TaskOutput` / `TaskStop` with `Bash`, `Agent` while its roster is not empty;
96
+ * - extension tools: every tool registered by an extension loaded on this replica and enabled in
97
+ * the org (`extension_org_configs.enabled`; required bootstrap plugins are enabled in every org,
98
+ * `enabled.ts`), whose effective config for the org is valid (layering spec A §6) and that the
99
+ * org did not switch off (§7: the org's switch wins);
100
+ * - connector tools: every enabled tool of every live, active connector of the org whose
101
+ * connector extension is installed, with a valid key.
102
+ * What cannot be offered goes to `hidden` with the reason; nothing is reported to the model as
103
+ * unavailable except two sources with one key (the first wins).
105
104
  */
106
105
  let ToolRegistry = class ToolRegistry {
107
106
  db;
@@ -213,92 +212,93 @@ let ToolRegistry = class ToolRegistry {
213
212
  return (await this.connectorKindsFor(orgId)).some((k) => k.kind === kind);
214
213
  }
215
214
  /**
216
- * 保存 agent 时校验工具引用(只看「存在」,停用 / 待复核 / 插件未启用等运行时状态不拒绝,由 `forAgent` 报不可用):
217
- * - 内置:名字在 {@link BUILTIN_TOOL_NAMES} 中;
218
- * - 插件:插件已加载且注册了该工具,key 合法;
219
- * - 连接器:连接器属于本组织且未删除;点名的工具必须在连接器的工具快照中。
220
- * 不同来源拼出同一个 key 也报出来(不截断、不猜)。
221
- * 返回 `keys`:这些引用可能产生的全部工具 key(`"all"` 含连接器当前所有工具,不论状态),供校验 `toolPolicies`。
215
+ * Checks a definition's `disabledTools` on save (existence only): a builtin an agent can turn off
216
+ * ({@link AGENT_BUILTIN_NAMES}), an extension loaded here and the tools it registered, a live
217
+ * connector of the org and tools of its snapshot. An entry equal to one of `kept` (the current
218
+ * version's) is not re-checked: a connector deleted or an extension uninstalled later never
219
+ * blocks other edits. Returns `keys`: every tool key the agent could have, on or turned off (all
220
+ * its builtins, every loaded extension's tools, every tool of the org's live connectors in any
221
+ * status), the keys `toolPolicies` may use.
222
222
  */
223
- async checkRefs(orgId, refs) {
223
+ async checkDisabled(orgId, disabled, kept = []) {
224
224
  const issues = [];
225
- const owner = new Map();
225
+ const keys = new Set();
226
+ for (const name of AGENT_BUILTIN_NAMES)
227
+ keys.add(name);
228
+ for (const name of BASH_COMPANION_TOOLS)
229
+ keys.add(name);
226
230
  const pluginTools = this.host.tools();
227
- const connectorIds = [
228
- ...new Set(refs.flatMap((r) => (r.kind === "connector" ? [r.connectorId] : []))),
229
- ];
230
- const apps = await this.loadConnectors(orgId, connectorIds);
231
- const claim = (path, key, source) => {
232
- const prev = owner.get(key);
233
- if (prev === undefined)
234
- owner.set(key, source);
235
- else if (prev !== source) {
236
- issues.push({ path, message: `Tool key "${key}" is already used by another tool` });
237
- }
238
- };
239
- refs.forEach((ref, i) => {
240
- const path = `tools.${i}`;
231
+ for (const t of pluginTools)
232
+ keys.add(extensionToolKey(t.plugin, t.spec.name));
233
+ const apps = await this.loadOrgConnectors(orgId, { includeDeleted: false });
234
+ for (const app of apps)
235
+ for (const t of app.tools)
236
+ keys.add(connectorToolKey(app.slug, t.name));
237
+ const builtins = new Set(AGENT_BUILTIN_NAMES);
238
+ const keptJson = new Set(kept.map((r) => canonicalJson(r)));
239
+ disabled.forEach((ref, i) => {
240
+ const path = `disabledTools.${i}`;
241
+ if (keptJson.has(canonicalJson(ref)))
242
+ return;
241
243
  if (ref.kind === "builtin") {
242
- if (!BUILTIN_TOOL_NAMES.includes(ref.name)) {
244
+ if (!builtins.has(ref.name)) {
243
245
  const renamed = legacyKeySaveText(ref.name);
244
246
  issues.push({
245
247
  path,
246
- message: renamed === null
247
- ? `Built-in tool "${ref.name}" does not exist`
248
- : `Built-in tool ${renamed}`,
248
+ message: renamed !== null
249
+ ? `Built-in tool ${renamed}`
250
+ : `"${ref.name}" is not a built-in tool an agent can turn off`,
249
251
  });
250
- return;
251
- }
252
- claim(path, ref.name, `builtin:${ref.name}`);
253
- // offered with Bash (see resolve), so their policies validate too
254
- if (ref.name === BUILTIN.Bash) {
255
- for (const c of BASH_COMPANION_TOOLS)
256
- claim(path, c, `builtin:${c}`);
257
252
  }
258
253
  }
259
254
  else if (ref.kind === "plugin") {
260
- const key = extensionToolKey(ref.plugin, ref.name);
261
- if (!pluginTools.some((x) => x.plugin === ref.plugin && x.spec.name === ref.name)) {
262
- issues.push({ path, message: `Plugin tool "${key}" does not exist` });
255
+ const own = pluginTools.filter((x) => x.plugin === ref.plugin);
256
+ if (own.length === 0) {
257
+ issues.push({ path, message: `Extension "${ref.plugin}" has no tools` });
263
258
  return;
264
259
  }
265
- const issue = toolKeyIssue(key);
266
- if (issue) {
267
- issues.push({ path, message: issue });
260
+ if (ref.tools === "all")
268
261
  return;
262
+ for (const name of ref.tools) {
263
+ if (!own.some((x) => x.spec.name === name)) {
264
+ issues.push({
265
+ path,
266
+ message: `Extension tool "${extensionToolKey(ref.plugin, name)}" does not exist`,
267
+ });
268
+ }
269
269
  }
270
- claim(path, key, `plugin:${ref.plugin}:${ref.name}`);
271
270
  }
272
271
  else {
273
- const app = apps.get(ref.connectorId);
274
- if (!app || app.deleted) {
272
+ const app = apps.find((a) => a.id === ref.connectorId);
273
+ if (!app) {
275
274
  issues.push({ path, message: `Connector "${ref.connectorId}" does not exist` });
276
275
  return;
277
276
  }
278
- const names = ref.tools === "all" ? app.tools.map((t) => t.name) : [...new Set(ref.tools)];
279
- for (const name of names) {
277
+ if (ref.tools === "all")
278
+ return;
279
+ for (const name of ref.tools) {
280
280
  if (!app.tools.some((t) => t.name === name)) {
281
281
  issues.push({
282
282
  path,
283
283
  message: `Tool "${name}" does not exist in connector ${app.slug}`,
284
284
  });
285
- continue;
286
285
  }
287
- claim(path, connectorToolKey(app.slug, name), `connector:${app.id}:${name}`);
288
286
  }
289
287
  }
290
288
  });
291
- return { keys: new Set(owner.keys()), issues };
289
+ return { keys, issues };
292
290
  }
293
291
  /**
294
- * 解析 agent 引用的工具(见类注释),再判定是否启用 `ToolSearch`:组织设置 `toolSearch === "on"`,且
295
- * 可用工具数 > `tools.searchThresholdTools` 或其定义的估算 token > `tools.searchThresholdTokens`。
296
- * 启用时把内置 `ToolSearch` 追加到末尾。定义里显式引用的 `ToolSearch` 忽略(由这里按设置管理)。
297
- * `skillLoad`:对话日志里有技能目录快照(`skills_catalog`,Ruling M17)→ 加入内置 `Skill`(始终完整加载);
298
- * 定义里显式引用的 `Skill` 同样忽略。
292
+ * Resolves what the agent has (see the class comment), then decides on `ToolSearch`: the org
293
+ * setting `toolSearch === "on"` and more than `tools.searchThresholdTools` tools or more than
294
+ * `tools.searchThresholdTokens` estimated definition tokens; when on, the builtin `ToolSearch` is
295
+ * appended. `skillLoad`: the log has a skills catalog snapshot (`skills_catalog`, Ruling M17) →
296
+ * the builtin `Skill` is added (always fully loaded).
299
297
  */
300
298
  async forAgent(orgId, def) {
301
- const { tools, unavailable, hidden } = await this.resolve(orgId, def);
299
+ const resolved = await this.resolve(orgId, def);
300
+ const { unavailable, hidden } = resolved;
301
+ const tools = filterSubagentTools(resolved.tools, def.subagentTools);
302
302
  // `SendMessage` to an agent that has `Agent` (to reach its sub-agents) or a parent;
303
303
  // `SubagentHandback` to a sub-agent only; a fork invocation's child reports by its reply
304
304
  const toParent = def.child === true && def.forkChild !== true;
@@ -347,6 +347,7 @@ let ToolRegistry = class ToolRegistry {
347
347
  return (await readOrgSettings(this.db.db, orgId)).toolSearch === "on";
348
348
  }
349
349
  async resolve(orgId, def) {
350
+ const disabled = def.disabledTools ?? [];
350
351
  const tools = [];
351
352
  const unavailable = [];
352
353
  const hidden = [];
@@ -365,155 +366,135 @@ let ToolRegistry = class ToolRegistry {
365
366
  });
366
367
  }
367
368
  };
368
- const [enabledPlugins, offKeys] = def.tools.some((r) => r.kind === "plugin")
369
- ? await Promise.all([this.enabledPlugins(orgId), this.switches.offKeys(orgId)])
370
- : [new Set(), new Set()];
371
- const connectorIds = [
372
- ...new Set(def.tools.flatMap((r) => (r.kind === "connector" ? [r.connectorId] : []))),
373
- ];
374
- const apps = await this.loadConnectors(orgId, connectorIds);
375
- const pluginTools = this.host.tools();
376
- // one effective config read per extension and resolution, however many of its tools are named
377
- const configured = new Map();
378
- const configuredIn = (plugin) => {
379
- let ok = configured.get(plugin);
380
- if (!ok) {
381
- ok = this.effective.get(orgId, plugin).then((e) => e.ok);
382
- configured.set(plugin, ok);
369
+ // builtins
370
+ for (const name of AGENT_BUILTIN_NAMES) {
371
+ if (builtinDisabled(disabled, name))
372
+ continue;
373
+ const b = this.builtins.find((x) => x.spec.name === name);
374
+ if (!b)
375
+ continue;
376
+ const why = (await b.unavailable?.({ orgId })) ?? null;
377
+ if (why !== null) {
378
+ hidden.push({ ref: name, reason: why });
379
+ continue;
383
380
  }
384
- return ok;
385
- };
386
- for (const ref of def.tools) {
387
- if (ref.kind === "builtin") {
388
- if (ref.name === TOOL_SEARCH || ref.name === SKILL_LOAD)
389
- continue;
390
- if (SUBAGENT_MESSAGE_TOOLS.has(ref.name))
381
+ // `Agent`: the description lists this definition's roster (sub-agents spec §4.3); with an
382
+ // empty roster there is nothing to dispatch, so the tool is not offered at all
383
+ let spec = b.spec;
384
+ if (name === AGENT_TOOL) {
385
+ const roster = await resolveRoster(this.db.db, orgId, { subagents: def.subagents });
386
+ if (roster.length === 0)
391
387
  continue;
392
- const b = this.builtins.find((x) => x.spec.name === ref.name);
393
- if (!b) {
394
- unavailable.push({ ref: ref.name, reason: "Built-in tool does not exist" });
395
- continue;
396
- }
397
- const why = (await b.unavailable?.({ orgId })) ?? null;
398
- if (why !== null) {
399
- unavailable.push({ ref: ref.name, reason: why });
400
- continue;
401
- }
402
- // `Agent`: the description lists this definition's roster (sub-agents spec §4.3); with an
403
- // empty roster there is nothing to dispatch, so the tool is not offered at all
404
- let spec = b.spec;
405
- if (b.spec.name === AGENT_TOOL) {
406
- const roster = await resolveRoster(this.db.db, orgId, { subagents: def.subagents });
407
- if (roster.length === 0)
408
- continue;
409
- spec = agentToolSpec(roster, await this.maxConcurrentSubagents(orgId));
410
- }
411
- add(builtinTool(b, spec));
412
- // `TaskOutput` and `TaskStop` come with an available `Bash` (background Bash spec §2)
413
- if (b.spec.name === BUILTIN.Bash) {
414
- for (const name of BASH_COMPANION_TOOLS) {
415
- const c = this.builtins.find((x) => x.spec.name === name);
416
- if (c && ((await c.unavailable?.({ orgId })) ?? null) === null)
417
- add(builtinTool(c, c.spec));
388
+ spec = agentToolSpec(roster, await this.maxConcurrentSubagents(orgId));
389
+ }
390
+ add(builtinTool(b, spec));
391
+ // `TaskOutput` and `TaskStop` come with an available `Bash` (background Bash spec §2)
392
+ if (name === BUILTIN.Bash) {
393
+ for (const companion of BASH_COMPANION_TOOLS) {
394
+ const c = this.builtins.find((x) => x.spec.name === companion);
395
+ if (c && ((await c.unavailable?.({ orgId })) ?? null) === null) {
396
+ add(builtinTool(c, c.spec));
418
397
  }
419
398
  }
420
399
  }
421
- else if (ref.kind === "plugin") {
422
- const key = extensionToolKey(ref.plugin, ref.name);
423
- const t = pluginTools.find((x) => x.plugin === ref.plugin && x.spec.name === ref.name);
424
- if (!t) {
425
- unavailable.push({ ref: key, reason: "Plugin tool does not exist" });
426
- continue;
400
+ }
401
+ // extension tools: the extensions enabled in the org
402
+ const pluginTools = this.host.tools();
403
+ if (pluginTools.length > 0) {
404
+ const [enabledPlugins, offKeys] = await Promise.all([
405
+ this.enabledPlugins(orgId),
406
+ this.switches.offKeys(orgId),
407
+ ]);
408
+ // one effective config read per extension and resolution, however many tools it has
409
+ const configured = new Map();
410
+ const configuredIn = (plugin) => {
411
+ let ok = configured.get(plugin);
412
+ if (!ok) {
413
+ ok = this.effective.get(orgId, plugin).then((e) => e.ok);
414
+ configured.set(plugin, ok);
427
415
  }
428
- if (!enabledPlugins.has(ref.plugin)) {
429
- unavailable.push({
430
- ref: key,
431
- reason: `Plugin ${ref.plugin} is not enabled in this organization`,
432
- });
416
+ return ok;
417
+ };
418
+ for (const t of pluginTools) {
419
+ if (!enabledPlugins.has(t.plugin))
433
420
  continue;
434
- }
421
+ if (extensionToolDisabled(disabled, t.plugin, t.spec.name))
422
+ continue;
423
+ const key = extensionToolKey(t.plugin, t.spec.name);
435
424
  // the pipeline refuses such calls too (a resumed step), this keeps them from the model
436
425
  if (offKeys.has(key)) {
437
- unavailable.push({ ref: key, reason: toolTurnedOffReason(key) });
426
+ hidden.push({ ref: key, reason: toolTurnedOffReason(key) });
438
427
  continue;
439
428
  }
440
- if (!(await configuredIn(ref.plugin))) {
441
- unavailable.push({ ref: key, reason: `Plugin ${ref.plugin} ${NEEDS_CONFIG_REASON}` });
429
+ if (!(await configuredIn(t.plugin))) {
430
+ hidden.push({ ref: key, reason: `Plugin ${t.plugin} ${NEEDS_CONFIG_REASON}` });
442
431
  continue;
443
432
  }
444
433
  const issue = toolKeyIssue(key);
445
434
  if (issue) {
446
- unavailable.push({ ref: key, reason: issue });
435
+ hidden.push({ ref: key, reason: issue });
447
436
  continue;
448
437
  }
449
438
  add({
450
439
  key,
451
- source: { kind: "plugin", plugin: ref.plugin, name: ref.name },
440
+ source: { kind: "plugin", plugin: t.plugin, name: t.spec.name },
452
441
  spec: t.spec,
453
442
  specHash: specHash(t.spec),
454
443
  defaultPolicy: t.spec.defaultPolicy ?? policyFromAnnotations(t.spec.annotations),
455
444
  });
456
445
  }
457
- else {
458
- const app = apps.get(ref.connectorId);
459
- if (!app) {
460
- unavailable.push({ ref: `app:${ref.connectorId}`, reason: "App does not exist" });
446
+ }
447
+ // connector tools: the org's live connectors
448
+ for (const app of await this.loadOrgConnectors(orgId, { includeDeleted: false })) {
449
+ if (disabled.some((r) => r.kind === "connector" && r.connectorId === app.id && r.tools === "all")) {
450
+ continue;
451
+ }
452
+ const all = connectorToolKey(app.slug, "*");
453
+ if (app.status !== "active") {
454
+ hidden.push({ ref: all, reason: `App ${app.slug} is disabled` });
455
+ continue;
456
+ }
457
+ if (!this.findConnector(app.connector)) {
458
+ hidden.push({
459
+ ref: all,
460
+ reason: `Connector ${app.connector} for app ${app.slug} is not installed`,
461
+ });
462
+ continue;
463
+ }
464
+ for (const t of app.tools) {
465
+ if (connectorToolDisabled(disabled, app.id, t.name))
461
466
  continue;
462
- }
463
- const all = connectorToolKey(app.slug, "*");
464
- if (app.deleted) {
465
- unavailable.push({ ref: all, reason: `App ${app.slug} was deleted` });
467
+ const key = connectorToolKey(app.slug, t.name);
468
+ // 远端已不再提供(漂移检测置停用并标记,见 drift.ts)
469
+ if (t.gone) {
470
+ hidden.push({ ref: key, reason: `Tool no longer exists in app ${app.slug}` });
466
471
  continue;
467
472
  }
468
- if (app.status !== "active") {
469
- unavailable.push({ ref: all, reason: `App ${app.slug} is disabled` });
473
+ if (t.status === "disabled") {
474
+ hidden.push({ ref: key, reason: "Tool is disabled" });
470
475
  continue;
471
476
  }
472
- if (!this.findConnector(app.connector)) {
473
- unavailable.push({
474
- ref: all,
475
- reason: `Connector ${app.connector} for app ${app.slug} is not installed`,
476
- });
477
+ if (t.status === "pending_review") {
478
+ hidden.push({ ref: key, reason: "Tool is pending review" });
477
479
  continue;
478
480
  }
479
- const wanted = ref.tools === "all"
480
- ? app.tools
481
- : ref.tools.map((name) => app.tools.find((t) => t.name === name) ?? { name, missing: true });
482
- // 「all」里未启用的工具不算 agent 点名要的,不进 unavailable(不提醒),只记进 hidden 备查
483
- const notEnabled = ref.tools === "all" ? hidden : unavailable;
484
- for (const t of wanted) {
485
- const key = connectorToolKey(app.slug, t.name);
486
- // 远端已不再提供(漂移检测置停用并标记,见 drift.ts):与「没有这一行」同一个事实
487
- if ("missing" in t || t.gone) {
488
- notEnabled.push({ ref: key, reason: `Tool no longer exists in app ${app.slug}` });
489
- continue;
490
- }
491
- if (t.status === "disabled") {
492
- notEnabled.push({ ref: key, reason: "Tool is disabled" });
493
- continue;
494
- }
495
- if (t.status === "pending_review") {
496
- notEnabled.push({ ref: key, reason: "Tool is pending review" });
497
- continue;
498
- }
499
- const issue = toolKeyIssue(key);
500
- if (issue) {
501
- unavailable.push({ ref: key, reason: issue });
502
- continue;
503
- }
504
- add({
505
- key,
506
- source: {
507
- kind: "connector",
508
- connectorId: app.id,
509
- name: t.name,
510
- ...(t.source === "resources" && { resources: true }),
511
- },
512
- spec: t.spec,
513
- specHash: t.specHash,
514
- defaultPolicy: t.defaultPolicy,
515
- });
481
+ const issue = toolKeyIssue(key);
482
+ if (issue) {
483
+ hidden.push({ ref: key, reason: issue });
484
+ continue;
516
485
  }
486
+ add({
487
+ key,
488
+ source: {
489
+ kind: "connector",
490
+ connectorId: app.id,
491
+ name: t.name,
492
+ ...(t.source === "resources" && { resources: true }),
493
+ },
494
+ spec: t.spec,
495
+ specHash: t.specHash,
496
+ defaultPolicy: t.defaultPolicy,
497
+ });
517
498
  }
518
499
  }
519
500
  return { tools, unavailable, hidden };
@@ -537,56 +518,50 @@ let ToolRegistry = class ToolRegistry {
537
518
  async enabledPlugins(orgId) {
538
519
  return this.host.enabledPlugins(orgId);
539
520
  }
540
- async loadConnectors(orgId, ids) {
541
- const out = new Map();
542
- if (ids.length === 0)
543
- return out;
544
- // 软删除的连接器也读出来,只为给出「已删除」这个更准确的原因(slug 可能已被新连接器复用,按 id 区分)
521
+ /** The org's connectors (live ones, sorted by slug) with their tool snapshots (by name). */
522
+ async loadOrgConnectors(orgId, _opts) {
545
523
  const apps = await this.db
546
524
  .selectFrom("connectors")
547
- .select(["id", "slug", "connector", "status", "deleted_at"])
525
+ .select(["id", "slug", "connector", "status"])
548
526
  .where("org_id", "=", orgId)
549
- .where("id", "in", ids)
527
+ .where("deleted_at", "is", null)
528
+ .orderBy("slug")
529
+ .orderBy("id")
550
530
  .execute();
551
- const live = apps.filter((a) => a.deleted_at === null).map((a) => a.id);
552
- const toolRows = live.length === 0
553
- ? []
554
- : await this.db
555
- .selectFrom("connector_tools")
556
- .select([
557
- "connector_id",
558
- "name",
559
- "spec",
560
- "spec_hash",
561
- "status",
562
- "default_policy",
563
- "source",
564
- "missing_since",
565
- ])
566
- .where("connector_id", "in", live)
567
- .orderBy("name")
568
- .execute();
569
- for (const a of apps) {
570
- out.set(a.id, {
571
- id: a.id,
572
- slug: a.slug,
573
- connector: a.connector,
574
- status: a.status,
575
- deleted: a.deleted_at !== null,
576
- tools: toolRows
577
- .filter((t) => t.connector_id === a.id)
578
- .map((t) => ({
579
- name: t.name,
580
- spec: t.spec,
581
- specHash: t.spec_hash,
582
- status: t.status,
583
- defaultPolicy: t.default_policy,
584
- source: t.source,
585
- gone: t.missing_since !== null,
586
- })),
587
- });
588
- }
589
- return out;
531
+ if (apps.length === 0)
532
+ return [];
533
+ const toolRows = await this.db
534
+ .selectFrom("connector_tools")
535
+ .select([
536
+ "connector_id",
537
+ "name",
538
+ "spec",
539
+ "spec_hash",
540
+ "status",
541
+ "default_policy",
542
+ "source",
543
+ "missing_since",
544
+ ])
545
+ .where("connector_id", "in", apps.map((a) => a.id))
546
+ .orderBy("name")
547
+ .execute();
548
+ return apps.map((a) => ({
549
+ id: a.id,
550
+ slug: a.slug,
551
+ connector: a.connector,
552
+ status: a.status,
553
+ tools: toolRows
554
+ .filter((t) => t.connector_id === a.id)
555
+ .map((t) => ({
556
+ name: t.name,
557
+ spec: t.spec,
558
+ specHash: t.spec_hash,
559
+ status: t.status,
560
+ defaultPolicy: t.default_policy,
561
+ source: t.source,
562
+ gone: t.missing_since !== null,
563
+ })),
564
+ }));
590
565
  }
591
566
  };
592
567
  ToolRegistry = __decorate([
@@ -600,3 +575,17 @@ ToolRegistry = __decorate([
600
575
  __param(6, Inject(KernelConfigService))
601
576
  ], ToolRegistry);
602
577
  export { ToolRegistry };
578
+ /**
579
+ * `tools` narrowed by a sub-agent's key filter (tools default-on spec §4): `deny` keys removed,
580
+ * and with `allow` only its keys kept. `TaskOutput` / `TaskStop` follow `Bash`, as they come with
581
+ * it. Without a filter the list is returned as it is.
582
+ */
583
+ export function filterSubagentTools(tools, filter) {
584
+ if (filter === undefined)
585
+ return tools;
586
+ const companions = new Set(BASH_COMPANION_TOOLS);
587
+ const deny = new Set(filter.deny ?? []);
588
+ const allow = filter.allow === undefined ? null : new Set(filter.allow);
589
+ const keep = (key) => !deny.has(key) && (allow === null || allow.has(key));
590
+ return tools.filter((t) => (companions.has(t.key) ? keep(BUILTIN.Bash) : keep(t.key)));
591
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capybara-hq/kernel",
3
- "version": "0.1.0-rc.6",
3
+ "version": "0.1.0-rc.7",
4
4
  "description": "Capybara kernel: config, database, plugin host and HTTP API of the Capybara agent platform",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -64,14 +64,14 @@
64
64
  "yaml": "^2.9.1",
65
65
  "yauzl": "3.4.0",
66
66
  "zod": "^4.6.7",
67
- "@capybara-hq/plugin-sdk": "^0.1.0-rc.4"
67
+ "@capybara-hq/plugin-sdk": "^0.1.0-rc.5"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@langchain/langgraph-checkpoint-validation": "^1.2.0",
71
71
  "@types/pg": "^8.23.1",
72
72
  "@types/semver": "^7.8.0",
73
73
  "@types/yauzl": "3.4.0",
74
- "@capybara-hq/testing": "0.1.0-rc.7"
74
+ "@capybara-hq/testing": "0.1.0-rc.8"
75
75
  },
76
76
  "scripts": {
77
77
  "build": "tsc -b"
@@ -0,0 +1,27 @@
1
+ -- Platform tool phase 2 (spec 2026-11-07-platform-tool-design.md §14.5 item 2): the super admin's
2
+ -- agent creates an account with a kernel-generated one-time password. Expand-only.
3
+ --
4
+ -- must_change_password: the account must set its own password before anything else (the auth
5
+ -- guard refuses every route but the password change, /me and logout until it does).
6
+ ALTER TABLE capybara.accounts ADD COLUMN IF NOT EXISTS must_change_password boolean NOT NULL DEFAULT false;
7
+
8
+ -- The generated password, sealed with the master keyring (AES-256-GCM, AAD = account id), waiting
9
+ -- for the person who approved the creation to read it once on the web. Keyed by the account; the
10
+ -- tool call it came from (conversation_id, run_id, call_id: a call id is unique only within its run)
11
+ -- and its recipient decide who may read it. Read once (deleted as it is read), dropped when the
12
+ -- account changes its password, and dropped after expires_at by the hourly cleanup job.
13
+ CREATE TABLE IF NOT EXISTS capybara.account_initial_passwords (
14
+ account_id text PRIMARY KEY REFERENCES capybara.accounts(id) ON DELETE CASCADE,
15
+ recipient_account_id text NOT NULL REFERENCES capybara.accounts(id) ON DELETE CASCADE,
16
+ conversation_id text NOT NULL REFERENCES capybara.conversations(id) ON DELETE CASCADE,
17
+ run_id text NOT NULL,
18
+ call_id text NOT NULL,
19
+ master_key_id text NOT NULL,
20
+ ciphertext bytea NOT NULL,
21
+ expires_at timestamptz NOT NULL,
22
+ created_at timestamptz NOT NULL DEFAULT now()
23
+ );
24
+ CREATE INDEX IF NOT EXISTS account_initial_passwords_call_idx
25
+ ON capybara.account_initial_passwords (conversation_id, run_id, call_id);
26
+ CREATE INDEX IF NOT EXISTS account_initial_passwords_expires_idx
27
+ ON capybara.account_initial_passwords (expires_at);