@openhands/agent-canvas 1.13.0 → 1.14.0
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 +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{acp-providers-D1PORKc0.js → acp-providers-CYy8qA2z.js} +1 -1
- package/build/assets/active-backend-context-BZDG15C0.js +2 -0
- package/build/assets/{agent-context-settings-DMrObcIS.js → agent-context-settings-DGWBBbcp.js} +1 -1
- package/build/assets/{agent-profiles-settings-DororXN5.js → agent-profiles-settings-DrkGdf4_.js} +1 -1
- package/build/assets/{agent-server-conversation-service.api-DWBe0rbX.js → agent-server-conversation-service.api-DK56YPTs.js} +7 -7
- package/build/assets/{agent-settings-BJVk92PU.js → agent-settings-DfcSgkLD.js} +2 -2
- package/build/assets/agent-settings-Lrc5-twS.js +1 -0
- package/build/assets/{alert-banner-CzZsm7ms.js → alert-banner-BgDHhL7b.js} +1 -1
- package/build/assets/api-error-message-BEIE_yD1.js +1 -0
- package/build/assets/{api-key-entry-screen-D8Fade_-.js → api-key-entry-screen-DaZnOlVo.js} +1 -1
- package/build/assets/{app-settings-CpyGB3AT.js → app-settings-BG5NAUbC.js} +1 -1
- package/build/assets/automation-detail-D4Hs831Z.js +3 -0
- package/build/assets/automation-export-n0X6FB0C.js +2 -0
- package/build/assets/automation-git-sync-CDrm8WV7.js +1 -0
- package/build/assets/automation-setup-route-CZCl4ONs.js +1 -0
- package/build/assets/{automation-templates-DgpCGOJV.js → automation-templates-DFF96AdL.js} +1 -1
- package/build/assets/automations-list-Bl-oGOrV.js +1 -0
- package/build/assets/{back-nav-button-HHEneWMw.js → back-nav-button-H_ThtDA0.js} +1 -1
- package/build/assets/{backend-form-modal-DiVrD4Cm.js → backend-form-modal-CbCemvHt.js} +1 -1
- package/build/assets/backend-not-configured-DP8KLNq_.js +1 -0
- package/build/assets/{backend-synced-settings-badge-7MIjpr8M.js → backend-synced-settings-badge-BBASWqsb.js} +1 -1
- package/build/assets/{badge-CpYmcVZV.js → badge-B-51h-SW.js} +1 -1
- package/build/assets/{base-modal-Fnh6Uln9.js → base-modal-BbjycA8X.js} +1 -1
- package/build/assets/{bot-BQZx8e2i.js → bot-CGPCg03p.js} +1 -1
- package/build/assets/{brand-button-swT1RyO0.js → brand-button-Blxv5nww.js} +1 -1
- package/build/assets/browser-CuW0nWvh.js +7 -0
- package/build/assets/{browser-tab-zAY12m_i.js → browser-tab-D5G0ORwt.js} +1 -1
- package/build/assets/{chat-send-button-DsJtivmL.js → chat-send-button-BD2tii1r.js} +1 -1
- package/build/assets/check-DSuS-lyr.js +1 -0
- package/build/assets/chevron-down-CgGcmtE2.js +1 -0
- package/build/assets/circle-check-CG5-NPw7.js +1 -0
- package/build/assets/{circle-plus-check-toggle-Cuzx55bo.js → circle-plus-check-toggle-ASbpB8vN.js} +1 -1
- package/build/assets/{cloud-funnel-analytics-86CwNdSh.js → cloud-funnel-analytics-GlCUG0gk.js} +1 -1
- package/build/assets/cog-CZiR80uT.js +1 -0
- package/build/assets/{combobox-caret-D0fRotFi.js → combobox-caret-DvpEsh2O.js} +1 -1
- package/build/assets/{command-menu-BXy03FBl.js → command-menu-DwUQzjYP.js} +1 -1
- package/build/assets/{condenser-settings-BmZa0ui_.js → condenser-settings-BptcoiLA.js} +1 -1
- package/build/assets/{confirmation-modal-BgoN6lbN.js → confirmation-modal-CiEwxZAA.js} +1 -1
- package/build/assets/{context-menu-list-item-Bq02tc-P.js → context-menu-list-item-CdcamfM1.js} +1 -1
- package/build/assets/conversation-DREHj4nT.js +1 -0
- package/build/assets/conversation-DotRfiDz.js +90 -0
- package/build/assets/conversation-panel-DREHj4nT.js +1 -0
- package/build/assets/conversation-state-store-DMLtlHbE.js +1 -0
- package/build/assets/{conversation-tab-empty-state-CMqo_0Bd.js → conversation-tab-empty-state-D-puECpY.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-Cg1pF0xn.js → copy-to-clipboard-button-BGxcUbgy.js} +1 -1
- package/build/assets/{device-verify-BfQLgNyq.js → device-verify-CZJfWaJf.js} +1 -1
- package/build/assets/{dropdown-classes-BIqQr5mx.js → dropdown-classes-tLhpwtxS.js} +1 -1
- package/build/assets/{entry.client-CxFjRYqH.js → entry.client-D8GnI6GZ.js} +2 -2
- package/build/assets/{enum-filter-dropdown-C_yV4_bo.js → enum-filter-dropdown-Fk8k60nk.js} +1 -1
- package/build/assets/{environment-switch-overlay-Bi4qbh2g.js → environment-switch-overlay-DeztVYuL.js} +1 -1
- package/build/assets/{extensions-hub-BqUINAhp.js → extensions-hub-Cd6GCYzq.js} +1 -1
- package/build/assets/{extensions-navigation-lraj88Wk.js → extensions-navigation-C4sgZg-y.js} +1 -1
- package/build/assets/{external-link-CgtpA_a1.js → external-link-C0UpBgsE.js} +1 -1
- package/build/assets/{file-text-DEK4LSVw.js → file-text-C6WYtNdV.js} +1 -1
- package/build/assets/files-tab-BW_qzyAm.js +1 -0
- package/build/assets/{form-control-classes-7yFSQJq_.js → form-control-classes-CGXBLcn1.js} +1 -1
- package/build/assets/format-model-name-BNPKVsIq.js +1 -0
- package/build/assets/format-relative-time-ZhQD4rsl.js +1 -0
- package/build/assets/git-provider-icon-CaQ1yLPi.js +1 -0
- package/build/assets/{git-repo-dropdown-ByMzpNko.js → git-repo-dropdown-CgXR6M_E.js} +1 -1
- package/build/assets/git-repo-dropdown-D2Uei3CO.js +1 -0
- package/build/assets/{highlighted-source-view-C_sfncLZ.js → highlighted-source-view-C_YOp8Fo.js} +1 -1
- package/build/assets/home-DNzzJcMP.js +1 -0
- package/build/assets/home-aCos-5vc.js +1 -0
- package/build/assets/{home-store-CxqsY9Fi.js → home-store-DgzViC3f.js} +1 -1
- package/build/assets/index-home-DNzzJcMP.js +1 -0
- package/build/assets/info-CLoC1LRo.js +1 -0
- package/build/assets/install-server-modal-D7zIqNKz.js +1 -0
- package/build/assets/kebab-menu-item-content-DERMdnDv.js +1 -0
- package/build/assets/{launch-CkqiSCqi.js → launch-5PjKeLak.js} +1 -1
- package/build/assets/{list-todo-DNWlzfaM.js → list-todo-BF049YaY.js} +1 -1
- package/build/assets/llm-not-configured-banner-BK9z5eS0.js +27 -0
- package/build/assets/llm-settings-BLAMK2tR.js +1 -0
- package/build/assets/llm-settings-BWsbarGM.js +1 -0
- package/build/assets/{llm-subscription-service-BAdOl5Xx.js → llm-subscription-service-SfnEV9Uc.js} +1 -1
- package/build/assets/loader-circle-D7IagAyF.js +1 -0
- package/build/assets/{loading-spinner-xhnrGP4Y.js → loading-spinner-DBgXgra0.js} +1 -1
- package/build/assets/{manage-backends-modal-DhGk5mJt.js → manage-backends-modal-BTqNPhzc.js} +1 -1
- package/build/assets/manifest-abebca3c.js +1 -0
- package/build/assets/manifest-subpage-layout-Rn-glaxV.js +1 -0
- package/build/assets/{map-provider-Mx8mZuE-.js → map-provider-BK4HnqYz.js} +1 -1
- package/build/assets/markdown-renderer-Cp6DlHQN.js +8 -0
- package/build/assets/{mcp-DCkvl6K0.js → mcp-BC-Ixn4T.js} +2 -2
- package/build/assets/{mcp-marketplace-utils-DEbMXlQr.js → mcp-marketplace-utils-BJWJgbB6.js} +1 -1
- package/build/assets/{messages-DSXvyc21.js → messages-CzFKrzPG.js} +5 -5
- package/build/assets/{modal-body-gIe21fDv.js → modal-body-BdKfD3Hl.js} +1 -1
- package/build/assets/{modal-classes-D66dlgZ7.js → modal-classes-D5_b5vMi.js} +1 -1
- package/build/assets/{modal-close-button-B6iOGYpI.js → modal-close-button-objukxk_.js} +1 -1
- package/build/assets/{mouse-pointer-click-BYX1Pw5W.js → mouse-pointer-click-C_gXyLyD.js} +1 -1
- package/build/assets/{npm-DLckoeJc.js → npm-CHVHV1MC.js} +1 -1
- package/build/assets/{onboarding-D7WDG66N.js → onboarding-Diw0V51A.js} +1 -1
- package/build/assets/onboarding-modal-Da4yHzsA.js +1 -0
- package/build/assets/{organization-service.api-D-s9z18a.js → organization-service.api-BztSy69u.js} +1 -1
- package/build/assets/parse-git-remote-url-BkXN9jzl.js +1 -0
- package/build/assets/{pencil-BGOCPRyu.js → pencil-49avMHlD.js} +1 -1
- package/build/assets/{planner-tab-AKaXIIfg.js → planner-tab-CJiSpNax.js} +1 -1
- package/build/assets/{plugins-management-service-wtmY4QQw.js → plugins-management-service-lHdNKWNU.js} +1 -1
- package/build/assets/plus-C0BagBpV.js +1 -0
- package/build/assets/profiles-service.api-BLr7FXec.js +1 -0
- package/build/assets/providers-CWXnb7S3.js +1 -0
- package/build/assets/{proxy-9Z_WZggZ.js → proxy-DYDXxtje.js} +1 -1
- package/build/assets/{puzzle-BWLmN8z4.js → puzzle-Bt2B1rzf.js} +1 -1
- package/build/assets/recommended-automations-launcher-CcFMfJRR.js +1 -0
- package/build/assets/{refresh-cw-CXtFWpwv.js → refresh-cw-nmcesifB.js} +1 -1
- package/build/assets/root-CT4t7apy.css +1 -0
- package/build/assets/root-DnRgLKpU.js +2 -0
- package/build/assets/root-layout-2L9tr-BN.js +2 -0
- package/build/assets/{schema-field-OnM5Uob_.js → schema-field-C59lVZTA.js} +1 -1
- package/build/assets/{sdk-section-page-m5WQm2sy.js → sdk-section-page-BbBEQQjq.js} +1 -1
- package/build/assets/search-CYSDBczG.js +1 -0
- package/build/assets/secrets-service-BtsgYSlj.js +1 -0
- package/build/assets/secrets-settings-DJ0OKa4_.js +1 -0
- package/build/assets/{segmented-toggle-DCspm2U5.js → segmented-toggle-DiVfTZuN.js} +1 -1
- package/build/assets/{settings-BJQI_iBM.js → settings-CDqL_Uqh.js} +1 -1
- package/build/assets/{settings-CWFxymAf.js → settings-DcNPxz0v.js} +1 -1
- package/build/assets/{settings-dropdown-input-BI8V_Nov.js → settings-dropdown-input-Ba1UN5Du.js} +1 -1
- package/build/assets/{settings-index-BiTqJoH7.js → settings-index-Cz2cKt2K.js} +1 -1
- package/build/assets/{settings-input-Cz62hWVW.js → settings-input-CWUEHHvS.js} +1 -1
- package/build/assets/{settings-list-classes-z_3FW5H3.js → settings-list-classes-DdcLXDGn.js} +1 -1
- package/build/assets/{settings-modal-BIrIVn97.js → settings-modal-nEEK1Kh1.js} +1 -1
- package/build/assets/{settings-service.api--rJmnuLa.js → settings-service.api-3yAUFcaP.js} +1 -1
- package/build/assets/{settings-switch-BRsSI8Vs.js → settings-switch-Dk9hChx1.js} +1 -1
- package/build/assets/{settings-utils-Ba7vel6T.js → settings-utils-CxjtCSB3.js} +1 -1
- package/build/assets/{shared-conversation-CQK_PqHx.js → shared-conversation-DbAcrx3s.js} +1 -1
- package/build/assets/{shield-check-T3JsDJiM.js → shield-check-CiOTXxV2.js} +1 -1
- package/build/assets/{sidebar-layout-Bhi3hVcu.js → sidebar-layout-lrfPooIB.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-YWJNRN4p.js → sidebar-mobile-menu-toggle-KERXfNu1.js} +1 -1
- package/build/assets/{sidebar-nav-link-BSUlY5Ml.js → sidebar-nav-link-B8lFD6Cb.js} +1 -1
- package/build/assets/{sidebar-store-Cl1cUv_F.js → sidebar-store-u6pUpxJ7.js} +1 -1
- package/build/assets/{skill-card-pill-row-BXz8L8Rn.js → skill-card-pill-row-dGIUzr_b.js} +1 -1
- package/build/assets/{skill-icon-badge-QgfKv31M.js → skill-icon-badge-kkOWZ89w.js} +1 -1
- package/build/assets/{skill-scope-Dc3JPW-8.js → skill-scope-DWN1PBPH.js} +1 -1
- package/build/assets/{skills-plugins-CpTV27n3.js → skills-plugins-DFjH2Nq6.js} +1 -1
- package/build/assets/{skills-settings-CSW__IW4.js → skills-settings-DIHpl3ol.js} +2 -2
- package/build/assets/{sparkles-TJ0mdECe.js → sparkles-ntyMLnbj.js} +1 -1
- package/build/assets/{styled-tooltip-BUMSbgrF.js → styled-tooltip-B6JXcsmL.js} +1 -1
- package/build/assets/{task-list-tab-mAHMOkUz.js → task-list-tab-aEJzEcHD.js} +1 -1
- package/build/assets/{terminal-BzxBaHx2.js → terminal-Dch7Ty5K.js} +1 -1
- package/build/assets/{toggle-switch-O5v1FgxW.js → toggle-switch-B2MLKsgt.js} +1 -1
- package/build/assets/{trash-2-C0xNVp9c.js → trash-2-yZnDM4Ji.js} +1 -1
- package/build/assets/{typography-NOKSk9_R.js → typography-DB5HoCk0.js} +1 -1
- package/build/assets/usage-tab-DrEtBmBT.js +1 -0
- package/build/assets/use-acp-credential-form-c8KXAa8A.js +1 -0
- package/build/assets/{use-activate-agent-profile-D9YRQPTF.js → use-activate-agent-profile-B0p34N3q.js} +1 -1
- package/build/assets/use-agent-profiles-CPIc6wLH.js +1 -0
- package/build/assets/{use-can-manage-org-profiles-Dxzq2AEd.js → use-can-manage-org-profiles-Dz_8Eqkv.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-Co2eJk2A.js → use-cloud-current-user-id-DvUVqCle.js} +1 -1
- package/build/assets/use-config-C3PO4TBw.js +1 -0
- package/build/assets/{use-create-conversation-CoHTiCbI.js → use-create-conversation-DVrA_uLD.js} +1 -1
- package/build/assets/use-create-secret-DbBIpaCR.js +1 -0
- package/build/assets/use-get-secrets-6PBitf54.js +1 -0
- package/build/assets/use-has-permission-CQ31Cl8j.js +1 -0
- package/build/assets/use-is-authed-2UrDIziV.js +1 -0
- package/build/assets/use-is-creating-conversation-BvYpmb3v.js +1 -0
- package/build/assets/use-llm-profiles-diZS4FiN.js +1 -0
- package/build/assets/use-manifest-capabilities-HIWCtIUm.js +1 -0
- package/build/assets/{use-onboarding-completion-CCE8OQgV.js → use-onboarding-completion-Bs8PcXik.js} +1 -1
- package/build/assets/{use-plugins-marketplace-CEiak69h.js → use-plugins-marketplace-BCuNLFsr.js} +1 -1
- package/build/assets/use-save-agent-profile-BaMNSpBV.js +1 -0
- package/build/assets/{use-save-settings-DNmnbG6f.js → use-save-settings-BahvC2Gw.js} +1 -1
- package/build/assets/{use-settings-wCwPaSIv.js → use-settings-C6ZxpBDX.js} +1 -1
- package/build/assets/{use-settings-nav-items-BlFL7YhM.js → use-settings-nav-items-Bqn69Ggw.js} +2 -2
- package/build/assets/use-tracking-Bhu7gk2y.js +3 -0
- package/build/assets/{use-user-conversation-DVtfg0B_.js → use-user-conversation-BkNXpXrd.js} +1 -1
- package/build/assets/{useInfiniteQuery-p1xq35r2.js → useInfiniteQuery-c_OmS3lK.js} +1 -1
- package/build/assets/{useMutation-BFDQmgk9.js → useMutation-6ZsQCqAn.js} +1 -1
- package/build/assets/{useQueries-DF1NAAeC.js → useQueries-xDrGlTO_.js} +1 -1
- package/build/assets/{useQuery-DRv--6bK.js → useQuery-Bs5NFz2s.js} +1 -1
- package/build/assets/{utils-zxEjKE70.js → utils-DUD5ScdA.js} +1 -1
- package/build/assets/{vendor~entry.client-CgNUwtQL.js → vendor~entry.client-BFE7Llz9.js} +1 -1
- package/build/assets/{vendor~entry.client-zSIea5EO.js → vendor~entry.client-BaKt_PIp.js} +1 -1
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kv3pap4j-B8i84bh4.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kepq2zme-D87mAf6K.js} +1 -1
- package/build/assets/{vendor~files-tab-D9wR9yM2.js → vendor~files-tab-B6POTS66.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation-Ipoe6hvY.js → vendor~index-home~home~conversation-panel~conversation-53Q_U6uP.js} +1 -1
- package/build/assets/{vendor~root-layout-C-IgVx6e.js → vendor~root-layout-DeQACFVA.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation-Dhd_I4H4.js → vendor~root-layout~conversation-panel~conversation-bv7ooVgH.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-Cc0f9kPP.js → vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-e8pX05xf.js} +1 -1
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-d7svw-BB.js → vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-BvS6PCK2.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-4WsUP-tz.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-DOPLJMH9.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gxu4j2ea-D5DWZVc7.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iw7io29p-Dz8NQve5.js} +1 -1
- package/build/assets/{verification-settings-B8UMQ7MG.js → verification-settings-COueVXmM.js} +1 -1
- package/build/assets/{wrench-DIka3hCq.js → wrench-C95ujnYo.js} +1 -1
- package/build/assets/x-86ZCfxKY.js +1 -0
- package/build/assets/{zap-DHddTPc0.js → zap-DRa-r-Tf.js} +1 -1
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +60 -2
- package/build/locales/ca/openhands.json +60 -2
- package/build/locales/de/openhands.json +60 -2
- package/build/locales/en/openhands.json +60 -2
- package/build/locales/es/openhands.json +60 -2
- package/build/locales/fr/openhands.json +60 -2
- package/build/locales/it/openhands.json +60 -2
- package/build/locales/ja/openhands.json +60 -2
- package/build/locales/ko-KR/openhands.json +60 -2
- package/build/locales/no/openhands.json +60 -2
- package/build/locales/pt/openhands.json +60 -2
- package/build/locales/tr/openhands.json +60 -2
- package/build/locales/uk/openhands.json +60 -2
- package/build/locales/zh-CN/openhands.json +60 -2
- package/build/locales/zh-TW/openhands.json +60 -2
- package/config/defaults.json +1 -1
- package/dist/api/automation-service/automation-service.api.cjs +1 -1
- package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
- package/dist/api/automation-service/automation-service.api.d.ts +10 -0
- package/dist/api/automation-service/automation-service.api.js +42 -0
- package/dist/api/automation-service/automation-service.api.js.map +1 -1
- package/dist/api/cloud/conversation-service.api.cjs +1 -1
- package/dist/api/cloud/conversation-service.api.cjs.map +1 -1
- package/dist/api/cloud/conversation-service.api.d.ts +9 -0
- package/dist/api/cloud/conversation-service.api.js +11 -1
- package/dist/api/cloud/conversation-service.api.js.map +1 -1
- package/dist/api/profiles-service/profiles-service.api.cjs +1 -1
- package/dist/api/profiles-service/profiles-service.api.cjs.map +1 -1
- package/dist/api/profiles-service/profiles-service.api.d.ts +15 -2
- package/dist/api/profiles-service/profiles-service.api.js +25 -2
- package/dist/api/profiles-service/profiles-service.api.js.map +1 -1
- package/dist/api/secrets-service.cjs +1 -1
- package/dist/api/secrets-service.cjs.map +1 -1
- package/dist/api/secrets-service.d.ts +5 -0
- package/dist/api/secrets-service.js +12 -6
- package/dist/api/secrets-service.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/index.d.ts +0 -1
- package/dist/components/features/automations/git-sync/git-sync-activity-row.d.ts +15 -0
- package/dist/components/features/automations/git-sync/git-sync-config-form.d.ts +13 -0
- package/dist/components/features/automations/git-sync/git-sync-error-banner.d.ts +6 -0
- package/dist/components/features/automations/git-sync/git-sync-not-local-state.d.ts +1 -0
- package/dist/components/features/automations/git-sync/git-sync-overview-section.d.ts +12 -0
- package/dist/components/features/automations/git-sync/git-sync-skeleton.d.ts +1 -0
- package/dist/components/features/automations/git-sync/git-sync-status-pill.d.ts +7 -0
- package/dist/components/features/automations/git-sync/git-sync-unsupported-state.d.ts +7 -0
- package/dist/components/features/automations/responder-deployment-modal.d.ts +2 -1
- package/dist/components/features/chat/chat-interface.cjs +2 -2
- package/dist/components/features/chat/chat-interface.cjs.map +1 -1
- package/dist/components/features/chat/chat-interface.js +177 -176
- package/dist/components/features/chat/chat-interface.js.map +1 -1
- package/dist/components/features/chat/error-message-banner.cjs +1 -1
- package/dist/components/features/chat/error-message-banner.cjs.map +1 -1
- package/dist/components/features/chat/error-message-banner.d.ts +3 -1
- package/dist/components/features/chat/error-message-banner.js +64 -58
- package/dist/components/features/chat/error-message-banner.js.map +1 -1
- package/dist/components/features/conversation-panel/compact-conversation-row.cjs +1 -1
- package/dist/components/features/conversation-panel/compact-conversation-row.js +6 -6
- package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.js +19 -19
- package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +10 -7
- package/dist/components/shared/buttons/conversation-confirmation-buttons.cjs +1 -1
- package/dist/components/shared/buttons/conversation-confirmation-buttons.cjs.map +1 -1
- package/dist/components/shared/buttons/conversation-confirmation-buttons.js +1 -1
- package/dist/components/shared/buttons/conversation-confirmation-buttons.js.map +1 -1
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/contexts/conversation-websocket-context.cjs +2 -2
- package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
- package/dist/contexts/conversation-websocket-context.js +12 -12
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/hooks/query/use-commit-changes.cjs +1 -1
- package/dist/hooks/query/use-commit-changes.js +4 -4
- package/dist/hooks/query/use-git-sync.d.ts +19 -0
- package/dist/hooks/query/use-task-polling.cjs +1 -1
- package/dist/hooks/query/use-task-polling.cjs.map +1 -1
- package/dist/hooks/query/use-task-polling.js +12 -10
- package/dist/hooks/query/use-task-polling.js.map +1 -1
- package/dist/hooks/query/use-unified-get-git-changes.cjs +1 -1
- package/dist/hooks/query/use-unified-get-git-changes.js +4 -4
- package/dist/hooks/query/use-unified-git-commits.cjs +1 -1
- package/dist/hooks/query/use-unified-git-commits.js +4 -4
- package/dist/hooks/query/use-unified-git-diff.cjs +1 -1
- package/dist/hooks/query/use-unified-git-diff.js +4 -4
- package/dist/hooks/query/use-workspace-files.cjs +1 -1
- package/dist/hooks/query/use-workspace-files.cjs.map +1 -1
- package/dist/hooks/query/use-workspace-files.d.ts +14 -4
- package/dist/hooks/query/use-workspace-files.js +45 -32
- package/dist/hooks/query/use-workspace-files.js.map +1 -1
- package/dist/hooks/use-responder-url-secret.d.ts +5 -0
- package/dist/hooks/use-tracking.cjs +1 -1
- package/dist/hooks/use-tracking.cjs.map +1 -1
- package/dist/hooks/use-tracking.d.ts +6 -0
- package/dist/hooks/use-tracking.js +6 -0
- package/dist/hooks/use-tracking.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 +59 -1
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +1 -1
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +1001 -15
- package/dist/i18n/translation.js.map +1 -1
- package/dist/locales/ar/openhands.json +60 -2
- package/dist/locales/ca/openhands.json +60 -2
- package/dist/locales/de/openhands.json +60 -2
- package/dist/locales/en/openhands.json +60 -2
- package/dist/locales/es/openhands.json +60 -2
- package/dist/locales/fr/openhands.json +60 -2
- package/dist/locales/it/openhands.json +60 -2
- package/dist/locales/ja/openhands.json +60 -2
- package/dist/locales/ko-KR/openhands.json +60 -2
- package/dist/locales/no/openhands.json +60 -2
- package/dist/locales/pt/openhands.json +60 -2
- package/dist/locales/tr/openhands.json +60 -2
- package/dist/locales/uk/openhands.json +60 -2
- package/dist/locales/zh-CN/openhands.json +60 -2
- package/dist/locales/zh-TW/openhands.json +60 -2
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-alert.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-alert.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-alert.js +27 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-alert.js.map +1 -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/files-tab.cjs +1 -1
- package/dist/routes/files-tab.js +11 -11
- package/dist/routes/files-tab.js.map +1 -1
- package/dist/services/settings.cjs +1 -1
- package/dist/services/settings.cjs.map +1 -1
- package/dist/services/settings.js +2 -2
- package/dist/services/settings.js.map +1 -1
- package/dist/services/telemetry.cjs +1 -1
- package/dist/services/telemetry.cjs.map +1 -1
- package/dist/services/telemetry.js +47 -51
- package/dist/services/telemetry.js.map +1 -1
- package/dist/stores/error-message-store.cjs +1 -1
- package/dist/stores/error-message-store.cjs.map +1 -1
- package/dist/stores/error-message-store.d.ts +3 -1
- package/dist/stores/error-message-store.js +5 -3
- package/dist/stores/error-message-store.js.map +1 -1
- package/dist/types/git-sync.d.ts +51 -0
- package/dist/utils/error-handler.cjs +1 -1
- package/dist/utils/error-handler.cjs.map +1 -1
- package/dist/utils/error-handler.d.ts +3 -2
- package/dist/utils/error-handler.js +18 -5
- package/dist/utils/error-handler.js.map +1 -1
- package/dist/utils/format-model-name.cjs +1 -1
- package/dist/utils/format-model-name.cjs.map +1 -1
- package/dist/utils/format-model-name.d.ts +1 -0
- package/dist/utils/format-model-name.js +1 -0
- package/dist/utils/format-model-name.js.map +1 -1
- package/dist/utils/transcript-export/load-complete-events.cjs +1 -1
- package/dist/utils/transcript-export/load-complete-events.cjs.map +1 -1
- package/dist/utils/transcript-export/load-complete-events.js +24 -16
- package/dist/utils/transcript-export/load-complete-events.js.map +1 -1
- package/package.json +1 -1
- package/scripts/check-translation-completeness.cjs +3 -0
- package/scripts/dev-with-automation.mjs +98 -9
- package/build/assets/active-backend-context-IqOjobNK.js +0 -2
- package/build/assets/agent-settings-COfJsQ1d.js +0 -1
- package/build/assets/automation-detail-B-jQ39Mm.js +0 -3
- package/build/assets/automation-export-B1dywoqk.js +0 -2
- package/build/assets/automation-setup-route-C-bWUZBi.js +0 -1
- package/build/assets/automations-list-DnMxlxsL.js +0 -1
- package/build/assets/browser-B9AbV6kG.js +0 -7
- package/build/assets/check-WAFXrrs_.js +0 -1
- package/build/assets/chevron-down-CifNWzme.js +0 -1
- package/build/assets/circle-check-CtnimJa8.js +0 -1
- package/build/assets/conversation-BPo8SvLN.js +0 -1
- package/build/assets/conversation-CPCVsCUY.js +0 -90
- package/build/assets/conversation-panel-BPo8SvLN.js +0 -1
- package/build/assets/conversation-state-store-C5YpjMNy.js +0 -1
- package/build/assets/files-tab-DV0L-lFE.js +0 -1
- package/build/assets/format-model-name-BN_rx1Y3.js +0 -1
- package/build/assets/format-relative-time-DSErAuVr.js +0 -1
- package/build/assets/git-provider-icon-BvlLAche.js +0 -1
- package/build/assets/git-repo-dropdown-C6R7hgM8.js +0 -1
- package/build/assets/home-BOrlwLqG.js +0 -1
- package/build/assets/home-BvMNC6E-.js +0 -1
- package/build/assets/index-home-BvMNC6E-.js +0 -1
- package/build/assets/info-BRVcJAUg.js +0 -1
- package/build/assets/install-server-modal-Bl4G1zF4.js +0 -1
- package/build/assets/kebab-menu-item-content-BGoGFEAg.js +0 -1
- package/build/assets/llm-not-configured-banner-DLw_tu-G.js +0 -27
- package/build/assets/llm-settings-B-pkVCrt.js +0 -1
- package/build/assets/llm-settings-DSC0-IQ7.js +0 -1
- package/build/assets/loader-circle-B47W9XqT.js +0 -1
- package/build/assets/manifest-653b89aa.js +0 -1
- package/build/assets/manifest-subpage-layout-CKWvL2ig.js +0 -1
- package/build/assets/markdown-renderer-DUmk7pFc.js +0 -8
- package/build/assets/onboarding-modal-C_xVrFNv.js +0 -1
- package/build/assets/plus-zNEL8rcX.js +0 -1
- package/build/assets/profiles-service.api-DCMYxHMi.js +0 -1
- package/build/assets/providers-BjrtjX4L.js +0 -1
- package/build/assets/recommended-automations-launcher-CFlzhu1o.js +0 -1
- package/build/assets/root-CanxKlNV.css +0 -1
- package/build/assets/root-DkfG_UWR.js +0 -2
- package/build/assets/root-layout-D75LHYhh.js +0 -2
- package/build/assets/search-CycosyjN.js +0 -1
- package/build/assets/secrets-service-B26R61C1.js +0 -1
- package/build/assets/secrets-settings-CbLYCKOX.js +0 -1
- package/build/assets/usage-tab-tEmVN0KD.js +0 -1
- package/build/assets/use-acp-credential-form-BPNi0Zbm.js +0 -1
- package/build/assets/use-agent-profiles-Cb2zUW3l.js +0 -1
- package/build/assets/use-config-DKAMiI5R.js +0 -1
- package/build/assets/use-create-secret-2zBlCDsF.js +0 -1
- package/build/assets/use-is-authed-C52-ivnB.js +0 -1
- package/build/assets/use-is-creating-conversation-DdaAE6jV.js +0 -1
- package/build/assets/use-llm-profiles-C_BHue65.js +0 -1
- package/build/assets/use-manifest-capabilities-DPrQsaPP.js +0 -1
- package/build/assets/use-save-agent-profile-DK9idD6a.js +0 -1
- package/build/assets/use-tracking-CVwPmhlX.js +0 -3
- package/build/assets/x-BWKA2Ver.js +0 -1
- package/dist/api/cloud/suggestions-service.api.d.ts +0 -8
- package/dist/api/suggestions-service/suggestions-service.api.d.ts +0 -11
- package/dist/components/conversation-events/chat/event-message-components/observation-pair-event-message.d.ts +0 -7
- package/dist/components/conversation-events/index.d.ts +0 -1
- package/dist/components/features/automations/metadata-chip.d.ts +0 -6
- package/dist/components/features/chat/task-tracking/status-badge.d.ts +0 -5
- package/dist/components/features/chat/task-tracking/status-icon.d.ts +0 -5
- package/dist/components/features/chat/task-tracking/task-list-section.d.ts +0 -10
- package/dist/components/features/controls/tools.d.ts +0 -2
- package/dist/components/features/conversation-panel/new-conversation-button.d.ts +0 -23
- package/dist/components/features/home/home-header/guide-message.d.ts +0 -1
- package/dist/components/features/home/home-header/home-header.d.ts +0 -1
- package/dist/components/features/home/new-conversation/create-conversation-button.d.ts +0 -1
- package/dist/components/features/home/new-conversation/new-conversation.d.ts +0 -1
- package/dist/components/features/home/new-conversation.d.ts +0 -1
- package/dist/components/features/home/tasks/task-card.d.ts +0 -6
- package/dist/components/features/home/tasks/task-group.d.ts +0 -7
- package/dist/components/features/home/tasks/task-issue-number.d.ts +0 -6
- package/dist/components/features/home/tasks/task-item-title.d.ts +0 -1
- package/dist/components/features/home/tasks/task-suggestions-skeleton.d.ts +0 -1
- package/dist/components/features/home/tasks/task-suggestions.d.ts +0 -6
- package/dist/components/features/settings/agent-server-onboarding.d.ts +0 -10
- package/dist/components/features/settings/mcp-settings/mcp-server-list-item.d.ts +0 -6
- package/dist/components/features/settings/mcp-settings/mcp-server-list.d.ts +0 -8
- package/dist/hooks/query/use-suggested-tasks.d.ts +0 -1
- package/dist/hooks/use-should-show-user-features.d.ts +0 -1
- package/dist/ui/card-title.d.ts +0 -16
- package/dist/ui/card.d.ts +0 -14
- package/dist/utils/group-suggested-tasks.d.ts +0 -7
- /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dh9v73sa-rfV8mQ9m.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dcc51rps-rfV8mQ9m.js} +0 -0
- /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~lq5hicxx-cHFhpUBq.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ox0jfsa0-cHFhpUBq.js} +0 -0
- /package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~9pstowjp-BOVIFA_g.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-BOVIFA_g.js} +0 -0
- /package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~ht43enc2-C0JXQb_q.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~jz4f6vo2-C0JXQb_q.js} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ErrorClassification } from "@openhands/typescript-client";
|
|
1
2
|
/**
|
|
2
3
|
* "connection" errors auto-clear once connectivity recovers; "conversation"
|
|
3
4
|
* errors (e.g. a wrong API key) are sticky and clear only on an explicit user
|
|
@@ -13,9 +14,10 @@ interface ErrorMessageState {
|
|
|
13
14
|
* null for errors that carry no code (connection errors, plain strings).
|
|
14
15
|
*/
|
|
15
16
|
errorCode: string | null;
|
|
17
|
+
errorClassification: ErrorClassification | null;
|
|
16
18
|
}
|
|
17
19
|
interface ErrorMessageActions {
|
|
18
|
-
setErrorMessage: (message: string, type?: ErrorMessageType, code?: string | null) => void;
|
|
20
|
+
setErrorMessage: (message: string, type?: ErrorMessageType, code?: string | null, classification?: ErrorClassification | null) => void;
|
|
19
21
|
removeErrorMessage: () => void;
|
|
20
22
|
/** Clears the error only when it is a transient connection error. */
|
|
21
23
|
clearConnectionError: () => void;
|
|
@@ -3,13 +3,15 @@ import { create as e } from "../node_modules/zustand/esm/react.js";
|
|
|
3
3
|
var t = {
|
|
4
4
|
errorMessage: null,
|
|
5
5
|
errorType: null,
|
|
6
|
-
errorCode: null
|
|
6
|
+
errorCode: null,
|
|
7
|
+
errorClassification: null
|
|
7
8
|
}, n = e((e) => ({
|
|
8
9
|
...t,
|
|
9
|
-
setErrorMessage: (t, n = "conversation", r = null) => e(() => ({
|
|
10
|
+
setErrorMessage: (t, n = "conversation", r = null, i = null) => e(() => ({
|
|
10
11
|
errorMessage: t,
|
|
11
12
|
errorType: n,
|
|
12
|
-
errorCode: r
|
|
13
|
+
errorCode: r,
|
|
14
|
+
errorClassification: i
|
|
13
15
|
})),
|
|
14
16
|
removeErrorMessage: () => e(() => ({ ...t })),
|
|
15
17
|
clearConnectionError: () => e((e) => e.errorType === "connection" ? { ...t } : e)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-message-store.js","names":[],"sources":["../../src/stores/error-message-store.ts"],"sourcesContent":["import { create } from \"zustand\";\n\n/**\n * \"connection\" errors auto-clear once connectivity recovers; \"conversation\"\n * errors (e.g. a wrong API key) are sticky and clear only on an explicit user\n * action (dismiss, retry, new message).\n */\nexport type ErrorMessageType = \"connection\" | \"conversation\";\n\ninterface ErrorMessageState {\n errorMessage: string | null;\n errorType: ErrorMessageType | null;\n /**\n * Structured error code from a ConversationErrorEvent/ServerErrorEvent (e.g.\n * \"ACPAuthRequired\"), used to render a code-specific header + recovery action.\n * null for errors that carry no code (connection errors, plain strings).\n */\n errorCode: string | null;\n}\n\ninterface ErrorMessageActions {\n setErrorMessage: (\n message: string,\n type?: ErrorMessageType,\n code?: string | null,\n ) => void;\n removeErrorMessage: () => void;\n /** Clears the error only when it is a transient connection error. */\n clearConnectionError: () => void;\n}\n\ntype ErrorMessageStore = ErrorMessageState & ErrorMessageActions;\n\nconst initialState: ErrorMessageState = {\n errorMessage: null,\n errorType: null,\n errorCode: null,\n};\n\nexport const useErrorMessageStore = create<ErrorMessageStore>((set) => ({\n ...initialState,\n\n setErrorMessage: (\n message: string,\n type: ErrorMessageType = \"conversation\",\n code: string | null = null,\n ) =>\n set(() => ({\n errorMessage: message,\n errorType: type,\n errorCode: code,\n })),\n\n removeErrorMessage: () => set(() => ({ ...initialState })),\n\n clearConnectionError: () =>\n set((state) =>\n state.errorType === \"connection\" ? { ...initialState } : state,\n ),\n}));\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"error-message-store.js","names":[],"sources":["../../src/stores/error-message-store.ts"],"sourcesContent":["import { create } from \"zustand\";\nimport type { ErrorClassification } from \"@openhands/typescript-client\";\n\n/**\n * \"connection\" errors auto-clear once connectivity recovers; \"conversation\"\n * errors (e.g. a wrong API key) are sticky and clear only on an explicit user\n * action (dismiss, retry, new message).\n */\nexport type ErrorMessageType = \"connection\" | \"conversation\";\n\ninterface ErrorMessageState {\n errorMessage: string | null;\n errorType: ErrorMessageType | null;\n /**\n * Structured error code from a ConversationErrorEvent/ServerErrorEvent (e.g.\n * \"ACPAuthRequired\"), used to render a code-specific header + recovery action.\n * null for errors that carry no code (connection errors, plain strings).\n */\n errorCode: string | null;\n errorClassification: ErrorClassification | null;\n}\n\ninterface ErrorMessageActions {\n setErrorMessage: (\n message: string,\n type?: ErrorMessageType,\n code?: string | null,\n classification?: ErrorClassification | null,\n ) => void;\n removeErrorMessage: () => void;\n /** Clears the error only when it is a transient connection error. */\n clearConnectionError: () => void;\n}\n\ntype ErrorMessageStore = ErrorMessageState & ErrorMessageActions;\n\nconst initialState: ErrorMessageState = {\n errorMessage: null,\n errorType: null,\n errorCode: null,\n errorClassification: null,\n};\n\nexport const useErrorMessageStore = create<ErrorMessageStore>((set) => ({\n ...initialState,\n\n setErrorMessage: (\n message: string,\n type: ErrorMessageType = \"conversation\",\n code: string | null = null,\n classification: ErrorClassification | null = null,\n ) =>\n set(() => ({\n errorMessage: message,\n errorType: type,\n errorCode: code,\n errorClassification: classification,\n })),\n\n removeErrorMessage: () => set(() => ({ ...initialState })),\n\n clearConnectionError: () =>\n set((state) =>\n state.errorType === \"connection\" ? { ...initialState } : state,\n ),\n}));\n"],"mappings":";;AAoCA,IAAM,IAAkC;CACtC,cAAc;CACd,WAAW;CACX,WAAW;CACX,qBAAqB;AACvB,GAEa,IAAuB,GAA2B,OAAS;CACtE,GAAG;CAEH,kBACE,GACA,IAAyB,gBACzB,IAAsB,MACtB,IAA6C,SAE7C,SAAW;EACT,cAAc;EACd,WAAW;EACX,WAAW;EACX,qBAAqB;CACvB,EAAE;CAEJ,0BAA0B,SAAW,EAAE,GAAG,EAAa,EAAE;CAEzD,4BACE,GAAK,MACH,EAAM,cAAc,eAAe,EAAE,GAAG,EAAa,IAAI,CAC3D;AACJ,EAAE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface GitSyncStatus {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
repo_url: string;
|
|
4
|
+
branch: string;
|
|
5
|
+
path: string;
|
|
6
|
+
encryption_enabled: boolean;
|
|
7
|
+
/** Seconds between automatic syncs; 0 means manual-only. */
|
|
8
|
+
interval_seconds: number;
|
|
9
|
+
last_synced_commit: string | null;
|
|
10
|
+
last_synced_at: string | null;
|
|
11
|
+
last_error: string | null;
|
|
12
|
+
last_error_at: string | null;
|
|
13
|
+
dirty_count: number;
|
|
14
|
+
/**
|
|
15
|
+
* Whether a sync cycle is running right now, including one the backend's own
|
|
16
|
+
* interval started. A cycle reports its outcome only once it ends, so
|
|
17
|
+
* without this the page cannot tell a sync in flight from one that never
|
|
18
|
+
* started. Absent on automation backends that predate the field.
|
|
19
|
+
*/
|
|
20
|
+
sync_in_progress?: boolean;
|
|
21
|
+
sync_started_at?: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface GitSyncConfigUpdateRequest {
|
|
24
|
+
enabled?: boolean | null;
|
|
25
|
+
interval_seconds?: number | null;
|
|
26
|
+
repo_url?: string | null;
|
|
27
|
+
branch?: string | null;
|
|
28
|
+
path?: string | null;
|
|
29
|
+
token?: string | null;
|
|
30
|
+
encryption_key?: string | null;
|
|
31
|
+
author_name?: string | null;
|
|
32
|
+
author_email?: string | null;
|
|
33
|
+
}
|
|
34
|
+
export interface GitSyncTriggerResponse {
|
|
35
|
+
triggered: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Whether a configuration can reach its repo, from `POST /v1/git-sync/check`.
|
|
39
|
+
*
|
|
40
|
+
* `ok` is about reachability only -- the backend runs a single `git ls-remote`
|
|
41
|
+
* rather than a sync, so a token without write scope passes here and still
|
|
42
|
+
* fails at push time, and the encryption key is never exercised.
|
|
43
|
+
* `branch_exists: false` alongside `ok: true` is normal for a repo that has
|
|
44
|
+
* never been synced: the first cycle creates the branch.
|
|
45
|
+
*/
|
|
46
|
+
export interface GitSyncCheckResponse {
|
|
47
|
+
ok: boolean;
|
|
48
|
+
branch_exists: boolean;
|
|
49
|
+
/** git's own failure output, with credentials in the URL redacted. */
|
|
50
|
+
detail: string | null;
|
|
51
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");const e=require("../services/telemetry.cjs");
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");const e=require("../services/telemetry.cjs");var t=new Set([`error_source`,`error_kind`,`error_id`,`error_telemetry`]);function n({source:n,metadata:r={},classification:i}){let a=Object.fromEntries(Object.entries(r).filter(([e])=>!t.has(e))),o=i?.kind||`unknown`,s=typeof r.eventId==`string`?r.eventId:void 0;s!=null&&delete a.eventId;let c=i?.error_id??s;e.trackEvent(`error_outcome`,{...a,current_url:window.location.href,error_source:n||`unknown`,error_kind:o,...c==null?{}:{error_id:c},error_telemetry:o===`internal`||o===`unknown`?`diagnostic`:`outcome`})}exports.trackError=n;
|
|
2
2
|
//# sourceMappingURL=error-handler.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.cjs","names":[],"sources":["../../src/utils/error-handler.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"error-handler.cjs","names":[],"sources":["../../src/utils/error-handler.ts"],"sourcesContent":["import { trackEvent } from \"#/services/telemetry\";\nimport type { ErrorClassification } from \"@openhands/typescript-client\";\n\ninterface ErrorDetails {\n source?: string;\n metadata?: Record<string, unknown>;\n classification?: ErrorClassification | null;\n}\n\nconst RESERVED_ERROR_KEYS = new Set([\n \"error_source\",\n \"error_kind\",\n \"error_id\",\n \"error_telemetry\",\n]);\n\nexport function trackError({\n source,\n metadata = {},\n classification,\n}: ErrorDetails) {\n // Reserved outcome fields are derived from `source`/`classification` and\n // must not be overridable through arbitrary caller metadata.\n const extra = Object.fromEntries(\n Object.entries(metadata).filter(([key]) => !RESERVED_ERROR_KEYS.has(key)),\n );\n const kind = classification?.kind || \"unknown\";\n // Promote a caller-provided `eventId` to the reserved `error_id` dimension as\n // a fallback so unclassified errors stay correlatable with server-side logs.\n const promotedEventId =\n typeof metadata.eventId === \"string\" ? metadata.eventId : undefined;\n if (promotedEventId != null) {\n delete extra.eventId;\n }\n const errorId = classification?.error_id ?? promotedEventId;\n\n void trackEvent(\"error_outcome\", {\n ...extra,\n current_url: window.location.href,\n error_source: source || \"unknown\",\n error_kind: kind,\n // Keep diagnostic errors correlatable without capturing raw messages.\n ...(errorId != null ? { error_id: errorId } : {}),\n error_telemetry:\n kind === \"internal\" || kind === \"unknown\" ? \"diagnostic\" : \"outcome\",\n });\n}\n"],"mappings":"0FASA,IAAM,EAAsB,IAAI,IAAI,CAClC,eACA,aACA,WACA,iBACF,CAAC,EAED,SAAgB,EAAW,CACzB,SACA,WAAW,CAAC,EACZ,kBACe,CAGf,IAAM,EAAQ,OAAO,YACnB,OAAO,QAAQ,CAAQ,EAAE,QAAQ,CAAC,KAAS,CAAC,EAAoB,IAAI,CAAG,CAAC,CAC1E,EACM,EAAO,GAAgB,MAAQ,UAG/B,EACJ,OAAO,EAAS,SAAY,SAAW,EAAS,QAAU,IAAA,GACxD,GAAmB,MACrB,OAAO,EAAM,QAEf,IAAM,EAAU,GAAgB,UAAY,EAE5C,EAAK,WAAW,gBAAiB,CAC/B,GAAG,EACH,YAAa,OAAO,SAAS,KAC7B,aAAc,GAAU,UACxB,WAAY,EAEZ,GAAI,GAAW,KAA+B,CAAC,EAAzB,CAAE,SAAU,CAAQ,EAC1C,gBACE,IAAS,YAAc,IAAS,UAAY,aAAe,SAC/D,CAAC,CACH"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { ErrorClassification } from "@openhands/typescript-client";
|
|
1
2
|
interface ErrorDetails {
|
|
2
|
-
message: string;
|
|
3
3
|
source?: string;
|
|
4
4
|
metadata?: Record<string, unknown>;
|
|
5
|
+
classification?: ErrorClassification | null;
|
|
5
6
|
}
|
|
6
|
-
export declare function trackError({
|
|
7
|
+
export declare function trackError({ source, metadata, classification, }: ErrorDetails): void;
|
|
7
8
|
export {};
|
|
@@ -1,12 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { trackEvent as e } from "../services/telemetry.js";
|
|
2
2
|
//#region src/utils/error-handler.ts
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
var t = new Set([
|
|
4
|
+
"error_source",
|
|
5
|
+
"error_kind",
|
|
6
|
+
"error_id",
|
|
7
|
+
"error_telemetry"
|
|
8
|
+
]);
|
|
9
|
+
function n({ source: n, metadata: r = {}, classification: i }) {
|
|
10
|
+
let a = Object.fromEntries(Object.entries(r).filter(([e]) => !t.has(e))), o = i?.kind || "unknown", s = typeof r.eventId == "string" ? r.eventId : void 0;
|
|
11
|
+
s != null && delete a.eventId;
|
|
12
|
+
let c = i?.error_id ?? s;
|
|
13
|
+
e("error_outcome", {
|
|
14
|
+
...a,
|
|
15
|
+
current_url: window.location.href,
|
|
5
16
|
error_source: n || "unknown",
|
|
6
|
-
|
|
17
|
+
error_kind: o,
|
|
18
|
+
...c == null ? {} : { error_id: c },
|
|
19
|
+
error_telemetry: o === "internal" || o === "unknown" ? "diagnostic" : "outcome"
|
|
7
20
|
});
|
|
8
21
|
}
|
|
9
22
|
//#endregion
|
|
10
|
-
export {
|
|
23
|
+
export { n as trackError };
|
|
11
24
|
|
|
12
25
|
//# sourceMappingURL=error-handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.js","names":[],"sources":["../../src/utils/error-handler.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"error-handler.js","names":[],"sources":["../../src/utils/error-handler.ts"],"sourcesContent":["import { trackEvent } from \"#/services/telemetry\";\nimport type { ErrorClassification } from \"@openhands/typescript-client\";\n\ninterface ErrorDetails {\n source?: string;\n metadata?: Record<string, unknown>;\n classification?: ErrorClassification | null;\n}\n\nconst RESERVED_ERROR_KEYS = new Set([\n \"error_source\",\n \"error_kind\",\n \"error_id\",\n \"error_telemetry\",\n]);\n\nexport function trackError({\n source,\n metadata = {},\n classification,\n}: ErrorDetails) {\n // Reserved outcome fields are derived from `source`/`classification` and\n // must not be overridable through arbitrary caller metadata.\n const extra = Object.fromEntries(\n Object.entries(metadata).filter(([key]) => !RESERVED_ERROR_KEYS.has(key)),\n );\n const kind = classification?.kind || \"unknown\";\n // Promote a caller-provided `eventId` to the reserved `error_id` dimension as\n // a fallback so unclassified errors stay correlatable with server-side logs.\n const promotedEventId =\n typeof metadata.eventId === \"string\" ? metadata.eventId : undefined;\n if (promotedEventId != null) {\n delete extra.eventId;\n }\n const errorId = classification?.error_id ?? promotedEventId;\n\n void trackEvent(\"error_outcome\", {\n ...extra,\n current_url: window.location.href,\n error_source: source || \"unknown\",\n error_kind: kind,\n // Keep diagnostic errors correlatable without capturing raw messages.\n ...(errorId != null ? { error_id: errorId } : {}),\n error_telemetry:\n kind === \"internal\" || kind === \"unknown\" ? \"diagnostic\" : \"outcome\",\n });\n}\n"],"mappings":";;AASA,IAAM,IAAsB,IAAI,IAAI;CAClC;CACA;CACA;CACA;AACF,CAAC;AAED,SAAgB,EAAW,EACzB,WACA,cAAW,CAAC,GACZ,qBACe;CAGf,IAAM,IAAQ,OAAO,YACnB,OAAO,QAAQ,CAAQ,EAAE,QAAQ,CAAC,OAAS,CAAC,EAAoB,IAAI,CAAG,CAAC,CAC1E,GACM,IAAO,GAAgB,QAAQ,WAG/B,IACJ,OAAO,EAAS,WAAY,WAAW,EAAS,UAAU,KAAA;CAC5D,AAAI,KAAmB,QACrB,OAAO,EAAM;CAEf,IAAM,IAAU,GAAgB,YAAY;CAE5C,EAAgB,iBAAiB;EAC/B,GAAG;EACH,aAAa,OAAO,SAAS;EAC7B,cAAc,KAAU;EACxB,YAAY;EAEZ,GAAI,KAAW,OAA+B,CAAC,IAAzB,EAAE,UAAU,EAAQ;EAC1C,iBACE,MAAS,cAAc,MAAS,YAAY,eAAe;CAC/D,CAAC;AACH"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");var e=`Free`,t={"openhands/glm-5.2":`OpenHands GLM-5.2 (free)`,"openhands/deepseek-v4-flash":`OpenHands DeepSeek V4 Flash (free)`,"openhands/minimax-m2.7":`OpenHands MiniMax M2.7 (free)`},n=`Free OpenHands models: ${Object.keys(t).join(`, `)}. Other provider endpoints with similar model names may require separate billing.`,r=e=>!!(e&&e in t);function i(e){return e?r(e)?t[e]:e:null}function a(e){return e?r(e)?t[e]:e.split(`/`).pop()||e:null}exports.FREE_MODEL_BADGE_LABEL=e,exports.FREE_OPENHANDS_MODEL_NOTE=n,exports.formatModelNameForDisplay=i,exports.formatNativeModelName=a,exports.isFreeOpenHandsModel=r;
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");var e=`Free`,t={"openhands/kimi-k3":`OpenHands Kimi K3 (free)`,"openhands/glm-5.2":`OpenHands GLM-5.2 (free)`,"openhands/deepseek-v4-flash":`OpenHands DeepSeek V4 Flash (free)`,"openhands/minimax-m2.7":`OpenHands MiniMax M2.7 (free)`},n=`Free OpenHands models: ${Object.keys(t).join(`, `)}. Other provider endpoints with similar model names may require separate billing.`,r=e=>!!(e&&e in t);function i(e){return e?r(e)?t[e]:e:null}function a(e){return e?r(e)?t[e]:e.split(`/`).pop()||e:null}exports.FREE_MODEL_BADGE_LABEL=e,exports.FREE_OPENHANDS_MODEL_NOTE=n,exports.formatModelNameForDisplay=i,exports.formatNativeModelName=a,exports.isFreeOpenHandsModel=r;
|
|
2
2
|
//# sourceMappingURL=format-model-name.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-model-name.cjs","names":[],"sources":["../../src/utils/format-model-name.ts"],"sourcesContent":["export const FREE_MODEL_BADGE_LABEL = \"Free\";\n\nexport const FREE_OPENHANDS_MODELS = {\n \"openhands/glm-5.2\": \"OpenHands GLM-5.2 (free)\",\n \"openhands/deepseek-v4-flash\": \"OpenHands DeepSeek V4 Flash (free)\",\n \"openhands/minimax-m2.7\": \"OpenHands MiniMax M2.7 (free)\",\n} as const;\n\nexport const FREE_OPENHANDS_MODEL_IDS = Object.keys(FREE_OPENHANDS_MODELS);\nexport const FREE_OPENHANDS_MODEL_NOTE = `Free OpenHands models: ${FREE_OPENHANDS_MODEL_IDS.join(\n \", \",\n)}. Other provider endpoints with similar model names may require separate billing.`;\n\nexport const isFreeOpenHandsModel = (\n model: string | null | undefined,\n): model is keyof typeof FREE_OPENHANDS_MODELS =>\n Boolean(model && model in FREE_OPENHANDS_MODELS);\n\nexport function formatModelNameForDisplay(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n return isFreeOpenHandsModel(model) ? FREE_OPENHANDS_MODELS[model] : model;\n}\n\nexport function formatProviderModelNameForDisplay(\n provider: string | null | undefined,\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n const fullModel = provider ? `${provider}/${model}` : model;\n return isFreeOpenHandsModel(fullModel)\n ? FREE_OPENHANDS_MODELS[fullModel]\n : model;\n}\n\n/**\n * Format a native (OpenHands-kind) routing model string for display, stripping\n * the provider route prefix (e.g. ``\"anthropic/claude-sonnet-4-5-20250929\"`` →\n * ``\"claude-sonnet-4-5-20250929\"``, ``\"litellm_proxy/openai/gpt-4o\"`` →\n * ``\"gpt-4o\"``) so a conversation chip shows a meaningful model name rather than\n * the full routing path.\n *\n * Returns ``null`` for an empty/nullish input, and falls back to the original\n * string when stripping the prefix would leave nothing (e.g. a trailing slash)\n * — never an empty string, which would collapse the chip text.\n *\n * Display-only: unlike {@link deriveProfileNameFromModel} this does not sanitize\n * to an identifier, so it keeps the real model id intact for the chip.\n */\nexport function formatNativeModelName(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n if (isFreeOpenHandsModel(model)) return FREE_OPENHANDS_MODELS[model];\n const lastSegment = model.split(\"/\").pop();\n return lastSegment || model;\n}\n"],"mappings":"6CAAA,IAAa,EAAyB,OAEzB,EAAwB,CACnC,oBAAqB,2BACrB,8BAA+B,qCAC/B,yBAA0B,+BAC5B,EAGa,EAA4B,0BADD,OAAO,KAAK,CACe,EAAyB,KAC1F,IACF,EAAE,mFAEW,EACX,GAEA,GAAQ,GAAS,KAAS,GAE5B,SAAgB,EACd,EACe,CAEf,OADK,EACE,EAAqB,CAAK,EAAI,EAAsB,GAAS,EADjD,IAErB,CA2BA,SAAgB,EACd,EACe,CAIf,OAHK,EACD,EAAqB,CAAK,EAAU,EAAsB,GAC1C,EAAM,MAAM,GAAG,EAAE,IAC9B,GAAe,EAHH,IAIrB"}
|
|
1
|
+
{"version":3,"file":"format-model-name.cjs","names":[],"sources":["../../src/utils/format-model-name.ts"],"sourcesContent":["export const FREE_MODEL_BADGE_LABEL = \"Free\";\n\nexport const FREE_OPENHANDS_MODELS = {\n \"openhands/kimi-k3\": \"OpenHands Kimi K3 (free)\",\n \"openhands/glm-5.2\": \"OpenHands GLM-5.2 (free)\",\n \"openhands/deepseek-v4-flash\": \"OpenHands DeepSeek V4 Flash (free)\",\n \"openhands/minimax-m2.7\": \"OpenHands MiniMax M2.7 (free)\",\n} as const;\n\nexport const FREE_OPENHANDS_MODEL_IDS = Object.keys(FREE_OPENHANDS_MODELS);\nexport const FREE_OPENHANDS_MODEL_NOTE = `Free OpenHands models: ${FREE_OPENHANDS_MODEL_IDS.join(\n \", \",\n)}. Other provider endpoints with similar model names may require separate billing.`;\n\nexport const isFreeOpenHandsModel = (\n model: string | null | undefined,\n): model is keyof typeof FREE_OPENHANDS_MODELS =>\n Boolean(model && model in FREE_OPENHANDS_MODELS);\n\nexport function formatModelNameForDisplay(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n return isFreeOpenHandsModel(model) ? FREE_OPENHANDS_MODELS[model] : model;\n}\n\nexport function formatProviderModelNameForDisplay(\n provider: string | null | undefined,\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n const fullModel = provider ? `${provider}/${model}` : model;\n return isFreeOpenHandsModel(fullModel)\n ? FREE_OPENHANDS_MODELS[fullModel]\n : model;\n}\n\n/**\n * Format a native (OpenHands-kind) routing model string for display, stripping\n * the provider route prefix (e.g. ``\"anthropic/claude-sonnet-4-5-20250929\"`` →\n * ``\"claude-sonnet-4-5-20250929\"``, ``\"litellm_proxy/openai/gpt-4o\"`` →\n * ``\"gpt-4o\"``) so a conversation chip shows a meaningful model name rather than\n * the full routing path.\n *\n * Returns ``null`` for an empty/nullish input, and falls back to the original\n * string when stripping the prefix would leave nothing (e.g. a trailing slash)\n * — never an empty string, which would collapse the chip text.\n *\n * Display-only: unlike {@link deriveProfileNameFromModel} this does not sanitize\n * to an identifier, so it keeps the real model id intact for the chip.\n */\nexport function formatNativeModelName(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n if (isFreeOpenHandsModel(model)) return FREE_OPENHANDS_MODELS[model];\n const lastSegment = model.split(\"/\").pop();\n return lastSegment || model;\n}\n"],"mappings":"6CAAA,IAAa,EAAyB,OAEzB,EAAwB,CACnC,oBAAqB,2BACrB,oBAAqB,2BACrB,8BAA+B,qCAC/B,yBAA0B,+BAC5B,EAGa,EAA4B,0BADD,OAAO,KAAK,CACe,EAAyB,KAC1F,IACF,EAAE,mFAEW,EACX,GAEA,GAAQ,GAAS,KAAS,GAE5B,SAAgB,EACd,EACe,CAEf,OADK,EACE,EAAqB,CAAK,EAAI,EAAsB,GAAS,EADjD,IAErB,CA2BA,SAAgB,EACd,EACe,CAIf,OAHK,EACD,EAAqB,CAAK,EAAU,EAAsB,GAC1C,EAAM,MAAM,GAAG,EAAE,IAC9B,GAAe,EAHH,IAIrB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const FREE_MODEL_BADGE_LABEL = "Free";
|
|
2
2
|
export declare const FREE_OPENHANDS_MODELS: {
|
|
3
|
+
readonly "openhands/kimi-k3": "OpenHands Kimi K3 (free)";
|
|
3
4
|
readonly "openhands/glm-5.2": "OpenHands GLM-5.2 (free)";
|
|
4
5
|
readonly "openhands/deepseek-v4-flash": "OpenHands DeepSeek V4 Flash (free)";
|
|
5
6
|
readonly "openhands/minimax-m2.7": "OpenHands MiniMax M2.7 (free)";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/utils/format-model-name.ts
|
|
2
2
|
var e = "Free", t = {
|
|
3
|
+
"openhands/kimi-k3": "OpenHands Kimi K3 (free)",
|
|
3
4
|
"openhands/glm-5.2": "OpenHands GLM-5.2 (free)",
|
|
4
5
|
"openhands/deepseek-v4-flash": "OpenHands DeepSeek V4 Flash (free)",
|
|
5
6
|
"openhands/minimax-m2.7": "OpenHands MiniMax M2.7 (free)"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-model-name.js","names":[],"sources":["../../src/utils/format-model-name.ts"],"sourcesContent":["export const FREE_MODEL_BADGE_LABEL = \"Free\";\n\nexport const FREE_OPENHANDS_MODELS = {\n \"openhands/glm-5.2\": \"OpenHands GLM-5.2 (free)\",\n \"openhands/deepseek-v4-flash\": \"OpenHands DeepSeek V4 Flash (free)\",\n \"openhands/minimax-m2.7\": \"OpenHands MiniMax M2.7 (free)\",\n} as const;\n\nexport const FREE_OPENHANDS_MODEL_IDS = Object.keys(FREE_OPENHANDS_MODELS);\nexport const FREE_OPENHANDS_MODEL_NOTE = `Free OpenHands models: ${FREE_OPENHANDS_MODEL_IDS.join(\n \", \",\n)}. Other provider endpoints with similar model names may require separate billing.`;\n\nexport const isFreeOpenHandsModel = (\n model: string | null | undefined,\n): model is keyof typeof FREE_OPENHANDS_MODELS =>\n Boolean(model && model in FREE_OPENHANDS_MODELS);\n\nexport function formatModelNameForDisplay(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n return isFreeOpenHandsModel(model) ? FREE_OPENHANDS_MODELS[model] : model;\n}\n\nexport function formatProviderModelNameForDisplay(\n provider: string | null | undefined,\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n const fullModel = provider ? `${provider}/${model}` : model;\n return isFreeOpenHandsModel(fullModel)\n ? FREE_OPENHANDS_MODELS[fullModel]\n : model;\n}\n\n/**\n * Format a native (OpenHands-kind) routing model string for display, stripping\n * the provider route prefix (e.g. ``\"anthropic/claude-sonnet-4-5-20250929\"`` →\n * ``\"claude-sonnet-4-5-20250929\"``, ``\"litellm_proxy/openai/gpt-4o\"`` →\n * ``\"gpt-4o\"``) so a conversation chip shows a meaningful model name rather than\n * the full routing path.\n *\n * Returns ``null`` for an empty/nullish input, and falls back to the original\n * string when stripping the prefix would leave nothing (e.g. a trailing slash)\n * — never an empty string, which would collapse the chip text.\n *\n * Display-only: unlike {@link deriveProfileNameFromModel} this does not sanitize\n * to an identifier, so it keeps the real model id intact for the chip.\n */\nexport function formatNativeModelName(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n if (isFreeOpenHandsModel(model)) return FREE_OPENHANDS_MODELS[model];\n const lastSegment = model.split(\"/\").pop();\n return lastSegment || model;\n}\n"],"mappings":";AAAA,IAAa,IAAyB,QAEzB,IAAwB;CACnC,qBAAqB;CACrB,+BAA+B;CAC/B,0BAA0B;AAC5B,GAGa,IAA4B,0BADD,OAAO,KAAK,CACe,EAAyB,KAC1F,IACF,EAAE,oFAEW,KACX,MAEA,GAAQ,KAAS,KAAS;AAE5B,SAAgB,EACd,GACe;CAEf,OADK,IACE,EAAqB,CAAK,IAAI,EAAsB,KAAS,IADjD;AAErB;AA2BA,SAAgB,EACd,GACe;CAIf,OAHK,IACD,EAAqB,CAAK,IAAU,EAAsB,KAC1C,EAAM,MAAM,GAAG,EAAE,IAC9B,KAAe,IAHH;AAIrB"}
|
|
1
|
+
{"version":3,"file":"format-model-name.js","names":[],"sources":["../../src/utils/format-model-name.ts"],"sourcesContent":["export const FREE_MODEL_BADGE_LABEL = \"Free\";\n\nexport const FREE_OPENHANDS_MODELS = {\n \"openhands/kimi-k3\": \"OpenHands Kimi K3 (free)\",\n \"openhands/glm-5.2\": \"OpenHands GLM-5.2 (free)\",\n \"openhands/deepseek-v4-flash\": \"OpenHands DeepSeek V4 Flash (free)\",\n \"openhands/minimax-m2.7\": \"OpenHands MiniMax M2.7 (free)\",\n} as const;\n\nexport const FREE_OPENHANDS_MODEL_IDS = Object.keys(FREE_OPENHANDS_MODELS);\nexport const FREE_OPENHANDS_MODEL_NOTE = `Free OpenHands models: ${FREE_OPENHANDS_MODEL_IDS.join(\n \", \",\n)}. Other provider endpoints with similar model names may require separate billing.`;\n\nexport const isFreeOpenHandsModel = (\n model: string | null | undefined,\n): model is keyof typeof FREE_OPENHANDS_MODELS =>\n Boolean(model && model in FREE_OPENHANDS_MODELS);\n\nexport function formatModelNameForDisplay(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n return isFreeOpenHandsModel(model) ? FREE_OPENHANDS_MODELS[model] : model;\n}\n\nexport function formatProviderModelNameForDisplay(\n provider: string | null | undefined,\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n const fullModel = provider ? `${provider}/${model}` : model;\n return isFreeOpenHandsModel(fullModel)\n ? FREE_OPENHANDS_MODELS[fullModel]\n : model;\n}\n\n/**\n * Format a native (OpenHands-kind) routing model string for display, stripping\n * the provider route prefix (e.g. ``\"anthropic/claude-sonnet-4-5-20250929\"`` →\n * ``\"claude-sonnet-4-5-20250929\"``, ``\"litellm_proxy/openai/gpt-4o\"`` →\n * ``\"gpt-4o\"``) so a conversation chip shows a meaningful model name rather than\n * the full routing path.\n *\n * Returns ``null`` for an empty/nullish input, and falls back to the original\n * string when stripping the prefix would leave nothing (e.g. a trailing slash)\n * — never an empty string, which would collapse the chip text.\n *\n * Display-only: unlike {@link deriveProfileNameFromModel} this does not sanitize\n * to an identifier, so it keeps the real model id intact for the chip.\n */\nexport function formatNativeModelName(\n model: string | null | undefined,\n): string | null {\n if (!model) return null;\n if (isFreeOpenHandsModel(model)) return FREE_OPENHANDS_MODELS[model];\n const lastSegment = model.split(\"/\").pop();\n return lastSegment || model;\n}\n"],"mappings":";AAAA,IAAa,IAAyB,QAEzB,IAAwB;CACnC,qBAAqB;CACrB,qBAAqB;CACrB,+BAA+B;CAC/B,0BAA0B;AAC5B,GAGa,IAA4B,0BADD,OAAO,KAAK,CACe,EAAyB,KAC1F,IACF,EAAE,oFAEW,KACX,MAEA,GAAQ,KAAS,KAAS;AAE5B,SAAgB,EACd,GACe;CAEf,OADK,IACE,EAAqB,CAAK,IAAI,EAAsB,KAAS,IADjD;AAErB;AA2BA,SAAgB,EACd,GACe;CAIf,OAHK,IACD,EAAqB,CAAK,IAAU,EAAsB,KAC1C,EAAM,MAAM,GAAG,EAAE,IAC9B,KAAe,IAHH;AAIrB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../../_virtual/_rolldown/runtime.cjs");var e=(e,t)=>(e.timestamp??``).localeCompare(t.timestamp??``),t=async(t,n,r)=>{let i=[],a=new Set,o=new Set,
|
|
1
|
+
require("../../_virtual/_rolldown/runtime.cjs");var e=(e,t)=>(e.timestamp??``).localeCompare(t.timestamp??``),t=async(t,n,r)=>{let i=[],a=new Set,o=[],s=0,c=new Set,l,u,d=!1,f=!1;for(;;){let e=await n({limit:100,sortOrder:`TIMESTAMP_DESC`,strictPagination:!0,...u?{pageId:u}:{},...l?{timestampLt:l}:{}});if(!Array.isArray(e.items))throw Error(`Invalid transcript history response: expected page.items to be an array.`);i.push(...e.items);let t,o=!1;if(e.items.forEach(e=>{a.has(e.id??``)||(e.id?a.add(e.id):s+=1,o=!0),(!t||(e.timestamp??``)<t)&&(t=e.timestamp??``)}),e.next_page_id){if(c.has(e.next_page_id))throw Error(`Transcript history pagination repeated a page cursor.`);c.add(e.next_page_id),u=e.next_page_id,l=void 0,d=!0;continue}if(d&&!f||e.items.length<100)break;if(r===void 0)throw Error(`Transcript history pagination cannot prove that all events were loaded.`);if(!t||l&&(!o||t>=l))throw Error(`Transcript history pagination did not advance.`);u=void 0,l=t,f=!0}let p=new Map;i.slice().reverse().forEach(e=>{if(e.id!==void 0){p.has(e.id)||p.set(e.id,e);return}o.push(e)}),t.forEach(e=>{if(e.id!==void 0){p.has(e.id)||p.set(e.id,e);return}o.push(e)});let m=[...o,...p.values()].sort(e);if(r!==void 0&&a.size+s<r)throw Error(`Transcript history is incomplete: expected ${r} persisted events, received ${a.size+s}.`);return m};exports.loadCompleteTranscriptEvents=t;
|
|
2
2
|
//# sourceMappingURL=load-complete-events.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-complete-events.cjs","names":[],"sources":["../../../src/utils/transcript-export/load-complete-events.ts"],"sourcesContent":["import type { OpenHandsEvent } from \"#/types/agent-server/core\";\n\nexport const TRANSCRIPT_HISTORY_PAGE_SIZE = 100;\n\ninterface TranscriptEventSearchOptions {\n limit: number;\n sortOrder: \"TIMESTAMP_DESC\";\n pageId?: string;\n timestampLt?: string;\n strictPagination: true;\n}\n\ninterface TranscriptEventPage {\n items: OpenHandsEvent[];\n next_page_id?: string | null;\n}\n\ntype SearchTranscriptEvents = (\n options: TranscriptEventSearchOptions,\n) => Promise<TranscriptEventPage>;\n\nconst compareEventTimestamps = (\n first: OpenHandsEvent,\n second: OpenHandsEvent,\n): number => (first.timestamp ?? \"\").localeCompare(second.timestamp ?? \"\");\n\n/**\n * Loads the persisted history from the newest page back to the beginning,\n * then merges any live store events that have not persisted yet. The timestamp\n * anchor matches the chat's existing history pagination, while id-based\n * de-duplication keeps the result stable if pages overlap.\n */\nexport const loadCompleteTranscriptEvents = async (\n loadedEvents: OpenHandsEvent[],\n searchEvents: SearchTranscriptEvents,\n expectedEventCount?: number,\n): Promise<OpenHandsEvent[]> => {\n const persistedDescending: OpenHandsEvent[] = [];\n const fetchedEventIds = new Set<string>();\n const seenPageIds = new Set<string>();\n let oldestTimestamp: string | undefined;\n let pageId: string | undefined;\n let usedCursor = false;\n let usingTimestampFallback = false;\n\n while (true) {\n const page = await searchEvents({\n limit: TRANSCRIPT_HISTORY_PAGE_SIZE,\n sortOrder: \"TIMESTAMP_DESC\",\n strictPagination: true,\n ...(pageId ? { pageId } : {}),\n ...(oldestTimestamp ? { timestampLt: oldestTimestamp } : {}),\n });\n\n if (!Array.isArray(page.items)) {\n throw new Error(\n \"Invalid transcript history response: expected page.items to be an array.\",\n );\n }\n\n persistedDescending.push(...page.items);\n let pageOldestTimestamp: string | undefined;\n let addedEvent = false;\n page.items.forEach((event) => {\n if (!fetchedEventIds.has(event.id ?? \"\")) {\n if (event.id) fetchedEventIds.add(event.id);\n addedEvent = true;\n }\n if (\n !pageOldestTimestamp ||\n (event.timestamp ?? \"\") < pageOldestTimestamp\n ) {\n pageOldestTimestamp = event.timestamp ?? \"\";\n }\n });\n\n if (page.next_page_id) {\n if (seenPageIds.has(page.next_page_id)) {\n throw new Error(\n \"Transcript history pagination repeated a page cursor.\",\n );\n }\n seenPageIds.add(page.next_page_id);\n pageId = page.next_page_id;\n oldestTimestamp = undefined;\n usedCursor = true;\n continue;\n }\n\n // Once a server supplies a cursor, a page without a next cursor is an\n // explicit exhaustion signal, even when the final page is exactly full.\n if (usedCursor && !usingTimestampFallback) break;\n if (page.items.length < TRANSCRIPT_HISTORY_PAGE_SIZE) break;\n\n // Some older servers omit cursors for filtered searches. A timestamp\n // fallback is safe to attempt only when an independent event count can\n // prove completeness; otherwise fail instead of exporting a partial tail.\n if (expectedEventCount === undefined) {\n throw new Error(\n \"Transcript history pagination cannot prove that all events were loaded.\",\n );\n }\n if (!pageOldestTimestamp) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n if (\n oldestTimestamp &&\n (!addedEvent || pageOldestTimestamp >= oldestTimestamp)\n ) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n\n pageId = undefined;\n oldestTimestamp = pageOldestTimestamp;\n usingTimestampFallback = true;\n }\n\n const eventsById = new Map<string, OpenHandsEvent>();\n persistedDescending\n .slice()\n .reverse()\n .forEach((event) => {\n if (
|
|
1
|
+
{"version":3,"file":"load-complete-events.cjs","names":[],"sources":["../../../src/utils/transcript-export/load-complete-events.ts"],"sourcesContent":["import type { OpenHandsEvent } from \"#/types/agent-server/core\";\n\nexport const TRANSCRIPT_HISTORY_PAGE_SIZE = 100;\n\ninterface TranscriptEventSearchOptions {\n limit: number;\n sortOrder: \"TIMESTAMP_DESC\";\n pageId?: string;\n timestampLt?: string;\n strictPagination: true;\n}\n\ninterface TranscriptEventPage {\n items: OpenHandsEvent[];\n next_page_id?: string | null;\n}\n\ntype SearchTranscriptEvents = (\n options: TranscriptEventSearchOptions,\n) => Promise<TranscriptEventPage>;\n\nconst compareEventTimestamps = (\n first: OpenHandsEvent,\n second: OpenHandsEvent,\n): number => (first.timestamp ?? \"\").localeCompare(second.timestamp ?? \"\");\n\n/**\n * Loads the persisted history from the newest page back to the beginning,\n * then merges any live store events that have not persisted yet. The timestamp\n * anchor matches the chat's existing history pagination, while id-based\n * de-duplication keeps the result stable if pages overlap.\n */\nexport const loadCompleteTranscriptEvents = async (\n loadedEvents: OpenHandsEvent[],\n searchEvents: SearchTranscriptEvents,\n expectedEventCount?: number,\n): Promise<OpenHandsEvent[]> => {\n const persistedDescending: OpenHandsEvent[] = [];\n const fetchedEventIds = new Set<string>();\n // Id-less events can't be de-duplicated by id, so keep a separate ordered\n // list and a count so they survive the merge and count toward completeness.\n const idLessEvents: OpenHandsEvent[] = [];\n let idLessPersisted = 0;\n const seenPageIds = new Set<string>();\n let oldestTimestamp: string | undefined;\n let pageId: string | undefined;\n let usedCursor = false;\n let usingTimestampFallback = false;\n\n while (true) {\n const page = await searchEvents({\n limit: TRANSCRIPT_HISTORY_PAGE_SIZE,\n sortOrder: \"TIMESTAMP_DESC\",\n strictPagination: true,\n ...(pageId ? { pageId } : {}),\n ...(oldestTimestamp ? { timestampLt: oldestTimestamp } : {}),\n });\n\n if (!Array.isArray(page.items)) {\n throw new Error(\n \"Invalid transcript history response: expected page.items to be an array.\",\n );\n }\n\n persistedDescending.push(...page.items);\n let pageOldestTimestamp: string | undefined;\n let addedEvent = false;\n page.items.forEach((event) => {\n if (!fetchedEventIds.has(event.id ?? \"\")) {\n if (event.id) {\n fetchedEventIds.add(event.id);\n } else {\n idLessPersisted += 1;\n }\n addedEvent = true;\n }\n if (\n !pageOldestTimestamp ||\n (event.timestamp ?? \"\") < pageOldestTimestamp\n ) {\n pageOldestTimestamp = event.timestamp ?? \"\";\n }\n });\n\n if (page.next_page_id) {\n if (seenPageIds.has(page.next_page_id)) {\n throw new Error(\n \"Transcript history pagination repeated a page cursor.\",\n );\n }\n seenPageIds.add(page.next_page_id);\n pageId = page.next_page_id;\n oldestTimestamp = undefined;\n usedCursor = true;\n continue;\n }\n\n // Once a server supplies a cursor, a page without a next cursor is an\n // explicit exhaustion signal, even when the final page is exactly full.\n if (usedCursor && !usingTimestampFallback) break;\n if (page.items.length < TRANSCRIPT_HISTORY_PAGE_SIZE) break;\n\n // Some older servers omit cursors for filtered searches. A timestamp\n // fallback is safe to attempt only when an independent event count can\n // prove completeness; otherwise fail instead of exporting a partial tail.\n if (expectedEventCount === undefined) {\n throw new Error(\n \"Transcript history pagination cannot prove that all events were loaded.\",\n );\n }\n if (!pageOldestTimestamp) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n if (\n oldestTimestamp &&\n (!addedEvent || pageOldestTimestamp >= oldestTimestamp)\n ) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n\n pageId = undefined;\n oldestTimestamp = pageOldestTimestamp;\n usingTimestampFallback = true;\n }\n\n const eventsById = new Map<string, OpenHandsEvent>();\n persistedDescending\n .slice()\n .reverse()\n .forEach((event) => {\n if (event.id !== undefined) {\n if (!eventsById.has(event.id)) {\n eventsById.set(event.id, event);\n }\n return;\n }\n idLessEvents.push(event);\n });\n loadedEvents.forEach((event) => {\n if (event.id !== undefined) {\n if (!eventsById.has(event.id)) {\n eventsById.set(event.id, event);\n }\n return;\n }\n idLessEvents.push(event);\n });\n // Array.prototype.sort is stable, so equal-timestamp events keep the causal\n // order returned by the server/store rather than being reordered by id.\n const completeEvents = [...idLessEvents, ...eventsById.values()].sort(\n compareEventTimestamps,\n );\n if (\n expectedEventCount !== undefined &&\n fetchedEventIds.size + idLessPersisted < expectedEventCount\n ) {\n throw new Error(\n `Transcript history is incomplete: expected ${expectedEventCount} persisted events, received ${fetchedEventIds.size + idLessPersisted}.`,\n );\n }\n return completeEvents;\n};\n"],"mappings":"gDAqBA,IAAM,GACJ,EACA,KACY,EAAM,WAAa,IAAI,cAAc,EAAO,WAAa,EAAE,EAQ5D,EAA+B,MAC1C,EACA,EACA,IAC8B,CAC9B,IAAM,EAAwC,CAAC,EACzC,EAAkB,IAAI,IAGtB,EAAiC,CAAC,EACpC,EAAkB,EAChB,EAAc,IAAI,IACpB,EACA,EACA,EAAa,GACb,EAAyB,GAE7B,OAAa,CACX,IAAM,EAAO,MAAM,EAAa,CAC9B,MAAA,IACA,UAAW,iBACX,iBAAkB,GAClB,GAAI,EAAS,CAAE,QAAO,EAAI,CAAC,EAC3B,GAAI,EAAkB,CAAE,YAAa,CAAgB,EAAI,CAAC,CAC5D,CAAC,EAED,GAAI,CAAC,MAAM,QAAQ,EAAK,KAAK,EAC3B,MAAU,MACR,0EACF,EAGF,EAAoB,KAAK,GAAG,EAAK,KAAK,EACtC,IAAI,EACA,EAAa,GAkBjB,GAjBA,EAAK,MAAM,QAAS,GAAU,CACvB,EAAgB,IAAI,EAAM,IAAM,EAAE,IACjC,EAAM,GACR,EAAgB,IAAI,EAAM,EAAE,EAE5B,GAAmB,EAErB,EAAa,KAGb,CAAC,IACA,EAAM,WAAa,IAAM,KAE1B,EAAsB,EAAM,WAAa,GAE7C,CAAC,EAEG,EAAK,aAAc,CACrB,GAAI,EAAY,IAAI,EAAK,YAAY,EACnC,MAAU,MACR,uDACF,EAEF,EAAY,IAAI,EAAK,YAAY,EACjC,EAAS,EAAK,aACd,EAAkB,IAAA,GAClB,EAAa,GACb,QACF,CAKA,GADI,GAAc,CAAC,GACf,EAAK,MAAM,OAAA,IAAuC,MAKtD,GAAI,IAAuB,IAAA,GACzB,MAAU,MACR,yEACF,EAKF,GAHI,CAAC,GAIH,IACC,CAAC,GAAc,GAAuB,GAEvC,MAAU,MAAM,gDAAgD,EAGlE,EAAS,IAAA,GACT,EAAkB,EAClB,EAAyB,EAC3B,CAEA,IAAM,EAAa,IAAI,IACvB,EACG,MAAM,EACN,QAAQ,EACR,QAAS,GAAU,CAClB,GAAI,EAAM,KAAO,IAAA,GAAW,CACrB,EAAW,IAAI,EAAM,EAAE,GAC1B,EAAW,IAAI,EAAM,GAAI,CAAK,EAEhC,MACF,CACA,EAAa,KAAK,CAAK,CACzB,CAAC,EACH,EAAa,QAAS,GAAU,CAC9B,GAAI,EAAM,KAAO,IAAA,GAAW,CACrB,EAAW,IAAI,EAAM,EAAE,GAC1B,EAAW,IAAI,EAAM,GAAI,CAAK,EAEhC,MACF,CACA,EAAa,KAAK,CAAK,CACzB,CAAC,EAGD,IAAM,EAAiB,CAAC,GAAG,EAAc,GAAG,EAAW,OAAO,CAAC,EAAE,KAC/D,CACF,EACA,GACE,IAAuB,IAAA,IACvB,EAAgB,KAAO,EAAkB,EAEzC,MAAU,MACR,8CAA8C,EAAmB,8BAA8B,EAAgB,KAAO,EAAgB,EACxI,EAEF,OAAO,CACT"}
|
|
@@ -1,37 +1,45 @@
|
|
|
1
1
|
var e = (e, t) => (e.timestamp ?? "").localeCompare(t.timestamp ?? ""), t = async (t, n, r) => {
|
|
2
|
-
let i = [], a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(),
|
|
2
|
+
let i = [], a = /* @__PURE__ */ new Set(), o = [], s = 0, c = /* @__PURE__ */ new Set(), l, u, d = !1, f = !1;
|
|
3
3
|
for (;;) {
|
|
4
4
|
let e = await n({
|
|
5
5
|
limit: 100,
|
|
6
6
|
sortOrder: "TIMESTAMP_DESC",
|
|
7
7
|
strictPagination: !0,
|
|
8
|
-
...
|
|
9
|
-
...
|
|
8
|
+
...u ? { pageId: u } : {},
|
|
9
|
+
...l ? { timestampLt: l } : {}
|
|
10
10
|
});
|
|
11
11
|
if (!Array.isArray(e.items)) throw Error("Invalid transcript history response: expected page.items to be an array.");
|
|
12
12
|
i.push(...e.items);
|
|
13
|
-
let t,
|
|
13
|
+
let t, o = !1;
|
|
14
14
|
if (e.items.forEach((e) => {
|
|
15
|
-
a.has(e.id ?? "") || (e.id
|
|
15
|
+
a.has(e.id ?? "") || (e.id ? a.add(e.id) : s += 1, o = !0), (!t || (e.timestamp ?? "") < t) && (t = e.timestamp ?? "");
|
|
16
16
|
}), e.next_page_id) {
|
|
17
|
-
if (
|
|
18
|
-
|
|
17
|
+
if (c.has(e.next_page_id)) throw Error("Transcript history pagination repeated a page cursor.");
|
|
18
|
+
c.add(e.next_page_id), u = e.next_page_id, l = void 0, d = !0;
|
|
19
19
|
continue;
|
|
20
20
|
}
|
|
21
|
-
if (
|
|
21
|
+
if (d && !f || e.items.length < 100) break;
|
|
22
22
|
if (r === void 0) throw Error("Transcript history pagination cannot prove that all events were loaded.");
|
|
23
|
-
if (!t ||
|
|
24
|
-
|
|
23
|
+
if (!t || l && (!o || t >= l)) throw Error("Transcript history pagination did not advance.");
|
|
24
|
+
u = void 0, l = t, f = !0;
|
|
25
25
|
}
|
|
26
|
-
let
|
|
26
|
+
let p = /* @__PURE__ */ new Map();
|
|
27
27
|
i.slice().reverse().forEach((e) => {
|
|
28
|
-
|
|
28
|
+
if (e.id !== void 0) {
|
|
29
|
+
p.has(e.id) || p.set(e.id, e);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
o.push(e);
|
|
29
33
|
}), t.forEach((e) => {
|
|
30
|
-
|
|
34
|
+
if (e.id !== void 0) {
|
|
35
|
+
p.has(e.id) || p.set(e.id, e);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
o.push(e);
|
|
31
39
|
});
|
|
32
|
-
let
|
|
33
|
-
if (r !== void 0 && a.size < r) throw Error(`Transcript history is incomplete: expected ${r} persisted events, received ${a.size}.`);
|
|
34
|
-
return
|
|
40
|
+
let m = [...o, ...p.values()].sort(e);
|
|
41
|
+
if (r !== void 0 && a.size + s < r) throw Error(`Transcript history is incomplete: expected ${r} persisted events, received ${a.size + s}.`);
|
|
42
|
+
return m;
|
|
35
43
|
};
|
|
36
44
|
//#endregion
|
|
37
45
|
export { t as loadCompleteTranscriptEvents };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-complete-events.js","names":[],"sources":["../../../src/utils/transcript-export/load-complete-events.ts"],"sourcesContent":["import type { OpenHandsEvent } from \"#/types/agent-server/core\";\n\nexport const TRANSCRIPT_HISTORY_PAGE_SIZE = 100;\n\ninterface TranscriptEventSearchOptions {\n limit: number;\n sortOrder: \"TIMESTAMP_DESC\";\n pageId?: string;\n timestampLt?: string;\n strictPagination: true;\n}\n\ninterface TranscriptEventPage {\n items: OpenHandsEvent[];\n next_page_id?: string | null;\n}\n\ntype SearchTranscriptEvents = (\n options: TranscriptEventSearchOptions,\n) => Promise<TranscriptEventPage>;\n\nconst compareEventTimestamps = (\n first: OpenHandsEvent,\n second: OpenHandsEvent,\n): number => (first.timestamp ?? \"\").localeCompare(second.timestamp ?? \"\");\n\n/**\n * Loads the persisted history from the newest page back to the beginning,\n * then merges any live store events that have not persisted yet. The timestamp\n * anchor matches the chat's existing history pagination, while id-based\n * de-duplication keeps the result stable if pages overlap.\n */\nexport const loadCompleteTranscriptEvents = async (\n loadedEvents: OpenHandsEvent[],\n searchEvents: SearchTranscriptEvents,\n expectedEventCount?: number,\n): Promise<OpenHandsEvent[]> => {\n const persistedDescending: OpenHandsEvent[] = [];\n const fetchedEventIds = new Set<string>();\n const seenPageIds = new Set<string>();\n let oldestTimestamp: string | undefined;\n let pageId: string | undefined;\n let usedCursor = false;\n let usingTimestampFallback = false;\n\n while (true) {\n const page = await searchEvents({\n limit: TRANSCRIPT_HISTORY_PAGE_SIZE,\n sortOrder: \"TIMESTAMP_DESC\",\n strictPagination: true,\n ...(pageId ? { pageId } : {}),\n ...(oldestTimestamp ? { timestampLt: oldestTimestamp } : {}),\n });\n\n if (!Array.isArray(page.items)) {\n throw new Error(\n \"Invalid transcript history response: expected page.items to be an array.\",\n );\n }\n\n persistedDescending.push(...page.items);\n let pageOldestTimestamp: string | undefined;\n let addedEvent = false;\n page.items.forEach((event) => {\n if (!fetchedEventIds.has(event.id ?? \"\")) {\n if (event.id) fetchedEventIds.add(event.id);\n addedEvent = true;\n }\n if (\n !pageOldestTimestamp ||\n (event.timestamp ?? \"\") < pageOldestTimestamp\n ) {\n pageOldestTimestamp = event.timestamp ?? \"\";\n }\n });\n\n if (page.next_page_id) {\n if (seenPageIds.has(page.next_page_id)) {\n throw new Error(\n \"Transcript history pagination repeated a page cursor.\",\n );\n }\n seenPageIds.add(page.next_page_id);\n pageId = page.next_page_id;\n oldestTimestamp = undefined;\n usedCursor = true;\n continue;\n }\n\n // Once a server supplies a cursor, a page without a next cursor is an\n // explicit exhaustion signal, even when the final page is exactly full.\n if (usedCursor && !usingTimestampFallback) break;\n if (page.items.length < TRANSCRIPT_HISTORY_PAGE_SIZE) break;\n\n // Some older servers omit cursors for filtered searches. A timestamp\n // fallback is safe to attempt only when an independent event count can\n // prove completeness; otherwise fail instead of exporting a partial tail.\n if (expectedEventCount === undefined) {\n throw new Error(\n \"Transcript history pagination cannot prove that all events were loaded.\",\n );\n }\n if (!pageOldestTimestamp) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n if (\n oldestTimestamp &&\n (!addedEvent || pageOldestTimestamp >= oldestTimestamp)\n ) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n\n pageId = undefined;\n oldestTimestamp = pageOldestTimestamp;\n usingTimestampFallback = true;\n }\n\n const eventsById = new Map<string, OpenHandsEvent>();\n persistedDescending\n .slice()\n .reverse()\n .forEach((event) => {\n if (
|
|
1
|
+
{"version":3,"file":"load-complete-events.js","names":[],"sources":["../../../src/utils/transcript-export/load-complete-events.ts"],"sourcesContent":["import type { OpenHandsEvent } from \"#/types/agent-server/core\";\n\nexport const TRANSCRIPT_HISTORY_PAGE_SIZE = 100;\n\ninterface TranscriptEventSearchOptions {\n limit: number;\n sortOrder: \"TIMESTAMP_DESC\";\n pageId?: string;\n timestampLt?: string;\n strictPagination: true;\n}\n\ninterface TranscriptEventPage {\n items: OpenHandsEvent[];\n next_page_id?: string | null;\n}\n\ntype SearchTranscriptEvents = (\n options: TranscriptEventSearchOptions,\n) => Promise<TranscriptEventPage>;\n\nconst compareEventTimestamps = (\n first: OpenHandsEvent,\n second: OpenHandsEvent,\n): number => (first.timestamp ?? \"\").localeCompare(second.timestamp ?? \"\");\n\n/**\n * Loads the persisted history from the newest page back to the beginning,\n * then merges any live store events that have not persisted yet. The timestamp\n * anchor matches the chat's existing history pagination, while id-based\n * de-duplication keeps the result stable if pages overlap.\n */\nexport const loadCompleteTranscriptEvents = async (\n loadedEvents: OpenHandsEvent[],\n searchEvents: SearchTranscriptEvents,\n expectedEventCount?: number,\n): Promise<OpenHandsEvent[]> => {\n const persistedDescending: OpenHandsEvent[] = [];\n const fetchedEventIds = new Set<string>();\n // Id-less events can't be de-duplicated by id, so keep a separate ordered\n // list and a count so they survive the merge and count toward completeness.\n const idLessEvents: OpenHandsEvent[] = [];\n let idLessPersisted = 0;\n const seenPageIds = new Set<string>();\n let oldestTimestamp: string | undefined;\n let pageId: string | undefined;\n let usedCursor = false;\n let usingTimestampFallback = false;\n\n while (true) {\n const page = await searchEvents({\n limit: TRANSCRIPT_HISTORY_PAGE_SIZE,\n sortOrder: \"TIMESTAMP_DESC\",\n strictPagination: true,\n ...(pageId ? { pageId } : {}),\n ...(oldestTimestamp ? { timestampLt: oldestTimestamp } : {}),\n });\n\n if (!Array.isArray(page.items)) {\n throw new Error(\n \"Invalid transcript history response: expected page.items to be an array.\",\n );\n }\n\n persistedDescending.push(...page.items);\n let pageOldestTimestamp: string | undefined;\n let addedEvent = false;\n page.items.forEach((event) => {\n if (!fetchedEventIds.has(event.id ?? \"\")) {\n if (event.id) {\n fetchedEventIds.add(event.id);\n } else {\n idLessPersisted += 1;\n }\n addedEvent = true;\n }\n if (\n !pageOldestTimestamp ||\n (event.timestamp ?? \"\") < pageOldestTimestamp\n ) {\n pageOldestTimestamp = event.timestamp ?? \"\";\n }\n });\n\n if (page.next_page_id) {\n if (seenPageIds.has(page.next_page_id)) {\n throw new Error(\n \"Transcript history pagination repeated a page cursor.\",\n );\n }\n seenPageIds.add(page.next_page_id);\n pageId = page.next_page_id;\n oldestTimestamp = undefined;\n usedCursor = true;\n continue;\n }\n\n // Once a server supplies a cursor, a page without a next cursor is an\n // explicit exhaustion signal, even when the final page is exactly full.\n if (usedCursor && !usingTimestampFallback) break;\n if (page.items.length < TRANSCRIPT_HISTORY_PAGE_SIZE) break;\n\n // Some older servers omit cursors for filtered searches. A timestamp\n // fallback is safe to attempt only when an independent event count can\n // prove completeness; otherwise fail instead of exporting a partial tail.\n if (expectedEventCount === undefined) {\n throw new Error(\n \"Transcript history pagination cannot prove that all events were loaded.\",\n );\n }\n if (!pageOldestTimestamp) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n if (\n oldestTimestamp &&\n (!addedEvent || pageOldestTimestamp >= oldestTimestamp)\n ) {\n throw new Error(\"Transcript history pagination did not advance.\");\n }\n\n pageId = undefined;\n oldestTimestamp = pageOldestTimestamp;\n usingTimestampFallback = true;\n }\n\n const eventsById = new Map<string, OpenHandsEvent>();\n persistedDescending\n .slice()\n .reverse()\n .forEach((event) => {\n if (event.id !== undefined) {\n if (!eventsById.has(event.id)) {\n eventsById.set(event.id, event);\n }\n return;\n }\n idLessEvents.push(event);\n });\n loadedEvents.forEach((event) => {\n if (event.id !== undefined) {\n if (!eventsById.has(event.id)) {\n eventsById.set(event.id, event);\n }\n return;\n }\n idLessEvents.push(event);\n });\n // Array.prototype.sort is stable, so equal-timestamp events keep the causal\n // order returned by the server/store rather than being reordered by id.\n const completeEvents = [...idLessEvents, ...eventsById.values()].sort(\n compareEventTimestamps,\n );\n if (\n expectedEventCount !== undefined &&\n fetchedEventIds.size + idLessPersisted < expectedEventCount\n ) {\n throw new Error(\n `Transcript history is incomplete: expected ${expectedEventCount} persisted events, received ${fetchedEventIds.size + idLessPersisted}.`,\n );\n }\n return completeEvents;\n};\n"],"mappings":"AAqBA,IAAM,KACJ,GACA,OACY,EAAM,aAAa,IAAI,cAAc,EAAO,aAAa,EAAE,GAQ5D,IAA+B,OAC1C,GACA,GACA,MAC8B;CAC9B,IAAM,IAAwC,CAAC,GACzC,oBAAkB,IAAI,IAAY,GAGlC,IAAiC,CAAC,GACpC,IAAkB,GAChB,oBAAc,IAAI,IAAY,GAChC,GACA,GACA,IAAa,IACb,IAAyB;CAE7B,SAAa;EACX,IAAM,IAAO,MAAM,EAAa;GAC9B,OAAA;GACA,WAAW;GACX,kBAAkB;GAClB,GAAI,IAAS,EAAE,UAAO,IAAI,CAAC;GAC3B,GAAI,IAAkB,EAAE,aAAa,EAAgB,IAAI,CAAC;EAC5D,CAAC;EAED,IAAI,CAAC,MAAM,QAAQ,EAAK,KAAK,GAC3B,MAAU,MACR,0EACF;EAGF,EAAoB,KAAK,GAAG,EAAK,KAAK;EACtC,IAAI,GACA,IAAa;EAkBjB,IAjBA,EAAK,MAAM,SAAS,MAAU;GAS5B,AARK,EAAgB,IAAI,EAAM,MAAM,EAAE,MACjC,EAAM,KACR,EAAgB,IAAI,EAAM,EAAE,IAE5B,KAAmB,GAErB,IAAa,MAGb,CAAC,MACA,EAAM,aAAa,MAAM,OAE1B,IAAsB,EAAM,aAAa;EAE7C,CAAC,GAEG,EAAK,cAAc;GACrB,IAAI,EAAY,IAAI,EAAK,YAAY,GACnC,MAAU,MACR,uDACF;GAKF,AAHA,EAAY,IAAI,EAAK,YAAY,GACjC,IAAS,EAAK,cACd,IAAkB,KAAA,GAClB,IAAa;GACb;EACF;EAKA,IADI,KAAc,CAAC,KACf,EAAK,MAAM,SAAA,KAAuC;EAKtD,IAAI,MAAuB,KAAA,GACzB,MAAU,MACR,yEACF;EAKF,IAHI,CAAC,KAIH,MACC,CAAC,KAAc,KAAuB,IAEvC,MAAU,MAAM,gDAAgD;EAKlE,AAFA,IAAS,KAAA,GACT,IAAkB,GAClB,IAAyB;CAC3B;CAEA,IAAM,oBAAa,IAAI,IAA4B;CAanD,AAZA,EACG,MAAM,EACN,QAAQ,EACR,SAAS,MAAU;EAClB,IAAI,EAAM,OAAO,KAAA,GAAW;GAC1B,AAAK,EAAW,IAAI,EAAM,EAAE,KAC1B,EAAW,IAAI,EAAM,IAAI,CAAK;GAEhC;EACF;EACA,EAAa,KAAK,CAAK;CACzB,CAAC,GACH,EAAa,SAAS,MAAU;EAC9B,IAAI,EAAM,OAAO,KAAA,GAAW;GAC1B,AAAK,EAAW,IAAI,EAAM,EAAE,KAC1B,EAAW,IAAI,EAAM,IAAI,CAAK;GAEhC;EACF;EACA,EAAa,KAAK,CAAK;CACzB,CAAC;CAGD,IAAM,IAAiB,CAAC,GAAG,GAAc,GAAG,EAAW,OAAO,CAAC,EAAE,KAC/D,CACF;CACA,IACE,MAAuB,KAAA,KACvB,EAAgB,OAAO,IAAkB,GAEzC,MAAU,MACR,8CAA8C,EAAmB,8BAA8B,EAAgB,OAAO,EAAgB,EACxI;CAEF,OAAO;AACT"}
|
package/package.json
CHANGED
|
@@ -17,6 +17,9 @@ const IDENTICAL_VALUE_ALLOWLIST = new Set([
|
|
|
17
17
|
'API$TAVILY_KEY_EXAMPLE',
|
|
18
18
|
'API$TVLY_KEY_EXAMPLE',
|
|
19
19
|
'AUTOMATIONS$DOWNLOAD_TARBALL',
|
|
20
|
+
'AUTOMATIONS$GIT_SYNC$BRANCH_PLACEHOLDER',
|
|
21
|
+
'AUTOMATIONS$GIT_SYNC$PATH_PLACEHOLDER',
|
|
22
|
+
'AUTOMATIONS$GIT_SYNC$REPO_URL_PLACEHOLDER',
|
|
20
23
|
'BACKEND$CLOUD_TITLE',
|
|
21
24
|
'BACKEND$VERSION_LABEL',
|
|
22
25
|
'BRANDING$OPENHANDS',
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
import { spawn, spawnSync } from "node:child_process";
|
|
48
48
|
import { mkdirSync, existsSync, readFileSync } from "node:fs";
|
|
49
|
-
import { join, resolve, dirname } from "node:path";
|
|
49
|
+
import { join, resolve, dirname, isAbsolute } from "node:path";
|
|
50
50
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
51
51
|
import { homedir } from "node:os";
|
|
52
52
|
import { setTimeout as delay } from "node:timers/promises";
|
|
@@ -252,6 +252,7 @@ ENVIRONMENT VARIABLES:
|
|
|
252
252
|
PORT Alternative to --port
|
|
253
253
|
OH_AUTOMATION_GIT_REF Git ref for automation (overrides default version)
|
|
254
254
|
OH_AUTOMATION_VERSION Specific PyPI version for automation (default: ${DEFAULT_AUTOMATION_VERSION})
|
|
255
|
+
OH_AUTOMATION_LOCAL_PATH Absolute path to a local automation checkout (overridden only by --automation-git-ref)
|
|
255
256
|
OH_AGENT_SERVER_LOCAL_PATH Absolute path to a local software-agent-sdk checkout (highest precedence)
|
|
256
257
|
OH_AGENT_SERVER_GIT_REF Git ref for agent-server SDK (overrides default version)
|
|
257
258
|
OH_AGENT_SERVER_VERSION Specific PyPI version for agent-server
|
|
@@ -270,10 +271,34 @@ ACCESS POINTS:
|
|
|
270
271
|
`);
|
|
271
272
|
}
|
|
272
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Fail fast on an unusable OH_AUTOMATION_LOCAL_PATH instead of letting
|
|
276
|
+
* `uv run --project <bad path>` exit on its own -- that leaves the rest of the
|
|
277
|
+
* stack up and the automations UI just reporting "backend unavailable", with
|
|
278
|
+
* nothing pointing at the env var. Mirrors validateLocalAgentServerPath.
|
|
279
|
+
*/
|
|
280
|
+
function validateLocalAutomationPath(localPath) {
|
|
281
|
+
if (!isAbsolute(localPath)) {
|
|
282
|
+
throw new Error(
|
|
283
|
+
`OH_AUTOMATION_LOCAL_PATH must be an absolute path, got: ${localPath}`,
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
if (!existsSync(localPath)) {
|
|
287
|
+
throw new Error(`OH_AUTOMATION_LOCAL_PATH does not exist: ${localPath}`);
|
|
288
|
+
}
|
|
289
|
+
const projectFile = join(localPath, "pyproject.toml");
|
|
290
|
+
if (!existsSync(projectFile)) {
|
|
291
|
+
throw new Error(
|
|
292
|
+
`OH_AUTOMATION_LOCAL_PATH is not a Python project (no pyproject.toml): ${projectFile}`,
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
273
297
|
/**
|
|
274
298
|
* Build the uvx command for running automation backend.
|
|
275
299
|
*
|
|
276
300
|
* Environment variables (highest precedence first):
|
|
301
|
+
* - OH_AUTOMATION_LOCAL_PATH: Absolute path to a local checkout
|
|
277
302
|
* - OH_AUTOMATION_GIT_REF: Git commit SHA or branch name
|
|
278
303
|
* - OH_AUTOMATION_VERSION: Specific PyPI version (e.g., "1.0.0a1")
|
|
279
304
|
*
|
|
@@ -282,6 +307,7 @@ ACCESS POINTS:
|
|
|
282
307
|
* git branch or commit instead.
|
|
283
308
|
*/
|
|
284
309
|
function buildAutomationCommand(env = process.env) {
|
|
310
|
+
const localPath = env.OH_AUTOMATION_LOCAL_PATH;
|
|
285
311
|
const gitRef = env.OH_AUTOMATION_GIT_REF;
|
|
286
312
|
const version = env.OH_AUTOMATION_VERSION;
|
|
287
313
|
const repoUrl = env.OH_AUTOMATION_REPO || DEFAULT_AUTOMATION_REPO;
|
|
@@ -289,6 +315,25 @@ function buildAutomationCommand(env = process.env) {
|
|
|
289
315
|
const uvxArgs = [];
|
|
290
316
|
let source = "";
|
|
291
317
|
|
|
318
|
+
if (localPath) {
|
|
319
|
+
// Run straight from a local checkout via `uv run --project`, so
|
|
320
|
+
// uncommitted working-tree changes are picked up. Outranks the other
|
|
321
|
+
// automation env vars, mirroring OH_AGENT_SERVER_LOCAL_PATH for the
|
|
322
|
+
// agent-server SDK; buildConfig drops it when --automation-git-ref asks
|
|
323
|
+
// for a specific ref.
|
|
324
|
+
return {
|
|
325
|
+
command: "uv",
|
|
326
|
+
args: [
|
|
327
|
+
"run",
|
|
328
|
+
"--project",
|
|
329
|
+
localPath,
|
|
330
|
+
"uvicorn",
|
|
331
|
+
"openhands.automation.app:app",
|
|
332
|
+
],
|
|
333
|
+
source: `local (${localPath})`,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
292
337
|
if (gitRef) {
|
|
293
338
|
// Use git ref - refresh to ensure latest commit is fetched
|
|
294
339
|
const gitUrl = `git+${repoUrl}@${gitRef}`;
|
|
@@ -331,6 +376,17 @@ async function buildConfig(args, env = process.env) {
|
|
|
331
376
|
// Apply args to env for buildAutomationCommand
|
|
332
377
|
if (args.automationGitRef) {
|
|
333
378
|
env.OH_AUTOMATION_GIT_REF = args.automationGitRef;
|
|
379
|
+
// An explicit flag outranks an ambient env var. Otherwise someone with
|
|
380
|
+
// OH_AUTOMATION_LOCAL_PATH exported in their shell profile would run their
|
|
381
|
+
// own working tree while believing they were reproducing against the ref
|
|
382
|
+
// they just passed.
|
|
383
|
+
if (env.OH_AUTOMATION_LOCAL_PATH) {
|
|
384
|
+
logStep(
|
|
385
|
+
"automation",
|
|
386
|
+
`--automation-git-ref ${args.automationGitRef} overrides OH_AUTOMATION_LOCAL_PATH (${env.OH_AUTOMATION_LOCAL_PATH})`,
|
|
387
|
+
);
|
|
388
|
+
delete env.OH_AUTOMATION_LOCAL_PATH;
|
|
389
|
+
}
|
|
334
390
|
}
|
|
335
391
|
if (args.automationRepo) {
|
|
336
392
|
env.OH_AUTOMATION_REPO = args.automationRepo;
|
|
@@ -730,17 +786,34 @@ function getFrontendBackend(config) {
|
|
|
730
786
|
}
|
|
731
787
|
|
|
732
788
|
function buildViteBackendEnv(config, env = process.env) {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
789
|
+
// VITE_BACKEND_HOST tells the Vite dev-server proxy (vite.config.ts) where
|
|
790
|
+
// to forward /api, /sockets, etc. It is NOT read by the frontend at
|
|
791
|
+
// runtime, so it is safe to keep as an absolute address.
|
|
792
|
+
//
|
|
793
|
+
// VITE_BACKEND_BASE_URL is intentionally left unset so the frontend falls
|
|
794
|
+
// back to window.location.origin (same-origin) at runtime — matching the
|
|
795
|
+
// behaviour of dev:static / agent-canvas and keeping the dev server
|
|
796
|
+
// portable across localhost, LAN hosts, SSH tunnels, and ngrok.
|
|
736
797
|
const backendHost = config.launchAgentServer
|
|
737
798
|
? `127.0.0.1:${config.ingressPort}`
|
|
738
|
-
: (env.VITE_BACKEND_HOST ??
|
|
799
|
+
: (env.VITE_BACKEND_HOST ??
|
|
800
|
+
env.VITE_BACKEND_BASE_URL?.replace(/^https?:\/\//, "") ??
|
|
801
|
+
"127.0.0.1:8000");
|
|
739
802
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
803
|
+
const env_out = { VITE_BACKEND_HOST: backendHost };
|
|
804
|
+
|
|
805
|
+
// If the user supplied VITE_BACKEND_BASE_URL with an https:// scheme and
|
|
806
|
+
// did not explicitly set VITE_USE_TLS, propagate the HTTPS intent so the
|
|
807
|
+
// Vite proxy forwards over TLS instead of plain HTTP.
|
|
808
|
+
if (
|
|
809
|
+
!config.launchAgentServer &&
|
|
810
|
+
env.VITE_BACKEND_BASE_URL?.startsWith("https://") &&
|
|
811
|
+
env.VITE_USE_TLS === undefined
|
|
812
|
+
) {
|
|
813
|
+
env_out.VITE_USE_TLS = "true";
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
return env_out;
|
|
744
817
|
}
|
|
745
818
|
|
|
746
819
|
function buildAgentServerAutomationEnv(config) {
|
|
@@ -1330,6 +1403,21 @@ async function main(options = {}) {
|
|
|
1330
1403
|
}
|
|
1331
1404
|
}
|
|
1332
1405
|
|
|
1406
|
+
// Same for the automation checkout -- skipped when --automation-git-ref was
|
|
1407
|
+
// passed, since buildConfig drops the env var in favor of the explicit flag.
|
|
1408
|
+
if (
|
|
1409
|
+
!args.frontendOnly &&
|
|
1410
|
+
!args.automationGitRef &&
|
|
1411
|
+
process.env.OH_AUTOMATION_LOCAL_PATH
|
|
1412
|
+
) {
|
|
1413
|
+
try {
|
|
1414
|
+
validateLocalAutomationPath(process.env.OH_AUTOMATION_LOCAL_PATH);
|
|
1415
|
+
} catch (error) {
|
|
1416
|
+
logError(error instanceof Error ? error.message : String(error));
|
|
1417
|
+
process.exit(1);
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1333
1421
|
// Build config with dynamic port allocation
|
|
1334
1422
|
const config = await buildConfig(args);
|
|
1335
1423
|
if (viteWorkingDir) config.viteWorkingDir = viteWorkingDir;
|
|
@@ -1504,6 +1592,7 @@ export {
|
|
|
1504
1592
|
registerShutdownHook,
|
|
1505
1593
|
spawnService,
|
|
1506
1594
|
commandExists,
|
|
1595
|
+
validateLocalAutomationPath,
|
|
1507
1596
|
logService,
|
|
1508
1597
|
logStep,
|
|
1509
1598
|
logSuccess,
|