comisai 1.0.27 → 1.0.30

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 (246) hide show
  1. package/node_modules/@comis/agent/dist/bootstrap/sections/tool-descriptions.js +62 -8
  2. package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.js +3 -1
  3. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +7 -0
  4. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +26 -0
  5. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +21 -0
  6. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +29 -9
  7. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.d.ts +10 -2
  8. package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.js +15 -9
  9. package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.d.ts +17 -2
  10. package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.js +19 -8
  11. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +28 -0
  12. package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +3 -0
  13. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +3 -1
  14. package/node_modules/@comis/agent/dist/executor/phase-filter.d.ts +20 -4
  15. package/node_modules/@comis/agent/dist/executor/phase-filter.js +62 -19
  16. package/node_modules/@comis/agent/dist/executor/pi-executor.js +6 -0
  17. package/node_modules/@comis/agent/dist/executor/stream-wrappers/config-resolver.js +2 -3
  18. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +2 -3
  19. package/node_modules/@comis/agent/dist/executor/ttl-guard.js +2 -3
  20. package/node_modules/@comis/agent/dist/index.d.ts +4 -2
  21. package/node_modules/@comis/agent/dist/index.js +3 -2
  22. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.d.ts +41 -0
  23. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.js +51 -0
  24. package/node_modules/@comis/agent/dist/model/model-registry-adapter.js +113 -26
  25. package/node_modules/@comis/agent/dist/model/model-scanner.d.ts +27 -0
  26. package/node_modules/@comis/agent/dist/model/model-scanner.js +64 -23
  27. package/node_modules/@comis/agent/dist/model/operation-model-defaults.d.ts +37 -15
  28. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +70 -25
  29. package/node_modules/@comis/agent/dist/model/operation-model-resolver.d.ts +2 -2
  30. package/node_modules/@comis/agent/dist/model/operation-model-resolver.js +12 -8
  31. package/node_modules/@comis/agent/dist/provider/capabilities.d.ts +21 -0
  32. package/node_modules/@comis/agent/dist/provider/capabilities.js +28 -0
  33. package/node_modules/@comis/agent/dist/session/orphaned-message-repair.js +61 -1
  34. package/node_modules/@comis/agent/dist/workspace/templates.js +1 -1
  35. package/node_modules/@comis/agent/package.json +1 -1
  36. package/node_modules/@comis/channels/dist/shared/channel-manager.d.ts +19 -1
  37. package/node_modules/@comis/channels/dist/shared/channel-manager.js +59 -3
  38. package/node_modules/@comis/channels/dist/shared/deliver-to-channel.d.ts +10 -0
  39. package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +25 -10
  40. package/node_modules/@comis/channels/dist/shared/execution-deliver.d.ts +1 -1
  41. package/node_modules/@comis/channels/dist/shared/execution-deliver.js +1 -1
  42. package/node_modules/@comis/channels/dist/shared/execution-pipeline.d.ts +8 -0
  43. package/node_modules/@comis/channels/dist/shared/inbound-gate.js +21 -3
  44. package/node_modules/@comis/channels/dist/shared/inbound-pipeline.d.ts +8 -0
  45. package/node_modules/@comis/channels/dist/shared/inbound-route.d.ts +1 -1
  46. package/node_modules/@comis/channels/dist/shared/inbound-route.js +1 -0
  47. package/node_modules/@comis/channels/dist/telegram/message-mapper.d.ts +18 -1
  48. package/node_modules/@comis/channels/dist/telegram/message-mapper.js +95 -1
  49. package/node_modules/@comis/channels/dist/telegram/telegram-adapter.js +7 -1
  50. package/node_modules/@comis/channels/package.json +1 -1
  51. package/node_modules/@comis/cli/package.json +1 -1
  52. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +15 -3
  53. package/node_modules/@comis/core/dist/config/schema-agent.js +6 -2
  54. package/node_modules/@comis/core/dist/config/schema-integrations.d.ts +4 -4
  55. package/node_modules/@comis/core/dist/config/schema-integrations.js +3 -3
  56. package/node_modules/@comis/core/dist/config/schema-models.d.ts +4 -2
  57. package/node_modules/@comis/core/dist/config/schema-models.js +4 -2
  58. package/node_modules/@comis/core/package.json +1 -1
  59. package/node_modules/@comis/daemon/dist/daemon.js +74 -9
  60. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +40 -9
  61. package/node_modules/@comis/daemon/dist/rpc/builtin-provider-guard.d.ts +16 -0
  62. package/node_modules/@comis/daemon/dist/rpc/builtin-provider-guard.js +60 -0
  63. package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +59 -0
  64. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +17 -0
  65. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +99 -0
  66. package/node_modules/@comis/daemon/dist/rpc/message-handlers.d.ts +5 -0
  67. package/node_modules/@comis/daemon/dist/rpc/message-handlers.js +25 -4
  68. package/node_modules/@comis/daemon/dist/rpc/model-handlers.d.ts +4 -3
  69. package/node_modules/@comis/daemon/dist/rpc/model-handlers.js +21 -3
  70. package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +82 -6
  71. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +4 -0
  72. package/node_modules/@comis/daemon/dist/wiring/inbound-message-id-resolver.d.ts +48 -0
  73. package/node_modules/@comis/daemon/dist/wiring/inbound-message-id-resolver.js +58 -0
  74. package/node_modules/@comis/daemon/dist/wiring/restart-continuation.d.ts +10 -0
  75. package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +18 -6
  76. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +98 -46
  77. package/node_modules/@comis/daemon/dist/wiring/setup-channels.d.ts +13 -1
  78. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +2 -1
  79. package/node_modules/@comis/daemon/dist/wiring/setup-gateway-rpc.js +1 -1
  80. package/node_modules/@comis/daemon/package.json +2 -2
  81. package/node_modules/@comis/gateway/package.json +1 -1
  82. package/node_modules/@comis/infra/package.json +1 -1
  83. package/node_modules/@comis/memory/package.json +1 -1
  84. package/node_modules/@comis/scheduler/package.json +1 -1
  85. package/node_modules/@comis/shared/package.json +1 -1
  86. package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.d.ts +1 -1
  87. package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.js +1 -1
  88. package/node_modules/@comis/skills/dist/bridge/tool-audit.js +1 -1
  89. package/node_modules/@comis/skills/dist/builtin/exec-tool.d.ts +12 -11
  90. package/node_modules/@comis/skills/dist/builtin/exec-tool.js +1 -1
  91. package/node_modules/@comis/skills/dist/builtin/file/apply-patch-tool.d.ts +3 -2
  92. package/node_modules/@comis/skills/dist/builtin/file/apply-patch-tool.js +1 -1
  93. package/node_modules/@comis/skills/dist/builtin/file-tools/edit-tool.d.ts +7 -6
  94. package/node_modules/@comis/skills/dist/builtin/file-tools/edit-tool.js +1 -1
  95. package/node_modules/@comis/skills/dist/builtin/file-tools/find-tool.d.ts +6 -5
  96. package/node_modules/@comis/skills/dist/builtin/file-tools/find-tool.js +1 -1
  97. package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.d.ts +16 -15
  98. package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +1 -1
  99. package/node_modules/@comis/skills/dist/builtin/file-tools/ls-tool.d.ts +4 -3
  100. package/node_modules/@comis/skills/dist/builtin/file-tools/ls-tool.js +1 -1
  101. package/node_modules/@comis/skills/dist/builtin/file-tools/notebook-edit-tool.d.ts +7 -6
  102. package/node_modules/@comis/skills/dist/builtin/file-tools/notebook-edit-tool.js +1 -1
  103. package/node_modules/@comis/skills/dist/builtin/file-tools/read-tool.d.ts +6 -5
  104. package/node_modules/@comis/skills/dist/builtin/file-tools/read-tool.js +1 -1
  105. package/node_modules/@comis/skills/dist/builtin/file-tools/write-tool.d.ts +5 -4
  106. package/node_modules/@comis/skills/dist/builtin/file-tools/write-tool.js +1 -1
  107. package/node_modules/@comis/skills/dist/builtin/platform/admin-manage-factory.d.ts +1 -1
  108. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +28 -27
  109. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +1 -1
  110. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -3
  111. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +1 -1
  112. package/node_modules/@comis/skills/dist/builtin/platform/browser-tool-schema.d.ts +67 -66
  113. package/node_modules/@comis/skills/dist/builtin/platform/browser-tool-schema.js +1 -1
  114. package/node_modules/@comis/skills/dist/builtin/platform/channels-manage-tool.d.ts +6 -5
  115. package/node_modules/@comis/skills/dist/builtin/platform/channels-manage-tool.js +1 -1
  116. package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.d.ts +20 -19
  117. package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
  118. package/node_modules/@comis/skills/dist/builtin/platform/ctx-expand-tool.d.ts +4 -3
  119. package/node_modules/@comis/skills/dist/builtin/platform/ctx-expand-tool.js +1 -1
  120. package/node_modules/@comis/skills/dist/builtin/platform/ctx-inspect-tool.d.ts +3 -2
  121. package/node_modules/@comis/skills/dist/builtin/platform/ctx-inspect-tool.js +1 -1
  122. package/node_modules/@comis/skills/dist/builtin/platform/ctx-recall-tool.d.ts +6 -5
  123. package/node_modules/@comis/skills/dist/builtin/platform/ctx-recall-tool.js +1 -1
  124. package/node_modules/@comis/skills/dist/builtin/platform/ctx-search-tool.d.ts +6 -5
  125. package/node_modules/@comis/skills/dist/builtin/platform/ctx-search-tool.js +1 -1
  126. package/node_modules/@comis/skills/dist/builtin/platform/describe-video-tool.d.ts +4 -3
  127. package/node_modules/@comis/skills/dist/builtin/platform/describe-video-tool.js +1 -1
  128. package/node_modules/@comis/skills/dist/builtin/platform/discord-action-tool.d.ts +2 -1
  129. package/node_modules/@comis/skills/dist/builtin/platform/discord-action-tool.js +1 -1
  130. package/node_modules/@comis/skills/dist/builtin/platform/extract-document-tool.d.ts +4 -3
  131. package/node_modules/@comis/skills/dist/builtin/platform/extract-document-tool.js +1 -1
  132. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +12 -11
  133. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +1 -1
  134. package/node_modules/@comis/skills/dist/builtin/platform/heartbeat-manage-tool.d.ts +23 -22
  135. package/node_modules/@comis/skills/dist/builtin/platform/heartbeat-manage-tool.js +1 -1
  136. package/node_modules/@comis/skills/dist/builtin/platform/image-generate-tool.d.ts +4 -3
  137. package/node_modules/@comis/skills/dist/builtin/platform/image-generate-tool.js +1 -1
  138. package/node_modules/@comis/skills/dist/builtin/platform/image-tool.d.ts +8 -7
  139. package/node_modules/@comis/skills/dist/builtin/platform/image-tool.js +1 -1
  140. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +9 -8
  141. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +1 -1
  142. package/node_modules/@comis/skills/dist/builtin/platform/memory-get-tool.d.ts +5 -4
  143. package/node_modules/@comis/skills/dist/builtin/platform/memory-get-tool.js +1 -1
  144. package/node_modules/@comis/skills/dist/builtin/platform/memory-manage-tool.d.ts +12 -11
  145. package/node_modules/@comis/skills/dist/builtin/platform/memory-manage-tool.js +1 -1
  146. package/node_modules/@comis/skills/dist/builtin/platform/memory-search-tool.d.ts +4 -3
  147. package/node_modules/@comis/skills/dist/builtin/platform/memory-search-tool.js +1 -1
  148. package/node_modules/@comis/skills/dist/builtin/platform/memory-store-tool.d.ts +4 -3
  149. package/node_modules/@comis/skills/dist/builtin/platform/memory-store-tool.js +1 -1
  150. package/node_modules/@comis/skills/dist/builtin/platform/message-tool.d.ts +32 -31
  151. package/node_modules/@comis/skills/dist/builtin/platform/message-tool.js +1 -1
  152. package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.d.ts +1 -1
  153. package/node_modules/@comis/skills/dist/builtin/platform/models-manage-tool.d.ts +4 -3
  154. package/node_modules/@comis/skills/dist/builtin/platform/models-manage-tool.js +11 -4
  155. package/node_modules/@comis/skills/dist/builtin/platform/notify-tool.d.ts +6 -5
  156. package/node_modules/@comis/skills/dist/builtin/platform/notify-tool.js +1 -1
  157. package/node_modules/@comis/skills/dist/builtin/platform/obs-query-tool.d.ts +11 -10
  158. package/node_modules/@comis/skills/dist/builtin/platform/obs-query-tool.js +1 -1
  159. package/node_modules/@comis/skills/dist/builtin/platform/pipeline-tool.d.ts +37 -36
  160. package/node_modules/@comis/skills/dist/builtin/platform/pipeline-tool.js +1 -1
  161. package/node_modules/@comis/skills/dist/builtin/platform/platform-action-tool.d.ts +1 -1
  162. package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.d.ts +21 -20
  163. package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.js +1 -1
  164. package/node_modules/@comis/skills/dist/builtin/platform/session-search-tool.d.ts +6 -5
  165. package/node_modules/@comis/skills/dist/builtin/platform/session-search-tool.js +1 -1
  166. package/node_modules/@comis/skills/dist/builtin/platform/session-status-tool.d.ts +3 -2
  167. package/node_modules/@comis/skills/dist/builtin/platform/session-status-tool.js +1 -1
  168. package/node_modules/@comis/skills/dist/builtin/platform/sessions-history-tool.d.ts +5 -4
  169. package/node_modules/@comis/skills/dist/builtin/platform/sessions-history-tool.js +1 -1
  170. package/node_modules/@comis/skills/dist/builtin/platform/sessions-list-tool.d.ts +4 -3
  171. package/node_modules/@comis/skills/dist/builtin/platform/sessions-list-tool.js +1 -1
  172. package/node_modules/@comis/skills/dist/builtin/platform/sessions-manage-tool.d.ts +5 -4
  173. package/node_modules/@comis/skills/dist/builtin/platform/sessions-manage-tool.js +1 -1
  174. package/node_modules/@comis/skills/dist/builtin/platform/sessions-send-tool.d.ts +7 -6
  175. package/node_modules/@comis/skills/dist/builtin/platform/sessions-send-tool.js +1 -1
  176. package/node_modules/@comis/skills/dist/builtin/platform/sessions-spawn-tool.d.ts +15 -14
  177. package/node_modules/@comis/skills/dist/builtin/platform/sessions-spawn-tool.js +1 -1
  178. package/node_modules/@comis/skills/dist/builtin/platform/skills-manage-tool.d.ts +8 -7
  179. package/node_modules/@comis/skills/dist/builtin/platform/skills-manage-tool.js +1 -1
  180. package/node_modules/@comis/skills/dist/builtin/platform/slack-action-tool.d.ts +2 -1
  181. package/node_modules/@comis/skills/dist/builtin/platform/slack-action-tool.js +1 -1
  182. package/node_modules/@comis/skills/dist/builtin/platform/subagents-tool.d.ts +7 -6
  183. package/node_modules/@comis/skills/dist/builtin/platform/subagents-tool.js +1 -1
  184. package/node_modules/@comis/skills/dist/builtin/platform/telegram-action-tool.d.ts +2 -1
  185. package/node_modules/@comis/skills/dist/builtin/platform/telegram-action-tool.js +1 -1
  186. package/node_modules/@comis/skills/dist/builtin/platform/tokens-manage-tool.d.ts +5 -4
  187. package/node_modules/@comis/skills/dist/builtin/platform/tokens-manage-tool.js +1 -1
  188. package/node_modules/@comis/skills/dist/builtin/platform/transcribe-audio-tool.d.ts +4 -3
  189. package/node_modules/@comis/skills/dist/builtin/platform/transcribe-audio-tool.js +1 -1
  190. package/node_modules/@comis/skills/dist/builtin/platform/tts-tool.d.ts +6 -5
  191. package/node_modules/@comis/skills/dist/builtin/platform/tts-tool.js +1 -1
  192. package/node_modules/@comis/skills/dist/builtin/platform/unified-context-tool.d.ts +13 -12
  193. package/node_modules/@comis/skills/dist/builtin/platform/unified-context-tool.js +1 -1
  194. package/node_modules/@comis/skills/dist/builtin/platform/unified-memory-tool.d.ts +18 -17
  195. package/node_modules/@comis/skills/dist/builtin/platform/unified-memory-tool.js +1 -1
  196. package/node_modules/@comis/skills/dist/builtin/platform/unified-session-tool.d.ts +11 -10
  197. package/node_modules/@comis/skills/dist/builtin/platform/unified-session-tool.js +1 -1
  198. package/node_modules/@comis/skills/dist/builtin/platform/whatsapp-action-tool.d.ts +2 -1
  199. package/node_modules/@comis/skills/dist/builtin/platform/whatsapp-action-tool.js +1 -1
  200. package/node_modules/@comis/skills/dist/builtin/process-tool.d.ts +6 -5
  201. package/node_modules/@comis/skills/dist/builtin/process-tool.js +1 -1
  202. package/node_modules/@comis/skills/dist/builtin/web-fetch-tool.d.ts +5 -4
  203. package/node_modules/@comis/skills/dist/builtin/web-fetch-tool.js +1 -1
  204. package/node_modules/@comis/skills/dist/builtin/web-search-tool.d.ts +9 -8
  205. package/node_modules/@comis/skills/dist/builtin/web-search-tool.js +1 -1
  206. package/node_modules/@comis/skills/package.json +1 -1
  207. package/node_modules/@comis/web/dist/assets/{agent-detail-DqL6Artv.js → agent-detail-71BSbSfD.js} +1 -1
  208. package/node_modules/@comis/web/dist/assets/{agent-editor-CNM_h94Y.js → agent-editor-CTSDZhwT.js} +1 -1
  209. package/node_modules/@comis/web/dist/assets/{agent-list-Dbh-xD_F.js → agent-list-BEhni2ea.js} +1 -1
  210. package/node_modules/@comis/web/dist/assets/{billing-view-C1DmtyzK.js → billing-view-DVP1IvVs.js} +1 -1
  211. package/node_modules/@comis/web/dist/assets/{channel-detail-CtCH22N1.js → channel-detail-N_YK74xC.js} +1 -1
  212. package/node_modules/@comis/web/dist/assets/{channel-list-C7xXn-60.js → channel-list-DRk6ZJaF.js} +1 -1
  213. package/node_modules/@comis/web/dist/assets/{chat-console-C51pjFwk.js → chat-console-Dm-GtSf9.js} +1 -1
  214. package/node_modules/@comis/web/dist/assets/{config-editor-BLArYRB7.js → config-editor-CIferYX6.js} +1 -1
  215. package/node_modules/@comis/web/dist/assets/{context-dag-browser-fuyMinNI.js → context-dag-browser-CL84rXXM.js} +1 -1
  216. package/node_modules/@comis/web/dist/assets/{context-engine-Bngf2bH0.js → context-engine-B1HOTEZv.js} +1 -1
  217. package/node_modules/@comis/web/dist/assets/{delivery-view-C80hucxX.js → delivery-view-Y6JKYVFw.js} +1 -1
  218. package/node_modules/@comis/web/dist/assets/{diagnostics-view-Cl4VbHZ6.js → diagnostics-view-DWV1UQjz.js} +1 -1
  219. package/node_modules/@comis/web/dist/assets/{ic-chat-message-ByFUoMm6.js → ic-chat-message-DfSERzzg.js} +1 -1
  220. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-C4nDHgY2.js → ic-connection-dot-CXyhlJup.js} +1 -1
  221. package/node_modules/@comis/web/dist/assets/{ic-tool-call-Bh5kq-yY.js → ic-tool-call-DNmwTjek.js} +1 -1
  222. package/node_modules/@comis/web/dist/assets/{index-BBkuC-EU.js → index-CBr0Tm9_.js} +2 -2
  223. package/node_modules/@comis/web/dist/assets/{mcp-management-DB-phOo7.js → mcp-management-BaH2-vox.js} +1 -1
  224. package/node_modules/@comis/web/dist/assets/{media-config-CRqZ1ZUH.js → media-config-CZLshJoN.js} +1 -1
  225. package/node_modules/@comis/web/dist/assets/{media-test-C9vE20Oy.js → media-test-C9NUWgo_.js} +1 -1
  226. package/node_modules/@comis/web/dist/assets/{memory-inspector-CeqfnxMZ.js → memory-inspector-D_fmTcRN.js} +1 -1
  227. package/node_modules/@comis/web/dist/assets/{message-center-Daup7Mof.js → message-center-BBFlNCZn.js} +1 -1
  228. package/node_modules/@comis/web/dist/assets/{models-DLYnEU8E.js → models-BytGLm99.js} +1 -1
  229. package/node_modules/@comis/web/dist/assets/{observe-view-BTSt_PO5.js → observe-view-VXtHqaqq.js} +1 -1
  230. package/node_modules/@comis/web/dist/assets/{pipeline-builder-DknfzyLt.js → pipeline-builder-CfXczlfJ.js} +1 -1
  231. package/node_modules/@comis/web/dist/assets/{pipeline-history-JnHZdeU_.js → pipeline-history-CPmXFnbe.js} +1 -1
  232. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-Dg4knsEb.js → pipeline-history-detail-DcueTMs9.js} +1 -1
  233. package/node_modules/@comis/web/dist/assets/{pipeline-list-AEnibjsp.js → pipeline-list-B-xG5WZh.js} +1 -1
  234. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-DG7RbIOO.js → pipeline-monitor-pnIOYaSY.js} +1 -1
  235. package/node_modules/@comis/web/dist/assets/{scheduler-uL1fYKAT.js → scheduler-BtUIFHhA.js} +1 -1
  236. package/node_modules/@comis/web/dist/assets/{security-C3DywRLH.js → security-C8mWRq2y.js} +1 -1
  237. package/node_modules/@comis/web/dist/assets/{session-detail-BtqCNWXV.js → session-detail-DgdkO5ka.js} +1 -1
  238. package/node_modules/@comis/web/dist/assets/{session-list-CJXWa2XT.js → session-list-DcylcfTn.js} +1 -1
  239. package/node_modules/@comis/web/dist/assets/{setup-wizard-ywn7oJvu.js → setup-wizard-BP5yjsuL.js} +75 -39
  240. package/node_modules/@comis/web/dist/assets/{skills-DX0KYnWD.js → skills-DXt1bX8Z.js} +1 -1
  241. package/node_modules/@comis/web/dist/assets/{subagents-B8p5YJEB.js → subagents-C7YbUHXY.js} +1 -1
  242. package/node_modules/@comis/web/dist/assets/{workspace-manager-CgzNIrw1.js → workspace-manager-DP6pW4wa.js} +1 -1
  243. package/node_modules/@comis/web/dist/index.html +1 -1
  244. package/node_modules/@comis/web/package.json +1 -1
  245. package/npm-shrinkwrap.json +6126 -0
  246. package/package.json +74 -74
@@ -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" | "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" | "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.
@@ -104,6 +104,7 @@ export async function routeInboundMessage(deps, adapter, processedMsg, originalM
104
104
  channelRegistry: deps.channelRegistry,
105
105
  retryEngine: deps.retryEngine,
106
106
  deliveryQueue: deps.deliveryQueue,
107
+ inFlightSends: deps.inFlightSends,
107
108
  followupTrigger: deps.followupTrigger,
108
109
  followupConfig: deps.followupConfig,
109
110
  commandQueue: deps.commandQueue,
@@ -1,5 +1,15 @@
1
1
  import type { NormalizedMessage } from "@comis/core";
2
2
  import type { Message } from "grammy/types";
3
+ /**
4
+ * Identifying details of the bot account, used to detect addressing in
5
+ * inbound Telegram messages (mentions, replies, bot_command targets).
6
+ *
7
+ * Sourced from `bot.api.getMe()` after token validation in the adapter.
8
+ */
9
+ export interface TelegramBotIdentity {
10
+ id: number;
11
+ username: string;
12
+ }
3
13
  /**
4
14
  * Map a Grammy Message object to a NormalizedMessage.
5
15
  *
@@ -14,8 +24,15 @@ import type { Message } from "grammy/types";
14
24
  * - Media -> attachments via `buildAttachments()`
15
25
  * - Platform metadata preserved in `metadata` field
16
26
  *
27
+ * When `bot` is provided, message entities and `reply_to_message` are
28
+ * inspected to populate `metadata.isBotMentioned`, `metadata.replyToBot`,
29
+ * and `metadata.isBotCommand` so that the inbound gate's mention-gated
30
+ * activation policy can correctly route addressed group messages to the
31
+ * agent. Omitting `bot` preserves prior behavior (no addressing flags).
32
+ *
17
33
  * @param msg - A plain Telegram Message object
18
34
  * @param chatId - The chat ID (used as channelId)
35
+ * @param bot - Optional bot identity for addressing detection
19
36
  * @returns A fully populated NormalizedMessage
20
37
  */
21
- export declare function mapGrammyToNormalized(msg: Message, chatId: number): NormalizedMessage;
38
+ export declare function mapGrammyToNormalized(msg: Message, chatId: number, bot?: TelegramBotIdentity): NormalizedMessage;
@@ -2,6 +2,81 @@ import { randomUUID } from "node:crypto";
2
2
  import { buildAttachments } from "./media-handler.js";
3
3
  import { normalizeLocation } from "../shared/location-normalizer.js";
4
4
  import { resolveTelegramThreadContext } from "./thread-context.js";
5
+ /**
6
+ * Inspect a Telegram message for any signal that the bot is being addressed:
7
+ *
8
+ * - `mention` entity (`@username`) matching the bot's username
9
+ * - `text_mention` entity referencing the bot's user id (no public username
10
+ * required; this is what private bots receive)
11
+ * - `bot_command` entity — bare `/cmd` (privacy-off DM) or `/cmd@<botUsername>`
12
+ * (group with privacy-on)
13
+ * - `reply_to_message` whose author is the bot itself
14
+ *
15
+ * Mentions of *other* users / `text_mention` of *other* users / commands
16
+ * targeted at *other* bots do not flip any flag.
17
+ */
18
+ function detectBotAddressing(msg, bot) {
19
+ const result = {
20
+ isBotMentioned: false,
21
+ replyToBot: false,
22
+ isBotCommand: false,
23
+ };
24
+ // Reply-to detection: a reply to a message authored by the bot is treated
25
+ // as addressing, mirroring the convention used by other channels.
26
+ if (msg.reply_to_message?.from?.id === bot.id) {
27
+ result.replyToBot = true;
28
+ }
29
+ // Entities live on text or caption depending on whether the message is
30
+ // a plain message or a media-with-caption.
31
+ const entities = msg.entities ?? msg.caption_entities ?? [];
32
+ if (entities.length === 0) {
33
+ return result;
34
+ }
35
+ const source = msg.text ?? msg.caption ?? "";
36
+ const expectedMention = `@${bot.username.toLowerCase()}`;
37
+ for (const ent of entities) {
38
+ if (ent.type === "mention") {
39
+ // `mention` entity covers `@username` text — slice and case-insensitive compare.
40
+ const slice = source.slice(ent.offset, ent.offset + ent.length).toLowerCase();
41
+ if (slice === expectedMention) {
42
+ result.isBotMentioned = true;
43
+ }
44
+ }
45
+ else if (ent.type === "text_mention") {
46
+ // `text_mention` entity carries a `user` payload — used for bots without
47
+ // a public username, or when Telegram resolves the mention server-side.
48
+ const tm = ent;
49
+ if (tm.user?.id === bot.id) {
50
+ result.isBotMentioned = true;
51
+ }
52
+ }
53
+ else if (ent.type === "bot_command") {
54
+ // Slash command targeting: `/cmd` (no target — DM/privacy-off) or
55
+ // `/cmd@<botUsername>` (group with privacy-on). Either form addressed
56
+ // to this bot activates it; commands targeted at *other* bots do not.
57
+ const slice = source.slice(ent.offset, ent.offset + ent.length);
58
+ const atIdx = slice.indexOf("@");
59
+ if (atIdx === -1) {
60
+ // Bare /cmd — only meaningful in DMs or privacy-off groups, where
61
+ // Telegram delivers it to us in the first place.
62
+ result.isBotCommand = true;
63
+ }
64
+ else {
65
+ const target = slice.slice(atIdx + 1).toLowerCase();
66
+ if (target === bot.username.toLowerCase()) {
67
+ result.isBotCommand = true;
68
+ }
69
+ }
70
+ }
71
+ }
72
+ // A bot_command entity for this bot implies activation — surface it as a
73
+ // mention so downstream gates (which key off `isBotMentioned`) treat it
74
+ // identically to an explicit @mention.
75
+ if (result.isBotCommand) {
76
+ result.isBotMentioned = true;
77
+ }
78
+ return result;
79
+ }
5
80
  /**
6
81
  * Map a Grammy Message object to a NormalizedMessage.
7
82
  *
@@ -16,11 +91,18 @@ import { resolveTelegramThreadContext } from "./thread-context.js";
16
91
  * - Media -> attachments via `buildAttachments()`
17
92
  * - Platform metadata preserved in `metadata` field
18
93
  *
94
+ * When `bot` is provided, message entities and `reply_to_message` are
95
+ * inspected to populate `metadata.isBotMentioned`, `metadata.replyToBot`,
96
+ * and `metadata.isBotCommand` so that the inbound gate's mention-gated
97
+ * activation policy can correctly route addressed group messages to the
98
+ * agent. Omitting `bot` preserves prior behavior (no addressing flags).
99
+ *
19
100
  * @param msg - A plain Telegram Message object
20
101
  * @param chatId - The chat ID (used as channelId)
102
+ * @param bot - Optional bot identity for addressing detection
21
103
  * @returns A fully populated NormalizedMessage
22
104
  */
23
- export function mapGrammyToNormalized(msg, chatId) {
105
+ export function mapGrammyToNormalized(msg, chatId, bot) {
24
106
  const metadata = {
25
107
  telegramMessageId: msg.message_id,
26
108
  telegramChatType: msg.chat.type,
@@ -42,6 +124,18 @@ export function mapGrammyToNormalized(msg, chatId) {
42
124
  metadata.telegramIsForum = isForum;
43
125
  metadata.telegramThreadScope = threadCtx.scope;
44
126
  }
127
+ // Bot addressing detection — only when bot identity is supplied. The
128
+ // adapter populates `bot` after token validation; tests that exercise
129
+ // the pure mapper without a bot identity continue to omit these flags.
130
+ if (bot) {
131
+ const addressing = detectBotAddressing(msg, bot);
132
+ if (addressing.isBotMentioned)
133
+ metadata.isBotMentioned = true;
134
+ if (addressing.replyToBot)
135
+ metadata.replyToBot = true;
136
+ if (addressing.isBotCommand)
137
+ metadata.isBotCommand = true;
138
+ }
45
139
  // Extract text from message body or caption
46
140
  let text = msg.text ?? msg.caption ?? "";
47
141
  // GPS location extraction from venue and location messages
@@ -125,6 +125,9 @@ export function createTelegramAdapter(deps) {
125
125
  const handlers = [];
126
126
  let _channelId = "telegram-pending";
127
127
  let runnerHandle = null;
128
+ // Bot identity is populated after token validation in start(). Used by the
129
+ // message mapper to detect mentions/replies/bot_commands aimed at this bot.
130
+ let botIdentity;
128
131
  // Health tracking
129
132
  let _connected = false;
130
133
  let _startedAt;
@@ -140,7 +143,7 @@ export function createTelegramAdapter(deps) {
140
143
  return;
141
144
  }
142
145
  _lastMessageAt = Date.now();
143
- const normalized = mapGrammyToNormalized(msg, chatId);
146
+ const normalized = mapGrammyToNormalized(msg, chatId, botIdentity);
144
147
  deps.logger.info({ channelType: "telegram", messageId: normalized.id, chatId: String(chatId), previewLen: (normalized.text ?? "").length }, "Inbound message");
145
148
  for (const handler of handlers) {
146
149
  // Fire-and-forget: don't block Grammy middleware
@@ -175,6 +178,9 @@ export function createTelegramAdapter(deps) {
175
178
  }
176
179
  const botInfo = tokenResult.value;
177
180
  _channelId = `telegram-${botInfo.id}`;
181
+ // Populate identity now that getMe() has succeeded — message mapper
182
+ // uses this to detect mentions/replies/bot_commands aimed at us.
183
+ botIdentity = { id: botInfo.id, username: botInfo.username };
178
184
  // Validate webhook secret if provided
179
185
  if (deps.webhookSecret) {
180
186
  const secretResult = validateWebhookSecret(deps.webhookSecret);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/channels",
3
3
  "private": true,
4
- "version": "1.0.27",
4
+ "version": "1.0.30",
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",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/cli",
3
3
  "private": true,
4
- "version": "1.0.27",
4
+ "version": "1.0.30",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Command-line interface for the Comis AI agent platform",
@@ -397,7 +397,11 @@ export declare const ContextEngineConfigSchema: z.ZodObject<{
397
397
  * triggers on model id / provider / api change (those checks are
398
398
  * unconditional regardless of this idle threshold). Range: 1 min .. 24 h. */
399
399
  replayDriftIdleMs: z.ZodDefault<z.ZodNumber>;
400
- /** Model for LLM compaction in "provider:modelId" format. Defaults to Haiku for cost efficiency. Empty string falls through to session model. */
400
+ /** Model for LLM compaction in "provider:modelId" format. Empty string
401
+ * (the default) triggers runtime resolution against the agent's primary
402
+ * provider via pi-ai catalog (fast-tier cost model). Avoids pinning a
403
+ * hardcoded Anthropic literal that goes stale on pi-ai upgrades and
404
+ * cross-routes background ops to Claude when primary is OpenRouter/Google/etc. */
401
405
  compactionModel: z.ZodDefault<z.ZodString>;
402
406
  /** Minimum age (in tool result positions) before content is eligible for dead content eviction. */
403
407
  evictionMinAge: z.ZodDefault<z.ZodNumber>;
@@ -1616,7 +1620,11 @@ export declare const PerAgentConfigSchema: z.ZodObject<{
1616
1620
  * triggers on model id / provider / api change (those checks are
1617
1621
  * unconditional regardless of this idle threshold). Range: 1 min .. 24 h. */
1618
1622
  replayDriftIdleMs: z.ZodDefault<z.ZodNumber>;
1619
- /** Model for LLM compaction in "provider:modelId" format. Defaults to Haiku for cost efficiency. Empty string falls through to session model. */
1623
+ /** Model for LLM compaction in "provider:modelId" format. Empty string
1624
+ * (the default) triggers runtime resolution against the agent's primary
1625
+ * provider via pi-ai catalog (fast-tier cost model). Avoids pinning a
1626
+ * hardcoded Anthropic literal that goes stale on pi-ai upgrades and
1627
+ * cross-routes background ops to Claude when primary is OpenRouter/Google/etc. */
1620
1628
  compactionModel: z.ZodDefault<z.ZodString>;
1621
1629
  /** Minimum age (in tool result positions) before content is eligible for dead content eviction. */
1622
1630
  evictionMinAge: z.ZodDefault<z.ZodNumber>;
@@ -2309,7 +2317,11 @@ export declare const AgentsMapSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
2309
2317
  * triggers on model id / provider / api change (those checks are
2310
2318
  * unconditional regardless of this idle threshold). Range: 1 min .. 24 h. */
2311
2319
  replayDriftIdleMs: z.ZodDefault<z.ZodNumber>;
2312
- /** Model for LLM compaction in "provider:modelId" format. Defaults to Haiku for cost efficiency. Empty string falls through to session model. */
2320
+ /** Model for LLM compaction in "provider:modelId" format. Empty string
2321
+ * (the default) triggers runtime resolution against the agent's primary
2322
+ * provider via pi-ai catalog (fast-tier cost model). Avoids pinning a
2323
+ * hardcoded Anthropic literal that goes stale on pi-ai upgrades and
2324
+ * cross-routes background ops to Claude when primary is OpenRouter/Google/etc. */
2313
2325
  compactionModel: z.ZodDefault<z.ZodString>;
2314
2326
  /** Minimum age (in tool result positions) before content is eligible for dead content eviction. */
2315
2327
  evictionMinAge: z.ZodDefault<z.ZodNumber>;
@@ -294,8 +294,12 @@ export const ContextEngineConfigSchema = z.strictObject({
294
294
  * triggers on model id / provider / api change (those checks are
295
295
  * unconditional regardless of this idle threshold). Range: 1 min .. 24 h. */
296
296
  replayDriftIdleMs: z.number().int().min(60_000).max(24 * 60 * 60_000).default(30 * 60_000),
297
- /** Model for LLM compaction in "provider:modelId" format. Defaults to Haiku for cost efficiency. Empty string falls through to session model. */
298
- compactionModel: z.string().default("anthropic:claude-haiku-4-5-20250929"),
297
+ /** Model for LLM compaction in "provider:modelId" format. Empty string
298
+ * (the default) triggers runtime resolution against the agent's primary
299
+ * provider via pi-ai catalog (fast-tier cost model). Avoids pinning a
300
+ * hardcoded Anthropic literal that goes stale on pi-ai upgrades and
301
+ * cross-routes background ops to Claude when primary is OpenRouter/Google/etc. */
302
+ compactionModel: z.string().default(""),
299
303
  /** Minimum age (in tool result positions) before content is eligible for dead content eviction. */
300
304
  evictionMinAge: z.number().int().min(3).max(50).default(15),
301
305
  // --- Pipeline mode ---
@@ -306,10 +306,10 @@ export declare const VisionConfigSchema: z.ZodObject<{
306
306
  * Link understanding configuration.
307
307
  *
308
308
  * Controls automatic URL detection, fetching, and content extraction
309
- * from inbound messages. Disabled by default for backward compatibility.
309
+ * from inbound messages.
310
310
  */
311
311
  export declare const LinkUnderstandingConfigSchema: z.ZodObject<{
312
- /** Enable automatic link understanding (default: false) */
312
+ /** Enable automatic link understanding (default: true) */
313
313
  enabled: z.ZodDefault<z.ZodBoolean>;
314
314
  /** Maximum number of links to process per message (default: 3) */
315
315
  maxLinks: z.ZodDefault<z.ZodNumber>;
@@ -541,7 +541,7 @@ export declare const MediaConfigSchema: z.ZodObject<{
541
541
  }, z.core.$strict>>;
542
542
  /** Link understanding settings */
543
543
  linkUnderstanding: z.ZodDefault<z.ZodObject<{
544
- /** Enable automatic link understanding (default: false) */
544
+ /** Enable automatic link understanding (default: true) */
545
545
  enabled: z.ZodDefault<z.ZodBoolean>;
546
546
  /** Maximum number of links to process per message (default: 3) */
547
547
  maxLinks: z.ZodDefault<z.ZodNumber>;
@@ -848,7 +848,7 @@ export declare const IntegrationsConfigSchema: z.ZodObject<{
848
848
  }, z.core.$strict>>;
849
849
  /** Link understanding settings */
850
850
  linkUnderstanding: z.ZodDefault<z.ZodObject<{
851
- /** Enable automatic link understanding (default: false) */
851
+ /** Enable automatic link understanding (default: true) */
852
852
  enabled: z.ZodDefault<z.ZodBoolean>;
853
853
  /** Maximum number of links to process per message (default: 3) */
854
854
  maxLinks: z.ZodDefault<z.ZodNumber>;
@@ -197,11 +197,11 @@ export const VisionConfigSchema = z.strictObject({
197
197
  * Link understanding configuration.
198
198
  *
199
199
  * Controls automatic URL detection, fetching, and content extraction
200
- * from inbound messages. Disabled by default for backward compatibility.
200
+ * from inbound messages.
201
201
  */
202
202
  export const LinkUnderstandingConfigSchema = z.strictObject({
203
- /** Enable automatic link understanding (default: false) */
204
- enabled: z.boolean().default(false),
203
+ /** Enable automatic link understanding (default: true) */
204
+ enabled: z.boolean().default(true),
205
205
  /** Maximum number of links to process per message (default: 3) */
206
206
  maxLinks: z.number().int().positive().default(3),
207
207
  /** Timeout for fetching each URL in milliseconds (default: 10000) */
@@ -34,10 +34,12 @@ export declare const ModelsConfigSchema: z.ZodObject<{
34
34
  modelId: z.ZodString;
35
35
  }, z.core.$strict>>>;
36
36
  /** Default model identifier. When a per-agent config sets model: "default", this value is used.
37
- * Falls back to "claude-sonnet-4-5-20250929" if empty. */
37
+ * When empty (the default), runtime resolution picks the mid-tier cost
38
+ * model from the resolved provider's pi-ai catalog (resolveOperationDefaults). */
38
39
  defaultModel: z.ZodDefault<z.ZodString>;
39
40
  /** Default provider. When a per-agent config sets provider: "default", this value is used.
40
- * Falls back to "anthropic" if empty. */
41
+ * When empty (the default), runtime resolution picks the most-populated
42
+ * native provider from the pi-ai catalog (heuristic). */
41
43
  defaultProvider: z.ZodDefault<z.ZodString>;
42
44
  }, z.core.$strict>;
43
45
  /** Inferred models configuration type. */
@@ -28,9 +28,11 @@ export const ModelsConfigSchema = z.strictObject({
28
28
  /** Friendly model aliases (e.g., "claude" -> anthropic/claude-sonnet-4) */
29
29
  aliases: z.array(ModelAliasSchema).default([]),
30
30
  /** Default model identifier. When a per-agent config sets model: "default", this value is used.
31
- * Falls back to "claude-sonnet-4-5-20250929" if empty. */
31
+ * When empty (the default), runtime resolution picks the mid-tier cost
32
+ * model from the resolved provider's pi-ai catalog (resolveOperationDefaults). */
32
33
  defaultModel: z.string().default(""),
33
34
  /** Default provider. When a per-agent config sets provider: "default", this value is used.
34
- * Falls back to "anthropic" if empty. */
35
+ * When empty (the default), runtime resolution picks the most-populated
36
+ * native provider from the pi-ai catalog (heuristic). */
35
37
  defaultProvider: z.string().default(""),
36
38
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/core",
3
3
  "private": true,
4
- "version": "1.0.27",
4
+ "version": "1.0.30",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Core domain types, ports, event bus, security, and config for Comis",
@@ -9,7 +9,7 @@ import { ok, err, suppressError } from "@comis/shared";
9
9
  import { createGatewayServer } from "@comis/gateway";
10
10
  import { setupLogging, setupObservability, setupHealth, setupMemory, setupAgents, setupSchedulers, setupChannels, setupMedia, setupCrossSession, setupMcp, setupTools, setupMonitoring, setupHeartbeat, setupTaskExtraction, setupShutdown, setupGateway, setupRpcBridge, setupDeliveryQueue, setupDeliveryMirror, setupNotifications, setupBackgroundTasks, } from "./wiring/index.js";
11
11
  import { setupSingleAgent } from "./wiring/setup-agents.js";
12
- import { createActiveRunRegistry, createModelCatalog, wireSessionStateCleanup, wireMcpDisconnectCleanup, createGeminiCacheManager, wireGeminiCacheCleanup, createSessionTrackerRegistry } from "@comis/agent";
12
+ import { createActiveRunRegistry, createModelCatalog, wireSessionStateCleanup, wireMcpDisconnectCleanup, createGeminiCacheManager, wireGeminiCacheCleanup, createSessionTrackerRegistry, validateProviderOverrides } from "@comis/agent";
13
13
  import { detectSandboxProvider, createImageGenProvider, createImageGenRateLimiter, createFileStateTracker } from "@comis/skills";
14
14
  import { createGraphCoordinator, createNodeTypeRegistry } from "./graph/index.js";
15
15
  import { createChannelHealthMonitor } from "@comis/channels";
@@ -33,6 +33,7 @@ import { writeFile as fsWriteFile, rm } from "node:fs/promises";
33
33
  import { createExecGit } from "./config/exec-git.js";
34
34
  import { saveLastKnownGood, buildRollbackSuggestion, handleRestoreFlag } from "./config/last-known-good.js";
35
35
  import { createRestartContinuationTracker, loadContinuations, buildMcpStatusLine } from "./wiring/restart-continuation.js";
36
+ import { createInboundMessageIdResolver } from "./wiring/inbound-message-id-resolver.js";
36
37
  import { logOperationModelDryRun } from "./wiring/startup-dry-run.js";
37
38
  import os from "node:os";
38
39
  import { join as pathJoin, dirname as pathDirname, resolve as pathResolve } from "node:path";
@@ -327,6 +328,11 @@ export async function main(overrides = {}) {
327
328
  if (approvalsWarning) {
328
329
  daemonLogger.warn({ hint: "Set approvals.enabled: true or remove unused rules", errorKind: "config" }, approvalsWarning);
329
330
  }
331
+ // 3.6. Validate PROVIDER_OVERRIDES vs live pi-ai catalog (Layer 3C -- 260501-07g).
332
+ // Emits one structured WARN per orphaned override key (provider listed in
333
+ // PROVIDER_OVERRIDES that pi-ai no longer ships). Fire-and-forget: never
334
+ // throws, daemon continues to boot with dead override entries.
335
+ validateProviderOverrides(agentLogger);
330
336
  // 4. Observability
331
337
  const { tokenTracker, latencyRecorder, sharedCostTracker, // needed for obs.reset billing clear
332
338
  diagnosticCollector, billingEstimator, channelActivityTracker, deliveryTracer, } = setupObservability({ eventBus: container.eventBus, _createTokenTracker, _createLatencyRecorder, logger: logLevelManager.getLogger("observability"), dataDir });
@@ -620,11 +626,20 @@ export async function main(overrides = {}) {
620
626
  // before setupTools completes).
621
627
  // Deferred notification session tracker ref: wired after setupNotifications returns.
622
628
  // The onMessageProcessed callback reads this at call time (not definition time),
623
- // so it is always set before any message arrives.
629
+ // so it is always set before any message arrives. recordActivity MUST stay in
630
+ // the post-processing callback because the ref is wired AFTER setupChannels
631
+ // returns; tracker.track moved to onMessageReceived which has no such dep.
624
632
  const sessionTrackerRef = {};
625
633
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches assembleToolsForAgent signature from setup-tools.ts
626
634
  const toolAssemblerRef = {};
627
- const { adaptersByType, channelManager, resolveAttachment, lifecycleReactors, channelPlugins, commandQueue } = await setupChannels({
635
+ // Resolver translating daemon UUIDs (NormalizedMessage.id) back to platform-
636
+ // native message ids (e.g. Telegram integer message_id) for the
637
+ // message.delete/edit/react RPC handlers. Built post-setupChannels (needs
638
+ // channelCapabilities from the return), captured by reference inside the
639
+ // onMessageReceived lambda below — safe because no inbound message can fire
640
+ // before channelManager.start() runs later.
641
+ let inboundMessageIdResolver;
642
+ const { adaptersByType, channelManager, resolveAttachment, lifecycleReactors, channelPlugins, channelCapabilities, commandQueue } = await setupChannels({
628
643
  container, executors, defaultAgentId, sessionManager, sessionStore,
629
644
  logger, channelsLogger,
630
645
  linkRunner,
@@ -654,18 +669,41 @@ export async function main(overrides = {}) {
654
669
  rpcCall,
655
670
  // Task extraction callback (gated by config.scheduler.tasks.enabled)
656
671
  onTaskExtraction: extractFromConversation,
657
- // Restart continuation: track recently-active sessions for SIGUSR2 replay
658
- onMessageProcessed: (msg, channelType) => {
672
+ // Restart continuation: track recently-active sessions for SIGUSR2 replay.
673
+ // Two-callback timing split (260430-s4m corrects the r4i-A flaw):
674
+ // onMessageReceived fires BEFORE processInboundMessage so the tracker
675
+ // Map is populated before any tool call could trigger SIGUSR2 mid-
676
+ // execution. Without this, multi-restart chains saw 0 captured records
677
+ // and the next instance had nothing to replay -> silent bot.
678
+ // onMessageProcessed fires AFTER processing for sessionTrackerRef
679
+ // because the ref is wired post-setupNotifications (deferred-ref
680
+ // pattern); calling it pre-processing would fire on an undefined ref.
681
+ onMessageReceived: (msg, channelType) => {
682
+ // Preserve channel-native chat type so post-restart synthetic messages
683
+ // can frame group sessions correctly. Without this, group inbounds are
684
+ // mis-framed as DMs on first turn after restart.
685
+ const chatType = typeof msg.metadata?.telegramChatType === "string"
686
+ ? msg.metadata.telegramChatType
687
+ : undefined;
659
688
  continuationTracker.track({
660
689
  agentId: defaultAgentId,
661
690
  channelType,
662
691
  channelId: msg.channelId,
663
692
  userId: msg.senderId,
693
+ chatType,
664
694
  tenantId: container.config.tenantId,
665
695
  timestamp: Date.now(),
666
696
  });
697
+ // Translate daemon UUID -> platform-native message id so message.delete/
698
+ // edit/react can call channel adapters with what they actually expect.
699
+ // Resolver is assigned just after setupChannels returns (below).
700
+ inboundMessageIdResolver?.record(msg, channelType);
701
+ },
702
+ onMessageProcessed: (msg, channelType) => {
667
703
  // Record session activity for notification channel resolution fallback.
668
- // sessionTrackerRef is populated after setupNotifications() returns (below).
704
+ // sessionTrackerRef.ref is populated post-construction by
705
+ // setupNotifications (line 879 below), so this MUST stay in the
706
+ // after-processing callback -- moving it earlier would fire on undefined.
669
707
  sessionTrackerRef.ref?.recordActivity(defaultAgentId, channelType, msg.channelId);
670
708
  },
671
709
  // /approve and /deny chat command interception
@@ -680,6 +718,18 @@ export async function main(overrides = {}) {
680
718
  });
681
719
  // Populate channel plugins ref for per-message char limit resolution.
682
720
  channelPluginsRef.ref = channelPlugins;
721
+ // Build the inbound message id resolver now that we have channelCapabilities.
722
+ // Each enabled channel contributes its `replyToMetaKey` (e.g. "telegramMessageId")
723
+ // so the resolver knows which metadata field to read on inbound to capture
724
+ // the platform-native id. Safe to assign now: setupChannels has not started
725
+ // adapters yet, so no inbound message has fired the onMessageReceived lambda.
726
+ {
727
+ const metaKeyByChannel = new Map();
728
+ for (const [type, cap] of channelCapabilities) {
729
+ metaKeyByChannel.set(type, cap.replyToMetaKey);
730
+ }
731
+ inboundMessageIdResolver = createInboundMessageIdResolver({ metaKeyByChannel });
732
+ }
683
733
  // Populate channelAdapters ref now that setupChannels has returned.
684
734
  // The drain cycle needs adapters to re-deliver pending messages.
685
735
  for (const [type, adapter] of adaptersByType) {
@@ -1022,7 +1072,7 @@ export async function main(overrides = {}) {
1022
1072
  agentDataDir: pathJoin(container.config.dataDir ?? pathJoin(os.homedir(), ".comis"), "agents"),
1023
1073
  sessionStore: sessionStoreBridge,
1024
1074
  crossSessionSender, subAgentRunner, graphCoordinator, namedGraphStore, nodeTypeRegistry,
1025
- securityConfig: container.config.security, adaptersByType, visionRegistry,
1075
+ securityConfig: container.config.security, adaptersByType, inboundMessageIdResolver, visionRegistry,
1026
1076
  mediaConfig: container.config.integrations.media, ttsAdapter, linkRunner,
1027
1077
  logger, container, configPaths, defaultConfigPaths: DEFAULT_CONFIG_PATHS,
1028
1078
  configGitManager,
@@ -1160,7 +1210,7 @@ export async function main(overrides = {}) {
1160
1210
  errorKind: "dependency",
1161
1211
  }, "MCP connection failures detected during restart continuation replay");
1162
1212
  }
1163
- const baseText = "[system: daemon restarted after config change session restored. Do NOT repeat, re-send, or re-execute anything from the previous conversation. Simply greet the user or wait for their next message.]";
1213
+ const baseText = "[system: daemon restarted to apply a config change. The result of your previous tool call is in the conversation above react to it naturally, confirm or surface any issue, then yield to the user.]";
1164
1214
  for (const record of continuations) {
1165
1215
  // Skip sessions that already received a message during this startup cycle
1166
1216
  // (e.g., Telegram webhook delivered before continuation replay ran).
@@ -1168,6 +1218,21 @@ export async function main(overrides = {}) {
1168
1218
  daemonLogger.debug({ channelType: record.channelType, channelId: record.channelId }, "Skipping continuation replay: session already active this cycle");
1169
1219
  continue;
1170
1220
  }
1221
+ // Rehydrate chat-type metadata so downstream resolveChatType /
1222
+ // isGroupMessage classify the resumed session correctly. Without this,
1223
+ // a synthetic restart message for a group is mis-framed as a DM on the
1224
+ // first post-restart turn.
1225
+ const syntheticMetadata = {
1226
+ isRestartContinuation: true,
1227
+ mcpStatusLine: mcpStatusLine ?? null,
1228
+ };
1229
+ if (record.channelType === "telegram" && record.chatType) {
1230
+ syntheticMetadata.telegramChatType = record.chatType;
1231
+ }
1232
+ if (record.chatType === "group" || record.chatType === "supergroup") {
1233
+ // Channel-agnostic flag mirrored by other adapters (e.g. WhatsApp).
1234
+ syntheticMetadata.isGroup = true;
1235
+ }
1171
1236
  const syntheticMsg = {
1172
1237
  id: randomUUID(),
1173
1238
  channelId: record.channelId,
@@ -1176,7 +1241,7 @@ export async function main(overrides = {}) {
1176
1241
  text: mcpStatusLine ? `${baseText}\n${mcpStatusLine}` : baseText,
1177
1242
  timestamp: Date.now(),
1178
1243
  attachments: [],
1179
- metadata: { isRestartContinuation: true, mcpStatusLine: mcpStatusLine ?? null },
1244
+ metadata: syntheticMetadata,
1180
1245
  };
1181
1246
  channelManager.injectMessage(record.channelType, syntheticMsg).catch((injectErr) => {
1182
1247
  daemonLogger.warn({ err: injectErr, channelType: record.channelType, channelId: record.channelId, hint: "Continuation replay failed; user can re-send to resume", errorKind: "internal" }, "Failed to replay continuation");
@@ -18,6 +18,7 @@ import { resolveWorkspaceDir, resolveOperationModel, resolveProviderFamily, OPER
18
18
  import { persistToConfig } from "./persist-to-config.js";
19
19
  import { writeInlineWorkspaceFiles, } from "./agent-inline-workspace.js";
20
20
  import { probeProviderAuth } from "./probe-provider-auth.js";
21
+ import { resolveProviderCredential } from "./credential-resolver.js";
21
22
  // ---------------------------------------------------------------------------
22
23
  // Factory
23
24
  // ---------------------------------------------------------------------------
@@ -68,6 +69,18 @@ export function createAgentHandlers(deps) {
68
69
  existingSkills.builtinTools = { ...DEFAULT_BUILTIN_TOOLS, ...existingBt };
69
70
  raw.skills = existingSkills;
70
71
  const parsedConfig = PerAgentConfigSchema.parse(config);
72
+ // Credential guard (260501-2pz): fail-loud if the new agent's
73
+ // provider has no resolvable API key. Mirrors agents.update guard
74
+ // ordering — runs BEFORE the in-memory commit so rejection prevents
75
+ // assignment, file persist, and hot-add. Same helper as the patch /
76
+ // update call sites for cross-handler consistency.
77
+ const credCheck = resolveProviderCredential(parsedConfig.provider, {
78
+ providerEntries: deps.providerEntries ?? {},
79
+ secretManager: deps.secretManager,
80
+ });
81
+ if (!credCheck.ok) {
82
+ throw new Error(credCheck.reason);
83
+ }
71
84
  deps.agents[agentId] = parsedConfig;
72
85
  // Best-effort persistence to config.yaml
73
86
  if (deps.persistDeps) {
@@ -207,18 +220,36 @@ export function createAgentHandlers(deps) {
207
220
  }
208
221
  const merged = { ...existing, ...config };
209
222
  const parsedConfig = PerAgentConfigSchema.parse(merged);
210
- // Probe provider API key when provider or model changes
223
+ // Credential guard + probe (260501-2pz): when provider OR model
224
+ // changes, (a) GUARD — fail-loud if the resulting provider's API key
225
+ // is not resolvable from any source (no silent skip), then (b) PROBE
226
+ // — preexisting wire validation when an explicit providers.entries
227
+ // record with apiKeyName exists. Order matters: guard runs first
228
+ // (cheap, all paths), probe runs second (only when applicable).
211
229
  const providerChanging = config.provider !== undefined && config.provider !== existing.provider;
212
230
  const modelChanging = config.model !== undefined && config.model !== existing.model;
213
- if ((providerChanging || modelChanging) && deps.providerEntries) {
231
+ if (providerChanging || modelChanging) {
214
232
  const targetProvider = parsedConfig.provider;
215
- const providerEntry = deps.providerEntries[targetProvider];
216
- if (providerEntry?.apiKeyName && deps.secretManager) {
217
- const apiKey = deps.secretManager.get(providerEntry.apiKeyName);
218
- if (apiKey) {
219
- const probeResult = await probeProviderAuth(providerEntry.baseUrl, apiKey, parsedConfig.model);
220
- if (!probeResult.ok) {
221
- throw new Error(`Cannot switch agent "${agentId}" to provider "${targetProvider}": ${probeResult.error}`);
233
+ // (a) GUARD — fail-loud if no credential source resolves
234
+ const resolution = resolveProviderCredential(targetProvider, {
235
+ providerEntries: deps.providerEntries ?? {},
236
+ secretManager: deps.secretManager,
237
+ });
238
+ if (!resolution.ok) {
239
+ throw new Error(resolution.reason);
240
+ }
241
+ // (b) PROBE — preexisting behavior, fires only when an explicit
242
+ // providers.entries record with apiKeyName exists and the secret
243
+ // is retrievable. Validates the key works against the wire.
244
+ if (deps.providerEntries) {
245
+ const providerEntry = deps.providerEntries[targetProvider];
246
+ if (providerEntry?.apiKeyName && deps.secretManager) {
247
+ const apiKey = deps.secretManager.get(providerEntry.apiKeyName);
248
+ if (apiKey) {
249
+ const probeResult = await probeProviderAuth(providerEntry.baseUrl, apiKey, parsedConfig.model);
250
+ if (!probeResult.ok) {
251
+ throw new Error(`Cannot switch agent "${agentId}" to provider "${targetProvider}": ${probeResult.error}`);
252
+ }
222
253
  }
223
254
  }
224
255
  }
@@ -0,0 +1,16 @@
1
+ export type BuiltInProviderGuardResult = {
2
+ ok: true;
3
+ } | {
4
+ ok: false;
5
+ reason: string;
6
+ };
7
+ /**
8
+ * Check whether a providers.create call would land a redundant custom
9
+ * entry that shadows pi-ai's dynamic catalog. Returns ok=true when the
10
+ * call is legitimate (genuine custom provider OR proxy with distinct
11
+ * baseUrl), ok=false with an actionable reason otherwise.
12
+ */
13
+ export declare function checkBuiltInProviderRedundancy(providerId: string, config: {
14
+ baseUrl?: string;
15
+ apiKeyName?: string;
16
+ }): BuiltInProviderGuardResult;