comisai 1.0.36 → 1.0.37

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 (239) hide show
  1. package/node_modules/@comis/agent/dist/background/auto-background-middleware.js +9 -0
  2. package/node_modules/@comis/agent/dist/background/background-task-manager.d.ts +22 -2
  3. package/node_modules/@comis/agent/dist/background/background-task-manager.js +48 -41
  4. package/node_modules/@comis/agent/dist/background/background-task-persistence.js +28 -5
  5. package/node_modules/@comis/agent/dist/background/background-task-types.d.ts +49 -0
  6. package/node_modules/@comis/agent/dist/background/completion-dispatcher.d.ts +130 -0
  7. package/node_modules/@comis/agent/dist/background/completion-dispatcher.js +215 -0
  8. package/node_modules/@comis/agent/dist/background/completion-runner.d.ts +10 -1
  9. package/node_modules/@comis/agent/dist/background/completion-runner.js +98 -15
  10. package/node_modules/@comis/agent/dist/background/index.d.ts +6 -1
  11. package/node_modules/@comis/agent/dist/background/index.js +2 -0
  12. package/node_modules/@comis/agent/dist/background/session-resolver.d.ts +85 -0
  13. package/node_modules/@comis/agent/dist/background/session-resolver.js +78 -0
  14. package/node_modules/@comis/agent/dist/bootstrap/sections/messaging-sections.js +1 -0
  15. package/node_modules/@comis/agent/dist/bootstrap/sections/tool-descriptions.js +3 -3
  16. package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.d.ts +30 -2
  17. package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.js +51 -2
  18. package/node_modules/@comis/agent/dist/bootstrap/system-prompt-assembler.d.ts +22 -0
  19. package/node_modules/@comis/agent/dist/bootstrap/system-prompt-assembler.js +2 -2
  20. package/node_modules/@comis/agent/dist/bridge/bridge-event-handlers.d.ts +1 -5
  21. package/node_modules/@comis/agent/dist/bridge/bridge-event-handlers.js +2 -14
  22. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +26 -0
  23. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +3 -0
  24. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +9 -0
  25. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +73 -2
  26. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.d.ts +10 -10
  27. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.js +14 -14
  28. package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.d.ts +11 -13
  29. package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.js +14 -15
  30. package/node_modules/@comis/agent/dist/executor/capability-index-context.d.ts +72 -0
  31. package/node_modules/@comis/agent/dist/executor/capability-index-context.js +329 -0
  32. package/node_modules/@comis/agent/dist/executor/drain-helper.d.ts +122 -0
  33. package/node_modules/@comis/agent/dist/executor/drain-helper.js +173 -0
  34. package/node_modules/@comis/agent/dist/executor/error-classifier.js +2 -2
  35. package/node_modules/@comis/agent/dist/executor/executor-post-execution.d.ts +48 -4
  36. package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +134 -31
  37. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.d.ts +7 -0
  38. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +25 -4
  39. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.d.ts +18 -1
  40. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +19 -16
  41. package/node_modules/@comis/agent/dist/executor/jit-guide-injector.d.ts +11 -2
  42. package/node_modules/@comis/agent/dist/executor/jit-guide-injector.js +16 -2
  43. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +8 -2
  44. package/node_modules/@comis/agent/dist/executor/pi-executor.js +25 -12
  45. package/node_modules/@comis/agent/dist/executor/prompt-assembly.d.ts +9 -1
  46. package/node_modules/@comis/agent/dist/executor/prompt-assembly.js +15 -1
  47. package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +18 -27
  48. package/node_modules/@comis/agent/dist/executor/tool-deferral.js +29 -38
  49. package/node_modules/@comis/agent/dist/model/model-registry-adapter.js +1 -1
  50. package/node_modules/@comis/agent/dist/model/model-scanner.js +1 -1
  51. package/node_modules/@comis/agent/dist/safety/tool-retry-breaker.d.ts +11 -1
  52. package/node_modules/@comis/agent/dist/safety/tool-retry-breaker.js +19 -22
  53. package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +16 -2
  54. package/node_modules/@comis/agent/dist/spawn/pi-mono-adapters.d.ts +1 -1
  55. package/node_modules/@comis/agent/dist/spawn/pi-mono-adapters.js +5 -5
  56. package/node_modules/@comis/agent/dist/workspace/data-env.d.ts +38 -0
  57. package/node_modules/@comis/agent/dist/workspace/data-env.js +56 -0
  58. package/node_modules/@comis/agent/dist/workspace/index.d.ts +1 -0
  59. package/node_modules/@comis/agent/dist/workspace/index.js +1 -0
  60. package/node_modules/@comis/agent/dist/workspace/templates.js +5 -1
  61. package/node_modules/@comis/agent/package.json +1 -1
  62. package/node_modules/@comis/channels/dist/index.d.ts +1 -1
  63. package/node_modules/@comis/channels/dist/index.js +1 -1
  64. package/node_modules/@comis/channels/dist/shared/channel-manager.d.ts +9 -3
  65. package/node_modules/@comis/channels/dist/shared/inbound-gate.d.ts +1 -1
  66. package/node_modules/@comis/channels/dist/shared/inbound-gate.js +22 -7
  67. package/node_modules/@comis/channels/dist/shared/inbound-pipeline.d.ts +10 -3
  68. package/node_modules/@comis/channels/dist/shared/inbound-route.d.ts +1 -1
  69. package/node_modules/@comis/channels/dist/shared/inbound-route.js +13 -2
  70. package/node_modules/@comis/channels/dist/shared/response-filter.d.ts +11 -24
  71. package/node_modules/@comis/channels/dist/shared/response-filter.js +25 -53
  72. package/node_modules/@comis/channels/package.json +1 -1
  73. package/node_modules/@comis/cli/dist/commands/providers.d.ts +1 -2
  74. package/node_modules/@comis/cli/dist/commands/providers.js +5 -6
  75. package/node_modules/@comis/cli/package.json +1 -1
  76. package/node_modules/@comis/core/dist/config/field-metadata.js +2 -0
  77. package/node_modules/@comis/core/dist/config/immutable-keys.js +4 -1
  78. package/node_modules/@comis/core/dist/config/index.d.ts +4 -0
  79. package/node_modules/@comis/core/dist/config/index.js +2 -0
  80. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +0 -792
  81. package/node_modules/@comis/core/dist/config/schema-approvals.d.ts +0 -14
  82. package/node_modules/@comis/core/dist/config/schema-auto-reply-engine.d.ts +0 -6
  83. package/node_modules/@comis/core/dist/config/schema-background-tasks.d.ts +0 -12
  84. package/node_modules/@comis/core/dist/config/schema-browser.d.ts +0 -18
  85. package/node_modules/@comis/core/dist/config/schema-channel.d.ts +0 -158
  86. package/node_modules/@comis/core/dist/config/schema-coalescer.d.ts +0 -5
  87. package/node_modules/@comis/core/dist/config/schema-daemon.d.ts +0 -32
  88. package/node_modules/@comis/core/dist/config/schema-delivery.d.ts +0 -18
  89. package/node_modules/@comis/core/dist/config/schema-documentation.d.ts +0 -12
  90. package/node_modules/@comis/core/dist/config/schema-embedding.d.ts +0 -20
  91. package/node_modules/@comis/core/dist/config/schema-envelope.d.ts +0 -15
  92. package/node_modules/@comis/core/dist/config/schema-gateway.d.ts +0 -37
  93. package/node_modules/@comis/core/dist/config/schema-gemini-cache.d.ts +0 -2
  94. package/node_modules/@comis/core/dist/config/schema-integrations.d.ts +0 -318
  95. package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.d.ts +0 -18
  96. package/node_modules/@comis/core/dist/config/schema-memory-review.d.ts +0 -7
  97. package/node_modules/@comis/core/dist/config/schema-memory.d.ts +0 -16
  98. package/node_modules/@comis/core/dist/config/schema-messages.d.ts +0 -8
  99. package/node_modules/@comis/core/dist/config/schema-models.d.ts +0 -15
  100. package/node_modules/@comis/core/dist/config/schema-notification.d.ts +0 -5
  101. package/node_modules/@comis/core/dist/config/schema-oauth.d.ts +0 -5
  102. package/node_modules/@comis/core/dist/config/schema-observability.d.ts +0 -38
  103. package/node_modules/@comis/core/dist/config/schema-output-retention.d.ts +34 -0
  104. package/node_modules/@comis/core/dist/config/schema-output-retention.js +48 -0
  105. package/node_modules/@comis/core/dist/config/schema-plugins.d.ts +0 -8
  106. package/node_modules/@comis/core/dist/config/schema-providers.d.ts +0 -64
  107. package/node_modules/@comis/core/dist/config/schema-queue.d.ts +0 -58
  108. package/node_modules/@comis/core/dist/config/schema-response-prefix.d.ts +0 -2
  109. package/node_modules/@comis/core/dist/config/schema-retry.d.ts +0 -6
  110. package/node_modules/@comis/core/dist/config/schema-scheduler.d.ts +0 -39
  111. package/node_modules/@comis/core/dist/config/schema-secrets.d.ts +0 -3
  112. package/node_modules/@comis/core/dist/config/schema-security.d.ts +0 -18
  113. package/node_modules/@comis/core/dist/config/schema-send-policy.d.ts +0 -13
  114. package/node_modules/@comis/core/dist/config/schema-sender-trust-display.d.ts +0 -5
  115. package/node_modules/@comis/core/dist/config/schema-serializer.js +2 -0
  116. package/node_modules/@comis/core/dist/config/schema-skills.d.ts +0 -61
  117. package/node_modules/@comis/core/dist/config/schema-streaming.d.ts +0 -38
  118. package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.d.ts +0 -3
  119. package/node_modules/@comis/core/dist/config/schema-tooling.d.ts +87 -0
  120. package/node_modules/@comis/core/dist/config/schema-tooling.js +152 -0
  121. package/node_modules/@comis/core/dist/config/schema-verbosity.d.ts +0 -12
  122. package/node_modules/@comis/core/dist/config/schema-webhooks.d.ts +0 -40
  123. package/node_modules/@comis/core/dist/config/schema.d.ts +41 -38
  124. package/node_modules/@comis/core/dist/config/schema.js +6 -0
  125. package/node_modules/@comis/core/dist/context/context.d.ts +0 -4
  126. package/node_modules/@comis/core/dist/domain/approval-request.d.ts +0 -17
  127. package/node_modules/@comis/core/dist/domain/background-task-origin.d.ts +0 -10
  128. package/node_modules/@comis/core/dist/domain/delivery-origin.d.ts +0 -5
  129. package/node_modules/@comis/core/dist/domain/execution-graph.d.ts +0 -48
  130. package/node_modules/@comis/core/dist/domain/memory-entry.d.ts +0 -3
  131. package/node_modules/@comis/core/dist/domain/model-compat.d.ts +0 -4
  132. package/node_modules/@comis/core/dist/domain/normalized-message.d.ts +0 -15
  133. package/node_modules/@comis/core/dist/domain/provider-capabilities.d.ts +0 -6
  134. package/node_modules/@comis/core/dist/domain/rich-message.d.ts +0 -14
  135. package/node_modules/@comis/core/dist/domain/subagent-context-config.d.ts +0 -22
  136. package/node_modules/@comis/core/dist/domain/subagent-context-types.d.ts +0 -8
  137. package/node_modules/@comis/core/dist/event-bus/events-agent.d.ts +31 -0
  138. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +5 -0
  139. package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
  140. package/node_modules/@comis/core/dist/exports/config.js +3 -1
  141. package/node_modules/@comis/core/dist/exports/hooks.d.ts +1 -1
  142. package/node_modules/@comis/core/dist/exports/ports.d.ts +2 -2
  143. package/node_modules/@comis/core/dist/exports/ports.js +1 -1
  144. package/node_modules/@comis/core/dist/ports/channel-plugin.d.ts +0 -13
  145. package/node_modules/@comis/core/dist/ports/index.d.ts +2 -0
  146. package/node_modules/@comis/core/dist/ports/index.js +4 -0
  147. package/node_modules/@comis/core/dist/ports/no-op-tool-capability.d.ts +30 -0
  148. package/node_modules/@comis/core/dist/ports/no-op-tool-capability.js +47 -0
  149. package/node_modules/@comis/core/dist/ports/tool-capability.d.ts +165 -0
  150. package/node_modules/@comis/core/dist/ports/tool-capability.js +15 -0
  151. package/node_modules/@comis/core/dist/security/audit.d.ts +0 -11
  152. package/node_modules/@comis/core/dist/tool-metadata.d.ts +21 -1
  153. package/node_modules/@comis/core/dist/tool-metadata.js +1 -1
  154. package/node_modules/@comis/core/package.json +1 -1
  155. package/node_modules/@comis/daemon/bundled-skills/skill-creator/scripts/validate-skill.py +1 -1
  156. package/node_modules/@comis/daemon/dist/daemon.js +89 -14
  157. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.d.ts +1 -1
  158. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +1 -1
  159. package/node_modules/@comis/daemon/dist/rpc/builtin-provider-guard.js +2 -2
  160. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +1 -1
  161. package/node_modules/@comis/daemon/dist/rpc/model-handlers.d.ts +1 -1
  162. package/node_modules/@comis/daemon/dist/rpc/model-handlers.js +2 -2
  163. package/node_modules/@comis/daemon/dist/sub-agent-runner.d.ts +18 -0
  164. package/node_modules/@comis/daemon/dist/sub-agent-runner.js +41 -9
  165. package/node_modules/@comis/daemon/dist/wiring/index.d.ts +2 -0
  166. package/node_modules/@comis/daemon/dist/wiring/index.js +1 -0
  167. package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +36 -2
  168. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +45 -8
  169. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +28 -9
  170. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +36 -9
  171. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.js +2 -2
  172. package/node_modules/@comis/daemon/dist/wiring/setup-channels.d.ts +9 -2
  173. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +15 -9
  174. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.d.ts +20 -5
  175. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +20 -15
  176. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +14 -2
  177. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.d.ts +4 -6
  178. package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +3 -5
  179. package/node_modules/@comis/daemon/dist/wiring/setup-heartbeat.d.ts +20 -5
  180. package/node_modules/@comis/daemon/dist/wiring/setup-heartbeat.js +11 -2
  181. package/node_modules/@comis/daemon/dist/wiring/setup-output-retention.d.ts +89 -0
  182. package/node_modules/@comis/daemon/dist/wiring/setup-output-retention.js +212 -0
  183. package/node_modules/@comis/daemon/dist/wiring/setup-tools.d.ts +18 -4
  184. package/node_modules/@comis/daemon/dist/wiring/setup-tools.js +29 -10
  185. package/node_modules/@comis/daemon/dist/wiring/tool-capability-adapter.d.ts +75 -0
  186. package/node_modules/@comis/daemon/dist/wiring/tool-capability-adapter.js +253 -0
  187. package/node_modules/@comis/daemon/package.json +1 -1
  188. package/node_modules/@comis/gateway/dist/webhook/webhook-endpoint.d.ts +0 -4
  189. package/node_modules/@comis/gateway/package.json +1 -1
  190. package/node_modules/@comis/infra/package.json +1 -1
  191. package/node_modules/@comis/memory/package.json +1 -1
  192. package/node_modules/@comis/scheduler/dist/cron/cron-types.d.ts +0 -42
  193. package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.d.ts +29 -8
  194. package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +19 -7
  195. package/node_modules/@comis/scheduler/dist/system-events/system-event-types.d.ts +0 -3
  196. package/node_modules/@comis/scheduler/dist/tasks/task-types.d.ts +0 -17
  197. package/node_modules/@comis/scheduler/package.json +1 -1
  198. package/node_modules/@comis/shared/dist/index.d.ts +3 -0
  199. package/node_modules/@comis/shared/dist/index.js +4 -0
  200. package/node_modules/@comis/shared/dist/mcp-tool-name.d.ts +78 -0
  201. package/node_modules/@comis/shared/dist/mcp-tool-name.js +92 -0
  202. package/node_modules/@comis/shared/dist/silent-tokens.d.ts +38 -0
  203. package/node_modules/@comis/shared/dist/silent-tokens.js +51 -0
  204. package/node_modules/@comis/shared/dist/visible-delivery.d.ts +28 -0
  205. package/node_modules/@comis/shared/dist/visible-delivery.js +16 -0
  206. package/node_modules/@comis/shared/package.json +1 -1
  207. package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.d.ts +2 -13
  208. package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.js +3 -21
  209. package/node_modules/@comis/skills/dist/bridge/tool-metadata-enforcement.js +1 -1
  210. package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +4 -4
  211. package/node_modules/@comis/skills/dist/builtin/exec-tool.d.ts +55 -9
  212. package/node_modules/@comis/skills/dist/builtin/exec-tool.js +383 -19
  213. package/node_modules/@comis/skills/dist/builtin/install-detour.d.ts +67 -0
  214. package/node_modules/@comis/skills/dist/builtin/install-detour.js +342 -0
  215. package/node_modules/@comis/skills/dist/builtin/platform/admin-manage-factory.js +5 -5
  216. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +2 -2
  217. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +2 -2
  218. package/node_modules/@comis/skills/dist/builtin/platform/message-tool.js +18 -0
  219. package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.d.ts +18 -1
  220. package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.js +18 -2
  221. package/node_modules/@comis/skills/dist/builtin/platform/models-manage-tool.js +3 -3
  222. package/node_modules/@comis/skills/dist/builtin/process-registry.d.ts +14 -0
  223. package/node_modules/@comis/skills/dist/builtin/process-tool.d.ts +24 -4
  224. package/node_modules/@comis/skills/dist/builtin/process-tool.js +25 -7
  225. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.d.ts +1 -1
  226. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.js +9 -0
  227. package/node_modules/@comis/skills/dist/index.d.ts +4 -1
  228. package/node_modules/@comis/skills/dist/index.js +3 -1
  229. package/node_modules/@comis/skills/dist/manifest/capability-parser.d.ts +44 -0
  230. package/node_modules/@comis/skills/dist/manifest/capability-parser.js +68 -0
  231. package/node_modules/@comis/skills/dist/manifest/schema.d.ts +44 -37
  232. package/node_modules/@comis/skills/dist/manifest/schema.js +35 -0
  233. package/node_modules/@comis/skills/dist/registry/discovery.d.ts +8 -0
  234. package/node_modules/@comis/skills/dist/registry/discovery.js +10 -3
  235. package/node_modules/@comis/skills/dist/registry/skill-registry.d.ts +45 -1
  236. package/node_modules/@comis/skills/dist/registry/skill-registry.js +70 -7
  237. package/node_modules/@comis/skills/package.json +1 -1
  238. package/node_modules/@comis/web/package.json +1 -1
  239. package/package.json +21 -21
@@ -1,14 +1,13 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  /**
3
3
  * Tool assembly setup: assembleToolsForAgent and preprocessMessageText.
4
- * Extracted from daemon.ts steps 6.6.8.5 (tool pipeline assembly) to isolate
5
- * per-agent tool creation and message preprocessing from the main wiring
6
- * sequence.
4
+ * Isolates per-agent tool creation and message preprocessing from the
5
+ * main wiring sequence.
7
6
  * @module
8
7
  */
9
8
  import { isAbsolute, resolve } from "node:path";
10
9
  import { enterConfigMutationFence, leaveConfigMutationFence } from "../rpc/persist-to-config.js";
11
- import { SkillsConfigSchema, sanitizeLogString, tryGetContext, parseFormattedSessionKey, safePath, formatSessionKey } from "@comis/core";
10
+ import { SkillsConfigSchema, sanitizeLogString, tryGetContext, parseFormattedSessionKey, safePath, formatSessionKey, } from "@comis/core";
12
11
  import { sessionKeyToPath, WORKSPACE_FILE_NAMES, DEFAULT_TEMPLATES, registerWorkspaceFilesInTracker, } from "@comis/agent";
13
12
  import { stat as fsStat } from "node:fs/promises";
14
13
  import { assembleToolPipeline, createFileStateTracker, createCronTool, createUnifiedMemoryTool, createUnifiedSessionTool, createUnifiedContextTool, createMessageTool, createDiscordActionTool, createTelegramActionTool, createSlackActionTool, createWhatsAppActionTool, createSessionsSendTool, createSessionsSpawnTool, createSubagentsTool, createPipelineTool, createImageTool, createTTSTool, createTranscribeAudioTool, createDescribeVideoTool, createExtractDocumentTool, createGatewayTool, createBrowserTool, createAgentsManageTool, createObsQueryTool, createSessionsManageTool, createModelsManageTool, createTokensManageTool, createChannelsManageTool, createSkillsManageTool, createMcpManageTool, createHeartbeatManageTool, createProvidersManageTool, createNotifyTool, createImageGenerateTool, createBackgroundTasksTool, createExecTool, createProcessTool, createProcessRegistry, createApplyPatchTool, sanitizeImageForApi, createMediaPersistenceService, createCredentialInjector, mcpToolsToAgentTools, TOOL_PROFILES, TOOL_GROUPS, } from "@comis/skills";
@@ -117,7 +116,7 @@ export function setupTools(deps) {
117
116
  // admin agents are covered by agents_manage's onAgentCreated callback.
118
117
  const ownWorkspaceDir = workspaceDirs.get(agentId) ?? defaultWorkspaceDir;
119
118
  await registerWorkspaceFilesInTracker(ownWorkspaceDir, fileStateTracker, skillsLogger);
120
- // Enrich sharedPaths for admin-trust agents: grant cross-workspace file access (Quick 165)
119
+ // Enrich sharedPaths for admin-trust agents: grant cross-workspace file access.
121
120
  // Default agent (orchestrator) and supervisor-profile agents can access other agent workspaces.
122
121
  // Lazy callback for admin agents so hot-added workspaces are visible without re-assembling tools.
123
122
  const isDefaultAgent = agentId === defaultAgentId;
@@ -273,15 +272,35 @@ export function setupTools(deps) {
273
272
  const sessionDir = sessionKeyToPath(parsed, sessionBaseDir);
274
273
  return safePath(sessionDir, "tool-results");
275
274
  };
276
- tools.push(createExecTool(agentWorkspaceDir, registry, secretManager, platformSecretNames, skillsLogger, subprocessEnv, // Filtered subprocess environment
277
- sandboxCfg, // Per-agent sandbox config
278
- eventBus, // command:blocked + secret:accessed audit events
279
- getToolResultsDir));
275
+ tools.push(createExecTool({
276
+ workspacePath: agentWorkspaceDir,
277
+ registry,
278
+ secretManager,
279
+ platformSecretNames,
280
+ logger: skillsLogger,
281
+ subprocessEnv, // Filtered subprocess environment
282
+ sandboxConfig: sandboxCfg, // Per-agent sandbox config
283
+ eventBus, // command:blocked + secret:accessed audit events
284
+ getToolResultsDir, // Session tool-results dir for output persistence
285
+ // Live per-agent ToolCapabilityPort resolver populated by daemon.ts
286
+ // from AgentsResult.toolCapabilityPorts map. Single mandated form
287
+ // `deps.<field>(agentId)` mirrors the surrounding direct-deps-access
288
+ // convention.
289
+ toolCapabilityPort: deps.getCapabilityPortForAgent(agentId),
290
+ approvalGate, // Soft-stop override path
291
+ }));
280
292
  }
281
293
  // Process tool -- always instantiated; builtinTools ceiling applied after profile filtering
282
294
  {
283
295
  const registry = getOrCreateRegistry(agentId);
284
- tools.push(createProcessTool(registry, skillsLogger));
296
+ tools.push(createProcessTool({
297
+ registry,
298
+ logger: skillsLogger,
299
+ // Live per-agent ToolCapabilityPort resolver populated by daemon.ts
300
+ // from AgentsResult.toolCapabilityPorts. Single mandated form
301
+ // `deps.<field>(agentId)`.
302
+ toolCapabilityPort: deps.getCapabilityPortForAgent(agentId),
303
+ }));
285
304
  }
286
305
  // Apply patch tool -- always included, gated by tool policy
287
306
  tools.push(createApplyPatchTool(workspaceDirs.get(agentId) ?? defaultWorkspaceDir, effectiveSharedPaths, skillsLogger));
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Live ToolCapabilityPort adapter -- daemon-side wiring.
3
+ *
4
+ * Factory whose 9 frozen methods read live state from:
5
+ * - `deps.toolingConfig` (operator config; the `tooling.*` subtree)
6
+ * - `deps.skillRegistry` (already applies allow/deny + eligibility +
7
+ * disableModelInvocation filters)
8
+ * - `deps.mcpClientManager` (live MCP connection state per server)
9
+ *
10
+ * Cross-field cluster-ID validation runs at construction time across three
11
+ * surfaces (`builtinAssignments`, `mcp.capabilityHints[*].cluster`,
12
+ * `skills.capabilityHints[*].cluster`). Operator typos emit a Pino WARN with
13
+ * { errorKind: "config", configPath, unresolvedClusterId, hint }
14
+ * and DO NOT throw -- lookup-time fallback applies (`external-integrations`
15
+ * for unresolved MCP clusters; `prompt-skills` for unresolved skill clusters).
16
+ * WARN (not DEBUG) is intentional: operator visibility for misconfiguration.
17
+ *
18
+ * Default merge contract: `mergedClusters = { ...DEFAULT_CLUSTER_CONFIG,
19
+ * ...operator.clusters }` because `z.record(...).default({})` would replace
20
+ * the entire record. Empty operator config preserves the 3 reserved IDs;
21
+ * partial-add preserves defaults plus addition; per-key override wins for the
22
+ * overridden key only. The same shape applies to `mergedBuiltinAssignments`.
23
+ *
24
+ * Liveness:
25
+ * - `getConnectedMcpServers()` filters `getAllConnections()` by
26
+ * `c.status === "connected"` on EVERY call -- never cached at construction
27
+ * (TOCTOU mitigation).
28
+ * - `getPackageAliasMap()` rebuilds fresh per call from operator MCP hints +
29
+ * visible skills + universal MCP fallback. No memoization.
30
+ * - `getPromptSkillCapabilities()` re-invokes `skillRegistry`'s sweep on
31
+ * every call; the operator-hint callback resolves through `port.getSkillHint`
32
+ * at call time (the arrow lambda holds the `port` reference, not a
33
+ * snapshot of `getSkillHint`).
34
+ *
35
+ * Returned port is `Object.freeze`d -- post-construction tampering is
36
+ * structurally impossible in strict mode (silently no-ops in sloppy mode).
37
+ *
38
+ * Boundary discipline: production source MUST NOT import test stubs from
39
+ * `@comis/core/__test-helpers/`.
40
+ *
41
+ * @module
42
+ */
43
+ import type { ToolCapabilityPort, ToolingConfig } from "@comis/core";
44
+ import type { SkillRegistry, McpClientManager } from "@comis/skills";
45
+ import type { ComisLogger } from "@comis/infra";
46
+ /**
47
+ * Dependencies for the live ToolCapabilityPort adapter.
48
+ *
49
+ * Receivers MUST hold the daemon's container.config.tooling slice (NOT the
50
+ * top-level AppConfig) and the live skill registry / MCP client manager
51
+ * instances -- the adapter closes over them and re-reads on every method call.
52
+ */
53
+ export interface ToolCapabilityAdapterDeps {
54
+ readonly toolingConfig: ToolingConfig;
55
+ readonly skillRegistry: SkillRegistry;
56
+ readonly mcpClientManager: McpClientManager;
57
+ readonly logger: ComisLogger;
58
+ }
59
+ /**
60
+ * Build the live ToolCapabilityPort adapter.
61
+ *
62
+ * Pure synchronous function. Construction-time work:
63
+ * - Key-by-key merge of `DEFAULT_CLUSTER_CONFIG` with operator clusters.
64
+ * - Key-by-key merge of `DEFAULT_BUILTIN_ASSIGNMENTS` with operator assignments.
65
+ * - Cross-field cluster-ID validation across 3 surfaces (one Pino WARN per
66
+ * unresolved reference; never throws).
67
+ *
68
+ * Lookup-time work:
69
+ * - All 9 port methods are closures over the merged maps + the live
70
+ * `skillRegistry` / `mcpClientManager` references.
71
+ *
72
+ * @param deps - The adapter's dependencies.
73
+ * @returns A frozen `ToolCapabilityPort`.
74
+ */
75
+ export declare function createToolCapabilityAdapter(deps: ToolCapabilityAdapterDeps): ToolCapabilityPort;
@@ -0,0 +1,253 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Live ToolCapabilityPort adapter -- daemon-side wiring.
4
+ *
5
+ * Factory whose 9 frozen methods read live state from:
6
+ * - `deps.toolingConfig` (operator config; the `tooling.*` subtree)
7
+ * - `deps.skillRegistry` (already applies allow/deny + eligibility +
8
+ * disableModelInvocation filters)
9
+ * - `deps.mcpClientManager` (live MCP connection state per server)
10
+ *
11
+ * Cross-field cluster-ID validation runs at construction time across three
12
+ * surfaces (`builtinAssignments`, `mcp.capabilityHints[*].cluster`,
13
+ * `skills.capabilityHints[*].cluster`). Operator typos emit a Pino WARN with
14
+ * { errorKind: "config", configPath, unresolvedClusterId, hint }
15
+ * and DO NOT throw -- lookup-time fallback applies (`external-integrations`
16
+ * for unresolved MCP clusters; `prompt-skills` for unresolved skill clusters).
17
+ * WARN (not DEBUG) is intentional: operator visibility for misconfiguration.
18
+ *
19
+ * Default merge contract: `mergedClusters = { ...DEFAULT_CLUSTER_CONFIG,
20
+ * ...operator.clusters }` because `z.record(...).default({})` would replace
21
+ * the entire record. Empty operator config preserves the 3 reserved IDs;
22
+ * partial-add preserves defaults plus addition; per-key override wins for the
23
+ * overridden key only. The same shape applies to `mergedBuiltinAssignments`.
24
+ *
25
+ * Liveness:
26
+ * - `getConnectedMcpServers()` filters `getAllConnections()` by
27
+ * `c.status === "connected"` on EVERY call -- never cached at construction
28
+ * (TOCTOU mitigation).
29
+ * - `getPackageAliasMap()` rebuilds fresh per call from operator MCP hints +
30
+ * visible skills + universal MCP fallback. No memoization.
31
+ * - `getPromptSkillCapabilities()` re-invokes `skillRegistry`'s sweep on
32
+ * every call; the operator-hint callback resolves through `port.getSkillHint`
33
+ * at call time (the arrow lambda holds the `port` reference, not a
34
+ * snapshot of `getSkillHint`).
35
+ *
36
+ * Returned port is `Object.freeze`d -- post-construction tampering is
37
+ * structurally impossible in strict mode (silently no-ops in sloppy mode).
38
+ *
39
+ * Boundary discipline: production source MUST NOT import test stubs from
40
+ * `@comis/core/__test-helpers/`.
41
+ *
42
+ * @module
43
+ */
44
+ import { DEFAULT_CLUSTER_CONFIG, DEFAULT_BUILTIN_ASSIGNMENTS, getToolMetadata, } from "@comis/core";
45
+ // Module-level reference-stable empty alias map. Returned only when no
46
+ // operator hints / visible skills / connected servers exist; downstream
47
+ // callers can rely on stable identity for cheap equality checks.
48
+ const EMPTY_ALIAS_MAP = new Map();
49
+ /**
50
+ * PEP-503-like normalization for package alias keys.
51
+ *
52
+ * - npm scoped packages (`@scope/name`) are preserved as-is, lowercased.
53
+ * - Everything else: lowercased, with runs of `_`, `.`, `-` collapsed to a
54
+ * single `-`.
55
+ *
56
+ * @param pkg - The raw package identifier from operator config or skill metadata.
57
+ * @returns The normalized key for `getPackageAliasMap`.
58
+ */
59
+ function normalizeAliasKey(pkg) {
60
+ if (pkg.startsWith("@"))
61
+ return pkg.toLowerCase();
62
+ return pkg.toLowerCase().replace(/[_.\-]+/g, "-");
63
+ }
64
+ /**
65
+ * Build the live ToolCapabilityPort adapter.
66
+ *
67
+ * Pure synchronous function. Construction-time work:
68
+ * - Key-by-key merge of `DEFAULT_CLUSTER_CONFIG` with operator clusters.
69
+ * - Key-by-key merge of `DEFAULT_BUILTIN_ASSIGNMENTS` with operator assignments.
70
+ * - Cross-field cluster-ID validation across 3 surfaces (one Pino WARN per
71
+ * unresolved reference; never throws).
72
+ *
73
+ * Lookup-time work:
74
+ * - All 9 port methods are closures over the merged maps + the live
75
+ * `skillRegistry` / `mcpClientManager` references.
76
+ *
77
+ * @param deps - The adapter's dependencies.
78
+ * @returns A frozen `ToolCapabilityPort`.
79
+ */
80
+ export function createToolCapabilityAdapter(deps) {
81
+ const log = deps.logger.child({ submodule: "tool-capability-adapter" });
82
+ // Key-by-key default merge at adapter construction. Schema cannot supply
83
+ // DEFAULT_CLUSTER_CONFIG via `.default(...)` because z.record(...).default({})
84
+ // replaces the entire record.
85
+ const mergedClusters = {
86
+ ...DEFAULT_CLUSTER_CONFIG,
87
+ ...deps.toolingConfig.capabilityClusters.clusters,
88
+ };
89
+ const mergedBuiltinAssignments = {
90
+ ...DEFAULT_BUILTIN_ASSIGNMENTS,
91
+ ...deps.toolingConfig.capabilityClusters.builtinAssignments,
92
+ };
93
+ // Build the validation set once; used by all three loops AND by the lookup
94
+ // closures below (so a runtime typo also falls through to the documented
95
+ // fallback rather than silently substituting at lookup time).
96
+ const validClusterIds = new Set(Object.keys(mergedClusters));
97
+ // ---------------------------------------------------------------------------
98
+ // Cross-field cluster-ID validation (3 surfaces). Each loop emits one Pino
99
+ // WARN per unresolved reference. Construction is total -- no throws.
100
+ // ---------------------------------------------------------------------------
101
+ // Surface 1: builtinAssignments[toolName] -> clusterId
102
+ for (const [toolName, clusterId] of Object.entries(mergedBuiltinAssignments)) {
103
+ if (!validClusterIds.has(clusterId)) {
104
+ log.warn({
105
+ hint: `Add cluster '${clusterId}' to tooling.capabilityClusters.clusters or fix the reference at tooling.capabilityClusters.builtinAssignments.${toolName}`,
106
+ errorKind: "config",
107
+ configPath: `tooling.capabilityClusters.builtinAssignments.${toolName}`,
108
+ unresolvedClusterId: clusterId,
109
+ }, "Unresolved cluster ID in tooling config (builtinAssignments)");
110
+ }
111
+ }
112
+ // Surface 2: mcp.capabilityHints[serverName].cluster
113
+ for (const [serverName, hint] of Object.entries(deps.toolingConfig.mcp.capabilityHints)) {
114
+ if (!validClusterIds.has(hint.cluster)) {
115
+ log.warn({
116
+ hint: `Add cluster '${hint.cluster}' to tooling.capabilityClusters.clusters or fix the reference at tooling.mcp.capabilityHints.${serverName}.cluster`,
117
+ errorKind: "config",
118
+ configPath: `tooling.mcp.capabilityHints.${serverName}.cluster`,
119
+ unresolvedClusterId: hint.cluster,
120
+ }, "Unresolved cluster ID in tooling config (mcp.capabilityHints)");
121
+ }
122
+ }
123
+ // Surface 3: skills.capabilityHints[skillName].cluster
124
+ for (const [skillName, hint] of Object.entries(deps.toolingConfig.skills.capabilityHints)) {
125
+ if (!validClusterIds.has(hint.cluster)) {
126
+ log.warn({
127
+ hint: `Add cluster '${hint.cluster}' to tooling.capabilityClusters.clusters or fix the reference at tooling.skills.capabilityHints.${skillName}.cluster`,
128
+ errorKind: "config",
129
+ configPath: `tooling.skills.capabilityHints.${skillName}.cluster`,
130
+ unresolvedClusterId: hint.cluster,
131
+ }, "Unresolved cluster ID in tooling config (skills.capabilityHints)");
132
+ }
133
+ }
134
+ // ---------------------------------------------------------------------------
135
+ // Build the frozen port. All closures capture `deps`, `mergedClusters`,
136
+ // `mergedBuiltinAssignments`, and `validClusterIds` lexically; runtime state
137
+ // (MCP connections, visible skills) is re-read on every method call.
138
+ // ---------------------------------------------------------------------------
139
+ const port = Object.freeze({
140
+ isCapabilityIndexEnabled: () => deps.toolingConfig.capabilityIndex.enabled,
141
+ getInstallDetourMode: () => deps.toolingConfig.installDetours.mode,
142
+ getBuiltinCluster: (toolName) => {
143
+ // Operator override wins when it resolves; an unresolved override
144
+ // already triggered a construction-time WARN -- fall through to
145
+ // metadata so the caller never sees a phantom cluster ID.
146
+ const opOverride = mergedBuiltinAssignments[toolName];
147
+ if (opOverride !== undefined && validClusterIds.has(opOverride)) {
148
+ return opOverride;
149
+ }
150
+ const meta = getToolMetadata(toolName);
151
+ return meta?.capability?.cluster;
152
+ },
153
+ getClusterConfig: (clusterId) => mergedClusters[clusterId],
154
+ getMcpServerHint: (serverName) => {
155
+ const hint = deps.toolingConfig.mcp.capabilityHints[serverName];
156
+ if (!hint)
157
+ return undefined;
158
+ // Fallback: unresolved cluster -> "external-integrations".
159
+ const cluster = validClusterIds.has(hint.cluster)
160
+ ? hint.cluster
161
+ : "external-integrations";
162
+ return {
163
+ cluster,
164
+ description: hint.description,
165
+ replacesPackages: hint.replacesPackages,
166
+ };
167
+ },
168
+ getSkillHint: (skillName, skillKey) => {
169
+ // Precedence: operator(skillKey) > operator(skillName).
170
+ const hintByKey = skillKey
171
+ ? deps.toolingConfig.skills.capabilityHints[skillKey]
172
+ : undefined;
173
+ const hintByName = !hintByKey
174
+ ? deps.toolingConfig.skills.capabilityHints[skillName]
175
+ : undefined;
176
+ const hint = hintByKey ?? hintByName;
177
+ if (!hint)
178
+ return undefined;
179
+ // Fallback: unresolved cluster -> "prompt-skills".
180
+ const cluster = validClusterIds.has(hint.cluster)
181
+ ? hint.cluster
182
+ : "prompt-skills";
183
+ return {
184
+ cluster,
185
+ ...(hint.description !== undefined ? { description: hint.description } : {}),
186
+ replacesPackages: hint.replacesPackages,
187
+ };
188
+ },
189
+ getPackageAliasMap: () => {
190
+ // Fresh per call -- no memoization. Visible skills can change
191
+ // mid-session (file-watcher reloads, allow/deny edits); MCP servers
192
+ // connect/disconnect; capturing at construction would freeze stale
193
+ // state.
194
+ const skills = port.getPromptSkillCapabilities();
195
+ const connectedServers = port.getConnectedMcpServers();
196
+ const mcpHints = Object.entries(deps.toolingConfig.mcp.capabilityHints);
197
+ // Reference-stable empty result for cheap equality checks downstream.
198
+ if (mcpHints.length === 0 &&
199
+ skills.length === 0 &&
200
+ connectedServers.length === 0) {
201
+ return EMPTY_ALIAS_MAP;
202
+ }
203
+ const map = new Map();
204
+ // 1. Operator MCP hints -- replacesPackages entries point at the server.
205
+ for (const [serverName, hint] of mcpHints) {
206
+ for (const pkg of hint.replacesPackages) {
207
+ const key = normalizeAliasKey(pkg);
208
+ if (!map.has(key)) {
209
+ map.set(key, { type: "mcp", name: serverName });
210
+ }
211
+ }
212
+ }
213
+ // 2. Visible skills -- replacesPackages entries point at the skill.
214
+ // `port.getPromptSkillCapabilities()` reference resolves at call time;
215
+ // the lexical `port` const is in scope by the time
216
+ // `getPackageAliasMap` fires.
217
+ for (const skill of skills) {
218
+ for (const pkg of skill.replacesPackages) {
219
+ const key = normalizeAliasKey(pkg);
220
+ if (!map.has(key)) {
221
+ map.set(key, { type: "skill", name: skill.name });
222
+ }
223
+ }
224
+ }
225
+ // 3. Universal MCP fallback -- each connected server alias-keyed by its
226
+ // own name (so `pip install <serverName>` resolves to the server itself
227
+ // even without an operator-supplied replacesPackages entry).
228
+ for (const serverName of connectedServers) {
229
+ const key = normalizeAliasKey(serverName);
230
+ if (!map.has(key)) {
231
+ map.set(key, { type: "mcp", name: serverName });
232
+ }
233
+ }
234
+ // Reference-stability guarantee (line 80-82 module docstring):
235
+ // the early-return shortcut above only fires when ALL three input
236
+ // sources are length-zero. Operator hints / skills / connected servers
237
+ // that produce zero map entries (e.g. every hint has
238
+ // `replacesPackages: []`) bypass that shortcut and would otherwise
239
+ // return a fresh empty map -- silently breaking the documented
240
+ // identity-stable empty-result contract. Re-check the size after the
241
+ // loops complete and collapse to the shared sentinel when empty.
242
+ if (map.size === 0)
243
+ return EMPTY_ALIAS_MAP;
244
+ return map;
245
+ },
246
+ getConnectedMcpServers: () => deps.mcpClientManager
247
+ .getAllConnections()
248
+ .filter((c) => c.status === "connected")
249
+ .map((c) => c.name),
250
+ getPromptSkillCapabilities: () => deps.skillRegistry.getPromptSkillCapabilities((skillName, skillKey) => port.getSkillHint(skillName, skillKey)),
251
+ });
252
+ return port;
253
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/daemon",
3
3
  "private": true,
4
- "version": "1.0.36",
4
+ "version": "1.0.37",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Background daemon and orchestrator for the Comis platform",
@@ -19,13 +19,9 @@ interface WebhookEnv extends Env {
19
19
  * the required fields before passing to the handler.
20
20
  */
21
21
  export declare const WebhookPayloadSchema: z.ZodObject<{
22
- /** Event type (e.g., "deployment.completed", "alert.fired") */
23
22
  event: z.ZodString;
24
- /** Source system identifier */
25
23
  source: z.ZodString;
26
- /** Arbitrary event data */
27
24
  data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
28
- /** Optional ISO 8601 timestamp */
29
25
  timestamp: z.ZodOptional<z.ZodString>;
30
26
  }, z.core.$strict>;
31
27
  /**
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/gateway",
3
3
  "private": true,
4
- "version": "1.0.36",
4
+ "version": "1.0.37",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "HTTP, JSON-RPC, and WebSocket gateway for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/infra",
3
3
  "private": true,
4
- "version": "1.0.36",
4
+ "version": "1.0.37",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Structured logging infrastructure for Comis",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/memory",
3
3
  "private": true,
4
- "version": "1.0.36",
4
+ "version": "1.0.37",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "SQLite memory, embeddings, and RAG storage for Comis agents",
@@ -8,19 +8,14 @@ import { z } from "zod";
8
8
  */
9
9
  export declare const CronScheduleSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
10
10
  kind: z.ZodLiteral<"cron">;
11
- /** Standard cron expression (5 or 6 fields) */
12
11
  expr: z.ZodString;
13
- /** IANA timezone (e.g. "America/New_York"), omit for UTC */
14
12
  tz: z.ZodOptional<z.ZodString>;
15
13
  }, z.core.$strict>, z.ZodObject<{
16
14
  kind: z.ZodLiteral<"every">;
17
- /** Interval in milliseconds */
18
15
  everyMs: z.ZodNumber;
19
- /** Optional anchor timestamp in ms (first tick aligned to this) */
20
16
  anchorMs: z.ZodOptional<z.ZodNumber>;
21
17
  }, z.core.$strict>, z.ZodObject<{
22
18
  kind: z.ZodLiteral<"at">;
23
- /** ISO 8601 datetime string for one-shot execution */
24
19
  at: z.ZodString;
25
20
  }, z.core.$strict>], "kind">;
26
21
  export type CronSchedule = z.infer<typeof CronScheduleSchema>;
@@ -32,15 +27,11 @@ export type CronSchedule = z.infer<typeof CronScheduleSchema>;
32
27
  */
33
28
  export declare const CronPayloadSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
34
29
  kind: z.ZodLiteral<"system_event">;
35
- /** Event text to emit */
36
30
  text: z.ZodString;
37
31
  }, z.core.$strict>, z.ZodObject<{
38
32
  kind: z.ZodLiteral<"agent_turn">;
39
- /** Message to send to the agent */
40
33
  message: z.ZodString;
41
- /** Optional model override for this turn */
42
34
  model: z.ZodOptional<z.ZodString>;
43
- /** Optional timeout in seconds for this turn */
44
35
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
45
36
  }, z.core.$strict>], "kind">;
46
37
  export type CronPayload = z.infer<typeof CronPayloadSchema>;
@@ -80,99 +71,66 @@ export type CronDeliveryTarget = z.infer<typeof CronDeliveryTargetSchema>;
80
71
  * Full cron job definition.
81
72
  */
82
73
  export declare const CronJobSchema: z.ZodObject<{
83
- /** Unique job identifier */
84
74
  id: z.ZodString;
85
- /** Human-readable job name */
86
75
  name: z.ZodString;
87
- /** Agent ID that owns this job */
88
76
  agentId: z.ZodString;
89
- /** Schedule definition */
90
77
  schedule: z.ZodDiscriminatedUnion<[z.ZodObject<{
91
78
  kind: z.ZodLiteral<"cron">;
92
- /** Standard cron expression (5 or 6 fields) */
93
79
  expr: z.ZodString;
94
- /** IANA timezone (e.g. "America/New_York"), omit for UTC */
95
80
  tz: z.ZodOptional<z.ZodString>;
96
81
  }, z.core.$strict>, z.ZodObject<{
97
82
  kind: z.ZodLiteral<"every">;
98
- /** Interval in milliseconds */
99
83
  everyMs: z.ZodNumber;
100
- /** Optional anchor timestamp in ms (first tick aligned to this) */
101
84
  anchorMs: z.ZodOptional<z.ZodNumber>;
102
85
  }, z.core.$strict>, z.ZodObject<{
103
86
  kind: z.ZodLiteral<"at">;
104
- /** ISO 8601 datetime string for one-shot execution */
105
87
  at: z.ZodString;
106
88
  }, z.core.$strict>], "kind">;
107
- /** Payload to execute */
108
89
  payload: z.ZodDiscriminatedUnion<[z.ZodObject<{
109
90
  kind: z.ZodLiteral<"system_event">;
110
- /** Event text to emit */
111
91
  text: z.ZodString;
112
92
  }, z.core.$strict>, z.ZodObject<{
113
93
  kind: z.ZodLiteral<"agent_turn">;
114
- /** Message to send to the agent */
115
94
  message: z.ZodString;
116
- /** Optional model override for this turn */
117
95
  model: z.ZodOptional<z.ZodString>;
118
- /** Optional timeout in seconds for this turn */
119
96
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
120
97
  }, z.core.$strict>], "kind">;
121
- /** Session target for execution */
122
98
  sessionTarget: z.ZodDefault<z.ZodEnum<{
123
99
  main: "main";
124
100
  isolated: "isolated";
125
101
  }>>;
126
- /** Wake mode: when to trigger heartbeat after enqueuing a system event. */
127
102
  wakeMode: z.ZodDefault<z.ZodEnum<{
128
103
  now: "now";
129
104
  "next-heartbeat": "next-heartbeat";
130
105
  }>>;
131
- /** Whether to forward isolated session results back to main heartbeat session. */
132
106
  forwardToMain: z.ZodDefault<z.ZodBoolean>;
133
- /** Session history strategy for cron executions. Default: fresh. */
134
107
  sessionStrategy: z.ZodDefault<z.ZodEnum<{
135
108
  fresh: "fresh";
136
109
  rolling: "rolling";
137
110
  accumulate: "accumulate";
138
111
  }>>;
139
- /** Number of recent turns to keep for rolling strategy (default 3). */
140
112
  maxHistoryTurns: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
141
- /** Per-job cache retention override. Default inherits OPERATION_CACHE_DEFAULTS["cron"] = "short". */
142
113
  cacheRetention: z.ZodOptional<z.ZodEnum<{
143
114
  none: "none";
144
115
  short: "short";
145
116
  long: "long";
146
117
  }>>;
147
- /** Per-job tool policy override -- matches AgentConfig.toolPolicy shape.
148
- *
149
- * Resolution order: job.toolPolicy > agentConfig.toolPolicy > passthrough
150
- * (no filtering). Opt-in: omitting this field preserves existing tool set
151
- * for the job. No silent defaults -- operators explicitly request
152
- * conservative presets like `{ profile: "cron-minimal" }`. */
153
118
  toolPolicy: z.ZodOptional<z.ZodObject<{
154
119
  profile: z.ZodDefault<z.ZodString>;
155
120
  allow: z.ZodDefault<z.ZodArray<z.ZodString>>;
156
121
  deny: z.ZodDefault<z.ZodArray<z.ZodString>>;
157
122
  }, z.core.$strip>>;
158
- /** Delivery target for routing results to originating channel */
159
123
  deliveryTarget: z.ZodOptional<z.ZodObject<{
160
124
  channelId: z.ZodString;
161
125
  userId: z.ZodString;
162
126
  tenantId: z.ZodString;
163
127
  channelType: z.ZodOptional<z.ZodString>;
164
128
  }, z.core.$strict>>;
165
- /** Whether this job is currently enabled */
166
129
  enabled: z.ZodDefault<z.ZodBoolean>;
167
- /** Next scheduled run timestamp (ms since epoch) */
168
130
  nextRunAtMs: z.ZodOptional<z.ZodNumber>;
169
- /** Last completed run timestamp (ms since epoch) */
170
131
  lastRunAtMs: z.ZodOptional<z.ZodNumber>;
171
- /** Number of consecutive errors */
172
132
  consecutiveErrors: z.ZodDefault<z.ZodNumber>;
173
- /** Maximum consecutive errors before auto-suspend. Per-job override of scheduler default. */
174
133
  maxConsecutiveErrors: z.ZodOptional<z.ZodNumber>;
175
- /** Job creation timestamp (ms since epoch) */
176
134
  createdAtMs: z.ZodNumber;
177
135
  }, z.core.$strict>;
178
136
  export type CronJob = z.infer<typeof CronJobSchema>;
@@ -37,9 +37,19 @@ interface HeartbeatExecutor {
37
37
  response: string;
38
38
  }>;
39
39
  }
40
- /** Minimal ActiveRunRegistry -- only needs has() for queue-busy check. */
41
- interface HeartbeatActiveRunRegistry {
42
- has(sessionKey: string): boolean;
40
+ /**
41
+ * Minimal BackgroundSessionResolver shape -- only needs hasActiveSession()
42
+ * for the queue-busy check. The scheduler package cannot import @comis/agent
43
+ * (would create a cycle), so we re-declare the structural minimum here. The
44
+ * daemon wires `createBackgroundSessionResolver({activeRunRegistry})` and
45
+ * the resulting object is structurally assignable to this shape (R3, B36).
46
+ */
47
+ interface HeartbeatSessionResolver {
48
+ hasActiveSession(key: {
49
+ agentId: string;
50
+ channelType: string;
51
+ channelId: string;
52
+ }): boolean;
43
53
  }
44
54
  /** Tool policy filter function signature -- matches applyToolPolicy from @comis/skills.
45
55
  * Injected as a dep so scheduler doesn't take a hard dependency on skills. */
@@ -96,8 +106,12 @@ export interface AgentHeartbeatSourceDeps {
96
106
  systemEventQueue: SystemEventQueue;
97
107
  /** Delivery bridge dependencies for routing notifications. */
98
108
  deliveryBridge: DeliveryBridgeDeps;
99
- /** Optional ActiveRunRegistry for queue-busy detection. */
100
- activeRunRegistry?: HeartbeatActiveRunRegistry;
109
+ /**
110
+ * Optional composite-key resolver for queue-busy detection (R3, B36).
111
+ * Wired by the daemon as
112
+ * `createBackgroundSessionResolver({activeRunRegistry})`.
113
+ */
114
+ sessionResolver?: HeartbeatSessionResolver;
101
115
  /** Optional session operations for response processing side-effects. */
102
116
  sessionOps?: HeartbeatSessionOps;
103
117
  /** Optional: fetch memory stats for an agent (for heartbeat prompt injection). */
@@ -119,12 +133,19 @@ export interface AgentHeartbeatSourceDeps {
119
133
  */
120
134
  export declare function resolveHeartbeatModel(perAgentHeartbeatModel: string | undefined, globalHeartbeatModel: string | undefined, agentDefaultModel: string): string;
121
135
  /**
122
- * Check if a session is actively running an agent turn.
136
+ * Check if a session is actively running an agent turn (R3, B36).
123
137
  *
124
- * Returns false when no ActiveRunRegistry is provided (heartbeat
138
+ * Uses the composite-key resolver: `(agentId, channelType, channelId)`
139
+ * uniquely identifies a session across multi-agent / multi-channel
140
+ * deployments (the previous single-arg `formattedKey` collapsed those
141
+ * dimensions). Returns false when no resolver is provided (heartbeat
125
142
  * operates in isolation without collision detection).
126
143
  */
127
- export declare function isQueueBusy(activeRunRegistry: HeartbeatActiveRunRegistry | undefined, sessionKey: string): boolean;
144
+ export declare function isQueueBusy(sessionResolver: HeartbeatSessionResolver | undefined, composite: {
145
+ agentId: string;
146
+ channelType: string;
147
+ channelId: string;
148
+ }): boolean;
128
149
  /**
129
150
  * Resolve the SessionKey for a heartbeat tick.
130
151
  *