@xopcai/xopc 0.0.420 → 0.0.422
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/background.js +184 -2
- package/dist/browser-ext/dist/sidepanel.js +9 -0
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DnqOM8GN.js → activity-store-CvJ9rdwP.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-1UABT2KS.js → agent-avatar-dicebear-CFP6g4w7.js} +1 -1
- package/dist/gateway/static/root/assets/agent-avatar-display-BHBe88Gu.js +2 -0
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DlGRuKMv.js +1 -0
- package/dist/gateway/static/root/assets/agent-plugin-dialog-C_Dm-u6_.js +1 -0
- package/dist/gateway/static/root/assets/{agents-O7mago-m.js → agents-BdVJHOiK.js} +5 -5
- package/dist/gateway/static/root/assets/{agents-admin-api-CyjykMEh.js → agents-admin-api-Do1Pza0R.js} +1 -1
- package/dist/gateway/static/root/assets/{api-Ddrs70xV.js → api-BQv5dLcH.js} +1 -1
- package/dist/gateway/static/root/assets/{api-C1dxxDZx.js → api-ONg37_fH.js} +1 -1
- package/dist/gateway/static/root/assets/app-link-1j40sJ-z.js +1 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-B4Wqhf4J.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-Dm1kRzKL.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-D1MMk1P7.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-n5lPr79c.js → archive-plugin-p_yLkyaC.js} +1 -1
- package/dist/gateway/static/root/assets/automation-api-DQaWBR03.js +1 -0
- package/dist/gateway/static/root/assets/automation-result-state-CO_243JM.js +1 -0
- package/dist/gateway/static/root/assets/automation-task-card-D2p9qlYE.js +3 -0
- package/dist/gateway/static/root/assets/{automations-page-oLsNzu_6.js → automations-page-Ba64H37d.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BkzC3oIM.js +9 -0
- package/dist/gateway/static/root/assets/{binary-plugins-D9VW7dWP.js → binary-plugins-B-6kyqtt.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-C477bTtO.js → block-editor-B5ysJ96n.js} +4 -4
- package/dist/gateway/static/root/assets/{browser-automation-inputs-CCiYXxmh.js → browser-automation-inputs-C2A3NIt3.js} +1 -1
- package/dist/gateway/static/root/assets/browser-automations-page-CnbXFw1_.js +3 -0
- package/dist/gateway/static/root/assets/{browser-control-api-Y3fvmeBk.js → browser-control-api-Aj_seKE9.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-DjkGahlz.js → browser-settings-page-C7fxPq_z.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-DAyA681v.js → capabilities-BgtCwC_E.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-DRVXLssH.js → capabilities-DOTgaSgA.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-page-m3b9sLFG.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-pYWZtPeU.js +8 -0
- package/dist/gateway/static/root/assets/channels-DGpRM6pj.js +1 -0
- package/dist/gateway/static/root/assets/{chat-agents-api-D5nR_JVe.js → chat-agents-api-EvJ_Wvuc.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-chart-block-K2t333qv.js → chat-chart-block-BQDbHLcw.js} +1 -1
- package/dist/gateway/static/root/assets/chat-page-GF9NIuZN.js +72 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CkFG6mA3.js → chat-terminal-dock-DHFTGoEp.js} +2 -2
- package/dist/gateway/static/root/assets/{list-filter-COkzTdOz.js → clipboard-copy-DuJk5WD6.js} +1 -1
- package/dist/gateway/static/root/assets/{command-palette-api-Do_66X1B.js → command-palette-api-DPA_yEuy.js} +1 -1
- package/dist/gateway/static/root/assets/composer-payload-handoff-BTjauSNp.js +1 -0
- package/dist/gateway/static/root/assets/{computer-settings-page-DBxOcMko.js → computer-settings-page-BFSSQfcx.js} +1 -1
- package/dist/gateway/static/root/assets/connected-providers-grid-DM2glQN3.js +1 -0
- package/dist/gateway/static/root/assets/{connector-service-page-rWpnchb3.js → connector-service-page-CFvg58qa.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-api-DIBG72k4.js → connectors-api-CbC6Yht5.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-D7pipFHA.js +1 -0
- package/dist/gateway/static/root/assets/date-picker-Dd3MbG0x.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-7SpSfDSg.js → dependency-picker-DcsHg2ml.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-DldzQT2h.js +1 -0
- package/dist/gateway/static/root/assets/desktop-pet-settings-CYdI4KxB.js +1 -0
- package/dist/gateway/static/root/assets/{dev-view-store-57HgVuZ6.js → dev-view-store-JiJv585f.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-D8cLc41G.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-D4jMhpka.js → directory-picker-path-field-8WOXv8zw.js} +1 -1
- package/dist/gateway/static/root/assets/discussion-annotation-sync-B-grSe0w.js +1 -0
- package/dist/gateway/static/root/assets/{dist-DNCdG_qB.js → dist-D3lWNSe7.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BsK2LMXQ.js → extension-debug-page-EEQkTNEu.js} +1 -1
- package/dist/gateway/static/root/assets/extension-iframe-host-vlZVeMCY.js +1 -0
- package/dist/gateway/static/root/assets/{extension-marketplace-api-CVJPqJOB.js → extension-marketplace-api-_o2In_al.js} +1 -1
- package/dist/gateway/static/root/assets/extension-page-CPrT111s.js +1 -0
- package/dist/gateway/static/root/assets/{extension-provider-Byrd8Sor.js → extension-provider-B2Mf3FBu.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CznJEgWV.js +1 -0
- package/dist/gateway/static/root/assets/{file-preview-surface-BlprUrIs.js → file-preview-surface-7h8_fZul.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BAmUhiP1.js → gateway-config-swr-DbbNEOKj.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-CsykKL4l.js → gateway-realtime-D20ZrAuM.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-C6sMzYDT.js +1 -0
- package/dist/gateway/static/root/assets/gateway-restart-5ut-lhJm.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-settings-BA5-Uuwx.js → gateway-settings-BCf_cibp.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CtUB3g6N.js → gateway-startup-retry-DlHL0DpH.js} +1 -1
- package/dist/gateway/static/root/assets/{global-defaults-api-CINf-C6a.js → global-defaults-api-CmODomcV.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-uz22TRB-.js +2 -0
- package/dist/gateway/static/root/assets/image-generation-api-dzPnpUFu.js +1 -0
- package/dist/gateway/static/root/assets/{imports-page-BWShtGRQ.js → imports-page-ChBoNMyE.js} +1 -1
- package/dist/gateway/static/root/assets/index-CSIg7V1A.js +11 -0
- package/dist/gateway/static/root/assets/index-Dv8mUlNN.css +1 -0
- package/dist/gateway/static/root/assets/install-connector-dialog-CNcdQDX0.js +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CdM4BQwp.js → keyboard-shortcuts-settings-CRbYq2_g.js} +1 -1
- package/dist/gateway/static/root/assets/list-filter-CIPvpfLA.js +1 -0
- package/dist/gateway/static/root/assets/local-app-workbench-page-04cX5TJu.js +1 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CxyRVfjD.js → local-apps-page-fWM0FEhN.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-B9ZPwotC.js → local-session-drafts-ClrSe5mH.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-lIXD1FMw.js → locale-store-VNjH18Dj.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-6GanGLrm.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-BxD_lc4E.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-CJt-i2Dp.js → markdown-view-DLCBYWtx.js} +4 -4
- package/dist/gateway/static/root/assets/{media-plugins-D_bR23mA.js → media-plugins-BvtNwKFb.js} +1 -1
- package/dist/gateway/static/root/assets/messages-Btr7C0hF.js +3 -0
- package/dist/gateway/static/root/assets/model-selector-DYUnp917.js +1 -0
- package/dist/gateway/static/root/assets/{models-hub-cache-za2fWJLg.js → models-hub-cache-_qE7L-_H.js} +1 -1
- package/dist/gateway/static/root/assets/navigation-D62kPsA9.js +1 -0
- package/dist/gateway/static/root/assets/note-detail-panel-bjRZesmS.js +5 -0
- package/dist/gateway/static/root/assets/note-image-lightbox-D7Jqb75C.js +1 -0
- package/dist/gateway/static/root/assets/{notes-api-C_458rv5.js → notes-api-Bxa11X3a.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-D2QpJ3WZ.js +8 -0
- package/dist/gateway/static/root/assets/{oauth-api-C3X9FLYw.js → oauth-api-DIE4UpP7.js} +1 -1
- package/dist/gateway/static/root/assets/{oauth-provider-connect-H81se_3n.js → oauth-provider-connect-B95tiddN.js} +1 -1
- package/dist/gateway/static/root/assets/open-capability-settings-Cvb65hQB.js +1 -0
- package/dist/gateway/static/root/assets/{page-context-capture-button-BkAlQ7cB.js → page-context-capture-button-C-QbbwmN.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-draft-ClLgaOaD.js → page-context-draft-BHmOfksL.js} +1 -1
- package/dist/gateway/static/root/assets/page-header-store-bPV8_tKL.js +1 -0
- package/dist/gateway/static/root/assets/{personal-avatar-BLtHt8fV.js → personal-avatar-nXrmMfrV.js} +1 -1
- package/dist/gateway/static/root/assets/personal-page-BCwlYT3F.js +1 -0
- package/dist/gateway/static/root/assets/personal-settings-panel-vkYmXK8h.js +1 -0
- package/dist/gateway/static/root/assets/{phone-dependencies-card-DISHarj8.js → phone-dependencies-card-CZDAxTWv.js} +1 -1
- package/dist/gateway/static/root/assets/phone-model-picker-4Snfs8Hq.js +1 -0
- package/dist/gateway/static/root/assets/phone-settings-page-D8HperfA.js +1 -0
- package/dist/gateway/static/root/assets/{phone-workspace-store-fhnZrgy_.js → phone-workspace-store-Di9R9Ux5.js} +1 -1
- package/dist/gateway/static/root/assets/plugin-details-dialog-DJsDu-_8.js +1 -0
- package/dist/gateway/static/root/assets/popover-select-DD8fmrxH.js +1 -0
- package/dist/gateway/static/root/assets/preference-select-fields-C6abaM3k.js +1 -0
- package/dist/gateway/static/root/assets/product-automation-feedback-C74s9Mjz.js +7 -0
- package/dist/gateway/static/root/assets/product-delivery-DRyD9_Xq.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-xn9G4hSI.js → product-open-page-AbDP5w1c.js} +1 -1
- package/dist/gateway/static/root/assets/product-preview-content-CktjvFbc.js +1 -0
- package/dist/gateway/static/root/assets/product-preview-modal-CzsqLwB4.js +2 -0
- package/dist/gateway/static/root/assets/project-detail-page-Cf3tggGP.js +7 -0
- package/dist/gateway/static/root/assets/project-understanding-jmhFbHch.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-jMgZiFnO.js +1 -0
- package/dist/gateway/static/root/assets/{providers-api-CzVkFKFg.js → providers-api-CJBYFKAK.js} +1 -1
- package/dist/gateway/static/root/assets/{recording-upload-0jxahBMo.js → recording-upload-Dl9a5yOV.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-n8TwtJ_j.js → registry-api-BwkbPUYu.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-cZpBi4Rk.js → remote-access-hub-CBQ_bOy9.js} +1 -1
- package/dist/gateway/static/root/assets/resource-unavailable-35wBZxmz.js +1 -0
- package/dist/gateway/static/root/assets/route-preload-BcA6SPeC.js +2 -0
- package/dist/gateway/static/root/assets/runtime-impact-DbySfhdp.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-api-D-8KjYK6.js → runtime-tools-api-BF28JDAO.js} +1 -1
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-Bq2xQ2qd.js +1 -0
- package/dist/gateway/static/root/assets/schema-form-BKeP5G7b.js +1 -0
- package/dist/gateway/static/root/assets/service-recommendation-list-CdaS4MPF.js +1 -0
- package/dist/gateway/static/root/assets/{session-api-CsCoI2im.js → session-api-zJXYlRPt.js} +1 -1
- package/dist/gateway/static/root/assets/session-manager-wWxpzSo0.js +23 -0
- package/dist/gateway/static/root/assets/sessions-page-BkjD_dUD.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BUMCEtA_.js +1 -0
- package/dist/gateway/static/root/assets/{settings-advanced-section-BqoVSko2.js → settings-advanced-section-C84IghdL.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-mode-store-CBsJ-Qg2.js → settings-mode-store-CtQBJvbO.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DROUGyJl.js → settings-page-eEIz9InP.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-header-Bv-kQFTm.js → settings-page-header-CsPAYlqV.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-DHP6MrrL.js → settings-page-layout-lPLeJQoV.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BSU5WpaE.js +1 -0
- package/dist/gateway/static/root/assets/{share-link-dialog-BJHRQVKC.js → share-link-dialog-NaM6jvIz.js} +1 -1
- package/dist/gateway/static/root/assets/share-preview-page-CHjZn27s.js +2 -0
- package/dist/gateway/static/root/assets/{shares-api-rtWVHA_d.js → shares-api-B9rVcV1y.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-5sB15V5v.js +1 -0
- package/dist/gateway/static/root/assets/skill-api-D6zVfEuK.js +1 -0
- package/dist/gateway/static/root/assets/{skill-list-api-BzlKXPsE.js → skill-list-api-SLmTBYF5.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-Cff2GgZb.js → skill-reload-api-UQkq2orI.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-Ca0pYZ4i.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-BeQeUUMH.js → system-settings-panel-BARWbjRN.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-roqAsGue.js +2 -0
- package/dist/gateway/static/root/assets/task-result-evidence-Bb1F7nAM.js +1 -0
- package/dist/gateway/static/root/assets/{terminal-panel-store-5Fzctajw.js → terminal-panel-store-DYDeXXAg.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-DW45fWYQ.js → theme-store-DbStcH89.js} +1 -1
- package/dist/gateway/static/root/assets/tracing-settings-page-YfkNCxbP.js +1 -0
- package/dist/gateway/static/root/assets/tunnel-api-BK_ivyIb.js +1 -0
- package/dist/gateway/static/root/assets/{understanding-activity-store-CTe6TFB0.js → understanding-activity-store-p7Z7oq8z.js} +1 -1
- package/dist/gateway/static/root/assets/{understanding-refresh-store-mE9OKG6q.js → understanding-refresh-store-D-U6rcwZ.js} +1 -1
- package/dist/gateway/static/root/assets/usage-page-URFSiswS.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-Cs2Ga_Y_.js → use-autosave-B7cbumro.js} +1 -1
- package/dist/gateway/static/root/assets/use-composer-attachments-DAtiwLsE.js +2 -0
- package/dist/gateway/static/root/assets/use-file-preview-expanded-B8erpWsX.js +2 -0
- package/dist/gateway/static/root/assets/{use-personal-profile-BHL2AxWU.js → use-personal-profile-DDW29nm-.js} +1 -1
- package/dist/gateway/static/root/assets/{use-workspace-tree-CnmPZrpx.js → use-workspace-tree-DCoTf22f.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-DSV5NkNj.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-3gyc2UV3.js → voice-api-key-field-DzYdJZN4.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-Cda2uBIC.js → voice-config-api-wotvT6Hw.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-input-shortcut-events-DtYHsPLF.js → voice-input-shortcut-events-BI6PuiIB.js} +1 -1
- package/dist/gateway/static/root/assets/voice-transcribe-api-DAK9eLRr.js +1 -0
- package/dist/gateway/static/root/assets/{work-discovery-overlay-Dqu5CQCS.js → work-discovery-overlay-BzmB9Rub.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-CmGjxUIT.js +1 -0
- package/dist/gateway/static/root/assets/{working-directory-picker-modal-DHl2cZY1.js → working-directory-picker-modal-B-EHm52-.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-api-CtDbI6T7.js → workspace-api-uhiEMPpK.js} +2 -2
- package/dist/gateway/static/root/assets/workspace-editor-agent-store-DrPVyikA.js +1 -0
- package/dist/gateway/static/root/assets/{workspace-file-preview-dialog-CTIbUfKb.js → workspace-file-preview-dialog-BDm06MZm.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-open-location-menu-BwxouqdZ.js → workspace-open-location-menu-Bv83uoqu.js} +1 -1
- package/dist/gateway/static/root/assets/{xopc-cloud-account-card-CFb-23rS.js → xopc-cloud-account-card-Cd5GdpGL.js} +1 -1
- package/dist/gateway/static/root/index.html +91 -86
- package/dist/gateway/static/root/notification-sw.js +21 -7
- package/dist/package.js +1 -1
- package/dist/packages/endpoint-tools-protocol/src/context.js +115 -0
- package/dist/packages/endpoint-tools-protocol/src/index.js +4 -0
- package/dist/packages/endpoint-tools-protocol/src/location-sharing.js +51 -0
- package/dist/packages/gateway-contract/src/gateway-scopes.js +5 -1
- package/dist/packages/gateway-contract/src/index.js +4 -0
- package/dist/packages/gateway-contract/src/phone-workspace.js +6 -0
- package/dist/packages/gateway-contract/src/product-delivery.js +9 -3
- package/dist/packages/gateway-contract/src/task-display.js +14 -0
- package/dist/src/agent/agent-manager.js +1 -1
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/context/execution-scope.js +10 -5
- package/dist/src/agent/embedded/external-tool-discovery.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +2 -2
- package/dist/src/agent/embedded/run-turn.js +72 -9
- package/dist/src/agent/embedded/session-runner.js +2 -1
- package/dist/src/agent/embedded/types.d.ts +1 -1
- package/dist/src/agent/external-tools/cliProvider.js +2 -2
- package/dist/src/agent/external-tools/composio-provider.js +2 -2
- package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
- package/dist/src/agent/prompt/system-prompt.js +1 -0
- package/dist/src/agent/service/direct-turn-helpers.d.ts +0 -7
- package/dist/src/agent/service/direct-turn-helpers.js +3 -2
- package/dist/src/agent/service/process-direct-streaming.js +2 -1
- package/dist/src/agent/service.js +1 -1
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/source-context/device-environment.d.ts +3 -0
- package/dist/src/agent/source-context/device-environment.js +38 -0
- package/dist/src/agent/source-context/injector.js +2 -1
- package/dist/src/agent/tool-manuals/phone.d.ts +1 -1
- package/dist/src/agent/tool-manuals/phone.js +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +2 -1
- package/dist/src/agent/tools/automation-tool.js +13 -5
- package/dist/src/agent/tools/factory.js +2 -1
- package/dist/src/agent/tools/personal-read-tool.js +2 -2
- package/dist/src/agent/tools/personal-task-tool.js +2 -1
- package/dist/src/agent/tools/phone-use-tool.js +46 -2
- package/dist/src/agent/tools/xopc-use-tool.js +8 -5
- package/dist/src/agent-catalog/capabilities.js +2 -2
- package/dist/src/agent-catalog/repository.js +1 -1
- package/dist/src/automations/api/routes.js +38 -0
- package/dist/src/automations/capabilities/drafts.js +1 -1
- package/dist/src/automations/capabilities/write.js +25 -9
- package/dist/src/automations/configuration-conversation.d.ts +16 -0
- package/dist/src/automations/configuration-conversation.js +120 -0
- package/dist/src/automations/delivery/delivery-router.d.ts +2 -0
- package/dist/src/automations/delivery/delivery-router.js +30 -9
- package/dist/src/automations/domain/types.d.ts +1 -0
- package/dist/src/automations/index.js +5 -5
- package/dist/src/automations/service/action-executor.js +41 -12
- package/dist/src/automations/service/automation-service.d.ts +6 -0
- package/dist/src/automations/service/automation-service.js +47 -12
- package/dist/src/automations/service/index.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/capabilities/runtime/dispatcher.js +1 -1
- package/dist/src/capabilities/runtime/product.js +1 -1
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/computer/broker.js +16 -3
- package/dist/src/computer/diagnostics.js +1 -1
- package/dist/src/computer/errors.js +4 -0
- package/dist/src/computer/runtime.d.ts +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/schema.d.ts +1 -0
- package/dist/src/endpoint-tools/context-store.d.ts +29 -0
- package/dist/src/endpoint-tools/context-store.js +138 -0
- package/dist/src/endpoint-tools/location-sharing.d.ts +42 -0
- package/dist/src/endpoint-tools/location-sharing.js +203 -0
- package/dist/src/endpoint-tools/runtime.d.ts +4 -0
- package/dist/src/endpoint-tools/runtime.js +8 -0
- package/dist/src/endpoint-tools/turn-context.d.ts +2 -1
- package/dist/src/endpoint-tools/turn-context.js +4 -2
- package/dist/src/execution-environments/local-worktree-manager.js +1 -1
- package/dist/src/extensions/agent-plugins/skill-catalog.js +1 -1
- package/dist/src/extensions/agent-plugins/validation.js +1 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/automation-completion-delivery.d.ts +4 -0
- package/dist/src/gateway/automation-completion-delivery.js +14 -0
- package/dist/src/gateway/global-defaults-admin.js +1 -1
- package/dist/src/gateway/hono/middleware/auth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/devices.js +1 -0
- package/dist/src/gateway/hono/routes/endpoint-compatibility.js +4 -0
- package/dist/src/gateway/hono/routes/endpoint-environment.d.ts +3 -0
- package/dist/src/gateway/hono/routes/endpoint-environment.js +98 -0
- package/dist/src/gateway/hono/routes/endpoint-tools.js +1 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +16 -0
- package/dist/src/gateway/hono/routes/location-sharing.d.ts +3 -0
- package/dist/src/gateway/hono/routes/location-sharing.js +164 -0
- package/dist/src/gateway/hono/routes/notes.js +2 -2
- package/dist/src/gateway/hono/routes/phone-setup.js +1 -1
- package/dist/src/gateway/hono/routes/phone.js +246 -34
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/session-command-handler.js +1 -1
- package/dist/src/gateway/hono/routes/session-input-handler.js +3 -2
- package/dist/src/gateway/hono/routes/tasks.js +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +10 -0
- package/dist/src/gateway/image-generation-setup.js +1 -1
- package/dist/src/gateway/respawn.js +2 -1
- package/dist/src/gateway/security/gateway-scopes.js +6 -0
- package/dist/src/gateway/security/phone-access.d.ts +4 -0
- package/dist/src/gateway/security/phone-access.js +20 -0
- package/dist/src/gateway/service/agent-runner.js +3 -1
- package/dist/src/gateway/service/config-coordinator.d.ts +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +2 -1
- package/dist/src/gateway/service/session-input-coordinator.d.ts +3 -0
- package/dist/src/gateway/service/session-input-coordinator.js +50 -2
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +12 -4
- package/dist/src/gateway/session-reset-service.js +4 -0
- package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
- package/dist/src/imports/importService.js +1 -1
- package/dist/src/local-apps/service.js +1 -1
- package/dist/src/notifications/planner.js +6 -6
- package/dist/src/observability/store.d.ts +9 -0
- package/dist/src/observability/store.js +77 -32
- package/dist/src/personal-agent/communication.d.ts +1 -1
- package/dist/src/personal-agent/communication.js +3 -6
- package/dist/src/personal-agent/request-service.js +2 -1
- package/dist/src/personal-agent/service.js +1 -1
- package/dist/src/phone/assistance-service.d.ts +6 -0
- package/dist/src/phone/assistance-service.js +32 -0
- package/dist/src/phone/assistance.d.ts +40 -0
- package/dist/src/phone/assistance.js +273 -0
- package/dist/src/phone/cloud-phones.d.ts +5 -0
- package/dist/src/phone/cloud-phones.js +14 -0
- package/dist/src/phone/contracts.d.ts +7 -1
- package/dist/src/phone/contracts.js +5 -0
- package/dist/src/phone/environment-adapter.d.ts +3 -0
- package/dist/src/phone/environment-adapter.js +11 -0
- package/dist/src/phone/location-baseline-store.d.ts +9 -0
- package/dist/src/phone/location-baseline-store.js +61 -0
- package/dist/src/phone/location-environment.d.ts +61 -0
- package/dist/src/phone/location-environment.js +157 -0
- package/dist/src/phone/model-adapter.js +16 -5
- package/dist/src/phone/runtime.d.ts +17 -2
- package/dist/src/phone/runtime.js +203 -20
- package/dist/src/phone/stream-gateway.d.ts +5 -0
- package/dist/src/phone/stream-gateway.js +85 -51
- package/dist/src/phone/wuying-location.d.ts +18 -0
- package/dist/src/phone/wuying-location.js +86 -0
- package/dist/src/runtime-tools/archive.js +1 -1
- package/dist/src/storage/sqlite/device-access-repository.d.ts +4 -0
- package/dist/src/storage/sqlite/device-access-repository.js +18 -1
- package/dist/src/tasks/capabilities/read.js +2 -2
- package/dist/src/tasks/capabilities/write.js +1 -1
- package/dist/src/tasks/task-contract-planner.js +2 -1
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tunnel/broker-client.d.ts +8 -0
- package/dist/src/tunnel/broker-client.js +18 -1
- package/dist/src/voice/realtime/persona-context.js +1 -1
- package/dist/src/voice/realtime/runtime.js +1 -1
- package/package.json +4 -3
- package/dist/gateway/static/root/assets/agent-avatar-display-Cy50vjbq.js +0 -2
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-V4NX_cWz.js +0 -1
- package/dist/gateway/static/root/assets/agent-plugin-dialog-CQ5LLDMO.js +0 -1
- package/dist/gateway/static/root/assets/app-link-CytZ5zkp.js +0 -1
- package/dist/gateway/static/root/assets/app-management-settings-panel-C1Zs-eha.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-lIfGokbz.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-CUvtsRYD.js +0 -1
- package/dist/gateway/static/root/assets/automation-api-Bld8blNl.js +0 -1
- package/dist/gateway/static/root/assets/automation-display-BcfZOQTC.js +0 -2
- package/dist/gateway/static/root/assets/automations-workspace-BgtYY2Mm.js +0 -8
- package/dist/gateway/static/root/assets/browser-automations-page-DIUNY94X.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-page-DFW4Y0x8.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-uOHSMQPZ.js +0 -8
- package/dist/gateway/static/root/assets/channels-D2a69dSt.js +0 -1
- package/dist/gateway/static/root/assets/chat-page-CG38tCHE.js +0 -71
- package/dist/gateway/static/root/assets/composer-payload-handoff-BU3B-C26.js +0 -1
- package/dist/gateway/static/root/assets/connected-providers-grid-Dmnu2zle.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DT_WrC1y.js +0 -1
- package/dist/gateway/static/root/assets/date-picker-CE-cZFCU.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-lorocS9j.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-CEcohlZq.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-CLCPuf4R.js +0 -1
- package/dist/gateway/static/root/assets/discussion-annotation-sync-BKjf9gWe.js +0 -1
- package/dist/gateway/static/root/assets/extension-iframe-host-Dhkk5JV2.js +0 -1
- package/dist/gateway/static/root/assets/extension-page-Brps2XDP.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CHY68DpG.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-DQqMBruB.js +0 -1
- package/dist/gateway/static/root/assets/gateway-restart-Ch128Lrr.js +0 -1
- package/dist/gateway/static/root/assets/home-page-DaMFBYo1.js +0 -2
- package/dist/gateway/static/root/assets/image-generation-api-I_JgLL_m.js +0 -1
- package/dist/gateway/static/root/assets/index-DY2Y83b9.css +0 -1
- package/dist/gateway/static/root/assets/index-UCOlAnf-.js +0 -11
- package/dist/gateway/static/root/assets/install-connector-dialog-DU1Tz7B3.js +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-qPflPuQD.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-CbY1N-zi.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-Diy12JfQ.js +0 -1
- package/dist/gateway/static/root/assets/messages-DRR9N3HC.js +0 -3
- package/dist/gateway/static/root/assets/model-selector-DCYA_ntf.js +0 -1
- package/dist/gateway/static/root/assets/navigation-BkjnOw30.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-DBs1yHLy.js +0 -5
- package/dist/gateway/static/root/assets/note-image-lightbox-CivkB6LB.js +0 -1
- package/dist/gateway/static/root/assets/notes-page-DL3c-41a.js +0 -8
- package/dist/gateway/static/root/assets/page-header-store-DH8K0xii.js +0 -1
- package/dist/gateway/static/root/assets/personal-page-B5DP3lO-.js +0 -1
- package/dist/gateway/static/root/assets/personal-settings-panel-DjDc5Kaz.js +0 -1
- package/dist/gateway/static/root/assets/phone-model-picker-u8YIQCgo.js +0 -1
- package/dist/gateway/static/root/assets/phone-settings-page-el3pT0PD.js +0 -1
- package/dist/gateway/static/root/assets/plugin-details-dialog-CTBs1Jde.js +0 -1
- package/dist/gateway/static/root/assets/popover-select-DniHw2dy.js +0 -1
- package/dist/gateway/static/root/assets/preference-select-fields-D7oluyHN.js +0 -1
- package/dist/gateway/static/root/assets/product-automation-feedback-DsUSqCOX.js +0 -7
- package/dist/gateway/static/root/assets/product-delivery-BU_H84jL.js +0 -1
- package/dist/gateway/static/root/assets/product-preview-content-DcoK-iZe.js +0 -1
- package/dist/gateway/static/root/assets/product-preview-modal-Ruw9WSKK.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-BKvWLiMw.js +0 -7
- package/dist/gateway/static/root/assets/project-understanding-BCQr0AZ_.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-D4g7bB7X.js +0 -1
- package/dist/gateway/static/root/assets/route-preload-B5UiReO7.js +0 -2
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-MKlLFuow.js +0 -1
- package/dist/gateway/static/root/assets/schema-form-v4N4lawq.js +0 -1
- package/dist/gateway/static/root/assets/service-recommendation-list-B1xuVT3N.js +0 -1
- package/dist/gateway/static/root/assets/session-manager-5l9q0cd5.js +0 -16
- package/dist/gateway/static/root/assets/sessions-page-DsLw2aMD.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-B5lQeVNi.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-MJE3B_LX.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-Bsrv_zOQ.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-CfIRv4uX.js +0 -1
- package/dist/gateway/static/root/assets/skill-api-B_W1K3sv.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-DtBloYeU.js +0 -2
- package/dist/gateway/static/root/assets/task-detail-page-Drrv-Hp0.js +0 -2
- package/dist/gateway/static/root/assets/task-result-evidence-D1Kyskm_.js +0 -1
- package/dist/gateway/static/root/assets/tracing-settings-page-B12u5D9A.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-DGO56LQU.js +0 -1
- package/dist/gateway/static/root/assets/usage-page-Ud2U9UG1.js +0 -1
- package/dist/gateway/static/root/assets/use-composer-attachments-BCbMj-MN.js +0 -2
- package/dist/gateway/static/root/assets/use-file-preview-expanded-DSpCRXUW.js +0 -2
- package/dist/gateway/static/root/assets/user-model-page-p5iPfnwl.js +0 -2
- package/dist/gateway/static/root/assets/voice-transcribe-api-TInEfIYo.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-p-8ciZ0i.js +0 -1
- package/dist/gateway/static/root/assets/workspace-editor-agent-store-B94Q2nN8.js +0 -1
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
+
import { setDevicePhoneAccess } from "../../../storage/sqlite/device-access-repository.js";
|
|
3
4
|
import { MOCK_PHONE_MODEL, PhoneActionSchema, PhoneConfigSchema, PhoneDeviceSchema, PhoneError, PhoneExecutionModeSchema, PhoneInputSchema, init_contracts } from "../../../phone/contracts.js";
|
|
4
5
|
import { createConversation, init_conversation_repository } from "../../../storage/sqlite/conversation-repository.js";
|
|
5
6
|
import { getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
|
|
6
7
|
import { getModelRegistry, init_model_registry } from "../../../providers/model-registry.js";
|
|
7
8
|
import { init_providers, isProviderConfiguredSync } from "../../../providers/index.js";
|
|
8
9
|
import { normalizePhoneAppAccess, phoneAppAccess } from "../../../phone/app-access.js";
|
|
10
|
+
import { cancelPhoneAssistance, pendingPhoneAssistance, phoneAssistance, phoneAssistanceReport } from "../../../phone/assistance.js";
|
|
9
11
|
import { resolveAdbPath } from "../../../phone/adb-driver.js";
|
|
10
12
|
import { createPhoneModel, phoneModelProfile } from "../../../phone/model-adapter.js";
|
|
11
13
|
import { getPhoneRuntime, phoneExecutionContext } from "../../../phone/runtime.js";
|
|
12
14
|
import { registerPhoneSetupRoutes } from "./phone-setup.js";
|
|
13
15
|
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
16
|
+
import { authorizePhoneAccess, phoneAdministrator } from "../../security/phone-access.js";
|
|
14
17
|
import { registerPhoneWirelessRoutes } from "./phone-wireless.js";
|
|
15
18
|
import { randomUUID } from "node:crypto";
|
|
16
19
|
import { z } from "zod";
|
|
@@ -51,20 +54,118 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
51
54
|
const { service, strictRateLimitMiddleware } = deps;
|
|
52
55
|
app.use("/api/phone/*", async (c, next) => {
|
|
53
56
|
const principal = getGatewayPrincipal(c);
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
if (!phoneAdministrator(principal)) {
|
|
58
|
+
const path = c.req.path;
|
|
59
|
+
const conversation = /^\/api\/phone\/conversations\/([0-9a-f-]{36})(?:\/(summary|[0-9a-f-]{36}\/(?:frame|video-ticket|control)))?$/i.test(path);
|
|
60
|
+
const summary = path.endsWith("/summary") && c.req.method === "GET";
|
|
61
|
+
if (!(conversation && (c.req.method === "GET" || c.req.method === "POST" && /\/(video-ticket|control)$/.test(path))) || principal.kind !== "device" || !principal.scopes.includes("sessions.read")) throw new PhoneError("PHONE_ADMIN_REQUIRED", "Phone management requires administrator access", 403);
|
|
62
|
+
if (!summary) authorizePhoneAccess(principal, path.endsWith("/control"));
|
|
63
|
+
}
|
|
64
|
+
await next();
|
|
65
|
+
if (principal.kind === "device" && c.res.status === 200 && c.res.headers.get("Content-Type")?.includes("application/json")) {
|
|
66
|
+
const body = await c.res.clone().json();
|
|
67
|
+
const report = body.payload?.report;
|
|
68
|
+
if (report && body.payload) {
|
|
69
|
+
const { sessionId, deviceId, deviceName, status, mode, controlOwner, controlEpoch, handoff, assistanceId, reconnectRequired, stopReason, currentAction, updatedAt } = report;
|
|
70
|
+
body.payload = {
|
|
71
|
+
ownControl: body.payload.ownControl,
|
|
72
|
+
textInput: body.payload.textInput,
|
|
73
|
+
report: {
|
|
74
|
+
sessionId,
|
|
75
|
+
deviceId,
|
|
76
|
+
deviceName,
|
|
77
|
+
status,
|
|
78
|
+
mode,
|
|
79
|
+
controlOwner,
|
|
80
|
+
controlEpoch,
|
|
81
|
+
handoff,
|
|
82
|
+
assistanceId,
|
|
83
|
+
reconnectRequired,
|
|
84
|
+
stopReason,
|
|
85
|
+
currentAction,
|
|
86
|
+
updatedAt
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
c.res = c.json(body);
|
|
90
|
+
c.header("Cache-Control", "no-store");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
app.patch("/api/phone/device-access/:id", strictRateLimitMiddleware, async (c) => {
|
|
95
|
+
const actor = getGatewayPrincipal(c);
|
|
96
|
+
if (actor.kind === "device" || !actor.scopes.includes("gateway.admin")) return c.json({ ok: false }, 403);
|
|
97
|
+
const input = z.object({ access: z.enum([
|
|
98
|
+
"none",
|
|
99
|
+
"view",
|
|
100
|
+
"control"
|
|
101
|
+
]) }).strict().safeParse(await c.req.json().catch(() => null));
|
|
102
|
+
if (!input.success) return c.json({ ok: false }, 400);
|
|
103
|
+
const device = setDevicePhoneAccess(c.req.param("id"), input.data.access);
|
|
104
|
+
if (!device) return c.json({ ok: false }, 404);
|
|
105
|
+
deps.service.phoneStreams.disconnectPrincipal(device.id);
|
|
106
|
+
c.header("Cache-Control", "no-store");
|
|
107
|
+
return c.json({
|
|
108
|
+
ok: true,
|
|
109
|
+
payload: {
|
|
110
|
+
id: device.id,
|
|
111
|
+
scopes: device.scopes
|
|
59
112
|
}
|
|
60
|
-
}
|
|
61
|
-
return next();
|
|
113
|
+
});
|
|
62
114
|
});
|
|
63
115
|
registerPhoneSetupRoutes(app, deps);
|
|
64
116
|
registerPhoneWirelessRoutes(app, deps, runtime);
|
|
117
|
+
app.get("/api/phone/devices/:id/environment", (c) => {
|
|
118
|
+
const id = z.uuid().parse(c.req.param("id"));
|
|
119
|
+
const device = runtime.repository.get(id);
|
|
120
|
+
c.header("Cache-Control", "no-store");
|
|
121
|
+
return c.json({
|
|
122
|
+
ok: true,
|
|
123
|
+
payload: {
|
|
124
|
+
...runtime.environment.status(id),
|
|
125
|
+
supported: device.connection?.kind === "aliyun-adb"
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
app.post("/api/phone/devices/:id/environment/cleanup", strictRateLimitMiddleware, async (c) => {
|
|
130
|
+
const id = z.uuid().parse(c.req.param("id"));
|
|
131
|
+
runtime.repository.get(id);
|
|
132
|
+
const state = runtime.environment.status(id);
|
|
133
|
+
const cleared = state.shareId ? await runtime.environment.clear(state.shareId, id) : true;
|
|
134
|
+
return c.json({
|
|
135
|
+
ok: true,
|
|
136
|
+
payload: {
|
|
137
|
+
cleared,
|
|
138
|
+
...runtime.environment.status(id)
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
const connectionReports = () => {
|
|
143
|
+
const reports = runtime.reports().filter((report) => report.status !== "closed");
|
|
144
|
+
for (const wait of pendingPhoneAssistance()) if (!reports.some((report) => report.deviceId === wait.checkpoint.report.deviceId)) reports.push(phoneAssistanceReport(wait));
|
|
145
|
+
return reports.map((report) => {
|
|
146
|
+
const wait = phoneAssistance(report.owner);
|
|
147
|
+
return wait && ["open", "queued"].includes(wait.status) ? {
|
|
148
|
+
...report,
|
|
149
|
+
assistanceId: wait.id,
|
|
150
|
+
...wait.status === "open" && report.controlOwner !== "human" ? { status: "needs_user" } : {}
|
|
151
|
+
} : report;
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
const liveStatus = (owner, id, context, client) => {
|
|
155
|
+
const state = runtime.liveStatus(owner, id, context, client);
|
|
156
|
+
const wait = phoneAssistance(owner);
|
|
157
|
+
return wait && ["open", "queued"].includes(wait.status) ? {
|
|
158
|
+
...state,
|
|
159
|
+
report: {
|
|
160
|
+
...state.report,
|
|
161
|
+
assistanceId: wait.id,
|
|
162
|
+
...wait.status === "open" && state.report.controlOwner !== "human" ? { status: "needs_user" } : {}
|
|
163
|
+
}
|
|
164
|
+
} : state;
|
|
165
|
+
};
|
|
65
166
|
app.get("/api/phone/connections", async (c) => {
|
|
66
167
|
c.header("Cache-Control", "no-store");
|
|
67
|
-
const payload = await Promise.all(
|
|
168
|
+
const payload = await Promise.all(connectionReports().map(async (report) => {
|
|
68
169
|
const source = report.sourceConversationId ?? report.owner;
|
|
69
170
|
const conversation = /^[\da-f]{8}-[\da-f-]{27}$/i.test(source) ? await service.sessions.getSession(source) : void 0;
|
|
70
171
|
const { facts: _facts, readings: _readings, steps: _steps, task: _task, feedback: _feedback, ...metadata } = report;
|
|
@@ -235,6 +336,7 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
235
336
|
...patch.allowedApps && patch.appAccess === void 0 ? { appAccess: "selected" } : {}
|
|
236
337
|
});
|
|
237
338
|
await runtime.stopDevice(id);
|
|
339
|
+
if (previous.connection) await runtime.environment.recover(id, true);
|
|
238
340
|
return c.json({
|
|
239
341
|
ok: true,
|
|
240
342
|
payload: runtime.repository.save(next, id)
|
|
@@ -244,6 +346,7 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
244
346
|
const id = c.req.param("id");
|
|
245
347
|
const device = runtime.repository.get(id);
|
|
246
348
|
await runtime.stopDevice(id);
|
|
349
|
+
if (device.connection) await runtime.environment.recover(id, true);
|
|
247
350
|
await runtime.cloud.remove(device);
|
|
248
351
|
runtime.repository.remove(id);
|
|
249
352
|
return c.json({ ok: true });
|
|
@@ -332,6 +435,7 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
332
435
|
clientId: liveClient,
|
|
333
436
|
operationId: z.string().uuid(),
|
|
334
437
|
epoch: z.number().int().positive(),
|
|
438
|
+
assistanceId: z.string().uuid().optional(),
|
|
335
439
|
op: z.enum([
|
|
336
440
|
"takeover",
|
|
337
441
|
"release",
|
|
@@ -342,6 +446,7 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
342
446
|
"input",
|
|
343
447
|
"recover"
|
|
344
448
|
]),
|
|
449
|
+
expectedTranscriptId: z.uuid().optional(),
|
|
345
450
|
frameSeq: z.number().int().positive().optional(),
|
|
346
451
|
geometry: z.number().int().positive().optional(),
|
|
347
452
|
action: PhoneActionSchema.optional()
|
|
@@ -349,20 +454,22 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
349
454
|
async function conversationPhone(conversationId, requestedSessionId) {
|
|
350
455
|
if (conversationId.startsWith("device:")) {
|
|
351
456
|
const deviceId = z.string().uuid().parse(conversationId.slice(7));
|
|
352
|
-
const report =
|
|
457
|
+
const report = connectionReports().find((report) => report.deviceId === deviceId);
|
|
353
458
|
if (!report || requestedSessionId && report.sessionId !== requestedSessionId) throw new PhoneError("PHONE_SESSION_NOT_FOUND", "Phone connection changed. Refresh the phone panel.", 404);
|
|
354
459
|
const conversation = /^[\da-f]{8}-[\da-f-]{27}$/i.test(report.owner) ? await service.sessions.getSession(report.owner) : void 0;
|
|
355
460
|
return {
|
|
356
461
|
owner: report.owner,
|
|
357
462
|
report,
|
|
358
463
|
transcriptId: conversation?.transcriptId,
|
|
359
|
-
context: runtime.deviceContext(deviceId, service.currentConfig)
|
|
464
|
+
context: runtime.status(report.owner) && runtime.status(report.owner)?.status !== "closed" ? runtime.deviceContext(deviceId, service.currentConfig) : phoneExecutionContext(service.currentConfig, report.agentId)
|
|
360
465
|
};
|
|
361
466
|
}
|
|
362
467
|
z.string().uuid().parse(conversationId);
|
|
363
468
|
const conversation = await service.sessions.getSession(conversationId);
|
|
364
469
|
if (!conversation) throw new PhoneError("PHONE_CONVERSATION_NOT_FOUND", "Conversation not found", 404);
|
|
365
|
-
const
|
|
470
|
+
const connected = runtime.status(conversationId);
|
|
471
|
+
const wait = phoneAssistance(conversationId);
|
|
472
|
+
const report = connected && connected.status !== "closed" ? connected : wait && ["open", "queued"].includes(wait.status) ? phoneAssistanceReport(wait) : void 0;
|
|
366
473
|
if (requestedSessionId && report?.sessionId !== requestedSessionId) throw new PhoneError("PHONE_SESSION_NOT_FOUND", "Phone session not found", 404);
|
|
367
474
|
if (report && report.agentId !== conversation.agentId) throw new PhoneError("PHONE_ACCESS_CHANGED", "Conversation Agent changed", 403);
|
|
368
475
|
return {
|
|
@@ -372,6 +479,41 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
372
479
|
context: phoneExecutionContext(service.currentConfig, conversation.agentId)
|
|
373
480
|
};
|
|
374
481
|
}
|
|
482
|
+
app.get("/api/phone/conversations/:conversationId/summary", async (c) => {
|
|
483
|
+
const principal = getGatewayPrincipal(c);
|
|
484
|
+
const id = c.req.param("conversationId");
|
|
485
|
+
const { report, transcriptId } = await conversationPhone(id);
|
|
486
|
+
let access = "none";
|
|
487
|
+
try {
|
|
488
|
+
authorizePhoneAccess(principal);
|
|
489
|
+
access = "view";
|
|
490
|
+
} catch {}
|
|
491
|
+
if (access === "view") try {
|
|
492
|
+
authorizePhoneAccess(principal, true);
|
|
493
|
+
access = "control";
|
|
494
|
+
} catch {}
|
|
495
|
+
const payload = {
|
|
496
|
+
available: Boolean(report),
|
|
497
|
+
access,
|
|
498
|
+
needsUser: Boolean(report && access !== "none" && report.status === "needs_user")
|
|
499
|
+
};
|
|
500
|
+
if (report && access !== "none") {
|
|
501
|
+
payload.deviceName = report.deviceName;
|
|
502
|
+
payload.taskState = report.status;
|
|
503
|
+
payload.updatedAt = report.updatedAt;
|
|
504
|
+
if (transcriptId && report.deviceId) payload.binding = {
|
|
505
|
+
conversationId: id,
|
|
506
|
+
transcriptId,
|
|
507
|
+
phoneSessionId: report.sessionId,
|
|
508
|
+
phoneDeviceId: report.deviceId
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
c.header("Cache-Control", "no-store");
|
|
512
|
+
return c.json({
|
|
513
|
+
ok: true,
|
|
514
|
+
payload
|
|
515
|
+
});
|
|
516
|
+
});
|
|
375
517
|
app.get("/api/phone/conversations/:conversationId", async (c) => {
|
|
376
518
|
let owner = c.req.param("conversationId");
|
|
377
519
|
const client = liveClient.parse(c.req.query("clientId"));
|
|
@@ -380,7 +522,11 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
380
522
|
c.header("Cache-Control", "no-store");
|
|
381
523
|
return c.json({
|
|
382
524
|
ok: true,
|
|
383
|
-
payload: report ? runtime.liveStatus(owner, report.sessionId, context, `${getGatewayPrincipal(c).principalId}:${client}${c.req.param("conversationId").startsWith("device:") ? ":viewer" : ""}`) :
|
|
525
|
+
payload: report ? runtime.status(owner)?.status !== "closed" && runtime.status(owner) ? liveStatus(owner, report.sessionId, context, `${getGatewayPrincipal(c).principalId}:${client}${c.req.param("conversationId").startsWith("device:") ? ":viewer" : ""}`) : {
|
|
526
|
+
report,
|
|
527
|
+
ownControl: false,
|
|
528
|
+
frame: null
|
|
529
|
+
} : null
|
|
384
530
|
});
|
|
385
531
|
});
|
|
386
532
|
app.post("/api/phone/conversations/:conversationId/:sessionId/execution-mode", strictRateLimitMiddleware, async (c) => {
|
|
@@ -397,15 +543,23 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
397
543
|
c.header("Cache-Control", "no-store");
|
|
398
544
|
return c.json({
|
|
399
545
|
ok: true,
|
|
400
|
-
payload:
|
|
546
|
+
payload: liveStatus(owner, c.req.param("sessionId"), context, `${getGatewayPrincipal(c).principalId}:${input.clientId}`)
|
|
401
547
|
});
|
|
402
548
|
});
|
|
403
549
|
app.get("/api/phone/conversations/:conversationId/:sessionId/frame", async (c) => {
|
|
404
550
|
let owner = c.req.param("conversationId");
|
|
405
551
|
const id = c.req.param("sessionId");
|
|
406
|
-
const { context, owner: resolvedOwner } = await conversationPhone(owner, id);
|
|
552
|
+
const { context, transcriptId, owner: resolvedOwner } = await conversationPhone(owner, id);
|
|
407
553
|
owner = resolvedOwner;
|
|
554
|
+
const principal = getGatewayPrincipal(c);
|
|
555
|
+
if (principal.kind === "device" && c.req.query("expectedTranscriptId") !== transcriptId) throw new PhoneError("PHONE_BINDING_CHANGED", "Conversation changed", 409);
|
|
408
556
|
const frame = await runtime.liveFrame(owner, id, context, c.req.raw.signal);
|
|
557
|
+
try {
|
|
558
|
+
authorizePhoneAccess(principal);
|
|
559
|
+
} catch (error) {
|
|
560
|
+
frame.frame.fill(0);
|
|
561
|
+
throw error;
|
|
562
|
+
}
|
|
409
563
|
c.header("Cache-Control", "no-store");
|
|
410
564
|
c.header("Content-Type", "image/png");
|
|
411
565
|
c.header("X-Content-Type-Options", "nosniff");
|
|
@@ -421,15 +575,32 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
421
575
|
app.post("/api/phone/conversations/:conversationId/:sessionId/video-ticket", strictRateLimitMiddleware, async (c) => {
|
|
422
576
|
const address = c.req.param("conversationId");
|
|
423
577
|
const id = c.req.param("sessionId");
|
|
424
|
-
const { clientId } = z.object({
|
|
425
|
-
|
|
578
|
+
const { clientId, purpose, expectedTranscriptId, epoch } = z.object({
|
|
579
|
+
clientId: liveClient,
|
|
580
|
+
purpose: z.enum(["view", "control"]).optional(),
|
|
581
|
+
expectedTranscriptId: z.uuid().optional(),
|
|
582
|
+
epoch: z.number().int().positive().optional()
|
|
583
|
+
}).strict().parse(await c.req.json());
|
|
584
|
+
const initial = await conversationPhone(address, id);
|
|
426
585
|
const principal = getGatewayPrincipal(c);
|
|
427
|
-
const client = `${principal.principalId}:${clientId}${
|
|
586
|
+
const client = `${principal.principalId}:${clientId}${address.startsWith("device:") || principal.kind === "device" && purpose !== "control" ? ":viewer" : ""}`;
|
|
587
|
+
const native = principal.kind === "device";
|
|
588
|
+
const interactive = native ? purpose === "control" : purpose !== "view" && !address.startsWith("device:");
|
|
589
|
+
if (native && (!expectedTranscriptId || expectedTranscriptId !== initial.transcriptId)) throw new PhoneError("PHONE_BINDING_CHANGED", "Conversation changed; refresh the phone", 409);
|
|
428
590
|
const validate = async () => {
|
|
591
|
+
authorizePhoneAccess(principal, interactive);
|
|
429
592
|
const resolved = await conversationPhone(address, id);
|
|
430
|
-
|
|
593
|
+
if (resolved.transcriptId !== initial.transcriptId) throw new PhoneError("PHONE_BINDING_CHANGED", "Conversation changed", 409);
|
|
594
|
+
const state = runtime.liveStatus(resolved.owner, id, resolved.context, client);
|
|
595
|
+
if (native && interactive && (!state.ownControl || epoch !== state.report.controlEpoch)) throw new PhoneError("PHONE_CONTROL_CHANGED", "Take over before opening an interactive stream", 409);
|
|
431
596
|
};
|
|
597
|
+
if (native) await validate();
|
|
432
598
|
const issued = service.phoneStreams.issue({
|
|
599
|
+
...native ? {
|
|
600
|
+
deviceId: principal.deviceId,
|
|
601
|
+
readOnly: !interactive,
|
|
602
|
+
inputEpoch: interactive ? epoch : void 0
|
|
603
|
+
} : { readOnly: !interactive },
|
|
433
604
|
origin: new URL(c.req.url).origin,
|
|
434
605
|
principal: principal.principalId,
|
|
435
606
|
client,
|
|
@@ -439,8 +610,7 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
439
610
|
return runtime.liveVideo(resolved.owner, id, resolved.context);
|
|
440
611
|
},
|
|
441
612
|
disconnect: async () => {
|
|
442
|
-
|
|
443
|
-
if (resolved) await runtime.disconnectVideo(resolved.owner, id, client);
|
|
613
|
+
await runtime.disconnectVideo(initial.owner, id, client, native ? epoch : void 0);
|
|
444
614
|
}
|
|
445
615
|
});
|
|
446
616
|
c.header("Cache-Control", "no-store");
|
|
@@ -457,22 +627,64 @@ function registerPhoneRoutes(parent, deps, runtime = getPhoneRuntime()) {
|
|
|
457
627
|
if (c.req.param("conversationId").startsWith("device:")) throw new PhoneError("PHONE_OBSERVE_ONLY", "The global phone viewer is read only. Use the controlling conversation for input.", 403);
|
|
458
628
|
let owner = c.req.param("conversationId");
|
|
459
629
|
const id = c.req.param("sessionId");
|
|
460
|
-
const
|
|
630
|
+
const actor = getGatewayPrincipal(c);
|
|
631
|
+
const { clientId, assistanceId, expectedTranscriptId, ...input } = liveControlInput.parse(await c.req.json());
|
|
632
|
+
const requestedWait = phoneAssistance(owner);
|
|
633
|
+
const allowRecovery = assistanceId && requestedWait?.id === assistanceId && requestedWait.checkpoint.report.sessionId === id && ["takeover", "handback"].includes(input.op);
|
|
634
|
+
const { context, transcriptId, owner: resolvedOwner } = await conversationPhone(owner, allowRecovery ? void 0 : id);
|
|
461
635
|
owner = resolvedOwner;
|
|
462
|
-
|
|
463
|
-
const
|
|
464
|
-
if (
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
636
|
+
if (getGatewayPrincipal(c).kind === "device" && (!expectedTranscriptId || expectedTranscriptId !== transcriptId)) throw new PhoneError("PHONE_BINDING_CHANGED", "Conversation changed; refresh the phone", 409);
|
|
637
|
+
const wait = phoneAssistance(owner);
|
|
638
|
+
if (assistanceId && (!wait || wait.id !== assistanceId || ![
|
|
639
|
+
"open",
|
|
640
|
+
"queued",
|
|
641
|
+
"resuming",
|
|
642
|
+
"completed"
|
|
643
|
+
].includes(wait.status))) throw new PhoneError("PHONE_ASSISTANCE_CHANGED", "The phone task changed. Refresh before continuing.", 409);
|
|
644
|
+
if (input.op === "handback" && assistanceId && wait?.status !== "open") {
|
|
645
|
+
service.resumePhoneAssistance(owner, assistanceId);
|
|
646
|
+
return c.json({
|
|
647
|
+
ok: true,
|
|
648
|
+
payload: runtime.status(owner) && runtime.status(owner)?.status !== "closed" ? liveStatus(owner, runtime.status(owner).sessionId, context, `${getGatewayPrincipal(c).principalId}:${clientId}`) : {
|
|
649
|
+
report: phoneAssistanceReport(wait),
|
|
650
|
+
ownControl: false,
|
|
651
|
+
frame: null
|
|
474
652
|
}
|
|
475
|
-
})
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
let sessionId = id;
|
|
656
|
+
if (wait?.status === "open" && ["takeover", "handback"].includes(input.op)) {
|
|
657
|
+
const restored = await runtime.restoreAssistance(wait.checkpoint, context, c.req.raw.signal, wait.id);
|
|
658
|
+
if (restored.sessionId !== id) {
|
|
659
|
+
sessionId = restored.sessionId;
|
|
660
|
+
input.epoch = restored.controlEpoch;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
let result;
|
|
664
|
+
try {
|
|
665
|
+
const current = runtime.status(owner);
|
|
666
|
+
result = input.op === "handback" && wait?.status === "open" && current?.status === "ready" && current.controlOwner === "agent" ? liveStatus(owner, sessionId, context, `${getGatewayPrincipal(c).principalId}:${clientId}`) : await runtime.liveControl(owner, sessionId, context, `${getGatewayPrincipal(c).principalId}:${clientId}`, input, () => authorizePhoneAccess(actor, true));
|
|
667
|
+
} catch (error) {
|
|
668
|
+
const latest = phoneAssistance(owner);
|
|
669
|
+
if (input.op !== "handback" || !wait || latest?.id !== wait.id || latest.status === "open" || !(error instanceof PhoneError) || !["PHONE_CONTROL_CHANGED", "PHONE_CONTROL_BUSY"].includes(error.code)) throw error;
|
|
670
|
+
result = liveStatus(owner, sessionId, context, `${getGatewayPrincipal(c).principalId}:${clientId}`);
|
|
671
|
+
}
|
|
672
|
+
if (input.op === "cancel") cancelPhoneAssistance(owner);
|
|
673
|
+
if (input.op === "handback") {
|
|
674
|
+
if (wait?.status === "open") service.resumePhoneAssistance(owner, wait.id);
|
|
675
|
+
else if (transcriptId && result.resumeTurnRequired) {
|
|
676
|
+
if (!(await service.submitSessionInput({
|
|
677
|
+
conversationId: owner,
|
|
678
|
+
expectedTranscriptId: transcriptId,
|
|
679
|
+
clientMessageId: `phone-handback:${sessionId}:${input.epoch}`,
|
|
680
|
+
delivery: "next",
|
|
681
|
+
content: "手机已交还,请先确认当前页面,继续未完成的任务;已完成的步骤不要重复。",
|
|
682
|
+
origin: {
|
|
683
|
+
type: "system",
|
|
684
|
+
source: "internal"
|
|
685
|
+
}
|
|
686
|
+
})).ok) throw new PhoneError("PHONE_RESUME_FAILED", "Phone control returned. Send Continue in chat to resume the task.", 409);
|
|
687
|
+
}
|
|
476
688
|
}
|
|
477
689
|
c.header("Cache-Control", "no-store");
|
|
478
690
|
return c.json({
|
|
@@ -6,12 +6,12 @@ import { loadTranscriptRowsForSession } from "../../../storage/sqlite/transcript
|
|
|
6
6
|
import "../../../storage/sqlite/index.js";
|
|
7
7
|
import { ActivityService } from "../../../activity/service.js";
|
|
8
8
|
import "../../../activity/index.js";
|
|
9
|
-
import { CapabilityError } from "../../../capabilities/runtime/errors.js";
|
|
10
|
-
import "../../../capabilities/runtime/dispatcher.js";
|
|
11
9
|
import { listKnowledgeItems, writeKnowledgeItem } from "../../../knowledge-memory/repository.js";
|
|
12
10
|
import "../../../knowledge-memory/index.js";
|
|
13
11
|
import { resolveEffectiveAgentProfile } from "../../../config/agent-profile.js";
|
|
14
12
|
import { TaskReadModelProjector } from "../../../tasks/task-read-model-projector.js";
|
|
13
|
+
import { CapabilityError } from "../../../capabilities/runtime/errors.js";
|
|
14
|
+
import "../../../capabilities/runtime/dispatcher.js";
|
|
15
15
|
import { ProjectWorkspaceConflictError, ProjectWorkspaceMissingError } from "../../../projects/workspace-project.js";
|
|
16
16
|
import { inferProjectExecutionMode, inferProjectKind } from "../../../projects/project-kind.js";
|
|
17
17
|
import { ProjectDeletionBlockedError, ProjectWorkspaceInUseError } from "../../../projects/project-service.js";
|
|
@@ -114,7 +114,7 @@ async function handleSessionCommand(c, deps, materialize = false) {
|
|
|
114
114
|
const payload = await receiveSessionCommand(deps.service, id.data, principal.principalId, command, async () => {
|
|
115
115
|
if (!("input" in command)) return [];
|
|
116
116
|
const endpoint = command.origin.type === "endpoint" ? deps.service.endpointTools.registry.get(command.origin.endpointId) : void 0;
|
|
117
|
-
const contexts = endpoint ? [deviceTurnSourceContext(endpoint, command.input.endpointContext)] : [];
|
|
117
|
+
const contexts = endpoint ? [deviceTurnSourceContext(endpoint, command.input.endpointContext, deps.service.endpointTools.contexts?.view(endpoint.endpointId), deps.service.endpointTools.locations?.list(endpoint.endpointId, id.data))] : [];
|
|
118
118
|
contexts.push(...(command.input.browserContexts ?? []).map(browserPageContextToAgentContext));
|
|
119
119
|
if (command.input.appContext) contexts.push(await deps.service.prepareSessionAppContext(command.input.appContext, principal, id.data, command.clientMessageId));
|
|
120
120
|
return contexts;
|
|
@@ -5,9 +5,9 @@ import { endpointContextSchema } from "../../../../packages/gateway-contract/src
|
|
|
5
5
|
import { parseUserTurnDocument, userTurnDocumentRefIds } from "../../../../packages/gateway-contract/src/user-turn-document.js";
|
|
6
6
|
import { init_src } from "../../../../packages/gateway-contract/src/index.js";
|
|
7
7
|
import { endpointTurnClaimSchema, init_src as init_src$1 } from "../../../../packages/endpoint-tools-protocol/src/index.js";
|
|
8
|
+
import { init_providers, resolveModel } from "../../../providers/index.js";
|
|
8
9
|
import { CapabilityError } from "../../../capabilities/runtime/errors.js";
|
|
9
10
|
import "../../../capabilities/runtime/dispatcher.js";
|
|
10
|
-
import { init_providers, resolveModel } from "../../../providers/index.js";
|
|
11
11
|
import { getModelThinking } from "../../../providers/model-thinking.js";
|
|
12
12
|
import { parseTurnContextRefs } from "../../../agent/source-context/types.js";
|
|
13
13
|
import { validateWebchatAttachments, validateWebchatContent } from "../../chat-limits.js";
|
|
@@ -193,7 +193,8 @@ async function submitSessionInput(c, deps, conversationId, options) {
|
|
|
193
193
|
}, 409);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
-
const
|
|
196
|
+
const endpoint = deps.service.endpointTools.registry.get(origin.data.endpointId);
|
|
197
|
+
const sourceContexts = [deviceTurnSourceContext(endpoint, environment.data, deps.service.endpointTools.contexts?.view(endpoint.endpointId), deps.service.endpointTools.locations?.list(endpoint.endpointId, conversationId)), ...browserContexts.data.map(browserPageContextToAgentContext)];
|
|
197
198
|
if (body.appContext !== void 0) try {
|
|
198
199
|
sourceContexts.push(await deps.service.prepareSessionAppContext(body.appContext, getGatewayPrincipal(c), conversationId, typeof body.clientMessageId === "string" ? body.clientMessageId.trim() : ""));
|
|
199
200
|
} catch (error) {
|
|
@@ -6,9 +6,9 @@ import { hasGatewayScope } from "../../security/gateway-scopes.js";
|
|
|
6
6
|
import { enqueueTaskChangedEvent, init_task_change_events } from "../../../tasks/task-change-events.js";
|
|
7
7
|
import { TaskRepository, init_task_repository } from "../../../tasks/task-repository.js";
|
|
8
8
|
import { TaskRunRepository, init_task_run_repository } from "../../../tasks/task-run-repository.js";
|
|
9
|
+
import { TaskConversationRepository } from "../../../tasks/task-conversation-repository.js";
|
|
9
10
|
import { CapabilityError } from "../../../capabilities/runtime/errors.js";
|
|
10
11
|
import "../../../capabilities/runtime/dispatcher.js";
|
|
11
|
-
import { TaskConversationRepository } from "../../../tasks/task-conversation-repository.js";
|
|
12
12
|
import { TaskCollaborationRepository } from "../../../tasks/task-collaboration-repository.js";
|
|
13
13
|
import { TaskCriterionReviewRepository } from "../../../tasks/task-criterion-review-repository.js";
|
|
14
14
|
import { TaskContextMutationOutputSchema } from "../../../tasks/capabilities/relations.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
3
|
import { init_public_url, validatePublicUrl } from "../../../config/public-url.js";
|
|
4
|
+
import { TunnelRecoveryProofRejectedError, TunnelRegistrationKeyRejectedError } from "../../../tunnel/broker-client.js";
|
|
4
5
|
import { TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE, TunnelRegistrationSecretError, getTunnelRegistrationSecretMeta, readTunnelRegistrationSecretFromConfigOnly, resolveTunnelBrokerUrl } from "../../../tunnel/env.js";
|
|
5
6
|
import { logTunnelAudit } from "../../../tunnel/tunnel-audit.js";
|
|
6
7
|
import { getTunnelService, hashGatewayToken } from "../../../tunnel/tunnel-service.js";
|
|
@@ -258,6 +259,15 @@ function registerTunnelRoutes(authenticated, deps) {
|
|
|
258
259
|
});
|
|
259
260
|
} catch (err) {
|
|
260
261
|
const message = err instanceof Error ? err.message : String(err);
|
|
262
|
+
log.warn({
|
|
263
|
+
err,
|
|
264
|
+
errorMessage: message,
|
|
265
|
+
phase: "tunnel_start"
|
|
266
|
+
}, `Tunnel start failed: ${message}`);
|
|
267
|
+
if (err instanceof TunnelRegistrationKeyRejectedError || err instanceof TunnelRecoveryProofRejectedError) return c.json({
|
|
268
|
+
error: message,
|
|
269
|
+
code: err.code
|
|
270
|
+
}, 409);
|
|
261
271
|
if (err instanceof TunnelRegistrationSecretError) return c.json({
|
|
262
272
|
error: message,
|
|
263
273
|
code: TUNNEL_REGISTRATION_SECRET_REQUIRED_CODE
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { normalizeAgentId } from "../agent-catalog/id.js";
|
|
2
2
|
import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
|
|
3
3
|
import { init_agent_scope } from "../agent/agent-scope.js";
|
|
4
|
-
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
5
4
|
import { ConfigSchema, init_schema } from "../config/schema.js";
|
|
6
5
|
import { resolveEffectiveAgentConfigForAgent } from "../config/agent-profile.js";
|
|
7
6
|
import { fetchWithTimeoutGuarded } from "../media-shared/http/provider-http.js";
|
|
8
7
|
import "../media-shared/http/index.js";
|
|
8
|
+
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
9
9
|
import { getImageGenerationProvider, listImageGenerationProvidersSummary } from "../agent/image/generation/provider-registry.js";
|
|
10
10
|
//#region src/gateway/image-generation-setup.ts
|
|
11
11
|
init_repository();
|
|
@@ -52,7 +52,8 @@ function restartGatewayProcessWithFreshPid() {
|
|
|
52
52
|
const child = spawn(process.execPath, args, {
|
|
53
53
|
env: process.env,
|
|
54
54
|
detached: true,
|
|
55
|
-
stdio: "inherit"
|
|
55
|
+
stdio: process.platform === "win32" ? "ignore" : "inherit",
|
|
56
|
+
windowsHide: true
|
|
56
57
|
});
|
|
57
58
|
child.unref();
|
|
58
59
|
log.info({ pid: child.pid }, "New process spawned, exiting");
|
|
@@ -17,7 +17,13 @@ function requiredGatewayScope(method, path) {
|
|
|
17
17
|
if (path === "/api/realtime/tickets" || path.startsWith("/api/status")) return "gateway.status";
|
|
18
18
|
if (path === "/api/device-auth/refresh" || path === "/api/devices/me") return "device.self";
|
|
19
19
|
if (path.startsWith("/api/devices/me/push")) return "notifications.self";
|
|
20
|
+
if (/^\/api\/phone\/conversations\/[^/]+\/summary$/.test(path) && method === "GET") return "sessions.read";
|
|
21
|
+
if (/^\/api\/phone\/conversations\/[^/]+$/.test(path) && method === "GET") return "phone.view";
|
|
22
|
+
if (/^\/api\/phone\/conversations\/[^/]+\/[^/]+\/frame$/.test(path) && method === "GET") return "phone.view";
|
|
23
|
+
if (/^\/api\/phone\/conversations\/[^/]+\/[^/]+\/video-ticket$/.test(path) && method === "POST") return "phone.view";
|
|
24
|
+
if (/^\/api\/phone\/conversations\/[^/]+\/[^/]+\/control$/.test(path) && method === "POST") return "phone.control";
|
|
20
25
|
if (path.startsWith("/api/endpoint-tools")) return "device.self";
|
|
26
|
+
if (path === "/api/user-context/environment" || path.startsWith("/api/user-context/environment/")) return "device.self";
|
|
21
27
|
if (path === "/api/personal-agent/activity") return "tasks.read";
|
|
22
28
|
if (path === "/api/personal-agent" || path.startsWith("/api/personal-agent/")) return methodScope(method, "sessions.read", "sessions.write");
|
|
23
29
|
if (path.startsWith("/api/browser/recordings/")) return "device.self";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GatewayPrincipal } from './gateway-principal.js';
|
|
2
|
+
export declare function phoneAdministrator(principal: GatewayPrincipal): boolean;
|
|
3
|
+
/** Reload mutable device grants even for already established streams. */
|
|
4
|
+
export declare function authorizePhoneAccess(principal: GatewayPrincipal, control?: boolean): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getDevice, isDeviceAccessSessionActive } from "../../storage/sqlite/device-access-repository.js";
|
|
2
|
+
import { PhoneError, init_contracts } from "../../phone/contracts.js";
|
|
3
|
+
//#region src/gateway/security/phone-access.ts
|
|
4
|
+
init_contracts();
|
|
5
|
+
function phoneAdministrator(principal) {
|
|
6
|
+
return principal.kind !== "device" && principal.scopes.includes("gateway.admin");
|
|
7
|
+
}
|
|
8
|
+
/** Reload mutable device grants even for already established streams. */
|
|
9
|
+
function authorizePhoneAccess(principal, control = false) {
|
|
10
|
+
if (phoneAdministrator(principal)) return;
|
|
11
|
+
const device = principal.deviceId ? getDevice(principal.deviceId) : void 0;
|
|
12
|
+
if (principal.kind !== "device" || !device || device.platform === "chrome" || !principal.accessSessionId || !isDeviceAccessSessionActive(device.id, principal.accessSessionId)) throw new PhoneError("PHONE_ACCESS_REVOKED", "Phone access is unavailable for this device", 403);
|
|
13
|
+
if (![
|
|
14
|
+
"sessions.read",
|
|
15
|
+
"phone.view",
|
|
16
|
+
...control ? ["sessions.write", "phone.control"] : []
|
|
17
|
+
].every((scope) => device.scopes.includes(scope))) throw new PhoneError("PHONE_PERMISSION_REQUIRED", "Authorize phone access in Gateway device settings", 403);
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { authorizePhoneAccess, phoneAdministrator };
|
|
@@ -15,6 +15,7 @@ import { TaskCollaborationRepository } from "../../tasks/task-collaboration-repo
|
|
|
15
15
|
import { reserveEmbeddedRunCancellation } from "../../agent/embedded/runs.js";
|
|
16
16
|
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
17
17
|
import { EphemeralClarificationWaiter } from "../ephemeral-clarification-waiter.js";
|
|
18
|
+
import { completePhoneAssistanceFromUser, preparePhoneContinuation } from "../../phone/assistance-service.js";
|
|
18
19
|
import { describeActiveExecution } from "./active-execution.js";
|
|
19
20
|
import { runGatewayAgent } from "./run-gateway-agent.js";
|
|
20
21
|
import { NextTurnSuggestionService } from "../next-turn-suggestions/service.js";
|
|
@@ -67,9 +68,10 @@ var GatewayAgentRunner = class {
|
|
|
67
68
|
});
|
|
68
69
|
});
|
|
69
70
|
this.inputs = new SessionInputCoordinator({
|
|
70
|
-
beforeExecute: opts.validateConnectionResume,
|
|
71
|
+
beforeExecute: async (input) => (await opts.validateConnectionResume?.(input) ?? true) && await preparePhoneContinuation(input, opts.getConfig()),
|
|
71
72
|
continueConnection: opts.continueConnection,
|
|
72
73
|
cancelConnection: opts.cancelConnection,
|
|
74
|
+
completePhone: (wait) => completePhoneAssistanceFromUser(wait, opts.getConfig()),
|
|
73
75
|
prioritizeInput: (input) => (input.origin.type !== "system" || input.origin.source === "cli") && isPersonalConversation(input.conversationId),
|
|
74
76
|
interrupt: async (conversationId, runId, reason) => {
|
|
75
77
|
const execution = this.activeExecutionBySession.get(conversationId);
|
|
@@ -330,6 +330,7 @@ export declare class GatewayConfigCoordinator {
|
|
|
330
330
|
hierarchicalPlanning: boolean;
|
|
331
331
|
maxActionsPerSession: number;
|
|
332
332
|
maxModelRequests: number;
|
|
333
|
+
modelRequestTimeoutMs: number;
|
|
333
334
|
maxOperationDurationMs: number;
|
|
334
335
|
maxSessionDurationMs: number;
|
|
335
336
|
idleDisconnectMs: number;
|
|
@@ -13,6 +13,7 @@ import { getConversationRouting } from "../../storage/sqlite/conversation-reposi
|
|
|
13
13
|
import { init_session_key } from "../../routing/session-key.js";
|
|
14
14
|
import { resolveAgentTurnTimeoutMs } from "../../agent/orchestration/run-agent-turn-with-timeout.js";
|
|
15
15
|
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
16
|
+
import { isPhoneAssistanceSuspended } from "../../phone/assistance.js";
|
|
16
17
|
import { recordPersonalPerformance } from "../../personal-agent/performance.js";
|
|
17
18
|
import { resolveExecutionContext } from "../../tasks/execution-context.js";
|
|
18
19
|
import { TaskRunCoordinator } from "../../tasks/task-run-coordinator.js";
|
|
@@ -224,7 +225,7 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
224
225
|
for await (const event of coalesceThinkingDeltas(mappedEvents)) yield* emitAndYield([event]);
|
|
225
226
|
const connectionSuspended = isConnectionSuspended(conversationId, runId);
|
|
226
227
|
const clarificationSuspended = isClarificationSuspended(conversationId, runId);
|
|
227
|
-
const suspended = connectionSuspended || clarificationSuspended;
|
|
228
|
+
const suspended = connectionSuspended || clarificationSuspended || isPhoneAssistanceSuspended(conversationId, runId);
|
|
228
229
|
const cancelled = mergedSignal.aborted || embeddedAborted;
|
|
229
230
|
const endStatus = cancelled ? "cancelled" : suspended ? "suspended" : streamError ? "error" : "success";
|
|
230
231
|
const endSummary = cancelled ? "Interrupted" : connectionSuspended ? "Waiting for connection" : clarificationSuspended ? "Waiting for user input" : streamError ?? "Message processed successfully";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PhoneAssistance } from '../../phone/assistance.js';
|
|
1
2
|
import type { TurnOrigin } from '@xopcai/endpoint-tools-protocol';
|
|
2
3
|
import type { ConnectionWait } from '@xopcai/gateway-contract';
|
|
3
4
|
import { type SessionInput } from '../../storage/sqlite/session-input-repository.js';
|
|
@@ -36,6 +37,7 @@ export declare class SessionInputCoordinator {
|
|
|
36
37
|
beforeExecute?: (input: SessionInput) => Promise<boolean>;
|
|
37
38
|
continueConnection?: (wait: ConnectionWait, idempotencyKey: string) => Promise<void>;
|
|
38
39
|
cancelConnection?: (wait: ConnectionWait) => void;
|
|
40
|
+
completePhone?: (wait: PhoneAssistance) => Promise<void>;
|
|
39
41
|
sessionExists: (conversationId: string) => Promise<boolean>;
|
|
40
42
|
execute: (input: {
|
|
41
43
|
inputReceivedAtMs?: number;
|
|
@@ -58,6 +60,7 @@ export declare class SessionInputCoordinator {
|
|
|
58
60
|
});
|
|
59
61
|
isAcceptingInput(conversationId: string): boolean;
|
|
60
62
|
snapshot(conversationId: string): SessionInputState;
|
|
63
|
+
resumePhone(conversationId: string, waitId: string): void;
|
|
61
64
|
private connectionTarget;
|
|
62
65
|
prepareInput(input: SubmitSessionInput): Promise<{
|
|
63
66
|
payload?: import("../../storage/sqlite/session-input-repository.js").SessionInputPayload;
|