@capybara-hq/kernel 0.1.0-rc.0 → 0.1.0-rc.2

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 (626) hide show
  1. package/bootstrap.json +10 -6
  2. package/dist/admin/admin.controller.d.ts +17 -17
  3. package/dist/admin/admin.controller.js +43 -26
  4. package/dist/admin/admin.module.d.ts +3 -0
  5. package/dist/admin/admin.module.js +22 -0
  6. package/dist/admin/extensions.controller.d.ts +14 -14
  7. package/dist/admin/extensions.controller.js +30 -17
  8. package/dist/admin/setup-lock.d.ts +16 -0
  9. package/dist/admin/setup-lock.js +47 -0
  10. package/dist/admin/setup.controller.d.ts +8 -8
  11. package/dist/admin/setup.controller.js +27 -25
  12. package/dist/admin/setup.service.d.ts +19 -27
  13. package/dist/admin/setup.service.js +61 -61
  14. package/dist/agents/agent-lookup.d.ts +53 -0
  15. package/dist/agents/agent-lookup.js +179 -0
  16. package/dist/agents/agents.controller.d.ts +1 -1
  17. package/dist/agents/agents.controller.js +14 -8
  18. package/dist/agents/agents.module.d.ts +7 -0
  19. package/dist/agents/agents.module.js +41 -0
  20. package/dist/agents/agents.service.d.ts +39 -58
  21. package/dist/agents/agents.service.js +261 -329
  22. package/dist/agents/definition.d.ts +8 -0
  23. package/dist/agents/definition.js +8 -0
  24. package/dist/agents/models.controller.d.ts +1 -1
  25. package/dist/agents/models.controller.js +2 -2
  26. package/dist/agents/templates.controller.d.ts +1 -1
  27. package/dist/agents/templates.controller.js +2 -2
  28. package/dist/agents/templates.d.ts +6 -8
  29. package/dist/agents/templates.js +20 -4
  30. package/dist/app.d.ts +93 -0
  31. package/dist/app.js +150 -0
  32. package/dist/catalog/admin-catalog.controller.d.ts +3 -3
  33. package/dist/catalog/admin-catalog.controller.js +27 -13
  34. package/dist/catalog/catalog-content.d.ts +185 -0
  35. package/dist/catalog/catalog-content.js +323 -0
  36. package/dist/catalog/catalog-items.d.ts +186 -0
  37. package/dist/catalog/catalog-items.js +410 -0
  38. package/dist/catalog/catalog.module.d.ts +14 -0
  39. package/dist/catalog/catalog.module.js +71 -0
  40. package/dist/catalog/catalog.service.d.ts +34 -188
  41. package/dist/catalog/catalog.service.js +155 -489
  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 +30 -13
  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 +2 -2
  70. package/dist/channels/channels.module.d.ts +40 -0
  71. package/dist/channels/channels.module.js +128 -0
  72. package/dist/channels/connections.controller.d.ts +1 -1
  73. package/dist/channels/connections.controller.js +11 -6
  74. package/dist/channels/connections.service.d.ts +43 -21
  75. package/dist/channels/connections.service.js +236 -131
  76. package/dist/channels/inbound.d.ts +34 -38
  77. package/dist/channels/inbound.js +107 -41
  78. package/dist/channels/job-ids.d.ts +10 -0
  79. package/dist/channels/job-ids.js +10 -0
  80. package/dist/channels/jobs.d.ts +85 -0
  81. package/dist/channels/jobs.js +157 -0
  82. package/dist/channels/outbound.d.ts +60 -82
  83. package/dist/channels/outbound.js +165 -193
  84. package/dist/channels/supervisor.d.ts +88 -46
  85. package/dist/channels/supervisor.js +230 -132
  86. package/dist/channels/threads.d.ts +29 -8
  87. package/dist/channels/threads.js +71 -13
  88. package/dist/channels/webhook.d.ts +20 -14
  89. package/dist/channels/webhook.js +51 -20
  90. package/dist/config/load.d.ts +3 -2
  91. package/dist/config/load.js +3 -2
  92. package/dist/config/nacos-source.js +11 -2
  93. package/dist/config/schema.d.ts +16 -1
  94. package/dist/config/schema.js +54 -7
  95. package/dist/conversations/access.d.ts +29 -0
  96. package/dist/conversations/access.js +86 -0
  97. package/dist/conversations/artifacts.d.ts +10 -10
  98. package/dist/conversations/artifacts.js +35 -9
  99. package/dist/conversations/attachments.controller.d.ts +1 -1
  100. package/dist/conversations/attachments.controller.js +8 -6
  101. package/dist/conversations/attachments.module.d.ts +7 -0
  102. package/dist/conversations/attachments.module.js +25 -0
  103. package/dist/conversations/attachments.service.d.ts +30 -22
  104. package/dist/conversations/attachments.service.js +119 -46
  105. package/dist/conversations/conversations.controller.d.ts +8 -7
  106. package/dist/conversations/conversations.controller.js +59 -29
  107. package/dist/conversations/conversations.module.d.ts +8 -0
  108. package/dist/conversations/conversations.module.js +69 -0
  109. package/dist/conversations/conversations.service.d.ts +40 -38
  110. package/dist/conversations/conversations.service.js +130 -140
  111. package/dist/conversations/event-log.d.ts +28 -18
  112. package/dist/conversations/event-log.js +74 -27
  113. package/dist/conversations/files.d.ts +10 -10
  114. package/dist/conversations/files.js +37 -11
  115. package/dist/conversations/idem-keys.d.ts +5 -0
  116. package/dist/conversations/idem-keys.js +5 -0
  117. package/dist/conversations/job-ids.d.ts +6 -0
  118. package/dist/conversations/job-ids.js +6 -0
  119. package/dist/conversations/outputs-read.d.ts +11 -11
  120. package/dist/conversations/outputs-read.js +31 -7
  121. package/dist/conversations/queue.d.ts +48 -56
  122. package/dist/conversations/queue.js +13 -289
  123. package/dist/conversations/queue.service.d.ts +60 -0
  124. package/dist/conversations/queue.service.js +343 -0
  125. package/dist/conversations/sandbox-status.d.ts +13 -10
  126. package/dist/conversations/sandbox-status.js +36 -8
  127. package/dist/conversations/titles.d.ts +71 -24
  128. package/dist/conversations/titles.js +159 -62
  129. package/dist/ctx/bus.js +9 -3
  130. package/dist/ctx/create-ctx.d.ts +6 -0
  131. package/dist/ctx/create-ctx.js +7 -9
  132. package/dist/ctx/lock.d.ts +7 -3
  133. package/dist/ctx/lock.js +9 -20
  134. package/dist/ctx/queue.js +3 -2
  135. package/dist/ctx/secrets.d.ts +10 -2
  136. package/dist/ctx/secrets.js +7 -3
  137. package/dist/db/kernel-schema.d.ts +2 -2
  138. package/dist/db/pool.d.ts +5 -0
  139. package/dist/db/pool.js +1 -0
  140. package/dist/errors.d.ts +2 -0
  141. package/dist/errors.js +2 -0
  142. package/dist/evals/budget.d.ts +42 -21
  143. package/dist/evals/budget.js +114 -62
  144. package/dist/evals/evals.module.d.ts +31 -0
  145. package/dist/evals/evals.module.js +114 -0
  146. package/dist/evals/jobs.d.ts +20 -0
  147. package/dist/evals/jobs.js +45 -0
  148. package/dist/evals/run-replay.d.ts +56 -8
  149. package/dist/evals/run-replay.js +140 -80
  150. package/dist/evals/runs.controller.d.ts +1 -1
  151. package/dist/evals/runs.controller.js +17 -8
  152. package/dist/evals/runs.service.d.ts +23 -45
  153. package/dist/evals/runs.service.js +245 -234
  154. package/dist/evals/sets.controller.d.ts +1 -1
  155. package/dist/evals/sets.controller.js +17 -8
  156. package/dist/evals/sets.service.d.ts +22 -6
  157. package/dist/evals/sets.service.js +248 -194
  158. package/dist/evals/snapshot.d.ts +2 -2
  159. package/dist/evals/step-replay.d.ts +2 -2
  160. package/dist/evals/step-replay.js +1 -1
  161. package/dist/evals/trajectory.controller.d.ts +1 -1
  162. package/dist/evals/trajectory.controller.js +11 -7
  163. package/dist/evals/trajectory.service.d.ts +5 -4
  164. package/dist/evals/trajectory.service.js +30 -7
  165. package/dist/evals/worker.d.ts +44 -27
  166. package/dist/evals/worker.js +220 -120
  167. package/dist/extensions/admin-ops.d.ts +61 -33
  168. package/dist/extensions/admin-ops.js +248 -154
  169. package/dist/extensions/admin-view.d.ts +38 -27
  170. package/dist/extensions/admin-view.js +126 -55
  171. package/dist/extensions/approvals.d.ts +12 -8
  172. package/dist/extensions/approvals.js +73 -46
  173. package/dist/extensions/blobs.d.ts +27 -10
  174. package/dist/extensions/blobs.js +111 -45
  175. package/dist/extensions/bootstrap.d.ts +96 -42
  176. package/dist/extensions/bootstrap.js +303 -155
  177. package/dist/extensions/cli.d.ts +20 -10
  178. package/dist/extensions/cli.js +41 -96
  179. package/dist/extensions/config-issues.d.ts +7 -0
  180. package/dist/extensions/config-issues.js +31 -0
  181. package/dist/extensions/deployment-config-store.d.ts +49 -0
  182. package/dist/extensions/deployment-config-store.js +133 -0
  183. package/dist/extensions/deployment-config.d.ts +58 -67
  184. package/dist/extensions/deployment-config.js +202 -230
  185. package/dist/extensions/enabled.d.ts +5 -5
  186. package/dist/extensions/extensions.module.d.ts +8 -0
  187. package/dist/extensions/extensions.module.js +77 -0
  188. package/dist/extensions/hooks.d.ts +3 -2
  189. package/dist/extensions/hooks.js +1 -1
  190. package/dist/extensions/host.d.ts +72 -68
  191. package/dist/extensions/host.js +191 -152
  192. package/dist/extensions/installs.d.ts +49 -16
  193. package/dist/extensions/installs.js +128 -32
  194. package/dist/extensions/job-ids.d.ts +6 -0
  195. package/dist/extensions/job-ids.js +6 -0
  196. package/dist/extensions/lifecycle-topics.d.ts +18 -0
  197. package/dist/extensions/lifecycle-topics.js +18 -0
  198. package/dist/extensions/lifecycle.d.ts +35 -47
  199. package/dist/extensions/lifecycle.js +103 -39
  200. package/dist/extensions/locks.d.ts +33 -0
  201. package/dist/extensions/locks.js +86 -0
  202. package/dist/extensions/migrate-lock.d.ts +3 -4
  203. package/dist/extensions/org-config.controller.d.ts +1 -1
  204. package/dist/extensions/org-config.controller.js +8 -5
  205. package/dist/extensions/org-config.d.ts +48 -46
  206. package/dist/extensions/org-config.js +284 -226
  207. package/dist/extensions/registry.d.ts +50 -2
  208. package/dist/extensions/registry.js +89 -4
  209. package/dist/extensions/sources.d.ts +12 -8
  210. package/dist/extensions/sources.js +34 -13
  211. package/dist/files/files.module.d.ts +3 -0
  212. package/dist/files/files.module.js +22 -0
  213. package/dist/files/previewers.controller.d.ts +7 -2
  214. package/dist/files/previewers.controller.js +17 -9
  215. package/dist/files/previewers.d.ts +13 -18
  216. package/dist/files/previewers.js +83 -36
  217. package/dist/http/adapter.d.ts +3 -0
  218. package/dist/http/adapter.js +25 -0
  219. package/dist/http/api.module.d.ts +3 -110
  220. package/dist/http/api.module.js +47 -355
  221. package/dist/http/app.d.ts +11 -15
  222. package/dist/http/app.js +52 -47
  223. package/dist/http/error-filter.module.d.ts +5 -0
  224. package/dist/http/error-filter.module.js +18 -0
  225. package/dist/http/error.filter.js +2 -2
  226. package/dist/identity/accounts.d.ts +82 -29
  227. package/dist/identity/accounts.js +294 -175
  228. package/dist/identity/api-tokens.d.ts +11 -7
  229. package/dist/identity/api-tokens.js +71 -44
  230. package/dist/identity/audit.d.ts +7 -4
  231. package/dist/identity/audit.js +5 -1
  232. package/dist/identity/auth.controller.d.ts +11 -10
  233. package/dist/identity/auth.controller.js +31 -25
  234. package/dist/identity/auth.guard.d.ts +3 -3
  235. package/dist/identity/auth.guard.js +6 -4
  236. package/dist/identity/binding.d.ts +9 -11
  237. package/dist/identity/binding.js +41 -13
  238. package/dist/identity/enterprise-admin.d.ts +18 -12
  239. package/dist/identity/enterprise-admin.js +67 -13
  240. package/dist/identity/external-identity-lock.d.ts +17 -0
  241. package/dist/identity/external-identity-lock.js +39 -0
  242. package/dist/identity/external.d.ts +19 -15
  243. package/dist/identity/external.js +163 -125
  244. package/dist/identity/identity.module.d.ts +6 -0
  245. package/dist/identity/identity.module.js +56 -0
  246. package/dist/identity/me.controller.d.ts +16 -15
  247. package/dist/identity/me.controller.js +37 -31
  248. package/dist/identity/sessions.d.ts +12 -10
  249. package/dist/identity/sessions.js +74 -42
  250. package/dist/identity/settings.d.ts +20 -14
  251. package/dist/identity/settings.js +85 -57
  252. package/dist/identity/sso.controller.d.ts +7 -7
  253. package/dist/identity/sso.controller.js +13 -9
  254. package/dist/identity/sso.d.ts +9 -12
  255. package/dist/identity/sso.js +54 -24
  256. package/dist/inbox/inbox.module.d.ts +3 -0
  257. package/dist/inbox/inbox.module.js +22 -0
  258. package/dist/inbox/inbox.service.d.ts +7 -9
  259. package/dist/inbox/inbox.service.js +32 -11
  260. package/dist/index.d.ts +19 -12
  261. package/dist/index.js +13 -8
  262. package/dist/infra/cache/cache.module.d.ts +3 -0
  263. package/dist/infra/cache/cache.module.js +16 -0
  264. package/dist/infra/cache/cache.service.d.ts +21 -0
  265. package/dist/infra/cache/cache.service.js +80 -0
  266. package/dist/infra/cache/cacheable.decorator.d.ts +32 -0
  267. package/dist/infra/cache/cacheable.decorator.js +83 -0
  268. package/dist/infra/cli/kernel-cli.module.d.ts +66 -0
  269. package/dist/infra/cli/kernel-cli.module.js +165 -0
  270. package/dist/infra/close-within.d.ts +15 -0
  271. package/dist/infra/close-within.js +36 -0
  272. package/dist/infra/config/config.module.d.ts +13 -0
  273. package/dist/infra/config/config.module.js +39 -0
  274. package/dist/infra/config/kernel-config.service.d.ts +25 -0
  275. package/dist/infra/config/kernel-config.service.js +126 -0
  276. package/dist/infra/database/after-commit.d.ts +6 -0
  277. package/dist/infra/database/after-commit.js +9 -0
  278. package/dist/infra/database/database.module.d.ts +25 -0
  279. package/dist/infra/database/database.module.js +90 -0
  280. package/dist/infra/database/kernel-db.d.ts +22 -0
  281. package/dist/infra/database/kernel-db.js +65 -0
  282. package/dist/infra/database/transaction-host.d.ts +50 -0
  283. package/dist/infra/database/transaction-host.js +125 -0
  284. package/dist/infra/database/transactional.decorator.d.ts +15 -0
  285. package/dist/infra/database/transactional.decorator.js +27 -0
  286. package/dist/infra/database/xact-lock.d.ts +17 -0
  287. package/dist/infra/database/xact-lock.js +43 -0
  288. package/dist/infra/events/kernel-events.d.ts +96 -0
  289. package/dist/infra/events/kernel-events.js +65 -0
  290. package/dist/infra/health/health.controller.d.ts +26 -0
  291. package/dist/infra/health/health.controller.js +104 -0
  292. package/dist/infra/health/health.module.d.ts +9 -0
  293. package/dist/infra/health/health.module.js +24 -0
  294. package/dist/infra/health/health.options.d.ts +10 -0
  295. package/dist/infra/health/health.options.js +15 -0
  296. package/dist/infra/health/shutdown-state.d.ts +6 -0
  297. package/dist/infra/health/shutdown-state.js +2 -0
  298. package/dist/infra/lifecycle/graceful-shutdown.module.d.ts +6 -0
  299. package/dist/infra/lifecycle/graceful-shutdown.module.js +23 -0
  300. package/dist/infra/lifecycle/graceful-shutdown.service.d.ts +70 -0
  301. package/dist/infra/lifecycle/graceful-shutdown.service.js +135 -0
  302. package/dist/infra/lifecycle/process-guards.d.ts +52 -0
  303. package/dist/infra/lifecycle/process-guards.js +86 -0
  304. package/dist/infra/lifecycle/shutdown-signals.d.ts +30 -0
  305. package/dist/infra/lifecycle/shutdown-signals.js +48 -0
  306. package/dist/infra/lock/key-template.d.ts +13 -0
  307. package/dist/infra/lock/key-template.js +46 -0
  308. package/dist/infra/lock/lock.module.d.ts +3 -0
  309. package/dist/infra/lock/lock.module.js +16 -0
  310. package/dist/infra/lock/lock.service.d.ts +120 -0
  311. package/dist/infra/lock/lock.service.js +343 -0
  312. package/dist/infra/lock/shared-lease.d.ts +44 -0
  313. package/dist/infra/lock/shared-lease.js +121 -0
  314. package/dist/infra/lock/with-lock.decorator.d.ts +28 -0
  315. package/dist/infra/lock/with-lock.decorator.js +49 -0
  316. package/dist/infra/logging/logging.module.d.ts +16 -0
  317. package/dist/infra/logging/logging.module.js +34 -0
  318. package/dist/infra/queue/configured-processor.d.ts +18 -0
  319. package/dist/infra/queue/configured-processor.js +23 -0
  320. package/dist/infra/queue/job-failure.d.ts +18 -0
  321. package/dist/infra/queue/job-failure.js +26 -0
  322. package/dist/infra/queue/queue-shutdown.d.ts +27 -0
  323. package/dist/infra/queue/queue-shutdown.js +81 -0
  324. package/dist/infra/queue/queue.module.d.ts +16 -0
  325. package/dist/infra/queue/queue.module.js +61 -0
  326. package/dist/infra/queue/redis-connection.d.ts +7 -0
  327. package/dist/infra/queue/redis-connection.js +18 -0
  328. package/dist/infra/queue/retired-schedulers.d.ts +7 -0
  329. package/dist/infra/queue/retired-schedulers.js +9 -0
  330. package/dist/infra/queue/run-job.d.ts +16 -0
  331. package/dist/infra/queue/run-job.js +19 -0
  332. package/dist/infra/redis/redis.module.d.ts +24 -0
  333. package/dist/infra/redis/redis.module.js +87 -0
  334. package/dist/infra/schedule/cron-tick.d.ts +12 -0
  335. package/dist/infra/schedule/cron-tick.js +25 -0
  336. package/dist/infra/schedule/locked-cron.decorator.d.ts +27 -0
  337. package/dist/infra/schedule/locked-cron.decorator.js +53 -0
  338. package/dist/infra/schedule/locked-interval.d.ts +69 -0
  339. package/dist/infra/schedule/locked-interval.js +190 -0
  340. package/dist/infra/schedule/locked-tick.d.ts +90 -0
  341. package/dist/infra/schedule/locked-tick.js +137 -0
  342. package/dist/infra/schedule/schedule.module.d.ts +8 -0
  343. package/dist/infra/schedule/schedule.module.js +27 -0
  344. package/dist/infra/schedule/scheduled-runs.d.ts +69 -0
  345. package/dist/infra/schedule/scheduled-runs.js +163 -0
  346. package/dist/infra/swagger/swagger.d.ts +16 -0
  347. package/dist/infra/swagger/swagger.js +31 -0
  348. package/dist/infra/throttler/credential-throttler.d.ts +35 -0
  349. package/dist/infra/throttler/credential-throttler.js +77 -0
  350. package/dist/infra/throttler/named-throttlers.d.ts +31 -0
  351. package/dist/infra/throttler/named-throttlers.js +119 -0
  352. package/dist/infra/throttler/redis-throttler-storage.d.ts +38 -0
  353. package/dist/infra/throttler/redis-throttler-storage.js +130 -0
  354. package/dist/infra/throttler/throttler.guard.d.ts +23 -0
  355. package/dist/infra/throttler/throttler.guard.js +68 -0
  356. package/dist/infra/throttler/throttler.module.d.ts +15 -0
  357. package/dist/infra/throttler/throttler.module.js +53 -0
  358. package/dist/infra/tokens.d.ts +15 -0
  359. package/dist/infra/tokens.js +15 -0
  360. package/dist/infra/validation/create-zod-dto.d.ts +23 -0
  361. package/dist/infra/validation/create-zod-dto.js +35 -0
  362. package/dist/infra/validation/parse-with-zod.d.ts +7 -0
  363. package/dist/infra/validation/parse-with-zod.js +12 -0
  364. package/dist/infra/validation/validation.module.d.ts +3 -0
  365. package/dist/infra/validation/validation.module.js +16 -0
  366. package/dist/infra/validation/zod-params.d.ts +7 -0
  367. package/dist/infra/validation/zod-params.js +42 -0
  368. package/dist/infra/validation/zod-validation.pipe.d.ts +11 -0
  369. package/dist/infra/validation/zod-validation.pipe.js +31 -0
  370. package/dist/kernel.d.ts +9 -241
  371. package/dist/kernel.js +8 -1305
  372. package/dist/kernel.module.d.ts +17 -0
  373. package/dist/kernel.module.js +136 -0
  374. package/dist/lifecycle/kernel-lifecycle.d.ts +140 -0
  375. package/dist/lifecycle/kernel-lifecycle.js +451 -0
  376. package/dist/lifecycle/tokens.d.ts +3 -0
  377. package/dist/lifecycle/tokens.js +3 -0
  378. package/dist/log-config.d.ts +9 -0
  379. package/dist/log-config.js +27 -0
  380. package/dist/log-context.d.ts +34 -0
  381. package/dist/log-context.js +44 -0
  382. package/dist/log-loki.d.ts +34 -0
  383. package/dist/log-loki.js +145 -0
  384. package/dist/log.d.ts +41 -10
  385. package/dist/log.js +91 -17
  386. package/dist/models/models.module.d.ts +3 -0
  387. package/dist/models/models.module.js +24 -0
  388. package/dist/models/prices.d.ts +8 -2
  389. package/dist/models/prices.js +65 -37
  390. package/dist/models/purposes.controller.d.ts +1 -1
  391. package/dist/models/purposes.controller.js +5 -6
  392. package/dist/models/purposes.d.ts +35 -13
  393. package/dist/models/purposes.js +101 -51
  394. package/dist/net/public-address.js +3 -2
  395. package/dist/orgs/directory-sync.controller.d.ts +1 -1
  396. package/dist/orgs/directory-sync.controller.js +2 -2
  397. package/dist/orgs/directory-sync.d.ts +61 -31
  398. package/dist/orgs/directory-sync.js +212 -125
  399. package/dist/orgs/invitations.controller.d.ts +8 -8
  400. package/dist/orgs/invitations.controller.js +27 -26
  401. package/dist/orgs/invitations.service.d.ts +12 -9
  402. package/dist/orgs/invitations.service.js +130 -92
  403. package/dist/orgs/job-ids.d.ts +8 -0
  404. package/dist/orgs/job-ids.js +8 -0
  405. package/dist/orgs/members.service.d.ts +19 -12
  406. package/dist/orgs/members.service.js +161 -117
  407. package/dist/orgs/offboarding.d.ts +54 -57
  408. package/dist/orgs/offboarding.js +161 -71
  409. package/dist/orgs/org-lock.d.ts +28 -19
  410. package/dist/orgs/org-lock.js +81 -35
  411. package/dist/orgs/org.guard.d.ts +1 -1
  412. package/dist/orgs/org.guard.js +2 -2
  413. package/dist/orgs/orgs.controller.d.ts +13 -13
  414. package/dist/orgs/orgs.controller.js +29 -17
  415. package/dist/orgs/orgs.module.d.ts +6 -0
  416. package/dist/orgs/orgs.module.js +68 -0
  417. package/dist/orgs/orgs.service.d.ts +30 -19
  418. package/dist/orgs/orgs.service.js +139 -86
  419. package/dist/orgs/settings.controller.d.ts +1 -1
  420. package/dist/orgs/settings.controller.js +8 -6
  421. package/dist/orgs/settings.service.d.ts +14 -8
  422. package/dist/orgs/settings.service.js +75 -46
  423. package/dist/overrides.d.ts +56 -0
  424. package/dist/overrides.js +30 -0
  425. package/dist/roles/gateway-role.d.ts +43 -0
  426. package/dist/roles/gateway-role.js +98 -0
  427. package/dist/roles/gateway.module.d.ts +8 -0
  428. package/dist/roles/gateway.module.js +28 -0
  429. package/dist/roles/worker-role.d.ts +63 -0
  430. package/dist/roles/worker-role.js +144 -0
  431. package/dist/roles/worker.module.d.ts +14 -0
  432. package/dist/roles/worker.module.js +90 -0
  433. package/dist/runtime/abort.js +19 -2
  434. package/dist/runtime/checkpointer.d.ts +8 -3
  435. package/dist/runtime/checkpointer.js +87 -55
  436. package/dist/runtime/conversation-lock.d.ts +20 -11
  437. package/dist/runtime/conversation-lock.js +62 -72
  438. package/dist/runtime/hook-calls.d.ts +3 -3
  439. package/dist/runtime/hook-calls.js +1 -6
  440. package/dist/runtime/job-ids.d.ts +10 -0
  441. package/dist/runtime/job-ids.js +10 -0
  442. package/dist/runtime/langgraph-loop.js +1 -1
  443. package/dist/runtime/loop.d.ts +7 -0
  444. package/dist/runtime/loop.js +14 -0
  445. package/dist/runtime/maintenance-queue.d.ts +10 -0
  446. package/dist/runtime/maintenance-queue.js +10 -0
  447. package/dist/runtime/maintenance.d.ts +45 -74
  448. package/dist/runtime/maintenance.js +139 -136
  449. package/dist/runtime/model-call.d.ts +7 -4
  450. package/dist/runtime/model-call.js +24 -57
  451. package/dist/runtime/providers.d.ts +17 -6
  452. package/dist/runtime/providers.js +66 -25
  453. package/dist/runtime/quota.d.ts +17 -3
  454. package/dist/runtime/quota.js +27 -2
  455. package/dist/runtime/retired-schedulers.d.ts +7 -0
  456. package/dist/runtime/retired-schedulers.js +31 -0
  457. package/dist/runtime/run-control.d.ts +33 -0
  458. package/dist/runtime/run-control.js +77 -0
  459. package/dist/runtime/run-finish.d.ts +26 -17
  460. package/dist/runtime/run-finish.js +98 -51
  461. package/dist/runtime/run-jobs.d.ts +48 -0
  462. package/dist/runtime/run-jobs.js +95 -0
  463. package/dist/runtime/run-processors.d.ts +60 -0
  464. package/dist/runtime/run-processors.js +185 -0
  465. package/dist/runtime/run-queue.d.ts +32 -57
  466. package/dist/runtime/run-queue.js +291 -295
  467. package/dist/runtime/run-steps.d.ts +39 -0
  468. package/dist/runtime/run-steps.js +96 -0
  469. package/dist/runtime/run-worker.d.ts +121 -75
  470. package/dist/runtime/run-worker.js +340 -225
  471. package/dist/runtime/runtime.module.d.ts +10 -0
  472. package/dist/runtime/runtime.module.js +112 -0
  473. package/dist/runtime/step-log.d.ts +40 -0
  474. package/dist/runtime/step-log.js +94 -0
  475. package/dist/runtime/stream.controller.d.ts +5 -8
  476. package/dist/runtime/stream.controller.js +14 -12
  477. package/dist/runtime/stream.d.ts +24 -6
  478. package/dist/runtime/stream.js +78 -7
  479. package/dist/runtime/subagents/child.d.ts +3 -44
  480. package/dist/runtime/subagents/child.js +0 -79
  481. package/dist/runtime/subagents/definition.d.ts +4 -4
  482. package/dist/runtime/subagents/definition.js +2 -2
  483. package/dist/runtime/subagents/dispatch.d.ts +87 -6
  484. package/dist/runtime/subagents/dispatch.js +135 -140
  485. package/dist/runtime/subagents/limits.d.ts +9 -4
  486. package/dist/runtime/subagents/limits.js +4 -2
  487. package/dist/runtime/subagents/org-agents.d.ts +4 -4
  488. package/dist/runtime/subagents/org-agents.js +1 -1
  489. package/dist/runtime/subagents/progress.d.ts +2 -2
  490. package/dist/runtime/subagents/roster.d.ts +3 -3
  491. package/dist/runtime/subagents/roster.js +1 -1
  492. package/dist/runtime/subagents/skill-fork.d.ts +6 -7
  493. package/dist/runtime/subagents/skill-fork.js +16 -5
  494. package/dist/runtime/subagents/subagents.service.d.ts +40 -0
  495. package/dist/runtime/subagents/subagents.service.js +101 -0
  496. package/dist/runtime/usage-report.d.ts +94 -52
  497. package/dist/runtime/usage-report.js +200 -99
  498. package/dist/runtime/waits.d.ts +125 -57
  499. package/dist/runtime/waits.js +431 -208
  500. package/dist/sandbox/job-ids.d.ts +10 -0
  501. package/dist/sandbox/job-ids.js +10 -0
  502. package/dist/sandbox/jobs.d.ts +41 -0
  503. package/dist/sandbox/jobs.js +113 -0
  504. package/dist/sandbox/leases.d.ts +39 -31
  505. package/dist/sandbox/leases.js +117 -257
  506. package/dist/sandbox/providers.d.ts +19 -0
  507. package/dist/sandbox/providers.js +38 -0
  508. package/dist/sandbox/sandbox.module.d.ts +8 -0
  509. package/dist/sandbox/sandbox.module.js +30 -0
  510. package/dist/sandbox/sandbox.service.d.ts +24 -29
  511. package/dist/sandbox/sandbox.service.js +106 -75
  512. package/dist/skills/catalog.d.ts +33 -20
  513. package/dist/skills/catalog.js +96 -53
  514. package/dist/skills/changes.controller.d.ts +4 -4
  515. package/dist/skills/changes.controller.js +15 -9
  516. package/dist/skills/changes.service.d.ts +28 -18
  517. package/dist/skills/changes.service.js +421 -364
  518. package/dist/skills/invocable.controller.d.ts +1 -1
  519. package/dist/skills/invocable.controller.js +8 -5
  520. package/dist/skills/invoke.d.ts +16 -15
  521. package/dist/skills/invoke.js +48 -17
  522. package/dist/skills/skills.controller.d.ts +1 -1
  523. package/dist/skills/skills.controller.js +11 -6
  524. package/dist/skills/skills.module.d.ts +6 -0
  525. package/dist/skills/skills.module.js +30 -0
  526. package/dist/skills/skills.service.d.ts +47 -30
  527. package/dist/skills/skills.service.js +221 -158
  528. package/dist/storage/job-ids.d.ts +6 -0
  529. package/dist/storage/job-ids.js +6 -0
  530. package/dist/storage/purge.d.ts +22 -7
  531. package/dist/storage/purge.js +55 -3
  532. package/dist/storage/storage.module.d.ts +6 -0
  533. package/dist/storage/storage.module.js +23 -0
  534. package/dist/storage/storage.service.d.ts +18 -4
  535. package/dist/storage/storage.service.js +44 -3
  536. package/dist/tools/approvals.controller.d.ts +1 -1
  537. package/dist/tools/approvals.controller.js +12 -8
  538. package/dist/tools/approvals.service.d.ts +27 -25
  539. package/dist/tools/approvals.service.js +324 -258
  540. package/dist/tools/breaker.d.ts +2 -2
  541. package/dist/tools/breaker.js +21 -3
  542. package/dist/tools/builtins/ask-user.d.ts +2 -2
  543. package/dist/tools/builtins/ask-user.js +1 -1
  544. package/dist/tools/builtins/builtin-tools.d.ts +21 -0
  545. package/dist/tools/builtins/builtin-tools.js +80 -0
  546. package/dist/tools/builtins/read-tool-output.d.ts +2 -2
  547. package/dist/tools/builtins/read-tool-output.js +1 -1
  548. package/dist/tools/builtins/sandbox/bash.js +2 -2
  549. package/dist/tools/builtins/sandbox/common.d.ts +7 -4
  550. package/dist/tools/builtins/sandbox/common.js +5 -3
  551. package/dist/tools/builtins/sandbox/deliver.js +2 -2
  552. package/dist/tools/builtins/sandbox/edit.js +1 -1
  553. package/dist/tools/builtins/sandbox/glob.js +2 -2
  554. package/dist/tools/builtins/sandbox/grep.js +2 -2
  555. package/dist/tools/builtins/sandbox/read.js +1 -1
  556. package/dist/tools/builtins/sandbox/write.js +1 -1
  557. package/dist/tools/builtins/skill-load.d.ts +3 -3
  558. package/dist/tools/builtins/skill-load.js +1 -1
  559. package/dist/tools/canonical-json.d.ts +6 -0
  560. package/dist/tools/canonical-json.js +16 -0
  561. package/dist/tools/connector-content.controller.d.ts +1 -1
  562. package/dist/tools/connector-content.controller.js +11 -6
  563. package/dist/tools/connector-content.d.ts +12 -15
  564. package/dist/tools/connector-content.js +53 -18
  565. package/dist/tools/connectors.controller.d.ts +1 -1
  566. package/dist/tools/connectors.controller.js +21 -10
  567. package/dist/tools/connectors.service.d.ts +31 -13
  568. package/dist/tools/connectors.service.js +434 -344
  569. package/dist/tools/credentials.d.ts +17 -20
  570. package/dist/tools/credentials.js +55 -34
  571. package/dist/tools/drift.d.ts +29 -41
  572. package/dist/tools/drift.js +111 -79
  573. package/dist/tools/info.d.ts +12 -9
  574. package/dist/tools/info.js +33 -7
  575. package/dist/tools/job-ids.d.ts +13 -0
  576. package/dist/tools/job-ids.js +15 -0
  577. package/dist/tools/jobs.d.ts +24 -0
  578. package/dist/tools/jobs.js +69 -0
  579. package/dist/tools/oauth/flow-paths.d.ts +16 -0
  580. package/dist/tools/oauth/flow-paths.js +38 -0
  581. package/dist/tools/oauth/flow.d.ts +30 -30
  582. package/dist/tools/oauth/flow.js +109 -81
  583. package/dist/tools/oauth/oauth.controller.d.ts +3 -3
  584. package/dist/tools/oauth/oauth.controller.js +12 -9
  585. package/dist/tools/oauth/tokens.d.ts +11 -3
  586. package/dist/tools/oauth/tokens.js +15 -14
  587. package/dist/tools/outputs.d.ts +13 -4
  588. package/dist/tools/outputs.js +47 -3
  589. package/dist/tools/pipeline.d.ts +62 -46
  590. package/dist/tools/pipeline.js +145 -64
  591. package/dist/tools/policy.d.ts +2 -2
  592. package/dist/tools/questions.controller.d.ts +1 -1
  593. package/dist/tools/questions.controller.js +8 -5
  594. package/dist/tools/questions.service.d.ts +25 -24
  595. package/dist/tools/questions.service.js +201 -142
  596. package/dist/tools/registry.d.ts +30 -20
  597. package/dist/tools/registry.js +73 -37
  598. package/dist/tools/specs.d.ts +5 -4
  599. package/dist/tools/specs.js +3 -1
  600. package/dist/tools/tools.module.d.ts +10 -0
  601. package/dist/tools/tools.module.js +91 -0
  602. package/dist/ui/call-extension.d.ts +16 -0
  603. package/dist/ui/call-extension.js +38 -0
  604. package/dist/ui/embed-token.d.ts +9 -5
  605. package/dist/ui/embed-token.js +34 -6
  606. package/dist/ui/ui-stream.d.ts +22 -17
  607. package/dist/ui/ui-stream.js +72 -12
  608. package/dist/ui/ui.module.d.ts +7 -0
  609. package/dist/ui/ui.module.js +28 -0
  610. package/dist/ui/views.controller.d.ts +14 -12
  611. package/dist/ui/views.controller.js +32 -25
  612. package/dist/ui/views.d.ts +9 -57
  613. package/dist/ui/views.js +43 -45
  614. package/package.json +11 -2
  615. package/dist/http/health.controller.d.ts +0 -26
  616. package/dist/http/health.controller.js +0 -79
  617. package/dist/http/tokens.d.ts +0 -131
  618. package/dist/http/tokens.js +0 -131
  619. package/dist/http/zod.pipe.d.ts +0 -8
  620. package/dist/http/zod.pipe.js +0 -14
  621. package/dist/identity/rate-limit.d.ts +0 -55
  622. package/dist/identity/rate-limit.js +0 -121
  623. package/dist/sandbox/lifecycle.d.ts +0 -21
  624. package/dist/sandbox/lifecycle.js +0 -68
  625. /package/dist/http/{gateway.module.d.ts → gateway-routes.d.ts} +0 -0
  626. /package/dist/http/{gateway.module.js → gateway-routes.js} +0 -0
@@ -1,24 +1,49 @@
1
- import { hostname } from "node:os";
2
- import { DelayedError, Worker } from "bullmq";
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
+ };
10
+ import { Inject, Injectable, Optional } from "@nestjs/common";
11
+ import { DelayedError } from "bullmq";
3
12
  import { sql } from "kysely";
4
13
  import { normalizeStoredDefinition } from "../agents/definition.js";
14
+ import { conversationTopic, EventLog, } from "../conversations/event-log.js";
5
15
  import { effectiveDefinition, NO_SELECTION, readSelection, sameModel, sameSelection, } from "../conversations/selection.js";
16
+ import { TitleQueue } from "../conversations/titles.js";
6
17
  import { ApiError } from "../errors.js";
7
- import { pinnedFailureText, recordSkillsCatalog } from "../skills/catalog.js";
18
+ import { SettingsService } from "../identity/settings.js";
19
+ import { waitWithin } from "../infra/close-within.js";
20
+ import { KernelConfigService } from "../infra/config/kernel-config.service.js";
21
+ import { KernelDb } from "../infra/database/kernel-db.js";
22
+ import { TransactionHost } from "../infra/database/transaction-host.js";
23
+ import { Transactional } from "../infra/database/transactional.decorator.js";
24
+ import { KernelEvents } from "../infra/events/kernel-events.js";
25
+ import { KERNEL_BUS, KERNEL_LOGGER } from "../infra/tokens.js";
26
+ import { pinnedFailureText, SkillsCatalogService } from "../skills/catalog.js";
27
+ import { ToolPipeline } from "../tools/pipeline.js";
28
+ import { RunAbort } from "./abort.js";
29
+ import { KyselyCheckpointSaver } from "./checkpointer.js";
30
+ import { ConversationLock } from "./conversation-lock.js";
8
31
  import { RunError } from "./model-call.js";
9
- import { ProviderListError } from "./providers.js";
10
- import { ORG_QUOTA_LEASE_MS, orgRunLimit } from "./quota.js";
11
- import { finishRun, TERMINAL_STATUSES } from "./run-finish.js";
12
- import { bullConnection, RUN_QUEUE_NAME, SUBAGENT_RUN_QUEUE_NAME, } from "./run-queue.js";
32
+ import { ProviderListError, ProviderRegistry } from "./providers.js";
33
+ import { ORG_QUOTA_LEASE_MS, orgRunLimit, RUN_QUOTA } from "./quota.js";
34
+ import { RunFinish, TERMINAL_STATUSES } from "./run-finish.js";
35
+ import { RunQueue } from "./run-queue.js";
36
+ import { AgentLoops, RunSteps } from "./run-steps.js";
13
37
  import { dispatchOfChildRun } from "./subagents/child.js";
14
38
  import { childRunDefinition } from "./subagents/definition.js";
15
39
  import { forkBoundary } from "./subagents/skill-fork.js";
40
+ import { Waits } from "./waits.js";
16
41
  /** 会话锁被占用时任务延后的时间。 */
17
42
  const LOCK_BUSY_DELAY_MS = 1000;
18
43
  /** 组织配额已满时任务延后的时间。 */
19
44
  const QUOTA_FULL_DELAY_MS = 2000;
20
45
  /** BullMQ stalled 检测允许的最大次数(超过则任务失败)。 */
21
- const MAX_STALLED_COUNT = 3;
46
+ export const MAX_STALLED_COUNT = 3;
22
47
  /** 停机时等待任务结束后处理(ensureRun 等)的最短时间。 */
23
48
  const FOLLOW_UP_MIN_WAIT_MS = 250;
24
49
  /** 读插话的分页大小。 */
@@ -28,88 +53,179 @@ const READ_PAGE = 500;
28
53
  * 后续处理,由 close() 跟踪并限时;全部失败也不会让会话永远卡住——打开 SSE / 读事件时会再次 ensureRun。
29
54
  */
30
55
  const ENSURE_RETRY_DELAYS_MS = [200, 1000, 3000];
31
- const noopSink = () => { };
56
+ /** Optional provider: the run worker's {@link RunHooks} (tests). */
57
+ export const RUN_HOOKS = Symbol("RUN_HOOKS");
32
58
  /** 任务回到队列:延后 delayMs 再处理(不计入 attempts)。 */
33
59
  async function requeue(job, token, delayMs) {
34
60
  await job.moveToDelayed(Date.now() + delayMs, token);
35
61
  throw new DelayedError();
36
62
  }
37
63
  /**
38
- * 运行 worker(只在含 `worker` 角色的进程启动):领取 `cap-kernel-runs` 的任务,取会话锁与组织配额,
39
- * 调用 AgentLoop,按结果写终态事件并推进 `consumed_seq`;结束后再调用一次 `ensureRun` 处理
40
- * 运行期间到达但没被吸收的消息(Review Focus 2)。
64
+ * 运行 worker(只在含 `worker` 角色的进程消费):领取 `cap-kernel-runs` 与 `cap-kernel-subagent-runs` 的任务
65
+ * (两个 `@Processor`,见 run-processors.ts),取会话锁与组织配额,调用 AgentLoop,按结果写终态事件并推进
66
+ * `consumed_seq`;结束后再调用一次 `ensureRun` 处理运行期间到达但没被吸收的消息(Review Focus 2)。
41
67
  */
42
- export class RunWorker {
43
- d;
44
- /** One BullMQ worker per run queue: conversation runs and sub-agent runs (spec §7.4). */
68
+ let RunWorker = class RunWorker {
69
+ kdb;
70
+ eventLog;
71
+ lock;
72
+ quota;
73
+ abort;
74
+ queue;
75
+ settings;
76
+ config;
77
+ log;
78
+ bus;
79
+ checkpoints;
80
+ waits;
81
+ events;
82
+ titles;
83
+ models;
84
+ skillsCatalog;
85
+ pipeline;
86
+ finisher;
87
+ txHost;
88
+ hooks;
89
+ /** The two run queues' BullMQ workers (spec §7.4), once {@link start}ed on the worker role. */
45
90
  workers = [];
46
- /** 传给 Worker 的连接:BullMQ 不关闭调用方传入的连接,close() 时自己关。 */
47
- conn;
48
91
  active = new Map();
49
92
  /** 进行中的「任务结束后」处理(完成后的 ensureRun、失败标记):停机时等它们做完再关闭队列。 */
50
93
  followUps = new Set();
51
94
  closing = false;
52
95
  /** close() 开始时触发:ensureRun 重试不再等待退避间隔。 */
53
96
  closingSignal = new AbortController();
54
- constructor(d) {
55
- this.d = d;
97
+ loop;
98
+ constructor(kdb, eventLog, lock, quota, abort, queue, settings, loops, steps, config, log, bus,
99
+ /** 运行到达终态后删除该运行(thread_id = runId)的 checkpoint thread(只用于续跑,结束后无用)。 */
100
+ checkpoints,
101
+ /** loop 返回 `suspended` 后把运行置为 waiting(释放会话锁与配额之后); the child lifecycle. */
102
+ waits,
103
+ /** `run.started` (the channel outbound enqueues the conversation's IM delivery). */
104
+ events,
105
+ /** A completed run enqueues the conversation's title job. */
106
+ titles,
107
+ /** Resolves a switched-to model at run start (fallback when it is gone; UI refresh B). */
108
+ models,
109
+ /** Run start's skills catalog snapshot (reads the pinned skills' bodies, phase B). */
110
+ skillsCatalog,
111
+ /**
112
+ * In the terminal transaction of every run: writes its open `agent` call results
113
+ * (`stopOpenAgentCalls`; a no-op without dispatches); `fire` runs their observe hooks after the
114
+ * commit (sub-agents spec §12, review m1: a failed or stalled parent too).
115
+ */
116
+ pipeline, finisher, txHost, hooks) {
117
+ this.kdb = kdb;
118
+ this.eventLog = eventLog;
119
+ this.lock = lock;
120
+ this.quota = quota;
121
+ this.abort = abort;
122
+ this.queue = queue;
123
+ this.settings = settings;
124
+ this.config = config;
125
+ this.log = log;
126
+ this.bus = bus;
127
+ this.checkpoints = checkpoints;
128
+ this.waits = waits;
129
+ this.events = events;
130
+ this.titles = titles;
131
+ this.models = models;
132
+ this.skillsCatalog = skillsCatalog;
133
+ this.pipeline = pipeline;
134
+ this.finisher = finisher;
135
+ this.txHost = txHost;
136
+ this.hooks = hooks;
137
+ this.loop = loops.create(steps.deps);
138
+ }
139
+ get db() {
140
+ return this.kdb.db;
56
141
  }
57
- start() {
58
- if (this.workers.length > 0)
142
+ /**
143
+ * Starts consuming (worker role only): `workers` are the `@Processor` workers of both run queues
144
+ * (built with `runtime.workerConcurrency`, `jobLockMs`, `stalledIntervalMs`; never autorun).
145
+ */
146
+ start(workers) {
147
+ if (this.workers.length > 0 || this.closing)
59
148
  return;
60
- const runtime = this.d.config().runtime;
61
- this.conn = bullConnection(this.d.redisUrl, this.d.log);
62
- for (const queue of [RUN_QUEUE_NAME, SUBAGENT_RUN_QUEUE_NAME]) {
63
- const worker = new Worker(queue, (job, token) => this.process(job, token), {
64
- // the worker name is recorded on the job (BullMQ processedBy): which replica ran it
65
- name: `${hostname()}-${process.pid}`,
66
- connection: this.conn,
67
- concurrency: runtime.workerConcurrency,
68
- lockDuration: runtime.jobLockMs,
69
- stalledInterval: runtime.stalledIntervalMs,
70
- maxStalledCount: MAX_STALLED_COUNT,
71
- });
72
- // ensureRun after a run goes after its job completed and left the queue: when the latest
73
- // unconsumed message is this run's own trigger (e.g. a run ended by its deadline without
74
- // absorbing it, R34), the new job has this job's id and would be dropped as a duplicate
75
- // while this one is still active. Relies on BullMQ moving the job to completed (deleted by
76
- // removeOnComplete) before emitting "completed" (pinned by the R34 test).
77
- worker.on("completed", (job, result) => {
78
- if (result !== "ensure")
79
- return;
80
- const { conversationId, runId } = job.data;
81
- this.track(this.ensureAfterRun(conversationId, runId));
82
- });
83
- worker.on("error", (err) => this.d.log.error("run worker error", { err, queue }));
84
- worker.on("failed", (job, err) => {
85
- this.d.log.error("run job failed", { jobId: job?.id, runId: job?.data.runId, err });
86
- if (job) {
87
- this.track(this.onJobFailed(job.data, err).catch((e) => this.d.log.error("cannot mark failed run job", { runId: job.data.runId, err: e })));
88
- }
89
- });
90
- this.workers.push(worker);
149
+ this.workers = workers;
150
+ for (const w of workers) {
151
+ void w.run().catch((err) => this.onError(err, w.name));
91
152
  }
92
153
  }
93
- /** Stops the active children of a finished run (see {@link RunWorkerDeps.stopChildren}). */
94
- async stopChildren(runId) {
95
- if (!this.d.stopChildren)
154
+ /** A worker's `error` event. */
155
+ onError(err, queue) {
156
+ this.log.error("run worker error", { err, queue });
157
+ }
158
+ /**
159
+ * A job completed (the worker's `completed` event). ensureRun after a run goes after its job
160
+ * completed and left the queue: when the latest unconsumed message is this run's own trigger
161
+ * (e.g. a run ended by its deadline without absorbing it, R34), the new job has this job's id
162
+ * and would be dropped as a duplicate while this one is still active. Relies on BullMQ moving
163
+ * the job to completed (deleted by removeOnComplete) before emitting "completed" (pinned by the
164
+ * R34 test).
165
+ */
166
+ onCompleted(job, result) {
167
+ if (result !== "ensure")
96
168
  return;
169
+ const { conversationId, runId } = job.data;
170
+ this.track(this.ensureAfterRun(conversationId, runId));
171
+ }
172
+ /** A job failed (the worker's `failed` event). */
173
+ onFailed(job, err) {
174
+ this.log.error("run job failed", { jobId: job?.id, runId: job?.data.runId, err });
175
+ if (job) {
176
+ this.track(this.onJobFailed(job.data, err).catch((e) => this.log.error("cannot mark failed run job", { runId: job.data.runId, err: e })));
177
+ }
178
+ }
179
+ /**
180
+ * 流式增量发布到会话频道(与 `{ kind: "events" }` 共用 `conv.<id>`),任意副本上的订阅方都能收到。
181
+ * 发布失败只记日志:增量只是草稿,最终内容以日志中的 assistant_message 为准。
182
+ */
183
+ sinkFor(conversationId) {
184
+ // 本次运行执行中推出的文本字符数(按步,step_reset 清零):本进程正在执行的这次运行自己的计数
185
+ let at = { runId: "", step: -1, chars: 0 };
186
+ return (d) => {
187
+ if (at.runId !== d.runId || at.step !== d.step || d.kind === "step_reset") {
188
+ at = { runId: d.runId, step: d.step, chars: 0 };
189
+ }
190
+ const offset = at.chars;
191
+ if (d.kind === "text")
192
+ at.chars += d.text?.length ?? 0;
193
+ const msg = {
194
+ kind: "delta",
195
+ runId: d.runId,
196
+ step: d.step,
197
+ delta: d.kind,
198
+ ...(d.text !== undefined && { text: d.text }),
199
+ ...(d.kind === "text" && { offset }),
200
+ };
201
+ this.bus
202
+ .publish(conversationTopic(conversationId), msg)
203
+ .catch((err) => this.log.warn("stream delta publish failed", { conversationId, err }));
204
+ };
205
+ }
206
+ /**
207
+ * After any terminal commit of a run that is not a sub-agent's (sub-agents spec §12): stops its
208
+ * active children on its behalf (no account). The wait sweep is the backstop.
209
+ */
210
+ async stopChildren(runId) {
97
211
  try {
98
- await this.d.stopChildren(runId);
212
+ await this.waits.stopChildren(runId, null);
99
213
  }
100
214
  catch (err) {
101
- this.d.log.error("cannot stop the sub-agents of a finished run", { runId, err });
215
+ this.log.error("cannot stop the sub-agents of a finished run", { runId, err });
102
216
  }
103
217
  }
104
- /** Reports a finished sub-agent run to its parent (see {@link RunWorkerDeps.onChildFinished}). */
218
+ /**
219
+ * After a sub-agent run's terminal state committed (sub-agents spec §7.3): reports it to the
220
+ * parent. Called with any run id whose conversation may be a child; runs that were not
221
+ * dispatched are ignored. Errors are logged (the wait sweep repairs a missed call).
222
+ */
105
223
  async childFinished(runId) {
106
- if (!this.d.onChildFinished)
107
- return;
108
224
  try {
109
- await this.d.onChildFinished(runId);
225
+ await this.waits.childFinished(runId);
110
226
  }
111
227
  catch (err) {
112
- this.d.log.error("cannot report finished sub-agent run to its parent", { runId, err });
228
+ this.log.error("cannot report finished sub-agent run to its parent", { runId, err });
113
229
  }
114
230
  }
115
231
  /**
@@ -119,14 +235,14 @@ export class RunWorker {
119
235
  async ensureAfterRun(conversationId, runId) {
120
236
  for (let attempt = 0;; attempt++) {
121
237
  try {
122
- await this.d.hooks?.beforeEnsureRun?.(conversationId, attempt);
123
- await this.d.queue.ensureRun(conversationId);
238
+ await this.hooks?.beforeEnsureRun?.(conversationId, attempt);
239
+ await this.queue.ensureRun(conversationId);
124
240
  return;
125
241
  }
126
242
  catch (err) {
127
243
  const delay = ENSURE_RETRY_DELAYS_MS[attempt];
128
244
  if (delay === undefined) {
129
- this.d.log.error("ensureRun after run failed; giving up", {
245
+ this.log.error("ensureRun after run failed; giving up", {
130
246
  conversationId,
131
247
  runId,
132
248
  attempts: attempt + 1,
@@ -134,7 +250,7 @@ export class RunWorker {
134
250
  });
135
251
  return;
136
252
  }
137
- this.d.log.warn("ensureRun after run failed; retrying", {
253
+ this.log.warn("ensureRun after run failed; retrying", {
138
254
  conversationId,
139
255
  runId,
140
256
  attempt,
@@ -173,15 +289,15 @@ export class RunWorker {
173
289
  async onJobFailed(data, err) {
174
290
  const { runId, conversationId } = data;
175
291
  const stalled = /stalled/i.test(err.message);
176
- await this.d.lock.releaseFor(conversationId, runId);
292
+ await this.lock.releaseFor(conversationId, runId);
177
293
  // 运行已进入 waiting(暂停后任务才失败):它有自己的续跑路径(人工决定 / 超时任务),不标记失败。
178
- const cur = await this.d.db
294
+ const cur = await this.db
179
295
  .selectFrom("runs")
180
296
  .select("status")
181
297
  .where("id", "=", runId)
182
298
  .executeTakeFirst();
183
299
  if (cur?.status === "waiting") {
184
- this.d.log.warn("run job failed after the run was suspended; leaving it waiting", { runId });
300
+ this.log.warn("run job failed after the run was suspended; leaving it waiting", { runId });
185
301
  return;
186
302
  }
187
303
  await this.finish(conversationId, runId, "failed", null, {
@@ -214,25 +330,18 @@ export class RunWorker {
214
330
  this.workers = [];
215
331
  this.closing = true;
216
332
  this.closingSignal.abort();
217
- await Promise.all(workers.map((w) => w.pause(true).catch((err) => this.d.log.warn("run worker pause failed", { err }))));
333
+ await Promise.all(workers.map((w) => w.pause(true).catch((err) => this.log.warn("run worker pause failed", { err }))));
218
334
  for (const a of this.active.values())
219
335
  a.shutdown.abort();
220
336
  const all = Promise.all([...this.active.values()].map((a) => a.done));
221
- let timer;
222
- const finished = await Promise.race([
223
- all.then(() => true),
224
- new Promise((resolve) => {
225
- timer = setTimeout(() => resolve(false), Math.max(0, budgetMs));
226
- timer.unref();
227
- }),
228
- ]);
229
- clearTimeout(timer);
337
+ const finished = await waitWithin(all, budgetMs);
230
338
  if (!finished) {
231
339
  for (const [runId, a] of this.active) {
232
340
  a.abandoned = true;
233
341
  a.lease.abandon();
342
+ a.quota?.abandon();
234
343
  a.stopTimers();
235
- this.d.log.warn("run did not reach a step boundary before shutdown; leaving it to another worker", {
344
+ this.log.warn("run did not reach a step boundary before shutdown; leaving it to another worker", {
236
345
  runId,
237
346
  });
238
347
  }
@@ -241,26 +350,15 @@ export class RunWorker {
241
350
  // 关闭期间完成 / 失败的任务登记的后续处理(ensureRun 等)要在调用方关闭运行队列之前做完,
242
351
  // 否则投递半途被打断,待处理的消息无人处理。以剩余预算为限(至少留一点时间)。
243
352
  if (this.followUps.size > 0) {
244
- let t;
245
- await Promise.race([
246
- Promise.allSettled([...this.followUps]),
247
- new Promise((resolve) => {
248
- t = setTimeout(resolve, Math.max(FOLLOW_UP_MIN_WAIT_MS, deadline - Date.now()));
249
- t.unref();
250
- }),
251
- ]);
252
- clearTimeout(t);
353
+ await waitWithin(Promise.allSettled([...this.followUps]), Math.max(FOLLOW_UP_MIN_WAIT_MS, deadline - Date.now()));
253
354
  }
254
- const conn = this.conn;
255
- this.conn = undefined;
256
- if (conn)
257
- await conn.quit().catch(() => conn.disconnect());
258
355
  }
356
+ /** One run job (the `@Processor`s of both run queues call it). */
259
357
  async process(job, token) {
260
358
  const { runId, conversationId } = job.data;
261
359
  if (this.closing)
262
360
  return requeue(job, token, 0);
263
- const run = await this.d.db
361
+ const run = await this.db
264
362
  .selectFrom("runs")
265
363
  .select([
266
364
  "id",
@@ -285,7 +383,7 @@ export class RunWorker {
285
383
  // 运行在等人处理(例如暂停后本任务被 stalled 机制重新投递):不执行,续跑由处理 / 超时发起的新任务负责。
286
384
  if (run.status === "waiting")
287
385
  return;
288
- const conv = await this.d.db
386
+ const conv = await this.db
289
387
  .selectFrom("conversations")
290
388
  .select(["org_id", "agent_id", "kind"])
291
389
  .where("id", "=", conversationId)
@@ -293,14 +391,14 @@ export class RunWorker {
293
391
  if (!conv)
294
392
  return;
295
393
  // 会话锁 TTL 与任务锁一致:持有者崩溃后,任务被判定 stalled 时会话锁也差不多同时过期。
296
- const lease = await this.d.lock.acquire(conversationId, runId, this.d.hooks?.lockTtlMs ?? this.d.config().runtime.jobLockMs);
394
+ const lease = await this.lock.acquire(conversationId, runId, this.hooks?.lockTtlMs ?? this.config.get().runtime.jobLockMs);
297
395
  if (!lease)
298
396
  return requeue(job, token, LOCK_BUSY_DELAY_MS);
299
397
  // A sub-agent stopped while still queued (its parent's stop or wait timeout) ends here, before
300
398
  // taking an org run slot: under a full quota it would otherwise wait for a slot only to be
301
399
  // aborted, and its parent would stay waiting meanwhile (final review m7)
302
400
  if (conv.kind === "subagent" && run.status === "queued") {
303
- const stop = await this.d.abort.requested(runId);
401
+ const stop = await this.abort.requested(runId);
304
402
  if (stop !== null) {
305
403
  try {
306
404
  await this.finish(conversationId, runId, "aborted", null, {
@@ -315,7 +413,7 @@ export class RunWorker {
315
413
  finally {
316
414
  await lease
317
415
  .release()
318
- .catch((err) => this.d.log.warn("conversation lock release failed", { runId, err }));
416
+ .catch((err) => this.log.warn("conversation lock release failed", { runId, err }));
319
417
  }
320
418
  await this.dropCheckpoints(runId);
321
419
  await this.childFinished(runId);
@@ -345,30 +443,28 @@ export class RunWorker {
345
443
  let entered = false;
346
444
  let delayMs = null;
347
445
  try {
348
- const limit = await orgRunLimit(this.d.settings, this.d.config, conv.org_id);
349
- entered = await this.d.quota.tryEnter(conv.org_id, runId, limit, ORG_QUOTA_LEASE_MS);
446
+ const limit = await orgRunLimit(this.settings, this.config, conv.org_id);
447
+ const slot = await this.quota.enter(conv.org_id, runId, limit, ORG_QUOTA_LEASE_MS);
448
+ if (slot !== undefined)
449
+ state.quota = slot;
450
+ entered = slot !== undefined;
350
451
  if (!entered) {
351
452
  delayMs = QUOTA_FULL_DELAY_MS;
352
453
  }
353
454
  else {
354
455
  // 运行开始执行(含续跑、stalled 后接手):通知旁路(渠道出站投递据此把输出投到 IM),失败不影响运行
355
- try {
356
- this.d.onRunStart?.(conversationId);
357
- }
358
- catch (err) {
359
- this.d.log.warn("onRunStart hook failed", { conversationId, err });
360
- }
456
+ void this.events.emit("run.started", { conversationId, runId });
361
457
  const r = await this.execute(run, { id: conversationId, ...conv }, state).catch(async (err) => {
362
458
  if (state.abandoned)
363
459
  return "abandoned";
364
460
  if (state.leaseLost)
365
461
  return "interrupted";
366
462
  // 编排自身出错(如写事件失败):尽力把运行标记为失败,避免会话卡在 running。
367
- this.d.log.error("run orchestration failed", { conversationId, runId, err });
463
+ this.log.error("run orchestration failed", { conversationId, runId, err });
368
464
  await this.finish(conversationId, runId, "failed", null, {
369
465
  type: "run_failed",
370
466
  payload: { error: { code: "run.internal", message: "The run failed unexpectedly" } },
371
- }).catch((e) => this.d.log.error("cannot mark run as failed", { runId, err: e }));
467
+ }).catch((e) => this.log.error("cannot mark run as failed", { runId, err: e }));
372
468
  return "broken";
373
469
  });
374
470
  if (r === "interrupted")
@@ -378,16 +474,14 @@ export class RunWorker {
378
474
  finally {
379
475
  state.stopTimers();
380
476
  if (!state.abandoned) {
381
- if (entered) {
382
- await this.d.quota
383
- .leave(conv.org_id, runId)
384
- .catch((err) => this.d.log.warn("org quota leave failed", { runId, err }));
385
- }
477
+ // releasing the slot stops its renewal and leaves (a failure is logged by the lock service)
478
+ if (entered)
479
+ await state.quota?.release();
386
480
  // 锁已丢失时不释放(已不属于本运行;RELEASE 虽比对 runId,这里也不再触碰)。
387
481
  if (!state.leaseLost) {
388
482
  await lease
389
483
  .release()
390
- .catch((err) => this.d.log.warn("conversation lock release failed", { runId, err }));
484
+ .catch((err) => this.log.warn("conversation lock release failed", { runId, err }));
391
485
  }
392
486
  }
393
487
  this.active.delete(runId);
@@ -400,7 +494,7 @@ export class RunWorker {
400
494
  // 暂停:会话锁与配额已释放,checkpoint 保留;置 waiting 并投递超时任务。任务就此完成,不 ensureRun
401
495
  // (等待期间的新消息在续跑后作为插话吸收)。
402
496
  if (state.suspended) {
403
- await this.d.waits.suspend(runId, conversationId, state.suspended.waitingFor, state.suspended.abort);
497
+ await this.waits.suspend(runId, conversationId, state.suspended.waitingFor, state.suspended.abort);
404
498
  return;
405
499
  }
406
500
  // 运行已到达终态(broken 时已尽力标记失败):checkpoint 只用于续跑,删除。
@@ -414,7 +508,7 @@ export class RunWorker {
414
508
  async execute(run, conv, state) {
415
509
  const runId = run.id;
416
510
  const conversationId = conv.id;
417
- const runtime = this.d.config().runtime;
511
+ const runtime = this.config.get().runtime;
418
512
  let agent;
419
513
  // a chat run's saved agent version, under the conversation's model switch (UI refresh B); a
420
514
  // sub-agent has none: it never takes a selection
@@ -424,18 +518,18 @@ export class RunWorker {
424
518
  if (conv.kind === "subagent") {
425
519
  // a sub-agent runs its effective definition frozen at dispatch, never agent_versions
426
520
  // (spec §6.3), and works for the parent call that dispatched this run
427
- const started = await this.d.eventLog.findByIdem(conversationId, "subagent_started");
521
+ const started = await this.eventLog.findByIdem(conversationId, "subagent_started");
428
522
  if (started?.type !== "subagent_started") {
429
523
  throw new Error(`sub-agent conversation ${conversationId} has no subagent_started`);
430
524
  }
431
525
  // a follow-up runs with its task message's narrowing (final review I1): the frozen tools
432
526
  // and org skills the current version still allows, recorded at its dispatch
433
- const trigger = (await this.d.eventLog.readAfter(conversationId, Number(run.trigger_seq) - 1, 1))[0];
527
+ const trigger = (await this.eventLog.readAfter(conversationId, Number(run.trigger_seq) - 1, 1))[0];
434
528
  agent = childRunDefinition(normalizeStoredDefinition(started.payload.definition), trigger?.type === "user_message" && trigger.seq === Number(run.trigger_seq)
435
529
  ? trigger.payload.dispatch?.narrowed
436
530
  : undefined);
437
531
  maxSteps = Math.min(started.payload.maxSteps, runtime.maxSteps);
438
- const row = await dispatchOfChildRun(this.d.db, runId);
532
+ const row = await dispatchOfChildRun(this.db, runId);
439
533
  const otherAgent = started.payload.template.source === "agent";
440
534
  parent = row
441
535
  ? {
@@ -452,7 +546,7 @@ export class RunWorker {
452
546
  };
453
547
  }
454
548
  else {
455
- const version = await this.d.db
549
+ const version = await this.db
456
550
  .selectFrom("agent_versions")
457
551
  .select("definition")
458
552
  .where("agent_id", "=", conv.agent_id)
@@ -466,66 +560,40 @@ export class RunWorker {
466
560
  // run's `run_started`, read under the conversation lock when the run starts, so a replay
467
561
  // (`selectionAt`) sees exactly what the run used.
468
562
  // A sub-agent (no `saved`) runs its frozen definition as is.
469
- const existingStart = await this.d.eventLog.findByIdem(conversationId, `run_started:${runId}`);
563
+ const existingStart = await this.eventLog.findByIdem(conversationId, `run_started:${runId}`);
470
564
  if (existingStart && saved !== undefined) {
471
- agent = effectiveDefinition(saved, await readSelection(this.d.db, conversationId, existingStart.seq));
565
+ agent = effectiveDefinition(saved, await readSelection(this.db, conversationId, existingStart.seq));
472
566
  }
473
567
  if (run.status === "queued" || startedAt === null) {
474
568
  if (!existingStart) {
475
569
  if (saved !== undefined)
476
570
  await this.fallBackIfUnavailable(conversationId, runId, saved);
477
- const toSeq = await this.d.db.transaction().execute(async (t) => {
478
- await t
479
- .selectFrom("conversations")
480
- .select("id")
481
- .where("id", "=", conversationId)
482
- .forUpdate()
483
- .execute();
484
- if (saved !== undefined) {
485
- agent = effectiveDefinition(saved, await readSelection(t, conversationId));
486
- }
487
- const [ev] = await this.d.eventLog.append(conversationId, [
488
- {
489
- type: "run_started",
490
- runId,
491
- idemKey: `run_started:${runId}`,
492
- payload: {
493
- agentVersion: run.agent_version,
494
- model: agent.model,
495
- triggerAccountId: run.trigger_account_id,
496
- },
497
- },
498
- ], t);
499
- return ev?.seq;
500
- });
571
+ const started = await this.appendRunStarted(conversationId, run, agent, saved);
572
+ agent = started.agent;
573
+ const toSeq = started.toSeq;
501
574
  if (toSeq !== undefined)
502
- await this.d.eventLog.notify(conversationId, toSeq);
575
+ await this.eventLog.notify(conversationId, toSeq);
503
576
  }
504
577
  // 技能目录快照(Ruling M17):在置为 running 之前写,崩溃重试时仍走这里(幂等键去重)
505
578
  try {
506
- await recordSkillsCatalog({
507
- db: this.d.db,
508
- eventLog: this.d.eventLog,
509
- log: this.d.log,
510
- ...(this.d.storage !== undefined && { storage: this.d.storage }),
511
- }, {
579
+ await this.skillsCatalog.record({
512
580
  orgId: conv.org_id,
513
581
  agentId: conv.agent_id,
514
582
  conversationId,
515
583
  runId,
516
584
  agent,
517
- });
585
+ }, { log: this.log });
518
586
  }
519
587
  catch (e) {
520
588
  // Pinned skill bodies could not be read (Decision 9), or the pinned skills kept changing
521
589
  // while they were read (`conflict`): fail before any model request. A transient failure
522
590
  // or a conflict is fixed by sending again; a permanent one names the skill for the owner
523
- // (`recordSkillsCatalog` already logged it at error). Other errors take the generic path.
591
+ // (`SkillsCatalogService.record` already logged it at error). Other errors take the generic path.
524
592
  if (!(e instanceof ApiError) ||
525
593
  (e.code !== "storage.unavailable" && e.code !== "conflict")) {
526
594
  throw e;
527
595
  }
528
- this.d.log.warn("skills catalog not recorded at run start", {
596
+ this.log.warn("skills catalog not recorded at run start", {
529
597
  conversationId,
530
598
  runId,
531
599
  code: e.code,
@@ -538,7 +606,7 @@ export class RunWorker {
538
606
  });
539
607
  return "finished";
540
608
  }
541
- const updated = await this.d.db
609
+ const updated = await this.db
542
610
  .updateTable("runs")
543
611
  .set({ status: "running", started_at: sql `COALESCE(started_at, now())` })
544
612
  .where("id", "=", runId)
@@ -556,29 +624,18 @@ export class RunWorker {
556
624
  deadlineHit = true;
557
625
  ac.abort();
558
626
  }, Math.max(0, deadline - Date.now()));
559
- const quotaTimer = setInterval(() => {
560
- this.d.quota
561
- .renew(conv.org_id, runId, ORG_QUOTA_LEASE_MS)
562
- .then((ok) => {
563
- if (!ok)
564
- this.d.log.warn("org quota lease lost", { runId, orgId: conv.org_id });
565
- })
566
- .catch((err) => this.d.log.warn("org quota renew failed", { runId, err }));
567
- }, ORG_QUOTA_LEASE_MS / 3);
568
- quotaTimer.unref();
569
627
  state.stopTimers = () => {
570
628
  clearTimeout(deadlineTimer);
571
- clearInterval(quotaTimer);
572
629
  };
573
630
  let unwatch;
574
631
  try {
575
- unwatch = await this.d.abort.watch(runId, (by, detail) => {
632
+ unwatch = await this.abort.watch(runId, (by, detail) => {
576
633
  abortedBy = by;
577
634
  abortDetail = detail;
578
635
  ac.abort();
579
636
  });
580
637
  // 取得会话锁之后再读 consumed_seq(锁内不会有别的运行推进它)。
581
- const { consumed_seq } = await this.d.db
638
+ const { consumed_seq } = await this.db
582
639
  .selectFrom("conversations")
583
640
  .select("consumed_seq")
584
641
  .where("id", "=", conversationId)
@@ -591,7 +648,7 @@ export class RunWorker {
591
648
  const out = [];
592
649
  let after = Math.max(afterSeq, startConsumed);
593
650
  for (;;) {
594
- const page = await this.d.eventLog.readAfter(conversationId, after, READ_PAGE);
651
+ const page = await this.eventLog.readAfter(conversationId, after, READ_PAGE);
595
652
  for (const e of page)
596
653
  if (e.type === "user_message")
597
654
  out.push(e);
@@ -609,7 +666,7 @@ export class RunWorker {
609
666
  };
610
667
  let outcome;
611
668
  try {
612
- outcome = await this.d.loop.run({
669
+ outcome = await this.loop.run({
613
670
  orgId: conv.org_id,
614
671
  conversationId,
615
672
  runId,
@@ -619,7 +676,7 @@ export class RunWorker {
619
676
  agentVersion: run.agent_version,
620
677
  signal: ac.signal,
621
678
  shutdown: state.shutdown.signal,
622
- sink: this.d.sinkFor?.(conversationId) ?? noopSink,
679
+ sink: this.sinkFor(conversationId),
623
680
  pendingUserMessages,
624
681
  limits: { maxSteps, deadline },
625
682
  // a sub-agent's conversation fires hooks like a chat, with `parent` set (spec §11)
@@ -634,7 +691,7 @@ export class RunWorker {
634
691
  return "interrupted";
635
692
  const err = e instanceof RunError ? e : new RunError("run.internal", "The run failed unexpectedly");
636
693
  if (!(e instanceof RunError)) {
637
- this.d.log.error("agent loop threw", { conversationId, runId, err: e });
694
+ this.log.error("agent loop threw", { conversationId, runId, err: e });
638
695
  }
639
696
  // 失败也推进 consumed_seq 到已吸收的位置:否则结束时的 ensureRun 会对同一条消息无限重试;
640
697
  // 用户看到 run_failed 后可以重发。
@@ -701,16 +758,12 @@ export class RunWorker {
701
758
  }
702
759
  finally {
703
760
  state.stopTimers();
704
- await unwatch?.().catch((err) => this.d.log.warn("abort unwatch failed", { runId, err }));
761
+ await unwatch?.().catch((err) => this.log.warn("abort unwatch failed", { runId, err }));
705
762
  }
706
763
  }
707
764
  completed(conversationId) {
708
- try {
709
- this.d.onRunCompleted?.(conversationId);
710
- }
711
- catch (err) {
712
- this.d.log.warn("onRunCompleted hook failed", { conversationId, err });
713
- }
765
+ // a completed run enqueues the conversation's title job (never throws)
766
+ void this.titles.maybeEnqueue(conversationId);
714
767
  }
715
768
  /**
716
769
  * When the conversation was switched to a model that no longer resolves (provider disabled,
@@ -720,13 +773,11 @@ export class RunWorker {
720
773
  * handles it).
721
774
  */
722
775
  async fallBackIfUnavailable(conversationId, runId, agent) {
723
- if (!this.d.models)
724
- return;
725
- const sel = await readSelection(this.d.db, conversationId);
776
+ const sel = await readSelection(this.db, conversationId);
726
777
  if (sel.model === null || sameModel(sel.model, agent.model))
727
778
  return;
728
779
  try {
729
- await this.d.models.resolve(sel.model);
780
+ await this.models.resolve(sel.model);
730
781
  return;
731
782
  }
732
783
  catch (e) {
@@ -735,71 +786,135 @@ export class RunWorker {
735
786
  if (!(e instanceof ApiError && e.code === "agent.model_unavailable"))
736
787
  throw e;
737
788
  }
738
- this.d.log.warn("switched-to model unavailable; falling back to the agent's model", {
789
+ this.log.warn("switched-to model unavailable; falling back to the agent's model", {
739
790
  conversationId,
740
791
  runId,
741
792
  model: sel.model,
742
793
  });
743
- const ev = await this.d.db.transaction().execute(async (t) => {
744
- // re-check under the row lock: a person who switched again since the read above wins
745
- await t
746
- .selectFrom("conversations")
747
- .select("id")
748
- .where("id", "=", conversationId)
749
- .forUpdate()
750
- .executeTakeFirst();
751
- if (!sameSelection(await readSelection(t, conversationId), sel))
752
- return null;
753
- const [written] = await this.d.eventLog.append(conversationId, [
754
- {
755
- type: "model_switched",
756
- runId,
757
- idemKey: `model_fallback:${runId}`,
758
- payload: { model: null, effort: null, byAccountId: null, reason: "unavailable" },
759
- },
760
- ], t);
761
- await t
762
- .updateTable("conversations")
763
- .set({ selection: JSON.stringify(NO_SELECTION) })
764
- .where("id", "=", conversationId)
765
- .execute();
766
- return written ?? null;
767
- });
794
+ const ev = await this.fallBackIn(conversationId, runId, sel);
768
795
  if (ev === null)
769
796
  return;
770
- await this.d.eventLog.notify(conversationId, ev.seq);
771
- await this.d.eventLog.publishChanged(conversationId, "selection");
797
+ await this.eventLog.notify(conversationId, ev.seq);
798
+ await this.eventLog.publishChanged(conversationId, "selection");
799
+ }
800
+ /**
801
+ * `run_started` under the conversation row lock, with the model / effort switch in effect then
802
+ * (a chat run's `saved` version under the conversation's selection): what the run uses.
803
+ */
804
+ async appendRunStarted(conversationId, run,
805
+ /** The definition so far (a sub-agent's frozen one is final). */
806
+ current, saved) {
807
+ const t = this.db;
808
+ await t
809
+ .selectFrom("conversations")
810
+ .select("id")
811
+ .where("id", "=", conversationId)
812
+ .forUpdate()
813
+ .execute();
814
+ const agent = saved !== undefined
815
+ ? effectiveDefinition(saved, await readSelection(t, conversationId))
816
+ : current;
817
+ const [ev] = await this.eventLog.appendIn(conversationId, [
818
+ {
819
+ type: "run_started",
820
+ runId: run.id,
821
+ idemKey: `run_started:${run.id}`,
822
+ payload: {
823
+ agentVersion: run.agent_version,
824
+ model: agent.model,
825
+ triggerAccountId: run.trigger_account_id,
826
+ },
827
+ },
828
+ ]);
829
+ return { toSeq: ev?.seq, agent };
830
+ }
831
+ /** {@link fallBackIfUnavailable}'s write: null when the person switched again meanwhile. */
832
+ async fallBackIn(conversationId, runId, sel) {
833
+ const t = this.db;
834
+ // re-check under the row lock: a person who switched again since the read above wins
835
+ await t
836
+ .selectFrom("conversations")
837
+ .select("id")
838
+ .where("id", "=", conversationId)
839
+ .forUpdate()
840
+ .executeTakeFirst();
841
+ if (!sameSelection(await readSelection(t, conversationId), sel))
842
+ return null;
843
+ const [written] = await this.eventLog.appendIn(conversationId, [
844
+ {
845
+ type: "model_switched",
846
+ runId,
847
+ idemKey: `model_fallback:${runId}`,
848
+ payload: { model: null, effort: null, byAccountId: null, reason: "unavailable" },
849
+ },
850
+ ]);
851
+ await t
852
+ .updateTable("conversations")
853
+ .set({ selection: JSON.stringify(NO_SELECTION) })
854
+ .where("id", "=", conversationId)
855
+ .execute();
856
+ return written ?? null;
772
857
  }
773
858
  /** 删除已结束运行的 checkpoint thread(失败只记日志)。 */
774
859
  async dropCheckpoints(runId) {
775
- await this.d.checkpoints
776
- ?.deleteThread(runId)
777
- .catch((err) => this.d.log.warn("checkpoint delete failed", { runId, err }));
860
+ await this.checkpoints
861
+ .deleteThread(runId)
862
+ .catch((err) => this.log.warn("checkpoint delete failed", { runId, err }));
778
863
  }
779
864
  /**
780
865
  * 写终态(见 `finishRun`:运行仍未结束才写,同一事务内推进 `consumed_seq` 并更新 `runs.status`),
781
866
  * 提交后发布会话通知,然后调用测试钩子。返回终态事件 seq;运行已是终态 → null。
782
867
  */
783
868
  async finish(conversationId, runId, status, consumed, event, hook = true, floorToTrigger = true) {
784
- const stopOpen = this.d.stopOpenCalls;
785
869
  let fire = () => { };
786
- const toSeq = await finishRun(this.d.db, this.d.eventLog, {
870
+ const toSeq = await this.finisher.finish({
787
871
  conversationId,
788
872
  runId,
789
873
  status,
790
874
  consumed,
791
875
  event,
792
876
  floorToTrigger,
793
- ...(stopOpen !== undefined && {
794
- beforeTerminal: async (t) => {
795
- fire = (await stopOpen(t, runId)).fire;
796
- },
797
- }),
877
+ beforeTerminal: async () => {
878
+ fire = (await this.pipeline.stopOpenAgentCalls(runId)).fire;
879
+ },
798
880
  });
799
881
  if (toSeq !== null)
800
882
  fire();
801
883
  if (hook)
802
- await this.d.hooks?.beforeRelease?.(runId, conversationId);
884
+ await this.hooks?.beforeRelease?.(runId, conversationId);
803
885
  return toSeq;
804
886
  }
805
- }
887
+ };
888
+ __decorate([
889
+ Transactional({ propagation: "requires_new" })
890
+ ], RunWorker.prototype, "appendRunStarted", null);
891
+ __decorate([
892
+ Transactional({ propagation: "requires_new" })
893
+ ], RunWorker.prototype, "fallBackIn", null);
894
+ RunWorker = __decorate([
895
+ Injectable(),
896
+ __param(0, Inject(KernelDb)),
897
+ __param(1, Inject(EventLog)),
898
+ __param(2, Inject(ConversationLock)),
899
+ __param(3, Inject(RUN_QUOTA)),
900
+ __param(4, Inject(RunAbort)),
901
+ __param(5, Inject(RunQueue)),
902
+ __param(6, Inject(SettingsService)),
903
+ __param(7, Inject(AgentLoops)),
904
+ __param(8, Inject(RunSteps)),
905
+ __param(9, Inject(KernelConfigService)),
906
+ __param(10, Inject(KERNEL_LOGGER)),
907
+ __param(11, Inject(KERNEL_BUS)),
908
+ __param(12, Inject(KyselyCheckpointSaver)),
909
+ __param(13, Inject(Waits)),
910
+ __param(14, Inject(KernelEvents)),
911
+ __param(15, Inject(TitleQueue)),
912
+ __param(16, Inject(ProviderRegistry)),
913
+ __param(17, Inject(SkillsCatalogService)),
914
+ __param(18, Inject(ToolPipeline)),
915
+ __param(19, Inject(RunFinish)),
916
+ __param(20, Inject(TransactionHost)),
917
+ __param(21, Optional()),
918
+ __param(21, Inject(RUN_HOOKS))
919
+ ], RunWorker);
920
+ export { RunWorker };