@xopcai/xopc 0.0.269 → 0.0.272
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/dist/assets/{auth-cwEj8rFb.js → auth-C1QI-uMG.js} +65 -14
- package/dist/browser-ext/dist/background.js +23 -2
- package/dist/browser-ext/dist/pairing-handoff.js +51 -0
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +39 -27
- package/dist/browser-ext/manifest.json +12 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DcwCSY6s.js → activity-store-DffqjeqQ.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D0NBOWC4.js → agent-avatar-dicebear-Cwj4HCYY.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-6CLfLxVc.js +1 -0
- package/dist/gateway/static/root/assets/agents-B6mu64fY.js +1 -0
- package/dist/gateway/static/root/assets/{api-eaPO-mdr.js → api-CGLdye4i.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-E3xm2teY.js → app-management-settings-panel-BLujSbaw.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CiZOjgls.js → appearance-settings-BXMcueb8.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BEgy4hY3.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-D09yo_Hc.js → archive-plugin-D4bUampf.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CNYb8Qru.js → attachment-load-CBGNA2Ys.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DsrfW5ii.js → automations-page-dQyolNmy.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-DxRFrmrV.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-OWlaGqlY.js → binary-plugins-bbvp81h2.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CVND3M6r.js → block-editor-C8e6Wri4.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-D7IzVK_J.js → browser-automation-inputs-oJWJtQa6.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-CQ6cCpIv.js → browser-automations-page-CAcJQSjN.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-TLAlqcPo.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-z-K_jrZz.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-Dzrk33aB.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-D4JrgJKa.js → channels-status-swr-CfOPNnVr.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BUjnhT7C.js → chat-terminal-dock-9ZOl92kh.js} +2 -2
- package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-B1dIoRNi.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-C26e13YU.js +2 -0
- package/dist/gateway/static/root/assets/date-picker-Dj6FRLF9.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-Z6Nf0Wjq.js → dependency-picker-D1q89tVc.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-C0F5Iqnc.js → desktop-pet-DfqZBvhp.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Bj_W6HL1.js → desktop-pet-settings-HCEh2MOm.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-CPth92s6.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Ba09EnAn.js → extension-debug-page-C8cAWVoK.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C88aGXJs.js → extension-page-5N87Vaym.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-D85SAUFP.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-swr-bjzk_4hn.js → gateway-config-swr-BjsDnB_n.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-Dqx8PmcT.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DrbIzFyB.js → gateway-startup-retry-BIf0eLWX.js} +1 -1
- package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-BpDWGE1a.js +1 -0
- package/dist/gateway/static/root/assets/home-page-DJaqpC8-.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-CBWU9Ner.js → image-generation-api-1m8xTVS_.js} +1 -1
- package/dist/gateway/static/root/assets/index-C6PmD0cK.js +74 -0
- package/dist/gateway/static/root/assets/index-DKy1Qn1_.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B8Z7kKQY.js → keyboard-shortcuts-settings-Byy8mCSq.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-l2AEiG2C.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CLSfzkRp.js → local-apps-page-BPo0wBgM.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-CRNble2Z.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-X5FdLlXK.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-DT6NoIjm.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DIcfrLmG.js → markdown-view-AglreSOj.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CSv6-xTA.js → media-plugins-Bzka9qXu.js} +1 -1
- package/dist/gateway/static/root/assets/message-circle-Badhj-4D.js +1 -0
- package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +1 -0
- package/dist/gateway/static/root/assets/{messages-BRjoarIr.js → messages-DH_HCgmw.js} +3 -3
- package/dist/gateway/static/root/assets/note-detail-panel-BUJPoaGZ.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BwFpWRuo.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-BfV-PQa5.js → page-tabs-Ys0p65Lt.js} +1 -1
- package/dist/gateway/static/root/assets/popover-select-Dz_Qis2R.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DQS7NFpg.js → preview-open-alternatives-iknB5xEp.js} +1 -1
- package/dist/gateway/static/root/assets/proactive-card-BPZDgNNR.js +1 -0
- package/dist/gateway/static/root/assets/proactive-page-CxdZR-p2.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-BIhjZLKg.js → product-open-page-W1o3f-kz.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BU1RKAcy.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-z0X0tL8G.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-CwveUfe8.js → registry-api-DmYFpjsH.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-NNTut2I8.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DMQ0wpNg.js → runtime-tools-settings-panel-DP1XyYO8.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-C91g2PRU.js → schema-form-BMYKdzsH.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-B6SsHlz5.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BQu8bAcN.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Cem6L49Y.js → settings-form-section-2LGjz7bu.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-afDUxqlV.js → settings-page-7DjpC9_C.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Dj9jFWJt.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-CVEVHksg.js → share-preview-page-BxYdSi8c.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CMqE0KuK.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BXqSJymN.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CNrq1W6C.js → skills-page-DNEScMZH.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page.utils-q88l65YU.js +1 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-BLE8PxWE.js → system-settings-panel-8NIssGKj.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-L6dp9v2y.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-BejLVjIT.js → theme-store-BXZG3S25.js} +1 -1
- package/dist/gateway/static/root/assets/tunnel-api-CWsRPM84.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-DmgEA8Qb.js → use-autosave-BwQuoTQU.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-D4BucMrZ.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-sZ0J83SF.js → voice-api-key-field-Bd03Ic0s.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-BEbz3avx.js → voice-config-api-gggUp3u9.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BXnAlbmO.js → work-discovery-overlay-DF8PR_pK.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BkwFey0a.js → workflow-run-setup-panel-BiAAWlir.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DryKUMfA.js +6 -0
- package/dist/gateway/static/root/index.html +15 -11
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/device-pairing.js +2 -1
- package/dist/packages/gateway-contract/src/notifications.js +2 -2
- package/dist/packages/gateway-contract/src/proactive.js +22 -6
- package/dist/packages/gateway-contract/src/session-identity.js +37 -0
- package/dist/src/agent/memory/compaction-chunks.d.ts +18 -0
- package/dist/src/agent/memory/compaction-chunks.js +53 -0
- package/dist/src/agent/memory/compaction-request.d.ts +12 -0
- package/dist/src/agent/memory/compaction-request.js +72 -0
- package/dist/src/agent/memory/compaction.d.ts +3 -0
- package/dist/src/agent/memory/compaction.js +166 -118
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +19 -1
- package/dist/src/agent/tools/factory.js +1 -0
- package/dist/src/agent/tools/xopc-use-tool.d.ts +3 -2
- package/dist/src/agent/tools/xopc-use-tool.js +48 -4
- package/dist/src/browser/automations/schema.d.ts +1 -1
- package/dist/src/browser/automations/service.d.ts +1 -1
- package/dist/src/browser/native-messaging-host.js +3 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/tunnel.js +5 -0
- package/dist/src/connectors/connected-source-ingestion.js +1 -1
- package/dist/src/connectors/connected-source-normalizers.js +3 -0
- package/dist/src/connectors/connection-recovery-service.js +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +1 -0
- package/dist/src/gateway/hono/middleware/auth.d.ts +1 -2
- package/dist/src/gateway/hono/middleware/auth.js +49 -31
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +11 -15
- package/dist/src/gateway/hono/routes/browser-session.d.ts +3 -0
- package/dist/src/gateway/hono/routes/browser-session.js +43 -0
- package/dist/src/gateway/hono/routes/capabilities.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/devices.js +61 -96
- package/dist/src/gateway/hono/routes/exposure.js +3 -7
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/models.js +60 -1
- package/dist/src/gateway/hono/routes/notes.js +3 -7
- package/dist/src/gateway/hono/routes/proactive-control.js +31 -24
- package/dist/src/gateway/hono/routes/sessions.js +11 -0
- package/dist/src/gateway/hono/routes/shares.js +8 -20
- package/dist/src/gateway/hono/routes/site-shares.js +4 -8
- package/dist/src/gateway/hono/routes/tunnel.js +13 -13
- package/dist/src/gateway/image-generation-setup.d.ts +17 -0
- package/dist/src/gateway/image-generation-setup.js +30 -21
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +10 -0
- package/dist/src/gateway/runtime-config.js +2 -0
- package/dist/src/gateway/security/browser-session.d.ts +5 -0
- package/dist/src/gateway/security/browser-session.js +45 -0
- package/dist/src/gateway/security/gateway-principal.d.ts +1 -0
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +21 -11
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/rate-limit/keyed-store.d.ts +3 -0
- package/dist/src/infra/rate-limit/keyed-store.js +9 -2
- package/dist/src/notifications/web-push.js +1 -1
- package/dist/src/proactive/actions/service.js +4 -2
- package/dist/src/proactive/execution/authorization.d.ts +2 -0
- package/dist/src/proactive/execution/authorization.js +39 -1
- package/dist/src/proactive/execution/context.d.ts +4 -0
- package/dist/src/proactive/execution/context.js +51 -5
- package/dist/src/proactive/execution/insight.js +3 -1
- package/dist/src/proactive/execution/repository.js +15 -5
- package/dist/src/proactive/execution/types.d.ts +2 -0
- package/dist/src/proactive/execution/worker.js +7 -2
- package/dist/src/proactive/experience.d.ts +69 -0
- package/dist/src/proactive/experience.js +90 -0
- package/dist/src/proactive/follow-ups.d.ts +123 -0
- package/dist/src/proactive/follow-ups.js +169 -0
- package/dist/src/proactive/inbox/cards.js +35 -6
- package/dist/src/proactive/inbox/delivery.js +4 -2
- package/dist/src/proactive/inbox/digest.js +2 -2
- package/dist/src/proactive/inbox/lifecycle.js +4 -1
- package/dist/src/proactive/inbox/notification-policy.js +4 -2
- package/dist/src/proactive/inbox/repository.js +17 -11
- package/dist/src/proactive/inbox/types.d.ts +2 -0
- package/dist/src/proactive/inbox/worker.js +1 -1
- package/dist/src/proactive/index.js +2 -2
- package/dist/src/proactive/mail-thread.d.ts +13 -0
- package/dist/src/proactive/mail-thread.js +54 -0
- package/dist/src/proactive/policy/service.d.ts +3 -5
- package/dist/src/proactive/policy/service.js +3 -5
- package/dist/src/proactive/scenarios/control.d.ts +4 -7
- package/dist/src/proactive/scenarios/control.js +3 -4
- package/dist/src/proactive/scenarios/preview.js +1 -1
- package/dist/src/proactive/scenarios/prompt-composer.js +2 -0
- package/dist/src/proactive/service.js +1 -1
- package/dist/src/proactive/temporal/worker.d.ts +1 -0
- package/dist/src/proactive/temporal/worker.js +18 -4
- package/dist/src/realtime/runtime.d.ts +2 -1
- package/dist/src/realtime/runtime.js +9 -3
- package/dist/src/realtime/tickets.d.ts +1 -0
- package/dist/src/realtime/tickets.js +3 -0
- package/dist/src/session/store.d.ts +2 -0
- package/dist/src/session/store.js +17 -2
- package/dist/src/session/types.d.ts +2 -1
- package/dist/src/storage/sqlite/browser-session-repository.d.ts +17 -0
- package/dist/src/storage/sqlite/browser-session-repository.js +54 -0
- package/dist/src/storage/sqlite/device-pairing-approval.js +2 -1
- package/dist/src/storage/sqlite/device-pairing-repository.d.ts +4 -10
- package/dist/src/storage/sqlite/device-pairing-repository.js +10 -62
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/storage/sqlite/migrations/162_proactive_product.sql +7 -0
- package/dist/src/storage/sqlite/migrations/163_proactive_follow_ups.sql +29 -0
- package/dist/src/storage/sqlite/migrations/164_browser_sessions.sql +8 -0
- package/dist/src/storage/sqlite/migrations/165_device_pairing_target.sql +40 -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/session-identity-sql.d.ts +2 -0
- package/dist/src/storage/sqlite/session-identity-sql.js +18 -0
- package/dist/src/storage/sqlite/session-repository.js +26 -22
- package/dist/src/tasks/home-query-service.js +1 -1
- package/dist/src/tasks/index.js +4 -4
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tunnel/auth-policy.d.ts +3 -0
- package/dist/src/tunnel/auth-policy.js +8 -0
- package/dist/src/tunnel/broker-client.d.ts +5 -15
- package/dist/src/tunnel/broker-client.js +37 -49
- package/dist/src/tunnel/frpc-binary.d.ts +8 -6
- package/dist/src/tunnel/frpc-binary.js +76 -88
- package/dist/src/tunnel/frpc-config.d.ts +2 -1
- package/dist/src/tunnel/frpc-config.js +29 -12
- package/dist/src/tunnel/frpc-release.d.ts +27 -0
- package/dist/src/tunnel/frpc-release.js +30 -0
- package/dist/src/tunnel/gateway-lifecycle.js +8 -2
- package/dist/src/tunnel/index.js +2 -1
- package/dist/src/tunnel/registration-proof.d.ts +19 -0
- package/dist/src/tunnel/registration-proof.js +37 -0
- package/dist/src/tunnel/tunnel-persist.js +3 -1
- package/dist/src/tunnel/tunnel-service.d.ts +1 -0
- package/dist/src/tunnel/tunnel-service.js +35 -8
- package/dist/src/tunnel/tunnel-state.js +11 -5
- package/dist/src/tunnel/tunnel-types.d.ts +2 -0
- package/dist/src/tunnel/well-known.js +5 -1
- package/dist/src/user-context/config.js +2 -2
- package/dist/src/utils/logger/redact.js +4 -0
- package/dist/src/voice/dashscope/streaming-stt-session.js +1 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +1 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.js +8 -0
- package/dist/src/voice/realtime/agentBroker.js +1 -1
- package/dist/src/voice/realtime/agentEngine.js +1 -1
- package/dist/src/voice/realtime/pcm-output-gain.d.ts +2 -0
- package/dist/src/voice/realtime/pcm-output-gain.js +16 -0
- package/dist/src/voice/realtime/runtime.d.ts +1 -0
- package/dist/src/voice/realtime/runtime.js +21 -3
- package/dist/src/voice/realtime/runtime.types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +3 -1
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -0
- package/package.json +4 -4
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-qKCezlBg.js +0 -1
- package/dist/gateway/static/root/assets/agents-BMhnZKhP.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-DduJDWGY.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-X7hNHCjW.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-BZ7nK_pN.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BfKvJO1C.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-D1UDxJuA.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-C2nuqs_O.js +0 -2
- package/dist/gateway/static/root/assets/cron-expression-DlyRIyUn.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-CU-ij_yE.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CMyt0A32.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-ogv8ZbvG.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-BnrMRKaZ.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CbcJCREd.js +0 -1
- package/dist/gateway/static/root/assets/index-7PZ6jmhy.css +0 -2
- package/dist/gateway/static/root/assets/index-CfyyA9-g.js +0 -74
- package/dist/gateway/static/root/assets/local-app-workbench-page-D5XVZnK1.js +0 -2
- package/dist/gateway/static/root/assets/locale-store-BQ2HKTWb.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-CWDU1AGN.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-CuFNgQUy.js +0 -1
- package/dist/gateway/static/root/assets/mobile-pairing-wizard-C7d_ztgp.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-D5JuBLyt.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-C5-ccCi4.js +0 -8
- package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +0 -1
- package/dist/gateway/static/root/assets/proactive-page-fHjPigmx.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-6v_khvEt.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CCy1aK4V.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-pkqKRnch.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Cr4E4cap.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D1JRDRyL.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Cc_iP_vv.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BrMECMAB.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DuqIDYjc.js +0 -1
- package/dist/gateway/static/root/assets/skills-page.utils-D1wGfm22.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-m0oXUKl2.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-Dur80zSQ.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Dl10D_5q.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-CswgoIFU.js +0 -6
- package/dist/src/proactive/actions/workflow.d.ts +0 -15
- package/dist/src/proactive/actions/workflow.js +0 -88
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BrowserSessionLimitError, createBrowserSession, deleteBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
|
|
2
|
+
import { browserCookieRequestAllowed, clearBrowserSessionCookie, writeBrowserSessionCookie } from "../../security/browser-session.js";
|
|
3
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
4
|
+
//#region src/gateway/hono/routes/browser-session.ts
|
|
5
|
+
function registerBrowserSessionRoutes(app, deps) {
|
|
6
|
+
app.get("/api/browser-session", (c) => {
|
|
7
|
+
c.header("Cache-Control", "no-store");
|
|
8
|
+
const principal = getGatewayPrincipal(c);
|
|
9
|
+
return c.json({ sessionKey: principal.principalId });
|
|
10
|
+
});
|
|
11
|
+
app.post("/api/browser-session", deps.strictRateLimitMiddleware, (c) => {
|
|
12
|
+
const principal = getGatewayPrincipal(c);
|
|
13
|
+
if (principal.kind !== "owner" || !browserCookieRequestAllowed(c)) return c.json({ error: "Forbidden" }, 403);
|
|
14
|
+
let session;
|
|
15
|
+
try {
|
|
16
|
+
session = createBrowserSession(deps.service.getResolvedAuth(), principal.browserSessionId);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof BrowserSessionLimitError) return c.json({ error: "Browser session limit reached" }, 409);
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
if (principal.browserSessionId) {
|
|
22
|
+
deps.service.realtime.disconnectPrincipal(principal.principalId);
|
|
23
|
+
deps.service.voiceRealtime.disconnectPrincipal(principal.principalId);
|
|
24
|
+
}
|
|
25
|
+
writeBrowserSessionCookie(c, session.token, session.expiresAt);
|
|
26
|
+
c.header("Cache-Control", "no-store");
|
|
27
|
+
return c.json({ sessionKey: `browser:${session.sessionId}` });
|
|
28
|
+
});
|
|
29
|
+
app.delete("/api/browser-session", (c) => {
|
|
30
|
+
if (!browserCookieRequestAllowed(c)) return c.json({ error: "Forbidden" }, 403);
|
|
31
|
+
const principal = getGatewayPrincipal(c);
|
|
32
|
+
if (principal.browserSessionId) {
|
|
33
|
+
deleteBrowserSession(principal.browserSessionId);
|
|
34
|
+
deps.service.realtime.disconnectPrincipal(principal.principalId);
|
|
35
|
+
deps.service.voiceRealtime.disconnectPrincipal(principal.principalId);
|
|
36
|
+
}
|
|
37
|
+
clearBrowserSessionCookie(c);
|
|
38
|
+
c.header("Cache-Control", "no-store");
|
|
39
|
+
return c.json({ ok: true });
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { registerBrowserSessionRoutes };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ConfigPersistenceError, persistConfigMutation } from "../../../config/config-mutation.js";
|
|
2
1
|
import { getStoreConnectorInstallPlan, installStoreConnector, listStoreConnectors } from "../../../capabilities/store-connector.js";
|
|
2
|
+
import { ConfigPersistenceError, persistConfigMutation } from "../../../config/config-mutation.js";
|
|
3
3
|
//#region src/gateway/hono/routes/capabilities.ts
|
|
4
4
|
function errorMessage(error) {
|
|
5
5
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -12,10 +12,10 @@ import { createConnectorSetupSecretRequest, submitConnectorSetupSecret } from ".
|
|
|
12
12
|
import { configureComposioApiKey, executeComposioTool, getComposioInstallationPolicy, getComposioToolkitAuthState, getComposioToolkitScope, inspectComposioConnectorHealth, listComposioConnections, listComposioTools, refreshComposioConnection, revokeComposioConnection, setComposioToolkitScope, updateComposioConnection, updateComposioInstallationPolicy } from "../../../connectors/composio.js";
|
|
13
13
|
import { listConnectorProviders } from "../../../connectors/providers.js";
|
|
14
14
|
import { getConnectorDefinition, listConnectorCatalog } from "../../../connectors/catalog.js";
|
|
15
|
-
import { ConfigPersistenceError, persistConfigMutation } from "../../../config/config-mutation.js";
|
|
16
15
|
import { recordConnectorHealthUsage } from "../../../connectors/usage.js";
|
|
17
16
|
import { getConnectorInstance, getInstalledConnectorDefinition, listConnectorInstances } from "../../../connectors/instances.js";
|
|
18
17
|
import { installConnector, installConnectorDefinition, uninstallConnector, updateConnectorConfig } from "../../../connectors/install.js";
|
|
18
|
+
import { ConfigPersistenceError, persistConfigMutation } from "../../../config/config-mutation.js";
|
|
19
19
|
import { getMcpOAuthManager } from "../../../agent/mcp/oauth/mcp-oauth-manager.js";
|
|
20
20
|
import { startConnectorAuthorization } from "../../../connectors/auth-provider-registry.js";
|
|
21
21
|
import { composioLogoResponse } from "../../../connectors/composio-logo.js";
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { createDevice, issueDeviceTokenPair, listDevices, revokeDevice, rotateDeviceRefreshToken } from "../../../storage/sqlite/device-access-repository.js";
|
|
1
|
+
import { devicePairingTargetKindSchema } from "../../../../packages/gateway-contract/src/device-pairing.js";
|
|
2
|
+
import { listDevices, revokeDevice, rotateDeviceRefreshToken } from "../../../storage/sqlite/device-access-repository.js";
|
|
4
3
|
import { getGatewayIdentityPublicKeyRaw, getOrCreateGatewayIdentity, signGatewayPayload } from "../../../storage/sqlite/gateway-identity-repository.js";
|
|
5
|
-
import {
|
|
4
|
+
import { createDevicePairingSetup, isDevicePairingSetupActive } from "../../../storage/sqlite/device-pairing-repository.js";
|
|
6
5
|
import { resolveSecureDeviceRoutes } from "../../device-routes.js";
|
|
6
|
+
import { buckets } from "../../rate-limit/buckets.js";
|
|
7
|
+
import "../../rate-limit/index.js";
|
|
7
8
|
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
8
9
|
import { registerPairingApprovalAdminRoutes, registerPairingApprovalPublicRoutes } from "./device-pairing-approval.js";
|
|
9
10
|
import os from "node:os";
|
|
10
11
|
import { z } from "zod";
|
|
12
|
+
import { bodyLimit } from "hono/body-limit";
|
|
11
13
|
//#region src/gateway/hono/routes/devices.ts
|
|
12
14
|
const refreshRequestSchema = z.strictObject({
|
|
13
15
|
refreshToken: z.string().min(1).max(256),
|
|
@@ -17,40 +19,33 @@ const refreshRequestSchema = z.strictObject({
|
|
|
17
19
|
nextRefreshToken: z.string().min(80).max(256),
|
|
18
20
|
signature: z.string().min(1).max(256)
|
|
19
21
|
});
|
|
20
|
-
const pairingExchangeSchema = z.strictObject({
|
|
21
|
-
pairingToken: z.string().min(1).max(256),
|
|
22
|
-
device: z.strictObject({
|
|
23
|
-
displayName: z.string().trim().min(1).max(80),
|
|
24
|
-
platform: z.enum([
|
|
25
|
-
"ios",
|
|
26
|
-
"android",
|
|
27
|
-
"chrome"
|
|
28
|
-
]),
|
|
29
|
-
extensionId: z.string().regex(/^[a-p]{32}$/).optional(),
|
|
30
|
-
publicKeyJwk: z.strictObject({
|
|
31
|
-
kty: z.literal("EC"),
|
|
32
|
-
crv: z.literal("P-256"),
|
|
33
|
-
x: z.string().min(40).max(64),
|
|
34
|
-
y: z.string().min(40).max(64)
|
|
35
|
-
})
|
|
36
|
-
})
|
|
37
|
-
}).superRefine((value, context) => {
|
|
38
|
-
if (value.device.platform === "chrome" && !value.device.extensionId) context.addIssue({
|
|
39
|
-
code: "custom",
|
|
40
|
-
path: ["device", "extensionId"],
|
|
41
|
-
message: "Chrome devices require an extension id"
|
|
42
|
-
});
|
|
43
|
-
if (value.device.platform !== "chrome" && value.device.extensionId) context.addIssue({
|
|
44
|
-
code: "custom",
|
|
45
|
-
path: ["device", "extensionId"],
|
|
46
|
-
message: "Only Chrome devices may set an extension id"
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
22
|
const pairingProbeSchema = z.strictObject({ pairingId: z.string().uuid() });
|
|
23
|
+
const pairingSetupSchema = z.strictObject({ targetKind: devicePairingTargetKindSchema });
|
|
50
24
|
function pairingLinkPayload(input) {
|
|
51
25
|
return Buffer.from(JSON.stringify(input)).toString("base64url");
|
|
52
26
|
}
|
|
53
27
|
function registerDeviceAuthPublicRoutes(app) {
|
|
28
|
+
app.post("/api/gateway-identity/challenge", bodyLimit({ maxSize: 512 }), async (c) => {
|
|
29
|
+
const budget = buckets.identityChallenge().consume("gateway");
|
|
30
|
+
if (!budget.allowed) {
|
|
31
|
+
c.header("Retry-After", String(Math.ceil(budget.retryAfterMs / 1e3)));
|
|
32
|
+
return c.json({ error: "Too many identity challenges" }, 429);
|
|
33
|
+
}
|
|
34
|
+
const parsed = z.strictObject({ nonce: z.string().regex(/^[A-Za-z0-9_-]{32,64}$/) }).safeParse(await c.req.json().catch(() => null));
|
|
35
|
+
if (!parsed.success) return c.json({ error: "Invalid identity challenge" }, 400);
|
|
36
|
+
const identity = getOrCreateGatewayIdentity();
|
|
37
|
+
const signedPayload = Buffer.from(JSON.stringify({
|
|
38
|
+
purpose: "gateway-route-v1",
|
|
39
|
+
gatewayId: identity.id,
|
|
40
|
+
nonce: parsed.data.nonce,
|
|
41
|
+
expiresAt: Date.now() + 3e4
|
|
42
|
+
})).toString("base64url");
|
|
43
|
+
c.header("Cache-Control", "no-store");
|
|
44
|
+
return c.json({
|
|
45
|
+
signedPayload,
|
|
46
|
+
signature: signGatewayPayload(signedPayload)
|
|
47
|
+
});
|
|
48
|
+
});
|
|
54
49
|
registerPairingApprovalPublicRoutes(app);
|
|
55
50
|
app.post("/api/device-auth/refresh", async (c) => {
|
|
56
51
|
const parsed = refreshRequestSchema.safeParse(await c.req.json().catch(() => null));
|
|
@@ -62,9 +57,19 @@ function registerDeviceAuthPublicRoutes(app) {
|
|
|
62
57
|
}
|
|
63
58
|
}, 400);
|
|
64
59
|
try {
|
|
60
|
+
const tokens = rotateDeviceRefreshToken(parsed.data);
|
|
61
|
+
const signedPayload = Buffer.from(JSON.stringify({
|
|
62
|
+
purpose: "device-refresh-v3",
|
|
63
|
+
gatewayId: getOrCreateGatewayIdentity().id,
|
|
64
|
+
requestId: parsed.data.requestId,
|
|
65
|
+
nonce: parsed.data.nonce,
|
|
66
|
+
expiresAt: Date.now() + 3e4,
|
|
67
|
+
tokens
|
|
68
|
+
})).toString("base64url");
|
|
65
69
|
return c.json({
|
|
66
70
|
ok: true,
|
|
67
|
-
|
|
71
|
+
signedPayload,
|
|
72
|
+
signature: signGatewayPayload(signedPayload)
|
|
68
73
|
});
|
|
69
74
|
} catch (error) {
|
|
70
75
|
return c.json({
|
|
@@ -97,61 +102,6 @@ function registerDeviceAuthPublicRoutes(app) {
|
|
|
97
102
|
signature: signGatewayPayload(payload)
|
|
98
103
|
});
|
|
99
104
|
});
|
|
100
|
-
app.post("/api/device-pairing/exchange", async (c) => {
|
|
101
|
-
const parsed = pairingExchangeSchema.safeParse(await c.req.json().catch(() => null));
|
|
102
|
-
if (!parsed.success) return c.json({
|
|
103
|
-
ok: false,
|
|
104
|
-
error: {
|
|
105
|
-
code: "BAD_REQUEST",
|
|
106
|
-
message: "Invalid pairing request"
|
|
107
|
-
}
|
|
108
|
-
}, 400);
|
|
109
|
-
const completed = runSqliteWriteTransaction(() => {
|
|
110
|
-
const pairing = consumeDevicePairingToken(parsed.data.pairingToken);
|
|
111
|
-
if (!pairing.ok && "reason" in pairing) return {
|
|
112
|
-
success: false,
|
|
113
|
-
reason: pairing.reason
|
|
114
|
-
};
|
|
115
|
-
const device = createDevice({
|
|
116
|
-
displayName: parsed.data.device.displayName,
|
|
117
|
-
platform: parsed.data.device.platform,
|
|
118
|
-
publicKeyJwk: parsed.data.device.publicKeyJwk,
|
|
119
|
-
extensionId: parsed.data.device.extensionId,
|
|
120
|
-
scopes: parsed.data.device.platform === "chrome" ? DEFAULT_BROWSER_EXTENSION_SCOPES : DEFAULT_MOBILE_SCOPES
|
|
121
|
-
});
|
|
122
|
-
return {
|
|
123
|
-
success: true,
|
|
124
|
-
device,
|
|
125
|
-
routes: pairing.routes,
|
|
126
|
-
tokens: issueDeviceTokenPair(device.id)
|
|
127
|
-
};
|
|
128
|
-
});
|
|
129
|
-
if ("reason" in completed) return c.json({
|
|
130
|
-
ok: false,
|
|
131
|
-
error: {
|
|
132
|
-
code: "PAIRING_DENIED",
|
|
133
|
-
message: `Pairing ${completed.reason}`
|
|
134
|
-
}
|
|
135
|
-
}, 401);
|
|
136
|
-
const identity = getOrCreateGatewayIdentity();
|
|
137
|
-
const payload = Buffer.from(JSON.stringify({
|
|
138
|
-
gateway: {
|
|
139
|
-
id: identity.id,
|
|
140
|
-
name: os.hostname()
|
|
141
|
-
},
|
|
142
|
-
device: {
|
|
143
|
-
id: completed.device.id,
|
|
144
|
-
scopes: completed.device.scopes
|
|
145
|
-
},
|
|
146
|
-
routes: completed.routes,
|
|
147
|
-
tokens: completed.tokens
|
|
148
|
-
})).toString("base64url");
|
|
149
|
-
return c.json({
|
|
150
|
-
ok: true,
|
|
151
|
-
signedPayload: payload,
|
|
152
|
-
signature: signGatewayPayload(payload)
|
|
153
|
-
}, 201);
|
|
154
|
-
});
|
|
155
105
|
}
|
|
156
106
|
function registerDeviceRoutes(authenticated, deps) {
|
|
157
107
|
registerPairingApprovalAdminRoutes(authenticated);
|
|
@@ -161,14 +111,21 @@ function registerDeviceRoutes(authenticated, deps) {
|
|
|
161
111
|
ok: true,
|
|
162
112
|
ready: routes.length > 0,
|
|
163
113
|
routes,
|
|
164
|
-
|
|
114
|
+
protocolVersion: 3,
|
|
165
115
|
routeState: routes.length > 0 ? "configured" : "missing",
|
|
166
116
|
nextAction: routes.length > 0 ? "scan" : "configure-route",
|
|
167
117
|
serverTime: Date.now()
|
|
168
118
|
});
|
|
169
119
|
});
|
|
170
120
|
authenticated.post("/api/device-pairing/setups", async (c) => {
|
|
171
|
-
const
|
|
121
|
+
const parsed = pairingSetupSchema.safeParse(await c.req.json().catch(() => null));
|
|
122
|
+
if (!parsed.success) return c.json({
|
|
123
|
+
ok: false,
|
|
124
|
+
error: {
|
|
125
|
+
code: "BAD_REQUEST",
|
|
126
|
+
message: "Choose a device type"
|
|
127
|
+
}
|
|
128
|
+
}, 400);
|
|
172
129
|
const routes = resolveSecureDeviceRoutes(deps.service.currentConfig);
|
|
173
130
|
if (routes.length === 0) return c.json({
|
|
174
131
|
ok: false,
|
|
@@ -177,15 +134,16 @@ function registerDeviceRoutes(authenticated, deps) {
|
|
|
177
134
|
message: "Configure XOPC Secure Link, Tailscale Serve, or an HTTPS public URL first"
|
|
178
135
|
}
|
|
179
136
|
}, 409);
|
|
180
|
-
const setup = createDevicePairingSetup(routes, Date.now(),
|
|
137
|
+
const setup = createDevicePairingSetup(routes, Date.now(), { targetKind: parsed.data.targetKind });
|
|
181
138
|
const identity = getOrCreateGatewayIdentity();
|
|
182
139
|
const encoded = pairingLinkPayload({
|
|
183
|
-
version,
|
|
140
|
+
version: 3,
|
|
184
141
|
pairingToken: setup.token,
|
|
185
142
|
gatewayId: identity.id,
|
|
186
143
|
gatewayName: os.hostname(),
|
|
187
144
|
gatewayPublicKey: getGatewayIdentityPublicKeyRaw(identity),
|
|
188
145
|
routes,
|
|
146
|
+
targetKind: setup.targetKind,
|
|
189
147
|
expiresAt: setup.expiresAt
|
|
190
148
|
});
|
|
191
149
|
return c.json({
|
|
@@ -195,7 +153,8 @@ function registerDeviceRoutes(authenticated, deps) {
|
|
|
195
153
|
universalLink: `https://link.xopc.ai/connect#p=${encoded}`,
|
|
196
154
|
expiresAt: setup.expiresAt,
|
|
197
155
|
routes,
|
|
198
|
-
protocolVersion:
|
|
156
|
+
protocolVersion: 3,
|
|
157
|
+
targetKind: setup.targetKind
|
|
199
158
|
}
|
|
200
159
|
}, 201);
|
|
201
160
|
});
|
|
@@ -234,7 +193,10 @@ function registerDeviceRoutes(authenticated, deps) {
|
|
|
234
193
|
}
|
|
235
194
|
}, 403);
|
|
236
195
|
const revoked = revokeDevice(principal.deviceId);
|
|
237
|
-
if (revoked)
|
|
196
|
+
if (revoked) {
|
|
197
|
+
deps.service.realtime.disconnectPrincipal(principal.deviceId);
|
|
198
|
+
deps.service.voiceRealtime.disconnectPrincipal(principal.deviceId);
|
|
199
|
+
}
|
|
238
200
|
return c.json({
|
|
239
201
|
ok: true,
|
|
240
202
|
revoked
|
|
@@ -243,7 +205,10 @@ function registerDeviceRoutes(authenticated, deps) {
|
|
|
243
205
|
authenticated.delete("/api/devices/:deviceId", (c) => {
|
|
244
206
|
const deviceId = c.req.param("deviceId");
|
|
245
207
|
const revoked = revokeDevice(deviceId);
|
|
246
|
-
if (revoked)
|
|
208
|
+
if (revoked) {
|
|
209
|
+
deps.service.realtime.disconnectPrincipal(deviceId);
|
|
210
|
+
deps.service.voiceRealtime.disconnectPrincipal(deviceId);
|
|
211
|
+
}
|
|
247
212
|
return c.json({
|
|
248
213
|
ok: true,
|
|
249
214
|
revoked
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import { extractToken } from "../../auth.js";
|
|
2
1
|
import { getExposureManager } from "../../../remote-access/exposure-manager.js";
|
|
2
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
3
3
|
import { consumeTunnelMutationLimit } from "../../../tunnel/tunnel-rate-limit.js";
|
|
4
4
|
//#region src/gateway/hono/routes/exposure.ts
|
|
5
|
-
function requireGatewayToken(c) {
|
|
6
|
-
return extractToken({ authorization: c.req.header("authorization") ?? void 0 }) ?? null;
|
|
7
|
-
}
|
|
8
5
|
function createExposureMutationRateLimitMiddleware() {
|
|
9
6
|
return async (c, next) => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const result = consumeTunnelMutationLimit(token);
|
|
7
|
+
const principalId = getGatewayPrincipal(c).principalId;
|
|
8
|
+
const result = consumeTunnelMutationLimit(principalId);
|
|
13
9
|
if (!result.allowed) {
|
|
14
10
|
const retryAfterSec = Math.ceil(result.retryAfterMs / 1e3);
|
|
15
11
|
c.header("Retry-After", String(retryAfterSec));
|
|
@@ -3,6 +3,14 @@ function startsWithAny(path, prefixes) {
|
|
|
3
3
|
return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
|
|
4
4
|
}
|
|
5
5
|
const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
|
|
6
|
+
{
|
|
7
|
+
id: "browser-session",
|
|
8
|
+
match: (path) => path === "/api/browser-session",
|
|
9
|
+
load: async () => {
|
|
10
|
+
const { registerBrowserSessionRoutes } = await import("./browser-session.js");
|
|
11
|
+
return { register: registerBrowserSessionRoutes };
|
|
12
|
+
}
|
|
13
|
+
},
|
|
6
14
|
{
|
|
7
15
|
id: "proactive",
|
|
8
16
|
match: (path) => startsWithAny(path, [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { canonicalizeConfiguredMcpServer, normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
|
|
2
2
|
import { loadMergedBundleMcpConfig } from "../../../agent/mcp/bundle-mcp-config.js";
|
|
3
|
-
import { getWorkspacePath } from "../../../config/workspace-path-helpers.js";
|
|
4
3
|
import { isManagedConnectorServer } from "../../../connectors/materialize.js";
|
|
4
|
+
import { getWorkspacePath } from "../../../config/workspace-path-helpers.js";
|
|
5
5
|
import { getMcpOAuthManager } from "../../../agent/mcp/oauth/mcp-oauth-manager.js";
|
|
6
6
|
import { listBundleMcpServerCapabilitiesForGateway, listBundleMcpServerToolsForGateway } from "../../../agent/mcp/bundle-mcp-gateway.js";
|
|
7
7
|
//#region src/gateway/hono/routes/mcp.ts
|
|
@@ -13,7 +13,7 @@ import { getImageGenerationProvider, reloadImageGenerationProviders, resolveImag
|
|
|
13
13
|
import { SessionConfigStore } from "../../../session/config-store.js";
|
|
14
14
|
import { getModelThinking } from "../../../providers/model-thinking.js";
|
|
15
15
|
import { deleteCustomImageProvider, listCustomImageProviders, upsertCustomImageProvider } from "../../custom-image-providers.js";
|
|
16
|
-
import { getAgentImageGenerationConfig, getImageGenerationCatalog, prepareImageGenerationSetup, verifyImageGenerationCredential } from "../../image-generation-setup.js";
|
|
16
|
+
import { getAgentImageGenerationConfig, getDefaultImageGenerationConfig, getImageGenerationCatalog, prepareDefaultImageGenerationSetup, prepareImageGenerationSetup, verifyImageGenerationCredential } from "../../image-generation-setup.js";
|
|
17
17
|
import { discoverProviderModels, isProviderApiDiscoverable } from "../../../providers/model-discovery.js";
|
|
18
18
|
import { getXopcCloudCatalogCoordinator } from "../../../providers/xopc-cloud-catalog-coordinator.js";
|
|
19
19
|
import { respondStartupUnavailable } from "../lib/startup-unavailable.js";
|
|
@@ -505,6 +505,65 @@ function registerModelsRoutes(authenticated, deps) {
|
|
|
505
505
|
}, 502);
|
|
506
506
|
}
|
|
507
507
|
});
|
|
508
|
+
authenticated.get("/api/image-generation/default", (c) => c.json({
|
|
509
|
+
ok: true,
|
|
510
|
+
payload: getDefaultImageGenerationConfig(service.currentConfig)
|
|
511
|
+
}));
|
|
512
|
+
authenticated.post("/api/image-generation/default/setup", strictRateLimitMiddleware, async (c) => {
|
|
513
|
+
const body = await c.req.json().catch(() => null);
|
|
514
|
+
if (!body || typeof body.providerId !== "string") return c.json({
|
|
515
|
+
ok: false,
|
|
516
|
+
error: { message: "providerId is required" }
|
|
517
|
+
}, 400);
|
|
518
|
+
const prepared = prepareDefaultImageGenerationSetup(service.currentConfig, {
|
|
519
|
+
providerId: body.providerId,
|
|
520
|
+
...typeof body.modelId === "string" ? { modelId: body.modelId } : {},
|
|
521
|
+
...body.providerConfig && typeof body.providerConfig === "object" && !Array.isArray(body.providerConfig) ? { providerConfig: body.providerConfig } : {}
|
|
522
|
+
});
|
|
523
|
+
if (prepared.ok === false) return c.json({
|
|
524
|
+
ok: false,
|
|
525
|
+
error: { message: prepared.error }
|
|
526
|
+
}, 400);
|
|
527
|
+
const resolver = new CredentialResolver();
|
|
528
|
+
const usesApiKey = resolveImageGenerationCredentialMode(getImageGenerationProvider(prepared.providerId)) === "api-key";
|
|
529
|
+
const previousKey = usesApiKey ? await resolver.revealGatewayStoredApiKey(prepared.providerId) : void 0;
|
|
530
|
+
const suppliedKey = typeof body.apiKey === "string" ? body.apiKey.trim() : "";
|
|
531
|
+
const effectiveKey = usesApiKey ? suppliedKey || await resolver.resolveApiKey(prepared.providerId) : void 0;
|
|
532
|
+
if (usesApiKey && !effectiveKey) return c.json({
|
|
533
|
+
ok: false,
|
|
534
|
+
error: { message: "API key is required" }
|
|
535
|
+
}, 400);
|
|
536
|
+
const verification = usesApiKey && suppliedKey ? await verifyImageGenerationCredential({
|
|
537
|
+
providerId: prepared.providerId,
|
|
538
|
+
apiKey: suppliedKey,
|
|
539
|
+
baseUrl: typeof body.providerConfig?.baseUrl === "string" ? body.providerConfig.baseUrl : void 0
|
|
540
|
+
}) : {
|
|
541
|
+
verified: false,
|
|
542
|
+
supported: false
|
|
543
|
+
};
|
|
544
|
+
if (verification.supported && !verification.verified) return c.json({
|
|
545
|
+
ok: false,
|
|
546
|
+
error: { message: verification.message ?? "Credential verification failed" }
|
|
547
|
+
}, 400);
|
|
548
|
+
if (usesApiKey && suppliedKey) await resolver.saveApiKey(prepared.providerId, suppliedKey, { profileName: "default" });
|
|
549
|
+
const saved = await service.saveConfig(prepared.config);
|
|
550
|
+
if (!saved.saved) {
|
|
551
|
+
if (usesApiKey && suppliedKey) if (previousKey) await resolver.saveApiKey(prepared.providerId, previousKey, { profileName: "default" });
|
|
552
|
+
else await resolver.deleteProfile(`${prepared.providerId}:default`);
|
|
553
|
+
return c.json({
|
|
554
|
+
ok: false,
|
|
555
|
+
error: { message: saved.error ?? "Failed to save configuration" }
|
|
556
|
+
}, 500);
|
|
557
|
+
}
|
|
558
|
+
return c.json({
|
|
559
|
+
ok: true,
|
|
560
|
+
payload: {
|
|
561
|
+
default: getDefaultImageGenerationConfig(service.currentConfig),
|
|
562
|
+
providers: getImageGenerationCatalog(service.currentConfig),
|
|
563
|
+
verification
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
});
|
|
508
567
|
authenticated.get("/api/agents/:agentId/image-generation", (c) => {
|
|
509
568
|
try {
|
|
510
569
|
return c.json({
|
|
@@ -5,7 +5,7 @@ import { resolveGatewayEffectiveHost } from "../../../config/gateway-bind.js";
|
|
|
5
5
|
import { getShareStore } from "../../../share/share-store.js";
|
|
6
6
|
import { resolveShareUrl } from "../../../share/share-url.js";
|
|
7
7
|
import { resolveReverseProxyPublicUrl } from "../../public-url.js";
|
|
8
|
-
import {
|
|
8
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
9
9
|
import { NoteShareService, NoteShareVersionConflictError } from "../../../share/note-share-service.js";
|
|
10
10
|
import { createReadStream } from "node:fs";
|
|
11
11
|
import { createHash } from "node:crypto";
|
|
@@ -412,11 +412,7 @@ function registerNotesRoutes(authenticated, deps) {
|
|
|
412
412
|
});
|
|
413
413
|
});
|
|
414
414
|
authenticated.post("/api/notes/:id/shares", async (c) => {
|
|
415
|
-
const
|
|
416
|
-
if (!gatewayToken) return c.json({
|
|
417
|
-
ok: false,
|
|
418
|
-
error: { message: "Token required" }
|
|
419
|
-
}, 401);
|
|
415
|
+
const principalId = getGatewayPrincipal(c).principalId;
|
|
420
416
|
const body = await c.req.json().catch(() => ({}));
|
|
421
417
|
const shares = noteShares();
|
|
422
418
|
try {
|
|
@@ -426,7 +422,7 @@ function registerNotesRoutes(authenticated, deps) {
|
|
|
426
422
|
ttlMs: typeof body.ttlMs === "number" ? body.ttlMs : void 0,
|
|
427
423
|
maxViews: body.maxViews === null ? null : typeof body.maxViews === "number" ? body.maxViews : void 0,
|
|
428
424
|
description: typeof body.description === "string" ? body.description.trim() || void 0 : void 0,
|
|
429
|
-
gatewayTokenHash: createHash("sha256").update(
|
|
425
|
+
gatewayTokenHash: createHash("sha256").update(principalId, "utf8").digest("hex").slice(0, 12)
|
|
430
426
|
});
|
|
431
427
|
const resolved = resolveShareUrl(record.token, shareUrlContext());
|
|
432
428
|
return c.json({
|
|
@@ -1,26 +1,51 @@
|
|
|
1
1
|
import { getSqliteDatabase } from "../../../storage/sqlite/transaction.js";
|
|
2
|
-
import { getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
|
|
3
|
-
import { resolveProjectAgentId } from "../../../projects/project-agent.js";
|
|
4
|
-
import "../../../projects/index.js";
|
|
5
2
|
import { ProactiveConflict, proactivePreferences, updateProactivePreferences } from "../../../proactive/policy/service.js";
|
|
6
|
-
import { recordProactivePresence } from "../../../proactive/policy/presence.js";
|
|
7
3
|
import { controlledSubscriptions, createControlledSubscription, requireSubscription, templateCatalog, updateControlledSubscription } from "../../../proactive/scenarios/control.js";
|
|
4
|
+
import { listMailFollowUps, mailFollowUpSources, startMailFollowUp, updateMailFollowUp } from "../../../proactive/follow-ups.js";
|
|
8
5
|
import { cardChanges, getCard, listCards, performCardAction } from "../../../proactive/inbox/cards.js";
|
|
6
|
+
import { checkDelegation, delegationOverview, startDelegation } from "../../../proactive/experience.js";
|
|
7
|
+
import { recordProactivePresence } from "../../../proactive/policy/presence.js";
|
|
9
8
|
import { digestCards } from "../../../proactive/inbox/digest.js";
|
|
10
9
|
import { acknowledgeBrowserProbe, listBrowserProbes, prepareBrowserPush, registerBrowserPush, testBrowserPush, unregisterBrowserPush } from "../../../notifications/web-push.js";
|
|
11
10
|
import { ReadonlyProactiveAgentExecutor } from "../../../proactive/execution/agent-executor.js";
|
|
12
11
|
import { proactiveMetrics } from "../../../proactive/metrics.js";
|
|
13
|
-
import { prepareCardWorkflow, workflowForCard } from "../../../proactive/actions/workflow.js";
|
|
14
12
|
import { previewSubscription } from "../../../proactive/scenarios/preview.js";
|
|
15
13
|
import { ZodError } from "zod";
|
|
16
14
|
//#region src/gateway/hono/routes/proactive-control.ts
|
|
17
|
-
init_resolve_route();
|
|
18
15
|
function registerProactiveControlRoutes(app, deps) {
|
|
19
16
|
app.onError((error, c) => c.json({
|
|
20
17
|
ok: false,
|
|
21
18
|
error: error instanceof ZodError ? "Invalid request" : error.message
|
|
22
19
|
}, error instanceof ProactiveConflict ? 409 : 400));
|
|
23
20
|
const workspace = () => deps.service.currentWorkspacePath;
|
|
21
|
+
app.get("/api/proactive/follow-ups/sources", (c) => c.json({
|
|
22
|
+
ok: true,
|
|
23
|
+
sources: mailFollowUpSources(workspace())
|
|
24
|
+
}));
|
|
25
|
+
app.get("/api/proactive/follow-ups", (c) => c.json({
|
|
26
|
+
ok: true,
|
|
27
|
+
followUps: listMailFollowUps(workspace())
|
|
28
|
+
}));
|
|
29
|
+
app.post("/api/proactive/follow-ups", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
30
|
+
ok: true,
|
|
31
|
+
followUp: startMailFollowUp(workspace(), await c.req.json())
|
|
32
|
+
}, 201));
|
|
33
|
+
app.patch("/api/proactive/follow-ups/:id", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
34
|
+
ok: true,
|
|
35
|
+
followUp: updateMailFollowUp(workspace(), c.req.param("id"), await c.req.json())
|
|
36
|
+
}));
|
|
37
|
+
app.get("/api/proactive/overview", (c) => c.json({
|
|
38
|
+
ok: true,
|
|
39
|
+
...delegationOverview(workspace())
|
|
40
|
+
}));
|
|
41
|
+
app.post("/api/proactive/delegations", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
42
|
+
ok: true,
|
|
43
|
+
subscription: startDelegation(workspace(), await c.req.json())
|
|
44
|
+
}, 201));
|
|
45
|
+
app.post("/api/proactive/subscriptions/:id/check", deps.strictRateLimitMiddleware, (c) => c.json({
|
|
46
|
+
ok: true,
|
|
47
|
+
...checkDelegation(workspace(), c.req.param("id"))
|
|
48
|
+
}, 202));
|
|
24
49
|
for (const path of ["/api/proactive/*", "/api/inbox/judgments/*"]) app.use(path, async (c, next) => {
|
|
25
50
|
try {
|
|
26
51
|
const id = c.req.path.match(/^\/api\/inbox\/judgments\/([^/]+)/)?.[1];
|
|
@@ -57,24 +82,6 @@ function registerProactiveControlRoutes(app, deps) {
|
|
|
57
82
|
unregisterBrowserPush(workspace(), c.req.param("id"));
|
|
58
83
|
return c.json({ ok: true });
|
|
59
84
|
});
|
|
60
|
-
app.get("/api/inbox/judgments/:itemId/workflow", async (c) => c.json({
|
|
61
|
-
ok: true,
|
|
62
|
-
workflow: await workflowForCard(c.req.param("itemId"), workspace(), deps.service.createWorkflowRunService())
|
|
63
|
-
}));
|
|
64
|
-
app.post("/api/inbox/judgments/:itemId/prepare", deps.strictRateLimitMiddleware, async (c) => {
|
|
65
|
-
const card = getCard(c.req.param("itemId"), workspace());
|
|
66
|
-
const sub = requireSubscription(card.subscriptionId, workspace());
|
|
67
|
-
const config = deps.service.currentConfig;
|
|
68
|
-
const agentId = sub.scopeKind === "project" ? resolveProjectAgentId({
|
|
69
|
-
config,
|
|
70
|
-
projects: deps.service.projects,
|
|
71
|
-
projectId: sub.scopeId
|
|
72
|
-
}) : getDefaultAgentId(config);
|
|
73
|
-
return c.json({
|
|
74
|
-
ok: true,
|
|
75
|
-
workflow: await prepareCardWorkflow(workspace(), card.id, await c.req.json(), agentId, deps.service.createWorkflowRunService())
|
|
76
|
-
}, 202);
|
|
77
|
-
});
|
|
78
85
|
app.post("/api/proactive/presence", deps.strictRateLimitMiddleware, async (c) => {
|
|
79
86
|
recordProactivePresence(workspace(), await c.req.json());
|
|
80
87
|
return c.json({ ok: true });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { deleteBrowserTabBinding } from "../../../storage/sqlite/browser-tab-binding-repository.js";
|
|
2
|
+
import { SessionDiscoveryQuerySchema } from "../../../../packages/gateway-contract/src/session-identity.js";
|
|
2
3
|
import { buildSessionKey, init_session_key } from "../../../routing/session-key.js";
|
|
3
4
|
import { resolveProjectAgentId } from "../../../projects/project-agent.js";
|
|
4
5
|
import "../../../projects/index.js";
|
|
@@ -259,8 +260,18 @@ function registerSessionsRoutes(authenticated, deps) {
|
|
|
259
260
|
const blocked = ensureGatewayReadyForSessions(c, service, "sessions.list");
|
|
260
261
|
if (blocked) return blocked;
|
|
261
262
|
const query = c.req.query();
|
|
263
|
+
const discovery = SessionDiscoveryQuerySchema.safeParse({
|
|
264
|
+
sources: query.sources?.split(","),
|
|
265
|
+
purposes: query.purposes?.split(","),
|
|
266
|
+
activity: query.activity,
|
|
267
|
+
agentId: query.agentId,
|
|
268
|
+
excludeArchived: query.excludeArchived === "true"
|
|
269
|
+
});
|
|
270
|
+
if (!discovery.success) return c.json({ error: "Invalid session filters" }, 400);
|
|
271
|
+
if (query.updatedAfter && !Number.isFinite(Number(query.updatedAfter))) return c.json({ error: "Invalid session time filter" }, 400);
|
|
262
272
|
const sessionTypes = query.types?.split(",").map((value) => value.trim()).filter(isSessionType);
|
|
263
273
|
const result = await service.sessions.listSessions({
|
|
274
|
+
...discovery.data,
|
|
264
275
|
status: query.status,
|
|
265
276
|
search: query.search,
|
|
266
277
|
channel: query.channel,
|
|
@@ -15,10 +15,10 @@ import { publishHostedStaticSite } from "../../../share/hosted-static-site-publi
|
|
|
15
15
|
import { resolveReverseProxyPublicUrl } from "../../public-url.js";
|
|
16
16
|
import { audienceDefaults, cleanupStagedSite, decideShareKind, forgetStagedSite, makeDescription, makeTitle, probeShareTarget, rememberStagedSite, stageSingleHtmlAsSite } from "../../../share/share-auto.js";
|
|
17
17
|
import { deleteThumbnail, placeholderSvg, readThumbnail, scheduleThumbnail, thumbnailContentType, thumbnailExists } from "../../../share/share-thumbnail.js";
|
|
18
|
-
import { extractToken } from "../../auth.js";
|
|
19
18
|
import { getGatewayFileSpaceService } from "../../file-space-service.js";
|
|
20
19
|
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
21
20
|
import { SHARED_HTML_CSP } from "../../security/csp.js";
|
|
21
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
22
22
|
import { renderFolderLandingPage, renderShareExpiredPage, renderShareLandingPage, renderSnapshotShareLandingPage } from "../../../share/share-landing.js";
|
|
23
23
|
import { resolveScopedMediaReference } from "../../media-access.js";
|
|
24
24
|
import { NoteShareService } from "../../../share/note-share-service.js";
|
|
@@ -56,7 +56,7 @@ function resolveShareConfig(service) {
|
|
|
56
56
|
if (!raw || typeof raw !== "object") return {};
|
|
57
57
|
return raw;
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function hashPrincipal(token) {
|
|
60
60
|
return createHash("sha256").update(token, "utf8").digest("hex").slice(0, 12);
|
|
61
61
|
}
|
|
62
62
|
const MAX_CONCURRENT_DOWNLOADS_PER_TOKEN = 5;
|
|
@@ -594,11 +594,7 @@ function registerShareRoutes(authenticated, deps) {
|
|
|
594
594
|
});
|
|
595
595
|
});
|
|
596
596
|
authenticated.post("/api/sessions/:key/shares", async (c) => {
|
|
597
|
-
const
|
|
598
|
-
if (!gatewayToken) return c.json({
|
|
599
|
-
ok: false,
|
|
600
|
-
error: { message: "Token required" }
|
|
601
|
-
}, 401);
|
|
597
|
+
const principalId = getGatewayPrincipal(c).principalId;
|
|
602
598
|
const body = await c.req.json().catch(() => ({}));
|
|
603
599
|
if (typeof body.expectedSessionId !== "string" || typeof body.expectedCutoffSeq !== "number" || typeof body.expectedMetadataUpdatedAt !== "string") return c.json({
|
|
604
600
|
ok: false,
|
|
@@ -614,7 +610,7 @@ function registerShareRoutes(authenticated, deps) {
|
|
|
614
610
|
description: typeof body.description === "string" ? body.description.trim() || void 0 : void 0,
|
|
615
611
|
includeToolActivities: body.includeToolActivities === true,
|
|
616
612
|
attachmentIds: Array.isArray(body.attachmentIds) ? body.attachmentIds.filter((id) => typeof id === "string") : void 0,
|
|
617
|
-
gatewayTokenHash:
|
|
613
|
+
gatewayTokenHash: hashPrincipal(principalId)
|
|
618
614
|
});
|
|
619
615
|
const resolved = resolveShareUrl(record.token, getShareUrlContext(service));
|
|
620
616
|
return c.json({
|
|
@@ -1130,11 +1126,7 @@ function registerShareRoutes(authenticated, deps) {
|
|
|
1130
1126
|
}
|
|
1131
1127
|
});
|
|
1132
1128
|
authenticated.post("/api/shares", async (c) => {
|
|
1133
|
-
const
|
|
1134
|
-
if (!gatewayToken) return c.json({
|
|
1135
|
-
ok: false,
|
|
1136
|
-
error: { message: "Token required" }
|
|
1137
|
-
}, 401);
|
|
1129
|
+
const principalId = getGatewayPrincipal(c).principalId;
|
|
1138
1130
|
let body;
|
|
1139
1131
|
try {
|
|
1140
1132
|
body = await c.req.json();
|
|
@@ -1201,7 +1193,7 @@ function registerShareRoutes(authenticated, deps) {
|
|
|
1201
1193
|
sessionKey,
|
|
1202
1194
|
agentId,
|
|
1203
1195
|
workspaceRoot,
|
|
1204
|
-
gatewayTokenHash:
|
|
1196
|
+
gatewayTokenHash: hashPrincipal(principalId),
|
|
1205
1197
|
kind,
|
|
1206
1198
|
directoryMode,
|
|
1207
1199
|
followSymlinks,
|
|
@@ -1242,11 +1234,7 @@ function registerShareRoutes(authenticated, deps) {
|
|
|
1242
1234
|
* reachability) in a single round-trip.
|
|
1243
1235
|
*/
|
|
1244
1236
|
authenticated.post("/api/shares/auto", async (c) => {
|
|
1245
|
-
const
|
|
1246
|
-
if (!gatewayToken) return c.json({
|
|
1247
|
-
ok: false,
|
|
1248
|
-
error: { message: "Token required" }
|
|
1249
|
-
}, 401);
|
|
1237
|
+
const principalId = getGatewayPrincipal(c).principalId;
|
|
1250
1238
|
let body;
|
|
1251
1239
|
try {
|
|
1252
1240
|
body = await c.req.json();
|
|
@@ -1309,7 +1297,7 @@ function registerShareRoutes(authenticated, deps) {
|
|
|
1309
1297
|
const defaults = audienceDefaults(audience);
|
|
1310
1298
|
const ttlMs = ttlOverride ?? defaults.ttlMs;
|
|
1311
1299
|
const maxViews = maxViewsOverride !== void 0 ? maxViewsOverride : defaults.maxViews;
|
|
1312
|
-
const tokenHash =
|
|
1300
|
+
const tokenHash = hashPrincipal(principalId);
|
|
1313
1301
|
const urlCtx = getShareUrlContext(service);
|
|
1314
1302
|
try {
|
|
1315
1303
|
if (decision.kind === "site") {
|