@openhands/agent-canvas 1.0.0-alpha.9 → 1.0.0-beta.1
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 +2 -2
- package/bin/agent-canvas.mjs +22 -2
- package/build/assets/{QueryClientProvider-B7kl84Kj.js → QueryClientProvider-CkGuhXg-.js} +1 -1
- package/build/assets/{Trans-1j65oy9O.js → Trans-Cvm_-SMi.js} +1 -1
- package/build/assets/acp-providers-CbiRekh9.js +1 -0
- package/build/assets/{acp-route-guard-CQTmeJwM.js → acp-route-guard-B2yoBZ_4.js} +1 -1
- package/build/assets/{active-backend-context-TVbjnvmP.js → active-backend-context-cCM1vYYZ.js} +1 -1
- package/build/assets/add-backend-modal-DIUQzMPa.js +1 -0
- package/build/assets/agent-server-client-options-Bc5ZorQZ.js +1 -0
- package/build/assets/agent-server-compatibility-BlkUsrX2.js +1 -0
- package/build/assets/agent-server-conversation-service.api-DFvqqEDo.js +5 -0
- package/build/assets/{agent-settings-B247S9G3.js → agent-settings-CnGSCmK8.js} +1 -1
- package/build/assets/{alert-banner-BWoqueRw.js → alert-banner-DtzAX654.js} +1 -1
- package/build/assets/{analytics-consent-form-modal-C7sXfxRh.js → analytics-consent-form-modal-CHZ3I37v.js} +1 -1
- package/build/assets/api-key-entry-screen-B2gynaCp.js +1 -0
- package/build/assets/{app-settings-BVeSaty9.js → app-settings-Db9ITeJH.js} +1 -1
- package/build/assets/{automation-detail-R-99FUce.js → automation-detail-Di7EOIZD.js} +1 -1
- package/build/assets/{automations-list-Dfu2c-_D.js → automations-list-IsIWdDiw.js} +1 -1
- package/build/assets/{backend-form-modal-DxYjqqAK.js → backend-form-modal-Dnk33xA_.js} +1 -1
- package/build/assets/{backend-synced-settings-badge-nAfiUWvM.js → backend-synced-settings-badge-Dc6c7GT4.js} +1 -1
- package/build/assets/{base-modal-CQRvRHu1.js → base-modal-_dYTw1ri.js} +1 -1
- package/build/assets/{brand-button-C2nEKopC.js → brand-button-Br7f0kZJ.js} +1 -1
- package/build/assets/{browser-HrYc5Gce.js → browser-D810xUYt.js} +2 -2
- package/build/assets/browser-store-Couc4S5D.js +1 -0
- package/build/assets/browser-tab-B-aIqXRl.js +1 -0
- package/build/assets/{checkmark-BJJrZUF8.js → checkmark-DL7acQA7.js} +1 -1
- package/build/assets/{chevron-left-small-CSh-sE9L.js → chevron-left-small-CVWf8TI6.js} +1 -1
- package/build/assets/{circle-plus-check-toggle-qs8Va1cC.js → circle-plus-check-toggle-P7ZZToV4.js} +1 -1
- package/build/assets/{clock-ZR4Kn-_Y.js → clock-BRjCgHTc.js} +1 -1
- package/build/assets/{close-BdmyeRqS.js → close-B5LROHR3.js} +1 -1
- package/build/assets/{combobox-caret-B53O9Hsq.js → combobox-caret-to1O8irE.js} +1 -1
- package/build/assets/{condenser-settings-A35V3yng.js → condenser-settings-wnEKhBof.js} +1 -1
- package/build/assets/{confirmation-modal-C9-La0h3.js → confirmation-modal-Dau3w_sa.js} +1 -1
- package/build/assets/{context-menu-list-item-Buu9nc0q.js → context-menu-list-item-CWNFpuiC.js} +1 -1
- package/build/assets/conversation-HlncOV7n.js +19 -0
- package/build/assets/conversation-MtnkpqA9.js +1 -0
- package/build/assets/conversation-panel-DxnM6tRe.js +1 -0
- package/build/assets/{conversation-service.api--f8WglOC.js → conversation-service.api-nb5W1PqR.js} +1 -1
- package/build/assets/{conversation-tab-empty-state-D8dNvo-V.js → conversation-tab-empty-state-DyssnnWa.js} +1 -1
- package/build/assets/conversation-websocket-context-C8_PkGLi.js +3 -0
- package/build/assets/{copy-C7Ti2d8C.js → copy-DYgmUdIw.js} +1 -1
- package/build/assets/{custom-toast-handlers-BOc3qeQ7.js → custom-toast-handlers-C-SZFmto.js} +1 -1
- package/build/assets/declaration-BNMqORFE.js +1 -0
- package/build/assets/{device-verify-CMusn8nX.js → device-verify-DqDlphsG.js} +1 -1
- package/build/assets/{dist-DZHSA2e6.js → dist-C6t0EXL7.js} +1 -1
- package/build/assets/{edit-automation-modal-Dnjxbjn7.js → edit-automation-modal-BGzR3nfZ.js} +1 -1
- package/build/assets/{ellipsis-button-ugUATsNo.js → ellipsis-button-ZyLMPURn.js} +1 -1
- package/build/assets/{entry.client-CqqXOSvd.js → entry.client-1VMHpktY.js} +2 -2
- package/build/assets/{enum-filter-dropdown-1vpOGySB.js → enum-filter-dropdown-CEgCdu4A.js} +1 -1
- package/build/assets/{environment-switch-overlay-CTCTQikP.js → environment-switch-overlay-XL8yCGP6.js} +1 -1
- package/build/assets/{extensions-hub-BSUseHVF.js → extensions-hub-C651jsVh.js} +1 -1
- package/build/assets/{extensions-navigation-CT1kc1u_.js → extensions-navigation-BYR8Giqq.js} +1 -1
- package/build/assets/files-tab-BhnLgimi.js +1 -0
- package/build/assets/{folder-0WSMImNX.js → folder-ZZJVGgd7.js} +1 -1
- package/build/assets/{git-control-bar-branch-button-C8u5rzjc.js → git-control-bar-branch-button-M34A5_vX.js} +2 -2
- package/build/assets/{git-provider-icon-D-a-rcLm.js → git-provider-icon-D5dCNy-k.js} +1 -1
- package/build/assets/home-CYQv7yc_.js +1 -0
- package/build/assets/{i18n-DjAGhTis.js → i18n-CTohRuoO.js} +1 -1
- package/build/assets/install-server-modal-f31_CLrW.js +1 -0
- package/build/assets/{launch-B2mbfOSm.js → launch-DHEUYn2A.js} +1 -1
- package/build/assets/{lesson-plan-DRYG5SLI.js → lesson-plan-dH5Bj0pN.js} +1 -1
- package/build/assets/{link-external-C9d6Fo3x.js → link-external-D2POYx4c.js} +1 -1
- package/build/assets/{llm-client-ChQzg4wX.js → llm-client-DaH1TuyR.js} +1 -1
- package/build/assets/llm-settings-Bql-vydt.js +1 -0
- package/build/assets/llm-settings-C_tal6Ds.js +1 -0
- package/build/assets/{loading-spinner-C04FGh14.js → loading-spinner-BPtYORNK.js} +1 -1
- package/build/assets/{manage-backends-modal-s22zCdEW.js → manage-backends-modal-l7RkKfwX.js} +1 -1
- package/build/assets/{manage-workspaces-modal-C5EuW8m1.js → manage-workspaces-modal-DhKF_8z3.js} +1 -1
- package/build/assets/manifest-9fee01b9.js +1 -0
- package/build/assets/{markdown-renderer-CEX4Becj.js → markdown-renderer-DMzf2i4x.js} +1 -1
- package/build/assets/mcp-D2onbwVk.js +9 -0
- package/build/assets/{messages-6aOyUu3r.js → messages-BMzyOW2V.js} +1 -1
- package/build/assets/{modal-backdrop-DTYGVmOR.js → modal-backdrop-BAbgYsqB.js} +1 -1
- package/build/assets/{modal-body-YElmM1dV.js → modal-body-BI6Ru2Qr.js} +1 -1
- package/build/assets/{modal-close-button-C_GpQt9F.js → modal-close-button-t1Gh3qmL.js} +1 -1
- package/build/assets/{model-selector-DeMmw-Xa.js → model-selector-SM9IUz-q.js} +1 -1
- package/build/assets/{mutation-Cz7N4XAo.js → mutation-D0OogFCz.js} +1 -1
- package/build/assets/{navigation-context-DeIPtGPp.js → navigation-context-D0YWpT8d.js} +1 -1
- package/build/assets/{navigation-link-C9JD4PYD.js → navigation-link-Cn7KP3c5.js} +1 -1
- package/build/assets/{openhands-logo-CI5Fhn1W.js → openhands-logo-CnrF6LKb.js} +1 -1
- package/build/assets/{option-service.api-DsI1UW7N.js → option-service.api-KvY_mZMY.js} +1 -1
- package/build/assets/{organization-service.api-COwMPFg5.js → organization-service.api-DzYTHTYC.js} +1 -1
- package/build/assets/{path-utils-BVbe598W.js → path-utils-YohAYyMv.js} +1 -1
- package/build/assets/{plan-components-DEjMuDDG.js → plan-components-atxXCF0R.js} +1 -1
- package/build/assets/{planner-tab-bN6r1G-1.js → planner-tab-CFc-hV07.js} +1 -1
- package/build/assets/{profiles-client-BGkKEV9j.js → profiles-client-D6IkTJof.js} +1 -1
- package/build/assets/{providers-DXvCAN_u.js → providers-Bx6EfrzZ.js} +1 -1
- package/build/assets/{proxy-CurRmrqf.js → proxy-CxydCnis.js} +1 -1
- package/build/assets/{query-client-config-Ba7qAAoO.js → query-client-config-B7u9asM0.js} +1 -1
- package/build/assets/{recommended-automations-launcher-mJhK6Atl.js → recommended-automations-launcher-sgvfU62c.js} +3 -3
- package/build/assets/root-BXWU99D-.js +2 -0
- package/build/assets/{root-layout-BjVwHmta.js → root-layout-DVepR4To.js} +2 -2
- package/build/assets/sdk-section-page-DOIKvwSL.js +1 -0
- package/build/assets/{sdk-settings-schema-QBYH-ONX.js → sdk-settings-schema-DsUf9wu1.js} +1 -1
- package/build/assets/{search-Cq_cFrDt.js → search-27Owlc3A.js} +1 -1
- package/build/assets/{secrets-service-Bwd5DeUs.js → secrets-service-BsnKFc2x.js} +1 -1
- package/build/assets/secrets-settings-Bz_UohPJ.js +1 -0
- package/build/assets/{server-client-C3mC8Hl3.js → server-client-DyAQ3NZ_.js} +1 -1
- package/build/assets/{settings-D7E2U5tK.js → settings-BYkVX7vW.js} +1 -1
- package/build/assets/{settings-client-CwjfwoiB.js → settings-client-C73C7IgV.js} +1 -1
- package/build/assets/{settings-dropdown-input-VwAXNrOb.js → settings-dropdown-input-BJYvGdg-.js} +1 -1
- package/build/assets/{settings-gear-BJwWR1ej.js → settings-gear-C77PgE_O.js} +1 -1
- package/build/assets/{settings-index-J-3BNR0W.js → settings-index-Dz0BmdJD.js} +1 -1
- package/build/assets/{settings-input-DBywAnA7.js → settings-input-Bn7F5C75.js} +1 -1
- package/build/assets/{settings-list-classes-BOS092DR.js → settings-list-classes-Bf80tWtc.js} +1 -1
- package/build/assets/{settings-modal-B8vgWDTe.js → settings-modal-Brzgh5Yw.js} +1 -1
- package/build/assets/{settings-section-header-context-32x6WTyL.js → settings-section-header-context-BgZe5YkE.js} +1 -1
- package/build/assets/{settings-service.api-FvJGK45W.js → settings-service.api-CZ3uWx4v.js} +1 -1
- package/build/assets/{settings-switch-DTKmHC8F.js → settings-switch-BeIKrWms.js} +1 -1
- package/build/assets/{shared-conversation-EZV0FRIf.js → shared-conversation-DChOdb0t.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-BnbzzpQl.js → sidebar-mobile-menu-toggle-BWuf4PRH.js} +1 -1
- package/build/assets/{sidebar-nav-link-CnWoZcwc.js → sidebar-nav-link-BGjiJq-4.js} +1 -1
- package/build/assets/{skill-card-pill-row-tZ599jli.js → skill-card-pill-row-DF1axQCG.js} +1 -1
- package/build/assets/{skills-ZyAO5dyK.js → skills-ChIKZPK4.js} +1 -1
- package/build/assets/{skills-plugins-BSRz041I.js → skills-plugins-CcI_19lM.js} +1 -1
- package/build/assets/{skills-settings-CG2hu34D.js → skills-settings-DlA5hlXw.js} +1 -1
- package/build/assets/{status-CsatcFbK.js → status-hp6M6E7E.js} +1 -1
- package/build/assets/{styled-tooltip-CS3mB_1X.js → styled-tooltip-CBzrri6o.js} +1 -1
- package/build/assets/{switch-skeleton-C-CfhYYV.js → switch-skeleton-DnC9wLp7.js} +1 -1
- package/build/assets/{task-list-tab-465DDju0.js → task-list-tab-DUJn1sgz.js} +1 -1
- package/build/assets/{terminal-CcgBEVnC.js → terminal-CRf9S0Z2.js} +1 -1
- package/build/assets/{terminal-LNa-iU5c.js → terminal-RmuaSdhJ.js} +1 -1
- package/build/assets/{toggle-switch-k-IZCDbt.js → toggle-switch-Pvyp2RAN.js} +1 -1
- package/build/assets/{typography-vVUMoNUg.js → typography-gpuWmrQO.js} +1 -1
- package/build/assets/{u-check-circle-DplbarS5.js → u-check-circle-IUIfACQQ.js} +1 -1
- package/build/assets/{u-check-circle-half-yDuiSZHC.js → u-check-circle-half-C1YxB6py.js} +1 -1
- package/build/assets/{u-circuit-C9tYkpeK.js → u-circuit-BmVikJHu.js} +1 -1
- package/build/assets/{u-edit-KAUlufD8.js → u-edit-CFvXHqZk.js} +1 -1
- package/build/assets/use-active-conversation-Db3IWSPK.js +1 -0
- package/build/assets/{use-agent-settings-schema-Bvp5UzV8.js → use-agent-settings-schema-33Un7UF2.js} +1 -1
- package/build/assets/{use-agent-state-D2C9SeGw.js → use-agent-state-Bn8vS5sY.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-DWVar4st.js → use-cloud-current-user-id-CvkXFnTT.js} +1 -1
- package/build/assets/use-config-Co1O8-Ey.js +1 -0
- package/build/assets/{use-create-conversation-BEZg__Vv.js → use-create-conversation-CKS3EAHu.js} +1 -1
- package/build/assets/use-get-secrets-DuhdIA59.js +1 -0
- package/build/assets/{use-handle-plan-click-uOpew2LO.js → use-handle-plan-click-C9zJpK8A.js} +1 -1
- package/build/assets/use-is-authed-BggE5wPj.js +1 -0
- package/build/assets/{use-is-creating-conversation-DhDeeWfA.js → use-is-creating-conversation-BZ5hB_Bg.js} +1 -1
- package/build/assets/{use-launch-skill-in-chat-DVGPFrbI.js → use-launch-skill-in-chat-fNN_xGZG.js} +1 -1
- package/build/assets/{use-llm-profiles-O4a9V6RC.js → use-llm-profiles-DDOol3gK.js} +1 -1
- package/build/assets/use-runtime-is-ready-CQCE3xZC.js +1 -0
- package/build/assets/{use-save-settings-CEEKSTWG.js → use-save-settings-VUrj_QNG.js} +1 -1
- package/build/assets/{use-settings-DQ7Oo1Hj.js → use-settings-DQIZmIov.js} +1 -1
- package/build/assets/{use-settings-nav-items-YmrXrjn9.js → use-settings-nav-items-1ZvovKSr.js} +1 -1
- package/build/assets/{use-skills-BIvlWblA.js → use-skills-DAMLFjKU.js} +1 -1
- package/build/assets/use-unified-vscode-url-sZt29HrC.js +1 -0
- package/build/assets/use-user-conversation-DfgEB6RW.js +1 -0
- package/build/assets/{useMutation-B4OUESdw.js → useMutation-DqrumCWD.js} +1 -1
- package/build/assets/{useTranslation-CpIcQBq6.js → useTranslation-DCOdSSMl.js} +1 -1
- package/build/assets/{utils-D-HX7JCe.js → utils-i18rdUj2.js} +1 -1
- package/build/assets/v4-CNn21NXa.js +1 -0
- package/build/assets/{vendor~browser-Dr71AdrG.js → vendor~browser-BNjNhjFU.js} +1 -1
- package/build/assets/{vendor~browser-tab-BiVxfjJo.js → vendor~browser-tab-BgwV1mxF.js} +1 -1
- package/build/assets/{vendor~conversation-panel~conversation-BlCIz9XQ.js → vendor~conversation-panel~conversation-a9SyrrhV.js} +1 -1
- package/build/assets/{vendor~files-tab-DtLR-QD9.js → vendor~files-tab-BGKayPiK.js} +1 -1
- package/build/assets/{vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Ds9quNZ9.js → vendor~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-smY2r837.js} +1 -1
- package/build/assets/{vendor~home~mcp~automations-list-C5PoHCy6.js → vendor~home~mcp~automations-list-Ccy2I0KU.js} +1 -1
- package/build/assets/{vendor~home~mcp~automations-list-BUBGGGYz.js → vendor~home~mcp~automations-list-DoPfwaXj.js} +1 -1
- package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-CGlZoBKa.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-DbfELDJu.js} +2 -2
- package/build/assets/{vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-DE11mPxp.js → vendor~home~mcp~llm-settings~agent-settings~condenser-settings~verification-settings~app-se~ocm3mykx-Z3nsiNNq.js} +1 -1
- package/build/assets/{vendor~launch-Dg--Ssk6.js → vendor~launch-vdeRTWFu.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-DrXgiSCq.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-DW31UyBp.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-8b8V5bfO.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-BkQGKpye.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-Dy7L6fMG.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~iguv7bgw-DzIXV3Ui.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-D40EXhZx.js → vendor~root-layout~home~conversation-panel~conversation~extensions-hub~skills-settings~skil~k776hupu-Bbs7UJ5U.js} +2 -2
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-CHrEOFl6.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-DTwbEEcX.js} +1 -1
- package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-BP1SKG0F.js → vendor~root-layout~home~conversation-panel~conversation~shared-conversation~alert-banner~pl~rqjteh0a-d2oallMa.js} +1 -1
- package/build/assets/{vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~kyz9p27j-CyUbhpbm.js → vendor~root~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-s~f2l2lr17-CDXvdvb2.js} +1 -1
- package/build/assets/{verification-settings-BtlTiHP8.js → verification-settings-CsbvQcYS.js} +1 -1
- package/build/assets/{vscode-tab-B0vdh9gU.js → vscode-tab-Zb-QbTuV.js} +1 -1
- package/build/assets/{waiting-for-runtime-message-DWPl_Yby.js → waiting-for-runtime-message-CntjExbU.js} +1 -1
- package/build/assets/{x-mark-CWI0f9yI.js → x-mark-CrpjscNc.js} +1 -1
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +7 -0
- package/build/locales/ca/openhands.json +7 -0
- package/build/locales/de/openhands.json +7 -0
- package/build/locales/en/openhands.json +7 -0
- package/build/locales/es/openhands.json +7 -0
- package/build/locales/fr/openhands.json +7 -0
- package/build/locales/it/openhands.json +7 -0
- package/build/locales/ja/openhands.json +7 -0
- package/build/locales/ko-KR/openhands.json +7 -0
- package/build/locales/no/openhands.json +7 -0
- package/build/locales/pt/openhands.json +7 -0
- package/build/locales/tr/openhands.json +7 -0
- package/build/locales/uk/openhands.json +7 -0
- package/build/locales/zh-CN/openhands.json +7 -0
- package/build/locales/zh-TW/openhands.json +7 -0
- package/config/defaults.json +0 -4
- package/dist/api/agent-server-adapter.cjs +1 -1
- package/dist/api/agent-server-adapter.cjs.map +1 -1
- package/dist/api/agent-server-adapter.js +1 -1
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/agent-server-compatibility.cjs +1 -1
- package/dist/api/agent-server-compatibility.cjs.map +1 -1
- package/dist/api/agent-server-compatibility.d.ts +16 -0
- package/dist/api/agent-server-compatibility.js +31 -20
- package/dist/api/agent-server-compatibility.js.map +1 -1
- package/dist/api/agent-server-config.cjs +1 -1
- package/dist/api/agent-server-config.cjs.map +1 -1
- package/dist/api/agent-server-config.d.ts +45 -0
- package/dist/api/agent-server-config.js +49 -21
- package/dist/api/agent-server-config.js.map +1 -1
- package/dist/api/backend-registry/storage.cjs +1 -1
- package/dist/api/backend-registry/storage.cjs.map +1 -1
- package/dist/api/backend-registry/storage.js +34 -32
- package/dist/api/backend-registry/storage.js.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +5 -4
- package/dist/api/conversation-service/agent-server-conversation-service.api.js +70 -76
- package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
- package/dist/components/features/backends/api-key-entry-screen.d.ts +10 -0
- package/dist/components/features/backends/backend-form-modal.cjs +1 -1
- package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
- package/dist/components/features/backends/backend-form-modal.d.ts +23 -2
- package/dist/components/features/backends/backend-form-modal.js +43 -38
- package/dist/components/features/backends/backend-form-modal.js.map +1 -1
- package/dist/components/features/browser/browser.cjs +1 -1
- package/dist/components/features/browser/browser.cjs.map +1 -1
- package/dist/components/features/browser/browser.js +10 -16
- package/dist/components/features/browser/browser.js.map +1 -1
- package/dist/components/features/mcp-page/install-server-modal.cjs +1 -1
- package/dist/components/features/mcp-page/install-server-modal.cjs.map +1 -1
- package/dist/components/features/mcp-page/install-server-modal.js +123 -116
- package/dist/components/features/mcp-page/install-server-modal.js.map +1 -1
- package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
- package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
- package/dist/components/features/mcp-page/installed-server-card.js +40 -40
- package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
- package/dist/components/features/mcp-page/marketplace-card.cjs +1 -1
- package/dist/components/features/mcp-page/marketplace-card.cjs.map +1 -1
- package/dist/components/features/mcp-page/marketplace-card.js +2 -3
- package/dist/components/features/mcp-page/marketplace-card.js.map +1 -1
- package/dist/components/features/mcp-page/marketplace-section.cjs +1 -1
- package/dist/components/features/mcp-page/marketplace-section.cjs.map +1 -1
- package/dist/components/features/mcp-page/marketplace-section.js +21 -21
- package/dist/components/features/mcp-page/marketplace-section.js.map +1 -1
- package/dist/components/features/onboarding/steps/setup-acp-secrets-step.d.ts +27 -0
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +2 -0
- package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs +1 -1
- package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs.map +1 -1
- package/dist/components/features/settings/sdk-settings/sdk-section-page.d.ts +10 -1
- package/dist/components/features/settings/sdk-settings/sdk-section-page.js +87 -84
- package/dist/components/features/settings/sdk-settings/sdk-section-page.js.map +1 -1
- package/dist/constants/acp-providers.cjs +1 -1
- package/dist/constants/acp-providers.cjs.map +1 -1
- package/dist/constants/acp-providers.d.ts +25 -0
- package/dist/constants/acp-providers.js +1 -0
- package/dist/constants/acp-providers.js.map +1 -1
- package/dist/contexts/conversation-websocket-context.cjs +3 -3
- package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
- package/dist/contexts/conversation-websocket-context.js +136 -132
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/hooks/chat/use-model-interceptor.cjs.map +1 -1
- package/dist/hooks/chat/use-model-interceptor.js.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.cjs.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.d.ts +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.js.map +1 -1
- package/dist/hooks/query/use-config.cjs +1 -1
- package/dist/hooks/query/use-config.cjs.map +1 -1
- package/dist/hooks/query/use-config.js +10 -10
- package/dist/hooks/query/use-config.js.map +1 -1
- package/dist/hooks/query/use-local-git-info.cjs +3 -3
- package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
- package/dist/hooks/query/use-local-git-info.js +24 -25
- package/dist/hooks/query/use-local-git-info.js.map +1 -1
- package/dist/i18n/declaration.cjs +1 -1
- package/dist/i18n/declaration.cjs.map +1 -1
- package/dist/i18n/declaration.d.ts +7 -0
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +2 -2
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +119 -0
- package/dist/i18n/translation.js.map +1 -1
- package/dist/locales/ar/openhands.json +7 -0
- package/dist/locales/ca/openhands.json +7 -0
- package/dist/locales/de/openhands.json +7 -0
- package/dist/locales/en/openhands.json +7 -0
- package/dist/locales/es/openhands.json +7 -0
- package/dist/locales/fr/openhands.json +7 -0
- package/dist/locales/it/openhands.json +7 -0
- package/dist/locales/ja/openhands.json +7 -0
- package/dist/locales/ko-KR/openhands.json +7 -0
- package/dist/locales/no/openhands.json +7 -0
- package/dist/locales/pt/openhands.json +7 -0
- package/dist/locales/tr/openhands.json +7 -0
- package/dist/locales/uk/openhands.json +7 -0
- package/dist/locales/zh-CN/openhands.json +7 -0
- package/dist/locales/zh-TW/openhands.json +7 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/routes/mcp.cjs +1 -1
- package/dist/routes/mcp.cjs.map +1 -1
- package/dist/routes/mcp.js +64 -64
- package/dist/routes/mcp.js.map +1 -1
- package/dist/stores/browser-store.cjs +1 -1
- package/dist/stores/browser-store.cjs.map +1 -1
- package/dist/stores/browser-store.js +1 -1
- package/dist/stores/browser-store.js.map +1 -1
- package/dist/utils/mcp-marketplace-utils.cjs +1 -1
- package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
- package/dist/utils/mcp-marketplace-utils.d.ts +13 -22
- package/dist/utils/mcp-marketplace-utils.js +46 -28
- package/dist/utils/mcp-marketplace-utils.js.map +1 -1
- package/dist/utils/sdk-settings-schema.cjs +1 -1
- package/dist/utils/sdk-settings-schema.cjs.map +1 -1
- package/dist/utils/sdk-settings-schema.d.ts +1 -0
- package/dist/utils/sdk-settings-schema.js +1 -1
- package/dist/utils/sdk-settings-schema.js.map +1 -1
- package/package.json +1 -1
- package/scripts/dev-safe.mjs +59 -40
- package/scripts/dev-static.mjs +2 -3
- package/scripts/dev-with-automation.mjs +75 -19
- package/scripts/static-server.mjs +77 -35
- package/tools/canvas_ui_tool.py +4 -0
- package/build/assets/acp-providers-DauuOsW9.js +0 -1
- package/build/assets/add-backend-modal-FsnpTTgO.js +0 -1
- package/build/assets/agent-server-client-options-DT2GP6VJ.js +0 -1
- package/build/assets/agent-server-compatibility-2aOx5iWd.js +0 -1
- package/build/assets/agent-server-conversation-service.api-BZmUqtiO.js +0 -5
- package/build/assets/browser-store-C3AqxAO7.js +0 -1
- package/build/assets/browser-tab-B_BuTvrO.js +0 -1
- package/build/assets/conversation--ldUK72N.js +0 -19
- package/build/assets/conversation-eNrhH94O.js +0 -1
- package/build/assets/conversation-panel-B49Jpqpb.js +0 -1
- package/build/assets/conversation-websocket-context-BW68-J8o.js +0 -3
- package/build/assets/declaration-D378OjpZ.js +0 -1
- package/build/assets/files-tab-CQHdWpQt.js +0 -1
- package/build/assets/home-DD0GroCu.js +0 -1
- package/build/assets/install-server-modal-z5VaHeXd.js +0 -1
- package/build/assets/llm-settings-BEyqixPI.js +0 -1
- package/build/assets/llm-settings-BdiaGFbg.js +0 -1
- package/build/assets/manifest-9d1c34fb.js +0 -1
- package/build/assets/mcp-C06YssEI.js +0 -9
- package/build/assets/root-3t9rxEpE.js +0 -2
- package/build/assets/sdk-section-page-CJW0G04-.js +0 -1
- package/build/assets/secrets-settings-MLXqOtX2.js +0 -1
- package/build/assets/use-active-conversation-DS5j9R4q.js +0 -1
- package/build/assets/use-config-BSu_53GL.js +0 -1
- package/build/assets/use-conversation-id-DajhCn2A.js +0 -1
- package/build/assets/use-is-authed-hXC8vxgT.js +0 -1
- package/build/assets/use-runtime-is-ready-pGSbPddC.js +0 -1
- package/build/assets/use-unified-vscode-url-wAMzv8Sn.js +0 -1
- package/build/assets/use-user-conversation-B_zDoSeh.js +0 -1
- /package/build/assets/{automation-XLxhq3I8.js → automation-IdgZq6ZK.js} +0 -0
- /package/build/assets/{common-SMkEaBSr.js → common-DR1t-EeP.js} +0 -0
- /package/build/assets/{conversation-state-store-Bc0slAjL.js → conversation-state-store-u5jepov0.js} +0 -0
- /package/build/assets/{dist-yMQV8IUk.js → dist-BxBP7tFD.js} +0 -0
- /package/build/assets/{git-status-mapper-BI8FyUVp.js → git-status-mapper-DnL9OC8_.js} +0 -0
- /package/build/assets/{handle-capture-consent-BfZATzpI.js → handle-capture-consent-3XrjZ8wi.js} +0 -0
- /package/build/assets/{iconBase-C7N9pPOs.js → iconBase-DE30Zj_-.js} +0 -0
- /package/build/assets/{settings-D5am1n6X.js → settings-D_H-qsRm.js} +0 -0
- /package/build/assets/{settings-like-page-layout-classes-Bn-M9oOa.js → settings-like-page-layout-classes-I0BDBEoq.js} +0 -0
- /package/build/assets/{settings-utils-BsvSU3OM.js → settings-utils-B6Nl07io.js} +0 -0
- /package/build/assets/{sidebar-store-cOeaKmIm.js → sidebar-store-Uy3v0AOV.js} +0 -0
- /package/build/assets/{use-breakpoint-B86yKT9n.js → use-breakpoint-DbJ6FkQ-.js} +0 -0
- /package/build/assets/{use-click-outside-element-835W9pC6.js → use-click-outside-element-DffgWWoZ.js} +0 -0
- /package/build/assets/{use-task-list-DDeNHprj.js → use-task-list-CLJbuJgM.js} +0 -0
- /package/build/assets/{vendor~browser-BpdPBhgZ.js → vendor~browser-DDiZgqD3.js} +0 -0
- /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-Df7_G0zR.js → vendor~conversation-panel~conversation~alert-banner-DbvX3OcM.js} +0 -0
- /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~b4cctr4k-B7YVdv1X.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~g56ukk6u-DsSvIDZQ.js} +0 -0
- /package/build/assets/{vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~i9dbt75i-CI82Did1.js → vendor~entry.client~root~root-layout~home~conversation-panel~conversation~launch~extensions~hkqzh1hb-BZ0HXuHD.js} +0 -0
- /package/build/assets/{vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~pfbaerbd-zhv9fooy.js → vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~ninslayh-D9P8e98a.js} +0 -0
- /package/build/assets/{vendor~terminal-BUxzHKcC.js → vendor~terminal-DUrOWGFE.js} +0 -0
- /package/build/assets/{vscode-url-helper-jesbpos5.js → vscode-url-helper-Cwy1A62q.js} +0 -0
|
@@ -134,6 +134,7 @@ function parseArgs() {
|
|
|
134
134
|
dynamic: false,
|
|
135
135
|
staticDir: null,
|
|
136
136
|
skipBuild: false,
|
|
137
|
+
public: false,
|
|
137
138
|
};
|
|
138
139
|
|
|
139
140
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -164,6 +165,9 @@ function parseArgs() {
|
|
|
164
165
|
case "--skip-build":
|
|
165
166
|
config.skipBuild = true;
|
|
166
167
|
break;
|
|
168
|
+
case "--public":
|
|
169
|
+
config.public = true;
|
|
170
|
+
break;
|
|
167
171
|
case "-h":
|
|
168
172
|
case "--help":
|
|
169
173
|
showHelp();
|
|
@@ -281,6 +285,18 @@ async function buildConfig(args, env = process.env) {
|
|
|
281
285
|
env.OH_AUTOMATION_REPO = args.automationRepo;
|
|
282
286
|
}
|
|
283
287
|
|
|
288
|
+
const isPublic = args.public;
|
|
289
|
+
|
|
290
|
+
// In public mode, LOCAL_BACKEND_API_KEY is required — without it the
|
|
291
|
+
// auth screen has nothing to validate against.
|
|
292
|
+
if (isPublic && !env.LOCAL_BACKEND_API_KEY) {
|
|
293
|
+
logError(
|
|
294
|
+
"PUBLIC MODE requires LOCAL_BACKEND_API_KEY environment variable.\n" +
|
|
295
|
+
" Example: LOCAL_BACKEND_API_KEY=my-secret npm run dev -- --public",
|
|
296
|
+
);
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|
|
299
|
+
|
|
284
300
|
// Preferred ports (from env or defaults).
|
|
285
301
|
// OH_CANVAS_SAFE_BACKEND_PORT / OH_CANVAS_SAFE_AUTOMATION_PORT /
|
|
286
302
|
// OH_CANVAS_SAFE_VITE_PORT allow tests (and advanced users) to redirect
|
|
@@ -303,11 +319,14 @@ async function buildConfig(args, env = process.env) {
|
|
|
303
319
|
|
|
304
320
|
const vscodePort = preferredBackendPort + 1000;
|
|
305
321
|
|
|
306
|
-
//
|
|
322
|
+
// API key — shared by both agent-server and automation backend.
|
|
307
323
|
// Both validate it via the `X-Session-API-Key` header.
|
|
324
|
+
// LOCAL_BACKEND_API_KEY is the single user-facing env var: if set it's
|
|
325
|
+
// used directly; otherwise one is auto-generated and persisted.
|
|
308
326
|
const stateDir =
|
|
309
327
|
env.OH_CANVAS_SAFE_STATE_DIR ||
|
|
310
328
|
join(homedir(), ".openhands", "agent-canvas");
|
|
329
|
+
|
|
311
330
|
const safeConfig = buildSafeDevConfig(projectRoot, {
|
|
312
331
|
...env,
|
|
313
332
|
OH_CANVAS_SAFE_STATE_DIR: stateDir,
|
|
@@ -316,6 +335,19 @@ async function buildConfig(args, env = process.env) {
|
|
|
316
335
|
});
|
|
317
336
|
const sessionApiKey = safeConfig.sessionApiKey;
|
|
318
337
|
|
|
338
|
+
if (isPublic) {
|
|
339
|
+
logService(
|
|
340
|
+
"auth",
|
|
341
|
+
"PUBLIC MODE — key will NOT be injected into the frontend",
|
|
342
|
+
c.yellow,
|
|
343
|
+
);
|
|
344
|
+
logService(
|
|
345
|
+
"auth",
|
|
346
|
+
"Users must paste the LOCAL_BACKEND_API_KEY in the browser",
|
|
347
|
+
c.dim,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
319
351
|
return {
|
|
320
352
|
// Ingress port (main entry point)
|
|
321
353
|
ingressPort: preferredIngressPort,
|
|
@@ -335,6 +367,9 @@ async function buildConfig(args, env = process.env) {
|
|
|
335
367
|
// Auth — single key for both backends
|
|
336
368
|
sessionApiKey,
|
|
337
369
|
|
|
370
|
+
// Public mode — the session key should NOT be baked into the frontend
|
|
371
|
+
isPublic,
|
|
372
|
+
|
|
338
373
|
verbose: args.verbose,
|
|
339
374
|
};
|
|
340
375
|
}
|
|
@@ -517,6 +552,9 @@ function startAgentServer(config) {
|
|
|
517
552
|
const agentServerEnv = {
|
|
518
553
|
...buildAgentServerEnv(safeConfig),
|
|
519
554
|
...buildAgentServerAutomationEnv(config),
|
|
555
|
+
// Ensure the agent-server uses the resolved key from config. This is
|
|
556
|
+
// LOCAL_BACKEND_API_KEY when set, or the auto-generated persisted key.
|
|
557
|
+
OH_SESSION_API_KEYS_0: config.sessionApiKey,
|
|
520
558
|
};
|
|
521
559
|
|
|
522
560
|
spawnService(
|
|
@@ -726,22 +764,31 @@ function startVite(config) {
|
|
|
726
764
|
const frontendCommand = buildNpmScriptCommand("dev:frontend");
|
|
727
765
|
const runtimeServicesInfo = buildAutomationRuntimeServicesInfo(config);
|
|
728
766
|
|
|
767
|
+
const viteEnv = {
|
|
768
|
+
// Point Vite at the ingress (so client-side fetches work)
|
|
769
|
+
VITE_BACKEND_HOST: `127.0.0.1:${config.ingressPort}`,
|
|
770
|
+
VITE_BACKEND_BASE_URL: `http://127.0.0.1:${config.ingressPort}`,
|
|
771
|
+
VITE_WORKING_DIR:
|
|
772
|
+
config.viteWorkingDir ?? join(config.stateDir, "workspaces"),
|
|
773
|
+
VITE_FRONTEND_PORT: config.vitePort.toString(),
|
|
774
|
+
// Inform the frontend (and downstream, the agent's system prompt) about
|
|
775
|
+
// which services are available in this dev stack.
|
|
776
|
+
VITE_RUNTIME_SERVICES_INFO: JSON.stringify(runtimeServicesInfo),
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// In local mode, bake the session key into the frontend so the user
|
|
780
|
+
// never has to paste it. In public mode, omit the key and set
|
|
781
|
+
// VITE_AUTH_REQUIRED so the frontend shows the API key entry screen
|
|
782
|
+
// immediately (no network round-trip needed).
|
|
783
|
+
if (config.isPublic) {
|
|
784
|
+
viteEnv.VITE_AUTH_REQUIRED = "true";
|
|
785
|
+
} else {
|
|
786
|
+
viteEnv.VITE_SESSION_API_KEY = config.sessionApiKey;
|
|
787
|
+
}
|
|
788
|
+
|
|
729
789
|
spawnService("vite", frontendCommand.command, frontendCommand.args, {
|
|
730
790
|
cwd: config.canvasPath,
|
|
731
|
-
env:
|
|
732
|
-
// Point Vite at the ingress (so client-side fetches work)
|
|
733
|
-
VITE_BACKEND_HOST: `127.0.0.1:${config.ingressPort}`,
|
|
734
|
-
VITE_BACKEND_BASE_URL: `http://127.0.0.1:${config.ingressPort}`,
|
|
735
|
-
VITE_WORKING_DIR:
|
|
736
|
-
config.viteWorkingDir ?? join(config.stateDir, "workspaces"),
|
|
737
|
-
VITE_FRONTEND_PORT: config.vitePort.toString(),
|
|
738
|
-
// Session API key — used by the frontend for both agent-server and
|
|
739
|
-
// automation auth via the `X-Session-API-Key` header.
|
|
740
|
-
VITE_SESSION_API_KEY: config.sessionApiKey,
|
|
741
|
-
// Inform the frontend (and downstream, the agent's system prompt) about
|
|
742
|
-
// which services are available in this dev stack.
|
|
743
|
-
VITE_RUNTIME_SERVICES_INFO: JSON.stringify(runtimeServicesInfo),
|
|
744
|
-
},
|
|
791
|
+
env: viteEnv,
|
|
745
792
|
color: c.magenta,
|
|
746
793
|
});
|
|
747
794
|
}
|
|
@@ -905,10 +952,18 @@ async function main(options = {}) {
|
|
|
905
952
|
// Human-readable label for the dev mode, surfaced in the agent's
|
|
906
953
|
// <RUNTIME_SERVICES> system-prompt block.
|
|
907
954
|
mode = "dev:automation",
|
|
955
|
+
// When true, enable public mode (require LOCAL_BACKEND_API_KEY,
|
|
956
|
+
// don't bake session key into frontend).
|
|
957
|
+
isPublic: isPublicOverride,
|
|
908
958
|
} = options;
|
|
909
959
|
|
|
910
960
|
const args = parseArgs();
|
|
911
961
|
|
|
962
|
+
// Allow options to override CLI args for public mode
|
|
963
|
+
if (isPublicOverride != null) {
|
|
964
|
+
args.public = isPublicOverride;
|
|
965
|
+
}
|
|
966
|
+
|
|
912
967
|
// Allow options to override CLI args (for bin/agent-canvas.mjs)
|
|
913
968
|
const useStaticMode =
|
|
914
969
|
staticModeOverride ??
|
|
@@ -1041,12 +1096,13 @@ function startStaticFrontend(config, staticDir) {
|
|
|
1041
1096
|
"0.0.0.0",
|
|
1042
1097
|
"--port",
|
|
1043
1098
|
String(config.vitePort),
|
|
1044
|
-
//
|
|
1045
|
-
// authenticate
|
|
1046
|
-
//
|
|
1047
|
-
...(config.sessionApiKey
|
|
1099
|
+
// In local mode, inject the API key so the pre-built frontend can
|
|
1100
|
+
// authenticate transparently. In public mode, pass --auth-required
|
|
1101
|
+
// so the frontend shows the API key entry screen instead.
|
|
1102
|
+
...(!config.isPublic && config.sessionApiKey
|
|
1048
1103
|
? ["--session-api-key", config.sessionApiKey]
|
|
1049
1104
|
: []),
|
|
1105
|
+
...(config.isPublic ? ["--auth-required"] : []),
|
|
1050
1106
|
// Proxy routes to backends (same as ingress but for direct access to vitePort)
|
|
1051
1107
|
"--route",
|
|
1052
1108
|
`/api/automation=http://localhost:${config.autoBackendPort}`,
|
|
@@ -73,6 +73,7 @@ export function parseArgs(argv = process.argv.slice(2)) {
|
|
|
73
73
|
dir: "build",
|
|
74
74
|
routes: {},
|
|
75
75
|
sessionApiKey: null,
|
|
76
|
+
authRequired: false,
|
|
76
77
|
};
|
|
77
78
|
|
|
78
79
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -108,6 +109,9 @@ export function parseArgs(argv = process.argv.slice(2)) {
|
|
|
108
109
|
case "--session-api-key":
|
|
109
110
|
config.sessionApiKey = argv[++i] || null;
|
|
110
111
|
break;
|
|
112
|
+
case "--auth-required":
|
|
113
|
+
config.authRequired = true;
|
|
114
|
+
break;
|
|
111
115
|
case "-h":
|
|
112
116
|
case "--help":
|
|
113
117
|
showHelp();
|
|
@@ -117,6 +121,19 @@ export function parseArgs(argv = process.argv.slice(2)) {
|
|
|
117
121
|
}
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
// Guard: --session-api-key and --auth-required are semantically
|
|
125
|
+
// mutually exclusive. The first auto-injects the key (local mode);
|
|
126
|
+
// the second forces the user to paste it (public mode). Combining
|
|
127
|
+
// both is a misconfiguration.
|
|
128
|
+
if (config.sessionApiKey && config.authRequired) {
|
|
129
|
+
console.error(
|
|
130
|
+
"ERROR: --session-api-key and --auth-required are mutually exclusive.\n" +
|
|
131
|
+
" Use --session-api-key for local mode (key auto-injected).\n" +
|
|
132
|
+
" Use --auth-required for public mode (user pastes key).",
|
|
133
|
+
);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
|
|
120
137
|
return config;
|
|
121
138
|
}
|
|
122
139
|
|
|
@@ -136,6 +153,9 @@ OPTIONS:
|
|
|
136
153
|
--session-api-key <key> Inject session API key into index.html so the
|
|
137
154
|
pre-built frontend authenticates to agent-server
|
|
138
155
|
without needing VITE_SESSION_API_KEY baked in.
|
|
156
|
+
--auth-required Inject authRequired flag into index.html so the
|
|
157
|
+
pre-built frontend shows the API key entry screen
|
|
158
|
+
(public mode) without VITE_AUTH_REQUIRED baked in.
|
|
139
159
|
-h, --help Show this help
|
|
140
160
|
|
|
141
161
|
ROUTING:
|
|
@@ -152,39 +172,55 @@ ROUTING:
|
|
|
152
172
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
153
173
|
|
|
154
174
|
/**
|
|
155
|
-
* Build a tiny inline script that seeds
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
175
|
+
* Build a tiny inline script that seeds runtime config into the page.
|
|
176
|
+
*
|
|
177
|
+
* - `sessionApiKey`: written to `openhands-agent-server-config` in localStorage
|
|
178
|
+
* so the pre-built frontend authenticates without VITE_SESSION_API_KEY baked in.
|
|
179
|
+
* Only writes if no key is already stored — explicit user overrides are preserved.
|
|
159
180
|
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
181
|
+
* - `authRequired`: sets `window.__AGENT_CANVAS_AUTH_REQUIRED__ = true` so the
|
|
182
|
+
* pre-built frontend shows the API key entry screen (public mode) without
|
|
183
|
+
* VITE_AUTH_REQUIRED baked in.
|
|
162
184
|
*/
|
|
163
|
-
function makeConfigInjectionScript(sessionApiKey) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
function makeConfigInjectionScript(sessionApiKey, authRequired) {
|
|
186
|
+
const parts = [];
|
|
187
|
+
|
|
188
|
+
if (sessionApiKey) {
|
|
189
|
+
const keyLiteral = JSON.stringify(sessionApiKey);
|
|
190
|
+
// Always overwrite when the stored key differs from the runtime key.
|
|
191
|
+
// A previous session may have persisted a now-stale key; the runtime
|
|
192
|
+
// value (from --session-api-key) is the server's truth.
|
|
193
|
+
parts.push(
|
|
194
|
+
`try{` +
|
|
195
|
+
`var _k='openhands-agent-server-config',` +
|
|
196
|
+
`_c=JSON.parse(localStorage.getItem(_k)||'{}');` +
|
|
197
|
+
`if(_c.sessionApiKey!==${keyLiteral}){` +
|
|
198
|
+
`_c.sessionApiKey=${keyLiteral};` +
|
|
199
|
+
`localStorage.setItem(_k,JSON.stringify(_c));` +
|
|
200
|
+
`}` +
|
|
201
|
+
`}catch(e){}`,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (authRequired) {
|
|
206
|
+
parts.push(`window.__AGENT_CANVAS_AUTH_REQUIRED__=true;`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (parts.length === 0) return "";
|
|
210
|
+
|
|
211
|
+
return `<script>(function(){${parts.join("")}}());</script>`;
|
|
181
212
|
}
|
|
182
213
|
|
|
183
214
|
/**
|
|
184
|
-
* Serve index.html with
|
|
215
|
+
* Serve index.html with runtime config injected into <head>.
|
|
185
216
|
* Returns true if the response was written, false if the file was not found.
|
|
186
217
|
*/
|
|
187
|
-
async function serveInjectedIndexHtml(
|
|
218
|
+
async function serveInjectedIndexHtml(
|
|
219
|
+
req,
|
|
220
|
+
res,
|
|
221
|
+
indexPath,
|
|
222
|
+
{ sessionApiKey, authRequired } = {},
|
|
223
|
+
) {
|
|
188
224
|
let content;
|
|
189
225
|
try {
|
|
190
226
|
content = await readFile(indexPath, "utf8");
|
|
@@ -192,7 +228,7 @@ async function serveInjectedIndexHtml(req, res, indexPath, sessionApiKey) {
|
|
|
192
228
|
return false;
|
|
193
229
|
}
|
|
194
230
|
|
|
195
|
-
const script = makeConfigInjectionScript(sessionApiKey);
|
|
231
|
+
const script = makeConfigInjectionScript(sessionApiKey, authRequired);
|
|
196
232
|
// Inject right before </head> so the key is available before any app code runs.
|
|
197
233
|
// replace() targets the first (and only) </head> in well-formed HTML.
|
|
198
234
|
const injected = content.includes("</head>")
|
|
@@ -393,7 +429,7 @@ async function serveFile(req, res, filePath, urlPath) {
|
|
|
393
429
|
return true;
|
|
394
430
|
}
|
|
395
431
|
|
|
396
|
-
async function handleStatic(req, res, dirAbs,
|
|
432
|
+
async function handleStatic(req, res, dirAbs, injectionOpts = {}) {
|
|
397
433
|
const rawPath = req.url.split("?")[0];
|
|
398
434
|
let urlPath;
|
|
399
435
|
try {
|
|
@@ -417,9 +453,12 @@ async function handleStatic(req, res, dirAbs, sessionApiKey = null) {
|
|
|
417
453
|
filePath = resolve(filePath, "index.html");
|
|
418
454
|
}
|
|
419
455
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
456
|
+
const needsInjection =
|
|
457
|
+
injectionOpts.sessionApiKey || injectionOpts.authRequired;
|
|
458
|
+
|
|
459
|
+
// Serve index.html with runtime config injection when configured.
|
|
460
|
+
if (needsInjection && filePath.endsWith("index.html")) {
|
|
461
|
+
if (await serveInjectedIndexHtml(req, res, filePath, injectionOpts)) return;
|
|
423
462
|
// Fall through to regular serveFile (handles 404 path correctly).
|
|
424
463
|
}
|
|
425
464
|
|
|
@@ -431,8 +470,8 @@ async function handleStatic(req, res, dirAbs, sessionApiKey = null) {
|
|
|
431
470
|
!looksLikeAssetRequest(urlPath)
|
|
432
471
|
) {
|
|
433
472
|
const indexPath = resolve(dirAbs, "index.html");
|
|
434
|
-
if (
|
|
435
|
-
if (await serveInjectedIndexHtml(req, res, indexPath,
|
|
473
|
+
if (needsInjection) {
|
|
474
|
+
if (await serveInjectedIndexHtml(req, res, indexPath, injectionOpts))
|
|
436
475
|
return;
|
|
437
476
|
} else if (await serveFile(req, res, indexPath, "/")) return;
|
|
438
477
|
}
|
|
@@ -448,7 +487,10 @@ async function handleStatic(req, res, dirAbs, sessionApiKey = null) {
|
|
|
448
487
|
export function startStaticServer(config) {
|
|
449
488
|
const route = createRouter(config.routes);
|
|
450
489
|
const dirAbs = resolve(config.dir);
|
|
451
|
-
const
|
|
490
|
+
const injectionOpts = {
|
|
491
|
+
sessionApiKey: config.sessionApiKey || null,
|
|
492
|
+
authRequired: config.authRequired || false,
|
|
493
|
+
};
|
|
452
494
|
|
|
453
495
|
const server = createServer((req, res) => {
|
|
454
496
|
const backend = route(req.url);
|
|
@@ -456,7 +498,7 @@ export function startStaticServer(config) {
|
|
|
456
498
|
proxyRequest(req, res, backend);
|
|
457
499
|
return;
|
|
458
500
|
}
|
|
459
|
-
handleStatic(req, res, dirAbs,
|
|
501
|
+
handleStatic(req, res, dirAbs, injectionOpts).catch((err) => {
|
|
460
502
|
console.error(`Static handler error for ${req.url}:`, err);
|
|
461
503
|
if (!res.headersSent) {
|
|
462
504
|
res.writeHead(500);
|
package/tools/canvas_ui_tool.py
CHANGED
|
@@ -90,7 +90,11 @@ When to call (pick the most specific option that matches your last action):
|
|
|
90
90
|
command="open_tab", tab="terminal"
|
|
91
91
|
|
|
92
92
|
* You browsed to a URL the user should see →
|
|
93
|
+
First call browser_get_state(include_screenshot=true) after your final
|
|
94
|
+
browser interaction so Agent Canvas has a screenshot to display, then call
|
|
93
95
|
command="open_tab", tab="browser"
|
|
96
|
+
(browser_navigate alone only updates the URL; without browser_get_state,
|
|
97
|
+
the Browser tab will open without a screenshot.)
|
|
94
98
|
|
|
95
99
|
Call this BEFORE writing your chat-message summary of the change, so the
|
|
96
100
|
artifact is visible while the user reads what you did. One canvas_ui call
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./declaration-D378OjpZ.js";import{t}from"./vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-CHrEOFl6.js";var n=`cli-generic`,r=new Set([`default`,`default (recommended)`]);function i(e){if(typeof e!=`string`)return null;let t=e.trim();return!t||r.has(t.toLowerCase())||t===`acp-managed`?null:t}function a(e){for(let t of[e.runtimeName,e.runtimeId,e.configured,e.sdkLlm]){let e=i(t);if(e)return e}return e.providerDefault??null}var o={"claude-code":{icon:`claude-code`,description_key:e.ONBOARDING$AGENT_CLAUDE_CODE_DESCRIPTION},codex:{icon:`codex`,description_key:e.ONBOARDING$AGENT_CODEX_DESCRIPTION},"gemini-cli":{icon:`gemini`,description_key:e.ONBOARDING$AGENT_GEMINI_CLI_DESCRIPTION}},s=Object.entries(o).map(([e,n])=>{let r=t(e);return{key:e,display_name:r?.display_name??e,default_command:r?[...r.default_command]:[],available_models:r?.available_models?.map(e=>({id:e.id,label:e.label})),default_model:r?.default_model??void 0,description_key:n.description_key,icon:n.icon}}),c=`custom`;function l(e){if(e)return s.find(t=>t.key===e)}function u(e){let t=l(e);return t?t.display_name:null}function d(e){return l(e)?.icon??`cli-generic`}function f(e,t){return t?l(e)?.available_models?.find(e=>e.id===t)?.label??t:null}function p(e,t={}){if(e===`openhands`)return{agent_kind:`openhands`};let n=e===c,r=n?void 0:l(e);if(!n&&!r&&!t.allowUnknownServer)return null;let i=t.model===void 0?r?.default_model??null:t.model;return{agent_kind:`acp`,acp_server:e,acp_command:t.command??[],acp_args:[],acp_model:i??null}}export{l as a,d as c,p as i,a as l,s as n,u as o,n as r,f as s,c as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-BFRubm34.js";import{o as t}from"./declaration-D378OjpZ.js";import{n}from"./backend-form-modal-DxYjqqAK.js";var r=e({AddBackendModal:()=>a}),i=t();function a({onClose:e}){return(0,i.jsx)(n,{mode:`add`,onClose:e})}export{r as n,a as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=`openhands-agent-server-config`,t=`workspace/project`;function n(){if(typeof window>`u`)return{};try{let t=window.localStorage.getItem(e);return t?JSON.parse(t)??{}:{}}catch{return{}}}function r(e){return e?.trim()||null}function i(e){if(!e)return null;let t=e.trim().replace(/\/$/,``);return t?/^https?:\/\//i.test(t)?t:typeof window<`u`?`${window.location.protocol}//${t}`:`http://${t}`:null}function a(){return i(n().baseUrl)||i(void 0)}function o(){return r(n().sessionApiKey)||r(void 0)}function s(e){if(typeof window>`u`)return!1;try{let t=new URL(e),n=new Set([`127.0.0.1`,`localhost`,`0.0.0.0`]),r=window.location.hostname;return n.has(t.hostname)&&!n.has(r)}catch{return!1}}function c(e){return e?s(e)?window.location.origin:e:null}function l(){return c(a())||(typeof window<`u`?window.location.origin:`http://127.0.0.1:8000`)}function u(){return o()}function d(){return(void 0)?.trim()||n().workingDir?.trim()||t}function f(e){return`${d().replace(/\/+$/,``)}/${e.replace(/-/g,``)}`}function p(){let e=u();return e?{"X-Session-API-Key":e}:{}}function m(){return!0}var h=`default-local`,g=`Local`;function _(){return{id:h,name:g,host:l(),apiKey:u()??``,kind:`local`}}var v=`openhands-backends`,y=`openhands-active-backend`;function b(e){return e===`local`||e===`cloud`}function x(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.name==`string`&&typeof t.host==`string`&&typeof t.apiKey==`string`&&b(t.kind)}function S(e){try{return new URL(e).origin}catch{return e.replace(/\/+$/,``)}}function C(e){let t=_();return e.id!==t.id||e.kind!==`local`||!t.apiKey||S(e.host)!==S(t.host)||e.apiKey===t.apiKey?e:{...e,apiKey:t.apiKey}}function w(e){if(!(typeof window>`u`))try{window.localStorage.setItem(v,JSON.stringify(e))}catch{}}function T(){if(typeof window>`u`)return[];try{let e=window.localStorage.getItem(v);if(e===null){let e=[_()];return w(e),e}let t=JSON.parse(e);if(!Array.isArray(t))return[];let n=t.filter(x);if(n.length===0){let e=[_()];return w(e),e}let r=n.map(C);return r.some((e,t)=>e!==n[t])&&w(r),r}catch{return[]}}function E(){if(typeof window>`u`)return null;try{let e=window.localStorage.getItem(y);if(!e)return null;let t=JSON.parse(e);if(typeof t!=`object`||!t||typeof t.backendId!=`string`)return null;let n=t.orgId;return{backendId:t.backendId,orgId:typeof n==`string`&&n.length>0?n:null}}catch{return null}}function D(e){if(!(typeof window>`u`))try{if(!e){window.localStorage.removeItem(y);return}window.localStorage.setItem(y,JSON.stringify({backendId:e.backendId,orgId:e.orgId??null}))}catch{}}function O(e){return e.find(e=>e.kind===`local`)??_()}function k(e,t){let n=null,r=null;if(t){let i=e.find(e=>e.id===t.backendId);i&&(n=i,r=t.orgId??null)}return n||(n=O(e),r=null),{backends:e,selection:t,active:{backend:n,orgId:r}}}var A=k(T(),E()),j=new Set;function M(){j.forEach(e=>e())}function N(){return A.active}function P(){let e=A.active.backend;return e.kind===`local`?e:O(A.backends)}function F(){return A.backends}function I(){return A.selection}function L(){return A}function R(e){D(e),A=k(A.backends,e),M()}function z(e){w(e);let t=A.selection;t&&!e.some(e=>e.id===t.backendId)&&(t=null,D(null)),A=k(e,t),M()}function B(e){return j.add(e),()=>{j.delete(e)}}var V=class extends Error{constructor(e,t,n,r){super(r||`HTTP ${e}: ${t}`),this.status=e,this.statusText=t,this.response=n,this.name=`HttpError`}},H=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,``),this.apiKey=e.apiKey,this.timeout=e.timeout||6e4}async request(e){let t=e.url.startsWith(`/`)?e.url.slice(1):e.url,n=new URL(t,this.baseUrl+`/`);e.params&&Object.entries(e.params).forEach(([e,t])=>{t!=null&&(Array.isArray(t)?t.forEach(t=>n.searchParams.append(e,String(t))):n.searchParams.append(e,String(t)))});let r={"Content-Type":`application/json`,...e.headers};this.apiKey&&(r[`X-Session-API-Key`]=this.apiKey);let i={method:e.method,headers:r,signal:AbortSignal.timeout(e.timeout||this.timeout)};e.credentials&&(i.credentials=e.credentials),e.data&&e.method!==`GET`&&(e.data instanceof FormData?(delete r[`Content-Type`],i.body=e.data):i.body=JSON.stringify(e.data));try{let t=await fetch(n.toString(),i);if(!(e.acceptableStatusCodes?.has(t.status)||!e.acceptableStatusCodes&&t.ok)){let e;try{e=t.headers.get(`content-type`)?.includes(`application/json`)?await t.json():await t.text()}catch{e=null}throw new V(t.status,t.statusText,e,`HTTP request failed (${t.status} ${t.statusText}): ${JSON.stringify(e)}`)}let r=await this.parseResponse(t,e.responseType||`auto`),a={};return t.headers.forEach((e,t)=>{a[t]=e}),{data:r,status:t.status,statusText:t.statusText,headers:a}}catch(t){throw t instanceof V?t:t instanceof Error?t.name===`AbortError`?Error(`Request timeout after ${e.timeout||this.timeout}ms`,{cause:t}):Error(`Request failed: ${t.message}`,{cause:t}):Error(`Unknown request error`,{cause:t})}}async parseResponse(e,t){return t===`json`?await e.json():t===`text`?await e.text():t===`blob`?await e.blob():t===`arrayBuffer`?await e.arrayBuffer():e.headers.get(`content-type`)?.includes(`application/json`)?await e.json():await e.text()}async get(e,t){return this.request({method:`GET`,url:e,...t})}async post(e,t,n){return this.request({method:`POST`,url:e,data:t,...n})}async put(e,t,n){return this.request({method:`PUT`,url:e,data:t,...n})}async patch(e,t,n){return this.request({method:`PATCH`,url:e,data:t,...n})}async delete(e,t){return this.request({method:`DELETE`,url:e,...t})}close(){}};function U(e){if(e&&!e.startsWith(`/`))try{let t=new URL(e),n=t.hostname,r=window.location.hostname??window.location.host?.split(`:`)[0];return r&&(n===`localhost`||n===`127.0.0.1`)&&r!==`localhost`&&r!==`127.0.0.1`?`${r}:${t.port}`:t.host}catch{return window.location.host}return window.location.host}function W(e){if(e&&!e.startsWith(`/`))try{return(new URL(e).pathname.split(`/api/conversations`)[0]||``).replace(/\/$/,``)}catch{return``}return``}function G(e){let t=U(e),n=W(e);return`${window.location.protocol===`https:`?`https:`:`http:`}//${t}${n}`}function K(e){if(!e||e.startsWith(`/`))return null;try{return new URL(e).protocol}catch{return null}}function q(e,t){let n=U(e),r=W(e),i=window.location.protocol===`https:`,a=K(e)===`https:`,o=`${i||a?`wss:`:`ws:`}//${n}${r}/sockets/bash-events`;return t?`${o}?session_api_key=${encodeURIComponent(t)}`:o}function J(e,t){if(!e)return null;let n=U(t),r=W(t),i=window.location.protocol===`https:`,a=K(t)===`https:`;return`${i||a?`wss:`:`ws:`}//${n}${r}/sockets/events/${e}`}function Y(e){return e.replace(/\/+$/,``)}function X(e,t){return e.host?Y(e.host):e.conversationUrl?Y(G(e.conversationUrl)):Y(t.host)}function Z(e={}){let t=P(),n=u(),r=t.id===`default-local`?n:null,i=e.sessionApiKey??e.apiKey??r??t.apiKey??void 0;return{host:X(e,t),...i?{apiKey:i}:{},workingDir:e.workingDir??d(),...e.timeout===void 0?{}:{timeout:e.timeout}}}function Q(e){let{host:t,apiKey:n,timeout:r}=Z(e);return{baseUrl:t,...n?{apiKey:n}:{},timeout:r??6e4}}export{m as C,d as S,_,J as a,p as b,N as c,F as d,L as f,h as g,B as h,G as i,I as l,z as m,Q as n,H as o,R as p,q as r,V as s,Z as t,P as u,t as v,u as x,f as y};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e,u as t}from"./agent-server-client-options-DT2GP6VJ.js";import{t as n}from"./server-client-C3mC8Hl3.js";var r=5e3,i=null,a=e=>Array.isArray(e?.usable_tools)?e.usable_tools:null,o=class extends Error{details;constructor(e){super(`Agent server not found. Could not connect to the configured agent server. Start a compatible agent server and reload the page.`),this.name=`AgentServerUnavailableError`,this.details=e??null}},s=e=>e instanceof o||typeof e==`object`&&!!e&&`name`in e&&e.name===`AgentServerUnavailableError`;function c(){i=null}function l(e){let t=a(i);return Array.isArray(t)?t.includes(e):!0}function u(e){return e instanceof Error&&e.name===`HttpError`&&`status`in e&&typeof e.status==`number`}async function d(){let a=t(),s;try{s=await new n(e({host:a.host,sessionApiKey:a.apiKey||null,timeout:r})).getServerInfo()}catch(e){throw c(),u(e)?e:new o(e instanceof Error?e.message:null)}return i=s,s}export{s as n,d as r,l as t};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/secrets-service-Bwd5DeUs.js","assets/rolldown-runtime-BFRubm34.js","assets/agent-server-client-options-DT2GP6VJ.js","assets/settings-client-CwjfwoiB.js","assets/proxy-CurRmrqf.js","assets/vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~pfbaerbd-zhv9fooy.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{t as e}from"./preload-helper-CT1Z6Pdu.js";import{C as t,S as n,c as r,i,o as a,s as o,t as s,u as c,y as l}from"./agent-server-client-options-DT2GP6VJ.js";import{n as u,s as d,u as f}from"./vendor~root-layout~home~conversation-panel~conversation~launch~extensions-hub~skills-settin~dp08i1qy-CHrEOFl6.js";import{t as p}from"./profiles-client-BGkKEV9j.js";import{t as m}from"./agent-server-compatibility-2aOx5iWd.js";import{n as h,t as g}from"./proxy-CurRmrqf.js";import{t as _}from"./settings-D5am1n6X.js";import{t as ee}from"./common-SMkEaBSr.js";import{a as v,l as y}from"./acp-providers-DauuOsW9.js";import{t as b}from"./settings-service.api-FvJGK45W.js";var x=class{constructor(e){this.host=e.host.replace(/\/$/,``),this.apiKey=e.apiKey,this.client=new a({baseUrl:this.host,apiKey:this.apiKey,timeout:e.timeout||6e4})}async createConversation(e){return(await this.client.post(`/api/conversations`,e)).data}async searchConversations(e={}){return(await this.client.get(`/api/conversations/search`,{params:e})).data}async countConversations(e={}){return(await this.client.get(`/api/conversations/count`,{params:e})).data}async getConversations(e){return(await this.client.get(`/api/conversations`,{params:{ids:e}})).data}async getConversation(e){return(await this.client.get(`/api/conversations/${e}`)).data}async searchEvents(e,t={}){return(await this.client.get(`/api/conversations/${e}/events/search`,{params:t})).data}async getEvent(e,t){return(await this.client.get(`/api/conversations/${e}/events/${t}`)).data}async getEvents(e,t){return Promise.all(t.map(async t=>{try{return await this.getEvent(e,t)}catch(e){if(e instanceof o&&e.status===404)return null;throw e}}))}async sendEvent(e,t,n={}){await this.client.post(`/api/conversations/${e}/events`,{...t,...n.run===void 0?{}:{run:n.run}})}async pauseConversation(e){return(await this.client.post(`/api/conversations/${e}/pause`,{})).data}async interruptConversation(e){return(await this.client.post(`/api/conversations/${e}/interrupt`,{})).data}async runConversation(e){return(await this.client.post(`/api/conversations/${e}/run`,{})).data}async askAgent(e,t){return(await this.client.post(`/api/conversations/${e}/ask_agent`,{question:t})).data}async getEventCount(e,t={}){return(await this.client.get(`/api/conversations/${e}/events/count`,{params:t})).data}async respondToConfirmation(e,t){return(await this.client.post(`/api/conversations/${e}/events/respond_to_confirmation`,t)).data}async getAgentFinalResponse(e){return(await this.client.get(`/api/conversations/${e}/agent_final_response`)).data}async setConfirmationPolicy(e,t){let n=`policy`in t?t:{policy:t};return(await this.client.post(`/api/conversations/${e}/confirmation_policy`,n)).data}async condenseConversation(e){return(await this.client.post(`/api/conversations/${e}/condense`,{})).data}async setSecurityAnalyzer(e,t){let n=te(t)?t:{security_analyzer:t};return(await this.client.post(`/api/conversations/${e}/security_analyzer`,n)).data}async updateSecrets(e,t){return(await this.client.post(`/api/conversations/${e}/secrets`,t)).data}async forkConversation(e,t={},n={}){return(await this.client.post(`/api/conversations/${e}/fork`,t,{params:n.includeSkills===void 0?void 0:{include_skills:n.includeSkills}})).data}async switchProfile(e,t){await this.client.post(`/api/conversations/${e}/switch_profile`,{profile_name:t})}async switchLLM(e,t){await this.client.post(`/api/conversations/${e}/switch_llm`,{llm:t})}async switchAcpModel(e,t){await this.client.post(`/api/conversations/${e}/switch_acp_model`,{model:t})}async deleteConversation(e){await this.client.delete(`/api/conversations/${e}`)}async updateConversation(e,t){return(await this.client.patch(`/api/conversations/${e}`,t)).data}close(){this.client.close()}};function te(e){return typeof e==`object`&&!!e&&`security_analyzer`in e}var S=[];for(let e=0;e<256;++e)S.push((e+256).toString(16).slice(1));function ne(e,t=0){return(S[e[t+0]]+S[e[t+1]]+S[e[t+2]]+S[e[t+3]]+`-`+S[e[t+4]]+S[e[t+5]]+`-`+S[e[t+6]]+S[e[t+7]]+`-`+S[e[t+8]]+S[e[t+9]]+`-`+S[e[t+10]]+S[e[t+11]]+S[e[t+12]]+S[e[t+13]]+S[e[t+14]]+S[e[t+15]]).toLowerCase()}var re=new Uint8Array(16);function ie(){return crypto.getRandomValues(re)}function ae(e,t,n){return!t&&!e&&crypto.randomUUID?crypto.randomUUID():oe(e,t,n)}function oe(e,t,n){e||={};let r=e.random??e.rng?.()??ie();if(r.length<16)throw Error(`Random bytes length must be >= 16`);if(r[6]=r[6]&15|64,r[8]=r[8]&63|128,t){if(n||=0,n<0||n+16>t.length)throw RangeError(`UUID byte range ${n}:${n+15} is out of buffer bounds`);for(let e=0;e<16;++e)t[n+e]=r[e];return t}return ne(r)}var C=`openhands-agent-server-conversation-metadata`,w=()=>{if(typeof window>`u`)return{};try{let e=window.localStorage.getItem(C);if(!e)return{};let t=JSON.parse(e);return!t||typeof t!=`object`?{}:t}catch{return{}}},T=e=>{if(!(typeof window>`u`)){if(Object.keys(e).length===0){window.localStorage.removeItem(C);return}window.localStorage.setItem(C,JSON.stringify(e))}},E=e=>w()[e]??null,D=(e,t)=>{let n=w();n[e]=t,T(n)},O=e=>{let t=w();e in t&&(delete t[e],T(t))};function k(e){if(!e?.id)return e;let t=E(e.id);return t?{...e,selected_repository:e.selected_repository??t.selected_repository??null,selected_branch:e.selected_branch??t.selected_branch??null,git_provider:e.git_provider??t.git_provider??null,selected_workspace:e.selected_workspace??t.selected_workspace??null}:e}function A(){let e=r().backend;if(e.kind!==`cloud`)throw Error(`Cloud conversations call requires a cloud backend.`);return e}async function se(e=20,t){let n=A(),r=new URLSearchParams;r.set(`limit`,String(e)),t&&r.set(`page_id`,t),r.set(`sort_order`,`UPDATED_AT_DESC`);let i=await g({backend:n,method:`GET`,path:`/api/v1/app-conversations/search?${r.toString()}`});return{items:(i?.items??[]).map(e=>k(e)),next_page_id:i?.next_page_id??null}}async function j(e){if(e.length===0)return[];let t=A(),n=new URLSearchParams;for(let t of e)n.append(`ids`,t);return(await g({backend:t,method:`GET`,path:`/api/v1/app-conversations?${n.toString()}`})??[]).map(k)}async function ce(e){return await g({backend:A(),method:`POST`,path:`/api/v1/app-conversations`,body:e})}async function le(e){return g({backend:A(),method:`GET`,path:`/api/v1/app-conversations/${e}/download`,responseType:`blob`})}async function ue(e){await g({backend:A(),method:`DELETE`,path:`/api/v1/app-conversations/${e}`})}async function de(e,t){return await g({backend:A(),method:`PATCH`,path:`/api/v1/app-conversations/${e}`,body:{public:t}})}async function fe(e){await g({backend:A(),method:`POST`,path:`/api/v1/sandboxes/${e}/pause`})}async function pe(e){await g({backend:A(),method:`POST`,path:`/api/v1/sandboxes/${e}/resume`})}async function me(e,t){let n=A(),r=new URLSearchParams;return r.append(`file_path`,t),await g({backend:n,method:`GET`,path:`/api/v1/app-conversations/${e}/file?${r.toString()}`})??``}async function he(e){let t=A(),n=new URLSearchParams;return n.set(`ids`,e),(await g({backend:t,method:`GET`,path:`/api/v1/app-conversations/start-tasks?${n.toString()}`}))?.[0]??null}var M=`canvas_ui`,ge=`canvas_ui_tool`,_e=[`terminal`,`file_editor`,`task_tracker`,M],N=`browser_tool_set`,P=`task_tool_set`;function ve(){return!0}function ye(){let e=(void 0)?.trim();if(!e)return null;try{let t=JSON.parse(e);return!t||typeof t!=`object`?null:t}catch{return null}}function be(){let e=ye();if(!e?.services)return;let t=[];t.push(`<RUNTIME_SERVICES>`),e.mode?t.push(`You are running inside an agent-canvas dev stack started in '${e.mode}' mode.`):t.push(`You are running inside an agent-canvas dev stack.`),t.push(`The following services are reachable from your sandbox. URLs are written`,`from your point of view (i.e., as you should curl/fetch them).`,``);let{agent_server:n,ingress:r,automation:i}=e.services,a=e.services.frontend??e.services.vite;n?.url_from_agent&&t.push(`* Agent Server (you): ${n.url_from_agent}`,` ${n.description??`The agent-server hosting your tool calls.`}`),r?.url_from_agent&&t.push(`* Ingress: ${r.url_from_agent}`,` ${r.description??`Unified entry point for browser-facing traffic.`}`),a?.url_from_agent&&t.push(`* Frontend: ${a.url_from_agent}`,` ${a.description??`Frontend dev server.`}`),i?.url_from_agent?(t.push(`* Automation backend: ${i.url_from_agent}`,` ${i.description??`OpenHands Automations service.`}`),i.docs_url&&t.push(` Docs: ${i.docs_url}`),i.openapi_url&&t.push(` OpenAPI: ${i.openapi_url}`),i.auth_env_var&&t.push(` Auth: header 'X-API-Key: $${i.auth_env_var}'`)):t.push(`* Automation backend: not running in this dev mode (skip /api/automation calls).`);let o=n?.url_from_agent;return t.push(``,`Trust this block over guessing: do not assume any other URLs are running.`),o&&t.push(`In particular, ${o} inside your sandbox is the Agent Server`,`you are running inside of — NOT the automation backend.`),t.push(`</RUNTIME_SERVICES>`),t.join(`
|
|
3
|
-
`)}function xe(e){let{host:t}=s();return`${t}/api/conversations/${e}`}function F(e){return`Conversation ${e.slice(0,5)}`}function I(e){let t=E(e.id),r=e.agent?.kind===`ACPAgent`,i=r?e.tags?.acpserver??null:null;return{id:e.id,created_by_user_id:null,selected_repository:t?.selected_repository??null,selected_branch:t?.selected_branch??null,git_provider:t?.git_provider??null,selected_workspace:t?.selected_workspace??null,title:e.title?.trim()?e.title:F(e.id),trigger:null,pr_number:[],agent_kind:r?`acp`:`openhands`,acp_server:i,llm_model:r?y({runtimeName:e.current_model_name,runtimeId:e.current_model_id,configured:e.agent?.acp_model,sdkLlm:e.agent?.llm?.model}):e.agent?.llm?.model??_.llm_model,metrics:e.metrics?{accumulated_cost:e.metrics.accumulated_cost??null,max_budget_per_task:e.metrics.max_budget_per_task??null,accumulated_token_usage:e.metrics.accumulated_token_usage?{prompt_tokens:e.metrics.accumulated_token_usage.prompt_tokens??0,completion_tokens:e.metrics.accumulated_token_usage.completion_tokens??0,cache_read_tokens:e.metrics.accumulated_token_usage.cache_read_tokens??0,cache_write_tokens:e.metrics.accumulated_token_usage.cache_write_tokens??0,context_window:e.metrics.accumulated_token_usage.context_window??0,per_turn_token:e.metrics.accumulated_token_usage.per_turn_token??0}:null}:null,created_at:e.created_at,updated_at:e.updated_at,execution_status:e.execution_status??ee.IDLE,sandbox_status:e.sandbox_status??null,conversation_url:xe(e.id),session_api_key:s().apiKey??null,sandbox_id:null,workspace:{working_dir:e.workspace?.working_dir??n()},public:!1,sub_conversation_ids:[]}}function Se(e){return{items:e.items.map(I),next_page_id:e.next_page_id??null}}var L=[`acp_command`,`acp_args`,`acp_env`,`acp_model`,`acp_session_mode`,`acp_prompt_timeout`],Ce=`acpserver`,we=new Set([`schema_version`,`agent_settings`,`workspace`,`conversation_id`,`initial_message`,`plugins`]);function R(e){return!e||typeof e!=`object`||Array.isArray(e)?{}:structuredClone(e)}function z(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function Te(e){return e.confirmation_mode===!0?e.security_analyzer===`llm`?{kind:`ConfirmRisky`,threshold:`HIGH`,confirm_unknown:!0}:{kind:`AlwaysConfirm`}:{kind:`NeverConfirm`}}function Ee(e){switch(e.security_analyzer){case`llm`:return{kind:`LLMSecurityAnalyzer`};case`pattern`:return{kind:`PatternSecurityAnalyzer`};case`policy_rail`:return{kind:`PolicyRailSecurityAnalyzer`};default:return}}function De(e){return!!e&&typeof e==`object`&&!Array.isArray(e)&&typeof e.name==`string`}function B(e,t){return e===N?ve()&&m(e):e===P?t.enable_sub_agents===!0&&m(e):!0}function Oe(e){let t=new Map;for(let e of _e)t.set(e,{name:e,params:{}});for(let n of[N,P])B(n,e)&&t.set(n,{name:n,params:{}});let n=e.tools;if(Array.isArray(n)&&n.every(e=>De(e)))for(let r of n)B(r.name,e)&&t.set(r.name,{name:r.name,params:R(r.params)});return Array.from(t.values())}function ke(e,t){let n=[e?.trim(),t?.trim()].filter(Boolean);return n.length===0?null:{role:`user`,content:[{type:`text`,text:n.join(`
|
|
4
|
-
|
|
5
|
-
`)}],run:!0}}function V(e){let n=be();return{...R(e.agent_context),load_public_skills:t(),load_user_skills:!0,load_project_skills:!0,...n?{system_message_suffix:n}:{}}}function H(e){return R(e.agent_settings).agent_kind===`acp`}function Ae(e){let t=R(e.agent_settings).acp_server;return typeof t==`string`&&t.length>0?t:void 0}function je(e){let t=e.acp_command;if(!(Array.isArray(t)&&t.length===0)&&t!==void 0)return t;let n=v(typeof e.acp_server==`string`?e.acp_server:void 0);return n?[...n.default_command]:t}function Me(e){let t=R(e.agent_settings),n={agent_kind:`acp`,agent_context:V(t)};for(let e of L){if(e===`acp_model`)continue;let r=e===`acp_command`?je(t):t[e];r!=null&&(n[e]=r)}let r=v(typeof t.acp_server==`string`?t.acp_server:void 0),i=y({configured:t.acp_model,providerDefault:r?.default_model});return i&&(n.acp_model=i),n}function Ne(e){let t=R(e.agent_settings),n=R(t.llm);n.model=typeof n.model==`string`?n.model:_.llm_model;let r=z(n.api_key);r?n.api_key=r:delete n.api_key;let i=z(n.base_url);i?n.base_url=i:delete n.base_url;let a=R(t.mcp_config);(Object.keys(a).length===0||!(`mcpServers`in a))&&delete t.mcp_config,delete t.acp_server;for(let e of L)delete t[e];return{...t,llm:n,agent_context:V(t),tools:Oe(t)}}function Pe(e){return H(e)?Me(e):Ne(e)}function Fe(e){let{settings:t,query:r,conversationInstructions:i,plugins:a,workingDir:o}=e,s=R(t.conversation_settings),c=ke(r,i);return we.forEach(e=>delete s[e]),{...s,workspace:{kind:`LocalWorkspace`,working_dir:o??n()},...c?{initial_message:c}:{},...a?.length?{plugins:a.map(e=>({source:e.source,...e.ref?{ref:e.ref}:{},...e.repo_path?{repo_path:e.repo_path}:{}}))}:{}}}function Ie(e){let t=e.encryptedAgentSettings?{...e.settings,agent_settings:e.encryptedAgentSettings}:e.settings,n=H(t),r=Pe(t),i=n?Ae(t):void 0,a=Fe(e.encryptedConversationSettings?{...e,settings:{...e.settings,conversation_settings:e.encryptedConversationSettings}}:e),o={agent_settings:r,workspace:a.workspace,confirmation_policy:Te(a),max_iterations:typeof a.max_iterations==`number`?a.max_iterations:500,stuck_detection:!0,autotitle:!0,worktree:!0};i&&(o.tags={[Ce]:i}),e.secretsEncrypted&&(o.secrets_encrypted=!0),e.conversationId&&(o.conversation_id=e.conversationId);let s=Ee(a);if(s&&(o.security_analyzer=s),a.initial_message&&(o.initial_message=a.initial_message),a.plugins&&(o.plugins=a.plugins),a.hook_config&&(o.hook_config=a.hook_config),o.tool_module_qualnames={[M]:ge,...a.tool_module_qualnames??{}},a.agent_definitions&&(o.agent_definitions=a.agent_definitions),e.customSecrets&&e.customSecrets.length>0){let t=h(c()),r={};for(let n of e.customSecrets){let e={kind:`LookupSecret`,url:`/api/settings/secrets/${encodeURIComponent(n.name)}`,description:n.description};Object.keys(t).length>0&&(e.headers=t),r[n.name]=e}o.secrets=r,n&&(o.agent_settings.agent_context={...o.agent_settings.agent_context,secrets:r})}return o}async function Le(t){let{SecretsService:n}=await e(async()=>{let{SecretsService:e}=await import(`./secrets-service-Bwd5DeUs.js`).then(e=>e.n);return{SecretsService:e}},__vite__mapDeps([0,1,2,3,4,5])),[r,i]=await Promise.all([b.getSettingsForConversation(),n.getSecrets()]),{agentSettings:a,conversationSettings:o,secretsEncrypted:s}=r;return Ie({...t,encryptedAgentSettings:a,encryptedConversationSettings:o,secretsEncrypted:s,customSecrets:i})}function Re(){return{hooks:[]}}var ze=`1970-01-01T00:00:00.000Z`,Be=`Unable to load conversations because the selected agent server returned data this UI does not understand. Check the backend URL/session key and update the agent server if needed.`,Ve=`Unable to switch LLM profiles because the selected agent server returned profile data this UI does not understand. Check the backend URL/session key and update the agent server if needed.`;function U(){return Error(Be)}function W(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function He(e){return W(e)&&typeof e.model==`string`}function G(e){return typeof e==`number`?e:null}function K(e){return typeof e==`number`?e:0}function q(e){return typeof e==`string`?e:null}function J(e,t,n){let r=e[t]??e[n];return typeof r==`string`&&r.trim()?r:ze}function Ue(e){return W(e)?{prompt_tokens:K(e.prompt_tokens),completion_tokens:K(e.completion_tokens),cache_read_tokens:K(e.cache_read_tokens),cache_write_tokens:K(e.cache_write_tokens),context_window:K(e.context_window),per_turn_token:K(e.per_turn_token)}:null}function Y(e){return W(e)?{accumulated_cost:G(e.accumulated_cost),max_budget_per_task:G(e.max_budget_per_task),accumulated_token_usage:Ue(e.accumulated_token_usage)}:null}function We(e){if(!W(e))return null;let t=W(e.llm)?{model:q(e.llm.model)}:null;return{kind:q(e.kind),acp_model:q(e.acp_model),llm:t}}function Ge(e){return W(e)?{working_dir:q(e.working_dir)}:null}function Ke(e){if(!W(e))return null;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function X(e){if(!e.startsWith(`/`))return null;let t=[];for(let n of e.split(`/`))if(n&&n!==`.`)if(n===`..`){if(!t.length)return null;t.pop()}else t.push(n);return`/${t.join(`/`)}`}function Z(e,t){let n=X(e),r=X(t);if(!n||!r||n!==r&&!n.startsWith(`${r}/`))throw Error(`Conversation file path must stay inside the workspace`);return n}function Q(e){if(!W(e)||typeof e.id!=`string`||!e.id.trim())throw U();return{id:e.id.trim(),title:q(e.title),created_at:J(e,`created_at`,`createdAt`),updated_at:J(e,`updated_at`,`updatedAt`),execution_status:q(e.execution_status),sandbox_status:q(e.sandbox_status),metrics:Y(e.metrics),agent:We(e.agent),workspace:Ge(e.workspace),tags:Ke(e.tags),current_model_id:q(e.current_model_id),current_model_name:q(e.current_model_name)}}function $(e){if(!Array.isArray(e))throw U();return e.map(Q)}function qe(e){if(Array.isArray(e))return{items:$(e),next_page_id:null};if(!W(e))throw U();return{items:$(e.items),next_page_id:typeof e.next_page_id==`string`?e.next_page_id:null}}var Je=new Set([`idle`,`running`,`paused`,`waiting_for_confirmation`,`finished`,`error`,`stuck`]);function Ye(e){let t=e??`idle`;return Je.has(t)?t:`idle`}function Xe(e,t){if(!e)throw Error(`Conversation ${t} was not found`);return e}var Ze=class{static async sendMessage(e,t,n){let a=r().backend,o=n?.conversationUrl??null,c=n?.sessionApiKey??null;if(a.kind===`cloud`){if(!o||!c){let[t]=await j([e]);o=t?.conversation_url?.trim()??null,c=t?.session_api_key?.trim()??null}if(!o||!c)throw Error(`Conversation sandbox is still starting. Wait for it to finish, then try again.`);return await g({backend:a,method:`POST`,hostOverride:i(o),path:`/api/conversations/${e}/events`,body:{...t,run:!0},authMode:`session-api-key`,sessionApiKey:c}),t}return await new x(s({conversationUrl:o,sessionApiKey:c})).sendEvent(e,t,{run:!0}),t}static async createConversation(e,t,n,i,a,o,u,d){if(r().backend.kind===`cloud`)return ce({initial_message:e?{role:`user`,content:[{type:`text`,text:e}]}:null,title:t??null,selected_repository:i?.selected_repository??null,selected_branch:i?.selected_branch??null,git_provider:i?.git_provider??null,plugins:n??null,parent_conversation_id:o??null,agent_type:u,sandbox_id:d??null});let f=await b.getSettings(),p=ae(),m=await Le({settings:f,query:e,conversationInstructions:t,plugins:n,conversationId:p,workingDir:a??l(p)}),h=await new x(s()).createConversation(m);return(i?.selected_repository||a)&&D(h.id,{selected_repository:i?.selected_repository??null,selected_branch:i?.selected_branch??null,git_provider:i?.git_provider??null,selected_workspace:a??null}),{id:h.id,created_by_user_id:null,status:`READY`,detail:null,app_conversation_id:h.id,agent_server_url:c().host,request:{initial_message:m.initial_message,plugins:n??null},created_at:h.created_at,updated_at:h.updated_at}}static async getStartTask(e){return r().backend.kind===`cloud`?he(e):null}static async getVSCodeUrl(e,t,n){let r=await this.resolveConversationWorkingDir(e);return{vscode_url:await new d(s({conversationUrl:t,sessionApiKey:n})).getUrl({baseUrl:typeof window<`u`?window.location.origin:void 0,workspaceDir:r})}}static async resolveConversationWorkingDir(e){let[t]=await this.batchGetAppConversations([e]);return t?.workspace?.working_dir??n()}static async batchGetAppConversations(e){return e.length===0?[]:r().backend.kind===`cloud`?j(e):$(await new x(s()).getConversations(e)).map(e=>I(e))}static async updateConversationPublicFlag(e,t){if(r().backend.kind!==`cloud`)throw Error(`Public sharing requires a cloud backend.`);return de(e,t)}static async updateConversationRepository(e,t,n,r){t?D(e,{...E(e)??{},selected_repository:t,selected_branch:n??null,git_provider:r??null}):O(e);let[i]=await this.batchGetAppConversations([e]);return Xe(i,e)}static async readConversationFile(e,t){if(r().backend.kind===`cloud`)return me(e,Z(t??`/workspace/project/.agents_tmp/PLAN.md`,`/workspace/project`));let n=await this.resolveConversationWorkingDir(e),i=Z(t??`${n}/.agents_tmp/PLAN.md`,n);return new f(s()).downloadTextFile(i)}static async downloadConversation(e){return r().backend.kind===`cloud`?le(e):new f(s()).downloadTrajectory(e)}static async getHooks(e){return Re()}static async getRuntimeConversation(e,t,n){let a=r().backend,o=a.kind===`cloud`&&t?await g({backend:a,method:`GET`,hostOverride:i(t),path:`/api/conversations/${e}`,authMode:`session-api-key`,sessionApiKey:n}):await new x(s({conversationUrl:t,sessionApiKey:n})).getConversation(e),c=Q(o),l=W(o)?o.stats:null;return{id:c.id,title:c.title?.trim()?c.title:F(c.id),metrics:Y(c.metrics),created_at:c.created_at,updated_at:c.updated_at,status:Ye(c.execution_status),stats:W(l)?l:{usage_to_metrics:{}}}}static async searchConversations(e=20,t){return r().backend.kind===`cloud`?se(e,t):Se(qe(await new x(s()).searchConversations({limit:e,page_id:t,sort_order:u.UPDATED_AT_DESC})))}static async deleteConversation(e){r().backend.kind===`cloud`?await ue(e):await new x(s()).deleteConversation(e),O(e)}static async updateConversationTitle(e,t){await new x(s()).updateConversation(e,{title:t});let[n]=await this.batchGetAppConversations([e]);return Xe(n,e)}static async switchProfile(e,t){if(r().backend.kind===`cloud`)throw Error(`LLM profile switching is only supported for local agent-server backends.`);let n=new p(s());if(!e){await n.activateProfile(t);return}let i=await n.getProfile(t,{exposeSecrets:`encrypted`});if(!He(i.config))throw Error(Ve);await new x(s()).switchLLM(e,i.config)}static async switchAcpModel(e,t){if(r().backend.kind===`cloud`)throw Error(`ACP model switching is only supported for local agent-server backends.`);await new x(s()).switchAcpModel(e,t)}};export{E as a,pe as i,j as n,ae as o,fe as r,x as s,Ze as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./react-Do0CT17Y.js";var t={url:`https://github.com/OpenHands/OpenHands`,screenshotSrc:``},n=e(e=>({...t,setUrl:t=>e({url:t}),setScreenshotSrc:t=>e({screenshotSrc:t}),reset:()=>e(t)}));export{n as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-BFRubm34.js";import{t}from"./react-CM_dJw1Z.js";import{o as n,t as r}from"./declaration-D378OjpZ.js";import{t as i}from"./useTranslation-CpIcQBq6.js";import{t as a}from"./use-conversation-id-DajhCn2A.js";import{t as o}from"./browser-store-C3AqxAO7.js";import{t as s}from"./vendor~browser-tab-BiVxfjJo.js";import{t as c}from"./conversation-tab-empty-state-D8dNvo-V.js";var l=e(t(),1),u=n();function d({src:e}){let{t}=i(`openhands`);return(0,u.jsx)(`img`,{src:e,className:`rounded-xl object-contain w-full h-auto`,alt:t(r.BROWSER$SCREENSHOT_ALT)})}function f(){let{t:e}=i(`openhands`);return(0,u.jsx)(c,{icon:(0,u.jsx)(s,{}),children:e(r.BROWSER$NO_PAGE_LOADED)})}function p(){let{url:e,screenshotSrc:t,reset:n}=o(),{conversationId:r}=a();(0,l.useEffect)(()=>{n()},[r,n]);let i=t?.startsWith(`data:image/png;base64,`)?t:`data:image/png;base64,${t??``}`;return(0,u.jsxs)(`div`,{className:`h-full w-full flex flex-col text-[var(--oh-muted)]`,children:[(0,u.jsx)(`div`,{className:`w-full p-2 truncate border-b border-[var(--oh-border)]`,children:e}),(0,u.jsx)(`div`,{className:`overflow-y-auto grow scrollbar-hide rounded-xl`,children:t?(0,u.jsx)(d,{src:i}):(0,u.jsx)(f,{})})]})}function m(){return(0,u.jsx)(p,{})}export{m as default};
|