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

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 (312) hide show
  1. package/dist/admin/admin.controller.d.ts +9 -4
  2. package/dist/admin/admin.controller.js +13 -4
  3. package/dist/admin/extensions.controller.d.ts +8 -1
  4. package/dist/admin/extensions.controller.js +22 -2
  5. package/dist/agents/agent-lookup.d.ts +3 -0
  6. package/dist/agents/agent-lookup.js +20 -2
  7. package/dist/agents/agent-profile.service.d.ts +29 -0
  8. package/dist/agents/agent-profile.service.js +117 -0
  9. package/dist/agents/agents.controller.d.ts +93 -3
  10. package/dist/agents/agents.controller.js +114 -4
  11. package/dist/agents/agents.module.js +6 -2
  12. package/dist/agents/agents.service.d.ts +13 -5
  13. package/dist/agents/agents.service.js +49 -13
  14. package/dist/agents/definition.d.ts +35 -8
  15. package/dist/agents/definition.js +203 -17
  16. package/dist/agents/instruction-files.d.ts +60 -0
  17. package/dist/agents/instruction-files.js +111 -0
  18. package/dist/agents/models.controller.d.ts +9 -3
  19. package/dist/agents/models.controller.js +19 -4
  20. package/dist/agents/profile.d.ts +96 -0
  21. package/dist/agents/profile.js +51 -0
  22. package/dist/agents/readiness.controller.d.ts +26 -0
  23. package/dist/agents/readiness.controller.js +56 -0
  24. package/dist/agents/templates.js +20 -5
  25. package/dist/background/background.controller.d.ts +38 -0
  26. package/dist/background/background.controller.js +87 -0
  27. package/dist/background/background.module.d.ts +10 -0
  28. package/dist/background/background.module.js +32 -0
  29. package/dist/background/finish.d.ts +43 -0
  30. package/dist/background/finish.js +94 -0
  31. package/dist/background/launch-lock.d.ts +14 -0
  32. package/dist/background/launch-lock.js +39 -0
  33. package/dist/background/launch.d.ts +36 -0
  34. package/dist/background/launch.js +70 -0
  35. package/dist/background/poll.job.d.ts +53 -0
  36. package/dist/background/poll.job.js +182 -0
  37. package/dist/background/render.d.ts +23 -0
  38. package/dist/background/render.js +48 -0
  39. package/dist/background/session.d.ts +37 -0
  40. package/dist/background/session.js +66 -0
  41. package/dist/background/status.d.ts +35 -0
  42. package/dist/background/status.js +57 -0
  43. package/dist/background/stop.d.ts +62 -0
  44. package/dist/background/stop.js +225 -0
  45. package/dist/background/store.d.ts +150 -0
  46. package/dist/background/store.js +351 -0
  47. package/dist/background/store.module.d.ts +6 -0
  48. package/dist/background/store.module.js +22 -0
  49. package/dist/background/tasks.service.d.ts +67 -0
  50. package/dist/background/tasks.service.js +186 -0
  51. package/dist/background/wake-rules.d.ts +57 -0
  52. package/dist/background/wake-rules.js +83 -0
  53. package/dist/background/wake.d.ts +28 -0
  54. package/dist/background/wake.js +57 -0
  55. package/dist/catalog/catalog-content.js +4 -1
  56. package/dist/catalog/claude/agents.js +15 -10
  57. package/dist/catalog/marketplaces.service.d.ts +1 -1
  58. package/dist/catalog/plugin-import.js +1 -1
  59. package/dist/catalog/plugin-upgrade.js +1 -1
  60. package/dist/channels/cards.d.ts +8 -2
  61. package/dist/channels/cards.js +17 -9
  62. package/dist/channels/connections.service.d.ts +16 -1
  63. package/dist/channels/connections.service.js +38 -4
  64. package/dist/channels/threads.d.ts +5 -0
  65. package/dist/channels/threads.js +8 -0
  66. package/dist/config/schema.d.ts +18 -0
  67. package/dist/config/schema.js +104 -2
  68. package/dist/conversations/access.js +2 -0
  69. package/dist/conversations/artifacts.d.ts +1 -1
  70. package/dist/conversations/artifacts.js +1 -1
  71. package/dist/conversations/attachments.service.d.ts +30 -0
  72. package/dist/conversations/attachments.service.js +130 -5
  73. package/dist/conversations/conversations.controller.d.ts +36 -5
  74. package/dist/conversations/conversations.controller.js +62 -12
  75. package/dist/conversations/conversations.module.js +3 -0
  76. package/dist/conversations/conversations.service.d.ts +44 -2
  77. package/dist/conversations/conversations.service.js +140 -12
  78. package/dist/conversations/event-log.d.ts +12 -1
  79. package/dist/conversations/event-log.js +29 -1
  80. package/dist/conversations/events.d.ts +81 -3
  81. package/dist/conversations/events.js +83 -16
  82. package/dist/conversations/queue.d.ts +3 -1
  83. package/dist/conversations/queue.js +13 -2
  84. package/dist/conversations/queue.service.js +3 -1
  85. package/dist/conversations/titles.d.ts +7 -0
  86. package/dist/conversations/titles.js +15 -0
  87. package/dist/db/kernel-schema.d.ts +60 -4
  88. package/dist/db/pool.d.ts +5 -0
  89. package/dist/db/pool.js +3 -0
  90. package/dist/errors.d.ts +8 -0
  91. package/dist/errors.js +8 -0
  92. package/dist/evals/recorded-tools.d.ts +27 -1
  93. package/dist/evals/recorded-tools.js +85 -10
  94. package/dist/evals/run-replay.d.ts +10 -2
  95. package/dist/evals/run-replay.js +49 -12
  96. package/dist/evals/step-replay.js +12 -6
  97. package/dist/evals/trajectory.d.ts +2 -2
  98. package/dist/evals/trajectory.js +1 -1
  99. package/dist/extensions/admin-ops.js +2 -0
  100. package/dist/extensions/admin-view.d.ts +3 -1
  101. package/dist/extensions/admin-view.js +10 -2
  102. package/dist/extensions/blobs.js +1 -0
  103. package/dist/extensions/config-issues.d.ts +13 -1
  104. package/dist/extensions/config-issues.js +22 -5
  105. package/dist/extensions/config-json-schema.d.ts +43 -7
  106. package/dist/extensions/config-json-schema.js +124 -58
  107. package/dist/extensions/deployment-config-store.d.ts +6 -0
  108. package/dist/extensions/deployment-config.d.ts +50 -3
  109. package/dist/extensions/deployment-config.js +125 -28
  110. package/dist/extensions/display-name.d.ts +22 -0
  111. package/dist/extensions/display-name.js +77 -0
  112. package/dist/extensions/extensions.module.js +6 -0
  113. package/dist/extensions/host.d.ts +26 -1
  114. package/dist/extensions/host.js +82 -9
  115. package/dist/extensions/org-config.controller.d.ts +11 -3
  116. package/dist/extensions/org-config.controller.js +14 -6
  117. package/dist/extensions/org-config.d.ts +6 -0
  118. package/dist/extensions/org-config.js +12 -13
  119. package/dist/extensions/package.d.ts +14 -1
  120. package/dist/extensions/package.js +51 -2
  121. package/dist/extensions/permission-view.d.ts +3 -0
  122. package/dist/extensions/point-defaults.controller.d.ts +34 -0
  123. package/dist/extensions/point-defaults.controller.js +71 -0
  124. package/dist/extensions/point-defaults.d.ts +64 -0
  125. package/dist/extensions/point-defaults.js +206 -0
  126. package/dist/extensions/registry.d.ts +1 -1
  127. package/dist/extensions/registry.js +2 -0
  128. package/dist/http/api.module.js +8 -0
  129. package/dist/http/nest-logger.d.ts +6 -5
  130. package/dist/http/nest-logger.js +24 -10
  131. package/dist/identity/auth.controller.js +9 -5
  132. package/dist/identity/cookies.d.ts +20 -5
  133. package/dist/identity/cookies.js +44 -6
  134. package/dist/identity/me.controller.d.ts +5 -1
  135. package/dist/identity/me.controller.js +12 -3
  136. package/dist/identity/sessions.d.ts +12 -0
  137. package/dist/identity/sessions.js +45 -0
  138. package/dist/identity/settings.js +1 -1
  139. package/dist/index.d.ts +1 -1
  140. package/dist/infra/config/kernel-config.service.js +6 -0
  141. package/dist/infra/database/database.module.js +1 -0
  142. package/dist/infra/events/kernel-events.d.ts +8 -0
  143. package/dist/infra/lifecycle/process-guards.js +4 -0
  144. package/dist/infra/logging/logging.module.d.ts +4 -2
  145. package/dist/infra/logging/logging.module.js +24 -6
  146. package/dist/infra/queue/redis-connection.d.ts +6 -0
  147. package/dist/infra/queue/redis-connection.js +7 -0
  148. package/dist/infra/redis/redis.module.js +6 -2
  149. package/dist/infra/tokens.d.ts +6 -1
  150. package/dist/infra/tokens.js +6 -1
  151. package/dist/lifecycle/kernel-lifecycle.js +5 -0
  152. package/dist/log.d.ts +13 -1
  153. package/dist/log.js +93 -17
  154. package/dist/models/purposes.d.ts +23 -0
  155. package/dist/models/purposes.js +31 -10
  156. package/dist/orgs/offboarding.d.ts +3 -1
  157. package/dist/orgs/offboarding.js +26 -16
  158. package/dist/orgs/settings.service.d.ts +7 -2
  159. package/dist/orgs/settings.service.js +15 -4
  160. package/dist/roles/worker.module.js +6 -0
  161. package/dist/runtime/context/build.d.ts +15 -13
  162. package/dist/runtime/context/build.js +45 -27
  163. package/dist/runtime/context/claude-tools.d.ts +3 -1
  164. package/dist/runtime/context/claude-tools.js +12 -12
  165. package/dist/runtime/context/compaction.js +4 -0
  166. package/dist/runtime/context/legacy-text.d.ts +22 -0
  167. package/dist/runtime/context/legacy-text.js +37 -0
  168. package/dist/runtime/context/skills.d.ts +29 -11
  169. package/dist/runtime/context/skills.js +37 -30
  170. package/dist/runtime/langgraph-loop.js +3 -2
  171. package/dist/runtime/loop.d.ts +5 -4
  172. package/dist/runtime/maintenance.d.ts +4 -2
  173. package/dist/runtime/maintenance.js +17 -5
  174. package/dist/runtime/model-call.d.ts +17 -1
  175. package/dist/runtime/model-call.js +4 -3
  176. package/dist/runtime/providers.d.ts +6 -0
  177. package/dist/runtime/providers.js +8 -0
  178. package/dist/runtime/run-finish.d.ts +1 -1
  179. package/dist/runtime/run-queue.d.ts +28 -5
  180. package/dist/runtime/run-queue.js +131 -35
  181. package/dist/runtime/run-worker.d.ts +2 -2
  182. package/dist/runtime/run-worker.js +20 -7
  183. package/dist/runtime/runtime.module.js +8 -3
  184. package/dist/runtime/step-log.d.ts +6 -0
  185. package/dist/runtime/step-log.js +16 -2
  186. package/dist/runtime/subagents/definition.d.ts +1 -6
  187. package/dist/runtime/subagents/definition.js +14 -13
  188. package/dist/runtime/subagents/dispatch.d.ts +2 -2
  189. package/dist/runtime/subagents/dispatch.js +2 -2
  190. package/dist/runtime/subagents/org-agents.js +2 -1
  191. package/dist/runtime/subagents/roster.d.ts +1 -1
  192. package/dist/runtime/subagents/roster.js +1 -1
  193. package/dist/runtime/subagents/skill-fork.d.ts +2 -2
  194. package/dist/runtime/subagents/skill-fork.js +2 -2
  195. package/dist/runtime/subagents/subagents.service.d.ts +3 -3
  196. package/dist/runtime/subagents/subagents.service.js +3 -3
  197. package/dist/runtime/usage-report.d.ts +2 -1
  198. package/dist/runtime/usage-report.js +2 -1
  199. package/dist/runtime/waits.d.ts +13 -7
  200. package/dist/runtime/waits.js +42 -16
  201. package/dist/sandbox/sandbox.module.js +6 -1
  202. package/dist/sandbox/sandbox.service.d.ts +61 -3
  203. package/dist/sandbox/sandbox.service.js +141 -7
  204. package/dist/skills/catalog.d.ts +4 -4
  205. package/dist/skills/catalog.js +4 -4
  206. package/dist/skills/changes.service.d.ts +2 -2
  207. package/dist/skills/changes.service.js +5 -4
  208. package/dist/skills/invocation-keys.d.ts +1 -1
  209. package/dist/skills/invocation-keys.js +1 -1
  210. package/dist/skills/invoke.d.ts +1 -1
  211. package/dist/skills/invoke.js +5 -4
  212. package/dist/tools/approvals.service.d.ts +6 -0
  213. package/dist/tools/approvals.service.js +21 -1
  214. package/dist/tools/builtin-names.d.ts +91 -0
  215. package/dist/tools/builtin-names.js +143 -0
  216. package/dist/tools/builtins/agent.d.ts +7 -7
  217. package/dist/tools/builtins/agent.js +7 -11
  218. package/dist/tools/builtins/ask-user.d.ts +1 -1
  219. package/dist/tools/builtins/ask-user.js +2 -2
  220. package/dist/tools/builtins/builtin-tools.d.ts +17 -3
  221. package/dist/tools/builtins/builtin-tools.js +36 -4
  222. package/dist/tools/builtins/read-tool-output.d.ts +1 -1
  223. package/dist/tools/builtins/read-tool-output.js +2 -2
  224. package/dist/tools/builtins/sandbox/bash.d.ts +4 -4
  225. package/dist/tools/builtins/sandbox/bash.js +259 -29
  226. package/dist/tools/builtins/sandbox/common.d.ts +30 -7
  227. package/dist/tools/builtins/sandbox/common.js +9 -5
  228. package/dist/tools/builtins/sandbox/deliver.d.ts +1 -1
  229. package/dist/tools/builtins/sandbox/deliver.js +12 -12
  230. package/dist/tools/builtins/sandbox/edit.d.ts +1 -1
  231. package/dist/tools/builtins/sandbox/edit.js +41 -30
  232. package/dist/tools/builtins/sandbox/file-state.d.ts +34 -0
  233. package/dist/tools/builtins/sandbox/file-state.js +34 -0
  234. package/dist/tools/builtins/sandbox/glob-match.d.ts +1 -1
  235. package/dist/tools/builtins/sandbox/glob-match.js +1 -1
  236. package/dist/tools/builtins/sandbox/glob.d.ts +1 -1
  237. package/dist/tools/builtins/sandbox/glob.js +4 -4
  238. package/dist/tools/builtins/sandbox/grep.d.ts +7 -4
  239. package/dist/tools/builtins/sandbox/grep.js +147 -30
  240. package/dist/tools/builtins/sandbox/index.d.ts +3 -1
  241. package/dist/tools/builtins/sandbox/index.js +7 -1
  242. package/dist/tools/builtins/sandbox/read.d.ts +2 -2
  243. package/dist/tools/builtins/sandbox/read.js +21 -14
  244. package/dist/tools/builtins/sandbox/task-output.d.ts +63 -0
  245. package/dist/tools/builtins/sandbox/task-output.js +304 -0
  246. package/dist/tools/builtins/sandbox/task-stop.d.ts +10 -0
  247. package/dist/tools/builtins/sandbox/task-stop.js +112 -0
  248. package/dist/tools/builtins/sandbox/write.d.ts +1 -1
  249. package/dist/tools/builtins/sandbox/write.js +37 -33
  250. package/dist/tools/builtins/skill-load.d.ts +3 -3
  251. package/dist/tools/builtins/skill-load.js +32 -16
  252. package/dist/tools/builtins/skill-write.d.ts +4 -4
  253. package/dist/tools/builtins/skill-write.js +10 -10
  254. package/dist/tools/builtins/tool-search.d.ts +13 -9
  255. package/dist/tools/builtins/tool-search.js +25 -14
  256. package/dist/tools/builtins/web/errors.d.ts +8 -0
  257. package/dist/tools/builtins/web/errors.js +53 -0
  258. package/dist/tools/builtins/web/extract.d.ts +62 -0
  259. package/dist/tools/builtins/web/extract.js +267 -0
  260. package/dist/tools/builtins/web/fetch.d.ts +55 -0
  261. package/dist/tools/builtins/web/fetch.js +174 -0
  262. package/dist/tools/builtins/web/index.d.ts +13 -0
  263. package/dist/tools/builtins/web/index.js +12 -0
  264. package/dist/tools/builtins/web/page-cache.d.ts +25 -0
  265. package/dist/tools/builtins/web/page-cache.js +77 -0
  266. package/dist/tools/builtins/web/search.d.ts +25 -0
  267. package/dist/tools/builtins/web/search.js +209 -0
  268. package/dist/tools/builtins/web/url.d.ts +17 -0
  269. package/dist/tools/builtins/web/url.js +43 -0
  270. package/dist/tools/connectors.service.js +4 -4
  271. package/dist/tools/display-names.d.ts +9 -0
  272. package/dist/tools/display-names.js +24 -0
  273. package/dist/tools/drift.js +5 -5
  274. package/dist/tools/elicitation.js +1 -1
  275. package/dist/tools/info.d.ts +20 -4
  276. package/dist/tools/info.js +55 -32
  277. package/dist/tools/legacy-data.d.ts +34 -0
  278. package/dist/tools/legacy-data.js +76 -0
  279. package/dist/tools/legacy-keys.d.ts +51 -0
  280. package/dist/tools/legacy-keys.js +115 -0
  281. package/dist/tools/naming.d.ts +1 -5
  282. package/dist/tools/naming.js +1 -7
  283. package/dist/tools/oauth/flow-paths.d.ts +1 -1
  284. package/dist/tools/oauth/flow-paths.js +1 -1
  285. package/dist/tools/outputs.js +1 -1
  286. package/dist/tools/pipeline.d.ts +13 -7
  287. package/dist/tools/pipeline.js +112 -39
  288. package/dist/tools/policy.d.ts +1 -14
  289. package/dist/tools/policy.js +13 -19
  290. package/dist/tools/questions.controller.d.ts +1 -1
  291. package/dist/tools/questions.controller.js +1 -1
  292. package/dist/tools/questions.service.d.ts +1 -1
  293. package/dist/tools/registry.d.ts +38 -24
  294. package/dist/tools/registry.js +54 -47
  295. package/dist/tools/resources.d.ts +1 -1
  296. package/dist/tools/resources.js +1 -1
  297. package/dist/tools/tools.module.js +13 -1
  298. package/dist/tools/validate.js +1 -1
  299. package/package.json +3 -3
  300. package/src/migrations/0063_tool_keys_claude_code.sql +220 -0
  301. package/src/migrations/0064_account_last_org.sql +7 -0
  302. package/src/migrations/0065_conversation_archive.sql +8 -0
  303. package/src/migrations/0066_extension_display_name.sql +4 -0
  304. package/src/migrations/0067_agent_profiles.sql +20 -0
  305. package/src/migrations/0068_agent_avatar_uploads.sql +7 -0
  306. package/src/migrations/0069_attachments_agent_idx.sql +3 -0
  307. package/src/migrations/0070_background_tasks.sql +37 -0
  308. package/src/migrations/0071_background_tasks_reserve.sql +6 -0
  309. package/src/migrations/0072_background_tasks_stopping.sql +5 -0
  310. package/src/migrations/0073_org_extension_point_defaults.sql +11 -0
  311. package/dist/tools/builtins/sandbox/names.d.ts +0 -7
  312. package/dist/tools/builtins/sandbox/names.js +0 -20
@@ -0,0 +1,57 @@
1
+ import type { KernelSchemaDb } from "../db/kernel-schema.js";
2
+ /**
3
+ * The wake rules of a finished background task (spec 2026-11-05-background-bash-design §3), read
4
+ * by `RunQueue.ensureRun` in its transaction: every path that may start a run (a finish, the end of
5
+ * a run, the delayed wake job, a page opening) applies the same rules. `BackgroundWake` is what
6
+ * calls `ensureRun` when a task finishes.
7
+ */
8
+ /** No two wakes of one conversation start within this window. */
9
+ export declare const WAKE_WINDOW_MS = 60000;
10
+ /** The delayed job that wakes a conversation at the end of its window (`cap-kernel-maintenance`). */
11
+ export declare const BG_WAKE_JOB = "bg-wake";
12
+ /**
13
+ * Its job id: one job per conversation and window end (no `:`). `retry` > 0 is a job that fired
14
+ * before the window ended on the database's clock and scheduled itself again: a distinct id, since
15
+ * BullMQ ignores an add under the id of the job still running.
16
+ */
17
+ export declare const bgWakeJobId: (conversationId: string, windowEnd: number, retry?: number) => string;
18
+ export interface BgWakeJobData {
19
+ conversationId: string;
20
+ /** How many times this window's wake fired early (absent: none). */
21
+ retry?: number;
22
+ }
23
+ /**
24
+ * What a conversation's unconsumed finishes decide:
25
+ * - `wake`: start a run whose boundary is the finish at `seq`, as `triggerAccountId`;
26
+ * - `later`: a wake started less than {@link WAKE_WINDOW_MS} ago; the window ends at `windowEnd`
27
+ * (epoch ms, the database's clock), `delayMs` from now;
28
+ * - null: nothing wakes the conversation.
29
+ */
30
+ export type WakeDecision = {
31
+ kind: "wake";
32
+ seq: number;
33
+ triggerAccountId: string;
34
+ } | {
35
+ kind: "later";
36
+ windowEnd: number;
37
+ delayMs: number;
38
+ } | null;
39
+ /**
40
+ * The wake decision for a chat conversation that is idle, whose queue is not paused and has no
41
+ * unconsumed message (the caller checked these under the conversation's row lock). A finish
42
+ * wakes it when:
43
+ * - it is after `consumed`, not `reported` (a tool call already told the model) and has no
44
+ * `stoppedBy` (`"person"`: that person is looking at the conversation; `"deletion"`: the
45
+ * conversation is being deleted);
46
+ * - it belongs to a task of this conversation (the join on `conversation_id` reads the task's
47
+ * trigger account). A sub-agent's task is excluded by the conversation's kind, not here: its
48
+ * finish is in the child's log, and `ensureRun` never wakes a non-chat conversation;
49
+ * - the wake setting is on (the org's override, else `deploymentOn`);
50
+ * - the task's trigger account can still send to the conversation (`canSend`);
51
+ * - no other wake started in the last {@link WAKE_WINDOW_MS} (else `later`).
52
+ * The boundary is the newest finish whose trigger account can send.
53
+ */
54
+ export declare function wakeDecisionIn(t: KernelSchemaDb, conv: {
55
+ id: string;
56
+ orgId: string;
57
+ }, consumed: number, deploymentOn: boolean, canSend: (accountId: string) => Promise<boolean>): Promise<WakeDecision>;
@@ -0,0 +1,83 @@
1
+ import { sql } from "kysely";
2
+ import { effectiveWakeOnBackgroundTask, readOrgSettings } from "../orgs/settings.service.js";
3
+ /**
4
+ * The wake rules of a finished background task (spec 2026-11-05-background-bash-design §3), read
5
+ * by `RunQueue.ensureRun` in its transaction: every path that may start a run (a finish, the end of
6
+ * a run, the delayed wake job, a page opening) applies the same rules. `BackgroundWake` is what
7
+ * calls `ensureRun` when a task finishes.
8
+ */
9
+ /** No two wakes of one conversation start within this window. */
10
+ export const WAKE_WINDOW_MS = 60_000;
11
+ /** The delayed job that wakes a conversation at the end of its window (`cap-kernel-maintenance`). */
12
+ export const BG_WAKE_JOB = "bg-wake";
13
+ /**
14
+ * Its job id: one job per conversation and window end (no `:`). `retry` > 0 is a job that fired
15
+ * before the window ended on the database's clock and scheduled itself again: a distinct id, since
16
+ * BullMQ ignores an add under the id of the job still running.
17
+ */
18
+ export const bgWakeJobId = (conversationId, windowEnd, retry = 0) => `bg-wake-${conversationId}-${windowEnd}${retry > 0 ? `-r${retry}` : ""}`;
19
+ /** How many unconsumed finishes are tried for a trigger account that can still send. */
20
+ const CANDIDATES = 20;
21
+ /**
22
+ * The wake decision for a chat conversation that is idle, whose queue is not paused and has no
23
+ * unconsumed message (the caller checked these under the conversation's row lock). A finish
24
+ * wakes it when:
25
+ * - it is after `consumed`, not `reported` (a tool call already told the model) and has no
26
+ * `stoppedBy` (`"person"`: that person is looking at the conversation; `"deletion"`: the
27
+ * conversation is being deleted);
28
+ * - it belongs to a task of this conversation (the join on `conversation_id` reads the task's
29
+ * trigger account). A sub-agent's task is excluded by the conversation's kind, not here: its
30
+ * finish is in the child's log, and `ensureRun` never wakes a non-chat conversation;
31
+ * - the wake setting is on (the org's override, else `deploymentOn`);
32
+ * - the task's trigger account can still send to the conversation (`canSend`);
33
+ * - no other wake started in the last {@link WAKE_WINDOW_MS} (else `later`).
34
+ * The boundary is the newest finish whose trigger account can send.
35
+ */
36
+ export async function wakeDecisionIn(t, conv, consumed, deploymentOn, canSend) {
37
+ const candidates = await t
38
+ .selectFrom("conversation_events as e")
39
+ .innerJoin("background_tasks as b", (j) => j
40
+ .on(sql `b.id = e.payload ->> 'taskId'`)
41
+ .onRef("b.conversation_id", "=", "e.conversation_id"))
42
+ .select(["e.seq", "b.trigger_account_id"])
43
+ .where("e.conversation_id", "=", conv.id)
44
+ .where("e.type", "=", "background_task_finished")
45
+ .where("e.seq", ">", String(consumed))
46
+ .where(sql `(e.payload ->> 'reported')::boolean = false`)
47
+ .where(sql `e.payload ->> 'stoppedBy' IS NULL`)
48
+ .orderBy("e.seq", "desc")
49
+ .limit(CANDIDATES)
50
+ .execute();
51
+ if (candidates.length === 0)
52
+ return null;
53
+ const org = (await readOrgSettings(t, conv.orgId)).wakeOnBackgroundTask;
54
+ if (!effectiveWakeOnBackgroundTask(deploymentOn, org))
55
+ return null;
56
+ let boundary;
57
+ for (const c of candidates) {
58
+ if (await canSend(c.trigger_account_id)) {
59
+ boundary = { seq: Number(c.seq), triggerAccountId: c.trigger_account_id };
60
+ break;
61
+ }
62
+ }
63
+ if (boundary === undefined)
64
+ return null;
65
+ // the window starts when the last wake run was created (PG, so every replica reads the same)
66
+ const last = await t
67
+ .selectFrom("runs as r")
68
+ .innerJoin("conversation_events as w", (j) => j.onRef("w.conversation_id", "=", "r.conversation_id").onRef("w.seq", "=", "r.trigger_seq"))
69
+ .select([
70
+ sql `floor(extract(epoch from max(r.created_at)) * 1000)::bigint`.as("started"),
71
+ sql `floor(extract(epoch from now()) * 1000)::bigint`.as("now"),
72
+ ])
73
+ .where("r.conversation_id", "=", conv.id)
74
+ .where("w.type", "=", "background_task_finished")
75
+ .executeTakeFirst();
76
+ if (last?.started != null) {
77
+ const windowEnd = Number(last.started) + WAKE_WINDOW_MS;
78
+ const now = Number(last.now);
79
+ if (windowEnd > now)
80
+ return { kind: "later", windowEnd, delayMs: windowEnd - now };
81
+ }
82
+ return { kind: "wake", ...boundary };
83
+ }
@@ -0,0 +1,28 @@
1
+ import type { Logger } from "@capybara-hq/plugin-sdk";
2
+ import { type OnApplicationShutdown } from "@nestjs/common";
3
+ import { KernelEvents } from "../infra/events/kernel-events.js";
4
+ import { RunQueue } from "../runtime/run-queue.js";
5
+ /**
6
+ * Wakes an idle conversation when one of its background tasks finished (spec
7
+ * 2026-11-05-background-bash-design §3). {@link BackgroundTaskFinisher} announces the committed
8
+ * finish (`background_task.finished`, an in-process domain event: the finisher's module sits
9
+ * below the runtime); {@link onFinished} asks the run queue for a run. The wake rules themselves
10
+ * (own task, not reported, the wake setting, the queue not paused, the trigger account can still
11
+ * send, the 60 s window and its delayed `bg-wake` job) are applied by `RunQueue.ensureRun` in its
12
+ * transaction (`wakeDecisionIn`, ./wake-rules.ts), so a run's end, the delayed job and a page
13
+ * opening apply the same rules. Provided by `RuntimeModule`.
14
+ */
15
+ export declare class BackgroundWake implements OnApplicationShutdown {
16
+ private readonly runs;
17
+ private readonly log;
18
+ /** Drops the subscription (the events may outlive this instance). */
19
+ private readonly unsubscribe;
20
+ constructor(runs: Pick<RunQueue, "ensureRun">, events: KernelEvents, log: Pick<Logger, "warn">);
21
+ /**
22
+ * A task of `conversationId` finished (after the commit): starts a wake run when the rules
23
+ * allow it, or schedules one at the end of the wake window. A run in progress absorbs the finish
24
+ * at its next step instead, or its end starts the wake. Never throws.
25
+ */
26
+ onFinished(conversationId: string): Promise<void>;
27
+ onApplicationShutdown(): void;
28
+ }
@@ -0,0 +1,57 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
+ return function (target, key) { decorator(target, key, paramIndex); }
9
+ };
10
+ import { Inject, Injectable } from "@nestjs/common";
11
+ import { KernelEvents } from "../infra/events/kernel-events.js";
12
+ import { KERNEL_LOGGER } from "../infra/tokens.js";
13
+ import { RunQueue } from "../runtime/run-queue.js";
14
+ /**
15
+ * Wakes an idle conversation when one of its background tasks finished (spec
16
+ * 2026-11-05-background-bash-design §3). {@link BackgroundTaskFinisher} announces the committed
17
+ * finish (`background_task.finished`, an in-process domain event: the finisher's module sits
18
+ * below the runtime); {@link onFinished} asks the run queue for a run. The wake rules themselves
19
+ * (own task, not reported, the wake setting, the queue not paused, the trigger account can still
20
+ * send, the 60 s window and its delayed `bg-wake` job) are applied by `RunQueue.ensureRun` in its
21
+ * transaction (`wakeDecisionIn`, ./wake-rules.ts), so a run's end, the delayed job and a page
22
+ * opening apply the same rules. Provided by `RuntimeModule`.
23
+ */
24
+ let BackgroundWake = class BackgroundWake {
25
+ runs;
26
+ log;
27
+ /** Drops the subscription (the events may outlive this instance). */
28
+ unsubscribe;
29
+ constructor(runs, events, log) {
30
+ this.runs = runs;
31
+ this.log = log;
32
+ this.unsubscribe = events.on("background_task.finished", ({ conversationId }) => this.onFinished(conversationId));
33
+ }
34
+ /**
35
+ * A task of `conversationId` finished (after the commit): starts a wake run when the rules
36
+ * allow it, or schedules one at the end of the wake window. A run in progress absorbs the finish
37
+ * at its next step instead, or its end starts the wake. Never throws.
38
+ */
39
+ async onFinished(conversationId) {
40
+ try {
41
+ await this.runs.ensureRun(conversationId);
42
+ }
43
+ catch (err) {
44
+ this.log.warn("background task wake failed", { conversationId, err });
45
+ }
46
+ }
47
+ onApplicationShutdown() {
48
+ this.unsubscribe();
49
+ }
50
+ };
51
+ BackgroundWake = __decorate([
52
+ Injectable(),
53
+ __param(0, Inject(RunQueue)),
54
+ __param(1, Inject(KernelEvents)),
55
+ __param(2, Inject(KERNEL_LOGGER))
56
+ ], BackgroundWake);
57
+ export { BackgroundWake };
@@ -4,6 +4,7 @@
4
4
  // module whose provider injects PluginInstaller (an ESM import cycle would run decorators early).
5
5
  import { createHash } from "node:crypto";
6
6
  import { parseAgentTemplate, parseConnectorTemplateFile, } from "@capybara-hq/plugin-sdk";
7
+ import { normalizeToolKeys } from "../agents/definition.js";
7
8
  import { ApiError } from "../errors.js";
8
9
  import { can } from "../orgs/roles.js";
9
10
  import { packagePath } from "../packages/tgz.js";
@@ -318,6 +319,8 @@ export async function readCatalogAgentTemplates(storage, v) {
318
319
  if (!parsed || "errors" in parsed) {
319
320
  throw new ApiError("internal", `Stored agent template ${path} is missing or invalid`);
320
321
  }
321
- return { path, template: parsed.template };
322
+ // an rc package's template may name old builtins: read as the current names (tool naming
323
+ // spec §8.3); rc `<x>__<tool>` keys are read with the org's scope by `loadTemplates`
324
+ return { path, template: normalizeToolKeys(parsed.template) };
322
325
  });
323
326
  }
@@ -13,16 +13,21 @@ import { item } from "./report.js";
13
13
  export const GENERATED_AGENTS_DIR = ".capybara-generated/agents";
14
14
  /** Claude Code tool names -> Capybara tool keys (spec §16.4; anything else is dropped). */
15
15
  const TOOL_MAP = {
16
- Bash: "sandbox_bash",
17
- Read: "sandbox_read",
18
- Write: "sandbox_write",
19
- Edit: "sandbox_edit",
20
- MultiEdit: "sandbox_edit",
21
- Glob: "sandbox_glob",
22
- Grep: "sandbox_grep",
23
- Skill: "skill_load",
24
- TodoWrite: "todo__write",
25
- ToolSearch: "tool_search",
16
+ Bash: "Bash",
17
+ Read: "Read",
18
+ Write: "Write",
19
+ Edit: "Edit",
20
+ MultiEdit: "Edit",
21
+ Glob: "Glob",
22
+ Grep: "Grep",
23
+ Skill: "Skill",
24
+ AskUserQuestion: "AskUserQuestion",
25
+ ToolSearch: "ToolSearch",
26
+ Agent: "Agent",
27
+ Task: "Agent",
28
+ TodoWrite: "plugin__todo__write",
29
+ WebFetch: "WebFetch",
30
+ WebSearch: "WebSearch",
26
31
  };
27
32
  /** Claude ignores these for plugin agents: `not_applicable`. */
28
33
  const NOT_APPLICABLE = new Set(["permissionMode", "hooks", "mcpServers"]);
@@ -164,7 +164,7 @@ export declare function headsToResolve(entries: readonly MarketplaceEntry[], imp
164
164
  /** The host versions (an entry's `minKernel` is judged against them). */
165
165
  export declare const HOST_VERSIONS: {
166
166
  readonly kernel: string;
167
- readonly sdk: "0.1.0-rc.0";
167
+ readonly sdk: "0.1.0-rc.2";
168
168
  };
169
169
  /** Whether this deployment satisfies the entry's `minKernel`. */
170
170
  export declare const entryCompatible: (e: Pick<MarketplaceEntry, "minKernel">) => boolean;
@@ -33,8 +33,8 @@ import { KERNEL_LOGGER } from "../infra/tokens.js";
33
33
  import { packPackageTgz } from "../packages/tgz.js";
34
34
  import { checkSkillFiles, SkillArchiveError } from "../skills/package.js";
35
35
  import { StorageService } from "../storage/storage.service.js";
36
+ import { canonicalJson } from "../tools/canonical-json.js";
36
37
  import { endpointCredentialIssues } from "../tools/endpoint.js";
37
- import { canonicalJson } from "../tools/registry.js";
38
38
  import { findConnectorIn } from "./catalog-content.js";
39
39
  import { assertPluginNameOwner, catalogObjectPrefix, itemView, permissionsMismatch, precheckCatalogImport, putCatalogFiles, templateProblems, writeCatalogVersion, } from "./catalog-items.js";
40
40
  import { CLAUDE_PLUGIN_FILE, claudeContentDigest, } from "./claude/manifest.js";
@@ -24,8 +24,8 @@ import { OrgLock } from "../orgs/org-lock.js";
24
24
  import { packagePath } from "../packages/tgz.js";
25
25
  import { SkillsService, skillConflictError } from "../skills/skills.service.js";
26
26
  import { StorageService } from "../storage/storage.service.js";
27
+ import { canonicalJson } from "../tools/canonical-json.js";
27
28
  import { ConnectorsService } from "../tools/connectors.service.js";
28
- import { canonicalJson } from "../tools/registry.js";
29
29
  import { getPath, lockOrgForActions, orgTemplateView, readCatalogAgentTemplates, readCatalogFiles, readCatalogTemplates, requiredActions, setPath, skillOf, templatePluginProblem, } from "./catalog-content.js";
30
30
  import { catalogSkillNames, InstallFailure, journalEntries, missingTemplateInput, PluginInstaller, planActions, planSkillConflicts, resolveDependencies, under, } from "./plugin-install.js";
31
31
  import { assertItemInstallable, CatalogRequestsService } from "./requests.service.js";
@@ -1,6 +1,6 @@
1
- import type { ChannelCard, FormAnswer, InputForm, OutboundMessage } from "@capybara-hq/plugin-sdk";
1
+ import { type ChannelCard, type FormAnswer, type InputForm, type OutboundMessage } from "@capybara-hq/plugin-sdk";
2
2
  import type { KernelSchemaDb } from "../db/kernel-schema.js";
3
- import type { ApprovalsService } from "../tools/approvals.service.js";
3
+ import type { ApprovalsService, ApprovalView } from "../tools/approvals.service.js";
4
4
  import { type ChannelLocale } from "./phrases.js";
5
5
  /** 审批卡片里工具参数预览的最大长度(字符)。 */
6
6
  export declare const INPUT_PREVIEW_MAX = 500;
@@ -23,6 +23,12 @@ export declare function webBase(publicUrl: string | undefined): string | undefin
23
23
  export declare const conversationUrl: (base: string, conversationId: string) => string;
24
24
  /** 个人连接页里某个连接器的位置(与网页 ConnectCard 的链接一致)。 */
25
25
  export declare const connectUrl: (base: string, connectorId: string) => string;
26
+ /**
27
+ * The tool as the card names it (tool naming spec §7): a builtin by its name; a connector or
28
+ * extension tool as `<display name> [<tool>]` (the connector's name, the plugin's display name in
29
+ * the card's language), the way the web labels it.
30
+ */
31
+ export declare function approvalToolName(v: Pick<ApprovalView, "toolKey" | "toolName" | "connector" | "extension">, locale: ChannelLocale): string;
26
32
  export interface CardDeps {
27
33
  db: KernelSchemaDb;
28
34
  approvals: Pick<ApprovalsService, "describe">;
@@ -1,4 +1,4 @@
1
- import { KEY_SEPARATOR } from "../tools/naming.js";
1
+ import { parseToolKey, } from "@capybara-hq/plugin-sdk";
2
2
  import { phrase } from "./phrases.js";
3
3
  /** 审批卡片里工具参数预览的最大长度(字符)。 */
4
4
  export const INPUT_PREVIEW_MAX = 500;
@@ -83,13 +83,21 @@ export function webBase(publicUrl) {
83
83
  /** 会话的网页链接(与审批详情的 `conversationPath` 一致:`/chat/<id>`,不含语言前缀)。 */
84
84
  export const conversationUrl = (base, conversationId) => `${base}/chat/${conversationId}`;
85
85
  /** 个人连接页里某个连接器的位置(与网页 ConnectCard 的链接一致)。 */
86
- export const connectUrl = (base, connectorId) => `${base}/settings/connections#connector-${encodeURIComponent(connectorId)}`;
87
- /** 来源内的工具名:连接器工具去掉 `<slug>__`(审批详情已处理),插件工具去掉 `<插件>__`。 */
88
- function shortToolName(v) {
86
+ export const connectUrl = (base, connectorId) => `${base}/account/connections#connector-${encodeURIComponent(connectorId)}`;
87
+ /**
88
+ * The tool as the card names it (tool naming spec §7): a builtin by its name; a connector or
89
+ * extension tool as `<display name> [<tool>]` (the connector's name, the plugin's display name in
90
+ * the card's language), the way the web labels it.
91
+ */
92
+ export function approvalToolName(v, locale) {
93
+ // `toolName` is already the connector's own name for its tool
89
94
  if (v.connector)
90
- return v.toolName;
91
- const i = v.toolKey.indexOf(KEY_SEPARATOR);
92
- return i > 0 ? v.toolKey.slice(i + KEY_SEPARATOR.length) : v.toolKey;
95
+ return `${v.connector.name} [${v.toolName}]`;
96
+ const parsed = parseToolKey(v.toolKey);
97
+ const tool = parsed && parsed.kind !== "builtin" ? parsed.tool : v.toolName;
98
+ if (v.extension)
99
+ return `${v.extension.displayName[locale]} [${tool}]`;
100
+ return v.toolKey;
93
101
  }
94
102
  /** 账号显示名;不存在返回 undefined。 */
95
103
  async function displayName(db, accountId) {
@@ -115,8 +123,8 @@ export async function approvalCard(d, approvalId, base, locale, redact) {
115
123
  kind: "approval",
116
124
  id: v.id,
117
125
  title: phrase("approvalTitle", locale),
118
- toolName: shortToolName(v),
119
- ...(v.connector && { appName: v.connector.name }),
126
+ // the label carries the source, so no separate appName (renderers would repeat it)
127
+ toolName: approvalToolName(v, locale),
120
128
  agentName: v.agent.name || "Agent",
121
129
  inputPreview: inputPreview(v.input, redact),
122
130
  scopes: v.requestedFor === null ? ["once"] : ["once", "session", "always"],
@@ -106,6 +106,8 @@ export declare class ChannelConnections implements OnApplicationShutdown {
106
106
  private readonly log;
107
107
  readonly txHost: TransactionHost;
108
108
  private readonly unsubscribe;
109
+ /** `<plugin>@<version>` whose invalid connection hints were warned about (a log dedupe only). */
110
+ private readonly hintsWarned;
109
111
  constructor(db: KernelDb,
110
112
  /** The org row lock (orgs/org-lock.ts): joins the transaction of the write. */
111
113
  orgLock: Pick<OrgLock, "lockAndAuthorize">, keyring: Keyring, registry: Pick<ExtensionRegistry, "list">, bus: ExtensionContext["bus"], redis: Pick<Redis, "del">,
@@ -122,8 +124,21 @@ export declare class ChannelConnections implements OnApplicationShutdown {
122
124
  private channelEntry;
123
125
  /** The extension is not enabled in this organization -> `extension.not_enabled`. */
124
126
  private assertEnabled;
125
- /** `connectionSchema` 的 JSON Schema(同组织插件配置的转换:密钥字段带 `x-secret`、不输出取值)。 */
127
+ /**
128
+ * The connection schema's form JSON Schema (secret fields carry `x-secret`, no values), a copy.
129
+ * Never throws: when even the plain conversion fails, an empty object schema (a save is still
130
+ * validated here).
131
+ */
126
132
  jsonSchema(plugin: string): JsonSchema;
133
+ /**
134
+ * The connection schema's form JSON Schema; invalid hints are stripped and warned about once per
135
+ * `<plugin>@<version>` on this replica (spec §4.1: the connection level is checked at its first
136
+ * conversion, not at load). Never throws: a hint conversion that throws serves the plain schema,
137
+ * else null, with one warning per schema.
138
+ */
139
+ private formSchema;
140
+ /** The loaded version of a channel extension, for warnings ("unknown" when not provided). */
141
+ private versionOf;
127
142
  private parse;
128
143
  private verify;
129
144
  private reportSecrets;
@@ -16,7 +16,7 @@ import { queryEnabledPlugins } from "../ctx/create-ctx.js";
16
16
  import { createSecrets } from "../ctx/secrets.js";
17
17
  import { ApiError } from "../errors.js";
18
18
  import { toIssues } from "../extensions/config-issues.js";
19
- import { configToJsonSchema } from "../extensions/config-json-schema.js";
19
+ import { configMessages, describeConfigUiProblems, safeConfigFormSchema, } from "../extensions/config-json-schema.js";
20
20
  import { enabledExtensionsByOrg } from "../extensions/enabled.js";
21
21
  import { ExtensionRegistry } from "../extensions/registry.js";
22
22
  import { audit } from "../identity/audit.js";
@@ -121,6 +121,8 @@ let ChannelConnections = class ChannelConnections {
121
121
  log;
122
122
  txHost;
123
123
  unsubscribe;
124
+ /** `<plugin>@<version>` whose invalid connection hints were warned about (a log dedupe only). */
125
+ hintsWarned = new Set();
124
126
  constructor(db,
125
127
  /** The org row lock (orgs/org-lock.ts): joins the transaction of the write. */
126
128
  orgLock, keyring, registry, bus, redis,
@@ -171,14 +173,46 @@ let ChannelConnections = class ChannelConnections {
171
173
  throw new ApiError("extension.not_enabled", `Extension ${plugin} is not enabled for this organization`);
172
174
  }
173
175
  }
174
- /** `connectionSchema` 的 JSON Schema(同组织插件配置的转换:密钥字段带 `x-secret`、不输出取值)。 */
176
+ /**
177
+ * The connection schema's form JSON Schema (secret fields carry `x-secret`, no values), a copy.
178
+ * Never throws: when even the plain conversion fails, an empty object schema (a save is still
179
+ * validated here).
180
+ */
175
181
  jsonSchema(plugin) {
176
- return configToJsonSchema(this.channel(plugin).connectionSchema);
182
+ const entry = this.channelEntry(plugin);
183
+ const r = this.formSchema(plugin, entry.version, entry.impl.connectionSchema);
184
+ return r ? structuredClone(r.schema) : { type: "object" };
185
+ }
186
+ /**
187
+ * The connection schema's form JSON Schema; invalid hints are stripped and warned about once per
188
+ * `<plugin>@<version>` on this replica (spec §4.1: the connection level is checked at its first
189
+ * conversion, not at load). Never throws: a hint conversion that throws serves the plain schema,
190
+ * else null, with one warning per schema.
191
+ */
192
+ formSchema(plugin, version, schema) {
193
+ const r = safeConfigFormSchema(schema, "connection", (err, fallback) => this.log.warn("the channel connection form schema could not be built with its UI hints; hints dropped", { plugin, version, schema: fallback, err }));
194
+ const key = `${plugin}@${version}`;
195
+ if (r && r.problems.length > 0 && !this.hintsWarned.has(key)) {
196
+ this.hintsWarned.add(key);
197
+ this.log.warn("extension config UI hints are invalid and ignored", {
198
+ plugin,
199
+ version,
200
+ detail: describeConfigUiProblems("connection", r.problems),
201
+ });
202
+ }
203
+ return r;
204
+ }
205
+ /** The loaded version of a channel extension, for warnings ("unknown" when not provided). */
206
+ versionOf(plugin) {
207
+ return (this.registry
208
+ .list("channel")
209
+ .find((x) => x.plugin === plugin && x.capability === CHANNEL_EXTENSION_POINT)?.version ??
210
+ "unknown");
177
211
  }
178
212
  parse(plugin, schema, config) {
179
213
  const r = schema.safeParse(config);
180
214
  if (!r.success) {
181
- throw new ApiError("extension.config_invalid", `Invalid channel connection config for extension ${plugin}`, toIssues(r.error));
215
+ throw new ApiError("extension.config_invalid", `Invalid channel connection config for extension ${plugin}`, toIssues(r.error, configMessages(this.formSchema(plugin, this.versionOf(plugin), schema)?.schema)));
182
216
  }
183
217
  return r.data;
184
218
  }
@@ -48,3 +48,8 @@ export declare function findThread(db: KernelSchemaDb, k: ThreadKey): Promise<st
48
48
  export declare function insertThread(db: KernelSchemaDb, k: ThreadKey, conversationId: string): Promise<string>;
49
49
  /** 私聊 `/new`:归档当前话题行(下一条消息新建对话)。返回是否归档了一行。 */
50
50
  export declare function archiveThread(db: KernelSchemaDb, k: ThreadKey): Promise<boolean>;
51
+ /**
52
+ * Drops a conversation's channel bindings (its thread rows and its delivery target), so a deleted
53
+ * conversation neither receives inbound messages nor posts to the chat any more.
54
+ */
55
+ export declare function unbindConversation(db: KernelSchemaDb, conversationId: string): Promise<void>;
@@ -160,3 +160,11 @@ export async function archiveThread(db, k) {
160
160
  .executeTakeFirst();
161
161
  return r.numUpdatedRows > 0n;
162
162
  }
163
+ /**
164
+ * Drops a conversation's channel bindings (its thread rows and its delivery target), so a deleted
165
+ * conversation neither receives inbound messages nor posts to the chat any more.
166
+ */
167
+ export async function unbindConversation(db, conversationId) {
168
+ await db.deleteFrom("channel_threads").where("conversation_id", "=", conversationId).execute();
169
+ await db.deleteFrom("channel_deliveries").where("conversation_id", "=", conversationId).execute();
170
+ }
@@ -51,6 +51,7 @@ export declare const KernelConfigSchema: z.ZodObject<{
51
51
  url: z.ZodString;
52
52
  poolMax: z.ZodDefault<z.ZodNumber>;
53
53
  connectTimeoutMs: z.ZodDefault<z.ZodNumber>;
54
+ idleTimeoutMs: z.ZodDefault<z.ZodNumber>;
54
55
  }, z.core.$strip>>;
55
56
  redis: z.ZodPrefault<z.ZodObject<{
56
57
  url: z.ZodString;
@@ -119,6 +120,7 @@ export declare const KernelConfigSchema: z.ZodObject<{
119
120
  }, z.core.$strip>>;
120
121
  runtime: z.ZodDefault<z.ZodObject<{
121
122
  maxSteps: z.ZodDefault<z.ZodNumber>;
123
+ wakeOnBackgroundTask: z.ZodDefault<z.ZodBoolean>;
122
124
  maxRunSeconds: z.ZodDefault<z.ZodNumber>;
123
125
  streamIdleMs: z.ZodDefault<z.ZodNumber>;
124
126
  maxOutputTokens: z.ZodDefault<z.ZodNumber>;
@@ -179,11 +181,27 @@ export declare const KernelConfigSchema: z.ZodObject<{
179
181
  maxDispatchesPerRun: z.ZodDefault<z.ZodNumber>;
180
182
  maxTokensPerRun: z.ZodDefault<z.ZodNumber>;
181
183
  }, z.core.$strip>>;
184
+ web: z.ZodPrefault<z.ZodObject<{
185
+ search: z.ZodPrefault<z.ZodObject<{
186
+ maxResults: z.ZodDefault<z.ZodNumber>;
187
+ }, z.core.$strip>>;
188
+ fetch: z.ZodPrefault<z.ZodObject<{
189
+ maxPageChars: z.ZodDefault<z.ZodNumber>;
190
+ maxAnswerTokens: z.ZodDefault<z.ZodNumber>;
191
+ cacheSeconds: z.ZodDefault<z.ZodNumber>;
192
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
193
+ }, z.core.$strip>>;
194
+ }, z.core.$strip>>;
182
195
  sandbox: z.ZodPrefault<z.ZodObject<{
183
196
  image: z.ZodDefault<z.ZodString>;
184
197
  lockWaitSeconds: z.ZodDefault<z.ZodNumber>;
185
198
  maxConcurrentCommands: z.ZodDefault<z.ZodNumber>;
186
199
  deliverMaxBytes: z.ZodDefault<z.ZodNumber>;
200
+ background: z.ZodPrefault<z.ZodObject<{
201
+ maxTasks: z.ZodDefault<z.ZodNumber>;
202
+ maxSeconds: z.ZodDefault<z.ZodNumber>;
203
+ pollSeconds: z.ZodDefault<z.ZodNumber>;
204
+ }, z.core.$strip>>;
187
205
  limits: z.ZodPrefault<z.ZodObject<{
188
206
  cpu: z.ZodDefault<z.ZodNumber>;
189
207
  memoryMb: z.ZodDefault<z.ZodNumber>;