@xopcai/xopc 0.0.433 → 0.0.435
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/README.zh-CN.md +5 -5
- package/dist/browser-ext/dist/sidepanel.js +11 -0
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-BpYGrRXw.js → activity-store-Cwn_CNwl.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DTgOSv6G.js → agent-avatar-dicebear-Cd23LnJJ.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-display-BUH7ljEo.js → agent-avatar-display-ByzM7u9S.js} +2 -2
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-B_FAikHA.js → agent-defaults-settings-panel-B0i37diS.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-DPabZaSE.js → agent-plugin-dialog-XN-tZ-Ox.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-BAPYP1Ka.js → agents-ZDA1OaLv.js} +3 -3
- package/dist/gateway/static/root/assets/{agents-admin-api-CXCAHNPj.js → agents-admin-api-B5lKH_ps.js} +1 -1
- package/dist/gateway/static/root/assets/{api-oIK4hYkJ.js → api-B9fZL-V8.js} +1 -1
- package/dist/gateway/static/root/assets/{api-DMbimMEi.js → api-Djju8qIR.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BZ3Fy8ZR.js → app-management-settings-panel-IlyzDPJu.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DsRTj1by.js → appearance-settings-BxdFGob3.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-CxEKiOTA.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-Bg1VTieK.js → archive-plugin-4gEvotPr.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-api-CLPsgcQN.js → automation-api-4fVKv9PJ.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-result-state-CKVnR4KG.js → automation-result-state-m7PeK2kl.js} +1 -1
- package/dist/gateway/static/root/assets/automation-run-list-CJOdy_R2.js +1 -0
- package/dist/gateway/static/root/assets/{automation-task-card-D27Mw66U.js → automation-task-card-DZWhCWJa.js} +3 -3
- package/dist/gateway/static/root/assets/{automations-page-DGNTJ8lN.js → automations-page-BjbM15eY.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-CqurzLYX.js +9 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CuwSdCG5.js → binary-plugins-69WyJLNW.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Dtl2BG3t.js → block-editor-DUONDIZR.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automation-inputs-uGK086ag.js → browser-automation-inputs-DL4YPCuN.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-Da_edNNS.js → browser-automations-page-1Aq6XmRs.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-control-api-k3OOX3bS.js → browser-control-api-yjru8E7R.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-C1bSw-Jq.js → browser-settings-page-CvwpT8Um.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-DlHPLld_.js → capabilities-C7lnwKKm.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-CoeuLRt6.js → capabilities-DaeQXJT4.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-page-B5avAOUM.js +2 -0
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-CtY-bGIi.js → capabilities-settings-panel-_9yCS78i.js} +1 -1
- package/dist/gateway/static/root/assets/capability-links-DeO34GIF.js +1 -0
- package/dist/gateway/static/root/assets/{channels-Cn1MWBL_.js → channels-CoQb4HOF.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-agents-api-BB0biwc7.js → chat-agents-api-BUi_7GRo.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-chart-block-QSvjx4w6.js → chat-chart-block-CcVcKsDZ.js} +1 -1
- package/dist/gateway/static/root/assets/chat-page--wcFhTjW.js +72 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-Cd51G9eG.js → chat-terminal-dock-BMXJpPuH.js} +1 -1
- package/dist/gateway/static/root/assets/{command-palette-api-CEG10uE-.js → command-palette-api-luUjQPsh.js} +1 -1
- package/dist/gateway/static/root/assets/{composer-payload-handoff-Bogdq9Hy.js → composer-payload-handoff-B5XNxNCb.js} +1 -1
- package/dist/gateway/static/root/assets/computer-settings-page-CWtdyEJH.js +1 -0
- package/dist/gateway/static/root/assets/connected-providers-grid-2idMtk65.js +1 -0
- package/dist/gateway/static/root/assets/connection-usage-Cm_McddI.js +1 -0
- package/dist/gateway/static/root/assets/connection-usage-guide-Ddh0bfkj.js +1 -0
- package/dist/gateway/static/root/assets/{connector-service-page-k2rjyjrp.js → connector-service-page-C3msXaBk.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-api-DtvB9Cjm.js → connectors-api-NcWECWKg.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-Crb6DILX.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-CAankdQw.js → date-picker-Cfjq1hD_.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DjM73fir.js → desktop-pet-ChFn9v-3.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Rmh-GxHl.js → desktop-pet-settings-DvnVIv25.js} +1 -1
- package/dist/gateway/static/root/assets/{dev-view-store-BgW2Riyk.js → dev-view-store-DQJ61P5L.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-UdzSpNa5.js → device-pairing-wizard-KxaIL-OX.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-Rkw3f7lG.js → directory-picker-path-field-Drv864uE.js} +1 -1
- package/dist/gateway/static/root/assets/{discussion-annotation-sync-Dudoj_Fz.js → discussion-annotation-sync-DfBRkWtw.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DxIGAO23.js → extension-debug-page-DAlBIt_R.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-iframe-host-63KpX6IP.js → extension-iframe-host-Bds-5kY_.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-marketplace-api-yXNUkQDA.js → extension-marketplace-api-CZg8nBwW.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C811A_Ww.js → extension-page-ZTw-oucT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-C4jLFIgh.js → extension-provider-NKWfjpdP.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-WJSw5MT0.js → extension-settings-page-CT7PPt_q.js} +1 -1
- package/dist/gateway/static/root/assets/{file-preview-surface-zE9AcaHM.js → file-preview-surface-BcLeaSNe.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-D6cc6W6E.js → gateway-config-swr-Cq-ByXL4.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-BSRNLciy.js → gateway-realtime-DwMd2PCt.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-CHrf6-nR.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-restart-Unun5hRL.js → gateway-restart-DdiVzbkL.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DP-DV-e5.js → gateway-settings-1QUdNwrZ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-C8g666Ja.js → gateway-startup-retry-PMJi5mX4.js} +1 -1
- package/dist/gateway/static/root/assets/{global-defaults-api-BObi-1ww.js → global-defaults-api-DgzZh3wX.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-CIcs7Mzy.js → home-page-Chn7YTiD.js} +2 -2
- package/dist/gateway/static/root/assets/{image-generation-api-C2SqYNyD.js → image-generation-api-CjVpsckq.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-C8ezUkOJ.js → imports-page-CJCvZFaQ.js} +1 -1
- package/dist/gateway/static/root/assets/index-8xLWo0Tt.js +11 -0
- package/dist/gateway/static/root/assets/index-iukJWzxG.css +1 -0
- package/dist/gateway/static/root/assets/install-connector-dialog-Bo06Ry3H.js +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BRaY4-wA.js → keyboard-shortcuts-settings-BylFJeGu.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-BZtVcjF3.js → local-app-workbench-page-B3MSSFsr.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-MqP4EnJm.js → local-apps-page-BeV86rMJ.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-DTq9776a.js → local-session-drafts-jgw8UGsO.js} +2 -2
- package/dist/gateway/static/root/assets/{locale-store-B6OrWgY1.js → locale-store-CAZaC05J.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-hkHBjblX.js → logs-page-BMmSsUP5.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-DoX4eTM3.js → management-settings-Bu7T8ewk.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-DrhYZSmg.js → markdown-view-BatP4qeK.js} +1 -1
- package/dist/gateway/static/root/assets/{mcp-conversation-setup-page-BEp5E6TD.js → mcp-conversation-setup-page-rROtr0UN.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-D987i9Gc.js → media-plugins-88OV72YE.js} +1 -1
- package/dist/gateway/static/root/assets/messages-C7fckbyG.js +3 -0
- package/dist/gateway/static/root/assets/{model-selector-DXm4NS1_.js → model-selector-raBRBkN_.js} +1 -1
- package/dist/gateway/static/root/assets/{models-hub-cache-BLcha5rx.js → models-hub-cache-CzC9y3D0.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-panel-Cl851ivY.js → note-detail-panel-BvA8Vkbm.js} +3 -3
- package/dist/gateway/static/root/assets/note-image-lightbox-D6kUDDd5.js +1 -0
- package/dist/gateway/static/root/assets/{notes-api-Ddsf7FVg.js → notes-api-zXpV6UXu.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-DSwA1MU1.js → notes-page-CjYH9Kle.js} +1 -1
- package/dist/gateway/static/root/assets/{oauth-api-CMmu4DzH.js → oauth-api-DmxSaxM1.js} +1 -1
- package/dist/gateway/static/root/assets/{oauth-provider-connect-BkhnftBq.js → oauth-provider-connect-D4Gfs-Ba.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-urhQBRaN.js → page-context-capture-button-Mig3d0UX.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-draft-BuNUerth.js → page-context-draft-C4IIZaKd.js} +1 -1
- package/dist/gateway/static/root/assets/page-header-store-D7G5utVi.js +1 -0
- package/dist/gateway/static/root/assets/{personal-avatar-B49ueeZO.js → personal-avatar-DLa-CpaK.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-page-f05ceuFn.js → personal-page-BhuT79Wd.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-settings-panel-DLQxzPYr.js → personal-settings-panel-XSUkgcr2.js} +1 -1
- package/dist/gateway/static/root/assets/phone-dependencies-card-DYwnuVh3.js +1 -0
- package/dist/gateway/static/root/assets/phone-model-connection-2F32QTHA.js +1 -0
- package/dist/gateway/static/root/assets/phone-model-picker-DCVzIr0s.js +1 -0
- package/dist/gateway/static/root/assets/phone-settings-page-DJttE4id.js +1 -0
- package/dist/gateway/static/root/assets/{phone-workspace-store-DbqktZbO.js → phone-workspace-store-Dxp-KhFP.js} +1 -1
- package/dist/gateway/static/root/assets/plugin-details-dialog-tyjAjFjA.js +1 -0
- package/dist/gateway/static/root/assets/{preference-select-fields-BZWqG7pu.js → preference-select-fields-BVP3MhGK.js} +1 -1
- package/dist/gateway/static/root/assets/{product-automation-feedback-DDQUsag7.js → product-automation-feedback-DbJvv92z.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-BkRP_HmA.js → product-open-page-RImqlhCD.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-o2Y3VNE7.js → product-preview-content-DxSqrKsg.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-modal-7Ohx-7OR.js → product-preview-modal-Cw8Q8Uom.js} +2 -2
- package/dist/gateway/static/root/assets/{project-detail-page-B2RsSHya.js → project-detail-page-CuugOYfe.js} +1 -1
- package/dist/gateway/static/root/assets/{project-understanding-BIMouiYX.js → project-understanding-BMKcoUW5.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-C9R5u3tF.js → projects-page-CFsABLvs.js} +1 -1
- package/dist/gateway/static/root/assets/{providers-api-BOCkRZ7X.js → providers-api-CAeXbJNF.js} +1 -1
- package/dist/gateway/static/root/assets/{recording-upload-C6muEHEO.js → recording-upload-CfpllTe5.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-Bl2guMRg.js → registry-api-fLOqFyrz.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BceSMbCs.js → remote-access-hub-BvKOxy0L.js} +1 -1
- package/dist/gateway/static/root/assets/{resource-unavailable-CUNbPkdj.js → resource-unavailable-D15jzjV_.js} +1 -1
- package/dist/gateway/static/root/assets/route-preload-BQapekpy.js +2 -0
- package/dist/gateway/static/root/assets/{runtime-tools-api-LopLjgvu.js → runtime-tools-api-D0Nrvuqv.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-9HIPerDP.js → runtime-tools-settings-panel-CA27XgL2.js} +1 -1
- package/dist/gateway/static/root/assets/{service-recommendation-list-CoMI6MB1.js → service-recommendation-list-B0RoYLVT.js} +1 -1
- package/dist/gateway/static/root/assets/session-api-CHRP5Lwf.js +1 -0
- package/dist/gateway/static/root/assets/session-channel-icon-D1ktvt1P.js +1 -0
- package/dist/gateway/static/root/assets/session-identity-label-BP7OIYth.js +1 -0
- package/dist/gateway/static/root/assets/session-manager-DRRWwKE4.js +25 -0
- package/dist/gateway/static/root/assets/{sessions-page-BT0GdXdS.js → sessions-page-uJHS3-6F.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CZ4J3Kuy.js +1 -0
- package/dist/gateway/static/root/assets/{settings-advanced-section-CEorDLUp.js → settings-advanced-section-D-llwfSj.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-mode-store-C2LZqBES.js → settings-mode-store-BspMKc9N.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-C_Np_6qZ.js → settings-page-CedwaHM0.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-header-BAN34UQi.js → settings-page-header-LuOJvqNa.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-B5TVFBV2.js → settings-page-layout-CduQ8w4a.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-interaction-page-BYvTJW3_.js → setup-interaction-page-ujpPGl84.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-UY2dH-sK.js → setup-status-panel-BN2aCJUN.js} +1 -1
- package/dist/gateway/static/root/assets/{share-link-dialog-BMcXyzr2.js → share-link-dialog-CTATUaa4.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-UQ6eUM2_.js → share-preview-page-Dq0J3VgS.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-api-DOeDN6Tm.js → shares-api-zegE8pSE.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-W8XhuAoL.js → shares-settings-DXpvsRXq.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-Do_c0d9n.js → skill-api-DCL1EN7f.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-list-api-DpHaXI2l.js → skill-list-api-Bv0mmHbu.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-DDRd9IJ2.js → skill-reload-api-DPZbadiO.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-CaeJVKhO.js → skills-page-DMC7Gaku.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-DYWlWPJL.js → system-settings-panel-BYFUhlqG.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-De0qD7xw.js → task-detail-page-_Og3plZL.js} +3 -3
- package/dist/gateway/static/root/assets/{task-result-evidence-CICR5K1t.js → task-result-evidence-Bxm8-H0B.js} +1 -1
- package/dist/gateway/static/root/assets/{terminal-panel-store-BbWUcQe7.js → terminal-panel-store-Djf9l2qZ.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-TkG5mo0p.js → theme-store-8GFVtotZ.js} +1 -1
- package/dist/gateway/static/root/assets/{tracing-settings-page-CYXEy4EG.js → tracing-settings-page-oWW3SBZ4.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-DquDm6U2.js → tunnel-api-D-mEsSGF.js} +1 -1
- package/dist/gateway/static/root/assets/{understanding-activity-store-Ot3wZ3oQ.js → understanding-activity-store-CvDjsd0I.js} +1 -1
- package/dist/gateway/static/root/assets/{understanding-refresh-store-C5KYFMaC.js → understanding-refresh-store-DzOZJm7A.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-1xFO4smo.js → usage-page-z-o6Uuev.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-HL8XRNR8.js → use-autosave-BVYS8UoK.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-XRlQBdNF.js → use-composer-attachments-lecOV2q5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-CW956CXS.js → use-file-preview-expanded-nd_CuFsd.js} +2 -2
- package/dist/gateway/static/root/assets/{use-personal-profile-202s6tJt.js → use-personal-profile-CQi2ZCxV.js} +1 -1
- package/dist/gateway/static/root/assets/{use-workspace-tree-CjydkmH1.js → use-workspace-tree-BiaddkzX.js} +1 -1
- package/dist/gateway/static/root/assets/{user-model-page-OGPXx3pe.js → user-model-page-Bks1n0Nj.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CxFu4MEA.js → voice-api-key-field-BbW8NFeZ.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-MHe5Pn-A.js → voice-config-api-jSMzZWWy.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-input-shortcut-events-B9xc1oK8.js → voice-input-shortcut-events-_SgYmx7X.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-transcribe-api-CVEcB6Pe.js → voice-transcribe-api-BJCfiRFU.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-C-JoAg2D.js → work-discovery-overlay-DSTSNyU7.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-B5Kx29Ru.js → work-discovery-page-Dd_QJJvb.js} +1 -1
- package/dist/gateway/static/root/assets/{working-directory-picker-modal-DGp9cNzH.js → working-directory-picker-modal-q39BUcJ6.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-api-HBXn8pL9.js → workspace-api-Di2OmCvz.js} +2 -2
- package/dist/gateway/static/root/assets/workspace-editor-agent-store-B2r9wlix.js +1 -0
- package/dist/gateway/static/root/assets/{workspace-file-preview-dialog-3cpwSG2w.js → workspace-file-preview-dialog-BUGNT765.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-open-location-menu-D0VOFvuP.js → workspace-open-location-menu-bMSvmQW7.js} +1 -1
- package/dist/gateway/static/root/assets/{xopc-cloud-account-card-BkdW2p3v.js → xopc-cloud-account-card-Bbe19Del.js} +1 -1
- package/dist/gateway/static/root/index.html +87 -85
- package/dist/package.js +1 -1
- package/dist/packages/computer-control-contract/src/index.js +33 -3
- package/dist/packages/gateway-contract/src/session-identity.js +2 -1
- package/dist/packages/gateway-contract/src/session-input-command.js +19 -2
- package/dist/packages/gateway-contract/src/specialists.js +1 -0
- package/dist/src/agent/embedded/execution-tool-policy.d.ts +1 -1
- package/dist/src/agent/embedded/execution-tool-policy.js +2 -2
- package/dist/src/agent/embedded/run-for-session.js +23 -8
- package/dist/src/agent/embedded/run-turn.js +30 -7
- package/dist/src/agent/embedded/runs.d.ts +2 -2
- package/dist/src/agent/embedded/runs.js +4 -4
- package/dist/src/agent/embedded/session-runner.js +26 -11
- package/dist/src/agent/embedded/tool-search-extension.d.ts +8 -2
- package/dist/src/agent/embedded/tool-search-extension.js +122 -30
- package/dist/src/agent/external-tools/cliProvider.d.ts +10 -9
- package/dist/src/agent/external-tools/cliProvider.js +24 -4
- package/dist/src/agent/external-tools/composio-provider.d.ts +3 -3
- package/dist/src/agent/external-tools/composio-provider.js +6 -3
- package/dist/src/agent/external-tools/discovery.d.ts +47 -0
- package/dist/src/agent/external-tools/discovery.js +56 -0
- package/dist/src/agent/external-tools/gateway-tools.js +26 -46
- package/dist/src/agent/external-tools/index.d.ts +1 -0
- package/dist/src/agent/external-tools/index.js +7 -0
- package/dist/src/agent/external-tools/personal-request-scope.d.ts +7 -0
- package/dist/src/agent/external-tools/personal-request-scope.js +83 -0
- package/dist/src/agent/external-tools/read-policy.js +5 -4
- package/dist/src/agent/external-tools/service.d.ts +2 -0
- package/dist/src/agent/external-tools/service.js +22 -3
- package/dist/src/agent/external-tools/tool-registry.d.ts +6 -0
- package/dist/src/agent/external-tools/types.d.ts +7 -2
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.js +3 -2
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +1 -1
- package/dist/src/agent/orchestration/llm-turn-retry.js +13 -8
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +1 -0
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +3 -1
- package/dist/src/agent/prompt/sections/tooling.js +1 -1
- package/dist/src/agent/tool-manuals/computer.d.ts +1 -1
- package/dist/src/agent/tool-manuals/computer.js +6 -4
- package/dist/src/agent/tool-manuals/phone.d.ts +1 -1
- package/dist/src/agent/tool-manuals/phone.js +4 -4
- package/dist/src/agent/tool-manuals/xopc-configuration.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-configuration.js +4 -2
- package/dist/src/agent/tools/computer-use-tool.js +7 -6
- package/dist/src/agent/tools/delegation-policy.js +1 -0
- package/dist/src/agent/tools/factory.js +4 -2
- package/dist/src/agent/tools/phone-use-tool.js +2 -2
- package/dist/src/agent/tools/web.js +22 -3
- package/dist/src/agent-matching/service.js +2 -2
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/computer/batch.d.ts +108 -0
- package/dist/src/computer/batch.js +125 -0
- package/dist/src/computer/broker.d.ts +30 -2
- package/dist/src/computer/broker.js +109 -17
- package/dist/src/computer/diagnostics.d.ts +5 -1
- package/dist/src/computer/diagnostics.js +22 -3
- package/dist/src/computer/errors.d.ts +15 -0
- package/dist/src/computer/errors.js +59 -3
- package/dist/src/computer/model-adapter.d.ts +58 -0
- package/dist/src/computer/model-adapter.js +112 -66
- package/dist/src/computer/native-errors.d.ts +2 -0
- package/dist/src/computer/native-errors.js +13 -0
- package/dist/src/computer/program-runtime.d.ts +1 -1
- package/dist/src/computer/program-runtime.js +1 -0
- package/dist/src/computer/runtime.d.ts +11 -0
- package/dist/src/computer/runtime.js +102 -34
- package/dist/src/computer/semantic-actions.js +4 -0
- package/dist/src/config/schema.d.ts +6 -0
- package/dist/src/extensions/agent-plugins/formats.js +2 -1
- package/dist/src/extensions/agent-plugins/inventory.d.ts +2 -0
- package/dist/src/extensions/agent-plugins/inventory.js +4 -1
- package/dist/src/extensions/agent-plugins/validation.d.ts +1 -0
- package/dist/src/extensions/agent-plugins/validation.js +2 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/phone-dependencies.js +26 -5
- package/dist/src/gateway/hono/routes/phone-setup.js +42 -16
- package/dist/src/gateway/hono/routes/phone.js +22 -7
- package/dist/src/gateway/hono/routes/session-command-handler.js +9 -0
- package/dist/src/gateway/hono/routes/session-input-control.d.ts +3 -0
- package/dist/src/gateway/hono/routes/session-input-control.js +37 -0
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +12 -0
- package/dist/src/gateway/hono/routes/session-input-handler.js +22 -0
- package/dist/src/gateway/hono/routes/sessions.js +4 -0
- package/dist/src/gateway/service/agent-runner.js +5 -4
- package/dist/src/gateway/service/config-coordinator.d.ts +6 -0
- package/dist/src/gateway/service/session-input-coordinator.d.ts +6 -3
- package/dist/src/gateway/service/session-input-coordinator.js +47 -6
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +8 -5
- package/dist/src/home-intelligence/host.js +2 -2
- package/dist/src/personal-agent/capability-service.js +1 -1
- package/dist/src/personal-agent/request-access.d.ts +2 -0
- package/dist/src/personal-agent/request-access.js +22 -2
- package/dist/src/personal-agent/request-service.js +2 -2
- package/dist/src/personal-agent/specialist-capabilities.d.ts +2 -0
- package/dist/src/personal-agent/specialist-capabilities.js +9 -3
- package/dist/src/phone/adb-driver.d.ts +3 -0
- package/dist/src/phone/adb-driver.js +29 -0
- package/dist/src/phone/contracts.d.ts +14 -2
- package/dist/src/phone/contracts.js +8 -1
- package/dist/src/phone/gui-protocol.js +1 -1
- package/dist/src/phone/hdc-driver.d.ts +30 -0
- package/dist/src/phone/hdc-driver.js +331 -0
- package/dist/src/phone/hdc-video-bridge.d.ts +2 -0
- package/dist/src/phone/hdc-video-bridge.js +91 -0
- package/dist/src/phone/hdc-video-tools.d.ts +15 -0
- package/dist/src/phone/hdc-video-tools.js +123 -0
- package/dist/src/phone/hdc-video.d.ts +69 -0
- package/dist/src/phone/hdc-video.js +350 -0
- package/dist/src/phone/interactive-session.js +1 -1
- package/dist/src/phone/live-provider.d.ts +6 -0
- package/dist/src/phone/live-provider.js +1 -0
- package/dist/src/phone/model-adapter.d.ts +3 -0
- package/dist/src/phone/model-adapter.js +5 -3
- package/dist/src/phone/repository.js +2 -1
- package/dist/src/phone/runtime.d.ts +10 -4
- package/dist/src/phone/runtime.js +151 -85
- package/dist/src/phone/setup/service.d.ts +8 -6
- package/dist/src/phone/setup/service.js +33 -16
- package/dist/src/platform/client.d.ts +1 -1
- package/dist/src/platform/contracts.d.ts +1 -1
- package/dist/src/process/phone-process.d.ts +1 -1
- package/dist/src/process/phone-process.js +2 -2
- package/dist/src/runtime-tools/downloader.d.ts +1 -0
- package/dist/src/runtime-tools/downloader.js +8 -4
- package/dist/src/runtime-tools/harmony-dependencies.d.ts +24 -0
- package/dist/src/runtime-tools/harmony-dependencies.js +272 -0
- package/dist/src/runtime-tools/harmony-dependency-catalog.d.ts +4 -0
- package/dist/src/runtime-tools/harmony-dependency-catalog.js +54 -0
- package/dist/src/runtime-tools/harmony-paths.d.ts +9 -0
- package/dist/src/runtime-tools/harmony-paths.js +15 -0
- package/dist/src/runtime-tools/hdc-dependency-catalog.d.ts +8 -0
- package/dist/src/runtime-tools/hdc-dependency-catalog.js +83 -0
- package/dist/src/runtime-tools/hdc-files.d.ts +14 -0
- package/dist/src/runtime-tools/hdc-files.js +87 -0
- package/dist/src/runtime-tools/phone-dependencies.d.ts +6 -1
- package/dist/src/runtime-tools/phone-dependencies.js +20 -2
- package/dist/src/runtime-tools/phone-dependency-catalog.d.ts +10 -1
- package/dist/src/runtime-tools/phone-dependency-catalog.js +2 -0
- package/dist/src/runtime-tools/types.d.ts +1 -1
- package/dist/src/storage/sqlite/schema.d.ts +2 -2
- package/dist/src/storage/sqlite/schema.js +7 -7
- package/dist/src/storage/sqlite/schema.sql +16 -0
- package/dist/src/storage/sqlite/session-creation-repository.js +3 -0
- package/dist/src/storage/sqlite/session-input-control-repository.d.ts +12 -0
- package/dist/src/storage/sqlite/session-input-control-repository.js +83 -0
- package/dist/src/storage/sqlite/session-input-repository.d.ts +2 -0
- package/dist/src/storage/sqlite/session-input-repository.js +17 -5
- package/dist/src/storage/sqlite/session-repository.js +1 -0
- package/dist/src/storage/sqlite/session-turn-replace-repository.d.ts +2 -0
- package/dist/src/storage/sqlite/session-turn-replace-repository.js +14 -2
- package/dist/src/storage/sqlite/upgrades/262_session_input_control.sql +15 -0
- package/package.json +2 -2
- package/skills/tools/configure-xopc/SKILL.md +2 -2
- package/skills/tools/configure-xopc/references/phone/acceptance.md +3 -2
- package/skills/tools/configure-xopc/references/phone/dependencies.md +18 -2
- package/skills/tools/configure-xopc/references/phone/harmonyos.md +16 -0
- package/skills/tools/configure-xopc/references/phone/overview.md +2 -2
- package/skills/tools/configure-xopc/references/scene-index.md +2 -2
- package/dist/gateway/static/root/assets/apps-page-D-n71lO1.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-DWDWy-SG.js +0 -9
- package/dist/gateway/static/root/assets/capabilities-page-IcwojmJK.js +0 -2
- package/dist/gateway/static/root/assets/capability-links-DzQWK1Fh.js +0 -1
- package/dist/gateway/static/root/assets/chat-page-CwP4OMdW.js +0 -72
- package/dist/gateway/static/root/assets/computer-settings-page-DyAlOzqY.js +0 -1
- package/dist/gateway/static/root/assets/connected-providers-grid-D0lXg22c.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DI_Q0CKz.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-BFeFfApQ.js +0 -1
- package/dist/gateway/static/root/assets/index-Cz-VjTNd.css +0 -1
- package/dist/gateway/static/root/assets/index-D1_PUrJf.js +0 -11
- package/dist/gateway/static/root/assets/install-connector-dialog-Cn4nRSyt.js +0 -1
- package/dist/gateway/static/root/assets/list-tree-B0OMswgM.js +0 -1
- package/dist/gateway/static/root/assets/messages-jwdBhfL9.js +0 -3
- package/dist/gateway/static/root/assets/note-image-lightbox-DGYRJS03.js +0 -1
- package/dist/gateway/static/root/assets/page-header-store-CEn_kPsn.js +0 -1
- package/dist/gateway/static/root/assets/phone-dependencies-card-DjmC1Z5j.js +0 -1
- package/dist/gateway/static/root/assets/phone-model-connection-BRjHSgYn.js +0 -1
- package/dist/gateway/static/root/assets/phone-model-picker-DgIiWLhR.js +0 -1
- package/dist/gateway/static/root/assets/phone-settings-page-DCZGCL_z.js +0 -1
- package/dist/gateway/static/root/assets/plugin-details-dialog-D4tGKip4.js +0 -1
- package/dist/gateway/static/root/assets/route-preload-C1BKDjnu.js +0 -2
- package/dist/gateway/static/root/assets/session-api-Bfmlmn9F.js +0 -1
- package/dist/gateway/static/root/assets/session-channel-icon-SsY70Z6t.js +0 -1
- package/dist/gateway/static/root/assets/session-identity-label-B7sgG1PE.js +0 -1
- package/dist/gateway/static/root/assets/session-manager-X4UHOjjO.js +0 -25
- package/dist/gateway/static/root/assets/settings-advanced-gate-Dk9c-Z5e.js +0 -1
- 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 };
|
|
@@ -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,
|
|
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
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
...
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
/**
|
|
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
|
-
|
|
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
|
-
/**
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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") ? "
|
|
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.",
|