comisai 1.0.33 → 1.0.36

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 (285) hide show
  1. package/node_modules/@comis/agent/dist/background/auto-background-middleware.d.ts +11 -1
  2. package/node_modules/@comis/agent/dist/background/auto-background-middleware.js +21 -4
  3. package/node_modules/@comis/agent/dist/background/background-task-manager.d.ts +2 -2
  4. package/node_modules/@comis/agent/dist/background/background-task-manager.js +61 -20
  5. package/node_modules/@comis/agent/dist/background/background-task-persistence.js +10 -3
  6. package/node_modules/@comis/agent/dist/background/background-task-types.d.ts +10 -3
  7. package/node_modules/@comis/agent/dist/background/background-task-types.js +1 -1
  8. package/node_modules/@comis/agent/dist/background/completion-formatter.d.ts +39 -0
  9. package/node_modules/@comis/agent/dist/background/completion-formatter.js +77 -0
  10. package/node_modules/@comis/agent/dist/background/completion-runner.d.ts +53 -0
  11. package/node_modules/@comis/agent/dist/background/completion-runner.js +151 -0
  12. package/node_modules/@comis/agent/dist/background/index.d.ts +4 -0
  13. package/node_modules/@comis/agent/dist/background/index.js +2 -0
  14. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +17 -2
  15. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +14 -2
  16. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +23 -23
  17. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +72 -60
  18. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.d.ts +6 -7
  19. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.js +24 -25
  20. package/node_modules/@comis/agent/dist/budget/cost-tracker.d.ts +1 -1
  21. package/node_modules/@comis/agent/dist/context-engine/constants.d.ts +5 -5
  22. package/node_modules/@comis/agent/dist/context-engine/constants.js +12 -12
  23. package/node_modules/@comis/agent/dist/context-engine/context-engine.js +13 -4
  24. package/node_modules/@comis/agent/dist/context-engine/dag-annotator.d.ts +1 -2
  25. package/node_modules/@comis/agent/dist/context-engine/dag-annotator.js +1 -2
  26. package/node_modules/@comis/agent/dist/context-engine/llm-compaction.js +20 -16
  27. package/node_modules/@comis/agent/dist/context-engine/rehydration.js +6 -6
  28. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +12 -12
  29. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +36 -22
  30. package/node_modules/@comis/agent/dist/context-engine/types-core.d.ts +15 -0
  31. package/node_modules/@comis/agent/dist/executor/cache-break-detection.d.ts +6 -6
  32. package/node_modules/@comis/agent/dist/executor/cache-break-detection.js +8 -8
  33. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.d.ts +16 -0
  34. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +46 -5
  35. package/node_modules/@comis/agent/dist/executor/executor-post-execution.d.ts +30 -0
  36. package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +17 -1
  37. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +1 -1
  38. package/node_modules/@comis/agent/dist/executor/executor-response-filter.d.ts +7 -6
  39. package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +9 -42
  40. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +2 -3
  41. package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.d.ts +2 -2
  42. package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.js +4 -4
  43. package/node_modules/@comis/agent/dist/executor/phase-filter.d.ts +2 -2
  44. package/node_modules/@comis/agent/dist/executor/phase-filter.js +5 -7
  45. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +13 -0
  46. package/node_modules/@comis/agent/dist/executor/pi-executor.js +71 -6
  47. package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +7 -7
  48. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.d.ts +1 -1
  49. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +1 -1
  50. package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +2 -2
  51. package/node_modules/@comis/agent/dist/executor/tool-deferral.js +7 -7
  52. package/node_modules/@comis/agent/dist/index.d.ts +17 -0
  53. package/node_modules/@comis/agent/dist/index.js +32 -11
  54. package/node_modules/@comis/agent/dist/model/auth-provider.d.ts +25 -2
  55. package/node_modules/@comis/agent/dist/model/auth-provider.js +6 -0
  56. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.d.ts +3 -3
  57. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.js +3 -3
  58. package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.d.ts +37 -0
  59. package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.js +279 -0
  60. package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.d.ts +49 -0
  61. package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.js +50 -0
  62. package/node_modules/@comis/agent/dist/model/oauth-device-code.d.ts +57 -0
  63. package/node_modules/@comis/agent/dist/model/oauth-device-code.js +302 -0
  64. package/node_modules/@comis/agent/dist/model/oauth-env.d.ts +33 -0
  65. package/node_modules/@comis/agent/dist/model/oauth-env.js +38 -0
  66. package/node_modules/@comis/agent/dist/model/oauth-errors.d.ts +41 -0
  67. package/node_modules/@comis/agent/dist/model/oauth-errors.js +88 -0
  68. package/node_modules/@comis/agent/dist/model/oauth-identity.d.ts +53 -0
  69. package/node_modules/@comis/agent/dist/model/oauth-identity.js +141 -0
  70. package/node_modules/@comis/agent/dist/model/oauth-login-runner.d.ts +99 -0
  71. package/node_modules/@comis/agent/dist/model/oauth-login-runner.js +374 -0
  72. package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.d.ts +58 -0
  73. package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.js +82 -0
  74. package/node_modules/@comis/agent/dist/model/oauth-token-manager.d.ts +86 -16
  75. package/node_modules/@comis/agent/dist/model/oauth-token-manager.js +961 -66
  76. package/node_modules/@comis/agent/dist/model/operation-model-defaults.d.ts +9 -4
  77. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +36 -9
  78. package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.d.ts +48 -0
  79. package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.js +66 -0
  80. package/node_modules/@comis/agent/dist/provider/capabilities.d.ts +5 -5
  81. package/node_modules/@comis/agent/dist/provider/capabilities.js +10 -23
  82. package/node_modules/@comis/agent/dist/safety/tool-output-safety.js +3 -3
  83. package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +1 -1
  84. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +1 -1
  85. package/node_modules/@comis/agent/dist/spawn/narrative-caster.d.ts +10 -0
  86. package/node_modules/@comis/agent/dist/spawn/narrative-caster.js +5 -1
  87. package/node_modules/@comis/agent/package.json +1 -1
  88. package/node_modules/@comis/channels/dist/email/email-adapter.js +6 -6
  89. package/node_modules/@comis/channels/dist/email/imap-lifecycle.js +7 -7
  90. package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +12 -10
  91. package/node_modules/@comis/channels/dist/telegram/telegram-adapter.js +1 -1
  92. package/node_modules/@comis/channels/package.json +1 -1
  93. package/node_modules/@comis/cli/dist/cli.js +2 -0
  94. package/node_modules/@comis/cli/dist/commands/agent.d.ts +3 -3
  95. package/node_modules/@comis/cli/dist/commands/agent.js +46 -3
  96. package/node_modules/@comis/cli/dist/commands/auth.d.ts +37 -0
  97. package/node_modules/@comis/cli/dist/commands/auth.js +433 -0
  98. package/node_modules/@comis/cli/dist/commands/doctor.d.ts +4 -1
  99. package/node_modules/@comis/cli/dist/commands/doctor.js +20 -5
  100. package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.d.ts +39 -0
  101. package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.js +399 -0
  102. package/node_modules/@comis/cli/dist/doctor/types.d.ts +19 -0
  103. package/node_modules/@comis/cli/dist/index.d.ts +1 -0
  104. package/node_modules/@comis/cli/dist/index.js +10 -4
  105. package/node_modules/@comis/cli/dist/output/relative-time.d.ts +23 -0
  106. package/node_modules/@comis/cli/dist/output/relative-time.js +36 -0
  107. package/node_modules/@comis/cli/dist/wizard/non-interactive.js +17 -8
  108. package/node_modules/@comis/cli/dist/wizard/steps/03-provider.js +2 -1
  109. package/node_modules/@comis/cli/dist/wizard/steps/04-credentials.js +223 -34
  110. package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +14 -0
  111. package/node_modules/@comis/cli/dist/wizard/steps/11-daemon-start.js +3 -3
  112. package/node_modules/@comis/cli/dist/wizard/types.d.ts +7 -0
  113. package/node_modules/@comis/cli/package.json +1 -1
  114. package/node_modules/@comis/core/dist/bootstrap.d.ts +1 -1
  115. package/node_modules/@comis/core/dist/config/env-substitution.d.ts +66 -0
  116. package/node_modules/@comis/core/dist/config/env-substitution.js +115 -0
  117. package/node_modules/@comis/core/dist/config/index.d.ts +3 -1
  118. package/node_modules/@comis/core/dist/config/index.js +2 -1
  119. package/node_modules/@comis/core/dist/config/loader.js +61 -0
  120. package/node_modules/@comis/core/dist/config/managed-sections.d.ts +3 -3
  121. package/node_modules/@comis/core/dist/config/managed-sections.js +10 -5
  122. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +4 -0
  123. package/node_modules/@comis/core/dist/config/schema-agent.js +16 -1
  124. package/node_modules/@comis/core/dist/config/schema-background-tasks.d.ts +7 -0
  125. package/node_modules/@comis/core/dist/config/schema-background-tasks.js +7 -0
  126. package/node_modules/@comis/core/dist/config/schema-delivery.d.ts +2 -0
  127. package/node_modules/@comis/core/dist/config/schema-delivery.js +2 -0
  128. package/node_modules/@comis/core/dist/config/schema-gemini-cache.d.ts +0 -2
  129. package/node_modules/@comis/core/dist/config/schema-gemini-cache.js +0 -2
  130. package/node_modules/@comis/core/dist/config/schema-oauth.d.ts +23 -0
  131. package/node_modules/@comis/core/dist/config/schema-oauth.js +19 -0
  132. package/node_modules/@comis/core/dist/config/schema-skills.d.ts +6 -8
  133. package/node_modules/@comis/core/dist/config/schema-skills.js +3 -4
  134. package/node_modules/@comis/core/dist/config/schema.d.ts +10 -0
  135. package/node_modules/@comis/core/dist/config/schema.js +3 -0
  136. package/node_modules/@comis/core/dist/domain/background-task-origin.d.ts +39 -0
  137. package/node_modules/@comis/core/dist/domain/background-task-origin.js +39 -0
  138. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +71 -2
  139. package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
  140. package/node_modules/@comis/core/dist/exports/config.js +1 -1
  141. package/node_modules/@comis/core/dist/exports/domain.d.ts +2 -0
  142. package/node_modules/@comis/core/dist/exports/domain.js +1 -0
  143. package/node_modules/@comis/core/dist/exports/ports.d.ts +2 -2
  144. package/node_modules/@comis/core/dist/exports/ports.js +1 -1
  145. package/node_modules/@comis/core/dist/ports/delivery-queue.d.ts +23 -0
  146. package/node_modules/@comis/core/dist/ports/delivery-queue.js +2 -0
  147. package/node_modules/@comis/core/dist/ports/index.d.ts +2 -0
  148. package/node_modules/@comis/core/dist/ports/index.js +1 -0
  149. package/node_modules/@comis/core/dist/ports/oauth-credential-store.d.ts +64 -0
  150. package/node_modules/@comis/core/dist/ports/oauth-credential-store.js +37 -0
  151. package/node_modules/@comis/core/dist/tool-metadata.d.ts +20 -0
  152. package/node_modules/@comis/core/package.json +1 -1
  153. package/node_modules/@comis/daemon/dist/daemon-types.d.ts +23 -3
  154. package/node_modules/@comis/daemon/dist/daemon.js +82 -19
  155. package/node_modules/@comis/daemon/dist/health/watchdog.js +18 -3
  156. package/node_modules/@comis/daemon/dist/index.d.ts +2 -0
  157. package/node_modules/@comis/daemon/dist/index.js +5 -0
  158. package/node_modules/@comis/daemon/dist/observability/channel-health-logger.js +3 -3
  159. package/node_modules/@comis/daemon/dist/observability/delivery-queue-logger.js +1 -1
  160. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +22 -1
  161. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +84 -21
  162. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +2 -2
  163. package/node_modules/@comis/daemon/dist/rpc/config-handlers.d.ts +9 -1
  164. package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +104 -23
  165. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +30 -1
  166. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +74 -11
  167. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.d.ts +8 -0
  168. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.js +22 -8
  169. package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +9 -12
  170. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +1 -0
  171. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +27 -2
  172. package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +0 -1
  173. package/node_modules/@comis/daemon/dist/wiring/index.d.ts +2 -0
  174. package/node_modules/@comis/daemon/dist/wiring/index.js +1 -0
  175. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.d.ts +21 -0
  176. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.js +134 -0
  177. package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +46 -1
  178. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +127 -3
  179. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +39 -0
  180. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +32 -0
  181. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.d.ts +10 -3
  182. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.js +11 -5
  183. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +20 -1
  184. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +1 -1
  185. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.d.ts +14 -5
  186. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +52 -19
  187. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +4 -0
  188. package/node_modules/@comis/daemon/package.json +1 -1
  189. package/node_modules/@comis/gateway/dist/index.d.ts +2 -0
  190. package/node_modules/@comis/gateway/dist/index.js +2 -0
  191. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.d.ts +66 -0
  192. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.js +212 -0
  193. package/node_modules/@comis/gateway/dist/server/hono-server.d.ts +14 -0
  194. package/node_modules/@comis/gateway/dist/server/hono-server.js +10 -0
  195. package/node_modules/@comis/gateway/package.json +1 -1
  196. package/node_modules/@comis/infra/dist/logging/log-fields.d.ts +23 -0
  197. package/node_modules/@comis/infra/package.json +1 -1
  198. package/node_modules/@comis/memory/dist/compaction.d.ts +3 -5
  199. package/node_modules/@comis/memory/dist/compaction.js +2 -3
  200. package/node_modules/@comis/memory/dist/delivery-queue-adapter.d.ts +2 -2
  201. package/node_modules/@comis/memory/dist/delivery-queue-adapter.js +49 -1
  202. package/node_modules/@comis/memory/dist/index.d.ts +2 -0
  203. package/node_modules/@comis/memory/dist/index.js +3 -0
  204. package/node_modules/@comis/memory/dist/memory-api.d.ts +1 -1
  205. package/node_modules/@comis/memory/dist/memory-api.js +1 -1
  206. package/node_modules/@comis/memory/dist/oauth-profile-schema.d.ts +17 -0
  207. package/node_modules/@comis/memory/dist/oauth-profile-schema.js +33 -0
  208. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.d.ts +27 -0
  209. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.js +144 -0
  210. package/node_modules/@comis/memory/dist/session-store.d.ts +1 -1
  211. package/node_modules/@comis/memory/dist/session-store.js +1 -1
  212. package/node_modules/@comis/memory/dist/sqlite-secret-store.d.ts +29 -3
  213. package/node_modules/@comis/memory/dist/sqlite-secret-store.js +11 -3
  214. package/node_modules/@comis/memory/package.json +1 -1
  215. package/node_modules/@comis/scheduler/dist/execution/execution-lock.d.ts +13 -0
  216. package/node_modules/@comis/scheduler/dist/execution/execution-lock.js +1 -1
  217. package/node_modules/@comis/scheduler/dist/execution/index.d.ts +2 -0
  218. package/node_modules/@comis/scheduler/dist/execution/index.js +2 -0
  219. package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +1 -1
  220. package/node_modules/@comis/scheduler/dist/index.d.ts +2 -0
  221. package/node_modules/@comis/scheduler/dist/index.js +2 -0
  222. package/node_modules/@comis/scheduler/package.json +1 -1
  223. package/node_modules/@comis/shared/package.json +1 -1
  224. package/node_modules/@comis/skills/dist/bridge/schema-validator.d.ts +38 -0
  225. package/node_modules/@comis/skills/dist/bridge/schema-validator.js +169 -0
  226. package/node_modules/@comis/skills/dist/bridge/tool-metadata-enforcement.js +12 -0
  227. package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +130 -0
  228. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.d.ts +32 -0
  229. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.js +127 -0
  230. package/node_modules/@comis/skills/dist/builtin/exec-security.js +38 -0
  231. package/node_modules/@comis/skills/dist/builtin/exec-tool.js +9 -0
  232. package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +6 -6
  233. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +5 -4
  234. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +38 -27
  235. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -1
  236. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +3 -3
  237. package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
  238. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +6 -6
  239. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +1 -1
  240. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +9 -9
  241. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.d.ts +11 -0
  242. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.js +114 -1
  243. package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +40 -15
  244. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.d.ts +7 -0
  245. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.js +9 -2
  246. package/node_modules/@comis/skills/package.json +1 -1
  247. package/node_modules/@comis/web/dist/assets/{agent-detail-71BSbSfD.js → agent-detail-q8t1NB7w.js} +1 -1
  248. package/node_modules/@comis/web/dist/assets/{agent-editor-CTSDZhwT.js → agent-editor-B46io5gv.js} +1 -1
  249. package/node_modules/@comis/web/dist/assets/{agent-list-BEhni2ea.js → agent-list-DQ6g2Rcx.js} +1 -1
  250. package/node_modules/@comis/web/dist/assets/{billing-view-DVP1IvVs.js → billing-view-IWPR8LgF.js} +1 -1
  251. package/node_modules/@comis/web/dist/assets/{channel-detail-N_YK74xC.js → channel-detail-DlNNZuuC.js} +1 -1
  252. package/node_modules/@comis/web/dist/assets/{channel-list-DRk6ZJaF.js → channel-list-DhGwxiMc.js} +1 -1
  253. package/node_modules/@comis/web/dist/assets/{chat-console-Dm-GtSf9.js → chat-console-Nv6fM3Rc.js} +1 -1
  254. package/node_modules/@comis/web/dist/assets/{config-editor-CIferYX6.js → config-editor-BYKuJF76.js} +1 -1
  255. package/node_modules/@comis/web/dist/assets/{context-dag-browser-CL84rXXM.js → context-dag-browser-ClNEtzYE.js} +1 -1
  256. package/node_modules/@comis/web/dist/assets/{context-engine-B1HOTEZv.js → context-engine-BZJ6HChd.js} +1 -1
  257. package/node_modules/@comis/web/dist/assets/{delivery-view-Y6JKYVFw.js → delivery-view-Cb7I3vGu.js} +1 -1
  258. package/node_modules/@comis/web/dist/assets/{diagnostics-view-DWV1UQjz.js → diagnostics-view-9u9Lyu5a.js} +1 -1
  259. package/node_modules/@comis/web/dist/assets/{ic-chat-message-DfSERzzg.js → ic-chat-message-BFt3cVpx.js} +1 -1
  260. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CXyhlJup.js → ic-connection-dot-y77LZ3Gu.js} +1 -1
  261. package/node_modules/@comis/web/dist/assets/{ic-tool-call-DNmwTjek.js → ic-tool-call-qt6w1NQl.js} +1 -1
  262. package/node_modules/@comis/web/dist/assets/{index-CBr0Tm9_.js → index-8Tg9oc-C.js} +2 -2
  263. package/node_modules/@comis/web/dist/assets/{mcp-management-BaH2-vox.js → mcp-management-69dtH_kY.js} +2 -2
  264. package/node_modules/@comis/web/dist/assets/{media-config-CZLshJoN.js → media-config-BdjLj5c1.js} +1 -1
  265. package/node_modules/@comis/web/dist/assets/{media-test-C9NUWgo_.js → media-test-DuPqrixi.js} +1 -1
  266. package/node_modules/@comis/web/dist/assets/{memory-inspector-D_fmTcRN.js → memory-inspector-B-Pepbq-.js} +1 -1
  267. package/node_modules/@comis/web/dist/assets/{message-center-BBFlNCZn.js → message-center-B7l0yNYY.js} +1 -1
  268. package/node_modules/@comis/web/dist/assets/{models-BytGLm99.js → models-JHFHuv5S.js} +1 -1
  269. package/node_modules/@comis/web/dist/assets/{observe-view-VXtHqaqq.js → observe-view-r8mqhy4O.js} +1 -1
  270. package/node_modules/@comis/web/dist/assets/{pipeline-builder-CfXczlfJ.js → pipeline-builder-XjkiZRcR.js} +1 -1
  271. package/node_modules/@comis/web/dist/assets/{pipeline-history-CPmXFnbe.js → pipeline-history-CZqJv_Hj.js} +1 -1
  272. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-DcueTMs9.js → pipeline-history-detail-BEFGMoDy.js} +1 -1
  273. package/node_modules/@comis/web/dist/assets/{pipeline-list-B-xG5WZh.js → pipeline-list-B6q5LvO1.js} +1 -1
  274. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-pnIOYaSY.js → pipeline-monitor-BNomXjVL.js} +1 -1
  275. package/node_modules/@comis/web/dist/assets/{scheduler-BtUIFHhA.js → scheduler-BJEjcGKA.js} +1 -1
  276. package/node_modules/@comis/web/dist/assets/{security-C8mWRq2y.js → security-2G1jhBfV.js} +1 -1
  277. package/node_modules/@comis/web/dist/assets/{session-detail-DgdkO5ka.js → session-detail-DmVPzFBR.js} +1 -1
  278. package/node_modules/@comis/web/dist/assets/{session-list-DcylcfTn.js → session-list-CsqMQoHs.js} +1 -1
  279. package/node_modules/@comis/web/dist/assets/{setup-wizard-BP5yjsuL.js → setup-wizard-CAdM-gSP.js} +1 -1
  280. package/node_modules/@comis/web/dist/assets/{skills-DXt1bX8Z.js → skills-2ODqKaWr.js} +1 -1
  281. package/node_modules/@comis/web/dist/assets/{subagents-C7YbUHXY.js → subagents-BFlwfTbD.js} +1 -1
  282. package/node_modules/@comis/web/dist/assets/{workspace-manager-DP6pW4wa.js → workspace-manager--CbOx_dI.js} +1 -1
  283. package/node_modules/@comis/web/dist/index.html +1 -1
  284. package/node_modules/@comis/web/package.json +1 -1
  285. package/package.json +17 -16
@@ -1,6 +1,7 @@
1
1
  import type { BackgroundTasksConfig } from "@comis/core";
2
2
  import type { AgentToolResult } from "@mariozechner/pi-agent-core";
3
3
  import type { BackgroundTaskManager, NotifyFn } from "./background-task-manager.js";
4
+ import type { BackgroundTaskOrigin } from "./background-task-types.js";
4
5
  /**
5
6
  * Tool definition interface matching pi-agent-core ToolDefinition.
6
7
  *
@@ -19,9 +20,18 @@ export interface ToolDefinition {
19
20
  /**
20
21
  * Wrap a tool's execute() with auto-background promotion on timeout.
21
22
  *
23
+ * `originResolver` is called synchronously at promote-time (before the agent
24
+ * yields) so the captured origin reflects the originating session, not the
25
+ * background continuation context. Returns undefined when the wrap-site cannot
26
+ * resolve a valid origin (e.g., during a non-session-bound subagent path) --
27
+ * in that case the wrapper falls through to foreground execution (no promote).
28
+ *
29
+ * Explicit threading, NOT AsyncLocalStorage. Origin flows through factory
30
+ * params end-to-end.
31
+ *
22
32
  * If the tool is in `config.excludeTools`, returns unchanged.
23
33
  * If the tool completes before `config.autoBackgroundMs`, returns the result directly.
24
34
  * If the tool exceeds the timeout, promotes to background via manager.promote().
25
35
  * If promotion fails (concurrency limit), awaits the tool normally (foreground fallback).
26
36
  */
27
- export declare function wrapToolForAutoBackground(tool: ToolDefinition, manager: BackgroundTaskManager, config: BackgroundTasksConfig, notifyFn: NotifyFn, agentId: string): ToolDefinition;
37
+ export declare function wrapToolForAutoBackground(tool: ToolDefinition, manager: BackgroundTaskManager, config: BackgroundTasksConfig, notifyFn: NotifyFn, originResolver: () => BackgroundTaskOrigin | undefined): ToolDefinition;
@@ -12,12 +12,21 @@ import { suppressError } from "@comis/shared";
12
12
  /**
13
13
  * Wrap a tool's execute() with auto-background promotion on timeout.
14
14
  *
15
+ * `originResolver` is called synchronously at promote-time (before the agent
16
+ * yields) so the captured origin reflects the originating session, not the
17
+ * background continuation context. Returns undefined when the wrap-site cannot
18
+ * resolve a valid origin (e.g., during a non-session-bound subagent path) --
19
+ * in that case the wrapper falls through to foreground execution (no promote).
20
+ *
21
+ * Explicit threading, NOT AsyncLocalStorage. Origin flows through factory
22
+ * params end-to-end.
23
+ *
15
24
  * If the tool is in `config.excludeTools`, returns unchanged.
16
25
  * If the tool completes before `config.autoBackgroundMs`, returns the result directly.
17
26
  * If the tool exceeds the timeout, promotes to background via manager.promote().
18
27
  * If promotion fails (concurrency limit), awaits the tool normally (foreground fallback).
19
28
  */
20
- export function wrapToolForAutoBackground(tool, manager, config, notifyFn, agentId) {
29
+ export function wrapToolForAutoBackground(tool, manager, config, notifyFn, originResolver) {
21
30
  if (config.excludeTools.includes(tool.name)) {
22
31
  return tool;
23
32
  }
@@ -57,8 +66,16 @@ export function wrapToolForAutoBackground(tool, manager, config, notifyFn, agent
57
66
  if (raceResult.kind === "result") {
58
67
  return raceResult.value;
59
68
  }
60
- // Timeout: attempt background promotion
61
- const promoteResult = manager.promote(agentId, tool.name, taskPromise, ac);
69
+ // Timeout: resolve origin synchronously before yielding to the background.
70
+ // Explicit threading, NOT AsyncLocalStorage.
71
+ const origin = originResolver();
72
+ if (!origin) {
73
+ // No originating session context (e.g., wrap-site is a subagent without
74
+ // a captured caller session). Treat like a concurrency-limit fallback:
75
+ // run the tool in the foreground, no background promotion.
76
+ return await taskPromise;
77
+ }
78
+ const promoteResult = manager.promote(tool.name, taskPromise, ac, origin);
62
79
  if (!promoteResult.ok) {
63
80
  // Concurrency limit hit: fall back to foreground (await normally)
64
81
  return await taskPromise;
@@ -73,7 +90,7 @@ export function wrapToolForAutoBackground(tool, manager, config, notifyFn, agent
73
90
  // collapses to `content: undefined` and triggers the silent-LLM-failure
74
91
  // cascade (see AGENTS.md / auto-background-middleware.test.ts invariant).
75
92
  const placeholderText = `Tool "${tool.name}" is taking longer than expected and has been moved to the background. ` +
76
- `Task ID: ${taskId}. The user will be notified when it completes.`;
93
+ `Task ID: ${taskId}. I'll continue when it completes.`;
77
94
  return {
78
95
  content: [{ type: "text", text: placeholderText }],
79
96
  details: {
@@ -1,6 +1,6 @@
1
1
  import { type Result } from "@comis/shared";
2
2
  import type { TypedEventBus } from "@comis/core";
3
- import type { BackgroundTask } from "./background-task-types.js";
3
+ import type { BackgroundTask, BackgroundTaskOrigin } from "./background-task-types.js";
4
4
  /** Notification callback fired when background task completes or fails. */
5
5
  export type NotifyFn = (opts: {
6
6
  agentId: string;
@@ -21,7 +21,7 @@ export interface BackgroundTaskManagerOpts {
21
21
  maxBackgroundDurationMs?: number;
22
22
  }
23
23
  export interface BackgroundTaskManager {
24
- promote(agentId: string, toolName: string, promise: Promise<unknown>, ac: AbortController): Result<string, Error>;
24
+ promote(toolName: string, promise: Promise<unknown>, ac: AbortController, origin: BackgroundTaskOrigin): Result<string, Error>;
25
25
  complete(taskId: string, result: unknown, notifyFn?: NotifyFn): void;
26
26
  fail(taskId: string, error: unknown, notifyFn?: NotifyFn): void;
27
27
  cancel(taskId: string): Result<void, Error>;
@@ -35,7 +35,26 @@ export function createBackgroundTaskManager(opts) {
35
35
  }
36
36
  }
37
37
  const manager = {
38
- promote(agentId, toolName, promise, ac) {
38
+ promote(toolName, promise, ac, origin) {
39
+ // Reject calls with missing/invalid origin (no silent fallback).
40
+ if (!origin || typeof origin !== "object") {
41
+ return err(new Error("BackgroundTaskOrigin is required (received undefined or non-object)"));
42
+ }
43
+ if (!origin.agentId || origin.agentId.length === 0) {
44
+ return err(new Error("BackgroundTaskOrigin.agentId must be a non-empty string"));
45
+ }
46
+ if (!origin.sessionKey || origin.sessionKey.length === 0) {
47
+ return err(new Error("BackgroundTaskOrigin.sessionKey must be a non-empty string"));
48
+ }
49
+ if (!origin.channelType || origin.channelType.length === 0) {
50
+ return err(new Error("BackgroundTaskOrigin.channelType must be a non-empty string"));
51
+ }
52
+ if (!origin.channelId || origin.channelId.length === 0) {
53
+ return err(new Error("BackgroundTaskOrigin.channelId must be a non-empty string"));
54
+ }
55
+ // traceId may be null (per BackgroundTaskOriginSchema), so no length check.
56
+ // backgroundHopCount has a schema-level default of 0; no inline guard needed.
57
+ const agentId = origin.agentId;
39
58
  const agentCurrent = perAgentCount.get(agentId) ?? 0;
40
59
  if (agentCurrent >= maxPerAgent) {
41
60
  return err(new Error(`Concurrency limit exceeded: agent ${agentId} has ${agentCurrent}/${maxPerAgent} tasks`));
@@ -46,24 +65,25 @@ export function createBackgroundTaskManager(opts) {
46
65
  const taskId = randomUUID();
47
66
  const task = {
48
67
  id: taskId,
49
- agentId,
50
68
  toolName,
51
69
  status: "running",
52
70
  startedAt: Date.now(),
71
+ origin,
53
72
  _promise: promise,
54
73
  _abortController: ac,
55
74
  };
56
- tasks.set(taskId, task);
57
- incrementCounters(agentId);
58
- // sync write BEFORE returning placeholder
59
- persistTaskSync(dataDir, task);
60
- // Hard timeout
61
- task._hardTimeoutTimer = setTimeout(() => {
75
+ // Hard-timeout abort
76
+ const timer = setTimeout(() => {
62
77
  if (task.status === "running") {
63
78
  ac.abort();
64
79
  manager.fail(taskId, new Error("Hard timeout exceeded"));
65
80
  }
66
81
  }, maxBackgroundDurationMs);
82
+ timer.unref();
83
+ task._hardTimeoutTimer = timer;
84
+ tasks.set(taskId, task);
85
+ incrementCounters(agentId);
86
+ persistTaskSync(dataDir, task);
67
87
  eventBus.emit("background_task:promoted", {
68
88
  agentId,
69
89
  taskId,
@@ -81,19 +101,20 @@ export function createBackgroundTaskManager(opts) {
81
101
  task.result = truncateResult(result);
82
102
  if (task._hardTimeoutTimer)
83
103
  clearTimeout(task._hardTimeoutTimer);
84
- decrementCounters(task.agentId);
104
+ decrementCounters(task.origin.agentId);
85
105
  persistTaskSync(dataDir, task);
86
106
  const durationMs = task.completedAt - task.startedAt;
87
107
  eventBus.emit("background_task:completed", {
88
- agentId: task.agentId,
108
+ agentId: task.origin.agentId,
89
109
  taskId,
90
110
  toolName: task.toolName,
91
111
  durationMs,
112
+ origin: task.origin,
92
113
  timestamp: Date.now(),
93
114
  });
94
115
  if (notifyFn) {
95
116
  suppressError(notifyFn({
96
- agentId: task.agentId,
117
+ agentId: task.origin.agentId,
97
118
  message: `Background task "${task.toolName}" completed (${Math.round(durationMs / 1000)}s). Task ID: ${taskId}`,
98
119
  priority: "normal",
99
120
  origin: "background_task",
@@ -109,20 +130,21 @@ export function createBackgroundTaskManager(opts) {
109
130
  task.error = error instanceof Error ? error.message : String(error);
110
131
  if (task._hardTimeoutTimer)
111
132
  clearTimeout(task._hardTimeoutTimer);
112
- decrementCounters(task.agentId);
133
+ decrementCounters(task.origin.agentId);
113
134
  persistTaskSync(dataDir, task);
114
135
  const durationMs = task.completedAt - task.startedAt;
115
136
  eventBus.emit("background_task:failed", {
116
- agentId: task.agentId,
137
+ agentId: task.origin.agentId,
117
138
  taskId,
118
139
  toolName: task.toolName,
119
140
  error: task.error,
120
141
  durationMs,
142
+ origin: task.origin,
121
143
  timestamp: Date.now(),
122
144
  });
123
145
  if (notifyFn) {
124
146
  suppressError(notifyFn({
125
- agentId: task.agentId,
147
+ agentId: task.origin.agentId,
126
148
  message: `Background task "${task.toolName}" failed: ${task.error}. Task ID: ${taskId}`,
127
149
  priority: "normal",
128
150
  origin: "background_task",
@@ -141,10 +163,10 @@ export function createBackgroundTaskManager(opts) {
141
163
  task._abortController.abort();
142
164
  if (task._hardTimeoutTimer)
143
165
  clearTimeout(task._hardTimeoutTimer);
144
- decrementCounters(task.agentId);
166
+ decrementCounters(task.origin.agentId);
145
167
  persistTaskSync(dataDir, task);
146
168
  eventBus.emit("background_task:cancelled", {
147
- agentId: task.agentId,
169
+ agentId: task.origin.agentId,
148
170
  taskId,
149
171
  toolName: task.toolName,
150
172
  timestamp: Date.now(),
@@ -155,7 +177,7 @@ export function createBackgroundTaskManager(opts) {
155
177
  return tasks.get(taskId);
156
178
  },
157
179
  getTasks(agentId) {
158
- return [...tasks.values()].filter((t) => t.agentId === agentId);
180
+ return [...tasks.values()].filter((t) => t.origin.agentId === agentId);
159
181
  },
160
182
  getAllTasks() {
161
183
  return [...tasks.values()];
@@ -163,8 +185,19 @@ export function createBackgroundTaskManager(opts) {
163
185
  recoverOnStartup() {
164
186
  const recovered = recoverTasks(dataDir);
165
187
  let count = 0;
188
+ let skipped = 0;
166
189
  for (const persisted of recovered) {
167
- // Only import tasks that were recovered (previously running -> now failed)
190
+ if (!persisted.origin || typeof persisted.origin !== "object" || !persisted.origin.agentId || !persisted.origin.sessionKey) {
191
+ // Legacy file without origin. Skip with a warning -- the file
192
+ // remains on disk for audit, but the manager doesn't import it.
193
+ skipped++;
194
+ logger.warn({
195
+ taskId: persisted.id,
196
+ hint: "Legacy task file lacks origin; skipping recovery -- delete the file or wait for cleanup",
197
+ errorKind: "internal",
198
+ }, "Skipping recovered task without origin");
199
+ continue;
200
+ }
168
201
  const task = {
169
202
  ...persisted,
170
203
  };
@@ -172,11 +205,12 @@ export function createBackgroundTaskManager(opts) {
172
205
  if (persisted.status === "failed" && persisted.error === "Daemon restarted while task was running") {
173
206
  count++;
174
207
  eventBus.emit("background_task:failed", {
175
- agentId: task.agentId,
208
+ agentId: task.origin.agentId,
176
209
  taskId: task.id,
177
210
  toolName: task.toolName,
178
211
  error: persisted.error,
179
212
  durationMs: (persisted.completedAt ?? Date.now()) - persisted.startedAt,
213
+ origin: task.origin,
180
214
  timestamp: Date.now(),
181
215
  });
182
216
  }
@@ -184,13 +218,20 @@ export function createBackgroundTaskManager(opts) {
184
218
  if (count > 0) {
185
219
  logger.info({ count }, "Recovered background tasks marked as failed");
186
220
  }
221
+ if (skipped > 0) {
222
+ logger.warn({
223
+ skipped,
224
+ hint: "Legacy task files cannot be recovered without origin -- they remain on disk for audit",
225
+ errorKind: "internal",
226
+ }, "Skipped legacy task files during recovery");
227
+ }
187
228
  },
188
229
  cleanup(maxAgeMs = 86_400_000) {
189
230
  const cutoff = Date.now() - maxAgeMs;
190
231
  for (const [taskId, task] of tasks) {
191
232
  if (task.status !== "running" && (task.completedAt ?? task.startedAt) < cutoff) {
192
233
  tasks.delete(taskId);
193
- removeTaskFile(dataDir, task.agentId, taskId);
234
+ removeTaskFile(dataDir, task.origin.agentId, taskId);
194
235
  }
195
236
  }
196
237
  },
@@ -17,13 +17,13 @@ export const TASK_DIR_NAME = "background-tasks";
17
17
  function toPersistedState(task) {
18
18
  return {
19
19
  id: task.id,
20
- agentId: task.agentId,
21
20
  toolName: task.toolName,
22
21
  status: task.status,
23
22
  startedAt: task.startedAt,
24
23
  completedAt: task.completedAt,
25
24
  result: task.result,
26
25
  error: task.error,
26
+ origin: task.origin,
27
27
  };
28
28
  }
29
29
  /**
@@ -32,7 +32,7 @@ function toPersistedState(task) {
32
32
  * Writes to `dataDir/{agentId}/{taskId}.json`.
33
33
  */
34
34
  export function persistTaskSync(dataDir, task) {
35
- const agentDir = safePath(dataDir, task.agentId);
35
+ const agentDir = safePath(dataDir, task.origin.agentId);
36
36
  mkdirSync(agentDir, { recursive: true });
37
37
  const filePath = safePath(agentDir, `${task.id}.json`);
38
38
  const state = "_promise" in task ? toPersistedState(task) : task;
@@ -85,7 +85,14 @@ export function recoverTasks(dataDir) {
85
85
  const filePath = safePath(agentDir, file);
86
86
  try {
87
87
  const raw = readFileSync(filePath, "utf-8");
88
- const task = JSON.parse(raw);
88
+ const parsed = JSON.parse(raw);
89
+ // Sanity guard: skip completely malformed files (no id or toolName).
90
+ // Files missing origin (pre-Phase-14) are passed through to the manager
91
+ // so recoverOnStartup can warn about them and track the skip count.
92
+ if (!parsed.id || !parsed.toolName) {
93
+ continue;
94
+ }
95
+ const task = parsed;
89
96
  if (task.status === "running") {
90
97
  task.status = "failed";
91
98
  task.error = "Daemon restarted while task was running";
@@ -1,18 +1,23 @@
1
1
  /**
2
- * Background task types for automatic tool execution promotion.
2
+ * Background task type definitions.
3
3
  *
4
4
  * @module
5
5
  */
6
+ import type { BackgroundTaskOrigin } from "@comis/core";
7
+ export type { BackgroundTaskOrigin };
6
8
  export type BackgroundTaskStatus = "running" | "completed" | "failed" | "cancelled";
7
9
  export interface BackgroundTask {
8
10
  id: string;
9
- agentId: string;
10
11
  toolName: string;
11
12
  status: BackgroundTaskStatus;
12
13
  startedAt: number;
13
14
  completedAt?: number;
14
15
  result?: string;
15
16
  error?: string;
17
+ /** Originating session attribution (incl. backgroundHopCount) -- captured at
18
+ * promote-time, persisted on disk, preserved across recoverOnStartup.
19
+ * Required (no silent fallback). */
20
+ origin: BackgroundTaskOrigin;
16
21
  _promise?: Promise<unknown>;
17
22
  _abortController?: AbortController;
18
23
  _hardTimeoutTimer?: ReturnType<typeof setTimeout>;
@@ -20,11 +25,13 @@ export interface BackgroundTask {
20
25
  /** Serializable subset of BackgroundTask for file persistence. */
21
26
  export interface PersistedTaskState {
22
27
  id: string;
23
- agentId: string;
24
28
  toolName: string;
25
29
  status: BackgroundTaskStatus;
26
30
  startedAt: number;
27
31
  completedAt?: number;
28
32
  result?: string;
29
33
  error?: string;
34
+ /** Persisted origin -- read back by recoverOnStartup so completion routing
35
+ * survives daemon restarts. */
36
+ origin: BackgroundTaskOrigin;
30
37
  }
@@ -1,6 +1,6 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  /**
3
- * Background task types for automatic tool execution promotion.
3
+ * Background task type definitions.
4
4
  *
5
5
  * @module
6
6
  */
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Background completion formatter: transforms a BackgroundTask into a
3
+ * tagged announcement string ready for injection into the originating
4
+ * agent's session as a synthetic NormalizedMessage.
5
+ *
6
+ * Mirrors the shape of packages/agent/src/spawn/narrative-caster.ts (the
7
+ * sub-agent announcement formatter). Simplified: no condensation levels,
8
+ * no metadata stats, no labels -- just a single tool result with
9
+ * toolName + result/error.
10
+ *
11
+ * The trailing instruction is byte-identical to TRAILING_INSTRUCTION in
12
+ * narrative-caster.ts so AnnouncementBatcher.stripSystemPrefix()
13
+ * (announcement-batcher.ts:81-85) keeps working unchanged.
14
+ *
15
+ * Pure synchronous string formatting -- no async, no LLM calls, no I/O.
16
+ *
17
+ * @module
18
+ */
19
+ import type { BackgroundTask } from "./background-task-types.js";
20
+ /** Re-export so consumers (tests, completion runner) can assert byte-identity. */
21
+ export { TRAILING_INSTRUCTION } from "../spawn/narrative-caster.js";
22
+ /**
23
+ * Format a BackgroundTask completion or failure into a tagged announcement.
24
+ *
25
+ * Header forms:
26
+ * - success: `[Background Task: ${toolName}]`
27
+ * - failure: `[Background Task Failed: ${toolName}]`
28
+ *
29
+ * Body:
30
+ * - success: `task.result` (already capped at 100 KB by manager.truncateResult).
31
+ * - generic failure: `task.error`.
32
+ * - restart-recovery failure (`task.error === "Daemon restarted while task was running"`):
33
+ * uses the explicit recovery copy.
34
+ *
35
+ * Total-length cap: NormalizedMessageSchema.text limits at 32768 chars.
36
+ * If the assembled string would exceed the cap, only the body section is
37
+ * truncated; the header and trailing instruction are NEVER touched.
38
+ */
39
+ export declare function formatCompletionAnnouncement(task: BackgroundTask): string;
@@ -0,0 +1,77 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Background completion formatter: transforms a BackgroundTask into a
4
+ * tagged announcement string ready for injection into the originating
5
+ * agent's session as a synthetic NormalizedMessage.
6
+ *
7
+ * Mirrors the shape of packages/agent/src/spawn/narrative-caster.ts (the
8
+ * sub-agent announcement formatter). Simplified: no condensation levels,
9
+ * no metadata stats, no labels -- just a single tool result with
10
+ * toolName + result/error.
11
+ *
12
+ * The trailing instruction is byte-identical to TRAILING_INSTRUCTION in
13
+ * narrative-caster.ts so AnnouncementBatcher.stripSystemPrefix()
14
+ * (announcement-batcher.ts:81-85) keeps working unchanged.
15
+ *
16
+ * Pure synchronous string formatting -- no async, no LLM calls, no I/O.
17
+ *
18
+ * @module
19
+ */
20
+ import { TRAILING_INSTRUCTION } from "../spawn/narrative-caster.js";
21
+ /** Re-export so consumers (tests, completion runner) can assert byte-identity. */
22
+ export { TRAILING_INSTRUCTION } from "../spawn/narrative-caster.js";
23
+ /** NormalizedMessageSchema.text caps at 32768 chars. Reserve headroom for header + trailing instruction. */
24
+ const MAX_ANNOUNCEMENT_CHARS = 32768;
25
+ const TRUNCATION_MARKER = "\n…[truncated]";
26
+ /** Recovery announcement body for tasks failed via recoverOnStartup. */
27
+ const RESTART_RECOVERY_BODY = "This background task was interrupted by a daemon restart. The result is unavailable; let the user know if relevant.";
28
+ const RESTART_RECOVERY_ERROR = "Daemon restarted while task was running";
29
+ /**
30
+ * Format a BackgroundTask completion or failure into a tagged announcement.
31
+ *
32
+ * Header forms:
33
+ * - success: `[Background Task: ${toolName}]`
34
+ * - failure: `[Background Task Failed: ${toolName}]`
35
+ *
36
+ * Body:
37
+ * - success: `task.result` (already capped at 100 KB by manager.truncateResult).
38
+ * - generic failure: `task.error`.
39
+ * - restart-recovery failure (`task.error === "Daemon restarted while task was running"`):
40
+ * uses the explicit recovery copy.
41
+ *
42
+ * Total-length cap: NormalizedMessageSchema.text limits at 32768 chars.
43
+ * If the assembled string would exceed the cap, only the body section is
44
+ * truncated; the header and trailing instruction are NEVER touched.
45
+ */
46
+ export function formatCompletionAnnouncement(task) {
47
+ const isFailure = task.status === "failed" || task.status === "cancelled";
48
+ const headerPrefix = isFailure ? "Background Task Failed" : "Background Task";
49
+ const header = `[${headerPrefix}: ${task.toolName}]`;
50
+ let body;
51
+ if (isFailure) {
52
+ const rawError = task.error ?? "(no error message)";
53
+ body = rawError === RESTART_RECOVERY_ERROR ? RESTART_RECOVERY_BODY : rawError;
54
+ }
55
+ else {
56
+ body = task.result ?? "(no result)";
57
+ }
58
+ // Build assembled string: header, blank line, body, blank line, trailing instruction.
59
+ const sections = [];
60
+ sections.push(header);
61
+ sections.push("");
62
+ sections.push(body);
63
+ sections.push("");
64
+ sections.push(TRAILING_INSTRUCTION);
65
+ let assembled = sections.join("\n");
66
+ // Enforce NormalizedMessageSchema.text.max(32768). Truncate the body section
67
+ // ONLY if needed; header and trailing instruction are byte-identical guarantees.
68
+ if (assembled.length > MAX_ANNOUNCEMENT_CHARS) {
69
+ const headerSection = `${header}\n\n`;
70
+ const tailSection = `\n\n${TRAILING_INSTRUCTION}`;
71
+ const reservedChars = headerSection.length + tailSection.length + TRUNCATION_MARKER.length;
72
+ const allowedBodyChars = MAX_ANNOUNCEMENT_CHARS - reservedChars;
73
+ const truncatedBody = body.slice(0, Math.max(0, allowedBodyChars)) + TRUNCATION_MARKER;
74
+ assembled = headerSection + truncatedBody + tailSection;
75
+ }
76
+ return assembled;
77
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Background completion runner: subscribes to background_task:completed and
3
+ * background_task:failed events from the TypedEventBus and re-enters the
4
+ * originating agent session with a formatted completion announcement.
5
+ *
6
+ * Per-session lock serialization is delegated to the existing session
7
+ * manager (ComisSessionManager.withSession in packages/agent/src/session/).
8
+ * The runner does NOT introduce its own queueing -- one turn per completion
9
+ * event, ordering follows the existing per-session lock.
10
+ *
11
+ * Recursion bound: per-task incoming hop count + 1 must stay below
12
+ * `maxBackgroundHops` (default 3). When the cap is hit, the runner emits
13
+ * the fallback notification instead of triggering executor.execute().
14
+ * The hop count is read from `task.origin.backgroundHopCount`
15
+ * (populated by the originResolver).
16
+ *
17
+ * Latency-instrumentation hook: emits `background_task:reentered`
18
+ * immediately before executor.execute(). Integration tests compute the delta
19
+ * from `background_task:completed.timestamp` to this event for SLO tracking.
20
+ *
21
+ * Failure isolation: each handler is wrapped in suppressError so a single
22
+ * completion's failure does not tear down the subscription (AGENTS §2.1).
23
+ *
24
+ * @module
25
+ */
26
+ import type { TypedEventBus } from "@comis/core";
27
+ import type { ComisLogger } from "@comis/infra";
28
+ import type { AgentExecutor } from "../executor/types.js";
29
+ import type { BackgroundTaskManager, NotifyFn } from "./background-task-manager.js";
30
+ /** Public-facing handle on the runner returned by createBackgroundCompletionRunner. */
31
+ export interface BackgroundCompletionRunner {
32
+ /** Unsubscribe from the event bus. Idempotent. Awaitable so callers can
33
+ * ensure no in-flight handler outlives the daemon shutdown. */
34
+ shutdown(): Promise<void>;
35
+ }
36
+ /** Minimal session-store contract the runner needs (fallback gate). */
37
+ export interface RunnerSessionStore {
38
+ loadByFormattedKey(sessionKey: string): unknown | undefined;
39
+ }
40
+ export interface BackgroundCompletionRunnerDeps {
41
+ eventBus: TypedEventBus;
42
+ getExecutor: (agentId: string) => AgentExecutor;
43
+ sessionStore: RunnerSessionStore;
44
+ taskManager: Pick<BackgroundTaskManager, "getTask">;
45
+ fallbackNotifyFn: NotifyFn;
46
+ maxBackgroundHops: number;
47
+ logger: ComisLogger;
48
+ }
49
+ /**
50
+ * Wire the completion runner against an event bus + executor + session store.
51
+ * Subscriptions are installed synchronously; call shutdown() to remove them.
52
+ */
53
+ export declare function createBackgroundCompletionRunner(deps: BackgroundCompletionRunnerDeps): BackgroundCompletionRunner;