@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.1

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 (637) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +20 -2
  4. package/bootstrap.json +26 -0
  5. package/dist/admin/admin.controller.d.ts +139 -0
  6. package/dist/admin/admin.controller.js +238 -0
  7. package/dist/admin/extensions.controller.d.ts +100 -0
  8. package/dist/admin/extensions.controller.js +226 -0
  9. package/dist/admin/setup.controller.d.ts +36 -0
  10. package/dist/admin/setup.controller.js +106 -0
  11. package/dist/admin/setup.service.d.ts +47 -0
  12. package/dist/admin/setup.service.js +90 -0
  13. package/dist/agents/agents.controller.d.ts +205 -0
  14. package/dist/agents/agents.controller.js +144 -0
  15. package/dist/agents/agents.service.d.ts +177 -0
  16. package/dist/agents/agents.service.js +677 -0
  17. package/dist/agents/definition.d.ts +198 -0
  18. package/dist/agents/definition.js +152 -0
  19. package/dist/agents/models.controller.d.ts +13 -0
  20. package/dist/agents/models.controller.js +31 -0
  21. package/dist/agents/templates.controller.d.ts +15 -0
  22. package/dist/agents/templates.controller.js +37 -0
  23. package/dist/agents/templates.d.ts +83 -0
  24. package/dist/agents/templates.js +173 -0
  25. package/dist/catalog/admin-catalog.controller.d.ts +143 -0
  26. package/dist/catalog/admin-catalog.controller.js +245 -0
  27. package/dist/catalog/catalog.service.d.ts +430 -0
  28. package/dist/catalog/catalog.service.js +882 -0
  29. package/dist/catalog/claude/agents.d.ts +27 -0
  30. package/dist/catalog/claude/agents.js +270 -0
  31. package/dist/catalog/claude/commands.d.ts +50 -0
  32. package/dist/catalog/claude/commands.js +179 -0
  33. package/dist/catalog/claude/manifest.d.ts +69 -0
  34. package/dist/catalog/claude/manifest.js +134 -0
  35. package/dist/catalog/claude/marketplace.d.ts +35 -0
  36. package/dist/catalog/claude/marketplace.js +194 -0
  37. package/dist/catalog/claude/mcp.d.ts +33 -0
  38. package/dist/catalog/claude/mcp.js +226 -0
  39. package/dist/catalog/claude/report.d.ts +86 -0
  40. package/dist/catalog/claude/report.js +121 -0
  41. package/dist/catalog/claude/translate.d.ts +56 -0
  42. package/dist/catalog/claude/translate.js +857 -0
  43. package/dist/catalog/cli.d.ts +46 -0
  44. package/dist/catalog/cli.js +211 -0
  45. package/dist/catalog/git-source.d.ts +127 -0
  46. package/dist/catalog/git-source.js +520 -0
  47. package/dist/catalog/marketplace-fetch.d.ts +99 -0
  48. package/dist/catalog/marketplace-fetch.js +203 -0
  49. package/dist/catalog/marketplaces.controller.d.ts +97 -0
  50. package/dist/catalog/marketplaces.controller.js +197 -0
  51. package/dist/catalog/marketplaces.service.d.ts +340 -0
  52. package/dist/catalog/marketplaces.service.js +1217 -0
  53. package/dist/catalog/org-catalog.controller.d.ts +128 -0
  54. package/dist/catalog/org-catalog.controller.js +277 -0
  55. package/dist/catalog/org-catalog.service.d.ts +246 -0
  56. package/dist/catalog/org-catalog.service.js +625 -0
  57. package/dist/catalog/plugin-import.d.ts +436 -0
  58. package/dist/catalog/plugin-import.js +1069 -0
  59. package/dist/catalog/plugin-install.d.ts +447 -0
  60. package/dist/catalog/plugin-install.js +1333 -0
  61. package/dist/catalog/plugin-package.d.ts +143 -0
  62. package/dist/catalog/plugin-package.js +382 -0
  63. package/dist/catalog/plugin-upgrade.d.ts +222 -0
  64. package/dist/catalog/plugin-upgrade.js +1219 -0
  65. package/dist/catalog/requests.service.d.ts +162 -0
  66. package/dist/catalog/requests.service.js +504 -0
  67. package/dist/catalog/schema-path.d.ts +7 -0
  68. package/dist/catalog/schema-path.js +63 -0
  69. package/dist/catalog/upgrade-targets.d.ts +59 -0
  70. package/dist/catalog/upgrade-targets.js +90 -0
  71. package/dist/catalog/versions.d.ts +31 -0
  72. package/dist/catalog/versions.js +44 -0
  73. package/dist/channels/actions.d.ts +37 -0
  74. package/dist/channels/actions.js +121 -0
  75. package/dist/channels/cards.d.ts +44 -0
  76. package/dist/channels/cards.js +156 -0
  77. package/dist/channels/connections.controller.d.ts +59 -0
  78. package/dist/channels/connections.controller.js +115 -0
  79. package/dist/channels/connections.service.d.ts +187 -0
  80. package/dist/channels/connections.service.js +534 -0
  81. package/dist/channels/features.d.ts +12 -0
  82. package/dist/channels/features.js +22 -0
  83. package/dist/channels/inbound.d.ts +120 -0
  84. package/dist/channels/inbound.js +332 -0
  85. package/dist/channels/outbound.d.ts +140 -0
  86. package/dist/channels/outbound.js +1126 -0
  87. package/dist/channels/phrases.d.ts +100 -0
  88. package/dist/channels/phrases.js +81 -0
  89. package/dist/channels/supervisor.d.ts +182 -0
  90. package/dist/channels/supervisor.js +625 -0
  91. package/dist/channels/threads.d.ts +29 -0
  92. package/dist/channels/threads.js +104 -0
  93. package/dist/channels/webhook-url.d.ts +16 -0
  94. package/dist/channels/webhook-url.js +34 -0
  95. package/dist/channels/webhook.controller.d.ts +19 -0
  96. package/dist/channels/webhook.controller.js +72 -0
  97. package/dist/channels/webhook.d.ts +73 -0
  98. package/dist/channels/webhook.js +274 -0
  99. package/dist/config/docs.d.ts +9 -0
  100. package/dist/config/docs.js +85 -0
  101. package/dist/config/env.d.ts +6 -0
  102. package/dist/config/env.js +73 -0
  103. package/dist/config/fields.d.ts +42 -0
  104. package/dist/config/fields.js +214 -0
  105. package/dist/config/file-source.d.ts +3 -0
  106. package/dist/config/file-source.js +31 -0
  107. package/dist/config/load.d.ts +20 -0
  108. package/dist/config/load.js +98 -0
  109. package/dist/config/nacos-source.d.ts +31 -0
  110. package/dist/config/nacos-source.js +229 -0
  111. package/dist/config/schema.d.ts +237 -0
  112. package/dist/config/schema.js +1192 -0
  113. package/dist/config/sources.d.ts +18 -0
  114. package/dist/config/sources.js +59 -0
  115. package/dist/config/types.d.ts +9 -0
  116. package/dist/config/types.js +7 -0
  117. package/dist/conversations/artifacts.d.ts +52 -0
  118. package/dist/conversations/artifacts.js +137 -0
  119. package/dist/conversations/attachments.controller.d.ts +28 -0
  120. package/dist/conversations/attachments.controller.js +96 -0
  121. package/dist/conversations/attachments.service.d.ts +180 -0
  122. package/dist/conversations/attachments.service.js +578 -0
  123. package/dist/conversations/conversations.controller.d.ts +288 -0
  124. package/dist/conversations/conversations.controller.js +607 -0
  125. package/dist/conversations/conversations.service.d.ts +321 -0
  126. package/dist/conversations/conversations.service.js +754 -0
  127. package/dist/conversations/event-log.d.ts +122 -0
  128. package/dist/conversations/event-log.js +259 -0
  129. package/dist/conversations/events.d.ts +856 -0
  130. package/dist/conversations/events.js +639 -0
  131. package/dist/conversations/files.d.ts +92 -0
  132. package/dist/conversations/files.js +213 -0
  133. package/dist/conversations/outputs-read.d.ts +34 -0
  134. package/dist/conversations/outputs-read.js +37 -0
  135. package/dist/conversations/queue.d.ts +169 -0
  136. package/dist/conversations/queue.js +527 -0
  137. package/dist/conversations/sandbox-status.d.ts +21 -0
  138. package/dist/conversations/sandbox-status.js +24 -0
  139. package/dist/conversations/selection.d.ts +46 -0
  140. package/dist/conversations/selection.js +75 -0
  141. package/dist/conversations/titles.d.ts +93 -0
  142. package/dist/conversations/titles.js +423 -0
  143. package/dist/ctx/bus.d.ts +16 -0
  144. package/dist/ctx/bus.js +101 -0
  145. package/dist/ctx/create-ctx.d.ts +109 -0
  146. package/dist/ctx/create-ctx.js +592 -0
  147. package/dist/ctx/kv.d.ts +4 -0
  148. package/dist/ctx/kv.js +31 -0
  149. package/dist/ctx/lock.d.ts +4 -0
  150. package/dist/ctx/lock.js +39 -0
  151. package/dist/ctx/namespace.d.ts +6 -0
  152. package/dist/ctx/namespace.js +12 -0
  153. package/dist/ctx/queue.d.ts +25 -0
  154. package/dist/ctx/queue.js +151 -0
  155. package/dist/ctx/secrets.d.ts +45 -0
  156. package/dist/ctx/secrets.js +175 -0
  157. package/dist/db/kernel-schema.d.ts +1122 -0
  158. package/dist/db/kernel-schema.js +5 -0
  159. package/dist/db/migrator.d.ts +28 -0
  160. package/dist/db/migrator.js +140 -0
  161. package/dist/db/pool.d.ts +21 -0
  162. package/dist/db/pool.js +28 -0
  163. package/dist/db/sql-statements.d.ts +34 -0
  164. package/dist/db/sql-statements.js +168 -0
  165. package/dist/errors.d.ts +211 -0
  166. package/dist/errors.js +213 -0
  167. package/dist/evals/budget.d.ts +61 -0
  168. package/dist/evals/budget.js +181 -0
  169. package/dist/evals/diff.d.ts +55 -0
  170. package/dist/evals/diff.js +133 -0
  171. package/dist/evals/judge.d.ts +53 -0
  172. package/dist/evals/judge.js +149 -0
  173. package/dist/evals/plan.d.ts +47 -0
  174. package/dist/evals/plan.js +77 -0
  175. package/dist/evals/reconstruct.d.ts +137 -0
  176. package/dist/evals/reconstruct.js +322 -0
  177. package/dist/evals/recorded-tools.d.ts +54 -0
  178. package/dist/evals/recorded-tools.js +167 -0
  179. package/dist/evals/run-replay.d.ts +86 -0
  180. package/dist/evals/run-replay.js +502 -0
  181. package/dist/evals/runs.controller.d.ts +100 -0
  182. package/dist/evals/runs.controller.js +199 -0
  183. package/dist/evals/runs.service.d.ts +275 -0
  184. package/dist/evals/runs.service.js +836 -0
  185. package/dist/evals/sets.controller.d.ts +61 -0
  186. package/dist/evals/sets.controller.js +183 -0
  187. package/dist/evals/sets.service.d.ts +128 -0
  188. package/dist/evals/sets.service.js +558 -0
  189. package/dist/evals/snapshot.d.ts +76 -0
  190. package/dist/evals/snapshot.js +207 -0
  191. package/dist/evals/step-replay.d.ts +113 -0
  192. package/dist/evals/step-replay.js +181 -0
  193. package/dist/evals/trajectory.controller.d.ts +41 -0
  194. package/dist/evals/trajectory.controller.js +88 -0
  195. package/dist/evals/trajectory.d.ts +144 -0
  196. package/dist/evals/trajectory.js +338 -0
  197. package/dist/evals/trajectory.service.d.ts +108 -0
  198. package/dist/evals/trajectory.service.js +323 -0
  199. package/dist/evals/worker.d.ts +101 -0
  200. package/dist/evals/worker.js +790 -0
  201. package/dist/extensions/admin-ops.d.ts +105 -0
  202. package/dist/extensions/admin-ops.js +353 -0
  203. package/dist/extensions/admin-view.d.ts +79 -0
  204. package/dist/extensions/admin-view.js +327 -0
  205. package/dist/extensions/approvals.d.ts +119 -0
  206. package/dist/extensions/approvals.js +205 -0
  207. package/dist/extensions/blobs.d.ts +45 -0
  208. package/dist/extensions/blobs.js +160 -0
  209. package/dist/extensions/bootstrap.d.ts +176 -0
  210. package/dist/extensions/bootstrap.js +535 -0
  211. package/dist/extensions/cli.d.ts +61 -0
  212. package/dist/extensions/cli.js +165 -0
  213. package/dist/extensions/config-json-schema.d.ts +9 -0
  214. package/dist/extensions/config-json-schema.js +73 -0
  215. package/dist/extensions/deployment-config.d.ts +138 -0
  216. package/dist/extensions/deployment-config.js +394 -0
  217. package/dist/extensions/enabled.d.ts +31 -0
  218. package/dist/extensions/enabled.js +55 -0
  219. package/dist/extensions/hooks.d.ts +161 -0
  220. package/dist/extensions/hooks.js +425 -0
  221. package/dist/extensions/host.d.ts +577 -0
  222. package/dist/extensions/host.js +2071 -0
  223. package/dist/extensions/inflight.d.ts +69 -0
  224. package/dist/extensions/inflight.js +277 -0
  225. package/dist/extensions/installs.d.ts +166 -0
  226. package/dist/extensions/installs.js +253 -0
  227. package/dist/extensions/instance.d.ts +167 -0
  228. package/dist/extensions/instance.js +329 -0
  229. package/dist/extensions/ledger.d.ts +30 -0
  230. package/dist/extensions/ledger.js +50 -0
  231. package/dist/extensions/lifecycle.d.ts +80 -0
  232. package/dist/extensions/lifecycle.js +152 -0
  233. package/dist/extensions/migrate-lock.d.ts +51 -0
  234. package/dist/extensions/migrate-lock.js +100 -0
  235. package/dist/extensions/org-config.controller.d.ts +24 -0
  236. package/dist/extensions/org-config.controller.js +59 -0
  237. package/dist/extensions/org-config.d.ts +169 -0
  238. package/dist/extensions/org-config.js +520 -0
  239. package/dist/extensions/package.d.ts +115 -0
  240. package/dist/extensions/package.js +246 -0
  241. package/dist/extensions/permission-set.d.ts +117 -0
  242. package/dist/extensions/permission-set.js +184 -0
  243. package/dist/extensions/permission-view.d.ts +194 -0
  244. package/dist/extensions/permission-view.js +284 -0
  245. package/dist/extensions/registry.d.ts +24 -0
  246. package/dist/extensions/registry.js +56 -0
  247. package/dist/extensions/resolve.d.ts +12 -0
  248. package/dist/extensions/resolve.js +71 -0
  249. package/dist/extensions/sources.d.ts +69 -0
  250. package/dist/extensions/sources.js +120 -0
  251. package/dist/extensions/sync.d.ts +40 -0
  252. package/dist/extensions/sync.js +242 -0
  253. package/dist/files/previewers.controller.d.ts +46 -0
  254. package/dist/files/previewers.controller.js +105 -0
  255. package/dist/files/previewers.d.ts +100 -0
  256. package/dist/files/previewers.js +250 -0
  257. package/dist/http/api.module.d.ts +114 -0
  258. package/dist/http/api.module.js +448 -0
  259. package/dist/http/app.d.ts +77 -0
  260. package/dist/http/app.js +220 -0
  261. package/dist/http/error.filter.d.ts +21 -0
  262. package/dist/http/error.filter.js +85 -0
  263. package/dist/http/gateway.module.d.ts +15 -0
  264. package/dist/http/gateway.module.js +13 -0
  265. package/dist/http/health.controller.d.ts +26 -0
  266. package/dist/http/health.controller.js +79 -0
  267. package/dist/http/nest-logger.d.ts +20 -0
  268. package/dist/http/nest-logger.js +28 -0
  269. package/dist/http/plugin-dispatch.d.ts +68 -0
  270. package/dist/http/plugin-dispatch.js +200 -0
  271. package/dist/http/tokens.d.ts +131 -0
  272. package/dist/http/tokens.js +131 -0
  273. package/dist/http/zod.pipe.d.ts +8 -0
  274. package/dist/http/zod.pipe.js +14 -0
  275. package/dist/identity/accounts.d.ts +93 -0
  276. package/dist/identity/accounts.js +367 -0
  277. package/dist/identity/api-tokens.d.ts +73 -0
  278. package/dist/identity/api-tokens.js +197 -0
  279. package/dist/identity/audit.d.ts +23 -0
  280. package/dist/identity/audit.js +41 -0
  281. package/dist/identity/auth.controller.d.ts +40 -0
  282. package/dist/identity/auth.controller.js +130 -0
  283. package/dist/identity/auth.guard.d.ts +41 -0
  284. package/dist/identity/auth.guard.js +162 -0
  285. package/dist/identity/binding.d.ts +47 -0
  286. package/dist/identity/binding.js +84 -0
  287. package/dist/identity/cookies.d.ts +16 -0
  288. package/dist/identity/cookies.js +32 -0
  289. package/dist/identity/credential-check.d.ts +17 -0
  290. package/dist/identity/credential-check.js +24 -0
  291. package/dist/identity/enterprise-admin.d.ts +14 -0
  292. package/dist/identity/enterprise-admin.js +27 -0
  293. package/dist/identity/external.d.ts +106 -0
  294. package/dist/identity/external.js +337 -0
  295. package/dist/identity/hash.d.ts +2 -0
  296. package/dist/identity/hash.js +3 -0
  297. package/dist/identity/login.d.ts +6 -0
  298. package/dist/identity/login.js +20 -0
  299. package/dist/identity/me.controller.d.ts +61 -0
  300. package/dist/identity/me.controller.js +159 -0
  301. package/dist/identity/passwords.d.ts +6 -0
  302. package/dist/identity/passwords.js +37 -0
  303. package/dist/identity/principal.d.ts +56 -0
  304. package/dist/identity/principal.js +38 -0
  305. package/dist/identity/rate-limit.d.ts +55 -0
  306. package/dist/identity/rate-limit.js +121 -0
  307. package/dist/identity/sessions.d.ts +84 -0
  308. package/dist/identity/sessions.js +306 -0
  309. package/dist/identity/settings.d.ts +121 -0
  310. package/dist/identity/settings.js +248 -0
  311. package/dist/identity/sso.controller.d.ts +59 -0
  312. package/dist/identity/sso.controller.js +192 -0
  313. package/dist/identity/sso.d.ts +83 -0
  314. package/dist/identity/sso.js +202 -0
  315. package/dist/inbox/inbox.service.d.ts +43 -0
  316. package/dist/inbox/inbox.service.js +57 -0
  317. package/dist/index.d.ts +69 -0
  318. package/dist/index.js +67 -0
  319. package/dist/kernel.d.ts +259 -0
  320. package/dist/kernel.js +1326 -0
  321. package/dist/log-config.d.ts +9 -0
  322. package/dist/log-config.js +27 -0
  323. package/dist/log-context.d.ts +32 -0
  324. package/dist/log-context.js +40 -0
  325. package/dist/log-loki.d.ts +34 -0
  326. package/dist/log-loki.js +145 -0
  327. package/dist/log.d.ts +79 -0
  328. package/dist/log.js +303 -0
  329. package/dist/models/prices.d.ts +53 -0
  330. package/dist/models/prices.js +121 -0
  331. package/dist/models/purposes.controller.d.ts +19 -0
  332. package/dist/models/purposes.controller.js +56 -0
  333. package/dist/models/purposes.d.ts +140 -0
  334. package/dist/models/purposes.js +267 -0
  335. package/dist/net/proxy.d.ts +44 -0
  336. package/dist/net/proxy.js +162 -0
  337. package/dist/net/public-address.d.ts +60 -0
  338. package/dist/net/public-address.js +272 -0
  339. package/dist/net/safe-fetch.d.ts +38 -0
  340. package/dist/net/safe-fetch.js +140 -0
  341. package/dist/orgs/directory-sync.controller.d.ts +14 -0
  342. package/dist/orgs/directory-sync.controller.js +40 -0
  343. package/dist/orgs/directory-sync.d.ts +166 -0
  344. package/dist/orgs/directory-sync.js +558 -0
  345. package/dist/orgs/invitations.controller.d.ts +58 -0
  346. package/dist/orgs/invitations.controller.js +137 -0
  347. package/dist/orgs/invitations.service.d.ts +80 -0
  348. package/dist/orgs/invitations.service.js +217 -0
  349. package/dist/orgs/members.service.d.ts +63 -0
  350. package/dist/orgs/members.service.js +234 -0
  351. package/dist/orgs/offboarding.d.ts +141 -0
  352. package/dist/orgs/offboarding.js +398 -0
  353. package/dist/orgs/org-lock.d.ts +32 -0
  354. package/dist/orgs/org-lock.js +46 -0
  355. package/dist/orgs/org.guard.d.ts +35 -0
  356. package/dist/orgs/org.guard.js +95 -0
  357. package/dist/orgs/orgs.controller.d.ts +78 -0
  358. package/dist/orgs/orgs.controller.js +192 -0
  359. package/dist/orgs/orgs.service.d.ts +61 -0
  360. package/dist/orgs/orgs.service.js +209 -0
  361. package/dist/orgs/roles.d.ts +13 -0
  362. package/dist/orgs/roles.js +58 -0
  363. package/dist/orgs/settings.controller.d.ts +20 -0
  364. package/dist/orgs/settings.controller.js +53 -0
  365. package/dist/orgs/settings.service.d.ts +120 -0
  366. package/dist/orgs/settings.service.js +178 -0
  367. package/dist/packages/npm.d.ts +50 -0
  368. package/dist/packages/npm.js +218 -0
  369. package/dist/packages/provenance.d.ts +47 -0
  370. package/dist/packages/provenance.js +147 -0
  371. package/dist/packages/tgz.d.ts +76 -0
  372. package/dist/packages/tgz.js +225 -0
  373. package/dist/runtime/abort.d.ts +32 -0
  374. package/dist/runtime/abort.js +71 -0
  375. package/dist/runtime/checkpointer.d.ts +32 -0
  376. package/dist/runtime/checkpointer.js +243 -0
  377. package/dist/runtime/context/build.d.ts +254 -0
  378. package/dist/runtime/context/build.js +693 -0
  379. package/dist/runtime/context/claude-tools.d.ts +11 -0
  380. package/dist/runtime/context/claude-tools.js +24 -0
  381. package/dist/runtime/context/compaction.d.ts +26 -0
  382. package/dist/runtime/context/compaction.js +195 -0
  383. package/dist/runtime/context/pairing.d.ts +11 -0
  384. package/dist/runtime/context/pairing.js +82 -0
  385. package/dist/runtime/context/reminders.d.ts +5 -0
  386. package/dist/runtime/context/reminders.js +11 -0
  387. package/dist/runtime/context/skills.d.ts +105 -0
  388. package/dist/runtime/context/skills.js +283 -0
  389. package/dist/runtime/context/tokens.d.ts +19 -0
  390. package/dist/runtime/context/tokens.js +104 -0
  391. package/dist/runtime/conversation-lock.d.ts +40 -0
  392. package/dist/runtime/conversation-lock.js +97 -0
  393. package/dist/runtime/hook-calls.d.ts +84 -0
  394. package/dist/runtime/hook-calls.js +136 -0
  395. package/dist/runtime/langgraph-loop.d.ts +52 -0
  396. package/dist/runtime/langgraph-loop.js +247 -0
  397. package/dist/runtime/loop.d.ts +93 -0
  398. package/dist/runtime/loop.js +7 -0
  399. package/dist/runtime/maintenance.d.ts +80 -0
  400. package/dist/runtime/maintenance.js +148 -0
  401. package/dist/runtime/media-cache.d.ts +21 -0
  402. package/dist/runtime/media-cache.js +51 -0
  403. package/dist/runtime/model-call.d.ts +176 -0
  404. package/dist/runtime/model-call.js +1049 -0
  405. package/dist/runtime/providers.d.ts +86 -0
  406. package/dist/runtime/providers.js +224 -0
  407. package/dist/runtime/quota.d.ts +29 -0
  408. package/dist/runtime/quota.js +70 -0
  409. package/dist/runtime/run-finish.d.ts +45 -0
  410. package/dist/runtime/run-finish.js +69 -0
  411. package/dist/runtime/run-queue.d.ts +121 -0
  412. package/dist/runtime/run-queue.js +493 -0
  413. package/dist/runtime/run-worker.d.ts +138 -0
  414. package/dist/runtime/run-worker.js +806 -0
  415. package/dist/runtime/stream.controller.d.ts +34 -0
  416. package/dist/runtime/stream.controller.js +122 -0
  417. package/dist/runtime/stream.d.ts +63 -0
  418. package/dist/runtime/stream.js +262 -0
  419. package/dist/runtime/subagents/child.d.ts +80 -0
  420. package/dist/runtime/subagents/child.js +225 -0
  421. package/dist/runtime/subagents/definition.d.ts +103 -0
  422. package/dist/runtime/subagents/definition.js +392 -0
  423. package/dist/runtime/subagents/dispatch.d.ts +69 -0
  424. package/dist/runtime/subagents/dispatch.js +502 -0
  425. package/dist/runtime/subagents/limits.d.ts +23 -0
  426. package/dist/runtime/subagents/limits.js +34 -0
  427. package/dist/runtime/subagents/org-agents.d.ts +50 -0
  428. package/dist/runtime/subagents/org-agents.js +70 -0
  429. package/dist/runtime/subagents/preamble.d.ts +7 -0
  430. package/dist/runtime/subagents/preamble.js +11 -0
  431. package/dist/runtime/subagents/progress.d.ts +26 -0
  432. package/dist/runtime/subagents/progress.js +36 -0
  433. package/dist/runtime/subagents/roster.d.ts +55 -0
  434. package/dist/runtime/subagents/roster.js +111 -0
  435. package/dist/runtime/subagents/skill-fork.d.ts +123 -0
  436. package/dist/runtime/subagents/skill-fork.js +259 -0
  437. package/dist/runtime/usage-report.d.ts +163 -0
  438. package/dist/runtime/usage-report.js +551 -0
  439. package/dist/runtime/waits.d.ts +233 -0
  440. package/dist/runtime/waits.js +883 -0
  441. package/dist/sandbox/leases.d.ts +169 -0
  442. package/dist/sandbox/leases.js +515 -0
  443. package/dist/sandbox/lifecycle.d.ts +21 -0
  444. package/dist/sandbox/lifecycle.js +68 -0
  445. package/dist/sandbox/sandbox.service.d.ts +249 -0
  446. package/dist/sandbox/sandbox.service.js +908 -0
  447. package/dist/skills/catalog.d.ts +149 -0
  448. package/dist/skills/catalog.js +405 -0
  449. package/dist/skills/changes.controller.d.ts +56 -0
  450. package/dist/skills/changes.controller.js +136 -0
  451. package/dist/skills/changes.service.d.ts +175 -0
  452. package/dist/skills/changes.service.js +805 -0
  453. package/dist/skills/invocable.controller.d.ts +23 -0
  454. package/dist/skills/invocable.controller.js +50 -0
  455. package/dist/skills/invocation-keys.d.ts +23 -0
  456. package/dist/skills/invocation-keys.js +44 -0
  457. package/dist/skills/invoke.d.ts +135 -0
  458. package/dist/skills/invoke.js +286 -0
  459. package/dist/skills/package.d.ts +87 -0
  460. package/dist/skills/package.js +227 -0
  461. package/dist/skills/skills.controller.d.ts +40 -0
  462. package/dist/skills/skills.controller.js +110 -0
  463. package/dist/skills/skills.service.d.ts +192 -0
  464. package/dist/skills/skills.service.js +567 -0
  465. package/dist/storage/prefix.d.ts +36 -0
  466. package/dist/storage/prefix.js +104 -0
  467. package/dist/storage/purge.d.ts +27 -0
  468. package/dist/storage/purge.js +75 -0
  469. package/dist/storage/storage.service.d.ts +44 -0
  470. package/dist/storage/storage.service.js +145 -0
  471. package/dist/text.d.ts +13 -0
  472. package/dist/text.js +13 -0
  473. package/dist/tools/approvals.controller.d.ts +53 -0
  474. package/dist/tools/approvals.controller.js +128 -0
  475. package/dist/tools/approvals.service.d.ts +172 -0
  476. package/dist/tools/approvals.service.js +568 -0
  477. package/dist/tools/breaker.d.ts +28 -0
  478. package/dist/tools/breaker.js +72 -0
  479. package/dist/tools/builtins/agent.d.ts +81 -0
  480. package/dist/tools/builtins/agent.js +223 -0
  481. package/dist/tools/builtins/ask-user.d.ts +28 -0
  482. package/dist/tools/builtins/ask-user.js +139 -0
  483. package/dist/tools/builtins/read-tool-output.d.ts +18 -0
  484. package/dist/tools/builtins/read-tool-output.js +108 -0
  485. package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
  486. package/dist/tools/builtins/sandbox/bash.js +137 -0
  487. package/dist/tools/builtins/sandbox/common.d.ts +116 -0
  488. package/dist/tools/builtins/sandbox/common.js +306 -0
  489. package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
  490. package/dist/tools/builtins/sandbox/deliver.js +180 -0
  491. package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
  492. package/dist/tools/builtins/sandbox/edit.js +98 -0
  493. package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
  494. package/dist/tools/builtins/sandbox/glob-match.js +240 -0
  495. package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
  496. package/dist/tools/builtins/sandbox/glob.js +104 -0
  497. package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
  498. package/dist/tools/builtins/sandbox/grep.js +133 -0
  499. package/dist/tools/builtins/sandbox/index.d.ts +12 -0
  500. package/dist/tools/builtins/sandbox/index.js +27 -0
  501. package/dist/tools/builtins/sandbox/names.d.ts +7 -0
  502. package/dist/tools/builtins/sandbox/names.js +20 -0
  503. package/dist/tools/builtins/sandbox/read.d.ts +8 -0
  504. package/dist/tools/builtins/sandbox/read.js +121 -0
  505. package/dist/tools/builtins/sandbox/write.d.ts +4 -0
  506. package/dist/tools/builtins/sandbox/write.js +88 -0
  507. package/dist/tools/builtins/skill-load.d.ts +53 -0
  508. package/dist/tools/builtins/skill-load.js +446 -0
  509. package/dist/tools/builtins/skill-write.d.ts +59 -0
  510. package/dist/tools/builtins/skill-write.js +244 -0
  511. package/dist/tools/builtins/tool-search.d.ts +31 -0
  512. package/dist/tools/builtins/tool-search.js +171 -0
  513. package/dist/tools/connector-content.controller.d.ts +34 -0
  514. package/dist/tools/connector-content.controller.js +78 -0
  515. package/dist/tools/connector-content.d.ts +104 -0
  516. package/dist/tools/connector-content.js +267 -0
  517. package/dist/tools/connectors.controller.d.ts +210 -0
  518. package/dist/tools/connectors.controller.js +234 -0
  519. package/dist/tools/connectors.service.d.ts +303 -0
  520. package/dist/tools/connectors.service.js +1102 -0
  521. package/dist/tools/credentials.d.ts +139 -0
  522. package/dist/tools/credentials.js +351 -0
  523. package/dist/tools/drift.d.ts +141 -0
  524. package/dist/tools/drift.js +539 -0
  525. package/dist/tools/elicitation.d.ts +81 -0
  526. package/dist/tools/elicitation.js +266 -0
  527. package/dist/tools/endpoint.d.ts +18 -0
  528. package/dist/tools/endpoint.js +115 -0
  529. package/dist/tools/info.d.ts +67 -0
  530. package/dist/tools/info.js +113 -0
  531. package/dist/tools/naming.d.ts +27 -0
  532. package/dist/tools/naming.js +47 -0
  533. package/dist/tools/oauth/discovery.d.ts +65 -0
  534. package/dist/tools/oauth/discovery.js +307 -0
  535. package/dist/tools/oauth/flow.d.ts +63 -0
  536. package/dist/tools/oauth/flow.js +237 -0
  537. package/dist/tools/oauth/oauth.controller.d.ts +31 -0
  538. package/dist/tools/oauth/oauth.controller.js +95 -0
  539. package/dist/tools/oauth/tokens.d.ts +111 -0
  540. package/dist/tools/oauth/tokens.js +258 -0
  541. package/dist/tools/outputs.d.ts +61 -0
  542. package/dist/tools/outputs.js +156 -0
  543. package/dist/tools/pipeline.d.ts +322 -0
  544. package/dist/tools/pipeline.js +1236 -0
  545. package/dist/tools/policy.d.ts +60 -0
  546. package/dist/tools/policy.js +236 -0
  547. package/dist/tools/questions.controller.d.ts +24 -0
  548. package/dist/tools/questions.controller.js +58 -0
  549. package/dist/tools/questions.service.d.ts +103 -0
  550. package/dist/tools/questions.service.js +295 -0
  551. package/dist/tools/redact.d.ts +20 -0
  552. package/dist/tools/redact.js +60 -0
  553. package/dist/tools/registry.d.ts +246 -0
  554. package/dist/tools/registry.js +481 -0
  555. package/dist/tools/resources.d.ts +16 -0
  556. package/dist/tools/resources.js +76 -0
  557. package/dist/tools/specs.d.ts +14 -0
  558. package/dist/tools/specs.js +31 -0
  559. package/dist/tools/validate.d.ts +20 -0
  560. package/dist/tools/validate.js +183 -0
  561. package/dist/tools/view.d.ts +43 -0
  562. package/dist/tools/view.js +225 -0
  563. package/dist/ui/embed-token.d.ts +31 -0
  564. package/dist/ui/embed-token.js +132 -0
  565. package/dist/ui/registry.d.ts +58 -0
  566. package/dist/ui/registry.js +90 -0
  567. package/dist/ui/ui-stream.d.ts +37 -0
  568. package/dist/ui/ui-stream.js +162 -0
  569. package/dist/ui/views.controller.d.ts +81 -0
  570. package/dist/ui/views.controller.js +261 -0
  571. package/dist/ui/views.d.ts +155 -0
  572. package/dist/ui/views.js +306 -0
  573. package/dist/version.d.ts +5 -0
  574. package/dist/version.js +6 -0
  575. package/package.json +69 -3
  576. package/src/migrations/0001_init.sql +8 -0
  577. package/src/migrations/0002_secrets.sql +8 -0
  578. package/src/migrations/0003_identity.sql +117 -0
  579. package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
  580. package/src/migrations/0005_agents.sql +27 -0
  581. package/src/migrations/0006_conversations.sql +37 -0
  582. package/src/migrations/0007_checkpoints.sql +26 -0
  583. package/src/migrations/0008_runs_trigger_seq.sql +3 -0
  584. package/src/migrations/0009_runs_active_unique.sql +4 -0
  585. package/src/migrations/0010_tools.sql +125 -0
  586. package/src/migrations/0011_approvals_spec.sql +10 -0
  587. package/src/migrations/0012_run_waits.sql +24 -0
  588. package/src/migrations/0013_app_tools_source.sql +4 -0
  589. package/src/migrations/0014_tool_specs.sql +8 -0
  590. package/src/migrations/0015_tool_drift.sql +20 -0
  591. package/src/migrations/0016_plugin_permissions.sql +11 -0
  592. package/src/migrations/0017_identity_sources.sql +6 -0
  593. package/src/migrations/0018_channels.sql +74 -0
  594. package/src/migrations/0019_identity_trust.sql +17 -0
  595. package/src/migrations/0020_channel_card_lookup.sql +10 -0
  596. package/src/migrations/0021_org_storage_purge.sql +9 -0
  597. package/src/migrations/0022_attachments.sql +29 -0
  598. package/src/migrations/0023_sandboxes.sql +37 -0
  599. package/src/migrations/0024_skills.sql +46 -0
  600. package/src/migrations/0025_skills_catalog_idx.sql +6 -0
  601. package/src/migrations/0026_skill_changes.sql +34 -0
  602. package/src/migrations/0027_model_prices.sql +18 -0
  603. package/src/migrations/0028_evals.sql +105 -0
  604. package/src/migrations/0029_model_purposes.sql +18 -0
  605. package/src/migrations/0030_plugin_installs.sql +73 -0
  606. package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
  607. package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
  608. package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
  609. package/src/migrations/0034_directory.sql +49 -0
  610. package/src/migrations/0035_catalogs.sql +40 -0
  611. package/src/migrations/0036_app_import_staging.sql +17 -0
  612. package/src/migrations/0037_directory_installs.sql +92 -0
  613. package/src/migrations/0038_channel_inbound_mode.sql +6 -0
  614. package/src/migrations/0039_channel_card_pending.sql +8 -0
  615. package/src/migrations/0040_usage_report_sweep.sql +10 -0
  616. package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
  617. package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
  618. package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
  619. package/src/migrations/0044_catalog_one_kind.sql +90 -0
  620. package/src/migrations/0045_plugin_dependencies.sql +9 -0
  621. package/src/migrations/0046_git_sources.sql +25 -0
  622. package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
  623. package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
  624. package/src/migrations/0049_plugin_upgrades.sql +37 -0
  625. package/src/migrations/0050_bootstrap.sql +53 -0
  626. package/src/migrations/0051_claude_compat.sql +26 -0
  627. package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
  628. package/src/migrations/0053_subagents.sql +73 -0
  629. package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
  630. package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
  631. package/src/migrations/0056_approval_reason.sql +3 -0
  632. package/src/migrations/0057_conversation_titles.sql +11 -0
  633. package/src/migrations/0058_conversation_selection.sql +4 -0
  634. package/src/migrations/0059_conversation_queue.sql +22 -0
  635. package/src/migrations/0060_file_previewers.sql +10 -0
  636. package/src/migrations/0061_queue_selection.sql +5 -0
  637. package/src/migrations/0062_queued_skill.sql +8 -0
@@ -0,0 +1,493 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { Queue } from "bullmq";
3
+ import { Redis } from "ioredis";
4
+ import { sql } from "kysely";
5
+ import { visibleTo } from "../agents/agents.service.js";
6
+ import { dispatchQueuedIn, pauseQueueWith } from "../conversations/queue.js";
7
+ import { finishRunIn, notifyFinished } from "./run-finish.js";
8
+ /** 内核运行队列的 BullMQ 队列名(不含 `:`;与插件队列 `cap.<插件>.<名>` 不会重名)。 */
9
+ export const RUN_QUEUE_NAME = "cap-kernel-runs";
10
+ /**
11
+ * Queue of sub-agent (child) runs (sub-agents spec §7.4): a replica still on a version without
12
+ * sub-agents never takes a child job, and child load shows apart from conversations.
13
+ */
14
+ export const SUBAGENT_RUN_QUEUE_NAME = "cap-kernel-subagent-runs";
15
+ /** The run queue of a conversation kind: sub-agent conversations have their own. */
16
+ export const runQueueNameFor = (kind) => kind === "subagent" ? SUBAGENT_RUN_QUEUE_NAME : RUN_QUEUE_NAME;
17
+ /** 同一触发点(会话 + 最新用户消息 seq)只投递一次。 */
18
+ export const runJobId = (conversationId, maxUserSeq) => `run-${conversationId}-${maxUserSeq}`;
19
+ /** 未结束的运行状态(waiting:等人处理审批 / 输入请求,没有任务、不占会话锁与配额)。 */
20
+ export const ACTIVE_RUN_STATUSES = ["queued", "running", "waiting"];
21
+ /**
22
+ * queued 运行的宽限期(秒):`ensureRun` / 续跑先提交 runs 行、再投递任务,两步之间任务暂时不存在;
23
+ * 只有进入 queued 超过这么久(`COALESCE(queued_at, created_at)`)仍没有任务的 queued 行才视为孤儿。
24
+ */
25
+ const ORPHAN_QUEUED_GRACE_SECONDS = 30;
26
+ /** BullMQ 连接要求 maxRetriesPerRequest 为 null(Worker 的阻塞连接);Queue 复用同样的配置。 */
27
+ export function bullConnection(redisUrl, log) {
28
+ const c = new Redis(redisUrl, { maxRetriesPerRequest: null });
29
+ c.on("error", (err) => log.error("run queue redis connection error", { err }));
30
+ return c;
31
+ }
32
+ /**
33
+ * 运行队列(生产方):`ensureRun` 在会话有未消费的用户消息、且没有进行中的运行时插入 `runs` 行并投递任务。
34
+ * 「是否已有运行」以 PG 为准(会话行锁内检查 `runs` 中的 queued / running),并参考会话锁的持有者;
35
+ * 多副本并发调用对同一会话串行化,同一时刻至多一个未结束的运行。
36
+ */
37
+ export class RunQueue {
38
+ db;
39
+ eventLog;
40
+ lock;
41
+ redisUrl;
42
+ log;
43
+ checkpoints;
44
+ subagents;
45
+ queues = new Map();
46
+ conn;
47
+ closed = false;
48
+ constructor(db, eventLog, lock, redisUrl, log,
49
+ /** 运行以孤儿结束(标记失败 / 直接中止)后删除它的 checkpoint thread(thread_id = runId)。 */
50
+ checkpoints,
51
+ /** Sub-agent cleanup when an orphan repair ends a parent run (sub-agents spec §12). */
52
+ subagents) {
53
+ this.db = db;
54
+ this.eventLog = eventLog;
55
+ this.lock = lock;
56
+ this.redisUrl = redisUrl;
57
+ this.log = log;
58
+ this.checkpoints = checkpoints;
59
+ this.subagents = subagents;
60
+ }
61
+ /**
62
+ * The `beforeTerminal` of an orphan repair: writes the run's open `agent` call results in `t`;
63
+ * `fire()` runs their observe hooks after the commit (review m1).
64
+ */
65
+ stopOpenCalls(runId) {
66
+ const sub = this.subagents;
67
+ if (!sub)
68
+ return { fire: () => { } };
69
+ let fire = () => { };
70
+ return {
71
+ beforeTerminal: async (t) => {
72
+ fire = (await sub.stopOpenCalls(t, runId)).fire;
73
+ },
74
+ fire: () => fire(),
75
+ };
76
+ }
77
+ /** The BullMQ queue `name` (default: conversation runs); both share one connection. */
78
+ getQueue(name = RUN_QUEUE_NAME) {
79
+ if (this.closed)
80
+ throw new Error("run queue is closed");
81
+ let queue = this.queues.get(name);
82
+ if (!queue) {
83
+ this.conn ??= bullConnection(this.redisUrl, this.log);
84
+ queue = new Queue(name, { connection: this.conn });
85
+ queue.on("error", (err) => this.log.error("run queue error", { err, queue: name }));
86
+ this.queues.set(name, queue);
87
+ }
88
+ return queue;
89
+ }
90
+ /**
91
+ * 有未消费的用户消息(最新 user_message 的 seq > `consumed_seq`)、会话锁无人持有、
92
+ * 且没有 queued / running / waiting 的运行时:插入 `runs`(queued)并投递任务,返回 runId;否则返回 null。
93
+ *
94
+ * 孤儿清理(R29,按需进行,没有定时器):已有的 queued / running 运行若 BullMQ 任务已不存在、
95
+ * 会话锁也无人持有(queued 的还要超过宽限期),说明没有任何 worker 会再执行它——写
96
+ * `run_failed { code: "run.orphaned" }` 把它标记为失败(consumed_seq 推进到它的触发消息),
97
+ * 再按常规判断是否起新一轮,并删除它的 checkpoint thread。会话因此不会永远卡在「有运行」。
98
+ * 除了写入消息后,打开 SSE、读事件、运行结束后也会调用它(幂等),孤儿因此在有人查看时就被清理。
99
+ *
100
+ * agent 已软删除的会话不起新运行(孤儿清理照常进行)。
101
+ */
102
+ async ensureRun(conversationId) {
103
+ if ((await this.lock.holder(conversationId)) !== null)
104
+ return null;
105
+ let orphanSeq = null;
106
+ let orphanRunId = null;
107
+ let dispatchedSeq = null;
108
+ let dispatchedSwitch = false;
109
+ /** The queue paused in this transaction: the open pages hear it after the commit. */
110
+ let pausedNow = false;
111
+ let orphanStop;
112
+ const created = await this.db.transaction().execute(async (t) => {
113
+ const conv = await t
114
+ .selectFrom("conversations")
115
+ .select(["consumed_seq", "agent_id", "kind", "queue_paused", "account_id"])
116
+ .where("id", "=", conversationId)
117
+ .forUpdate()
118
+ .executeTakeFirst();
119
+ // 评测回放的隐藏对话:运行由评测 worker 在里面直接驱动(工具只回放记录),绝不为它起真实运行
120
+ if (conv?.kind !== "chat")
121
+ return null;
122
+ let last = await t
123
+ .selectFrom("conversation_events")
124
+ .select(["seq", "payload"])
125
+ .where("conversation_id", "=", conversationId)
126
+ .where("type", "=", "user_message")
127
+ .orderBy("seq", "desc")
128
+ .limit(1)
129
+ .executeTakeFirst();
130
+ if (!last || Number(last.seq) <= Number(conv.consumed_seq)) {
131
+ // Nothing unconsumed: the queue's head goes out when the conversation is idle (no active
132
+ // run, which includes runs waiting for approval or an answer) and the queue is not paused.
133
+ // Interjections are always unconsumed messages, so the queue never jumps ahead of them.
134
+ if (conv.queue_paused || (await this.activeRun(t, conversationId)))
135
+ return null;
136
+ const owner = await t
137
+ .selectFrom("agents")
138
+ .select("deleted_at")
139
+ .where("id", "=", conv.agent_id)
140
+ .executeTakeFirstOrThrow();
141
+ if (owner.deleted_at !== null)
142
+ return null;
143
+ const head = await t
144
+ .selectFrom("conversation_queue")
145
+ .select("id")
146
+ .where("conversation_id", "=", conversationId)
147
+ .limit(1)
148
+ .executeTakeFirst();
149
+ if (!head)
150
+ return null;
151
+ // A queued message may wait for hours: it goes out only while its author can still use
152
+ // the conversation (active, a member, the agent visible to them; the isAccessible rule).
153
+ // Otherwise the queue pauses instead of posting as someone who lost access.
154
+ if (!(await authorCanSend(t, conversationId, conv.account_id))) {
155
+ await pauseQueueWith(t, conversationId, "author_cannot_send");
156
+ pausedNow = true;
157
+ this.log.warn("queued message not sent: its author can no longer use the conversation", {
158
+ conversationId,
159
+ });
160
+ return null;
161
+ }
162
+ const sent = await dispatchQueuedIn(t, this.eventLog, conversationId);
163
+ if (!sent)
164
+ return null;
165
+ if ("paused" in sent) {
166
+ pausedNow = true;
167
+ this.log.warn("queued skill invocation not sent: the skill can no longer be invoked", {
168
+ conversationId,
169
+ });
170
+ return null;
171
+ }
172
+ dispatchedSeq = sent.event.seq;
173
+ dispatchedSwitch = sent.switched;
174
+ last = { seq: String(sent.event.seq), payload: sent.event.payload };
175
+ }
176
+ const active = await this.activeRun(t, conversationId);
177
+ if (active) {
178
+ if (!(await this.isOrphan(conversationId, active, conv.kind)))
179
+ return null;
180
+ this.log.warn("marking orphaned run as failed", { conversationId, runId: active.id });
181
+ orphanRunId = active.id;
182
+ const stop = this.stopOpenCalls(active.id);
183
+ orphanStop = stop;
184
+ orphanSeq = await finishRunIn(t, this.eventLog, {
185
+ conversationId,
186
+ runId: active.id,
187
+ status: "failed",
188
+ consumed: null,
189
+ ...(stop.beforeTerminal !== undefined && { beforeTerminal: stop.beforeTerminal }),
190
+ event: {
191
+ type: "run_failed",
192
+ payload: {
193
+ error: { code: "run.orphaned", message: "The run was lost and will not continue" },
194
+ },
195
+ },
196
+ });
197
+ // 孤儿运行的触发消息已被消费:之后没有更新的消息就不起新一轮。
198
+ if (Number(last.seq) <= Math.max(Number(conv.consumed_seq), Number(active.trigger_seq))) {
199
+ return null;
200
+ }
201
+ }
202
+ // what is consumed now (an orphan's failure consumed up to its trigger)
203
+ const consumedNow = Math.max(Number(conv.consumed_seq), orphanRunId !== null && active ? Number(active.trigger_seq) : 0);
204
+ // phase D run boundary: the first unconsumed fork invocation is the trigger of the run that
205
+ // absorbs it (`forkBoundary`); later messages wait for the next run
206
+ const fork = await t
207
+ .selectFrom("conversation_events")
208
+ .select(["seq", "payload"])
209
+ .where("conversation_id", "=", conversationId)
210
+ .where("type", "=", "user_message")
211
+ .where("seq", ">", String(consumedNow))
212
+ .where(sql `payload -> 'skill' ->> 'mode' = 'fork'`)
213
+ .orderBy("seq")
214
+ .limit(1)
215
+ .executeTakeFirst();
216
+ const trigger = fork ?? last;
217
+ // BullMQ 对重复的 jobId 静默忽略(add 返回的 Job 由调用方数据构造,看不出是否真的入队):
218
+ // 先显式查同一触发点的任务;仍存在(例如属于刚结束、尚未从队列移除的运行)就不插入 runs 行。
219
+ const jobId = runJobId(conversationId, Number(trigger.seq));
220
+ const existing = await this.getQueue().getJob(jobId);
221
+ if (existing) {
222
+ this.log.warn("run job for this trigger already exists; not enqueuing", {
223
+ conversationId,
224
+ jobId,
225
+ existingRunId: existing.data?.runId,
226
+ });
227
+ return null;
228
+ }
229
+ const agent = await t
230
+ .selectFrom("agents")
231
+ .select(["current_version", "deleted_at"])
232
+ .where("id", "=", conv.agent_id)
233
+ .executeTakeFirstOrThrow();
234
+ // agent 已软删除:会话对任何人都不可见,不再为它起运行。
235
+ if (agent.deleted_at !== null)
236
+ return null;
237
+ const runId = randomUUID();
238
+ await t
239
+ .insertInto("runs")
240
+ .values({
241
+ id: runId,
242
+ conversation_id: conversationId,
243
+ status: "queued",
244
+ agent_version: agent.current_version,
245
+ trigger_account_id: trigger.payload.authorAccountId,
246
+ trigger_seq: Number(trigger.seq),
247
+ })
248
+ .execute();
249
+ return { runId, jobId };
250
+ });
251
+ if (orphanSeq !== null) {
252
+ await notifyFinished(this.eventLog, conversationId, orphanSeq, "failed");
253
+ orphanStop?.fire();
254
+ }
255
+ // a pause is published too (batch 5 review I1): the page shows the reason without a reload
256
+ if (pausedNow)
257
+ await this.eventLog.publishChanged(conversationId, "queue");
258
+ if (dispatchedSeq !== null) {
259
+ await this.eventLog.notify(conversationId, dispatchedSeq);
260
+ await this.eventLog.publishChanged(conversationId, "queue");
261
+ if (dispatchedSwitch)
262
+ await this.eventLog.publishChanged(conversationId, "selection");
263
+ }
264
+ if (orphanRunId !== null) {
265
+ await this.dropCheckpoints(orphanRunId);
266
+ // a lost parent stops its children now, not at the next sweep (review m2)
267
+ if (orphanSeq !== null) {
268
+ await this.subagents?.stopChildren(orphanRunId).catch((err) => this.log.error("cannot stop the sub-agents of an orphaned run", {
269
+ runId: orphanRunId,
270
+ err,
271
+ }));
272
+ }
273
+ }
274
+ if (!created)
275
+ return null;
276
+ const { runId, jobId } = created;
277
+ try {
278
+ const queue = this.getQueue();
279
+ await queue.add("run", { runId, conversationId }, { jobId, attempts: 1, removeOnComplete: true, removeOnFail: true });
280
+ // 从 Redis 读回核对:检查与 add 之间出现了同 jobId 的任务时 add 被静默忽略,撤销本次插入,
281
+ // 不留下没有任务的 queued 行。读不到说明任务已被领取并移除(只可能是本次投递的),不撤销。
282
+ const stored = await queue.getJob(jobId);
283
+ if (stored && stored.data.runId !== runId) {
284
+ this.log.warn("run job already queued for this trigger", {
285
+ conversationId,
286
+ runId,
287
+ existingRunId: stored.data.runId,
288
+ });
289
+ await this.deleteQueued(runId);
290
+ return null;
291
+ }
292
+ }
293
+ catch (err) {
294
+ // 投递失败:撤销 queued 行,避免会话卡在「有运行但没有任务」。
295
+ await this.deleteQueued(runId).catch(() => { });
296
+ throw err;
297
+ }
298
+ return runId;
299
+ }
300
+ /**
301
+ * Enqueues a run job under the caller's job id (resumes, dispatches, repairs), with the same
302
+ * options as {@link ensureRun}. The queue follows the conversation's kind (a sub-agent's runs go
303
+ * to {@link SUBAGENT_RUN_QUEUE_NAME}); pass `kind` when the caller knows it, else it is read.
304
+ */
305
+ async enqueue(data, jobId, kind) {
306
+ const k = kind ??
307
+ (await this.db
308
+ .selectFrom("conversations")
309
+ .select("kind")
310
+ .where("id", "=", data.conversationId)
311
+ .executeTakeFirst())?.kind ??
312
+ "chat";
313
+ await this.getQueue(runQueueNameFor(k)).add("run", data, {
314
+ jobId,
315
+ attempts: 1,
316
+ removeOnComplete: true,
317
+ removeOnFail: true,
318
+ });
319
+ }
320
+ /**
321
+ * 中止一个孤儿运行(`POST .../abort` 用):运行仍是 queued / running、会话锁无人持有、BullMQ 任务已不存在
322
+ * (queued 的还要超过宽限期,判定同 {@link ensureRun} 的孤儿清理)时,没有任何 worker 会收到中止广播——
323
+ * 直接写 `run_aborted`、status 置为 aborted、consumed_seq 至少推进到触发消息,返回 true。
324
+ * 不是孤儿(有人在执行或即将执行)或运行已结束 → 返回 false,由调用方走广播中止。
325
+ */
326
+ async abortIfOrphaned(conversationId, runId, byAccountId, detail) {
327
+ if ((await this.lock.holder(conversationId)) !== null)
328
+ return false;
329
+ const stop = this.stopOpenCalls(runId);
330
+ const toSeq = await this.db.transaction().execute(async (t) => {
331
+ const conv = await t
332
+ .selectFrom("conversations")
333
+ .select("kind")
334
+ .where("id", "=", conversationId)
335
+ .forUpdate()
336
+ .executeTakeFirst();
337
+ const active = await this.activeRun(t, conversationId);
338
+ if (!conv || !active || active.id !== runId)
339
+ return null;
340
+ if (!(await this.isOrphan(conversationId, active, conv.kind)))
341
+ return null;
342
+ this.log.warn("aborting orphaned run directly", { conversationId, runId });
343
+ return finishRunIn(t, this.eventLog, {
344
+ conversationId,
345
+ runId,
346
+ status: "aborted",
347
+ consumed: null,
348
+ ...(stop.beforeTerminal !== undefined && { beforeTerminal: stop.beforeTerminal }),
349
+ event: {
350
+ type: "run_aborted",
351
+ payload: { byAccountId, reason: "user", ...(detail !== undefined && { detail }) },
352
+ },
353
+ });
354
+ });
355
+ if (toSeq === null)
356
+ return false;
357
+ await notifyFinished(this.eventLog, conversationId, toSeq, "aborted");
358
+ stop.fire();
359
+ await this.dropCheckpoints(runId);
360
+ return true;
361
+ }
362
+ /**
363
+ * Repairs an orphaned run of a conversation nobody else repairs on demand (a sub-agent's: no
364
+ * `ensureRun` ever runs for it; sub-agents spec §7.5), with the same orphan test as
365
+ * {@link ensureRun}: the conversation lock is free, the run is still `queued` / `running`, its
366
+ * job is gone, and a `queued` one is past the grace period.
367
+ * - `queued` (the dispatch or resume committed, its enqueue was lost) → enqueued again under its
368
+ * own job id (`runs.job_id`, else the trigger's), so concurrent repairs on several replicas
369
+ * still leave one job: `"requeued"`;
370
+ * - `running` (its worker died without a terminal state and BullMQ dropped the job) → marked
371
+ * failed `run.orphaned`; the caller reports it to the parent: `"failed"`.
372
+ * Not an orphan, or already finished → null.
373
+ */
374
+ async repairOrphan(conversationId, runId) {
375
+ if ((await this.lock.holder(conversationId)) !== null)
376
+ return null;
377
+ const r = await this.db.transaction().execute(async (t) => {
378
+ const conv = await t
379
+ .selectFrom("conversations")
380
+ .select("kind")
381
+ .where("id", "=", conversationId)
382
+ .forUpdate()
383
+ .executeTakeFirst();
384
+ const active = await this.activeRun(t, conversationId);
385
+ if (!conv || !active || active.id !== runId)
386
+ return null;
387
+ if (!(await this.isOrphan(conversationId, active, conv.kind)))
388
+ return null;
389
+ if (active.status === "queued") {
390
+ const jobId = active.job_id ?? runJobId(conversationId, Number(active.trigger_seq));
391
+ return { kind: "requeued", jobId, convKind: conv.kind };
392
+ }
393
+ this.log.warn("marking orphaned run as failed", { conversationId, runId });
394
+ const seq = await finishRunIn(t, this.eventLog, {
395
+ conversationId,
396
+ runId,
397
+ status: "failed",
398
+ consumed: null,
399
+ event: {
400
+ type: "run_failed",
401
+ payload: {
402
+ error: { code: "run.orphaned", message: "The run was lost and will not continue" },
403
+ },
404
+ },
405
+ });
406
+ return { kind: "failed", seq };
407
+ });
408
+ if (!r)
409
+ return null;
410
+ if (r.kind === "requeued") {
411
+ await this.enqueue({ runId, conversationId }, r.jobId, r.convKind);
412
+ return "requeued";
413
+ }
414
+ if (r.seq !== null)
415
+ await notifyFinished(this.eventLog, conversationId, r.seq, "failed");
416
+ await this.dropCheckpoints(runId);
417
+ return "failed";
418
+ }
419
+ /** 会话当前未结束的运行(调用方已持有会话行锁)。 */
420
+ activeRun(t, conversationId) {
421
+ return t
422
+ .selectFrom("runs")
423
+ .select([
424
+ "id",
425
+ "status",
426
+ "trigger_seq",
427
+ "job_id",
428
+ sql `COALESCE(queued_at, created_at) < now() - make_interval(secs => ${ORPHAN_QUEUED_GRACE_SECONDS})`.as("past_grace"),
429
+ ])
430
+ .where("conversation_id", "=", conversationId)
431
+ .where("status", "in", ACTIVE_RUN_STATUSES)
432
+ .executeTakeFirst();
433
+ }
434
+ /**
435
+ * 未结束的运行是否已是孤儿(调用方已确认会话锁无人持有):waiting → 否(等人处理,本来就没有任务,
436
+ * 由人工决定或超时任务续跑);queued 且仍在宽限期内 → 否(任务可能还没投递);BullMQ 任务(续跑任务按
437
+ * `runs.job_id`)仍存在 → 否;否则是。
438
+ */
439
+ async isOrphan(conversationId, active, kind) {
440
+ if (active.status === "waiting")
441
+ return false;
442
+ if (active.status === "queued" && !active.past_grace)
443
+ return false;
444
+ const jobId = active.job_id ?? runJobId(conversationId, Number(active.trigger_seq));
445
+ const job = await this.getQueue(runQueueNameFor(kind)).getJob(jobId);
446
+ return !job;
447
+ }
448
+ /** 删除已结束运行的 checkpoint thread(失败只记日志)。 */
449
+ async dropCheckpoints(runId) {
450
+ await this.checkpoints
451
+ ?.deleteThread(runId)
452
+ .catch((err) => this.log.warn("checkpoint delete failed", { runId, err }));
453
+ }
454
+ async deleteQueued(runId) {
455
+ await this.db
456
+ .deleteFrom("runs")
457
+ .where("id", "=", runId)
458
+ .where("status", "=", "queued")
459
+ .execute();
460
+ }
461
+ async close() {
462
+ this.closed = true;
463
+ const qs = [...this.queues.values()];
464
+ const c = this.conn;
465
+ this.queues.clear();
466
+ this.conn = undefined;
467
+ await Promise.all(qs.map((q) => q.close().catch(() => { })));
468
+ if (c)
469
+ await c.quit().catch(() => c.disconnect());
470
+ }
471
+ }
472
+ /** The conversation's owner is active and can still see its agent (`isAccessible`'s rule). */
473
+ async function authorCanSend(t, conversationId, accountId) {
474
+ const row = await t
475
+ .selectFrom("conversations")
476
+ .select("conversations.id")
477
+ .where("conversations.id", "=", conversationId)
478
+ .where((eb) => eb.and([
479
+ eb.exists(eb
480
+ .selectFrom("accounts")
481
+ .select(sql `1`.as("one"))
482
+ .where("accounts.id", "=", accountId)
483
+ .where("accounts.status", "=", "active")),
484
+ eb.exists(eb
485
+ .selectFrom("agents")
486
+ .select(sql `1`.as("one"))
487
+ .whereRef("agents.id", "=", "conversations.agent_id")
488
+ .where("agents.deleted_at", "is", null)
489
+ .where(visibleTo(accountId))),
490
+ ]))
491
+ .executeTakeFirst();
492
+ return row !== undefined;
493
+ }
@@ -0,0 +1,138 @@
1
+ import type { Logger } from "@capybara-hq/plugin-sdk";
2
+ import { type Transaction } from "kysely";
3
+ import type { KernelConfig } from "../config/schema.js";
4
+ import type { EventLog } from "../conversations/event-log.js";
5
+ import type { KernelDatabase, KernelDb } from "../db/kernel-schema.js";
6
+ import type { SettingsService } from "../identity/settings.js";
7
+ import type { StorageService } from "../storage/storage.service.js";
8
+ import type { RunAbort } from "./abort.js";
9
+ import type { KyselyCheckpointSaver } from "./checkpointer.js";
10
+ import type { ConversationLock } from "./conversation-lock.js";
11
+ import type { AgentLoop } from "./loop.js";
12
+ import { type StreamSink } from "./model-call.js";
13
+ import { type ProviderRegistry } from "./providers.js";
14
+ import { type OrgQuota } from "./quota.js";
15
+ import { type RunQueue } from "./run-queue.js";
16
+ import type { Waits } from "./waits.js";
17
+ /** 测试钩子与参数。 */
18
+ export interface RunHooks {
19
+ /** 终态事件已写入、释放配额与会话锁之前调用(用于构造「运行结束瞬间到达的消息」)。 */
20
+ beforeRelease?(runId: string, conversationId: string): Promise<void>;
21
+ /** 会话锁 TTL(毫秒),默认 `runtime.jobLockMs`;测试调短以快速触发续租。 */
22
+ lockTtlMs?: number;
23
+ /** 任务结束后的每次 ensureRun 尝试之前调用(attempt 从 0 起);抛错即模拟该次尝试失败。 */
24
+ beforeEnsureRun?(conversationId: string, attempt: number): Promise<void>;
25
+ }
26
+ export interface RunWorkerDeps {
27
+ db: KernelDb;
28
+ eventLog: EventLog;
29
+ lock: ConversationLock;
30
+ quota: OrgQuota;
31
+ abort: RunAbort;
32
+ queue: Pick<RunQueue, "ensureRun">;
33
+ settings: Pick<SettingsService, "get">;
34
+ loop: AgentLoop;
35
+ config: () => KernelConfig;
36
+ log: Logger;
37
+ redisUrl: string;
38
+ /** 按会话取流式增量出口;默认丢弃。 */
39
+ sinkFor?: (conversationId: string) => StreamSink;
40
+ /** 运行到达终态后删除该运行(thread_id = runId)的 checkpoint thread(只用于续跑,结束后无用)。 */
41
+ checkpoints?: Pick<KyselyCheckpointSaver, "deleteThread">;
42
+ /** loop 返回 `suspended` 后把运行置为 waiting(释放会话锁与配额之后)。 */
43
+ waits: Pick<Waits, "suspend">;
44
+ /** 取得会话锁与配额、开始执行运行时调用(同步、不等待;渠道出站投递用它排投递任务)。 */
45
+ onRunStart?: (conversationId: string) => void;
46
+ /**
47
+ * A run reached `completed` (`run_finished`, any reason): called after the terminal event is
48
+ * written (sync, not awaited). The kernel enqueues the conversation's title job with it.
49
+ */
50
+ onRunCompleted?: (conversationId: string) => void;
51
+ hooks?: RunHooks;
52
+ /** Resolves a switched-to model at run start (fallback when it is gone; UI refresh B). */
53
+ models?: Pick<ProviderRegistry, "resolve">;
54
+ /** Object storage: run start reads the pinned skills' bodies from it (phase B). */
55
+ storage?: StorageService;
56
+ /**
57
+ * After a sub-agent run's terminal state committed (sub-agents spec §7.3; `onChildFinished`):
58
+ * reports it to the parent. Called with any run id whose conversation may be a child; it ignores
59
+ * runs that were not dispatched. Errors are logged (the wait sweep repairs a missed call).
60
+ */
61
+ onChildFinished?: (runId: string) => Promise<void>;
62
+ /**
63
+ * After any terminal commit of a run that is not a sub-agent's (sub-agents spec §12): stops its
64
+ * active children on its behalf (`stopChildren` with no account). The wait sweep is the backstop.
65
+ */
66
+ stopChildren?: (runId: string) => Promise<number>;
67
+ /**
68
+ * In the terminal transaction of every run: writes its open `agent` call results
69
+ * (`ToolPipeline.stopOpenAgentCalls`; a no-op without dispatches); `fire` runs their observe
70
+ * hooks after the commit (sub-agents spec §12, review m1: a failed or stalled parent too).
71
+ */
72
+ stopOpenCalls?: (t: Transaction<KernelDatabase>, runId: string) => Promise<{
73
+ fire: () => void;
74
+ }>;
75
+ }
76
+ /**
77
+ * 运行 worker(只在含 `worker` 角色的进程启动):领取 `cap-kernel-runs` 的任务,取会话锁与组织配额,
78
+ * 调用 AgentLoop,按结果写终态事件并推进 `consumed_seq`;结束后再调用一次 `ensureRun` 处理
79
+ * 运行期间到达但没被吸收的消息(Review Focus 2)。
80
+ */
81
+ export declare class RunWorker {
82
+ private readonly d;
83
+ /** One BullMQ worker per run queue: conversation runs and sub-agent runs (spec §7.4). */
84
+ private workers;
85
+ /** 传给 Worker 的连接:BullMQ 不关闭调用方传入的连接,close() 时自己关。 */
86
+ private conn;
87
+ private readonly active;
88
+ /** 进行中的「任务结束后」处理(完成后的 ensureRun、失败标记):停机时等它们做完再关闭队列。 */
89
+ private readonly followUps;
90
+ private closing;
91
+ /** close() 开始时触发:ensureRun 重试不再等待退避间隔。 */
92
+ private readonly closingSignal;
93
+ constructor(d: RunWorkerDeps);
94
+ start(): void;
95
+ /** Stops the active children of a finished run (see {@link RunWorkerDeps.stopChildren}). */
96
+ private stopChildren;
97
+ /** Reports a finished sub-agent run to its parent (see {@link RunWorkerDeps.onChildFinished}). */
98
+ private childFinished;
99
+ /**
100
+ * 任务结束后的 ensureRun,失败按 {@link ENSURE_RETRY_DELAYS_MS} 退避重试;停机开始后不再等待间隔
101
+ * (剩余的尝试立即进行,close() 以剩余预算为限等待)。全部失败只记日志,不抛出。
102
+ */
103
+ private ensureAfterRun;
104
+ /** 等待 ms 毫秒;停机开始时立即返回。 */
105
+ private retryDelay;
106
+ /** 登记一个任务结束后的处理,做完自动移除。 */
107
+ private track;
108
+ /**
109
+ * BullMQ 判定任务失败(R29):stalled 次数超过上限(持有者反复崩溃),或处理函数在自己的终态处理之外抛错。
110
+ * 运行若仍未结束:清理死去持有者留下的会话锁,写 `run_failed`(stalled → `run.stalled`,
111
+ * 其他 → `run.internal`),status 置为 failed,consumed_seq 至少推进到触发消息,删除 checkpoint,然后 ensureRun(带重试)。
112
+ */
113
+ private onJobFailed;
114
+ /**
115
+ * 优雅停机:停止领取新任务 → 向本进程的运行发停机信号(loop 在下一个步骤边界返回 `interrupted`,
116
+ * 任务回到队列)→ 在 budgetMs 内等它们结束。超出预算的运行放弃执行(停止续租会话锁、强制关闭
117
+ * worker,不再续任务锁),由 BullMQ 的 stalled 机制交给其他 worker 续跑。
118
+ */
119
+ close(budgetMs: number): Promise<void>;
120
+ private process;
121
+ private execute;
122
+ private completed;
123
+ /**
124
+ * When the conversation was switched to a model that no longer resolves (provider disabled,
125
+ * model removed), writes `model_switched { model: null, effort: null, reason: "unavailable" }`
126
+ * for this run (idempotent) and clears the cached selection: the run and the next ones use the
127
+ * agent's model. A provider that only failed to list its models is not "gone" (the run's ladder
128
+ * handles it).
129
+ */
130
+ private fallBackIfUnavailable;
131
+ /** 删除已结束运行的 checkpoint thread(失败只记日志)。 */
132
+ private dropCheckpoints;
133
+ /**
134
+ * 写终态(见 `finishRun`:运行仍未结束才写,同一事务内推进 `consumed_seq` 并更新 `runs.status`),
135
+ * 提交后发布会话通知,然后调用测试钩子。返回终态事件 seq;运行已是终态 → null。
136
+ */
137
+ private finish;
138
+ }