@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.
Files changed (414) hide show
  1. package/dist/browser-ext/dist/background.js +184 -2
  2. package/dist/browser-ext/dist/sidepanel.js +9 -0
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{activity-store-DnqOM8GN.js → activity-store-CvJ9rdwP.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-1UABT2KS.js → agent-avatar-dicebear-CFP6g4w7.js} +1 -1
  7. package/dist/gateway/static/root/assets/agent-avatar-display-BHBe88Gu.js +2 -0
  8. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DlGRuKMv.js +1 -0
  9. package/dist/gateway/static/root/assets/agent-plugin-dialog-C_Dm-u6_.js +1 -0
  10. package/dist/gateway/static/root/assets/{agents-O7mago-m.js → agents-BdVJHOiK.js} +5 -5
  11. package/dist/gateway/static/root/assets/{agents-admin-api-CyjykMEh.js → agents-admin-api-Do1Pza0R.js} +1 -1
  12. package/dist/gateway/static/root/assets/{api-Ddrs70xV.js → api-BQv5dLcH.js} +1 -1
  13. package/dist/gateway/static/root/assets/{api-C1dxxDZx.js → api-ONg37_fH.js} +1 -1
  14. package/dist/gateway/static/root/assets/app-link-1j40sJ-z.js +1 -0
  15. package/dist/gateway/static/root/assets/app-management-settings-panel-B4Wqhf4J.js +1 -0
  16. package/dist/gateway/static/root/assets/appearance-settings-Dm1kRzKL.js +1 -0
  17. package/dist/gateway/static/root/assets/apps-page-D1MMk1P7.js +1 -0
  18. package/dist/gateway/static/root/assets/{archive-plugin-n5lPr79c.js → archive-plugin-p_yLkyaC.js} +1 -1
  19. package/dist/gateway/static/root/assets/automation-api-DQaWBR03.js +1 -0
  20. package/dist/gateway/static/root/assets/automation-result-state-CO_243JM.js +1 -0
  21. package/dist/gateway/static/root/assets/automation-task-card-D2p9qlYE.js +3 -0
  22. package/dist/gateway/static/root/assets/{automations-page-oLsNzu_6.js → automations-page-Ba64H37d.js} +1 -1
  23. package/dist/gateway/static/root/assets/automations-workspace-BkzC3oIM.js +9 -0
  24. package/dist/gateway/static/root/assets/{binary-plugins-D9VW7dWP.js → binary-plugins-B-6kyqtt.js} +1 -1
  25. package/dist/gateway/static/root/assets/{block-editor-C477bTtO.js → block-editor-B5ysJ96n.js} +4 -4
  26. package/dist/gateway/static/root/assets/{browser-automation-inputs-CCiYXxmh.js → browser-automation-inputs-C2A3NIt3.js} +1 -1
  27. package/dist/gateway/static/root/assets/browser-automations-page-CnbXFw1_.js +3 -0
  28. package/dist/gateway/static/root/assets/{browser-control-api-Y3fvmeBk.js → browser-control-api-Aj_seKE9.js} +1 -1
  29. package/dist/gateway/static/root/assets/{browser-settings-page-DjkGahlz.js → browser-settings-page-C7fxPq_z.js} +2 -2
  30. package/dist/gateway/static/root/assets/{capabilities-DAyA681v.js → capabilities-BgtCwC_E.js} +1 -1
  31. package/dist/gateway/static/root/assets/{capabilities-DRVXLssH.js → capabilities-DOTgaSgA.js} +1 -1
  32. package/dist/gateway/static/root/assets/capabilities-page-m3b9sLFG.js +2 -0
  33. package/dist/gateway/static/root/assets/capabilities-settings-panel-pYWZtPeU.js +8 -0
  34. package/dist/gateway/static/root/assets/channels-DGpRM6pj.js +1 -0
  35. package/dist/gateway/static/root/assets/{chat-agents-api-D5nR_JVe.js → chat-agents-api-EvJ_Wvuc.js} +1 -1
  36. package/dist/gateway/static/root/assets/{chat-chart-block-K2t333qv.js → chat-chart-block-BQDbHLcw.js} +1 -1
  37. package/dist/gateway/static/root/assets/chat-page-GF9NIuZN.js +72 -0
  38. package/dist/gateway/static/root/assets/{chat-terminal-dock-CkFG6mA3.js → chat-terminal-dock-DHFTGoEp.js} +2 -2
  39. package/dist/gateway/static/root/assets/{list-filter-COkzTdOz.js → clipboard-copy-DuJk5WD6.js} +1 -1
  40. package/dist/gateway/static/root/assets/{command-palette-api-Do_66X1B.js → command-palette-api-DPA_yEuy.js} +1 -1
  41. package/dist/gateway/static/root/assets/composer-payload-handoff-BTjauSNp.js +1 -0
  42. package/dist/gateway/static/root/assets/{computer-settings-page-DBxOcMko.js → computer-settings-page-BFSSQfcx.js} +1 -1
  43. package/dist/gateway/static/root/assets/connected-providers-grid-DM2glQN3.js +1 -0
  44. package/dist/gateway/static/root/assets/{connector-service-page-rWpnchb3.js → connector-service-page-CFvg58qa.js} +1 -1
  45. package/dist/gateway/static/root/assets/{connectors-api-DIBG72k4.js → connectors-api-CbC6Yht5.js} +1 -1
  46. package/dist/gateway/static/root/assets/connectors-page-D7pipFHA.js +1 -0
  47. package/dist/gateway/static/root/assets/date-picker-Dd3MbG0x.js +1 -0
  48. package/dist/gateway/static/root/assets/{dependency-picker-7SpSfDSg.js → dependency-picker-DcsHg2ml.js} +1 -1
  49. package/dist/gateway/static/root/assets/desktop-pet-DldzQT2h.js +1 -0
  50. package/dist/gateway/static/root/assets/desktop-pet-settings-CYdI4KxB.js +1 -0
  51. package/dist/gateway/static/root/assets/{dev-view-store-57HgVuZ6.js → dev-view-store-JiJv585f.js} +1 -1
  52. package/dist/gateway/static/root/assets/device-pairing-wizard-D8cLc41G.js +1 -0
  53. package/dist/gateway/static/root/assets/{directory-picker-path-field-D4jMhpka.js → directory-picker-path-field-8WOXv8zw.js} +1 -1
  54. package/dist/gateway/static/root/assets/discussion-annotation-sync-B-grSe0w.js +1 -0
  55. package/dist/gateway/static/root/assets/{dist-DNCdG_qB.js → dist-D3lWNSe7.js} +1 -1
  56. package/dist/gateway/static/root/assets/{extension-debug-page-BsK2LMXQ.js → extension-debug-page-EEQkTNEu.js} +1 -1
  57. package/dist/gateway/static/root/assets/extension-iframe-host-vlZVeMCY.js +1 -0
  58. package/dist/gateway/static/root/assets/{extension-marketplace-api-CVJPqJOB.js → extension-marketplace-api-_o2In_al.js} +1 -1
  59. package/dist/gateway/static/root/assets/extension-page-CPrT111s.js +1 -0
  60. package/dist/gateway/static/root/assets/{extension-provider-Byrd8Sor.js → extension-provider-B2Mf3FBu.js} +1 -1
  61. package/dist/gateway/static/root/assets/extension-settings-page-CznJEgWV.js +1 -0
  62. package/dist/gateway/static/root/assets/{file-preview-surface-BlprUrIs.js → file-preview-surface-7h8_fZul.js} +1 -1
  63. package/dist/gateway/static/root/assets/{gateway-config-swr-BAmUhiP1.js → gateway-config-swr-DbbNEOKj.js} +1 -1
  64. package/dist/gateway/static/root/assets/{gateway-realtime-CsykKL4l.js → gateway-realtime-D20ZrAuM.js} +1 -1
  65. package/dist/gateway/static/root/assets/gateway-realtime-store-C6sMzYDT.js +1 -0
  66. package/dist/gateway/static/root/assets/gateway-restart-5ut-lhJm.js +1 -0
  67. package/dist/gateway/static/root/assets/{gateway-settings-BA5-Uuwx.js → gateway-settings-BCf_cibp.js} +1 -1
  68. package/dist/gateway/static/root/assets/{gateway-startup-retry-CtUB3g6N.js → gateway-startup-retry-DlHL0DpH.js} +1 -1
  69. package/dist/gateway/static/root/assets/{global-defaults-api-CINf-C6a.js → global-defaults-api-CmODomcV.js} +1 -1
  70. package/dist/gateway/static/root/assets/home-page-uz22TRB-.js +2 -0
  71. package/dist/gateway/static/root/assets/image-generation-api-dzPnpUFu.js +1 -0
  72. package/dist/gateway/static/root/assets/{imports-page-BWShtGRQ.js → imports-page-ChBoNMyE.js} +1 -1
  73. package/dist/gateway/static/root/assets/index-CSIg7V1A.js +11 -0
  74. package/dist/gateway/static/root/assets/index-Dv8mUlNN.css +1 -0
  75. package/dist/gateway/static/root/assets/install-connector-dialog-CNcdQDX0.js +1 -0
  76. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CdM4BQwp.js → keyboard-shortcuts-settings-CRbYq2_g.js} +1 -1
  77. package/dist/gateway/static/root/assets/list-filter-CIPvpfLA.js +1 -0
  78. package/dist/gateway/static/root/assets/local-app-workbench-page-04cX5TJu.js +1 -0
  79. package/dist/gateway/static/root/assets/{local-apps-page-CxyRVfjD.js → local-apps-page-fWM0FEhN.js} +1 -1
  80. package/dist/gateway/static/root/assets/{local-session-drafts-B9ZPwotC.js → local-session-drafts-ClrSe5mH.js} +1 -1
  81. package/dist/gateway/static/root/assets/{locale-store-lIXD1FMw.js → locale-store-VNjH18Dj.js} +1 -1
  82. package/dist/gateway/static/root/assets/logs-page-6GanGLrm.js +2 -0
  83. package/dist/gateway/static/root/assets/management-settings-BxD_lc4E.js +1 -0
  84. package/dist/gateway/static/root/assets/{markdown-view-CJt-i2Dp.js → markdown-view-DLCBYWtx.js} +4 -4
  85. package/dist/gateway/static/root/assets/{media-plugins-D_bR23mA.js → media-plugins-BvtNwKFb.js} +1 -1
  86. package/dist/gateway/static/root/assets/messages-Btr7C0hF.js +3 -0
  87. package/dist/gateway/static/root/assets/model-selector-DYUnp917.js +1 -0
  88. package/dist/gateway/static/root/assets/{models-hub-cache-za2fWJLg.js → models-hub-cache-_qE7L-_H.js} +1 -1
  89. package/dist/gateway/static/root/assets/navigation-D62kPsA9.js +1 -0
  90. package/dist/gateway/static/root/assets/note-detail-panel-bjRZesmS.js +5 -0
  91. package/dist/gateway/static/root/assets/note-image-lightbox-D7Jqb75C.js +1 -0
  92. package/dist/gateway/static/root/assets/{notes-api-C_458rv5.js → notes-api-Bxa11X3a.js} +1 -1
  93. package/dist/gateway/static/root/assets/notes-page-D2QpJ3WZ.js +8 -0
  94. package/dist/gateway/static/root/assets/{oauth-api-C3X9FLYw.js → oauth-api-DIE4UpP7.js} +1 -1
  95. package/dist/gateway/static/root/assets/{oauth-provider-connect-H81se_3n.js → oauth-provider-connect-B95tiddN.js} +1 -1
  96. package/dist/gateway/static/root/assets/open-capability-settings-Cvb65hQB.js +1 -0
  97. package/dist/gateway/static/root/assets/{page-context-capture-button-BkAlQ7cB.js → page-context-capture-button-C-QbbwmN.js} +1 -1
  98. package/dist/gateway/static/root/assets/{page-context-draft-ClLgaOaD.js → page-context-draft-BHmOfksL.js} +1 -1
  99. package/dist/gateway/static/root/assets/page-header-store-bPV8_tKL.js +1 -0
  100. package/dist/gateway/static/root/assets/{personal-avatar-BLtHt8fV.js → personal-avatar-nXrmMfrV.js} +1 -1
  101. package/dist/gateway/static/root/assets/personal-page-BCwlYT3F.js +1 -0
  102. package/dist/gateway/static/root/assets/personal-settings-panel-vkYmXK8h.js +1 -0
  103. package/dist/gateway/static/root/assets/{phone-dependencies-card-DISHarj8.js → phone-dependencies-card-CZDAxTWv.js} +1 -1
  104. package/dist/gateway/static/root/assets/phone-model-picker-4Snfs8Hq.js +1 -0
  105. package/dist/gateway/static/root/assets/phone-settings-page-D8HperfA.js +1 -0
  106. package/dist/gateway/static/root/assets/{phone-workspace-store-fhnZrgy_.js → phone-workspace-store-Di9R9Ux5.js} +1 -1
  107. package/dist/gateway/static/root/assets/plugin-details-dialog-DJsDu-_8.js +1 -0
  108. package/dist/gateway/static/root/assets/popover-select-DD8fmrxH.js +1 -0
  109. package/dist/gateway/static/root/assets/preference-select-fields-C6abaM3k.js +1 -0
  110. package/dist/gateway/static/root/assets/product-automation-feedback-C74s9Mjz.js +7 -0
  111. package/dist/gateway/static/root/assets/product-delivery-DRyD9_Xq.js +1 -0
  112. package/dist/gateway/static/root/assets/{product-open-page-xn9G4hSI.js → product-open-page-AbDP5w1c.js} +1 -1
  113. package/dist/gateway/static/root/assets/product-preview-content-CktjvFbc.js +1 -0
  114. package/dist/gateway/static/root/assets/product-preview-modal-CzsqLwB4.js +2 -0
  115. package/dist/gateway/static/root/assets/project-detail-page-Cf3tggGP.js +7 -0
  116. package/dist/gateway/static/root/assets/project-understanding-jmhFbHch.js +1 -0
  117. package/dist/gateway/static/root/assets/projects-page-jMgZiFnO.js +1 -0
  118. package/dist/gateway/static/root/assets/{providers-api-CzVkFKFg.js → providers-api-CJBYFKAK.js} +1 -1
  119. package/dist/gateway/static/root/assets/{recording-upload-0jxahBMo.js → recording-upload-Dl9a5yOV.js} +1 -1
  120. package/dist/gateway/static/root/assets/{registry-api-n8TwtJ_j.js → registry-api-BwkbPUYu.js} +1 -1
  121. package/dist/gateway/static/root/assets/{remote-access-hub-cZpBi4Rk.js → remote-access-hub-CBQ_bOy9.js} +1 -1
  122. package/dist/gateway/static/root/assets/resource-unavailable-35wBZxmz.js +1 -0
  123. package/dist/gateway/static/root/assets/route-preload-BcA6SPeC.js +2 -0
  124. package/dist/gateway/static/root/assets/runtime-impact-DbySfhdp.js +1 -0
  125. package/dist/gateway/static/root/assets/{runtime-tools-api-D-8KjYK6.js → runtime-tools-api-BF28JDAO.js} +1 -1
  126. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-Bq2xQ2qd.js +1 -0
  127. package/dist/gateway/static/root/assets/schema-form-BKeP5G7b.js +1 -0
  128. package/dist/gateway/static/root/assets/service-recommendation-list-CdaS4MPF.js +1 -0
  129. package/dist/gateway/static/root/assets/{session-api-CsCoI2im.js → session-api-zJXYlRPt.js} +1 -1
  130. package/dist/gateway/static/root/assets/session-manager-wWxpzSo0.js +23 -0
  131. package/dist/gateway/static/root/assets/sessions-page-BkjD_dUD.js +1 -0
  132. package/dist/gateway/static/root/assets/settings-advanced-gate-BUMCEtA_.js +1 -0
  133. package/dist/gateway/static/root/assets/{settings-advanced-section-BqoVSko2.js → settings-advanced-section-C84IghdL.js} +1 -1
  134. package/dist/gateway/static/root/assets/{settings-mode-store-CBsJ-Qg2.js → settings-mode-store-CtQBJvbO.js} +1 -1
  135. package/dist/gateway/static/root/assets/{settings-page-DROUGyJl.js → settings-page-eEIz9InP.js} +1 -1
  136. package/dist/gateway/static/root/assets/{settings-page-header-Bv-kQFTm.js → settings-page-header-CsPAYlqV.js} +1 -1
  137. package/dist/gateway/static/root/assets/{settings-page-layout-DHP6MrrL.js → settings-page-layout-lPLeJQoV.js} +1 -1
  138. package/dist/gateway/static/root/assets/setup-status-panel-BSU5WpaE.js +1 -0
  139. package/dist/gateway/static/root/assets/{share-link-dialog-BJHRQVKC.js → share-link-dialog-NaM6jvIz.js} +1 -1
  140. package/dist/gateway/static/root/assets/share-preview-page-CHjZn27s.js +2 -0
  141. package/dist/gateway/static/root/assets/{shares-api-rtWVHA_d.js → shares-api-B9rVcV1y.js} +1 -1
  142. package/dist/gateway/static/root/assets/shares-settings-5sB15V5v.js +1 -0
  143. package/dist/gateway/static/root/assets/skill-api-D6zVfEuK.js +1 -0
  144. package/dist/gateway/static/root/assets/{skill-list-api-BzlKXPsE.js → skill-list-api-SLmTBYF5.js} +1 -1
  145. package/dist/gateway/static/root/assets/{skill-reload-api-Cff2GgZb.js → skill-reload-api-UQkq2orI.js} +1 -1
  146. package/dist/gateway/static/root/assets/skills-page-Ca0pYZ4i.js +2 -0
  147. package/dist/gateway/static/root/assets/{system-settings-panel-BeQeUUMH.js → system-settings-panel-BARWbjRN.js} +1 -1
  148. package/dist/gateway/static/root/assets/task-detail-page-roqAsGue.js +2 -0
  149. package/dist/gateway/static/root/assets/task-result-evidence-Bb1F7nAM.js +1 -0
  150. package/dist/gateway/static/root/assets/{terminal-panel-store-5Fzctajw.js → terminal-panel-store-DYDeXXAg.js} +1 -1
  151. package/dist/gateway/static/root/assets/{theme-store-DW45fWYQ.js → theme-store-DbStcH89.js} +1 -1
  152. package/dist/gateway/static/root/assets/tracing-settings-page-YfkNCxbP.js +1 -0
  153. package/dist/gateway/static/root/assets/tunnel-api-BK_ivyIb.js +1 -0
  154. package/dist/gateway/static/root/assets/{understanding-activity-store-CTe6TFB0.js → understanding-activity-store-p7Z7oq8z.js} +1 -1
  155. package/dist/gateway/static/root/assets/{understanding-refresh-store-mE9OKG6q.js → understanding-refresh-store-D-U6rcwZ.js} +1 -1
  156. package/dist/gateway/static/root/assets/usage-page-URFSiswS.js +1 -0
  157. package/dist/gateway/static/root/assets/{use-autosave-Cs2Ga_Y_.js → use-autosave-B7cbumro.js} +1 -1
  158. package/dist/gateway/static/root/assets/use-composer-attachments-DAtiwLsE.js +2 -0
  159. package/dist/gateway/static/root/assets/use-file-preview-expanded-B8erpWsX.js +2 -0
  160. package/dist/gateway/static/root/assets/{use-personal-profile-BHL2AxWU.js → use-personal-profile-DDW29nm-.js} +1 -1
  161. package/dist/gateway/static/root/assets/{use-workspace-tree-CnmPZrpx.js → use-workspace-tree-DCoTf22f.js} +1 -1
  162. package/dist/gateway/static/root/assets/user-model-page-DSV5NkNj.js +2 -0
  163. package/dist/gateway/static/root/assets/{voice-api-key-field-3gyc2UV3.js → voice-api-key-field-DzYdJZN4.js} +1 -1
  164. package/dist/gateway/static/root/assets/{voice-config-api-Cda2uBIC.js → voice-config-api-wotvT6Hw.js} +1 -1
  165. package/dist/gateway/static/root/assets/{voice-input-shortcut-events-DtYHsPLF.js → voice-input-shortcut-events-BI6PuiIB.js} +1 -1
  166. package/dist/gateway/static/root/assets/voice-transcribe-api-DAK9eLRr.js +1 -0
  167. package/dist/gateway/static/root/assets/{work-discovery-overlay-Dqu5CQCS.js → work-discovery-overlay-BzmB9Rub.js} +1 -1
  168. package/dist/gateway/static/root/assets/work-discovery-page-CmGjxUIT.js +1 -0
  169. package/dist/gateway/static/root/assets/{working-directory-picker-modal-DHl2cZY1.js → working-directory-picker-modal-B-EHm52-.js} +1 -1
  170. package/dist/gateway/static/root/assets/{workspace-api-CtDbI6T7.js → workspace-api-uhiEMPpK.js} +2 -2
  171. package/dist/gateway/static/root/assets/workspace-editor-agent-store-DrPVyikA.js +1 -0
  172. package/dist/gateway/static/root/assets/{workspace-file-preview-dialog-CTIbUfKb.js → workspace-file-preview-dialog-BDm06MZm.js} +1 -1
  173. package/dist/gateway/static/root/assets/{workspace-open-location-menu-BwxouqdZ.js → workspace-open-location-menu-Bv83uoqu.js} +1 -1
  174. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-CFb-23rS.js → xopc-cloud-account-card-Cd5GdpGL.js} +1 -1
  175. package/dist/gateway/static/root/index.html +91 -86
  176. package/dist/gateway/static/root/notification-sw.js +21 -7
  177. package/dist/package.js +1 -1
  178. package/dist/packages/endpoint-tools-protocol/src/context.js +115 -0
  179. package/dist/packages/endpoint-tools-protocol/src/index.js +4 -0
  180. package/dist/packages/endpoint-tools-protocol/src/location-sharing.js +51 -0
  181. package/dist/packages/gateway-contract/src/gateway-scopes.js +5 -1
  182. package/dist/packages/gateway-contract/src/index.js +4 -0
  183. package/dist/packages/gateway-contract/src/phone-workspace.js +6 -0
  184. package/dist/packages/gateway-contract/src/product-delivery.js +9 -3
  185. package/dist/packages/gateway-contract/src/task-display.js +14 -0
  186. package/dist/src/agent/agent-manager.js +1 -1
  187. package/dist/src/agent/background-review/run-background-review.js +1 -1
  188. package/dist/src/agent/context/execution-scope.js +10 -5
  189. package/dist/src/agent/embedded/external-tool-discovery.js +1 -1
  190. package/dist/src/agent/embedded/run-for-session.js +2 -2
  191. package/dist/src/agent/embedded/run-turn.js +72 -9
  192. package/dist/src/agent/embedded/session-runner.js +2 -1
  193. package/dist/src/agent/embedded/types.d.ts +1 -1
  194. package/dist/src/agent/external-tools/cliProvider.js +2 -2
  195. package/dist/src/agent/external-tools/composio-provider.js +2 -2
  196. package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
  197. package/dist/src/agent/prompt/system-prompt.js +1 -0
  198. package/dist/src/agent/service/direct-turn-helpers.d.ts +0 -7
  199. package/dist/src/agent/service/direct-turn-helpers.js +3 -2
  200. package/dist/src/agent/service/process-direct-streaming.js +2 -1
  201. package/dist/src/agent/service.js +1 -1
  202. package/dist/src/agent/skills/index.js +1 -1
  203. package/dist/src/agent/skills/managed-store.js +1 -1
  204. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  205. package/dist/src/agent/source-context/device-environment.d.ts +3 -0
  206. package/dist/src/agent/source-context/device-environment.js +38 -0
  207. package/dist/src/agent/source-context/injector.js +2 -1
  208. package/dist/src/agent/tool-manuals/phone.d.ts +1 -1
  209. package/dist/src/agent/tool-manuals/phone.js +1 -1
  210. package/dist/src/agent/tools/automation-tool.d.ts +2 -1
  211. package/dist/src/agent/tools/automation-tool.js +13 -5
  212. package/dist/src/agent/tools/factory.js +2 -1
  213. package/dist/src/agent/tools/personal-read-tool.js +2 -2
  214. package/dist/src/agent/tools/personal-task-tool.js +2 -1
  215. package/dist/src/agent/tools/phone-use-tool.js +46 -2
  216. package/dist/src/agent/tools/xopc-use-tool.js +8 -5
  217. package/dist/src/agent-catalog/capabilities.js +2 -2
  218. package/dist/src/agent-catalog/repository.js +1 -1
  219. package/dist/src/automations/api/routes.js +38 -0
  220. package/dist/src/automations/capabilities/drafts.js +1 -1
  221. package/dist/src/automations/capabilities/write.js +25 -9
  222. package/dist/src/automations/configuration-conversation.d.ts +16 -0
  223. package/dist/src/automations/configuration-conversation.js +120 -0
  224. package/dist/src/automations/delivery/delivery-router.d.ts +2 -0
  225. package/dist/src/automations/delivery/delivery-router.js +30 -9
  226. package/dist/src/automations/domain/types.d.ts +1 -0
  227. package/dist/src/automations/index.js +5 -5
  228. package/dist/src/automations/service/action-executor.js +41 -12
  229. package/dist/src/automations/service/automation-service.d.ts +6 -0
  230. package/dist/src/automations/service/automation-service.js +47 -12
  231. package/dist/src/automations/service/index.js +2 -2
  232. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  233. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  234. package/dist/src/capabilities/runtime/product.js +1 -1
  235. package/dist/src/cli/commands/agents.js +1 -1
  236. package/dist/src/cli/commands/models.js +1 -1
  237. package/dist/src/cli/commands/onboard/model.js +1 -1
  238. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  239. package/dist/src/computer/broker.js +16 -3
  240. package/dist/src/computer/diagnostics.js +1 -1
  241. package/dist/src/computer/errors.js +4 -0
  242. package/dist/src/computer/runtime.d.ts +1 -1
  243. package/dist/src/config/agent-profile.js +1 -1
  244. package/dist/src/config/schema.d.ts +1 -0
  245. package/dist/src/endpoint-tools/context-store.d.ts +29 -0
  246. package/dist/src/endpoint-tools/context-store.js +138 -0
  247. package/dist/src/endpoint-tools/location-sharing.d.ts +42 -0
  248. package/dist/src/endpoint-tools/location-sharing.js +203 -0
  249. package/dist/src/endpoint-tools/runtime.d.ts +4 -0
  250. package/dist/src/endpoint-tools/runtime.js +8 -0
  251. package/dist/src/endpoint-tools/turn-context.d.ts +2 -1
  252. package/dist/src/endpoint-tools/turn-context.js +4 -2
  253. package/dist/src/execution-environments/local-worktree-manager.js +1 -1
  254. package/dist/src/extensions/agent-plugins/skill-catalog.js +1 -1
  255. package/dist/src/extensions/agent-plugins/validation.js +1 -1
  256. package/dist/src/gateway/agents-admin.js +2 -2
  257. package/dist/src/gateway/automation-completion-delivery.d.ts +4 -0
  258. package/dist/src/gateway/automation-completion-delivery.js +14 -0
  259. package/dist/src/gateway/global-defaults-admin.js +1 -1
  260. package/dist/src/gateway/hono/middleware/auth.js +1 -1
  261. package/dist/src/gateway/hono/routes/agents.js +1 -1
  262. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  263. package/dist/src/gateway/hono/routes/devices.js +1 -0
  264. package/dist/src/gateway/hono/routes/endpoint-compatibility.js +4 -0
  265. package/dist/src/gateway/hono/routes/endpoint-environment.d.ts +3 -0
  266. package/dist/src/gateway/hono/routes/endpoint-environment.js +98 -0
  267. package/dist/src/gateway/hono/routes/endpoint-tools.js +1 -0
  268. package/dist/src/gateway/hono/routes/lazy-bundles.js +16 -0
  269. package/dist/src/gateway/hono/routes/location-sharing.d.ts +3 -0
  270. package/dist/src/gateway/hono/routes/location-sharing.js +164 -0
  271. package/dist/src/gateway/hono/routes/notes.js +2 -2
  272. package/dist/src/gateway/hono/routes/phone-setup.js +1 -1
  273. package/dist/src/gateway/hono/routes/phone.js +246 -34
  274. package/dist/src/gateway/hono/routes/projects.js +2 -2
  275. package/dist/src/gateway/hono/routes/session-command-handler.js +1 -1
  276. package/dist/src/gateway/hono/routes/session-input-handler.js +3 -2
  277. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  278. package/dist/src/gateway/hono/routes/tunnel.js +10 -0
  279. package/dist/src/gateway/image-generation-setup.js +1 -1
  280. package/dist/src/gateway/respawn.js +2 -1
  281. package/dist/src/gateway/security/gateway-scopes.js +6 -0
  282. package/dist/src/gateway/security/phone-access.d.ts +4 -0
  283. package/dist/src/gateway/security/phone-access.js +20 -0
  284. package/dist/src/gateway/service/agent-runner.js +3 -1
  285. package/dist/src/gateway/service/config-coordinator.d.ts +1 -0
  286. package/dist/src/gateway/service/run-gateway-agent.js +2 -1
  287. package/dist/src/gateway/service/session-input-coordinator.d.ts +3 -0
  288. package/dist/src/gateway/service/session-input-coordinator.js +50 -2
  289. package/dist/src/gateway/service.d.ts +1 -0
  290. package/dist/src/gateway/service.js +12 -4
  291. package/dist/src/gateway/session-reset-service.js +4 -0
  292. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  293. package/dist/src/imports/importService.js +1 -1
  294. package/dist/src/local-apps/service.js +1 -1
  295. package/dist/src/notifications/planner.js +6 -6
  296. package/dist/src/observability/store.d.ts +9 -0
  297. package/dist/src/observability/store.js +77 -32
  298. package/dist/src/personal-agent/communication.d.ts +1 -1
  299. package/dist/src/personal-agent/communication.js +3 -6
  300. package/dist/src/personal-agent/request-service.js +2 -1
  301. package/dist/src/personal-agent/service.js +1 -1
  302. package/dist/src/phone/assistance-service.d.ts +6 -0
  303. package/dist/src/phone/assistance-service.js +32 -0
  304. package/dist/src/phone/assistance.d.ts +40 -0
  305. package/dist/src/phone/assistance.js +273 -0
  306. package/dist/src/phone/cloud-phones.d.ts +5 -0
  307. package/dist/src/phone/cloud-phones.js +14 -0
  308. package/dist/src/phone/contracts.d.ts +7 -1
  309. package/dist/src/phone/contracts.js +5 -0
  310. package/dist/src/phone/environment-adapter.d.ts +3 -0
  311. package/dist/src/phone/environment-adapter.js +11 -0
  312. package/dist/src/phone/location-baseline-store.d.ts +9 -0
  313. package/dist/src/phone/location-baseline-store.js +61 -0
  314. package/dist/src/phone/location-environment.d.ts +61 -0
  315. package/dist/src/phone/location-environment.js +157 -0
  316. package/dist/src/phone/model-adapter.js +16 -5
  317. package/dist/src/phone/runtime.d.ts +17 -2
  318. package/dist/src/phone/runtime.js +203 -20
  319. package/dist/src/phone/stream-gateway.d.ts +5 -0
  320. package/dist/src/phone/stream-gateway.js +85 -51
  321. package/dist/src/phone/wuying-location.d.ts +18 -0
  322. package/dist/src/phone/wuying-location.js +86 -0
  323. package/dist/src/runtime-tools/archive.js +1 -1
  324. package/dist/src/storage/sqlite/device-access-repository.d.ts +4 -0
  325. package/dist/src/storage/sqlite/device-access-repository.js +18 -1
  326. package/dist/src/tasks/capabilities/read.js +2 -2
  327. package/dist/src/tasks/capabilities/write.js +1 -1
  328. package/dist/src/tasks/task-contract-planner.js +2 -1
  329. package/dist/src/tui/backends/embedded-backend.js +1 -1
  330. package/dist/src/tunnel/broker-client.d.ts +8 -0
  331. package/dist/src/tunnel/broker-client.js +18 -1
  332. package/dist/src/voice/realtime/persona-context.js +1 -1
  333. package/dist/src/voice/realtime/runtime.js +1 -1
  334. package/package.json +4 -3
  335. package/dist/gateway/static/root/assets/agent-avatar-display-Cy50vjbq.js +0 -2
  336. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-V4NX_cWz.js +0 -1
  337. package/dist/gateway/static/root/assets/agent-plugin-dialog-CQ5LLDMO.js +0 -1
  338. package/dist/gateway/static/root/assets/app-link-CytZ5zkp.js +0 -1
  339. package/dist/gateway/static/root/assets/app-management-settings-panel-C1Zs-eha.js +0 -1
  340. package/dist/gateway/static/root/assets/appearance-settings-lIfGokbz.js +0 -1
  341. package/dist/gateway/static/root/assets/apps-page-CUvtsRYD.js +0 -1
  342. package/dist/gateway/static/root/assets/automation-api-Bld8blNl.js +0 -1
  343. package/dist/gateway/static/root/assets/automation-display-BcfZOQTC.js +0 -2
  344. package/dist/gateway/static/root/assets/automations-workspace-BgtYY2Mm.js +0 -8
  345. package/dist/gateway/static/root/assets/browser-automations-page-DIUNY94X.js +0 -3
  346. package/dist/gateway/static/root/assets/capabilities-page-DFW4Y0x8.js +0 -2
  347. package/dist/gateway/static/root/assets/capabilities-settings-panel-uOHSMQPZ.js +0 -8
  348. package/dist/gateway/static/root/assets/channels-D2a69dSt.js +0 -1
  349. package/dist/gateway/static/root/assets/chat-page-CG38tCHE.js +0 -71
  350. package/dist/gateway/static/root/assets/composer-payload-handoff-BU3B-C26.js +0 -1
  351. package/dist/gateway/static/root/assets/connected-providers-grid-Dmnu2zle.js +0 -1
  352. package/dist/gateway/static/root/assets/connectors-page-DT_WrC1y.js +0 -1
  353. package/dist/gateway/static/root/assets/date-picker-CE-cZFCU.js +0 -1
  354. package/dist/gateway/static/root/assets/desktop-pet-lorocS9j.js +0 -1
  355. package/dist/gateway/static/root/assets/desktop-pet-settings-CEcohlZq.js +0 -1
  356. package/dist/gateway/static/root/assets/device-pairing-wizard-CLCPuf4R.js +0 -1
  357. package/dist/gateway/static/root/assets/discussion-annotation-sync-BKjf9gWe.js +0 -1
  358. package/dist/gateway/static/root/assets/extension-iframe-host-Dhkk5JV2.js +0 -1
  359. package/dist/gateway/static/root/assets/extension-page-Brps2XDP.js +0 -1
  360. package/dist/gateway/static/root/assets/extension-settings-page-CHY68DpG.js +0 -1
  361. package/dist/gateway/static/root/assets/gateway-realtime-store-DQqMBruB.js +0 -1
  362. package/dist/gateway/static/root/assets/gateway-restart-Ch128Lrr.js +0 -1
  363. package/dist/gateway/static/root/assets/home-page-DaMFBYo1.js +0 -2
  364. package/dist/gateway/static/root/assets/image-generation-api-I_JgLL_m.js +0 -1
  365. package/dist/gateway/static/root/assets/index-DY2Y83b9.css +0 -1
  366. package/dist/gateway/static/root/assets/index-UCOlAnf-.js +0 -11
  367. package/dist/gateway/static/root/assets/install-connector-dialog-DU1Tz7B3.js +0 -1
  368. package/dist/gateway/static/root/assets/local-app-workbench-page-qPflPuQD.js +0 -1
  369. package/dist/gateway/static/root/assets/logs-page-CbY1N-zi.js +0 -2
  370. package/dist/gateway/static/root/assets/management-settings-Diy12JfQ.js +0 -1
  371. package/dist/gateway/static/root/assets/messages-DRR9N3HC.js +0 -3
  372. package/dist/gateway/static/root/assets/model-selector-DCYA_ntf.js +0 -1
  373. package/dist/gateway/static/root/assets/navigation-BkjnOw30.js +0 -1
  374. package/dist/gateway/static/root/assets/note-detail-panel-DBs1yHLy.js +0 -5
  375. package/dist/gateway/static/root/assets/note-image-lightbox-CivkB6LB.js +0 -1
  376. package/dist/gateway/static/root/assets/notes-page-DL3c-41a.js +0 -8
  377. package/dist/gateway/static/root/assets/page-header-store-DH8K0xii.js +0 -1
  378. package/dist/gateway/static/root/assets/personal-page-B5DP3lO-.js +0 -1
  379. package/dist/gateway/static/root/assets/personal-settings-panel-DjDc5Kaz.js +0 -1
  380. package/dist/gateway/static/root/assets/phone-model-picker-u8YIQCgo.js +0 -1
  381. package/dist/gateway/static/root/assets/phone-settings-page-el3pT0PD.js +0 -1
  382. package/dist/gateway/static/root/assets/plugin-details-dialog-CTBs1Jde.js +0 -1
  383. package/dist/gateway/static/root/assets/popover-select-DniHw2dy.js +0 -1
  384. package/dist/gateway/static/root/assets/preference-select-fields-D7oluyHN.js +0 -1
  385. package/dist/gateway/static/root/assets/product-automation-feedback-DsUSqCOX.js +0 -7
  386. package/dist/gateway/static/root/assets/product-delivery-BU_H84jL.js +0 -1
  387. package/dist/gateway/static/root/assets/product-preview-content-DcoK-iZe.js +0 -1
  388. package/dist/gateway/static/root/assets/product-preview-modal-Ruw9WSKK.js +0 -2
  389. package/dist/gateway/static/root/assets/project-detail-page-BKvWLiMw.js +0 -7
  390. package/dist/gateway/static/root/assets/project-understanding-BCQr0AZ_.js +0 -1
  391. package/dist/gateway/static/root/assets/projects-page-D4g7bB7X.js +0 -1
  392. package/dist/gateway/static/root/assets/route-preload-B5UiReO7.js +0 -2
  393. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-MKlLFuow.js +0 -1
  394. package/dist/gateway/static/root/assets/schema-form-v4N4lawq.js +0 -1
  395. package/dist/gateway/static/root/assets/service-recommendation-list-B1xuVT3N.js +0 -1
  396. package/dist/gateway/static/root/assets/session-manager-5l9q0cd5.js +0 -16
  397. package/dist/gateway/static/root/assets/sessions-page-DsLw2aMD.js +0 -1
  398. package/dist/gateway/static/root/assets/settings-advanced-gate-B5lQeVNi.js +0 -1
  399. package/dist/gateway/static/root/assets/setup-status-panel-MJE3B_LX.js +0 -1
  400. package/dist/gateway/static/root/assets/share-preview-page-Bsrv_zOQ.js +0 -2
  401. package/dist/gateway/static/root/assets/shares-settings-CfIRv4uX.js +0 -1
  402. package/dist/gateway/static/root/assets/skill-api-B_W1K3sv.js +0 -1
  403. package/dist/gateway/static/root/assets/skills-page-DtBloYeU.js +0 -2
  404. package/dist/gateway/static/root/assets/task-detail-page-Drrv-Hp0.js +0 -2
  405. package/dist/gateway/static/root/assets/task-result-evidence-D1Kyskm_.js +0 -1
  406. package/dist/gateway/static/root/assets/tracing-settings-page-B12u5D9A.js +0 -1
  407. package/dist/gateway/static/root/assets/tunnel-api-DGO56LQU.js +0 -1
  408. package/dist/gateway/static/root/assets/usage-page-Ud2U9UG1.js +0 -1
  409. package/dist/gateway/static/root/assets/use-composer-attachments-BCbMj-MN.js +0 -2
  410. package/dist/gateway/static/root/assets/use-file-preview-expanded-DSpCRXUW.js +0 -2
  411. package/dist/gateway/static/root/assets/user-model-page-p5iPfnwl.js +0 -2
  412. package/dist/gateway/static/root/assets/voice-transcribe-api-TInEfIYo.js +0 -1
  413. package/dist/gateway/static/root/assets/work-discovery-page-p-8ciZ0i.js +0 -1
  414. 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 (principal.kind !== "owner" && principal.kind !== "trusted-proxy" || !principal.scopes.includes("gateway.admin")) return c.json({
55
- ok: false,
56
- error: {
57
- code: "PHONE_ADMIN_REQUIRED",
58
- message: "Phone settings require Gateway administrator access"
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
- }, 403);
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(runtime.reports().filter((report) => report.status !== "closed").map(async (report) => {
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 = runtime.reports().find((report) => report.deviceId === deviceId && report.status !== "closed");
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 report = runtime.status(conversationId);
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" : ""}`) : null
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: runtime.liveStatus(owner, c.req.param("sessionId"), context, `${getGatewayPrincipal(c).principalId}:${input.clientId}`)
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({ clientId: liveClient }).strict().parse(await c.req.json());
425
- await conversationPhone(address, id);
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}${c.req.param("conversationId").startsWith("device:") ? ":viewer" : ""}`;
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
- runtime.liveStatus(resolved.owner, id, resolved.context, client);
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
- const resolved = await conversationPhone(address, id).catch(() => void 0);
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 { context, transcriptId, owner: resolvedOwner } = await conversationPhone(owner, id);
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
- const { clientId, ...input } = liveControlInput.parse(await c.req.json());
463
- const result = await runtime.liveControl(owner, id, context, `${getGatewayPrincipal(c).principalId}:${clientId}`, input);
464
- if (transcriptId && input.op === "handback" && result.resumeTurnRequired && !service.sessions.getActiveRun(owner).active) {
465
- if (!(await service.submitSessionInput({
466
- conversationId: owner,
467
- expectedTranscriptId: transcriptId,
468
- clientMessageId: input.operationId,
469
- delivery: "next",
470
- content: "手机已交还,请先确认当前页面,继续未完成的任务;已完成的步骤不要重复,结束后释放操作权,保持手机连接。",
471
- origin: {
472
- type: "system",
473
- source: "internal"
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
- })).ok) throw new PhoneError("PHONE_RESUME_FAILED", "Phone control returned. Send Continue in chat to resume the task.", 409);
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 sourceContexts = [deviceTurnSourceContext(deps.service.endpointTools.registry.get(origin.data.endpointId), environment.data), ...browserContexts.data.map(browserPageContextToAgentContext)];
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;