@xopcai/xopc 0.0.210 → 0.0.213
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/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-JLmEb1p0.js → activity-store-Xw-pOm9A.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CI1zQfzY.js → agent-avatar-dicebear-Ca1bciiK.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DD3TqNrC.js +68 -0
- package/dist/gateway/static/root/assets/{api-C6MmWfcb.js → api-CZK-lRew.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cd02GGpV.js → app-management-settings-panel-BLFIG09j.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Db-h2I3G.js → appearance-settings-BsTWUq1i.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-cJkDKn72.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CMHzJT2a.js → archive-plugin-B9LsFfEx.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BzhI2LoH.js → attachment-load-CsWiFfmN.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-CbjU2e75.js +1 -0
- package/dist/gateway/static/root/assets/automations-workspace-C4xyo0c4.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DsUeHvZO.js → binary-plugins-DbqhT_JB.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CFfsIeZ4.js → block-editor-BGpHwxZ5.js} +4 -4
- package/dist/gateway/static/root/assets/browser-settings-page-CrhpQl-e.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-BiWghvJ0.js → browser-workflow-inputs-BXlon_hL.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-DPLdT6Zn.js → browser-workflows-page-B3BBDM_r.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-B9MoPW9u.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-CTxGFvsS.js → capability-presets-api-BqvMm6UW.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BmwldV9R.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BklVUOxC.js → channel-recipient-api-9uca5kDa.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CwLqWcy_.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-DeBw3du9.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-0F4Jmma2.js → chat-terminal-dock-DJjYT3WX.js} +2 -2
- package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-BMhrPKJC.js → chunk-KS7C4IRE-BaASWQor.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-api-BvIZ51ty.js → connectors-api-XCLfuDrN.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CVkGtcMS.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-BHmwaMbO.js → cron-expression-DzQN7zBR.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-fj_pPCv5.js → date-picker-B-r5O5qd.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DsWvwOv-.js → dependency-picker-Ch2XBU2s.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-mjkF0Xxh.js → desktop-pet-BdjX8jde.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-ClwUpRYu.js → desktop-pet-settings-CzjjgMMn.js} +1 -1
- package/dist/gateway/static/root/assets/directory-picker-path-field-BCTgGTk4.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DC69wplH.js → extension-debug-page-6OGgOucD.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DCtk6zdJ.js → extension-page-Cf6MUfCF.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Bkm4zzv-.js → extension-settings-page-pSY_ZvQZ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-Dr_NQt7v.js → gateway-config-api-CFJMng9v.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-CEfv8N1J.js → gateway-config-swr-DpiY6aub.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-aQYxNePf.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B8hebJ7s.js → gateway-startup-retry-BZ_6ChP4.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CI33q9i1.js +1 -0
- package/dist/gateway/static/root/assets/home-page-CAIaWs6r.js +1 -0
- package/dist/gateway/static/root/assets/image-generation-api-DPndEWOU.js +1 -0
- package/dist/gateway/static/root/assets/index-BhstAl5i.js +108 -0
- package/dist/gateway/static/root/assets/index-DQzjgIkQ.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DCQvf05d.js → keyboard-shortcuts-settings-CbLJRGXR.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BqFnCaKT.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-B3Ugd0my.js → local-apps-page-Crf6c3SK.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-hDBVeG3G.js → locale-store-BYSRjM6g.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-nXdF3wOT.js → logs-page-BpfLQWex.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-C-S5Llq3.js → management-settings-mxyYWKgM.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-DuVq37Uh.js → markdown-split-kZaPrUTM.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-view-DD_PgVue.css +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-D8eO_6h3.js → markdown-view-DlsczsQ1.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C1V6pkX3.js → media-plugins-Dk67jaG6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DyM8OOVG.js +3 -0
- package/dist/gateway/static/root/assets/notes-api-DaeeQw8A.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-Dn71ZV8c.js → notes-page-CQDzw8fX.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-BYiROmRJ.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-B5a5aSoS.js → page-tabs-C4UkhX2U.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-5041AIBX.js → preview-open-alternatives-nzcjh6y0.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-7UkouFQU.js → product-open-page-3FvW5cHm.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-p45i1sMj.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-Y9yXB4DX.js +1 -0
- package/dist/gateway/static/root/assets/registry-api-Bu6OGEY2.js +2 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CNsGY0VS.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DvaXzHYS.js → runtime-tools-settings-panel-CVqPSfUb.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-Dlxl_5X0.js → schema-form-Dz6eZpqv.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BAtpgb1t.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-pgBQ21Oe.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CSaiuuer.js → settings-form-section-BaWFAZv4.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-H3mJwt3r.js → settings-loading-skeleton-BWmdZfNg.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Cs7zA4BS.js → settings-page-Btcb-Dc8.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BNllZUFP.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Bdpw5m7M.js → share-preview-page-CGzY3S0N.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CncwbTHY.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CcW2dhSW.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-Bup3Lg1Z.js → skills-page-Bi2IWpU0.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-D22ORR21.js → skills-page.utils-BancvwN2.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-GmtWsfjB.js → system-settings-panel-CihjIzWx.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-SSNFtY-d.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-CtY8RwMX.js → theme-store-D1_t_31B.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-C2aOdlEA.js → typed-models-lib-C2LhiQq5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DOj5i8d_.js → use-autosave-tf_8rxAK.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-BnPTFEar.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-5WfurWYa.js → voice-api-key-field-DN-y7Zfe.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-overlay-bqqH4aZ9.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-bBA8LinI.js → workflow-run-setup-panel-2H33iXOB.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BnfxRf1q.js +5 -0
- package/dist/gateway/static/root/index.html +13 -11
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +1 -1
- package/dist/src/agent/image/generation/providers/xopc-cloud.js +2 -1
- package/dist/src/agent/image/tool-model-config.js +15 -9
- package/dist/src/agent/memory/builtin-provider.js +0 -1
- package/dist/src/agent/memory/create-memory-manager.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +23 -7
- package/dist/src/agent-runtime/index.js +1 -1
- package/dist/src/agent-runtime/runtime-profile.js +1 -1
- package/dist/src/auth/oauth/xopc-cloud.js +1 -1
- package/dist/src/capabilities/readiness/from-config.d.ts +10 -0
- package/dist/src/capabilities/readiness/from-config.js +128 -0
- package/dist/src/capabilities/readiness/index.d.ts +3 -0
- package/dist/src/capabilities/readiness/index.js +3 -0
- package/dist/src/capabilities/readiness/planner.d.ts +3 -0
- package/dist/src/capabilities/readiness/planner.js +56 -0
- package/dist/src/capabilities/readiness/types.d.ts +35 -0
- package/dist/src/capabilities/readiness/types.js +1 -0
- package/dist/src/cli/commands/agent.js +9 -0
- package/dist/src/cli/commands/auth.js +4 -3
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/models.js +2 -1
- package/dist/src/cli/commands/onboard/model.d.ts +3 -21
- package/dist/src/cli/commands/onboard/model.js +10 -86
- package/dist/src/cli/commands/tunnel.js +3 -3
- package/dist/src/cli/utils/oauth-login.d.ts +2 -0
- package/dist/src/cli/utils/oauth-login.js +9 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/paths-state.d.ts +2 -0
- package/dist/src/config/paths-state.js +5 -1
- package/dist/src/config/paths.d.ts +1 -1
- package/dist/src/config/paths.js +2 -2
- package/dist/src/config/schema.js +1 -1
- package/dist/src/connectors/composio-managed-client.d.ts +60 -0
- package/dist/src/connectors/composio-managed-client.js +135 -0
- package/dist/src/connectors/composio-managed-events.d.ts +41 -0
- package/dist/src/connectors/composio-managed-events.js +105 -0
- package/dist/src/connectors/composio-sessions.d.ts +3 -1
- package/dist/src/connectors/composio-sessions.js +15 -8
- package/dist/src/connectors/composio.js +10 -4
- package/dist/src/connectors/connected-source-cursor.d.ts +9 -0
- package/dist/src/connectors/connected-source-cursor.js +30 -0
- package/dist/src/connectors/connected-source-ingestion.js +128 -65
- package/dist/src/connectors/connected-source-normalizers.d.ts +1 -0
- package/dist/src/connectors/connected-source-normalizers.js +33 -2
- package/dist/src/connectors/connected-source-sanitization.d.ts +1 -0
- package/dist/src/connectors/connected-source-sanitization.js +21 -0
- package/dist/src/connectors/connector-identity.js +10 -2
- package/dist/src/connectors/content-enrichment.d.ts +29 -0
- package/dist/src/connectors/content-enrichment.js +273 -0
- package/dist/src/connectors/learning-coordinator.js +1 -2
- package/dist/src/connectors/learning-recipes.js +30 -33
- package/dist/src/connectors/runtime-adapter-registry.js +2 -2
- package/dist/src/discussions/live-worker.d.ts +1 -0
- package/dist/src/discussions/live-worker.js +7 -1
- package/dist/src/discussions/repository.js +11 -1
- package/dist/src/discussions/sealer.d.ts +1 -1
- package/dist/src/discussions/sealer.js +16 -7
- package/dist/src/discussions/service.js +6 -2
- package/dist/src/discussions/transcript.d.ts +2 -0
- package/dist/src/discussions/transcript.js +42 -3
- package/dist/src/discussions/types.d.ts +4 -0
- package/dist/src/extensions/install.d.ts +10 -0
- package/dist/src/extensions/install.js +111 -14
- package/dist/src/extensions/loader.js +22 -18
- package/dist/src/gateway/hono/app.js +8 -3
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/middleware/auth.js +2 -2
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +9 -2
- package/dist/src/gateway/hono/oauth-async.d.ts +11 -5
- package/dist/src/gateway/hono/oauth-async.js +29 -16
- package/dist/src/gateway/hono/oauth.d.ts +1 -3
- package/dist/src/gateway/hono/oauth.js +22 -22
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +10 -3
- package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
- package/dist/src/gateway/hono/routes/discussions.js +2 -1
- package/dist/src/gateway/hono/routes/exposure.js +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +1 -1
- package/dist/src/gateway/hono/routes/home.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +2 -1
- package/dist/src/gateway/hono/routes/models.js +59 -5
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +3 -3
- package/dist/src/gateway/hono/routes/understanding-sources.js +29 -0
- package/dist/src/gateway/hono/routes/voice.d.ts +1 -2
- package/dist/src/gateway/hono/routes/voice.js +16 -35
- package/dist/src/gateway/hono/routes/workflows.js +69 -0
- package/dist/src/gateway/index.js +2 -2
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +12 -0
- package/dist/src/gateway/runtime-config.js +2 -2
- package/dist/src/gateway/security/audit.js +2 -2
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/session-input-coordinator.js +1 -2
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +37 -7
- package/dist/src/knowledge/connected-understanding-pipeline.d.ts +1 -1
- package/dist/src/knowledge/connected-understanding-pipeline.js +74 -25
- package/dist/src/knowledge/ingestion-service.js +33 -15
- package/dist/src/knowledge/types.d.ts +2 -0
- package/dist/src/media-understanding/audio-transcription-runner.d.ts +2 -0
- package/dist/src/media-understanding/audio-transcription-runner.js +3 -1
- package/dist/src/media-understanding/runner.js +3 -1
- package/dist/src/media-understanding/types.d.ts +2 -0
- package/dist/src/notes/note-attachment-sync.js +1 -1
- package/dist/src/notes/service.d.ts +1 -0
- package/dist/src/notes/service.js +2 -1
- package/dist/src/notes/types.d.ts +2 -0
- package/dist/src/providers/model-catalog-persistence.d.ts +9 -0
- package/dist/src/providers/model-catalog-persistence.js +172 -0
- package/dist/src/providers/model-catalog-ranking.d.ts +2 -0
- package/dist/src/providers/model-catalog-ranking.js +17 -0
- package/dist/src/providers/model-catalog-store.d.ts +9 -57
- package/dist/src/providers/model-catalog-store.js +24 -5
- package/dist/src/providers/model-catalog-sync-service.d.ts +3 -3
- package/dist/src/providers/model-catalog-sync-service.js +12 -7
- package/dist/src/providers/model-catalog-types.d.ts +60 -0
- package/dist/src/providers/model-catalog-types.js +1 -0
- package/dist/src/providers/provider-auth-service.d.ts +1 -0
- package/dist/src/providers/provider-auth-service.js +3 -0
- package/dist/src/providers/provider-disconnect-core.d.ts +11 -0
- package/dist/src/providers/provider-disconnect-core.js +35 -0
- package/dist/src/providers/provider-disconnect.d.ts +3 -0
- package/dist/src/providers/provider-disconnect.js +11 -0
- package/dist/src/providers/xopc-cloud-catalog-coordinator.d.ts +56 -0
- package/dist/src/providers/xopc-cloud-catalog-coordinator.js +182 -0
- package/dist/src/providers/xopc-cloud-model-source.d.ts +6 -10
- package/dist/src/providers/xopc-cloud-model-source.js +49 -27
- package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
- package/dist/src/storage/sqlite/migrations/124_workflow_context_snapshots.sql +15 -0
- package/dist/src/storage/sqlite/migrations/125_project_workflow_presets.sql +12 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/user-context-quality-repository.d.ts +8 -0
- package/dist/src/storage/sqlite/user-context-quality-repository.js +21 -1
- package/dist/src/tasks/home-query-service.d.ts +12 -127
- package/dist/src/tasks/home-query-service.js +73 -271
- package/dist/src/tasks/index.js +2 -2
- package/dist/src/tui/backends/embedded-backend.js +11 -3
- package/dist/src/tui/tui-oauth-login.js +5 -0
- package/dist/src/tui/xopc-tui-keybindings.d.ts +2 -2
- package/dist/src/tunnel/index.js +2 -2
- package/dist/src/user-context/sources/activity-clustering.js +30 -117
- package/dist/src/user-context/sources/index.d.ts +1 -0
- package/dist/src/user-context/sources/index.js +2 -1
- package/dist/src/user-context/sources/signal-clustering.d.ts +18 -0
- package/dist/src/user-context/sources/signal-clustering.js +131 -0
- package/dist/src/voice/audio/normalize.d.ts +18 -0
- package/dist/src/voice/audio/normalize.js +175 -0
- package/dist/src/voice/language-profile.d.ts +1 -4
- package/dist/src/voice/language-profile.js +2 -25
- package/dist/src/voice/local/runtime-client.d.ts +2 -0
- package/dist/src/voice/local/runtime-client.js +20 -1
- package/dist/src/voice/local/runtime-worker.js +7 -13
- package/dist/src/voice/local/wav.d.ts +3 -0
- package/dist/src/voice/local/wav.js +11 -5
- package/dist/src/voice/stt/availability.d.ts +1 -4
- package/dist/src/voice/stt/availability.js +3 -15
- package/dist/src/voice/stt/config.js +1 -0
- package/dist/src/voice/stt/factory.js +23 -0
- package/dist/src/voice/stt/index.d.ts +1 -0
- package/dist/src/voice/stt/index.js +2 -2
- package/dist/src/voice/stt/list-providers.js +1 -1
- package/dist/src/voice/stt/providers/local-transcription.js +7 -3
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +3 -1
- package/dist/src/voice/stt/transcribe-core.d.ts +5 -1
- package/dist/src/voice/stt/transcribe-core.js +13 -5
- package/dist/src/voice/stt/types.d.ts +2 -0
- package/dist/src/voice/tts/factory.d.ts +1 -1
- package/dist/src/voice/tts/factory.js +23 -1
- package/dist/src/voice/tts/merge-config.js +5 -3
- package/dist/src/voice/tts/providers/xopc-cloud-speech.js +3 -1
- package/dist/src/voice/tts/types.d.ts +2 -0
- package/dist/src/voice/tts/types.js +4 -2
- package/dist/src/work-discovery/evaluation.d.ts +23 -0
- package/dist/src/work-discovery/evaluation.js +18 -1
- package/dist/src/work-discovery/index.js +2 -2
- package/dist/src/work-discovery/service.js +6 -8
- package/dist/src/work-discovery/types.d.ts +2 -0
- package/dist/src/workflows/context/workflow-context-snapshot-repository.d.ts +21 -0
- package/dist/src/workflows/context/workflow-context-snapshot-repository.js +40 -0
- package/dist/src/workflows/context/workflow-context.d.ts +18 -0
- package/dist/src/workflows/context/workflow-context.js +159 -0
- package/dist/src/workflows/domain/run.d.ts +10 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +1 -0
- package/dist/src/workflows/engine/workflow-engine.js +2 -0
- package/dist/src/workflows/project-presets/project-workflow-preset-repository.d.ts +20 -0
- package/dist/src/workflows/project-presets/project-workflow-preset-repository.js +38 -0
- package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +107 -22
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-writeback-service.d.ts +9 -0
- package/dist/src/workflows/service/workflow-writeback-service.js +106 -0
- package/package.json +9 -8
- package/dist/gateway/static/root/assets/agents-DqGMj3QJ.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-BT7F4WBI.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-CwOXGV9z.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CyRLhCod.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-jRKcS7lZ.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-B3bKdtwU.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-yZBWH02s.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-C3zlimZd.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-OX4KvUkA.js +0 -2
- package/dist/gateway/static/root/assets/directory-picker-path-field-OkqRFyRL.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-V1XVxjHa.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CWUBAQrE.js +0 -1
- package/dist/gateway/static/root/assets/home-page-D57cYRd3.js +0 -1
- package/dist/gateway/static/root/assets/index-DJ7HSgKs.js +0 -85
- package/dist/gateway/static/root/assets/index-PNBFdxHb.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-BbAiMZE1.js +0 -2
- package/dist/gateway/static/root/assets/markdown-view-B12xeflb.css +0 -1
- package/dist/gateway/static/root/assets/messages-1qg_hOOd.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-BYPoZeRw.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-D27nOKbo.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CdB5cJJ-.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DFoZ3UNS.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-C1cbIcJ7.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DnXRlQXS.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CwgMODfJ.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-hlUgIkrp.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DR31B_Gz.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-CTKDpxhf.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-keJJYpix.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-overlay-D5_MH3n3.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BcvBiebt.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-Cz2VpWdj.js +0 -5
- package/dist/src/voice/local/runtime-dispatcher.d.ts +0 -9
- package/dist/src/voice/local/runtime-dispatcher.js +0 -20
|
@@ -7,8 +7,9 @@ import { checkEngineCompatibility } from "./engine-check.js";
|
|
|
7
7
|
import { collectExtensionPackageDependencyIssues } from "./package-contract.js";
|
|
8
8
|
import { dirname, isAbsolute, join, resolve, sep } from "path";
|
|
9
9
|
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
|
|
10
|
-
import {
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
11
|
import AdmZip from "adm-zip";
|
|
12
|
+
import semver from "semver";
|
|
12
13
|
import { tmpdir } from "os";
|
|
13
14
|
//#region src/extensions/install.ts
|
|
14
15
|
/**
|
|
@@ -21,6 +22,58 @@ init_package_version();
|
|
|
21
22
|
init_logger();
|
|
22
23
|
const log = createLogger("ExtensionInstall");
|
|
23
24
|
const NPM_INSTALL_ENV = process.env.XOPC_EXTENSION_NPM_INSTALL?.trim().toLowerCase();
|
|
25
|
+
const NPM_INSTALL_SCRIPTS_ENV = process.env.XOPC_EXTENSION_NPM_INSTALL_SCRIPTS?.trim().toLowerCase();
|
|
26
|
+
const ALLOW_NPM_INSTALL_SCRIPTS = [
|
|
27
|
+
"1",
|
|
28
|
+
"true",
|
|
29
|
+
"allow"
|
|
30
|
+
].includes(NPM_INSTALL_SCRIPTS_ENV ?? "");
|
|
31
|
+
const NPM_PACKAGE_PART_RE = /^(?![._])[a-z0-9][a-z0-9._~-]*$/;
|
|
32
|
+
/** Accept registry package names with an optional exact semver; reject URLs, paths, tags, and ranges. */
|
|
33
|
+
function validateNpmPackageSpec(packageSpec) {
|
|
34
|
+
if (!packageSpec || packageSpec !== packageSpec.trim() || /\s/.test(packageSpec)) return {
|
|
35
|
+
ok: false,
|
|
36
|
+
error: "npm package spec must not be empty or contain whitespace"
|
|
37
|
+
};
|
|
38
|
+
let packageName = packageSpec;
|
|
39
|
+
let version;
|
|
40
|
+
if (packageSpec.startsWith("@")) {
|
|
41
|
+
const slashIndex = packageSpec.indexOf("/");
|
|
42
|
+
const versionSeparator = packageSpec.lastIndexOf("@");
|
|
43
|
+
if (slashIndex <= 1) return {
|
|
44
|
+
ok: false,
|
|
45
|
+
error: "Invalid scoped npm package name"
|
|
46
|
+
};
|
|
47
|
+
if (versionSeparator > slashIndex) {
|
|
48
|
+
packageName = packageSpec.slice(0, versionSeparator);
|
|
49
|
+
version = packageSpec.slice(versionSeparator + 1);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
const versionSeparator = packageSpec.lastIndexOf("@");
|
|
53
|
+
if (versionSeparator > 0) {
|
|
54
|
+
packageName = packageSpec.slice(0, versionSeparator);
|
|
55
|
+
version = packageSpec.slice(versionSeparator + 1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (packageName.length > 214) return {
|
|
59
|
+
ok: false,
|
|
60
|
+
error: "npm package name exceeds 214 characters"
|
|
61
|
+
};
|
|
62
|
+
const parts = packageName.startsWith("@") ? packageName.slice(1).split("/") : [packageName];
|
|
63
|
+
if (parts.length !== (packageName.startsWith("@") ? 2 : 1) || parts.some((part) => !NPM_PACKAGE_PART_RE.test(part))) return {
|
|
64
|
+
ok: false,
|
|
65
|
+
error: "Only npm registry package names are allowed (for example pkg or @scope/pkg)"
|
|
66
|
+
};
|
|
67
|
+
if (version !== void 0 && !semver.valid(version)) return {
|
|
68
|
+
ok: false,
|
|
69
|
+
error: "npm package versions must be exact semver values; tags and ranges are not allowed"
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
ok: true,
|
|
73
|
+
packageName,
|
|
74
|
+
...version ? { version } : {}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
24
77
|
function extractExecSyncOutput(error) {
|
|
25
78
|
if (!error || typeof error !== "object") return "";
|
|
26
79
|
const o = error;
|
|
@@ -41,8 +94,9 @@ function truncateOutput(text, max = 4500) {
|
|
|
41
94
|
}
|
|
42
95
|
/**
|
|
43
96
|
* Install production `node_modules` for an unpacked extension (package.json dependencies).
|
|
44
|
-
* Uses pnpm when `pnpm-lock.yaml` is present, otherwise npm.
|
|
45
|
-
*
|
|
97
|
+
* Uses pnpm when `pnpm-lock.yaml` is present, otherwise npm. Lifecycle scripts are disabled by
|
|
98
|
+
* default; set `XOPC_EXTENSION_NPM_INSTALL_SCRIPTS=allow` only for a reviewed extension that needs
|
|
99
|
+
* them. Set `XOPC_EXTENSION_NPM_INSTALL=skip` to skip dependency installation entirely.
|
|
46
100
|
*/
|
|
47
101
|
function installExtensionProdDependencies(extensionDir) {
|
|
48
102
|
if (NPM_INSTALL_ENV === "skip" || NPM_INSTALL_ENV === "0" || NPM_INSTALL_ENV === "false") {
|
|
@@ -65,9 +119,9 @@ function installExtensionProdDependencies(extensionDir) {
|
|
|
65
119
|
env: process.env,
|
|
66
120
|
...process.platform === "win32" ? { shell: process.env.ComSpec && process.env.ComSpec.trim() || "cmd.exe" } : {}
|
|
67
121
|
};
|
|
68
|
-
const run = (label,
|
|
122
|
+
const run = (label, executable, args) => {
|
|
69
123
|
try {
|
|
70
|
-
|
|
124
|
+
execFileSync(executable, args, execOpts);
|
|
71
125
|
return { ok: true };
|
|
72
126
|
} catch (err) {
|
|
73
127
|
const out = truncateOutput(extractExecSyncOutput(err));
|
|
@@ -77,17 +131,38 @@ function installExtensionProdDependencies(extensionDir) {
|
|
|
77
131
|
};
|
|
78
132
|
}
|
|
79
133
|
};
|
|
80
|
-
|
|
81
|
-
|
|
134
|
+
const usePnpm = existsSync(join(extensionDir, "pnpm-lock.yaml"));
|
|
135
|
+
const scriptArgs = ALLOW_NPM_INSTALL_SCRIPTS ? [] : ["--ignore-scripts"];
|
|
136
|
+
const npmExecutable = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
137
|
+
const pnpmExecutable = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
138
|
+
if (usePnpm) {
|
|
139
|
+
const pnpm = run("pnpm", pnpmExecutable, [
|
|
140
|
+
"install",
|
|
141
|
+
"--prod",
|
|
142
|
+
"--no-frozen-lockfile",
|
|
143
|
+
...scriptArgs
|
|
144
|
+
]);
|
|
82
145
|
if (pnpm.ok) return pnpm;
|
|
83
|
-
const npmFallback = run("npm",
|
|
146
|
+
const npmFallback = run("npm", npmExecutable, [
|
|
147
|
+
"install",
|
|
148
|
+
"--omit=dev",
|
|
149
|
+
"--no-audit",
|
|
150
|
+
"--no-fund",
|
|
151
|
+
...scriptArgs
|
|
152
|
+
]);
|
|
84
153
|
if (npmFallback.ok) {
|
|
85
154
|
log.warn({ extensionDir }, "pnpm failed; extension dependencies installed with npm instead");
|
|
86
155
|
return { ok: true };
|
|
87
156
|
}
|
|
88
157
|
return npmFallback;
|
|
89
158
|
}
|
|
90
|
-
return run("npm",
|
|
159
|
+
return run("npm", npmExecutable, [
|
|
160
|
+
"install",
|
|
161
|
+
"--omit=dev",
|
|
162
|
+
"--no-audit",
|
|
163
|
+
"--no-fund",
|
|
164
|
+
...scriptArgs
|
|
165
|
+
]);
|
|
91
166
|
}
|
|
92
167
|
function isSafeZipPath(name) {
|
|
93
168
|
if (!name) return false;
|
|
@@ -261,11 +336,20 @@ function resolveExtensionsDir(workspaceDir, global = false) {
|
|
|
261
336
|
* Install extension from npm package
|
|
262
337
|
*/
|
|
263
338
|
async function installFromNpm(packageSpec, extensionsDir, timeoutMs = 12e4) {
|
|
264
|
-
const
|
|
339
|
+
const validation = validateNpmPackageSpec(packageSpec);
|
|
340
|
+
if (validation.ok === false) return {
|
|
341
|
+
ok: false,
|
|
342
|
+
error: `Invalid npm package spec: ${validation.error}`
|
|
343
|
+
};
|
|
344
|
+
const tmpDir = mkdtempSync(join(tmpdir(), "xopc-install-"));
|
|
265
345
|
try {
|
|
266
346
|
console.log(`📦 Downloading ${packageSpec} from npm...`);
|
|
267
|
-
|
|
268
|
-
|
|
347
|
+
const packedFile = execFileSync(process.platform === "win32" ? "npm.cmd" : "npm", [
|
|
348
|
+
"pack",
|
|
349
|
+
packageSpec,
|
|
350
|
+
"--pack-destination",
|
|
351
|
+
tmpDir
|
|
352
|
+
], {
|
|
269
353
|
timeout: timeoutMs,
|
|
270
354
|
encoding: "utf-8",
|
|
271
355
|
stdio: "pipe"
|
|
@@ -274,9 +358,22 @@ async function installFromNpm(packageSpec, extensionsDir, timeoutMs = 12e4) {
|
|
|
274
358
|
ok: false,
|
|
275
359
|
error: "Failed to download package from npm"
|
|
276
360
|
};
|
|
361
|
+
if (packedFile !== packedFile.split(/[\\/]/).pop() || !packedFile.endsWith(".tgz")) return {
|
|
362
|
+
ok: false,
|
|
363
|
+
error: "npm returned an invalid archive filename"
|
|
364
|
+
};
|
|
277
365
|
const archivePath = join(tmpDir, packedFile);
|
|
366
|
+
if (!existsSync(archivePath)) return {
|
|
367
|
+
ok: false,
|
|
368
|
+
error: "npm package archive was not created"
|
|
369
|
+
};
|
|
278
370
|
console.log(`📂 Extracting ${packedFile}...`);
|
|
279
|
-
|
|
371
|
+
execFileSync("tar", [
|
|
372
|
+
"-xzf",
|
|
373
|
+
archivePath,
|
|
374
|
+
"-C",
|
|
375
|
+
tmpDir
|
|
376
|
+
], {
|
|
280
377
|
timeout: 3e4,
|
|
281
378
|
stdio: "pipe"
|
|
282
379
|
});
|
|
@@ -532,4 +629,4 @@ function readManifest(extensionDir) {
|
|
|
532
629
|
}
|
|
533
630
|
}
|
|
534
631
|
//#endregion
|
|
535
|
-
export { installExtensionFromStoreZip, installFromLocal, installFromNpm, listAllExtensions, peekExtensionIdFromStoreZip, peekExtensionManifestFromStoreZip, peekExtensionPackageJsonFromStoreZip, removeExtension, resolveExtensionsDir };
|
|
632
|
+
export { installExtensionFromStoreZip, installFromLocal, installFromNpm, listAllExtensions, peekExtensionIdFromStoreZip, peekExtensionManifestFromStoreZip, peekExtensionPackageJsonFromStoreZip, removeExtension, resolveExtensionsDir, validateNpmPackageSpec };
|
|
@@ -290,13 +290,6 @@ var ExtensionLoader = class {
|
|
|
290
290
|
}
|
|
291
291
|
async loadExtension(config) {
|
|
292
292
|
try {
|
|
293
|
-
const cacheKey = this.cache.buildKey(this.options, [config.id]);
|
|
294
|
-
const cached = this.cache.get(cacheKey);
|
|
295
|
-
if (cached) {
|
|
296
|
-
log.debug({ extensionId: config.id }, "Extension loaded from cache");
|
|
297
|
-
return cached;
|
|
298
|
-
}
|
|
299
|
-
if (this.extensionInstances.has(config.id)) return this.extensionInstances.get(config.id);
|
|
300
293
|
let extensionPath;
|
|
301
294
|
if (isAbsolute(config.path)) extensionPath = config.path;
|
|
302
295
|
else extensionPath = resolveExtensionPath(config.path, this.options) || resolveExtensionPath(config.id, this.options);
|
|
@@ -314,19 +307,30 @@ var ExtensionLoader = class {
|
|
|
314
307
|
}, "Resolved extension path");
|
|
315
308
|
const source = config.source || "bundled";
|
|
316
309
|
const safetyResult = checkExtensionPathSafety(extensionPath, extensionPath, source);
|
|
317
|
-
if (!safetyResult.safe) {
|
|
310
|
+
if (this.securityConfig.checkPermissions && !safetyResult.safe) {
|
|
318
311
|
logSecurityIssue(config.id, safetyResult);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}, "Extension blocked by security policy");
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
312
|
+
this.diagnostics.error(config.id, `Unsafe extension path: ${safetyResult.detail}`);
|
|
313
|
+
log.error({
|
|
314
|
+
extensionId: config.id,
|
|
315
|
+
reason: safetyResult.reason
|
|
316
|
+
}, "Extension blocked because its path is unsafe");
|
|
317
|
+
return null;
|
|
329
318
|
}
|
|
319
|
+
if (source !== "bundled" && !isExtensionAllowed(config.id, this.securityConfig)) {
|
|
320
|
+
this.diagnostics.error(config.id, "Extension is not present in extensions.security.allow");
|
|
321
|
+
log.error({
|
|
322
|
+
extensionId: config.id,
|
|
323
|
+
source
|
|
324
|
+
}, "Extension blocked because it is not trusted by security policy");
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
const cacheKey = this.cache.buildKey(this.options, [config.id]);
|
|
328
|
+
const cached = this.cache.get(cacheKey);
|
|
329
|
+
if (cached) {
|
|
330
|
+
log.debug({ extensionId: config.id }, "Extension loaded from cache");
|
|
331
|
+
return cached;
|
|
332
|
+
}
|
|
333
|
+
if (this.extensionInstances.has(config.id)) return this.extensionInstances.get(config.id);
|
|
330
334
|
provenanceTracker.track(config.id, source);
|
|
331
335
|
const manifest = this.loadManifest(extensionPath);
|
|
332
336
|
if (!manifest) {
|
|
@@ -10,7 +10,7 @@ import { buildGatewayConsoleCspHeader } from "../security/csp.js";
|
|
|
10
10
|
import { checkBrowserOrigin } from "../security/origin-check.js";
|
|
11
11
|
import { auth } from "./middleware/auth.js";
|
|
12
12
|
import { operatorScopes } from "./middleware/scopes.js";
|
|
13
|
-
import { createChannelRateLimitMiddleware, createChatRateLimitMiddleware, createStrictRateLimitMiddleware, createTaskRateLimitMiddleware, createXopcCloudPollRateLimitMiddleware } from "./middleware/strict-rate-limit.js";
|
|
13
|
+
import { createChannelRateLimitMiddleware, createChatRateLimitMiddleware, createMediaRateLimitMiddleware, createStrictRateLimitMiddleware, createTaskRateLimitMiddleware, createXopcCloudPollRateLimitMiddleware } from "./middleware/strict-rate-limit.js";
|
|
14
14
|
import { logContextMiddleware } from "./middleware/log-context.js";
|
|
15
15
|
import { logger } from "./middleware/logger.js";
|
|
16
16
|
import { routeErrorMiddleware } from "./middleware/route-errors.js";
|
|
@@ -147,7 +147,7 @@ function createHonoApp(config) {
|
|
|
147
147
|
const DEFAULT_API_BODY_MAX = 1 * 1024 * 1024;
|
|
148
148
|
const SKILL_UPLOAD_BODY_MAX = 10 * 1024 * 1024;
|
|
149
149
|
const NOTE_MEDIA_BODY_MAX = 25 * 1024 * 1024;
|
|
150
|
-
const VOICE_TRANSCRIBE_BODY_MAX =
|
|
150
|
+
const VOICE_TRANSCRIBE_BODY_MAX = 26 * 1024 * 1024;
|
|
151
151
|
const SESSION_INPUT_BODY_MAX = maxSessionInputRequestBodyBytes();
|
|
152
152
|
const isNoteMediaUploadRequest = (path, method, contentType) => {
|
|
153
153
|
if (method !== "POST") return false;
|
|
@@ -175,7 +175,7 @@ function createHonoApp(config) {
|
|
|
175
175
|
}));
|
|
176
176
|
app.use("/api/*", async (c, next) => {
|
|
177
177
|
const contentType = c.req.header("content-type");
|
|
178
|
-
const maxSize = c.req.method === "POST" && c.req.path === "/api/tasks" || c.req.method === "POST" && /^\/api\/sessions\/[^/]+\/inputs$/.test(c.req.path) || c.req.method === "POST" && /^\/api\/tasks\/[^/]+\/inputs$/.test(c.req.path) || c.req.method === "PATCH" && /^\/api\/sessions\/[^/]+\/inputs\/[^/]+$/.test(c.req.path) ? SESSION_INPUT_BODY_MAX : c.req.path === "/api/skills/upload" ? SKILL_UPLOAD_BODY_MAX : c.req.path === "/api/voice/
|
|
178
|
+
const maxSize = c.req.method === "POST" && c.req.path === "/api/tasks" || c.req.method === "POST" && /^\/api\/sessions\/[^/]+\/inputs$/.test(c.req.path) || c.req.method === "POST" && /^\/api\/tasks\/[^/]+\/inputs$/.test(c.req.path) || c.req.method === "PATCH" && /^\/api\/sessions\/[^/]+\/inputs\/[^/]+$/.test(c.req.path) ? SESSION_INPUT_BODY_MAX : c.req.path === "/api/skills/upload" ? SKILL_UPLOAD_BODY_MAX : c.req.path === "/api/voice/transcriptions" ? VOICE_TRANSCRIBE_BODY_MAX : isNoteMediaUploadRequest(c.req.path, c.req.method, contentType) ? NOTE_MEDIA_BODY_MAX : isProjectFileUploadRequest(c.req.path, c.req.method, contentType) ? NOTE_MEDIA_BODY_MAX : discussionUploadBodyMax(c.req.path, c.req.method, contentType) ?? DEFAULT_API_BODY_MAX;
|
|
179
179
|
const maxSizeMb = Math.ceil(maxSize / (1024 * 1024));
|
|
180
180
|
return bodyLimit({
|
|
181
181
|
maxSize,
|
|
@@ -213,6 +213,10 @@ function createHonoApp(config) {
|
|
|
213
213
|
trustedProxies: service.currentConfig.gateway?.trustedProxies,
|
|
214
214
|
allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true
|
|
215
215
|
}) });
|
|
216
|
+
const mediaRateLimitMiddleware = createMediaRateLimitMiddleware({ getTrustedProxyContext: () => ({
|
|
217
|
+
trustedProxies: service.currentConfig.gateway?.trustedProxies,
|
|
218
|
+
allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true
|
|
219
|
+
}) });
|
|
216
220
|
const taskRateLimitMiddleware = createTaskRateLimitMiddleware({ getTrustedProxyContext: () => ({
|
|
217
221
|
trustedProxies: service.currentConfig.gateway?.trustedProxies,
|
|
218
222
|
allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true
|
|
@@ -225,6 +229,7 @@ function createHonoApp(config) {
|
|
|
225
229
|
service,
|
|
226
230
|
strictRateLimitMiddleware,
|
|
227
231
|
chatRateLimitMiddleware,
|
|
232
|
+
mediaRateLimitMiddleware,
|
|
228
233
|
taskRateLimitMiddleware,
|
|
229
234
|
xopcCloudPollRateLimitMiddleware: createXopcCloudPollRateLimitMiddleware({ getTrustedProxyContext: () => ({
|
|
230
235
|
trustedProxies: service.currentConfig.gateway?.trustedProxies,
|
|
@@ -8,10 +8,10 @@ import { getProviderRegistry, init_plugin_registry } from "../../../providers/pl
|
|
|
8
8
|
import { getAllProviders, init_providers, isProviderConfigured } from "../../../providers/index.js";
|
|
9
9
|
import { normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
|
|
10
10
|
import { resolveShareConfig } from "../../../share/share-config.js";
|
|
11
|
-
import { maskTunnelSecretForWeb } from "../../../tunnel/env.js";
|
|
12
11
|
import { resolveSessionConfigForWeb, resolveUpdateConfigForWeb } from "../../../config/web-patch.js";
|
|
13
12
|
import { GENERIC_MASKED_SECRET, maskSecretLength } from "./mask-secret-length.js";
|
|
14
13
|
import { safeToolsWebForGet } from "../../config-tools-web.js";
|
|
14
|
+
import { maskTunnelSecretForWeb } from "../../../tunnel/env.js";
|
|
15
15
|
import { buildSafeProvidersConfigForWeb } from "./safe-providers-config.js";
|
|
16
16
|
import { maskSttConfigForWeb, maskTtsConfigForWeb } from "./safe-voice-config.js";
|
|
17
17
|
//#region src/gateway/hono/lib/config-payload.ts
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { logAuthEvent } from "../../../utils/logger/audit.js";
|
|
2
2
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../../../utils/logger.js";
|
|
4
|
+
import { safeEqualSecret } from "../../security/secret-equal.js";
|
|
5
|
+
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
4
6
|
import { authPolicyConfig, buckets, resolveAuthRateLimit } from "../../rate-limit/buckets.js";
|
|
5
7
|
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
6
8
|
import { resolveAuthTracking } from "../../rate-limit/auth-policy.js";
|
|
7
9
|
import { isAuthRateLimitGloballyDisabled } from "../../rate-limit/env-flags.js";
|
|
8
10
|
import "../../rate-limit/index.js";
|
|
9
|
-
import { safeEqualSecret } from "../../security/secret-equal.js";
|
|
10
|
-
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
11
11
|
import { authorizeTrustedProxy } from "../../trusted-proxy.js";
|
|
12
12
|
import { createMiddleware } from "hono/factory";
|
|
13
13
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
-
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
4
3
|
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
4
|
+
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
5
5
|
import { createMiddleware } from "hono/factory";
|
|
6
6
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
7
7
|
//#region src/gateway/hono/middleware/logger.ts
|
|
@@ -16,6 +16,10 @@ export declare function createChatRateLimitMiddleware(deps: StrictRateLimitDeps)
|
|
|
16
16
|
error: string;
|
|
17
17
|
code: string;
|
|
18
18
|
}, 429, "json">>;
|
|
19
|
+
export declare function createMediaRateLimitMiddleware(deps: StrictRateLimitDeps): import("hono").MiddlewareHandler<any, string, {}, Response & import("hono").TypedResponse<{
|
|
20
|
+
error: string;
|
|
21
|
+
code: string;
|
|
22
|
+
}, 429, "json">>;
|
|
19
23
|
export declare function createTaskRateLimitMiddleware(deps: StrictRateLimitDeps): import("hono").MiddlewareHandler<any, string, {}, Response & import("hono").TypedResponse<{
|
|
20
24
|
error: string;
|
|
21
25
|
code: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
+
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
3
4
|
import { buckets } from "../../rate-limit/buckets.js";
|
|
4
5
|
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
5
6
|
import "../../rate-limit/index.js";
|
|
6
|
-
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
7
7
|
import { createMiddleware } from "hono/factory";
|
|
8
8
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
9
9
|
//#region src/gateway/hono/middleware/strict-rate-limit.ts
|
|
@@ -70,6 +70,13 @@ function createChatRateLimitMiddleware(deps) {
|
|
|
70
70
|
reason: "chat_rate_limit_exceeded"
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
+
function createMediaRateLimitMiddleware(deps) {
|
|
74
|
+
return createClientRateLimitMiddleware(deps, {
|
|
75
|
+
limiter: () => buckets.mediaApi(),
|
|
76
|
+
exceededMessage: "Media API rate limit exceeded",
|
|
77
|
+
reason: "media_rate_limit_exceeded"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
73
80
|
function createTaskRateLimitMiddleware(deps) {
|
|
74
81
|
return createClientRateLimitMiddleware(deps, {
|
|
75
82
|
limiter: () => buckets.taskApi(),
|
|
@@ -92,4 +99,4 @@ function createChannelRateLimitMiddleware(deps) {
|
|
|
92
99
|
});
|
|
93
100
|
}
|
|
94
101
|
//#endregion
|
|
95
|
-
export { createChannelRateLimitMiddleware, createChatRateLimitMiddleware, createStrictRateLimitMiddleware, createTaskRateLimitMiddleware, createXopcCloudPollRateLimitMiddleware };
|
|
102
|
+
export { createChannelRateLimitMiddleware, createChatRateLimitMiddleware, createMediaRateLimitMiddleware, createStrictRateLimitMiddleware, createTaskRateLimitMiddleware, createXopcCloudPollRateLimitMiddleware };
|
|
@@ -7,8 +7,17 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Hono } from 'hono';
|
|
9
9
|
import type { GatewayService } from '../service.js';
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import type { Config } from '../../config/schema.js';
|
|
11
|
+
import { type CapabilityId } from '../../capabilities/readiness/index.js';
|
|
12
|
+
import type { CatalogReadiness } from '../../providers/xopc-cloud-catalog-coordinator.js';
|
|
13
|
+
export interface OAuthCompletionReadiness {
|
|
14
|
+
authorized: true;
|
|
15
|
+
state: 'connected' | 'connected-degraded';
|
|
16
|
+
catalog: CatalogReadiness;
|
|
17
|
+
capabilities: Record<CapabilityId, 'ready' | 'unavailable' | 'disabled'>;
|
|
18
|
+
}
|
|
19
|
+
export declare function buildOAuthCompletionReadiness(config: Config, catalog: CatalogReadiness): OAuthCompletionReadiness;
|
|
20
|
+
export declare function refreshModelCatalogAfterOAuth(provider: string, service: Pick<GatewayService, 'getModelCatalogSync'>): Promise<CatalogReadiness | undefined>;
|
|
12
21
|
export declare function normalizeDesktopOAuthReturnPath(value: unknown): string | undefined;
|
|
13
22
|
export declare function resolveOAuthLoginMethodPreference(params: {
|
|
14
23
|
requestedMethod?: unknown;
|
|
@@ -16,6 +25,3 @@ export declare function resolveOAuthLoginMethodPreference(params: {
|
|
|
16
25
|
remote: boolean;
|
|
17
26
|
}): string | undefined;
|
|
18
27
|
export declare function createOAuthAsyncHandler(service: GatewayService): Hono<import("hono/dist/types/types.js").BlankEnv, import("hono/dist/types/types.js").BlankSchema, "/">;
|
|
19
|
-
export declare function getOAuthCredentialsFromCache(provider: string): OAuthCredentials | undefined;
|
|
20
|
-
export declare function setOAuthCredentialsToCache(provider: string, creds: OAuthCredentials): void;
|
|
21
|
-
export declare function deleteOAuthCredentialsFromCache(provider: string): void;
|
|
@@ -4,6 +4,8 @@ import { getOAuthProviderInterfaces, init_registry } from "../../auth/oauth/regi
|
|
|
4
4
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
5
5
|
import { isLoopbackHost } from "../host.js";
|
|
6
6
|
import { resolveReverseProxyPublicUrl } from "../public-url.js";
|
|
7
|
+
import { buildCapabilityPlansForConfig } from "../../capabilities/readiness/from-config.js";
|
|
8
|
+
import "../../capabilities/readiness/index.js";
|
|
7
9
|
import { Hono } from "hono";
|
|
8
10
|
//#region src/gateway/hono/oauth-async.ts
|
|
9
11
|
/**
|
|
@@ -17,10 +19,20 @@ init_registry();
|
|
|
17
19
|
init_credentials();
|
|
18
20
|
init_logger();
|
|
19
21
|
const log = createLogger("OAuthAsync");
|
|
22
|
+
function buildOAuthCompletionReadiness(config, catalog) {
|
|
23
|
+
const plans = buildCapabilityPlansForConfig(config);
|
|
24
|
+
const capabilities = Object.fromEntries(Object.entries(plans).map(([capability, plan]) => [capability, plan.status === "disabled" ? "disabled" : plan.status === "unavailable" ? "unavailable" : "ready"]));
|
|
25
|
+
return {
|
|
26
|
+
authorized: true,
|
|
27
|
+
state: Boolean(catalog.error) || Object.values(capabilities).some((status) => status === "unavailable") ? "connected-degraded" : "connected",
|
|
28
|
+
catalog,
|
|
29
|
+
capabilities
|
|
30
|
+
};
|
|
31
|
+
}
|
|
20
32
|
async function refreshModelCatalogAfterOAuth(provider, service) {
|
|
21
|
-
if (provider !== "xopc-cloud") return;
|
|
33
|
+
if (provider !== "xopc-cloud") return void 0;
|
|
22
34
|
try {
|
|
23
|
-
await service.getModelCatalogSync().refreshNow();
|
|
35
|
+
return await service.getModelCatalogSync().refreshNow();
|
|
24
36
|
} catch (err) {
|
|
25
37
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
26
38
|
log.warn({
|
|
@@ -28,6 +40,16 @@ async function refreshModelCatalogAfterOAuth(provider, service) {
|
|
|
28
40
|
provider,
|
|
29
41
|
errorMessage
|
|
30
42
|
}, `OAuth completed, but the model catalog could not be refreshed: ${errorMessage}`);
|
|
43
|
+
return {
|
|
44
|
+
state: "unavailable",
|
|
45
|
+
source: "none",
|
|
46
|
+
modelCount: 0,
|
|
47
|
+
error: {
|
|
48
|
+
code: "refresh_failed",
|
|
49
|
+
message: errorMessage,
|
|
50
|
+
retryable: true
|
|
51
|
+
}
|
|
52
|
+
};
|
|
31
53
|
}
|
|
32
54
|
}
|
|
33
55
|
/** User-facing message when undici/fetch fails (often DNS, firewall, or wrong machine for localhost callback). */
|
|
@@ -172,6 +194,7 @@ function createOAuthAsyncHandler(service) {
|
|
|
172
194
|
verificationUri: session.verificationUri,
|
|
173
195
|
message: session.message,
|
|
174
196
|
error: session.error,
|
|
197
|
+
readiness: session.readiness,
|
|
175
198
|
expiresAt: session.expiresAt
|
|
176
199
|
}
|
|
177
200
|
});
|
|
@@ -301,13 +324,13 @@ async function runOAuthFlow(session, oauthProvider, service) {
|
|
|
301
324
|
};
|
|
302
325
|
try {
|
|
303
326
|
const credentials = await oauthProvider.login(callbacks);
|
|
304
|
-
setOAuthCredentialsToCache(session.provider, credentials);
|
|
305
327
|
await new CredentialResolver().saveOAuthCredentials(session.provider, credentials);
|
|
306
328
|
session.message = session.provider === "xopc-cloud" ? "OAuth login successful. Syncing available models..." : "OAuth login successful";
|
|
307
|
-
await refreshModelCatalogAfterOAuth(session.provider, service);
|
|
329
|
+
const catalog = await refreshModelCatalogAfterOAuth(session.provider, service);
|
|
330
|
+
if (catalog && session.provider === "xopc-cloud") session.readiness = buildOAuthCompletionReadiness(service.currentConfig, catalog);
|
|
308
331
|
session.status = "completed";
|
|
309
332
|
session.credentials = credentials;
|
|
310
|
-
session.message = "OAuth login successful";
|
|
333
|
+
session.message = session.readiness?.state === "connected-degraded" ? `OAuth login successful, but capability setup is degraded${catalog?.error ? `: ${catalog.error.message}` : ""}` : "OAuth login successful";
|
|
311
334
|
log.info({
|
|
312
335
|
sessionId: session.id,
|
|
313
336
|
provider: session.provider
|
|
@@ -331,15 +354,5 @@ async function runOAuthFlow(session, oauthProvider, service) {
|
|
|
331
354
|
session.manualCodeReject = void 0;
|
|
332
355
|
}
|
|
333
356
|
}
|
|
334
|
-
const oauthCredentialsCache = /* @__PURE__ */ new Map();
|
|
335
|
-
function getOAuthCredentialsFromCache(provider) {
|
|
336
|
-
return oauthCredentialsCache.get(provider);
|
|
337
|
-
}
|
|
338
|
-
function setOAuthCredentialsToCache(provider, creds) {
|
|
339
|
-
oauthCredentialsCache.set(provider, creds);
|
|
340
|
-
}
|
|
341
|
-
function deleteOAuthCredentialsFromCache(provider) {
|
|
342
|
-
oauthCredentialsCache.delete(provider);
|
|
343
|
-
}
|
|
344
357
|
//#endregion
|
|
345
|
-
export {
|
|
358
|
+
export { buildOAuthCompletionReadiness, createOAuthAsyncHandler, normalizeDesktopOAuthReturnPath, refreshModelCatalogAfterOAuth, resolveOAuthLoginMethodPreference };
|
|
@@ -5,6 +5,4 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Hono } from 'hono';
|
|
7
7
|
import type { GatewayService } from '../service.js';
|
|
8
|
-
|
|
9
|
-
export declare function loadOAuthCredentialsToCache(_service: GatewayService): void;
|
|
10
|
-
export declare function createOAuthHandler(_service: GatewayService): Hono<import("hono/dist/types/types.js").BlankEnv, import("hono/dist/types/types.js").BlankSchema, "/">;
|
|
8
|
+
export declare function createOAuthHandler(service: GatewayService): Hono<import("hono/dist/types/types.js").BlankEnv, import("hono/dist/types/types.js").BlankSchema, "/">;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getOAuthProviderInterfaces, init_registry } from "../../auth/oauth/registry.js";
|
|
2
2
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
3
3
|
import { getProviderAuthState, init_providers, isProviderConfigured } from "../../providers/index.js";
|
|
4
|
+
import { disconnectProvider } from "../../providers/provider-disconnect.js";
|
|
5
|
+
import { buildOAuthCompletionReadiness, refreshModelCatalogAfterOAuth } from "./oauth-async.js";
|
|
4
6
|
import { Hono } from "hono";
|
|
5
7
|
//#region src/gateway/hono/oauth.ts
|
|
6
8
|
/**
|
|
@@ -12,19 +14,7 @@ init_registry();
|
|
|
12
14
|
init_credentials();
|
|
13
15
|
init_providers();
|
|
14
16
|
const OAUTH_PROVIDERS = getOAuthProviderInterfaces();
|
|
15
|
-
|
|
16
|
-
function getOAuthCredentialsFromCache(provider) {
|
|
17
|
-
return oauthCredentialsCache.get(provider);
|
|
18
|
-
}
|
|
19
|
-
function setOAuthCredentialsToCache(provider, creds) {
|
|
20
|
-
oauthCredentialsCache.set(provider, creds);
|
|
21
|
-
}
|
|
22
|
-
function deleteOAuthCredentialsFromCache(provider) {
|
|
23
|
-
oauthCredentialsCache.delete(provider);
|
|
24
|
-
}
|
|
25
|
-
/** No-op: OAuth tokens live on disk under auth paths; cache is populated during login. */
|
|
26
|
-
function loadOAuthCredentialsToCache(_service) {}
|
|
27
|
-
function createOAuthHandler(_service) {
|
|
17
|
+
function createOAuthHandler(service) {
|
|
28
18
|
const oauth = new Hono();
|
|
29
19
|
/**
|
|
30
20
|
* POST /api/auth/oauth/start
|
|
@@ -73,21 +63,28 @@ function createOAuthHandler(_service) {
|
|
|
73
63
|
return prompt.options.find((option) => option.id === "browser")?.id ?? prompt.options[0]?.id;
|
|
74
64
|
}
|
|
75
65
|
});
|
|
76
|
-
setOAuthCredentialsToCache(provider, credentials);
|
|
77
66
|
await new CredentialResolver().saveOAuthCredentials(provider, credentials);
|
|
67
|
+
const catalog = await refreshModelCatalogAfterOAuth(provider, service);
|
|
68
|
+
const readiness = catalog ? buildOAuthCompletionReadiness(service.currentConfig, catalog) : void 0;
|
|
69
|
+
service.emit("provider.auth.changed", {
|
|
70
|
+
provider,
|
|
71
|
+
connected: true
|
|
72
|
+
});
|
|
78
73
|
return c.json({
|
|
79
74
|
ok: true,
|
|
80
75
|
payload: {
|
|
81
76
|
success: true,
|
|
82
77
|
provider,
|
|
83
|
-
message: "OAuth login successful",
|
|
78
|
+
message: readiness?.state === "connected-degraded" ? "OAuth login successful, but capability setup is degraded" : "OAuth login successful",
|
|
84
79
|
expires: credentials.expires,
|
|
85
80
|
authUrl: authResult?.url,
|
|
86
81
|
deviceCode: authResult?.deviceCode,
|
|
87
82
|
verificationUri: authResult?.verificationUri,
|
|
88
83
|
instructions: authResult?.instructions,
|
|
89
84
|
usesCallbackServer: oauthProvider.usesCallbackServer ?? false,
|
|
90
|
-
manualCodeRequested
|
|
85
|
+
manualCodeRequested,
|
|
86
|
+
catalog,
|
|
87
|
+
readiness
|
|
91
88
|
}
|
|
92
89
|
});
|
|
93
90
|
} catch (err) {
|
|
@@ -101,16 +98,15 @@ function createOAuthHandler(_service) {
|
|
|
101
98
|
*/
|
|
102
99
|
oauth.get("/:provider", async (c) => {
|
|
103
100
|
const provider = c.req.param("provider");
|
|
104
|
-
const credentials = getOAuthCredentialsFromCache(provider);
|
|
105
101
|
const authState = await getProviderAuthState(provider);
|
|
106
102
|
const configured = await isProviderConfigured(provider);
|
|
107
103
|
return c.json({
|
|
108
104
|
ok: true,
|
|
109
105
|
payload: {
|
|
110
|
-
configured
|
|
106
|
+
configured,
|
|
111
107
|
authMode: authState.authMode,
|
|
112
108
|
authStatus: authState.authStatus,
|
|
113
|
-
expiresAt: authState.expiresAt
|
|
109
|
+
expiresAt: authState.expiresAt
|
|
114
110
|
}
|
|
115
111
|
});
|
|
116
112
|
});
|
|
@@ -120,8 +116,12 @@ function createOAuthHandler(_service) {
|
|
|
120
116
|
*/
|
|
121
117
|
oauth.delete("/:provider", async (c) => {
|
|
122
118
|
const provider = c.req.param("provider");
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
await disconnectProvider(provider);
|
|
120
|
+
service.emit("provider.auth.changed", {
|
|
121
|
+
provider,
|
|
122
|
+
connected: false
|
|
123
|
+
});
|
|
124
|
+
if (provider === "xopc-cloud") service.emit("model-catalog.updated", { modelCount: 0 });
|
|
125
125
|
return c.json({
|
|
126
126
|
ok: true,
|
|
127
127
|
payload: { disconnected: provider }
|
|
@@ -144,4 +144,4 @@ function createOAuthHandler(_service) {
|
|
|
144
144
|
return oauth;
|
|
145
145
|
}
|
|
146
146
|
//#endregion
|
|
147
|
-
export { createOAuthHandler
|
|
147
|
+
export { createOAuthHandler };
|
|
@@ -3,8 +3,8 @@ import { ActivationPlanner } from "../../../extensions/activation-planner.js";
|
|
|
3
3
|
import { mergeActivationContext } from "../../../extensions/activation-context.js";
|
|
4
4
|
import { fetchRegistry, listExtensions, searchExtensions } from "../../../extensions/marketplace.js";
|
|
5
5
|
import { buildWhenContextSnapshot } from "../../../extensions/when-context.js";
|
|
6
|
-
import { createOAuthHandler } from "../oauth.js";
|
|
7
6
|
import { createOAuthAsyncHandler } from "../oauth-async.js";
|
|
7
|
+
import { createOAuthHandler } from "../oauth.js";
|
|
8
8
|
import { extensionAssetMimeType } from "../lib/extension-assets.js";
|
|
9
9
|
import { loadExtensionStore, saveExtensionStore } from "../lib/extension-store.js";
|
|
10
10
|
import { relative, resolve } from "node:path";
|
|
@@ -3,11 +3,11 @@ import { BindingsConfigSchema, BrowserConfigSchema, McpConfigSchema, VoiceConfig
|
|
|
3
3
|
import { CredentialResolver, init_credentials } from "../../../../auth/credentials.js";
|
|
4
4
|
import { canonicalizeConfiguredMcpServer } from "../../../../config/mcp-config-normalize.js";
|
|
5
5
|
import { setTuiDefaultAgentConfig } from "../../../../commands/agents.config.js";
|
|
6
|
-
import { mergeTunnelConfigPatch } from "../../../../tunnel/tunnel-config.js";
|
|
7
6
|
import { mergeGatewaySkillsMarketplacePatch, mergeSessionConfigPatch, mergeUpdateConfigPatch } from "../../../../config/web-patch.js";
|
|
8
7
|
import { assertGatewayAuthConfigured, resolveGatewayAuth } from "../../../auth.js";
|
|
9
8
|
import { isMaskedSecretPatchValue } from "../../lib/mask-secret-length.js";
|
|
10
9
|
import { applyToolsWebPatch } from "../../../config-tools-web.js";
|
|
10
|
+
import { mergeTunnelConfigPatch } from "../../../../tunnel/tunnel-config.js";
|
|
11
11
|
import { assertGatewayRuntimeConfig } from "../../../runtime-config.js";
|
|
12
12
|
import { mergeSttConfigPatch, mergeTtsConfigPatch } from "../../lib/safe-voice-config.js";
|
|
13
13
|
import { PATCH_OK, patchError } from "./result.js";
|