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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BackgroundTasksConfig } from "@comis/core";
|
|
2
2
|
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
3
3
|
import type { BackgroundTaskManager, NotifyFn } from "./background-task-manager.js";
|
|
4
|
+
import type { BackgroundTaskOrigin } from "./background-task-types.js";
|
|
4
5
|
/**
|
|
5
6
|
* Tool definition interface matching pi-agent-core ToolDefinition.
|
|
6
7
|
*
|
|
@@ -19,9 +20,18 @@ export interface ToolDefinition {
|
|
|
19
20
|
/**
|
|
20
21
|
* Wrap a tool's execute() with auto-background promotion on timeout.
|
|
21
22
|
*
|
|
23
|
+
* `originResolver` is called synchronously at promote-time (before the agent
|
|
24
|
+
* yields) so the captured origin reflects the originating session, not the
|
|
25
|
+
* background continuation context. Returns undefined when the wrap-site cannot
|
|
26
|
+
* resolve a valid origin (e.g., during a non-session-bound subagent path) --
|
|
27
|
+
* in that case the wrapper falls through to foreground execution (no promote).
|
|
28
|
+
*
|
|
29
|
+
* Explicit threading, NOT AsyncLocalStorage. Origin flows through factory
|
|
30
|
+
* params end-to-end.
|
|
31
|
+
*
|
|
22
32
|
* If the tool is in `config.excludeTools`, returns unchanged.
|
|
23
33
|
* If the tool completes before `config.autoBackgroundMs`, returns the result directly.
|
|
24
34
|
* If the tool exceeds the timeout, promotes to background via manager.promote().
|
|
25
35
|
* If promotion fails (concurrency limit), awaits the tool normally (foreground fallback).
|
|
26
36
|
*/
|
|
27
|
-
export declare function wrapToolForAutoBackground(tool: ToolDefinition, manager: BackgroundTaskManager, config: BackgroundTasksConfig, notifyFn: NotifyFn,
|
|
37
|
+
export declare function wrapToolForAutoBackground(tool: ToolDefinition, manager: BackgroundTaskManager, config: BackgroundTasksConfig, notifyFn: NotifyFn, originResolver: () => BackgroundTaskOrigin | undefined): ToolDefinition;
|
|
@@ -12,12 +12,21 @@ import { suppressError } from "@comis/shared";
|
|
|
12
12
|
/**
|
|
13
13
|
* Wrap a tool's execute() with auto-background promotion on timeout.
|
|
14
14
|
*
|
|
15
|
+
* `originResolver` is called synchronously at promote-time (before the agent
|
|
16
|
+
* yields) so the captured origin reflects the originating session, not the
|
|
17
|
+
* background continuation context. Returns undefined when the wrap-site cannot
|
|
18
|
+
* resolve a valid origin (e.g., during a non-session-bound subagent path) --
|
|
19
|
+
* in that case the wrapper falls through to foreground execution (no promote).
|
|
20
|
+
*
|
|
21
|
+
* Explicit threading, NOT AsyncLocalStorage. Origin flows through factory
|
|
22
|
+
* params end-to-end.
|
|
23
|
+
*
|
|
15
24
|
* If the tool is in `config.excludeTools`, returns unchanged.
|
|
16
25
|
* If the tool completes before `config.autoBackgroundMs`, returns the result directly.
|
|
17
26
|
* If the tool exceeds the timeout, promotes to background via manager.promote().
|
|
18
27
|
* If promotion fails (concurrency limit), awaits the tool normally (foreground fallback).
|
|
19
28
|
*/
|
|
20
|
-
export function wrapToolForAutoBackground(tool, manager, config, notifyFn,
|
|
29
|
+
export function wrapToolForAutoBackground(tool, manager, config, notifyFn, originResolver) {
|
|
21
30
|
if (config.excludeTools.includes(tool.name)) {
|
|
22
31
|
return tool;
|
|
23
32
|
}
|
|
@@ -57,8 +66,16 @@ export function wrapToolForAutoBackground(tool, manager, config, notifyFn, agent
|
|
|
57
66
|
if (raceResult.kind === "result") {
|
|
58
67
|
return raceResult.value;
|
|
59
68
|
}
|
|
60
|
-
// Timeout:
|
|
61
|
-
|
|
69
|
+
// Timeout: resolve origin synchronously before yielding to the background.
|
|
70
|
+
// Explicit threading, NOT AsyncLocalStorage.
|
|
71
|
+
const origin = originResolver();
|
|
72
|
+
if (!origin) {
|
|
73
|
+
// No originating session context (e.g., wrap-site is a subagent without
|
|
74
|
+
// a captured caller session). Treat like a concurrency-limit fallback:
|
|
75
|
+
// run the tool in the foreground, no background promotion.
|
|
76
|
+
return await taskPromise;
|
|
77
|
+
}
|
|
78
|
+
const promoteResult = manager.promote(tool.name, taskPromise, ac, origin);
|
|
62
79
|
if (!promoteResult.ok) {
|
|
63
80
|
// Concurrency limit hit: fall back to foreground (await normally)
|
|
64
81
|
return await taskPromise;
|
|
@@ -73,7 +90,7 @@ export function wrapToolForAutoBackground(tool, manager, config, notifyFn, agent
|
|
|
73
90
|
// collapses to `content: undefined` and triggers the silent-LLM-failure
|
|
74
91
|
// cascade (see AGENTS.md / auto-background-middleware.test.ts invariant).
|
|
75
92
|
const placeholderText = `Tool "${tool.name}" is taking longer than expected and has been moved to the background. ` +
|
|
76
|
-
`Task ID: ${taskId}.
|
|
93
|
+
`Task ID: ${taskId}. I'll continue when it completes.`;
|
|
77
94
|
return {
|
|
78
95
|
content: [{ type: "text", text: placeholderText }],
|
|
79
96
|
details: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Result } from "@comis/shared";
|
|
2
2
|
import type { TypedEventBus } from "@comis/core";
|
|
3
|
-
import type { BackgroundTask } from "./background-task-types.js";
|
|
3
|
+
import type { BackgroundTask, BackgroundTaskOrigin } from "./background-task-types.js";
|
|
4
4
|
/** Notification callback fired when background task completes or fails. */
|
|
5
5
|
export type NotifyFn = (opts: {
|
|
6
6
|
agentId: string;
|
|
@@ -21,7 +21,7 @@ export interface BackgroundTaskManagerOpts {
|
|
|
21
21
|
maxBackgroundDurationMs?: number;
|
|
22
22
|
}
|
|
23
23
|
export interface BackgroundTaskManager {
|
|
24
|
-
promote(
|
|
24
|
+
promote(toolName: string, promise: Promise<unknown>, ac: AbortController, origin: BackgroundTaskOrigin): Result<string, Error>;
|
|
25
25
|
complete(taskId: string, result: unknown, notifyFn?: NotifyFn): void;
|
|
26
26
|
fail(taskId: string, error: unknown, notifyFn?: NotifyFn): void;
|
|
27
27
|
cancel(taskId: string): Result<void, Error>;
|
|
@@ -35,7 +35,26 @@ export function createBackgroundTaskManager(opts) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
const manager = {
|
|
38
|
-
promote(
|
|
38
|
+
promote(toolName, promise, ac, origin) {
|
|
39
|
+
// Reject calls with missing/invalid origin (no silent fallback).
|
|
40
|
+
if (!origin || typeof origin !== "object") {
|
|
41
|
+
return err(new Error("BackgroundTaskOrigin is required (received undefined or non-object)"));
|
|
42
|
+
}
|
|
43
|
+
if (!origin.agentId || origin.agentId.length === 0) {
|
|
44
|
+
return err(new Error("BackgroundTaskOrigin.agentId must be a non-empty string"));
|
|
45
|
+
}
|
|
46
|
+
if (!origin.sessionKey || origin.sessionKey.length === 0) {
|
|
47
|
+
return err(new Error("BackgroundTaskOrigin.sessionKey must be a non-empty string"));
|
|
48
|
+
}
|
|
49
|
+
if (!origin.channelType || origin.channelType.length === 0) {
|
|
50
|
+
return err(new Error("BackgroundTaskOrigin.channelType must be a non-empty string"));
|
|
51
|
+
}
|
|
52
|
+
if (!origin.channelId || origin.channelId.length === 0) {
|
|
53
|
+
return err(new Error("BackgroundTaskOrigin.channelId must be a non-empty string"));
|
|
54
|
+
}
|
|
55
|
+
// traceId may be null (per BackgroundTaskOriginSchema), so no length check.
|
|
56
|
+
// backgroundHopCount has a schema-level default of 0; no inline guard needed.
|
|
57
|
+
const agentId = origin.agentId;
|
|
39
58
|
const agentCurrent = perAgentCount.get(agentId) ?? 0;
|
|
40
59
|
if (agentCurrent >= maxPerAgent) {
|
|
41
60
|
return err(new Error(`Concurrency limit exceeded: agent ${agentId} has ${agentCurrent}/${maxPerAgent} tasks`));
|
|
@@ -46,24 +65,25 @@ export function createBackgroundTaskManager(opts) {
|
|
|
46
65
|
const taskId = randomUUID();
|
|
47
66
|
const task = {
|
|
48
67
|
id: taskId,
|
|
49
|
-
agentId,
|
|
50
68
|
toolName,
|
|
51
69
|
status: "running",
|
|
52
70
|
startedAt: Date.now(),
|
|
71
|
+
origin,
|
|
53
72
|
_promise: promise,
|
|
54
73
|
_abortController: ac,
|
|
55
74
|
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// sync write BEFORE returning placeholder
|
|
59
|
-
persistTaskSync(dataDir, task);
|
|
60
|
-
// Hard timeout
|
|
61
|
-
task._hardTimeoutTimer = setTimeout(() => {
|
|
75
|
+
// Hard-timeout abort
|
|
76
|
+
const timer = setTimeout(() => {
|
|
62
77
|
if (task.status === "running") {
|
|
63
78
|
ac.abort();
|
|
64
79
|
manager.fail(taskId, new Error("Hard timeout exceeded"));
|
|
65
80
|
}
|
|
66
81
|
}, maxBackgroundDurationMs);
|
|
82
|
+
timer.unref();
|
|
83
|
+
task._hardTimeoutTimer = timer;
|
|
84
|
+
tasks.set(taskId, task);
|
|
85
|
+
incrementCounters(agentId);
|
|
86
|
+
persistTaskSync(dataDir, task);
|
|
67
87
|
eventBus.emit("background_task:promoted", {
|
|
68
88
|
agentId,
|
|
69
89
|
taskId,
|
|
@@ -81,19 +101,20 @@ export function createBackgroundTaskManager(opts) {
|
|
|
81
101
|
task.result = truncateResult(result);
|
|
82
102
|
if (task._hardTimeoutTimer)
|
|
83
103
|
clearTimeout(task._hardTimeoutTimer);
|
|
84
|
-
decrementCounters(task.agentId);
|
|
104
|
+
decrementCounters(task.origin.agentId);
|
|
85
105
|
persistTaskSync(dataDir, task);
|
|
86
106
|
const durationMs = task.completedAt - task.startedAt;
|
|
87
107
|
eventBus.emit("background_task:completed", {
|
|
88
|
-
agentId: task.agentId,
|
|
108
|
+
agentId: task.origin.agentId,
|
|
89
109
|
taskId,
|
|
90
110
|
toolName: task.toolName,
|
|
91
111
|
durationMs,
|
|
112
|
+
origin: task.origin,
|
|
92
113
|
timestamp: Date.now(),
|
|
93
114
|
});
|
|
94
115
|
if (notifyFn) {
|
|
95
116
|
suppressError(notifyFn({
|
|
96
|
-
agentId: task.agentId,
|
|
117
|
+
agentId: task.origin.agentId,
|
|
97
118
|
message: `Background task "${task.toolName}" completed (${Math.round(durationMs / 1000)}s). Task ID: ${taskId}`,
|
|
98
119
|
priority: "normal",
|
|
99
120
|
origin: "background_task",
|
|
@@ -109,20 +130,21 @@ export function createBackgroundTaskManager(opts) {
|
|
|
109
130
|
task.error = error instanceof Error ? error.message : String(error);
|
|
110
131
|
if (task._hardTimeoutTimer)
|
|
111
132
|
clearTimeout(task._hardTimeoutTimer);
|
|
112
|
-
decrementCounters(task.agentId);
|
|
133
|
+
decrementCounters(task.origin.agentId);
|
|
113
134
|
persistTaskSync(dataDir, task);
|
|
114
135
|
const durationMs = task.completedAt - task.startedAt;
|
|
115
136
|
eventBus.emit("background_task:failed", {
|
|
116
|
-
agentId: task.agentId,
|
|
137
|
+
agentId: task.origin.agentId,
|
|
117
138
|
taskId,
|
|
118
139
|
toolName: task.toolName,
|
|
119
140
|
error: task.error,
|
|
120
141
|
durationMs,
|
|
142
|
+
origin: task.origin,
|
|
121
143
|
timestamp: Date.now(),
|
|
122
144
|
});
|
|
123
145
|
if (notifyFn) {
|
|
124
146
|
suppressError(notifyFn({
|
|
125
|
-
agentId: task.agentId,
|
|
147
|
+
agentId: task.origin.agentId,
|
|
126
148
|
message: `Background task "${task.toolName}" failed: ${task.error}. Task ID: ${taskId}`,
|
|
127
149
|
priority: "normal",
|
|
128
150
|
origin: "background_task",
|
|
@@ -141,10 +163,10 @@ export function createBackgroundTaskManager(opts) {
|
|
|
141
163
|
task._abortController.abort();
|
|
142
164
|
if (task._hardTimeoutTimer)
|
|
143
165
|
clearTimeout(task._hardTimeoutTimer);
|
|
144
|
-
decrementCounters(task.agentId);
|
|
166
|
+
decrementCounters(task.origin.agentId);
|
|
145
167
|
persistTaskSync(dataDir, task);
|
|
146
168
|
eventBus.emit("background_task:cancelled", {
|
|
147
|
-
agentId: task.agentId,
|
|
169
|
+
agentId: task.origin.agentId,
|
|
148
170
|
taskId,
|
|
149
171
|
toolName: task.toolName,
|
|
150
172
|
timestamp: Date.now(),
|
|
@@ -155,7 +177,7 @@ export function createBackgroundTaskManager(opts) {
|
|
|
155
177
|
return tasks.get(taskId);
|
|
156
178
|
},
|
|
157
179
|
getTasks(agentId) {
|
|
158
|
-
return [...tasks.values()].filter((t) => t.agentId === agentId);
|
|
180
|
+
return [...tasks.values()].filter((t) => t.origin.agentId === agentId);
|
|
159
181
|
},
|
|
160
182
|
getAllTasks() {
|
|
161
183
|
return [...tasks.values()];
|
|
@@ -163,8 +185,19 @@ export function createBackgroundTaskManager(opts) {
|
|
|
163
185
|
recoverOnStartup() {
|
|
164
186
|
const recovered = recoverTasks(dataDir);
|
|
165
187
|
let count = 0;
|
|
188
|
+
let skipped = 0;
|
|
166
189
|
for (const persisted of recovered) {
|
|
167
|
-
|
|
190
|
+
if (!persisted.origin || typeof persisted.origin !== "object" || !persisted.origin.agentId || !persisted.origin.sessionKey) {
|
|
191
|
+
// Legacy file without origin. Skip with a warning -- the file
|
|
192
|
+
// remains on disk for audit, but the manager doesn't import it.
|
|
193
|
+
skipped++;
|
|
194
|
+
logger.warn({
|
|
195
|
+
taskId: persisted.id,
|
|
196
|
+
hint: "Legacy task file lacks origin; skipping recovery -- delete the file or wait for cleanup",
|
|
197
|
+
errorKind: "internal",
|
|
198
|
+
}, "Skipping recovered task without origin");
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
168
201
|
const task = {
|
|
169
202
|
...persisted,
|
|
170
203
|
};
|
|
@@ -172,11 +205,12 @@ export function createBackgroundTaskManager(opts) {
|
|
|
172
205
|
if (persisted.status === "failed" && persisted.error === "Daemon restarted while task was running") {
|
|
173
206
|
count++;
|
|
174
207
|
eventBus.emit("background_task:failed", {
|
|
175
|
-
agentId: task.agentId,
|
|
208
|
+
agentId: task.origin.agentId,
|
|
176
209
|
taskId: task.id,
|
|
177
210
|
toolName: task.toolName,
|
|
178
211
|
error: persisted.error,
|
|
179
212
|
durationMs: (persisted.completedAt ?? Date.now()) - persisted.startedAt,
|
|
213
|
+
origin: task.origin,
|
|
180
214
|
timestamp: Date.now(),
|
|
181
215
|
});
|
|
182
216
|
}
|
|
@@ -184,13 +218,20 @@ export function createBackgroundTaskManager(opts) {
|
|
|
184
218
|
if (count > 0) {
|
|
185
219
|
logger.info({ count }, "Recovered background tasks marked as failed");
|
|
186
220
|
}
|
|
221
|
+
if (skipped > 0) {
|
|
222
|
+
logger.warn({
|
|
223
|
+
skipped,
|
|
224
|
+
hint: "Legacy task files cannot be recovered without origin -- they remain on disk for audit",
|
|
225
|
+
errorKind: "internal",
|
|
226
|
+
}, "Skipped legacy task files during recovery");
|
|
227
|
+
}
|
|
187
228
|
},
|
|
188
229
|
cleanup(maxAgeMs = 86_400_000) {
|
|
189
230
|
const cutoff = Date.now() - maxAgeMs;
|
|
190
231
|
for (const [taskId, task] of tasks) {
|
|
191
232
|
if (task.status !== "running" && (task.completedAt ?? task.startedAt) < cutoff) {
|
|
192
233
|
tasks.delete(taskId);
|
|
193
|
-
removeTaskFile(dataDir, task.agentId, taskId);
|
|
234
|
+
removeTaskFile(dataDir, task.origin.agentId, taskId);
|
|
194
235
|
}
|
|
195
236
|
}
|
|
196
237
|
},
|
|
@@ -17,13 +17,13 @@ export const TASK_DIR_NAME = "background-tasks";
|
|
|
17
17
|
function toPersistedState(task) {
|
|
18
18
|
return {
|
|
19
19
|
id: task.id,
|
|
20
|
-
agentId: task.agentId,
|
|
21
20
|
toolName: task.toolName,
|
|
22
21
|
status: task.status,
|
|
23
22
|
startedAt: task.startedAt,
|
|
24
23
|
completedAt: task.completedAt,
|
|
25
24
|
result: task.result,
|
|
26
25
|
error: task.error,
|
|
26
|
+
origin: task.origin,
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
@@ -32,7 +32,7 @@ function toPersistedState(task) {
|
|
|
32
32
|
* Writes to `dataDir/{agentId}/{taskId}.json`.
|
|
33
33
|
*/
|
|
34
34
|
export function persistTaskSync(dataDir, task) {
|
|
35
|
-
const agentDir = safePath(dataDir, task.agentId);
|
|
35
|
+
const agentDir = safePath(dataDir, task.origin.agentId);
|
|
36
36
|
mkdirSync(agentDir, { recursive: true });
|
|
37
37
|
const filePath = safePath(agentDir, `${task.id}.json`);
|
|
38
38
|
const state = "_promise" in task ? toPersistedState(task) : task;
|
|
@@ -85,7 +85,14 @@ export function recoverTasks(dataDir) {
|
|
|
85
85
|
const filePath = safePath(agentDir, file);
|
|
86
86
|
try {
|
|
87
87
|
const raw = readFileSync(filePath, "utf-8");
|
|
88
|
-
const
|
|
88
|
+
const parsed = JSON.parse(raw);
|
|
89
|
+
// Sanity guard: skip completely malformed files (no id or toolName).
|
|
90
|
+
// Files missing origin (pre-Phase-14) are passed through to the manager
|
|
91
|
+
// so recoverOnStartup can warn about them and track the skip count.
|
|
92
|
+
if (!parsed.id || !parsed.toolName) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const task = parsed;
|
|
89
96
|
if (task.status === "running") {
|
|
90
97
|
task.status = "failed";
|
|
91
98
|
task.error = "Daemon restarted while task was running";
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Background task
|
|
2
|
+
* Background task type definitions.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
import type { BackgroundTaskOrigin } from "@comis/core";
|
|
7
|
+
export type { BackgroundTaskOrigin };
|
|
6
8
|
export type BackgroundTaskStatus = "running" | "completed" | "failed" | "cancelled";
|
|
7
9
|
export interface BackgroundTask {
|
|
8
10
|
id: string;
|
|
9
|
-
agentId: string;
|
|
10
11
|
toolName: string;
|
|
11
12
|
status: BackgroundTaskStatus;
|
|
12
13
|
startedAt: number;
|
|
13
14
|
completedAt?: number;
|
|
14
15
|
result?: string;
|
|
15
16
|
error?: string;
|
|
17
|
+
/** Originating session attribution (incl. backgroundHopCount) -- captured at
|
|
18
|
+
* promote-time, persisted on disk, preserved across recoverOnStartup.
|
|
19
|
+
* Required (no silent fallback). */
|
|
20
|
+
origin: BackgroundTaskOrigin;
|
|
16
21
|
_promise?: Promise<unknown>;
|
|
17
22
|
_abortController?: AbortController;
|
|
18
23
|
_hardTimeoutTimer?: ReturnType<typeof setTimeout>;
|
|
@@ -20,11 +25,13 @@ export interface BackgroundTask {
|
|
|
20
25
|
/** Serializable subset of BackgroundTask for file persistence. */
|
|
21
26
|
export interface PersistedTaskState {
|
|
22
27
|
id: string;
|
|
23
|
-
agentId: string;
|
|
24
28
|
toolName: string;
|
|
25
29
|
status: BackgroundTaskStatus;
|
|
26
30
|
startedAt: number;
|
|
27
31
|
completedAt?: number;
|
|
28
32
|
result?: string;
|
|
29
33
|
error?: string;
|
|
34
|
+
/** Persisted origin -- read back by recoverOnStartup so completion routing
|
|
35
|
+
* survives daemon restarts. */
|
|
36
|
+
origin: BackgroundTaskOrigin;
|
|
30
37
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background completion formatter: transforms a BackgroundTask into a
|
|
3
|
+
* tagged announcement string ready for injection into the originating
|
|
4
|
+
* agent's session as a synthetic NormalizedMessage.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors the shape of packages/agent/src/spawn/narrative-caster.ts (the
|
|
7
|
+
* sub-agent announcement formatter). Simplified: no condensation levels,
|
|
8
|
+
* no metadata stats, no labels -- just a single tool result with
|
|
9
|
+
* toolName + result/error.
|
|
10
|
+
*
|
|
11
|
+
* The trailing instruction is byte-identical to TRAILING_INSTRUCTION in
|
|
12
|
+
* narrative-caster.ts so AnnouncementBatcher.stripSystemPrefix()
|
|
13
|
+
* (announcement-batcher.ts:81-85) keeps working unchanged.
|
|
14
|
+
*
|
|
15
|
+
* Pure synchronous string formatting -- no async, no LLM calls, no I/O.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import type { BackgroundTask } from "./background-task-types.js";
|
|
20
|
+
/** Re-export so consumers (tests, completion runner) can assert byte-identity. */
|
|
21
|
+
export { TRAILING_INSTRUCTION } from "../spawn/narrative-caster.js";
|
|
22
|
+
/**
|
|
23
|
+
* Format a BackgroundTask completion or failure into a tagged announcement.
|
|
24
|
+
*
|
|
25
|
+
* Header forms:
|
|
26
|
+
* - success: `[Background Task: ${toolName}]`
|
|
27
|
+
* - failure: `[Background Task Failed: ${toolName}]`
|
|
28
|
+
*
|
|
29
|
+
* Body:
|
|
30
|
+
* - success: `task.result` (already capped at 100 KB by manager.truncateResult).
|
|
31
|
+
* - generic failure: `task.error`.
|
|
32
|
+
* - restart-recovery failure (`task.error === "Daemon restarted while task was running"`):
|
|
33
|
+
* uses the explicit recovery copy.
|
|
34
|
+
*
|
|
35
|
+
* Total-length cap: NormalizedMessageSchema.text limits at 32768 chars.
|
|
36
|
+
* If the assembled string would exceed the cap, only the body section is
|
|
37
|
+
* truncated; the header and trailing instruction are NEVER touched.
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatCompletionAnnouncement(task: BackgroundTask): string;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Background completion formatter: transforms a BackgroundTask into a
|
|
4
|
+
* tagged announcement string ready for injection into the originating
|
|
5
|
+
* agent's session as a synthetic NormalizedMessage.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors the shape of packages/agent/src/spawn/narrative-caster.ts (the
|
|
8
|
+
* sub-agent announcement formatter). Simplified: no condensation levels,
|
|
9
|
+
* no metadata stats, no labels -- just a single tool result with
|
|
10
|
+
* toolName + result/error.
|
|
11
|
+
*
|
|
12
|
+
* The trailing instruction is byte-identical to TRAILING_INSTRUCTION in
|
|
13
|
+
* narrative-caster.ts so AnnouncementBatcher.stripSystemPrefix()
|
|
14
|
+
* (announcement-batcher.ts:81-85) keeps working unchanged.
|
|
15
|
+
*
|
|
16
|
+
* Pure synchronous string formatting -- no async, no LLM calls, no I/O.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import { TRAILING_INSTRUCTION } from "../spawn/narrative-caster.js";
|
|
21
|
+
/** Re-export so consumers (tests, completion runner) can assert byte-identity. */
|
|
22
|
+
export { TRAILING_INSTRUCTION } from "../spawn/narrative-caster.js";
|
|
23
|
+
/** NormalizedMessageSchema.text caps at 32768 chars. Reserve headroom for header + trailing instruction. */
|
|
24
|
+
const MAX_ANNOUNCEMENT_CHARS = 32768;
|
|
25
|
+
const TRUNCATION_MARKER = "\n…[truncated]";
|
|
26
|
+
/** Recovery announcement body for tasks failed via recoverOnStartup. */
|
|
27
|
+
const RESTART_RECOVERY_BODY = "This background task was interrupted by a daemon restart. The result is unavailable; let the user know if relevant.";
|
|
28
|
+
const RESTART_RECOVERY_ERROR = "Daemon restarted while task was running";
|
|
29
|
+
/**
|
|
30
|
+
* Format a BackgroundTask completion or failure into a tagged announcement.
|
|
31
|
+
*
|
|
32
|
+
* Header forms:
|
|
33
|
+
* - success: `[Background Task: ${toolName}]`
|
|
34
|
+
* - failure: `[Background Task Failed: ${toolName}]`
|
|
35
|
+
*
|
|
36
|
+
* Body:
|
|
37
|
+
* - success: `task.result` (already capped at 100 KB by manager.truncateResult).
|
|
38
|
+
* - generic failure: `task.error`.
|
|
39
|
+
* - restart-recovery failure (`task.error === "Daemon restarted while task was running"`):
|
|
40
|
+
* uses the explicit recovery copy.
|
|
41
|
+
*
|
|
42
|
+
* Total-length cap: NormalizedMessageSchema.text limits at 32768 chars.
|
|
43
|
+
* If the assembled string would exceed the cap, only the body section is
|
|
44
|
+
* truncated; the header and trailing instruction are NEVER touched.
|
|
45
|
+
*/
|
|
46
|
+
export function formatCompletionAnnouncement(task) {
|
|
47
|
+
const isFailure = task.status === "failed" || task.status === "cancelled";
|
|
48
|
+
const headerPrefix = isFailure ? "Background Task Failed" : "Background Task";
|
|
49
|
+
const header = `[${headerPrefix}: ${task.toolName}]`;
|
|
50
|
+
let body;
|
|
51
|
+
if (isFailure) {
|
|
52
|
+
const rawError = task.error ?? "(no error message)";
|
|
53
|
+
body = rawError === RESTART_RECOVERY_ERROR ? RESTART_RECOVERY_BODY : rawError;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
body = task.result ?? "(no result)";
|
|
57
|
+
}
|
|
58
|
+
// Build assembled string: header, blank line, body, blank line, trailing instruction.
|
|
59
|
+
const sections = [];
|
|
60
|
+
sections.push(header);
|
|
61
|
+
sections.push("");
|
|
62
|
+
sections.push(body);
|
|
63
|
+
sections.push("");
|
|
64
|
+
sections.push(TRAILING_INSTRUCTION);
|
|
65
|
+
let assembled = sections.join("\n");
|
|
66
|
+
// Enforce NormalizedMessageSchema.text.max(32768). Truncate the body section
|
|
67
|
+
// ONLY if needed; header and trailing instruction are byte-identical guarantees.
|
|
68
|
+
if (assembled.length > MAX_ANNOUNCEMENT_CHARS) {
|
|
69
|
+
const headerSection = `${header}\n\n`;
|
|
70
|
+
const tailSection = `\n\n${TRAILING_INSTRUCTION}`;
|
|
71
|
+
const reservedChars = headerSection.length + tailSection.length + TRUNCATION_MARKER.length;
|
|
72
|
+
const allowedBodyChars = MAX_ANNOUNCEMENT_CHARS - reservedChars;
|
|
73
|
+
const truncatedBody = body.slice(0, Math.max(0, allowedBodyChars)) + TRUNCATION_MARKER;
|
|
74
|
+
assembled = headerSection + truncatedBody + tailSection;
|
|
75
|
+
}
|
|
76
|
+
return assembled;
|
|
77
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background completion runner: subscribes to background_task:completed and
|
|
3
|
+
* background_task:failed events from the TypedEventBus and re-enters the
|
|
4
|
+
* originating agent session with a formatted completion announcement.
|
|
5
|
+
*
|
|
6
|
+
* Per-session lock serialization is delegated to the existing session
|
|
7
|
+
* manager (ComisSessionManager.withSession in packages/agent/src/session/).
|
|
8
|
+
* The runner does NOT introduce its own queueing -- one turn per completion
|
|
9
|
+
* event, ordering follows the existing per-session lock.
|
|
10
|
+
*
|
|
11
|
+
* Recursion bound: per-task incoming hop count + 1 must stay below
|
|
12
|
+
* `maxBackgroundHops` (default 3). When the cap is hit, the runner emits
|
|
13
|
+
* the fallback notification instead of triggering executor.execute().
|
|
14
|
+
* The hop count is read from `task.origin.backgroundHopCount`
|
|
15
|
+
* (populated by the originResolver).
|
|
16
|
+
*
|
|
17
|
+
* Latency-instrumentation hook: emits `background_task:reentered`
|
|
18
|
+
* immediately before executor.execute(). Integration tests compute the delta
|
|
19
|
+
* from `background_task:completed.timestamp` to this event for SLO tracking.
|
|
20
|
+
*
|
|
21
|
+
* Failure isolation: each handler is wrapped in suppressError so a single
|
|
22
|
+
* completion's failure does not tear down the subscription (AGENTS §2.1).
|
|
23
|
+
*
|
|
24
|
+
* @module
|
|
25
|
+
*/
|
|
26
|
+
import type { TypedEventBus } from "@comis/core";
|
|
27
|
+
import type { ComisLogger } from "@comis/infra";
|
|
28
|
+
import type { AgentExecutor } from "../executor/types.js";
|
|
29
|
+
import type { BackgroundTaskManager, NotifyFn } from "./background-task-manager.js";
|
|
30
|
+
/** Public-facing handle on the runner returned by createBackgroundCompletionRunner. */
|
|
31
|
+
export interface BackgroundCompletionRunner {
|
|
32
|
+
/** Unsubscribe from the event bus. Idempotent. Awaitable so callers can
|
|
33
|
+
* ensure no in-flight handler outlives the daemon shutdown. */
|
|
34
|
+
shutdown(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/** Minimal session-store contract the runner needs (fallback gate). */
|
|
37
|
+
export interface RunnerSessionStore {
|
|
38
|
+
loadByFormattedKey(sessionKey: string): unknown | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface BackgroundCompletionRunnerDeps {
|
|
41
|
+
eventBus: TypedEventBus;
|
|
42
|
+
getExecutor: (agentId: string) => AgentExecutor;
|
|
43
|
+
sessionStore: RunnerSessionStore;
|
|
44
|
+
taskManager: Pick<BackgroundTaskManager, "getTask">;
|
|
45
|
+
fallbackNotifyFn: NotifyFn;
|
|
46
|
+
maxBackgroundHops: number;
|
|
47
|
+
logger: ComisLogger;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Wire the completion runner against an event bus + executor + session store.
|
|
51
|
+
* Subscriptions are installed synchronously; call shutdown() to remove them.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createBackgroundCompletionRunner(deps: BackgroundCompletionRunnerDeps): BackgroundCompletionRunner;
|