@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
|
@@ -3,10 +3,10 @@ import { resolveSiteShareConfig } from "../../../share/site-share-config.js";
|
|
|
3
3
|
import { getSiteShareStore } from "../../../share/site-share-store.js";
|
|
4
4
|
import { resolveSiteShareUrl } from "../../../share/share-url.js";
|
|
5
5
|
import { resolveReverseProxyPublicUrl } from "../../public-url.js";
|
|
6
|
-
import {
|
|
6
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
//#region src/gateway/hono/routes/site-shares.ts
|
|
9
|
-
function
|
|
9
|
+
function hashPrincipal(token) {
|
|
10
10
|
return createHash("sha256").update(token, "utf8").digest("hex").slice(0, 12);
|
|
11
11
|
}
|
|
12
12
|
function buildShareUrls(record, publicHostSuffix, service) {
|
|
@@ -42,11 +42,7 @@ function registerSiteShareRoutes(authenticated, deps) {
|
|
|
42
42
|
return resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
|
|
43
43
|
}
|
|
44
44
|
authenticated.post("/api/site-shares", async (c) => {
|
|
45
|
-
const
|
|
46
|
-
if (!gatewayToken) return c.json({
|
|
47
|
-
ok: false,
|
|
48
|
-
error: { message: "Token required" }
|
|
49
|
-
}, 401);
|
|
45
|
+
const principalId = getGatewayPrincipal(c).principalId;
|
|
50
46
|
let body;
|
|
51
47
|
try {
|
|
52
48
|
body = await c.req.json();
|
|
@@ -96,7 +92,7 @@ function registerSiteShareRoutes(authenticated, deps) {
|
|
|
96
92
|
sessionKey,
|
|
97
93
|
agentId,
|
|
98
94
|
workspaceRoot,
|
|
99
|
-
gatewayTokenHash:
|
|
95
|
+
gatewayTokenHash: hashPrincipal(principalId)
|
|
100
96
|
});
|
|
101
97
|
const urls = buildShareUrls(record, store.getConfig().publicHostSuffix, service);
|
|
102
98
|
return c.json({
|
|
@@ -2,10 +2,11 @@ import { init_public_url, validatePublicUrl } from "../../../config/public-url.j
|
|
|
2
2
|
import { TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TunnelRegistrationSecretError, getTunnelRegistrationSecretMeta, readTunnelRegistrationSecretFromConfigOnly, resolveTunnelBrokerUrl } from "../../../tunnel/env.js";
|
|
3
3
|
import { logTunnelAudit } from "../../../tunnel/tunnel-audit.js";
|
|
4
4
|
import { getTunnelService, hashGatewayToken } from "../../../tunnel/tunnel-service.js";
|
|
5
|
-
import {
|
|
5
|
+
import { requireTunnelGatewayToken } from "../../../tunnel/auth-policy.js";
|
|
6
6
|
import { TUNNEL_CONSENT_REQUIRED_CODE, TunnelConsentError, assertTunnelMayStart, getTunnelConsentState } from "../../../tunnel/consent.js";
|
|
7
7
|
import { configureTunnelFromGatewayConfig } from "../../../tunnel/gateway-lifecycle.js";
|
|
8
8
|
import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, setTunnelEnabledInConfig } from "../../../tunnel/tunnel-config.js";
|
|
9
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
9
10
|
import { consumeTunnelMutationLimit } from "../../../tunnel/tunnel-rate-limit.js";
|
|
10
11
|
import "../../../tunnel/index.js";
|
|
11
12
|
import { provisionTunnelRegistrationKey } from "../../../tunnel/xopc-cloud-registration.js";
|
|
@@ -36,14 +37,9 @@ function enrichTunnelStatus(config, status) {
|
|
|
36
37
|
registrationSecret
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
|
-
function requireGatewayToken(c) {
|
|
40
|
-
return extractToken({ authorization: c.req.header("authorization") ?? void 0 }) ?? null;
|
|
41
|
-
}
|
|
42
40
|
function createTunnelMutationRateLimitMiddleware() {
|
|
43
41
|
return async (c, next) => {
|
|
44
|
-
const
|
|
45
|
-
if (!token) return c.json({ error: "Gateway token required" }, 401);
|
|
46
|
-
const result = consumeTunnelMutationLimit(token);
|
|
42
|
+
const result = consumeTunnelMutationLimit(getGatewayPrincipal(c).principalId);
|
|
47
43
|
if (!result.allowed) {
|
|
48
44
|
c.header("Retry-After", String(Math.ceil(result.retryAfterMs / 1e3)));
|
|
49
45
|
return c.json({
|
|
@@ -66,7 +62,6 @@ function registerTunnelRoutes(authenticated, deps) {
|
|
|
66
62
|
* the UI can render targeted hints (TLS / DNS / wrong service / blocked path).
|
|
67
63
|
*/
|
|
68
64
|
authenticated.post("/api/tunnel/probe-public", tunnelMutationLimit, async (c) => {
|
|
69
|
-
if (!requireGatewayToken(c)) return c.json({ error: "Gateway token required" }, 401);
|
|
70
65
|
let body;
|
|
71
66
|
try {
|
|
72
67
|
body = await c.req.json();
|
|
@@ -142,8 +137,6 @@ function registerTunnelRoutes(authenticated, deps) {
|
|
|
142
137
|
return c.json(enrichTunnelStatus(config, tunnel.getStatus()));
|
|
143
138
|
});
|
|
144
139
|
authenticated.post("/api/tunnel/consent", tunnelMutationLimit, async (c) => {
|
|
145
|
-
const token = requireGatewayToken(c);
|
|
146
|
-
if (!token) return c.json({ error: "Gateway token required" }, 401);
|
|
147
140
|
const config = deps.service.currentConfig;
|
|
148
141
|
applyTunnelConsentToConfig(config);
|
|
149
142
|
const result = await deps.service.saveConfig(config);
|
|
@@ -154,7 +147,7 @@ function registerTunnelRoutes(authenticated, deps) {
|
|
|
154
147
|
const consent = getTunnelConsentState(config);
|
|
155
148
|
logTunnelAudit("tunnel.consent", {
|
|
156
149
|
consentVersion: consent.currentVersion,
|
|
157
|
-
|
|
150
|
+
principalId: getGatewayPrincipal(c).principalId
|
|
158
151
|
}, "Remote access security consent recorded");
|
|
159
152
|
return c.json({
|
|
160
153
|
ok: true,
|
|
@@ -190,10 +183,17 @@ function registerTunnelRoutes(authenticated, deps) {
|
|
|
190
183
|
}
|
|
191
184
|
});
|
|
192
185
|
authenticated.post("/api/tunnel/start", tunnelMutationLimit, async (c) => {
|
|
186
|
+
let token;
|
|
187
|
+
try {
|
|
188
|
+
token = requireTunnelGatewayToken(deps.service.getResolvedAuth());
|
|
189
|
+
} catch (error) {
|
|
190
|
+
return c.json({
|
|
191
|
+
error: error.message,
|
|
192
|
+
code: "TUNNEL_AUTH_REQUIRED"
|
|
193
|
+
}, 403);
|
|
194
|
+
}
|
|
193
195
|
await configureTunnelFromService(deps, { force: true });
|
|
194
196
|
const config = deps.service.currentConfig;
|
|
195
|
-
const token = requireGatewayToken(c);
|
|
196
|
-
if (!token) return c.json({ error: "Gateway token required" }, 401);
|
|
197
197
|
try {
|
|
198
198
|
assertTunnelMayStart(config);
|
|
199
199
|
} catch (err) {
|
|
@@ -19,6 +19,23 @@ export declare function getAgentImageGenerationConfig(config: Config, agentIdRaw
|
|
|
19
19
|
timeoutMs?: number;
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
|
+
export declare function getDefaultImageGenerationConfig(config: Config): {
|
|
23
|
+
model: {
|
|
24
|
+
primary: string;
|
|
25
|
+
fallbacks: string[];
|
|
26
|
+
autoProviderFallback: boolean;
|
|
27
|
+
timeoutMs?: number;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare function prepareDefaultImageGenerationSetup(config: Config, input: ImageGenerationSetupInput): {
|
|
31
|
+
ok: true;
|
|
32
|
+
config: Config;
|
|
33
|
+
providerId: string;
|
|
34
|
+
modelId: string;
|
|
35
|
+
} | {
|
|
36
|
+
ok: false;
|
|
37
|
+
error: string;
|
|
38
|
+
};
|
|
22
39
|
export declare function prepareImageGenerationSetup(config: Config, agentIdRaw: string, input: ImageGenerationSetupInput): {
|
|
23
40
|
ok: true;
|
|
24
41
|
config: Config;
|
|
@@ -59,12 +59,10 @@ function getAgentImageGenerationConfig(config, agentIdRaw) {
|
|
|
59
59
|
model: resolveEffectiveAgentConfigForAgent(config, agentId).config.models.imageGeneration ?? null
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
error: `Agent not found: ${agentId}`
|
|
67
|
-
};
|
|
62
|
+
function getDefaultImageGenerationConfig(config) {
|
|
63
|
+
return { model: config.agents.defaults.models.imageGeneration ?? null };
|
|
64
|
+
}
|
|
65
|
+
function prepareImageGenerationConfig(config, input, applyModel) {
|
|
68
66
|
const providerId = input.providerId.trim();
|
|
69
67
|
const provider = getImageGenerationProvider(providerId);
|
|
70
68
|
if (!provider) return {
|
|
@@ -82,11 +80,6 @@ function prepareImageGenerationSetup(config, agentIdRaw, input) {
|
|
|
82
80
|
error: parsedProviderConfig.error
|
|
83
81
|
};
|
|
84
82
|
const next = structuredClone(config);
|
|
85
|
-
const index = next.agents.list.findIndex((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId);
|
|
86
|
-
if (index < 0) return {
|
|
87
|
-
ok: false,
|
|
88
|
-
error: `Agent not found: ${agentId}`
|
|
89
|
-
};
|
|
90
83
|
next.providers = {
|
|
91
84
|
...next.providers ?? {},
|
|
92
85
|
[providerId]: {
|
|
@@ -94,15 +87,11 @@ function prepareImageGenerationSetup(config, agentIdRaw, input) {
|
|
|
94
87
|
...parsedProviderConfig.value
|
|
95
88
|
}
|
|
96
89
|
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
fallbacks: [],
|
|
103
|
-
autoProviderFallback: false
|
|
104
|
-
}
|
|
105
|
-
};
|
|
90
|
+
applyModel(next, {
|
|
91
|
+
primary: `${providerId}/${modelId}`,
|
|
92
|
+
fallbacks: [],
|
|
93
|
+
autoProviderFallback: false
|
|
94
|
+
});
|
|
106
95
|
const parsed = ConfigSchema.safeParse(next);
|
|
107
96
|
if (!parsed.success) return {
|
|
108
97
|
ok: false,
|
|
@@ -115,6 +104,26 @@ function prepareImageGenerationSetup(config, agentIdRaw, input) {
|
|
|
115
104
|
modelId
|
|
116
105
|
};
|
|
117
106
|
}
|
|
107
|
+
function prepareDefaultImageGenerationSetup(config, input) {
|
|
108
|
+
return prepareImageGenerationConfig(config, input, (next, model) => {
|
|
109
|
+
next.agents.defaults.models.imageGeneration = model;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function prepareImageGenerationSetup(config, agentIdRaw, input) {
|
|
113
|
+
const agentId = normalizeAgentId(agentIdRaw);
|
|
114
|
+
if (!config.agents.list.some((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId)) return {
|
|
115
|
+
ok: false,
|
|
116
|
+
error: `Agent not found: ${agentId}`
|
|
117
|
+
};
|
|
118
|
+
return prepareImageGenerationConfig(config, input, (next, model) => {
|
|
119
|
+
const index = next.agents.list.findIndex((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === agentId);
|
|
120
|
+
const entry = next.agents.list[index];
|
|
121
|
+
entry.models = {
|
|
122
|
+
...entry.models ?? {},
|
|
123
|
+
imageGeneration: model
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
}
|
|
118
127
|
async function verifyImageGenerationCredential(input) {
|
|
119
128
|
const apiKey = input.apiKey.trim();
|
|
120
129
|
if (!apiKey) return {
|
|
@@ -165,4 +174,4 @@ async function verifyImageGenerationCredential(input) {
|
|
|
165
174
|
}
|
|
166
175
|
}
|
|
167
176
|
//#endregion
|
|
168
|
-
export { getAgentImageGenerationConfig, getImageGenerationCatalog, prepareImageGenerationSetup, verifyImageGenerationCredential };
|
|
177
|
+
export { getAgentImageGenerationConfig, getDefaultImageGenerationConfig, getImageGenerationCatalog, prepareDefaultImageGenerationSetup, prepareImageGenerationSetup, verifyImageGenerationCredential };
|
|
@@ -34,6 +34,7 @@ export declare function authPolicyConfig(cfg: ResolvedAuthRateLimitConfig): Auth
|
|
|
34
34
|
declare class BucketRegistry {
|
|
35
35
|
private authFailureLimiter?;
|
|
36
36
|
private authFailureSignature?;
|
|
37
|
+
private identityChallengeLimiter?;
|
|
37
38
|
private strictApiLimiter?;
|
|
38
39
|
private chatApiLimiter?;
|
|
39
40
|
private mediaApiLimiter?;
|
|
@@ -50,6 +51,8 @@ declare class BucketRegistry {
|
|
|
50
51
|
* config read.
|
|
51
52
|
*/
|
|
52
53
|
authFailure(cfg: ResolvedAuthRateLimitConfig): FailureLimiter;
|
|
54
|
+
/** Global pre-authentication signing budget; independent of authenticated traffic. */
|
|
55
|
+
identityChallenge(): RateLimiter;
|
|
53
56
|
/** Authenticated admin / mutation endpoints — 150 req / 60 s per client IP. */
|
|
54
57
|
strictApi(): RateLimiter;
|
|
55
58
|
/** Interactive chat actions — 180 req / 60 s per client IP. */
|
|
@@ -46,6 +46,7 @@ function authPolicyConfig(cfg) {
|
|
|
46
46
|
var BucketRegistry = class {
|
|
47
47
|
authFailureLimiter;
|
|
48
48
|
authFailureSignature;
|
|
49
|
+
identityChallengeLimiter;
|
|
49
50
|
strictApiLimiter;
|
|
50
51
|
chatApiLimiter;
|
|
51
52
|
mediaApiLimiter;
|
|
@@ -75,6 +76,13 @@ var BucketRegistry = class {
|
|
|
75
76
|
}
|
|
76
77
|
return this.authFailureLimiter;
|
|
77
78
|
}
|
|
79
|
+
/** Global pre-authentication signing budget; independent of authenticated traffic. */
|
|
80
|
+
identityChallenge() {
|
|
81
|
+
return this.identityChallengeLimiter ??= new RateLimiter({
|
|
82
|
+
maxRequests: 300,
|
|
83
|
+
windowMs: 6e4
|
|
84
|
+
});
|
|
85
|
+
}
|
|
78
86
|
/** Authenticated admin / mutation endpoints — 150 req / 60 s per client IP. */
|
|
79
87
|
strictApi() {
|
|
80
88
|
if (!this.strictApiLimiter) this.strictApiLimiter = new RateLimiter({
|
|
@@ -158,6 +166,7 @@ var BucketRegistry = class {
|
|
|
158
166
|
}
|
|
159
167
|
destroyAll() {
|
|
160
168
|
this.authFailureLimiter?.destroy();
|
|
169
|
+
this.identityChallengeLimiter?.destroy();
|
|
161
170
|
this.strictApiLimiter?.destroy();
|
|
162
171
|
this.chatApiLimiter?.destroy();
|
|
163
172
|
this.mediaApiLimiter?.destroy();
|
|
@@ -169,6 +178,7 @@ var BucketRegistry = class {
|
|
|
169
178
|
this.sharePublicShortLimiter?.destroy();
|
|
170
179
|
this.sharePublicLongLimiter?.destroy();
|
|
171
180
|
this.authFailureLimiter = void 0;
|
|
181
|
+
this.identityChallengeLimiter = void 0;
|
|
172
182
|
this.strictApiLimiter = void 0;
|
|
173
183
|
this.chatApiLimiter = void 0;
|
|
174
184
|
this.mediaApiLimiter = void 0;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isAllInterfacesHost, isLoopbackHost, resolveGatewayCorsOrigins } from "./host.js";
|
|
2
2
|
import { resolveGatewayListenPlan } from "./listen.js";
|
|
3
3
|
import { assertTailscaleExposureCompatible } from "./tailscale-lifecycle.js";
|
|
4
|
+
import { requireTunnelGatewayToken } from "../tunnel/auth-policy.js";
|
|
4
5
|
import { isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled } from "./rate-limit/env-flags.js";
|
|
5
6
|
import "./rate-limit/index.js";
|
|
6
7
|
//#region src/gateway/runtime-config.ts
|
|
@@ -15,6 +16,7 @@ function hasSharedSecret(auth) {
|
|
|
15
16
|
* Throws when bind/auth/origin combinations are unsafe for network exposure.
|
|
16
17
|
*/
|
|
17
18
|
function assertGatewayRuntimeConfig(params) {
|
|
19
|
+
if (params.cfg.tunnel?.enabled) requireTunnelGatewayToken(params.auth);
|
|
18
20
|
const { bindMode, bindHost, customBindHost } = resolveGatewayListenPlan({
|
|
19
21
|
cfg: params.cfg,
|
|
20
22
|
bindOverride: params.bindOverride
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Context } from 'hono';
|
|
2
|
+
export declare function readBrowserSessionCookie(c: Context): string | undefined;
|
|
3
|
+
export declare function browserCookieRequestAllowed(c: Context): boolean;
|
|
4
|
+
export declare function writeBrowserSessionCookie(c: Context, token: string, expiresAt: number): void;
|
|
5
|
+
export declare function clearBrowserSessionCookie(c: Context): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { isLoopbackHost } from "../host.js";
|
|
2
|
+
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
|
|
3
|
+
//#region src/gateway/security/browser-session.ts
|
|
4
|
+
function origin(c) {
|
|
5
|
+
return new URL(`http://${c.req.header("host") ?? new URL(c.req.url).host}`);
|
|
6
|
+
}
|
|
7
|
+
function secure(c) {
|
|
8
|
+
return !isLoopbackHost(origin(c).hostname.replace(/^\[|\]$/g, ""));
|
|
9
|
+
}
|
|
10
|
+
function name(c) {
|
|
11
|
+
return secure(c) ? "__Host-xopc-session" : "xopc-local-session";
|
|
12
|
+
}
|
|
13
|
+
function readBrowserSessionCookie(c) {
|
|
14
|
+
return getCookie(c, name(c));
|
|
15
|
+
}
|
|
16
|
+
function browserCookieRequestAllowed(c) {
|
|
17
|
+
const requestOrigin = c.req.header("origin");
|
|
18
|
+
if (requestOrigin) try {
|
|
19
|
+
const parsed = new URL(requestOrigin);
|
|
20
|
+
const localOrigin = isLoopbackHost(parsed.hostname.replace(/^\[|\]$/g, ""));
|
|
21
|
+
return (parsed.host === origin(c).host || !secure(c) && localOrigin) && (parsed.protocol === "https:" || !secure(c) && parsed.protocol === "http:");
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return ["GET", "HEAD"].includes(c.req.method) && c.req.header("sec-fetch-site") !== "cross-site";
|
|
26
|
+
}
|
|
27
|
+
function writeBrowserSessionCookie(c, token, expiresAt) {
|
|
28
|
+
setCookie(c, name(c), token, {
|
|
29
|
+
httpOnly: true,
|
|
30
|
+
secure: secure(c),
|
|
31
|
+
sameSite: "Strict",
|
|
32
|
+
path: "/",
|
|
33
|
+
expires: new Date(expiresAt)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function clearBrowserSessionCookie(c) {
|
|
37
|
+
deleteCookie(c, name(c), {
|
|
38
|
+
httpOnly: true,
|
|
39
|
+
secure: secure(c),
|
|
40
|
+
sameSite: "Strict",
|
|
41
|
+
path: "/"
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { browserCookieRequestAllowed, clearBrowserSessionCookie, readBrowserSessionCookie, writeBrowserSessionCookie };
|
|
@@ -5,6 +5,7 @@ export type GatewayPrincipal = {
|
|
|
5
5
|
principalId: string;
|
|
6
6
|
deviceId?: string;
|
|
7
7
|
accessSessionId?: string;
|
|
8
|
+
browserSessionId?: string;
|
|
8
9
|
scopes: readonly GatewayScope[];
|
|
9
10
|
};
|
|
10
11
|
export declare function setGatewayPrincipal(c: Context, principal: GatewayPrincipal): void;
|
|
@@ -48,6 +48,7 @@ export declare class GatewayService {
|
|
|
48
48
|
private readonly modelCatalogSync;
|
|
49
49
|
private auth;
|
|
50
50
|
readonly endpointTools: EndpointToolRuntime;
|
|
51
|
+
private isRealtimePrincipalActive;
|
|
51
52
|
readonly realtime: RealtimeRuntime;
|
|
52
53
|
readonly voiceRealtime: VoiceRealtimeRuntime;
|
|
53
54
|
getConfig(): Config;
|
|
@@ -31,11 +31,13 @@ import { resolveProjectAgentId } from "../projects/project-agent.js";
|
|
|
31
31
|
import "../projects/index.js";
|
|
32
32
|
import { resolveEffectiveGatewayPort } from "./host.js";
|
|
33
33
|
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
34
|
+
import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
|
|
35
|
+
import { ProactiveEventService } from "../proactive/service.js";
|
|
36
|
+
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
37
|
+
import { ProactiveInboxService } from "../proactive/inbox/service.js";
|
|
34
38
|
import { AutomationService } from "../automations/service/automation-service.js";
|
|
35
39
|
import { onAutomationProductEvent, publishAutomationProductEvent } from "../automations/product-events.js";
|
|
36
40
|
import "../automations/index.js";
|
|
37
|
-
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
38
|
-
import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
|
|
39
41
|
import { TaskOutboxDispatcher } from "../tasks/task-outbox-dispatcher.js";
|
|
40
42
|
import { TaskRunDispatcher } from "../tasks/task-run-dispatcher.js";
|
|
41
43
|
import { TaskSignalService } from "../tasks/task-signal-service.js";
|
|
@@ -54,12 +56,6 @@ import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
|
|
|
54
56
|
import { ChannelManager } from "../channels/manager.js";
|
|
55
57
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
56
58
|
import "../config/index.js";
|
|
57
|
-
import { DiscussionService } from "../discussions/service.js";
|
|
58
|
-
import { DiscussionOrganizer } from "../discussions/organizer.js";
|
|
59
|
-
import { DiscussionLiveWorker } from "../discussions/live-worker.js";
|
|
60
|
-
import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
|
|
61
|
-
import { DiscussionSealer } from "../discussions/sealer.js";
|
|
62
|
-
import "../discussions/index.js";
|
|
63
59
|
import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
|
|
64
60
|
import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
|
|
65
61
|
import "../knowledge/index.js";
|
|
@@ -67,12 +63,17 @@ import { ConnectionRecoveryService } from "../connectors/connection-recovery-ser
|
|
|
67
63
|
import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
|
|
68
64
|
import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
|
|
69
65
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
66
|
+
import { DiscussionService } from "../discussions/service.js";
|
|
67
|
+
import { DiscussionOrganizer } from "../discussions/organizer.js";
|
|
68
|
+
import { DiscussionLiveWorker } from "../discussions/live-worker.js";
|
|
69
|
+
import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
|
|
70
|
+
import { DiscussionSealer } from "../discussions/sealer.js";
|
|
71
|
+
import "../discussions/index.js";
|
|
70
72
|
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
71
73
|
import "../endpoint-tools/index.js";
|
|
72
74
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
73
75
|
import { prepareAutomationAgentSession } from "./automation-agent-session.js";
|
|
74
76
|
import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
|
|
75
|
-
import { ProactiveInboxService } from "../proactive/inbox/service.js";
|
|
76
77
|
import { deliverProactiveCard } from "../proactive/inbox/delivery.js";
|
|
77
78
|
import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
|
|
78
79
|
import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
|
|
@@ -108,7 +109,6 @@ import "../local-apps/index.js";
|
|
|
108
109
|
import { createRuntimeBrowserAutomationService } from "../browser/automations/runtime-service.js";
|
|
109
110
|
import "../browser/automations/index.js";
|
|
110
111
|
import { mapProductEventToProactive } from "../proactive/events/product-event-bridge.js";
|
|
111
|
-
import { ProactiveEventService } from "../proactive/service.js";
|
|
112
112
|
import { ReadonlyProactiveAgentExecutor } from "../proactive/execution/agent-executor.js";
|
|
113
113
|
import { listInsights } from "../proactive/execution/repository.js";
|
|
114
114
|
import { ProactiveWorker } from "../proactive/execution/worker.js";
|
|
@@ -122,6 +122,7 @@ import { GatewaySessionsApi } from "./service/sessions-api.js";
|
|
|
122
122
|
import { GatewayMarketplaceService } from "./service/marketplace-service.js";
|
|
123
123
|
import { GatewayConfigCoordinator } from "./service/config-coordinator.js";
|
|
124
124
|
import { GatewayAgentRunner } from "./service/agent-runner.js";
|
|
125
|
+
import { isBrowserSessionActive } from "../storage/sqlite/browser-session-repository.js";
|
|
125
126
|
import { RealtimeRuntime } from "../realtime/runtime.js";
|
|
126
127
|
import { VoiceRealtimeRuntime } from "../voice/realtime/runtime.js";
|
|
127
128
|
import { DurableVoiceAgentBroker } from "../voice/realtime/agentBroker.js";
|
|
@@ -165,8 +166,17 @@ var GatewayService = class {
|
|
|
165
166
|
});
|
|
166
167
|
auth;
|
|
167
168
|
endpointTools = new EndpointToolRuntime();
|
|
168
|
-
|
|
169
|
+
isRealtimePrincipalActive = (principalId) => {
|
|
170
|
+
if (!principalId.startsWith("browser:")) return true;
|
|
171
|
+
try {
|
|
172
|
+
return isBrowserSessionActive(principalId.slice(8), this.auth);
|
|
173
|
+
} catch {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
realtime = new RealtimeRuntime(this.endpointTools, this.isRealtimePrincipalActive);
|
|
169
178
|
voiceRealtime = new VoiceRealtimeRuntime({
|
|
179
|
+
isPrincipalActive: this.isRealtimePrincipalActive,
|
|
170
180
|
getConversationContext: async (sessionKey, expectedSessionId) => {
|
|
171
181
|
if ((await this.sessionIndex.getSessionMetadata(sessionKey))?.sessionId !== expectedSessionId) throw new Error("Conversation changed before voice connection");
|
|
172
182
|
const messages = await this.sessionIndex.loadMessages(sessionKey);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
|
|
2
|
+
import { appendCronEventLines } from "./event-prompt.js";
|
|
2
3
|
import { isWithinActiveHours } from "./active-hours.js";
|
|
3
4
|
import { isHeartbeatContentEmpty } from "./content-check.js";
|
|
4
|
-
import { appendCronEventLines } from "./event-prompt.js";
|
|
5
5
|
import { createHeartbeatWake } from "./wake.js";
|
|
6
6
|
export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
|
|
@@ -11,6 +11,7 @@ export type Clock = () => number;
|
|
|
11
11
|
export type KeyedStoreOptions = {
|
|
12
12
|
/** Drop entries whose `lastTouchedMs` is older than this. */
|
|
13
13
|
staleAfterMs: number;
|
|
14
|
+
maxEntries?: number;
|
|
14
15
|
/** How often the sweep runs. Defaults to `staleAfterMs / 4` (capped at 10min). */
|
|
15
16
|
cleanupIntervalMs?: number;
|
|
16
17
|
/** Injected clock for deterministic tests. */
|
|
@@ -20,6 +21,8 @@ export declare class KeyedStore<V extends {
|
|
|
20
21
|
lastTouchedMs: number;
|
|
21
22
|
}> {
|
|
22
23
|
private readonly map;
|
|
24
|
+
private readonly maxEntries;
|
|
25
|
+
private overflow?;
|
|
23
26
|
private readonly clock;
|
|
24
27
|
private readonly staleAfterMs;
|
|
25
28
|
private cleanupTimer?;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
//#region src/infra/rate-limit/keyed-store.ts
|
|
2
2
|
var KeyedStore = class {
|
|
3
3
|
map = /* @__PURE__ */ new Map();
|
|
4
|
+
maxEntries;
|
|
5
|
+
overflow;
|
|
4
6
|
clock;
|
|
5
7
|
staleAfterMs;
|
|
6
8
|
cleanupTimer;
|
|
7
9
|
constructor(opts) {
|
|
10
|
+
this.maxEntries = Math.max(1, opts.maxEntries ?? 1e4);
|
|
8
11
|
this.clock = opts.clock ?? Date.now;
|
|
9
12
|
this.staleAfterMs = Math.max(1e3, opts.staleAfterMs);
|
|
10
13
|
const interval = Math.min(600 * 1e3, Math.max(1e3, opts.cleanupIntervalMs ?? Math.floor(this.staleAfterMs / 4)));
|
|
@@ -12,10 +15,11 @@ var KeyedStore = class {
|
|
|
12
15
|
this.cleanupTimer.unref?.();
|
|
13
16
|
}
|
|
14
17
|
get(key) {
|
|
15
|
-
return this.map.get(key);
|
|
18
|
+
return this.map.get(key) ?? (this.map.size >= this.maxEntries ? this.overflow : void 0);
|
|
16
19
|
}
|
|
17
20
|
set(key, value) {
|
|
18
|
-
this.map.set(key, value);
|
|
21
|
+
if (this.map.has(key) || this.map.size < this.maxEntries) this.map.set(key, value);
|
|
22
|
+
else this.overflow ??= value;
|
|
19
23
|
}
|
|
20
24
|
delete(key) {
|
|
21
25
|
this.map.delete(key);
|
|
@@ -25,6 +29,7 @@ var KeyedStore = class {
|
|
|
25
29
|
}
|
|
26
30
|
clear() {
|
|
27
31
|
this.map.clear();
|
|
32
|
+
this.overflow = void 0;
|
|
28
33
|
}
|
|
29
34
|
destroy() {
|
|
30
35
|
if (this.cleanupTimer) {
|
|
@@ -32,9 +37,11 @@ var KeyedStore = class {
|
|
|
32
37
|
this.cleanupTimer = void 0;
|
|
33
38
|
}
|
|
34
39
|
this.map.clear();
|
|
40
|
+
this.overflow = void 0;
|
|
35
41
|
}
|
|
36
42
|
sweep() {
|
|
37
43
|
const now = this.clock();
|
|
44
|
+
if (this.overflow && now - this.overflow.lastTouchedMs > this.staleAfterMs) this.overflow = void 0;
|
|
38
45
|
for (const [k, v] of this.map.entries()) if (now - v.lastTouchedMs > this.staleAfterMs) this.map.delete(k);
|
|
39
46
|
}
|
|
40
47
|
};
|
|
@@ -152,7 +152,7 @@ async function testBrowserPush(workspaceId, subscriptionId, send = webPush.sendN
|
|
|
152
152
|
id,
|
|
153
153
|
title: "xopc 推送测试 / Push test",
|
|
154
154
|
body: "点击此通知确认打开 / Tap to confirm opening",
|
|
155
|
-
route: `/
|
|
155
|
+
route: `/assistant-work?probe=${encodeURIComponent(id)}`
|
|
156
156
|
}), {
|
|
157
157
|
vapidDetails: {
|
|
158
158
|
subject: "https://xopc.ai",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
2
|
-
import {
|
|
2
|
+
import { insightSourcesAuthorized, insightSourcesChanged } from "../execution/authorization.js";
|
|
3
3
|
import { effectiveProactivePolicy } from "../policy/service.js";
|
|
4
|
-
import { insightSourcesAuthorized } from "../execution/authorization.js";
|
|
5
4
|
import { insightCorrelation } from "../inbox/lifecycle.js";
|
|
5
|
+
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
6
6
|
//#region src/proactive/actions/service.ts
|
|
7
7
|
function projectIdFromAggregationKey(value) {
|
|
8
8
|
if (!value.startsWith("project:") || value.length === 8) throw new Error("Proactive action has no project scope");
|
|
@@ -13,6 +13,7 @@ function executeClaimedAction(row, now = /* @__PURE__ */ new Date()) {
|
|
|
13
13
|
try {
|
|
14
14
|
if (getSqliteDatabase().prepare("SELECT 1 FROM proactive_inbox_items WHERE insight_id = ? AND withdrawn_at IS NOT NULL").get(row.insight_id)) throw new Error("Card was withdrawn");
|
|
15
15
|
if (!insightSourcesAuthorized(row.insight_id)) throw new Error("Source permission is no longer available");
|
|
16
|
+
if (insightSourcesChanged(row.insight_id)) throw new Error("Source changed; review updated work before acting");
|
|
16
17
|
if (!effectiveProactivePolicy(row.subscription_id).enabled) throw new Error("Proactive subscription paused");
|
|
17
18
|
const permission = getSqliteDatabase().prepare(`SELECT mode, allowed_actions_json FROM project_monitoring_policies WHERE project_id = ?`).get(projectIdFromAggregationKey(row.aggregation_key));
|
|
18
19
|
if (!getSqliteDatabase().prepare(`SELECT 1 FROM proactive_decisions d JOIN proactive_inbox_items i USING(inbox_item_id) WHERE i.insight_id = ? AND d.choice = 'approve'`).get(row.insight_id) && !(permission?.mode === "auto_low_risk" && JSON.parse(permission.allowed_actions_json).includes(action.id))) throw new Error("Action permission is no longer available");
|
|
@@ -48,6 +49,7 @@ function executeClaimedAction(row, now = /* @__PURE__ */ new Date()) {
|
|
|
48
49
|
getSqliteDatabase().prepare(`UPDATE proactive_insights
|
|
49
50
|
SET action_status = 'completed', action_result_json = ?, action_error = NULL, action_updated_at = ?
|
|
50
51
|
WHERE insight_id = ? AND action_status = 'executing'`).run(JSON.stringify({ taskId: result.model.task.id }), now.toISOString(), row.insight_id);
|
|
52
|
+
getSqliteDatabase().prepare("UPDATE proactive_inbox_items SET status = 'read', resolution = NULL, updated_at = ? WHERE insight_id = ?").run(now.toISOString(), row.insight_id);
|
|
51
53
|
} catch (error) {
|
|
52
54
|
getSqliteDatabase().prepare(`UPDATE proactive_insights
|
|
53
55
|
SET action_status = 'failed', action_error = ?, action_updated_at = ?
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
/** Recheck connector consent for stored cards and actions, not just model input. */
|
|
2
2
|
export declare function insightSourcesAuthorized(insightId: string): boolean;
|
|
3
|
+
/** Compare versions, not generated prose, before showing or executing prepared work. */
|
|
4
|
+
export declare function insightSourcesChanged(insightId: string): boolean;
|
|
3
5
|
export declare function authorizedConnectedSource(itemId: string, workspaceId: string, scenarioKey: string, agentId?: string | null): import("../../knowledge/types.js").KnowledgeSourceItem;
|
|
@@ -1,14 +1,52 @@
|
|
|
1
1
|
import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
|
|
2
2
|
import { getKnowledgeSourceItem } from "../../storage/sqlite/knowledge-repository.js";
|
|
3
3
|
import { getConnectorSyncPolicyForConnection } from "../../storage/sqlite/connector-sync-policy-repository.js";
|
|
4
|
+
import { readMailThread } from "../mail-thread.js";
|
|
4
5
|
//#region src/proactive/execution/authorization.ts
|
|
5
6
|
/** Recheck connector consent for stored cards and actions, not just model input. */
|
|
6
7
|
function insightSourcesAuthorized(insightId) {
|
|
8
|
+
const snapshot = getSqliteDatabase().prepare(`SELECT s.workspace_id, x.scenario_key, c.evidence_ids_json
|
|
9
|
+
FROM proactive_insights x JOIN proactive_scenario_subscriptions s USING(subscription_id)
|
|
10
|
+
JOIN proactive_runs r USING(run_id) LEFT JOIN proactive_context_snapshots c ON c.snapshot_id = r.context_snapshot_id
|
|
11
|
+
WHERE x.insight_id = ?`).get(insightId);
|
|
12
|
+
if (snapshot?.evidence_ids_json) {
|
|
13
|
+
if (JSON.parse(snapshot.evidence_ids_json).some((id) => id.startsWith("source-item:") && !authorizedConnectedSource(id.slice(12), snapshot.workspace_id, snapshot.scenario_key))) return false;
|
|
14
|
+
}
|
|
7
15
|
return getSqliteDatabase().prepare(`SELECT e.subject_id, e.workspace_id, x.scenario_key
|
|
8
16
|
FROM proactive_insights x JOIN proactive_runs r USING(run_id)
|
|
9
17
|
JOIN proactive_batch_events be ON be.batch_id = r.batch_id JOIN proactive_events e USING(event_id)
|
|
10
18
|
WHERE x.insight_id = ? AND e.type LIKE 'connected_source.%'`).all(insightId).every((row) => Boolean(authorizedConnectedSource(row.subject_id, row.workspace_id, row.scenario_key)));
|
|
11
19
|
}
|
|
20
|
+
/** Compare versions, not generated prose, before showing or executing prepared work. */
|
|
21
|
+
function insightSourcesChanged(insightId) {
|
|
22
|
+
const db = getSqliteDatabase();
|
|
23
|
+
const row = db.prepare(`SELECT c.content_json FROM proactive_insights x JOIN proactive_runs r USING(run_id)
|
|
24
|
+
JOIN proactive_context_snapshots c ON c.snapshot_id = r.context_snapshot_id WHERE x.insight_id = ?`).get(insightId);
|
|
25
|
+
if (!row) return false;
|
|
26
|
+
const snapshot = JSON.parse(row.content_json);
|
|
27
|
+
if (snapshot.follow_up?.followUpId) {
|
|
28
|
+
const follow = db.prepare("SELECT source_item_id, revision, status, due_at FROM proactive_follow_ups WHERE id = ?").get(snapshot.follow_up.followUpId);
|
|
29
|
+
if (!follow || follow.status !== "watching" || follow.revision !== snapshot.follow_up.revision || Date.parse(follow.due_at) <= Date.now() !== snapshot.follow_up.deadlinePassed || readMailThread(follow.source_item_id)?.fingerprint !== snapshot.follow_up.fingerprint) return true;
|
|
30
|
+
}
|
|
31
|
+
for (const source of [...snapshot.connected_source?.items ?? [], ...snapshot.follow_up?.items ?? []]) {
|
|
32
|
+
const current = getKnowledgeSourceItem(source.sourceItemId);
|
|
33
|
+
if (!current || current.deletedAt || current.contentHash !== source.contentHash || current.occurredAt !== source.occurredAt) return true;
|
|
34
|
+
}
|
|
35
|
+
const project = snapshot.project_state?.project;
|
|
36
|
+
if (project) {
|
|
37
|
+
const current = db.prepare("SELECT updated_at FROM projects WHERE project_id = ?").get(project.project_id);
|
|
38
|
+
if (!current || current.updated_at !== project.updated_at) return true;
|
|
39
|
+
}
|
|
40
|
+
for (const task of [...snapshot.project_state?.activeTasks ?? [], ...snapshot.meeting_workspace?.activeTasks ?? []]) {
|
|
41
|
+
const current = db.prepare("SELECT updated_at FROM tasks WHERE task_id = ?").get(task.task_id);
|
|
42
|
+
if (!current || current.updated_at !== task.updated_at) return true;
|
|
43
|
+
}
|
|
44
|
+
for (const note of snapshot.meeting_workspace?.recentNotes ?? []) {
|
|
45
|
+
const current = db.prepare("SELECT updated_at FROM notes WHERE note_id = ?").get(note.note_id);
|
|
46
|
+
if (!current || current.updated_at !== note.updated_at) return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
12
50
|
function authorizedConnectedSource(itemId, workspaceId, scenarioKey, agentId) {
|
|
13
51
|
const item = getKnowledgeSourceItem(itemId);
|
|
14
52
|
if (!item || item.deletedAt || item.metadata.workspaceId !== workspaceId || item.sensitivity === "secret" || item.sensitivity === "regulated") return null;
|
|
@@ -20,4 +58,4 @@ function authorizedConnectedSource(itemId, workspaceId, scenarioKey, agentId) {
|
|
|
20
58
|
return policy?.scanEnabled && policy.proactiveEnabled && (!policy.allowedScenarioKeys.length || policy.allowedScenarioKeys.includes(scenarioKey)) ? item : null;
|
|
21
59
|
}
|
|
22
60
|
//#endregion
|
|
23
|
-
export { authorizedConnectedSource, insightSourcesAuthorized };
|
|
61
|
+
export { authorizedConnectedSource, insightSourcesAuthorized, insightSourcesChanged };
|
|
@@ -33,6 +33,10 @@ export declare class DiscussionContextProvider implements ContextProvider {
|
|
|
33
33
|
readonly id = "discussion";
|
|
34
34
|
collect(input: ContextInput): Promise<ResolvedContext>;
|
|
35
35
|
}
|
|
36
|
+
export declare class MailFollowUpContextProvider implements ContextProvider {
|
|
37
|
+
readonly id = "follow_up";
|
|
38
|
+
collect(input: ContextInput): Promise<ResolvedContext>;
|
|
39
|
+
}
|
|
36
40
|
export declare class ContextProviderRegistry {
|
|
37
41
|
private readonly providers;
|
|
38
42
|
constructor(providers?: ContextProvider[]);
|