@capybara-hq/kernel 0.1.0-rc.1 → 0.1.0-rc.3

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 (670) hide show
  1. package/dist/admin/admin.controller.d.ts +17 -17
  2. package/dist/admin/admin.controller.js +43 -26
  3. package/dist/admin/admin.module.d.ts +3 -0
  4. package/dist/admin/admin.module.js +22 -0
  5. package/dist/admin/extensions.controller.d.ts +14 -14
  6. package/dist/admin/extensions.controller.js +30 -17
  7. package/dist/admin/setup-lock.d.ts +16 -0
  8. package/dist/admin/setup-lock.js +47 -0
  9. package/dist/admin/setup.controller.d.ts +8 -8
  10. package/dist/admin/setup.controller.js +27 -25
  11. package/dist/admin/setup.service.d.ts +19 -27
  12. package/dist/admin/setup.service.js +61 -61
  13. package/dist/agents/agent-lookup.d.ts +53 -0
  14. package/dist/agents/agent-lookup.js +187 -0
  15. package/dist/agents/agents.controller.d.ts +1 -1
  16. package/dist/agents/agents.controller.js +14 -8
  17. package/dist/agents/agents.module.d.ts +7 -0
  18. package/dist/agents/agents.module.js +41 -0
  19. package/dist/agents/agents.service.d.ts +39 -58
  20. package/dist/agents/agents.service.js +280 -335
  21. package/dist/agents/definition.d.ts +39 -8
  22. package/dist/agents/definition.js +201 -17
  23. package/dist/agents/models.controller.d.ts +1 -1
  24. package/dist/agents/models.controller.js +2 -2
  25. package/dist/agents/templates.controller.d.ts +1 -1
  26. package/dist/agents/templates.controller.js +2 -2
  27. package/dist/agents/templates.d.ts +6 -8
  28. package/dist/agents/templates.js +39 -8
  29. package/dist/app.d.ts +93 -0
  30. package/dist/app.js +150 -0
  31. package/dist/catalog/admin-catalog.controller.d.ts +3 -3
  32. package/dist/catalog/admin-catalog.controller.js +27 -13
  33. package/dist/catalog/catalog-content.d.ts +185 -0
  34. package/dist/catalog/catalog-content.js +326 -0
  35. package/dist/catalog/catalog-items.d.ts +186 -0
  36. package/dist/catalog/catalog-items.js +410 -0
  37. package/dist/catalog/catalog.module.d.ts +14 -0
  38. package/dist/catalog/catalog.module.js +71 -0
  39. package/dist/catalog/catalog.service.d.ts +34 -188
  40. package/dist/catalog/catalog.service.js +155 -489
  41. package/dist/catalog/claude/agents.js +13 -10
  42. package/dist/catalog/cli.d.ts +3 -2
  43. package/dist/catalog/cli.js +13 -31
  44. package/dist/catalog/job-ids.d.ts +15 -0
  45. package/dist/catalog/job-ids.js +15 -0
  46. package/dist/catalog/jobs.d.ts +27 -0
  47. package/dist/catalog/jobs.js +70 -0
  48. package/dist/catalog/locks.d.ts +24 -0
  49. package/dist/catalog/locks.js +63 -0
  50. package/dist/catalog/marketplaces.controller.d.ts +4 -4
  51. package/dist/catalog/marketplaces.controller.js +22 -11
  52. package/dist/catalog/marketplaces.service.d.ts +31 -14
  53. package/dist/catalog/marketplaces.service.js +330 -256
  54. package/dist/catalog/org-catalog.controller.d.ts +4 -3
  55. package/dist/catalog/org-catalog.controller.js +29 -14
  56. package/dist/catalog/org-catalog.service.d.ts +32 -198
  57. package/dist/catalog/org-catalog.service.js +159 -400
  58. package/dist/catalog/plugin-import.d.ts +73 -34
  59. package/dist/catalog/plugin-import.js +356 -217
  60. package/dist/catalog/plugin-install.d.ts +83 -41
  61. package/dist/catalog/plugin-install.js +421 -269
  62. package/dist/catalog/plugin-upgrade.d.ts +59 -4
  63. package/dist/catalog/plugin-upgrade.js +407 -282
  64. package/dist/catalog/requests.service.d.ts +27 -15
  65. package/dist/catalog/requests.service.js +201 -145
  66. package/dist/catalog/upgrade-targets.d.ts +4 -7
  67. package/dist/channels/actions.d.ts +6 -4
  68. package/dist/channels/actions.js +1 -1
  69. package/dist/channels/cards.d.ts +10 -4
  70. package/dist/channels/cards.js +16 -8
  71. package/dist/channels/channels.module.d.ts +40 -0
  72. package/dist/channels/channels.module.js +128 -0
  73. package/dist/channels/connections.controller.d.ts +1 -1
  74. package/dist/channels/connections.controller.js +11 -6
  75. package/dist/channels/connections.service.d.ts +43 -21
  76. package/dist/channels/connections.service.js +236 -131
  77. package/dist/channels/inbound.d.ts +34 -38
  78. package/dist/channels/inbound.js +107 -41
  79. package/dist/channels/job-ids.d.ts +10 -0
  80. package/dist/channels/job-ids.js +10 -0
  81. package/dist/channels/jobs.d.ts +85 -0
  82. package/dist/channels/jobs.js +157 -0
  83. package/dist/channels/outbound.d.ts +60 -82
  84. package/dist/channels/outbound.js +165 -194
  85. package/dist/channels/supervisor.d.ts +88 -46
  86. package/dist/channels/supervisor.js +230 -132
  87. package/dist/channels/threads.d.ts +29 -8
  88. package/dist/channels/threads.js +71 -13
  89. package/dist/channels/webhook.d.ts +20 -14
  90. package/dist/channels/webhook.js +51 -20
  91. package/dist/config/load.d.ts +3 -2
  92. package/dist/config/load.js +3 -2
  93. package/dist/config/nacos-source.js +11 -2
  94. package/dist/config/schema.d.ts +1 -0
  95. package/dist/config/schema.js +12 -6
  96. package/dist/conversations/access.d.ts +29 -0
  97. package/dist/conversations/access.js +86 -0
  98. package/dist/conversations/artifacts.d.ts +11 -11
  99. package/dist/conversations/artifacts.js +36 -10
  100. package/dist/conversations/attachments.controller.d.ts +1 -1
  101. package/dist/conversations/attachments.controller.js +8 -6
  102. package/dist/conversations/attachments.module.d.ts +7 -0
  103. package/dist/conversations/attachments.module.js +25 -0
  104. package/dist/conversations/attachments.service.d.ts +30 -22
  105. package/dist/conversations/attachments.service.js +119 -46
  106. package/dist/conversations/conversations.controller.d.ts +8 -7
  107. package/dist/conversations/conversations.controller.js +59 -29
  108. package/dist/conversations/conversations.module.d.ts +8 -0
  109. package/dist/conversations/conversations.module.js +69 -0
  110. package/dist/conversations/conversations.service.d.ts +40 -38
  111. package/dist/conversations/conversations.service.js +130 -140
  112. package/dist/conversations/event-log.d.ts +39 -18
  113. package/dist/conversations/event-log.js +93 -27
  114. package/dist/conversations/events.d.ts +23 -3
  115. package/dist/conversations/events.js +26 -14
  116. package/dist/conversations/files.d.ts +10 -10
  117. package/dist/conversations/files.js +37 -11
  118. package/dist/conversations/idem-keys.d.ts +5 -0
  119. package/dist/conversations/idem-keys.js +5 -0
  120. package/dist/conversations/job-ids.d.ts +6 -0
  121. package/dist/conversations/job-ids.js +6 -0
  122. package/dist/conversations/outputs-read.d.ts +11 -11
  123. package/dist/conversations/outputs-read.js +31 -7
  124. package/dist/conversations/queue.d.ts +48 -56
  125. package/dist/conversations/queue.js +13 -289
  126. package/dist/conversations/queue.service.d.ts +60 -0
  127. package/dist/conversations/queue.service.js +343 -0
  128. package/dist/conversations/sandbox-status.d.ts +13 -10
  129. package/dist/conversations/sandbox-status.js +36 -8
  130. package/dist/conversations/titles.d.ts +71 -24
  131. package/dist/conversations/titles.js +159 -63
  132. package/dist/ctx/bus.js +9 -3
  133. package/dist/ctx/create-ctx.d.ts +6 -0
  134. package/dist/ctx/create-ctx.js +7 -9
  135. package/dist/ctx/lock.d.ts +7 -3
  136. package/dist/ctx/lock.js +9 -20
  137. package/dist/ctx/secrets.d.ts +10 -2
  138. package/dist/ctx/secrets.js +7 -3
  139. package/dist/db/kernel-schema.d.ts +4 -4
  140. package/dist/db/pool.d.ts +5 -0
  141. package/dist/db/pool.js +1 -0
  142. package/dist/errors.d.ts +1 -0
  143. package/dist/errors.js +1 -0
  144. package/dist/evals/budget.d.ts +42 -21
  145. package/dist/evals/budget.js +114 -62
  146. package/dist/evals/evals.module.d.ts +31 -0
  147. package/dist/evals/evals.module.js +114 -0
  148. package/dist/evals/jobs.d.ts +20 -0
  149. package/dist/evals/jobs.js +45 -0
  150. package/dist/evals/recorded-tools.d.ts +27 -1
  151. package/dist/evals/recorded-tools.js +85 -10
  152. package/dist/evals/run-replay.d.ts +61 -8
  153. package/dist/evals/run-replay.js +159 -85
  154. package/dist/evals/runs.controller.d.ts +1 -1
  155. package/dist/evals/runs.controller.js +17 -8
  156. package/dist/evals/runs.service.d.ts +23 -45
  157. package/dist/evals/runs.service.js +245 -234
  158. package/dist/evals/sets.controller.d.ts +1 -1
  159. package/dist/evals/sets.controller.js +17 -8
  160. package/dist/evals/sets.service.d.ts +22 -6
  161. package/dist/evals/sets.service.js +248 -194
  162. package/dist/evals/snapshot.d.ts +2 -2
  163. package/dist/evals/step-replay.d.ts +2 -2
  164. package/dist/evals/step-replay.js +1 -1
  165. package/dist/evals/trajectory.controller.d.ts +1 -1
  166. package/dist/evals/trajectory.controller.js +11 -7
  167. package/dist/evals/trajectory.d.ts +2 -2
  168. package/dist/evals/trajectory.service.d.ts +5 -4
  169. package/dist/evals/trajectory.service.js +30 -7
  170. package/dist/evals/worker.d.ts +44 -27
  171. package/dist/evals/worker.js +220 -121
  172. package/dist/extensions/admin-ops.d.ts +61 -33
  173. package/dist/extensions/admin-ops.js +248 -154
  174. package/dist/extensions/admin-view.d.ts +38 -27
  175. package/dist/extensions/admin-view.js +126 -55
  176. package/dist/extensions/approvals.d.ts +12 -8
  177. package/dist/extensions/approvals.js +73 -46
  178. package/dist/extensions/blobs.d.ts +27 -10
  179. package/dist/extensions/blobs.js +111 -45
  180. package/dist/extensions/bootstrap.d.ts +58 -31
  181. package/dist/extensions/bootstrap.js +175 -121
  182. package/dist/extensions/cli.d.ts +20 -10
  183. package/dist/extensions/cli.js +41 -96
  184. package/dist/extensions/config-issues.d.ts +7 -0
  185. package/dist/extensions/config-issues.js +31 -0
  186. package/dist/extensions/deployment-config-store.d.ts +49 -0
  187. package/dist/extensions/deployment-config-store.js +133 -0
  188. package/dist/extensions/deployment-config.d.ts +58 -67
  189. package/dist/extensions/deployment-config.js +202 -230
  190. package/dist/extensions/enabled.d.ts +5 -5
  191. package/dist/extensions/extensions.module.d.ts +8 -0
  192. package/dist/extensions/extensions.module.js +77 -0
  193. package/dist/extensions/hooks.d.ts +3 -2
  194. package/dist/extensions/hooks.js +1 -1
  195. package/dist/extensions/host.d.ts +72 -68
  196. package/dist/extensions/host.js +191 -152
  197. package/dist/extensions/installs.d.ts +49 -16
  198. package/dist/extensions/installs.js +128 -32
  199. package/dist/extensions/job-ids.d.ts +6 -0
  200. package/dist/extensions/job-ids.js +6 -0
  201. package/dist/extensions/lifecycle-topics.d.ts +18 -0
  202. package/dist/extensions/lifecycle-topics.js +18 -0
  203. package/dist/extensions/lifecycle.d.ts +35 -47
  204. package/dist/extensions/lifecycle.js +103 -39
  205. package/dist/extensions/locks.d.ts +33 -0
  206. package/dist/extensions/locks.js +86 -0
  207. package/dist/extensions/migrate-lock.d.ts +3 -4
  208. package/dist/extensions/org-config.controller.d.ts +1 -1
  209. package/dist/extensions/org-config.controller.js +8 -5
  210. package/dist/extensions/org-config.d.ts +48 -46
  211. package/dist/extensions/org-config.js +284 -226
  212. package/dist/extensions/registry.d.ts +50 -2
  213. package/dist/extensions/registry.js +89 -4
  214. package/dist/extensions/sources.d.ts +12 -8
  215. package/dist/extensions/sources.js +34 -13
  216. package/dist/files/files.module.d.ts +3 -0
  217. package/dist/files/files.module.js +22 -0
  218. package/dist/files/previewers.controller.d.ts +7 -2
  219. package/dist/files/previewers.controller.js +17 -9
  220. package/dist/files/previewers.d.ts +13 -18
  221. package/dist/files/previewers.js +83 -36
  222. package/dist/http/adapter.d.ts +3 -0
  223. package/dist/http/adapter.js +25 -0
  224. package/dist/http/api.module.d.ts +3 -110
  225. package/dist/http/api.module.js +47 -355
  226. package/dist/http/app.d.ts +11 -15
  227. package/dist/http/app.js +17 -62
  228. package/dist/http/error-filter.module.d.ts +5 -0
  229. package/dist/http/error-filter.module.js +18 -0
  230. package/dist/http/error.filter.js +2 -2
  231. package/dist/identity/accounts.d.ts +82 -29
  232. package/dist/identity/accounts.js +294 -175
  233. package/dist/identity/api-tokens.d.ts +11 -7
  234. package/dist/identity/api-tokens.js +71 -44
  235. package/dist/identity/audit.d.ts +7 -4
  236. package/dist/identity/audit.js +5 -1
  237. package/dist/identity/auth.controller.d.ts +11 -10
  238. package/dist/identity/auth.controller.js +31 -25
  239. package/dist/identity/auth.guard.d.ts +3 -3
  240. package/dist/identity/auth.guard.js +6 -4
  241. package/dist/identity/binding.d.ts +9 -11
  242. package/dist/identity/binding.js +41 -13
  243. package/dist/identity/enterprise-admin.d.ts +18 -12
  244. package/dist/identity/enterprise-admin.js +67 -13
  245. package/dist/identity/external-identity-lock.d.ts +17 -0
  246. package/dist/identity/external-identity-lock.js +39 -0
  247. package/dist/identity/external.d.ts +19 -15
  248. package/dist/identity/external.js +163 -125
  249. package/dist/identity/identity.module.d.ts +6 -0
  250. package/dist/identity/identity.module.js +56 -0
  251. package/dist/identity/me.controller.d.ts +16 -15
  252. package/dist/identity/me.controller.js +37 -31
  253. package/dist/identity/sessions.d.ts +12 -10
  254. package/dist/identity/sessions.js +74 -42
  255. package/dist/identity/settings.d.ts +20 -14
  256. package/dist/identity/settings.js +86 -58
  257. package/dist/identity/sso.controller.d.ts +7 -7
  258. package/dist/identity/sso.controller.js +13 -9
  259. package/dist/identity/sso.d.ts +9 -12
  260. package/dist/identity/sso.js +54 -24
  261. package/dist/inbox/inbox.module.d.ts +3 -0
  262. package/dist/inbox/inbox.module.js +22 -0
  263. package/dist/inbox/inbox.service.d.ts +7 -9
  264. package/dist/inbox/inbox.service.js +32 -11
  265. package/dist/index.d.ts +16 -11
  266. package/dist/index.js +9 -6
  267. package/dist/infra/cache/cache.module.d.ts +3 -0
  268. package/dist/infra/cache/cache.module.js +16 -0
  269. package/dist/infra/cache/cache.service.d.ts +21 -0
  270. package/dist/infra/cache/cache.service.js +80 -0
  271. package/dist/infra/cache/cacheable.decorator.d.ts +32 -0
  272. package/dist/infra/cache/cacheable.decorator.js +83 -0
  273. package/dist/infra/cli/kernel-cli.module.d.ts +66 -0
  274. package/dist/infra/cli/kernel-cli.module.js +165 -0
  275. package/dist/infra/close-within.d.ts +15 -0
  276. package/dist/infra/close-within.js +36 -0
  277. package/dist/infra/config/config.module.d.ts +13 -0
  278. package/dist/infra/config/config.module.js +39 -0
  279. package/dist/infra/config/kernel-config.service.d.ts +25 -0
  280. package/dist/infra/config/kernel-config.service.js +126 -0
  281. package/dist/infra/database/after-commit.d.ts +6 -0
  282. package/dist/infra/database/after-commit.js +9 -0
  283. package/dist/infra/database/database.module.d.ts +25 -0
  284. package/dist/infra/database/database.module.js +90 -0
  285. package/dist/infra/database/kernel-db.d.ts +22 -0
  286. package/dist/infra/database/kernel-db.js +65 -0
  287. package/dist/infra/database/transaction-host.d.ts +50 -0
  288. package/dist/infra/database/transaction-host.js +125 -0
  289. package/dist/infra/database/transactional.decorator.d.ts +15 -0
  290. package/dist/infra/database/transactional.decorator.js +27 -0
  291. package/dist/infra/database/xact-lock.d.ts +17 -0
  292. package/dist/infra/database/xact-lock.js +43 -0
  293. package/dist/infra/events/kernel-events.d.ts +96 -0
  294. package/dist/infra/events/kernel-events.js +65 -0
  295. package/dist/infra/health/health.controller.d.ts +26 -0
  296. package/dist/infra/health/health.controller.js +104 -0
  297. package/dist/infra/health/health.module.d.ts +9 -0
  298. package/dist/infra/health/health.module.js +24 -0
  299. package/dist/infra/health/health.options.d.ts +10 -0
  300. package/dist/infra/health/health.options.js +15 -0
  301. package/dist/infra/health/shutdown-state.d.ts +6 -0
  302. package/dist/infra/health/shutdown-state.js +2 -0
  303. package/dist/infra/lifecycle/graceful-shutdown.module.d.ts +6 -0
  304. package/dist/infra/lifecycle/graceful-shutdown.module.js +23 -0
  305. package/dist/infra/lifecycle/graceful-shutdown.service.d.ts +70 -0
  306. package/dist/infra/lifecycle/graceful-shutdown.service.js +135 -0
  307. package/dist/infra/lifecycle/process-guards.d.ts +52 -0
  308. package/dist/infra/lifecycle/process-guards.js +86 -0
  309. package/dist/infra/lifecycle/shutdown-signals.d.ts +30 -0
  310. package/dist/infra/lifecycle/shutdown-signals.js +48 -0
  311. package/dist/infra/lock/key-template.d.ts +13 -0
  312. package/dist/infra/lock/key-template.js +46 -0
  313. package/dist/infra/lock/lock.module.d.ts +3 -0
  314. package/dist/infra/lock/lock.module.js +16 -0
  315. package/dist/infra/lock/lock.service.d.ts +120 -0
  316. package/dist/infra/lock/lock.service.js +343 -0
  317. package/dist/infra/lock/shared-lease.d.ts +44 -0
  318. package/dist/infra/lock/shared-lease.js +121 -0
  319. package/dist/infra/lock/with-lock.decorator.d.ts +28 -0
  320. package/dist/infra/lock/with-lock.decorator.js +49 -0
  321. package/dist/infra/logging/logging.module.d.ts +16 -0
  322. package/dist/infra/logging/logging.module.js +34 -0
  323. package/dist/infra/queue/configured-processor.d.ts +18 -0
  324. package/dist/infra/queue/configured-processor.js +23 -0
  325. package/dist/infra/queue/job-failure.d.ts +18 -0
  326. package/dist/infra/queue/job-failure.js +26 -0
  327. package/dist/infra/queue/queue-shutdown.d.ts +27 -0
  328. package/dist/infra/queue/queue-shutdown.js +81 -0
  329. package/dist/infra/queue/queue.module.d.ts +16 -0
  330. package/dist/infra/queue/queue.module.js +61 -0
  331. package/dist/infra/queue/redis-connection.d.ts +7 -0
  332. package/dist/infra/queue/redis-connection.js +18 -0
  333. package/dist/infra/queue/retired-schedulers.d.ts +7 -0
  334. package/dist/infra/queue/retired-schedulers.js +9 -0
  335. package/dist/infra/queue/run-job.d.ts +16 -0
  336. package/dist/infra/queue/run-job.js +19 -0
  337. package/dist/infra/redis/redis.module.d.ts +24 -0
  338. package/dist/infra/redis/redis.module.js +87 -0
  339. package/dist/infra/schedule/cron-tick.d.ts +12 -0
  340. package/dist/infra/schedule/cron-tick.js +25 -0
  341. package/dist/infra/schedule/locked-cron.decorator.d.ts +27 -0
  342. package/dist/infra/schedule/locked-cron.decorator.js +53 -0
  343. package/dist/infra/schedule/locked-interval.d.ts +69 -0
  344. package/dist/infra/schedule/locked-interval.js +190 -0
  345. package/dist/infra/schedule/locked-tick.d.ts +90 -0
  346. package/dist/infra/schedule/locked-tick.js +137 -0
  347. package/dist/infra/schedule/schedule.module.d.ts +8 -0
  348. package/dist/infra/schedule/schedule.module.js +27 -0
  349. package/dist/infra/schedule/scheduled-runs.d.ts +69 -0
  350. package/dist/infra/schedule/scheduled-runs.js +163 -0
  351. package/dist/infra/swagger/swagger.d.ts +16 -0
  352. package/dist/infra/swagger/swagger.js +31 -0
  353. package/dist/infra/throttler/credential-throttler.d.ts +35 -0
  354. package/dist/infra/throttler/credential-throttler.js +77 -0
  355. package/dist/infra/throttler/named-throttlers.d.ts +31 -0
  356. package/dist/infra/throttler/named-throttlers.js +119 -0
  357. package/dist/infra/throttler/redis-throttler-storage.d.ts +38 -0
  358. package/dist/infra/throttler/redis-throttler-storage.js +130 -0
  359. package/dist/infra/throttler/throttler.guard.d.ts +23 -0
  360. package/dist/infra/throttler/throttler.guard.js +68 -0
  361. package/dist/infra/throttler/throttler.module.d.ts +15 -0
  362. package/dist/infra/throttler/throttler.module.js +53 -0
  363. package/dist/infra/tokens.d.ts +15 -0
  364. package/dist/infra/tokens.js +15 -0
  365. package/dist/infra/validation/create-zod-dto.d.ts +23 -0
  366. package/dist/infra/validation/create-zod-dto.js +35 -0
  367. package/dist/infra/validation/parse-with-zod.d.ts +7 -0
  368. package/dist/infra/validation/parse-with-zod.js +12 -0
  369. package/dist/infra/validation/validation.module.d.ts +3 -0
  370. package/dist/infra/validation/validation.module.js +16 -0
  371. package/dist/infra/validation/zod-params.d.ts +7 -0
  372. package/dist/infra/validation/zod-params.js +42 -0
  373. package/dist/infra/validation/zod-validation.pipe.d.ts +11 -0
  374. package/dist/infra/validation/zod-validation.pipe.js +31 -0
  375. package/dist/kernel.d.ts +9 -244
  376. package/dist/kernel.js +8 -1305
  377. package/dist/kernel.module.d.ts +17 -0
  378. package/dist/kernel.module.js +136 -0
  379. package/dist/lifecycle/kernel-lifecycle.d.ts +140 -0
  380. package/dist/lifecycle/kernel-lifecycle.js +456 -0
  381. package/dist/lifecycle/tokens.d.ts +3 -0
  382. package/dist/lifecycle/tokens.js +3 -0
  383. package/dist/log-context.d.ts +2 -0
  384. package/dist/log-context.js +4 -0
  385. package/dist/models/models.module.d.ts +3 -0
  386. package/dist/models/models.module.js +24 -0
  387. package/dist/models/prices.d.ts +8 -2
  388. package/dist/models/prices.js +65 -37
  389. package/dist/models/purposes.controller.d.ts +1 -1
  390. package/dist/models/purposes.controller.js +5 -6
  391. package/dist/models/purposes.d.ts +35 -13
  392. package/dist/models/purposes.js +101 -51
  393. package/dist/orgs/directory-sync.controller.d.ts +1 -1
  394. package/dist/orgs/directory-sync.controller.js +2 -2
  395. package/dist/orgs/directory-sync.d.ts +61 -31
  396. package/dist/orgs/directory-sync.js +212 -125
  397. package/dist/orgs/invitations.controller.d.ts +8 -8
  398. package/dist/orgs/invitations.controller.js +27 -26
  399. package/dist/orgs/invitations.service.d.ts +12 -9
  400. package/dist/orgs/invitations.service.js +130 -92
  401. package/dist/orgs/job-ids.d.ts +8 -0
  402. package/dist/orgs/job-ids.js +8 -0
  403. package/dist/orgs/members.service.d.ts +19 -12
  404. package/dist/orgs/members.service.js +161 -117
  405. package/dist/orgs/offboarding.d.ts +54 -57
  406. package/dist/orgs/offboarding.js +161 -71
  407. package/dist/orgs/org-lock.d.ts +28 -19
  408. package/dist/orgs/org-lock.js +81 -35
  409. package/dist/orgs/org.guard.d.ts +1 -1
  410. package/dist/orgs/org.guard.js +2 -2
  411. package/dist/orgs/orgs.controller.d.ts +13 -13
  412. package/dist/orgs/orgs.controller.js +29 -17
  413. package/dist/orgs/orgs.module.d.ts +6 -0
  414. package/dist/orgs/orgs.module.js +68 -0
  415. package/dist/orgs/orgs.service.d.ts +30 -19
  416. package/dist/orgs/orgs.service.js +139 -86
  417. package/dist/orgs/settings.controller.d.ts +1 -1
  418. package/dist/orgs/settings.controller.js +8 -6
  419. package/dist/orgs/settings.service.d.ts +16 -10
  420. package/dist/orgs/settings.service.js +77 -48
  421. package/dist/overrides.d.ts +56 -0
  422. package/dist/overrides.js +30 -0
  423. package/dist/roles/gateway-role.d.ts +43 -0
  424. package/dist/roles/gateway-role.js +98 -0
  425. package/dist/roles/gateway.module.d.ts +8 -0
  426. package/dist/roles/gateway.module.js +28 -0
  427. package/dist/roles/worker-role.d.ts +63 -0
  428. package/dist/roles/worker-role.js +144 -0
  429. package/dist/roles/worker.module.d.ts +14 -0
  430. package/dist/roles/worker.module.js +90 -0
  431. package/dist/runtime/abort.js +19 -2
  432. package/dist/runtime/checkpointer.d.ts +8 -3
  433. package/dist/runtime/checkpointer.js +87 -55
  434. package/dist/runtime/context/build.d.ts +6 -6
  435. package/dist/runtime/context/build.js +18 -8
  436. package/dist/runtime/context/claude-tools.d.ts +2 -1
  437. package/dist/runtime/context/claude-tools.js +9 -10
  438. package/dist/runtime/context/legacy-text.d.ts +22 -0
  439. package/dist/runtime/context/legacy-text.js +37 -0
  440. package/dist/runtime/context/skills.d.ts +29 -11
  441. package/dist/runtime/context/skills.js +37 -30
  442. package/dist/runtime/conversation-lock.d.ts +20 -11
  443. package/dist/runtime/conversation-lock.js +62 -72
  444. package/dist/runtime/hook-calls.d.ts +3 -3
  445. package/dist/runtime/hook-calls.js +1 -6
  446. package/dist/runtime/job-ids.d.ts +10 -0
  447. package/dist/runtime/job-ids.js +10 -0
  448. package/dist/runtime/langgraph-loop.js +1 -1
  449. package/dist/runtime/loop.d.ts +8 -1
  450. package/dist/runtime/loop.js +14 -0
  451. package/dist/runtime/maintenance-queue.d.ts +10 -0
  452. package/dist/runtime/maintenance-queue.js +10 -0
  453. package/dist/runtime/maintenance.d.ts +45 -74
  454. package/dist/runtime/maintenance.js +139 -137
  455. package/dist/runtime/model-call.d.ts +7 -4
  456. package/dist/runtime/model-call.js +25 -58
  457. package/dist/runtime/providers.d.ts +17 -6
  458. package/dist/runtime/providers.js +66 -25
  459. package/dist/runtime/quota.d.ts +17 -3
  460. package/dist/runtime/quota.js +27 -2
  461. package/dist/runtime/retired-schedulers.d.ts +7 -0
  462. package/dist/runtime/retired-schedulers.js +31 -0
  463. package/dist/runtime/run-control.d.ts +33 -0
  464. package/dist/runtime/run-control.js +77 -0
  465. package/dist/runtime/run-finish.d.ts +27 -18
  466. package/dist/runtime/run-finish.js +98 -51
  467. package/dist/runtime/run-jobs.d.ts +48 -0
  468. package/dist/runtime/run-jobs.js +95 -0
  469. package/dist/runtime/run-processors.d.ts +60 -0
  470. package/dist/runtime/run-processors.js +185 -0
  471. package/dist/runtime/run-queue.d.ts +32 -57
  472. package/dist/runtime/run-queue.js +291 -295
  473. package/dist/runtime/run-steps.d.ts +39 -0
  474. package/dist/runtime/run-steps.js +96 -0
  475. package/dist/runtime/run-worker.d.ts +122 -76
  476. package/dist/runtime/run-worker.js +343 -229
  477. package/dist/runtime/runtime.module.d.ts +10 -0
  478. package/dist/runtime/runtime.module.js +112 -0
  479. package/dist/runtime/step-log.d.ts +40 -0
  480. package/dist/runtime/step-log.js +94 -0
  481. package/dist/runtime/stream.controller.d.ts +5 -8
  482. package/dist/runtime/stream.controller.js +14 -12
  483. package/dist/runtime/stream.d.ts +24 -6
  484. package/dist/runtime/stream.js +78 -7
  485. package/dist/runtime/subagents/child.d.ts +3 -44
  486. package/dist/runtime/subagents/child.js +0 -79
  487. package/dist/runtime/subagents/definition.d.ts +5 -10
  488. package/dist/runtime/subagents/definition.js +13 -14
  489. package/dist/runtime/subagents/dispatch.d.ts +89 -8
  490. package/dist/runtime/subagents/dispatch.js +137 -142
  491. package/dist/runtime/subagents/limits.d.ts +9 -4
  492. package/dist/runtime/subagents/limits.js +4 -2
  493. package/dist/runtime/subagents/org-agents.d.ts +4 -4
  494. package/dist/runtime/subagents/org-agents.js +3 -2
  495. package/dist/runtime/subagents/progress.d.ts +2 -2
  496. package/dist/runtime/subagents/roster.d.ts +4 -4
  497. package/dist/runtime/subagents/roster.js +2 -2
  498. package/dist/runtime/subagents/skill-fork.d.ts +8 -9
  499. package/dist/runtime/subagents/skill-fork.js +17 -6
  500. package/dist/runtime/subagents/subagents.service.d.ts +40 -0
  501. package/dist/runtime/subagents/subagents.service.js +101 -0
  502. package/dist/runtime/usage-report.d.ts +94 -52
  503. package/dist/runtime/usage-report.js +200 -100
  504. package/dist/runtime/waits.d.ts +127 -59
  505. package/dist/runtime/waits.js +433 -210
  506. package/dist/sandbox/job-ids.d.ts +10 -0
  507. package/dist/sandbox/job-ids.js +10 -0
  508. package/dist/sandbox/jobs.d.ts +41 -0
  509. package/dist/sandbox/jobs.js +113 -0
  510. package/dist/sandbox/leases.d.ts +39 -31
  511. package/dist/sandbox/leases.js +117 -257
  512. package/dist/sandbox/providers.d.ts +19 -0
  513. package/dist/sandbox/providers.js +38 -0
  514. package/dist/sandbox/sandbox.module.d.ts +8 -0
  515. package/dist/sandbox/sandbox.module.js +30 -0
  516. package/dist/sandbox/sandbox.service.d.ts +24 -29
  517. package/dist/sandbox/sandbox.service.js +106 -75
  518. package/dist/skills/catalog.d.ts +37 -24
  519. package/dist/skills/catalog.js +100 -57
  520. package/dist/skills/changes.controller.d.ts +4 -4
  521. package/dist/skills/changes.controller.js +15 -9
  522. package/dist/skills/changes.service.d.ts +30 -20
  523. package/dist/skills/changes.service.js +425 -367
  524. package/dist/skills/invocable.controller.d.ts +1 -1
  525. package/dist/skills/invocable.controller.js +8 -5
  526. package/dist/skills/invocation-keys.d.ts +1 -1
  527. package/dist/skills/invocation-keys.js +1 -1
  528. package/dist/skills/invoke.d.ts +17 -16
  529. package/dist/skills/invoke.js +53 -21
  530. package/dist/skills/skills.controller.d.ts +1 -1
  531. package/dist/skills/skills.controller.js +11 -6
  532. package/dist/skills/skills.module.d.ts +6 -0
  533. package/dist/skills/skills.module.js +30 -0
  534. package/dist/skills/skills.service.d.ts +47 -30
  535. package/dist/skills/skills.service.js +221 -158
  536. package/dist/storage/job-ids.d.ts +6 -0
  537. package/dist/storage/job-ids.js +6 -0
  538. package/dist/storage/purge.d.ts +22 -7
  539. package/dist/storage/purge.js +55 -3
  540. package/dist/storage/storage.module.d.ts +6 -0
  541. package/dist/storage/storage.module.js +23 -0
  542. package/dist/storage/storage.service.d.ts +18 -4
  543. package/dist/storage/storage.service.js +44 -3
  544. package/dist/tools/approvals.controller.d.ts +1 -1
  545. package/dist/tools/approvals.controller.js +12 -8
  546. package/dist/tools/approvals.service.d.ts +33 -25
  547. package/dist/tools/approvals.service.js +343 -259
  548. package/dist/tools/breaker.d.ts +2 -2
  549. package/dist/tools/breaker.js +21 -3
  550. package/dist/tools/builtin-names.d.ts +73 -0
  551. package/dist/tools/builtin-names.js +116 -0
  552. package/dist/tools/builtins/agent.d.ts +7 -7
  553. package/dist/tools/builtins/agent.js +7 -11
  554. package/dist/tools/builtins/ask-user.d.ts +3 -3
  555. package/dist/tools/builtins/ask-user.js +3 -3
  556. package/dist/tools/builtins/builtin-tools.d.ts +21 -0
  557. package/dist/tools/builtins/builtin-tools.js +80 -0
  558. package/dist/tools/builtins/read-tool-output.d.ts +3 -3
  559. package/dist/tools/builtins/read-tool-output.js +3 -3
  560. package/dist/tools/builtins/sandbox/bash.d.ts +5 -5
  561. package/dist/tools/builtins/sandbox/bash.js +33 -30
  562. package/dist/tools/builtins/sandbox/common.d.ts +5 -4
  563. package/dist/tools/builtins/sandbox/common.js +2 -2
  564. package/dist/tools/builtins/sandbox/deliver.d.ts +1 -1
  565. package/dist/tools/builtins/sandbox/deliver.js +13 -13
  566. package/dist/tools/builtins/sandbox/edit.d.ts +1 -1
  567. package/dist/tools/builtins/sandbox/edit.js +42 -31
  568. package/dist/tools/builtins/sandbox/file-state.d.ts +34 -0
  569. package/dist/tools/builtins/sandbox/file-state.js +34 -0
  570. package/dist/tools/builtins/sandbox/glob-match.d.ts +1 -1
  571. package/dist/tools/builtins/sandbox/glob-match.js +1 -1
  572. package/dist/tools/builtins/sandbox/glob.d.ts +1 -1
  573. package/dist/tools/builtins/sandbox/glob.js +6 -6
  574. package/dist/tools/builtins/sandbox/grep.d.ts +7 -4
  575. package/dist/tools/builtins/sandbox/grep.js +149 -32
  576. package/dist/tools/builtins/sandbox/index.d.ts +1 -1
  577. package/dist/tools/builtins/sandbox/index.js +1 -1
  578. package/dist/tools/builtins/sandbox/read.d.ts +2 -2
  579. package/dist/tools/builtins/sandbox/read.js +22 -15
  580. package/dist/tools/builtins/sandbox/write.d.ts +1 -1
  581. package/dist/tools/builtins/sandbox/write.js +38 -34
  582. package/dist/tools/builtins/skill-load.d.ts +6 -6
  583. package/dist/tools/builtins/skill-load.js +33 -17
  584. package/dist/tools/builtins/skill-write.d.ts +4 -4
  585. package/dist/tools/builtins/skill-write.js +10 -10
  586. package/dist/tools/builtins/tool-search.d.ts +13 -9
  587. package/dist/tools/builtins/tool-search.js +25 -14
  588. package/dist/tools/canonical-json.d.ts +6 -0
  589. package/dist/tools/canonical-json.js +16 -0
  590. package/dist/tools/connector-content.controller.d.ts +1 -1
  591. package/dist/tools/connector-content.controller.js +11 -6
  592. package/dist/tools/connector-content.d.ts +12 -15
  593. package/dist/tools/connector-content.js +53 -18
  594. package/dist/tools/connectors.controller.d.ts +1 -1
  595. package/dist/tools/connectors.controller.js +21 -10
  596. package/dist/tools/connectors.service.d.ts +31 -13
  597. package/dist/tools/connectors.service.js +438 -348
  598. package/dist/tools/credentials.d.ts +17 -20
  599. package/dist/tools/credentials.js +55 -34
  600. package/dist/tools/display-names.d.ts +9 -0
  601. package/dist/tools/display-names.js +24 -0
  602. package/dist/tools/drift.d.ts +29 -41
  603. package/dist/tools/drift.js +116 -84
  604. package/dist/tools/elicitation.js +1 -1
  605. package/dist/tools/info.d.ts +32 -13
  606. package/dist/tools/info.js +88 -39
  607. package/dist/tools/job-ids.d.ts +13 -0
  608. package/dist/tools/job-ids.js +15 -0
  609. package/dist/tools/jobs.d.ts +24 -0
  610. package/dist/tools/jobs.js +69 -0
  611. package/dist/tools/legacy-data.d.ts +34 -0
  612. package/dist/tools/legacy-data.js +76 -0
  613. package/dist/tools/legacy-keys.d.ts +51 -0
  614. package/dist/tools/legacy-keys.js +115 -0
  615. package/dist/tools/naming.d.ts +1 -5
  616. package/dist/tools/naming.js +1 -7
  617. package/dist/tools/oauth/flow-paths.d.ts +16 -0
  618. package/dist/tools/oauth/flow-paths.js +38 -0
  619. package/dist/tools/oauth/flow.d.ts +30 -30
  620. package/dist/tools/oauth/flow.js +109 -81
  621. package/dist/tools/oauth/oauth.controller.d.ts +3 -3
  622. package/dist/tools/oauth/oauth.controller.js +12 -9
  623. package/dist/tools/oauth/tokens.d.ts +11 -3
  624. package/dist/tools/oauth/tokens.js +15 -14
  625. package/dist/tools/outputs.d.ts +13 -4
  626. package/dist/tools/outputs.js +48 -4
  627. package/dist/tools/pipeline.d.ts +72 -50
  628. package/dist/tools/pipeline.js +239 -100
  629. package/dist/tools/policy.d.ts +3 -16
  630. package/dist/tools/policy.js +13 -19
  631. package/dist/tools/questions.controller.d.ts +2 -2
  632. package/dist/tools/questions.controller.js +9 -6
  633. package/dist/tools/questions.service.d.ts +26 -25
  634. package/dist/tools/questions.service.js +201 -142
  635. package/dist/tools/registry.d.ts +43 -38
  636. package/dist/tools/registry.js +100 -72
  637. package/dist/tools/resources.d.ts +1 -1
  638. package/dist/tools/resources.js +1 -1
  639. package/dist/tools/specs.d.ts +5 -4
  640. package/dist/tools/specs.js +3 -1
  641. package/dist/tools/tools.module.d.ts +10 -0
  642. package/dist/tools/tools.module.js +91 -0
  643. package/dist/ui/call-extension.d.ts +16 -0
  644. package/dist/ui/call-extension.js +38 -0
  645. package/dist/ui/embed-token.d.ts +9 -5
  646. package/dist/ui/embed-token.js +34 -6
  647. package/dist/ui/ui-stream.d.ts +22 -17
  648. package/dist/ui/ui-stream.js +72 -12
  649. package/dist/ui/ui.module.d.ts +7 -0
  650. package/dist/ui/ui.module.js +28 -0
  651. package/dist/ui/views.controller.d.ts +14 -12
  652. package/dist/ui/views.controller.js +32 -25
  653. package/dist/ui/views.d.ts +9 -57
  654. package/dist/ui/views.js +43 -45
  655. package/package.json +10 -3
  656. package/src/migrations/0063_tool_keys_claude_code.sql +220 -0
  657. package/dist/http/health.controller.d.ts +0 -26
  658. package/dist/http/health.controller.js +0 -79
  659. package/dist/http/tokens.d.ts +0 -131
  660. package/dist/http/tokens.js +0 -131
  661. package/dist/http/zod.pipe.d.ts +0 -8
  662. package/dist/http/zod.pipe.js +0 -14
  663. package/dist/identity/rate-limit.d.ts +0 -55
  664. package/dist/identity/rate-limit.js +0 -121
  665. package/dist/sandbox/lifecycle.d.ts +0 -21
  666. package/dist/sandbox/lifecycle.js +0 -68
  667. package/dist/tools/builtins/sandbox/names.d.ts +0 -7
  668. package/dist/tools/builtins/sandbox/names.js +0 -20
  669. /package/dist/http/{gateway.module.d.ts → gateway-routes.d.ts} +0 -0
  670. /package/dist/http/{gateway.module.js → gateway-routes.js} +0 -0
@@ -1,11 +1,28 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
+ return function (target, key) { decorator(target, key, paramIndex); }
9
+ };
1
10
  import { randomUUID } from "node:crypto";
2
11
  import { parseSkillMd, SKILL_ENTRY_FILE, ToolError } from "@capybara-hq/plugin-sdk";
12
+ import { Inject, Injectable } from "@nestjs/common";
3
13
  import { sql } from "kysely";
4
- import { visibleTo } from "../agents/agents.service.js";
14
+ import { visibleTo } from "../agents/agent-lookup.js";
5
15
  import { skillFilesPrefix } from "../conversations/attachments.service.js";
16
+ import { EventLog } from "../conversations/event-log.js";
6
17
  import { ApiError } from "../errors.js";
7
18
  import { audit } from "../identity/audit.js";
19
+ import { KernelDb } from "../infra/database/kernel-db.js";
20
+ import { TransactionHost } from "../infra/database/transaction-host.js";
21
+ import { Transactional } from "../infra/database/transactional.decorator.js";
22
+ import { KERNEL_LOGGER } from "../infra/tokens.js";
8
23
  import { sameSnapshot, } from "../runtime/context/skills.js";
24
+ import { StorageService } from "../storage/storage.service.js";
25
+ import { BUILTIN } from "../tools/builtin-names.js";
9
26
  import { fitPinned, invocationOf, lockLatestCatalog } from "./catalog.js";
10
27
  /**
11
28
  * 每个 agent 自己的技能(`scope = agent`)上限,含待批准的新技能。远低于目录快照的上限(`SKILLS_CATALOG_MAX`),
@@ -26,7 +43,7 @@ const AGENT_GONE_TEXT = "This agent no longer exists, so the skill cannot be sav
26
43
  const iso = (v) => new Date(v).toISOString();
27
44
  const byName = (a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
28
45
  const notFound = () => new ApiError("skill_change.not_found", "Skill change not found");
29
- /** The body of the SKILL.md a skill_write just stored (as run start would read it); null if unparsable. */
46
+ /** The body of the SKILL.md a SkillWrite just stored (as run start would read it); null if unparsable. */
30
47
  function writtenBody(pkg) {
31
48
  const md = pkg.files.find((f) => f.path === SKILL_ENTRY_FILE);
32
49
  if (!md)
@@ -41,27 +58,34 @@ function writtenBody(pkg) {
41
58
  }
42
59
  /**
43
60
  * agent 自写技能与共享 agent 的技能变更审批(M5 T15,R4):
44
- * - `write`(工具 `skill_write` 调用):私有 agent 直接生成新版本;共享 agent 生成一条待负责人批准的申请,
61
+ * - `write`(工具 `SkillWrite` 调用):私有 agent 直接生成新版本;共享 agent 生成一条待负责人批准的申请,
45
62
  * 期间只有发起对话试用(`resolveEffectiveSkills` 按对话合并);两种情况都在同一事务里往发起对话追加一份
46
- * 技能目录快照(Ruling M17:日志是唯一事实源),同一运行的下一步即可 `skill_load`;
63
+ * 技能目录快照(Ruling M17:日志是唯一事实源),同一运行的下一步即可 `Skill`;
47
64
  * - `decide`(HTTP,只有该 agent 当前的负责人):批准 → 版本对所有对话生效(各对话下一次运行开始时写新快照);
48
65
  * 拒绝 → 删除草稿对象,发起对话下一次运行开始时目录回到当前版本;
49
66
  * - 同一 agent 的同名技能最多一条待处理申请:同一对话再写取代旧的(旧的 cancelled、草稿删除、技能 id 不变),
50
67
  * 别的对话再写被拒绝(英文说明)。
51
68
  * 状态都在 PG(agent 行锁串行化同一 agent 的写与决定),文件在对象存储 `kernel/<orgId>/skills/<id>/`;无进程内状态。
52
69
  */
53
- export class SkillChangesService {
54
- d;
55
- constructor(d) {
56
- this.d = d;
70
+ let SkillChangesService = class SkillChangesService {
71
+ db;
72
+ storage;
73
+ eventLog;
74
+ log;
75
+ txHost;
76
+ constructor(db, storage, eventLog, log, txHost) {
77
+ this.db = db;
78
+ this.storage = storage;
79
+ this.eventLog = eventLog;
80
+ this.log = log;
81
+ this.txHost = txHost;
57
82
  }
58
83
  /** 写技能(见类注释)。模型可见的失败抛 `ToolError`。 */
59
84
  async write(ctx, pkg) {
60
- const { db, eventLog } = this.d;
61
85
  let store;
62
86
  try {
63
- this.d.storage.assertAvailable();
64
- store = this.d.storage.kernel(ctx.orgId);
87
+ this.storage.assertAvailable();
88
+ store = this.storage.kernel(ctx.orgId);
65
89
  }
66
90
  catch (e) {
67
91
  throw storageError(e);
@@ -77,175 +101,15 @@ export class SkillChangesService {
77
101
  }
78
102
  let committed;
79
103
  try {
80
- committed = await db.transaction().execute(async (t) => {
81
- await keyShareOrg(t, ctx.orgId);
82
- // NO KEY UPDATE, not UPDATE (here, in decide and in deleteAgentSkill): it still serializes
83
- // the writes and decisions of one agent, but not the foreign key check (FOR KEY SHARE) of a
84
- // transaction that already holds the conversation row this one locks last, e.g. an event
85
- // log append updating that row a second time (the title job): FOR UPDATE made that 40P01
86
- const agent = await t
87
- .selectFrom("agents")
88
- .select(["visibility", "deleted_at"])
89
- .where("id", "=", ctx.agentId)
90
- .where("org_id", "=", ctx.orgId)
91
- .forNoKeyUpdate()
92
- .executeTakeFirst();
93
- if (!agent || agent.deleted_at !== null)
94
- throw new ToolError(AGENT_GONE_TEXT);
95
- // Then the conversation row (appendCatalog's lock, still after the agent row like decide),
96
- // before the change request insert: its foreign key check takes FOR KEY SHARE on that row,
97
- // and upgrading to FOR UPDATE afterwards deadlocked with another writer doing the same
98
- await t
99
- .selectFrom("conversations")
100
- .select("id")
101
- .where("id", "=", ctx.conversationId)
102
- .forUpdate()
103
- .execute();
104
- const existing = await t
105
- .selectFrom("skills")
106
- .select(["id", "current_version"])
107
- .where("org_id", "=", ctx.orgId)
108
- .where("scope", "=", "agent")
109
- .where("agent_id", "=", ctx.agentId)
110
- .where("name", "=", pkg.name)
111
- .where("deleted_at", "is", null)
112
- .forUpdate()
113
- .executeTakeFirst();
114
- const pend = await t
115
- .selectFrom("skill_change_requests")
116
- .selectAll()
117
- .where("agent_id", "=", ctx.agentId)
118
- .where("status", "=", "pending")
119
- .where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", pkg.name)
120
- .forUpdate()
121
- .executeTakeFirst();
122
- const drop = [];
123
- if (pend) {
124
- if (pend.requested_in_conversation !== ctx.conversationId) {
125
- throw new ToolError(pendingElsewhereText(pkg.name));
126
- }
127
- // 同一对话再写:取代旧申请
128
- await t
129
- .updateTable("skill_change_requests")
130
- .set({ status: "cancelled", decided_at: sql `now()` })
131
- .where("id", "=", pend.id)
132
- .execute();
133
- drop.push(pend.object_prefix);
134
- await audit(t, {
135
- actorAccountId: ctx.accountId,
136
- orgId: ctx.orgId,
137
- action: "skill.change_decided",
138
- target: pend.id,
139
- detail: {
140
- decision: "cancelled",
141
- reason: "superseded",
142
- supersededBy: id,
143
- agentId: ctx.agentId,
144
- name: pkg.name,
145
- },
146
- });
147
- }
148
- if (!existing)
149
- await this.assertBelowCap(t, ctx.agentId, pend?.id);
150
- const version = (existing?.current_version ?? 0) + 1;
151
- const skillId = existing?.id ?? pend?.proposed_version.skillId ?? randomUUID();
152
- let outcome;
153
- if (agent.visibility === "private") {
154
- await this.createVersion(t, {
155
- orgId: ctx.orgId,
156
- agentId: ctx.agentId,
157
- skillId,
158
- exists: existing !== undefined,
159
- version,
160
- manifest: pkg.manifest,
161
- prefix,
162
- createdBy: ctx.accountId,
163
- });
164
- await audit(t, {
165
- actorAccountId: ctx.accountId,
166
- orgId: ctx.orgId,
167
- action: existing ? "skill.version_created" : "skill.created",
168
- target: skillId,
169
- detail: {
170
- name: pkg.name,
171
- version,
172
- files: pkg.manifest.files.length,
173
- agentId: ctx.agentId,
174
- conversationId: ctx.conversationId,
175
- via: "skill_write",
176
- },
177
- });
178
- outcome = { kind: "version", skillId, version, created: !existing };
179
- }
180
- else {
181
- const proposed = { skillId, version, manifest: pkg.manifest };
182
- await t
183
- .insertInto("skill_change_requests")
184
- .values({
185
- id,
186
- org_id: ctx.orgId,
187
- agent_id: ctx.agentId,
188
- skill_id: existing?.id ?? null,
189
- proposed_version: JSON.stringify(proposed),
190
- object_prefix: prefix,
191
- requested_by_account: ctx.accountId,
192
- requested_in_conversation: ctx.conversationId,
193
- decided_by: null,
194
- })
195
- .execute();
196
- await audit(t, {
197
- actorAccountId: ctx.accountId,
198
- orgId: ctx.orgId,
199
- action: "skill.change_requested",
200
- target: id,
201
- detail: {
202
- agentId: ctx.agentId,
203
- skillId: existing?.id ?? null,
204
- name: pkg.name,
205
- version,
206
- files: pkg.manifest.files.length,
207
- conversationId: ctx.conversationId,
208
- },
209
- });
210
- outcome = { kind: "requested", requestId: id, skillId, version };
211
- }
212
- // 本对话立即看到新版本:在上一份快照上替换 / 加入这个技能(确定、来自日志;来源 = 本次的对象前缀)
213
- // A pinned entry of this skill gets the version, source and body just written (phase B)
214
- // A manual-only version (phase D) is never in the model's catalog: it removes the skill from
215
- // the snapshot instead, and appendCatalog drops its pinned entry with it (no longer live)
216
- const forModel = invocationOf(pkg.manifest).model;
217
- const pinnedBody = writtenBody(pkg);
218
- const toSeq = await this.appendCatalog(t, ctx.conversationId, (base) => ({
219
- ...base,
220
- skills: [
221
- ...base.skills.filter((s) => s.name !== pkg.name),
222
- ...(forModel
223
- ? [
224
- {
225
- id: skillId,
226
- name: pkg.name,
227
- description: pkg.description,
228
- version,
229
- source: prefix,
230
- },
231
- ]
232
- : []),
233
- ],
234
- ...(base.pinned && {
235
- pinned: base.pinned.map((p) => p.id === skillId && pinnedBody !== null
236
- ? { id: skillId, version, name: pkg.name, source: prefix, body: pinnedBody }
237
- : p),
238
- }),
239
- }), `skills_catalog:write:${id}`, ctx.runId);
240
- return { outcome, drop, toSeq };
241
- });
104
+ committed = await this.writeIn(ctx, pkg, id, prefix);
242
105
  }
243
106
  catch (e) {
244
107
  await this.deletePrefix(ctx.orgId, prefix);
245
108
  throw e;
246
109
  }
247
- if (committed.toSeq !== null)
248
- await eventLog.notify(ctx.conversationId, committed.toSeq);
110
+ if (committed.toSeq !== null) {
111
+ await this.eventLog.notify(ctx.conversationId, committed.toSeq);
112
+ }
249
113
  for (const p of committed.drop)
250
114
  await this.deletePrefix(ctx.orgId, p);
251
115
  return committed.outcome;
@@ -257,8 +121,7 @@ export class SkillChangesService {
257
121
  * 拒绝:提交后删除草稿对象。审计 `skill.change_decided`。
258
122
  */
259
123
  async decide(orgId, id, accountId, body, actorTokenId) {
260
- const { db } = this.d;
261
- const head = await db
124
+ const head = await this.db
262
125
  .selectFrom("skill_change_requests")
263
126
  .select("agent_id")
264
127
  .where("id", "=", id)
@@ -266,95 +129,10 @@ export class SkillChangesService {
266
129
  .executeTakeFirst();
267
130
  if (!head)
268
131
  throw notFound();
269
- const done = await db.transaction().execute(async (t) => {
270
- // 加锁顺序与 write 一致:组织行(KEY SHARE)→ agent 行 → 申请行 → 会话行
271
- await keyShareOrg(t, orgId);
272
- const agent = await t
273
- .selectFrom("agents")
274
- .select(["owner_account_id", "deleted_at"])
275
- .where("id", "=", head.agent_id)
276
- .forNoKeyUpdate()
277
- .executeTakeFirst();
278
- if (!agent || agent.deleted_at !== null)
279
- throw notFound();
280
- const req = await t
281
- .selectFrom("skill_change_requests")
282
- .selectAll()
283
- .where("id", "=", id)
284
- .forUpdate()
285
- .executeTakeFirst();
286
- // 首次读与加锁重读之间行被删了(agent / 组织被硬删除)→ 404,不是 500
287
- if (!req)
288
- throw notFound();
289
- if (agent.owner_account_id !== accountId) {
290
- throw new ApiError("skill_change.not_owner", "Only the agent's owner can decide on its skill changes");
291
- }
292
- if (req.status !== "pending") {
293
- throw new ApiError("skill_change.already_decided", "This skill change has already been decided");
294
- }
295
- const p = req.proposed_version;
296
- const approved = body.decision === "approve";
297
- let skillId = req.skill_id;
298
- let version = p.version;
299
- if (approved) {
300
- const existing = await t
301
- .selectFrom("skills")
302
- .select(["id", "current_version"])
303
- .where("org_id", "=", orgId)
304
- .where("scope", "=", "agent")
305
- .where("agent_id", "=", req.agent_id)
306
- .where("name", "=", p.manifest.name)
307
- .where("deleted_at", "is", null)
308
- .forUpdate()
309
- .executeTakeFirst();
310
- skillId = existing?.id ?? p.skillId;
311
- version = (existing?.current_version ?? 0) + 1;
312
- await this.createVersion(t, {
313
- orgId,
314
- agentId: req.agent_id,
315
- skillId,
316
- exists: existing !== undefined,
317
- version,
318
- manifest: p.manifest,
319
- prefix: req.object_prefix,
320
- createdBy: req.requested_by_account,
321
- });
322
- }
323
- const updated = await t
324
- .updateTable("skill_change_requests")
325
- .set({
326
- status: approved ? "approved" : "rejected",
327
- decided_by: accountId,
328
- decided_at: sql `now()`,
329
- ...(approved && { skill_id: skillId }),
330
- })
331
- .where("id", "=", id)
332
- .returningAll()
333
- .executeTakeFirstOrThrow();
334
- await audit(t, {
335
- actorAccountId: accountId,
336
- ...(actorTokenId !== undefined && { actorTokenId }),
337
- orgId,
338
- action: "skill.change_decided",
339
- target: id,
340
- detail: {
341
- decision: approved ? "approved" : "rejected",
342
- agentId: req.agent_id,
343
- skillId,
344
- name: p.manifest.name,
345
- version: approved ? version : p.version,
346
- requestedBy: req.requested_by_account,
347
- conversationId: req.requested_in_conversation,
348
- ...(body.note !== undefined && { note: body.note }),
349
- },
350
- });
351
- // 拒绝:发起对话立即回退到正式版本(或移除),模型在当前位置看到提醒
352
- const revertSeq = approved ? null : await this.revertTrial(t, req);
353
- return { updated, revertSeq };
354
- });
132
+ const done = await this.decideIn(orgId, id, accountId, body, actorTokenId, head.agent_id);
355
133
  const row = done.updated;
356
134
  if (done.revertSeq !== null) {
357
- await this.d.eventLog.notify(row.requested_in_conversation, done.revertSeq);
135
+ await this.eventLog.notify(row.requested_in_conversation, done.revertSeq);
358
136
  }
359
137
  if (row.status === "rejected")
360
138
  await this.deletePrefix(orgId, row.object_prefix);
@@ -369,85 +147,337 @@ export class SkillChangesService {
369
147
  * 各对话下一次运行开始时目录里去掉它;之后同名可再写为新技能。
370
148
  */
371
149
  async deleteAgentSkill(orgId, agentId, skillId, accountId, actorTokenId) {
372
- const cancelled = await this.d.db.transaction().execute(async (t) => {
373
- await keyShareOrg(t, orgId);
374
- const agent = await t
375
- .selectFrom("agents")
376
- .select(["owner_account_id", "deleted_at"])
377
- .where("id", "=", agentId)
378
- .where("org_id", "=", orgId)
379
- .forNoKeyUpdate()
380
- .executeTakeFirst();
381
- const agentNotFound = () => new ApiError("agent.not_found", "Agent not found");
382
- if (!agent || agent.deleted_at !== null)
383
- throw agentNotFound();
384
- if (agent.owner_account_id !== accountId) {
385
- // 与 AgentsService 一致:看不到的 agent → 404,看得到但不是负责人 → 403
386
- const visible = await t
387
- .selectFrom("agents")
388
- .select("id")
389
- .where("id", "=", agentId)
390
- .where(visibleTo(accountId))
391
- .executeTakeFirst();
392
- if (!visible)
393
- throw agentNotFound();
394
- throw new ApiError("forbidden", "Only the agent's owner can delete its skills");
150
+ const cancelled = await this.deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId);
151
+ await this.finishCancel(orgId, cancelled);
152
+ }
153
+ /** The transaction of {@link write}. */
154
+ async writeIn(ctx, pkg, id, prefix) {
155
+ await this.keyShareOrg(ctx.orgId);
156
+ // NO KEY UPDATE, not UPDATE (here, in decide and in deleteAgentSkill): it still serializes
157
+ // the writes and decisions of one agent, but not the foreign key check (FOR KEY SHARE) of a
158
+ // transaction that already holds the conversation row this one locks last, e.g. an event
159
+ // log append updating that row a second time (the title job): FOR UPDATE made that 40P01
160
+ const agent = await this.db
161
+ .selectFrom("agents")
162
+ .select(["visibility", "deleted_at"])
163
+ .where("id", "=", ctx.agentId)
164
+ .where("org_id", "=", ctx.orgId)
165
+ .forNoKeyUpdate()
166
+ .executeTakeFirst();
167
+ if (!agent || agent.deleted_at !== null)
168
+ throw new ToolError(AGENT_GONE_TEXT);
169
+ // Then the conversation row (appendCatalog's lock, still after the agent row like decide),
170
+ // before the change request insert: its foreign key check takes FOR KEY SHARE on that row,
171
+ // and upgrading to FOR UPDATE afterwards deadlocked with another writer doing the same
172
+ await this.db
173
+ .selectFrom("conversations")
174
+ .select("id")
175
+ .where("id", "=", ctx.conversationId)
176
+ .forUpdate()
177
+ .execute();
178
+ const existing = await this.db
179
+ .selectFrom("skills")
180
+ .select(["id", "current_version"])
181
+ .where("org_id", "=", ctx.orgId)
182
+ .where("scope", "=", "agent")
183
+ .where("agent_id", "=", ctx.agentId)
184
+ .where("name", "=", pkg.name)
185
+ .where("deleted_at", "is", null)
186
+ .forUpdate()
187
+ .executeTakeFirst();
188
+ const pend = await this.db
189
+ .selectFrom("skill_change_requests")
190
+ .selectAll()
191
+ .where("agent_id", "=", ctx.agentId)
192
+ .where("status", "=", "pending")
193
+ .where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", pkg.name)
194
+ .forUpdate()
195
+ .executeTakeFirst();
196
+ const drop = [];
197
+ if (pend) {
198
+ if (pend.requested_in_conversation !== ctx.conversationId) {
199
+ throw new ToolError(pendingElsewhereText(pkg.name));
395
200
  }
396
- const r = await t
397
- .updateTable("skills")
398
- .set({ deleted_at: sql `now()`, updated_at: sql `now()` })
399
- .where("id", "=", skillId)
201
+ // 同一对话再写:取代旧申请
202
+ await this.db
203
+ .updateTable("skill_change_requests")
204
+ .set({ status: "cancelled", decided_at: sql `now()` })
205
+ .where("id", "=", pend.id)
206
+ .execute();
207
+ drop.push(pend.object_prefix);
208
+ await audit(this.db.db, {
209
+ actorAccountId: ctx.accountId,
210
+ orgId: ctx.orgId,
211
+ action: "skill.change_decided",
212
+ target: pend.id,
213
+ detail: {
214
+ decision: "cancelled",
215
+ reason: "superseded",
216
+ supersededBy: id,
217
+ agentId: ctx.agentId,
218
+ name: pkg.name,
219
+ },
220
+ });
221
+ }
222
+ if (!existing)
223
+ await this.assertBelowCap(ctx.agentId, pend?.id);
224
+ const version = (existing?.current_version ?? 0) + 1;
225
+ const skillId = existing?.id ?? pend?.proposed_version.skillId ?? randomUUID();
226
+ let outcome;
227
+ if (agent.visibility === "private") {
228
+ await this.createVersion({
229
+ orgId: ctx.orgId,
230
+ agentId: ctx.agentId,
231
+ skillId,
232
+ exists: existing !== undefined,
233
+ version,
234
+ manifest: pkg.manifest,
235
+ prefix,
236
+ createdBy: ctx.accountId,
237
+ });
238
+ await audit(this.db.db, {
239
+ actorAccountId: ctx.accountId,
240
+ orgId: ctx.orgId,
241
+ action: existing ? "skill.version_created" : "skill.created",
242
+ target: skillId,
243
+ detail: {
244
+ name: pkg.name,
245
+ version,
246
+ files: pkg.manifest.files.length,
247
+ agentId: ctx.agentId,
248
+ conversationId: ctx.conversationId,
249
+ via: BUILTIN.SkillWrite,
250
+ },
251
+ });
252
+ outcome = { kind: "version", skillId, version, created: !existing };
253
+ }
254
+ else {
255
+ const proposed = { skillId, version, manifest: pkg.manifest };
256
+ await this.db
257
+ .insertInto("skill_change_requests")
258
+ .values({
259
+ id,
260
+ org_id: ctx.orgId,
261
+ agent_id: ctx.agentId,
262
+ skill_id: existing?.id ?? null,
263
+ proposed_version: JSON.stringify(proposed),
264
+ object_prefix: prefix,
265
+ requested_by_account: ctx.accountId,
266
+ requested_in_conversation: ctx.conversationId,
267
+ decided_by: null,
268
+ })
269
+ .execute();
270
+ await audit(this.db.db, {
271
+ actorAccountId: ctx.accountId,
272
+ orgId: ctx.orgId,
273
+ action: "skill.change_requested",
274
+ target: id,
275
+ detail: {
276
+ agentId: ctx.agentId,
277
+ skillId: existing?.id ?? null,
278
+ name: pkg.name,
279
+ version,
280
+ files: pkg.manifest.files.length,
281
+ conversationId: ctx.conversationId,
282
+ },
283
+ });
284
+ outcome = { kind: "requested", requestId: id, skillId, version };
285
+ }
286
+ // 本对话立即看到新版本:在上一份快照上替换 / 加入这个技能(确定、来自日志;来源 = 本次的对象前缀)
287
+ // A pinned entry of this skill gets the version, source and body just written (phase B)
288
+ // A manual-only version (phase D) is never in the model's catalog: it removes the skill from
289
+ // the snapshot instead, and appendCatalog drops its pinned entry with it (no longer live)
290
+ const forModel = invocationOf(pkg.manifest).model;
291
+ const pinnedBody = writtenBody(pkg);
292
+ const toSeq = await this.appendCatalog(ctx.conversationId, (base) => ({
293
+ ...base,
294
+ skills: [
295
+ ...base.skills.filter((s) => s.name !== pkg.name),
296
+ ...(forModel
297
+ ? [
298
+ {
299
+ id: skillId,
300
+ name: pkg.name,
301
+ description: pkg.description,
302
+ version,
303
+ source: prefix,
304
+ },
305
+ ]
306
+ : []),
307
+ ],
308
+ ...(base.pinned && {
309
+ pinned: base.pinned.map((p) => p.id === skillId && pinnedBody !== null
310
+ ? { id: skillId, version, name: pkg.name, source: prefix, body: pinnedBody }
311
+ : p),
312
+ }),
313
+ }), `skills_catalog:write:${id}`, ctx.runId);
314
+ return { outcome, drop, toSeq };
315
+ }
316
+ /** The transaction of {@link decide}. */
317
+ async decideIn(orgId, id, accountId, body, actorTokenId, agentId) {
318
+ // 加锁顺序与 write 一致:组织行(KEY SHARE)→ agent 行 → 申请行 → 会话行
319
+ await this.keyShareOrg(orgId);
320
+ const agent = await this.db
321
+ .selectFrom("agents")
322
+ .select(["owner_account_id", "deleted_at"])
323
+ .where("id", "=", agentId)
324
+ .forNoKeyUpdate()
325
+ .executeTakeFirst();
326
+ if (!agent || agent.deleted_at !== null)
327
+ throw notFound();
328
+ const req = await this.db
329
+ .selectFrom("skill_change_requests")
330
+ .selectAll()
331
+ .where("id", "=", id)
332
+ .forUpdate()
333
+ .executeTakeFirst();
334
+ // 首次读与加锁重读之间行被删了(agent / 组织被硬删除)→ 404,不是 500
335
+ if (!req)
336
+ throw notFound();
337
+ if (agent.owner_account_id !== accountId) {
338
+ throw new ApiError("skill_change.not_owner", "Only the agent's owner can decide on its skill changes");
339
+ }
340
+ if (req.status !== "pending") {
341
+ throw new ApiError("skill_change.already_decided", "This skill change has already been decided");
342
+ }
343
+ const p = req.proposed_version;
344
+ const approved = body.decision === "approve";
345
+ let skillId = req.skill_id;
346
+ let version = p.version;
347
+ if (approved) {
348
+ const existing = await this.db
349
+ .selectFrom("skills")
350
+ .select(["id", "current_version"])
400
351
  .where("org_id", "=", orgId)
401
352
  .where("scope", "=", "agent")
402
- .where("agent_id", "=", agentId)
353
+ .where("agent_id", "=", req.agent_id)
354
+ .where("name", "=", p.manifest.name)
403
355
  .where("deleted_at", "is", null)
404
- .returning(["name"])
405
- .executeTakeFirst();
406
- if (!r)
407
- throw new ApiError("skill.not_found", "Skill not found");
408
- const out = { prefixes: [], seqs: [] };
409
- const pend = await t
410
- .selectFrom("skill_change_requests")
411
- .selectAll()
412
- .where("agent_id", "=", agentId)
413
- .where("status", "=", "pending")
414
- .where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", r.name)
415
356
  .forUpdate()
416
357
  .executeTakeFirst();
417
- if (pend) {
418
- await t
419
- .updateTable("skill_change_requests")
420
- .set({ status: "cancelled", decided_at: sql `now()` })
421
- .where("id", "=", pend.id)
422
- .execute();
423
- await audit(t, {
424
- actorAccountId: accountId,
425
- ...(actorTokenId !== undefined && { actorTokenId }),
426
- orgId,
427
- action: "skill.change_decided",
428
- target: pend.id,
429
- detail: { decision: "cancelled", reason: "skill_deleted", agentId, name: r.name },
430
- });
431
- const seq = await this.revertTrial(t, pend);
432
- if (seq !== null)
433
- out.seqs.push([pend.requested_in_conversation, seq]);
434
- out.prefixes.push(pend.object_prefix);
435
- }
436
- await audit(t, {
358
+ skillId = existing?.id ?? p.skillId;
359
+ version = (existing?.current_version ?? 0) + 1;
360
+ await this.createVersion({
361
+ orgId,
362
+ agentId: req.agent_id,
363
+ skillId,
364
+ exists: existing !== undefined,
365
+ version,
366
+ manifest: p.manifest,
367
+ prefix: req.object_prefix,
368
+ createdBy: req.requested_by_account,
369
+ });
370
+ }
371
+ const updated = await this.db
372
+ .updateTable("skill_change_requests")
373
+ .set({
374
+ status: approved ? "approved" : "rejected",
375
+ decided_by: accountId,
376
+ decided_at: sql `now()`,
377
+ ...(approved && { skill_id: skillId }),
378
+ })
379
+ .where("id", "=", id)
380
+ .returningAll()
381
+ .executeTakeFirstOrThrow();
382
+ await audit(this.db.db, {
383
+ actorAccountId: accountId,
384
+ ...(actorTokenId !== undefined && { actorTokenId }),
385
+ orgId,
386
+ action: "skill.change_decided",
387
+ target: id,
388
+ detail: {
389
+ decision: approved ? "approved" : "rejected",
390
+ agentId: req.agent_id,
391
+ skillId,
392
+ name: p.manifest.name,
393
+ version: approved ? version : p.version,
394
+ requestedBy: req.requested_by_account,
395
+ conversationId: req.requested_in_conversation,
396
+ ...(body.note !== undefined && { note: body.note }),
397
+ },
398
+ });
399
+ // 拒绝:发起对话立即回退到正式版本(或移除),模型在当前位置看到提醒
400
+ const revertSeq = approved ? null : await this.revertTrial(req);
401
+ return { updated, revertSeq };
402
+ }
403
+ /** The transaction of {@link deleteAgentSkill}. */
404
+ async deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId) {
405
+ await this.keyShareOrg(orgId);
406
+ const agent = await this.db
407
+ .selectFrom("agents")
408
+ .select(["owner_account_id", "deleted_at"])
409
+ .where("id", "=", agentId)
410
+ .where("org_id", "=", orgId)
411
+ .forNoKeyUpdate()
412
+ .executeTakeFirst();
413
+ const agentNotFound = () => new ApiError("agent.not_found", "Agent not found");
414
+ if (!agent || agent.deleted_at !== null)
415
+ throw agentNotFound();
416
+ if (agent.owner_account_id !== accountId) {
417
+ // 与 AgentsService 一致:看不到的 agent → 404,看得到但不是负责人 → 403
418
+ const visible = await this.db
419
+ .selectFrom("agents")
420
+ .select("id")
421
+ .where("id", "=", agentId)
422
+ .where(visibleTo(accountId))
423
+ .executeTakeFirst();
424
+ if (!visible)
425
+ throw agentNotFound();
426
+ throw new ApiError("forbidden", "Only the agent's owner can delete its skills");
427
+ }
428
+ const r = await this.db
429
+ .updateTable("skills")
430
+ .set({ deleted_at: sql `now()`, updated_at: sql `now()` })
431
+ .where("id", "=", skillId)
432
+ .where("org_id", "=", orgId)
433
+ .where("scope", "=", "agent")
434
+ .where("agent_id", "=", agentId)
435
+ .where("deleted_at", "is", null)
436
+ .returning(["name"])
437
+ .executeTakeFirst();
438
+ if (!r)
439
+ throw new ApiError("skill.not_found", "Skill not found");
440
+ const out = { prefixes: [], seqs: [] };
441
+ const pend = await this.db
442
+ .selectFrom("skill_change_requests")
443
+ .selectAll()
444
+ .where("agent_id", "=", agentId)
445
+ .where("status", "=", "pending")
446
+ .where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", r.name)
447
+ .forUpdate()
448
+ .executeTakeFirst();
449
+ if (pend) {
450
+ await this.db
451
+ .updateTable("skill_change_requests")
452
+ .set({ status: "cancelled", decided_at: sql `now()` })
453
+ .where("id", "=", pend.id)
454
+ .execute();
455
+ await audit(this.db.db, {
437
456
  actorAccountId: accountId,
438
457
  ...(actorTokenId !== undefined && { actorTokenId }),
439
458
  orgId,
440
- action: "skill.deleted",
441
- target: skillId,
442
- detail: { name: r.name, agentId },
459
+ action: "skill.change_decided",
460
+ target: pend.id,
461
+ detail: { decision: "cancelled", reason: "skill_deleted", agentId, name: r.name },
443
462
  });
444
- return out;
463
+ const seq = await this.revertTrial(pend);
464
+ if (seq !== null)
465
+ out.seqs.push([pend.requested_in_conversation, seq]);
466
+ out.prefixes.push(pend.object_prefix);
467
+ }
468
+ await audit(this.db.db, {
469
+ actorAccountId: accountId,
470
+ ...(actorTokenId !== undefined && { actorTokenId }),
471
+ orgId,
472
+ action: "skill.deleted",
473
+ target: skillId,
474
+ detail: { name: r.name, agentId },
445
475
  });
446
- await this.finishCancel(orgId, cancelled);
476
+ return out;
447
477
  }
448
478
  /** 当前用户(作为 agent 负责人)能决定的待处理申请,新的在前,最多 {@link SKILL_CHANGES_LIST_MAX} 条。 */
449
479
  async listPending(orgId, accountId) {
450
- const rows = await this.d.db
480
+ const rows = await this.db
451
481
  .selectFrom("skill_change_requests")
452
482
  .innerJoin("agents", "agents.id", "skill_change_requests.agent_id")
453
483
  .selectAll("skill_change_requests")
@@ -465,7 +495,7 @@ export class SkillChangesService {
465
495
  * 草稿对象已删除(拒绝 / 取消)时文件内容为 null。
466
496
  */
467
497
  async get(orgId, id, accountId) {
468
- const row = await this.d.db
498
+ const row = await this.db
469
499
  .selectFrom("skill_change_requests")
470
500
  .innerJoin("agents", "agents.id", "skill_change_requests.agent_id")
471
501
  .selectAll("skill_change_requests")
@@ -483,13 +513,13 @@ export class SkillChangesService {
483
513
  if (!view)
484
514
  throw notFound();
485
515
  const live = row.status === "pending" || row.status === "approved";
486
- const store = this.d.storage.kernel(orgId);
516
+ const store = this.storage.kernel(orgId);
487
517
  const budget = { left: DETAIL_MAX_BYTES };
488
518
  const files = await readTexts(live ? store : undefined, row.object_prefix, row.proposed_version.manifest.files, budget);
489
519
  // 改动已有技能:附上当前生效版本的文件(批准后它就是上一版,差异仍按申请时的当前版本显示)
490
520
  let current = null;
491
521
  if (row.skill_id !== null) {
492
- const cur = await this.d.db
522
+ const cur = await this.db
493
523
  .selectFrom("skills")
494
524
  .innerJoin("skill_versions", (j) => j
495
525
  .onRef("skill_versions.skill_id", "=", "skills.id")
@@ -520,14 +550,14 @@ export class SkillChangesService {
520
550
  * skills), and the pinned bodies still fit the size limit. The tool map is only recomputed at run
521
551
  * start.
522
552
  */
523
- async appendCatalog(t, conversationId, derive, idemKey, runId) {
524
- const base = (await lockLatestCatalog(t, conversationId)) ?? { skills: [] };
553
+ async appendCatalog(conversationId, derive, idemKey, runId) {
554
+ const base = (await lockLatestCatalog(this.db.db, conversationId)) ?? { skills: [] };
525
555
  const derived = derive(base);
526
556
  if (derived === null)
527
557
  return null;
528
558
  const skills = [...derived.skills].sort(byName);
529
559
  const live = (p) => skills.some((s) => s.id === p.id && s.version === p.version && s.source === p.source);
530
- const pinned = fitPinned((derived.pinned ?? []).filter(live), this.d.log, {
560
+ const pinned = fitPinned((derived.pinned ?? []).filter(live), this.log, {
531
561
  conversationId,
532
562
  });
533
563
  const next = {
@@ -537,14 +567,14 @@ export class SkillChangesService {
537
567
  };
538
568
  if (sameSnapshot(base, next))
539
569
  return null;
540
- const written = await this.d.eventLog.append(conversationId, [
570
+ const written = await this.eventLog.appendIn(conversationId, [
541
571
  {
542
572
  type: "skills_catalog",
543
573
  ...(runId !== undefined && { runId }),
544
574
  idemKey,
545
575
  payload: next,
546
576
  },
547
- ], t);
577
+ ]);
548
578
  return Math.max(...written.map((e) => e.seq));
549
579
  }
550
580
  /**
@@ -553,9 +583,9 @@ export class SkillChangesService {
553
583
  * 快照里已没有这份草稿 → 不写。对话正在运行时,提醒落在当前位置(构建时排在工具结果之后),下一步即生效。
554
584
  * 移除时不推测同名的组织技能(快照里已被替换掉),下一次运行开始的解析会把它补回来。
555
585
  */
556
- async revertTrial(t, req) {
586
+ async revertTrial(req) {
557
587
  const name = req.proposed_version.manifest.name;
558
- const real = await t
588
+ const real = await this.db
559
589
  .selectFrom("skills")
560
590
  .innerJoin("skill_versions", (j) => j
561
591
  .onRef("skill_versions.skill_id", "=", "skills.id")
@@ -572,7 +602,7 @@ export class SkillChangesService {
572
602
  .where("skills.name", "=", name)
573
603
  .where("skills.deleted_at", "is", null)
574
604
  .executeTakeFirst();
575
- return this.appendCatalog(t, req.requested_in_conversation, (base) => {
605
+ return this.appendCatalog(req.requested_in_conversation, (base) => {
576
606
  if (!base.skills.some((s) => s.source === req.object_prefix))
577
607
  return null;
578
608
  const rest = base.skills.filter((s) => s.source !== req.object_prefix);
@@ -599,11 +629,13 @@ export class SkillChangesService {
599
629
  }, `skills_catalog:revert:${req.id}`);
600
630
  }
601
631
  /**
602
- * 在事务 `t` 里取消该 agent 全部待处理的技能改动(agent 被删除时由 `AgentsService.softDelete` 调用):
603
- * 置 cancelled、审计、给各发起对话追加回退快照。提交后调用 {@link finishCancel} 删除草稿并发布事件。
632
+ * In the caller's transaction (`mandatory`: `AgentsService.softDelete` holds the org and agent
633
+ * row locks), cancels every pending skill change of the agent: marks them cancelled, audits, and
634
+ * appends a reverting snapshot to each requesting conversation. After the commit the caller runs
635
+ * {@link finishCancel} to delete the drafts and publish the events.
604
636
  */
605
- async cancelPendingForAgent(t, orgId, agentId, actorAccountId, reason, actorTokenId) {
606
- const rows = await t
637
+ async cancelPendingForAgent(orgId, agentId, actorAccountId, reason, actorTokenId) {
638
+ const rows = await this.db
607
639
  .selectFrom("skill_change_requests")
608
640
  .selectAll()
609
641
  .where("org_id", "=", orgId)
@@ -614,12 +646,12 @@ export class SkillChangesService {
614
646
  .execute();
615
647
  const out = { prefixes: [], seqs: [] };
616
648
  for (const r of rows) {
617
- await t
649
+ await this.db
618
650
  .updateTable("skill_change_requests")
619
651
  .set({ status: "cancelled", decided_at: sql `now()` })
620
652
  .where("id", "=", r.id)
621
653
  .execute();
622
- await audit(t, {
654
+ await audit(this.db.db, {
623
655
  actorAccountId,
624
656
  ...(actorTokenId !== undefined && { actorTokenId }),
625
657
  orgId,
@@ -627,7 +659,7 @@ export class SkillChangesService {
627
659
  target: r.id,
628
660
  detail: { decision: "cancelled", reason, agentId, name: r.proposed_version.manifest.name },
629
661
  });
630
- const seq = await this.revertTrial(t, r);
662
+ const seq = await this.revertTrial(r);
631
663
  if (seq !== null)
632
664
  out.seqs.push([r.requested_in_conversation, seq]);
633
665
  out.prefixes.push(r.object_prefix);
@@ -637,20 +669,20 @@ export class SkillChangesService {
637
669
  /** {@link cancelPendingForAgent} 提交之后:发布事件、尽力删除草稿对象。 */
638
670
  async finishCancel(orgId, c) {
639
671
  for (const [conv, seq] of c.seqs)
640
- await this.d.eventLog.notify(conv, seq);
672
+ await this.eventLog.notify(conv, seq);
641
673
  for (const p of c.prefixes)
642
674
  await this.deletePrefix(orgId, p);
643
675
  }
644
676
  /** 新技能的数量上限(含待批准的新技能;`excluding` 是将被取代的申请)。 */
645
- async assertBelowCap(t, agentId, excluding) {
646
- const skills = await t
677
+ async assertBelowCap(agentId, excluding) {
678
+ const skills = await this.db
647
679
  .selectFrom("skills")
648
680
  .select((eb) => eb.fn.countAll().as("n"))
649
681
  .where("scope", "=", "agent")
650
682
  .where("agent_id", "=", agentId)
651
683
  .where("deleted_at", "is", null)
652
684
  .executeTakeFirstOrThrow();
653
- let q = t
685
+ let q = this.db
654
686
  .selectFrom("skill_change_requests")
655
687
  .select((eb) => eb.fn.countAll().as("n"))
656
688
  .where("agent_id", "=", agentId)
@@ -663,9 +695,9 @@ export class SkillChangesService {
663
695
  throw new ToolError(capText());
664
696
  }
665
697
  /** 写一个版本并让 `current_version` 指向它(技能不存在则新建)。 */
666
- async createVersion(t, v) {
698
+ async createVersion(v) {
667
699
  if (v.exists) {
668
- await t
700
+ await this.db
669
701
  .updateTable("skills")
670
702
  .set({
671
703
  current_version: v.version,
@@ -676,7 +708,7 @@ export class SkillChangesService {
676
708
  .execute();
677
709
  }
678
710
  else {
679
- await t
711
+ await this.db
680
712
  .insertInto("skills")
681
713
  .values({
682
714
  id: v.skillId,
@@ -690,7 +722,7 @@ export class SkillChangesService {
690
722
  })
691
723
  .execute();
692
724
  }
693
- await t
725
+ await this.db
694
726
  .insertInto("skill_versions")
695
727
  .values({
696
728
  skill_id: v.skillId,
@@ -701,13 +733,25 @@ export class SkillChangesService {
701
733
  })
702
734
  .execute();
703
735
  }
736
+ /**
737
+ * 先给组织行加 KEY SHARE 锁,再锁 agent 行:与 `AgentsService`(组织行 FOR UPDATE → agent 行)同一顺序。
738
+ * 不先锁的话,本事务持有 agent 行后插入引用组织的行(外键取 KEY SHARE)会与之互相等待(40P01)。
739
+ */
740
+ async keyShareOrg(orgId) {
741
+ await this.db
742
+ .selectFrom("orgs")
743
+ .select("id")
744
+ .where("id", "=", orgId)
745
+ .forKeyShare()
746
+ .executeTakeFirst();
747
+ }
704
748
  /** 尽力删除草稿对象(失败只记日志:孤儿对象随组织数据清理删除)。 */
705
749
  async deletePrefix(orgId, prefix) {
706
750
  try {
707
- await this.d.storage.kernel(orgId).deletePrefix(prefix);
751
+ await this.storage.kernel(orgId).deletePrefix(prefix);
708
752
  }
709
753
  catch (err) {
710
- this.d.log.warn("skill draft cleanup failed", { orgId, prefix, err });
754
+ this.log.warn("skill draft cleanup failed", { orgId, prefix, err });
711
755
  }
712
756
  }
713
757
  /** 补齐 agent 名。 */
@@ -715,7 +759,7 @@ export class SkillChangesService {
715
759
  if (rows.length === 0)
716
760
  return [];
717
761
  const agentIds = [...new Set(rows.map((r) => r.agent_id))];
718
- const agents = await this.d.db
762
+ const agents = await this.db
719
763
  .selectFrom("agents")
720
764
  .innerJoin("agent_versions", (j) => j
721
765
  .onRef("agent_versions.agent_id", "=", "agents.id")
@@ -723,7 +767,7 @@ export class SkillChangesService {
723
767
  .select(["agents.id", "agent_versions.definition"])
724
768
  .where("agents.id", "in", agentIds)
725
769
  .execute();
726
- const requesters = await this.d.db
770
+ const requesters = await this.db
727
771
  .selectFrom("accounts")
728
772
  .select(["id", "display_name"])
729
773
  .where("id", "in", [...new Set(rows.map((r) => r.requested_by_account))])
@@ -752,14 +796,28 @@ export class SkillChangesService {
752
796
  createdAt: iso(r.created_at),
753
797
  }));
754
798
  }
755
- }
756
- /**
757
- * 先给组织行加 KEY SHARE 锁,再锁 agent 行:与 `AgentsService`(组织行 FOR UPDATE → agent 行)同一顺序。
758
- * 不先锁的话,本事务持有 agent 行后插入引用组织的行(外键取 KEY SHARE)会与之互相等待(40P01)。
759
- */
760
- async function keyShareOrg(t, orgId) {
761
- await t.selectFrom("orgs").select("id").where("id", "=", orgId).forKeyShare().executeTakeFirst();
762
- }
799
+ };
800
+ __decorate([
801
+ Transactional()
802
+ ], SkillChangesService.prototype, "writeIn", null);
803
+ __decorate([
804
+ Transactional()
805
+ ], SkillChangesService.prototype, "decideIn", null);
806
+ __decorate([
807
+ Transactional()
808
+ ], SkillChangesService.prototype, "deleteAgentSkillIn", null);
809
+ __decorate([
810
+ Transactional({ propagation: "mandatory" })
811
+ ], SkillChangesService.prototype, "cancelPendingForAgent", null);
812
+ SkillChangesService = __decorate([
813
+ Injectable(),
814
+ __param(0, Inject(KernelDb)),
815
+ __param(1, Inject(StorageService)),
816
+ __param(2, Inject(EventLog)),
817
+ __param(3, Inject(KERNEL_LOGGER)),
818
+ __param(4, Inject(TransactionHost))
819
+ ], SkillChangesService);
820
+ export { SkillChangesService };
763
821
  /**
764
822
  * 按清单顺序读文件文本,共用读取额度 `budget`(超出、对象缺失、存储出错时该文件内容为 null)。
765
823
  * `store` 为 undefined 表示不读(如草稿已删除)。