@xopcai/xopc 0.0.87 → 0.0.88
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/agents-CRxETUZx.js +222 -0
- package/dist/gateway/static/root/assets/{apps-page-Dg8R-Szf.js → apps-page-wKWf3l57.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-BSHqqCF1.js → channels-status-swr-DIsl75Y3.js} +1 -1
- package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +1 -0
- package/dist/gateway/static/root/assets/{cron-api-0h_QT8U3.js → cron-api-N9hvuRrn.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-BkfKFfFk.js → cron-page-tlNGNxhP.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-Cmjp2APP.js → dist-CJwfHYvT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CFa9z_1N.js → extension-debug-page-BVJohZoZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BI8eaTPq.js → extension-page-BT2tmElC.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BSS47c2j.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-DRqwef_Q.js → fetch-BaFNUtkE.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-BiNHBo2Y.js → field-primitives-QwYEq6Hz.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-ZRb8qhuz.js → heartbeat-config-api-BVSidEDJ.js} +1 -1
- package/dist/gateway/static/root/assets/index-CqZzHNEg.css +1 -0
- package/dist/gateway/static/root/assets/{index-Cu7bKuUi.js → index-qNrVJp-y.js} +97 -97
- package/dist/gateway/static/root/assets/{logs-page-BFZ8GgCv.js → logs-page-DDonPVLn.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-DiqqVs6m.js → settings-form-section-B8N3A3Zo.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-n1Gprylk.js → share-preview-page-Q7KqkO-u.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-CZOh1nT3.js → theme-store-BbRc5ugR.js} +1 -1
- package/dist/gateway/static/root/assets/url-D6jvVYIA.js +7 -0
- package/dist/gateway/static/root/assets/{utils-CkWBfxs4.js → utils-CxDGduqK.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CTyHz7L_.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +27 -0
- package/dist/gateway/static/root/index.html +6 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +15 -0
- package/dist/src/agent/child-agent-factory.js +35 -2
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/client-error-format.d.ts +20 -0
- package/dist/src/agent/client-error-format.js +97 -0
- package/dist/src/agent/client-error-format.js.map +1 -0
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/embedded/run-turn.js +23 -4
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.d.ts +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.js +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +2 -0
- package/dist/src/agent/orchestration/llm-turn-retry.js +9 -1
- package/dist/src/agent/orchestration/llm-turn-retry.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +19 -3
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +1 -2
- package/dist/src/agent/service/webchat-tts.js +1 -1
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.js +4 -4
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +64 -16
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/agent-progress.d.ts +5 -0
- package/dist/src/agent/workflow/agent-progress.js +65 -0
- package/dist/src/agent/workflow/agent-progress.js.map +1 -0
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/audit-repo.js +14 -0
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/debug-incident.js +14 -0
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js +175 -0
- package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -0
- package/dist/src/agent/workflow/builtins/index.d.ts +3 -1
- package/dist/src/agent/workflow/builtins/index.js +11 -1
- package/dist/src/agent/workflow/builtins/index.js.map +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +14 -0
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/pr-review.js +14 -0
- package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/release-check.js +165 -0
- package/dist/src/agent/workflow/builtins/release-check.js.map +1 -0
- package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
- package/dist/src/agent/workflow/builtins/research.js +14 -0
- package/dist/src/agent/workflow/builtins/research.js.map +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/index.d.ts +2 -1
- package/dist/src/agent/workflow/index.js +3 -2
- package/dist/src/agent/workflow/meta-locale.d.ts +12 -0
- package/dist/src/agent/workflow/meta-locale.js +62 -0
- package/dist/src/agent/workflow/meta-locale.js.map +1 -0
- package/dist/src/agent/workflow/parser.js +3 -0
- package/dist/src/agent/workflow/parser.js.map +1 -1
- package/dist/src/agent/workflow/runtime.d.ts +2 -2
- package/dist/src/agent/workflow/runtime.js +21 -14
- package/dist/src/agent/workflow/runtime.js.map +1 -1
- package/dist/src/agent/workflow/snapshot.js +2 -12
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/step-labels.d.ts +8 -0
- package/dist/src/agent/workflow/step-labels.js +48 -0
- package/dist/src/agent/workflow/step-labels.js.map +1 -0
- package/dist/src/agent/workflow/subagent-runner.js +46 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +74 -1
- package/dist/src/auth/credentials.d.ts +5 -0
- package/dist/src/auth/credentials.js +12 -3
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +3 -3
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/agent-typed-models.d.ts +18 -0
- package/dist/src/config/agent-typed-models.js +53 -0
- package/dist/src/config/agent-typed-models.js.map +1 -0
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +6 -6
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +52 -0
- package/dist/src/config/schema.js +39 -3
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/voice.d.ts +3 -28
- package/dist/src/config/voice.js +27 -261
- package/dist/src/config/voice.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.js +2 -2
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/gateway/agents-admin.d.ts +9 -0
- package/dist/src/gateway/agents-admin.js +18 -2
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/config-tools-web.js +3 -2
- package/dist/src/gateway/config-tools-web.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/hono/lib/agent-model.d.ts +7 -0
- package/dist/src/gateway/hono/lib/agent-model.js +36 -1
- package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +28 -5
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/mask-secret-length.d.ts +6 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js +16 -0
- package/dist/src/gateway/hono/lib/mask-secret-length.js.map +1 -0
- package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +1 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js +2 -1
- package/dist/src/gateway/hono/lib/safe-providers-config.js.map +1 -1
- package/dist/src/gateway/hono/lib/safe-voice-config.js +2 -1
- package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +2 -2
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +8 -2
- package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +3 -2
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -3
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +59 -0
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +75 -12
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/voice.js +75 -0
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.d.ts +3 -0
- package/dist/src/gateway/hono/routes/workflows.js +347 -0
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -0
- package/dist/src/gateway/hono/routes/workspace.js +4 -4
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +2 -20
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service.d.ts +3 -0
- package/dist/src/gateway/service.js +7 -1
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/resolve-session.js +4 -4
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.js +5 -5
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-agent-events.js +2 -1
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +3 -3
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/voice/metadata/builtin.d.ts +2 -0
- package/dist/src/voice/metadata/builtin.js +420 -0
- package/dist/src/voice/metadata/builtin.js.map +1 -0
- package/dist/src/voice/metadata/index.d.ts +4 -0
- package/dist/src/voice/metadata/index.js +3 -0
- package/dist/src/voice/metadata/registry.d.ts +5 -0
- package/dist/src/voice/metadata/registry.js +34 -0
- package/dist/src/voice/metadata/registry.js.map +1 -0
- package/dist/src/voice/metadata/types.d.ts +41 -0
- package/dist/src/voice/metadata/types.js +1 -0
- package/dist/src/voice/stt/list-providers.d.ts +3 -3
- package/dist/src/voice/stt/list-providers.js +41 -6
- package/dist/src/voice/stt/list-providers.js.map +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/list-providers.d.ts +3 -3
- package/dist/src/voice/tts/list-providers.js +41 -6
- package/dist/src/voice/tts/list-providers.js.map +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/domain/command.d.ts +18 -0
- package/dist/src/workflows/domain/command.js +1 -0
- package/dist/src/workflows/domain/definition.d.ts +62 -0
- package/dist/src/workflows/domain/definition.js +1 -0
- package/dist/src/workflows/domain/event.d.ts +67 -0
- package/dist/src/workflows/domain/event.js +1 -0
- package/dist/src/workflows/domain/index.d.ts +5 -0
- package/dist/src/workflows/domain/index.js +2 -0
- package/dist/src/workflows/domain/result.d.ts +65 -0
- package/dist/src/workflows/domain/result.js +1 -0
- package/dist/src/workflows/domain/run.d.ts +120 -0
- package/dist/src/workflows/domain/run.js +14 -0
- package/dist/src/workflows/domain/run.js.map +1 -0
- package/dist/src/workflows/engine/index.d.ts +2 -0
- package/dist/src/workflows/engine/index.js +3 -0
- package/dist/src/workflows/engine/projector.d.ts +3 -0
- package/dist/src/workflows/engine/projector.js +205 -0
- package/dist/src/workflows/engine/projector.js.map +1 -0
- package/dist/src/workflows/engine/workflow-engine.d.ts +31 -0
- package/dist/src/workflows/engine/workflow-engine.js +188 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -0
- package/dist/src/workflows/index.d.ts +6 -0
- package/dist/src/workflows/index.js +11 -0
- package/dist/src/workflows/runtime/index.d.ts +1 -0
- package/dist/src/workflows/runtime/index.js +4 -0
- package/dist/src/workflows/runtime/script-runtime.d.ts +3 -0
- package/dist/src/workflows/runtime/script-runtime.js +3 -0
- package/dist/src/workflows/store/event-store.d.ts +17 -0
- package/dist/src/workflows/store/event-store.js +83 -0
- package/dist/src/workflows/store/event-store.js.map +1 -0
- package/dist/src/workflows/store/paths.d.ts +7 -0
- package/dist/src/workflows/store/paths.js +26 -0
- package/dist/src/workflows/store/paths.js.map +1 -0
- package/dist/src/workflows/store/run-store.d.ts +13 -0
- package/dist/src/workflows/store/run-store.js +68 -0
- package/dist/src/workflows/store/run-store.js.map +1 -0
- package/package.json +5 -5
- package/dist/gateway/static/root/assets/agents-BEAbXpuP.js +0 -222
- package/dist/gateway/static/root/assets/channels-settings-yohw9YSu.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-x4BB7q1X.js +0 -1
- package/dist/gateway/static/root/assets/index-a5gWIdZQ.css +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CD7AfB-2.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-BBOjEQW3.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-CcN_gj--.js +0 -2
- package/dist/gateway/static/root/assets/url-Dd8Q7kZZ.js +0 -3
- package/dist/gateway/static/root/assets/voice-api-key-field-O6awz9hi.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-providers-config.js","names":[],"sources":["../../../../../src/gateway/hono/lib/safe-providers-config.ts"],"sourcesContent":["import type { Config } from '../../../config/schema.js';\n\n/**\n * Per-vendor slice of {@link Config.providers} safe for GET `/api/config`.\n * Secrets are never sent verbatim; `apiKey` is
|
|
1
|
+
{"version":3,"file":"safe-providers-config.js","names":[],"sources":["../../../../../src/gateway/hono/lib/safe-providers-config.ts"],"sourcesContent":["import type { Config } from '../../../config/schema.js';\nimport { maskSecretLength } from './mask-secret-length.js';\n\n/**\n * Per-vendor slice of {@link Config.providers} safe for GET `/api/config`.\n * Secrets are never sent verbatim; `apiKey` is length-preserving bullets when set, else empty.\n */\nexport type SafeProviderAuthEntry = {\n apiKey: string;\n region?: string;\n baseUrl?: string;\n imageBaseUrl?: string;\n};\n\n/**\n * Build a redacted `providersConfig` map for the gateway console (image / audio / video keys).\n */\nexport function buildSafeProvidersConfigForWeb(\n providers: Config['providers'] | undefined,\n): Record<string, SafeProviderAuthEntry> {\n if (!providers || typeof providers !== 'object') return {};\n const out: Record<string, SafeProviderAuthEntry> = {};\n for (const [id, raw] of Object.entries(providers)) {\n if (!id) continue;\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) continue;\n const o = raw as Record<string, unknown>;\n const apiKey =\n typeof o.apiKey === 'string' && o.apiKey.trim() ? maskSecretLength(o.apiKey) : '';\n const entry: SafeProviderAuthEntry = { apiKey };\n if (typeof o.region === 'string' && o.region.trim()) {\n entry.region = o.region.trim();\n }\n if (typeof o.baseUrl === 'string' && o.baseUrl.trim()) {\n entry.baseUrl = o.baseUrl.trim();\n }\n if (typeof o.imageBaseUrl === 'string' && o.imageBaseUrl.trim()) {\n entry.imageBaseUrl = o.imageBaseUrl.trim();\n }\n out[id] = entry;\n }\n return out;\n}\n"],"mappings":";;;;;AAiBA,SAAgB,+BACd,WACuC;AACvC,KAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO,EAAE;CAC1D,MAAM,MAA6C,EAAE;AACrD,MAAK,MAAM,CAAC,IAAI,QAAQ,OAAO,QAAQ,UAAU,EAAE;AACjD,MAAI,CAAC,GAAI;AACT,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,IAAI,CAAE;EAC3D,MAAM,IAAI;EAGV,MAAM,QAA+B,EAAE,QADrC,OAAO,EAAE,WAAW,YAAY,EAAE,OAAO,MAAM,GAAG,iBAAiB,EAAE,OAAO,GAAG,IAClC;AAC/C,MAAI,OAAO,EAAE,WAAW,YAAY,EAAE,OAAO,MAAM,CACjD,OAAM,SAAS,EAAE,OAAO,MAAM;AAEhC,MAAI,OAAO,EAAE,YAAY,YAAY,EAAE,QAAQ,MAAM,CACnD,OAAM,UAAU,EAAE,QAAQ,MAAM;AAElC,MAAI,OAAO,EAAE,iBAAiB,YAAY,EAAE,aAAa,MAAM,CAC7D,OAAM,eAAe,EAAE,aAAa,MAAM;AAE5C,MAAI,MAAM;;AAEZ,QAAO"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { maskSecretLength } from "./mask-secret-length.js";
|
|
1
2
|
import { isMaskedApiKey } from "../../config-tools-web.js";
|
|
2
3
|
//#region src/gateway/hono/lib/safe-voice-config.ts
|
|
3
4
|
function maskProviderSlice(slice) {
|
|
4
5
|
const next = { ...slice };
|
|
5
|
-
if (typeof next.apiKey === "string" && next.apiKey.trim()) next.apiKey =
|
|
6
|
+
if (typeof next.apiKey === "string" && next.apiKey.trim()) next.apiKey = maskSecretLength(next.apiKey);
|
|
6
7
|
return next;
|
|
7
8
|
}
|
|
8
9
|
function mergeApiKeyField(incoming, previous) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-voice-config.js","names":[],"sources":["../../../../../src/gateway/hono/lib/safe-voice-config.ts"],"sourcesContent":["import { isMaskedApiKey } from '../../config-tools-web.js';\n\nfunction maskProviderSlice(slice: Record<string, unknown>): Record<string, unknown> {\n const next = { ...slice };\n if (typeof next.apiKey === 'string' && next.apiKey.trim()) {\n next.apiKey =
|
|
1
|
+
{"version":3,"file":"safe-voice-config.js","names":[],"sources":["../../../../../src/gateway/hono/lib/safe-voice-config.ts"],"sourcesContent":["import { isMaskedApiKey } from '../../config-tools-web.js';\nimport { maskSecretLength } from './mask-secret-length.js';\n\nfunction maskProviderSlice(slice: Record<string, unknown>): Record<string, unknown> {\n const next = { ...slice };\n if (typeof next.apiKey === 'string' && next.apiKey.trim()) {\n next.apiKey = maskSecretLength(next.apiKey);\n }\n return next;\n}\n\nfunction mergeApiKeyField(incoming: unknown, previous: unknown): unknown {\n if (typeof incoming !== 'string') return previous;\n if (isMaskedApiKey(incoming) && typeof previous === 'string' && previous.trim()) {\n return previous;\n }\n return incoming;\n}\n\nfunction mergeProviderSlice(\n incoming: Record<string, unknown>,\n previous: Record<string, unknown>,\n): Record<string, unknown> {\n const next = { ...previous, ...incoming };\n if ('apiKey' in incoming) {\n next.apiKey = mergeApiKeyField(incoming.apiKey, previous.apiKey);\n }\n return next;\n}\n\nfunction maskProviderMap(providers: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [id, value] of Object.entries(providers)) {\n out[id] =\n value && typeof value === 'object' && !Array.isArray(value)\n ? maskProviderSlice(value as Record<string, unknown>)\n : value;\n }\n return out;\n}\n\nfunction mergeProviderMap(\n incoming: Record<string, unknown>,\n previous: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...previous };\n for (const [id, value] of Object.entries(incoming)) {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n out[id] = mergeProviderSlice(value as Record<string, unknown>, (out[id] ?? {}) as Record<string, unknown>);\n } else {\n out[id] = value;\n }\n }\n return out;\n}\n\nfunction maskVoiceConfigForWeb(cfg: unknown): unknown {\n if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) return cfg;\n const raw = { ...(cfg as Record<string, unknown>) };\n if (raw.providers && typeof raw.providers === 'object' && !Array.isArray(raw.providers)) {\n raw.providers = maskProviderMap(raw.providers as Record<string, unknown>);\n }\n return raw;\n}\n\n/** Mask STT api keys for GET `/api/config`. */\nexport function maskSttConfigForWeb(stt: unknown): unknown {\n return maskVoiceConfigForWeb(stt);\n}\n\n/** Mask TTS api keys for GET `/api/config`. */\nexport function maskTtsConfigForWeb(tts: unknown): unknown {\n return maskVoiceConfigForWeb(tts);\n}\n\nfunction mergeVoiceConfigPatch(previous: unknown, incoming: unknown): unknown {\n if (!incoming || typeof incoming !== 'object' || Array.isArray(incoming)) return previous ?? incoming;\n const prev = previous && typeof previous === 'object' && !Array.isArray(previous)\n ? (previous as Record<string, unknown>)\n : {};\n const patch = incoming as Record<string, unknown>;\n const next: Record<string, unknown> = { ...prev, ...patch };\n if (patch.providers && typeof patch.providers === 'object' && !Array.isArray(patch.providers)) {\n next.providers = mergeProviderMap(\n patch.providers as Record<string, unknown>,\n (prev.providers ?? {}) as Record<string, unknown>,\n );\n }\n return next;\n}\n\n/** Merge incoming STT patch, preserving api keys when the UI sends masked sentinels. */\nexport function mergeSttConfigPatch(previous: unknown, incoming: unknown): unknown {\n return mergeVoiceConfigPatch(previous, incoming);\n}\n\n/** Merge incoming TTS patch, preserving api keys when the UI sends masked sentinels. */\nexport function mergeTtsConfigPatch(previous: unknown, incoming: unknown): unknown {\n return mergeVoiceConfigPatch(previous, incoming);\n}\n"],"mappings":";;;AAGA,SAAS,kBAAkB,OAAyD;CAClF,MAAM,OAAO,EAAE,GAAG,OAAO;AACzB,KAAI,OAAO,KAAK,WAAW,YAAY,KAAK,OAAO,MAAM,CACvD,MAAK,SAAS,iBAAiB,KAAK,OAAO;AAE7C,QAAO;;AAGT,SAAS,iBAAiB,UAAmB,UAA4B;AACvE,KAAI,OAAO,aAAa,SAAU,QAAO;AACzC,KAAI,eAAe,SAAS,IAAI,OAAO,aAAa,YAAY,SAAS,MAAM,CAC7E,QAAO;AAET,QAAO;;AAGT,SAAS,mBACP,UACA,UACyB;CACzB,MAAM,OAAO;EAAE,GAAG;EAAU,GAAG;EAAU;AACzC,KAAI,YAAY,SACd,MAAK,SAAS,iBAAiB,SAAS,QAAQ,SAAS,OAAO;AAElE,QAAO;;AAGT,SAAS,gBAAgB,WAA6D;CACpF,MAAM,MAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAQ,UAAU,CACjD,KAAI,MACF,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,GACvD,kBAAkB,MAAiC,GACnD;AAER,QAAO;;AAGT,SAAS,iBACP,UACA,UACyB;CACzB,MAAM,MAA+B,EAAE,GAAG,UAAU;AACpD,MAAK,MAAM,CAAC,IAAI,UAAU,OAAO,QAAQ,SAAS,CAChD,KAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,CAC7D,KAAI,MAAM,mBAAmB,OAAmC,IAAI,OAAO,EAAE,CAA6B;KAE1G,KAAI,MAAM;AAGd,QAAO;;AAGT,SAAS,sBAAsB,KAAuB;AACpD,KAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,IAAI,CAAE,QAAO;CAClE,MAAM,MAAM,EAAE,GAAI,KAAiC;AACnD,KAAI,IAAI,aAAa,OAAO,IAAI,cAAc,YAAY,CAAC,MAAM,QAAQ,IAAI,UAAU,CACrF,KAAI,YAAY,gBAAgB,IAAI,UAAqC;AAE3E,QAAO;;;AAIT,SAAgB,oBAAoB,KAAuB;AACzD,QAAO,sBAAsB,IAAI;;;AAInC,SAAgB,oBAAoB,KAAuB;AACzD,QAAO,sBAAsB,IAAI;;AAGnC,SAAS,sBAAsB,UAAmB,UAA4B;AAC5E,KAAI,CAAC,YAAY,OAAO,aAAa,YAAY,MAAM,QAAQ,SAAS,CAAE,QAAO,YAAY;CAC7F,MAAM,OAAO,YAAY,OAAO,aAAa,YAAY,CAAC,MAAM,QAAQ,SAAS,GAC5E,WACD,EAAE;CACN,MAAM,QAAQ;CACd,MAAM,OAAgC;EAAE,GAAG;EAAM,GAAG;EAAO;AAC3D,KAAI,MAAM,aAAa,OAAO,MAAM,cAAc,YAAY,CAAC,MAAM,QAAQ,MAAM,UAAU,CAC3F,MAAK,YAAY,iBACf,MAAM,WACL,KAAK,aAAa,EAAE,CACtB;AAEH,QAAO;;;AAIT,SAAgB,oBAAoB,UAAmB,UAA4B;AACjF,QAAO,sBAAsB,UAAU,SAAS;;;AAIlD,SAAgB,oBAAoB,UAAmB,UAA4B;AACjF,QAAO,sBAAsB,UAAU,SAAS"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { dirname, resolve } from "node:path";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
3
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
//#region src/gateway/hono/lib/static-ui.ts
|
|
6
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
2
|
-
import { init_providers, isProviderConfigured } from "../../providers/index.js";
|
|
3
2
|
import { anthropicOAuthProvider } from "../../auth/oauth/anthropic.js";
|
|
3
|
+
import { init_providers, isProviderConfigured } from "../../providers/index.js";
|
|
4
4
|
import { minimaxOAuthProvider } from "../../auth/oauth/minimax.js";
|
|
5
5
|
import { minimaxCnOAuthProvider } from "../../auth/oauth/minimax-cn.js";
|
|
6
6
|
import { kimiCodingOAuthProvider } from "../../auth/oauth/kimi-coding.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { init_schema, parseModelRef } from "../../../config/schema.js";
|
|
2
1
|
import { init_agent_scope, normalizeAgentId } from "../../../agent/agent-scope.js";
|
|
2
|
+
import { init_schema, parseModelRef } from "../../../config/schema.js";
|
|
3
3
|
import { init_providers, isProviderConfigured, resolveModel } from "../../../providers/index.js";
|
|
4
4
|
import { getVoiceModelsConfig } from "../../../config/voice.js";
|
|
5
|
+
import { agentModelFallbacksToArray, agentModelRefToString } from "../lib/agent-model.js";
|
|
5
6
|
import { deleteAgentAvatarFile, finalizeCreateAgentDirs, listAgentProfileFiles, listGatewayAgents, prepareCreateAgent, prepareCreateAgentsBatch, prepareDeleteAgent, prepareUpdateAgent, readAgentAvatarFile, readAgentProfileFile, runAfterDeletePurge, writeAgentAvatarFromBase64, writeAgentProfileFile } from "../../agents-admin.js";
|
|
6
7
|
import { resolveImageGenerationCapabilities, resolveImageUnderstandingCapabilities } from "../../image-capabilities.js";
|
|
7
|
-
import { agentModelFallbacksToArray, agentModelRefToString } from "../lib/agent-model.js";
|
|
8
8
|
//#region src/gateway/hono/routes/agents.ts
|
|
9
9
|
init_schema();
|
|
10
10
|
init_providers();
|
|
@@ -7,8 +7,8 @@ import { createOAuthHandler } from "../oauth.js";
|
|
|
7
7
|
import { createOAuthAsyncHandler } from "../oauth-async.js";
|
|
8
8
|
import { extensionAssetMimeType } from "../lib/extension-assets.js";
|
|
9
9
|
import { loadExtensionStore, saveExtensionStore } from "../lib/extension-store.js";
|
|
10
|
-
import { relative, resolve } from "node:path";
|
|
11
10
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
11
|
+
import { relative, resolve } from "node:path";
|
|
12
12
|
//#region src/gateway/hono/routes/auth-registry-extensions.ts
|
|
13
13
|
init_providers();
|
|
14
14
|
const EXTENSION_ASSET_CSP = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'none'; frame-ancestors 'self'; frame-src 'none'; base-uri 'none'; object-src 'none'; form-action 'none'";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { normalizePatchAgentImageGenerationModel, normalizePatchAgentModel } from "../../lib/agent-model.js";
|
|
1
|
+
import { normalizePatchAgentImageGenerationModel, normalizePatchAgentModel, normalizePatchTypedModels } from "../../lib/agent-model.js";
|
|
2
|
+
import { isMaskedSecretPatchValue } from "../../lib/mask-secret-length.js";
|
|
2
3
|
//#region src/gateway/hono/routes/config-patch/agents.ts
|
|
3
4
|
function applyAgentsPatch(config, body) {
|
|
4
5
|
if (!body.agents?.defaults) return;
|
|
@@ -95,7 +96,7 @@ function applyAgentsPatch(config, body) {
|
|
|
95
96
|
const cloudTarget = { ...target.cloud && typeof target.cloud === "object" && !Array.isArray(target.cloud) ? target.cloud : {} };
|
|
96
97
|
if (cloudPatch.apiKey !== void 0) {
|
|
97
98
|
if (cloudPatch.apiKey === null || cloudPatch.apiKey === "") delete cloudTarget.apiKey;
|
|
98
|
-
else if (cloudPatch.apiKey
|
|
99
|
+
else if (isMaskedSecretPatchValue(String(cloudPatch.apiKey))) {} else if (typeof cloudPatch.apiKey === "string") cloudTarget.apiKey = cloudPatch.apiKey.trim();
|
|
99
100
|
}
|
|
100
101
|
for (const key of ["projectId", "region"]) {
|
|
101
102
|
const value = cloudPatch[key];
|
|
@@ -405,6 +406,11 @@ function applyAgentsPatch(config, body) {
|
|
|
405
406
|
if (v === null) delete def.skills;
|
|
406
407
|
else if (Array.isArray(v) && v.every((x) => typeof x === "string")) def.skills = v;
|
|
407
408
|
}
|
|
409
|
+
if (dPatch.models !== void 0) {
|
|
410
|
+
const normalized = normalizePatchTypedModels(dPatch.models);
|
|
411
|
+
if (normalized === void 0) {} else if (normalized === null) delete def.models;
|
|
412
|
+
else def.models = normalized;
|
|
413
|
+
}
|
|
408
414
|
if (dPatch.tools !== void 0) {
|
|
409
415
|
const t0 = dPatch.tools;
|
|
410
416
|
if (t0 === null) delete def.tools;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","names":[],"sources":["../../../../../../src/gateway/hono/routes/config-patch/agents.ts"],"sourcesContent":["/**\n * `PATCH /api/config` — `body.agents.defaults.*` section.\n *\n * Mutates `config.agents.defaults` in place to match the patch body. All\n * branches are field-by-field \"if undefined skip, if null delete, else\n * coerce/validate then assign\" so the web UI can clear individual settings\n * with `{ field: null }` without rewriting the rest.\n *\n * Was 660 lines inlined in `config.ts` (40% of the route handler) — extracted\n * so the dispatcher can chain section patchers instead of being a single 1600\n * -line if-else cascade.\n *\n * **No early returns / errors.** This section never rejects the patch; out-of\n * -range numbers and unrecognized strings are silently dropped (preserves\n * pre-extraction behavior so the route stays a \"best-effort merge\").\n */\nimport type { Config } from '../../../../config/schema.js';\nimport {\n normalizePatchAgentImageGenerationModel,\n normalizePatchAgentModel,\n} from '../../lib/agent-model.js';\n\nexport function applyAgentsPatch(config: Config, body: any): void {\n if (!body.agents?.defaults) return;\n\n if (!config.agents) config.agents = { defaults: { workspace: '~/.xopc/workspace', model: { primary: 'anthropic/claude-sonnet-4-5' }, maxTokens: 8192, temperature: 0.7, maxToolIterations: 20, maxRequestsPerTurn: 50, maxToolFailuresPerTurn: 3, thinkingDefault: 'medium', reasoningDefault: 'stream', verboseDefault: 'full' } };\n if (!config.agents.defaults) config.agents.defaults = {} as any;\n\n if (body.agents.defaults.model !== undefined) {\n const v = body.agents.defaults.model;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).model;\n } else {\n const normalized = normalizePatchAgentModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).model;\n } else {\n config.agents.defaults.model = normalized as Config['agents']['defaults']['model'];\n }\n }\n }\n if (body.agents.defaults.maxTokens !== undefined) {\n config.agents.defaults.maxTokens = body.agents.defaults.maxTokens;\n }\n if (body.agents.defaults.temperature !== undefined) {\n config.agents.defaults.temperature = body.agents.defaults.temperature;\n }\n if (body.agents.defaults.maxToolIterations !== undefined) {\n config.agents.defaults.maxToolIterations = body.agents.defaults.maxToolIterations;\n }\n if (body.agents.defaults.workspace !== undefined) {\n config.agents.defaults.workspace = body.agents.defaults.workspace;\n }\n if (body.agents.defaults.thinkingDefault !== undefined) {\n config.agents.defaults.thinkingDefault = body.agents.defaults.thinkingDefault;\n }\n if (body.agents.defaults.reasoningDefault !== undefined) {\n config.agents.defaults.reasoningDefault = body.agents.defaults.reasoningDefault;\n }\n if (body.agents.defaults.verboseDefault !== undefined) {\n config.agents.defaults.verboseDefault = body.agents.defaults.verboseDefault;\n }\n if (body.agents.defaults.imageModel !== undefined) {\n const v = body.agents.defaults.imageModel;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageModel;\n } else {\n const normalized = normalizePatchAgentModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).imageModel;\n } else {\n config.agents.defaults.imageModel = normalized as Config['agents']['defaults']['imageModel'];\n }\n }\n }\n if (body.agents.defaults.imageGenerationModel !== undefined) {\n const v = body.agents.defaults.imageGenerationModel;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n const normalized = normalizePatchAgentImageGenerationModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n config.agents.defaults.imageGenerationModel =\n normalized as Config['agents']['defaults']['imageGenerationModel'];\n }\n }\n }\n if (body.agents.defaults.mediaMaxMb !== undefined) {\n const v = body.agents.defaults.mediaMaxMb;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).mediaMaxMb;\n } else {\n const n = typeof v === 'number' ? v : Number(v);\n if (!Number.isNaN(n) && n > 0) {\n config.agents.defaults.mediaMaxMb = n;\n }\n }\n }\n if (body.agents.defaults.browser !== undefined) {\n const b = body.agents.defaults.browser;\n if (b === null) {\n delete (config.agents.defaults as Record<string, unknown>).browser;\n } else if (typeof b === 'object' && !Array.isArray(b)) {\n const br = b as Record<string, unknown>;\n if (!config.agents.defaults.browser) {\n config.agents.defaults.browser = { enabled: false, headless: false };\n }\n const target = config.agents.defaults.browser as Record<string, unknown>;\n if (br.enabled !== undefined) {\n if (br.enabled === null) delete target.enabled;\n else target.enabled = Boolean(br.enabled);\n }\n if (br.headless !== undefined) {\n if (br.headless === null) delete target.headless;\n else target.headless = Boolean(br.headless);\n }\n if (br.allowPrivateUrls !== undefined) {\n if (br.allowPrivateUrls === null) delete target.allowPrivateUrls;\n else target.allowPrivateUrls = Boolean(br.allowPrivateUrls);\n }\n if (br.commandTimeout !== undefined) {\n if (br.commandTimeout === null) {\n delete target.commandTimeout;\n } else if (typeof br.commandTimeout === 'number' && Number.isFinite(br.commandTimeout)) {\n const n = Math.floor(br.commandTimeout);\n if (n >= 5 && n <= 900) {\n target.commandTimeout = n;\n }\n }\n }\n if (br.backend !== undefined) {\n if (br.backend === null || br.backend === '' || br.backend === 'extension') {\n delete target.backend;\n } else if (\n br.backend === 'local' ||\n br.backend === 'cdp' ||\n br.backend === 'cloud' ||\n br.backend === 'cloakbrowser'\n ) {\n target.backend = br.backend;\n }\n }\n if (br.cloudProvider !== undefined) {\n if (br.cloudProvider === null || br.cloudProvider === '') {\n delete target.cloudProvider;\n } else if (br.cloudProvider === 'browserbase' || br.cloudProvider === 'browser-use') {\n target.cloudProvider = br.cloudProvider;\n }\n }\n if (br.cloud !== undefined) {\n if (br.cloud === null) {\n delete target.cloud;\n } else if (typeof br.cloud === 'object' && !Array.isArray(br.cloud)) {\n const cloudPatch = br.cloud as Record<string, unknown>;\n const existingCloud =\n target.cloud && typeof target.cloud === 'object' && !Array.isArray(target.cloud)\n ? (target.cloud as Record<string, unknown>)\n : {};\n const cloudTarget: Record<string, unknown> = { ...existingCloud };\n if (cloudPatch.apiKey !== undefined) {\n if (cloudPatch.apiKey === null || cloudPatch.apiKey === '') {\n delete cloudTarget.apiKey;\n } else if (cloudPatch.apiKey === '***') {\n // Keep the existing stored key when the web UI sends the masked sentinel.\n } else if (typeof cloudPatch.apiKey === 'string') {\n cloudTarget.apiKey = cloudPatch.apiKey.trim();\n }\n }\n for (const key of ['projectId', 'region']) {\n const value = cloudPatch[key];\n if (value === null || value === '') {\n delete cloudTarget[key];\n } else if (typeof value === 'string' && value.trim()) {\n cloudTarget[key] = value.trim();\n }\n }\n if (Object.keys(cloudTarget).length > 0) {\n target.cloud = cloudTarget;\n } else {\n delete target.cloud;\n }\n }\n }\n if (br.cdpUrl !== undefined) {\n if (br.cdpUrl === null || br.cdpUrl === '') {\n delete target.cdpUrl;\n } else if (typeof br.cdpUrl === 'string') {\n target.cdpUrl = br.cdpUrl.trim();\n }\n }\n if (br.extension !== undefined) {\n if (br.extension === null) {\n delete target.extension;\n } else if (typeof br.extension === 'object' && !Array.isArray(br.extension)) {\n const ext = br.extension as Record<string, unknown>;\n const extTarget: Record<string, unknown> = {};\n if (ext.port === null || ext.port === '') {\n // explicit clear: leave unset (consumers fall back to default)\n } else if (typeof ext.port === 'number' && ext.port >= 1024 && ext.port <= 65535) {\n extTarget.port = Math.floor(ext.port);\n }\n if (ext.host === null || ext.host === '') {\n // explicit clear\n } else if (typeof ext.host === 'string' && ext.host.trim()) {\n extTarget.host = ext.host.trim();\n }\n if (\n ext.connectionTimeout === null ||\n ext.connectionTimeout === ''\n ) {\n // explicit clear\n } else if (\n typeof ext.connectionTimeout === 'number' &&\n Number.isFinite(ext.connectionTimeout) &&\n ext.connectionTimeout >= 1000\n ) {\n extTarget.connectionTimeout = Math.floor(ext.connectionTimeout);\n }\n if (Object.keys(extTarget).length > 0) {\n target.extension = extTarget;\n } else {\n delete target.extension;\n }\n }\n }\n if (br.cloakbrowser !== undefined) {\n if (br.cloakbrowser === null) {\n delete target.cloakbrowser;\n } else if (typeof br.cloakbrowser === 'object' && !Array.isArray(br.cloakbrowser)) {\n const cloakbrowserPatch = br.cloakbrowser as Record<string, unknown>;\n const cloakbrowserTarget: Record<string, unknown> = {};\n if (typeof cloakbrowserPatch.keepOpen === 'boolean') {\n cloakbrowserTarget.keepOpen = cloakbrowserPatch.keepOpen;\n }\n if (typeof cloakbrowserPatch.temporaryProfile === 'boolean') {\n cloakbrowserTarget.temporaryProfile = cloakbrowserPatch.temporaryProfile;\n }\n for (const key of ['cacheDir', 'binaryPath', 'timezone', 'locale', 'webrtcIp', 'fingerprintPlatform']) {\n const value = cloakbrowserPatch[key];\n if (typeof value === 'string' && value.trim()) {\n cloakbrowserTarget[key] = value.trim();\n }\n }\n if (\n Array.isArray(cloakbrowserPatch.extraArgs) &&\n cloakbrowserPatch.extraArgs.every((value) => typeof value === 'string')\n ) {\n cloakbrowserTarget.extraArgs = cloakbrowserPatch.extraArgs;\n }\n if (Object.keys(cloakbrowserTarget).length > 0) {\n target.cloakbrowser = cloakbrowserTarget;\n } else {\n delete target.cloakbrowser;\n }\n }\n }\n if (br.humanize !== undefined) {\n if (br.humanize === null) {\n delete target.humanize;\n } else {\n target.humanize = Boolean(br.humanize);\n }\n }\n if (br.humanPreset !== undefined) {\n if (br.humanPreset === null) {\n delete target.humanPreset;\n } else if (br.humanPreset === 'default' || br.humanPreset === 'careful') {\n target.humanPreset = br.humanPreset;\n }\n }\n if (br.dialogPolicy !== undefined) {\n if (br.dialogPolicy === null) {\n delete target.dialogPolicy;\n } else if (\n br.dialogPolicy === 'must_respond' ||\n br.dialogPolicy === 'auto_dismiss' ||\n br.dialogPolicy === 'auto_accept'\n ) {\n target.dialogPolicy = br.dialogPolicy;\n }\n }\n if (br.dialogTimeoutSeconds !== undefined) {\n if (br.dialogTimeoutSeconds === null) {\n delete target.dialogTimeoutSeconds;\n } else if (typeof br.dialogTimeoutSeconds === 'number' && Number.isFinite(br.dialogTimeoutSeconds)) {\n const n = Math.floor(br.dialogTimeoutSeconds);\n if (n >= 1 && n <= 86_400) {\n target.dialogTimeoutSeconds = n;\n }\n }\n }\n }\n }\n\n const dPatch = body.agents.defaults as Record<string, unknown>;\n const def = config.agents.defaults as Record<string, unknown>;\n\n if (dPatch.maxTaskDurationMs !== undefined) {\n const v = dPatch.maxTaskDurationMs;\n if (v === null) {\n delete def.maxTaskDurationMs;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const ms = Math.floor(v);\n if (ms >= 60_000 && ms <= 14_400_000) {\n def.maxTaskDurationMs = ms;\n }\n }\n }\n if (dPatch.maxRequestsPerTurn !== undefined) {\n const v = dPatch.maxRequestsPerTurn;\n if (v === null) {\n delete def.maxRequestsPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 10 && n <= 200) {\n def.maxRequestsPerTurn = n;\n }\n }\n }\n if (dPatch.maxToolFailuresPerTurn !== undefined) {\n const v = dPatch.maxToolFailuresPerTurn;\n if (v === null) {\n delete def.maxToolFailuresPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 1 && n <= 20) {\n def.maxToolFailuresPerTurn = n;\n }\n }\n }\n\n if (dPatch.compaction !== undefined) {\n const c = dPatch.compaction;\n if (c === null) {\n delete def.compaction;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.compaction || typeof def.compaction !== 'object') {\n def.compaction = {};\n }\n const t = def.compaction as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (p.mode === 'default' || p.mode === 'safeguard') t.mode = p.mode;\n if (typeof p.reserveTokens === 'number' && Number.isFinite(p.reserveTokens)) {\n t.reserveTokens = Math.floor(p.reserveTokens);\n }\n if (typeof p.triggerThreshold === 'number' && Number.isFinite(p.triggerThreshold)) {\n const x = p.triggerThreshold;\n if (x >= 0.5 && x <= 0.95) t.triggerThreshold = x;\n }\n if (typeof p.minMessagesBeforeCompact === 'number' && Number.isFinite(p.minMessagesBeforeCompact)) {\n t.minMessagesBeforeCompact = Math.floor(p.minMessagesBeforeCompact);\n }\n if (typeof p.keepRecentMessages === 'number' && Number.isFinite(p.keepRecentMessages)) {\n t.keepRecentMessages = Math.floor(p.keepRecentMessages);\n }\n if (typeof p.evictionWindow === 'number' && Number.isFinite(p.evictionWindow)) {\n const x = p.evictionWindow;\n if (x >= 0.1 && x <= 0.5) t.evictionWindow = x;\n }\n if (typeof p.retentionWindow === 'number' && Number.isFinite(p.retentionWindow)) {\n const n = Math.floor(p.retentionWindow);\n if (n >= 3 && n <= 20) t.retentionWindow = n;\n }\n }\n }\n\n if (dPatch.pruning !== undefined) {\n const c = dPatch.pruning;\n if (c === null) {\n delete def.pruning;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.pruning || typeof def.pruning !== 'object') {\n def.pruning = {};\n }\n const t = def.pruning as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (typeof p.maxToolResultChars === 'number' && Number.isFinite(p.maxToolResultChars)) {\n t.maxToolResultChars = Math.floor(p.maxToolResultChars);\n }\n if (typeof p.headKeepRatio === 'number' && Number.isFinite(p.headKeepRatio)) {\n t.headKeepRatio = p.headKeepRatio;\n }\n if (typeof p.tailKeepRatio === 'number' && Number.isFinite(p.tailKeepRatio)) {\n t.tailKeepRatio = p.tailKeepRatio;\n }\n }\n }\n\n if (dPatch.memory !== undefined) {\n const c = dPatch.memory;\n if (c === null) {\n delete def.memory;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.memory || typeof def.memory !== 'object') {\n def.memory = {};\n }\n const t = def.memory as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.useEnhancedSystem !== undefined) {\n if (p.useEnhancedSystem === null) delete t.useEnhancedSystem;\n else t.useEnhancedSystem = Boolean(p.useEnhancedSystem);\n }\n if (p.userProfileEnabled !== undefined) {\n if (p.userProfileEnabled === null) delete t.userProfileEnabled;\n else t.userProfileEnabled = Boolean(p.userProfileEnabled);\n }\n if (p.memoryCharLimit !== undefined) {\n if (p.memoryCharLimit === null) delete t.memoryCharLimit;\n else if (typeof p.memoryCharLimit === 'number' && p.memoryCharLimit > 0) {\n t.memoryCharLimit = Math.floor(p.memoryCharLimit);\n }\n }\n if (p.userCharLimit !== undefined) {\n if (p.userCharLimit === null) delete t.userCharLimit;\n else if (typeof p.userCharLimit === 'number' && p.userCharLimit > 0) {\n t.userCharLimit = Math.floor(p.userCharLimit);\n }\n }\n if (p.provider === 'none' || p.provider === 'stub') {\n t.provider = p.provider;\n } else if (p.provider === null) {\n delete t.provider;\n }\n if (p.injectionFrequency === 'every-turn' || p.injectionFrequency === 'first-turn') {\n t.injectionFrequency = p.injectionFrequency;\n } else if (p.injectionFrequency === null) {\n delete t.injectionFrequency;\n }\n if (p.contextCadence !== undefined) {\n if (p.contextCadence === null) delete t.contextCadence;\n else if (typeof p.contextCadence === 'number' && p.contextCadence >= 1) {\n t.contextCadence = Math.floor(p.contextCadence);\n }\n }\n if (p.dialecticCadence !== undefined) {\n if (p.dialecticCadence === null) delete t.dialecticCadence;\n else if (typeof p.dialecticCadence === 'number' && p.dialecticCadence >= 1) {\n t.dialecticCadence = Math.floor(p.dialecticCadence);\n }\n }\n\n // Dreaming (schemaless patch): agents.defaults.memory.dreaming\n if (p.dreaming !== undefined) {\n const d0 = p.dreaming;\n if (d0 === null) {\n delete (t as { dreaming?: unknown }).dreaming;\n } else if (typeof d0 === 'object' && d0 !== null && !Array.isArray(d0)) {\n if (!('dreaming' in t) || typeof (t as { dreaming?: unknown }).dreaming !== 'object') {\n (t as { dreaming?: Record<string, unknown> }).dreaming = {};\n }\n const dt = (t as { dreaming: Record<string, unknown> }).dreaming;\n const dp = d0 as Record<string, unknown>;\n\n if (dp.enabled !== undefined) {\n if (dp.enabled === null) delete dt.enabled;\n else dt.enabled = Boolean(dp.enabled);\n }\n if (dp.frequency !== undefined) {\n const v = dp.frequency;\n if (v === null || v === '') delete dt.frequency;\n else if (typeof v === 'string') dt.frequency = v;\n }\n if (dp.timezone !== undefined) {\n const v = dp.timezone;\n if (v === null || v === '') delete dt.timezone;\n else if (typeof v === 'string') dt.timezone = v;\n }\n\n // Accept either `phases.deep` or `deep`.\n if (dp.phases !== undefined || dp.deep !== undefined) {\n if (!('phases' in dt) || typeof (dt as { phases?: unknown }).phases !== 'object' || (dt as { phases?: unknown }).phases === null) {\n dt.phases = {};\n }\n const phases = (dt as { phases: Record<string, unknown> }).phases;\n if (!('deep' in phases) || typeof phases.deep !== 'object' || phases.deep === null) {\n phases.deep = {};\n }\n const deep = phases.deep as Record<string, unknown>;\n\n const deepPatchRaw =\n typeof dp.phases === 'object' && dp.phases !== null && !Array.isArray(dp.phases)\n ? (dp.phases as Record<string, unknown>).deep\n : dp.deep;\n const deepPatch =\n typeof deepPatchRaw === 'object' && deepPatchRaw !== null && !Array.isArray(deepPatchRaw)\n ? (deepPatchRaw as Record<string, unknown>)\n : null;\n\n if (deepPatch) {\n if (deepPatch.enabled !== undefined) {\n if (deepPatch.enabled === null) delete deep.enabled;\n else deep.enabled = Boolean(deepPatch.enabled);\n }\n if (deepPatch.minScore !== undefined) {\n const v = deepPatch.minScore;\n if (v === null) delete deep.minScore;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minScore = v;\n }\n if (deepPatch.minRecallCount !== undefined) {\n const v = deepPatch.minRecallCount;\n if (v === null) delete deep.minRecallCount;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minRecallCount = Math.floor(v);\n }\n if (deepPatch.limit !== undefined) {\n const v = deepPatch.limit;\n if (v === null) delete deep.limit;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.limit = Math.floor(v);\n }\n }\n }\n }\n }\n }\n }\n\n if (dPatch.sessionSearch !== undefined) {\n const c = dPatch.sessionSearch;\n if (c === null) {\n delete def.sessionSearch;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.sessionSearch || typeof def.sessionSearch !== 'object') {\n def.sessionSearch = {};\n }\n const t = def.sessionSearch as Record<string, unknown>;\n if (p.summaryModel !== undefined) {\n if (p.summaryModel === null || p.summaryModel === '') {\n delete t.summaryModel;\n } else if (typeof p.summaryModel === 'string') {\n t.summaryModel = p.summaryModel;\n }\n }\n }\n }\n\n if (dPatch.backgroundReview !== undefined) {\n const c = dPatch.backgroundReview;\n if (c === null) {\n delete def.backgroundReview;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.backgroundReview || typeof def.backgroundReview !== 'object') {\n def.backgroundReview = {};\n }\n const t = def.backgroundReview as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.memoryNudgeInterval !== undefined) {\n if (p.memoryNudgeInterval === null) delete t.memoryNudgeInterval;\n else if (typeof p.memoryNudgeInterval === 'number' && p.memoryNudgeInterval >= 0) {\n t.memoryNudgeInterval = Math.floor(p.memoryNudgeInterval);\n }\n }\n if (p.skillNudgeInterval !== undefined) {\n if (p.skillNudgeInterval === null) delete t.skillNudgeInterval;\n else if (typeof p.skillNudgeInterval === 'number' && p.skillNudgeInterval >= 0) {\n t.skillNudgeInterval = Math.floor(p.skillNudgeInterval);\n }\n }\n if (p.maxToolRounds !== undefined) {\n if (p.maxToolRounds === null) delete t.maxToolRounds;\n else if (typeof p.maxToolRounds === 'number' && p.maxToolRounds >= 1 && p.maxToolRounds <= 32) {\n t.maxToolRounds = Math.floor(p.maxToolRounds);\n }\n }\n if (p.maxHistoryMessages !== undefined) {\n if (p.maxHistoryMessages === null) delete t.maxHistoryMessages;\n else if (typeof p.maxHistoryMessages === 'number' && p.maxHistoryMessages >= 10 && p.maxHistoryMessages <= 200) {\n t.maxHistoryMessages = Math.floor(p.maxHistoryMessages);\n }\n }\n if (p.maxDurationMs !== undefined) {\n if (p.maxDurationMs === null) delete t.maxDurationMs;\n else if (typeof p.maxDurationMs === 'number' && p.maxDurationMs >= 30_000 && p.maxDurationMs <= 600_000) {\n t.maxDurationMs = Math.floor(p.maxDurationMs);\n }\n }\n }\n }\n\n if (dPatch.webExtract !== undefined) {\n const c = dPatch.webExtract;\n if (c === null) {\n delete def.webExtract;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.webExtract || typeof def.webExtract !== 'object') {\n def.webExtract = {};\n }\n const t = def.webExtract as Record<string, unknown>;\n if (p.model !== undefined) {\n if (p.model === null || p.model === '') {\n delete t.model;\n } else if (typeof p.model === 'string') {\n t.model = p.model;\n }\n }\n if (p.maxLength !== undefined) {\n if (p.maxLength === null) delete t.maxLength;\n else if (typeof p.maxLength === 'number' && p.maxLength > 0) {\n t.maxLength = p.maxLength;\n }\n }\n }\n }\n\n if (dPatch.delegate !== undefined) {\n const c = dPatch.delegate;\n if (c === null) {\n delete def.delegate;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.delegate || typeof def.delegate !== 'object') {\n def.delegate = {};\n }\n const t = def.delegate as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.executeCode !== undefined) {\n const c = dPatch.executeCode;\n if (c === null) {\n delete def.executeCode;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.executeCode || typeof def.executeCode !== 'object') {\n def.executeCode = {};\n }\n const t = def.executeCode as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.systemPromptOverride !== undefined) {\n const v = dPatch.systemPromptOverride;\n if (v === null || v === '') {\n delete def.systemPromptOverride;\n } else if (typeof v === 'string') {\n def.systemPromptOverride = v;\n }\n }\n\n if (dPatch.skills !== undefined) {\n const v = dPatch.skills;\n if (v === null) {\n delete def.skills;\n } else if (Array.isArray(v) && v.every((x) => typeof x === 'string')) {\n def.skills = v;\n }\n }\n\n if (dPatch.tools !== undefined) {\n const t0 = dPatch.tools;\n if (t0 === null) {\n delete def.tools;\n } else if (typeof t0 === 'object' && !Array.isArray(t0)) {\n const p = t0 as { disable?: unknown };\n if (!def.tools || typeof def.tools !== 'object') {\n def.tools = {};\n }\n const t = def.tools as { disable?: string[] };\n if (p.disable !== undefined) {\n if (p.disable === null || (Array.isArray(p.disable) && p.disable.length === 0)) {\n delete t.disable;\n } else if (Array.isArray(p.disable) && p.disable.every((x) => typeof x === 'string')) {\n t.disable = p.disable;\n }\n }\n }\n }\n\n if (dPatch.params !== undefined) {\n const v = dPatch.params;\n if (v === null) {\n delete def.params;\n } else if (typeof v === 'object' && !Array.isArray(v) && v !== null) {\n def.params = v as Record<string, unknown>;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agents.js","names":[],"sources":["../../../../../../src/gateway/hono/routes/config-patch/agents.ts"],"sourcesContent":["/**\n * `PATCH /api/config` — `body.agents.defaults.*` section.\n *\n * Mutates `config.agents.defaults` in place to match the patch body. All\n * branches are field-by-field \"if undefined skip, if null delete, else\n * coerce/validate then assign\" so the web UI can clear individual settings\n * with `{ field: null }` without rewriting the rest.\n *\n * Was 660 lines inlined in `config.ts` (40% of the route handler) — extracted\n * so the dispatcher can chain section patchers instead of being a single 1600\n * -line if-else cascade.\n *\n * **No early returns / errors.** This section never rejects the patch; out-of\n * -range numbers and unrecognized strings are silently dropped (preserves\n * pre-extraction behavior so the route stays a \"best-effort merge\").\n */\nimport type { Config } from '../../../../config/schema.js';\nimport { isMaskedSecretPatchValue } from '../../lib/mask-secret-length.js';\nimport {\n normalizePatchAgentImageGenerationModel,\n normalizePatchAgentModel,\n normalizePatchTypedModels,\n} from '../../lib/agent-model.js';\n\nexport function applyAgentsPatch(config: Config, body: any): void {\n if (!body.agents?.defaults) return;\n\n if (!config.agents) config.agents = { defaults: { workspace: '~/.xopc/workspace', model: { primary: 'anthropic/claude-sonnet-4-5' }, maxTokens: 8192, temperature: 0.7, maxToolIterations: 20, maxRequestsPerTurn: 50, maxToolFailuresPerTurn: 3, thinkingDefault: 'medium', reasoningDefault: 'stream', verboseDefault: 'full' } };\n if (!config.agents.defaults) config.agents.defaults = {} as any;\n\n if (body.agents.defaults.model !== undefined) {\n const v = body.agents.defaults.model;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).model;\n } else {\n const normalized = normalizePatchAgentModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).model;\n } else {\n config.agents.defaults.model = normalized as Config['agents']['defaults']['model'];\n }\n }\n }\n if (body.agents.defaults.maxTokens !== undefined) {\n config.agents.defaults.maxTokens = body.agents.defaults.maxTokens;\n }\n if (body.agents.defaults.temperature !== undefined) {\n config.agents.defaults.temperature = body.agents.defaults.temperature;\n }\n if (body.agents.defaults.maxToolIterations !== undefined) {\n config.agents.defaults.maxToolIterations = body.agents.defaults.maxToolIterations;\n }\n if (body.agents.defaults.workspace !== undefined) {\n config.agents.defaults.workspace = body.agents.defaults.workspace;\n }\n if (body.agents.defaults.thinkingDefault !== undefined) {\n config.agents.defaults.thinkingDefault = body.agents.defaults.thinkingDefault;\n }\n if (body.agents.defaults.reasoningDefault !== undefined) {\n config.agents.defaults.reasoningDefault = body.agents.defaults.reasoningDefault;\n }\n if (body.agents.defaults.verboseDefault !== undefined) {\n config.agents.defaults.verboseDefault = body.agents.defaults.verboseDefault;\n }\n if (body.agents.defaults.imageModel !== undefined) {\n const v = body.agents.defaults.imageModel;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageModel;\n } else {\n const normalized = normalizePatchAgentModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).imageModel;\n } else {\n config.agents.defaults.imageModel = normalized as Config['agents']['defaults']['imageModel'];\n }\n }\n }\n if (body.agents.defaults.imageGenerationModel !== undefined) {\n const v = body.agents.defaults.imageGenerationModel;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n const normalized = normalizePatchAgentImageGenerationModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n config.agents.defaults.imageGenerationModel =\n normalized as Config['agents']['defaults']['imageGenerationModel'];\n }\n }\n }\n if (body.agents.defaults.mediaMaxMb !== undefined) {\n const v = body.agents.defaults.mediaMaxMb;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).mediaMaxMb;\n } else {\n const n = typeof v === 'number' ? v : Number(v);\n if (!Number.isNaN(n) && n > 0) {\n config.agents.defaults.mediaMaxMb = n;\n }\n }\n }\n if (body.agents.defaults.browser !== undefined) {\n const b = body.agents.defaults.browser;\n if (b === null) {\n delete (config.agents.defaults as Record<string, unknown>).browser;\n } else if (typeof b === 'object' && !Array.isArray(b)) {\n const br = b as Record<string, unknown>;\n if (!config.agents.defaults.browser) {\n config.agents.defaults.browser = { enabled: false, headless: false };\n }\n const target = config.agents.defaults.browser as Record<string, unknown>;\n if (br.enabled !== undefined) {\n if (br.enabled === null) delete target.enabled;\n else target.enabled = Boolean(br.enabled);\n }\n if (br.headless !== undefined) {\n if (br.headless === null) delete target.headless;\n else target.headless = Boolean(br.headless);\n }\n if (br.allowPrivateUrls !== undefined) {\n if (br.allowPrivateUrls === null) delete target.allowPrivateUrls;\n else target.allowPrivateUrls = Boolean(br.allowPrivateUrls);\n }\n if (br.commandTimeout !== undefined) {\n if (br.commandTimeout === null) {\n delete target.commandTimeout;\n } else if (typeof br.commandTimeout === 'number' && Number.isFinite(br.commandTimeout)) {\n const n = Math.floor(br.commandTimeout);\n if (n >= 5 && n <= 900) {\n target.commandTimeout = n;\n }\n }\n }\n if (br.backend !== undefined) {\n if (br.backend === null || br.backend === '' || br.backend === 'extension') {\n delete target.backend;\n } else if (\n br.backend === 'local' ||\n br.backend === 'cdp' ||\n br.backend === 'cloud' ||\n br.backend === 'cloakbrowser'\n ) {\n target.backend = br.backend;\n }\n }\n if (br.cloudProvider !== undefined) {\n if (br.cloudProvider === null || br.cloudProvider === '') {\n delete target.cloudProvider;\n } else if (br.cloudProvider === 'browserbase' || br.cloudProvider === 'browser-use') {\n target.cloudProvider = br.cloudProvider;\n }\n }\n if (br.cloud !== undefined) {\n if (br.cloud === null) {\n delete target.cloud;\n } else if (typeof br.cloud === 'object' && !Array.isArray(br.cloud)) {\n const cloudPatch = br.cloud as Record<string, unknown>;\n const existingCloud =\n target.cloud && typeof target.cloud === 'object' && !Array.isArray(target.cloud)\n ? (target.cloud as Record<string, unknown>)\n : {};\n const cloudTarget: Record<string, unknown> = { ...existingCloud };\n if (cloudPatch.apiKey !== undefined) {\n if (cloudPatch.apiKey === null || cloudPatch.apiKey === '') {\n delete cloudTarget.apiKey;\n } else if (isMaskedSecretPatchValue(String(cloudPatch.apiKey))) {\n // Keep the existing stored key when the web UI sends the masked sentinel.\n } else if (typeof cloudPatch.apiKey === 'string') {\n cloudTarget.apiKey = cloudPatch.apiKey.trim();\n }\n }\n for (const key of ['projectId', 'region']) {\n const value = cloudPatch[key];\n if (value === null || value === '') {\n delete cloudTarget[key];\n } else if (typeof value === 'string' && value.trim()) {\n cloudTarget[key] = value.trim();\n }\n }\n if (Object.keys(cloudTarget).length > 0) {\n target.cloud = cloudTarget;\n } else {\n delete target.cloud;\n }\n }\n }\n if (br.cdpUrl !== undefined) {\n if (br.cdpUrl === null || br.cdpUrl === '') {\n delete target.cdpUrl;\n } else if (typeof br.cdpUrl === 'string') {\n target.cdpUrl = br.cdpUrl.trim();\n }\n }\n if (br.extension !== undefined) {\n if (br.extension === null) {\n delete target.extension;\n } else if (typeof br.extension === 'object' && !Array.isArray(br.extension)) {\n const ext = br.extension as Record<string, unknown>;\n const extTarget: Record<string, unknown> = {};\n if (ext.port === null || ext.port === '') {\n // explicit clear: leave unset (consumers fall back to default)\n } else if (typeof ext.port === 'number' && ext.port >= 1024 && ext.port <= 65535) {\n extTarget.port = Math.floor(ext.port);\n }\n if (ext.host === null || ext.host === '') {\n // explicit clear\n } else if (typeof ext.host === 'string' && ext.host.trim()) {\n extTarget.host = ext.host.trim();\n }\n if (\n ext.connectionTimeout === null ||\n ext.connectionTimeout === ''\n ) {\n // explicit clear\n } else if (\n typeof ext.connectionTimeout === 'number' &&\n Number.isFinite(ext.connectionTimeout) &&\n ext.connectionTimeout >= 1000\n ) {\n extTarget.connectionTimeout = Math.floor(ext.connectionTimeout);\n }\n if (Object.keys(extTarget).length > 0) {\n target.extension = extTarget;\n } else {\n delete target.extension;\n }\n }\n }\n if (br.cloakbrowser !== undefined) {\n if (br.cloakbrowser === null) {\n delete target.cloakbrowser;\n } else if (typeof br.cloakbrowser === 'object' && !Array.isArray(br.cloakbrowser)) {\n const cloakbrowserPatch = br.cloakbrowser as Record<string, unknown>;\n const cloakbrowserTarget: Record<string, unknown> = {};\n if (typeof cloakbrowserPatch.keepOpen === 'boolean') {\n cloakbrowserTarget.keepOpen = cloakbrowserPatch.keepOpen;\n }\n if (typeof cloakbrowserPatch.temporaryProfile === 'boolean') {\n cloakbrowserTarget.temporaryProfile = cloakbrowserPatch.temporaryProfile;\n }\n for (const key of ['cacheDir', 'binaryPath', 'timezone', 'locale', 'webrtcIp', 'fingerprintPlatform']) {\n const value = cloakbrowserPatch[key];\n if (typeof value === 'string' && value.trim()) {\n cloakbrowserTarget[key] = value.trim();\n }\n }\n if (\n Array.isArray(cloakbrowserPatch.extraArgs) &&\n cloakbrowserPatch.extraArgs.every((value) => typeof value === 'string')\n ) {\n cloakbrowserTarget.extraArgs = cloakbrowserPatch.extraArgs;\n }\n if (Object.keys(cloakbrowserTarget).length > 0) {\n target.cloakbrowser = cloakbrowserTarget;\n } else {\n delete target.cloakbrowser;\n }\n }\n }\n if (br.humanize !== undefined) {\n if (br.humanize === null) {\n delete target.humanize;\n } else {\n target.humanize = Boolean(br.humanize);\n }\n }\n if (br.humanPreset !== undefined) {\n if (br.humanPreset === null) {\n delete target.humanPreset;\n } else if (br.humanPreset === 'default' || br.humanPreset === 'careful') {\n target.humanPreset = br.humanPreset;\n }\n }\n if (br.dialogPolicy !== undefined) {\n if (br.dialogPolicy === null) {\n delete target.dialogPolicy;\n } else if (\n br.dialogPolicy === 'must_respond' ||\n br.dialogPolicy === 'auto_dismiss' ||\n br.dialogPolicy === 'auto_accept'\n ) {\n target.dialogPolicy = br.dialogPolicy;\n }\n }\n if (br.dialogTimeoutSeconds !== undefined) {\n if (br.dialogTimeoutSeconds === null) {\n delete target.dialogTimeoutSeconds;\n } else if (typeof br.dialogTimeoutSeconds === 'number' && Number.isFinite(br.dialogTimeoutSeconds)) {\n const n = Math.floor(br.dialogTimeoutSeconds);\n if (n >= 1 && n <= 86_400) {\n target.dialogTimeoutSeconds = n;\n }\n }\n }\n }\n }\n\n const dPatch = body.agents.defaults as Record<string, unknown>;\n const def = config.agents.defaults as Record<string, unknown>;\n\n if (dPatch.maxTaskDurationMs !== undefined) {\n const v = dPatch.maxTaskDurationMs;\n if (v === null) {\n delete def.maxTaskDurationMs;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const ms = Math.floor(v);\n if (ms >= 60_000 && ms <= 14_400_000) {\n def.maxTaskDurationMs = ms;\n }\n }\n }\n if (dPatch.maxRequestsPerTurn !== undefined) {\n const v = dPatch.maxRequestsPerTurn;\n if (v === null) {\n delete def.maxRequestsPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 10 && n <= 200) {\n def.maxRequestsPerTurn = n;\n }\n }\n }\n if (dPatch.maxToolFailuresPerTurn !== undefined) {\n const v = dPatch.maxToolFailuresPerTurn;\n if (v === null) {\n delete def.maxToolFailuresPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 1 && n <= 20) {\n def.maxToolFailuresPerTurn = n;\n }\n }\n }\n\n if (dPatch.compaction !== undefined) {\n const c = dPatch.compaction;\n if (c === null) {\n delete def.compaction;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.compaction || typeof def.compaction !== 'object') {\n def.compaction = {};\n }\n const t = def.compaction as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (p.mode === 'default' || p.mode === 'safeguard') t.mode = p.mode;\n if (typeof p.reserveTokens === 'number' && Number.isFinite(p.reserveTokens)) {\n t.reserveTokens = Math.floor(p.reserveTokens);\n }\n if (typeof p.triggerThreshold === 'number' && Number.isFinite(p.triggerThreshold)) {\n const x = p.triggerThreshold;\n if (x >= 0.5 && x <= 0.95) t.triggerThreshold = x;\n }\n if (typeof p.minMessagesBeforeCompact === 'number' && Number.isFinite(p.minMessagesBeforeCompact)) {\n t.minMessagesBeforeCompact = Math.floor(p.minMessagesBeforeCompact);\n }\n if (typeof p.keepRecentMessages === 'number' && Number.isFinite(p.keepRecentMessages)) {\n t.keepRecentMessages = Math.floor(p.keepRecentMessages);\n }\n if (typeof p.evictionWindow === 'number' && Number.isFinite(p.evictionWindow)) {\n const x = p.evictionWindow;\n if (x >= 0.1 && x <= 0.5) t.evictionWindow = x;\n }\n if (typeof p.retentionWindow === 'number' && Number.isFinite(p.retentionWindow)) {\n const n = Math.floor(p.retentionWindow);\n if (n >= 3 && n <= 20) t.retentionWindow = n;\n }\n }\n }\n\n if (dPatch.pruning !== undefined) {\n const c = dPatch.pruning;\n if (c === null) {\n delete def.pruning;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.pruning || typeof def.pruning !== 'object') {\n def.pruning = {};\n }\n const t = def.pruning as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (typeof p.maxToolResultChars === 'number' && Number.isFinite(p.maxToolResultChars)) {\n t.maxToolResultChars = Math.floor(p.maxToolResultChars);\n }\n if (typeof p.headKeepRatio === 'number' && Number.isFinite(p.headKeepRatio)) {\n t.headKeepRatio = p.headKeepRatio;\n }\n if (typeof p.tailKeepRatio === 'number' && Number.isFinite(p.tailKeepRatio)) {\n t.tailKeepRatio = p.tailKeepRatio;\n }\n }\n }\n\n if (dPatch.memory !== undefined) {\n const c = dPatch.memory;\n if (c === null) {\n delete def.memory;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.memory || typeof def.memory !== 'object') {\n def.memory = {};\n }\n const t = def.memory as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.useEnhancedSystem !== undefined) {\n if (p.useEnhancedSystem === null) delete t.useEnhancedSystem;\n else t.useEnhancedSystem = Boolean(p.useEnhancedSystem);\n }\n if (p.userProfileEnabled !== undefined) {\n if (p.userProfileEnabled === null) delete t.userProfileEnabled;\n else t.userProfileEnabled = Boolean(p.userProfileEnabled);\n }\n if (p.memoryCharLimit !== undefined) {\n if (p.memoryCharLimit === null) delete t.memoryCharLimit;\n else if (typeof p.memoryCharLimit === 'number' && p.memoryCharLimit > 0) {\n t.memoryCharLimit = Math.floor(p.memoryCharLimit);\n }\n }\n if (p.userCharLimit !== undefined) {\n if (p.userCharLimit === null) delete t.userCharLimit;\n else if (typeof p.userCharLimit === 'number' && p.userCharLimit > 0) {\n t.userCharLimit = Math.floor(p.userCharLimit);\n }\n }\n if (p.provider === 'none' || p.provider === 'stub') {\n t.provider = p.provider;\n } else if (p.provider === null) {\n delete t.provider;\n }\n if (p.injectionFrequency === 'every-turn' || p.injectionFrequency === 'first-turn') {\n t.injectionFrequency = p.injectionFrequency;\n } else if (p.injectionFrequency === null) {\n delete t.injectionFrequency;\n }\n if (p.contextCadence !== undefined) {\n if (p.contextCadence === null) delete t.contextCadence;\n else if (typeof p.contextCadence === 'number' && p.contextCadence >= 1) {\n t.contextCadence = Math.floor(p.contextCadence);\n }\n }\n if (p.dialecticCadence !== undefined) {\n if (p.dialecticCadence === null) delete t.dialecticCadence;\n else if (typeof p.dialecticCadence === 'number' && p.dialecticCadence >= 1) {\n t.dialecticCadence = Math.floor(p.dialecticCadence);\n }\n }\n\n // Dreaming (schemaless patch): agents.defaults.memory.dreaming\n if (p.dreaming !== undefined) {\n const d0 = p.dreaming;\n if (d0 === null) {\n delete (t as { dreaming?: unknown }).dreaming;\n } else if (typeof d0 === 'object' && d0 !== null && !Array.isArray(d0)) {\n if (!('dreaming' in t) || typeof (t as { dreaming?: unknown }).dreaming !== 'object') {\n (t as { dreaming?: Record<string, unknown> }).dreaming = {};\n }\n const dt = (t as { dreaming: Record<string, unknown> }).dreaming;\n const dp = d0 as Record<string, unknown>;\n\n if (dp.enabled !== undefined) {\n if (dp.enabled === null) delete dt.enabled;\n else dt.enabled = Boolean(dp.enabled);\n }\n if (dp.frequency !== undefined) {\n const v = dp.frequency;\n if (v === null || v === '') delete dt.frequency;\n else if (typeof v === 'string') dt.frequency = v;\n }\n if (dp.timezone !== undefined) {\n const v = dp.timezone;\n if (v === null || v === '') delete dt.timezone;\n else if (typeof v === 'string') dt.timezone = v;\n }\n\n // Accept either `phases.deep` or `deep`.\n if (dp.phases !== undefined || dp.deep !== undefined) {\n if (!('phases' in dt) || typeof (dt as { phases?: unknown }).phases !== 'object' || (dt as { phases?: unknown }).phases === null) {\n dt.phases = {};\n }\n const phases = (dt as { phases: Record<string, unknown> }).phases;\n if (!('deep' in phases) || typeof phases.deep !== 'object' || phases.deep === null) {\n phases.deep = {};\n }\n const deep = phases.deep as Record<string, unknown>;\n\n const deepPatchRaw =\n typeof dp.phases === 'object' && dp.phases !== null && !Array.isArray(dp.phases)\n ? (dp.phases as Record<string, unknown>).deep\n : dp.deep;\n const deepPatch =\n typeof deepPatchRaw === 'object' && deepPatchRaw !== null && !Array.isArray(deepPatchRaw)\n ? (deepPatchRaw as Record<string, unknown>)\n : null;\n\n if (deepPatch) {\n if (deepPatch.enabled !== undefined) {\n if (deepPatch.enabled === null) delete deep.enabled;\n else deep.enabled = Boolean(deepPatch.enabled);\n }\n if (deepPatch.minScore !== undefined) {\n const v = deepPatch.minScore;\n if (v === null) delete deep.minScore;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minScore = v;\n }\n if (deepPatch.minRecallCount !== undefined) {\n const v = deepPatch.minRecallCount;\n if (v === null) delete deep.minRecallCount;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minRecallCount = Math.floor(v);\n }\n if (deepPatch.limit !== undefined) {\n const v = deepPatch.limit;\n if (v === null) delete deep.limit;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.limit = Math.floor(v);\n }\n }\n }\n }\n }\n }\n }\n\n if (dPatch.sessionSearch !== undefined) {\n const c = dPatch.sessionSearch;\n if (c === null) {\n delete def.sessionSearch;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.sessionSearch || typeof def.sessionSearch !== 'object') {\n def.sessionSearch = {};\n }\n const t = def.sessionSearch as Record<string, unknown>;\n if (p.summaryModel !== undefined) {\n if (p.summaryModel === null || p.summaryModel === '') {\n delete t.summaryModel;\n } else if (typeof p.summaryModel === 'string') {\n t.summaryModel = p.summaryModel;\n }\n }\n }\n }\n\n if (dPatch.backgroundReview !== undefined) {\n const c = dPatch.backgroundReview;\n if (c === null) {\n delete def.backgroundReview;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.backgroundReview || typeof def.backgroundReview !== 'object') {\n def.backgroundReview = {};\n }\n const t = def.backgroundReview as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.memoryNudgeInterval !== undefined) {\n if (p.memoryNudgeInterval === null) delete t.memoryNudgeInterval;\n else if (typeof p.memoryNudgeInterval === 'number' && p.memoryNudgeInterval >= 0) {\n t.memoryNudgeInterval = Math.floor(p.memoryNudgeInterval);\n }\n }\n if (p.skillNudgeInterval !== undefined) {\n if (p.skillNudgeInterval === null) delete t.skillNudgeInterval;\n else if (typeof p.skillNudgeInterval === 'number' && p.skillNudgeInterval >= 0) {\n t.skillNudgeInterval = Math.floor(p.skillNudgeInterval);\n }\n }\n if (p.maxToolRounds !== undefined) {\n if (p.maxToolRounds === null) delete t.maxToolRounds;\n else if (typeof p.maxToolRounds === 'number' && p.maxToolRounds >= 1 && p.maxToolRounds <= 32) {\n t.maxToolRounds = Math.floor(p.maxToolRounds);\n }\n }\n if (p.maxHistoryMessages !== undefined) {\n if (p.maxHistoryMessages === null) delete t.maxHistoryMessages;\n else if (typeof p.maxHistoryMessages === 'number' && p.maxHistoryMessages >= 10 && p.maxHistoryMessages <= 200) {\n t.maxHistoryMessages = Math.floor(p.maxHistoryMessages);\n }\n }\n if (p.maxDurationMs !== undefined) {\n if (p.maxDurationMs === null) delete t.maxDurationMs;\n else if (typeof p.maxDurationMs === 'number' && p.maxDurationMs >= 30_000 && p.maxDurationMs <= 600_000) {\n t.maxDurationMs = Math.floor(p.maxDurationMs);\n }\n }\n }\n }\n\n if (dPatch.webExtract !== undefined) {\n const c = dPatch.webExtract;\n if (c === null) {\n delete def.webExtract;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.webExtract || typeof def.webExtract !== 'object') {\n def.webExtract = {};\n }\n const t = def.webExtract as Record<string, unknown>;\n if (p.model !== undefined) {\n if (p.model === null || p.model === '') {\n delete t.model;\n } else if (typeof p.model === 'string') {\n t.model = p.model;\n }\n }\n if (p.maxLength !== undefined) {\n if (p.maxLength === null) delete t.maxLength;\n else if (typeof p.maxLength === 'number' && p.maxLength > 0) {\n t.maxLength = p.maxLength;\n }\n }\n }\n }\n\n if (dPatch.delegate !== undefined) {\n const c = dPatch.delegate;\n if (c === null) {\n delete def.delegate;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.delegate || typeof def.delegate !== 'object') {\n def.delegate = {};\n }\n const t = def.delegate as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.executeCode !== undefined) {\n const c = dPatch.executeCode;\n if (c === null) {\n delete def.executeCode;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.executeCode || typeof def.executeCode !== 'object') {\n def.executeCode = {};\n }\n const t = def.executeCode as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.systemPromptOverride !== undefined) {\n const v = dPatch.systemPromptOverride;\n if (v === null || v === '') {\n delete def.systemPromptOverride;\n } else if (typeof v === 'string') {\n def.systemPromptOverride = v;\n }\n }\n\n if (dPatch.skills !== undefined) {\n const v = dPatch.skills;\n if (v === null) {\n delete def.skills;\n } else if (Array.isArray(v) && v.every((x) => typeof x === 'string')) {\n def.skills = v;\n }\n }\n\n if (dPatch.models !== undefined) {\n const normalized = normalizePatchTypedModels(dPatch.models);\n if (normalized === undefined) {\n // skip invalid shape\n } else if (normalized === null) {\n delete def.models;\n } else {\n def.models = normalized;\n }\n }\n\n if (dPatch.tools !== undefined) {\n const t0 = dPatch.tools;\n if (t0 === null) {\n delete def.tools;\n } else if (typeof t0 === 'object' && !Array.isArray(t0)) {\n const p = t0 as { disable?: unknown };\n if (!def.tools || typeof def.tools !== 'object') {\n def.tools = {};\n }\n const t = def.tools as { disable?: string[] };\n if (p.disable !== undefined) {\n if (p.disable === null || (Array.isArray(p.disable) && p.disable.length === 0)) {\n delete t.disable;\n } else if (Array.isArray(p.disable) && p.disable.every((x) => typeof x === 'string')) {\n t.disable = p.disable;\n }\n }\n }\n }\n\n if (dPatch.params !== undefined) {\n const v = dPatch.params;\n if (v === null) {\n delete def.params;\n } else if (typeof v === 'object' && !Array.isArray(v) && v !== null) {\n def.params = v as Record<string, unknown>;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isValidIPv4 } from "../../../../config/gateway-bind.js";
|
|
2
2
|
import { mergeShareConfigPatch } from "../../../../share/share-config.js";
|
|
3
|
+
import { isMaskedSecretPatchValue } from "../../lib/mask-secret-length.js";
|
|
3
4
|
import { PATCH_OK, patchError } from "./result.js";
|
|
4
5
|
//#region src/gateway/hono/routes/config-patch/gateway.ts
|
|
5
6
|
/**
|
|
@@ -149,11 +150,11 @@ function applyGatewayPatch(config, body) {
|
|
|
149
150
|
}
|
|
150
151
|
if (a.token !== void 0) {
|
|
151
152
|
if (a.token === null || typeof a.token === "string" && !a.token.trim()) delete gw.auth.token;
|
|
152
|
-
else if (typeof a.token === "string") gw.auth.token = a.token;
|
|
153
|
+
else if (typeof a.token === "string" && !isMaskedSecretPatchValue(a.token)) gw.auth.token = a.token;
|
|
153
154
|
}
|
|
154
155
|
if (a.password !== void 0) {
|
|
155
156
|
if (a.password === null || typeof a.password === "string" && !a.password.trim()) delete gw.auth.password;
|
|
156
|
-
else if (typeof a.password === "string" && a.password
|
|
157
|
+
else if (typeof a.password === "string" && !isMaskedSecretPatchValue(a.password)) gw.auth.password = a.password;
|
|
157
158
|
}
|
|
158
159
|
if (a.rateLimit !== void 0 && typeof a.rateLimit === "object" && a.rateLimit !== null) {
|
|
159
160
|
const rlIn = a.rateLimit;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.js","names":[],"sources":["../../../../../../src/gateway/hono/routes/config-patch/gateway.ts"],"sourcesContent":["/**\n * `PATCH /api/config` — `body.gateway.*` section.\n *\n * Covers heartbeat, bind/customBindHost/port, tailscale, auth (mode + token +\n * password + rateLimit + trustedProxy), trustedProxies, allowRealIpFallback,\n * dangerouslyAllowHostHeaderOriginFallback, security, share, corsOrigins,\n * maxSseConnections, and channelConnectDefer{Mode,Ids,SkipIds}.\n *\n * Validation policy: each subsection that can reject rejects with a 400 and a\n * specific `message`. The dispatcher converts these into `c.json(...)`.\n *\n * Initial-state branches use the same literal defaults the inline code did\n * (loopback + port 18790 + 1800s heartbeat + 100 SSE conn + empty CORS) so\n * a brand-new install gets a working gateway after the first PATCH.\n */\nimport type { Config, GatewayBindMode } from '../../../../config/schema.js';\nimport { isValidIPv4 } from '../../../../config/gateway-bind.js';\nimport { mergeShareConfigPatch } from '../../../../share/share-config.js';\nimport { type PatchResult, PATCH_OK, patchError } from './result.js';\n\n/**\n * Shared default for \"user PATCH'd a gateway subsection but `config.gateway`\n * was never initialised\". Identical to the inline literal repeated in the\n * pre-extraction handler so this is behavior-preserving.\n */\nfunction ensureGateway(config: Config): NonNullable<Config['gateway']> {\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n }\n return config.gateway;\n}\n\nfunction parseDeferIdList(raw: unknown): string[] | null {\n if (!Array.isArray(raw)) return null;\n const ids = raw\n .filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x) => x.trim());\n if (ids.length > 24) return null;\n return ids;\n}\n\nexport function applyGatewayPatch(config: Config, body: any): PatchResult {\n if (body.gateway?.heartbeat !== undefined && typeof body.gateway.heartbeat === 'object') {\n const gw = ensureGateway(config);\n if (!gw.heartbeat) {\n gw.heartbeat = { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false };\n }\n const h = gw.heartbeat;\n const p = body.gateway.heartbeat as Record<string, unknown>;\n if (p.enabled !== undefined) h.enabled = Boolean(p.enabled);\n if (p.intervalMs !== undefined && typeof p.intervalMs === 'number' && Number.isFinite(p.intervalMs)) {\n h.intervalMs = p.intervalMs;\n }\n if (p.includeSystemPromptSection !== undefined) {\n h.includeSystemPromptSection = Boolean(p.includeSystemPromptSection);\n }\n if (p.target !== undefined) {\n if (p.target === null || p.target === '') delete (h as { target?: string }).target;\n else (h as { target?: string }).target = String(p.target);\n }\n if (p.targetChatId !== undefined) {\n if (p.targetChatId === null || p.targetChatId === '') delete (h as { targetChatId?: string }).targetChatId;\n else (h as { targetChatId?: string }).targetChatId = String(p.targetChatId);\n }\n if (p.prompt !== undefined) {\n if (p.prompt === null || p.prompt === '') delete (h as { prompt?: string }).prompt;\n else (h as { prompt?: string }).prompt = String(p.prompt);\n }\n if (p.ackMaxChars !== undefined) {\n if (p.ackMaxChars === null || p.ackMaxChars === '') delete (h as { ackMaxChars?: number }).ackMaxChars;\n else if (typeof p.ackMaxChars === 'number' && Number.isFinite(p.ackMaxChars)) {\n (h as { ackMaxChars?: number }).ackMaxChars = p.ackMaxChars;\n }\n }\n if (p.isolatedSession !== undefined) {\n if (p.isolatedSession === null || p.isolatedSession === false) {\n delete (h as { isolatedSession?: boolean }).isolatedSession;\n } else {\n (h as { isolatedSession?: boolean }).isolatedSession = Boolean(p.isolatedSession);\n }\n }\n if (p.activeHours !== undefined) {\n if (p.activeHours === null) {\n delete (h as { activeHours?: unknown }).activeHours;\n } else if (typeof p.activeHours === 'object' && p.activeHours !== null) {\n const ah = p.activeHours as Record<string, unknown>;\n const start = typeof ah.start === 'string' ? ah.start : '';\n const end = typeof ah.end === 'string' ? ah.end : '';\n if (start && end) {\n (h as { activeHours?: { start: string; end: string; timezone?: string } }).activeHours = {\n start,\n end,\n ...(typeof ah.timezone === 'string' && ah.timezone.trim() ? { timezone: ah.timezone } : {}),\n };\n } else {\n delete (h as { activeHours?: unknown }).activeHours;\n }\n }\n }\n }\n\n if (body.gateway?.bind !== undefined) {\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bind = body.gateway.bind;\n if (typeof bind !== 'string' || !bindModes.has(bind)) {\n return patchError('gateway.bind must be one of: auto, loopback, lan, tailnet, custom');\n }\n if (!config.gateway) {\n config.gateway = {\n bind: bind as GatewayBindMode,\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n } else {\n config.gateway.bind = bind as GatewayBindMode;\n }\n if (bind !== 'custom') {\n delete config.gateway.customBindHost;\n }\n }\n\n if (body.gateway?.customBindHost !== undefined) {\n if (body.gateway.customBindHost === null || body.gateway.customBindHost === '') {\n if (config.gateway) {\n delete config.gateway.customBindHost;\n }\n } else if (typeof body.gateway.customBindHost !== 'string' || !isValidIPv4(body.gateway.customBindHost.trim())) {\n return patchError('gateway.customBindHost must be a valid IPv4 address');\n } else if (config.gateway) {\n config.gateway.customBindHost = body.gateway.customBindHost.trim();\n config.gateway.bind = 'custom';\n }\n }\n\n if (body.gateway?.port !== undefined) {\n if (\n typeof body.gateway.port !== 'number' ||\n !Number.isFinite(body.gateway.port) ||\n body.gateway.port < 1 ||\n body.gateway.port > 65535\n ) {\n return patchError('gateway.port must be an integer from 1 to 65535');\n }\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: Math.floor(body.gateway.port),\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n } else {\n config.gateway.port = Math.floor(body.gateway.port);\n }\n }\n\n if (body.gateway?.tailscale !== undefined && typeof body.gateway.tailscale === 'object') {\n const ts = body.gateway.tailscale as Record<string, unknown>;\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: 18790,\n auth: { mode: 'token' },\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n }\n config.gateway.tailscale = {\n ...(config.gateway.tailscale ?? { mode: 'off', resetOnExit: true }),\n };\n if (ts.mode !== undefined) {\n if (ts.mode !== 'off' && ts.mode !== 'serve' && ts.mode !== 'funnel') {\n return patchError('gateway.tailscale.mode must be off, serve, or funnel');\n }\n config.gateway.tailscale.mode = ts.mode as 'off' | 'serve' | 'funnel';\n }\n if (ts.resetOnExit !== undefined) {\n config.gateway.tailscale.resetOnExit = ts.resetOnExit === true;\n }\n }\n\n if (body.gateway?.auth !== undefined) {\n const gw = ensureGateway(config);\n if (!gw.auth) gw.auth = { mode: 'token' };\n const a = body.gateway.auth;\n if (a.mode !== undefined) {\n if (\n a.mode !== 'none' &&\n a.mode !== 'token' &&\n a.mode !== 'password' &&\n a.mode !== 'trusted-proxy'\n ) {\n return patchError('gateway.auth.mode must be none, token, password, or trusted-proxy');\n }\n gw.auth.mode = a.mode;\n }\n if (a.token !== undefined) {\n if (a.token === null || (typeof a.token === 'string' && !a.token.trim())) {\n delete gw.auth.token;\n } else if (typeof a.token === 'string') {\n gw.auth.token = a.token;\n }\n }\n if (a.password !== undefined) {\n if (a.password === null || (typeof a.password === 'string' && !a.password.trim())) {\n delete gw.auth.password;\n } else if (\n typeof a.password === 'string' &&\n a.password !== '***' &&\n a.password !== '••••••••••••'\n ) {\n gw.auth.password = a.password;\n }\n }\n if (a.rateLimit !== undefined && typeof a.rateLimit === 'object' && a.rateLimit !== null) {\n const rlIn = a.rateLimit as Record<string, unknown>;\n if (!gw.auth.rateLimit) {\n gw.auth.rateLimit = {\n enabled: true,\n maxAttempts: 5,\n windowMs: 900_000,\n blockDurationMs: 300_000,\n burstCoalesceMs: 1000,\n exemptLoopback: true,\n };\n }\n const rl = gw.auth.rateLimit!;\n if (rlIn.enabled !== undefined) rl.enabled = Boolean(rlIn.enabled);\n if (typeof rlIn.maxAttempts === 'number' && Number.isFinite(rlIn.maxAttempts)) {\n rl.maxAttempts = Math.max(1, Math.floor(rlIn.maxAttempts));\n }\n if (typeof rlIn.windowMs === 'number' && Number.isFinite(rlIn.windowMs) && rlIn.windowMs > 0) {\n rl.windowMs = Math.floor(rlIn.windowMs);\n }\n if (\n typeof rlIn.blockDurationMs === 'number' &&\n Number.isFinite(rlIn.blockDurationMs) &&\n rlIn.blockDurationMs > 0\n ) {\n rl.blockDurationMs = Math.floor(rlIn.blockDurationMs);\n }\n if (\n typeof rlIn.lockoutMs === 'number' &&\n Number.isFinite(rlIn.lockoutMs) &&\n rlIn.lockoutMs > 0\n ) {\n rl.blockDurationMs = Math.floor(rlIn.lockoutMs);\n }\n if (rlIn.exemptLoopback !== undefined) {\n rl.exemptLoopback = Boolean(rlIn.exemptLoopback);\n }\n }\n if (a.trustedProxy !== undefined) {\n if (a.trustedProxy === null) {\n delete gw.auth.trustedProxy;\n } else if (typeof a.trustedProxy === 'object' && a.trustedProxy !== null) {\n const tpIn = a.trustedProxy as Record<string, unknown>;\n const userHeader =\n typeof tpIn.userHeader === 'string' ? tpIn.userHeader.trim() : '';\n if (!userHeader) {\n return patchError('gateway.auth.trustedProxy.userHeader is required');\n }\n const trustedProxy: NonNullable<(typeof gw.auth)['trustedProxy']> = {\n userHeader,\n };\n if (tpIn.requiredHeaders !== undefined) {\n if (!Array.isArray(tpIn.requiredHeaders)) {\n return patchError('gateway.auth.trustedProxy.requiredHeaders must be an array');\n }\n trustedProxy.requiredHeaders = tpIn.requiredHeaders\n .filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x) => x.trim());\n }\n if (tpIn.allowUsers !== undefined) {\n if (!Array.isArray(tpIn.allowUsers)) {\n return patchError('gateway.auth.trustedProxy.allowUsers must be an array');\n }\n trustedProxy.allowUsers = tpIn.allowUsers\n .filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x) => x.trim());\n }\n if (tpIn.allowLoopback !== undefined) {\n trustedProxy.allowLoopback = Boolean(tpIn.allowLoopback);\n }\n gw.auth.trustedProxy = trustedProxy;\n }\n }\n }\n\n if (body.gateway?.trustedProxies !== undefined) {\n if (!Array.isArray(body.gateway.trustedProxies)) {\n return patchError('gateway.trustedProxies must be an array');\n }\n const gw = ensureGateway(config);\n gw.trustedProxies = body.gateway.trustedProxies\n .filter((x: unknown): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x: string) => x.trim());\n }\n\n if (body.gateway?.allowRealIpFallback !== undefined) {\n const gw = ensureGateway(config);\n gw.allowRealIpFallback = Boolean(body.gateway.allowRealIpFallback);\n }\n\n if (body.gateway?.dangerouslyAllowHostHeaderOriginFallback !== undefined) {\n const gw = ensureGateway(config);\n gw.dangerouslyAllowHostHeaderOriginFallback = Boolean(\n body.gateway.dangerouslyAllowHostHeaderOriginFallback,\n );\n }\n\n if (body.gateway?.security !== undefined) {\n if (typeof body.gateway.security !== 'object' || body.gateway.security === null) {\n return patchError('gateway.security must be an object');\n }\n const gw = ensureGateway(config);\n const secIn = body.gateway.security as Record<string, unknown>;\n if (!gw.security) {\n gw.security = {};\n }\n if (secIn.strict !== undefined) {\n gw.security.strict = Boolean(secIn.strict);\n }\n }\n\n if (body.gateway?.share !== undefined) {\n if (typeof body.gateway.share !== 'object' || body.gateway.share === null || Array.isArray(body.gateway.share)) {\n return patchError('gateway.share must be an object');\n }\n const shareResult = mergeShareConfigPatch(config, body.gateway.share as Record<string, unknown>);\n if (shareResult.ok === false) {\n return patchError(shareResult.message);\n }\n }\n\n if (body.gateway?.corsOrigins !== undefined) {\n if (!Array.isArray(body.gateway.corsOrigins)) {\n return patchError('gateway.corsOrigins must be an array');\n }\n const gw = ensureGateway(config);\n gw.corsOrigins = body.gateway.corsOrigins\n .filter((x: unknown): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x: string) => x.trim());\n }\n\n if (body.gateway?.maxSseConnections !== undefined) {\n if (\n typeof body.gateway.maxSseConnections !== 'number' ||\n !Number.isFinite(body.gateway.maxSseConnections) ||\n body.gateway.maxSseConnections < 1\n ) {\n return patchError('gateway.maxSseConnections must be a positive integer');\n }\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: Math.floor(body.gateway.maxSseConnections),\n corsOrigins: [],\n };\n } else {\n config.gateway.maxSseConnections = Math.floor(body.gateway.maxSseConnections);\n }\n }\n\n if (body.gateway?.channelConnectDeferMode !== undefined) {\n const mode = body.gateway.channelConnectDeferMode;\n if (mode !== 'auto' && mode !== 'off' && mode !== 'explicit') {\n return patchError('gateway.channelConnectDeferMode must be auto, off, or explicit');\n }\n const gw = ensureGateway(config);\n gw.channelConnectDeferMode = mode;\n }\n\n if (body.gateway?.channelConnectDeferIds !== undefined) {\n const ids = parseDeferIdList(body.gateway.channelConnectDeferIds);\n if (ids === null) {\n return patchError('gateway.channelConnectDeferIds must be an array of up to 24 strings');\n }\n const gw = ensureGateway(config);\n gw.channelConnectDeferIds = ids;\n }\n\n if (body.gateway?.channelConnectDeferSkipIds !== undefined) {\n const ids = parseDeferIdList(body.gateway.channelConnectDeferSkipIds);\n if (ids === null) {\n return patchError('gateway.channelConnectDeferSkipIds must be an array of up to 24 strings');\n }\n const gw = ensureGateway(config);\n gw.channelConnectDeferSkipIds = ids;\n }\n\n return PATCH_OK;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gateway.js","names":[],"sources":["../../../../../../src/gateway/hono/routes/config-patch/gateway.ts"],"sourcesContent":["/**\n * `PATCH /api/config` — `body.gateway.*` section.\n *\n * Covers heartbeat, bind/customBindHost/port, tailscale, auth (mode + token +\n * password + rateLimit + trustedProxy), trustedProxies, allowRealIpFallback,\n * dangerouslyAllowHostHeaderOriginFallback, security, share, corsOrigins,\n * maxSseConnections, and channelConnectDefer{Mode,Ids,SkipIds}.\n *\n * Validation policy: each subsection that can reject rejects with a 400 and a\n * specific `message`. The dispatcher converts these into `c.json(...)`.\n *\n * Initial-state branches use the same literal defaults the inline code did\n * (loopback + port 18790 + 1800s heartbeat + 100 SSE conn + empty CORS) so\n * a brand-new install gets a working gateway after the first PATCH.\n */\nimport type { Config, GatewayBindMode } from '../../../../config/schema.js';\nimport { isValidIPv4 } from '../../../../config/gateway-bind.js';\nimport { mergeShareConfigPatch } from '../../../../share/share-config.js';\nimport { isMaskedSecretPatchValue } from '../../lib/mask-secret-length.js';\nimport { type PatchResult, PATCH_OK, patchError } from './result.js';\n\n/**\n * Shared default for \"user PATCH'd a gateway subsection but `config.gateway`\n * was never initialised\". Identical to the inline literal repeated in the\n * pre-extraction handler so this is behavior-preserving.\n */\nfunction ensureGateway(config: Config): NonNullable<Config['gateway']> {\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n }\n return config.gateway;\n}\n\nfunction parseDeferIdList(raw: unknown): string[] | null {\n if (!Array.isArray(raw)) return null;\n const ids = raw\n .filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x) => x.trim());\n if (ids.length > 24) return null;\n return ids;\n}\n\nexport function applyGatewayPatch(config: Config, body: any): PatchResult {\n if (body.gateway?.heartbeat !== undefined && typeof body.gateway.heartbeat === 'object') {\n const gw = ensureGateway(config);\n if (!gw.heartbeat) {\n gw.heartbeat = { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false };\n }\n const h = gw.heartbeat;\n const p = body.gateway.heartbeat as Record<string, unknown>;\n if (p.enabled !== undefined) h.enabled = Boolean(p.enabled);\n if (p.intervalMs !== undefined && typeof p.intervalMs === 'number' && Number.isFinite(p.intervalMs)) {\n h.intervalMs = p.intervalMs;\n }\n if (p.includeSystemPromptSection !== undefined) {\n h.includeSystemPromptSection = Boolean(p.includeSystemPromptSection);\n }\n if (p.target !== undefined) {\n if (p.target === null || p.target === '') delete (h as { target?: string }).target;\n else (h as { target?: string }).target = String(p.target);\n }\n if (p.targetChatId !== undefined) {\n if (p.targetChatId === null || p.targetChatId === '') delete (h as { targetChatId?: string }).targetChatId;\n else (h as { targetChatId?: string }).targetChatId = String(p.targetChatId);\n }\n if (p.prompt !== undefined) {\n if (p.prompt === null || p.prompt === '') delete (h as { prompt?: string }).prompt;\n else (h as { prompt?: string }).prompt = String(p.prompt);\n }\n if (p.ackMaxChars !== undefined) {\n if (p.ackMaxChars === null || p.ackMaxChars === '') delete (h as { ackMaxChars?: number }).ackMaxChars;\n else if (typeof p.ackMaxChars === 'number' && Number.isFinite(p.ackMaxChars)) {\n (h as { ackMaxChars?: number }).ackMaxChars = p.ackMaxChars;\n }\n }\n if (p.isolatedSession !== undefined) {\n if (p.isolatedSession === null || p.isolatedSession === false) {\n delete (h as { isolatedSession?: boolean }).isolatedSession;\n } else {\n (h as { isolatedSession?: boolean }).isolatedSession = Boolean(p.isolatedSession);\n }\n }\n if (p.activeHours !== undefined) {\n if (p.activeHours === null) {\n delete (h as { activeHours?: unknown }).activeHours;\n } else if (typeof p.activeHours === 'object' && p.activeHours !== null) {\n const ah = p.activeHours as Record<string, unknown>;\n const start = typeof ah.start === 'string' ? ah.start : '';\n const end = typeof ah.end === 'string' ? ah.end : '';\n if (start && end) {\n (h as { activeHours?: { start: string; end: string; timezone?: string } }).activeHours = {\n start,\n end,\n ...(typeof ah.timezone === 'string' && ah.timezone.trim() ? { timezone: ah.timezone } : {}),\n };\n } else {\n delete (h as { activeHours?: unknown }).activeHours;\n }\n }\n }\n }\n\n if (body.gateway?.bind !== undefined) {\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bind = body.gateway.bind;\n if (typeof bind !== 'string' || !bindModes.has(bind)) {\n return patchError('gateway.bind must be one of: auto, loopback, lan, tailnet, custom');\n }\n if (!config.gateway) {\n config.gateway = {\n bind: bind as GatewayBindMode,\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n } else {\n config.gateway.bind = bind as GatewayBindMode;\n }\n if (bind !== 'custom') {\n delete config.gateway.customBindHost;\n }\n }\n\n if (body.gateway?.customBindHost !== undefined) {\n if (body.gateway.customBindHost === null || body.gateway.customBindHost === '') {\n if (config.gateway) {\n delete config.gateway.customBindHost;\n }\n } else if (typeof body.gateway.customBindHost !== 'string' || !isValidIPv4(body.gateway.customBindHost.trim())) {\n return patchError('gateway.customBindHost must be a valid IPv4 address');\n } else if (config.gateway) {\n config.gateway.customBindHost = body.gateway.customBindHost.trim();\n config.gateway.bind = 'custom';\n }\n }\n\n if (body.gateway?.port !== undefined) {\n if (\n typeof body.gateway.port !== 'number' ||\n !Number.isFinite(body.gateway.port) ||\n body.gateway.port < 1 ||\n body.gateway.port > 65535\n ) {\n return patchError('gateway.port must be an integer from 1 to 65535');\n }\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: Math.floor(body.gateway.port),\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n } else {\n config.gateway.port = Math.floor(body.gateway.port);\n }\n }\n\n if (body.gateway?.tailscale !== undefined && typeof body.gateway.tailscale === 'object') {\n const ts = body.gateway.tailscale as Record<string, unknown>;\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: 18790,\n auth: { mode: 'token' },\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: [],\n };\n }\n config.gateway.tailscale = {\n ...(config.gateway.tailscale ?? { mode: 'off', resetOnExit: true }),\n };\n if (ts.mode !== undefined) {\n if (ts.mode !== 'off' && ts.mode !== 'serve' && ts.mode !== 'funnel') {\n return patchError('gateway.tailscale.mode must be off, serve, or funnel');\n }\n config.gateway.tailscale.mode = ts.mode as 'off' | 'serve' | 'funnel';\n }\n if (ts.resetOnExit !== undefined) {\n config.gateway.tailscale.resetOnExit = ts.resetOnExit === true;\n }\n }\n\n if (body.gateway?.auth !== undefined) {\n const gw = ensureGateway(config);\n if (!gw.auth) gw.auth = { mode: 'token' };\n const a = body.gateway.auth;\n if (a.mode !== undefined) {\n if (\n a.mode !== 'none' &&\n a.mode !== 'token' &&\n a.mode !== 'password' &&\n a.mode !== 'trusted-proxy'\n ) {\n return patchError('gateway.auth.mode must be none, token, password, or trusted-proxy');\n }\n gw.auth.mode = a.mode;\n }\n if (a.token !== undefined) {\n if (a.token === null || (typeof a.token === 'string' && !a.token.trim())) {\n delete gw.auth.token;\n } else if (typeof a.token === 'string' && !isMaskedSecretPatchValue(a.token)) {\n gw.auth.token = a.token;\n }\n }\n if (a.password !== undefined) {\n if (a.password === null || (typeof a.password === 'string' && !a.password.trim())) {\n delete gw.auth.password;\n } else if (typeof a.password === 'string' && !isMaskedSecretPatchValue(a.password)) {\n gw.auth.password = a.password;\n }\n }\n if (a.rateLimit !== undefined && typeof a.rateLimit === 'object' && a.rateLimit !== null) {\n const rlIn = a.rateLimit as Record<string, unknown>;\n if (!gw.auth.rateLimit) {\n gw.auth.rateLimit = {\n enabled: true,\n maxAttempts: 5,\n windowMs: 900_000,\n blockDurationMs: 300_000,\n burstCoalesceMs: 1000,\n exemptLoopback: true,\n };\n }\n const rl = gw.auth.rateLimit!;\n if (rlIn.enabled !== undefined) rl.enabled = Boolean(rlIn.enabled);\n if (typeof rlIn.maxAttempts === 'number' && Number.isFinite(rlIn.maxAttempts)) {\n rl.maxAttempts = Math.max(1, Math.floor(rlIn.maxAttempts));\n }\n if (typeof rlIn.windowMs === 'number' && Number.isFinite(rlIn.windowMs) && rlIn.windowMs > 0) {\n rl.windowMs = Math.floor(rlIn.windowMs);\n }\n if (\n typeof rlIn.blockDurationMs === 'number' &&\n Number.isFinite(rlIn.blockDurationMs) &&\n rlIn.blockDurationMs > 0\n ) {\n rl.blockDurationMs = Math.floor(rlIn.blockDurationMs);\n }\n if (\n typeof rlIn.lockoutMs === 'number' &&\n Number.isFinite(rlIn.lockoutMs) &&\n rlIn.lockoutMs > 0\n ) {\n rl.blockDurationMs = Math.floor(rlIn.lockoutMs);\n }\n if (rlIn.exemptLoopback !== undefined) {\n rl.exemptLoopback = Boolean(rlIn.exemptLoopback);\n }\n }\n if (a.trustedProxy !== undefined) {\n if (a.trustedProxy === null) {\n delete gw.auth.trustedProxy;\n } else if (typeof a.trustedProxy === 'object' && a.trustedProxy !== null) {\n const tpIn = a.trustedProxy as Record<string, unknown>;\n const userHeader =\n typeof tpIn.userHeader === 'string' ? tpIn.userHeader.trim() : '';\n if (!userHeader) {\n return patchError('gateway.auth.trustedProxy.userHeader is required');\n }\n const trustedProxy: NonNullable<(typeof gw.auth)['trustedProxy']> = {\n userHeader,\n };\n if (tpIn.requiredHeaders !== undefined) {\n if (!Array.isArray(tpIn.requiredHeaders)) {\n return patchError('gateway.auth.trustedProxy.requiredHeaders must be an array');\n }\n trustedProxy.requiredHeaders = tpIn.requiredHeaders\n .filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x) => x.trim());\n }\n if (tpIn.allowUsers !== undefined) {\n if (!Array.isArray(tpIn.allowUsers)) {\n return patchError('gateway.auth.trustedProxy.allowUsers must be an array');\n }\n trustedProxy.allowUsers = tpIn.allowUsers\n .filter((x): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x) => x.trim());\n }\n if (tpIn.allowLoopback !== undefined) {\n trustedProxy.allowLoopback = Boolean(tpIn.allowLoopback);\n }\n gw.auth.trustedProxy = trustedProxy;\n }\n }\n }\n\n if (body.gateway?.trustedProxies !== undefined) {\n if (!Array.isArray(body.gateway.trustedProxies)) {\n return patchError('gateway.trustedProxies must be an array');\n }\n const gw = ensureGateway(config);\n gw.trustedProxies = body.gateway.trustedProxies\n .filter((x: unknown): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x: string) => x.trim());\n }\n\n if (body.gateway?.allowRealIpFallback !== undefined) {\n const gw = ensureGateway(config);\n gw.allowRealIpFallback = Boolean(body.gateway.allowRealIpFallback);\n }\n\n if (body.gateway?.dangerouslyAllowHostHeaderOriginFallback !== undefined) {\n const gw = ensureGateway(config);\n gw.dangerouslyAllowHostHeaderOriginFallback = Boolean(\n body.gateway.dangerouslyAllowHostHeaderOriginFallback,\n );\n }\n\n if (body.gateway?.security !== undefined) {\n if (typeof body.gateway.security !== 'object' || body.gateway.security === null) {\n return patchError('gateway.security must be an object');\n }\n const gw = ensureGateway(config);\n const secIn = body.gateway.security as Record<string, unknown>;\n if (!gw.security) {\n gw.security = {};\n }\n if (secIn.strict !== undefined) {\n gw.security.strict = Boolean(secIn.strict);\n }\n }\n\n if (body.gateway?.share !== undefined) {\n if (typeof body.gateway.share !== 'object' || body.gateway.share === null || Array.isArray(body.gateway.share)) {\n return patchError('gateway.share must be an object');\n }\n const shareResult = mergeShareConfigPatch(config, body.gateway.share as Record<string, unknown>);\n if (shareResult.ok === false) {\n return patchError(shareResult.message);\n }\n }\n\n if (body.gateway?.corsOrigins !== undefined) {\n if (!Array.isArray(body.gateway.corsOrigins)) {\n return patchError('gateway.corsOrigins must be an array');\n }\n const gw = ensureGateway(config);\n gw.corsOrigins = body.gateway.corsOrigins\n .filter((x: unknown): x is string => typeof x === 'string' && x.trim().length > 0)\n .map((x: string) => x.trim());\n }\n\n if (body.gateway?.maxSseConnections !== undefined) {\n if (\n typeof body.gateway.maxSseConnections !== 'number' ||\n !Number.isFinite(body.gateway.maxSseConnections) ||\n body.gateway.maxSseConnections < 1\n ) {\n return patchError('gateway.maxSseConnections must be a positive integer');\n }\n if (!config.gateway) {\n config.gateway = {\n bind: 'loopback',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: Math.floor(body.gateway.maxSseConnections),\n corsOrigins: [],\n };\n } else {\n config.gateway.maxSseConnections = Math.floor(body.gateway.maxSseConnections);\n }\n }\n\n if (body.gateway?.channelConnectDeferMode !== undefined) {\n const mode = body.gateway.channelConnectDeferMode;\n if (mode !== 'auto' && mode !== 'off' && mode !== 'explicit') {\n return patchError('gateway.channelConnectDeferMode must be auto, off, or explicit');\n }\n const gw = ensureGateway(config);\n gw.channelConnectDeferMode = mode;\n }\n\n if (body.gateway?.channelConnectDeferIds !== undefined) {\n const ids = parseDeferIdList(body.gateway.channelConnectDeferIds);\n if (ids === null) {\n return patchError('gateway.channelConnectDeferIds must be an array of up to 24 strings');\n }\n const gw = ensureGateway(config);\n gw.channelConnectDeferIds = ids;\n }\n\n if (body.gateway?.channelConnectDeferSkipIds !== undefined) {\n const ids = parseDeferIdList(body.gateway.channelConnectDeferSkipIds);\n if (ids === null) {\n return patchError('gateway.channelConnectDeferSkipIds must be an array of up to 24 strings');\n }\n const gw = ensureGateway(config);\n gw.channelConnectDeferSkipIds = ids;\n }\n\n return PATCH_OK;\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { BindingsConfigSchema, McpConfigSchema, init_schema } from "../../../../config/schema.js";
|
|
2
1
|
import { CredentialResolver, init_credentials } from "../../../../auth/credentials.js";
|
|
2
|
+
import { BindingsConfigSchema, McpConfigSchema, init_schema } from "../../../../config/schema.js";
|
|
3
3
|
import { canonicalizeConfiguredMcpServer } from "../../../../config/mcp-config-normalize.js";
|
|
4
4
|
import { mergeCronConfigPatch, mergeGatewaySkillsMarketplacePatch, mergeGoalsConfigPatch, mergeSessionConfigPatch, mergeUpdateConfigPatch } from "../../../../config/web-patch.js";
|
|
5
5
|
import { assertGatewayAuthConfigured, resolveGatewayAuth } from "../../../auth.js";
|
|
6
|
+
import { isMaskedSecretPatchValue } from "../../lib/mask-secret-length.js";
|
|
6
7
|
import { applyToolsWebPatch } from "../../../config-tools-web.js";
|
|
7
8
|
import { mergeTunnelConfigPatch } from "../../../../tunnel/tunnel-config.js";
|
|
8
9
|
import { assertGatewayRuntimeConfig } from "../../../runtime-config.js";
|
|
@@ -43,7 +44,7 @@ async function applyMiscPatch(config, body) {
|
|
|
43
44
|
}
|
|
44
45
|
if (body.providers) {
|
|
45
46
|
const resolver = new CredentialResolver();
|
|
46
|
-
for (const [key, apiKey] of Object.entries(body.providers)) if (apiKey !== void 0 && typeof apiKey === "string" && apiKey.trim() && apiKey
|
|
47
|
+
for (const [key, apiKey] of Object.entries(body.providers)) if (apiKey !== void 0 && typeof apiKey === "string" && apiKey.trim() && !isMaskedSecretPatchValue(apiKey)) await resolver.saveApiKey(key, apiKey, { profileName: "default" });
|
|
47
48
|
}
|
|
48
49
|
if (body.providersConfig && typeof body.providersConfig === "object" && !Array.isArray(body.providersConfig)) {
|
|
49
50
|
const cfgProviders = config.providers ?? {};
|
|
@@ -62,7 +63,11 @@ async function applyMiscPatch(config, body) {
|
|
|
62
63
|
"region",
|
|
63
64
|
"imageBaseUrl"
|
|
64
65
|
]) if (patch[field] === null || patch[field] === "") delete next[field];
|
|
65
|
-
else if (typeof patch[field] === "string")
|
|
66
|
+
else if (typeof patch[field] === "string") {
|
|
67
|
+
const trimmed = patch[field].trim();
|
|
68
|
+
if (field === "apiKey" && isMaskedSecretPatchValue(trimmed)) continue;
|
|
69
|
+
next[field] = trimmed;
|
|
70
|
+
}
|
|
66
71
|
if (patch.azure === null) delete next.azure;
|
|
67
72
|
else if (patch.azure && typeof patch.azure === "object" && !Array.isArray(patch.azure)) next.azure = {
|
|
68
73
|
...next.azure ?? {},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"misc.js","names":[],"sources":["../../../../../../src/gateway/hono/routes/config-patch/misc.ts"],"sourcesContent":["/**\n * `PATCH /api/config` — tail sections that are each <50 lines:\n * update / cron / goals / session / gateway.{skillsMarketplaceProvider,\n * skillsStoreBaseUrl} / providers / providersConfig / stt / tts / tools /\n * tunnel / bindings / mcp.\n *\n * Most of these delegate to a `mergeXxxConfigPatch(config, body) → { ok,\n * message? }` helper that lives next to the schema, so this file is mostly\n * \"validate object shape, call helper, surface 400 on failure\". The async\n * `providers` branch saves into the credential resolver rather than config.\n *\n * Final validation (resolveGatewayAuth + assertGatewayRuntimeConfig) runs\n * after every gateway-touching patch lands, so it sees the merged shape.\n */\nimport type { Config } from '../../../../config/schema.js';\nimport { BindingsConfigSchema, McpConfigSchema } from '../../../../config/schema.js';\nimport { CredentialResolver } from '../../../../auth/credentials.js';\nimport { applyToolsWebPatch } from '../../../config-tools-web.js';\nimport { mergeTunnelConfigPatch } from '../../../../tunnel/tunnel-config.js';\nimport { canonicalizeConfiguredMcpServer } from '../../../../config/mcp-config-normalize.js';\nimport {\n mergeCronConfigPatch,\n mergeGatewaySkillsMarketplacePatch,\n mergeGoalsConfigPatch,\n mergeSessionConfigPatch,\n mergeUpdateConfigPatch,\n} from '../../../../config/web-patch.js';\nimport { mergeSttConfigPatch, mergeTtsConfigPatch } from '../../lib/safe-voice-config.js';\nimport { assertGatewayRuntimeConfig } from '../../../runtime-config.js';\nimport { resolveGatewayAuth, assertGatewayAuthConfigured } from '../../../auth.js';\nimport { type PatchResult, PATCH_OK, patchError } from './result.js';\n\nexport async function applyMiscPatch(config: Config, body: any): Promise<PatchResult> {\n if (body.update !== undefined && typeof body.update === 'object' && body.update !== null) {\n const updateResult = mergeUpdateConfigPatch(config, body.update as Record<string, unknown>);\n if (updateResult.ok === false) {\n return patchError(updateResult.message);\n }\n }\n\n if (body.cron !== undefined) {\n if (typeof body.cron !== 'object' || body.cron === null || Array.isArray(body.cron)) {\n return patchError('cron must be an object');\n }\n const cronResult = mergeCronConfigPatch(config, body.cron as Record<string, unknown>);\n if (cronResult.ok === false) {\n return patchError(cronResult.message);\n }\n }\n\n if (body.goals !== undefined) {\n if (typeof body.goals !== 'object' || body.goals === null || Array.isArray(body.goals)) {\n return patchError('goals must be an object');\n }\n const goalsResult = mergeGoalsConfigPatch(config, body.goals as Record<string, unknown>);\n if (goalsResult.ok === false) {\n return patchError(goalsResult.message);\n }\n }\n\n if (body.session !== undefined) {\n if (typeof body.session !== 'object' || body.session === null || Array.isArray(body.session)) {\n return patchError('session must be an object');\n }\n const sessionResult = mergeSessionConfigPatch(config, body.session as Record<string, unknown>);\n if (sessionResult.ok === false) {\n return patchError(sessionResult.message);\n }\n }\n\n if (\n body.gateway !== undefined &&\n typeof body.gateway === 'object' &&\n body.gateway !== null &&\n !Array.isArray(body.gateway)\n ) {\n const gwPatch = body.gateway as Record<string, unknown>;\n if (gwPatch.skillsMarketplaceProvider !== undefined || gwPatch.skillsStoreBaseUrl !== undefined) {\n const skillsResult = mergeGatewaySkillsMarketplacePatch(config, {\n ...(gwPatch.skillsMarketplaceProvider !== undefined\n ? { skillsMarketplaceProvider: gwPatch.skillsMarketplaceProvider }\n : {}),\n ...(gwPatch.skillsStoreBaseUrl !== undefined\n ? { skillsStoreBaseUrl: gwPatch.skillsStoreBaseUrl }\n : {}),\n });\n if (skillsResult.ok === false) {\n return patchError(skillsResult.message);\n }\n }\n }\n\n // LLM provider credentials — saved into the credential system (not config).\n if (body.providers) {\n const resolver = new CredentialResolver();\n for (const [key, apiKey] of Object.entries(body.providers)) {\n if (\n apiKey !== undefined &&\n typeof apiKey === 'string' &&\n apiKey.trim() &&\n apiKey !== '***' &&\n apiKey !== '••••••••••••'\n ) {\n await resolver.saveApiKey(key, apiKey, { profileName: 'default' });\n }\n }\n }\n\n // Structured per-vendor provider config (cfg.providers.<id>) for capability\n // providers (image / audio / video). Distinct from `body.providers` above\n // which targets the LLM-side credential resolver.\n if (body.providersConfig && typeof body.providersConfig === 'object' && !Array.isArray(body.providersConfig)) {\n const cfgProviders = (config as { providers?: Record<string, Record<string, unknown>> }).providers ?? {};\n for (const [vendorId, raw] of Object.entries(body.providersConfig as Record<string, unknown>)) {\n if (!vendorId || typeof vendorId !== 'string') continue;\n if (raw === null) {\n delete cfgProviders[vendorId];\n continue;\n }\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) continue;\n const next = (cfgProviders[vendorId] ?? {}) as Record<string, unknown>;\n const patch = raw as Record<string, unknown>;\n for (const field of ['apiKey', 'baseUrl', 'region', 'imageBaseUrl'] as const) {\n if (patch[field] === null || patch[field] === '') {\n delete next[field];\n } else if (typeof patch[field] === 'string') {\n next[field] = (patch[field] as string).trim();\n }\n }\n if (patch.azure === null) {\n delete next.azure;\n } else if (patch.azure && typeof patch.azure === 'object' && !Array.isArray(patch.azure)) {\n next.azure = { ...(next.azure as Record<string, unknown> ?? {}), ...(patch.azure as Record<string, unknown>) };\n }\n if (patch.request === null) {\n delete next.request;\n } else if (patch.request && typeof patch.request === 'object' && !Array.isArray(patch.request)) {\n next.request = { ...(next.request as Record<string, unknown> ?? {}), ...(patch.request as Record<string, unknown>) };\n }\n cfgProviders[vendorId] = next;\n }\n (config as { providers?: Record<string, Record<string, unknown>> }).providers = cfgProviders;\n }\n\n // PATCH `stt` writes to tools.media.audio; PATCH `tts` writes to messages.tts.\n if (body.stt !== undefined) {\n config.tools = config.tools ?? {};\n config.tools.media = config.tools.media ?? {};\n (config.tools.media as Record<string, unknown>).audio = mergeSttConfigPatch(\n config.tools.media.audio,\n body.stt,\n );\n }\n if (body.tts !== undefined) {\n config.messages = config.messages ?? {};\n (config.messages as Record<string, unknown>).tts = mergeTtsConfigPatch(\n config.messages.tts,\n body.tts,\n );\n }\n\n const toolsPatchErr = applyToolsWebPatch(config, body as Record<string, unknown>);\n if (toolsPatchErr) {\n return patchError(toolsPatchErr);\n }\n\n if (body.tunnel !== undefined) {\n if (!body.tunnel || typeof body.tunnel !== 'object' || Array.isArray(body.tunnel)) {\n return patchError('tunnel must be an object');\n }\n const tunnelResult = mergeTunnelConfigPatch(config, body.tunnel as Record<string, unknown>);\n if (tunnelResult.ok === false) {\n return patchError(tunnelResult.message);\n }\n }\n\n if (body.bindings !== undefined) {\n if (!Array.isArray(body.bindings)) {\n return patchError('bindings must be an array');\n }\n const parsed = BindingsConfigSchema.safeParse(body.bindings);\n if (!parsed.success) {\n return patchError(parsed.error.issues.map((i) => i.message).join('; '));\n }\n config.bindings = parsed.data;\n }\n\n if (body.mcp !== undefined) {\n if (body.mcp === null) {\n delete config.mcp;\n } else if (typeof body.mcp !== 'object' || Array.isArray(body.mcp)) {\n return patchError('mcp must be an object');\n } else {\n const parsed = McpConfigSchema.safeParse(body.mcp);\n if (!parsed.success) {\n return patchError(parsed.error.issues.map((i) => i.message).join('; '));\n }\n if (parsed.data === undefined) {\n delete config.mcp;\n } else {\n const next = { ...parsed.data };\n if (next.servers) {\n next.servers = Object.fromEntries(\n Object.entries(next.servers).map(([name, server]) => [\n name,\n canonicalizeConfiguredMcpServer(server as Record<string, unknown>),\n ]),\n );\n }\n config.mcp = next;\n }\n }\n }\n\n return PATCH_OK;\n}\n\n/**\n * Re-validate gateway runtime config when `body.gateway` touched anything that\n * could break the bind/auth contract. Runs *after* all per-section patches\n * land so it sees the fully merged shape.\n */\nexport function validateGatewayAfterPatch(config: Config, body: any): PatchResult {\n if (body.gateway === undefined) return PATCH_OK;\n try {\n const auth = resolveGatewayAuth({ authConfig: config.gateway?.auth });\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: config,\n auth,\n port: config.gateway?.port ?? 18790,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return patchError(message);\n }\n return PATCH_OK;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"misc.js","names":[],"sources":["../../../../../../src/gateway/hono/routes/config-patch/misc.ts"],"sourcesContent":["/**\n * `PATCH /api/config` — tail sections that are each <50 lines:\n * update / cron / goals / session / gateway.{skillsMarketplaceProvider,\n * skillsStoreBaseUrl} / providers / providersConfig / stt / tts / tools /\n * tunnel / bindings / mcp.\n *\n * Most of these delegate to a `mergeXxxConfigPatch(config, body) → { ok,\n * message? }` helper that lives next to the schema, so this file is mostly\n * \"validate object shape, call helper, surface 400 on failure\". The async\n * `providers` branch saves into the credential resolver rather than config.\n *\n * Final validation (resolveGatewayAuth + assertGatewayRuntimeConfig) runs\n * after every gateway-touching patch lands, so it sees the merged shape.\n */\nimport type { Config } from '../../../../config/schema.js';\nimport { BindingsConfigSchema, McpConfigSchema } from '../../../../config/schema.js';\nimport { CredentialResolver } from '../../../../auth/credentials.js';\nimport { isMaskedSecretPatchValue } from '../../lib/mask-secret-length.js';\nimport { applyToolsWebPatch } from '../../../config-tools-web.js';\nimport { mergeTunnelConfigPatch } from '../../../../tunnel/tunnel-config.js';\nimport { canonicalizeConfiguredMcpServer } from '../../../../config/mcp-config-normalize.js';\nimport {\n mergeCronConfigPatch,\n mergeGatewaySkillsMarketplacePatch,\n mergeGoalsConfigPatch,\n mergeSessionConfigPatch,\n mergeUpdateConfigPatch,\n} from '../../../../config/web-patch.js';\nimport { mergeSttConfigPatch, mergeTtsConfigPatch } from '../../lib/safe-voice-config.js';\nimport { assertGatewayRuntimeConfig } from '../../../runtime-config.js';\nimport { resolveGatewayAuth, assertGatewayAuthConfigured } from '../../../auth.js';\nimport { type PatchResult, PATCH_OK, patchError } from './result.js';\n\nexport async function applyMiscPatch(config: Config, body: any): Promise<PatchResult> {\n if (body.update !== undefined && typeof body.update === 'object' && body.update !== null) {\n const updateResult = mergeUpdateConfigPatch(config, body.update as Record<string, unknown>);\n if (updateResult.ok === false) {\n return patchError(updateResult.message);\n }\n }\n\n if (body.cron !== undefined) {\n if (typeof body.cron !== 'object' || body.cron === null || Array.isArray(body.cron)) {\n return patchError('cron must be an object');\n }\n const cronResult = mergeCronConfigPatch(config, body.cron as Record<string, unknown>);\n if (cronResult.ok === false) {\n return patchError(cronResult.message);\n }\n }\n\n if (body.goals !== undefined) {\n if (typeof body.goals !== 'object' || body.goals === null || Array.isArray(body.goals)) {\n return patchError('goals must be an object');\n }\n const goalsResult = mergeGoalsConfigPatch(config, body.goals as Record<string, unknown>);\n if (goalsResult.ok === false) {\n return patchError(goalsResult.message);\n }\n }\n\n if (body.session !== undefined) {\n if (typeof body.session !== 'object' || body.session === null || Array.isArray(body.session)) {\n return patchError('session must be an object');\n }\n const sessionResult = mergeSessionConfigPatch(config, body.session as Record<string, unknown>);\n if (sessionResult.ok === false) {\n return patchError(sessionResult.message);\n }\n }\n\n if (\n body.gateway !== undefined &&\n typeof body.gateway === 'object' &&\n body.gateway !== null &&\n !Array.isArray(body.gateway)\n ) {\n const gwPatch = body.gateway as Record<string, unknown>;\n if (gwPatch.skillsMarketplaceProvider !== undefined || gwPatch.skillsStoreBaseUrl !== undefined) {\n const skillsResult = mergeGatewaySkillsMarketplacePatch(config, {\n ...(gwPatch.skillsMarketplaceProvider !== undefined\n ? { skillsMarketplaceProvider: gwPatch.skillsMarketplaceProvider }\n : {}),\n ...(gwPatch.skillsStoreBaseUrl !== undefined\n ? { skillsStoreBaseUrl: gwPatch.skillsStoreBaseUrl }\n : {}),\n });\n if (skillsResult.ok === false) {\n return patchError(skillsResult.message);\n }\n }\n }\n\n // LLM provider credentials — saved into the credential system (not config).\n if (body.providers) {\n const resolver = new CredentialResolver();\n for (const [key, apiKey] of Object.entries(body.providers)) {\n if (\n apiKey !== undefined &&\n typeof apiKey === 'string' &&\n apiKey.trim() &&\n !isMaskedSecretPatchValue(apiKey)\n ) {\n await resolver.saveApiKey(key, apiKey, { profileName: 'default' });\n }\n }\n }\n\n // Structured per-vendor provider config (cfg.providers.<id>) for capability\n // providers (image / audio / video). Distinct from `body.providers` above\n // which targets the LLM-side credential resolver.\n if (body.providersConfig && typeof body.providersConfig === 'object' && !Array.isArray(body.providersConfig)) {\n const cfgProviders = (config as { providers?: Record<string, Record<string, unknown>> }).providers ?? {};\n for (const [vendorId, raw] of Object.entries(body.providersConfig as Record<string, unknown>)) {\n if (!vendorId || typeof vendorId !== 'string') continue;\n if (raw === null) {\n delete cfgProviders[vendorId];\n continue;\n }\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) continue;\n const next = (cfgProviders[vendorId] ?? {}) as Record<string, unknown>;\n const patch = raw as Record<string, unknown>;\n for (const field of ['apiKey', 'baseUrl', 'region', 'imageBaseUrl'] as const) {\n if (patch[field] === null || patch[field] === '') {\n delete next[field];\n } else if (typeof patch[field] === 'string') {\n const trimmed = (patch[field] as string).trim();\n if (field === 'apiKey' && isMaskedSecretPatchValue(trimmed)) {\n continue;\n }\n next[field] = trimmed;\n }\n }\n if (patch.azure === null) {\n delete next.azure;\n } else if (patch.azure && typeof patch.azure === 'object' && !Array.isArray(patch.azure)) {\n next.azure = { ...(next.azure as Record<string, unknown> ?? {}), ...(patch.azure as Record<string, unknown>) };\n }\n if (patch.request === null) {\n delete next.request;\n } else if (patch.request && typeof patch.request === 'object' && !Array.isArray(patch.request)) {\n next.request = { ...(next.request as Record<string, unknown> ?? {}), ...(patch.request as Record<string, unknown>) };\n }\n cfgProviders[vendorId] = next;\n }\n (config as { providers?: Record<string, Record<string, unknown>> }).providers = cfgProviders;\n }\n\n // PATCH `stt` writes to tools.media.audio; PATCH `tts` writes to messages.tts.\n if (body.stt !== undefined) {\n config.tools = config.tools ?? {};\n config.tools.media = config.tools.media ?? {};\n (config.tools.media as Record<string, unknown>).audio = mergeSttConfigPatch(\n config.tools.media.audio,\n body.stt,\n );\n }\n if (body.tts !== undefined) {\n config.messages = config.messages ?? {};\n (config.messages as Record<string, unknown>).tts = mergeTtsConfigPatch(\n config.messages.tts,\n body.tts,\n );\n }\n\n const toolsPatchErr = applyToolsWebPatch(config, body as Record<string, unknown>);\n if (toolsPatchErr) {\n return patchError(toolsPatchErr);\n }\n\n if (body.tunnel !== undefined) {\n if (!body.tunnel || typeof body.tunnel !== 'object' || Array.isArray(body.tunnel)) {\n return patchError('tunnel must be an object');\n }\n const tunnelResult = mergeTunnelConfigPatch(config, body.tunnel as Record<string, unknown>);\n if (tunnelResult.ok === false) {\n return patchError(tunnelResult.message);\n }\n }\n\n if (body.bindings !== undefined) {\n if (!Array.isArray(body.bindings)) {\n return patchError('bindings must be an array');\n }\n const parsed = BindingsConfigSchema.safeParse(body.bindings);\n if (!parsed.success) {\n return patchError(parsed.error.issues.map((i) => i.message).join('; '));\n }\n config.bindings = parsed.data;\n }\n\n if (body.mcp !== undefined) {\n if (body.mcp === null) {\n delete config.mcp;\n } else if (typeof body.mcp !== 'object' || Array.isArray(body.mcp)) {\n return patchError('mcp must be an object');\n } else {\n const parsed = McpConfigSchema.safeParse(body.mcp);\n if (!parsed.success) {\n return patchError(parsed.error.issues.map((i) => i.message).join('; '));\n }\n if (parsed.data === undefined) {\n delete config.mcp;\n } else {\n const next = { ...parsed.data };\n if (next.servers) {\n next.servers = Object.fromEntries(\n Object.entries(next.servers).map(([name, server]) => [\n name,\n canonicalizeConfiguredMcpServer(server as Record<string, unknown>),\n ]),\n );\n }\n config.mcp = next;\n }\n }\n }\n\n return PATCH_OK;\n}\n\n/**\n * Re-validate gateway runtime config when `body.gateway` touched anything that\n * could break the bind/auth contract. Runs *after* all per-section patches\n * land so it sees the fully merged shape.\n */\nexport function validateGatewayAfterPatch(config: Config, body: any): PatchResult {\n if (body.gateway === undefined) return PATCH_OK;\n try {\n const auth = resolveGatewayAuth({ authConfig: config.gateway?.auth });\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: config,\n auth,\n port: config.gateway?.port ?? 18790,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return patchError(message);\n }\n return PATCH_OK;\n}\n"],"mappings":"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"}
|