@capybara-hq/kernel 0.1.0-rc.23 → 0.1.0-rc.25

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 (293) hide show
  1. package/bootstrap.json +25 -25
  2. package/dist/admin/admin.module.d.ts +2 -1
  3. package/dist/admin/admin.module.js +9 -3
  4. package/dist/admin/health.service.d.ts +2 -2
  5. package/dist/admin/health.service.js +6 -2
  6. package/dist/admin/outbox-dead.controller.d.ts +23 -0
  7. package/dist/admin/outbox-dead.controller.js +62 -0
  8. package/dist/admin/outbox-dead.schemas.d.ts +8 -0
  9. package/dist/admin/outbox-dead.schemas.js +18 -0
  10. package/dist/admin/outbox-dead.service.d.ts +66 -0
  11. package/dist/admin/outbox-dead.service.js +179 -0
  12. package/dist/admin/overview.service.d.ts +40 -5
  13. package/dist/admin/overview.service.js +41 -7
  14. package/dist/agents/agents.module.js +3 -0
  15. package/dist/agents/agents.service.d.ts +6 -1
  16. package/dist/agents/agents.service.js +11 -2
  17. package/dist/agents/from-template.js +1 -1
  18. package/dist/background/finish.d.ts +5 -2
  19. package/dist/background/finish.js +14 -3
  20. package/dist/background/launch.d.ts +2 -1
  21. package/dist/background/launch.js +5 -2
  22. package/dist/background/store.d.ts +8 -0
  23. package/dist/background/store.js +24 -0
  24. package/dist/catalog/admin-catalog.controller.d.ts +21 -2
  25. package/dist/catalog/admin-catalog.controller.js +45 -6
  26. package/dist/catalog/admin-catalog.schemas.d.ts +5 -0
  27. package/dist/catalog/admin-catalog.schemas.js +8 -0
  28. package/dist/catalog/catalog-import.module.js +0 -4
  29. package/dist/catalog/catalog-scope.service.d.ts +63 -26
  30. package/dist/catalog/catalog-scope.service.js +146 -71
  31. package/dist/catalog/catalog.module.d.ts +2 -1
  32. package/dist/catalog/catalog.module.js +9 -4
  33. package/dist/catalog/catalog.service.d.ts +11 -4
  34. package/dist/catalog/catalog.service.js +21 -5
  35. package/dist/catalog/cli.d.ts +4 -3
  36. package/dist/catalog/cli.js +8 -13
  37. package/dist/catalog/job-ids.d.ts +8 -20
  38. package/dist/catalog/job-ids.js +11 -16
  39. package/dist/catalog/marketplaces.service.d.ts +1 -1
  40. package/dist/catalog/org-plugin-uploads.d.ts +11 -4
  41. package/dist/catalog/org-plugin-uploads.js +21 -6
  42. package/dist/catalog/owned-items.d.ts +6 -13
  43. package/dist/catalog/owned-items.js +11 -29
  44. package/dist/catalog/owned-plugin-cleanup.d.ts +8 -17
  45. package/dist/catalog/owned-plugin-cleanup.js +12 -66
  46. package/dist/catalog/platform-components.d.ts +56 -34
  47. package/dist/catalog/platform-components.js +68 -78
  48. package/dist/catalog/platform-import-update.d.ts +50 -0
  49. package/dist/catalog/platform-import-update.js +116 -0
  50. package/dist/catalog/plugin-import.d.ts +64 -26
  51. package/dist/catalog/plugin-import.js +113 -77
  52. package/dist/catalog/plugin-upgrade.d.ts +22 -4
  53. package/dist/catalog/plugin-upgrade.js +26 -19
  54. package/dist/catalog/scope-jobs.d.ts +59 -0
  55. package/dist/catalog/scope-jobs.js +65 -0
  56. package/dist/catalog/scope-sync-workers.d.ts +22 -0
  57. package/dist/catalog/scope-sync-workers.js +58 -2
  58. package/dist/catalog/scope-sync.d.ts +40 -65
  59. package/dist/catalog/scope-sync.js +114 -122
  60. package/dist/channels/channels.module.d.ts +5 -2
  61. package/dist/channels/channels.module.js +9 -2
  62. package/dist/channels/deliver-job.d.ts +25 -0
  63. package/dist/channels/deliver-job.js +25 -0
  64. package/dist/channels/inbound.d.ts +1 -1
  65. package/dist/channels/inbound.js +4 -17
  66. package/dist/channels/jobs.d.ts +28 -18
  67. package/dist/channels/jobs.js +63 -26
  68. package/dist/channels/threads.d.ts +4 -3
  69. package/dist/channels/threads.js +4 -3
  70. package/dist/config/schema.d.ts +0 -3
  71. package/dist/config/schema.js +11 -20
  72. package/dist/conversations/agent-tree.d.ts +16 -0
  73. package/dist/conversations/agent-tree.js +36 -0
  74. package/dist/conversations/conversations.controller.js +4 -2
  75. package/dist/conversations/conversations.service.d.ts +61 -19
  76. package/dist/conversations/conversations.service.js +69 -43
  77. package/dist/conversations/event-log.d.ts +7 -10
  78. package/dist/conversations/event-log.js +24 -15
  79. package/dist/conversations/events.d.ts +21 -0
  80. package/dist/conversations/events.js +26 -2
  81. package/dist/conversations/queue.service.d.ts +8 -3
  82. package/dist/conversations/queue.service.js +37 -13
  83. package/dist/conversations/source.d.ts +10 -0
  84. package/dist/conversations/source.js +17 -0
  85. package/dist/conversations/titles.d.ts +21 -8
  86. package/dist/conversations/titles.js +42 -15
  87. package/dist/conversations/tree.d.ts +10 -0
  88. package/dist/conversations/tree.js +35 -0
  89. package/dist/db/kernel-schema.d.ts +35 -22
  90. package/dist/devices/devices.service.d.ts +23 -11
  91. package/dist/devices/devices.service.js +34 -26
  92. package/dist/errors.d.ts +11 -0
  93. package/dist/errors.js +11 -0
  94. package/dist/evals/run-replay.d.ts +13 -2
  95. package/dist/evals/run-replay.js +42 -9
  96. package/dist/evals/snapshot.d.ts +7 -1
  97. package/dist/evals/snapshot.js +2 -1
  98. package/dist/extensions/extensions.module.js +3 -0
  99. package/dist/extensions/hooks.d.ts +22 -3
  100. package/dist/extensions/hooks.js +15 -1
  101. package/dist/extensions/lifecycle-hooks.d.ts +99 -0
  102. package/dist/extensions/lifecycle-hooks.js +273 -0
  103. package/dist/extensions/lifecycle.d.ts +6 -1
  104. package/dist/extensions/lifecycle.js +9 -2
  105. package/dist/extensions/org-config.d.ts +13 -1
  106. package/dist/extensions/org-config.js +19 -2
  107. package/dist/extensions/permission-view.d.ts +9 -5
  108. package/dist/extensions/permission-view.js +9 -4
  109. package/dist/extensions/point-defaults.d.ts +28 -1
  110. package/dist/extensions/point-defaults.js +44 -13
  111. package/dist/extensions/usage-subscribers.d.ts +43 -0
  112. package/dist/extensions/usage-subscribers.js +108 -0
  113. package/dist/http/api.module.js +2 -0
  114. package/dist/inbox/inbox.service.d.ts +6 -20
  115. package/dist/inbox/inbox.service.js +0 -3
  116. package/dist/inbox/org-notices.d.ts +1 -1
  117. package/dist/inbox/platform-inbox.service.d.ts +3 -32
  118. package/dist/inbox/platform-inbox.service.js +5 -54
  119. package/dist/index.d.ts +1 -0
  120. package/dist/index.js +1 -0
  121. package/dist/infra/cli/kernel-cli.module.js +5 -0
  122. package/dist/infra/events/kernel-events.d.ts +9 -35
  123. package/dist/infra/outbox/outbox-relay.module.d.ts +6 -0
  124. package/dist/infra/outbox/outbox-relay.module.js +18 -0
  125. package/dist/infra/outbox/outbox.dispatcher.d.ts +103 -0
  126. package/dist/infra/outbox/outbox.dispatcher.js +310 -0
  127. package/dist/infra/outbox/outbox.module.d.ts +24 -0
  128. package/dist/infra/outbox/outbox.module.js +50 -0
  129. package/dist/infra/outbox/outbox.relay.d.ts +31 -0
  130. package/dist/infra/outbox/outbox.relay.js +76 -0
  131. package/dist/infra/outbox/outbox.service.d.ts +51 -0
  132. package/dist/infra/outbox/outbox.service.js +131 -0
  133. package/dist/infra/outbox/registry.d.ts +244 -0
  134. package/dist/infra/outbox/registry.js +234 -0
  135. package/dist/infra/queue/queue-names.d.ts +8 -0
  136. package/dist/infra/queue/queue-names.js +17 -0
  137. package/dist/kernel.module.js +3 -0
  138. package/dist/local-devices/device-policy.service.d.ts +4 -0
  139. package/dist/local-devices/device-policy.service.js +61 -3
  140. package/dist/local-devices/machines.d.ts +13 -5
  141. package/dist/local-devices/machines.js +45 -7
  142. package/dist/local-devices/policy-summary.d.ts +44 -1
  143. package/dist/local-devices/policy-summary.js +69 -0
  144. package/dist/models/embeddings.d.ts +9 -9
  145. package/dist/models/embeddings.js +11 -18
  146. package/dist/models/models.module.js +3 -0
  147. package/dist/orgs/directory-sync.js +1 -1
  148. package/dist/orgs/members.service.js +1 -1
  149. package/dist/orgs/offboarding.d.ts +50 -57
  150. package/dist/orgs/offboarding.js +117 -162
  151. package/dist/orgs/orgs.module.js +3 -0
  152. package/dist/orgs/orgs.service.d.ts +11 -5
  153. package/dist/orgs/orgs.service.js +22 -6
  154. package/dist/overrides.d.ts +23 -3
  155. package/dist/overrides.js +12 -2
  156. package/dist/platform/exclusions.js +5 -0
  157. package/dist/platform/ops/admin.ops.js +18 -2
  158. package/dist/platform/ops/catalog-admin.ops.d.ts +3 -1
  159. package/dist/platform/ops/catalog-admin.ops.js +32 -4
  160. package/dist/platform/ops/inbox.ops.js +4 -20
  161. package/dist/platform/ops/outbox.ops.d.ts +21 -0
  162. package/dist/platform/ops/outbox.ops.js +125 -0
  163. package/dist/platform/ops/platform.ops.d.ts +1 -0
  164. package/dist/platform/ops/platform.ops.js +6 -3
  165. package/dist/platform/ops/schedules.ops.js +40 -1
  166. package/dist/platform/platform-ops.module.d.ts +2 -1
  167. package/dist/platform/platform-ops.module.js +3 -0
  168. package/dist/platform/route-schemas.js +3 -0
  169. package/dist/roles/worker-role.d.ts +10 -5
  170. package/dist/roles/worker-role.js +19 -9
  171. package/dist/roles/worker.module.js +11 -8
  172. package/dist/runtime/context/build.d.ts +3 -0
  173. package/dist/runtime/context/build.js +15 -0
  174. package/dist/runtime/context/plugin-context.d.ts +20 -0
  175. package/dist/runtime/context/plugin-context.js +30 -0
  176. package/dist/runtime/langgraph-loop.js +17 -5
  177. package/dist/runtime/limits.d.ts +15 -0
  178. package/dist/runtime/limits.js +25 -0
  179. package/dist/runtime/loop.d.ts +16 -3
  180. package/dist/runtime/loop.js +2 -1
  181. package/dist/runtime/maintenance.d.ts +7 -3
  182. package/dist/runtime/maintenance.js +52 -12
  183. package/dist/runtime/model-call.d.ts +20 -17
  184. package/dist/runtime/model-call.js +15 -24
  185. package/dist/runtime/plugin-context.service.d.ts +69 -0
  186. package/dist/runtime/plugin-context.service.js +208 -0
  187. package/dist/runtime/queue-lost-jobs.d.ts +24 -0
  188. package/dist/runtime/queue-lost-jobs.js +51 -0
  189. package/dist/runtime/run-control.d.ts +47 -5
  190. package/dist/runtime/run-control.js +79 -12
  191. package/dist/runtime/run-finish.d.ts +39 -12
  192. package/dist/runtime/run-finish.js +97 -14
  193. package/dist/runtime/run-jobs.d.ts +95 -13
  194. package/dist/runtime/run-jobs.js +199 -28
  195. package/dist/runtime/run-orphan-check.job.d.ts +142 -0
  196. package/dist/runtime/run-orphan-check.job.js +339 -0
  197. package/dist/runtime/run-processors.d.ts +16 -9
  198. package/dist/runtime/run-processors.js +1 -1
  199. package/dist/runtime/run-queue.d.ts +75 -53
  200. package/dist/runtime/run-queue.js +189 -263
  201. package/dist/runtime/run-steps.d.ts +1 -2
  202. package/dist/runtime/run-steps.js +8 -11
  203. package/dist/runtime/run-worker.d.ts +26 -16
  204. package/dist/runtime/run-worker.js +132 -37
  205. package/dist/runtime/runtime.module.d.ts +2 -3
  206. package/dist/runtime/runtime.module.js +7 -6
  207. package/dist/runtime/step-log.d.ts +16 -4
  208. package/dist/runtime/step-log.js +26 -6
  209. package/dist/runtime/stream.controller.d.ts +2 -4
  210. package/dist/runtime/stream.controller.js +5 -11
  211. package/dist/runtime/subagents/child.js +1 -1
  212. package/dist/runtime/subagents/definition.d.ts +2 -1
  213. package/dist/runtime/subagents/definition.js +4 -2
  214. package/dist/runtime/subagents/deliveries.d.ts +6 -3
  215. package/dist/runtime/subagents/deliveries.js +16 -7
  216. package/dist/runtime/subagents/dispatch.d.ts +12 -12
  217. package/dist/runtime/subagents/dispatch.js +14 -38
  218. package/dist/runtime/subagents/messages.d.ts +5 -1
  219. package/dist/runtime/subagents/messages.js +11 -3
  220. package/dist/runtime/subagents/skill-fork.d.ts +3 -3
  221. package/dist/runtime/subagents/skill-fork.js +8 -5
  222. package/dist/runtime/subagents/subagents.service.js +1 -1
  223. package/dist/runtime/subagents/tree-jobs.d.ts +61 -0
  224. package/dist/runtime/subagents/tree-jobs.js +86 -0
  225. package/dist/runtime/usage-report-jobs.d.ts +23 -48
  226. package/dist/runtime/usage-report-jobs.js +67 -119
  227. package/dist/runtime/usage-report.d.ts +28 -77
  228. package/dist/runtime/usage-report.js +35 -213
  229. package/dist/runtime/waits.d.ts +48 -198
  230. package/dist/runtime/waits.js +103 -805
  231. package/dist/sandbox/jobs.d.ts +20 -10
  232. package/dist/sandbox/jobs.js +23 -17
  233. package/dist/sandbox/sandbox.service.d.ts +17 -4
  234. package/dist/sandbox/sandbox.service.js +55 -14
  235. package/dist/schedules/calendar.d.ts +134 -0
  236. package/dist/schedules/calendar.js +410 -0
  237. package/dist/schedules/fire.d.ts +26 -7
  238. package/dist/schedules/fire.js +91 -22
  239. package/dist/schedules/job-ids.d.ts +66 -17
  240. package/dist/schedules/job-ids.js +81 -13
  241. package/dist/schedules/run-tracker.d.ts +0 -5
  242. package/dist/schedules/run-tracker.js +2 -14
  243. package/dist/schedules/scan.job.d.ts +13 -32
  244. package/dist/schedules/scan.job.js +50 -164
  245. package/dist/schedules/schedule-math.d.ts +42 -0
  246. package/dist/schedules/schedule-math.js +52 -0
  247. package/dist/schedules/scheduled-tasks.service.d.ts +22 -6
  248. package/dist/schedules/scheduled-tasks.service.js +70 -14
  249. package/dist/schedules/schedules.controller.d.ts +5 -1
  250. package/dist/schedules/schedules.controller.js +15 -1
  251. package/dist/schedules/schedules.module.js +0 -4
  252. package/dist/schedules/schedules.schemas.d.ts +35 -0
  253. package/dist/schedules/schedules.schemas.js +27 -0
  254. package/dist/schedules/store.d.ts +5 -0
  255. package/dist/schedules/store.js +20 -0
  256. package/dist/skills/changes.controller.d.ts +1 -1
  257. package/dist/skills/changes.controller.js +1 -1
  258. package/dist/tools/approvals.service.d.ts +41 -11
  259. package/dist/tools/approvals.service.js +108 -14
  260. package/dist/tools/builtin-names.d.ts +5 -3
  261. package/dist/tools/builtin-names.js +12 -4
  262. package/dist/tools/builtins/builtin-tools.d.ts +1 -2
  263. package/dist/tools/builtins/builtin-tools.js +21 -17
  264. package/dist/tools/builtins/sandbox/bash.js +9 -3
  265. package/dist/tools/builtins/sandbox/common.d.ts +18 -1
  266. package/dist/tools/builtins/sandbox/common.js +14 -1
  267. package/dist/tools/builtins/sandbox/index.d.ts +2 -1
  268. package/dist/tools/builtins/sandbox/index.js +4 -1
  269. package/dist/tools/builtins/sandbox/task-list.d.ts +12 -0
  270. package/dist/tools/builtins/sandbox/task-list.js +130 -0
  271. package/dist/tools/builtins/sandbox/task-output.d.ts +8 -1
  272. package/dist/tools/builtins/sandbox/task-output.js +21 -3
  273. package/dist/tools/builtins/web/extract.d.ts +2 -4
  274. package/dist/tools/builtins/web/extract.js +2 -5
  275. package/dist/tools/pipeline.d.ts +12 -3
  276. package/dist/tools/pipeline.js +6 -1
  277. package/dist/tools/questions.service.d.ts +30 -10
  278. package/dist/tools/questions.service.js +41 -27
  279. package/dist/tools/registry.d.ts +12 -3
  280. package/dist/tools/registry.js +13 -3
  281. package/dist/tools/tools.module.js +4 -3
  282. package/package.json +3 -3
  283. package/src/migrations/0118_device_policy_ops.sql +6 -0
  284. package/src/migrations/0119_outbox.sql +22 -0
  285. package/src/migrations/0120_drop_usage_report_sweep.sql +7 -0
  286. package/src/migrations/0121_drop_platform_migration_runs.sql +12 -0
  287. package/src/migrations/0122_drop_scheduled_task_runs_rechecked_at.sql +5 -0
  288. package/src/migrations/0123_pgvector.sql +27 -0
  289. package/src/migrations/0124_conversation_source.sql +36 -0
  290. package/dist/catalog/platform-migration.d.ts +0 -115
  291. package/dist/catalog/platform-migration.js +0 -583
  292. package/dist/infra/queue/add-job-once.d.ts +0 -14
  293. package/dist/infra/queue/add-job-once.js +0 -16
@@ -12,7 +12,6 @@ import type { AgentLoop } from "./loop.js";
12
12
  import { ProviderRegistry } from "./providers.js";
13
13
  import { StepLog } from "./step-log.js";
14
14
  import { SubagentsService } from "./subagents/subagents.service.js";
15
- import { UsageReporter } from "./usage-report.js";
16
15
  /**
17
16
  * Builds the agent loop a run executes (default {@link LangGraphLoop}: its checkpoints live in the
18
17
  * kernel's {@link KyselyCheckpointSaver}, so another replica resumes a crashed worker's run).
@@ -35,5 +34,5 @@ export declare class AgentLoops {
35
34
  */
36
35
  export declare class RunSteps {
37
36
  readonly deps: LoopDeps;
38
- constructor(kdb: KernelDb, eventLog: EventLog, stepLog: StepLog, registry: ProviderRegistry, usageReport: UsageReporter, tools: ToolRegistry, config: KernelConfigService, log: KernelLogger, toolPipeline: ToolPipeline, host: ExtensionHost, subagents: SubagentsService, attachments: AttachmentsService);
37
+ constructor(kdb: KernelDb, eventLog: EventLog, stepLog: StepLog, registry: ProviderRegistry, tools: ToolRegistry, config: KernelConfigService, log: KernelLogger, toolPipeline: ToolPipeline, host: ExtensionHost, subagents: SubagentsService, attachments: AttachmentsService);
39
38
  }
@@ -21,7 +21,6 @@ import { LangGraphLoop } from "./langgraph-loop.js";
21
21
  import { ProviderRegistry } from "./providers.js";
22
22
  import { StepLog } from "./step-log.js";
23
23
  import { SubagentsService } from "./subagents/subagents.service.js";
24
- import { UsageReporter } from "./usage-report.js";
25
24
  /** Optional provider: the {@link AgentLoopFactory} runs use instead of the default (tests). */
26
25
  export const AGENT_LOOP_FACTORY = Symbol("AGENT_LOOP_FACTORY");
27
26
  /** The agent loops of chat runs and of eval full-run replays (one factory, one checkpoint store). */
@@ -52,7 +51,7 @@ export { AgentLoops };
52
51
  */
53
52
  let RunSteps = class RunSteps {
54
53
  deps;
55
- constructor(kdb, eventLog, stepLog, registry, usageReport, tools, config, log, toolPipeline, host, subagents, attachments) {
54
+ constructor(kdb, eventLog, stepLog, registry, tools, config, log, toolPipeline, host, subagents, attachments) {
56
55
  this.deps = {
57
56
  get db() {
58
57
  return kdb.db;
@@ -60,7 +59,6 @@ let RunSteps = class RunSteps {
60
59
  eventLog,
61
60
  stepLog,
62
61
  registry,
63
- usageReport,
64
62
  tools,
65
63
  config,
66
64
  log,
@@ -84,13 +82,12 @@ RunSteps = __decorate([
84
82
  __param(1, Inject(EventLog)),
85
83
  __param(2, Inject(StepLog)),
86
84
  __param(3, Inject(ProviderRegistry)),
87
- __param(4, Inject(UsageReporter)),
88
- __param(5, Inject(ToolRegistry)),
89
- __param(6, Inject(KernelConfigService)),
90
- __param(7, Inject(KERNEL_LOGGER)),
91
- __param(8, Inject(ToolPipeline)),
92
- __param(9, Inject(ExtensionHost)),
93
- __param(10, Inject(SubagentsService)),
94
- __param(11, Inject(AttachmentsService))
85
+ __param(4, Inject(ToolRegistry)),
86
+ __param(5, Inject(KernelConfigService)),
87
+ __param(6, Inject(KERNEL_LOGGER)),
88
+ __param(7, Inject(ToolPipeline)),
89
+ __param(8, Inject(ExtensionHost)),
90
+ __param(9, Inject(SubagentsService)),
91
+ __param(10, Inject(AttachmentsService))
95
92
  ], RunSteps);
96
93
  export { RunSteps };
@@ -8,16 +8,17 @@ import { KernelDb } from "../infra/database/kernel-db.js";
8
8
  import { TransactionHost } from "../infra/database/transaction-host.js";
9
9
  import { KernelEvents } from "../infra/events/kernel-events.js";
10
10
  import { SkillsCatalogService } from "../skills/catalog.js";
11
- import { ToolPipeline } from "../tools/pipeline.js";
11
+ import { ToolRegistry } from "../tools/registry.js";
12
12
  import { RunAbort } from "./abort.js";
13
13
  import { KyselyCheckpointSaver } from "./checkpointer.js";
14
14
  import { ConversationLock } from "./conversation-lock.js";
15
+ import { PluginContextService } from "./plugin-context.service.js";
15
16
  import { ProviderRegistry } from "./providers.js";
16
17
  import { type OrgQuota } from "./quota.js";
17
18
  import { RunContextService } from "./run-context.service.js";
18
19
  import { RunDrafts } from "./run-drafts.js";
19
20
  import { RunFinish } from "./run-finish.js";
20
- import type { RunJobData } from "./run-jobs.js";
21
+ import { type RunJobData } from "./run-jobs.js";
21
22
  import { RunQueue } from "./run-queue.js";
22
23
  import { AgentLoops, RunSteps } from "./run-steps.js";
23
24
  import { Waits } from "./waits.js";
@@ -33,6 +34,12 @@ export interface RunHooks {
33
34
  lockTtlMs?: number;
34
35
  /** 任务结束后的每次 ensureRun 尝试之前调用(attempt 从 0 起);抛错即模拟该次尝试失败。 */
35
36
  beforeEnsureRun?(conversationId: string, attempt: number): Promise<void>;
37
+ /** Called after a run job read the run's status, before it takes the conversation lock. */
38
+ afterRunRead?(runId: string, conversationId: string): Promise<void>;
39
+ /** Called with the conversation lock held, before a queued run's `run_started` is written. */
40
+ beforeRunStarted?(runId: string, conversationId: string): Promise<void>;
41
+ /** Called with the conversation lock held, before a queued run's status becomes `running`. */
42
+ beforeRunning?(runId: string, conversationId: string): Promise<void>;
36
43
  }
37
44
  /** 处理函数的返回值:`ensure` 表示任务完成后再调用一次 ensureRun。 */
38
45
  export type ProcessResult = "ensure" | undefined;
@@ -66,12 +73,10 @@ export declare class RunWorker {
66
73
  private readonly skillsCatalog;
67
74
  /** Run start's run context (run context spec §5): who the agent is, the day, the person. */
68
75
  private readonly runContext;
69
- /**
70
- * In the terminal transaction of every run: writes its open `Agent` call results
71
- * (`stopOpenAgentCalls`; a no-op without dispatches); `fire` runs their observe hooks after the
72
- * commit (sub-agents spec §12, review m1: a failed or stalled parent too).
73
- */
74
- private readonly pipeline;
76
+ /** Run start's plugin context (memory plugin spec §6.1): the `context@1` providers' text. */
77
+ private readonly pluginContext;
78
+ /** The run's resolved tools, for the plugin context's `tools` (chat runs with providers). */
79
+ private readonly tools;
75
80
  private readonly finisher;
76
81
  readonly txHost: TransactionHost;
77
82
  /** The steps' live drafts this process writes for the runs it executes. */
@@ -101,12 +106,10 @@ export declare class RunWorker {
101
106
  skillsCatalog: Pick<SkillsCatalogService, "record">,
102
107
  /** Run start's run context (run context spec §5): who the agent is, the day, the person. */
103
108
  runContext: Pick<RunContextService, "record">,
104
- /**
105
- * In the terminal transaction of every run: writes its open `Agent` call results
106
- * (`stopOpenAgentCalls`; a no-op without dispatches); `fire` runs their observe hooks after the
107
- * commit (sub-agents spec §12, review m1: a failed or stalled parent too).
108
- */
109
- pipeline: Pick<ToolPipeline, "stopOpenAgentCalls">, finisher: Pick<RunFinish, "finish">, txHost: TransactionHost,
109
+ /** Run start's plugin context (memory plugin spec §6.1): the `context@1` providers' text. */
110
+ pluginContext: Pick<PluginContextService, "record">,
111
+ /** The run's resolved tools, for the plugin context's `tools` (chat runs with providers). */
112
+ tools: Pick<ToolRegistry, "forAgent">, finisher: Pick<RunFinish, "finish">, txHost: TransactionHost,
110
113
  /** The steps' live drafts this process writes for the runs it executes. */
111
114
  drafts: RunDrafts, hooks?: RunHooks | undefined);
112
115
  private get db();
@@ -136,13 +139,15 @@ export declare class RunWorker {
136
139
  /**
137
140
  * After any terminal commit of a run that is not a sub-agent's (sub-agents spec §12): stops its
138
141
  * active fork invocation child on its behalf (no account); background `Agent` children keep
139
- * running (agent map spec §5.4). The wait sweep is the backstop.
142
+ * running (agent map spec §5.4). The terminal transaction owed the same stop (`stop-tree`), the
143
+ * backstop when this call never happens.
140
144
  */
141
145
  private stopChildren;
142
146
  /**
143
147
  * After a sub-agent run's terminal state committed (sub-agents spec §7.3): reports it to the
144
148
  * parent. Called with any run id whose conversation may be a child; runs that were not
145
- * dispatched are ignored. Errors are logged (the wait sweep repairs a missed call).
149
+ * dispatched are ignored. Errors are logged: the terminal transaction owed the same delivery
150
+ * (`deliver-to-parent`) and stop (`stop-tree`), which repair a missed call.
146
151
  */
147
152
  private childFinished;
148
153
  /**
@@ -170,6 +175,11 @@ export declare class RunWorker {
170
175
  process(job: Job<RunJobData>, token: string | undefined): Promise<ProcessResult>;
171
176
  private execute;
172
177
  private completed;
178
+ /**
179
+ * The run's extension tool keys by plugin, resolved as a chat run's first step lists them
180
+ * (disabled tools, org switches, the conversation's source): a provider's `tools`.
181
+ */
182
+ private pluginToolKeys;
173
183
  /**
174
184
  * When the conversation was switched to a model that no longer resolves (provider disabled,
175
185
  * model removed), writes `model_switched { model: null, effort: null, reason: "unavailable" }`
@@ -25,16 +25,19 @@ import { KernelEvents } from "../infra/events/kernel-events.js";
25
25
  import { KERNEL_BUS, KERNEL_LOGGER } from "../infra/tokens.js";
26
26
  import { SkillsCatalogService } from "../skills/catalog.js";
27
27
  import { normalizeStoredDefinitionIn } from "../tools/legacy-data.js";
28
- import { ToolPipeline } from "../tools/pipeline.js";
28
+ import { ToolRegistry } from "../tools/registry.js";
29
29
  import { RunAbort } from "./abort.js";
30
30
  import { KyselyCheckpointSaver } from "./checkpointer.js";
31
31
  import { ConversationLock } from "./conversation-lock.js";
32
+ import { runDeadline, tightestLimit } from "./limits.js";
32
33
  import { RunError } from "./model-call.js";
34
+ import { PluginContextService } from "./plugin-context.service.js";
33
35
  import { ProviderListError, ProviderRegistry } from "./providers.js";
34
36
  import { ORG_QUOTA_LEASE_MS, orgRunLimit, RUN_QUOTA } from "./quota.js";
35
37
  import { RunContextService } from "./run-context.service.js";
36
38
  import { RunDrafts, streamSink } from "./run-drafts.js";
37
- import { RunFinish, TERMINAL_STATUSES } from "./run-finish.js";
39
+ import { RunFinish } from "./run-finish.js";
40
+ import { TERMINAL_STATUSES } from "./run-jobs.js";
38
41
  import { RunQueue } from "./run-queue.js";
39
42
  import { AgentLoops, RunSteps } from "./run-steps.js";
40
43
  import { dispatchOfChildRun, rootConversationOf } from "./subagents/child.js";
@@ -63,6 +66,15 @@ async function requeue(job, token, delayMs) {
63
66
  await job.moveToDelayed(Date.now() + delayMs, token);
64
67
  throw new DelayedError();
65
68
  }
69
+ /** An account's display name ("" when it is gone). */
70
+ async function accountName(db, accountId) {
71
+ const row = await db
72
+ .selectFrom("accounts")
73
+ .select("display_name")
74
+ .where("id", "=", accountId)
75
+ .executeTakeFirst();
76
+ return row?.display_name ?? "";
77
+ }
66
78
  /**
67
79
  * 运行 worker(只在含 `worker` 角色的进程消费):领取 `cap-kernel-runs` 与 `cap-kernel-subagent-runs` 的任务
68
80
  * (两个 `@Processor`,见 run-processors.ts),取会话锁与组织配额,调用 AgentLoop,按结果写终态事件并推进
@@ -86,7 +98,8 @@ let RunWorker = class RunWorker {
86
98
  models;
87
99
  skillsCatalog;
88
100
  runContext;
89
- pipeline;
101
+ pluginContext;
102
+ tools;
90
103
  finisher;
91
104
  txHost;
92
105
  drafts;
@@ -115,12 +128,10 @@ let RunWorker = class RunWorker {
115
128
  skillsCatalog,
116
129
  /** Run start's run context (run context spec §5): who the agent is, the day, the person. */
117
130
  runContext,
118
- /**
119
- * In the terminal transaction of every run: writes its open `Agent` call results
120
- * (`stopOpenAgentCalls`; a no-op without dispatches); `fire` runs their observe hooks after the
121
- * commit (sub-agents spec §12, review m1: a failed or stalled parent too).
122
- */
123
- pipeline, finisher, txHost,
131
+ /** Run start's plugin context (memory plugin spec §6.1): the `context@1` providers' text. */
132
+ pluginContext,
133
+ /** The run's resolved tools, for the plugin context's `tools` (chat runs with providers). */
134
+ tools, finisher, txHost,
124
135
  /** The steps' live drafts this process writes for the runs it executes. */
125
136
  drafts, hooks) {
126
137
  this.kdb = kdb;
@@ -140,7 +151,8 @@ let RunWorker = class RunWorker {
140
151
  this.models = models;
141
152
  this.skillsCatalog = skillsCatalog;
142
153
  this.runContext = runContext;
143
- this.pipeline = pipeline;
154
+ this.pluginContext = pluginContext;
155
+ this.tools = tools;
144
156
  this.finisher = finisher;
145
157
  this.txHost = txHost;
146
158
  this.drafts = drafts;
@@ -197,7 +209,8 @@ let RunWorker = class RunWorker {
197
209
  /**
198
210
  * After any terminal commit of a run that is not a sub-agent's (sub-agents spec §12): stops its
199
211
  * active fork invocation child on its behalf (no account); background `Agent` children keep
200
- * running (agent map spec §5.4). The wait sweep is the backstop.
212
+ * running (agent map spec §5.4). The terminal transaction owed the same stop (`stop-tree`), the
213
+ * backstop when this call never happens.
201
214
  */
202
215
  async stopChildren(runId) {
203
216
  try {
@@ -210,7 +223,8 @@ let RunWorker = class RunWorker {
210
223
  /**
211
224
  * After a sub-agent run's terminal state committed (sub-agents spec §7.3): reports it to the
212
225
  * parent. Called with any run id whose conversation may be a child; runs that were not
213
- * dispatched are ignored. Errors are logged (the wait sweep repairs a missed call).
226
+ * dispatched are ignored. Errors are logged: the terminal transaction owed the same delivery
227
+ * (`deliver-to-parent`) and stop (`stop-tree`), which repair a missed call.
214
228
  */
215
229
  async childFinished(runId) {
216
230
  try {
@@ -384,9 +398,10 @@ let RunWorker = class RunWorker {
384
398
  // 运行在等人处理(例如暂停后本任务被 stalled 机制重新投递):不执行,续跑由处理 / 超时发起的新任务负责。
385
399
  if (run.status === "waiting")
386
400
  return;
401
+ await this.hooks?.afterRunRead?.(runId, conversationId);
387
402
  const conv = await this.db
388
403
  .selectFrom("conversations")
389
- .select(["org_id", "agent_id", "kind", "subagent_depth"])
404
+ .select(["org_id", "agent_id", "kind", "subagent_depth", "source", "account_id"])
390
405
  .where("id", "=", conversationId)
391
406
  .executeTakeFirst();
392
407
  if (!conv)
@@ -453,8 +468,6 @@ let RunWorker = class RunWorker {
453
468
  delayMs = QUOTA_FULL_DELAY_MS;
454
469
  }
455
470
  else {
456
- // 运行开始执行(含续跑、stalled 后接手):通知旁路(渠道出站投递据此把输出投到 IM),失败不影响运行
457
- void this.events.emit("run.started", { conversationId, runId });
458
471
  const r = await this.execute(run, { id: conversationId, ...conv }, state).catch(async (err) => {
459
472
  if (state.abandoned)
460
473
  return "abandoned";
@@ -514,7 +527,8 @@ let RunWorker = class RunWorker {
514
527
  // a chat run's saved agent version, under the conversation's model switch (UI refresh B); a
515
528
  // sub-agent has none: it never takes a selection
516
529
  let saved;
517
- let maxSteps = runtime.maxSteps;
530
+ /** The run's step limit; `undefined` = no limit (`runtime.maxSteps` 0). */
531
+ let maxSteps = tightestLimit(runtime.maxSteps);
518
532
  let parent;
519
533
  /** A sub-agent's name in its run context: the roster name, or the forked skill's. */
520
534
  let childName;
@@ -531,7 +545,8 @@ let RunWorker = class RunWorker {
531
545
  agent = childRunDefinition(await normalizeStoredDefinitionIn(this.db, conv.org_id, started.payload.definition), trigger?.type === "user_message" && trigger.seq === Number(run.trigger_seq)
532
546
  ? trigger.payload.dispatch?.narrowed
533
547
  : undefined);
534
- maxSteps = Math.min(started.payload.maxSteps, runtime.maxSteps);
548
+ // the tighter of the logged limit and the deployment's (0 in either = no limit there)
549
+ maxSteps = tightestLimit(started.payload.maxSteps, runtime.maxSteps);
535
550
  childName = started.payload.template.invokedSkill?.name ?? started.payload.agentType;
536
551
  const row = await dispatchOfChildRun(this.db, runId);
537
552
  const otherAgent = started.payload.template.source === "agent";
@@ -577,6 +592,14 @@ let RunWorker = class RunWorker {
577
592
  saved = await normalizeStoredDefinitionIn(this.db, conv.org_id, version.definition);
578
593
  agent = saved;
579
594
  }
595
+ // the trigger account's role, read once per run for the plugin context and plugin tool
596
+ // handlers (memory plugin spec §6.2); an account no longer in the org counts as a guest
597
+ const role = (await this.db
598
+ .selectFrom("memberships")
599
+ .select("role")
600
+ .where("org_id", "=", conv.org_id)
601
+ .where("account_id", "=", run.trigger_account_id)
602
+ .executeTakeFirst())?.role ?? "guest";
580
603
  let startedAt = run.started_at;
581
604
  // The model / effort switch in effect (UI refresh B): the latest `model_switched` before this
582
605
  // run's `run_started`, read under the conversation lock when the run starts, so a replay
@@ -588,9 +611,14 @@ let RunWorker = class RunWorker {
588
611
  }
589
612
  if (run.status === "queued" || startedAt === null) {
590
613
  if (!existingStart) {
614
+ await this.hooks?.beforeRunStarted?.(runId, conversationId);
591
615
  if (saved !== undefined)
592
616
  await this.fallBackIfUnavailable(conv.org_id, conversationId, runId, saved);
593
617
  const started = await this.appendRunStarted(conversationId, run, agent, saved);
618
+ // the status was read before the conversation lock: a stop that ended the run meanwhile
619
+ // (a queued run's direct abort, an orphan abort) wins, and the run never starts
620
+ if (started.terminal)
621
+ return "finished";
594
622
  agent = started.agent;
595
623
  const toSeq = started.toSeq;
596
624
  if (toSeq !== undefined)
@@ -620,26 +648,58 @@ let RunWorker = class RunWorker {
620
648
  },
621
649
  }),
622
650
  });
651
+ // plugin context (memory plugin spec §6.1): after the run context, still before the run is
652
+ // running; the providers are asked outside any transaction, a chat run only
653
+ await this.pluginContext.record({
654
+ orgId: conv.org_id,
655
+ conversationId,
656
+ runId,
657
+ agentId: conv.agent_id,
658
+ agentName: agent.name,
659
+ ownerAccountId: conv.account_id,
660
+ // only a chat run asks the providers
661
+ ownerName: conv.kind === "chat" ? await accountName(this.db, conv.account_id) : "",
662
+ triggerAccountId: run.trigger_account_id,
663
+ source: conv.source,
664
+ role,
665
+ kind: conv.kind,
666
+ toolKeysByPlugin: () => this.pluginToolKeys(conv, agent),
667
+ // the run's own abort watch starts with its execution below: until then, the shutdown
668
+ signal: state.shutdown.signal,
669
+ });
670
+ await this.hooks?.beforeRunning?.(runId, conversationId);
671
+ // never over a terminal status: a run finished meanwhile stays finished
623
672
  const updated = await this.db
624
673
  .updateTable("runs")
625
674
  .set({ status: "running", started_at: sql `COALESCE(started_at, now())` })
626
675
  .where("id", "=", runId)
676
+ .where("status", "in", ["queued", "running"])
627
677
  .returning("started_at")
628
- .executeTakeFirstOrThrow();
678
+ .executeTakeFirst();
679
+ if (updated === undefined)
680
+ return "finished";
629
681
  startedAt = updated.started_at;
630
682
  }
683
+ // the run executes (a first start, a resume, a stalled takeover): a hint to the side paths (the
684
+ // channel outbound delivers its output to IM), after the start went through, never for a run a
685
+ // stop ended first; a failure does not affect the run
686
+ void this.events.emit("run.started", { conversationId, runId });
631
687
  // 截止时间以首次开始为准:停机后在其他 worker 续跑也不重新计时;等人处理的时长(waited_ms)不计入。
632
- const deadline = startedAt.getTime() + Number(run.waited_ms) + runtime.maxRunSeconds * 1000;
688
+ // `runtime.maxRunSeconds` 0: no deadline, no timer (the run ends when the model stops or is stopped)
689
+ const deadline = runDeadline(startedAt.getTime() + Number(run.waited_ms), runtime.maxRunSeconds);
633
690
  const ac = new AbortController();
634
691
  let abortedBy;
635
692
  let abortDetail;
636
693
  let deadlineHit = false;
637
- const deadlineTimer = setTimeout(() => {
638
- deadlineHit = true;
639
- ac.abort();
640
- }, Math.max(0, deadline - Date.now()));
694
+ const deadlineTimer = deadline === undefined
695
+ ? undefined
696
+ : setTimeout(() => {
697
+ deadlineHit = true;
698
+ ac.abort();
699
+ }, Math.max(0, deadline - Date.now()));
641
700
  state.stopTimers = () => {
642
- clearTimeout(deadlineTimer);
701
+ if (deadlineTimer !== undefined)
702
+ clearTimeout(deadlineTimer);
643
703
  };
644
704
  let unwatch;
645
705
  try {
@@ -687,13 +747,19 @@ let RunWorker = class RunWorker {
687
747
  runId,
688
748
  agentId: conv.agent_id,
689
749
  triggerAccountId: run.trigger_account_id,
750
+ source: conv.source,
751
+ ownerAccountId: conv.account_id,
752
+ role,
690
753
  agent,
691
754
  agentVersion: run.agent_version,
692
755
  signal: ac.signal,
693
756
  shutdown: state.shutdown.signal,
694
757
  sink: this.sinkFor(conversationId),
695
758
  pendingAbsorbable,
696
- limits: { maxSteps, deadline },
759
+ limits: {
760
+ ...(maxSteps !== undefined && { maxSteps }),
761
+ ...(deadline !== undefined && { deadline }),
762
+ },
697
763
  // a sub-agent's conversation fires hooks like a chat, with `parent` set (spec §11)
698
764
  conversationKind: conv.kind === "eval" ? "eval" : conv.kind === "subagent" ? "subagent" : "chat",
699
765
  ...(parent !== undefined && { parent }),
@@ -784,6 +850,28 @@ let RunWorker = class RunWorker {
784
850
  // a completed run enqueues the conversation's title job (never throws)
785
851
  void this.titles.maybeEnqueue(conversationId);
786
852
  }
853
+ /**
854
+ * The run's extension tool keys by plugin, resolved as a chat run's first step lists them
855
+ * (disabled tools, org switches, the conversation's source): a provider's `tools`.
856
+ */
857
+ async pluginToolKeys(conv, agent) {
858
+ const { tools } = await this.tools.forAgent(conv.org_id, {
859
+ disabledTools: agent.disabledTools,
860
+ subagentTools: agent.subagentTools,
861
+ subagents: agent.subagents,
862
+ sandboxConversationId: conv.id,
863
+ source: conv.source,
864
+ });
865
+ const out = new Map();
866
+ for (const t of tools) {
867
+ if (t.source.kind !== "plugin")
868
+ continue;
869
+ const keys = out.get(t.source.plugin) ?? [];
870
+ keys.push(t.key);
871
+ out.set(t.source.plugin, keys);
872
+ }
873
+ return out;
874
+ }
787
875
  /**
788
876
  * When the conversation was switched to a model that no longer resolves (provider disabled,
789
877
  * model removed), writes `model_switched { model: null, effort: null, reason: "unavailable" }`
@@ -830,6 +918,17 @@ let RunWorker = class RunWorker {
830
918
  .where("id", "=", conversationId)
831
919
  .forUpdate()
832
920
  .execute();
921
+ // the run's status again under the locks (conversation, then run, as `RunFinish.finishIn`):
922
+ // the job read it before taking the conversation lock, and a stop may have ended it since
923
+ const row = await t
924
+ .selectFrom("runs")
925
+ .select("status")
926
+ .where("id", "=", run.id)
927
+ .forUpdate()
928
+ .executeTakeFirst();
929
+ if (!row || TERMINAL_STATUSES.has(row.status)) {
930
+ return { toSeq: undefined, agent: current, terminal: true };
931
+ }
833
932
  const agent = saved !== undefined
834
933
  ? effectiveDefinition(saved, await readSelection(t, conversationId))
835
934
  : current;
@@ -906,7 +1005,7 @@ let RunWorker = class RunWorker {
906
1005
  * 提交后发布会话通知,然后调用测试钩子。返回终态事件 seq;运行已是终态 → null。
907
1006
  */
908
1007
  async finish(conversationId, runId, status, consumed, event, hook = true, floorToTrigger = true) {
909
- let fire = () => { };
1008
+ // the terminal transaction also writes the run's open fork report and cancels its waits
910
1009
  const toSeq = await this.finisher.finish({
911
1010
  conversationId,
912
1011
  runId,
@@ -914,12 +1013,7 @@ let RunWorker = class RunWorker {
914
1013
  consumed,
915
1014
  event,
916
1015
  floorToTrigger,
917
- beforeTerminal: async () => {
918
- fire = (await this.pipeline.stopOpenAgentCalls(runId)).fire;
919
- },
920
1016
  });
921
- if (toSeq !== null)
922
- fire();
923
1017
  if (hook)
924
1018
  await this.hooks?.beforeRelease?.(runId, conversationId);
925
1019
  return toSeq;
@@ -952,11 +1046,12 @@ RunWorker = __decorate([
952
1046
  __param(16, Inject(ProviderRegistry)),
953
1047
  __param(17, Inject(SkillsCatalogService)),
954
1048
  __param(18, Inject(RunContextService)),
955
- __param(19, Inject(ToolPipeline)),
956
- __param(20, Inject(RunFinish)),
957
- __param(21, Inject(TransactionHost)),
958
- __param(22, Inject(RunDrafts)),
959
- __param(23, Optional()),
960
- __param(23, Inject(RUN_HOOKS))
1049
+ __param(19, Inject(PluginContextService)),
1050
+ __param(20, Inject(ToolRegistry)),
1051
+ __param(21, Inject(RunFinish)),
1052
+ __param(22, Inject(TransactionHost)),
1053
+ __param(23, Inject(RunDrafts)),
1054
+ __param(24, Optional()),
1055
+ __param(24, Inject(RUN_HOOKS))
961
1056
  ], RunWorker);
962
1057
  export { RunWorker };
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * The run runtime: the conversation run lock, this process's event streams, the run queue and its
3
- * worker (consumed through `RuntimeWorkersModule`'s processors), the waits (their sweep is the
4
- * worker role's `WaitSweepJob`), run
5
- * stops, the checkpoints, the org quotas, the step writes and the agent loops. The model provider
3
+ * worker (consumed through `RuntimeWorkersModule`'s processors), the waits (a run nobody runs is
4
+ * the worker role's `RunOrphanCheck`'s to repair), run stops, the checkpoints, the org quotas, the step writes and the agent loops. The model provider
6
5
  * registry, the sub-agent dispatch, `usage.report` and the titles have modules of their own (the
7
6
  * tools, models and conversations domains import them without the runtime).
8
7
  */
@@ -23,6 +23,7 @@ import { RunAbort } from "./abort.js";
23
23
  import { KyselyCheckpointSaver } from "./checkpointer.js";
24
24
  import { ConversationLock } from "./conversation-lock.js";
25
25
  import { MAINTENANCE_QUEUE_NAME } from "./maintenance-queue.js";
26
+ import { PluginContextService } from "./plugin-context.service.js";
26
27
  import { ProvidersModule } from "./providers.js";
27
28
  import { EVAL_QUOTA, EVAL_QUOTA_PREFIX, OrgQuota, RUN_QUOTA, RUN_QUOTA_PREFIX } from "./quota.js";
28
29
  import { RunContextService } from "./run-context.service.js";
@@ -37,12 +38,11 @@ import { StepLogModule } from "./step-log.js";
37
38
  import { ConversationStreams } from "./stream.js";
38
39
  import { SubagentsModule } from "./subagents/subagents.service.js";
39
40
  import { UsageReportModule } from "./usage-report.js";
40
- import { DecisionResumer, Waits } from "./waits.js";
41
+ import { Waits } from "./waits.js";
41
42
  /**
42
43
  * The run runtime: the conversation run lock, this process's event streams, the run queue and its
43
- * worker (consumed through `RuntimeWorkersModule`'s processors), the waits (their sweep is the
44
- * worker role's `WaitSweepJob`), run
45
- * stops, the checkpoints, the org quotas, the step writes and the agent loops. The model provider
44
+ * worker (consumed through `RuntimeWorkersModule`'s processors), the waits (a run nobody runs is
45
+ * the worker role's `RunOrphanCheck`'s to repair), run stops, the checkpoints, the org quotas, the step writes and the agent loops. The model provider
46
46
  * registry, the sub-agent dispatch, `usage.report` and the titles have modules of their own (the
47
47
  * tools, models and conversations domains import them without the runtime).
48
48
  */
@@ -67,7 +67,8 @@ RuntimeModule = __decorate([
67
67
  BackgroundModule,
68
68
  // a scheduled task's run follows its kernel run's end (`RunFinish`)
69
69
  ScheduledTaskTrackerModule,
70
- // the producer side of `wait-timeout` jobs (`MaintenanceProcessor` consumes them)
70
+ // the maintenance queue's handle: the outbox delivers the `wait-timeout` jobs the waits owe
71
+ // (`MaintenanceProcessor` consumes them)
71
72
  QueueModule.registerQueue(MAINTENANCE_QUEUE_NAME),
72
73
  ],
73
74
  providers: [
@@ -78,12 +79,12 @@ RuntimeModule = __decorate([
78
79
  RunFinish,
79
80
  RunQueue,
80
81
  Waits,
81
- DecisionResumer,
82
82
  RunControl,
83
83
  RunDrafts,
84
84
  AgentLoops,
85
85
  RunSteps,
86
86
  RunContextService,
87
+ PluginContextService,
87
88
  RunWorker,
88
89
  // a finished background task wakes an idle conversation (background Bash spec §3)
89
90
  BackgroundWake,
@@ -4,26 +4,38 @@ import type { ConversationEvent } from "../conversations/events.js";
4
4
  import { audit } from "../identity/audit.js";
5
5
  import { KernelDb } from "../infra/database/kernel-db.js";
6
6
  import { TransactionHost } from "../infra/database/transaction-host.js";
7
+ import { UsageReportJobs } from "./usage-report-jobs.js";
7
8
  /** An audit row written with the events (`identity/audit.ts`). */
8
9
  export type StepAuditEntry = Parameters<typeof audit>[1];
9
10
  /**
10
11
  * The writes of a run step that go to the event log together with another row, each in a
11
12
  * transaction of its own (the caller notifies the log after the commit): a model call with the
12
- * tool definitions it sent, a denial with its audit row, and a sub-agent's usage counted on its
13
- * parent run. The step functions (`model-call.ts`, `hook-calls.ts`) reach it through their deps.
13
+ * tool definitions it sent, a denial with its audit row, usage events with their owed
14
+ * `usage.report` deliveries (transactional outbox spec §8.1), and a sub-agent's usage counted on
15
+ * its parent run. The step functions (`model-call.ts`, `hook-calls.ts`) reach it through their deps.
14
16
  */
15
17
  export declare class StepLog {
16
18
  private readonly kdb;
17
19
  private readonly eventLog;
20
+ private readonly usage;
18
21
  readonly txHost: TransactionHost;
19
- constructor(kdb: KernelDb, eventLog: EventLog, txHost: TransactionHost);
22
+ constructor(kdb: KernelDb, eventLog: EventLog, usage: Pick<UsageReportJobs, "oweEvents">, txHost: TransactionHost);
23
+ /**
24
+ * Appends events and owes the `usage.report` delivery of the `usage` events it newly wrote, in
25
+ * one transaction. Returns what was written (hits included) and the highest new seq (null:
26
+ * nothing new).
27
+ */
28
+ appendReported(conversationId: string, events: AppendEvent[]): Promise<{
29
+ written: ConversationEvent[];
30
+ toSeq: number | null;
31
+ }>;
20
32
  /**
21
33
  * Appends events of a sub-agent's run and adds the tokens of the usage events it newly wrote to
22
34
  * the `subagent_tokens_used` of the tree's budget run (sub-agents spec §8.3, agent map spec §6:
23
35
  * the whole tree counts on one run): `counter.budgetRunId`, the run's own window
24
36
  * (`SubagentParent.budgetRunId`), else the parent run's ({@link budgetRunOf}). A usage event
25
37
  * already in the log (an idempotent hit after a crash) adds nothing, so each call counts exactly
26
- * once. Returns what was written (hits included) and the highest new seq (null: nothing new).
38
+ * once; the new usage events' `usage.report` deliveries are owed in the same transaction. Returns what was written (hits included) and the highest new seq (null: nothing new).
27
39
  */
28
40
  appendCounted(conversationId: string, counter: {
29
41
  parentRunId: string;