comisai 1.0.33 → 1.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/@comis/agent/dist/background/auto-background-middleware.d.ts +11 -1
- package/node_modules/@comis/agent/dist/background/auto-background-middleware.js +21 -4
- package/node_modules/@comis/agent/dist/background/background-task-manager.d.ts +2 -2
- package/node_modules/@comis/agent/dist/background/background-task-manager.js +61 -20
- package/node_modules/@comis/agent/dist/background/background-task-persistence.js +10 -3
- package/node_modules/@comis/agent/dist/background/background-task-types.d.ts +10 -3
- package/node_modules/@comis/agent/dist/background/background-task-types.js +1 -1
- package/node_modules/@comis/agent/dist/background/completion-formatter.d.ts +39 -0
- package/node_modules/@comis/agent/dist/background/completion-formatter.js +77 -0
- package/node_modules/@comis/agent/dist/background/completion-runner.d.ts +53 -0
- package/node_modules/@comis/agent/dist/background/completion-runner.js +151 -0
- package/node_modules/@comis/agent/dist/background/index.d.ts +4 -0
- package/node_modules/@comis/agent/dist/background/index.js +2 -0
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +17 -2
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +14 -2
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +23 -23
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +72 -60
- package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.d.ts +6 -7
- package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.js +24 -25
- package/node_modules/@comis/agent/dist/budget/cost-tracker.d.ts +1 -1
- package/node_modules/@comis/agent/dist/context-engine/constants.d.ts +5 -5
- package/node_modules/@comis/agent/dist/context-engine/constants.js +12 -12
- package/node_modules/@comis/agent/dist/context-engine/context-engine.js +13 -4
- package/node_modules/@comis/agent/dist/context-engine/dag-annotator.d.ts +1 -2
- package/node_modules/@comis/agent/dist/context-engine/dag-annotator.js +1 -2
- package/node_modules/@comis/agent/dist/context-engine/llm-compaction.js +20 -16
- package/node_modules/@comis/agent/dist/context-engine/rehydration.js +6 -6
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +12 -12
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +36 -22
- package/node_modules/@comis/agent/dist/context-engine/types-core.d.ts +15 -0
- package/node_modules/@comis/agent/dist/executor/cache-break-detection.d.ts +6 -6
- package/node_modules/@comis/agent/dist/executor/cache-break-detection.js +8 -8
- package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.d.ts +16 -0
- package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +46 -5
- package/node_modules/@comis/agent/dist/executor/executor-post-execution.d.ts +30 -0
- package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +17 -1
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +1 -1
- package/node_modules/@comis/agent/dist/executor/executor-response-filter.d.ts +7 -6
- package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +9 -42
- package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +2 -3
- package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.d.ts +2 -2
- package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.js +4 -4
- package/node_modules/@comis/agent/dist/executor/phase-filter.d.ts +2 -2
- package/node_modules/@comis/agent/dist/executor/phase-filter.js +5 -7
- package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +13 -0
- package/node_modules/@comis/agent/dist/executor/pi-executor.js +71 -6
- package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +7 -7
- package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.d.ts +1 -1
- package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +1 -1
- package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +2 -2
- package/node_modules/@comis/agent/dist/executor/tool-deferral.js +7 -7
- package/node_modules/@comis/agent/dist/index.d.ts +17 -0
- package/node_modules/@comis/agent/dist/index.js +32 -11
- package/node_modules/@comis/agent/dist/model/auth-provider.d.ts +25 -2
- package/node_modules/@comis/agent/dist/model/auth-provider.js +6 -0
- package/node_modules/@comis/agent/dist/model/compaction-model-resolver.d.ts +3 -3
- package/node_modules/@comis/agent/dist/model/compaction-model-resolver.js +3 -3
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.d.ts +37 -0
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.js +279 -0
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.d.ts +49 -0
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.js +50 -0
- package/node_modules/@comis/agent/dist/model/oauth-device-code.d.ts +57 -0
- package/node_modules/@comis/agent/dist/model/oauth-device-code.js +302 -0
- package/node_modules/@comis/agent/dist/model/oauth-env.d.ts +33 -0
- package/node_modules/@comis/agent/dist/model/oauth-env.js +38 -0
- package/node_modules/@comis/agent/dist/model/oauth-errors.d.ts +41 -0
- package/node_modules/@comis/agent/dist/model/oauth-errors.js +88 -0
- package/node_modules/@comis/agent/dist/model/oauth-identity.d.ts +53 -0
- package/node_modules/@comis/agent/dist/model/oauth-identity.js +141 -0
- package/node_modules/@comis/agent/dist/model/oauth-login-runner.d.ts +99 -0
- package/node_modules/@comis/agent/dist/model/oauth-login-runner.js +374 -0
- package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.d.ts +58 -0
- package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.js +82 -0
- package/node_modules/@comis/agent/dist/model/oauth-token-manager.d.ts +86 -16
- package/node_modules/@comis/agent/dist/model/oauth-token-manager.js +961 -66
- package/node_modules/@comis/agent/dist/model/operation-model-defaults.d.ts +9 -4
- package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +36 -9
- package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.d.ts +48 -0
- package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.js +66 -0
- package/node_modules/@comis/agent/dist/provider/capabilities.d.ts +5 -5
- package/node_modules/@comis/agent/dist/provider/capabilities.js +10 -23
- package/node_modules/@comis/agent/dist/safety/tool-output-safety.js +3 -3
- package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +1 -1
- package/node_modules/@comis/agent/dist/session/comis-session-manager.js +1 -1
- package/node_modules/@comis/agent/dist/spawn/narrative-caster.d.ts +10 -0
- package/node_modules/@comis/agent/dist/spawn/narrative-caster.js +5 -1
- package/node_modules/@comis/agent/package.json +1 -1
- package/node_modules/@comis/channels/dist/email/email-adapter.js +6 -6
- package/node_modules/@comis/channels/dist/email/imap-lifecycle.js +7 -7
- package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +12 -10
- package/node_modules/@comis/channels/dist/telegram/telegram-adapter.js +1 -1
- package/node_modules/@comis/channels/package.json +1 -1
- package/node_modules/@comis/cli/dist/cli.js +2 -0
- package/node_modules/@comis/cli/dist/commands/agent.d.ts +3 -3
- package/node_modules/@comis/cli/dist/commands/agent.js +46 -3
- package/node_modules/@comis/cli/dist/commands/auth.d.ts +37 -0
- package/node_modules/@comis/cli/dist/commands/auth.js +433 -0
- package/node_modules/@comis/cli/dist/commands/doctor.d.ts +4 -1
- package/node_modules/@comis/cli/dist/commands/doctor.js +20 -5
- package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.d.ts +39 -0
- package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.js +399 -0
- package/node_modules/@comis/cli/dist/doctor/types.d.ts +19 -0
- package/node_modules/@comis/cli/dist/index.d.ts +1 -0
- package/node_modules/@comis/cli/dist/index.js +10 -4
- package/node_modules/@comis/cli/dist/output/relative-time.d.ts +23 -0
- package/node_modules/@comis/cli/dist/output/relative-time.js +36 -0
- package/node_modules/@comis/cli/dist/wizard/non-interactive.js +17 -8
- package/node_modules/@comis/cli/dist/wizard/steps/03-provider.js +2 -1
- package/node_modules/@comis/cli/dist/wizard/steps/04-credentials.js +223 -34
- package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +14 -0
- package/node_modules/@comis/cli/dist/wizard/steps/11-daemon-start.js +3 -3
- package/node_modules/@comis/cli/dist/wizard/types.d.ts +7 -0
- package/node_modules/@comis/cli/package.json +1 -1
- package/node_modules/@comis/core/dist/bootstrap.d.ts +1 -1
- package/node_modules/@comis/core/dist/config/env-substitution.d.ts +66 -0
- package/node_modules/@comis/core/dist/config/env-substitution.js +115 -0
- package/node_modules/@comis/core/dist/config/index.d.ts +3 -1
- package/node_modules/@comis/core/dist/config/index.js +2 -1
- package/node_modules/@comis/core/dist/config/loader.js +61 -0
- package/node_modules/@comis/core/dist/config/managed-sections.d.ts +3 -3
- package/node_modules/@comis/core/dist/config/managed-sections.js +10 -5
- package/node_modules/@comis/core/dist/config/schema-agent.d.ts +4 -0
- package/node_modules/@comis/core/dist/config/schema-agent.js +16 -1
- package/node_modules/@comis/core/dist/config/schema-background-tasks.d.ts +7 -0
- package/node_modules/@comis/core/dist/config/schema-background-tasks.js +7 -0
- package/node_modules/@comis/core/dist/config/schema-delivery.d.ts +2 -0
- package/node_modules/@comis/core/dist/config/schema-delivery.js +2 -0
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.d.ts +0 -2
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.js +0 -2
- package/node_modules/@comis/core/dist/config/schema-oauth.d.ts +23 -0
- package/node_modules/@comis/core/dist/config/schema-oauth.js +19 -0
- package/node_modules/@comis/core/dist/config/schema-skills.d.ts +6 -8
- package/node_modules/@comis/core/dist/config/schema-skills.js +3 -4
- package/node_modules/@comis/core/dist/config/schema.d.ts +10 -0
- package/node_modules/@comis/core/dist/config/schema.js +3 -0
- package/node_modules/@comis/core/dist/domain/background-task-origin.d.ts +39 -0
- package/node_modules/@comis/core/dist/domain/background-task-origin.js +39 -0
- package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +71 -2
- package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
- package/node_modules/@comis/core/dist/exports/config.js +1 -1
- package/node_modules/@comis/core/dist/exports/domain.d.ts +2 -0
- package/node_modules/@comis/core/dist/exports/domain.js +1 -0
- package/node_modules/@comis/core/dist/exports/ports.d.ts +2 -2
- package/node_modules/@comis/core/dist/exports/ports.js +1 -1
- package/node_modules/@comis/core/dist/ports/delivery-queue.d.ts +23 -0
- package/node_modules/@comis/core/dist/ports/delivery-queue.js +2 -0
- package/node_modules/@comis/core/dist/ports/index.d.ts +2 -0
- package/node_modules/@comis/core/dist/ports/index.js +1 -0
- package/node_modules/@comis/core/dist/ports/oauth-credential-store.d.ts +64 -0
- package/node_modules/@comis/core/dist/ports/oauth-credential-store.js +37 -0
- package/node_modules/@comis/core/dist/tool-metadata.d.ts +20 -0
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/dist/daemon-types.d.ts +23 -3
- package/node_modules/@comis/daemon/dist/daemon.js +82 -19
- package/node_modules/@comis/daemon/dist/health/watchdog.js +18 -3
- package/node_modules/@comis/daemon/dist/index.d.ts +2 -0
- package/node_modules/@comis/daemon/dist/index.js +5 -0
- package/node_modules/@comis/daemon/dist/observability/channel-health-logger.js +3 -3
- package/node_modules/@comis/daemon/dist/observability/delivery-queue-logger.js +1 -1
- package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +22 -1
- package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +84 -21
- package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +2 -2
- package/node_modules/@comis/daemon/dist/rpc/config-handlers.d.ts +9 -1
- package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +104 -23
- package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +30 -1
- package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +74 -11
- package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.d.ts +8 -0
- package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.js +22 -8
- package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +9 -12
- package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +1 -0
- package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +27 -2
- package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +0 -1
- package/node_modules/@comis/daemon/dist/wiring/index.d.ts +2 -0
- package/node_modules/@comis/daemon/dist/wiring/index.js +1 -0
- package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.d.ts +21 -0
- package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.js +134 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +46 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +127 -3
- package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +39 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +32 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.d.ts +10 -3
- package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.js +11 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +20 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +1 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery.d.ts +14 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +52 -19
- package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +4 -0
- package/node_modules/@comis/daemon/package.json +1 -1
- package/node_modules/@comis/gateway/dist/index.d.ts +2 -0
- package/node_modules/@comis/gateway/dist/index.js +2 -0
- package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.d.ts +66 -0
- package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.js +212 -0
- package/node_modules/@comis/gateway/dist/server/hono-server.d.ts +14 -0
- package/node_modules/@comis/gateway/dist/server/hono-server.js +10 -0
- package/node_modules/@comis/gateway/package.json +1 -1
- package/node_modules/@comis/infra/dist/logging/log-fields.d.ts +23 -0
- package/node_modules/@comis/infra/package.json +1 -1
- package/node_modules/@comis/memory/dist/compaction.d.ts +3 -5
- package/node_modules/@comis/memory/dist/compaction.js +2 -3
- package/node_modules/@comis/memory/dist/delivery-queue-adapter.d.ts +2 -2
- package/node_modules/@comis/memory/dist/delivery-queue-adapter.js +49 -1
- package/node_modules/@comis/memory/dist/index.d.ts +2 -0
- package/node_modules/@comis/memory/dist/index.js +3 -0
- package/node_modules/@comis/memory/dist/memory-api.d.ts +1 -1
- package/node_modules/@comis/memory/dist/memory-api.js +1 -1
- package/node_modules/@comis/memory/dist/oauth-profile-schema.d.ts +17 -0
- package/node_modules/@comis/memory/dist/oauth-profile-schema.js +33 -0
- package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.d.ts +27 -0
- package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.js +144 -0
- package/node_modules/@comis/memory/dist/session-store.d.ts +1 -1
- package/node_modules/@comis/memory/dist/session-store.js +1 -1
- package/node_modules/@comis/memory/dist/sqlite-secret-store.d.ts +29 -3
- package/node_modules/@comis/memory/dist/sqlite-secret-store.js +11 -3
- package/node_modules/@comis/memory/package.json +1 -1
- package/node_modules/@comis/scheduler/dist/execution/execution-lock.d.ts +13 -0
- package/node_modules/@comis/scheduler/dist/execution/execution-lock.js +1 -1
- package/node_modules/@comis/scheduler/dist/execution/index.d.ts +2 -0
- package/node_modules/@comis/scheduler/dist/execution/index.js +2 -0
- package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +1 -1
- package/node_modules/@comis/scheduler/dist/index.d.ts +2 -0
- package/node_modules/@comis/scheduler/dist/index.js +2 -0
- 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/schema-validator.d.ts +38 -0
- package/node_modules/@comis/skills/dist/bridge/schema-validator.js +169 -0
- package/node_modules/@comis/skills/dist/bridge/tool-metadata-enforcement.js +12 -0
- package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +130 -0
- package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.d.ts +32 -0
- package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.js +127 -0
- package/node_modules/@comis/skills/dist/builtin/exec-security.js +38 -0
- package/node_modules/@comis/skills/dist/builtin/exec-tool.js +9 -0
- package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +6 -6
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +38 -27
- package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -1
- package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +3 -3
- package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +6 -6
- package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +9 -9
- package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.d.ts +11 -0
- package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.js +114 -1
- package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +40 -15
- package/node_modules/@comis/skills/dist/media/ssrf-fetcher.d.ts +7 -0
- package/node_modules/@comis/skills/dist/media/ssrf-fetcher.js +9 -2
- package/node_modules/@comis/skills/package.json +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-detail-71BSbSfD.js → agent-detail-q8t1NB7w.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-editor-CTSDZhwT.js → agent-editor-B46io5gv.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-list-BEhni2ea.js → agent-list-DQ6g2Rcx.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{billing-view-DVP1IvVs.js → billing-view-IWPR8LgF.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-detail-N_YK74xC.js → channel-detail-DlNNZuuC.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-list-DRk6ZJaF.js → channel-list-DhGwxiMc.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{chat-console-Dm-GtSf9.js → chat-console-Nv6fM3Rc.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{config-editor-CIferYX6.js → config-editor-BYKuJF76.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-dag-browser-CL84rXXM.js → context-dag-browser-ClNEtzYE.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-engine-B1HOTEZv.js → context-engine-BZJ6HChd.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{delivery-view-Y6JKYVFw.js → delivery-view-Cb7I3vGu.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{diagnostics-view-DWV1UQjz.js → diagnostics-view-9u9Lyu5a.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-chat-message-DfSERzzg.js → ic-chat-message-BFt3cVpx.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CXyhlJup.js → ic-connection-dot-y77LZ3Gu.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-tool-call-DNmwTjek.js → ic-tool-call-qt6w1NQl.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{index-CBr0Tm9_.js → index-8Tg9oc-C.js} +2 -2
- package/node_modules/@comis/web/dist/assets/{mcp-management-BaH2-vox.js → mcp-management-69dtH_kY.js} +2 -2
- package/node_modules/@comis/web/dist/assets/{media-config-CZLshJoN.js → media-config-BdjLj5c1.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{media-test-C9NUWgo_.js → media-test-DuPqrixi.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{memory-inspector-D_fmTcRN.js → memory-inspector-B-Pepbq-.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{message-center-BBFlNCZn.js → message-center-B7l0yNYY.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{models-BytGLm99.js → models-JHFHuv5S.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{observe-view-VXtHqaqq.js → observe-view-r8mqhy4O.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-builder-CfXczlfJ.js → pipeline-builder-XjkiZRcR.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-CPmXFnbe.js → pipeline-history-CZqJv_Hj.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-DcueTMs9.js → pipeline-history-detail-BEFGMoDy.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-list-B-xG5WZh.js → pipeline-list-B6q5LvO1.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-monitor-pnIOYaSY.js → pipeline-monitor-BNomXjVL.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{scheduler-BtUIFHhA.js → scheduler-BJEjcGKA.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{security-C8mWRq2y.js → security-2G1jhBfV.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-detail-DgdkO5ka.js → session-detail-DmVPzFBR.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-list-DcylcfTn.js → session-list-CsqMQoHs.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{setup-wizard-BP5yjsuL.js → setup-wizard-CAdM-gSP.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{skills-DXt1bX8Z.js → skills-2ODqKaWr.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{subagents-C7YbUHXY.js → subagents-BFlwfTbD.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{workspace-manager-DP6pW4wa.js → workspace-manager--CbOx_dI.js} +1 -1
- package/node_modules/@comis/web/dist/index.html +1 -1
- package/node_modules/@comis/web/package.json +1 -1
- package/package.json +17 -16
|
@@ -13,8 +13,15 @@ import { homedir } from "node:os";
|
|
|
13
13
|
import { existsSync, mkdirSync } from "node:fs";
|
|
14
14
|
import { isAbsolute, resolve } from "node:path";
|
|
15
15
|
import { getModels, getProviders } from "@mariozechner/pi-ai";
|
|
16
|
-
import { createCircuitBreaker, createBudgetGuard, createCostTracker, createStepCounter, createSessionLifecycle, ensureWorkspace, resolveWorkspaceDir, createPiExecutor, createComisSessionManager, cleanupStaleLocks, createAuthStorageAdapter, createModelRegistryAdapter, registerCustomProviders, createProviderHealthMonitor, createLastKnownModelTracker, createAuthProfileManager, createAuthRotationAdapter, setSanitizeLogger, setToolNormalizationLogger, resolveOperationDefaults, resolveCompactionModel, LEAN_TOOL_DESCRIPTIONS, resolveDescription, } from "@comis/agent";
|
|
16
|
+
import { createCircuitBreaker, createBudgetGuard, createCostTracker, createStepCounter, createSessionLifecycle, ensureWorkspace, resolveWorkspaceDir, createPiExecutor, createComisSessionManager, cleanupStaleLocks, createAuthStorageAdapter, createAuthProvider, selectOAuthCredentialStore, createModelRegistryAdapter, registerCustomProviders, createProviderHealthMonitor, createLastKnownModelTracker, createAuthProfileManager, createAuthRotationAdapter, setSanitizeLogger, setToolNormalizationLogger, resolveOperationDefaults, resolveCompactionModel, LEAN_TOOL_DESCRIPTIONS, resolveDescription, } from "@comis/agent";
|
|
17
17
|
import { agentToolsToToolDefinitions, createSkillRegistry, createRuntimeEligibilityContext, TOOL_PROFILES, } from "@comis/skills";
|
|
18
|
+
// Once-per-daemon-process WARN flag for the encrypted-store hot-reload
|
|
19
|
+
// limitation. Lifted to module scope so the flag survives across per-agent
|
|
20
|
+
// setupSingleAgent calls AND any future re-invocations of setupAgents within
|
|
21
|
+
// the same process. Operator-friendly notice — fires exactly once per daemon
|
|
22
|
+
// process so the operator sees it in startup logs without N-times-per-agent
|
|
23
|
+
// noise.
|
|
24
|
+
let encryptedModeWarnFired = false;
|
|
18
25
|
// ---------------------------------------------------------------------------
|
|
19
26
|
// Single-agent setup (extracted for hot-add reuse)
|
|
20
27
|
// ---------------------------------------------------------------------------
|
|
@@ -104,6 +111,75 @@ export async function setupSingleAgent(agentId, rawAgentConfig, deps) {
|
|
|
104
111
|
secretManager: scopedManager,
|
|
105
112
|
customProviderEntries,
|
|
106
113
|
});
|
|
114
|
+
// -------------------------------------------------------------------------
|
|
115
|
+
// FIRST daemon-side OAuth wiring.
|
|
116
|
+
//
|
|
117
|
+
// Closes the unwired-OAuth gap — the createAuthProvider symbol was exported
|
|
118
|
+
// by @comis/agent but never called by the daemon, so refreshed OAuth tokens
|
|
119
|
+
// lived only in the in-memory cache and silently disappeared on restart.
|
|
120
|
+
// AuthProviderConfig.oauth credentialStore + logger + dataDir are REQUIRED
|
|
121
|
+
// so this wiring is type-checked at compile time — future regressions
|
|
122
|
+
// surface as TS errors, not silent runtime failures.
|
|
123
|
+
//
|
|
124
|
+
// All path constructions in this block use safePath from @comis/core (NOT
|
|
125
|
+
// path.join — AGENTS.md §2.2 ESLint security rule).
|
|
126
|
+
// When storage === "encrypted", the OAuth profile adapter SHARES the
|
|
127
|
+
// existing secretsDb handle from createSqliteSecretStore (no dual-handle).
|
|
128
|
+
// -------------------------------------------------------------------------
|
|
129
|
+
const oauthStorageMode = container.config.oauth.storage;
|
|
130
|
+
const dataDirAbs = container.config.dataDir && container.config.dataDir.length > 0
|
|
131
|
+
? container.config.dataDir
|
|
132
|
+
: safePath(homedir(), ".comis");
|
|
133
|
+
// Use the daemon-level OAuthCredentialStore handle that setupAgents()
|
|
134
|
+
// constructed once and threaded through SingleAgentDeps. Same store
|
|
135
|
+
// reference is also exposed on AgentsResult so daemon.ts can plumb it into
|
|
136
|
+
// RpcDispatchDeps for the agents.update oauthProfiles existence check.
|
|
137
|
+
const oauthCredentialStore = deps.oauthCredentialStore;
|
|
138
|
+
const authProvider = createAuthProvider({
|
|
139
|
+
secretManager: scopedManager,
|
|
140
|
+
additionalProviderKeys: undefined,
|
|
141
|
+
oauth: {
|
|
142
|
+
eventBus: container.eventBus,
|
|
143
|
+
credentialStore: oauthCredentialStore,
|
|
144
|
+
logger: agentLogger.child({ submodule: "oauth-token-manager" }),
|
|
145
|
+
dataDir: dataDirAbs,
|
|
146
|
+
keyPrefix: "OAUTH_",
|
|
147
|
+
// Pass auth-profiles.json path when file adapter active so
|
|
148
|
+
// OAuthTokenManager can register the chokidar watcher and pick up
|
|
149
|
+
// CLI-written profiles within ~250ms without a daemon restart.
|
|
150
|
+
// Encrypted-mode: undefined -> no watcher; documented limitation.
|
|
151
|
+
watchPath: oauthStorageMode === "file"
|
|
152
|
+
? safePath(dataDirAbs, "auth-profiles.json")
|
|
153
|
+
: undefined,
|
|
154
|
+
// Closure-stability: the closure dereferences
|
|
155
|
+
// container.config.agents[agentId]?.oauthProfiles on every call.
|
|
156
|
+
// This is the only correct shape because:
|
|
157
|
+
// 1. Line ~222 above writes effectiveConfig (a NEW object built
|
|
158
|
+
// from { ...agentConfig, model, provider }) into
|
|
159
|
+
// container.config.agents[agentId]. The local `agentConfig`
|
|
160
|
+
// parameter diverges from the daemon's map immediately at
|
|
161
|
+
// startup — capturing it would observe the wrong value.
|
|
162
|
+
// 2. agents.update at agent-handlers.ts:341 executes
|
|
163
|
+
// `deps.agents[agentId] = parsedConfig`, REPLACING the
|
|
164
|
+
// reference at that key with a new validated object. Capturing
|
|
165
|
+
// the local agentConfig parameter would miss this hot-update.
|
|
166
|
+
// 3. daemon.ts:594, 634 confirm `deps.agents` and
|
|
167
|
+
// `container.config.agents` are THE SAME map object — the
|
|
168
|
+
// daemon's single per-process Container.config instance.
|
|
169
|
+
// The map identity is stable; only the value at the agent key
|
|
170
|
+
// changes. The closure-evaluated dereference observes (1) at
|
|
171
|
+
// startup AND (2) on every agents.update without an event-bus
|
|
172
|
+
// invalidation or daemon restart, allowing the agents_manage tool to
|
|
173
|
+
// update without a daemon restart.
|
|
174
|
+
getAgentOauthProfiles: () => container.config.agents?.[agentId]?.oauthProfiles,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
agentLogger.debug({
|
|
178
|
+
agentId,
|
|
179
|
+
oauthStorage: oauthStorageMode,
|
|
180
|
+
dataDir: dataDirAbs,
|
|
181
|
+
submodule: "setup-agents",
|
|
182
|
+
}, "OAuth credential store + auth provider + per-LLM-call dispatch wired");
|
|
107
183
|
const piModelRegistry = createModelRegistryAdapter(piAuthStorage);
|
|
108
184
|
const { registered: customProviderCount, providerAliases } = registerCustomProviders(piModelRegistry, customProviderEntries, scopedManager, agentLogger);
|
|
109
185
|
if (customProviderCount > 0) {
|
|
@@ -235,6 +311,11 @@ export async function setupSingleAgent(agentId, rawAgentConfig, deps) {
|
|
|
235
311
|
eventBus: container.eventBus,
|
|
236
312
|
logger: perAgentLogger,
|
|
237
313
|
authStorage: piAuthStorage,
|
|
314
|
+
// Thread OAuthTokenManager into the executor so the per-LLM-call
|
|
315
|
+
// dispatch hook (PiExecutor.execute pre-hook + the two compaction
|
|
316
|
+
// getApiKey callbacks in executor-context-engine-setup.ts) can resolve
|
|
317
|
+
// OAuth tokens via resolveProviderApiKey.
|
|
318
|
+
oauthManager: authProvider.oauth,
|
|
238
319
|
modelRegistry: piModelRegistry,
|
|
239
320
|
providerAliases,
|
|
240
321
|
fallbackModels: fallbackModelStrings.length > 0 ? fallbackModelStrings : undefined,
|
|
@@ -312,9 +393,23 @@ export async function setupSingleAgent(agentId, rawAgentConfig, deps) {
|
|
|
312
393
|
export async function setupAgents(deps) {
|
|
313
394
|
const { container, memoryAdapter, sessionStore, agentLogger } = deps;
|
|
314
395
|
// Inject module-level logger for response sanitization pipeline
|
|
315
|
-
setSanitizeLogger(agentLogger.child({
|
|
396
|
+
setSanitizeLogger(agentLogger.child({ submodule: "response-sanitize" }));
|
|
316
397
|
// Inject module-level logger for tool schema normalization pipeline
|
|
317
|
-
setToolNormalizationLogger(agentLogger.child({
|
|
398
|
+
setToolNormalizationLogger(agentLogger.child({ submodule: "tool-normalize" }));
|
|
399
|
+
// Once-per-daemon WARN for the encrypted-store hot-reload limitation.
|
|
400
|
+
// Placed in setupAgents() body (NOT setupSingleAgent) so the notice fires
|
|
401
|
+
// exactly once per daemon process — not N times for N agents. Operator
|
|
402
|
+
// sees this in startup logs without surprise; daemon restart is required
|
|
403
|
+
// to pick up CLI-written OAuth profiles in encrypted-store mode.
|
|
404
|
+
const overallStorageMode = container.config.oauth.storage;
|
|
405
|
+
if (overallStorageMode === "encrypted" && !encryptedModeWarnFired) {
|
|
406
|
+
encryptedModeWarnFired = true;
|
|
407
|
+
agentLogger.warn({
|
|
408
|
+
hint: "CLI auth login changes require daemon restart in encrypted mode (file-watch unsupported on encrypted SQLite WAL)",
|
|
409
|
+
errorKind: "limitation_known",
|
|
410
|
+
submodule: "setup-agents",
|
|
411
|
+
}, "OAuth hot-reload disabled in encrypted-store mode");
|
|
412
|
+
}
|
|
318
413
|
const agents = container.config.agents; // Always populated after schema transform
|
|
319
414
|
const routingConfig = container.config.routing;
|
|
320
415
|
// Daemon-level tracing defaults
|
|
@@ -368,6 +463,19 @@ export async function setupAgents(deps) {
|
|
|
368
463
|
});
|
|
369
464
|
// Global last-known-working model tracker (shared across all agents)
|
|
370
465
|
const lastKnownModel = createLastKnownModelTracker();
|
|
466
|
+
// Construct the daemon-level OAuthCredentialStore handle ONCE (instead of
|
|
467
|
+
// per-agent inside setupSingleAgent). Same handle is reused across every
|
|
468
|
+
// agent setup AND surfaced on AgentsResult so daemon.ts can plumb it into
|
|
469
|
+
// RpcDispatchDeps for the agents.update oauthProfiles existence check.
|
|
470
|
+
const dataDirAbsForOauth = container.config.dataDir && container.config.dataDir.length > 0
|
|
471
|
+
? container.config.dataDir
|
|
472
|
+
: safePath(homedir(), ".comis");
|
|
473
|
+
const oauthCredentialStore = selectOAuthCredentialStore({
|
|
474
|
+
storage: container.config.oauth.storage,
|
|
475
|
+
dataDir: dataDirAbsForOauth,
|
|
476
|
+
secretsCrypto: deps.secretsCrypto,
|
|
477
|
+
secretsDb: deps.secretsDb,
|
|
478
|
+
});
|
|
371
479
|
// Construct shared deps struct once before the loop (for hot-add reuse)
|
|
372
480
|
const singleAgentDeps = {
|
|
373
481
|
container,
|
|
@@ -395,6 +503,12 @@ export async function setupAgents(deps) {
|
|
|
395
503
|
getChannelMaxChars: deps.getChannelMaxChars,
|
|
396
504
|
backgroundTaskManager: deps.backgroundTaskManager,
|
|
397
505
|
backgroundNotifyFn: deps.backgroundNotifyFn,
|
|
506
|
+
// Secrets bootstrap output for OAuth wiring.
|
|
507
|
+
secretsCrypto: deps.secretsCrypto,
|
|
508
|
+
secretsDb: deps.secretsDb,
|
|
509
|
+
// Daemon-level OAuth credential store handle (constructed once above,
|
|
510
|
+
// reused per-agent + threaded into RPC deps).
|
|
511
|
+
oauthCredentialStore,
|
|
398
512
|
};
|
|
399
513
|
for (const [agentId, agentConfig] of Object.entries(agents)) {
|
|
400
514
|
const result = await setupSingleAgent(agentId, agentConfig, singleAgentDeps);
|
|
@@ -451,6 +565,10 @@ export async function setupAgents(deps) {
|
|
|
451
565
|
lockCleanupTimer,
|
|
452
566
|
singleAgentDeps,
|
|
453
567
|
providerHealth,
|
|
568
|
+
// Daemon-level OAuth credential store, plumbed by daemon.ts into
|
|
569
|
+
// RpcDispatchDeps.oauthCredentialStore so agents.update can validate
|
|
570
|
+
// oauthProfiles patches via has().
|
|
571
|
+
oauthCredentialStore,
|
|
454
572
|
};
|
|
455
573
|
}
|
|
456
574
|
// ---------------------------------------------------------------------------
|
|
@@ -543,3 +661,9 @@ function deriveCanaryFallback(baseSecret, agentId) {
|
|
|
543
661
|
.update(`canary-fallback:${agentId}`)
|
|
544
662
|
.digest("hex");
|
|
545
663
|
}
|
|
664
|
+
// ---------------------------------------------------------------------------
|
|
665
|
+
// OAuth credential store selection lives in @comis/agent (CLI cannot import
|
|
666
|
+
// from @comis/daemon, so the helper must live where both daemon and CLI
|
|
667
|
+
// consume it).
|
|
668
|
+
// See: packages/agent/src/model/oauth-credential-store-selector.ts
|
|
669
|
+
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background completion runner wiring for daemon startup.
|
|
3
|
+
*
|
|
4
|
+
* Subscribes the runner to background_task:{completed,failed} events after
|
|
5
|
+
* the notification service has been wired (so fallbackNotifyFn is live),
|
|
6
|
+
* and returns a shutdown handle for the daemon's system:shutdown sequence
|
|
7
|
+
* to await before tearing down the executor.
|
|
8
|
+
*
|
|
9
|
+
* Per AGENTS §2.4: composition root + factories. This wiring lives in
|
|
10
|
+
* @comis/daemon (composition root); the actual factory body is in
|
|
11
|
+
* @comis/agent.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import { type BackgroundCompletionRunner, type BackgroundTaskManager, type NotifyFn } from "@comis/agent";
|
|
16
|
+
import type { TypedEventBus } from "@comis/core";
|
|
17
|
+
import type { ComisLogger } from "@comis/infra";
|
|
18
|
+
import type { AgentExecutor } from "@comis/agent";
|
|
19
|
+
import type { RunnerSessionStore } from "@comis/agent";
|
|
20
|
+
/** Result of setupBackgroundCompletionRunner -- exposed to the daemon for shutdown. */
|
|
21
|
+
export interface BackgroundCompletionRunnerContext {
|
|
22
|
+
runner: BackgroundCompletionRunner;
|
|
23
|
+
}
|
|
24
|
+
export interface SetupBackgroundCompletionRunnerDeps {
|
|
25
|
+
eventBus: TypedEventBus;
|
|
26
|
+
getExecutor: (agentId: string) => AgentExecutor;
|
|
27
|
+
sessionStore: RunnerSessionStore;
|
|
28
|
+
taskManager: Pick<BackgroundTaskManager, "getTask">;
|
|
29
|
+
/** bgNotifyFn closure used when the originating session is gone. */
|
|
30
|
+
fallbackNotifyFn: NotifyFn;
|
|
31
|
+
/** From config.backgroundTasks.maxBackgroundHops (default 3). NOT config.workflow.*. */
|
|
32
|
+
maxBackgroundHops: number;
|
|
33
|
+
logger: ComisLogger;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Wire the background completion runner from daemon-level dependencies.
|
|
37
|
+
* Call this AFTER setupNotifications so fallbackNotifyFn is wired.
|
|
38
|
+
*/
|
|
39
|
+
export declare function setupBackgroundCompletionRunner(deps: SetupBackgroundCompletionRunnerDeps): BackgroundCompletionRunnerContext;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Background completion runner wiring for daemon startup.
|
|
4
|
+
*
|
|
5
|
+
* Subscribes the runner to background_task:{completed,failed} events after
|
|
6
|
+
* the notification service has been wired (so fallbackNotifyFn is live),
|
|
7
|
+
* and returns a shutdown handle for the daemon's system:shutdown sequence
|
|
8
|
+
* to await before tearing down the executor.
|
|
9
|
+
*
|
|
10
|
+
* Per AGENTS §2.4: composition root + factories. This wiring lives in
|
|
11
|
+
* @comis/daemon (composition root); the actual factory body is in
|
|
12
|
+
* @comis/agent.
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { createBackgroundCompletionRunner, } from "@comis/agent";
|
|
17
|
+
/**
|
|
18
|
+
* Wire the background completion runner from daemon-level dependencies.
|
|
19
|
+
* Call this AFTER setupNotifications so fallbackNotifyFn is wired.
|
|
20
|
+
*/
|
|
21
|
+
export function setupBackgroundCompletionRunner(deps) {
|
|
22
|
+
const runner = createBackgroundCompletionRunner({
|
|
23
|
+
eventBus: deps.eventBus,
|
|
24
|
+
getExecutor: deps.getExecutor,
|
|
25
|
+
sessionStore: deps.sessionStore,
|
|
26
|
+
taskManager: deps.taskManager,
|
|
27
|
+
fallbackNotifyFn: deps.fallbackNotifyFn,
|
|
28
|
+
maxBackgroundHops: deps.maxBackgroundHops,
|
|
29
|
+
logger: deps.logger,
|
|
30
|
+
});
|
|
31
|
+
return { runner };
|
|
32
|
+
}
|
|
@@ -19,9 +19,16 @@ export interface SetupBackgroundTasksDeps {
|
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Wire the background task subsystem from daemon-level dependencies.
|
|
22
|
-
* Creates BackgroundTaskManager with file-based persistence
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* Creates BackgroundTaskManager with file-based persistence and starts
|
|
23
|
+
* an hourly cleanup timer for stale completed/failed tasks.
|
|
24
|
+
*
|
|
25
|
+
* Note: startup recovery (marking interrupted tasks as failed) is
|
|
26
|
+
* INTENTIONALLY deferred to daemon.ts. The daemon calls it AFTER
|
|
27
|
+
* `setupBackgroundCompletionRunner` has subscribed to
|
|
28
|
+
* background_task:{completed,failed}. If recovery fires before the runner
|
|
29
|
+
* subscribes, the synthesized failure events for restart-interrupted tasks
|
|
30
|
+
* land in an empty handler set and the user never sees the recovery
|
|
31
|
+
* announcement.
|
|
25
32
|
* @param deps - Daemon-level dependencies
|
|
26
33
|
* @returns BackgroundTasksContext with manager instance
|
|
27
34
|
*/
|
|
@@ -9,9 +9,16 @@ import { createBackgroundTaskManager } from "@comis/agent";
|
|
|
9
9
|
import { safePath } from "@comis/core";
|
|
10
10
|
/**
|
|
11
11
|
* Wire the background task subsystem from daemon-level dependencies.
|
|
12
|
-
* Creates BackgroundTaskManager with file-based persistence
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Creates BackgroundTaskManager with file-based persistence and starts
|
|
13
|
+
* an hourly cleanup timer for stale completed/failed tasks.
|
|
14
|
+
*
|
|
15
|
+
* Note: startup recovery (marking interrupted tasks as failed) is
|
|
16
|
+
* INTENTIONALLY deferred to daemon.ts. The daemon calls it AFTER
|
|
17
|
+
* `setupBackgroundCompletionRunner` has subscribed to
|
|
18
|
+
* background_task:{completed,failed}. If recovery fires before the runner
|
|
19
|
+
* subscribes, the synthesized failure events for restart-interrupted tasks
|
|
20
|
+
* land in an empty handler set and the user never sees the recovery
|
|
21
|
+
* announcement.
|
|
15
22
|
* @param deps - Daemon-level dependencies
|
|
16
23
|
* @returns BackgroundTasksContext with manager instance
|
|
17
24
|
*/
|
|
@@ -21,8 +28,7 @@ export function setupBackgroundTasks(deps) {
|
|
|
21
28
|
eventBus: deps.eventBus,
|
|
22
29
|
logger: deps.logger,
|
|
23
30
|
});
|
|
24
|
-
//
|
|
25
|
-
manager.recoverOnStartup();
|
|
31
|
+
// Startup recovery is deferred to daemon.ts (after the completion runner subscribes).
|
|
26
32
|
// Periodic cleanup of stale completed/failed tasks (24h TTL)
|
|
27
33
|
const cleanupInterval = setInterval(() => manager.cleanup(), 3_600_000); // every hour
|
|
28
34
|
cleanupInterval.unref(); // don't keep daemon alive for cleanup
|
|
@@ -96,7 +96,7 @@ export async function setupChannels(deps) {
|
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
98
|
const workspacePath = deps.workspaceDirs?.get(agentId) ?? "";
|
|
99
|
-
const reviewLogger = logger.child({ agentId,
|
|
99
|
+
const reviewLogger = logger.child({ agentId, submodule: "memory-review" });
|
|
100
100
|
const reviewResult = await runMemoryReview({
|
|
101
101
|
agentId,
|
|
102
102
|
tenantId: deps.tenantId ?? container.config.tenantId ?? "default",
|
|
@@ -142,6 +142,25 @@ export async function setupChannels(deps) {
|
|
|
142
142
|
// Extract session strategy from event payload (defaults: fresh, 3 turns)
|
|
143
143
|
const sessionStrategy = payload.sessionStrategy ?? "fresh";
|
|
144
144
|
const maxHistoryTurns = payload.maxHistoryTurns ?? 3;
|
|
145
|
+
// Cadence-aware cache-waste guard: rolling/accumulate strategies on long cadences
|
|
146
|
+
// guarantee cache-write waste because the prompt cache TTL is short (5 min for "cron"
|
|
147
|
+
// operations — see OPERATION_CACHE_DEFAULTS.cron in @comis/agent). Threshold = 2x TTL
|
|
148
|
+
// so we don't warn on borderline-useful 6-9 min cadences. Operator intent is preserved
|
|
149
|
+
// (no auto-downgrade) — this is informational only. Scoped to schedule.kind === "every"
|
|
150
|
+
// because cron-expression cadence is not threaded through the event payload.
|
|
151
|
+
const CRON_CACHE_TTL_2X_MS = 600_000;
|
|
152
|
+
if (sessionStrategy !== "fresh" &&
|
|
153
|
+
payload.cadenceMs !== undefined &&
|
|
154
|
+
payload.cadenceMs > CRON_CACHE_TTL_2X_MS) {
|
|
155
|
+
logger.warn({
|
|
156
|
+
jobName,
|
|
157
|
+
agentId: payload.agentId,
|
|
158
|
+
sessionStrategy,
|
|
159
|
+
cadenceMs: payload.cadenceMs,
|
|
160
|
+
hint: "Cadence exceeds cache TTL by 2x; rolling/accumulate guarantees per-tick cache-write waste. Set sessionStrategy:'fresh' unless cross-tick session memory is essential.",
|
|
161
|
+
errorKind: "config",
|
|
162
|
+
}, "Cron sessionStrategy may waste cache writes at this cadence");
|
|
163
|
+
}
|
|
145
164
|
// Resolve cron operation model via 5-level priority chain
|
|
146
165
|
const agentConfig = agents[payload.agentId];
|
|
147
166
|
let cronOverrides;
|
|
@@ -581,7 +581,7 @@ export function setupCrossSession(deps) {
|
|
|
581
581
|
maxAgeMs: 3_600_000,
|
|
582
582
|
maxEntries: 100,
|
|
583
583
|
eventBus: container.eventBus,
|
|
584
|
-
logger: deps.logger?.child({
|
|
584
|
+
logger: deps.logger?.child({ submodule: "dead-letter-queue" }),
|
|
585
585
|
});
|
|
586
586
|
// Create announcement batcher for coalescing near-simultaneous sub-agent completions
|
|
587
587
|
const announcementBatcher = createAnnouncementBatcher({
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* Queue two-phase lifecycle resolves the circular dependency between the
|
|
6
6
|
* queue and channel adapters:
|
|
7
7
|
* 1. setupDeliveryQueue() creates the adapter immediately (before setupChannels).
|
|
8
|
-
* 2.
|
|
9
|
-
*
|
|
8
|
+
* 2. drainAndStart() recovers in_flight rows, runs startup drain, then starts
|
|
9
|
+
* both the recurring drain timer and the prune timer AFTER
|
|
10
|
+
* setupChannels populates channelAdapters.
|
|
10
11
|
* Crash-Safe Delivery Queue.
|
|
11
12
|
* Session Mirroring.
|
|
12
13
|
* @module setup-delivery — Delivery subsystem wiring (queue + mirror)
|
|
@@ -18,9 +19,9 @@ import type { PluginRegistry } from "@comis/core";
|
|
|
18
19
|
export interface DeliveryQueueResult {
|
|
19
20
|
/** The delivery queue adapter (real or no-op), available immediately. */
|
|
20
21
|
deliveryQueue: DeliveryQueuePort;
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
/** Clears the prune interval
|
|
22
|
+
/** Recovers in_flight rows, runs startup drain, then starts the recurring drain + prune timers. Call AFTER setupChannels. */
|
|
23
|
+
drainAndStart: () => Promise<void>;
|
|
24
|
+
/** Clears the recurring drain interval AND the prune interval (call on shutdown). */
|
|
24
25
|
shutdown: () => void;
|
|
25
26
|
}
|
|
26
27
|
export declare function setupDeliveryQueue(deps: {
|
|
@@ -31,6 +32,14 @@ export declare function setupDeliveryQueue(deps: {
|
|
|
31
32
|
logger: ComisLogger;
|
|
32
33
|
channelAdapters: Map<string, DeliveryAdapter>;
|
|
33
34
|
}): Promise<DeliveryQueueResult>;
|
|
35
|
+
export declare function drainDeliveryQueue(deps: {
|
|
36
|
+
deliveryQueue: DeliveryQueuePort;
|
|
37
|
+
channelAdapters: Map<string, DeliveryAdapter>;
|
|
38
|
+
eventBus: TypedEventBus;
|
|
39
|
+
logger: ComisLogger;
|
|
40
|
+
drainBudgetMs: number;
|
|
41
|
+
defaultMaxAttempts: number;
|
|
42
|
+
}): Promise<void>;
|
|
34
43
|
export interface DeliveryMirrorResult {
|
|
35
44
|
/** The delivery mirror adapter (real or no-op), available immediately. */
|
|
36
45
|
deliveryMirror: DeliveryMirrorPort;
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* Queue two-phase lifecycle resolves the circular dependency between the
|
|
7
7
|
* queue and channel adapters:
|
|
8
8
|
* 1. setupDeliveryQueue() creates the adapter immediately (before setupChannels).
|
|
9
|
-
* 2.
|
|
10
|
-
*
|
|
9
|
+
* 2. drainAndStart() recovers in_flight rows, runs startup drain, then starts
|
|
10
|
+
* both the recurring drain timer and the prune timer AFTER
|
|
11
|
+
* setupChannels populates channelAdapters.
|
|
11
12
|
* Crash-Safe Delivery Queue.
|
|
12
13
|
* Session Mirroring.
|
|
13
14
|
* @module setup-delivery — Delivery subsystem wiring (queue + mirror)
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
import { createNoOpDeliveryQueue, createNoOpDeliveryMirror } from "@comis/core";
|
|
16
17
|
import { createSqliteDeliveryQueue, createSqliteDeliveryMirror } from "@comis/memory";
|
|
17
18
|
import { isPermanentError, computeQueueBackoff } from "@comis/channels";
|
|
18
|
-
import { ok } from "@comis/shared";
|
|
19
|
+
import { ok, suppressError } from "@comis/shared";
|
|
19
20
|
import { createHash } from "node:crypto";
|
|
20
21
|
// ---------------------------------------------------------------------------
|
|
21
22
|
// Setup function
|
|
@@ -28,28 +29,56 @@ export async function setupDeliveryQueue(deps) {
|
|
|
28
29
|
logger.debug("Delivery queue disabled by config");
|
|
29
30
|
return {
|
|
30
31
|
deliveryQueue: createNoOpDeliveryQueue(),
|
|
31
|
-
|
|
32
|
+
drainAndStart: async () => { },
|
|
32
33
|
shutdown: () => { },
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- db is better-sqlite3 Database; typed as unknown to avoid cross-package type dependency
|
|
36
|
-
const deliveryQueue = createSqliteDeliveryQueue(db);
|
|
37
|
+
const deliveryQueue = createSqliteDeliveryQueue(db, eventBus);
|
|
37
38
|
logger.info({ maxQueueDepth: queueConfig.maxQueueDepth, defaultMaxAttempts: queueConfig.defaultMaxAttempts }, "Delivery queue enabled");
|
|
38
39
|
let pruneInterval;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
let drainInterval;
|
|
41
|
+
// Single-tick gate: in-flight Promise prevents overlapping ticks.
|
|
42
|
+
let draining = null;
|
|
43
|
+
// Inner helper: one drain pass. Reused by startup drain AND each recurring tick.
|
|
44
|
+
const runOneDrainPass = async () => {
|
|
45
|
+
await drainDeliveryQueue({
|
|
46
|
+
deliveryQueue,
|
|
47
|
+
channelAdapters,
|
|
48
|
+
eventBus,
|
|
49
|
+
logger,
|
|
50
|
+
drainBudgetMs: queueConfig.drainBudgetMs,
|
|
51
|
+
defaultMaxAttempts: queueConfig.defaultMaxAttempts,
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
// 2. Startup drain + recurring drain timer + prune timer (deferred until channelAdapters populated)
|
|
55
|
+
const drainAndStart = async () => {
|
|
56
|
+
// --- Step 1: Recover in_flight rows. ---
|
|
57
|
+
// Runs UNCONDITIONALLY -- independent of drainOnStartup policy. An 'in_flight'
|
|
58
|
+
// row from a prior crash is a correctness bug regardless of the drain policy.
|
|
59
|
+
const recoverResult = await deliveryQueue.recoverInFlight();
|
|
60
|
+
if (!recoverResult.ok) {
|
|
61
|
+
logger.warn({ err: recoverResult.error, hint: "Could not recover in_flight rows on startup; messages may stall until next restart", errorKind: "internal" }, "Delivery queue: recoverInFlight failed");
|
|
62
|
+
}
|
|
63
|
+
else if (recoverResult.value > 0) {
|
|
64
|
+
logger.info({ recovered: recoverResult.value }, "Delivery queue: recovered in_flight rows to pending");
|
|
65
|
+
}
|
|
66
|
+
// --- Step 2: Startup drain (existing behavior, unchanged). ---
|
|
42
67
|
if (queueConfig.drainOnStartup) {
|
|
43
|
-
await
|
|
44
|
-
deliveryQueue,
|
|
45
|
-
channelAdapters,
|
|
46
|
-
eventBus,
|
|
47
|
-
logger,
|
|
48
|
-
drainBudgetMs: queueConfig.drainBudgetMs,
|
|
49
|
-
defaultMaxAttempts: queueConfig.defaultMaxAttempts,
|
|
50
|
-
});
|
|
68
|
+
await runOneDrainPass();
|
|
51
69
|
}
|
|
52
|
-
// ---
|
|
70
|
+
// --- Step 3: Recurring drain timer. ---
|
|
71
|
+
drainInterval = setInterval(() => {
|
|
72
|
+
if (draining)
|
|
73
|
+
return; // single-tick gate
|
|
74
|
+
draining = runOneDrainPass().finally(() => { draining = null; });
|
|
75
|
+
// Fire-and-forget: failures inside drainDeliveryQueue are already logged
|
|
76
|
+
// and do not propagate (it never throws). suppressError satisfies the
|
|
77
|
+
// no-floating-promise lint without altering semantics.
|
|
78
|
+
suppressError(draining, "delivery queue recurring drain tick");
|
|
79
|
+
}, queueConfig.drainIntervalMs);
|
|
80
|
+
drainInterval.unref();
|
|
81
|
+
// --- Step 4: Prune timer (existing behavior, unchanged). ---
|
|
53
82
|
pruneInterval = setInterval(async () => {
|
|
54
83
|
const result = await deliveryQueue.pruneExpired();
|
|
55
84
|
if (result.ok && result.value > 0) {
|
|
@@ -59,17 +88,21 @@ export async function setupDeliveryQueue(deps) {
|
|
|
59
88
|
pruneInterval.unref();
|
|
60
89
|
};
|
|
61
90
|
const shutdown = () => {
|
|
91
|
+
if (drainInterval) {
|
|
92
|
+
clearInterval(drainInterval);
|
|
93
|
+
drainInterval = undefined;
|
|
94
|
+
}
|
|
62
95
|
if (pruneInterval) {
|
|
63
96
|
clearInterval(pruneInterval);
|
|
64
97
|
pruneInterval = undefined;
|
|
65
98
|
}
|
|
66
99
|
};
|
|
67
|
-
return { deliveryQueue,
|
|
100
|
+
return { deliveryQueue, drainAndStart, shutdown };
|
|
68
101
|
}
|
|
69
102
|
// ---------------------------------------------------------------------------
|
|
70
103
|
// Drain implementation
|
|
71
104
|
// ---------------------------------------------------------------------------
|
|
72
|
-
async function drainDeliveryQueue(deps) {
|
|
105
|
+
export async function drainDeliveryQueue(deps) {
|
|
73
106
|
const { deliveryQueue, channelAdapters, eventBus, logger, drainBudgetMs, defaultMaxAttempts } = deps;
|
|
74
107
|
const drainStart = Date.now();
|
|
75
108
|
const deadline = drainStart + drainBudgetMs;
|
|
@@ -108,6 +108,10 @@ export async function setupSchedulers(deps) {
|
|
|
108
108
|
payloadKind: job.payload.kind,
|
|
109
109
|
sessionStrategy: job.sessionStrategy,
|
|
110
110
|
maxHistoryTurns: job.maxHistoryTurns,
|
|
111
|
+
// Cadence is a literal number only for kind === "every"; cron-expression
|
|
112
|
+
// schedules would require parsing the expression to estimate a cadence,
|
|
113
|
+
// which is out of scope. Consumers must treat undefined as "unknown".
|
|
114
|
+
cadenceMs: job.schedule.kind === "every" ? job.schedule.everyMs : undefined,
|
|
111
115
|
cronJobModel: job.payload.kind === "agent_turn" ? job.payload.model : undefined,
|
|
112
116
|
cacheRetention: job.cacheRetention,
|
|
113
117
|
toolPolicy: job.toolPolicy,
|
|
@@ -9,6 +9,8 @@ export type { RpcAdapterDeps } from "./rpc/rpc-adapters.js";
|
|
|
9
9
|
export { WsConnectionManager } from "./rpc/ws-handler.js";
|
|
10
10
|
export { createMappedWebhookEndpoint } from "./webhook/webhook-endpoint.js";
|
|
11
11
|
export { getPresetMappings } from "./webhook/webhook-presets.js";
|
|
12
|
+
export { createOAuthCallbackRoute, insertPendingFlow, PENDING_FLOW_TIMEOUT_MS, } from "./oauth/oauth-callback-route.js";
|
|
13
|
+
export type { OAuthCallbackDeps, PendingFlow, } from "./oauth/oauth-callback-route.js";
|
|
12
14
|
export { createMediaRoutes } from "./web/index.js";
|
|
13
15
|
export { createOpenaiCompletionsRoute } from "./openai/index.js";
|
|
14
16
|
export { createOpenaiModelsRoute } from "./openai/index.js";
|
|
@@ -16,6 +16,8 @@ export { WsConnectionManager } from "./rpc/ws-handler.js";
|
|
|
16
16
|
// Webhook
|
|
17
17
|
export { createMappedWebhookEndpoint } from "./webhook/webhook-endpoint.js";
|
|
18
18
|
export { getPresetMappings } from "./webhook/webhook-presets.js";
|
|
19
|
+
// OAuth callback route exports
|
|
20
|
+
export { createOAuthCallbackRoute, insertPendingFlow, PENDING_FLOW_TIMEOUT_MS, } from "./oauth/oauth-callback-route.js";
|
|
19
21
|
// Web -- media routes
|
|
20
22
|
export { createMediaRoutes } from "./web/index.js";
|
|
21
23
|
// OpenAI compatibility endpoints
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth callback route for the Comis gateway.
|
|
3
|
+
*
|
|
4
|
+
* Mounted at `GET /callback/:provider` via `app.route("/oauth", subApp)`. The
|
|
5
|
+
* handler validates code+state, looks up the state in the in-memory pending-
|
|
6
|
+
* flow map, verifies path-vs-flow provider match, deletes the entry BEFORE
|
|
7
|
+
* the token exchange (one-time-use invariant), exchanges the code at
|
|
8
|
+
* auth.openai.com/oauth/token, resolves identity via
|
|
9
|
+
* resolveCodexAuthIdentity, persists via OAuthCredentialStorePort.set, emits
|
|
10
|
+
* auth:profile_bootstrapped, and returns a static "Login Successful" HTML
|
|
11
|
+
* page (200) on success or a "Login Failed" HTML page (400/500) on failure.
|
|
12
|
+
*
|
|
13
|
+
* HTTP method is GET, NOT POST (OAuth servers always redirect with GET).
|
|
14
|
+
* Logging discipline (CLAUDE.md): submodule: "oauth-callback"
|
|
15
|
+
* on every line; NEVER log code/state/verifier/access/refresh values.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { Hono } from "hono";
|
|
20
|
+
import type { OAuthCredentialStorePort, TypedEventBus } from "@comis/core";
|
|
21
|
+
import type { GatewayLogger } from "../server/hono-server.js";
|
|
22
|
+
/** 5-minute pending-flow expiry. Exported for test parity. */
|
|
23
|
+
export declare const PENDING_FLOW_TIMEOUT_MS: number;
|
|
24
|
+
/**
|
|
25
|
+
* Pending-flow entry stored in the in-memory map keyed by `state`.
|
|
26
|
+
* Created by insertPendingFlow at flow-initiation time; consumed by the
|
|
27
|
+
* /callback/:provider handler on a successful state-match.
|
|
28
|
+
*/
|
|
29
|
+
export interface PendingFlow {
|
|
30
|
+
/** PKCE code_verifier generated at flow initiation. */
|
|
31
|
+
verifier: string;
|
|
32
|
+
/** "openai-codex" — used for path-vs-flow provider validation. */
|
|
33
|
+
provider: string;
|
|
34
|
+
/** Date.now() at insertion time. */
|
|
35
|
+
createdAt: number;
|
|
36
|
+
/**
|
|
37
|
+
* Cleanup timer reference. The handler clearTimeout(timer) on consume;
|
|
38
|
+
* the auto-expiry path (PENDING_FLOW_TIMEOUT_MS) deletes the entry.
|
|
39
|
+
*/
|
|
40
|
+
timer: ReturnType<typeof setTimeout>;
|
|
41
|
+
}
|
|
42
|
+
/** Dependencies for createOAuthCallbackRoute. */
|
|
43
|
+
export interface OAuthCallbackDeps {
|
|
44
|
+
readonly credentialStore: OAuthCredentialStorePort;
|
|
45
|
+
readonly eventBus: TypedEventBus;
|
|
46
|
+
readonly logger: GatewayLogger;
|
|
47
|
+
/** State -> PendingFlow map; mutated by handler + insertPendingFlow. */
|
|
48
|
+
readonly pendingFlows: Map<string, PendingFlow>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Seed the pending-flow map with a new state -> PendingFlow entry, scheduling
|
|
52
|
+
* a 5-minute auto-delete cleanup timer.
|
|
53
|
+
*
|
|
54
|
+
* The caller is responsible for generating `state` via crypto.randomBytes(16)
|
|
55
|
+
* — never hand-roll a PRNG.
|
|
56
|
+
*/
|
|
57
|
+
export declare function insertPendingFlow(map: Map<string, PendingFlow>, state: string, flow: Omit<PendingFlow, "timer">, logger: GatewayLogger): void;
|
|
58
|
+
/**
|
|
59
|
+
* Create the OAuth callback Hono sub-app.
|
|
60
|
+
*
|
|
61
|
+
* Mount via:
|
|
62
|
+
* const app = new Hono();
|
|
63
|
+
* app.route("/oauth", createOAuthCallbackRoute(deps));
|
|
64
|
+
* Resulting URL: GET /oauth/callback/:provider
|
|
65
|
+
*/
|
|
66
|
+
export declare function createOAuthCallbackRoute(deps: OAuthCallbackDeps): Hono;
|