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

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 (631) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +20 -2
  4. package/bootstrap.json +22 -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 +1125 -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 +223 -0
  112. package/dist/config/schema.js +1151 -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 +422 -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 +150 -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 +210 -0
  166. package/dist/errors.js +212 -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 +789 -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 +149 -0
  210. package/dist/extensions/bootstrap.js +441 -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 +170 -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 +67 -0
  318. package/dist/index.js +65 -0
  319. package/dist/kernel.d.ts +256 -0
  320. package/dist/kernel.js +1326 -0
  321. package/dist/log.d.ts +48 -0
  322. package/dist/log.js +229 -0
  323. package/dist/models/prices.d.ts +53 -0
  324. package/dist/models/prices.js +121 -0
  325. package/dist/models/purposes.controller.d.ts +19 -0
  326. package/dist/models/purposes.controller.js +56 -0
  327. package/dist/models/purposes.d.ts +140 -0
  328. package/dist/models/purposes.js +267 -0
  329. package/dist/net/proxy.d.ts +44 -0
  330. package/dist/net/proxy.js +162 -0
  331. package/dist/net/public-address.d.ts +60 -0
  332. package/dist/net/public-address.js +271 -0
  333. package/dist/net/safe-fetch.d.ts +38 -0
  334. package/dist/net/safe-fetch.js +140 -0
  335. package/dist/orgs/directory-sync.controller.d.ts +14 -0
  336. package/dist/orgs/directory-sync.controller.js +40 -0
  337. package/dist/orgs/directory-sync.d.ts +166 -0
  338. package/dist/orgs/directory-sync.js +558 -0
  339. package/dist/orgs/invitations.controller.d.ts +58 -0
  340. package/dist/orgs/invitations.controller.js +137 -0
  341. package/dist/orgs/invitations.service.d.ts +80 -0
  342. package/dist/orgs/invitations.service.js +217 -0
  343. package/dist/orgs/members.service.d.ts +63 -0
  344. package/dist/orgs/members.service.js +234 -0
  345. package/dist/orgs/offboarding.d.ts +141 -0
  346. package/dist/orgs/offboarding.js +398 -0
  347. package/dist/orgs/org-lock.d.ts +32 -0
  348. package/dist/orgs/org-lock.js +46 -0
  349. package/dist/orgs/org.guard.d.ts +35 -0
  350. package/dist/orgs/org.guard.js +95 -0
  351. package/dist/orgs/orgs.controller.d.ts +78 -0
  352. package/dist/orgs/orgs.controller.js +192 -0
  353. package/dist/orgs/orgs.service.d.ts +61 -0
  354. package/dist/orgs/orgs.service.js +209 -0
  355. package/dist/orgs/roles.d.ts +13 -0
  356. package/dist/orgs/roles.js +58 -0
  357. package/dist/orgs/settings.controller.d.ts +20 -0
  358. package/dist/orgs/settings.controller.js +53 -0
  359. package/dist/orgs/settings.service.d.ts +120 -0
  360. package/dist/orgs/settings.service.js +178 -0
  361. package/dist/packages/npm.d.ts +50 -0
  362. package/dist/packages/npm.js +218 -0
  363. package/dist/packages/provenance.d.ts +47 -0
  364. package/dist/packages/provenance.js +147 -0
  365. package/dist/packages/tgz.d.ts +76 -0
  366. package/dist/packages/tgz.js +225 -0
  367. package/dist/runtime/abort.d.ts +32 -0
  368. package/dist/runtime/abort.js +71 -0
  369. package/dist/runtime/checkpointer.d.ts +32 -0
  370. package/dist/runtime/checkpointer.js +243 -0
  371. package/dist/runtime/context/build.d.ts +254 -0
  372. package/dist/runtime/context/build.js +693 -0
  373. package/dist/runtime/context/claude-tools.d.ts +11 -0
  374. package/dist/runtime/context/claude-tools.js +24 -0
  375. package/dist/runtime/context/compaction.d.ts +26 -0
  376. package/dist/runtime/context/compaction.js +195 -0
  377. package/dist/runtime/context/pairing.d.ts +11 -0
  378. package/dist/runtime/context/pairing.js +82 -0
  379. package/dist/runtime/context/reminders.d.ts +5 -0
  380. package/dist/runtime/context/reminders.js +11 -0
  381. package/dist/runtime/context/skills.d.ts +105 -0
  382. package/dist/runtime/context/skills.js +283 -0
  383. package/dist/runtime/context/tokens.d.ts +19 -0
  384. package/dist/runtime/context/tokens.js +104 -0
  385. package/dist/runtime/conversation-lock.d.ts +40 -0
  386. package/dist/runtime/conversation-lock.js +97 -0
  387. package/dist/runtime/hook-calls.d.ts +84 -0
  388. package/dist/runtime/hook-calls.js +136 -0
  389. package/dist/runtime/langgraph-loop.d.ts +52 -0
  390. package/dist/runtime/langgraph-loop.js +247 -0
  391. package/dist/runtime/loop.d.ts +93 -0
  392. package/dist/runtime/loop.js +7 -0
  393. package/dist/runtime/maintenance.d.ts +80 -0
  394. package/dist/runtime/maintenance.js +147 -0
  395. package/dist/runtime/media-cache.d.ts +21 -0
  396. package/dist/runtime/media-cache.js +51 -0
  397. package/dist/runtime/model-call.d.ts +176 -0
  398. package/dist/runtime/model-call.js +1049 -0
  399. package/dist/runtime/providers.d.ts +86 -0
  400. package/dist/runtime/providers.js +224 -0
  401. package/dist/runtime/quota.d.ts +29 -0
  402. package/dist/runtime/quota.js +70 -0
  403. package/dist/runtime/run-finish.d.ts +45 -0
  404. package/dist/runtime/run-finish.js +69 -0
  405. package/dist/runtime/run-queue.d.ts +121 -0
  406. package/dist/runtime/run-queue.js +493 -0
  407. package/dist/runtime/run-worker.d.ts +138 -0
  408. package/dist/runtime/run-worker.js +805 -0
  409. package/dist/runtime/stream.controller.d.ts +34 -0
  410. package/dist/runtime/stream.controller.js +122 -0
  411. package/dist/runtime/stream.d.ts +63 -0
  412. package/dist/runtime/stream.js +262 -0
  413. package/dist/runtime/subagents/child.d.ts +80 -0
  414. package/dist/runtime/subagents/child.js +225 -0
  415. package/dist/runtime/subagents/definition.d.ts +103 -0
  416. package/dist/runtime/subagents/definition.js +392 -0
  417. package/dist/runtime/subagents/dispatch.d.ts +69 -0
  418. package/dist/runtime/subagents/dispatch.js +502 -0
  419. package/dist/runtime/subagents/limits.d.ts +23 -0
  420. package/dist/runtime/subagents/limits.js +34 -0
  421. package/dist/runtime/subagents/org-agents.d.ts +50 -0
  422. package/dist/runtime/subagents/org-agents.js +70 -0
  423. package/dist/runtime/subagents/preamble.d.ts +7 -0
  424. package/dist/runtime/subagents/preamble.js +11 -0
  425. package/dist/runtime/subagents/progress.d.ts +26 -0
  426. package/dist/runtime/subagents/progress.js +36 -0
  427. package/dist/runtime/subagents/roster.d.ts +55 -0
  428. package/dist/runtime/subagents/roster.js +111 -0
  429. package/dist/runtime/subagents/skill-fork.d.ts +123 -0
  430. package/dist/runtime/subagents/skill-fork.js +259 -0
  431. package/dist/runtime/usage-report.d.ts +163 -0
  432. package/dist/runtime/usage-report.js +550 -0
  433. package/dist/runtime/waits.d.ts +233 -0
  434. package/dist/runtime/waits.js +883 -0
  435. package/dist/sandbox/leases.d.ts +169 -0
  436. package/dist/sandbox/leases.js +515 -0
  437. package/dist/sandbox/lifecycle.d.ts +21 -0
  438. package/dist/sandbox/lifecycle.js +68 -0
  439. package/dist/sandbox/sandbox.service.d.ts +249 -0
  440. package/dist/sandbox/sandbox.service.js +908 -0
  441. package/dist/skills/catalog.d.ts +149 -0
  442. package/dist/skills/catalog.js +405 -0
  443. package/dist/skills/changes.controller.d.ts +56 -0
  444. package/dist/skills/changes.controller.js +136 -0
  445. package/dist/skills/changes.service.d.ts +175 -0
  446. package/dist/skills/changes.service.js +805 -0
  447. package/dist/skills/invocable.controller.d.ts +23 -0
  448. package/dist/skills/invocable.controller.js +50 -0
  449. package/dist/skills/invocation-keys.d.ts +23 -0
  450. package/dist/skills/invocation-keys.js +44 -0
  451. package/dist/skills/invoke.d.ts +135 -0
  452. package/dist/skills/invoke.js +286 -0
  453. package/dist/skills/package.d.ts +87 -0
  454. package/dist/skills/package.js +227 -0
  455. package/dist/skills/skills.controller.d.ts +40 -0
  456. package/dist/skills/skills.controller.js +110 -0
  457. package/dist/skills/skills.service.d.ts +192 -0
  458. package/dist/skills/skills.service.js +567 -0
  459. package/dist/storage/prefix.d.ts +36 -0
  460. package/dist/storage/prefix.js +104 -0
  461. package/dist/storage/purge.d.ts +27 -0
  462. package/dist/storage/purge.js +75 -0
  463. package/dist/storage/storage.service.d.ts +44 -0
  464. package/dist/storage/storage.service.js +145 -0
  465. package/dist/text.d.ts +13 -0
  466. package/dist/text.js +13 -0
  467. package/dist/tools/approvals.controller.d.ts +53 -0
  468. package/dist/tools/approvals.controller.js +128 -0
  469. package/dist/tools/approvals.service.d.ts +172 -0
  470. package/dist/tools/approvals.service.js +568 -0
  471. package/dist/tools/breaker.d.ts +28 -0
  472. package/dist/tools/breaker.js +72 -0
  473. package/dist/tools/builtins/agent.d.ts +81 -0
  474. package/dist/tools/builtins/agent.js +223 -0
  475. package/dist/tools/builtins/ask-user.d.ts +28 -0
  476. package/dist/tools/builtins/ask-user.js +139 -0
  477. package/dist/tools/builtins/read-tool-output.d.ts +18 -0
  478. package/dist/tools/builtins/read-tool-output.js +108 -0
  479. package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
  480. package/dist/tools/builtins/sandbox/bash.js +137 -0
  481. package/dist/tools/builtins/sandbox/common.d.ts +114 -0
  482. package/dist/tools/builtins/sandbox/common.js +304 -0
  483. package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
  484. package/dist/tools/builtins/sandbox/deliver.js +180 -0
  485. package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
  486. package/dist/tools/builtins/sandbox/edit.js +98 -0
  487. package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
  488. package/dist/tools/builtins/sandbox/glob-match.js +240 -0
  489. package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
  490. package/dist/tools/builtins/sandbox/glob.js +104 -0
  491. package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
  492. package/dist/tools/builtins/sandbox/grep.js +133 -0
  493. package/dist/tools/builtins/sandbox/index.d.ts +12 -0
  494. package/dist/tools/builtins/sandbox/index.js +27 -0
  495. package/dist/tools/builtins/sandbox/names.d.ts +7 -0
  496. package/dist/tools/builtins/sandbox/names.js +20 -0
  497. package/dist/tools/builtins/sandbox/read.d.ts +8 -0
  498. package/dist/tools/builtins/sandbox/read.js +121 -0
  499. package/dist/tools/builtins/sandbox/write.d.ts +4 -0
  500. package/dist/tools/builtins/sandbox/write.js +88 -0
  501. package/dist/tools/builtins/skill-load.d.ts +53 -0
  502. package/dist/tools/builtins/skill-load.js +446 -0
  503. package/dist/tools/builtins/skill-write.d.ts +59 -0
  504. package/dist/tools/builtins/skill-write.js +244 -0
  505. package/dist/tools/builtins/tool-search.d.ts +31 -0
  506. package/dist/tools/builtins/tool-search.js +171 -0
  507. package/dist/tools/connector-content.controller.d.ts +34 -0
  508. package/dist/tools/connector-content.controller.js +78 -0
  509. package/dist/tools/connector-content.d.ts +104 -0
  510. package/dist/tools/connector-content.js +267 -0
  511. package/dist/tools/connectors.controller.d.ts +210 -0
  512. package/dist/tools/connectors.controller.js +234 -0
  513. package/dist/tools/connectors.service.d.ts +303 -0
  514. package/dist/tools/connectors.service.js +1102 -0
  515. package/dist/tools/credentials.d.ts +139 -0
  516. package/dist/tools/credentials.js +351 -0
  517. package/dist/tools/drift.d.ts +141 -0
  518. package/dist/tools/drift.js +539 -0
  519. package/dist/tools/elicitation.d.ts +81 -0
  520. package/dist/tools/elicitation.js +266 -0
  521. package/dist/tools/endpoint.d.ts +18 -0
  522. package/dist/tools/endpoint.js +115 -0
  523. package/dist/tools/info.d.ts +67 -0
  524. package/dist/tools/info.js +113 -0
  525. package/dist/tools/naming.d.ts +27 -0
  526. package/dist/tools/naming.js +47 -0
  527. package/dist/tools/oauth/discovery.d.ts +65 -0
  528. package/dist/tools/oauth/discovery.js +307 -0
  529. package/dist/tools/oauth/flow.d.ts +63 -0
  530. package/dist/tools/oauth/flow.js +237 -0
  531. package/dist/tools/oauth/oauth.controller.d.ts +31 -0
  532. package/dist/tools/oauth/oauth.controller.js +95 -0
  533. package/dist/tools/oauth/tokens.d.ts +111 -0
  534. package/dist/tools/oauth/tokens.js +258 -0
  535. package/dist/tools/outputs.d.ts +61 -0
  536. package/dist/tools/outputs.js +156 -0
  537. package/dist/tools/pipeline.d.ts +322 -0
  538. package/dist/tools/pipeline.js +1236 -0
  539. package/dist/tools/policy.d.ts +60 -0
  540. package/dist/tools/policy.js +236 -0
  541. package/dist/tools/questions.controller.d.ts +24 -0
  542. package/dist/tools/questions.controller.js +58 -0
  543. package/dist/tools/questions.service.d.ts +103 -0
  544. package/dist/tools/questions.service.js +295 -0
  545. package/dist/tools/redact.d.ts +20 -0
  546. package/dist/tools/redact.js +60 -0
  547. package/dist/tools/registry.d.ts +246 -0
  548. package/dist/tools/registry.js +481 -0
  549. package/dist/tools/resources.d.ts +16 -0
  550. package/dist/tools/resources.js +76 -0
  551. package/dist/tools/specs.d.ts +14 -0
  552. package/dist/tools/specs.js +31 -0
  553. package/dist/tools/validate.d.ts +20 -0
  554. package/dist/tools/validate.js +183 -0
  555. package/dist/tools/view.d.ts +43 -0
  556. package/dist/tools/view.js +225 -0
  557. package/dist/ui/embed-token.d.ts +31 -0
  558. package/dist/ui/embed-token.js +132 -0
  559. package/dist/ui/registry.d.ts +58 -0
  560. package/dist/ui/registry.js +90 -0
  561. package/dist/ui/ui-stream.d.ts +37 -0
  562. package/dist/ui/ui-stream.js +162 -0
  563. package/dist/ui/views.controller.d.ts +81 -0
  564. package/dist/ui/views.controller.js +261 -0
  565. package/dist/ui/views.d.ts +155 -0
  566. package/dist/ui/views.js +306 -0
  567. package/dist/version.d.ts +5 -0
  568. package/dist/version.js +6 -0
  569. package/package.json +67 -3
  570. package/src/migrations/0001_init.sql +8 -0
  571. package/src/migrations/0002_secrets.sql +8 -0
  572. package/src/migrations/0003_identity.sql +117 -0
  573. package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
  574. package/src/migrations/0005_agents.sql +27 -0
  575. package/src/migrations/0006_conversations.sql +37 -0
  576. package/src/migrations/0007_checkpoints.sql +26 -0
  577. package/src/migrations/0008_runs_trigger_seq.sql +3 -0
  578. package/src/migrations/0009_runs_active_unique.sql +4 -0
  579. package/src/migrations/0010_tools.sql +125 -0
  580. package/src/migrations/0011_approvals_spec.sql +10 -0
  581. package/src/migrations/0012_run_waits.sql +24 -0
  582. package/src/migrations/0013_app_tools_source.sql +4 -0
  583. package/src/migrations/0014_tool_specs.sql +8 -0
  584. package/src/migrations/0015_tool_drift.sql +20 -0
  585. package/src/migrations/0016_plugin_permissions.sql +11 -0
  586. package/src/migrations/0017_identity_sources.sql +6 -0
  587. package/src/migrations/0018_channels.sql +74 -0
  588. package/src/migrations/0019_identity_trust.sql +17 -0
  589. package/src/migrations/0020_channel_card_lookup.sql +10 -0
  590. package/src/migrations/0021_org_storage_purge.sql +9 -0
  591. package/src/migrations/0022_attachments.sql +29 -0
  592. package/src/migrations/0023_sandboxes.sql +37 -0
  593. package/src/migrations/0024_skills.sql +46 -0
  594. package/src/migrations/0025_skills_catalog_idx.sql +6 -0
  595. package/src/migrations/0026_skill_changes.sql +34 -0
  596. package/src/migrations/0027_model_prices.sql +18 -0
  597. package/src/migrations/0028_evals.sql +105 -0
  598. package/src/migrations/0029_model_purposes.sql +18 -0
  599. package/src/migrations/0030_plugin_installs.sql +73 -0
  600. package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
  601. package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
  602. package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
  603. package/src/migrations/0034_directory.sql +49 -0
  604. package/src/migrations/0035_catalogs.sql +40 -0
  605. package/src/migrations/0036_app_import_staging.sql +17 -0
  606. package/src/migrations/0037_directory_installs.sql +92 -0
  607. package/src/migrations/0038_channel_inbound_mode.sql +6 -0
  608. package/src/migrations/0039_channel_card_pending.sql +8 -0
  609. package/src/migrations/0040_usage_report_sweep.sql +10 -0
  610. package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
  611. package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
  612. package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
  613. package/src/migrations/0044_catalog_one_kind.sql +90 -0
  614. package/src/migrations/0045_plugin_dependencies.sql +9 -0
  615. package/src/migrations/0046_git_sources.sql +25 -0
  616. package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
  617. package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
  618. package/src/migrations/0049_plugin_upgrades.sql +37 -0
  619. package/src/migrations/0050_bootstrap.sql +53 -0
  620. package/src/migrations/0051_claude_compat.sql +26 -0
  621. package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
  622. package/src/migrations/0053_subagents.sql +73 -0
  623. package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
  624. package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
  625. package/src/migrations/0056_approval_reason.sql +3 -0
  626. package/src/migrations/0057_conversation_titles.sql +11 -0
  627. package/src/migrations/0058_conversation_selection.sql +4 -0
  628. package/src/migrations/0059_conversation_queue.sql +22 -0
  629. package/src/migrations/0060_file_previewers.sql +10 -0
  630. package/src/migrations/0061_queue_selection.sql +5 -0
  631. package/src/migrations/0062_queued_skill.sql +8 -0
@@ -0,0 +1,120 @@
1
+ import type { ChannelCard, InboundEvent, InboundSender, Logger } from "@capybara-hq/plugin-sdk";
2
+ import type { Redis } from "ioredis";
3
+ import type { ConversationsService } from "../conversations/conversations.service.js";
4
+ import type { KernelDb } from "../db/kernel-schema.js";
5
+ import type { IdentityBinding } from "../identity/binding.js";
6
+ import type { ExternalIdentities } from "../identity/external.js";
7
+ import type { ApprovalsService } from "../tools/approvals.service.js";
8
+ import type { QuestionsService } from "../tools/questions.service.js";
9
+ import type { ChannelConnectionRow, ChannelConnections } from "./connections.service.js";
10
+ import { type ChannelLocale, type ChannelPhrase } from "./phrases.js";
11
+ /** 入站消息去重键的保留时长(秒):平台在这段时间内重投同一条消息只处理一次。 */
12
+ export declare const MESSAGE_DEDUPE_TTL_SECONDS = 86400;
13
+ /** Dedupe key states: the enqueue is running (`pending`) or has succeeded (`done`). */
14
+ export declare const DEDUPE_PENDING = "pending";
15
+ export declare const DEDUPE_DONE = "done";
16
+ /** A `pending` key outlives a crashed enqueuer only this long, then redeliveries enqueue again. */
17
+ export declare const DEDUPE_PENDING_TTL_SECONDS = 60;
18
+ /** 入站消息去重键(Redis 键,不是队列名 / job id,可以含 `:`)。 */
19
+ export declare const messageDedupeKey: (connectionId: string, messageId: string) => string;
20
+ /** 带平台事件 id 的卡片点击的去重键(Ruling A26,Redis 键,可以含 `:`)。 */
21
+ export declare const actionDedupeKey: (connectionId: string, eventId: string) => string;
22
+ /** 通讯录同步的投递接口(实现见 orgs/directory-sync.ts:按 (组织, 插件) 每分钟去重的维护队列任务)。 */
23
+ export interface DirectorySyncScheduler {
24
+ /** 返回值(如 job id)不使用。 */
25
+ enqueue(orgId: string, plugin: string): Promise<unknown>;
26
+ }
27
+ /** 出站投递的投递接口(实现见 outbound.ts:把会话的新事件按 `channel_deliveries.last_seq` 续投到 IM)。 */
28
+ export interface ChannelOutboundScheduler {
29
+ enqueue(conversationId: string): Promise<void>;
30
+ }
31
+ /** 入站任务的投递接口(实现见 outbound.ts:同一队列 `cap-kernel-channels` 的 `inbound` 任务)。 */
32
+ export interface ChannelInboundQueue {
33
+ enqueueInbound(connectionId: string, event: InboundEvent, jobId: string): Promise<void>;
34
+ }
35
+ export interface ChannelInboundDeps {
36
+ db: KernelDb;
37
+ redis: Redis;
38
+ connections: Pick<ChannelConnections, "row" | "send">;
39
+ conversations: Pick<ConversationsService, "create" | "postUserMessage">;
40
+ external: Pick<ExternalIdentities, "findAccount">;
41
+ binding: Pick<IdentityBinding, "createBindToken">;
42
+ directorySync: DirectorySyncScheduler;
43
+ outbound: ChannelOutboundScheduler;
44
+ /** 入站任务队列(`onEvent` 只去重并入队,处理在 worker 上执行 {@link ChannelInbound.handle})。 */
45
+ queue: ChannelInboundQueue;
46
+ /** 卡片操作:审批决定与提问回答(授权由这两个服务按点击者映射到的账号判定)。 */
47
+ approvals: Pick<ApprovalsService, "decide">;
48
+ questions: Pick<QuestionsService, "answer">;
49
+ log: Pick<Logger, "warn" | "info">;
50
+ }
51
+ /**
52
+ * 渠道入站(Ruling A21:持久化处理)。
53
+ * - `onEvent`(插件 `connect` 的回调,必须快):消息按 `capk:channel-msg:<连接>:<消息>` `SET NX` 24 小时去重,
54
+ * 再排一个入站任务(`inbound-<连接>-<消息 id 哈希>`)后返回;入队失败删掉去重键并抛错(插件不确认,平台重投)。
55
+ * 带 `eventId` 的卡片操作同样按 `capk:channel-act:<连接>:<eventId>` 去重(任务 id 由 eventId 哈希,Ruling A26),
56
+ * 不带的直接入队(任务 id 随机);`directory_changed` 只是投递一个通讯录同步任务,就地完成。
57
+ * 返回即「内核已持久接收」:插件此后才向平台确认。
58
+ * - `handle`(worker 上执行入站任务):失败抛错由 BullMQ 指数退避重试(共 5 次;插件在本副本未加载时推迟、
59
+ * 回复报 auth / target_gone 时不重试);写用户消息带 `clientMessageId = "<连接>:<消息>"`,回复带由
60
+ * `<连接>-<消息 id>-reply` 哈希的幂等键,重试不会重复写 / 重复回复。步骤:
61
+ * 1. 连接停用、所属组织已删除或插件在该组织停用 → 什么都不做;群聊未 @ 机器人 → 忽略;
62
+ * 2. 发言人按 `<插件>:<租户>` + externalId 纯查找账号(不建账号、不合并),且须是连接所属组织的活跃成员;
63
+ * 否则按连接的未绑定策略:`bind` → 私聊回绑定卡片(群里只提示去私聊,绑定链接不能发在群里)、
64
+ * 已绑定但非成员回提示;`anonymous` → 仅当绑定的 agent 全组织可见、且发言人与连接同一租户时用该组织的
65
+ * 匿名访客(外部租户的人只能绑定),否则回提示。识别不出发言人时绝不借用连接创建者或任何人的身份;
66
+ * 3. 私聊 `/new` → 归档当前对话行并回「已开始新对话」;
67
+ * 4. 按话题找或建会话,写用户消息,记下投递目标并投递出站任务(Task 11)。A message whose text
68
+ * (bot mention stripped) is `/name args` is posted as a skill invocation (phase D spec §9): the
69
+ * same kernel path as the web, so the skill is resolved among the connection's agent's skills
70
+ * for the bound person; a refusal (`skill.not_invocable`: unknown, not user-invocable, gone
71
+ * since; `validation_failed`: over the limits) posts the text as typed, so nothing is lost.
72
+ * `directory_changed` → 投递通讯录同步(Task 12);`card_action` 见 actions.ts。
73
+ * 边界(已接受):同一 chat 的连续消息由不同任务并发处理,极少数情况下写入顺序可能与平台顺序不同;
74
+ * 处理在写入用户消息之后失败而重试时,固定话术 / 卡片回复可能再发一次。
75
+ */
76
+ export declare class ChannelInbound {
77
+ private readonly deps;
78
+ private readonly actions;
79
+ constructor(deps: ChannelInboundDeps);
80
+ /**
81
+ * 插件 `onEvent`:去重并入队后返回(见类注释)。返回后插件才向平台确认;抛错时插件不确认。
82
+ */
83
+ onEvent(connectionId: string, e: InboundEvent): Promise<void>;
84
+ /**
85
+ * Two-state dedupe, then enqueue (the key is `pending` while the enqueue runs, `done` after it):
86
+ * - fresh: `SET key pending NX EX 60`, enqueue, then `SET key done EX <dedupe TTL>`; on failure the
87
+ * key is deleted only if still `pending` (compare-and-delete) and the error is rethrown, so the
88
+ * plugin does not ack and the platform redelivers;
89
+ * - duplicate seeing `done`: already queued, return (the plugin acks);
90
+ * - duplicate seeing `pending` (the first enqueue is still running or hangs): enqueue again with the
91
+ * same deterministic job id and return only once that succeeds, else throw. BullMQ `add` with an
92
+ * existing job id is a no-op, and completed inbound jobs are retained (1 h / 1000), so this does
93
+ * not create a second run; it means a redelivery is never acked before the job is really queued.
94
+ */
95
+ private dedupeAndEnqueue;
96
+ /** 入站任务的处理(worker 上执行;失败抛错由队列重试)。 */
97
+ handle(connectionId: string, e: InboundEvent): Promise<void>;
98
+ private message;
99
+ /**
100
+ * Posts the person's message: `/name args` as a skill invocation when the kernel accepts it, else
101
+ * as typed (phase D spec §9). A retry of the job finds the first write by `clientMessageId`
102
+ * either way (an invocation input returns the written event before resolving the skill).
103
+ * `skillNotRun`: the skill was found but refused with `validation_failed` (too long), so the
104
+ * person is told it did not run (batch 4 review m2); an unknown command stays silent.
105
+ */
106
+ private post;
107
+ /**
108
+ * 第 3 步:发言人(或卡片点击者)→ 账号。按 `<插件>:<租户>` + externalId 纯查找,且须是该组织的活跃成员;
109
+ * 否则按连接的未绑定策略回复(绑定卡片只发在私聊里)并返回 undefined。
110
+ * `threadAccount` 为话题行记的账号(匿名访客为 null)。
111
+ */
112
+ resolveSpeaker(connectionId: string, row: ChannelConnectionRow, sender: InboundSender, isGroup: boolean, locale: ChannelLocale, reply: (key: ChannelPhrase, cards?: ChannelCard[]) => Promise<void>): Promise<{
113
+ accountId: string;
114
+ threadAccount: string | null;
115
+ } | undefined>;
116
+ /** 账号是该组织成员且账号未停用。 */
117
+ private isActiveMember;
118
+ /** 连接绑定的 agent 未删除且可见范围为「全组织」(匿名访客只能用这种 agent)。 */
119
+ private agentVisibleToOrg;
120
+ }
@@ -0,0 +1,332 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { ApiError } from "../errors.js";
3
+ import { readOrgSettings } from "../orgs/settings.service.js";
4
+ import { parseSlashCommand } from "../skills/invoke.js";
5
+ import { ChannelCardActions } from "./actions.js";
6
+ import { idempotencyKey, inboundJobId } from "./outbound.js";
7
+ import { phrase } from "./phrases.js";
8
+ import { archiveThread, ensureAnonymousGuest, findThread, insertThread, threadKeyOf, } from "./threads.js";
9
+ /** 入站消息去重键的保留时长(秒):平台在这段时间内重投同一条消息只处理一次。 */
10
+ export const MESSAGE_DEDUPE_TTL_SECONDS = 86_400;
11
+ /** Dedupe key states: the enqueue is running (`pending`) or has succeeded (`done`). */
12
+ export const DEDUPE_PENDING = "pending";
13
+ export const DEDUPE_DONE = "done";
14
+ /** A `pending` key outlives a crashed enqueuer only this long, then redeliveries enqueue again. */
15
+ export const DEDUPE_PENDING_TTL_SECONDS = 60;
16
+ /** Deletes KEYS[1] only while it still holds ARGV[1] (a failed enqueue must not drop `done`). */
17
+ const DEL_IF_PENDING = `if redis.call("GET", KEYS[1]) == ARGV[1] then
18
+ return redis.call("DEL", KEYS[1])
19
+ end
20
+ return 0`;
21
+ /** 入站消息去重键(Redis 键,不是队列名 / job id,可以含 `:`)。 */
22
+ export const messageDedupeKey = (connectionId, messageId) => `capk:channel-msg:${connectionId}:${messageId}`;
23
+ /** 带平台事件 id 的卡片点击的去重键(Ruling A26,Redis 键,可以含 `:`)。 */
24
+ export const actionDedupeKey = (connectionId, eventId) => `capk:channel-act:${connectionId}:${eventId}`;
25
+ /**
26
+ * 渠道入站(Ruling A21:持久化处理)。
27
+ * - `onEvent`(插件 `connect` 的回调,必须快):消息按 `capk:channel-msg:<连接>:<消息>` `SET NX` 24 小时去重,
28
+ * 再排一个入站任务(`inbound-<连接>-<消息 id 哈希>`)后返回;入队失败删掉去重键并抛错(插件不确认,平台重投)。
29
+ * 带 `eventId` 的卡片操作同样按 `capk:channel-act:<连接>:<eventId>` 去重(任务 id 由 eventId 哈希,Ruling A26),
30
+ * 不带的直接入队(任务 id 随机);`directory_changed` 只是投递一个通讯录同步任务,就地完成。
31
+ * 返回即「内核已持久接收」:插件此后才向平台确认。
32
+ * - `handle`(worker 上执行入站任务):失败抛错由 BullMQ 指数退避重试(共 5 次;插件在本副本未加载时推迟、
33
+ * 回复报 auth / target_gone 时不重试);写用户消息带 `clientMessageId = "<连接>:<消息>"`,回复带由
34
+ * `<连接>-<消息 id>-reply` 哈希的幂等键,重试不会重复写 / 重复回复。步骤:
35
+ * 1. 连接停用、所属组织已删除或插件在该组织停用 → 什么都不做;群聊未 @ 机器人 → 忽略;
36
+ * 2. 发言人按 `<插件>:<租户>` + externalId 纯查找账号(不建账号、不合并),且须是连接所属组织的活跃成员;
37
+ * 否则按连接的未绑定策略:`bind` → 私聊回绑定卡片(群里只提示去私聊,绑定链接不能发在群里)、
38
+ * 已绑定但非成员回提示;`anonymous` → 仅当绑定的 agent 全组织可见、且发言人与连接同一租户时用该组织的
39
+ * 匿名访客(外部租户的人只能绑定),否则回提示。识别不出发言人时绝不借用连接创建者或任何人的身份;
40
+ * 3. 私聊 `/new` → 归档当前对话行并回「已开始新对话」;
41
+ * 4. 按话题找或建会话,写用户消息,记下投递目标并投递出站任务(Task 11)。A message whose text
42
+ * (bot mention stripped) is `/name args` is posted as a skill invocation (phase D spec §9): the
43
+ * same kernel path as the web, so the skill is resolved among the connection's agent's skills
44
+ * for the bound person; a refusal (`skill.not_invocable`: unknown, not user-invocable, gone
45
+ * since; `validation_failed`: over the limits) posts the text as typed, so nothing is lost.
46
+ * `directory_changed` → 投递通讯录同步(Task 12);`card_action` 见 actions.ts。
47
+ * 边界(已接受):同一 chat 的连续消息由不同任务并发处理,极少数情况下写入顺序可能与平台顺序不同;
48
+ * 处理在写入用户消息之后失败而重试时,固定话术 / 卡片回复可能再发一次。
49
+ */
50
+ export class ChannelInbound {
51
+ deps;
52
+ actions;
53
+ constructor(deps) {
54
+ this.deps = deps;
55
+ this.actions = new ChannelCardActions({
56
+ db: deps.db,
57
+ connections: deps.connections,
58
+ approvals: deps.approvals,
59
+ questions: deps.questions,
60
+ outbound: deps.outbound,
61
+ resolveSpeaker: (...args) => this.resolveSpeaker(...args),
62
+ });
63
+ }
64
+ /**
65
+ * 插件 `onEvent`:去重并入队后返回(见类注释)。返回后插件才向平台确认;抛错时插件不确认。
66
+ */
67
+ async onEvent(connectionId, e) {
68
+ if (e.type === "directory_changed")
69
+ return this.handle(connectionId, e);
70
+ if (e.type === "card_action") {
71
+ if (e.eventId === undefined) {
72
+ // 平台没给事件 id:无法识别重投,每次都处理(重复的审批 / 回答由服务回「已处理」)
73
+ await this.deps.queue.enqueueInbound(connectionId, e, `inbound-${connectionId}-a${randomUUID()}`);
74
+ return;
75
+ }
76
+ return this.dedupeAndEnqueue(connectionId, e, actionDedupeKey(connectionId, e.eventId), inboundJobId(connectionId, `act:${e.eventId}`));
77
+ }
78
+ return this.dedupeAndEnqueue(connectionId, e, messageDedupeKey(connectionId, e.messageId), inboundJobId(connectionId, e.messageId));
79
+ }
80
+ /**
81
+ * Two-state dedupe, then enqueue (the key is `pending` while the enqueue runs, `done` after it):
82
+ * - fresh: `SET key pending NX EX 60`, enqueue, then `SET key done EX <dedupe TTL>`; on failure the
83
+ * key is deleted only if still `pending` (compare-and-delete) and the error is rethrown, so the
84
+ * plugin does not ack and the platform redelivers;
85
+ * - duplicate seeing `done`: already queued, return (the plugin acks);
86
+ * - duplicate seeing `pending` (the first enqueue is still running or hangs): enqueue again with the
87
+ * same deterministic job id and return only once that succeeds, else throw. BullMQ `add` with an
88
+ * existing job id is a no-op, and completed inbound jobs are retained (1 h / 1000), so this does
89
+ * not create a second run; it means a redelivery is never acked before the job is really queued.
90
+ */
91
+ async dedupeAndEnqueue(connectionId, e, key, jobId) {
92
+ const { redis, queue } = this.deps;
93
+ const fresh = await redis.set(key, DEDUPE_PENDING, "EX", DEDUPE_PENDING_TTL_SECONDS, "NX");
94
+ if (fresh !== "OK") {
95
+ const state = await redis.get(key);
96
+ // Ack only a known-queued event ("1" = key from the pre-two-state code during a rolling
97
+ // upgrade); pending, or a key that vanished meanwhile (failed attempt, TTL), enqueues again
98
+ if (state === DEDUPE_DONE || state === "1")
99
+ return;
100
+ }
101
+ // Accepted edge: if the completed-job cap evicts the original job within the pending window,
102
+ // the re-add below runs the event twice (a duplicate run, never a loss)
103
+ try {
104
+ await queue.enqueueInbound(connectionId, e, jobId);
105
+ }
106
+ catch (err) {
107
+ await redis.eval(DEL_IF_PENDING, 1, key, DEDUPE_PENDING).catch(() => { });
108
+ throw err;
109
+ }
110
+ await redis.set(key, DEDUPE_DONE, "EX", MESSAGE_DEDUPE_TTL_SECONDS);
111
+ }
112
+ /** 入站任务的处理(worker 上执行;失败抛错由队列重试)。 */
113
+ async handle(connectionId, e) {
114
+ if (e.type === "directory_changed") {
115
+ const row = await this.deps.connections.row(connectionId);
116
+ if (row?.status === "active" && row.pluginEnabled) {
117
+ await this.deps.directorySync.enqueue(row.orgId, row.plugin);
118
+ }
119
+ return;
120
+ }
121
+ if (e.type === "card_action") {
122
+ await this.actions.handle(connectionId, e);
123
+ return;
124
+ }
125
+ await this.message(connectionId, e);
126
+ }
127
+ async message(connectionId, e) {
128
+ const { db, connections } = this.deps;
129
+ const row = await connections.row(connectionId);
130
+ // 连接停用、组织已删除或插件在该组织停用(停用广播与长连接断开之间仍可能有事件到达):什么都不做
131
+ if (row?.status !== "active" || !row.pluginEnabled)
132
+ return;
133
+ const isGroup = e.target.chatType === "group";
134
+ if (isGroup && !e.mentionsBot)
135
+ return;
136
+ const threadKey = threadKeyOf(e.target, e.sender.externalId, e.messageId);
137
+ // 群里回在话题里(新话题以这条消息为根)
138
+ const replyTarget = isGroup ? { ...e.target, threadId: threadKey } : e.target;
139
+ const { locale } = await readOrgSettings(db, row.orgId);
140
+ // 回复带幂等键:任务重试时平台不会重复显示(一条消息至多一句回复)
141
+ const replyKey = idempotencyKey(`${connectionId}-${e.messageId}-reply`);
142
+ const reply = async (key, cards) => {
143
+ await connections.send(connectionId, replyTarget, { text: phrase(key, locale), ...(cards !== undefined && { cards }) }, replyKey);
144
+ };
145
+ const speaker = await this.resolveSpeaker(connectionId, row, e.sender, isGroup, locale, reply);
146
+ if (speaker === undefined)
147
+ return;
148
+ const { accountId, threadAccount } = speaker;
149
+ const k = {
150
+ connectionId,
151
+ chatId: e.target.chatId,
152
+ threadKey,
153
+ accountId: threadAccount,
154
+ };
155
+ if (!isGroup && e.text.trim().toLowerCase() === "/new") {
156
+ await archiveThread(db, k);
157
+ await reply("newConversation");
158
+ return;
159
+ }
160
+ let conversationId = await findThread(db, k);
161
+ if (conversationId === undefined) {
162
+ let created;
163
+ try {
164
+ created = (await this.deps.conversations.create(row.orgId, accountId, row.agentId)).id;
165
+ }
166
+ catch (err) {
167
+ if (err instanceof ApiError && err.code === "agent.not_found") {
168
+ await reply("agentUnavailable");
169
+ return;
170
+ }
171
+ throw err;
172
+ }
173
+ conversationId = await insertThread(db, k, created);
174
+ if (conversationId !== created) {
175
+ // 同一话题的另一条消息抢先建好了:删掉刚建、还没有任何事件的空会话
176
+ await db
177
+ .deleteFrom("conversations")
178
+ .where("id", "=", created)
179
+ .where("last_seq", "=", "0")
180
+ .execute();
181
+ }
182
+ }
183
+ let seq;
184
+ try {
185
+ const posted = await this.post(row.orgId, conversationId, accountId, {
186
+ text: e.text,
187
+ clientMessageId: `${connectionId}:${e.messageId}`,
188
+ });
189
+ seq = posted.event.seq;
190
+ // best-effort (batch 5 review m4): a failed note must not fail the job before the thread
191
+ // is bound for the agent's reply below
192
+ if (posted.skillNotRun) {
193
+ await reply("skillNotRun").catch((err) => this.deps.log.warn("cannot send the skill-not-run note", {
194
+ connectionId,
195
+ messageId: e.messageId,
196
+ err,
197
+ }));
198
+ }
199
+ }
200
+ catch (err) {
201
+ // agent 已对此人不可用(改了可见范围 / 已删除):会话按不存在处理
202
+ if (err instanceof ApiError && err.code === "conversation.not_found") {
203
+ await reply("agentUnavailable");
204
+ return;
205
+ }
206
+ throw err;
207
+ }
208
+ await db
209
+ .insertInto("channel_deliveries")
210
+ .values({
211
+ conversation_id: conversationId,
212
+ connection_id: connectionId,
213
+ target: JSON.stringify(replyTarget),
214
+ last_seq: seq,
215
+ })
216
+ .onConflict((oc) => oc.column("conversation_id").doUpdateSet({
217
+ connection_id: connectionId,
218
+ target: JSON.stringify(replyTarget),
219
+ updated_at: new Date(),
220
+ }))
221
+ .execute();
222
+ await this.deps.outbound.enqueue(conversationId);
223
+ }
224
+ /**
225
+ * Posts the person's message: `/name args` as a skill invocation when the kernel accepts it, else
226
+ * as typed (phase D spec §9). A retry of the job finds the first write by `clientMessageId`
227
+ * either way (an invocation input returns the written event before resolving the skill).
228
+ * `skillNotRun`: the skill was found but refused with `validation_failed` (too long), so the
229
+ * person is told it did not run (batch 4 review m2); an unknown command stays silent.
230
+ */
231
+ async post(orgId, conversationId, accountId, input) {
232
+ const cmd = parseSlashCommand(input.text.trimStart());
233
+ let skillNotRun = false;
234
+ if (cmd !== null) {
235
+ try {
236
+ const event = await this.deps.conversations.postUserMessage(orgId, conversationId, accountId, { ...input, text: cmd.args, skill: { name: cmd.name } });
237
+ return { event, skillNotRun };
238
+ }
239
+ catch (err) {
240
+ if (!(err instanceof ApiError) ||
241
+ (err.code !== "skill.not_invocable" && err.code !== "validation_failed")) {
242
+ throw err;
243
+ }
244
+ if (err.code === "validation_failed") {
245
+ skillNotRun = true;
246
+ this.deps.log.info("IM skill invocation posted as text", {
247
+ conversationId,
248
+ skill: cmd.name,
249
+ reason: err.message,
250
+ });
251
+ }
252
+ }
253
+ }
254
+ const event = await this.deps.conversations.postUserMessage(orgId, conversationId, accountId, input);
255
+ return { event, skillNotRun };
256
+ }
257
+ /**
258
+ * 第 3 步:发言人(或卡片点击者)→ 账号。按 `<插件>:<租户>` + externalId 纯查找,且须是该组织的活跃成员;
259
+ * 否则按连接的未绑定策略回复(绑定卡片只发在私聊里)并返回 undefined。
260
+ * `threadAccount` 为话题行记的账号(匿名访客为 null)。
261
+ */
262
+ async resolveSpeaker(connectionId, row, sender, isGroup, locale, reply) {
263
+ const { db } = this.deps;
264
+ const source = `${row.plugin}:${sender.tenantId}`;
265
+ const bound = await this.deps.external.findAccount(source, sender.externalId);
266
+ if (bound !== undefined && (await this.isActiveMember(row.orgId, bound))) {
267
+ return { accountId: bound, threadAccount: bound };
268
+ }
269
+ // 外部租户的人(外部联系人、共享频道里的其他企业,或连接还没有租户)只能绑定,不按匿名访客处理
270
+ const external = row.tenantId === null || sender.tenantId !== row.tenantId;
271
+ if (row.unboundPolicy === "anonymous" && !external) {
272
+ if (!(await this.agentVisibleToOrg(row.orgId, row.agentId))) {
273
+ await reply("anonymousNotAllowed");
274
+ return undefined;
275
+ }
276
+ return { accountId: await ensureAnonymousGuest(db, row.orgId), threadAccount: null };
277
+ }
278
+ if (bound !== undefined) {
279
+ await reply("notMember");
280
+ return undefined;
281
+ }
282
+ if (isGroup) {
283
+ await reply("bindInDm");
284
+ return undefined;
285
+ }
286
+ let url;
287
+ try {
288
+ url = await this.deps.binding.createBindToken({
289
+ connectionId,
290
+ identity: {
291
+ source,
292
+ externalId: sender.externalId,
293
+ tenantId: sender.tenantId,
294
+ emailVerified: false,
295
+ // 绑定确认页显示平台给的显示名(没有时用 externalId)
296
+ displayName: sender.displayName?.trim() || sender.externalId,
297
+ },
298
+ });
299
+ }
300
+ catch (err) {
301
+ this.deps.log.warn("cannot create channel bind link", { connectionId, err });
302
+ await reply("bindUnavailable");
303
+ return undefined;
304
+ }
305
+ await reply("bindPrompt", [{ kind: "bind", url, text: phrase("bindPrompt", locale) }]);
306
+ return undefined;
307
+ }
308
+ /** 账号是该组织成员且账号未停用。 */
309
+ async isActiveMember(orgId, accountId) {
310
+ const r = await this.deps.db
311
+ .selectFrom("memberships")
312
+ .innerJoin("accounts", "accounts.id", "memberships.account_id")
313
+ .select("memberships.role")
314
+ .where("memberships.org_id", "=", orgId)
315
+ .where("memberships.account_id", "=", accountId)
316
+ .where("accounts.status", "=", "active")
317
+ .executeTakeFirst();
318
+ return r !== undefined;
319
+ }
320
+ /** 连接绑定的 agent 未删除且可见范围为「全组织」(匿名访客只能用这种 agent)。 */
321
+ async agentVisibleToOrg(orgId, agentId) {
322
+ const r = await this.deps.db
323
+ .selectFrom("agents")
324
+ .select("id")
325
+ .where("id", "=", agentId)
326
+ .where("org_id", "=", orgId)
327
+ .where("visibility", "=", "org")
328
+ .where("deleted_at", "is", null)
329
+ .executeTakeFirst();
330
+ return r !== undefined;
331
+ }
332
+ }
@@ -0,0 +1,140 @@
1
+ import { type InboundEvent, type Logger } from "@capybara-hq/plugin-sdk";
2
+ import type { Redis } from "ioredis";
3
+ import type { KernelConfig } from "../config/schema.js";
4
+ import { type EventLog } from "../conversations/event-log.js";
5
+ import type { KernelDb } from "../db/kernel-schema.js";
6
+ import type { StreamBus } from "../runtime/stream.js";
7
+ import type { ApprovalsService } from "../tools/approvals.service.js";
8
+ import type { QuestionsService } from "../tools/questions.service.js";
9
+ import type { ChannelConnections } from "./connections.service.js";
10
+ import type { ChannelOutboundScheduler } from "./inbound.js";
11
+ import { type ChannelLocale } from "./phrases.js";
12
+ /** 渠道队列(出站投递与入站任务,不含 `:`),只在 worker 角色上消费。 */
13
+ export declare const CHANNEL_QUEUE_NAME = "cap-kernel-channels";
14
+ /** 投递任务名。 */
15
+ export declare const DELIVER_JOB = "deliver";
16
+ /** 投递任务 id(不含 `:`):同一会话、同一日志位置只排一个任务。 */
17
+ export declare const deliverJobId: (conversationId: string, seq: number) => string;
18
+ /**
19
+ * 结束后复核排的任务 id:每次唯一(带随机后缀,不含 `:`)。不能复用 `deliver-<会话>-<seq>`——同 id 的任务
20
+ * 可能正因锁被占而即将直接结束,BullMQ 会把新任务去重进它,于是没人投递。
21
+ */
22
+ export declare const followUpJobId: (conversationId: string, seq: number) => string;
23
+ /**
24
+ * 发给插件的幂等键(Ruling A15):把逻辑键(如 `<会话>-<seq>`)做 sha256,取 base64url 的前 32 个字符——
25
+ * 稳定、只含 `[A-Za-z0-9_-]`,满足常见平台的长度限制。
26
+ */
27
+ export declare function idempotencyKey(raw: string): string;
28
+ /**
29
+ * 投递锁被占时怎么办:读不到持有者(刚被释放)→ 再取一次;是自己上一次(已崩溃、被 stalled 重新投递)的尝试 →
30
+ * 推迟重试等它过期;别的任务 → 直接结束(它会读到新事件,结束时还会复核)。
31
+ */
32
+ export declare function busyLockAction(holder: string | null, owner: string): "retry" | "requeue" | "drop";
33
+ /** 草稿收尾的方式:运行失败加失败说明、中止加「已停止」,其余不改草稿内容。 */
34
+ export type DraftClosing = "failed" | "stopped" | "none";
35
+ /**
36
+ * 收尾草稿时写入的文本:`failed` / `stopped` 为「已有文本 + 空行 + 说明」(不知道已有文本时只有说明);
37
+ * `none` 返回 undefined(保留草稿原样,只清掉草稿 id)。
38
+ */
39
+ export declare function closingText(prior: string | undefined, how: DraftClosing, locale: ChannelLocale): string | undefined;
40
+ /** 按会话互斥的投递锁(Redis 键前缀;值为 `<job id>.<随机>`,TTL = `runtime.jobLockMs`)。 */
41
+ export declare const DELIVER_LOCK_PREFIX = "capk:channel-deliver:";
42
+ /** 草稿更新的最小间隔(毫秒);渠道声明了更大的 `features.minEditIntervalMs` 时取后者。 */
43
+ export declare const DRAFT_INTERVAL_MS = 1000;
44
+ /** 可重试失败(限流、5xx、网络、超时)的总尝试次数。 */
45
+ export declare const DELIVER_ATTEMPTS = 8;
46
+ /** 同一事件不可重试地失败这么多次后跳过它(Ruling A14)。 */
47
+ export declare const POISON_FAILURES = 3;
48
+ /** 入站任务名。 */
49
+ export declare const INBOUND_JOB = "inbound";
50
+ /**
51
+ * BullMQ 优先级(数字越小越先):入站任务先于出站投递任务——投递任务可能占着并发槽等输出,
52
+ * 用户发来的消息不能排在它们后面。
53
+ */
54
+ export declare const INBOUND_PRIORITY = 1;
55
+ export declare const DELIVER_PRIORITY = 10;
56
+ /** 入站任务的总尝试次数(处理失败由 BullMQ 指数退避重试:1s、2s、4s、8s)。 */
57
+ export declare const INBOUND_ATTEMPTS = 5;
58
+ /**
59
+ * 入站消息的任务 id(不含 `:`):`inbound-<连接>-<sha256(消息 id) 的 base64url 前 22 位>`。同一条消息只排一个任务
60
+ * (已完成的任务保留一段时间,期间重复入队被 BullMQ 忽略)。
61
+ */
62
+ export declare const inboundJobId: (connectionId: string, messageId: string) => string;
63
+ /** BullMQ 退避:平台给了等待时长就用它,否则指数退避。 */
64
+ export declare function deliverBackoff(attemptsMade: number, err?: Error): number;
65
+ export interface ChannelOutboundDeps {
66
+ db: KernelDb;
67
+ redis: Redis;
68
+ redisUrl: string;
69
+ bus: StreamBus;
70
+ eventLog: Pick<EventLog, "readAfter">;
71
+ connections: Pick<ChannelConnections, "outbound">;
72
+ approvals: Pick<ApprovalsService, "describe">;
73
+ questions: Pick<QuestionsService, "forCall">;
74
+ config: () => KernelConfig;
75
+ log: Pick<Logger, "error" | "warn" | "info">;
76
+ /** 入站任务的处理(worker 上执行 `ChannelInbound.handle`);失败抛错由 BullMQ 重试。 */
77
+ inbound?: (connectionId: string, e: InboundEvent) => Promise<void>;
78
+ }
79
+ /**
80
+ * 渠道出站投递:把会话日志里 `channel_deliveries.last_seq` 之后的内容按序投到 IM。
81
+ * - 生产方(任意角色):`enqueue(conversationId)` 投递 `deliver-<会话>-<当前 seq>` 任务(会话没有投递目标时什么都不做)。
82
+ * 内核在会话每次追加事件后都调用它(事件日志的 notify 钩子),运行开始时也调用。
83
+ * - Worker(只在 worker 角色):每个任务先取按会话互斥的投递锁,订阅 `conv.<id>` 后补读日志;运行进入 waiting /
84
+ * 终态且日志读完,或追上后 `channels.deliveryIdleMs` 内没有新的总线消息,任务就结束(不长期占并发槽)。
85
+ * 锁被别的任务持有 → 本任务直接结束:持有者会读到新事件,且它结束时(释放锁之后)复核日志是否有新内容,有就再排一个任务;
86
+ * 锁被自己上一次(已崩溃的)尝试占着 → 推迟重试,等锁过期。
87
+ * 崩溃后 BullMQ stalled 机制把任务交给其他副本,从 `last_seq` 续投;每投递一个事件就在同一事务里推进 `last_seq`
88
+ * 并记下 IM 消息 id(草稿 id、卡片消息 id),已投递的不会重发。
89
+ * 审批 / 提问卡片在发送之前先记一行 `pending`(T5a),卡片一出现就被点击也能通过 Ruling A13 的核对;
90
+ * 推进 `last_seq` 的事务再补上消息 id、改为 `sent`。崩溃后续投的副本用同一个幂等键重发。
91
+ * 同一队列还承载入站任务(`inbound`,Ruling A21):由 `enqueueInbound` 排入,worker 调用 `deps.inbound` 处理,
92
+ * 失败按 BullMQ 指数退避重试。
93
+ * 状态全部在 PG / Redis;进程内只有本任务自己的订阅、草稿节流时刻与等待定时器(本进程持有的资源)。
94
+ */
95
+ export declare class ChannelOutbound implements ChannelOutboundScheduler {
96
+ private readonly d;
97
+ private queue;
98
+ private queueConn;
99
+ private worker;
100
+ private workerConn;
101
+ private closed;
102
+ /** 停机:进行中的任务在下一个检查点交还队列(由其他副本续投)。 */
103
+ private readonly stopping;
104
+ private readonly lock;
105
+ constructor(d: ChannelOutboundDeps);
106
+ /** 会话有 IM 投递目标时投递一个出站任务(同一日志位置重复调用只排一个);已关闭时什么都不做。 */
107
+ enqueue(conversationId: string, opts?: {
108
+ followUp?: boolean;
109
+ }): Promise<void>;
110
+ /**
111
+ * 排一个入站任务(Ruling A21,同一队列 `cap-kernel-channels`):处理失败按 {@link INBOUND_ATTEMPTS} 次指数退避重试。
112
+ * 已关闭时抛错(调用方据此让插件不确认、由平台重投)。
113
+ */
114
+ enqueueInbound(connectionId: string, event: InboundEvent, jobId: string): Promise<void>;
115
+ /**
116
+ * 连接重新可投递(轮换了凭据 / 重新启用):给该连接投递进度落后于会话日志的会话各排一个出站任务,
117
+ * 补投停用或凭据失效期间落下的内容(不必等下一条消息)。
118
+ */
119
+ resumeConnection(connectionId: string): Promise<void>;
120
+ /** 启动 Worker(只在含 `worker` 角色的进程)。任务锁与 stalled 检测沿用运行队列的配置。 */
121
+ startWorker(): void;
122
+ close(): Promise<void>;
123
+ private getQueue;
124
+ private requeue;
125
+ private process;
126
+ /** 本副本没有加载连接的插件:推迟重试(不消耗重试次数),排队超过上限才放弃。 */
127
+ private pluginPending;
128
+ /**
129
+ * 入站任务:失败抛出由 BullMQ 重试;插件在本副本未加载 → 推迟重试(同出站);回复时插件报凭据失效 /
130
+ * 目标已不存在 → 不重试(`UnrecoverableError`)。最后一次也失败时记错误日志(消息丢失,平台已确认过)。
131
+ */
132
+ private processInbound;
133
+ private deliver;
134
+ /** 会话日志当前的最后位置(会话不存在时 undefined)。 */
135
+ private lastSeq;
136
+ /** 日志比 `seen` 更新时再排一个任务。 */
137
+ private followUp;
138
+ /** 不可重试(或重试用尽)的发送失败:记连接 `last_error`(已打码)。 */
139
+ private recordError;
140
+ }