@xopcai/xopc 0.0.433 → 0.0.434

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 (403) hide show
  1. package/README.md +5 -5
  2. package/README.zh-CN.md +5 -5
  3. package/dist/browser-ext/dist/sidepanel.js +11 -0
  4. package/dist/browser-ext/manifest.json +1 -1
  5. package/dist/extensions/telegram/xopc.extension.json +1 -1
  6. package/dist/gateway/static/root/assets/{activity-store-BpYGrRXw.js → activity-store-Cwn_CNwl.js} +1 -1
  7. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DTgOSv6G.js → agent-avatar-dicebear-Cd23LnJJ.js} +1 -1
  8. package/dist/gateway/static/root/assets/{agent-avatar-display-BUH7ljEo.js → agent-avatar-display-ByzM7u9S.js} +2 -2
  9. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-B_FAikHA.js → agent-defaults-settings-panel-B0i37diS.js} +1 -1
  10. package/dist/gateway/static/root/assets/{agent-plugin-dialog-DPabZaSE.js → agent-plugin-dialog-XN-tZ-Ox.js} +1 -1
  11. package/dist/gateway/static/root/assets/{agents-BAPYP1Ka.js → agents-ZDA1OaLv.js} +3 -3
  12. package/dist/gateway/static/root/assets/{agents-admin-api-CXCAHNPj.js → agents-admin-api-B5lKH_ps.js} +1 -1
  13. package/dist/gateway/static/root/assets/{api-oIK4hYkJ.js → api-B9fZL-V8.js} +1 -1
  14. package/dist/gateway/static/root/assets/{api-DMbimMEi.js → api-Djju8qIR.js} +1 -1
  15. package/dist/gateway/static/root/assets/{app-management-settings-panel-BZ3Fy8ZR.js → app-management-settings-panel-IlyzDPJu.js} +1 -1
  16. package/dist/gateway/static/root/assets/{appearance-settings-DsRTj1by.js → appearance-settings-BxdFGob3.js} +1 -1
  17. package/dist/gateway/static/root/assets/apps-page-CxEKiOTA.js +1 -0
  18. package/dist/gateway/static/root/assets/{archive-plugin-Bg1VTieK.js → archive-plugin-4gEvotPr.js} +1 -1
  19. package/dist/gateway/static/root/assets/{automation-api-CLPsgcQN.js → automation-api-4fVKv9PJ.js} +1 -1
  20. package/dist/gateway/static/root/assets/{automation-result-state-CKVnR4KG.js → automation-result-state-m7PeK2kl.js} +1 -1
  21. package/dist/gateway/static/root/assets/automation-run-list-CJOdy_R2.js +1 -0
  22. package/dist/gateway/static/root/assets/{automation-task-card-D27Mw66U.js → automation-task-card-DZWhCWJa.js} +3 -3
  23. package/dist/gateway/static/root/assets/{automations-page-DGNTJ8lN.js → automations-page-CmxICTM4.js} +1 -1
  24. package/dist/gateway/static/root/assets/automations-workspace-R6YNDdAO.js +9 -0
  25. package/dist/gateway/static/root/assets/{binary-plugins-CuwSdCG5.js → binary-plugins-69WyJLNW.js} +1 -1
  26. package/dist/gateway/static/root/assets/{block-editor-Dtl2BG3t.js → block-editor-DUONDIZR.js} +1 -1
  27. package/dist/gateway/static/root/assets/{browser-automation-inputs-uGK086ag.js → browser-automation-inputs-DL4YPCuN.js} +1 -1
  28. package/dist/gateway/static/root/assets/{browser-automations-page-Da_edNNS.js → browser-automations-page-1Aq6XmRs.js} +1 -1
  29. package/dist/gateway/static/root/assets/{browser-control-api-k3OOX3bS.js → browser-control-api-yjru8E7R.js} +1 -1
  30. package/dist/gateway/static/root/assets/{browser-settings-page-C1bSw-Jq.js → browser-settings-page-CvwpT8Um.js} +1 -1
  31. package/dist/gateway/static/root/assets/{capabilities-DlHPLld_.js → capabilities-C7lnwKKm.js} +1 -1
  32. package/dist/gateway/static/root/assets/{capabilities-CoeuLRt6.js → capabilities-DaeQXJT4.js} +1 -1
  33. package/dist/gateway/static/root/assets/capabilities-page-B5avAOUM.js +2 -0
  34. package/dist/gateway/static/root/assets/{capabilities-settings-panel-CtY-bGIi.js → capabilities-settings-panel-_9yCS78i.js} +1 -1
  35. package/dist/gateway/static/root/assets/capability-links-DeO34GIF.js +1 -0
  36. package/dist/gateway/static/root/assets/{channels-Cn1MWBL_.js → channels-CoQb4HOF.js} +1 -1
  37. package/dist/gateway/static/root/assets/{chat-agents-api-BB0biwc7.js → chat-agents-api-BUi_7GRo.js} +1 -1
  38. package/dist/gateway/static/root/assets/{chat-chart-block-QSvjx4w6.js → chat-chart-block-CcVcKsDZ.js} +1 -1
  39. package/dist/gateway/static/root/assets/chat-page-BJ8PlDjZ.js +72 -0
  40. package/dist/gateway/static/root/assets/{chat-terminal-dock-Cd51G9eG.js → chat-terminal-dock-BMXJpPuH.js} +1 -1
  41. package/dist/gateway/static/root/assets/{command-palette-api-CEG10uE-.js → command-palette-api-luUjQPsh.js} +1 -1
  42. package/dist/gateway/static/root/assets/{composer-payload-handoff-Bogdq9Hy.js → composer-payload-handoff-B5XNxNCb.js} +1 -1
  43. package/dist/gateway/static/root/assets/computer-settings-page-CWtdyEJH.js +1 -0
  44. package/dist/gateway/static/root/assets/connected-providers-grid-2idMtk65.js +1 -0
  45. package/dist/gateway/static/root/assets/connection-usage-Cm_McddI.js +1 -0
  46. package/dist/gateway/static/root/assets/connection-usage-guide-Ddh0bfkj.js +1 -0
  47. package/dist/gateway/static/root/assets/{connector-service-page-k2rjyjrp.js → connector-service-page-C3msXaBk.js} +1 -1
  48. package/dist/gateway/static/root/assets/{connectors-api-DtvB9Cjm.js → connectors-api-NcWECWKg.js} +1 -1
  49. package/dist/gateway/static/root/assets/connectors-page-Crb6DILX.js +1 -0
  50. package/dist/gateway/static/root/assets/{date-picker-CAankdQw.js → date-picker-Cfjq1hD_.js} +1 -1
  51. package/dist/gateway/static/root/assets/{desktop-pet-DjM73fir.js → desktop-pet-ChFn9v-3.js} +1 -1
  52. package/dist/gateway/static/root/assets/{desktop-pet-settings-Rmh-GxHl.js → desktop-pet-settings-DvnVIv25.js} +1 -1
  53. package/dist/gateway/static/root/assets/{dev-view-store-BgW2Riyk.js → dev-view-store-DQJ61P5L.js} +1 -1
  54. package/dist/gateway/static/root/assets/{device-pairing-wizard-UdzSpNa5.js → device-pairing-wizard-KxaIL-OX.js} +1 -1
  55. package/dist/gateway/static/root/assets/{directory-picker-path-field-Rkw3f7lG.js → directory-picker-path-field-Drv864uE.js} +1 -1
  56. package/dist/gateway/static/root/assets/{discussion-annotation-sync-Dudoj_Fz.js → discussion-annotation-sync-DfBRkWtw.js} +1 -1
  57. package/dist/gateway/static/root/assets/{extension-debug-page-DxIGAO23.js → extension-debug-page-DAlBIt_R.js} +1 -1
  58. package/dist/gateway/static/root/assets/{extension-iframe-host-63KpX6IP.js → extension-iframe-host-Bds-5kY_.js} +1 -1
  59. package/dist/gateway/static/root/assets/{extension-marketplace-api-yXNUkQDA.js → extension-marketplace-api-CZg8nBwW.js} +1 -1
  60. package/dist/gateway/static/root/assets/{extension-page-C811A_Ww.js → extension-page-ZTw-oucT.js} +1 -1
  61. package/dist/gateway/static/root/assets/{extension-provider-C4jLFIgh.js → extension-provider-NKWfjpdP.js} +1 -1
  62. package/dist/gateway/static/root/assets/{extension-settings-page-WJSw5MT0.js → extension-settings-page-CT7PPt_q.js} +1 -1
  63. package/dist/gateway/static/root/assets/{file-preview-surface-zE9AcaHM.js → file-preview-surface-BcLeaSNe.js} +1 -1
  64. package/dist/gateway/static/root/assets/{gateway-config-swr-D6cc6W6E.js → gateway-config-swr-Cq-ByXL4.js} +1 -1
  65. package/dist/gateway/static/root/assets/{gateway-realtime-BSRNLciy.js → gateway-realtime-DwMd2PCt.js} +1 -1
  66. package/dist/gateway/static/root/assets/gateway-realtime-store-CHrf6-nR.js +1 -0
  67. package/dist/gateway/static/root/assets/{gateway-restart-Unun5hRL.js → gateway-restart-DdiVzbkL.js} +1 -1
  68. package/dist/gateway/static/root/assets/{gateway-settings-DP-DV-e5.js → gateway-settings-1QUdNwrZ.js} +1 -1
  69. package/dist/gateway/static/root/assets/{gateway-startup-retry-C8g666Ja.js → gateway-startup-retry-PMJi5mX4.js} +1 -1
  70. package/dist/gateway/static/root/assets/{global-defaults-api-BObi-1ww.js → global-defaults-api-DgzZh3wX.js} +1 -1
  71. package/dist/gateway/static/root/assets/{home-page-CIcs7Mzy.js → home-page-Chn7YTiD.js} +2 -2
  72. package/dist/gateway/static/root/assets/{image-generation-api-C2SqYNyD.js → image-generation-api-CjVpsckq.js} +1 -1
  73. package/dist/gateway/static/root/assets/{imports-page-C8ezUkOJ.js → imports-page-CJCvZFaQ.js} +1 -1
  74. package/dist/gateway/static/root/assets/index-DWQ4LbBn.js +11 -0
  75. package/dist/gateway/static/root/assets/index-iukJWzxG.css +1 -0
  76. package/dist/gateway/static/root/assets/install-connector-dialog-Bo06Ry3H.js +1 -0
  77. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BRaY4-wA.js → keyboard-shortcuts-settings-BylFJeGu.js} +1 -1
  78. package/dist/gateway/static/root/assets/{local-app-workbench-page-BZtVcjF3.js → local-app-workbench-page-B3MSSFsr.js} +1 -1
  79. package/dist/gateway/static/root/assets/{local-apps-page-MqP4EnJm.js → local-apps-page-BeV86rMJ.js} +1 -1
  80. package/dist/gateway/static/root/assets/{local-session-drafts-DTq9776a.js → local-session-drafts-jgw8UGsO.js} +2 -2
  81. package/dist/gateway/static/root/assets/{locale-store-B6OrWgY1.js → locale-store-CAZaC05J.js} +1 -1
  82. package/dist/gateway/static/root/assets/{logs-page-hkHBjblX.js → logs-page-BMmSsUP5.js} +1 -1
  83. package/dist/gateway/static/root/assets/{management-settings-DoX4eTM3.js → management-settings-Bu7T8ewk.js} +1 -1
  84. package/dist/gateway/static/root/assets/{markdown-view-DrhYZSmg.js → markdown-view-BatP4qeK.js} +1 -1
  85. package/dist/gateway/static/root/assets/{mcp-conversation-setup-page-BEp5E6TD.js → mcp-conversation-setup-page-rROtr0UN.js} +1 -1
  86. package/dist/gateway/static/root/assets/{media-plugins-D987i9Gc.js → media-plugins-88OV72YE.js} +1 -1
  87. package/dist/gateway/static/root/assets/messages-C7fckbyG.js +3 -0
  88. package/dist/gateway/static/root/assets/{model-selector-DXm4NS1_.js → model-selector-raBRBkN_.js} +1 -1
  89. package/dist/gateway/static/root/assets/{models-hub-cache-BLcha5rx.js → models-hub-cache-CzC9y3D0.js} +1 -1
  90. package/dist/gateway/static/root/assets/{note-detail-panel-Cl851ivY.js → note-detail-panel-BvA8Vkbm.js} +3 -3
  91. package/dist/gateway/static/root/assets/note-image-lightbox-D6kUDDd5.js +1 -0
  92. package/dist/gateway/static/root/assets/{notes-api-Ddsf7FVg.js → notes-api-zXpV6UXu.js} +1 -1
  93. package/dist/gateway/static/root/assets/{notes-page-DSwA1MU1.js → notes-page-CjYH9Kle.js} +1 -1
  94. package/dist/gateway/static/root/assets/{oauth-api-CMmu4DzH.js → oauth-api-DmxSaxM1.js} +1 -1
  95. package/dist/gateway/static/root/assets/{oauth-provider-connect-BkhnftBq.js → oauth-provider-connect-D4Gfs-Ba.js} +1 -1
  96. package/dist/gateway/static/root/assets/{page-context-capture-button-urhQBRaN.js → page-context-capture-button-Mig3d0UX.js} +1 -1
  97. package/dist/gateway/static/root/assets/{page-context-draft-BuNUerth.js → page-context-draft-C4IIZaKd.js} +1 -1
  98. package/dist/gateway/static/root/assets/page-header-store-D7G5utVi.js +1 -0
  99. package/dist/gateway/static/root/assets/{personal-avatar-B49ueeZO.js → personal-avatar-DLa-CpaK.js} +1 -1
  100. package/dist/gateway/static/root/assets/{personal-page-f05ceuFn.js → personal-page-l9_vYfdJ.js} +1 -1
  101. package/dist/gateway/static/root/assets/{personal-settings-panel-DLQxzPYr.js → personal-settings-panel-XSUkgcr2.js} +1 -1
  102. package/dist/gateway/static/root/assets/phone-dependencies-card-DYwnuVh3.js +1 -0
  103. package/dist/gateway/static/root/assets/phone-model-connection-2F32QTHA.js +1 -0
  104. package/dist/gateway/static/root/assets/phone-model-picker-DCVzIr0s.js +1 -0
  105. package/dist/gateway/static/root/assets/phone-settings-page-DJttE4id.js +1 -0
  106. package/dist/gateway/static/root/assets/{phone-workspace-store-DbqktZbO.js → phone-workspace-store-Dxp-KhFP.js} +1 -1
  107. package/dist/gateway/static/root/assets/plugin-details-dialog-tyjAjFjA.js +1 -0
  108. package/dist/gateway/static/root/assets/{preference-select-fields-BZWqG7pu.js → preference-select-fields-BVP3MhGK.js} +1 -1
  109. package/dist/gateway/static/root/assets/{product-automation-feedback-DDQUsag7.js → product-automation-feedback-DbJvv92z.js} +1 -1
  110. package/dist/gateway/static/root/assets/{product-open-page-BkRP_HmA.js → product-open-page-RImqlhCD.js} +1 -1
  111. package/dist/gateway/static/root/assets/{product-preview-content-o2Y3VNE7.js → product-preview-content-DxSqrKsg.js} +1 -1
  112. package/dist/gateway/static/root/assets/{product-preview-modal-7Ohx-7OR.js → product-preview-modal-Cw8Q8Uom.js} +2 -2
  113. package/dist/gateway/static/root/assets/{project-detail-page-B2RsSHya.js → project-detail-page-BbyV8EiG.js} +1 -1
  114. package/dist/gateway/static/root/assets/{project-understanding-BIMouiYX.js → project-understanding-BMKcoUW5.js} +1 -1
  115. package/dist/gateway/static/root/assets/{projects-page-C9R5u3tF.js → projects-page-CFsABLvs.js} +1 -1
  116. package/dist/gateway/static/root/assets/{providers-api-BOCkRZ7X.js → providers-api-CAeXbJNF.js} +1 -1
  117. package/dist/gateway/static/root/assets/{recording-upload-C6muEHEO.js → recording-upload-CfpllTe5.js} +1 -1
  118. package/dist/gateway/static/root/assets/{registry-api-Bl2guMRg.js → registry-api-fLOqFyrz.js} +1 -1
  119. package/dist/gateway/static/root/assets/{remote-access-hub-BceSMbCs.js → remote-access-hub-BvKOxy0L.js} +1 -1
  120. package/dist/gateway/static/root/assets/{resource-unavailable-CUNbPkdj.js → resource-unavailable-D15jzjV_.js} +1 -1
  121. package/dist/gateway/static/root/assets/route-preload-BWpw9qxc.js +2 -0
  122. package/dist/gateway/static/root/assets/{runtime-tools-api-LopLjgvu.js → runtime-tools-api-D0Nrvuqv.js} +1 -1
  123. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-9HIPerDP.js → runtime-tools-settings-panel-CA27XgL2.js} +1 -1
  124. package/dist/gateway/static/root/assets/{service-recommendation-list-CoMI6MB1.js → service-recommendation-list-B0RoYLVT.js} +1 -1
  125. package/dist/gateway/static/root/assets/session-api-CHRP5Lwf.js +1 -0
  126. package/dist/gateway/static/root/assets/session-channel-icon-D1ktvt1P.js +1 -0
  127. package/dist/gateway/static/root/assets/session-identity-label-BP7OIYth.js +1 -0
  128. package/dist/gateway/static/root/assets/session-manager-DRRWwKE4.js +25 -0
  129. package/dist/gateway/static/root/assets/{sessions-page-BT0GdXdS.js → sessions-page-uJHS3-6F.js} +1 -1
  130. package/dist/gateway/static/root/assets/settings-advanced-gate-CZ4J3Kuy.js +1 -0
  131. package/dist/gateway/static/root/assets/{settings-advanced-section-CEorDLUp.js → settings-advanced-section-D-llwfSj.js} +1 -1
  132. package/dist/gateway/static/root/assets/{settings-mode-store-C2LZqBES.js → settings-mode-store-BspMKc9N.js} +1 -1
  133. package/dist/gateway/static/root/assets/{settings-page-C_Np_6qZ.js → settings-page-XJXcnE1_.js} +1 -1
  134. package/dist/gateway/static/root/assets/{settings-page-header-BAN34UQi.js → settings-page-header-LuOJvqNa.js} +1 -1
  135. package/dist/gateway/static/root/assets/{settings-page-layout-B5TVFBV2.js → settings-page-layout-CduQ8w4a.js} +1 -1
  136. package/dist/gateway/static/root/assets/{setup-interaction-page-BYvTJW3_.js → setup-interaction-page-ujpPGl84.js} +1 -1
  137. package/dist/gateway/static/root/assets/{setup-status-panel-UY2dH-sK.js → setup-status-panel-BN2aCJUN.js} +1 -1
  138. package/dist/gateway/static/root/assets/{share-link-dialog-BMcXyzr2.js → share-link-dialog-CTATUaa4.js} +1 -1
  139. package/dist/gateway/static/root/assets/{share-preview-page-UQ6eUM2_.js → share-preview-page-Dq0J3VgS.js} +1 -1
  140. package/dist/gateway/static/root/assets/{shares-api-DOeDN6Tm.js → shares-api-zegE8pSE.js} +1 -1
  141. package/dist/gateway/static/root/assets/{shares-settings-W8XhuAoL.js → shares-settings-DXpvsRXq.js} +1 -1
  142. package/dist/gateway/static/root/assets/{skill-api-Do_c0d9n.js → skill-api-DCL1EN7f.js} +1 -1
  143. package/dist/gateway/static/root/assets/{skill-list-api-DpHaXI2l.js → skill-list-api-Bv0mmHbu.js} +1 -1
  144. package/dist/gateway/static/root/assets/{skill-reload-api-DDRd9IJ2.js → skill-reload-api-DPZbadiO.js} +1 -1
  145. package/dist/gateway/static/root/assets/{skills-page-CaeJVKhO.js → skills-page-DMC7Gaku.js} +1 -1
  146. package/dist/gateway/static/root/assets/{system-settings-panel-DYWlWPJL.js → system-settings-panel-BYFUhlqG.js} +1 -1
  147. package/dist/gateway/static/root/assets/{task-detail-page-De0qD7xw.js → task-detail-page-DvX9JoEd.js} +3 -3
  148. package/dist/gateway/static/root/assets/{task-result-evidence-CICR5K1t.js → task-result-evidence-Bxm8-H0B.js} +1 -1
  149. package/dist/gateway/static/root/assets/{terminal-panel-store-BbWUcQe7.js → terminal-panel-store-Djf9l2qZ.js} +1 -1
  150. package/dist/gateway/static/root/assets/{theme-store-TkG5mo0p.js → theme-store-8GFVtotZ.js} +1 -1
  151. package/dist/gateway/static/root/assets/{tracing-settings-page-CYXEy4EG.js → tracing-settings-page-oWW3SBZ4.js} +1 -1
  152. package/dist/gateway/static/root/assets/{tunnel-api-DquDm6U2.js → tunnel-api-D-mEsSGF.js} +1 -1
  153. package/dist/gateway/static/root/assets/{understanding-activity-store-Ot3wZ3oQ.js → understanding-activity-store-CvDjsd0I.js} +1 -1
  154. package/dist/gateway/static/root/assets/{understanding-refresh-store-C5KYFMaC.js → understanding-refresh-store-DzOZJm7A.js} +1 -1
  155. package/dist/gateway/static/root/assets/{usage-page-1xFO4smo.js → usage-page-z-o6Uuev.js} +1 -1
  156. package/dist/gateway/static/root/assets/{use-autosave-HL8XRNR8.js → use-autosave-BVYS8UoK.js} +1 -1
  157. package/dist/gateway/static/root/assets/{use-composer-attachments-XRlQBdNF.js → use-composer-attachments-lecOV2q5.js} +1 -1
  158. package/dist/gateway/static/root/assets/{use-file-preview-expanded-CW956CXS.js → use-file-preview-expanded-nd_CuFsd.js} +2 -2
  159. package/dist/gateway/static/root/assets/{use-personal-profile-202s6tJt.js → use-personal-profile-CQi2ZCxV.js} +1 -1
  160. package/dist/gateway/static/root/assets/{use-workspace-tree-CjydkmH1.js → use-workspace-tree-BiaddkzX.js} +1 -1
  161. package/dist/gateway/static/root/assets/{user-model-page-OGPXx3pe.js → user-model-page-Bks1n0Nj.js} +1 -1
  162. package/dist/gateway/static/root/assets/{voice-api-key-field-CxFu4MEA.js → voice-api-key-field-BbW8NFeZ.js} +1 -1
  163. package/dist/gateway/static/root/assets/{voice-config-api-MHe5Pn-A.js → voice-config-api-jSMzZWWy.js} +1 -1
  164. package/dist/gateway/static/root/assets/{voice-input-shortcut-events-B9xc1oK8.js → voice-input-shortcut-events-_SgYmx7X.js} +1 -1
  165. package/dist/gateway/static/root/assets/{voice-transcribe-api-CVEcB6Pe.js → voice-transcribe-api-BJCfiRFU.js} +1 -1
  166. package/dist/gateway/static/root/assets/{work-discovery-overlay-C-JoAg2D.js → work-discovery-overlay-DSTSNyU7.js} +1 -1
  167. package/dist/gateway/static/root/assets/{work-discovery-page-B5Kx29Ru.js → work-discovery-page-Dd_QJJvb.js} +1 -1
  168. package/dist/gateway/static/root/assets/{working-directory-picker-modal-DGp9cNzH.js → working-directory-picker-modal-q39BUcJ6.js} +1 -1
  169. package/dist/gateway/static/root/assets/{workspace-api-HBXn8pL9.js → workspace-api-Di2OmCvz.js} +2 -2
  170. package/dist/gateway/static/root/assets/workspace-editor-agent-store-B2r9wlix.js +1 -0
  171. package/dist/gateway/static/root/assets/{workspace-file-preview-dialog-3cpwSG2w.js → workspace-file-preview-dialog-BUGNT765.js} +1 -1
  172. package/dist/gateway/static/root/assets/{workspace-open-location-menu-D0VOFvuP.js → workspace-open-location-menu-bMSvmQW7.js} +1 -1
  173. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-BkdW2p3v.js → xopc-cloud-account-card-Bbe19Del.js} +1 -1
  174. package/dist/gateway/static/root/index.html +87 -85
  175. package/dist/package.js +1 -1
  176. package/dist/packages/computer-control-contract/src/index.js +33 -3
  177. package/dist/packages/gateway-contract/src/session-identity.js +2 -1
  178. package/dist/packages/gateway-contract/src/session-input-command.js +19 -2
  179. package/dist/packages/gateway-contract/src/specialists.js +1 -0
  180. package/dist/src/agent/agent-manager.js +1 -1
  181. package/dist/src/agent/background-review/run-background-review.js +1 -1
  182. package/dist/src/agent/embedded/execution-tool-policy.d.ts +1 -1
  183. package/dist/src/agent/embedded/execution-tool-policy.js +2 -2
  184. package/dist/src/agent/embedded/run-for-session.js +23 -8
  185. package/dist/src/agent/embedded/run-turn.js +30 -7
  186. package/dist/src/agent/embedded/runs.d.ts +2 -2
  187. package/dist/src/agent/embedded/runs.js +4 -4
  188. package/dist/src/agent/embedded/session-runner.js +26 -11
  189. package/dist/src/agent/embedded/tool-search-extension.d.ts +8 -2
  190. package/dist/src/agent/embedded/tool-search-extension.js +122 -30
  191. package/dist/src/agent/external-tools/cliProvider.d.ts +10 -9
  192. package/dist/src/agent/external-tools/cliProvider.js +26 -6
  193. package/dist/src/agent/external-tools/composio-provider.d.ts +3 -3
  194. package/dist/src/agent/external-tools/composio-provider.js +8 -5
  195. package/dist/src/agent/external-tools/discovery.d.ts +47 -0
  196. package/dist/src/agent/external-tools/discovery.js +56 -0
  197. package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
  198. package/dist/src/agent/external-tools/gateway-tools.js +26 -46
  199. package/dist/src/agent/external-tools/index.d.ts +1 -0
  200. package/dist/src/agent/external-tools/index.js +7 -0
  201. package/dist/src/agent/external-tools/personal-request-scope.d.ts +7 -0
  202. package/dist/src/agent/external-tools/personal-request-scope.js +83 -0
  203. package/dist/src/agent/external-tools/read-policy.js +5 -4
  204. package/dist/src/agent/external-tools/service.d.ts +2 -0
  205. package/dist/src/agent/external-tools/service.js +22 -3
  206. package/dist/src/agent/external-tools/tool-registry.d.ts +6 -0
  207. package/dist/src/agent/external-tools/types.d.ts +7 -2
  208. package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -1
  209. package/dist/src/agent/inbound/turn-dispatcher.js +3 -2
  210. package/dist/src/agent/orchestration/llm-turn-retry.d.ts +1 -1
  211. package/dist/src/agent/orchestration/llm-turn-retry.js +13 -8
  212. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +1 -0
  213. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +3 -1
  214. package/dist/src/agent/prompt/sections/tooling.js +1 -1
  215. package/dist/src/agent/service.js +1 -1
  216. package/dist/src/agent/skills/index.js +1 -1
  217. package/dist/src/agent/skills/managed-store.js +1 -1
  218. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  219. package/dist/src/agent/tool-manuals/computer.d.ts +1 -1
  220. package/dist/src/agent/tool-manuals/computer.js +6 -4
  221. package/dist/src/agent/tool-manuals/phone.d.ts +1 -1
  222. package/dist/src/agent/tool-manuals/phone.js +4 -4
  223. package/dist/src/agent/tool-manuals/xopc-configuration.d.ts +1 -1
  224. package/dist/src/agent/tool-manuals/xopc-configuration.js +4 -2
  225. package/dist/src/agent/tools/computer-use-tool.js +7 -6
  226. package/dist/src/agent/tools/delegation-policy.js +1 -0
  227. package/dist/src/agent/tools/factory.js +4 -2
  228. package/dist/src/agent/tools/personal-read-tool.js +1 -1
  229. package/dist/src/agent/tools/phone-use-tool.js +2 -2
  230. package/dist/src/agent/tools/web.js +22 -3
  231. package/dist/src/agent/tools/xopc-use-tool.js +2 -2
  232. package/dist/src/agent-catalog/capabilities.js +2 -2
  233. package/dist/src/agent-catalog/repository.js +1 -1
  234. package/dist/src/agent-matching/service.js +2 -2
  235. package/dist/src/automations/api/routes.js +2 -2
  236. package/dist/src/automations/capabilities/drafts.js +1 -1
  237. package/dist/src/automations/capabilities/write.js +1 -1
  238. package/dist/src/automations/configuration-conversation.js +1 -1
  239. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  240. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  241. package/dist/src/capabilities/runtime/product.js +1 -1
  242. package/dist/src/cli/commands/agents.js +1 -1
  243. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  244. package/dist/src/cli/commands/models.js +1 -1
  245. package/dist/src/cli/commands/onboard/model.js +1 -1
  246. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  247. package/dist/src/computer/batch.d.ts +108 -0
  248. package/dist/src/computer/batch.js +125 -0
  249. package/dist/src/computer/broker.d.ts +28 -2
  250. package/dist/src/computer/broker.js +95 -17
  251. package/dist/src/computer/diagnostics.d.ts +5 -1
  252. package/dist/src/computer/diagnostics.js +22 -3
  253. package/dist/src/computer/errors.d.ts +15 -0
  254. package/dist/src/computer/errors.js +59 -3
  255. package/dist/src/computer/model-adapter.d.ts +58 -0
  256. package/dist/src/computer/model-adapter.js +112 -66
  257. package/dist/src/computer/native-errors.d.ts +2 -0
  258. package/dist/src/computer/native-errors.js +13 -0
  259. package/dist/src/computer/program-runtime.d.ts +1 -1
  260. package/dist/src/computer/program-runtime.js +1 -0
  261. package/dist/src/computer/runtime.d.ts +11 -0
  262. package/dist/src/computer/runtime.js +102 -34
  263. package/dist/src/computer/semantic-actions.js +4 -0
  264. package/dist/src/config/agent-profile.js +1 -1
  265. package/dist/src/config/schema.d.ts +6 -0
  266. package/dist/src/execution-environments/local-worktree-manager.js +1 -1
  267. package/dist/src/extensions/agent-plugins/formats.js +2 -1
  268. package/dist/src/extensions/agent-plugins/inventory.d.ts +2 -0
  269. package/dist/src/extensions/agent-plugins/inventory.js +4 -1
  270. package/dist/src/extensions/agent-plugins/skill-catalog.js +1 -1
  271. package/dist/src/extensions/agent-plugins/validation.d.ts +1 -0
  272. package/dist/src/extensions/agent-plugins/validation.js +3 -2
  273. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  274. package/dist/src/gateway/agents-admin.js +1 -1
  275. package/dist/src/gateway/global-defaults-admin.js +1 -1
  276. package/dist/src/gateway/hono/routes/agents.js +1 -1
  277. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  278. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  279. package/dist/src/gateway/hono/routes/notes.js +2 -2
  280. package/dist/src/gateway/hono/routes/phone-dependencies.js +26 -5
  281. package/dist/src/gateway/hono/routes/phone-setup.js +43 -17
  282. package/dist/src/gateway/hono/routes/phone.js +22 -7
  283. package/dist/src/gateway/hono/routes/projects.js +2 -2
  284. package/dist/src/gateway/hono/routes/session-command-handler.js +9 -0
  285. package/dist/src/gateway/hono/routes/session-input-control.d.ts +3 -0
  286. package/dist/src/gateway/hono/routes/session-input-control.js +37 -0
  287. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +12 -0
  288. package/dist/src/gateway/hono/routes/session-input-handler.js +23 -1
  289. package/dist/src/gateway/hono/routes/sessions.js +4 -0
  290. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  291. package/dist/src/gateway/image-generation-setup.js +1 -1
  292. package/dist/src/gateway/service/agent-runner.js +5 -4
  293. package/dist/src/gateway/service/config-coordinator.d.ts +6 -0
  294. package/dist/src/gateway/service/session-input-coordinator.d.ts +6 -3
  295. package/dist/src/gateway/service/session-input-coordinator.js +47 -6
  296. package/dist/src/gateway/service.d.ts +1 -0
  297. package/dist/src/gateway/service.js +4 -1
  298. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  299. package/dist/src/imports/importService.js +1 -1
  300. package/dist/src/local-apps/service.js +1 -1
  301. package/dist/src/personal-agent/capability-service.js +1 -1
  302. package/dist/src/personal-agent/request-access.d.ts +2 -0
  303. package/dist/src/personal-agent/request-access.js +22 -2
  304. package/dist/src/personal-agent/request-service.js +2 -2
  305. package/dist/src/personal-agent/service.js +1 -1
  306. package/dist/src/personal-agent/specialist-capabilities.d.ts +2 -0
  307. package/dist/src/personal-agent/specialist-capabilities.js +9 -3
  308. package/dist/src/phone/adb-driver.d.ts +3 -0
  309. package/dist/src/phone/adb-driver.js +29 -0
  310. package/dist/src/phone/contracts.d.ts +14 -2
  311. package/dist/src/phone/contracts.js +8 -1
  312. package/dist/src/phone/gui-protocol.js +1 -1
  313. package/dist/src/phone/hdc-driver.d.ts +30 -0
  314. package/dist/src/phone/hdc-driver.js +331 -0
  315. package/dist/src/phone/hdc-video-bridge.d.ts +2 -0
  316. package/dist/src/phone/hdc-video-bridge.js +91 -0
  317. package/dist/src/phone/hdc-video-tools.d.ts +15 -0
  318. package/dist/src/phone/hdc-video-tools.js +123 -0
  319. package/dist/src/phone/hdc-video.d.ts +69 -0
  320. package/dist/src/phone/hdc-video.js +350 -0
  321. package/dist/src/phone/interactive-session.js +1 -1
  322. package/dist/src/phone/live-provider.d.ts +6 -0
  323. package/dist/src/phone/live-provider.js +1 -0
  324. package/dist/src/phone/model-adapter.d.ts +3 -0
  325. package/dist/src/phone/model-adapter.js +5 -3
  326. package/dist/src/phone/repository.js +2 -1
  327. package/dist/src/phone/runtime.d.ts +10 -4
  328. package/dist/src/phone/runtime.js +151 -85
  329. package/dist/src/phone/setup/service.d.ts +8 -6
  330. package/dist/src/phone/setup/service.js +33 -16
  331. package/dist/src/platform/client.d.ts +1 -1
  332. package/dist/src/platform/contracts.d.ts +1 -1
  333. package/dist/src/process/phone-process.d.ts +1 -1
  334. package/dist/src/process/phone-process.js +2 -2
  335. package/dist/src/runtime-tools/archive.js +1 -1
  336. package/dist/src/runtime-tools/downloader.d.ts +1 -0
  337. package/dist/src/runtime-tools/downloader.js +8 -4
  338. package/dist/src/runtime-tools/harmony-dependencies.d.ts +24 -0
  339. package/dist/src/runtime-tools/harmony-dependencies.js +272 -0
  340. package/dist/src/runtime-tools/harmony-dependency-catalog.d.ts +4 -0
  341. package/dist/src/runtime-tools/harmony-dependency-catalog.js +54 -0
  342. package/dist/src/runtime-tools/harmony-paths.d.ts +9 -0
  343. package/dist/src/runtime-tools/harmony-paths.js +15 -0
  344. package/dist/src/runtime-tools/hdc-dependency-catalog.d.ts +8 -0
  345. package/dist/src/runtime-tools/hdc-dependency-catalog.js +83 -0
  346. package/dist/src/runtime-tools/hdc-files.d.ts +14 -0
  347. package/dist/src/runtime-tools/hdc-files.js +87 -0
  348. package/dist/src/runtime-tools/phone-dependencies.d.ts +6 -1
  349. package/dist/src/runtime-tools/phone-dependencies.js +20 -2
  350. package/dist/src/runtime-tools/phone-dependency-catalog.d.ts +10 -1
  351. package/dist/src/runtime-tools/phone-dependency-catalog.js +2 -0
  352. package/dist/src/runtime-tools/types.d.ts +1 -1
  353. package/dist/src/storage/sqlite/schema.d.ts +2 -2
  354. package/dist/src/storage/sqlite/schema.js +7 -7
  355. package/dist/src/storage/sqlite/schema.sql +16 -0
  356. package/dist/src/storage/sqlite/session-creation-repository.js +3 -0
  357. package/dist/src/storage/sqlite/session-input-control-repository.d.ts +12 -0
  358. package/dist/src/storage/sqlite/session-input-control-repository.js +83 -0
  359. package/dist/src/storage/sqlite/session-input-repository.d.ts +2 -0
  360. package/dist/src/storage/sqlite/session-input-repository.js +17 -5
  361. package/dist/src/storage/sqlite/session-repository.js +1 -0
  362. package/dist/src/storage/sqlite/session-turn-replace-repository.d.ts +2 -0
  363. package/dist/src/storage/sqlite/session-turn-replace-repository.js +14 -2
  364. package/dist/src/storage/sqlite/upgrades/262_session_input_control.sql +15 -0
  365. package/dist/src/tasks/capabilities/read.js +2 -2
  366. package/dist/src/tasks/capabilities/write.js +1 -1
  367. package/dist/src/tui/backends/embedded-backend.js +1 -1
  368. package/dist/src/voice/realtime/persona-context.js +1 -1
  369. package/package.json +2 -2
  370. package/skills/tools/configure-xopc/SKILL.md +2 -2
  371. package/skills/tools/configure-xopc/references/phone/acceptance.md +3 -2
  372. package/skills/tools/configure-xopc/references/phone/dependencies.md +18 -2
  373. package/skills/tools/configure-xopc/references/phone/harmonyos.md +16 -0
  374. package/skills/tools/configure-xopc/references/phone/overview.md +2 -2
  375. package/skills/tools/configure-xopc/references/scene-index.md +2 -2
  376. package/dist/gateway/static/root/assets/apps-page-D-n71lO1.js +0 -1
  377. package/dist/gateway/static/root/assets/automations-workspace-DWDWy-SG.js +0 -9
  378. package/dist/gateway/static/root/assets/capabilities-page-IcwojmJK.js +0 -2
  379. package/dist/gateway/static/root/assets/capability-links-DzQWK1Fh.js +0 -1
  380. package/dist/gateway/static/root/assets/chat-page-CwP4OMdW.js +0 -72
  381. package/dist/gateway/static/root/assets/computer-settings-page-DyAlOzqY.js +0 -1
  382. package/dist/gateway/static/root/assets/connected-providers-grid-D0lXg22c.js +0 -1
  383. package/dist/gateway/static/root/assets/connectors-page-DI_Q0CKz.js +0 -1
  384. package/dist/gateway/static/root/assets/gateway-realtime-store-BFeFfApQ.js +0 -1
  385. package/dist/gateway/static/root/assets/index-Cz-VjTNd.css +0 -1
  386. package/dist/gateway/static/root/assets/index-D1_PUrJf.js +0 -11
  387. package/dist/gateway/static/root/assets/install-connector-dialog-Cn4nRSyt.js +0 -1
  388. package/dist/gateway/static/root/assets/list-tree-B0OMswgM.js +0 -1
  389. package/dist/gateway/static/root/assets/messages-jwdBhfL9.js +0 -3
  390. package/dist/gateway/static/root/assets/note-image-lightbox-DGYRJS03.js +0 -1
  391. package/dist/gateway/static/root/assets/page-header-store-CEn_kPsn.js +0 -1
  392. package/dist/gateway/static/root/assets/phone-dependencies-card-DjmC1Z5j.js +0 -1
  393. package/dist/gateway/static/root/assets/phone-model-connection-BRjHSgYn.js +0 -1
  394. package/dist/gateway/static/root/assets/phone-model-picker-DgIiWLhR.js +0 -1
  395. package/dist/gateway/static/root/assets/phone-settings-page-DCZGCL_z.js +0 -1
  396. package/dist/gateway/static/root/assets/plugin-details-dialog-D4tGKip4.js +0 -1
  397. package/dist/gateway/static/root/assets/route-preload-C1BKDjnu.js +0 -2
  398. package/dist/gateway/static/root/assets/session-api-Bfmlmn9F.js +0 -1
  399. package/dist/gateway/static/root/assets/session-channel-icon-SsY70Z6t.js +0 -1
  400. package/dist/gateway/static/root/assets/session-identity-label-B7sgG1PE.js +0 -1
  401. package/dist/gateway/static/root/assets/session-manager-X4UHOjjO.js +0 -25
  402. package/dist/gateway/static/root/assets/settings-advanced-gate-Dk9c-Z5e.js +0 -1
  403. package/dist/gateway/static/root/assets/workspace-editor-agent-store-msZa42fU.js +0 -1
@@ -0,0 +1,56 @@
1
+ import { connectionBindings, getActiveConnectionWait, init_connection_wait_repository } from "../../storage/sqlite/connection-wait-repository.js";
2
+ import { searchStoreConnectorInstallCandidates } from "../../capabilities/store-connector.js";
3
+ import { connectionCandidates } from "../../connectors/connection-candidates.js";
4
+ import { EXTERNAL_TOOL_SOURCES } from "./types.js";
5
+ //#region src/agent/external-tools/discovery.ts
6
+ init_connection_wait_repository();
7
+ /** Discover capabilities without activating tools or granting execution permissions. */
8
+ async function discoverExternalTools(deps, params) {
9
+ const { service, nativeSources, getContext, getConfig } = deps;
10
+ const gatewaySources = EXTERNAL_TOOL_SOURCES.filter((source) => !nativeSources.includes(source));
11
+ const request = deps.getRequest();
12
+ const selectedSources = new Set(params.sources ?? []);
13
+ const excludedSources = selectedSources.size ? EXTERNAL_TOOL_SOURCES.filter((source) => !selectedSources.has(source)) : [];
14
+ if (params.sources?.length && params.sources.every((source) => nativeSources.includes(source))) return {
15
+ tools: [],
16
+ connectionCandidates: [],
17
+ installCandidates: [],
18
+ unavailableSources: [],
19
+ instruction: "Use tool_search for native tools."
20
+ };
21
+ const result = await service.search({
22
+ ...params,
23
+ sources: (params.sources?.length ? params.sources : gatewaySources).filter((source) => !nativeSources.includes(source))
24
+ });
25
+ const currentRequest = deps.getRequest();
26
+ if (request && (currentRequest?.requestId !== request.requestId || currentRequest.accountId !== request.accountId || currentRequest.connectorId !== request.connectorId)) throw new Error("Personal request execution identity changed");
27
+ const candidates = [...request ? [] : result.connectionCandidates, ...request ? [] : connectionCandidates(params.query)].filter((candidate, index, all) => all.findIndex((item) => item.candidateRef === candidate.candidateRef) === index).slice(0, params.limit ?? 8);
28
+ let installCandidates = [];
29
+ let installCatalogError;
30
+ const config = getConfig?.();
31
+ if (!request && !params.sources?.length && result.tools.length === 0 && candidates.length === 0 && config) try {
32
+ installCandidates = await searchStoreConnectorInstallCandidates(config, params.query, params.limit ?? 5);
33
+ } catch (error) {
34
+ installCatalogError = error instanceof Error ? error.message : String(error);
35
+ }
36
+ return {
37
+ ...result,
38
+ connectionCandidates: candidates,
39
+ installCandidates,
40
+ ...result.tools.length === 0 && (candidates.length > 0 || installCandidates.length > 0) ? { instruction: "No executable tool matched this search. This alone does not prove the account is disconnected. Retry without restrictive sources and inspect the returned account state. If authorization or account selection is actually required, call xopc_require_connection with an exact candidateRef from this result; the host owns selection, authorization and automatic continuation. Do not ask the user whether to perform an already requested read, or to reply continue after authorization. Do not fall back to browser automation unless the user explicitly asked for browser use or skips the connection." } : {},
41
+ ...result.tools.length > 0 ? { instruction: "Describe the relevant tool contracts and execute the requested read using the available authorized account. The user request already authorizes these reads; do not ask for another confirmation. Respect the exact contracts and host permission checks. Hand off to the user only when a required authorization, ambiguous account choice or essential missing decision cannot be resolved from existing context." } : {},
42
+ ...installCatalogError ? { installCatalogError } : {},
43
+ ...excludedSources.length ? { searchScope: {
44
+ excludedSources,
45
+ instruction: "This search excluded these sources. Results from other apps do not establish that the requested app is unavailable. Retry without sources before declaring a capability unavailable or requesting authorization. Feishu/Lark, WeCom and WPS 365 connectors use cli."
46
+ } } : {},
47
+ selectedConnections: !request && getContext?.()?.conversationId ? connectionBindings(getContext().conversationId) : [],
48
+ waitingObjective: !request && getContext?.()?.conversationId ? getActiveConnectionWait(getContext().conversationId)?.summary : void 0,
49
+ ...request ? {
50
+ selectedAccountId: request.accountId,
51
+ instruction: "Use only this request connector and selected account. Describe matching contracts before execution. If the selected account needs authorization, use personal_request_connection; the main chat owns reconnection and automatic continuation."
52
+ } : {}
53
+ };
54
+ }
55
+ //#endregion
56
+ export { discoverExternalTools };
@@ -1,7 +1,7 @@
1
- import { init_src } from "../../../packages/computer-control-contract/src/index.js";
2
- import "../../../packages/browser-control-contract/src/index.js";
3
1
  import { ExternalEffectNotAppliedError, executeExternalOperation } from "../../capabilities/runtime/external-operations.js";
4
2
  import { canonicalCapabilityJson } from "../../capabilities/runtime/dispatcher.js";
3
+ import { init_src } from "../../../packages/computer-control-contract/src/index.js";
4
+ import "../../../packages/browser-control-contract/src/index.js";
5
5
  import { externalToolRef, parseExternalToolRef } from "./refs.js";
6
6
  import { extractDocumentText } from "../../document-understanding/extract.js";
7
7
  import { prepareImageForModel } from "../image/prepare-image-for-model.js";
@@ -2,18 +2,20 @@ import { init_connection, isXopcDatabaseOpen } from "../../storage/sqlite/connec
2
2
  import { init_request_repository, personalRequestForExecution } from "../../personal-agent/request-repository.js";
3
3
  import { getConnectorAccount, init_connector_account_repository } from "../../storage/sqlite/connector-account-repository.js";
4
4
  import { getConnectorConnection, getConnectorInstallation, init_connector_repository, listConnectorActionMetadata, listConnectorConnections } from "../../storage/sqlite/connector-repository.js";
5
- import { connectionBindings, getActiveConnectionWait, init_connection_wait_repository, publishConnectionWait, requireSessionConnection, reviseCurrentConnectionObjective } from "../../storage/sqlite/connection-wait-repository.js";
5
+ import { connectionBindings, init_connection_wait_repository, publishConnectionWait, requireSessionConnection, reviseCurrentConnectionObjective } from "../../storage/sqlite/connection-wait-repository.js";
6
6
  import { getSessionMetadata } from "../../storage/sqlite/session-read-repository.js";
7
7
  import { init_session_repository } from "../../storage/sqlite/session-repository.js";
8
8
  import { connectorPrincipalForSession } from "../../connectors/principal.js";
9
9
  import { setXopcToolMetadata } from "../embedded/tool-metadata.js";
10
10
  import { listConnectorInstances } from "../../connectors/instances.js";
11
11
  import { parseExternalToolRef } from "./refs.js";
12
- import { getStoreConnectorInstallPlan, parseStoreConnectorCandidateRef, searchStoreConnectorInstallCandidates } from "../../capabilities/store-connector.js";
13
- import { assertPersonalRequestAccountAccess } from "../../personal-agent/request-access.js";
14
- import { connectionCandidates, resolveConnectionCandidate } from "../../connectors/connection-candidates.js";
12
+ import { getStoreConnectorInstallPlan, parseStoreConnectorCandidateRef } from "../../capabilities/store-connector.js";
13
+ import { createPersonalRequestExecutionAuthorizer } from "../../personal-agent/request-access.js";
14
+ import { resolveConnectionCandidate } from "../../connectors/connection-candidates.js";
15
15
  import { ExternalToolService } from "./service.js";
16
16
  import { EXTERNAL_TOOL_SOURCES } from "./types.js";
17
+ import { discoverExternalTools } from "./discovery.js";
18
+ import { personalRequestToolScope, scopePersonalRequestProvider } from "./personal-request-scope.js";
17
19
  import { bindExternalToolRegistry } from "./tool-registry.js";
18
20
  import { Type } from "@sinclair/typebox";
19
21
  //#region src/agent/external-tools/gateway-tools.ts
@@ -44,10 +46,10 @@ const ToolSearchSchema = Type.Object({
44
46
  const ToolDescribeSchema = Type.Object({ toolRefs: Type.Array(Type.String(), {
45
47
  minItems: 1,
46
48
  maxItems: 3,
47
- description: "Exact tool references returned by xopc_tool_search."
49
+ description: "Exact tool references returned by tool_search."
48
50
  }) });
49
51
  const ToolExecuteSchema = Type.Object({
50
- toolRef: Type.String({ description: "Exact tool reference returned by xopc_tool_search." }),
52
+ toolRef: Type.String({ description: "Exact tool reference returned by tool_search." }),
51
53
  revision: Type.String({ description: "Exact contract revision returned by xopc_tool_describe." }),
52
54
  arguments: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
53
55
  approvalId: Type.Optional(Type.String({ description: "One-time approval id when execution requested confirmation." })),
@@ -63,7 +65,15 @@ function textResult(value, details = {}) {
63
65
  };
64
66
  }
65
67
  function createExternalToolGatewayTools(providers, getContext, getConfig, getExecutionConversationId, nativeSources = [], executorConfig) {
66
- const service = new ExternalToolService(providers);
68
+ const getRequest = () => personalRequestToolScope(getExecutionConversationId?.() ?? getContext?.()?.conversationId);
69
+ const service = new ExternalToolService(providers.map((provider) => scopePersonalRequestProvider(provider, getRequest, getConfig)));
70
+ const discoveryDeps = {
71
+ service,
72
+ nativeSources,
73
+ getContext,
74
+ getConfig,
75
+ getRequest
76
+ };
67
77
  const gatewaySources = EXTERNAL_TOOL_SOURCES.filter((source) => !nativeSources.includes(source));
68
78
  const assertGatewayRef = (ref) => {
69
79
  if (nativeSources.some((source) => ref.startsWith(`${source}:`))) throw new Error("Use tool_search to load this native tool, then call it directly.");
@@ -74,45 +84,13 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
74
84
  description: `Search external tools from these sources: ${gatewaySources.join(", ")}.${nativeSources.length ? ` Use tool_search for native ${nativeSources.join(", ")} tools.` : ""} CLI connectors include Feishu/Lark, WeCom and WPS 365. Omit sources unless intentionally restricting the search; do not guess a source list. Use concise English capability keywords, e.g. "wecom doc.search". Returns executable tools, connection candidates, or reviewed Store install candidates. Call xopc_tool_describe before executing a tool. When no executable tool exists but a connection or install candidate is returned, use xopc_require_connection instead of falling back to browser automation. If a source-filtered search finds no relevant tools, retry without sources before concluding a capability is unavailable.`,
75
85
  parameters: ToolSearchSchema,
76
86
  async execute(_toolCallId, params) {
77
- const selectedSources = new Set(params.sources ?? []);
78
- const excludedSources = selectedSources.size ? EXTERNAL_TOOL_SOURCES.filter((source) => !selectedSources.has(source)) : [];
79
- if (params.sources?.length && params.sources.every((source) => nativeSources.includes(source))) return textResult({
80
- tools: [],
81
- instruction: "Use tool_search for native tools."
82
- });
83
- const result = await service.search({
84
- ...params,
85
- sources: (params.sources?.length ? params.sources : gatewaySources).filter((source) => !nativeSources.includes(source))
86
- });
87
- const candidates = [...result.connectionCandidates, ...connectionCandidates(params.query)].filter((candidate, index, all) => all.findIndex((item) => item.candidateRef === candidate.candidateRef) === index);
88
- let installCandidates = [];
89
- let installCatalogError;
90
- const config = getConfig?.();
91
- if (!params.sources?.length && result.tools.length === 0 && candidates.length === 0 && config) try {
92
- installCandidates = await searchStoreConnectorInstallCandidates(config, params.query, params.limit ?? 5);
93
- } catch (error) {
94
- installCatalogError = error instanceof Error ? error.message : String(error);
95
- }
96
- return textResult({
97
- ...result,
98
- connectionCandidates: candidates,
99
- installCandidates,
100
- ...result.tools.length === 0 && (candidates.length > 0 || installCandidates.length > 0) ? { instruction: "No executable tool matched this search. This alone does not prove the account is disconnected. Retry without restrictive sources and inspect the returned account state. If authorization or account selection is actually required, call xopc_require_connection with an exact candidateRef from this result; the host owns selection, authorization and automatic continuation. Do not ask the user whether to perform an already requested read, or to reply continue after authorization. Do not fall back to browser automation unless the user explicitly asked for browser use or skips the connection." } : {},
101
- ...result.tools.length > 0 ? { instruction: "Describe the relevant tool contracts and execute the requested read using the available authorized account. The user request already authorizes these reads; do not ask for another confirmation. Respect the exact contracts and host permission checks. Hand off to the user only when a required authorization, ambiguous account choice or essential missing decision cannot be resolved from existing context." } : {},
102
- ...installCatalogError ? { installCatalogError } : {},
103
- ...excludedSources.length ? { searchScope: {
104
- excludedSources,
105
- instruction: "This search excluded these sources. Results from other apps do not establish that the requested app is unavailable. Retry without sources before declaring a capability unavailable or requesting authorization. Feishu/Lark, WeCom and WPS 365 connectors use cli."
106
- } } : {},
107
- selectedConnections: getContext?.()?.conversationId ? connectionBindings(getContext().conversationId) : [],
108
- waitingObjective: getContext?.()?.conversationId ? getActiveConnectionWait(getContext().conversationId)?.summary : void 0
109
- });
87
+ return textResult(await discoverExternalTools(discoveryDeps, params));
110
88
  }
111
89
  };
112
90
  const describeTool = {
113
91
  name: EXTERNAL_TOOL_NAMES.describe,
114
92
  label: "📋 External Tool Contract",
115
- description: "Load exact contracts for up to three external tools returned by xopc_tool_search.",
93
+ description: "Load exact contracts for up to three external tools returned by tool_search.",
116
94
  parameters: ToolDescribeSchema,
117
95
  async execute(_toolCallId, params) {
118
96
  params.toolRefs.forEach(assertGatewayRef);
@@ -131,6 +109,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
131
109
  async execute(toolCallId, params, signal, onUpdate) {
132
110
  const conversationId = getExecutionConversationId?.() ?? getContext?.()?.conversationId;
133
111
  const request = conversationId ? personalRequestForExecution(conversationId) : void 0;
112
+ let authorize;
134
113
  if (!request && conversationId && isXopcDatabaseOpen() && getSessionMetadata(conversationId)?.customData?.personalReadRequestId) throw new Error("Personal request is no longer active");
135
114
  if (request) {
136
115
  if ([
@@ -145,7 +124,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
145
124
  const connectorId = composio ? getConnectorInstallation(composio.namespace)?.connectorId : cli && config ? listConnectorInstances(config).find((instance) => instance.instanceId === cli.namespace)?.connectorId : void 0;
146
125
  if (connectorId !== request.connectorId) throw new Error("Use only the selected Personal request connector");
147
126
  if (composio && !listConnectorActionMetadata(connectorId).some((action) => action.actionId === composio.toolName && action.scope === "read" && action.curated)) throw new Error("Personal requests permit only curated read operations");
148
- assertPersonalRequestAccountAccess(request);
127
+ authorize = createPersonalRequestExecutionAuthorizer(conversationId, request);
149
128
  const account = getConnectorAccount(request.accountId);
150
129
  const connection = account?.currentConnectionId ? getConnectorConnection(account.currentConnectionId) : void 0;
151
130
  if (!connection || connection.status !== "active" || connection.expiresAt && Date.parse(connection.expiresAt) <= Date.now()) {
@@ -168,7 +147,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
168
147
  toolCallId,
169
148
  signal,
170
149
  onUpdate,
171
- ...request ? { authorize: () => assertPersonalRequestAccountAccess(request) } : {}
150
+ ...authorize ? { authorize } : {}
172
151
  }
173
152
  });
174
153
  return {
@@ -190,7 +169,8 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
190
169
  service,
191
170
  nativeSources,
192
171
  execute: nativeExecute,
193
- executorConfig
172
+ executorConfig,
173
+ search: (params) => discoverExternalTools(discoveryDeps, params)
194
174
  });
195
175
  const requireSchema = Type.Object({
196
176
  requirements: Type.Array(Type.Object({
@@ -223,7 +203,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
223
203
  name: EXTERNAL_TOOL_NAMES.requireConnection,
224
204
  label: "Connect app",
225
205
  parameters: requireSchema,
226
- description: "Use only when a requested read cannot proceed because authorization, installation or account selection is required. Available authorized tools should be executed directly without asking the user to confirm the read. Request an exact connectionCandidates or installCandidates entry returned by xopc_tool_search. Explain the verified need once before calling. This saves and pauses the objective, displays one action area above the input, and lets the host resume automatically after the required user action. Stop this turn after connection_required; never ask the user to reply continue after authorization. Never invent a candidate reference, return OAuth URLs, or repeat a skipped request. If another objective is waiting, do not create a duplicate objective.",
206
+ description: "Use only when a requested read cannot proceed because authorization, installation or account selection is required. Available authorized tools should be executed directly without asking the user to confirm the read. Request an exact connectionCandidates or installCandidates entry returned by tool_search. Explain the verified need once before calling. This saves and pauses the objective, displays one action area above the input, and lets the host resume automatically after the required user action. Stop this turn after connection_required; never ask the user to reply continue after authorization. Never invent a candidate reference, return OAuth URLs, or repeat a skipped request. If another objective is waiting, do not create a duplicate objective.",
227
207
  async execute(_id, params) {
228
208
  const context = getContext?.();
229
209
  if (!context) throw new Error("No active conversation.");
@@ -313,7 +293,7 @@ function createExternalToolGatewayTools(providers, getContext, getConfig, getExe
313
293
  }
314
294
  };
315
295
  return [
316
- searchTool,
296
+ setXopcToolMetadata(searchTool, { exposure: "hidden" }),
317
297
  describeTool,
318
298
  executeTool,
319
299
  setXopcToolMetadata(requireTool, { exposure: "model-only" }),
@@ -13,6 +13,7 @@ export interface DefaultExternalToolGatewayDeps {
13
13
  agentId?: string;
14
14
  extensionRegistry?: ExtensionRegistry;
15
15
  disabledTools?: Set<string>;
16
+ toolAllowlist?: readonly string[];
16
17
  hookRunner?: ExtensionHookRunner;
17
18
  toolExecutorConfig?: Partial<ToolExecutorConfig>;
18
19
  getMemoryManager?: () => MemoryManager;
@@ -68,6 +68,13 @@ function createDefaultExternalToolGatewayTools(deps) {
68
68
  "memory"
69
69
  ], deps.toolExecutorConfig);
70
70
  const registry = getExternalToolRegistry(tools);
71
+ if (registry) {
72
+ const native = !deps.disabledTools?.has("tool_search");
73
+ registry.discovery = {
74
+ native,
75
+ connectors: native && !deps.disabledTools?.has("xopc_tool_search") && (!deps.toolAllowlist || deps.toolAllowlist.includes("tool_search") || deps.toolAllowlist.includes("xopc_tool_search"))
76
+ };
77
+ }
71
78
  if (registry && deps.endpointTools) {
72
79
  const endpoints = deps.endpointTools;
73
80
  registry.subscribeInvalidation = (conversationId, ref, listener) => {
@@ -0,0 +1,7 @@
1
+ import type { Config } from '../../config/schema.js';
2
+ import { type PersonalRequest } from '../../personal-agent/request-repository.js';
3
+ import type { ExternalToolProvider } from './types.js';
4
+ /** Read scope follows persisted request identity, including cancelled or detached workers. */
5
+ export declare function personalRequestToolScope(conversationId?: string): PersonalRequest | undefined;
6
+ /** Apply the same connector, account and curated-read boundary before search ranking and describe. */
7
+ export declare function scopePersonalRequestProvider(provider: ExternalToolProvider, getRequest: () => PersonalRequest | undefined, getConfig?: () => Config | undefined): ExternalToolProvider;
@@ -0,0 +1,83 @@
1
+ import { init_connection, isXopcDatabaseOpen } from "../../storage/sqlite/connection.js";
2
+ import { init_request_repository, personalRequestForExecution } from "../../personal-agent/request-repository.js";
3
+ import { getConnectorInstallation, init_connector_repository, listConnectorActionMetadata } from "../../storage/sqlite/connector-repository.js";
4
+ import { getSessionMetadata } from "../../storage/sqlite/session-read-repository.js";
5
+ import { init_session_repository } from "../../storage/sqlite/session-repository.js";
6
+ import { listConnectorInstances } from "../../connectors/instances.js";
7
+ import { parseExternalToolRef } from "./refs.js";
8
+ import { assertPersonalRequestAccountAccess } from "../../personal-agent/request-access.js";
9
+ //#region src/agent/external-tools/personal-request-scope.ts
10
+ init_request_repository();
11
+ init_connection();
12
+ init_connector_repository();
13
+ init_session_repository();
14
+ /** Read scope follows persisted request identity, including cancelled or detached workers. */
15
+ function personalRequestToolScope(conversationId) {
16
+ const request = conversationId ? personalRequestForExecution(conversationId) : void 0;
17
+ if (!request && conversationId && isXopcDatabaseOpen() && getSessionMetadata(conversationId)?.customData?.personalReadRequestId) throw new Error("Personal request is no longer active");
18
+ if (request) assertPersonalRequestAccountAccess(request);
19
+ return request;
20
+ }
21
+ /** Apply the same connector, account and curated-read boundary before search ranking and describe. */
22
+ function scopePersonalRequestProvider(provider, getRequest, getConfig) {
23
+ const describe = async (ref) => {
24
+ const request = getRequest();
25
+ if (!request) return provider.describe(ref);
26
+ if (!request.accountId) throw new Error("Personal request requires a selected account");
27
+ const parsed = parseExternalToolRef(ref, provider.source);
28
+ if (!parsed || !["cli", "composio"].includes(provider.source)) return void 0;
29
+ const config = getConfig?.();
30
+ const connectorId = provider.source === "composio" ? getConnectorInstallation(parsed.namespace)?.connectorId : config ? listConnectorInstances(config).find((instance) => instance.instanceId === parsed.namespace)?.connectorId : void 0;
31
+ if (connectorId !== request.connectorId) return void 0;
32
+ if (provider.source === "composio" && !listConnectorActionMetadata(connectorId).some((action) => action.actionId === parsed.toolName && action.scope === "read" && action.curated)) return void 0;
33
+ const descriptor = await provider.describe(ref, {
34
+ connectorId: request.connectorId,
35
+ accountId: request.accountId
36
+ });
37
+ const current = getRequest();
38
+ if (!current || current.accountId !== request.accountId || current.connectorId !== request.connectorId || current.requestId !== request.requestId) throw new Error("Personal request execution identity changed");
39
+ if (!descriptor || descriptor.readOnly !== true) return void 0;
40
+ return {
41
+ ...descriptor,
42
+ description: `${descriptor.summary}\nUse only selected account ${request.accountId}.`,
43
+ inputSchema: {
44
+ ...descriptor.inputSchema,
45
+ properties: {
46
+ ...descriptor.inputSchema.properties,
47
+ xopcAccountId: {
48
+ type: "string",
49
+ const: request.accountId
50
+ }
51
+ },
52
+ required: [...new Set([...descriptor.inputSchema.required ?? [], "xopcAccountId"])]
53
+ }
54
+ };
55
+ };
56
+ return {
57
+ source: provider.source,
58
+ async search(query) {
59
+ const request = getRequest();
60
+ if (!request) return provider.search(query);
61
+ if (!request.accountId) throw new Error("Personal request requires a selected account");
62
+ if (!["cli", "composio"].includes(provider.source)) return [];
63
+ const hits = await provider.search(query, {
64
+ connectorId: request.connectorId,
65
+ accountId: request.accountId
66
+ });
67
+ return (await Promise.all(hits.map(async (hit) => {
68
+ const descriptor = await describe(hit.toolRef);
69
+ return descriptor ? {
70
+ ...hit,
71
+ summary: descriptor.summary
72
+ } : void 0;
73
+ }))).filter((hit) => hit !== void 0);
74
+ },
75
+ async connectionCandidates(query) {
76
+ return getRequest() ? [] : await provider.connectionCandidates?.(query) ?? [];
77
+ },
78
+ describe,
79
+ execute: (ref, args, approvalId, context) => provider.execute(ref, args, approvalId, context)
80
+ };
81
+ }
82
+ //#endregion
83
+ export { personalRequestToolScope, scopePersonalRequestProvider };
@@ -3,16 +3,17 @@
3
3
  function withExternalReadPolicy(provider, getPolicy) {
4
4
  return {
5
5
  source: provider.source,
6
- search: (query) => provider.search(query),
6
+ search: (query, context) => context ? provider.search(query, context) : provider.search(query),
7
7
  ...provider.connectionCandidates ? { connectionCandidates: provider.connectionCandidates.bind(provider) } : {},
8
- describe: async (ref) => {
9
- const descriptor = await provider.describe(ref);
8
+ describe: async (ref, context) => {
9
+ const descriptor = await (context ? provider.describe(ref, context) : provider.describe(ref));
10
10
  if (!descriptor) return void 0;
11
11
  const policy = getPolicy(ref);
12
12
  if (policy?.mode === "deny") return void 0;
13
+ const batchRead = descriptor.readOnly === false ? false : provider.source === "endpoint" ? descriptor.batchRead === true && policy?.readOnly !== false : policy?.readOnly ?? descriptor.batchRead;
13
14
  return {
14
15
  ...descriptor,
15
- batchRead: provider.source === "endpoint" ? descriptor.batchRead === true && policy?.readOnly !== false : policy?.readOnly ?? descriptor.batchRead
16
+ batchRead
16
17
  };
17
18
  },
18
19
  execute: (ref, args, approval, context) => provider.execute(ref, args, approval, context)
@@ -10,6 +10,8 @@ export declare class ExternalToolService {
10
10
  query: string;
11
11
  sources?: ExternalToolSource[];
12
12
  limit?: number;
13
+ signal?: AbortSignal;
14
+ timeoutMs?: number;
13
15
  }): Promise<{
14
16
  tools: ExternalToolSearchHit[];
15
17
  connectionCandidates: ExternalConnectionCandidate[];
@@ -31,6 +31,7 @@ function descriptorRevision(descriptor) {
31
31
  outputSchema: descriptor.outputSchema,
32
32
  annotations: descriptor.annotations,
33
33
  batchRead: descriptor.batchRead === true,
34
+ readOnly: descriptor.readOnly,
34
35
  contractRevision: descriptor.contractRevision,
35
36
  exposure: descriptor.exposure
36
37
  })).digest("hex").slice(0, 16);
@@ -65,11 +66,12 @@ var ExternalToolService = class {
65
66
  }
66
67
  async search(params) {
67
68
  const selected = params.sources?.length ? params.sources.map((source) => this.providerBySource.get(source)).filter((provider) => provider !== void 0) : [...this.providerBySource.values()];
68
- const settled = await Promise.allSettled(selected.map(async (provider) => ({
69
+ const settled = await Promise.allSettled(selected.map((provider) => searchWithDeadline(async () => ({
69
70
  provider,
70
71
  hits: await provider.search(params.query),
71
72
  candidates: await provider.connectionCandidates?.(params.query) ?? []
72
- })));
73
+ }), params.timeoutMs, params.signal)));
74
+ params.signal?.throwIfAborted();
73
75
  const unavailableSources = [];
74
76
  const sourceErrors = [];
75
77
  const hits = [];
@@ -137,7 +139,7 @@ var ExternalToolService = class {
137
139
  const descriptor = await provider.describe(params.toolRef);
138
140
  if (!descriptor) throw new Error(`External tool is unavailable: ${params.toolRef}`);
139
141
  const current = versionDescriptor(descriptor);
140
- if (params.personalReadOnly && current.readOnly !== true && current.batchRead !== true) throw new Error("This external operation has no host-curated read-only contract");
142
+ if (params.personalReadOnly && current.readOnly !== true) throw new Error("This external operation has no host-curated read-only contract");
141
143
  if (params.readOnly && current.batchRead !== true) throw new Error("This external operation is not approved for batch reads");
142
144
  if (current.revision !== params.revision) throw new Error(`Tool contract changed. Describe ${params.toolRef} again before executing it.`);
143
145
  const args = params.arguments ?? {};
@@ -165,5 +167,22 @@ var ExternalToolService = class {
165
167
  return this.providerBySource.get(toolRef.slice(0, separator));
166
168
  }
167
169
  };
170
+ /** A stalled directory must not hide successful results from another provider. */
171
+ async function searchWithDeadline(search, timeoutMs, signal) {
172
+ signal?.throwIfAborted();
173
+ if (!timeoutMs && !signal) return search();
174
+ let timer;
175
+ let onAbort;
176
+ try {
177
+ return await Promise.race([search(), new Promise((_resolve, reject) => {
178
+ if (timeoutMs) timer = setTimeout(() => reject(Object.assign(/* @__PURE__ */ new Error("Tool source discovery timed out"), { code: "discovery_timeout" })), timeoutMs);
179
+ onAbort = () => reject(signal?.reason ?? /* @__PURE__ */ new Error("Tool search aborted"));
180
+ signal?.addEventListener("abort", onAbort, { once: true });
181
+ })]);
182
+ } finally {
183
+ clearTimeout(timer);
184
+ if (onAbort) signal?.removeEventListener("abort", onAbort);
185
+ }
186
+ }
168
187
  //#endregion
169
188
  export { ExternalToolService };
@@ -1,11 +1,17 @@
1
1
  import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ import type { ExternalDiscoveryParams, ExternalDiscoveryResult } from './discovery.js';
2
3
  import type { ExternalToolService } from './service.js';
3
4
  import type { ExternalToolSource } from './types.js';
4
5
  import type { ToolInvalidationReason } from '../embedded/tool-metadata.js';
5
6
  import type { ToolExecutorConfig } from '../tools/executor.js';
6
7
  export interface ExternalToolRegistry {
7
8
  service: ExternalToolService;
9
+ search: (params: ExternalDiscoveryParams) => Promise<ExternalDiscoveryResult>;
8
10
  nativeSources: readonly ExternalToolSource[];
11
+ discovery?: {
12
+ native: boolean;
13
+ connectors: boolean;
14
+ };
9
15
  execute: AgentTool['execute'];
10
16
  executorConfig?: Partial<ToolExecutorConfig>;
11
17
  subscribeInvalidation?: (conversationId: string, toolRef: string, listener: (reason?: ToolInvalidationReason) => void) => () => void;
@@ -48,10 +48,15 @@ export interface ExternalToolTurnContext {
48
48
  conversationId: string;
49
49
  origin: TurnOrigin;
50
50
  }
51
+ /** Host-selected discovery scope; never supplied by the model. */
52
+ export interface ExternalToolDiscoveryContext {
53
+ connectorId: string;
54
+ accountId: string;
55
+ }
51
56
  export interface ExternalToolProvider {
52
57
  readonly source: ExternalToolSource;
53
- search(query: string): Promise<ExternalToolSearchHit[]>;
58
+ search(query: string, context?: ExternalToolDiscoveryContext): Promise<ExternalToolSearchHit[]>;
54
59
  connectionCandidates?(query: string): Promise<ExternalConnectionCandidate[]>;
55
- describe(toolRef: string): Promise<ExternalToolDescriptor | undefined>;
60
+ describe(toolRef: string, context?: ExternalToolDiscoveryContext): Promise<ExternalToolDescriptor | undefined>;
56
61
  execute(toolRef: string, args: Record<string, unknown>, approvalId: string | undefined, context: ExternalToolExecutionContext): Promise<AgentToolResult<Record<string, unknown>>>;
57
62
  }
@@ -91,7 +91,7 @@ export declare class TurnDispatcher {
91
91
  * after current tool work, before the next LLM call). See `Agent.steer`
92
92
  * in `@earendil-works/pi-agent-core`.
93
93
  */
94
- steerWebchatSession(conversationId: string, text: string): Promise<boolean>;
94
+ steerWebchatSession(conversationId: string, text: string, expectedRunId?: string): Promise<boolean>;
95
95
  private buildStreamingDeps;
96
96
  private buildOneShotDeps;
97
97
  }
@@ -76,16 +76,17 @@ var TurnDispatcher = class {
76
76
  * after current tool work, before the next LLM call). See `Agent.steer`
77
77
  * in `@earendil-works/pi-agent-core`.
78
78
  */
79
- async steerWebchatSession(conversationId, text) {
79
+ async steerWebchatSession(conversationId, text, expectedRunId) {
80
80
  const trimmed = text.trim();
81
81
  if (!trimmed) return false;
82
82
  try {
83
- return await queueEmbeddedSteer(conversationId, trimmed);
83
+ return await queueEmbeddedSteer(conversationId, trimmed, expectedRunId);
84
84
  } catch (err) {
85
85
  this.log.warn({
86
86
  err,
87
87
  conversationId
88
88
  }, "steerWebchatSession failed");
89
+ if (expectedRunId !== void 0) throw err;
89
90
  return false;
90
91
  }
91
92
  }
@@ -13,7 +13,7 @@ export declare function getLastAssistantMessage(messages: AgentMessage[]): Agent
13
13
  export declare function getAssistantTurnErrorMessage(agent: Agent): string | undefined;
14
14
  /** After waitForIdle + transient retries, true if the last assistant turn ended in error. */
15
15
  export declare function isAssistantTurnFailed(agent: Agent): boolean;
16
- /** User or client aborted the assistant turn — do not try another model. */
16
+ /** Provider reported an aborted stream; the host signal determines whether the run was cancelled. */
17
17
  export declare function isAssistantTurnAborted(agent: Agent): boolean;
18
18
  /**
19
19
  * Remove trailing assistant messages that ended in error/aborted (typically one).
@@ -7,7 +7,7 @@ function isTransientLlmErrorMessage(message) {
7
7
  }
8
8
  function classifyLlmFailure(message) {
9
9
  const normalized = message.trim().toLowerCase();
10
- if (normalized === "aborted" || normalized.includes("aborterror")) return "aborted";
10
+ if (normalized === "aborted" || normalized.includes("aborterror") || normalized === "request was aborted" || normalized === "the operation was aborted") return "aborted";
11
11
  if (isContextOverflowError(message)) return "context_overflow";
12
12
  if (isTransientLlmErrorMessage(message)) return "transient_network";
13
13
  return "permanent";
@@ -19,7 +19,8 @@ function getLastAssistantMessage(messages) {
19
19
  function getAssistantTurnErrorMessage(agent) {
20
20
  const last = getLastAssistantMessage(agent.state.messages);
21
21
  if (!last) return void 0;
22
- if (last.stopReason !== "error") return void 0;
22
+ const stopReason = last.stopReason;
23
+ if (stopReason !== "error" && stopReason !== "aborted") return void 0;
23
24
  const errMsg = last.errorMessage;
24
25
  if (typeof errMsg === "string" && errMsg.trim()) return errMsg.trim();
25
26
  }
@@ -29,7 +30,7 @@ function isAssistantTurnFailed(agent) {
29
30
  if (!last) return true;
30
31
  return last.stopReason === "error";
31
32
  }
32
- /** User or client aborted the assistant turn — do not try another model. */
33
+ /** Provider reported an aborted stream; the host signal determines whether the run was cancelled. */
33
34
  function isAssistantTurnAborted(agent) {
34
35
  const last = getLastAssistantMessage(agent.state.messages);
35
36
  if (!last) return false;
@@ -78,10 +79,12 @@ async function maybeRetryTurnAfterTransientLlmFailure(agent, options) {
78
79
  while (budget.continues < maxContinues && options.shouldRetry?.() !== false) {
79
80
  const last = getLastAssistantMessage(agent.state.messages);
80
81
  if (!last) return;
81
- if (last.stopReason !== "error") return;
82
+ const sr = last.stopReason;
83
+ if (sr !== "error" && sr !== "aborted") return;
82
84
  const errMsg = String(last.errorMessage || "");
83
- const failureKind = classifyLlmFailure(errMsg);
84
- if (failureKind !== "transient_network") {
85
+ const failureKind = sr === "aborted" ? "aborted" : classifyLlmFailure(errMsg);
86
+ const providerAborted = failureKind === "aborted" && options.signal !== void 0 && !options.signal.aborted;
87
+ if (failureKind !== "transient_network" && !providerAborted) {
85
88
  options.log.warn({
86
89
  conversationId: options.conversationId,
87
90
  errorMessage: errMsg,
@@ -89,7 +92,8 @@ async function maybeRetryTurnAfterTransientLlmFailure(agent, options) {
89
92
  }, "Assistant turn ended with error (not retrying as transient)");
90
93
  return;
91
94
  }
92
- if (!canResumeAfterModelFailure(agent.state.messages)) {
95
+ const trimmed = stripTrailingErrorAssistantMessages(agent.state.messages);
96
+ if (agent.state.messages.slice(trimmed.length).some((message) => message.role === "assistant" && Array.isArray(message.content) && message.content.some((block) => block.type === "toolCall")) || !canResumeAfterModelFailure(trimmed)) {
93
97
  options.log.warn({ conversationId: options.conversationId }, "Model recovery stopped because a tool outcome is unconfirmed");
94
98
  return;
95
99
  }
@@ -102,6 +106,8 @@ async function maybeRetryTurnAfterTransientLlmFailure(agent, options) {
102
106
  conversationId: options.conversationId,
103
107
  errorMessage: errMsg,
104
108
  failureKind,
109
+ phase: "model_request_recovery",
110
+ hostSignalAborted: options.signal?.aborted ?? false,
105
111
  continueAttempt: continues,
106
112
  maxContinues,
107
113
  retryDelayMs
@@ -109,7 +115,6 @@ async function maybeRetryTurnAfterTransientLlmFailure(agent, options) {
109
115
  await waitForRetryDelay(retryDelayMs, options.signal);
110
116
  options.signal?.throwIfAborted();
111
117
  options.onRetry?.();
112
- const trimmed = stripTrailingErrorAssistantMessages(agent.state.messages);
113
118
  agent.state.messages = trimmed;
114
119
  await agent.continue();
115
120
  await agent.waitForIdle();
@@ -23,4 +23,5 @@ export declare function isAgentTurnTimeoutError(err: unknown): boolean;
23
23
  export declare function runAgentTurnWithTimeout(agent: Agent, runTurn: () => Promise<void>, timeoutMs: number, options?: {
24
24
  abortGraceMs?: number;
25
25
  timeoutExtensionMs?: () => number;
26
+ onTimeout?: (reason: AgentRunDeadlineError) => void;
26
27
  }): Promise<void>;
@@ -41,7 +41,9 @@ async function runAgentTurnWithTimeout(agent, runTurn, timeoutMs, options = {})
41
41
  timeoutId = setTimeout(expire, extensionMs);
42
42
  return;
43
43
  }
44
- reject(new AgentRunDeadlineError(`Agent turn timed out after ${effectiveTimeoutMs / 1e3}s`));
44
+ const reason = new AgentRunDeadlineError(`Agent turn timed out after ${effectiveTimeoutMs / 1e3}s`);
45
+ options.onTimeout?.(reason);
46
+ reject(reason);
45
47
  };
46
48
  timeoutId = setTimeout(expire, timeoutMs);
47
49
  });
@@ -132,7 +132,7 @@ function buildToolingSection(params) {
132
132
  "## Tooling",
133
133
  "Tool availability (filtered by policy):",
134
134
  "Use only case-sensitive names in current function schemas; prose/history examples grant no tool. Never probe invented names. Missing prerequisites: give a final blocker, without unrelated calls.",
135
- availableTools.has("tool_search") ? "Registered tools may be deferred. Use tool_search for the exact name before reporting it missing; call only after its schema loads." : "",
135
+ availableTools.has("tool_search") || availableTools.has("xopc_tool_execute") ? "Use tool_search as the single tool discovery entry. loadedTools can be called after their schemas load; externalTools require xopc_tool_describe then xopc_tool_execute. Connection candidates are recovery options, not proof of missing authorization. Respect the current execution scope." : "",
136
136
  hasPublishArtifacts && !hasRead && !hasWrite && !hasPatch && !hasExec ? "Only publication is available for workspace files. For a request to edit then publish, editing is blocked: make no publication call and explain the limitation. Publish an existing file only when the user requests that existing content without an outstanding edit." : "",
137
137
  "When a tool returns an xopc product link, reuse its exact URL in a Markdown link with a short descriptive label in the user's language (for example, [打开会话](url)). Do not invent link parameters, escape the link brackets/parentheses, or wrap a navigation link in a code span. Avoid repeating raw URLs or internal object metadata unless requested.",
138
138
  toolLines.length > 0 ? toolLines.join("\n") : "- No tools are registered for this session.",
@@ -2,13 +2,13 @@ import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { parseNoteAttachmentTarget } from "../notes/attachment-ref.js";
4
4
  import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "./agent-scope.js";
5
+ import { extractTextContent } from "./context/workspace.js";
5
6
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
6
7
  import { init_agent_session_key, resolveAgentIdFromConversationId } from "../routing/agent-session-key.js";
7
8
  import { extractProfileAgentId, resolveEffectiveAgentConfigForSession } from "../config/agent-profile.js";
8
9
  import { init_providers, resolveModel } from "../providers/index.js";
9
10
  import { configureTracing, flushTracing } from "../observability/runtime.js";
10
11
  import { getUserTimezone } from "../user-model/repository.js";
11
- import { extractTextContent } from "./context/workspace.js";
12
12
  import { resolveAgentTurnTimeoutMs } from "./orchestration/run-agent-turn-with-timeout.js";
13
13
  import { applyConfigOverrides } from "../config/runtime-overrides.js";
14
14
  import { effectiveWorkspacePathForSession } from "../session/session-workspace.js";