comisai 1.0.34 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +30 -4
- package/node_modules/@comis/agent/dist/background/background-task-manager.d.ts +22 -2
- package/node_modules/@comis/agent/dist/background/background-task-manager.js +88 -40
- package/node_modules/@comis/agent/dist/background/background-task-persistence.js +34 -4
- package/node_modules/@comis/agent/dist/background/background-task-types.d.ts +59 -3
- package/node_modules/@comis/agent/dist/background/background-task-types.js +1 -1
- package/node_modules/@comis/agent/dist/background/completion-dispatcher.d.ts +130 -0
- package/node_modules/@comis/agent/dist/background/completion-dispatcher.js +215 -0
- 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 +62 -0
- package/node_modules/@comis/agent/dist/background/completion-runner.js +234 -0
- package/node_modules/@comis/agent/dist/background/index.d.ts +10 -1
- package/node_modules/@comis/agent/dist/background/index.js +4 -0
- package/node_modules/@comis/agent/dist/background/session-resolver.d.ts +85 -0
- package/node_modules/@comis/agent/dist/background/session-resolver.js +78 -0
- package/node_modules/@comis/agent/dist/bootstrap/sections/messaging-sections.js +1 -0
- package/node_modules/@comis/agent/dist/bootstrap/sections/tool-descriptions.js +3 -3
- package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.d.ts +30 -2
- package/node_modules/@comis/agent/dist/bootstrap/sections/tooling-sections.js +51 -2
- package/node_modules/@comis/agent/dist/bootstrap/system-prompt-assembler.d.ts +22 -0
- package/node_modules/@comis/agent/dist/bootstrap/system-prompt-assembler.js +2 -2
- package/node_modules/@comis/agent/dist/bridge/bridge-event-handlers.d.ts +1 -5
- package/node_modules/@comis/agent/dist/bridge/bridge-event-handlers.js +2 -14
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +43 -2
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +17 -2
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +32 -23
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +145 -62
- 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/signature-surrogate-guard.d.ts +10 -10
- package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.js +14 -14
- package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.d.ts +11 -13
- package/node_modules/@comis/agent/dist/context-engine/thinking-block-cleaner.js +14 -15
- 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/capability-index-context.d.ts +72 -0
- package/node_modules/@comis/agent/dist/executor/capability-index-context.js +329 -0
- package/node_modules/@comis/agent/dist/executor/drain-helper.d.ts +122 -0
- package/node_modules/@comis/agent/dist/executor/drain-helper.js +173 -0
- package/node_modules/@comis/agent/dist/executor/error-classifier.js +2 -2
- 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 +78 -4
- package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +150 -31
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.d.ts +7 -0
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +26 -5
- 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.d.ts +18 -1
- package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +20 -18
- 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/jit-guide-injector.d.ts +11 -2
- package/node_modules/@comis/agent/dist/executor/jit-guide-injector.js +16 -2
- 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 +21 -2
- package/node_modules/@comis/agent/dist/executor/pi-executor.js +96 -18
- package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +7 -7
- package/node_modules/@comis/agent/dist/executor/prompt-assembly.d.ts +9 -1
- package/node_modules/@comis/agent/dist/executor/prompt-assembly.js +15 -1
- 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 +18 -27
- package/node_modules/@comis/agent/dist/executor/tool-deferral.js +34 -43
- 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/model-registry-adapter.js +1 -1
- package/node_modules/@comis/agent/dist/model/model-scanner.js +1 -1
- 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/safety/tool-retry-breaker.d.ts +11 -1
- package/node_modules/@comis/agent/dist/safety/tool-retry-breaker.js +19 -22
- package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +17 -3
- 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/dist/spawn/pi-mono-adapters.d.ts +1 -1
- package/node_modules/@comis/agent/dist/spawn/pi-mono-adapters.js +5 -5
- package/node_modules/@comis/agent/dist/workspace/data-env.d.ts +38 -0
- package/node_modules/@comis/agent/dist/workspace/data-env.js +56 -0
- package/node_modules/@comis/agent/dist/workspace/index.d.ts +1 -0
- package/node_modules/@comis/agent/dist/workspace/index.js +1 -0
- package/node_modules/@comis/agent/dist/workspace/templates.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/index.d.ts +1 -1
- package/node_modules/@comis/channels/dist/index.js +1 -1
- package/node_modules/@comis/channels/dist/shared/channel-manager.d.ts +9 -3
- package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +12 -10
- package/node_modules/@comis/channels/dist/shared/inbound-gate.d.ts +1 -1
- package/node_modules/@comis/channels/dist/shared/inbound-gate.js +22 -7
- package/node_modules/@comis/channels/dist/shared/inbound-pipeline.d.ts +10 -3
- package/node_modules/@comis/channels/dist/shared/inbound-route.d.ts +1 -1
- package/node_modules/@comis/channels/dist/shared/inbound-route.js +13 -2
- package/node_modules/@comis/channels/dist/shared/response-filter.d.ts +11 -24
- package/node_modules/@comis/channels/dist/shared/response-filter.js +25 -53
- 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/commands/providers.d.ts +1 -2
- package/node_modules/@comis/cli/dist/commands/providers.js +5 -6
- 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/field-metadata.js +2 -0
- package/node_modules/@comis/core/dist/config/immutable-keys.js +4 -1
- package/node_modules/@comis/core/dist/config/index.d.ts +7 -1
- package/node_modules/@comis/core/dist/config/index.js +4 -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 -792
- package/node_modules/@comis/core/dist/config/schema-agent.js +16 -1
- package/node_modules/@comis/core/dist/config/schema-approvals.d.ts +0 -14
- package/node_modules/@comis/core/dist/config/schema-auto-reply-engine.d.ts +0 -6
- package/node_modules/@comis/core/dist/config/schema-background-tasks.d.ts +1 -6
- package/node_modules/@comis/core/dist/config/schema-background-tasks.js +7 -0
- package/node_modules/@comis/core/dist/config/schema-browser.d.ts +0 -18
- package/node_modules/@comis/core/dist/config/schema-channel.d.ts +0 -158
- package/node_modules/@comis/core/dist/config/schema-coalescer.d.ts +0 -5
- package/node_modules/@comis/core/dist/config/schema-daemon.d.ts +0 -32
- package/node_modules/@comis/core/dist/config/schema-delivery.d.ts +1 -17
- package/node_modules/@comis/core/dist/config/schema-delivery.js +2 -0
- package/node_modules/@comis/core/dist/config/schema-documentation.d.ts +0 -12
- package/node_modules/@comis/core/dist/config/schema-embedding.d.ts +0 -20
- package/node_modules/@comis/core/dist/config/schema-envelope.d.ts +0 -15
- package/node_modules/@comis/core/dist/config/schema-gateway.d.ts +0 -37
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.d.ts +0 -4
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.js +0 -2
- package/node_modules/@comis/core/dist/config/schema-integrations.d.ts +0 -318
- package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.d.ts +0 -18
- package/node_modules/@comis/core/dist/config/schema-memory-review.d.ts +0 -7
- package/node_modules/@comis/core/dist/config/schema-memory.d.ts +0 -16
- package/node_modules/@comis/core/dist/config/schema-messages.d.ts +0 -8
- package/node_modules/@comis/core/dist/config/schema-models.d.ts +0 -15
- package/node_modules/@comis/core/dist/config/schema-notification.d.ts +0 -5
- package/node_modules/@comis/core/dist/config/schema-oauth.d.ts +18 -0
- package/node_modules/@comis/core/dist/config/schema-oauth.js +19 -0
- package/node_modules/@comis/core/dist/config/schema-observability.d.ts +0 -38
- package/node_modules/@comis/core/dist/config/schema-output-retention.d.ts +34 -0
- package/node_modules/@comis/core/dist/config/schema-output-retention.js +48 -0
- package/node_modules/@comis/core/dist/config/schema-plugins.d.ts +0 -8
- package/node_modules/@comis/core/dist/config/schema-providers.d.ts +0 -64
- package/node_modules/@comis/core/dist/config/schema-queue.d.ts +0 -58
- package/node_modules/@comis/core/dist/config/schema-response-prefix.d.ts +0 -2
- package/node_modules/@comis/core/dist/config/schema-retry.d.ts +0 -6
- package/node_modules/@comis/core/dist/config/schema-scheduler.d.ts +0 -39
- package/node_modules/@comis/core/dist/config/schema-secrets.d.ts +0 -3
- package/node_modules/@comis/core/dist/config/schema-security.d.ts +0 -18
- package/node_modules/@comis/core/dist/config/schema-send-policy.d.ts +0 -13
- package/node_modules/@comis/core/dist/config/schema-sender-trust-display.d.ts +0 -5
- package/node_modules/@comis/core/dist/config/schema-serializer.js +2 -0
- package/node_modules/@comis/core/dist/config/schema-skills.d.ts +0 -63
- package/node_modules/@comis/core/dist/config/schema-skills.js +3 -4
- package/node_modules/@comis/core/dist/config/schema-streaming.d.ts +0 -38
- package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.d.ts +0 -3
- package/node_modules/@comis/core/dist/config/schema-tooling.d.ts +87 -0
- package/node_modules/@comis/core/dist/config/schema-tooling.js +152 -0
- package/node_modules/@comis/core/dist/config/schema-verbosity.d.ts +0 -12
- package/node_modules/@comis/core/dist/config/schema-webhooks.d.ts +0 -40
- package/node_modules/@comis/core/dist/config/schema.d.ts +50 -37
- package/node_modules/@comis/core/dist/config/schema.js +9 -0
- package/node_modules/@comis/core/dist/context/context.d.ts +0 -4
- package/node_modules/@comis/core/dist/domain/approval-request.d.ts +0 -17
- package/node_modules/@comis/core/dist/domain/background-task-origin.d.ts +29 -0
- package/node_modules/@comis/core/dist/domain/background-task-origin.js +39 -0
- package/node_modules/@comis/core/dist/domain/delivery-origin.d.ts +0 -5
- package/node_modules/@comis/core/dist/domain/execution-graph.d.ts +0 -48
- package/node_modules/@comis/core/dist/domain/memory-entry.d.ts +0 -3
- package/node_modules/@comis/core/dist/domain/model-compat.d.ts +0 -4
- package/node_modules/@comis/core/dist/domain/normalized-message.d.ts +0 -15
- package/node_modules/@comis/core/dist/domain/provider-capabilities.d.ts +0 -6
- package/node_modules/@comis/core/dist/domain/rich-message.d.ts +0 -14
- package/node_modules/@comis/core/dist/domain/subagent-context-config.d.ts +0 -22
- package/node_modules/@comis/core/dist/domain/subagent-context-types.d.ts +0 -8
- package/node_modules/@comis/core/dist/event-bus/events-agent.d.ts +31 -0
- package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +76 -2
- package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
- package/node_modules/@comis/core/dist/exports/config.js +3 -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/hooks.d.ts +1 -1
- 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/channel-plugin.d.ts +0 -13
- 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 +4 -0
- package/node_modules/@comis/core/dist/ports/index.js +5 -0
- package/node_modules/@comis/core/dist/ports/no-op-tool-capability.d.ts +30 -0
- package/node_modules/@comis/core/dist/ports/no-op-tool-capability.js +47 -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/ports/tool-capability.d.ts +165 -0
- package/node_modules/@comis/core/dist/ports/tool-capability.js +15 -0
- package/node_modules/@comis/core/dist/security/audit.d.ts +0 -11
- package/node_modules/@comis/core/dist/tool-metadata.d.ts +41 -1
- package/node_modules/@comis/core/dist/tool-metadata.js +1 -1
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/bundled-skills/skill-creator/scripts/validate-skill.py +1 -1
- package/node_modules/@comis/daemon/dist/daemon-types.d.ts +23 -3
- package/node_modules/@comis/daemon/dist/daemon.js +168 -30
- 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.d.ts +1 -1
- package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +3 -3
- package/node_modules/@comis/daemon/dist/rpc/builtin-provider-guard.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/model-handlers.d.ts +1 -1
- package/node_modules/@comis/daemon/dist/rpc/model-handlers.js +2 -2
- 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/sub-agent-runner.d.ts +18 -0
- package/node_modules/@comis/daemon/dist/sub-agent-runner.js +41 -9
- package/node_modules/@comis/daemon/dist/wiring/index.d.ts +4 -0
- package/node_modules/@comis/daemon/dist/wiring/index.js +2 -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 +81 -2
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +164 -3
- package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +58 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +59 -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 +13 -7
- package/node_modules/@comis/daemon/dist/wiring/setup-channels.d.ts +9 -2
- package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +35 -10
- package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.d.ts +20 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +21 -16
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery.d.ts +14 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +65 -20
- package/node_modules/@comis/daemon/dist/wiring/setup-gateway.d.ts +4 -6
- package/node_modules/@comis/daemon/dist/wiring/setup-gateway.js +3 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-heartbeat.d.ts +20 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-heartbeat.js +11 -2
- package/node_modules/@comis/daemon/dist/wiring/setup-output-retention.d.ts +89 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-output-retention.js +212 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +4 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-tools.d.ts +18 -4
- package/node_modules/@comis/daemon/dist/wiring/setup-tools.js +29 -10
- package/node_modules/@comis/daemon/dist/wiring/tool-capability-adapter.d.ts +75 -0
- package/node_modules/@comis/daemon/dist/wiring/tool-capability-adapter.js +253 -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/dist/webhook/webhook-endpoint.d.ts +0 -4
- 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/cron/cron-types.d.ts +0 -42
- 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.d.ts +29 -8
- package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +20 -8
- 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/dist/system-events/system-event-types.d.ts +0 -3
- package/node_modules/@comis/scheduler/dist/tasks/task-types.d.ts +0 -17
- package/node_modules/@comis/scheduler/package.json +1 -1
- package/node_modules/@comis/shared/dist/index.d.ts +3 -0
- package/node_modules/@comis/shared/dist/index.js +4 -0
- package/node_modules/@comis/shared/dist/mcp-tool-name.d.ts +78 -0
- package/node_modules/@comis/shared/dist/mcp-tool-name.js +92 -0
- package/node_modules/@comis/shared/dist/silent-tokens.d.ts +38 -0
- package/node_modules/@comis/shared/dist/silent-tokens.js +51 -0
- package/node_modules/@comis/shared/dist/visible-delivery.d.ts +28 -0
- package/node_modules/@comis/shared/dist/visible-delivery.js +16 -0
- package/node_modules/@comis/shared/package.json +1 -1
- package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.d.ts +2 -13
- package/node_modules/@comis/skills/dist/bridge/mcp-tool-bridge.js +3 -21
- 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 +133 -3
- 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.d.ts +55 -9
- package/node_modules/@comis/skills/dist/builtin/exec-tool.js +392 -19
- package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +6 -6
- package/node_modules/@comis/skills/dist/builtin/install-detour.d.ts +67 -0
- package/node_modules/@comis/skills/dist/builtin/install-detour.js +342 -0
- package/node_modules/@comis/skills/dist/builtin/platform/admin-manage-factory.js +5 -5
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +7 -6
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +40 -29
- 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/platform/message-tool.js +18 -0
- package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.d.ts +18 -1
- package/node_modules/@comis/skills/dist/builtin/platform/messaging-factory.js +18 -2
- package/node_modules/@comis/skills/dist/builtin/platform/models-manage-tool.js +3 -3
- package/node_modules/@comis/skills/dist/builtin/process-registry.d.ts +14 -0
- package/node_modules/@comis/skills/dist/builtin/process-tool.d.ts +24 -4
- package/node_modules/@comis/skills/dist/builtin/process-tool.js +25 -7
- 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 +123 -1
- package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +40 -15
- package/node_modules/@comis/skills/dist/index.d.ts +4 -1
- package/node_modules/@comis/skills/dist/index.js +3 -1
- package/node_modules/@comis/skills/dist/manifest/capability-parser.d.ts +44 -0
- package/node_modules/@comis/skills/dist/manifest/capability-parser.js +68 -0
- package/node_modules/@comis/skills/dist/manifest/schema.d.ts +44 -37
- package/node_modules/@comis/skills/dist/manifest/schema.js +35 -0
- 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/dist/registry/discovery.d.ts +8 -0
- package/node_modules/@comis/skills/dist/registry/discovery.js +10 -3
- package/node_modules/@comis/skills/dist/registry/skill-registry.d.ts +45 -1
- package/node_modules/@comis/skills/dist/registry/skill-registry.js +70 -7
- 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 +25 -24
|
@@ -39,12 +39,12 @@ export function createAgentHandlers(deps) {
|
|
|
39
39
|
if (deps.agents[agentId] !== undefined) {
|
|
40
40
|
throw new Error(`Agent already exists: ${agentId}`);
|
|
41
41
|
}
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
42
|
+
// Extract inlineContent BEFORE config processing. role/identity
|
|
43
|
+
// are write-once side-effects (ROLE.md / IDENTITY.md file writes),
|
|
44
|
+
// NOT durable state — they NEVER enter the persisted config patch.
|
|
45
|
+
// The tool boundary is responsible for stripping them from
|
|
46
|
+
// `config.workspace` before this RPC is called; this handler only
|
|
47
|
+
// consumes the dedicated top-level `inlineContent`
|
|
48
48
|
// field. If a (mis)caller leaves them inside config.workspace, the
|
|
49
49
|
// downstream Zod strict-object will reject them — that's an
|
|
50
50
|
// explicit failure mode, not a silent drop.
|
|
@@ -69,17 +69,37 @@ export function createAgentHandlers(deps) {
|
|
|
69
69
|
existingSkills.builtinTools = { ...DEFAULT_BUILTIN_TOOLS, ...existingBt };
|
|
70
70
|
raw.skills = existingSkills;
|
|
71
71
|
const parsedConfig = PerAgentConfigSchema.parse(config);
|
|
72
|
-
// Credential guard
|
|
73
|
-
//
|
|
72
|
+
// Credential guard: fail-loud if the new agent's provider has no
|
|
73
|
+
// resolvable API key. Mirrors agents.update guard
|
|
74
74
|
// ordering — runs BEFORE the in-memory commit so rejection prevents
|
|
75
75
|
// assignment, file persist, and hot-add. Same helper as the patch /
|
|
76
76
|
// update call sites for cross-handler consistency.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
//
|
|
78
|
+
// Also plumb agents.<id>.oauthProfiles + the daemon-level OAuth
|
|
79
|
+
// credential store so OAuth-only providers (e.g. openai-codex) can
|
|
80
|
+
// resolve via Source C. Pre-resolve has() so the resolver itself stays
|
|
81
|
+
// synchronous (port-side validator does no I/O).
|
|
82
|
+
{
|
|
83
|
+
const targetProvider = parsedConfig.provider;
|
|
84
|
+
// eslint-disable-next-line security/detect-object-injection -- typed Record<string, string> read; targetProvider validated by schema parse
|
|
85
|
+
const configuredProfileId = parsedConfig.oauthProfiles?.[targetProvider];
|
|
86
|
+
let loaderHasProfile = false;
|
|
87
|
+
if (configuredProfileId && deps.oauthCredentialStore) {
|
|
88
|
+
const hasResult = await deps.oauthCredentialStore.has(configuredProfileId);
|
|
89
|
+
loaderHasProfile = hasResult.ok && hasResult.value === true;
|
|
90
|
+
}
|
|
91
|
+
const credCheck = resolveProviderCredential(targetProvider, {
|
|
92
|
+
providerEntries: deps.providerEntries ?? {},
|
|
93
|
+
secretManager: deps.secretManager,
|
|
94
|
+
modelsConfig: deps.modelsConfig,
|
|
95
|
+
oauthProfiles: parsedConfig.oauthProfiles,
|
|
96
|
+
oauthProfileLoader: configuredProfileId
|
|
97
|
+
? { has: (id) => id === configuredProfileId && loaderHasProfile }
|
|
98
|
+
: undefined,
|
|
99
|
+
});
|
|
100
|
+
if (!credCheck.ok) {
|
|
101
|
+
throw new Error(credCheck.reason);
|
|
102
|
+
}
|
|
83
103
|
}
|
|
84
104
|
deps.agents[agentId] = parsedConfig;
|
|
85
105
|
// Best-effort persistence to config.yaml
|
|
@@ -109,7 +129,7 @@ export function createAgentHandlers(deps) {
|
|
|
109
129
|
}
|
|
110
130
|
}
|
|
111
131
|
const workspaceDir = resolveWorkspaceDir(parsedConfig, agentId);
|
|
112
|
-
//
|
|
132
|
+
// Best-effort inline ROLE.md / IDENTITY.md write.
|
|
113
133
|
// Only invoke when inlineContent has at least one populated field
|
|
114
134
|
// AND the persistDeps logger is available (the helper requires a
|
|
115
135
|
// structured logger; the in-memory-only test path skips it).
|
|
@@ -220,20 +240,63 @@ export function createAgentHandlers(deps) {
|
|
|
220
240
|
}
|
|
221
241
|
const merged = { ...existing, ...config };
|
|
222
242
|
const parsedConfig = PerAgentConfigSchema.parse(merged);
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
//
|
|
243
|
+
// Validate oauthProfiles patch — each profileId must exist in the
|
|
244
|
+
// OAuth credential store. Skipped when no oauthCredentialStore is
|
|
245
|
+
// wired (test contexts; non-OAuth-aware setups). Critical: this
|
|
246
|
+
// throws BEFORE the `deps.agents[agentId] = parsedConfig`
|
|
247
|
+
// reference-replacement at the end of the handler, so on failure the
|
|
248
|
+
// daemon's in-memory map AND the YAML are both unchanged. The
|
|
249
|
+
// Zod-layer format check has already run during
|
|
250
|
+
// PerAgentConfigSchema.parse(merged) above — this block ONLY checks
|
|
251
|
+
// existence in the store.
|
|
252
|
+
if (parsedConfig.oauthProfiles !== undefined && deps.oauthCredentialStore) {
|
|
253
|
+
for (const [provider, profileId] of Object.entries(parsedConfig.oauthProfiles)) {
|
|
254
|
+
const has = await deps.oauthCredentialStore.has(profileId);
|
|
255
|
+
if (!has.ok || !has.value) {
|
|
256
|
+
throw new Error(`profile ${profileId} not found in store. Run "comis auth list" to see available profiles.`);
|
|
257
|
+
}
|
|
258
|
+
// The provider variable is iterated for completeness; the
|
|
259
|
+
// existence check is keyed on profileId alone (validateProfileId
|
|
260
|
+
// — invoked by the Zod refine — already enforced that the
|
|
261
|
+
// profile-id's provider portion equals the map key).
|
|
262
|
+
void provider;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Credential guard + probe: when provider changes,
|
|
266
|
+
// (a) GUARD — fail-loud if the resulting provider's API key is not
|
|
267
|
+
// resolvable from any source (no silent skip), then (b) PROBE —
|
|
268
|
+
// preexisting wire validation when an explicit providers.entries
|
|
227
269
|
// record with apiKeyName exists. Order matters: guard runs first
|
|
228
270
|
// (cheap, all paths), probe runs second (only when applicable).
|
|
271
|
+
//
|
|
272
|
+
// Model-only changes with unchanged provider DO NOT fire the guard
|
|
273
|
+
// or probe — they introduce no new credential surface.
|
|
274
|
+
// Stale-broken-config detection moves to the next chat turn
|
|
275
|
+
// (fail-loud at the request boundary), where the message is
|
|
276
|
+
// correctly shaped for the actual failure mode (not a pre-emptive
|
|
277
|
+
// API-key prompt that is wrong for OAuth providers like
|
|
278
|
+
// openai-codex). Also plumbs agents.<id>.oauthProfiles + the
|
|
279
|
+
// daemon-level OAuth credential store so Source C can fire.
|
|
229
280
|
const providerChanging = config.provider !== undefined && config.provider !== existing.provider;
|
|
230
|
-
|
|
231
|
-
if (providerChanging || modelChanging) {
|
|
281
|
+
if (providerChanging) {
|
|
232
282
|
const targetProvider = parsedConfig.provider;
|
|
283
|
+
// Pre-resolve has() at the daemon edge so the resolver stays sync.
|
|
284
|
+
// eslint-disable-next-line security/detect-object-injection -- typed Record<string, string> read; targetProvider validated by schema parse
|
|
285
|
+
const configuredProfileId = parsedConfig.oauthProfiles?.[targetProvider];
|
|
286
|
+
let loaderHasProfile = false;
|
|
287
|
+
if (configuredProfileId && deps.oauthCredentialStore) {
|
|
288
|
+
const hasResult = await deps.oauthCredentialStore.has(configuredProfileId);
|
|
289
|
+
loaderHasProfile = hasResult.ok && hasResult.value === true;
|
|
290
|
+
}
|
|
233
291
|
// (a) GUARD — fail-loud if no credential source resolves
|
|
234
292
|
const resolution = resolveProviderCredential(targetProvider, {
|
|
235
293
|
providerEntries: deps.providerEntries ?? {},
|
|
236
294
|
secretManager: deps.secretManager,
|
|
295
|
+
modelsConfig: deps.modelsConfig,
|
|
296
|
+
oauthProfiles: parsedConfig.oauthProfiles,
|
|
297
|
+
oauthProfileLoader: configuredProfileId
|
|
298
|
+
? { has: (id) => id === configuredProfileId && loaderHasProfile }
|
|
299
|
+
: undefined,
|
|
237
300
|
});
|
|
238
301
|
if (!resolution.ok) {
|
|
239
302
|
throw new Error(resolution.reason);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Best-effort writer for inline ROLE.md / IDENTITY.md content supplied via
|
|
3
|
-
* the L2 single-call agents.create path
|
|
3
|
+
* the L2 single-call agents.create path.
|
|
4
4
|
*
|
|
5
5
|
* Collapses the previous 3-call agent-creation workflow
|
|
6
6
|
* (`agents_manage.create` -> `write(ROLE.md)` -> `write(IDENTITY.md)`)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
3
|
* Best-effort writer for inline ROLE.md / IDENTITY.md content supplied via
|
|
4
|
-
* the L2 single-call agents.create path
|
|
4
|
+
* the L2 single-call agents.create path.
|
|
5
5
|
*
|
|
6
6
|
* Collapses the previous 3-call agent-creation workflow
|
|
7
7
|
* (`agents_manage.create` -> `write(ROLE.md)` -> `write(IDENTITY.md)`)
|
|
@@ -63,7 +63,7 @@ async function attemptWrite(deps, agentId, filename, targetPath, content) {
|
|
|
63
63
|
catch (e) {
|
|
64
64
|
const message = e instanceof Error ? e.message : String(e);
|
|
65
65
|
deps.logger.warn({
|
|
66
|
-
|
|
66
|
+
submodule: "rpc.agent-handlers",
|
|
67
67
|
agentId,
|
|
68
68
|
file: filename,
|
|
69
69
|
err: e,
|
|
@@ -128,7 +128,7 @@ export async function writeInlineWorkspaceFiles(deps, params) {
|
|
|
128
128
|
// Pure no-op invocations (both fields absent) stay silent.
|
|
129
129
|
if (roleWritten || identityWritten) {
|
|
130
130
|
deps.logger.info({
|
|
131
|
-
|
|
131
|
+
submodule: "rpc.agent-handlers",
|
|
132
132
|
agentId: params.agentId,
|
|
133
133
|
roleBytes: roleWritten ? params.role.length : 0,
|
|
134
134
|
identityBytes: identityWritten ? params.identity.length : 0,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
* Built-in provider redundancy guard for providers.create
|
|
3
|
+
* Built-in provider redundancy guard for providers.create.
|
|
4
4
|
*
|
|
5
5
|
* Rejects providers_manage create attempts that would shadow pi-ai's
|
|
6
6
|
* dynamic catalog with a redundant custom entry. A built-in provider
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* in the source template (catalog-agnostic). Pinned by source-grep
|
|
17
17
|
* regression test in builtin-provider-guard.test.ts.
|
|
18
18
|
*
|
|
19
|
-
* Mirrors credential-resolver.ts shape
|
|
19
|
+
* Mirrors credential-resolver.ts shape.
|
|
20
20
|
*
|
|
21
21
|
* @module
|
|
22
22
|
*/
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Extracted from daemon.ts rpcCallInner switch block
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
-
import { type AppContainer, type ConfigGitManager } from "@comis/core";
|
|
10
|
+
import { type AppContainer, type ConfigGitManager, type OAuthCredentialStorePort } from "@comis/core";
|
|
11
11
|
import type { ComisLogger } from "@comis/infra";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import type { RpcHandler } from "./types.js";
|
|
@@ -26,6 +26,14 @@ export interface ConfigHandlerDeps {
|
|
|
26
26
|
timeoutMs?: number;
|
|
27
27
|
secret?: string;
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Optional OAuth credential store, used by the credential guard to
|
|
31
|
+
* confirm that an agent's `oauthProfiles[provider]` entry refers to a
|
|
32
|
+
* profile that actually exists in ~/.comis/auth-profiles.json (or the
|
|
33
|
+
* encrypted-SQLite equivalent). When absent, the OAuth branch of the
|
|
34
|
+
* resolver is a no-op — existing API-key behavior is preserved.
|
|
35
|
+
*/
|
|
36
|
+
oauthCredentialStore?: OAuthCredentialStorePort;
|
|
29
37
|
}
|
|
30
38
|
/**
|
|
31
39
|
* Unwrap Zod schema wrappers (Optional / Nullable / Default / Pipe) to get
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Extracted from daemon.ts rpcCallInner switch block
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
|
-
import { isImmutableConfigPath, getConfigSchema, getConfigSections, deepMerge, AppConfigSchema, redactConfigSecrets, warnSuspiciousEnvValues, getManagedSectionRedirect, formatRedirectHint, } from "@comis/core";
|
|
11
|
+
import { isImmutableConfigPath, getConfigSchema, getConfigSections, deepMerge, AppConfigSchema, redactConfigSecrets, warnSuspiciousEnvValues, findUnresolvedEnvRefs, formatMissingEnvRefError, getManagedSectionRedirect, formatRedirectHint, } from "@comis/core";
|
|
12
12
|
import { suppressError } from "@comis/shared";
|
|
13
13
|
import { stringify as yamlStringify } from "yaml";
|
|
14
14
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from "node:fs";
|
|
@@ -444,7 +444,7 @@ export function createConfigHandlers(deps) {
|
|
|
444
444
|
// pre-flight and bridge metadata validator catch this earlier for
|
|
445
445
|
// LLM tool calls -- this path is reached when those layers are
|
|
446
446
|
// bypassed. Emit the same redirect hint so all clients see
|
|
447
|
-
// identical, model-agnostic recovery instructions
|
|
447
|
+
// identical, model-agnostic recovery instructions.
|
|
448
448
|
if (isImmutableConfigPath(section, key)) {
|
|
449
449
|
const redirect = getManagedSectionRedirect(section, key);
|
|
450
450
|
const suffix = redirect
|
|
@@ -452,29 +452,74 @@ export function createConfigHandlers(deps) {
|
|
|
452
452
|
: " This setting requires manual operator intervention via config files.";
|
|
453
453
|
throw new Error(`Config path "${key ? `${section}.${key}` : section}" is immutable and cannot be modified at runtime.${suffix}`);
|
|
454
454
|
}
|
|
455
|
-
// Credential guard
|
|
456
|
-
//
|
|
457
|
-
//
|
|
458
|
-
//
|
|
459
|
-
//
|
|
460
|
-
//
|
|
455
|
+
// Credential guard: when a patch targets an agent's provider/model
|
|
456
|
+
// field, verify the resulting provider's API key is resolvable from
|
|
457
|
+
// at least one source pi-coding-agent will consult at runtime.
|
|
458
|
+
// Fail-loud here rather than letting an unauthorized provider
|
|
459
|
+
// config persist and explode at the next chat turn.
|
|
460
|
+
//
|
|
461
|
+
// Model-only patches with unchanged provider introduce no new
|
|
462
|
+
// credential surface — short-circuit the guard entirely. The
|
|
463
|
+
// runtime auth chain that just authenticated the LLM call making
|
|
464
|
+
// this patch will keep working. Stale-broken-config detection
|
|
465
|
+
// moves back to the next chat turn (fail-loud at the request
|
|
466
|
+
// boundary), where the message is correctly shaped for the actual
|
|
467
|
+
// failure mode (not a pre-emptive API-key prompt that is wrong for
|
|
468
|
+
// OAuth providers like openai-codex).
|
|
461
469
|
if (section === "agents" && isAgentProviderOrModelKey(key)) {
|
|
462
470
|
const targetProvider = extractTargetProvider(key, coercedValue, deps.container.config);
|
|
463
471
|
if (targetProvider !== undefined) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
472
|
+
// For `.model` keys, extractTargetProvider returns the agent's
|
|
473
|
+
// CURRENT provider (config-handlers.ts:65-69) — so the resolved
|
|
474
|
+
// targetProvider always equals the current provider. The
|
|
475
|
+
// model-only short-circuit therefore always fires for `.model`
|
|
476
|
+
// keys; we still compute the equality explicitly so the
|
|
477
|
+
// intent is readable and the check survives any future change
|
|
478
|
+
// to extractTargetProvider's contract.
|
|
479
|
+
const isModelOnlyPatch = key.endsWith(".model");
|
|
480
|
+
const agentId = key.split(".")[0];
|
|
481
|
+
// eslint-disable-next-line security/detect-object-injection -- agentId from validated key; agents map is typed Record
|
|
482
|
+
const currentProvider = agentId
|
|
483
|
+
? deps.container.config.agents?.[agentId]?.provider
|
|
484
|
+
: undefined;
|
|
485
|
+
const providerUnchanged = currentProvider === targetProvider;
|
|
486
|
+
if (!(isModelOnlyPatch && providerUnchanged)) {
|
|
487
|
+
// Provider is changing (or this is a `.provider` patch where
|
|
488
|
+
// targetProvider is the new value) — run the credential guard.
|
|
489
|
+
// eslint-disable-next-line security/detect-object-injection -- agentId from validated key; agents map is typed Record
|
|
490
|
+
const agentOauthProfiles = (agentId
|
|
491
|
+
? deps.container.config.agents?.[agentId]?.oauthProfiles
|
|
492
|
+
: undefined);
|
|
493
|
+
// Pre-resolve the loader has() for the configured profile so the
|
|
494
|
+
// resolver can stay synchronous. This keeps Hexagonal port-side
|
|
495
|
+
// validators I/O-free.
|
|
496
|
+
// eslint-disable-next-line security/detect-object-injection -- typed Record<string, string> read; targetProvider validated above
|
|
497
|
+
const configuredProfileId = agentOauthProfiles?.[targetProvider];
|
|
498
|
+
let loaderHasProfile = false;
|
|
499
|
+
if (configuredProfileId && deps.oauthCredentialStore) {
|
|
500
|
+
const hasResult = await deps.oauthCredentialStore.has(configuredProfileId);
|
|
501
|
+
loaderHasProfile = hasResult.ok && hasResult.value === true;
|
|
502
|
+
}
|
|
503
|
+
const resolution = resolveProviderCredential(targetProvider, {
|
|
504
|
+
providerEntries: deps.container.config.providers?.entries ?? {},
|
|
505
|
+
secretManager: deps.container.secretManager,
|
|
506
|
+
modelsConfig: deps.container.config.models,
|
|
507
|
+
oauthProfiles: agentOauthProfiles,
|
|
508
|
+
oauthProfileLoader: configuredProfileId
|
|
509
|
+
? { has: (id) => id === configuredProfileId && loaderHasProfile }
|
|
510
|
+
: undefined,
|
|
511
|
+
});
|
|
512
|
+
if (!resolution.ok) {
|
|
513
|
+
deps.logger.warn({
|
|
514
|
+
method: "config.patch",
|
|
515
|
+
section,
|
|
516
|
+
key,
|
|
517
|
+
targetProvider,
|
|
518
|
+
hint: "Provider credential not resolvable",
|
|
519
|
+
errorKind: "validation",
|
|
520
|
+
}, "Config patch rejected: missing provider credential");
|
|
521
|
+
throw new Error(resolution.reason);
|
|
522
|
+
}
|
|
478
523
|
}
|
|
479
524
|
}
|
|
480
525
|
}
|
|
@@ -537,6 +582,42 @@ export function createConfigHandlers(deps) {
|
|
|
537
582
|
throw new Error(`Suspicious env value(s) in config patch: ${hints}. ` +
|
|
538
583
|
`Use \${VAR_NAME} syntax to reference secrets stored via env_set.`);
|
|
539
584
|
}
|
|
585
|
+
// Reject patches that reference env vars not in the secrets store, on
|
|
586
|
+
// enabled MCP servers only. The env-substitution skip on disabled
|
|
587
|
+
// servers makes `enabled:false + ${VAR}` harmless at bootstrap; this
|
|
588
|
+
// gate forbids the partially-valid `enabled:true + missing ${VAR}`
|
|
589
|
+
// shape.
|
|
590
|
+
//
|
|
591
|
+
// We walk `patch` (not the deep-merged config) because we only
|
|
592
|
+
// validate what's being WRITTEN this RPC. `restoreMcpServerEnv` above
|
|
593
|
+
// already restored env from existing YAML for partial-update-without-
|
|
594
|
+
// env patches, so `patch.integrations.mcp.servers[].env` is the
|
|
595
|
+
// post-restore truth. Full-config validation would re-flag pre-
|
|
596
|
+
// existing valid-at-write-time refs whose secrets were later removed
|
|
597
|
+
// (out of scope, separate problem).
|
|
598
|
+
const patchInteg = patch.integrations;
|
|
599
|
+
const patchMcp = patchInteg?.mcp;
|
|
600
|
+
const patchServers = patchMcp?.servers;
|
|
601
|
+
if (Array.isArray(patchServers)) {
|
|
602
|
+
for (const s of patchServers) {
|
|
603
|
+
if (!s || typeof s !== "object")
|
|
604
|
+
continue;
|
|
605
|
+
const server = s;
|
|
606
|
+
// McpServerEntrySchema.enabled defaults to true → absent = enabled.
|
|
607
|
+
// Only explicit `enabled: false` skips the check (preserves the
|
|
608
|
+
// placeholder-for-later pattern).
|
|
609
|
+
if (server.enabled === false)
|
|
610
|
+
continue;
|
|
611
|
+
if (!server.env)
|
|
612
|
+
continue;
|
|
613
|
+
const serverName = typeof server.name === "string" ? server.name : "<unnamed>";
|
|
614
|
+
const unresolved = findUnresolvedEnvRefs(server.env, (key) => deps.container.secretManager.get(key));
|
|
615
|
+
if (unresolved.length > 0) {
|
|
616
|
+
const missingNames = unresolved.map((u) => u.varName);
|
|
617
|
+
throw new Error(formatMissingEnvRefError(serverName, missingNames));
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
540
621
|
const updatedLocal = deepMerge(existingLocal, patch);
|
|
541
622
|
// ${VAR} env var references in string values are preserved
|
|
542
623
|
// through YAML round-trip. yamlStringify writes them literally, parseYaml
|
|
@@ -651,7 +732,7 @@ export function createConfigHandlers(deps) {
|
|
|
651
732
|
}
|
|
652
733
|
// Check immutable paths -- entire section is being replaced.
|
|
653
734
|
// Backstop for direct-RPC clients; LLM tool calls hit the same redirect
|
|
654
|
-
// earlier via gateway-tool / bridge validator
|
|
735
|
+
// earlier via gateway-tool / bridge validator.
|
|
655
736
|
if (isImmutableConfigPath(section)) {
|
|
656
737
|
const redirect = getManagedSectionRedirect(section);
|
|
657
738
|
const suffix = redirect
|
|
@@ -6,12 +6,41 @@ export interface CredentialResolverDeps {
|
|
|
6
6
|
secretManager?: {
|
|
7
7
|
has(key: string): boolean;
|
|
8
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Models config — used to resolve `provider: "default"` to the operator's
|
|
11
|
+
* configured `models.defaultProvider`, mirroring runtime resolution in
|
|
12
|
+
* `resolveAgentModel`. When omitted or `defaultProvider` is empty, a
|
|
13
|
+
* literal `"default"` input passes through and produces a clear rejection
|
|
14
|
+
* pointing the operator at `models.defaultProvider`.
|
|
15
|
+
*/
|
|
16
|
+
modelsConfig?: {
|
|
17
|
+
defaultProvider?: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Per-agent OAuth profile map (Record<provider, profileId>) sourced from
|
|
21
|
+
* `agents.<id>.oauthProfiles` on the daemon's container.config. When an
|
|
22
|
+
* entry exists for the resolved provider AND `oauthProfileLoader.has`
|
|
23
|
+
* returns true, the resolver returns ok with source: "oauth_profile".
|
|
24
|
+
*/
|
|
25
|
+
oauthProfiles?: Record<string, string>;
|
|
26
|
+
/**
|
|
27
|
+
* Synchronous facade over OAuthCredentialStorePort.has. The async port
|
|
28
|
+
* call MUST be performed at the daemon edge (config-handlers /
|
|
29
|
+
* agent-handlers) and adapted to this sync shape — the resolver itself
|
|
30
|
+
* does no I/O (hexagonal: port-side validator). Pass a closure such as
|
|
31
|
+
* `{ has: () => storeHasResult.ok && storeHasResult.value }`.
|
|
32
|
+
*/
|
|
33
|
+
oauthProfileLoader?: {
|
|
34
|
+
has(profileId: string): boolean;
|
|
35
|
+
};
|
|
9
36
|
}
|
|
10
37
|
export interface CredentialResolution {
|
|
11
38
|
ok: boolean;
|
|
12
39
|
/** When ok=false: actionable error message ready to throw. */
|
|
13
40
|
reason?: string;
|
|
14
41
|
/** When ok=true: which source resolved. Useful for debug logs. */
|
|
15
|
-
source?: "keyless" | "providers_entry" | "env_canonical";
|
|
42
|
+
source?: "keyless" | "providers_entry" | "env_canonical" | "oauth_profile";
|
|
43
|
+
/** When ok=true: the provider name actually checked (after "default" resolution). */
|
|
44
|
+
resolvedProvider?: string;
|
|
16
45
|
}
|
|
17
46
|
export declare function resolveProviderCredential(targetProvider: string, deps: CredentialResolverDeps): CredentialResolution;
|
|
@@ -9,11 +9,24 @@
|
|
|
9
9
|
* Resolution chain (matches pi-coding-agent runtime semantics):
|
|
10
10
|
* 1. KEYLESS_PROVIDER_TYPES.has(entry.type) — ollama / lm-studio
|
|
11
11
|
* 2. providers.entries.<provider>.apiKeyName → secretManager.has(...)
|
|
12
|
-
* 3. pi-ai's getEnvApiKey(provider) — canonical env
|
|
12
|
+
* 3. pi-ai's getEnvApiKey(provider) — canonical env vars (incl. ANTHROPIC_OAUTH_TOKEN
|
|
13
|
+
* and AWS/ADC special-cases). Does NOT cover comis-managed OAuth profiles in
|
|
14
|
+
* ~/.comis/auth-profiles.json (e.g. openai-codex).
|
|
15
|
+
* 4. Comis OAuth profiles — agent.oauthProfiles[provider] resolved against an
|
|
16
|
+
* injected oauthProfileLoader (the OAuthCredentialStorePort handle held by
|
|
17
|
+
* the daemon, adapted to a synchronous has-check at the call site).
|
|
18
|
+
*
|
|
19
|
+
* Note on synchronous loader facade: `OAuthCredentialStorePort.has`
|
|
20
|
+
* is async (returns Promise<Result<boolean, Error>>). To avoid an async cascade
|
|
21
|
+
* through every call site, this resolver remains SYNCHRONOUS and accepts a
|
|
22
|
+
* sync facade (`oauthProfileLoader: { has(profileId: string): boolean }`).
|
|
23
|
+
* The async port `has()` call MUST be performed at the daemon edge
|
|
24
|
+
* (config-handlers / agent-handlers) and adapted into the closure. This keeps
|
|
25
|
+
* the port-side validator I/O-free (Hexagonal: validator does no I/O).
|
|
13
26
|
*
|
|
14
27
|
* @module
|
|
15
28
|
*/
|
|
16
|
-
import { getEnvApiKey } from "@mariozechner/pi-ai";
|
|
29
|
+
import { getEnvApiKey, getProviders, getModels } from "@mariozechner/pi-ai";
|
|
17
30
|
/**
|
|
18
31
|
* Provider types that don't need an API key. Mirrors agent's
|
|
19
32
|
* KEYLESS_PROVIDER_TYPES at model-registry-adapter.ts:60 — extended here to
|
|
@@ -28,23 +41,73 @@ export function resolveProviderCredential(targetProvider, deps) {
|
|
|
28
41
|
reason: `Invalid provider value: must be a non-empty string (got ${JSON.stringify(targetProvider)})`,
|
|
29
42
|
};
|
|
30
43
|
}
|
|
31
|
-
//
|
|
32
|
-
|
|
44
|
+
// Resolve `provider: "default"` to the operator's configured default,
|
|
45
|
+
// mirroring runtime resolution in `resolveAgentModel`:
|
|
46
|
+
// 1. If `providers.entries.default` is explicitly configured, treat that
|
|
47
|
+
// as the operator's intent — the entry itself carries the credential
|
|
48
|
+
// resolution path (keyless / apiKeyName).
|
|
49
|
+
// 2. Else, if `models.defaultProvider` is set, use that.
|
|
50
|
+
// 3. Otherwise, fall back to the most-populated native provider in the
|
|
51
|
+
// pi-ai catalog (same heuristic the runtime applies).
|
|
52
|
+
// This keeps the credential check semantically aligned with the literal
|
|
53
|
+
// provider the runtime will select.
|
|
54
|
+
let effectiveProvider = targetProvider;
|
|
55
|
+
if (targetProvider.toLowerCase() === "default") {
|
|
56
|
+
const explicitDefault = deps.providerEntries?.default;
|
|
57
|
+
if (!explicitDefault) {
|
|
58
|
+
const dp = deps.modelsConfig?.defaultProvider;
|
|
59
|
+
if (dp && dp.length > 0) {
|
|
60
|
+
effectiveProvider = dp;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const allProviders = getProviders();
|
|
64
|
+
if (allProviders.length > 0) {
|
|
65
|
+
effectiveProvider = allProviders
|
|
66
|
+
.map((p) => ({ p, n: getModels(p).length }))
|
|
67
|
+
.sort((a, b) => b.n - a.n)[0].p;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// eslint-disable-next-line security/detect-object-injection -- typed Record<string, ProviderEntry> read; effectiveProvider validated above
|
|
73
|
+
const entry = deps.providerEntries?.[effectiveProvider];
|
|
33
74
|
// 1. Keyless types
|
|
34
75
|
if (entry && KEYLESS_PROVIDER_TYPES.has(entry.type)) {
|
|
35
|
-
return { ok: true, source: "keyless" };
|
|
76
|
+
return { ok: true, source: "keyless", resolvedProvider: effectiveProvider };
|
|
36
77
|
}
|
|
37
78
|
// 2. Source A: providers.entries with secret-manager-resolvable apiKeyName
|
|
38
79
|
if (entry?.apiKeyName && deps.secretManager?.has(entry.apiKeyName)) {
|
|
39
|
-
return { ok: true, source: "providers_entry" };
|
|
80
|
+
return { ok: true, source: "providers_entry", resolvedProvider: effectiveProvider };
|
|
81
|
+
}
|
|
82
|
+
// 3. Source C: comis OAuth profile (per-agent agents.<id>.oauthProfiles).
|
|
83
|
+
// Covers OAuth-only providers like openai-codex whose tokens live in
|
|
84
|
+
// ~/.comis/auth-profiles.json — pi-ai's getEnvApiKey does NOT see them.
|
|
85
|
+
// Inserted before Source B so OAuth profiles win over env-canonical when
|
|
86
|
+
// both would resolve (the operator explicitly configured the profile).
|
|
87
|
+
// eslint-disable-next-line security/detect-object-injection -- typed Record<string, string> read; effectiveProvider validated above
|
|
88
|
+
const configuredProfileId = deps.oauthProfiles?.[effectiveProvider];
|
|
89
|
+
if (configuredProfileId && deps.oauthProfileLoader?.has(configuredProfileId)) {
|
|
90
|
+
return { ok: true, source: "oauth_profile", resolvedProvider: effectiveProvider };
|
|
40
91
|
}
|
|
41
|
-
//
|
|
42
|
-
if (getEnvApiKey(
|
|
43
|
-
return { ok: true, source: "env_canonical" };
|
|
92
|
+
// 4. Source B: pi-ai canonical env / OAuth / ADC chain
|
|
93
|
+
if (getEnvApiKey(effectiveProvider)) {
|
|
94
|
+
return { ok: true, source: "env_canonical", resolvedProvider: effectiveProvider };
|
|
44
95
|
}
|
|
45
|
-
return { ok: false, reason: buildRejectionMessage(
|
|
96
|
+
return { ok: false, reason: buildRejectionMessage(effectiveProvider, entry, configuredProfileId) };
|
|
46
97
|
}
|
|
47
|
-
function buildRejectionMessage(targetProvider, entry) {
|
|
98
|
+
function buildRejectionMessage(targetProvider, entry, configuredProfileId) {
|
|
99
|
+
// OAuth-aware rejection: when the agent has an oauthProfiles entry for this
|
|
100
|
+
// provider but the loader could not confirm the profile, the failure mode is
|
|
101
|
+
// a missing OAuth profile (not a missing API key). Point the operator at
|
|
102
|
+
// `comis auth login` rather than env_set / apiKeyName recovery.
|
|
103
|
+
if (configuredProfileId) {
|
|
104
|
+
const lines = [];
|
|
105
|
+
lines.push(`Cannot set agent provider to "${targetProvider}": OAuth profile "${configuredProfileId}" is configured but not found in the OAuth credential store (~/.comis/auth-profiles.json).`);
|
|
106
|
+
lines.push(`Recovery:`);
|
|
107
|
+
lines.push(` Run \`comis auth login --provider ${targetProvider}\` to (re)authenticate and create the profile, then retry this patch.`);
|
|
108
|
+
lines.push(` Run \`comis auth list\` to see currently stored profiles.`);
|
|
109
|
+
return lines.join("\n");
|
|
110
|
+
}
|
|
48
111
|
const lines = [];
|
|
49
112
|
lines.push(`Cannot set agent provider to "${targetProvider}": no API key found.`);
|
|
50
113
|
if (entry?.apiKeyName) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { McpClientManager } from "@comis/skills";
|
|
8
8
|
import type { ComisLogger } from "@comis/infra";
|
|
9
|
+
import type { SecretManager } from "@comis/core";
|
|
9
10
|
import type { RpcHandler } from "./types.js";
|
|
10
11
|
/** Dependencies required by MCP management RPC handlers. */
|
|
11
12
|
export interface McpHandlerDeps {
|
|
@@ -17,6 +18,13 @@ export interface McpHandlerDeps {
|
|
|
17
18
|
mcpClientManager: McpClientManager;
|
|
18
19
|
/** Logger for MCP test connection (used by temporary manager). */
|
|
19
20
|
logger: ComisLogger;
|
|
21
|
+
/**
|
|
22
|
+
* Optional SecretManager for env-ref validation on mcp.connect. When
|
|
23
|
+
* undefined (legacy/test wiring), the env-ref check is skipped — the
|
|
24
|
+
* existing connect behavior is preserved. In production it is always
|
|
25
|
+
* wired via `deps.container.secretManager` from rpc-dispatch.
|
|
26
|
+
*/
|
|
27
|
+
secretManager?: SecretManager;
|
|
20
28
|
}
|
|
21
29
|
/**
|
|
22
30
|
* Create a record of MCP management RPC handlers bound to the given deps.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
8
|
import { createMcpClientManager } from "@comis/skills";
|
|
9
|
+
import { findUnresolvedEnvRefs, formatMissingEnvRefError } from "@comis/core";
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
10
11
|
// Factory
|
|
11
12
|
// ---------------------------------------------------------------------------
|
|
@@ -30,9 +31,9 @@ export function createMcpHandlers(deps) {
|
|
|
30
31
|
return { servers, total: servers.length };
|
|
31
32
|
},
|
|
32
33
|
"mcp.status": async (params) => {
|
|
33
|
-
const name = params.
|
|
34
|
+
const name = params.server_name;
|
|
34
35
|
if (!name)
|
|
35
|
-
throw new Error("Missing required parameter:
|
|
36
|
+
throw new Error("Missing required parameter: server_name");
|
|
36
37
|
const manager = deps.mcpClientManager;
|
|
37
38
|
const conn = manager.getConnection(name);
|
|
38
39
|
if (!conn) {
|
|
@@ -59,10 +60,10 @@ export function createMcpHandlers(deps) {
|
|
|
59
60
|
};
|
|
60
61
|
},
|
|
61
62
|
"mcp.connect": async (params) => {
|
|
62
|
-
const name = params.
|
|
63
|
+
const name = params.server_name;
|
|
63
64
|
const transport = params.transport;
|
|
64
65
|
if (!name)
|
|
65
|
-
throw new Error("Missing required parameter:
|
|
66
|
+
throw new Error("Missing required parameter: server_name");
|
|
66
67
|
if (!transport)
|
|
67
68
|
throw new Error("Missing required parameter: transport");
|
|
68
69
|
const manager = deps.mcpClientManager;
|
|
@@ -76,6 +77,19 @@ export function createMcpHandlers(deps) {
|
|
|
76
77
|
headers: params.headers,
|
|
77
78
|
enabled: true,
|
|
78
79
|
};
|
|
80
|
+
// Reject connects that reference env vars not in the secrets store.
|
|
81
|
+
// mcp.connect is unconditionally enabled (config.enabled = true
|
|
82
|
+
// above), so the check always applies when both env and secretManager
|
|
83
|
+
// are present. Skipped only when secretManager is unwired (test
|
|
84
|
+
// setups) — production always wires it via rpc-dispatch.
|
|
85
|
+
if (config.env && deps.secretManager) {
|
|
86
|
+
const sm = deps.secretManager;
|
|
87
|
+
const unresolved = findUnresolvedEnvRefs(config.env, (key) => sm.get(key));
|
|
88
|
+
if (unresolved.length > 0) {
|
|
89
|
+
const missingNames = unresolved.map((u) => u.varName);
|
|
90
|
+
throw new Error(formatMissingEnvRefError(name, missingNames));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
79
93
|
const result = await manager.connect(config);
|
|
80
94
|
if (!result.ok) {
|
|
81
95
|
throw new Error(`Failed to connect MCP server "${name}": ${result.error.message}`);
|
|
@@ -88,9 +102,9 @@ export function createMcpHandlers(deps) {
|
|
|
88
102
|
};
|
|
89
103
|
},
|
|
90
104
|
"mcp.disconnect": async (params) => {
|
|
91
|
-
const name = params.
|
|
105
|
+
const name = params.server_name;
|
|
92
106
|
if (!name)
|
|
93
|
-
throw new Error("Missing required parameter:
|
|
107
|
+
throw new Error("Missing required parameter: server_name");
|
|
94
108
|
const manager = deps.mcpClientManager;
|
|
95
109
|
const conn = manager.getConnection(name);
|
|
96
110
|
if (!conn) {
|
|
@@ -148,9 +162,9 @@ export function createMcpHandlers(deps) {
|
|
|
148
162
|
}
|
|
149
163
|
},
|
|
150
164
|
"mcp.reconnect": async (params) => {
|
|
151
|
-
const name = params.
|
|
165
|
+
const name = params.server_name;
|
|
152
166
|
if (!name)
|
|
153
|
-
throw new Error("Missing required parameter:
|
|
167
|
+
throw new Error("Missing required parameter: server_name");
|
|
154
168
|
const manager = deps.mcpClientManager;
|
|
155
169
|
// Use manager's reconnect (preserves generation counter, uses stored config)
|
|
156
170
|
const result = await manager.reconnect(name);
|