@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
|
@@ -195,8 +195,9 @@ var ComputerBroker = class {
|
|
|
195
195
|
return this.result(s);
|
|
196
196
|
}
|
|
197
197
|
async observe(s) {
|
|
198
|
-
let frame
|
|
198
|
+
let frame;
|
|
199
199
|
try {
|
|
200
|
+
frame = await this.driver.observe(s.target, s.controller.signal);
|
|
200
201
|
const validateFrame = () => {
|
|
201
202
|
this.active(s);
|
|
202
203
|
if (frame.target.appId !== s.appId || frame.target.processIdentity !== s.target.processIdentity || frame.target.windowId !== s.target.windowId) throw new Error("COMPUTER_TARGET_CHANGED");
|
|
@@ -251,7 +252,13 @@ var ComputerBroker = class {
|
|
|
251
252
|
}
|
|
252
253
|
};
|
|
253
254
|
} catch (error) {
|
|
254
|
-
frame
|
|
255
|
+
frame?.image.fill(0);
|
|
256
|
+
await this.stop().catch(() => {
|
|
257
|
+
log.warn({
|
|
258
|
+
sessionId: s.id,
|
|
259
|
+
phase: "cleanup"
|
|
260
|
+
}, "Computer driver cleanup failed after observation failure");
|
|
261
|
+
});
|
|
255
262
|
throw error;
|
|
256
263
|
}
|
|
257
264
|
}
|
|
@@ -302,7 +309,13 @@ var ComputerBroker = class {
|
|
|
302
309
|
const precheckStarted = this.now();
|
|
303
310
|
let matched = false;
|
|
304
311
|
for (let sample = 0; sample < 4; sample++) {
|
|
305
|
-
|
|
312
|
+
let current;
|
|
313
|
+
try {
|
|
314
|
+
current = await this.driver.observe(s.target, s.controller.signal);
|
|
315
|
+
} catch (error) {
|
|
316
|
+
await this.stop().catch(() => {});
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
306
319
|
try {
|
|
307
320
|
this.active(s);
|
|
308
321
|
if (!(JSON.stringify(current.target) === JSON.stringify(observed.target)) || e.deadlineAt <= this.now()) break;
|
|
@@ -173,7 +173,7 @@ function classifyComputerFailure(error, phase, dispatch = "notStarted", aborted
|
|
|
173
173
|
let category = categories[errorCode];
|
|
174
174
|
if (/^COMPUTER_MODEL_HTTP_[1-5]\d\d$/.test(errorCode)) category = "model";
|
|
175
175
|
if (/^COMPUTER_FRAME_UPLOAD_(HTTP_[1-5]\d\d|INVALID_GRANT|TOO_LARGE|TIMEOUT|NETWORK|INVALID_IMAGE|BUSY|INVALID_RESPONSE)$/.test(errorCode)) category = "transport";
|
|
176
|
-
if (/^COMPUTER_DRIVER_(CLICK|SET_VALUE|TYPE_TEXT|DRAG|KEY|SCROLL|BRING_TO_FRONT|LAUNCH_APP)_REFUSED$/.test(errorCode) || /^COMPUTER_DRIVER_SETUP_(START|BINARY|SDK|IDENTITY|PERMISSIONS)_FAILED$/.test(errorCode) || /^COMPUTER_DRIVER_(PRESS_KEY|HOTKEY)_REFUSED$/.test(errorCode) || /^COMPUTER_WINDOWS_(KEY|EDIT)_TARGET_CHANGED$/.test(errorCode)) category = "native";
|
|
176
|
+
if (errorCode === "COMPUTER_DRIVER_CLEANUP_UNCONFIRMED" || /^COMPUTER_DRIVER_(CLICK|SET_VALUE|TYPE_TEXT|DRAG|KEY|SCROLL|BRING_TO_FRONT|LAUNCH_APP)_REFUSED$/.test(errorCode) || /^COMPUTER_DRIVER_SETUP_(START|BINARY|SDK|IDENTITY|PERMISSIONS)_FAILED$/.test(errorCode) || /^COMPUTER_DRIVER_(PRESS_KEY|HOTKEY)_REFUSED$/.test(errorCode) || /^COMPUTER_WINDOWS_(KEY|EDIT)_TARGET_CHANGED$/.test(errorCode)) category = "native";
|
|
177
177
|
if (!category) {
|
|
178
178
|
category = "unknown";
|
|
179
179
|
errorCode = "COMPUTER_OPERATION_FAILED";
|
|
@@ -75,6 +75,10 @@ function computerRecovery(code) {
|
|
|
75
75
|
case "COMPUTER_EXPECTED_SINGLE_ACTION": return "The GUI model returned an invalid action after bounded format correction. No input from this prediction was dispatched. Report validationReason and diagnosticId; do not guess coordinates, replay the action or change providers.";
|
|
76
76
|
case "COMPUTER_MODEL_HTTP_400": return "The configured model service rejected the request. No input was dispatched from this model request. Report serviceErrorCode, requestId and diagnosticId; check the model request format and input/output limits before reopening. Do not automatically retry or change providers.";
|
|
77
77
|
case "COMPUTER_RELEASE_UNCONFIRMED": return "Desktop release was not confirmed. Do not switch to other tools. Stop desktop control locally or restore the endpoint connection, then call close again to confirm release.";
|
|
78
|
+
case "COMPUTER_DRIVER_CLEANUP_UNCONFIRMED": return "The private desktop driver did not confirm shutdown. The old grant is revoked and a new driver cannot start. Stop desktop control locally and confirm cleanup before reopening; never replay the previous input.";
|
|
79
|
+
case "COMPUTER_DRIVER_HOTKEY_REFUSED":
|
|
80
|
+
case "COMPUTER_DRIVER_PRESS_KEY_REFUSED":
|
|
81
|
+
case "COMPUTER_DRIVER_KEY_REFUSED": return "The native key delivery was refused and desktop control is stopped. Inspect the application locally and complete the key operation manually. Never replay it or switch to foreground/global key injection to bypass the refusal.";
|
|
78
82
|
case "COMPUTER_MODEL_HTTP_429": return "The configured model service is rate-limited. No input was dispatched from this model request. Check the service quota and retry only after it resets; do not automatically change providers.";
|
|
79
83
|
case "COMPUTER_MODEL_HTTP_409": return "The pinned model deployment changed. No input was dispatched from this model request. Refresh the model catalog and reopen after reviewing the configured screenshot recipient.";
|
|
80
84
|
case "COMPUTER_OBSERVATION_CHANGED": return "No input was dispatched. Observe the changed window and re-plan with fresh evidence; the old proposed action was discarded.";
|
|
@@ -118,8 +118,8 @@ export declare const ComputerUseInputSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
118
118
|
appRef: z.ZodString;
|
|
119
119
|
windowRef: z.ZodOptional<z.ZodString>;
|
|
120
120
|
mode: z.ZodEnum<{
|
|
121
|
-
observe: "observe";
|
|
122
121
|
control: "control";
|
|
122
|
+
observe: "observe";
|
|
123
123
|
}>;
|
|
124
124
|
prepare: z.ZodBoolean;
|
|
125
125
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { normalizeAgentId } from "../agent-catalog/id.js";
|
|
1
2
|
import { resolveEffectiveAgentConfig } from "../agent-config/resolver.js";
|
|
2
3
|
import { init_agent_config } from "../agent-config/index.js";
|
|
3
|
-
import { normalizeAgentId } from "../agent-catalog/id.js";
|
|
4
4
|
import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
|
|
5
5
|
import { init_agent_scope, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
6
6
|
import { getConversationRouting } from "../storage/sqlite/conversation-repository.js";
|
|
@@ -1789,6 +1789,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
1789
1789
|
hierarchicalPlanning: z.ZodDefault<z.ZodBoolean>;
|
|
1790
1790
|
maxActionsPerSession: z.ZodDefault<z.ZodNumber>;
|
|
1791
1791
|
maxModelRequests: z.ZodDefault<z.ZodNumber>;
|
|
1792
|
+
modelRequestTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
1792
1793
|
maxOperationDurationMs: z.ZodDefault<z.ZodNumber>;
|
|
1793
1794
|
maxSessionDurationMs: z.ZodDefault<z.ZodNumber>;
|
|
1794
1795
|
idleDisconnectMs: z.ZodDefault<z.ZodNumber>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type EndpointContextView } from '@xopcai/endpoint-tools-protocol';
|
|
2
|
+
import type { EndpointRegistry } from './registry.js';
|
|
3
|
+
export declare class EndpointContextError extends Error {
|
|
4
|
+
readonly code: 'CONTEXT_INVALID' | 'CONTEXT_CONFLICT' | 'SOURCE_UNAVAILABLE';
|
|
5
|
+
constructor(code: 'CONTEXT_INVALID' | 'CONTEXT_CONFLICT' | 'SOURCE_UNAVAILABLE', message: string);
|
|
6
|
+
}
|
|
7
|
+
/** Bounded, process-local observations. Heartbeats never refresh field timestamps. */
|
|
8
|
+
export declare class EndpointContextStore {
|
|
9
|
+
private readonly registry;
|
|
10
|
+
private readonly now;
|
|
11
|
+
private readonly snapshots;
|
|
12
|
+
private readonly unsubscribe;
|
|
13
|
+
constructor(registry: EndpointRegistry, now?: () => number);
|
|
14
|
+
private require;
|
|
15
|
+
connection(endpointId: string): {
|
|
16
|
+
connectionEpoch: string;
|
|
17
|
+
revision: number;
|
|
18
|
+
reportSequence: number;
|
|
19
|
+
heartbeatSequence: number;
|
|
20
|
+
};
|
|
21
|
+
report(endpointId: string, input: unknown): {
|
|
22
|
+
revision: number;
|
|
23
|
+
};
|
|
24
|
+
heartbeat(endpointId: string, input: unknown): {
|
|
25
|
+
revision: number;
|
|
26
|
+
};
|
|
27
|
+
view(endpointId: string): EndpointContextView | undefined;
|
|
28
|
+
close(): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { ENDPOINT_CONTEXT_OFFLINE_MS, endpointContextHeartbeatSchema, endpointContextReportSchema } from "../../packages/endpoint-tools-protocol/src/context.js";
|
|
2
|
+
import { canonicalJson, init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
//#region src/endpoint-tools/context-store.ts
|
|
5
|
+
init_src();
|
|
6
|
+
var EndpointContextError = class extends Error {
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
/** Bounded, process-local observations. Heartbeats never refresh field timestamps. */
|
|
13
|
+
var EndpointContextStore = class {
|
|
14
|
+
snapshots = /* @__PURE__ */ new Map();
|
|
15
|
+
unsubscribe;
|
|
16
|
+
constructor(registry, now = Date.now) {
|
|
17
|
+
this.registry = registry;
|
|
18
|
+
this.now = now;
|
|
19
|
+
this.unsubscribe = registry.onChange((endpointId, reason) => {
|
|
20
|
+
this.snapshots.delete(endpointId);
|
|
21
|
+
const endpoint = registry.get(endpointId);
|
|
22
|
+
if (reason === "authorization" || !endpoint) return;
|
|
23
|
+
if (this.snapshots.size >= 256) return;
|
|
24
|
+
this.snapshots.set(endpointId, {
|
|
25
|
+
epoch: endpoint.connectionId,
|
|
26
|
+
revision: 0,
|
|
27
|
+
sequence: 0,
|
|
28
|
+
heartbeatSequence: 0,
|
|
29
|
+
lastSeenAt: 0,
|
|
30
|
+
availability: "background",
|
|
31
|
+
fields: /* @__PURE__ */ new Map(),
|
|
32
|
+
receipts: /* @__PURE__ */ new Map()
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
require(endpointId) {
|
|
37
|
+
const state = this.snapshots.get(endpointId);
|
|
38
|
+
if (!state || this.registry.get(endpointId)?.connectionId !== state.epoch) throw new EndpointContextError("SOURCE_UNAVAILABLE", "Context source is unavailable");
|
|
39
|
+
return state;
|
|
40
|
+
}
|
|
41
|
+
connection(endpointId) {
|
|
42
|
+
const state = this.require(endpointId);
|
|
43
|
+
return {
|
|
44
|
+
connectionEpoch: state.epoch,
|
|
45
|
+
revision: state.revision,
|
|
46
|
+
reportSequence: state.sequence,
|
|
47
|
+
heartbeatSequence: state.heartbeatSequence
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
report(endpointId, input) {
|
|
51
|
+
const parsed = endpointContextReportSchema.safeParse(input);
|
|
52
|
+
if (!parsed.success) throw new EndpointContextError("CONTEXT_INVALID", "Invalid endpoint context report");
|
|
53
|
+
const report = parsed.data;
|
|
54
|
+
const state = this.require(endpointId);
|
|
55
|
+
if (report.connectionEpoch !== state.epoch) throw new EndpointContextError("SOURCE_UNAVAILABLE", "Context connection changed");
|
|
56
|
+
const digest = createHash("sha256").update(canonicalJson(report)).digest("hex");
|
|
57
|
+
const receipt = state.receipts.get(report.reportId);
|
|
58
|
+
if (receipt) {
|
|
59
|
+
if (receipt.digest !== digest) throw new EndpointContextError("CONTEXT_CONFLICT", "Report identity was reused");
|
|
60
|
+
return { revision: receipt.revision };
|
|
61
|
+
}
|
|
62
|
+
if (report.sequence <= state.sequence || report.mode === "patch" && report.baseRevision !== state.revision) throw new EndpointContextError("CONTEXT_CONFLICT", "Context baseline or sequence changed; send a full report");
|
|
63
|
+
const now = this.now();
|
|
64
|
+
if (report.capturedAt > now + 6e4 || report.capturedAt < now - 3e4) throw new EndpointContextError("CONTEXT_INVALID", "Context sample is stale or has an invalid clock");
|
|
65
|
+
const fields = report.mode === "full" ? /* @__PURE__ */ new Map() : new Map(state.fields);
|
|
66
|
+
for (const key of report.cleared) fields.delete(key);
|
|
67
|
+
for (const [key, value] of Object.entries(report.values)) {
|
|
68
|
+
if (value === void 0) continue;
|
|
69
|
+
const field = key;
|
|
70
|
+
const prior = state.fields.get(field);
|
|
71
|
+
if (prior && report.capturedAt < prior.capturedAt) throw new EndpointContextError("CONTEXT_CONFLICT", "Context sample moved backwards");
|
|
72
|
+
if (prior && report.capturedAt === prior.capturedAt) {
|
|
73
|
+
if (canonicalJson(prior.value) !== canonicalJson(value)) throw new EndpointContextError("CONTEXT_CONFLICT", "Context sample identity changed");
|
|
74
|
+
fields.set(field, prior);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
fields.set(field, {
|
|
78
|
+
value: structuredClone(value),
|
|
79
|
+
capturedAt: report.capturedAt,
|
|
80
|
+
receivedAt: now,
|
|
81
|
+
validUntil: Math.min(report.capturedAt, now) + (field === "device.power" ? 3e4 : 3e5)
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
state.fields = fields;
|
|
85
|
+
state.sequence = report.sequence;
|
|
86
|
+
state.revision += 1;
|
|
87
|
+
state.receipts.set(report.reportId, {
|
|
88
|
+
digest,
|
|
89
|
+
revision: state.revision
|
|
90
|
+
});
|
|
91
|
+
if (state.receipts.size > 64) state.receipts.delete(state.receipts.keys().next().value);
|
|
92
|
+
return { revision: state.revision };
|
|
93
|
+
}
|
|
94
|
+
heartbeat(endpointId, input) {
|
|
95
|
+
const parsed = endpointContextHeartbeatSchema.safeParse(input);
|
|
96
|
+
if (!parsed.success) throw new EndpointContextError("CONTEXT_INVALID", "Invalid context heartbeat");
|
|
97
|
+
const state = this.require(endpointId);
|
|
98
|
+
if (parsed.data.connectionEpoch !== state.epoch || parsed.data.sequence <= state.heartbeatSequence) throw new EndpointContextError("CONTEXT_CONFLICT", "Context heartbeat connection or sequence changed");
|
|
99
|
+
state.heartbeatSequence = parsed.data.sequence;
|
|
100
|
+
state.lastSeenAt = this.now();
|
|
101
|
+
state.availability = parsed.data.availability;
|
|
102
|
+
return { revision: state.revision };
|
|
103
|
+
}
|
|
104
|
+
view(endpointId) {
|
|
105
|
+
let state;
|
|
106
|
+
try {
|
|
107
|
+
state = this.require(endpointId);
|
|
108
|
+
} catch {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const now = this.now();
|
|
112
|
+
const availability = state.lastSeenAt === 0 || now - state.lastSeenAt >= 45e3 ? "offline" : this.registry.get(endpointId)?.kind !== "browser" && this.registry.get(endpointId)?.availability === "background" ? "background" : state.availability;
|
|
113
|
+
const fields = {};
|
|
114
|
+
for (const [key, reading] of state.fields) {
|
|
115
|
+
const status = availability !== "foreground" ? "unavailable" : reading.validUntil <= now ? "stale" : "fresh";
|
|
116
|
+
fields[key] = {
|
|
117
|
+
status,
|
|
118
|
+
capturedAt: reading.capturedAt,
|
|
119
|
+
validUntil: reading.validUntil,
|
|
120
|
+
...status === "fresh" ? { value: structuredClone(reading.value) } : {}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
version: 1,
|
|
125
|
+
endpointId,
|
|
126
|
+
revision: state.revision,
|
|
127
|
+
availability,
|
|
128
|
+
sourceValidUntil: state.lastSeenAt + ENDPOINT_CONTEXT_OFFLINE_MS,
|
|
129
|
+
fields
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
close() {
|
|
133
|
+
this.unsubscribe();
|
|
134
|
+
this.snapshots.clear();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
//#endregion
|
|
138
|
+
export { EndpointContextError, EndpointContextStore };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type LocationSample, type LocationShareRequest, type LocationShareSummary } from '@xopcai/endpoint-tools-protocol';
|
|
2
|
+
import type { EndpointRegistry } from './registry.js';
|
|
3
|
+
import type { EndpointContextStore } from './context-store.js';
|
|
4
|
+
export declare class LocationSharingError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
constructor(code: string, message: string);
|
|
7
|
+
}
|
|
8
|
+
export interface LocationConsumer {
|
|
9
|
+
apply(input: {
|
|
10
|
+
shareId: string;
|
|
11
|
+
conversationId: string;
|
|
12
|
+
phoneId: string;
|
|
13
|
+
sample: LocationSample;
|
|
14
|
+
validUntil: number;
|
|
15
|
+
assertCurrent(): void;
|
|
16
|
+
}, signal: AbortSignal): Promise<void>;
|
|
17
|
+
clear(shareId: string, phoneId: string): Promise<boolean>;
|
|
18
|
+
state?(shareId: string, phoneId: string): LocationShareSummary['sync'];
|
|
19
|
+
}
|
|
20
|
+
/** Explicitly authorized coordinates remain transient and are never part of public context values. */
|
|
21
|
+
export declare class LocationSharingService {
|
|
22
|
+
private readonly registry;
|
|
23
|
+
private readonly contexts;
|
|
24
|
+
private readonly now;
|
|
25
|
+
private readonly shares;
|
|
26
|
+
private consumer?;
|
|
27
|
+
private readonly timer;
|
|
28
|
+
private readonly unsubscribe;
|
|
29
|
+
constructor(registry: EndpointRegistry, contexts: EndpointContextStore, now?: () => number);
|
|
30
|
+
setConsumer(consumer: LocationConsumer): void;
|
|
31
|
+
create(endpointId: string, input: LocationShareRequest): LocationShareSummary;
|
|
32
|
+
private usable;
|
|
33
|
+
sample(id: string, endpointId: string, input: unknown): Promise<LocationShareSummary>;
|
|
34
|
+
private require;
|
|
35
|
+
private summary;
|
|
36
|
+
list(endpointId: string, conversationId?: string): LocationShareSummary[];
|
|
37
|
+
revoke(id: string, endpointId: string): Promise<LocationShareSummary>;
|
|
38
|
+
private invalidate;
|
|
39
|
+
private clear;
|
|
40
|
+
sweep(): Promise<void>;
|
|
41
|
+
close(): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { locationShareRequestSchema, locationShareSampleSchema } from "../../packages/endpoint-tools-protocol/src/location-sharing.js";
|
|
2
|
+
import { init_src } from "../../packages/endpoint-tools-protocol/src/index.js";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
//#region src/endpoint-tools/location-sharing.ts
|
|
5
|
+
init_src();
|
|
6
|
+
var LocationSharingError = class extends Error {
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
/** Explicitly authorized coordinates remain transient and are never part of public context values. */
|
|
13
|
+
var LocationSharingService = class {
|
|
14
|
+
shares = /* @__PURE__ */ new Map();
|
|
15
|
+
consumer;
|
|
16
|
+
timer;
|
|
17
|
+
unsubscribe;
|
|
18
|
+
constructor(registry, contexts, now = Date.now) {
|
|
19
|
+
this.registry = registry;
|
|
20
|
+
this.contexts = contexts;
|
|
21
|
+
this.now = now;
|
|
22
|
+
this.timer = setInterval(() => {
|
|
23
|
+
this.sweep();
|
|
24
|
+
}, 1e3);
|
|
25
|
+
this.timer.unref();
|
|
26
|
+
this.unsubscribe = registry.onChange((endpointId) => {
|
|
27
|
+
for (const share of this.shares.values()) if (share.summary.endpointId === endpointId) this.invalidate(share, "source_unavailable");
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
setConsumer(consumer) {
|
|
31
|
+
this.consumer = consumer;
|
|
32
|
+
}
|
|
33
|
+
create(endpointId, input) {
|
|
34
|
+
const request = locationShareRequestSchema.parse(input);
|
|
35
|
+
const endpoint = this.registry.get(endpointId);
|
|
36
|
+
if (!endpoint || this.contexts.view(endpointId)?.availability !== "foreground") throw new LocationSharingError("SOURCE_UNAVAILABLE", "Open the source device before sharing location");
|
|
37
|
+
for (const [id, share] of this.shares) if ([
|
|
38
|
+
"revoked",
|
|
39
|
+
"expired",
|
|
40
|
+
"source_unavailable"
|
|
41
|
+
].includes(share.summary.status) && share.summary.sync !== "cleanup_pending") this.shares.delete(id);
|
|
42
|
+
if (this.shares.size >= 64) throw new LocationSharingError("SHARING_CAPACITY", "Too many location shares");
|
|
43
|
+
if ([...this.shares.values()].some((share) => share.summary.endpointId === endpointId && share.summary.conversationId === request.conversationId && ![
|
|
44
|
+
"revoked",
|
|
45
|
+
"expired",
|
|
46
|
+
"source_unavailable"
|
|
47
|
+
].includes(share.summary.status))) throw new LocationSharingError("SHARING_EXISTS", "Stop the current location share first");
|
|
48
|
+
const summary = {
|
|
49
|
+
...request,
|
|
50
|
+
id: randomUUID(),
|
|
51
|
+
endpointId,
|
|
52
|
+
expiresAt: this.now() + request.durationMs,
|
|
53
|
+
status: "waiting",
|
|
54
|
+
sync: request.phoneId ? "pending" : "not_requested"
|
|
55
|
+
};
|
|
56
|
+
const share = {
|
|
57
|
+
summary,
|
|
58
|
+
epoch: endpoint.connectionId,
|
|
59
|
+
sequence: 0,
|
|
60
|
+
controller: new AbortController(),
|
|
61
|
+
operation: Promise.resolve()
|
|
62
|
+
};
|
|
63
|
+
this.shares.set(summary.id, share);
|
|
64
|
+
return { ...summary };
|
|
65
|
+
}
|
|
66
|
+
usable(share) {
|
|
67
|
+
return !share.controller.signal.aborted && share.summary.expiresAt > this.now() && this.registry.get(share.summary.endpointId)?.connectionId === share.epoch && this.contexts.view(share.summary.endpointId)?.availability === "foreground";
|
|
68
|
+
}
|
|
69
|
+
async sample(id, endpointId, input) {
|
|
70
|
+
const share = this.require(id, endpointId);
|
|
71
|
+
const parsed = locationShareSampleSchema.safeParse(input);
|
|
72
|
+
if (!parsed.success) throw new LocationSharingError("LOCATION_INVALID", "Invalid location sample");
|
|
73
|
+
if (!this.usable(share)) {
|
|
74
|
+
await this.invalidate(share, share.summary.expiresAt <= this.now() ? "expired" : "source_unavailable");
|
|
75
|
+
throw new LocationSharingError("GRANT_REVOKED", "Location sharing is no longer active");
|
|
76
|
+
}
|
|
77
|
+
const { sequence, sample } = parsed.data;
|
|
78
|
+
if (sequence <= share.sequence || share.summary.mode === "once" && share.sequence > 0) throw new LocationSharingError("LOCATION_REPLAY", "Location sample was already consumed");
|
|
79
|
+
if (sample.capturedAt < this.now() - 3e4 || sample.capturedAt > this.now() + 6e4 || share.sample && sample.capturedAt <= share.sample.capturedAt) throw new LocationSharingError("CONTEXT_STALE", "Acquire a fresh location sample");
|
|
80
|
+
if (share.summary.precision === "precise" && sample.precision !== "precise") throw new LocationSharingError("PRECISION_UNAVAILABLE", "Precise location is unavailable; choose approximate sharing");
|
|
81
|
+
const value = share.summary.precision === "approximate" || sample.precision === "approximate" ? {
|
|
82
|
+
...sample,
|
|
83
|
+
latitude: Math.round(sample.latitude * 50) / 50,
|
|
84
|
+
longitude: Math.round(sample.longitude * 50) / 50,
|
|
85
|
+
accuracyMeters: Math.max(3e3, sample.accuracyMeters),
|
|
86
|
+
precision: "approximate"
|
|
87
|
+
} : sample;
|
|
88
|
+
share.sequence = sequence;
|
|
89
|
+
share.sample = value;
|
|
90
|
+
share.sampleController?.abort();
|
|
91
|
+
share.sampleController = new AbortController();
|
|
92
|
+
const valueRef = randomUUID();
|
|
93
|
+
Object.assign(share.summary, {
|
|
94
|
+
status: "fresh",
|
|
95
|
+
capturedAt: value.capturedAt,
|
|
96
|
+
accuracyMeters: value.accuracyMeters,
|
|
97
|
+
validUntil: Math.min(value.capturedAt, this.now()) + 3e4,
|
|
98
|
+
valueRef
|
|
99
|
+
});
|
|
100
|
+
share.summary.validUntil = Math.min(share.summary.validUntil, share.summary.expiresAt);
|
|
101
|
+
if (share.summary.phoneId) {
|
|
102
|
+
share.summary.sync = "pending";
|
|
103
|
+
const consumer = this.consumer;
|
|
104
|
+
if (!consumer) throw new LocationSharingError("PHONE_ENV_UNSUPPORTED", "Phone location synchronization is unavailable");
|
|
105
|
+
const validUntil = share.summary.validUntil;
|
|
106
|
+
const signal = AbortSignal.any([
|
|
107
|
+
share.controller.signal,
|
|
108
|
+
share.sampleController.signal,
|
|
109
|
+
AbortSignal.timeout(Math.max(1, validUntil - this.now()))
|
|
110
|
+
]);
|
|
111
|
+
const assertCurrent = () => {
|
|
112
|
+
if (!this.usable(share) || share.summary.valueRef !== valueRef || validUntil <= this.now()) throw new LocationSharingError("CONTEXT_STALE", "Location authorization or sample expired");
|
|
113
|
+
};
|
|
114
|
+
share.operation = share.operation.catch(() => {}).then(async () => {
|
|
115
|
+
try {
|
|
116
|
+
assertCurrent();
|
|
117
|
+
await consumer.apply({
|
|
118
|
+
shareId: id,
|
|
119
|
+
conversationId: share.summary.conversationId,
|
|
120
|
+
phoneId: share.summary.phoneId,
|
|
121
|
+
sample: value,
|
|
122
|
+
validUntil,
|
|
123
|
+
assertCurrent
|
|
124
|
+
}, signal);
|
|
125
|
+
assertCurrent();
|
|
126
|
+
share.summary.sync = "applied";
|
|
127
|
+
} catch {
|
|
128
|
+
if (share.summary.valueRef === valueRef && share.summary.status === "fresh") share.summary.sync = "failed";
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
await share.operation;
|
|
132
|
+
}
|
|
133
|
+
return this.summary(share);
|
|
134
|
+
}
|
|
135
|
+
require(id, endpointId) {
|
|
136
|
+
const share = this.shares.get(id);
|
|
137
|
+
if (!share || share.summary.endpointId !== endpointId) throw new LocationSharingError("SHARE_NOT_FOUND", "Location share is unavailable");
|
|
138
|
+
return share;
|
|
139
|
+
}
|
|
140
|
+
summary(share) {
|
|
141
|
+
const result = { ...share.summary };
|
|
142
|
+
if (result.phoneId && ["applied", "cleanup_pending"].includes(result.sync)) result.sync = this.consumer?.state?.(result.id, result.phoneId) ?? result.sync;
|
|
143
|
+
if (!this.usable(share) || !share.sample || (result.validUntil ?? 0) <= this.now()) {
|
|
144
|
+
delete result.valueRef;
|
|
145
|
+
if (result.status === "fresh") result.status = "stale";
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
list(endpointId, conversationId) {
|
|
150
|
+
return [...this.shares.values()].filter((share) => share.summary.endpointId === endpointId && (!conversationId || share.summary.conversationId === conversationId)).map((share) => this.summary(share));
|
|
151
|
+
}
|
|
152
|
+
async revoke(id, endpointId) {
|
|
153
|
+
return this.invalidate(this.require(id, endpointId), "revoked");
|
|
154
|
+
}
|
|
155
|
+
async invalidate(share, status) {
|
|
156
|
+
share.controller.abort();
|
|
157
|
+
share.sampleController?.abort();
|
|
158
|
+
share.sample = void 0;
|
|
159
|
+
delete share.summary.valueRef;
|
|
160
|
+
if (![
|
|
161
|
+
"revoked",
|
|
162
|
+
"expired",
|
|
163
|
+
"source_unavailable"
|
|
164
|
+
].includes(share.summary.status)) share.summary.status = status;
|
|
165
|
+
await this.clear(share);
|
|
166
|
+
return this.summary(share);
|
|
167
|
+
}
|
|
168
|
+
async clear(share) {
|
|
169
|
+
if (!share.summary.phoneId || !this.consumer) return;
|
|
170
|
+
share.summary.sync = "cleanup_pending";
|
|
171
|
+
share.operation = share.operation.catch(() => {}).then(async () => {
|
|
172
|
+
try {
|
|
173
|
+
share.summary.sync = await this.consumer.clear(share.summary.id, share.summary.phoneId) ? "clean" : "cleanup_pending";
|
|
174
|
+
} catch {
|
|
175
|
+
share.summary.sync = "cleanup_pending";
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
await share.operation;
|
|
179
|
+
}
|
|
180
|
+
async sweep() {
|
|
181
|
+
const pending = [];
|
|
182
|
+
for (const share of this.shares.values()) {
|
|
183
|
+
if (share.summary.status === "waiting" && share.summary.expiresAt > this.now() && this.registry.get(share.summary.endpointId)?.connectionId === share.epoch) continue;
|
|
184
|
+
if (!share.controller.signal.aborted && !this.usable(share)) pending.push(this.invalidate(share, share.summary.expiresAt <= this.now() ? "expired" : "source_unavailable"));
|
|
185
|
+
else if (share.sample && (share.summary.validUntil ?? 0) <= this.now()) {
|
|
186
|
+
share.sampleController?.abort();
|
|
187
|
+
share.sample = void 0;
|
|
188
|
+
delete share.summary.valueRef;
|
|
189
|
+
share.summary.status = "stale";
|
|
190
|
+
pending.push(this.clear(share));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
await Promise.all(pending);
|
|
194
|
+
}
|
|
195
|
+
async close() {
|
|
196
|
+
clearInterval(this.timer);
|
|
197
|
+
this.unsubscribe();
|
|
198
|
+
await Promise.all([...this.shares.values()].map((share) => this.invalidate(share, "revoked")));
|
|
199
|
+
this.shares.clear();
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
//#endregion
|
|
203
|
+
export { LocationSharingError, LocationSharingService };
|
|
@@ -5,8 +5,12 @@ import { EndpointBindingService } from './binding-service.js';
|
|
|
5
5
|
import { EndpointInvocationService, type EndpointInvocationAuditSink } from './invocation-service.js';
|
|
6
6
|
import { EndpointRegistry, type EndpointRegistration, type EndpointTransport } from './registry.js';
|
|
7
7
|
import { EndpointUploadService } from './upload-service.js';
|
|
8
|
+
import { EndpointContextStore } from './context-store.js';
|
|
9
|
+
import { LocationSharingService } from './location-sharing.js';
|
|
8
10
|
export declare class EndpointToolRuntime {
|
|
9
11
|
readonly registry: EndpointRegistry;
|
|
12
|
+
readonly contexts: EndpointContextStore;
|
|
13
|
+
readonly locations: LocationSharingService;
|
|
10
14
|
readonly grants: DeviceGrantService;
|
|
11
15
|
readonly invocations: EndpointInvocationService;
|
|
12
16
|
readonly uploads: EndpointUploadService;
|
|
@@ -11,10 +11,12 @@ import { EndpointToolPolicy } from "./policy.js";
|
|
|
11
11
|
import { EndpointInvocationService } from "./invocation-service.js";
|
|
12
12
|
import { EndpointAuthenticator } from "./auth.js";
|
|
13
13
|
import { EndpointBindingService } from "./binding-service.js";
|
|
14
|
+
import { EndpointContextStore } from "./context-store.js";
|
|
14
15
|
import { DeviceGrantService } from "./grant-service.js";
|
|
15
16
|
import { recordDeviceGrantEvent } from "../storage/sqlite/device-grant-audit-repository.js";
|
|
16
17
|
import { EndpointRegistry } from "./registry.js";
|
|
17
18
|
import { EndpointUploadService } from "./upload-service.js";
|
|
19
|
+
import { LocationSharingService } from "./location-sharing.js";
|
|
18
20
|
import { join } from "node:path";
|
|
19
21
|
//#region src/endpoint-tools/runtime.ts
|
|
20
22
|
init_paths();
|
|
@@ -23,6 +25,8 @@ const log = createLogger("EndpointTools");
|
|
|
23
25
|
const MAX_MESSAGE_CLOCK_SKEW_MS = 6e4;
|
|
24
26
|
var EndpointToolRuntime = class {
|
|
25
27
|
registry;
|
|
28
|
+
contexts;
|
|
29
|
+
locations;
|
|
26
30
|
grants;
|
|
27
31
|
invocations;
|
|
28
32
|
uploads;
|
|
@@ -32,6 +36,8 @@ var EndpointToolRuntime = class {
|
|
|
32
36
|
constructor(options = {}) {
|
|
33
37
|
const policy = new EndpointToolPolicy();
|
|
34
38
|
this.registry = new EndpointRegistry(policy);
|
|
39
|
+
this.contexts = new EndpointContextStore(this.registry);
|
|
40
|
+
this.locations = new LocationSharingService(this.registry, this.contexts);
|
|
35
41
|
this.grants = new DeviceGrantService(this.registry, Date.now, recordDeviceGrantEvent);
|
|
36
42
|
this.bindings = new EndpointBindingService(this.registry, {
|
|
37
43
|
get: getEndpointSessionBinding,
|
|
@@ -103,6 +109,8 @@ var EndpointToolRuntime = class {
|
|
|
103
109
|
this.grants.close();
|
|
104
110
|
this.invocations.close();
|
|
105
111
|
this.uploads.close();
|
|
112
|
+
this.contexts.close();
|
|
113
|
+
this.locations.close();
|
|
106
114
|
this.registry.closeAll();
|
|
107
115
|
}
|
|
108
116
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EndpointContext } from '@xopcai/gateway-contract';
|
|
2
|
+
import type { EndpointContextView, LocationShareSummary } from '@xopcai/endpoint-tools-protocol';
|
|
2
3
|
import type { AgentSourceContext } from '../agent/source-context/types.js';
|
|
3
4
|
import type { GatewayPrincipal } from '../gateway/security/gateway-principal.js';
|
|
4
5
|
import type { EndpointConnectionSnapshot, EndpointRegistry } from './registry.js';
|
|
5
6
|
export declare function endpointClaimBelongsToPrincipal(registry: EndpointRegistry, endpointId: string, principal: GatewayPrincipal): boolean;
|
|
6
|
-
export declare function deviceTurnSourceContext(endpoint: EndpointConnectionSnapshot, environment?: EndpointContext): AgentSourceContext;
|
|
7
|
+
export declare function deviceTurnSourceContext(endpoint: EndpointConnectionSnapshot, environment?: EndpointContext, taskContext?: EndpointContextView, locationShares?: LocationShareSummary[]): AgentSourceContext;
|
|
@@ -5,7 +5,7 @@ function endpointClaimBelongsToPrincipal(registry, endpointId, principal) {
|
|
|
5
5
|
const endpoint = registry.get(endpointId);
|
|
6
6
|
return Boolean(endpoint && (principal.kind === "owner" || principal.kind === "device" && endpoint.principalId === principal.deviceId));
|
|
7
7
|
}
|
|
8
|
-
function deviceTurnSourceContext(endpoint, environment) {
|
|
8
|
+
function deviceTurnSourceContext(endpoint, environment, taskContext, locationShares) {
|
|
9
9
|
const name = getEndpointDeviceSettings(endpoint.principalId)?.nickname ?? endpoint.displayName;
|
|
10
10
|
const snapshot = {
|
|
11
11
|
endpointId: endpoint.endpointId,
|
|
@@ -13,7 +13,9 @@ function deviceTurnSourceContext(endpoint, environment) {
|
|
|
13
13
|
name: name.slice(0, 80),
|
|
14
14
|
platform: endpoint.platform.slice(0, 40),
|
|
15
15
|
kind: endpoint.kind,
|
|
16
|
-
...environment ? { environment } : {}
|
|
16
|
+
...environment ? { environment } : {},
|
|
17
|
+
...taskContext ? { taskContext } : {},
|
|
18
|
+
...locationShares?.length ? { locationShares: locationShares.slice(-3) } : {}
|
|
17
19
|
};
|
|
18
20
|
const text = JSON.stringify(snapshot).replaceAll("<", "\\u003c").replaceAll(">", "\\u003e");
|
|
19
21
|
return {
|
|
@@ -8,8 +8,8 @@ import { assertManagedWorktreePath, assertNoNestedRegisteredWorktrees, readDirec
|
|
|
8
8
|
import { dirname, resolve } from "node:path";
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
|
-
import { mkdir, rm, stat } from "node:fs/promises";
|
|
12
11
|
import lockfile from "proper-lockfile";
|
|
12
|
+
import { mkdir, rm, stat } from "node:fs/promises";
|
|
13
13
|
//#region src/execution-environments/local-worktree-manager.ts
|
|
14
14
|
init_logger();
|
|
15
15
|
const log = createLogger("ExecutionEnvironment:LocalWorktree");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
2
1
|
import { containedPath } from "./contained-path.js";
|
|
3
2
|
import "./validation.js";
|
|
4
3
|
import { AgentPluginStore } from "./store.js";
|
|
4
|
+
import { parseFrontmatter } from "../../markdown/frontmatter.js";
|
|
5
5
|
import { createSkillConfigManager } from "../../agent/skills/config.js";
|
|
6
6
|
import { parseSkillLocalizations } from "../../agent/skills/parse-skill-metadata.js";
|
|
7
7
|
import { buildSkillMarkdownPreviewFromRaw } from "../../agent/skills/skill-markdown-preview-from-raw.js";
|
|
@@ -9,8 +9,8 @@ import { dirname, join, resolve } from "node:path";
|
|
|
9
9
|
import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
11
|
import { z } from "zod";
|
|
12
|
-
import yaml from "js-yaml";
|
|
13
12
|
import { validateHeaderName, validateHeaderValue } from "node:http";
|
|
13
|
+
import yaml from "js-yaml";
|
|
14
14
|
//#region src/extensions/agent-plugins/validation.ts
|
|
15
15
|
init_schema();
|
|
16
16
|
const PLUGIN_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { normalizeAgentId, validateAgentIdForNewAgent } from "../agent-catalog/id.js";
|
|
2
2
|
import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
|
|
3
3
|
import { init_agent_scope, listAgentEntries, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath } from "../agent/agent-scope.js";
|
|
4
|
-
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
|
|
5
|
-
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
6
4
|
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
5
|
+
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
|
|
7
6
|
import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
|
|
7
|
+
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
8
8
|
import { GATEWAY_BUILTIN_TOOL_IDS } from "./agent-builtin-tools.js";
|
|
9
9
|
import { resolve } from "node:path";
|
|
10
10
|
import { mkdir, readFile, realpath, stat, unlink, writeFile } from "node:fs/promises";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AutomationRun, AutomationRunDeliveryContext } from '../automations/domain/types.js';
|
|
2
|
+
import type { NotificationService } from '../notifications/service.js';
|
|
3
|
+
/** Commit the inbox handoff before acknowledging the durable result outbox. */
|
|
4
|
+
export declare function deliverAutomationCompletion(run: AutomationRun, context: AutomationRunDeliveryContext, notifications: NotificationService, emit: (type: string, payload: unknown) => void): void;
|