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.
- package/node_modules/@comis/agent/dist/bootstrap/sections/tool-descriptions.js +62 -8
- package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.js +3 -1
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +7 -0
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +26 -0
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +21 -0
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +29 -9
- package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.d.ts +10 -2
- package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.js +15 -9
- package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.d.ts +17 -2
- package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.js +19 -8
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +28 -0
- package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +3 -0
- package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +3 -1
- package/node_modules/@comis/agent/dist/executor/phase-filter.d.ts +20 -4
- package/node_modules/@comis/agent/dist/executor/phase-filter.js +62 -19
- package/node_modules/@comis/agent/dist/executor/pi-executor.js +6 -0
- package/node_modules/@comis/agent/dist/executor/stream-wrappers/config-resolver.js +2 -3
- package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +2 -3
- package/node_modules/@comis/agent/dist/executor/ttl-guard.js +2 -3
- package/node_modules/@comis/agent/dist/index.d.ts +4 -2
- package/node_modules/@comis/agent/dist/index.js +3 -2
- package/node_modules/@comis/agent/dist/model/compaction-model-resolver.d.ts +41 -0
- package/node_modules/@comis/agent/dist/model/compaction-model-resolver.js +51 -0
- package/node_modules/@comis/agent/dist/model/model-registry-adapter.js +113 -26
- package/node_modules/@comis/agent/dist/model/model-scanner.d.ts +27 -0
- package/node_modules/@comis/agent/dist/model/model-scanner.js +64 -23
- package/node_modules/@comis/agent/dist/model/operation-model-defaults.d.ts +37 -15
- package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +70 -25
- package/node_modules/@comis/agent/dist/model/operation-model-resolver.d.ts +2 -2
- package/node_modules/@comis/agent/dist/model/operation-model-resolver.js +12 -8
- package/node_modules/@comis/agent/dist/provider/capabilities.d.ts +21 -0
- package/node_modules/@comis/agent/dist/provider/capabilities.js +28 -0
- package/node_modules/@comis/agent/dist/session/orphaned-message-repair.js +61 -1
- package/node_modules/@comis/agent/dist/workspace/templates.js +1 -1
- package/node_modules/@comis/agent/package.json +1 -1
- package/node_modules/@comis/channels/dist/shared/channel-manager.d.ts +19 -1
- package/node_modules/@comis/channels/dist/shared/channel-manager.js +59 -3
- package/node_modules/@comis/channels/dist/shared/deliver-to-channel.d.ts +10 -0
- package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +25 -10
- package/node_modules/@comis/channels/dist/shared/execution-deliver.d.ts +1 -1
- package/node_modules/@comis/channels/dist/shared/execution-deliver.js +1 -1
- package/node_modules/@comis/channels/dist/shared/execution-pipeline.d.ts +8 -0
- package/node_modules/@comis/channels/dist/shared/inbound-gate.js +21 -3
- package/node_modules/@comis/channels/dist/shared/inbound-pipeline.d.ts +8 -0
- package/node_modules/@comis/channels/dist/shared/inbound-route.d.ts +1 -1
- package/node_modules/@comis/channels/dist/shared/inbound-route.js +1 -0
- package/node_modules/@comis/channels/dist/telegram/message-mapper.d.ts +18 -1
- package/node_modules/@comis/channels/dist/telegram/message-mapper.js +95 -1
- package/node_modules/@comis/channels/dist/telegram/telegram-adapter.js +7 -1
- package/node_modules/@comis/channels/package.json +1 -1
- package/node_modules/@comis/cli/package.json +1 -1
- package/node_modules/@comis/core/dist/config/schema-agent.d.ts +15 -3
- package/node_modules/@comis/core/dist/config/schema-agent.js +6 -2
- package/node_modules/@comis/core/dist/config/schema-integrations.d.ts +4 -4
- package/node_modules/@comis/core/dist/config/schema-integrations.js +3 -3
- package/node_modules/@comis/core/dist/config/schema-models.d.ts +4 -2
- package/node_modules/@comis/core/dist/config/schema-models.js +4 -2
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/dist/daemon.js +74 -9
- package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +40 -9
- package/node_modules/@comis/daemon/dist/rpc/builtin-provider-guard.d.ts +16 -0
- package/node_modules/@comis/daemon/dist/rpc/builtin-provider-guard.js +60 -0
- package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +59 -0
- package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +17 -0
- package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +99 -0
- package/node_modules/@comis/daemon/dist/rpc/message-handlers.d.ts +5 -0
- package/node_modules/@comis/daemon/dist/rpc/message-handlers.js +25 -4
- package/node_modules/@comis/daemon/dist/rpc/model-handlers.d.ts +4 -3
- package/node_modules/@comis/daemon/dist/rpc/model-handlers.js +21 -3
- package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +82 -6
- package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +4 -0
- package/node_modules/@comis/daemon/dist/wiring/inbound-message-id-resolver.d.ts +48 -0
- package/node_modules/@comis/daemon/dist/wiring/inbound-message-id-resolver.js +58 -0
- package/node_modules/@comis/daemon/dist/wiring/restart-continuation.d.ts +10 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +18 -6
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +98 -46
- package/node_modules/@comis/daemon/dist/wiring/setup-channels.d.ts +13 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +2 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-gateway-rpc.js +1 -1
- package/node_modules/@comis/daemon/package.json +2 -2
- package/node_modules/@comis/gateway/package.json +1 -1
- package/node_modules/@comis/infra/package.json +1 -1
- package/node_modules/@comis/memory/package.json +1 -1
- package/node_modules/@comis/scheduler/package.json +1 -1
- package/node_modules/@comis/shared/package.json +1 -1
- package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.d.ts +1 -1
- package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.js +1 -1
- package/node_modules/@comis/skills/dist/bridge/tool-audit.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/exec-tool.d.ts +12 -11
- package/node_modules/@comis/skills/dist/builtin/exec-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file/apply-patch-tool.d.ts +3 -2
- package/node_modules/@comis/skills/dist/builtin/file/apply-patch-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file-tools/edit-tool.d.ts +7 -6
- package/node_modules/@comis/skills/dist/builtin/file-tools/edit-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file-tools/find-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/file-tools/find-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.d.ts +16 -15
- package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file-tools/ls-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/file-tools/ls-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file-tools/notebook-edit-tool.d.ts +7 -6
- package/node_modules/@comis/skills/dist/builtin/file-tools/notebook-edit-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file-tools/read-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/file-tools/read-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/file-tools/write-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/file-tools/write-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/admin-manage-factory.d.ts +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +28 -27
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/browser-tool-schema.d.ts +67 -66
- package/node_modules/@comis/skills/dist/builtin/platform/browser-tool-schema.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/channels-manage-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/platform/channels-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.d.ts +20 -19
- package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-expand-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-expand-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-inspect-tool.d.ts +3 -2
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-inspect-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-recall-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-recall-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-search-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/platform/ctx-search-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/describe-video-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/describe-video-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/discord-action-tool.d.ts +2 -1
- package/node_modules/@comis/skills/dist/builtin/platform/discord-action-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/extract-document-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/extract-document-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +12 -11
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/heartbeat-manage-tool.d.ts +23 -22
- package/node_modules/@comis/skills/dist/builtin/platform/heartbeat-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/image-generate-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/image-generate-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/image-tool.d.ts +8 -7
- package/node_modules/@comis/skills/dist/builtin/platform/image-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +9 -8
- package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/memory-get-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/platform/memory-get-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/memory-manage-tool.d.ts +12 -11
- package/node_modules/@comis/skills/dist/builtin/platform/memory-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/memory-search-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/memory-search-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/memory-store-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/memory-store-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/message-tool.d.ts +32 -31
- package/node_modules/@comis/skills/dist/builtin/platform/message-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.d.ts +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/models-manage-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/models-manage-tool.js +11 -4
- package/node_modules/@comis/skills/dist/builtin/platform/notify-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/platform/notify-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/obs-query-tool.d.ts +11 -10
- package/node_modules/@comis/skills/dist/builtin/platform/obs-query-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/pipeline-tool.d.ts +37 -36
- package/node_modules/@comis/skills/dist/builtin/platform/pipeline-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/platform-action-tool.d.ts +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.d.ts +21 -20
- package/node_modules/@comis/skills/dist/builtin/platform/providers-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/session-search-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/platform/session-search-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/session-status-tool.d.ts +3 -2
- package/node_modules/@comis/skills/dist/builtin/platform/session-status-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-history-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-history-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-list-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-list-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-manage-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-send-tool.d.ts +7 -6
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-send-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-spawn-tool.d.ts +15 -14
- package/node_modules/@comis/skills/dist/builtin/platform/sessions-spawn-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/skills-manage-tool.d.ts +8 -7
- package/node_modules/@comis/skills/dist/builtin/platform/skills-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/slack-action-tool.d.ts +2 -1
- package/node_modules/@comis/skills/dist/builtin/platform/slack-action-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/subagents-tool.d.ts +7 -6
- package/node_modules/@comis/skills/dist/builtin/platform/subagents-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/telegram-action-tool.d.ts +2 -1
- package/node_modules/@comis/skills/dist/builtin/platform/telegram-action-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/tokens-manage-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/platform/tokens-manage-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/transcribe-audio-tool.d.ts +4 -3
- package/node_modules/@comis/skills/dist/builtin/platform/transcribe-audio-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/tts-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/platform/tts-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/unified-context-tool.d.ts +13 -12
- package/node_modules/@comis/skills/dist/builtin/platform/unified-context-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/unified-memory-tool.d.ts +18 -17
- package/node_modules/@comis/skills/dist/builtin/platform/unified-memory-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/unified-session-tool.d.ts +11 -10
- package/node_modules/@comis/skills/dist/builtin/platform/unified-session-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/whatsapp-action-tool.d.ts +2 -1
- package/node_modules/@comis/skills/dist/builtin/platform/whatsapp-action-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/process-tool.d.ts +6 -5
- package/node_modules/@comis/skills/dist/builtin/process-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/web-fetch-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/web-fetch-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/web-search-tool.d.ts +9 -8
- package/node_modules/@comis/skills/dist/builtin/web-search-tool.js +1 -1
- package/node_modules/@comis/skills/package.json +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-detail-DqL6Artv.js → agent-detail-71BSbSfD.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-editor-CNM_h94Y.js → agent-editor-CTSDZhwT.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-list-Dbh-xD_F.js → agent-list-BEhni2ea.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{billing-view-C1DmtyzK.js → billing-view-DVP1IvVs.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-detail-CtCH22N1.js → channel-detail-N_YK74xC.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-list-C7xXn-60.js → channel-list-DRk6ZJaF.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{chat-console-C51pjFwk.js → chat-console-Dm-GtSf9.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{config-editor-BLArYRB7.js → config-editor-CIferYX6.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-dag-browser-fuyMinNI.js → context-dag-browser-CL84rXXM.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-engine-Bngf2bH0.js → context-engine-B1HOTEZv.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{delivery-view-C80hucxX.js → delivery-view-Y6JKYVFw.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{diagnostics-view-Cl4VbHZ6.js → diagnostics-view-DWV1UQjz.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-chat-message-ByFUoMm6.js → ic-chat-message-DfSERzzg.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-connection-dot-C4nDHgY2.js → ic-connection-dot-CXyhlJup.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-tool-call-Bh5kq-yY.js → ic-tool-call-DNmwTjek.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{index-BBkuC-EU.js → index-CBr0Tm9_.js} +2 -2
- package/node_modules/@comis/web/dist/assets/{mcp-management-DB-phOo7.js → mcp-management-BaH2-vox.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{media-config-CRqZ1ZUH.js → media-config-CZLshJoN.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{media-test-C9vE20Oy.js → media-test-C9NUWgo_.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{memory-inspector-CeqfnxMZ.js → memory-inspector-D_fmTcRN.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{message-center-Daup7Mof.js → message-center-BBFlNCZn.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{models-DLYnEU8E.js → models-BytGLm99.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{observe-view-BTSt_PO5.js → observe-view-VXtHqaqq.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-builder-DknfzyLt.js → pipeline-builder-CfXczlfJ.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-JnHZdeU_.js → pipeline-history-CPmXFnbe.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-Dg4knsEb.js → pipeline-history-detail-DcueTMs9.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-list-AEnibjsp.js → pipeline-list-B-xG5WZh.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-monitor-DG7RbIOO.js → pipeline-monitor-pnIOYaSY.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{scheduler-uL1fYKAT.js → scheduler-BtUIFHhA.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{security-C3DywRLH.js → security-C8mWRq2y.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-detail-BtqCNWXV.js → session-detail-DgdkO5ka.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-list-CJXWa2XT.js → session-list-DcylcfTn.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{setup-wizard-ywn7oJvu.js → setup-wizard-BP5yjsuL.js} +75 -39
- package/node_modules/@comis/web/dist/assets/{skills-DX0KYnWD.js → skills-DXt1bX8Z.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{subagents-B8p5YJEB.js → subagents-C7YbUHXY.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{workspace-manager-CgzNIrw1.js → workspace-manager-DP6pW4wa.js} +1 -1
- package/node_modules/@comis/web/dist/index.html +1 -1
- package/node_modules/@comis/web/package.json +1 -1
- package/npm-shrinkwrap.json +6126 -0
- package/package.json +74 -74
|
@@ -1,38 +1,83 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
* Operation model defaults:
|
|
3
|
+
* Operation model defaults: catalog-derived per-provider model tiering.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Replaces the previous hardcoded `OPERATION_MODEL_DEFAULTS` table (which
|
|
6
|
+
* pinned `mid`/`fast` model IDs per provider family) with a pure function
|
|
7
|
+
* that reads the live pi-ai catalog at call time. Two design properties:
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* 1. Pi-ai SDK upgrades automatically light up new providers/models — no
|
|
10
|
+
* per-release source edits to bump `OPERATION_MODEL_DEFAULTS` literals.
|
|
11
|
+
* 2. Closes the latent bug where switching primary to a non-Anthropic
|
|
12
|
+
* provider left cron/heartbeat/compaction routed to Claude Sonnet
|
|
13
|
+
* (because the old map was Anthropic/OpenAI/Google only).
|
|
14
|
+
*
|
|
15
|
+
* Tier picking: filter to text-capable models with non-zero cost, sort
|
|
16
|
+
* ascending by total cost (input + output), pick 10th-percentile = `fast`,
|
|
17
|
+
* 50th-percentile = `mid`. All-free-models providers (e.g. local Ollama,
|
|
18
|
+
* Z.AI most models) fall back to "first text-capable id" for both slots.
|
|
12
19
|
*
|
|
13
20
|
* @module
|
|
14
21
|
*/
|
|
22
|
+
import { getModels, getProviders } from "@mariozechner/pi-ai";
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Tier resolution
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/** Cached set of native pi-ai providers for O(1) membership check. */
|
|
27
|
+
const _nativeProviderSet = new Set(getProviders());
|
|
28
|
+
/** Sum of input + output cost (per-million-tokens). Treats undefined as 0. */
|
|
29
|
+
function totalCost(m) {
|
|
30
|
+
return (m.cost?.input ?? 0) + (m.cost?.output ?? 0);
|
|
31
|
+
}
|
|
15
32
|
/**
|
|
16
|
-
*
|
|
33
|
+
* Resolve cost-tier model defaults for a given native pi-ai provider.
|
|
34
|
+
*
|
|
35
|
+
* Returns `{ fast, mid }` model IDs (without provider prefix) selected from
|
|
36
|
+
* the catalog by ascending total cost. Both undefined fields when the
|
|
37
|
+
* provider is unknown to pi-ai (e.g. custom YAML providers like Ollama).
|
|
38
|
+
*
|
|
39
|
+
* Algorithm:
|
|
40
|
+
* 1. Fetch `getModels(provider)` -> all models for that provider.
|
|
41
|
+
* 2. Filter to models supporting text input (`m.input.includes("text")`).
|
|
42
|
+
* 3. Filter to non-zero cost (eliminates free/local-only models from
|
|
43
|
+
* ranking — they won't be reachable in production).
|
|
44
|
+
* 4. Sort ascending by total cost.
|
|
45
|
+
* 5. `fast` = 10th percentile, `mid` = 50th percentile.
|
|
46
|
+
* 6. If post-filter set is empty (all-free provider), use the first
|
|
47
|
+
* text-capable model id for both slots.
|
|
17
48
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
49
|
+
* Pure function — no async, no side effects. Re-callable per request.
|
|
50
|
+
*
|
|
51
|
+
* @param provider - Provider name to resolve (e.g. "anthropic", "openrouter")
|
|
52
|
+
* @returns `{ fast?: string, mid?: string }` — empty object for unknown providers
|
|
21
53
|
*/
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
54
|
+
export function resolveOperationDefaults(provider) {
|
|
55
|
+
if (!_nativeProviderSet.has(provider))
|
|
56
|
+
return {};
|
|
57
|
+
const all = getModels(provider);
|
|
58
|
+
const textCapable = all.filter((m) => m.input?.includes("text"));
|
|
59
|
+
// Non-free models, sorted ascending by total cost.
|
|
60
|
+
const priced = textCapable
|
|
61
|
+
.filter((m) => totalCost(m) > 0)
|
|
62
|
+
.sort((a, b) => totalCost(a) - totalCost(b));
|
|
63
|
+
if (priced.length === 0) {
|
|
64
|
+
// All-free-models provider (e.g. Z.AI's predominantly-free catalog,
|
|
65
|
+
// Github Copilot, Kimi Coding). Use first text-capable id for both
|
|
66
|
+
// slots — no division by zero, graceful degradation.
|
|
67
|
+
const fallback = textCapable[0]?.id;
|
|
68
|
+
return { fast: fallback, mid: fallback };
|
|
69
|
+
}
|
|
70
|
+
// Math.min clamp guards single-element arrays (10% of 1 -> 0).
|
|
71
|
+
const fastIdx = Math.min(priced.length - 1, Math.floor(priced.length * 0.1));
|
|
72
|
+
const midIdx = Math.min(priced.length - 1, Math.floor(priced.length * 0.5));
|
|
73
|
+
return {
|
|
74
|
+
fast: priced[fastIdx].id,
|
|
75
|
+
mid: priced[midIdx].id,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Operation -> tier mapping (provider-agnostic semantics)
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
36
81
|
/**
|
|
37
82
|
* Maps each operation type to its cost tier.
|
|
38
83
|
*
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Level 1: invocationOverride (e.g., CronPayload.model)
|
|
10
10
|
* Level 2: operationModels[operationType] from agent config
|
|
11
11
|
* Level 3: parentModel (sub-agent only)
|
|
12
|
-
* Level 4:
|
|
12
|
+
* Level 4: catalog-derived tier (resolveOperationDefaults + OPERATION_TIER_MAP)
|
|
13
13
|
* Level 5: Agent primary model (ultimate fallback)
|
|
14
14
|
*
|
|
15
15
|
* @module
|
|
@@ -47,7 +47,7 @@ export declare function resolveProviderFamily(provider: string): string;
|
|
|
47
47
|
* 1. invocationOverride -- per-call override (e.g., CronPayload.model)
|
|
48
48
|
* 2. operationModels[op] -- explicit agent config
|
|
49
49
|
* 3. parentModel -- inherited from parent agent (subagent only)
|
|
50
|
-
* 4.
|
|
50
|
+
* 4. resolveOperationDefaults -- pi-ai catalog-derived per-provider tier
|
|
51
51
|
* 5. agent primary -- ultimate fallback
|
|
52
52
|
*
|
|
53
53
|
* @param params - Resolution context (all inputs needed for the decision)
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
* Level 1: invocationOverride (e.g., CronPayload.model)
|
|
11
11
|
* Level 2: operationModels[operationType] from agent config
|
|
12
12
|
* Level 3: parentModel (sub-agent only)
|
|
13
|
-
* Level 4:
|
|
13
|
+
* Level 4: catalog-derived tier (resolveOperationDefaults + OPERATION_TIER_MAP)
|
|
14
14
|
* Level 5: Agent primary model (ultimate fallback)
|
|
15
15
|
*
|
|
16
16
|
* @module
|
|
17
17
|
*/
|
|
18
18
|
import { normalizeModelId } from "../provider/model-id-normalize.js";
|
|
19
|
-
import {
|
|
19
|
+
import { resolveOperationDefaults, OPERATION_TIER_MAP, OPERATION_TIMEOUT_DEFAULTS, OPERATION_CACHE_DEFAULTS, } from "./operation-model-defaults.js";
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
21
|
// Helpers
|
|
22
22
|
// ---------------------------------------------------------------------------
|
|
@@ -80,7 +80,7 @@ export function resolveProviderFamily(provider) {
|
|
|
80
80
|
* 1. invocationOverride -- per-call override (e.g., CronPayload.model)
|
|
81
81
|
* 2. operationModels[op] -- explicit agent config
|
|
82
82
|
* 3. parentModel -- inherited from parent agent (subagent only)
|
|
83
|
-
* 4.
|
|
83
|
+
* 4. resolveOperationDefaults -- pi-ai catalog-derived per-provider tier
|
|
84
84
|
* 5. agent primary -- ultimate fallback
|
|
85
85
|
*
|
|
86
86
|
* @param params - Resolution context (all inputs needed for the decision)
|
|
@@ -120,13 +120,17 @@ export function resolveOperationModel(params) {
|
|
|
120
120
|
const parsed = parseModelString(parentModel, agentProvider);
|
|
121
121
|
return buildResult(parsed.provider, parsed.modelId, "parent_inherited", operationType, timeoutMs, cacheRetention);
|
|
122
122
|
}
|
|
123
|
-
// -- Level 4:
|
|
123
|
+
// -- Level 4: catalog-derived tier --
|
|
124
|
+
// Reads pi-ai catalog at call time (no hardcoded family map). Picks the
|
|
125
|
+
// 10th-percentile cost text-capable model for `fast`, 50th for `mid`.
|
|
126
|
+
// Returns {} for unknown providers (custom YAML providers like Ollama).
|
|
124
127
|
const tier = OPERATION_TIER_MAP[operationType];
|
|
125
128
|
if (tier !== "primary") {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// Do NOT call normalizeModelId on
|
|
129
|
+
const defaults = resolveOperationDefaults(providerFamily);
|
|
130
|
+
const modelId = defaults[tier];
|
|
131
|
+
if (modelId) {
|
|
132
|
+
// Do NOT call normalizeModelId on catalog ids — they are already
|
|
133
|
+
// canonical pi-ai registry entries.
|
|
130
134
|
return buildResult(agentProvider, modelId, "family_default", operationType, timeoutMs, cacheRetention);
|
|
131
135
|
}
|
|
132
136
|
}
|
|
@@ -70,3 +70,24 @@ export declare function shouldDropThinkingBlocks(provider: string, modelId: stri
|
|
|
70
70
|
* Otherwise returns "default".
|
|
71
71
|
*/
|
|
72
72
|
export declare function resolveToolCallIdMode(provider: string, modelId: string): "default" | "strict9";
|
|
73
|
+
/**
|
|
74
|
+
* Minimal Pino-compatible logger surface for `validateProviderOverrides`.
|
|
75
|
+
* Object-first warn signature matches the project convention (object + msg).
|
|
76
|
+
*/
|
|
77
|
+
export interface ProviderOverridesValidatorLogger {
|
|
78
|
+
warn(obj: object, msg: string): void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validate that every key in `PROVIDER_OVERRIDES` exists in the live pi-ai
|
|
82
|
+
* catalog. Orphaned keys (override entries for providers pi-ai no longer
|
|
83
|
+
* ships) are emitted as structured WARNs so operators notice on the next
|
|
84
|
+
* pi-ai bump. Does NOT throw -- the daemon continues to boot. Orphaned
|
|
85
|
+
* overrides are dead-code, not active failures.
|
|
86
|
+
*
|
|
87
|
+
* @param logger - Pino-compatible logger (object-first warn signature)
|
|
88
|
+
* @returns Inventory: orphan keys + total count of override keys checked
|
|
89
|
+
*/
|
|
90
|
+
export declare function validateProviderOverrides(logger: ProviderOverridesValidatorLogger): {
|
|
91
|
+
orphans: string[];
|
|
92
|
+
checked: number;
|
|
93
|
+
};
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* @module
|
|
15
15
|
*/
|
|
16
|
+
import { getProviders } from "@mariozechner/pi-ai";
|
|
16
17
|
/**
|
|
17
18
|
* Default provider capabilities. Matches ProviderCapabilitiesSchema defaults.
|
|
18
19
|
* All fields present -- serves as the base layer in the 3-layer cascade.
|
|
@@ -161,3 +162,30 @@ export function resolveToolCallIdMode(provider, modelId) {
|
|
|
161
162
|
}
|
|
162
163
|
return caps.transcriptToolCallIdMode;
|
|
163
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Validate that every key in `PROVIDER_OVERRIDES` exists in the live pi-ai
|
|
167
|
+
* catalog. Orphaned keys (override entries for providers pi-ai no longer
|
|
168
|
+
* ships) are emitted as structured WARNs so operators notice on the next
|
|
169
|
+
* pi-ai bump. Does NOT throw -- the daemon continues to boot. Orphaned
|
|
170
|
+
* overrides are dead-code, not active failures.
|
|
171
|
+
*
|
|
172
|
+
* @param logger - Pino-compatible logger (object-first warn signature)
|
|
173
|
+
* @returns Inventory: orphan keys + total count of override keys checked
|
|
174
|
+
*/
|
|
175
|
+
export function validateProviderOverrides(logger) {
|
|
176
|
+
const liveProviders = new Set(getProviders());
|
|
177
|
+
const overrideKeys = Object.keys(PROVIDER_OVERRIDES);
|
|
178
|
+
const orphans = [];
|
|
179
|
+
for (const key of overrideKeys) {
|
|
180
|
+
if (!liveProviders.has(key)) {
|
|
181
|
+
orphans.push(key);
|
|
182
|
+
logger.warn({
|
|
183
|
+
provider: key,
|
|
184
|
+
hint: "Provider override exists for unknown pi-ai provider; remove from PROVIDER_OVERRIDES on next bump",
|
|
185
|
+
errorKind: "config",
|
|
186
|
+
module: "agent.capabilities",
|
|
187
|
+
}, "Capability override has no matching pi-ai provider");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return { orphans, checked: overrideKeys.length };
|
|
191
|
+
}
|
|
@@ -74,11 +74,27 @@ export function repairOrphanedMessages(sessionManager) {
|
|
|
74
74
|
}
|
|
75
75
|
// Case 2: Tool-result tail -- session ends with tool/toolResult after
|
|
76
76
|
// an assistant toolUse, but execution was interrupted by a restart.
|
|
77
|
+
// Content-aware (CONTEXT.md §Change 1A): the synthetic assistant text
|
|
78
|
+
// reflects the actual trailing toolResult body so the model is not given
|
|
79
|
+
// a prompt that contradicts the real successful result already on disk.
|
|
77
80
|
/* eslint-disable @typescript-eslint/no-explicit-any -- role "tool"/"toolResult" not in SDK AgentMessage union */
|
|
78
81
|
const isToolResult = lastMsg.role === "tool" || lastMsg.role === "toolResult";
|
|
79
82
|
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
80
83
|
if (isToolResult) {
|
|
81
|
-
|
|
84
|
+
let text;
|
|
85
|
+
if (isErroredToolResult(lastMsg)) {
|
|
86
|
+
text = "(previous tool errored before I could react)";
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const body = parseToolResultBody(lastMsg);
|
|
90
|
+
if (body && body.restarting === true) {
|
|
91
|
+
text = "(daemon restarted to apply the change — continuing)";
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
text = "(continuing after daemon restart)";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
appendSyntheticAssistant(sessionManager, text);
|
|
82
98
|
return {
|
|
83
99
|
repaired: true,
|
|
84
100
|
reason: "trailing tool result without assistant reply (interrupted by restart)",
|
|
@@ -153,6 +169,50 @@ function createSyntheticMessage(role, text) {
|
|
|
153
169
|
function appendSyntheticAssistant(sessionManager, text) {
|
|
154
170
|
sessionManager.appendMessage(createSyntheticMessage("assistant", text));
|
|
155
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Best-effort parse of a trailing toolResult message into its tool-body
|
|
174
|
+
* shape. The SDK wire format stores the body as one or more text content
|
|
175
|
+
* blocks containing JSON. Returns null when the content isn't parseable
|
|
176
|
+
* JSON (e.g., raw string output from a non-structured tool). Per CONTEXT.md
|
|
177
|
+
* §Change 1A, parsing is best-effort, not a domain operation, so Result<T,E>
|
|
178
|
+
* is intentionally not used here.
|
|
179
|
+
*/
|
|
180
|
+
function parseToolResultBody(msg) {
|
|
181
|
+
const m = msg;
|
|
182
|
+
if (!m || !Array.isArray(m.content))
|
|
183
|
+
return null;
|
|
184
|
+
const first = m.content[0];
|
|
185
|
+
if (!first || first.type !== "text" || typeof first.text !== "string")
|
|
186
|
+
return null;
|
|
187
|
+
const trimmed = first.text.trim();
|
|
188
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("["))
|
|
189
|
+
return null;
|
|
190
|
+
try {
|
|
191
|
+
const parsed = JSON.parse(trimmed);
|
|
192
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Best-effort detection of an errored toolResult. The SDK and various tool
|
|
200
|
+
* adapters surface errors either via `isError: true` on the message envelope
|
|
201
|
+
* or on the first content block. Inspect both.
|
|
202
|
+
*/
|
|
203
|
+
function isErroredToolResult(msg) {
|
|
204
|
+
const m = msg;
|
|
205
|
+
if (!m)
|
|
206
|
+
return false;
|
|
207
|
+
if (m.isError === true)
|
|
208
|
+
return true;
|
|
209
|
+
if (Array.isArray(m.content) && m.content.length > 0) {
|
|
210
|
+
const first = m.content[0];
|
|
211
|
+
if (first && first.isError === true)
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
156
216
|
// ---------------------------------------------------------------------------
|
|
157
217
|
// Case 4: Mid-session full-scan repair
|
|
158
218
|
// ---------------------------------------------------------------------------
|
|
@@ -31,7 +31,7 @@ That's the default you start from. Kind without being soft. Witty without being
|
|
|
31
31
|
|
|
32
32
|
## About Comis
|
|
33
33
|
|
|
34
|
-
Comis is an open-source, security-first AI agent platform. You're one of its agents. You live in your human's messaging apps -- Discord, Telegram, Slack, WhatsApp, Signal, iMessage, IRC, LINE -- and help them with real tools, persistent memory, and proactive scheduling. You're part of a fleet: multiple agents with different skills, models, and personalities, working together.
|
|
34
|
+
Comis is an open-source, security-first AI agent platform. You're one of its agents. You live in your human's messaging apps -- Discord, Telegram, Slack, WhatsApp, Signal, iMessage, IRC, LINE -- and help them with real tools, persistent memory, and proactive scheduling. You're part of a fleet: multiple agents with different skills, models, and personalities, working together. Apache-2.0 licensed. No cloud dependency. Self-hosted.
|
|
35
35
|
|
|
36
36
|
Friendly by nature. Powerful by design.
|
|
37
37
|
|
|
@@ -130,7 +130,15 @@ export interface ChannelManagerDeps {
|
|
|
130
130
|
handleConfigCommand?: (args: string[], channelType: string) => Promise<string | undefined>;
|
|
131
131
|
/** Optional callback for task extraction after successful agent execution. */
|
|
132
132
|
onTaskExtraction?: (conversationText: string, sessionKey: string, agentId: string) => Promise<void>;
|
|
133
|
-
/**
|
|
133
|
+
/**
|
|
134
|
+
* Optional hook fired BEFORE the inbound message is dispatched to the executor.
|
|
135
|
+
* Use this for state that must be visible during processing (e.g. continuation
|
|
136
|
+
* tracker for SIGUSR2 capture). Fires for both real adapter inbounds and
|
|
137
|
+
* synthetic injected messages. Does NOT fire for early-return paths
|
|
138
|
+
* (no-adapter warning, graph-report intercept).
|
|
139
|
+
*/
|
|
140
|
+
onMessageReceived?: (msg: NormalizedMessage, channelType: string) => void;
|
|
141
|
+
/** Optional callback fired AFTER each successful inbound message processing. Used by post-processing state (e.g. notification session activity recording). */
|
|
134
142
|
onMessageProcessed?: (msg: NormalizedMessage, channelType: string) => void;
|
|
135
143
|
/** When true, lifecycle reactor handles queued/thinking reactions -- skip ack reaction in inbound pipeline. */
|
|
136
144
|
lifecycleReactionsEnabled?: boolean;
|
|
@@ -149,6 +157,16 @@ export interface ChannelManagerDeps {
|
|
|
149
157
|
handleSlashCommand?: InboundPipelineDeps["handleSlashCommand"];
|
|
150
158
|
/** Per-agent enforceFinalTag config lookup. */
|
|
151
159
|
getEnforceFinalTag?: InboundPipelineDeps["getEnforceFinalTag"];
|
|
160
|
+
/**
|
|
161
|
+
* Optional in-flight outbound sendMessage promise tracker. PRODUCTION
|
|
162
|
+
* callers (daemon) MUST NOT pass this -- the factory creates its own
|
|
163
|
+
* per-instance Set. Exposed via deps strictly to allow unit tests to
|
|
164
|
+
* inject a controllable Set for drain-ordering and deadline assertions.
|
|
165
|
+
* Drained in stopAll() with a 5s deadline so SIGUSR2 cannot tear down
|
|
166
|
+
* adapters mid-send (which would orphan the SQLite delivery-queue ack
|
|
167
|
+
* and trigger a duplicate retry on the next instance).
|
|
168
|
+
*/
|
|
169
|
+
inFlightSends?: Set<Promise<unknown>>;
|
|
152
170
|
/** Optional allowFrom sender filter lookup. Returns allowed sender IDs for a channel type. Empty array = allow all. */
|
|
153
171
|
getAllowFrom?: (channelType: string) => string[];
|
|
154
172
|
}
|
|
@@ -33,6 +33,27 @@ export function createChannelManager(deps) {
|
|
|
33
33
|
const sendOverrides = createSendOverrideStore();
|
|
34
34
|
/** Adapter lookup map: channelType -> ChannelPort. Populated in startAll(). */
|
|
35
35
|
const adaptersByType = new Map();
|
|
36
|
+
/**
|
|
37
|
+
* Per-instance in-flight outbound sendMessage promises. Used by
|
|
38
|
+
* deliver-to-channel.ts to register active sends; drained in stopAll() with
|
|
39
|
+
* a 5s deadline so SIGUSR2 cannot tear down adapters mid-send (which would
|
|
40
|
+
* orphan the SQLite delivery-queue ack and trigger a duplicate retry on the
|
|
41
|
+
* next instance).
|
|
42
|
+
*
|
|
43
|
+
* Tests may inject a Set via deps.inFlightSends to seed controllable
|
|
44
|
+
* promises for drain-ordering and deadline assertions; production callers
|
|
45
|
+
* (daemon) must NOT pass this -- the factory creates its own.
|
|
46
|
+
*/
|
|
47
|
+
const inFlightSends = deps.inFlightSends ?? new Set();
|
|
48
|
+
/**
|
|
49
|
+
* Pipeline deps with inFlightSends threaded in. Spread once so the Set is
|
|
50
|
+
* visible to processInboundMessage at all three call sites (debounce flush
|
|
51
|
+
* handler, normal onMessage handler, injectMessage). The original deps
|
|
52
|
+
* object is left untouched -- callbacks like onMessageProcessed and
|
|
53
|
+
* onGraphReportRequest live on the same reference (spread copies the
|
|
54
|
+
* function references, not the underlying behavior).
|
|
55
|
+
*/
|
|
56
|
+
const pipelineDeps = { ...deps, inFlightSends };
|
|
36
57
|
// Clean up stale overrides, debounce entries, and group history when sessions expire
|
|
37
58
|
deps.eventBus.on("session:expired", (ev) => {
|
|
38
59
|
sendOverrides.delete(formatSessionKey(ev.sessionKey));
|
|
@@ -65,7 +86,7 @@ export function createChannelManager(deps) {
|
|
|
65
86
|
};
|
|
66
87
|
// Fire-and-forget: processInboundMessage is async but the flush callback is sync.
|
|
67
88
|
// Errors are caught by the onMessage error handler.
|
|
68
|
-
void processInboundMessage(
|
|
89
|
+
void processInboundMessage(pipelineDeps, adapter, syntheticMsg, activePacers, sendOverrides).catch((error) => {
|
|
69
90
|
deps.logger.error({
|
|
70
91
|
err: error instanceof Error ? error : new Error(String(error)),
|
|
71
92
|
channelType,
|
|
@@ -90,7 +111,12 @@ export function createChannelManager(deps) {
|
|
|
90
111
|
return; // Handled -- do not forward to agent
|
|
91
112
|
}
|
|
92
113
|
}
|
|
93
|
-
await processInboundMessage
|
|
114
|
+
// Fire onMessageReceived BEFORE await processInboundMessage so any
|
|
115
|
+
// mid-processing SIGUSR2 still sees the session in continuation
|
|
116
|
+
// tracker state. The graph-report intercept above must remain BEFORE
|
|
117
|
+
// this call so control-plane callbacks bypass both hooks.
|
|
118
|
+
deps.onMessageReceived?.(msg, adapter.channelType);
|
|
119
|
+
await processInboundMessage(pipelineDeps, adapter, msg, activePacers, sendOverrides);
|
|
94
120
|
deps.onMessageProcessed?.(msg, adapter.channelType);
|
|
95
121
|
}
|
|
96
122
|
catch (error) {
|
|
@@ -130,6 +156,25 @@ export function createChannelManager(deps) {
|
|
|
130
156
|
for (const pacer of activePacers) {
|
|
131
157
|
pacer.cancel();
|
|
132
158
|
}
|
|
159
|
+
// Await in-flight outbound sends with a 5s deadline so SIGUSR2 cannot
|
|
160
|
+
// tear down adapters mid-HTTP-response (which would orphan the SQLite
|
|
161
|
+
// delivery-queue ack and trigger a duplicate retry on the next instance).
|
|
162
|
+
// Empty-Set fast path takes no log line, no setTimeout, no Promise.race --
|
|
163
|
+
// existing shutdown latency is preserved when nothing is in flight.
|
|
164
|
+
if (inFlightSends.size > 0) {
|
|
165
|
+
const drainStart = Date.now();
|
|
166
|
+
const inFlightCount = inFlightSends.size;
|
|
167
|
+
await Promise.race([
|
|
168
|
+
Promise.allSettled([...inFlightSends]),
|
|
169
|
+
new Promise((resolve) => setTimeout(resolve, 5000)),
|
|
170
|
+
]);
|
|
171
|
+
deps.logger.info({
|
|
172
|
+
inFlightCount,
|
|
173
|
+
drainMs: Date.now() - drainStart,
|
|
174
|
+
remaining: inFlightSends.size,
|
|
175
|
+
hint: "Outbound sends drained before adapter teardown to avoid duplicate-message risk on SIGUSR2 hot-reload",
|
|
176
|
+
}, "Channel manager: in-flight outbound sends drained");
|
|
177
|
+
}
|
|
133
178
|
// Build combined adapter list: direct adapters + plugin-registered adapters
|
|
134
179
|
const registryAdapters = deps.channelRegistry
|
|
135
180
|
? deps.channelRegistry.getChannelPlugins().map((p) => p.adapter)
|
|
@@ -168,7 +213,18 @@ export function createChannelManager(deps) {
|
|
|
168
213
|
return;
|
|
169
214
|
}
|
|
170
215
|
}
|
|
171
|
-
|
|
216
|
+
// Two-callback contract (symmetric with the normal inbound path):
|
|
217
|
+
// onMessageReceived fires BEFORE processInboundMessage so any
|
|
218
|
+
// mid-execution SIGUSR2 sees the session in continuation tracker
|
|
219
|
+
// state. Daemon wires this to continuationTracker.track(...).
|
|
220
|
+
// onMessageProcessed fires AFTER processing for post-processing state
|
|
221
|
+
// that depends on deferred refs (e.g. sessionTrackerRef.recordActivity).
|
|
222
|
+
// Both early-return branches above (no-adapter warn, graph-report intercept)
|
|
223
|
+
// intentionally bypass both callbacks because they represent control-plane
|
|
224
|
+
// events, not real session activity.
|
|
225
|
+
deps.onMessageReceived?.(msg, channelType);
|
|
226
|
+
await processInboundMessage(pipelineDeps, adapter, msg, activePacers, sendOverrides);
|
|
227
|
+
deps.onMessageProcessed?.(msg, channelType);
|
|
172
228
|
},
|
|
173
229
|
};
|
|
174
230
|
}
|
|
@@ -118,6 +118,16 @@ export interface DeliverToChannelDeps {
|
|
|
118
118
|
* Aborted deliveries emit delivery:aborted (not delivery:complete).
|
|
119
119
|
*/
|
|
120
120
|
abortSignal?: AbortSignal;
|
|
121
|
+
/**
|
|
122
|
+
* Per-instance set of in-flight outbound sendMessage promises. When provided,
|
|
123
|
+
* each chunk send is added to the set BEFORE the await (so a throwing send
|
|
124
|
+
* is still tracked) and removed via .finally() on settle. Drained in
|
|
125
|
+
* channel-manager.stopAll() with a 5s deadline so SIGUSR2 cannot tear down
|
|
126
|
+
* adapters mid-send (which would orphan the SQLite delivery-queue ack and
|
|
127
|
+
* trigger a duplicate retry on the next instance). Created by the
|
|
128
|
+
* channel-manager factory; do not pass externally.
|
|
129
|
+
*/
|
|
130
|
+
inFlightSends?: Set<Promise<unknown>>;
|
|
121
131
|
}
|
|
122
132
|
/**
|
|
123
133
|
* Resolve the effective chunk limit for a delivery.
|
|
@@ -334,18 +334,33 @@ export async function deliverToChannel(adapter, channelId, text, options, deps)
|
|
|
334
334
|
// If enqueue fails, log and continue -- queue failure should not block delivery
|
|
335
335
|
}
|
|
336
336
|
// Send with or without retry
|
|
337
|
-
|
|
338
|
-
let retried = false;
|
|
337
|
+
const retried = Boolean(deps?.retryEngine);
|
|
339
338
|
const chunkSendStart = Date.now();
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
339
|
+
// Build the send promise WITHOUT awaiting yet, so we can register it
|
|
340
|
+
// in deps.inFlightSends synchronously before the underlying HTTPS POST
|
|
341
|
+
// is observable as in-flight. This guarantees that a SIGUSR2 hitting
|
|
342
|
+
// mid-send will see the promise in the Set and drain it before tearing
|
|
343
|
+
// down adapters (avoids orphaned SQLite delivery-queue acks and the
|
|
344
|
+
// resulting duplicate-message retry on the next instance).
|
|
345
|
+
const sendPromise = deps?.retryEngine
|
|
346
|
+
? deps.retryEngine.sendWithRetry(
|
|
347
|
+
// RetryEngine expects a ChannelPort-like adapter -- our
|
|
348
|
+
// DeliveryAdapter has the same sendMessage signature, so cast
|
|
349
|
+
// through unknown
|
|
350
|
+
adapter, channelId, chunk, sendOpts)
|
|
351
|
+
: adapter.sendMessage(channelId, chunk, sendOpts);
|
|
352
|
+
if (deps?.inFlightSends) {
|
|
353
|
+
const tracked = sendPromise;
|
|
354
|
+
deps.inFlightSends.add(tracked);
|
|
355
|
+
// .finally fires on both fulfillment and rejection -- guarantees
|
|
356
|
+
// Set cleanup even if sendPromise rejects. We intentionally do
|
|
357
|
+
// not await this side-effect; the void keeps no-floating-promise
|
|
358
|
+
// lint quiet without altering the awaited value below.
|
|
359
|
+
void sendPromise.finally(() => {
|
|
360
|
+
deps.inFlightSends?.delete(tracked);
|
|
361
|
+
});
|
|
348
362
|
}
|
|
363
|
+
const result = await sendPromise;
|
|
349
364
|
const chunkResult = {
|
|
350
365
|
ok: result.ok,
|
|
351
366
|
charCount: chunk.length,
|
|
@@ -11,7 +11,7 @@ import type { ExecutionPipelineDeps } from "./execution-pipeline.js";
|
|
|
11
11
|
import type { BlockPacer } from "./block-pacer.js";
|
|
12
12
|
import type { TypingLifecycleController } from "./typing-lifecycle-controller.js";
|
|
13
13
|
/** Minimal deps needed for the delivery phase. */
|
|
14
|
-
export type DeliverDeps = Pick<ExecutionPipelineDeps, "eventBus" | "logger" | "streamingConfig" | "channelRegistry" | "retryEngine" | "deliveryQueue">;
|
|
14
|
+
export type DeliverDeps = Pick<ExecutionPipelineDeps, "eventBus" | "logger" | "streamingConfig" | "channelRegistry" | "retryEngine" | "deliveryQueue" | "inFlightSends">;
|
|
15
15
|
/**
|
|
16
16
|
* Chunk, coalesce, pace, and deliver the response text to the channel.
|
|
17
17
|
*
|
|
@@ -101,7 +101,7 @@ export async function deliverExecutionResponse(deps, adapter, effectiveMsg, fina
|
|
|
101
101
|
skipChunking: true,
|
|
102
102
|
origin: "agent",
|
|
103
103
|
}, deps.deliveryQueue
|
|
104
|
-
? { retryEngine: deps.retryEngine, eventBus: deps.eventBus, deliveryQueue: deps.deliveryQueue, replyMode: resolvedReplyMode, abortSignal: deliverySignal }
|
|
104
|
+
? { retryEngine: deps.retryEngine, eventBus: deps.eventBus, deliveryQueue: deps.deliveryQueue, replyMode: resolvedReplyMode, abortSignal: deliverySignal, inFlightSends: deps.inFlightSends }
|
|
105
105
|
: undefined);
|
|
106
106
|
if (!deliveryResult.ok || !deliveryResult.value.ok) {
|
|
107
107
|
failedChunks++;
|
|
@@ -78,6 +78,14 @@ export interface ExecutionPipelineDeps {
|
|
|
78
78
|
executionTimeoutMs?: number;
|
|
79
79
|
/** Delivery queue for crash-safe persistence. */
|
|
80
80
|
deliveryQueue?: DeliveryQueuePort;
|
|
81
|
+
/**
|
|
82
|
+
* Per-instance set of in-flight outbound sendMessage promises. Threaded
|
|
83
|
+
* through DeliverToChannelDeps so deliver-to-channel can register active
|
|
84
|
+
* sends. Drained in stopAll() with a 5s deadline so SIGUSR2 cannot tear
|
|
85
|
+
* down adapters mid-send. Created by the channel-manager factory; do not
|
|
86
|
+
* pass externally.
|
|
87
|
+
*/
|
|
88
|
+
inFlightSends?: Set<Promise<unknown>>;
|
|
81
89
|
/** When true, only content inside <final> blocks reaches users. */
|
|
82
90
|
enforceFinalTag?: boolean;
|
|
83
91
|
}
|
|
@@ -65,6 +65,18 @@ export async function evaluateInboundGate(deps, adapter, processedMsg, sessionKe
|
|
|
65
65
|
injectedAsHistory: true,
|
|
66
66
|
timestamp: Date.now(),
|
|
67
67
|
});
|
|
68
|
+
deps.logger.info({
|
|
69
|
+
channelType: adapter.channelType,
|
|
70
|
+
chatId: msg.channelId,
|
|
71
|
+
senderId: msg.senderId,
|
|
72
|
+
reason: decision.reason,
|
|
73
|
+
activationMode: arConfig.groupActivation,
|
|
74
|
+
isBotMentioned: msg.metadata?.isBotMentioned === true,
|
|
75
|
+
replyToBot: msg.metadata?.replyToBot === true,
|
|
76
|
+
action: "inject-history",
|
|
77
|
+
hint: "Group activation policy did not match — message saved as history context only. Set autoReplyEngine.groupActivation=always to respond to all group messages, or @-mention/reply to the bot to activate it.",
|
|
78
|
+
errorKind: "config",
|
|
79
|
+
}, "Group message did not activate agent");
|
|
68
80
|
// Push to group history ring buffer for context injection
|
|
69
81
|
if (deps.groupHistoryBuffer) {
|
|
70
82
|
deps.groupHistoryBuffer.push(formatSessionKey(sessionKey), msg);
|
|
@@ -100,12 +112,18 @@ export async function evaluateInboundGate(deps, adapter, processedMsg, sessionKe
|
|
|
100
112
|
injectedAsHistory: false,
|
|
101
113
|
timestamp: Date.now(),
|
|
102
114
|
});
|
|
103
|
-
deps.logger.
|
|
104
|
-
step: "auto-reply-suppressed",
|
|
115
|
+
deps.logger.info({
|
|
105
116
|
channelType: adapter.channelType,
|
|
106
117
|
chatId: msg.channelId,
|
|
118
|
+
senderId: msg.senderId,
|
|
107
119
|
reason: decision.reason,
|
|
108
|
-
|
|
120
|
+
activationMode: arConfig.groupActivation,
|
|
121
|
+
isBotMentioned: msg.metadata?.isBotMentioned === true,
|
|
122
|
+
replyToBot: msg.metadata?.replyToBot === true,
|
|
123
|
+
action: "ignore",
|
|
124
|
+
hint: "Group activation policy did not match and history injection is disabled. Set autoReplyEngine.groupActivation=always or autoReplyEngine.historyInjection=true to change.",
|
|
125
|
+
errorKind: "config",
|
|
126
|
+
}, "Group message ignored");
|
|
109
127
|
return { action: "skip" };
|
|
110
128
|
}
|
|
111
129
|
}
|
|
@@ -89,6 +89,14 @@ export interface InboundPipelineDeps {
|
|
|
89
89
|
retryEngine?: RetryEngine;
|
|
90
90
|
/** Delivery queue for crash-safe message persistence. When present, agent responses are enqueued before send. */
|
|
91
91
|
deliveryQueue?: DeliveryQueuePort;
|
|
92
|
+
/**
|
|
93
|
+
* Per-instance set of in-flight outbound sendMessage promises. Threaded
|
|
94
|
+
* through ExecutionPipelineDeps -> DeliverToChannelDeps so deliver-to-channel
|
|
95
|
+
* can register active sends. Drained in stopAll() with a 5s deadline so
|
|
96
|
+
* SIGUSR2 cannot tear down adapters mid-send. Created by the channel-manager
|
|
97
|
+
* factory; do not pass externally.
|
|
98
|
+
*/
|
|
99
|
+
inFlightSends?: Set<Promise<unknown>>;
|
|
92
100
|
/** Optional active run registry for SDK-native steer+followup. */
|
|
93
101
|
activeRunRegistry?: ActiveRunRegistry;
|
|
94
102
|
/** Handle /config command. Returns response text or undefined if not a config command. */
|