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
@@ -0,0 +1,56 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Workspace-internal data env resolver.
4
+ *
5
+ * Returns environment variables for python/matplotlib subprocesses that
6
+ * derive ALL paths from `workspaceDir`. Avoids slow pip installs in the
7
+ * chart hot path and matplotlib Fontconfig errors from a non-writable
8
+ * default cache dir.
9
+ *
10
+ * This file contains no host-env reads. Subprocesses inheriting the
11
+ * daemon's full environment can pick up host paths (e.g.
12
+ * `/root/.cache/matplotlib`) that fail under read-only systemd hardening
13
+ * (`ProtectSystem=strict`) and leak host PATH into the agent's tool
14
+ * execution.
15
+ *
16
+ * matplotlib + python deps install into the agent workspace's `venv/`.
17
+ * The Dockerfile pre-warms the default workspace's venv at image build
18
+ * time so first-chart latency drops; subsequent chart calls reuse the
19
+ * venv. Full Docker image size goes up (acceptable trade-off).
20
+ *
21
+ * Mirrors workspace-resolver.ts's safePath + workspaceDir precedent
22
+ * (no path.join, no host-env reads).
23
+ *
24
+ * @module
25
+ */
26
+ import { safePath } from "@comis/core";
27
+ /**
28
+ * Resolve workspace-internal env vars for python/matplotlib subprocesses.
29
+ *
30
+ * The returned record is intended to be MERGED over an existing subprocess
31
+ * env at the call site (e.g. exec-tool's `{ ...baseEnv, ...resolveDataEnv(...) }`),
32
+ * so the workspace-internal values win on collision and the host PATH /
33
+ * cache dirs are not surfaced inside the subprocess.
34
+ *
35
+ * @param opts.workspaceDir - Absolute path to the agent workspace.
36
+ * @returns env-var record suitable for `child_process.spawn(..., { env })`.
37
+ */
38
+ export function resolveDataEnv(opts) {
39
+ const venvBin = safePath(opts.workspaceDir, "venv", "bin");
40
+ const cacheDir = safePath(opts.workspaceDir, ".cache");
41
+ const mplDir = safePath(cacheDir, "matplotlib");
42
+ return {
43
+ // Python venv binaries on PATH (no host-PATH pollution).
44
+ PATH: venvBin,
45
+ // matplotlib config + cache dir (writable, workspace-internal).
46
+ MPLCONFIGDIR: mplDir,
47
+ // XDG cache spec -- fontconfig + other libs honor this.
48
+ XDG_CACHE_HOME: cacheDir,
49
+ // Force matplotlib to use a non-interactive backend (avoids
50
+ // Tkinter / X11 dependencies that would bloat the container image
51
+ // and otherwise crash on headless containers).
52
+ MPLBACKEND: "Agg",
53
+ // Disable pip's distrust of the (workspace-internal) venv path.
54
+ PIP_DISABLE_PIP_VERSION_CHECK: "1",
55
+ };
56
+ }
@@ -1,6 +1,7 @@
1
1
  export { ensureWorkspace, getWorkspaceStatus, registerWorkspaceFilesInTracker, WORKSPACE_SUBDIRS, } from "./workspace-manager.js";
2
2
  export type { WorkspaceFiles, EnsureWorkspaceOptions, WorkspaceStatus, WorkspaceSeedTracker, RegisterWorkspaceResult, } from "./workspace-manager.js";
3
3
  export { resolveWorkspaceDir } from "./workspace-resolver.js";
4
+ export { resolveDataEnv } from "./data-env.js";
4
5
  export { WORKSPACE_FILE_NAMES, DEFAULT_TEMPLATES } from "./templates.js";
5
6
  export type { WorkspaceFileName } from "./templates.js";
6
7
  export { isHeartbeatContentEffectivelyEmpty } from "./heartbeat-file.js";
@@ -1,6 +1,7 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  export { ensureWorkspace, getWorkspaceStatus, registerWorkspaceFilesInTracker, WORKSPACE_SUBDIRS, } from "./workspace-manager.js";
3
3
  export { resolveWorkspaceDir } from "./workspace-resolver.js";
4
+ export { resolveDataEnv } from "./data-env.js";
4
5
  export { WORKSPACE_FILE_NAMES, DEFAULT_TEMPLATES } from "./templates.js";
5
6
  export { isHeartbeatContentEffectivelyEmpty } from "./heartbeat-file.js";
6
7
  export { isBootContentEffectivelyEmpty, BOOT_FILE_NAME } from "./boot-file.js";
@@ -203,7 +203,11 @@ Capture what matters. The system persists it automatically.
203
203
  ## Workspace Organization
204
204
 
205
205
  \`\`\`
206
- projects/ -- Code repos (each in its own subfolder, venvs inside as .venv)
206
+ projects/ -- Code repos (each in its own subfolder, .venv per repo)
207
+ venv/ -- Pre-warmed Python env (matplotlib, numpy, pandas on PATH).
208
+ Use venv/bin/python for chart/data work; venv/bin/pip
209
+ install <pkg> for extras. Per-project venvs go inside
210
+ projects/<name>/.venv (separate lifecycle).
207
211
  scripts/ -- Standalone reusable scripts
208
212
  documents/ -- Text docs, PDFs, spreadsheets, markdown
209
213
  media/ -- User-provided images, audio, video
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/agent",
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": "AI agent executor, budget control, and session management for Comis",
@@ -99,7 +99,7 @@ export { evaluateAutoReply, isGroupMessage, isBotMentioned } from "./shared/auto
99
99
  export type { AutoReplyDecision } from "./shared/auto-reply-engine.js";
100
100
  export { audioPreflight } from "./shared/audio-preflight.js";
101
101
  export type { PreflightResult, PreflightDeps } from "./shared/audio-preflight.js";
102
- export { filterResponse, NO_REPLY_TOKEN } from "./shared/response-filter.js";
102
+ export { filterResponse, NO_REPLY_TOKEN, HEARTBEAT_OK_TOKEN } from "./shared/response-filter.js";
103
103
  export type { FilterResult } from "./shared/response-filter.js";
104
104
  export { mimeToAttachmentType } from "./shared/media-utils.js";
105
105
  export { normalizeTelegramPollResult, normalizeDiscordPollResult, normalizeWhatsAppPollResult, } from "./shared/poll-normalizer.js";
@@ -91,7 +91,7 @@ export { evaluateAutoReply, isGroupMessage, isBotMentioned } from "./shared/auto
91
91
  // Audio preflight
92
92
  export { audioPreflight } from "./shared/audio-preflight.js";
93
93
  // Response filter (NO_REPLY + HEARTBEAT_OK token suppression)
94
- export { filterResponse, NO_REPLY_TOKEN } from "./shared/response-filter.js";
94
+ export { filterResponse, NO_REPLY_TOKEN, HEARTBEAT_OK_TOKEN } from "./shared/response-filter.js";
95
95
  // Media utilities (shared attachment type resolution)
96
96
  export { mimeToAttachmentType } from "./shared/media-utils.js";
97
97
  // Poll result normalizers (cross-platform)
@@ -22,7 +22,7 @@ import type { DebounceBuffer } from "@comis/agent";
22
22
  import type { FollowupTrigger } from "@comis/agent";
23
23
  import type { PriorityScheduler } from "@comis/agent";
24
24
  import type { SessionLabelStore } from "@comis/agent";
25
- import type { ActiveRunRegistry } from "@comis/agent";
25
+ import type { ActiveRunRegistry, BackgroundSessionResolver } from "@comis/agent";
26
26
  import type { ChannelPort, DeliveryQueuePort, NormalizedMessage, SessionKey, TypedEventBus } from "@comis/core";
27
27
  import type { StreamingConfig } from "@comis/core";
28
28
  import type { AutoReplyEngineConfig, SendPolicyConfig, QueueConfig, ElevatedReplyConfig, AckReactionConfig } from "@comis/core";
@@ -126,6 +126,12 @@ export interface ChannelManagerDeps {
126
126
  }, Error>>;
127
127
  /** Optional active run registry for SDK-native steer+followup message routing. When absent, all messages route through CommandQueue. */
128
128
  activeRunRegistry?: ActiveRunRegistry;
129
+ /**
130
+ * Optional composite-key resolver. When present, supersedes
131
+ * `activeRunRegistry.has/.get` for production lookups in the inbound
132
+ * pipeline.
133
+ */
134
+ sessionResolver?: BackgroundSessionResolver;
129
135
  /** Handle /config command. Returns response text or undefined if not a config command. */
130
136
  handleConfigCommand?: (args: string[], channelType: string) => Promise<string | undefined>;
131
137
  /** Optional callback for task extraction after successful agent execution. */
@@ -151,9 +157,9 @@ export interface ChannelManagerDeps {
151
157
  };
152
158
  /** Template context builder for response prefix variables. */
153
159
  buildTemplateContext?: (agentId: string, channelType: string, msg: NormalizedMessage) => Record<string, string>;
154
- /** Optional approval gate for /approve and /deny chat commands (APPR-CHAT). When absent, approval commands pass through as plain text. */
160
+ /** Optional approval gate for /approve and /deny chat commands. When absent, approval commands pass through as plain text. */
155
161
  approvalGate?: InboundPipelineDeps["approvalGate"];
156
- /** Handle general slash commands via command handler (CMD-WIRE). */
162
+ /** Handle general slash commands via command handler. */
157
163
  handleSlashCommand?: InboundPipelineDeps["handleSlashCommand"];
158
164
  /** Per-agent enforceFinalTag config lookup. */
159
165
  getEnforceFinalTag?: InboundPipelineDeps["getEnforceFinalTag"];
@@ -12,7 +12,7 @@ import type { ChannelPort, NormalizedMessage, SessionKey } from "@comis/core";
12
12
  import type { InboundPipelineDeps } from "./inbound-pipeline.js";
13
13
  import type { SendOverrideStore } from "./send-policy.js";
14
14
  /** Minimal deps needed for the gate phase. */
15
- export type GateDeps = Pick<InboundPipelineDeps, "logger" | "eventBus" | "sessionManager" | "autoReplyEngineConfig" | "groupHistoryBuffer" | "commandQueue" | "sessionLabelStore" | "getResetTriggers" | "greetingGenerator" | "loadPromptSkill" | "getUserInvocableSkillNames" | "approvalGate" | "handleConfigCommand" | "handleSlashCommand" | "activeRunRegistry">;
15
+ export type GateDeps = Pick<InboundPipelineDeps, "logger" | "eventBus" | "sessionManager" | "autoReplyEngineConfig" | "groupHistoryBuffer" | "commandQueue" | "sessionLabelStore" | "getResetTriggers" | "greetingGenerator" | "loadPromptSkill" | "getUserInvocableSkillNames" | "approvalGate" | "handleConfigCommand" | "handleSlashCommand" | "activeRunRegistry" | "sessionResolver">;
16
16
  /** Gate decision: what should happen with this message. */
17
17
  export type GateDecision = {
18
18
  action: "process";
@@ -152,7 +152,7 @@ export async function evaluateInboundGate(deps, adapter, processedMsg, sessionKe
152
152
  }
153
153
  }
154
154
  // -------------------------------------------------------------------
155
- // /approve and /deny COMMAND INTERCEPTION (APPR-CHAT)
155
+ // /approve and /deny COMMAND INTERCEPTION
156
156
  // -------------------------------------------------------------------
157
157
  if (msg.text && deps.approvalGate) {
158
158
  const result = await handleApprovalCommand(deps, adapter, msg, sessionKey);
@@ -178,8 +178,15 @@ export async function evaluateInboundGate(deps, adapter, processedMsg, sessionKe
178
178
  if (msg.text) {
179
179
  const stopParsed = parseSlashCommand(msg.text);
180
180
  if (stopParsed.found && stopParsed.command === "stop") {
181
+ // Active-session lookup goes through the composite-key resolver.
182
+ // `formattedKey` is retained as a diagnostic log field so
183
+ // operators can correlate /stop-aborts with session traces.
181
184
  const formattedKey = formatSessionKey(sessionKey);
182
- const runHandle = deps.activeRunRegistry?.get(formattedKey);
185
+ const runHandle = deps.sessionResolver?.resolveActiveSession({
186
+ agentId,
187
+ channelType: adapter.channelType,
188
+ channelId: msg.channelId,
189
+ });
183
190
  if (runHandle) {
184
191
  try {
185
192
  await runHandle.abort();
@@ -209,7 +216,7 @@ export async function evaluateInboundGate(deps, adapter, processedMsg, sessionKe
209
216
  }
210
217
  }
211
218
  // -------------------------------------------------------------------
212
- // GENERAL SLASH COMMAND INTERCEPTION (CMD-WIRE)
219
+ // GENERAL SLASH COMMAND INTERCEPTION
213
220
  // -------------------------------------------------------------------
214
221
  if (msg.text && deps.handleSlashCommand) {
215
222
  const cmdResult = await deps.handleSlashCommand(msg.text, sessionKey, agentId);
@@ -294,7 +301,7 @@ export async function evaluateInboundGate(deps, adapter, processedMsg, sessionKe
294
301
  }
295
302
  }
296
303
  }
297
- // Extract command directives from metadata (set by CMD-WIRE interception above)
304
+ // Extract command directives from metadata (set by general slash command interception above)
298
305
  const directives = msg.metadata?._commandDirectives;
299
306
  return { action: "process", processedMsg: msg, directives };
300
307
  }
@@ -353,13 +360,21 @@ async function handleApprovalCommand(deps, adapter, msg, sessionKey) {
353
360
  }
354
361
  }
355
362
  else {
356
- // Single: resolve by request ID prefix match
363
+ // Single: resolve by request ID prefix match.
364
+ // Use filter+length check instead of first-match lookup — when the
365
+ // prefix is short and two pending requests share it, the operator
366
+ // must NOT silently get the first match. Warn and bail; the
367
+ // operator can re-issue with a longer prefix.
357
368
  const pending = gate.pending();
358
- const match = pending.find((r) => r.requestId.startsWith(arg));
359
- if (!match) {
369
+ const matches = pending.filter((r) => r.requestId.startsWith(arg));
370
+ if (matches.length === 0) {
360
371
  await deliverToChannel(adapter, msg.channelId, `No pending approval found for ID: ${arg} (may have already been resolved or timed out).`, { skipChunking: true });
361
372
  }
373
+ else if (matches.length > 1) {
374
+ await deliverToChannel(adapter, msg.channelId, `Ambiguous prefix "${arg}" matches ${matches.length} pending approvals. Use a longer prefix.`, { skipChunking: true });
375
+ }
362
376
  else {
377
+ const match = matches[0];
363
378
  gate.resolveApproval(match.requestId, isApprove, approvedBy);
364
379
  const verb = isApprove ? "Approved" : "Denied";
365
380
  await deliverToChannel(adapter, msg.channelId, `${verb}: ${match.toolName ?? match.action} (${match.requestId.slice(0, 8)})`, { skipChunking: true });
@@ -18,7 +18,7 @@ import type { DebounceBuffer } from "@comis/agent";
18
18
  import type { FollowupTrigger } from "@comis/agent";
19
19
  import type { PriorityScheduler } from "@comis/agent";
20
20
  import type { SessionLabelStore } from "@comis/agent";
21
- import type { ActiveRunRegistry } from "@comis/agent";
21
+ import type { ActiveRunRegistry, BackgroundSessionResolver } from "@comis/agent";
22
22
  import type { ChannelPort, DeliveryQueuePort, NormalizedMessage, SessionKey, TypedEventBus } from "@comis/core";
23
23
  import type { StreamingConfig } from "@comis/core";
24
24
  import type { AutoReplyEngineConfig, SendPolicyConfig, QueueConfig, ElevatedReplyConfig, AckReactionConfig } from "@comis/core";
@@ -99,6 +99,13 @@ export interface InboundPipelineDeps {
99
99
  inFlightSends?: Set<Promise<unknown>>;
100
100
  /** Optional active run registry for SDK-native steer+followup. */
101
101
  activeRunRegistry?: ActiveRunRegistry;
102
+ /**
103
+ * Optional composite-key resolver for active-session lookup. When
104
+ * present, supersedes `activeRunRegistry.has/.get` for production
105
+ * lookups. Wired by the daemon as
106
+ * `createBackgroundSessionResolver({ activeRunRegistry })`.
107
+ */
108
+ sessionResolver?: BackgroundSessionResolver;
102
109
  /** Handle /config command. Returns response text or undefined if not a config command. */
103
110
  handleConfigCommand?: (args: string[], channelType: string) => Promise<string | undefined>;
104
111
  /** Optional callback for task extraction after successful agent execution. */
@@ -112,7 +119,7 @@ export interface InboundPipelineDeps {
112
119
  };
113
120
  /** Template context builder for response prefix variables. */
114
121
  buildTemplateContext?: (agentId: string, channelType: string, msg: NormalizedMessage) => Record<string, string>;
115
- /** Optional approval gate for resolving /approve and /deny chat commands (APPR-CHAT). When absent, approval commands pass through as plain text. */
122
+ /** Optional approval gate for resolving /approve and /deny chat commands. When absent, approval commands pass through as plain text. */
116
123
  approvalGate?: {
117
124
  resolveApproval(requestId: string, approved: boolean, approvedBy: string, reason?: string): void;
118
125
  pending(): Array<{
@@ -126,7 +133,7 @@ export interface InboundPipelineDeps {
126
133
  sessionKey: string;
127
134
  } | undefined;
128
135
  };
129
- /** Handle general slash commands via command handler (CMD-WIRE). Returns CommandResult or undefined if not a command. */
136
+ /** Handle general slash commands via command handler. Returns CommandResult or undefined if not a command. */
130
137
  handleSlashCommand?: (text: string, sessionKey: SessionKey, agentId: string) => Promise<{
131
138
  handled: boolean;
132
139
  response?: string;
@@ -15,7 +15,7 @@ import type { BlockPacer } from "./block-pacer.js";
15
15
  import type { TypingLifecycleController } from "./typing-lifecycle-controller.js";
16
16
  import type { SendOverrideStore } from "./send-policy.js";
17
17
  /** Minimal deps needed for the routing phase. */
18
- export type RouteDeps = Pick<InboundPipelineDeps, "logger" | "eventBus" | "debounceBuffer" | "groupHistoryBuffer" | "sessionLabelStore" | "commandQueue" | "priorityScheduler" | "queueConfig" | "activeRunRegistry" | "streamingConfig" | "sendPolicyConfig" | "getElevatedReplyConfig" | "channelRegistry" | "retryEngine" | "deliveryQueue" | "inFlightSends" | "followupTrigger" | "followupConfig" | "assembleToolsForAgent" | "voiceResponsePipeline" | "parseOutboundMedia" | "outboundMediaFetch" | "onTaskExtraction" | "responsePrefixConfig" | "buildTemplateContext" | "getEnforceFinalTag">;
18
+ export type RouteDeps = Pick<InboundPipelineDeps, "logger" | "eventBus" | "debounceBuffer" | "groupHistoryBuffer" | "sessionLabelStore" | "commandQueue" | "priorityScheduler" | "queueConfig" | "activeRunRegistry" | "sessionResolver" | "streamingConfig" | "sendPolicyConfig" | "getElevatedReplyConfig" | "channelRegistry" | "retryEngine" | "deliveryQueue" | "inFlightSends" | "followupTrigger" | "followupConfig" | "assembleToolsForAgent" | "voiceResponsePipeline" | "parseOutboundMedia" | "outboundMediaFetch" | "onTaskExtraction" | "responsePrefixConfig" | "buildTemplateContext" | "getEnforceFinalTag">;
19
19
  /**
20
20
  * Route an inbound message through debounce, group history, steer+followup,
21
21
  * or command queue. Falls back to direct execution when no queue is present.
@@ -120,12 +120,23 @@ export async function routeInboundMessage(deps, adapter, processedMsg, originalM
120
120
  // -------------------------------------------------------------------
121
121
  // STEER+FOLLOWUP ROUTING
122
122
  // -------------------------------------------------------------------
123
- if (deps.activeRunRegistry && deps.queueConfig) {
123
+ // Active-session lookup goes through BackgroundSessionResolver:
124
+ // composite (agentId, channelType, channelId) supersedes the single-arg
125
+ // formatted-key lookup so multi-agent / multi-channel sessions are
126
+ // distinguishable. The original
127
+ // `formattedKey = formatSessionKey(sessionKey)` is retained ONLY for
128
+ // diagnostic log fields (the SessionKey may itself be richer than the
129
+ // resolver's composite triple).
130
+ if (deps.sessionResolver && deps.queueConfig) {
124
131
  const channelQueueConfig = deps.queueConfig.perChannel[adapter.channelType];
125
132
  const effectiveMode = channelQueueConfig?.mode ?? deps.queueConfig.defaultMode;
126
133
  if (effectiveMode === "steer+followup") {
127
134
  const formattedKey = formatSessionKey(sessionKey);
128
- const runHandle = deps.activeRunRegistry.get(formattedKey);
135
+ const runHandle = deps.sessionResolver.resolveActiveSession({
136
+ agentId,
137
+ channelType: adapter.channelType,
138
+ channelId: msg.channelId,
139
+ });
129
140
  if (runHandle) {
130
141
  const messageText = msg.text ?? "";
131
142
  if (runHandle.isStreaming() && !runHandle.isCompacting()) {
@@ -2,40 +2,27 @@
2
2
  * Response Filter: Suppresses silent tokens and strips reply tags from
3
3
  * channel delivery.
4
4
  *
5
- * Detects NO_REPLY and HEARTBEAT_OK tokens in agent responses and
6
- * determines whether the response should be delivered to the user.
7
- * Only suppresses when the token is the ENTIRE response (after trimming
8
- * and stripping reply tags) or when the response is empty/whitespace.
9
- *
10
- * Also strips `<reply>` / `<reply to="...">` XML tags that the LLM uses
11
- * for channel routing, since these are not valid HTML for platform delivery.
12
- *
13
- * This filter operates in the channel-manager delivery path (outbound
14
- * to users), NOT in the scheduler's internal heartbeat classification
15
- * which uses HEARTBEAT_OK_TOKEN for a different purpose.
5
+ * Delegates the silent-token check to `isSilentResponse` from `@comis/shared`
6
+ * the helper is documented as idempotent under `stripReplyTags + trim` (see
7
+ * `packages/shared/src/silent-tokens.ts` JSDoc contract).
16
8
  *
17
9
  * @module
18
10
  */
19
- /** Token that suppresses delivery for silent operations (e.g., memory flush) */
20
- export declare const NO_REPLY_TOKEN = "NO_REPLY";
21
- /** Result of filtering an agent response */
11
+ import { NO_REPLY_TOKEN, HEARTBEAT_OK_TOKEN } from "@comis/shared";
12
+ export { NO_REPLY_TOKEN, HEARTBEAT_OK_TOKEN };
13
+ /** Regex retained for backward compatibility with downstream re-exports. */
14
+ export declare const REPLY_TAG_RE: RegExp;
22
15
  export interface FilterResult {
23
- /** Whether the response should be delivered to the user */
24
16
  shouldDeliver: boolean;
25
- /** The cleaned response text (reply tags stripped, trimmed) */
26
17
  cleanedText: string;
27
- /** Which token caused suppression (for observability) */
28
18
  suppressedBy?: "NO_REPLY" | "HEARTBEAT_OK" | "SILENT" | "empty";
29
19
  }
30
20
  /**
31
21
  * Check if an agent response should be delivered to the user.
32
22
  *
33
- * Processing order:
34
- * 1. Strip `<reply>` / `<reply to="...">` XML tags
35
- * 2. Trim whitespace
36
- * 3. Suppress if empty or exact silent token match
37
- *
38
- * Does NOT suppress when the token appears mid-sentence in
39
- * substantive content (e.g., "I used NO_REPLY in my example").
23
+ * The silent-token check delegates to `isSilentResponse(trimmed)` for
24
+ * self-documentation at the call site. The helper is idempotent under
25
+ * `stripReplyTags + trim`, so passing the already-stripped value is safe
26
+ * and explicit.
40
27
  */
41
28
  export declare function filterResponse(response: string): FilterResult;
@@ -3,73 +3,45 @@
3
3
  * Response Filter: Suppresses silent tokens and strips reply tags from
4
4
  * channel delivery.
5
5
  *
6
- * Detects NO_REPLY and HEARTBEAT_OK tokens in agent responses and
7
- * determines whether the response should be delivered to the user.
8
- * Only suppresses when the token is the ENTIRE response (after trimming
9
- * and stripping reply tags) or when the response is empty/whitespace.
10
- *
11
- * Also strips `<reply>` / `<reply to="...">` XML tags that the LLM uses
12
- * for channel routing, since these are not valid HTML for platform delivery.
13
- *
14
- * This filter operates in the channel-manager delivery path (outbound
15
- * to users), NOT in the scheduler's internal heartbeat classification
16
- * which uses HEARTBEAT_OK_TOKEN for a different purpose.
6
+ * Delegates the silent-token check to `isSilentResponse` from `@comis/shared`
7
+ * the helper is documented as idempotent under `stripReplyTags + trim` (see
8
+ * `packages/shared/src/silent-tokens.ts` JSDoc contract).
17
9
  *
18
10
  * @module
19
11
  */
20
- /** Token that suppresses delivery for silent operations (e.g., memory flush) */
21
- export const NO_REPLY_TOKEN = "NO_REPLY";
22
- /**
23
- * HEARTBEAT_OK token value. Defined as a string literal here (not imported
24
- * from @comis/scheduler) to avoid circular package dependencies.
25
- * Must match HEARTBEAT_OK_TOKEN in packages/scheduler/src/heartbeat/relevance-filter.ts.
26
- */
27
- const HEARTBEAT_OK_VALUE = "HEARTBEAT_OK";
28
- /** Tokens that suppress response delivery when they ARE the entire response */
29
- const SILENT_TOKENS = [NO_REPLY_TOKEN, HEARTBEAT_OK_VALUE];
30
- /** Regex to match `<reply>` or `<reply to="...">` opening tags and `</reply>` closing tags */
31
- const REPLY_TAG_RE = /<\/?reply(?:\s[^>]*)?>|<reply>/gi;
12
+ import { isSilentResponse, stripReplyTags, NO_REPLY_TOKEN, HEARTBEAT_OK_TOKEN, } from "@comis/shared";
13
+ // Preserve existing public exports for downstream @comis/channels consumers.
14
+ export { NO_REPLY_TOKEN, HEARTBEAT_OK_TOKEN };
15
+ /** Regex retained for backward compatibility with downstream re-exports. */
16
+ export const REPLY_TAG_RE = /<\/?reply(?:\s[^>]*)?>|<reply>/gi;
32
17
  /**
33
18
  * Check if an agent response should be delivered to the user.
34
19
  *
35
- * Processing order:
36
- * 1. Strip `<reply>` / `<reply to="...">` XML tags
37
- * 2. Trim whitespace
38
- * 3. Suppress if empty or exact silent token match
39
- *
40
- * Does NOT suppress when the token appears mid-sentence in
41
- * substantive content (e.g., "I used NO_REPLY in my example").
20
+ * The silent-token check delegates to `isSilentResponse(trimmed)` for
21
+ * self-documentation at the call site. The helper is idempotent under
22
+ * `stripReplyTags + trim`, so passing the already-stripped value is safe
23
+ * and explicit.
42
24
  */
43
25
  export function filterResponse(response) {
44
- // Empty or whitespace
45
26
  if (!response || !response.trim()) {
46
27
  return { shouldDeliver: false, cleanedText: "", suppressedBy: "empty" };
47
28
  }
48
- // Strip <reply> / <reply to="..."> / </reply> tags
49
- const stripped = response.replace(REPLY_TAG_RE, "");
50
- const trimmed = stripped.trim();
51
- // Empty after stripping tags
52
- if (!trimmed) {
29
+ const trimmed = stripReplyTags(response);
30
+ if (!trimmed)
53
31
  return { shouldDeliver: false, cleanedText: "", suppressedBy: "empty" };
54
- }
55
- // [SILENT] prefix: suppress delivery when response starts with [SILENT] marker
32
+ // [SILENT] prefix branch — preserved verbatim from existing behavior.
33
+ // Resolves before the helper so we can return suppressedBy: "SILENT" cleanly.
56
34
  if (trimmed.toUpperCase().startsWith("[SILENT]")) {
57
- return {
58
- shouldDeliver: false,
59
- cleanedText: "",
60
- suppressedBy: "SILENT",
61
- };
35
+ return { shouldDeliver: false, cleanedText: "", suppressedBy: "SILENT" };
62
36
  }
63
- // Exact token match (entire response is the token)
64
- for (const token of SILENT_TOKENS) {
65
- if (trimmed === token) {
66
- return {
67
- shouldDeliver: false,
68
- cleanedText: "",
69
- suppressedBy: token === NO_REPLY_TOKEN ? "NO_REPLY" : "HEARTBEAT_OK",
70
- };
71
- }
37
+ // Pass the already-stripped value. isSilentResponse is documented as
38
+ // idempotent under stripReplyTags + trim (see silent-tokens.ts JSDoc).
39
+ // Self-documenting at the call site.
40
+ if (isSilentResponse(trimmed)) {
41
+ const tokenMatch = trimmed === NO_REPLY_TOKEN ? "NO_REPLY"
42
+ : trimmed === HEARTBEAT_OK_TOKEN ? "HEARTBEAT_OK"
43
+ : "SILENT";
44
+ return { shouldDeliver: false, cleanedText: "", suppressedBy: tokenMatch };
72
45
  }
73
- // Substantive response -- deliver cleaned text
74
46
  return { shouldDeliver: true, cleanedText: trimmed };
75
47
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/channels",
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": "Chat platform adapters — Discord, Telegram, Slack, WhatsApp, Signal, iMessage, IRC, LINE",
@@ -4,8 +4,7 @@
4
4
  * Provides `comis providers list` for browsing available providers from
5
5
  * the live pi-ai catalog (with daemon RPC + local fallback). Status
6
6
  * column indicates whether a provider's API key is resolvable from the
7
- * env (mirrors credential-resolver.ts Source B semantics from
8
- * 260501-2pz).
7
+ * env (mirrors credential-resolver.ts Source B semantics).
9
8
  *
10
9
  * Mirrors `commands/models.ts` shape -- RPC-first, local catalog
11
10
  * fallback, `--format` flag, no `set` subcommand (provider switching
@@ -5,8 +5,7 @@
5
5
  * Provides `comis providers list` for browsing available providers from
6
6
  * the live pi-ai catalog (with daemon RPC + local fallback). Status
7
7
  * column indicates whether a provider's API key is resolvable from the
8
- * env (mirrors credential-resolver.ts Source B semantics from
9
- * 260501-2pz).
8
+ * env (mirrors credential-resolver.ts Source B semantics).
10
9
  *
11
10
  * Mirrors `commands/models.ts` shape -- RPC-first, local catalog
12
11
  * fallback, `--format` flag, no `set` subcommand (provider switching
@@ -64,9 +63,9 @@ async function getModelCount(provider) {
64
63
  * - `configured` : pi-ai's `getEnvApiKey` resolves a non-empty key
65
64
  * - `missing key` : no env key found
66
65
  *
67
- * Mirrors `credential-resolver.ts` Source B semantics from 260501-2pz.
68
- * Status reflects only env-key presence; it does NOT include the key
69
- * value itself (T-260501-kqq-02 information-disclosure threat).
66
+ * Mirrors `credential-resolver.ts` Source B semantics. Status reflects
67
+ * only env-key presence; it does NOT include the key value itself
68
+ * (information-disclosure threat).
70
69
  */
71
70
  function getProviderStatus(provider) {
72
71
  if (KEYLESS_PROVIDERS.has(provider))
@@ -99,7 +98,7 @@ export function registerProvidersCommand(program) {
99
98
  }
100
99
  // Sequentially fetch model counts. With ~11-23 providers this
101
100
  // is acceptable (single-digit RPC roundtrips). N+1 batching is
102
- // a v1.5 enhancement (T-260501-kqq-03 DoS disposition: accept).
101
+ // a v1.5 enhancement (DoS disposition: accept).
103
102
  const rows = [];
104
103
  for (const id of ids) {
105
104
  const modelCount = await getModelCount(id);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/cli",
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": "Command-line interface for the Comis AI agent platform",
@@ -31,6 +31,7 @@ import { SchedulerConfigSchema } from "./schema-scheduler.js";
31
31
  import { SecurityConfigSchema } from "./schema-security.js";
32
32
  import { SendPolicyConfigSchema } from "./schema-send-policy.js";
33
33
  import { StreamingConfigSchema } from "./schema-streaming.js";
34
+ import { ToolingConfigSchema } from "./schema-tooling.js";
34
35
  /**
35
36
  * Maps config section names to their Zod schema objects.
36
37
  */
@@ -52,6 +53,7 @@ const SECTION_SCHEMAS = {
52
53
  sendPolicy: SendPolicyConfigSchema,
53
54
  embedding: EmbeddingConfigSchema,
54
55
  envelope: EnvelopeConfigSchema,
56
+ tooling: ToolingConfigSchema,
55
57
  };
56
58
  /**
57
59
  * Resolve the effective type from a JSON Schema node.
@@ -22,7 +22,7 @@ export const MUTABLE_CONFIG_OVERRIDES = [
22
22
  "agents.*.skills.watchDebounceMs",
23
23
  "agents.*.skills.discoveryPaths",
24
24
  "agents.*.maxSteps",
25
- // 260428-rrr Bug A: removed dead "agents.*.persona" entry. PerAgentConfigSchema
25
+ // Bug A: removed dead "agents.*.persona" entry. PerAgentConfigSchema
26
26
  // is z.strictObject and has no `persona` field, so the override could never
27
27
  // produce a successful patch -- it only leaked a misleading capability hint
28
28
  // to LLMs (formatRedirectHint emitted "you can also patch agents.<id>.persona")
@@ -94,6 +94,9 @@ export const IMMUTABLE_CONFIG_PREFIXES = [
94
94
  "browser.noSandbox", // Sandbox bypass is security-sensitive
95
95
  // Logging rotation config requires daemon restart
96
96
  "daemon.logging", // File transport config requires daemon restart
97
+ // v1.1 capability layer -- operator-only; agents must not self-configure
98
+ // capability map or detour policy.
99
+ "tooling",
97
100
  ];
98
101
  /**
99
102
  * Check whether a config path is immutable (cannot be modified at runtime).
@@ -1,5 +1,7 @@
1
1
  export { AppConfigSchema } from "./schema.js";
2
2
  export { ApprovalsConfigSchema, ApprovalRuleSchema, checkApprovalsConfig } from "./schema-approvals.js";
3
+ export { ToolingConfigSchema, DEFAULT_CLUSTER_CONFIG, DEFAULT_BUILTIN_ASSIGNMENTS, } from "./schema-tooling.js";
4
+ export type { ToolingConfig } from "./schema-tooling.js";
3
5
  export { AutoReplyEngineConfigSchema, GroupActivationModeSchema, } from "./schema-auto-reply-engine.js";
4
6
  export { BrowserConfigSchema } from "./schema-browser.js";
5
7
  export { MessagesConfigSchema } from "./schema-messages.js";
@@ -22,6 +24,8 @@ export type { SubagentContextConfig } from "../domain/subagent-context-config.js
22
24
  export { AgentSecretsConfigSchema, SecretsConfigSchema, } from "./schema-secrets.js";
23
25
  export { BackgroundTasksConfigSchema } from "./schema-background-tasks.js";
24
26
  export type { BackgroundTasksConfig } from "./schema-background-tasks.js";
27
+ export { OutputRetentionConfigSchema } from "./schema-output-retention.js";
28
+ export type { OutputRetentionConfig, RetentionClass } from "./schema-output-retention.js";
25
29
  export { SkillsConfigSchema, PromptSkillsConfigSchema } from "./schema-skills.js";
26
30
  export { DaemonConfigSchema, LoggingConfigSchema, TracingDefaultsSchema, ConfigWebhookSchema } from "./schema-daemon.js";
27
31
  export { HeartbeatConfigSchema, SchedulerConfigSchema } from "./schema-scheduler.js";
@@ -3,6 +3,7 @@
3
3
  // Schemas (for direct validation or extension)
4
4
  export { AppConfigSchema } from "./schema.js";
5
5
  export { ApprovalsConfigSchema, ApprovalRuleSchema, checkApprovalsConfig } from "./schema-approvals.js";
6
+ export { ToolingConfigSchema, DEFAULT_CLUSTER_CONFIG, DEFAULT_BUILTIN_ASSIGNMENTS, } from "./schema-tooling.js";
6
7
  export { AutoReplyEngineConfigSchema, GroupActivationModeSchema, } from "./schema-auto-reply-engine.js";
7
8
  export { BrowserConfigSchema } from "./schema-browser.js";
8
9
  export { MessagesConfigSchema } from "./schema-messages.js";
@@ -25,6 +26,7 @@ export { SecurityConfigSchema, PermissionConfigSchema, ActionConfirmationConfigS
25
26
  export { SubagentContextConfigSchema } from "../domain/subagent-context-config.js";
26
27
  export { AgentSecretsConfigSchema, SecretsConfigSchema, } from "./schema-secrets.js";
27
28
  export { BackgroundTasksConfigSchema } from "./schema-background-tasks.js";
29
+ export { OutputRetentionConfigSchema } from "./schema-output-retention.js";
28
30
  export { SkillsConfigSchema, PromptSkillsConfigSchema } from "./schema-skills.js";
29
31
  export { DaemonConfigSchema, LoggingConfigSchema, TracingDefaultsSchema, ConfigWebhookSchema } from "./schema-daemon.js";
30
32
  export { HeartbeatConfigSchema, SchedulerConfigSchema } from "./schema-scheduler.js";