@openhands/agent-canvas 1.7.2 → 1.9.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/{Trans-DP5rcauH.js → Trans-Bwpzk1wT.js} +1 -1
- package/build/assets/{acp-providers-BHKZvEm5.js → acp-providers-C921BlYB.js} +1 -1
- package/build/assets/active-backend-context-BiwzkzDy.js +2 -0
- package/build/assets/agent-context-settings-DXNT_dcw.js +1 -0
- package/build/assets/agent-profiles-settings-BymJf3EP.js +1 -0
- package/build/assets/agent-server-conversation-service.api-CYSWw-2g.js +41 -0
- package/build/assets/agent-settings-BjgQQe-_.js +1 -0
- package/build/assets/{agent-settings-BIOsUglV.js → agent-settings-WzqXk6B4.js} +2 -2
- package/build/assets/{alert-banner-C1nzoXBC.js → alert-banner-DR8EVyZM.js} +1 -1
- package/build/assets/api-error-message-e16L1kwH.js +1 -0
- package/build/assets/api-key-entry-screen-DI0I04O3.js +1 -0
- package/build/assets/app-settings-DGistSFV.js +1 -0
- package/build/assets/automation-C_eCrGyP.js +1 -0
- package/build/assets/automation-detail-DY6x2FW1.js +2 -0
- package/build/assets/automation-export-C09f-Lua.js +2 -0
- package/build/assets/automation-setup-route-CqKp0717.js +1 -0
- package/build/assets/automations-list-CqWJ7qXW.js +1 -0
- package/build/assets/{back-nav-button-Be_L157B.js → back-nav-button-D4ngzpSh.js} +1 -1
- package/build/assets/backend-form-modal-B8D5hBzK.js +1 -0
- package/build/assets/{backend-synced-settings-badge-BNpEylNP.js → backend-synced-settings-badge-BnzI8Ysj.js} +1 -1
- package/build/assets/{badge-DwgrwohM.js → badge-1Mf1iPcX.js} +1 -1
- package/build/assets/{base-modal-CSHhJTSr.js → base-modal-BBuy0WQQ.js} +1 -1
- package/build/assets/{brand-button-CQO8oqVo.js → brand-button-DGN6Y9o6.js} +1 -1
- package/build/assets/browser-D_ekTlTS.js +6 -0
- package/build/assets/{browser-tab-CEApjoEV.js → browser-tab-D4a4Ou_w.js} +1 -1
- package/build/assets/{chat-send-button-D4614wUz.js → chat-send-button-CgbcjD97.js} +1 -1
- package/build/assets/check-CPLXgluF.js +1 -0
- package/build/assets/chevron-down-CP4QHvyc.js +1 -0
- package/build/assets/circle-check-Dpy2_xSI.js +1 -0
- package/build/assets/{circle-plus-check-toggle-E3Ecb_gg.js → circle-plus-check-toggle-yTAS-nX3.js} +1 -1
- package/build/assets/cloud-funnel-analytics-CEOl5Gxr.js +1 -0
- package/build/assets/{combobox-caret-C8_eGdp2.js → combobox-caret-Bd2yySnF.js} +1 -1
- package/build/assets/command-menu-Bj6X4ckE.js +1 -0
- package/build/assets/condenser-settings-EAXQNR2E.js +1 -0
- package/build/assets/{confirmation-modal-gZtbojCm.js → confirmation-modal-NCUPr2-O.js} +1 -1
- package/build/assets/{context-menu-list-item-BTHGFhIx.js → context-menu-list-item-CrCrYuPF.js} +1 -1
- package/build/assets/conversation-BzyIcSwr.js +1 -0
- package/build/assets/conversation-CUJ0Vo8g.js +90 -0
- package/build/assets/conversation-panel-BzyIcSwr.js +1 -0
- package/build/assets/conversation-state-store-F62HvuI1.js +1 -0
- package/build/assets/{conversation-tab-empty-state-BCMHkGQk.js → conversation-tab-empty-state-BCZ7rUMH.js} +1 -1
- package/build/assets/{copy-B8Y5ufoR.js → copy-DCmZtz6n.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-C4l3CMSd.js → copy-to-clipboard-button-D_Lp6-Fl.js} +1 -1
- package/build/assets/{device-verify-C_M7Z8xs.js → device-verify-DLmolX8Q.js} +1 -1
- package/build/assets/{dropdown-classes-DQlj-MpS.js → dropdown-classes-BB8rzqXL.js} +1 -1
- package/build/assets/{entry.client-DETaouwO.js → entry.client-BbIYOsIg.js} +2 -2
- package/build/assets/{enum-filter-dropdown-paB-lFSP.js → enum-filter-dropdown-C08-srev.js} +1 -1
- package/build/assets/{environment-switch-overlay-D0FgCMqs.js → environment-switch-overlay-BepBBX66.js} +1 -1
- package/build/assets/extensions-hub-R3KNv-5V.js +1 -0
- package/build/assets/extensions-navigation-CfWFmI1I.js +1 -0
- package/build/assets/{external-link-Cnnd6ikC.js → external-link-BdBSg8rk.js} +1 -1
- package/build/assets/files-tab-DEq8MbHu.js +1 -0
- package/build/assets/{form-control-classes-CSPevi7c.js → form-control-classes-DAfsCJTe.js} +1 -1
- package/build/assets/{format-time-delta-DuhE50B-.js → format-time-delta-CxfPJpzC.js} +1 -1
- package/build/assets/git-provider-icon-BZqqUPlm.js +1 -0
- package/build/assets/git-repo-dropdown-9WKINV6J.js +1 -0
- package/build/assets/git-repo-dropdown-DEpOwUez.js +1 -0
- package/build/assets/{highlighted-source-view-suUKd5if.js → highlighted-source-view-CX9oIoVT.js} +1 -1
- package/build/assets/home-CY0JaxiY.js +1 -0
- package/build/assets/home-CaNWlVvB.js +1 -0
- package/build/assets/home-store-Ch1ErdBc.js +1 -0
- package/build/assets/index-home-CaNWlVvB.js +1 -0
- package/build/assets/info-CmWQXtRQ.js +1 -0
- package/build/assets/install-server-modal-BWrudmZU.js +1 -0
- package/build/assets/{launch-Ccnhte5b.js → launch-B1POpHuP.js} +1 -1
- package/build/assets/{list-todo-_BXQzOiB.js → list-todo-DtiL3lTp.js} +1 -1
- package/build/assets/llm-not-configured-banner-3tMsM4K6.js +27 -0
- package/build/assets/llm-settings-CXo8iPNW.js +1 -0
- package/build/assets/llm-settings-D0W8mJDk.js +1 -0
- package/build/assets/{llm-subscription-service-W5BprsNA.js → llm-subscription-service-DBJbfd8Z.js} +1 -1
- package/build/assets/loader-circle-B4QDBARx.js +1 -0
- package/build/assets/{loading-spinner-CcpnCr_d.js → loading-spinner-DfZ_bhV7.js} +1 -1
- package/build/assets/manage-backends-modal-CwyWsiag.js +1 -0
- package/build/assets/manifest-39f4789d.js +1 -0
- package/build/assets/{markdown-renderer-CvOO0YIr.js → markdown-renderer-DgiLLhW6.js} +6 -6
- package/build/assets/mcp-DXG9LWrI.js +9 -0
- package/build/assets/mcp-marketplace-utils-DFmhKc5s.js +1 -0
- package/build/assets/messages-kBjKaAeA.js +40 -0
- package/build/assets/{modal-body-DQhiw-AR.js → modal-body-CMsDpalT.js} +1 -1
- package/build/assets/{modal-classes-YaEEa5eZ.js → modal-classes-B6PDrxXo.js} +1 -1
- package/build/assets/{modal-close-button-turIYn0t.js → modal-close-button-DyxBZaAb.js} +1 -1
- package/build/assets/{onboarding-BegDrOKn.js → onboarding-47hh2IHA.js} +1 -1
- package/build/assets/onboarding-modal-9BuvvROo.js +1 -0
- package/build/assets/organization-service.api-UDy63-oC.js +1 -0
- package/build/assets/{pencil-8_lvWDoZ.js → pencil-BjgtZmWp.js} +1 -1
- package/build/assets/{planner-tab-w6HT0N_A.js → planner-tab-BWk8885v.js} +1 -1
- package/build/assets/plugins-management-service-CjkgF2dd.js +1 -0
- package/build/assets/plus-DrKuuvMe.js +1 -0
- package/build/assets/profiles-service.api-CukSFLzz.js +1 -0
- package/build/assets/providers-CqUWC85T.js +1 -0
- package/build/assets/proxy-BBUG3sd2.js +1 -0
- package/build/assets/{puzzle-DXWdfaa7.js → puzzle-BoNc6zZ8.js} +1 -1
- package/build/assets/recommended-automations-launcher-ejxy1P27.js +1 -0
- package/build/assets/{refresh-cw-D7CYLy-d.js → refresh-cw-BrM5ZAZD.js} +1 -1
- package/build/assets/root-5S-M8SYa.js +2 -0
- package/build/assets/root-DZ39lS5f.css +1 -0
- package/build/assets/root-layout-BPqoa0gv.js +3 -0
- package/build/assets/schema-field-nImDoY6-.js +1 -0
- package/build/assets/{sdk-section-page-BW-i45yr.js → sdk-section-page-BxMrtUNV.js} +1 -1
- package/build/assets/search-Dc2qR4O2.js +1 -0
- package/build/assets/secrets-service-Dhjh3HhH.js +1 -0
- package/build/assets/{secrets-settings-D7U1ErCH.js → secrets-settings-CPdxceT_.js} +1 -1
- package/build/assets/segmented-toggle-Do6oyepX.js +1 -0
- package/build/assets/settings-BRbnfKEm.js +1 -0
- package/build/assets/{settings-dropdown-input-Dx6vlkgf.js → settings-dropdown-input-DYCULKpp.js} +1 -1
- package/build/assets/{settings-index-COAdxm2Q.js → settings-index-C9o2NBO0.js} +1 -1
- package/build/assets/settings-input-B-q2gkVy.js +1 -0
- package/build/assets/{settings-list-classes-gQdBahdt.js → settings-list-classes-WpQi0q1L.js} +1 -1
- package/build/assets/{settings-modal-CFnbQ8_4.js → settings-modal-CEK0AIx6.js} +1 -1
- package/build/assets/settings-service.api-CZiPD8__.js +1 -0
- package/build/assets/{settings-switch-UNSf8K8I.js → settings-switch-LqKdGxHL.js} +1 -1
- package/build/assets/shared-conversation-Bu-dQlgp.js +1 -0
- package/build/assets/{sidebar-layout-DXHtbEj1.js → sidebar-layout-oHBGQmLh.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-U78hQRJ1.js → sidebar-mobile-menu-toggle-ND-hgygu.js} +1 -1
- package/build/assets/{sidebar-nav-link-pvUivfK2.js → sidebar-nav-link-CrujNA09.js} +1 -1
- package/build/assets/{sidebar-store-DwrYKwYr.js → sidebar-store-Bui-WNEr.js} +1 -1
- package/build/assets/{skill-card-pill-row-D7XCz5uk.js → skill-card-pill-row-CZBI7OqH.js} +1 -1
- package/build/assets/{skill-icon-badge-HqBWZ2Eq.js → skill-icon-badge-BOov_phZ.js} +1 -1
- package/build/assets/{skills-plugins-BPhaNpfx.js → skills-plugins-D0PiHWAD.js} +1 -1
- package/build/assets/{skills-settings-CcwMtnnJ.js → skills-settings-B43KArIz.js} +2 -2
- package/build/assets/{styled-tooltip-DsjDnR_W.js → styled-tooltip-C7grwnOX.js} +1 -1
- package/build/assets/{task-list-tab-BmaTwjaS.js → task-list-tab-R3ac6m7O.js} +1 -1
- package/build/assets/{terminal-BRcoba5B.js → terminal-yqkNdEAx.js} +1 -1
- package/build/assets/{toggle-switch-BptY3XRG.js → toggle-switch-BeSrbgCg.js} +1 -1
- package/build/assets/{trash-2-Bq4lHbTB.js → trash-2-wW5TWcdN.js} +1 -1
- package/build/assets/{typography-C6fuRTTT.js → typography-iYhzLlHO.js} +1 -1
- package/build/assets/{use-acp-credential-form-B0_pZ_uS.js → use-acp-credential-form-DUxbxmbq.js} +1 -1
- package/build/assets/use-activate-agent-profile-CDHA52tC.js +1 -0
- package/build/assets/use-agent-profiles-TsOdIyw5.js +1 -0
- package/build/assets/{use-can-manage-org-profiles-CrG1km7R.js → use-can-manage-org-profiles-Bt1M71u5.js} +1 -1
- package/build/assets/use-cloud-current-user-id-DWt7HCgf.js +1 -0
- package/build/assets/{use-config-Csy8EAP9.js → use-config-CxlEdf_v.js} +1 -1
- package/build/assets/{use-create-conversation-Dsa4nzU9.js → use-create-conversation-nOJ6Um5h.js} +1 -1
- package/build/assets/{use-create-secret-BnxuAjDt.js → use-create-secret-Dj5ang9x.js} +1 -1
- package/build/assets/use-is-authed-BT7Iud4U.js +1 -0
- package/build/assets/{use-is-creating-conversation-CIAcnd8M.js → use-is-creating-conversation-CAggrM75.js} +1 -1
- package/build/assets/use-llm-profiles-2Wc2db8u.js +1 -0
- package/build/assets/use-onboarding-completion-gxQlcEy2.js +1 -0
- package/build/assets/use-plugins-marketplace-CVO7sXYR.js +1 -0
- package/build/assets/use-save-agent-profile-D0wC5ExW.js +1 -0
- package/build/assets/{use-save-settings-BRh9p_fv.js → use-save-settings-L3aMaDeS.js} +1 -1
- package/build/assets/use-settings-8nt3DGxW.js +1 -0
- package/build/assets/use-settings-nav-items-DHAAD-zk.js +16 -0
- package/build/assets/use-skills-CE6miQ3r.js +1 -0
- package/build/assets/use-tracking-BGboadaZ.js +68 -0
- package/build/assets/{use-user-conversation-GnGhs_Ob.js → use-user-conversation-BIIpGUgM.js} +1 -1
- package/build/assets/useInfiniteQuery-BLRVmVPU.js +1 -0
- package/build/assets/{useMutation-DyQXZFEF.js → useMutation-CaSHLnX0.js} +1 -1
- package/build/assets/{useQueries-B3T1a7qt.js → useQueries--d_WWAzc.js} +1 -1
- package/build/assets/{useQuery-B38jBavx.js → useQuery-DiPh8LRJ.js} +1 -1
- package/build/assets/utils-BgGG1znF.js +1 -0
- package/build/assets/{vendor~browser-CIoZCqGs.js → vendor~browser-IVYgIgG1.js} +1 -1
- package/build/assets/{vendor~entry.client-Di4qO77Y.js → vendor~entry.client-BcYIVQvB.js} +1 -1
- package/build/assets/{vendor~entry.client-BfviqoVc.js → vendor~entry.client-CXM9oiAk.js} +1 -1
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g4xrpilz-CJ7amdtQ.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0bpqexo-CbTboogo.js} +2 -2
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f9xdmd0z-DLMP7bZx.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~d4by102p-C2f0ZhS-.js} +1 -1
- package/build/assets/{vendor~files-tab-vm3f67Pz.js → vendor~files-tab-C7RmQJwN.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation-kX4LrGQC.js → vendor~index-home~home~conversation-panel~conversation-Bqp1ZqJM.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation-DpA6fir3.js → vendor~root-layout~conversation-panel~conversation-BCn8lzeG.js} +1 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~automation-setup-route-B_L-gcOG.js +1 -0
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-sjx0x5ac.js +1 -0
- package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~automation-setup-route~onboarding-modal-D7IDevqN.js +1 -0
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~bi2r7bko-Bw4AuHN1.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~dfc8ddxy-tTyxnjXT.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hakxo2tj-ClV0p9g3.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gy8zbn65-CGt6bWRT.js} +1 -1
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~eywn6ulz-BKxxr74w.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~dufan6ng-Dtdw8H0q.js} +17 -4
- package/build/assets/{verification-settings-CaCzojbc.js → verification-settings-DBsnSXC3.js} +1 -1
- package/build/assets/x-omAzpXkl.js +1 -0
- package/build/favicon-16x16.png +0 -0
- package/build/favicon-32x32.png +0 -0
- package/build/favicon.ico +0 -0
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +39 -2
- package/build/locales/ca/openhands.json +39 -2
- package/build/locales/de/openhands.json +39 -2
- package/build/locales/en/openhands.json +40 -3
- package/build/locales/es/openhands.json +39 -2
- package/build/locales/fr/openhands.json +39 -2
- package/build/locales/it/openhands.json +39 -2
- package/build/locales/ja/openhands.json +39 -2
- package/build/locales/ko-KR/openhands.json +39 -2
- package/build/locales/no/openhands.json +39 -2
- package/build/locales/pt/openhands.json +39 -2
- package/build/locales/tr/openhands.json +39 -2
- package/build/locales/uk/openhands.json +39 -2
- package/build/locales/zh-CN/openhands.json +39 -2
- package/build/locales/zh-TW/openhands.json +39 -2
- package/config/defaults.json +4 -4
- package/dist/api/agent-server-adapter.cjs +3 -3
- package/dist/api/agent-server-adapter.cjs.map +1 -1
- package/dist/api/agent-server-adapter.d.ts +46 -6
- package/dist/api/agent-server-adapter.js +187 -168
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/agent-server-compatibility.cjs +1 -1
- package/dist/api/agent-server-compatibility.cjs.map +1 -1
- package/dist/api/agent-server-compatibility.d.ts +4 -0
- package/dist/api/agent-server-compatibility.js +41 -38
- package/dist/api/agent-server-compatibility.js.map +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 +20 -0
- package/dist/api/automation-service/automation-service.api.js +136 -99
- package/dist/api/automation-service/automation-service.api.js.map +1 -1
- package/dist/api/backend-registry/storage.cjs +1 -1
- package/dist/api/backend-registry/storage.cjs.map +1 -1
- package/dist/api/backend-registry/storage.js +1 -1
- package/dist/api/backend-registry/storage.js.map +1 -1
- package/dist/api/backend-registry/types.d.ts +2 -0
- package/dist/api/cloud/conversation-service.api.cjs +1 -1
- package/dist/api/cloud/conversation-service.api.js +22 -22
- package/dist/api/mcp-service/mcp-service.api.cjs +1 -1
- package/dist/api/mcp-service/mcp-service.api.cjs.map +1 -1
- package/dist/api/mcp-service/mcp-service.api.js +19 -19
- package/dist/api/mcp-service/mcp-service.api.js.map +1 -1
- package/dist/api/settings-service/settings-service.api.cjs +1 -1
- package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
- package/dist/api/settings-service/settings-service.api.js +26 -12
- package/dist/api/settings-service/settings-service.api.js.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +2 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.d.ts +12 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +94 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +31 -90
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.d.ts +0 -7
- package/dist/components/features/automations/recommended-automations-section.d.ts +0 -6
- package/dist/components/features/backends/backend-form-modal.cjs +1 -1
- package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
- package/dist/components/features/backends/backend-form-modal.js +568 -358
- package/dist/components/features/backends/backend-form-modal.js.map +1 -1
- package/dist/components/features/backends/device-flow-auth.cjs +1 -1
- package/dist/components/features/backends/device-flow-auth.cjs.map +1 -1
- package/dist/components/features/backends/device-flow-auth.d.ts +9 -1
- package/dist/components/features/backends/device-flow-auth.js +56 -55
- package/dist/components/features/backends/device-flow-auth.js.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.js +1 -1
- package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
- package/dist/components/features/chat/chat-interface.cjs +1 -1
- package/dist/components/features/chat/chat-interface.cjs.map +1 -1
- package/dist/components/features/chat/chat-interface.js +105 -105
- package/dist/components/features/chat/chat-interface.js.map +1 -1
- package/dist/components/features/chat/chat-message.cjs +1 -1
- package/dist/components/features/chat/chat-message.cjs.map +1 -1
- package/dist/components/features/chat/chat-message.d.ts +2 -1
- package/dist/components/features/chat/chat-message.js +59 -49
- package/dist/components/features/chat/chat-message.js.map +1 -1
- package/dist/components/features/chat/pending-user-messages.cjs +1 -1
- package/dist/components/features/chat/pending-user-messages.cjs.map +1 -1
- package/dist/components/features/chat/pending-user-messages.js +4 -1
- package/dist/components/features/chat/pending-user-messages.js.map +1 -1
- package/dist/components/features/chat/typing-indicator.cjs +1 -1
- package/dist/components/features/chat/typing-indicator.cjs.map +1 -1
- package/dist/components/features/chat/typing-indicator.d.ts +8 -1
- package/dist/components/features/chat/typing-indicator.js +94 -10
- package/dist/components/features/chat/typing-indicator.js.map +1 -1
- package/dist/components/features/command-menu/command-menu-items.d.ts +5 -1
- package/dist/components/features/files-tab/segmented-toggle.cjs +1 -1
- package/dist/components/features/files-tab/segmented-toggle.cjs.map +1 -1
- package/dist/components/features/files-tab/segmented-toggle.d.ts +2 -0
- package/dist/components/features/files-tab/segmented-toggle.js +17 -14
- package/dist/components/features/files-tab/segmented-toggle.js.map +1 -1
- package/dist/components/features/manifest/manifest-form-field.d.ts +27 -0
- package/dist/components/features/manifest/manifest-prerequisites-step.d.ts +11 -0
- package/dist/components/features/manifest/manifest-review-step.d.ts +14 -0
- package/dist/components/features/manifest/manifest-setup-dialog.d.ts +14 -0
- package/dist/components/features/mcp-page/custom-server-editor.cjs +1 -1
- package/dist/components/features/mcp-page/custom-server-editor.js +16 -16
- package/dist/components/features/mcp-page/installed-server-card.cjs +1 -1
- package/dist/components/features/mcp-page/installed-server-card.cjs.map +1 -1
- package/dist/components/features/mcp-page/installed-server-card.d.ts +2 -2
- package/dist/components/features/mcp-page/installed-server-card.js +6 -7
- package/dist/components/features/mcp-page/installed-server-card.js.map +1 -1
- package/dist/components/features/mcp-page/installed-servers-section.cjs +1 -1
- package/dist/components/features/mcp-page/installed-servers-section.cjs.map +1 -1
- package/dist/components/features/mcp-page/installed-servers-section.d.ts +2 -2
- package/dist/components/features/mcp-page/installed-servers-section.js +2 -2
- package/dist/components/features/mcp-page/installed-servers-section.js.map +1 -1
- package/dist/components/features/mcp-page/mcp-server-health.cjs +1 -1
- package/dist/components/features/mcp-page/mcp-server-health.js +4 -4
- package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs +1 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.cjs.map +1 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.js +2 -1
- package/dist/components/features/settings/mcp-settings/mcp-server-form.js.map +1 -1
- package/dist/components/features/settings/settings-input.cjs +1 -1
- package/dist/components/features/settings/settings-input.cjs.map +1 -1
- package/dist/components/features/settings/settings-input.d.ts +6 -0
- package/dist/components/features/settings/settings-input.js +13 -8
- package/dist/components/features/settings/settings-input.js.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.js +124 -123
- package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +3 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/contexts/active-backend-context.cjs +1 -1
- package/dist/contexts/active-backend-context.cjs.map +1 -1
- package/dist/contexts/active-backend-context.d.ts +3 -2
- package/dist/contexts/active-backend-context.js +55 -42
- package/dist/contexts/active-backend-context.js.map +1 -1
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/hooks/mutation/use-update-mcp-server.cjs +1 -1
- package/dist/hooks/mutation/use-update-mcp-server.js +5 -5
- package/dist/hooks/query/query-keys.cjs.map +1 -1
- package/dist/hooks/query/query-keys.d.ts +4 -0
- package/dist/hooks/query/query-keys.js.map +1 -1
- package/dist/hooks/query/use-cloud-current-user-id.cjs +1 -1
- package/dist/hooks/query/use-cloud-current-user-id.cjs.map +1 -1
- package/dist/hooks/query/use-cloud-current-user-id.js +7 -5
- package/dist/hooks/query/use-cloud-current-user-id.js.map +1 -1
- package/dist/hooks/query/use-cloud-organizations.cjs +1 -1
- package/dist/hooks/query/use-cloud-organizations.cjs.map +1 -1
- package/dist/hooks/query/use-cloud-organizations.js +5 -1
- package/dist/hooks/query/use-cloud-organizations.js.map +1 -1
- package/dist/hooks/query/use-manifest-capabilities.d.ts +21 -0
- package/dist/hooks/query/use-manifest-prerequisites.d.ts +24 -0
- package/dist/hooks/use-can-manage-org-profiles.cjs +1 -1
- package/dist/hooks/use-can-manage-org-profiles.cjs.map +1 -1
- package/dist/hooks/use-can-manage-org-profiles.js +2 -1
- package/dist/hooks/use-can-manage-org-profiles.js.map +1 -1
- package/dist/hooks/use-llm-configured.cjs +1 -1
- package/dist/hooks/use-llm-configured.cjs.map +1 -1
- package/dist/hooks/use-llm-configured.js +2 -1
- package/dist/hooks/use-llm-configured.js.map +1 -1
- package/dist/hooks/use-manifest-preflight.d.ts +18 -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 +14 -0
- package/dist/hooks/use-tracking.js +28 -10
- 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 +38 -1
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +2 -2
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +645 -16
- package/dist/i18n/translation.js.map +1 -1
- package/dist/icons/external-link.cjs +2 -0
- package/dist/icons/external-link.cjs.map +1 -0
- package/dist/icons/external-link.js +22 -0
- package/dist/icons/external-link.js.map +1 -0
- package/dist/icons/server.cjs +2 -0
- package/dist/icons/server.cjs.map +1 -0
- package/dist/icons/server.js +17 -0
- package/dist/icons/server.js.map +1 -0
- package/dist/locales/ar/openhands.json +39 -2
- package/dist/locales/ca/openhands.json +39 -2
- package/dist/locales/de/openhands.json +39 -2
- package/dist/locales/en/openhands.json +40 -3
- package/dist/locales/es/openhands.json +39 -2
- package/dist/locales/fr/openhands.json +39 -2
- package/dist/locales/it/openhands.json +39 -2
- package/dist/locales/ja/openhands.json +39 -2
- package/dist/locales/ko-KR/openhands.json +39 -2
- package/dist/locales/no/openhands.json +39 -2
- package/dist/locales/pt/openhands.json +39 -2
- package/dist/locales/tr/openhands.json +39 -2
- package/dist/locales/uk/openhands.json +39 -2
- package/dist/locales/zh-CN/openhands.json +39 -2
- package/dist/locales/zh-TW/openhands.json +39 -2
- package/dist/manifests/automation-interface.cjs +2 -0
- package/dist/manifests/automation-interface.cjs.map +1 -0
- package/dist/manifests/automation-interface.d.ts +44 -0
- package/dist/manifests/automation-interface.js +81 -0
- package/dist/manifests/automation-interface.js.map +1 -0
- package/dist/manifests/automation-setup.cjs +2 -0
- package/dist/manifests/automation-setup.cjs.map +1 -0
- package/dist/manifests/automation-setup.d.ts +52 -0
- package/dist/manifests/automation-setup.js +8 -0
- package/dist/manifests/automation-setup.js.map +1 -0
- package/dist/manifests/interface-validation.cjs +2 -0
- package/dist/manifests/interface-validation.cjs.map +1 -0
- package/dist/manifests/interface-validation.d.ts +27 -0
- package/dist/manifests/interface-validation.js +182 -0
- package/dist/manifests/interface-validation.js.map +1 -0
- package/dist/manifests/manifest-actions.d.ts +15 -0
- package/dist/manifests/manifest-capabilities.d.ts +25 -0
- package/dist/manifests/manifest-error-map.d.ts +40 -0
- package/dist/manifests/manifest-local-validation.d.ts +56 -0
- package/dist/manifests/manifest-registry.cjs +2 -0
- package/dist/manifests/manifest-registry.cjs.map +1 -0
- package/dist/manifests/manifest-registry.d.ts +15 -0
- package/dist/manifests/manifest-registry.js +26 -0
- package/dist/manifests/manifest-registry.js.map +1 -0
- package/dist/manifests/manifest-sources.cjs +2 -0
- package/dist/manifests/manifest-sources.cjs.map +1 -0
- package/dist/manifests/manifest-sources.d.ts +15 -0
- package/dist/manifests/manifest-sources.js +8 -0
- package/dist/manifests/manifest-sources.js.map +1 -0
- package/dist/manifests/manifest-template.d.ts +18 -0
- package/dist/manifests/manifest-validation.cjs +2 -0
- package/dist/manifests/manifest-validation.cjs.map +1 -0
- package/dist/manifests/manifest-validation.d.ts +30 -0
- package/dist/manifests/manifest-validation.js +145 -0
- package/dist/manifests/manifest-validation.js.map +1 -0
- package/dist/manifests/types.cjs +2 -0
- package/dist/manifests/types.cjs.map +1 -0
- package/dist/manifests/types.d.ts +227 -0
- package/dist/manifests/types.js +6 -0
- package/dist/manifests/types.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +75 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js +78 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-repo-monitor/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs +17 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js +89 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/incident-retrospective-drafter/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs +10 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js +17 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/jira-issue-to-pr/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js +15 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/linear-triage-assistant/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js +18 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/research-brief-writer/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js +14 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-channel-monitor/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs +9 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js +14 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/slack-standup-digest/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +23 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/index.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/automations/index.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/index.js +18 -0
- package/dist/node_modules/@openhands/extensions/automations/index.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs +2 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.js +89 -0
- package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js +3 -3
- package/dist/node_modules/@openhands/extensions/integrations/catalog/datadog.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.cjs +17 -4
- package/dist/node_modules/@openhands/extensions/skills/index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/skills/index.js +5 -5
- package/dist/node_modules/@openhands/extensions/skills/index.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.js +9 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/settings-client.js.map +1 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js +29 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/monitor.js.map +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +3 -3
- package/dist/package.js.map +1 -1
- package/dist/routes/app-settings.cjs +1 -1
- package/dist/routes/app-settings.js +5 -5
- package/dist/routes/mcp.cjs +1 -1
- package/dist/routes/mcp.cjs.map +1 -1
- package/dist/routes/mcp.js +73 -82
- package/dist/routes/mcp.js.map +1 -1
- package/dist/services/telemetry.cjs +1 -1
- package/dist/services/telemetry.cjs.map +1 -1
- package/dist/services/telemetry.d.ts +8 -0
- package/dist/services/telemetry.js +163 -116
- package/dist/services/telemetry.js.map +1 -1
- package/dist/types/agent-server/core/events/conversation-state-event.d.ts +2 -19
- package/dist/types/agent-server/core/events/observation-event.d.ts +2 -18
- package/dist/types/automation.d.ts +7 -3
- package/dist/types/mcp-server.d.ts +5 -0
- package/dist/types/settings.d.ts +3 -0
- package/dist/utils/api-error-message.d.ts +6 -2
- package/dist/utils/automation-catalog.cjs +2 -0
- package/dist/utils/automation-catalog.cjs.map +1 -0
- package/dist/utils/automation-catalog.d.ts +28 -0
- package/dist/utils/automation-catalog.js +5 -0
- package/dist/utils/automation-catalog.js.map +1 -0
- package/dist/utils/automation-timeout.d.ts +3 -2
- package/dist/utils/mcp-config.cjs +1 -1
- package/dist/utils/mcp-config.cjs.map +1 -1
- package/dist/utils/mcp-config.d.ts +8 -0
- package/dist/utils/mcp-config.js +25 -20
- package/dist/utils/mcp-config.js.map +1 -1
- package/dist/utils/mcp-installed-servers.cjs +1 -1
- package/dist/utils/mcp-installed-servers.cjs.map +1 -1
- package/dist/utils/mcp-installed-servers.js +6 -3
- package/dist/utils/mcp-installed-servers.js.map +1 -1
- package/dist/utils/responder-deployment.d.ts +5 -1
- package/dist/utils/transcript-export/index.cjs +5 -5
- package/dist/utils/transcript-export/index.js +12 -12
- package/package.json +3 -3
- package/scripts/check-sdk-version-sync.mjs +6 -6
- package/scripts/check-translation-completeness.cjs +1 -0
- package/scripts/dev-safe.mjs +17 -12
- package/scripts/dev-static.mjs +17 -0
- package/scripts/dev-with-automation.mjs +12 -14
- package/scripts/ingress.mjs +22 -0
- package/scripts/proxy-utils.mjs +157 -2
- package/scripts/runtime-services-info.mjs +6 -6
- package/scripts/static-build.mjs +0 -7
- package/scripts/static-server.mjs +10 -0
- package/build/assets/active-backend-context-BlZPzZNU.js +0 -1
- package/build/assets/agent-context-settings-CTaN-Iw9.js +0 -1
- package/build/assets/agent-profiles-settings-CR4VTqv_.js +0 -1
- package/build/assets/agent-server-conversation-service.api-Btmi4q6d.js +0 -41
- package/build/assets/agent-settings-KQs-occT.js +0 -1
- package/build/assets/api-key-entry-screen-BhR24gkM.js +0 -1
- package/build/assets/app-settings-Bs4sY8WP.js +0 -1
- package/build/assets/automation-BGP_I1RR.js +0 -1
- package/build/assets/automation-detail-CwDnJbYR.js +0 -2
- package/build/assets/automation-export-Bu-r-EzL.js +0 -2
- package/build/assets/automations-list-CYw7_6FR.js +0 -1
- package/build/assets/backend-form-modal-Ce-KRHOJ.js +0 -1
- package/build/assets/browser-BUDJnBg4.js +0 -6
- package/build/assets/check-BMOG005H.js +0 -1
- package/build/assets/chevron-down-CV1zZP_K.js +0 -1
- package/build/assets/circle-check-lvN_jFN5.js +0 -1
- package/build/assets/client-source-1v-kWLNU.js +0 -1
- package/build/assets/cloud-funnel-analytics-CasMM7EO.js +0 -1
- package/build/assets/command-menu-N_BriUy8.js +0 -1
- package/build/assets/condenser-settings-Czi8cKxV.js +0 -1
- package/build/assets/conversation-C25pc2dT.js +0 -1
- package/build/assets/conversation-CObLYSJd.js +0 -90
- package/build/assets/conversation-panel-C25pc2dT.js +0 -1
- package/build/assets/conversation-state-store-DTq4hFoP.js +0 -1
- package/build/assets/extensions-hub-BKftOQ-X.js +0 -1
- package/build/assets/extensions-navigation-DF24q1H1.js +0 -1
- package/build/assets/files-tab-SAiFCnS5.js +0 -1
- package/build/assets/git-provider-icon-BREx-yUX.js +0 -1
- package/build/assets/home-EPNFgzUh.js +0 -1
- package/build/assets/home-sN90Xcxp.js +0 -1
- package/build/assets/index-home-EPNFgzUh.js +0 -1
- package/build/assets/install-server-modal-BI8yUfmr.js +0 -1
- package/build/assets/llm-not-configured-banner-DTWzISnk.js +0 -27
- package/build/assets/llm-settings-BXk5_Pac.js +0 -1
- package/build/assets/llm-settings-C1vpgWam.js +0 -1
- package/build/assets/loader-circle-6zlEYCJw.js +0 -1
- package/build/assets/manage-backends-modal-DhflyGTf.js +0 -1
- package/build/assets/manifest-8082e879.js +0 -1
- package/build/assets/mcp-CxLPda-W.js +0 -9
- package/build/assets/messages-DINDkPNK.js +0 -40
- package/build/assets/onboarding-modal-DdvE6rzw.js +0 -1
- package/build/assets/organization-service.api-CT2OQlLz.js +0 -1
- package/build/assets/plugins-management-service-DVkoM3eA.js +0 -1
- package/build/assets/plus-vIbGD459.js +0 -1
- package/build/assets/profiles-service.api-CBafmAPO.js +0 -1
- package/build/assets/providers-9UzRB9mT.js +0 -1
- package/build/assets/proxy-C79PCMjo.js +0 -1
- package/build/assets/recommended-automations-launcher-BF2mtAKw.js +0 -58
- package/build/assets/root-B5JXKp1P.css +0 -1
- package/build/assets/root-Sj7W28yE.js +0 -2
- package/build/assets/root-layout-DbhKVoc7.js +0 -3
- package/build/assets/schema-field-CV6bFnoL.js +0 -1
- package/build/assets/search-sKuYKllf.js +0 -1
- package/build/assets/secrets-service-BjK-bPN2.js +0 -1
- package/build/assets/segmented-toggle-DbbD3Tve.js +0 -1
- package/build/assets/settings-Bj5Oo45A.js +0 -1
- package/build/assets/settings-input-BjW_zyTN.js +0 -1
- package/build/assets/settings-service.api-DryhKdSr.js +0 -1
- package/build/assets/shared-conversation-CnMxy7p_.js +0 -1
- package/build/assets/telemetry-cmCL3o6Z.js +0 -2
- package/build/assets/use-activate-agent-profile-DH33MvVj.js +0 -1
- package/build/assets/use-agent-profiles-Dmd_4H8q.js +0 -1
- package/build/assets/use-cloud-current-user-id-B6DP3s47.js +0 -1
- package/build/assets/use-is-authed-BsS4XwSL.js +0 -1
- package/build/assets/use-llm-profiles-BMQoc612.js +0 -1
- package/build/assets/use-onboarding-completion-B-2BTS-y.js +0 -1
- package/build/assets/use-plugins-marketplace-PBc_XNz_.js +0 -1
- package/build/assets/use-save-agent-profile-2Mk9ZX37.js +0 -1
- package/build/assets/use-settings-DBI44RnH.js +0 -1
- package/build/assets/use-settings-nav-items-Cva28C-c.js +0 -16
- package/build/assets/use-skills-RQsCtdzN.js +0 -1
- package/build/assets/use-tracking-CN1nIMnY.js +0 -1
- package/build/assets/utils-qjs_KuS4.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation-EShpjxey.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-DD_UNO02.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-Be63Q2Ln.js +0 -1
- package/build/assets/x-EjvKGawc.js +0 -1
- /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~f1hl7voa-BrmgjeOw.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~emdr2jt4-BrmgjeOw.js} +0 -0
|
@@ -1,67 +1,79 @@
|
|
|
1
1
|
import { getLockedCloudAuthMode as e } from "../api/agent-server-config.js";
|
|
2
|
-
import t from "../
|
|
3
|
-
import n from "../
|
|
4
|
-
import {
|
|
5
|
-
import { getBackendTelemetryProperties as a, getCloudTelemetryProperties as o } from "./telemetry-context.js";
|
|
2
|
+
import t from "../package.js";
|
|
3
|
+
import { AGENT_CANVAS_CLIENT_SOURCE as n, AGENT_CANVAS_CLIENT_VERSION as r } from "../api/client-source.js";
|
|
4
|
+
import { getBackendTelemetryProperties as i, getCloudTelemetryProperties as a } from "./telemetry-context.js";
|
|
6
5
|
//#region src/services/telemetry.ts
|
|
7
|
-
var
|
|
8
|
-
client_source:
|
|
9
|
-
client_version:
|
|
10
|
-
package_name:
|
|
11
|
-
package_version:
|
|
12
|
-
}),
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
function
|
|
6
|
+
var o = "openhands-telemetry-consent", s = "openhands-telemetry-consent-pending-cloud-sync", c = "openhands-telemetry-consent-pending-local-revocation", l = "openhands-telemetry-consent-change", u = "openhands-telemetry-first-use", d = "openhands-telemetry-session", f = "agent-canvas", p = "history_change", ee = "phc_BgzfxKdgsYMLFTmJqt424ZoyVHvKFfrwttLimzdYTKFK", m = "https://z.openhands.dev", h = "https://us.posthog.com", g = null, _ = null, v, y = {}, b = !1, x, S = 0, C = -1, w = Object.freeze({
|
|
7
|
+
client_source: n,
|
|
8
|
+
client_version: r,
|
|
9
|
+
package_name: t.name,
|
|
10
|
+
package_version: t.version
|
|
11
|
+
}), T = i({}), E = a();
|
|
12
|
+
function D(e) {
|
|
13
|
+
T = i(e);
|
|
14
|
+
}
|
|
15
|
+
function O(e) {
|
|
16
|
+
E = a(e);
|
|
17
|
+
}
|
|
18
|
+
function k(e) {
|
|
17
19
|
return e ? {
|
|
18
20
|
...e,
|
|
19
21
|
properties: {
|
|
20
|
-
...
|
|
21
|
-
...
|
|
22
|
+
...T,
|
|
23
|
+
...E,
|
|
22
24
|
...e.properties,
|
|
23
|
-
...
|
|
25
|
+
...w
|
|
24
26
|
}
|
|
25
27
|
} : null;
|
|
26
28
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
+
function A(e) {
|
|
30
|
+
b || V() !== "granted" ? e.opt_out_capturing() : e.opt_in_capturing();
|
|
29
31
|
}
|
|
30
|
-
function
|
|
31
|
-
e.reset(t),
|
|
32
|
+
function j(e, t = !1) {
|
|
33
|
+
e.reset(t), C = -1, A(e);
|
|
32
34
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
+
function M(e) {
|
|
36
|
+
if (x === void 0 || !Z()) return;
|
|
37
|
+
let t = x?.distinctId, n = e.get_property("$user_id");
|
|
38
|
+
if (n != null && n !== t && j(e), x === null) {
|
|
39
|
+
C = S;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
(e.get_property("$user_id") !== x.distinctId || C !== S) && (e.identify(x.distinctId, x.properties), C = S);
|
|
35
43
|
}
|
|
36
|
-
function
|
|
44
|
+
function N(e, t) {
|
|
45
|
+
let n = Object.keys(e);
|
|
46
|
+
return n.length === Object.keys(t).length && n.every((n) => e[n] === t[n]);
|
|
47
|
+
}
|
|
48
|
+
function P(e) {
|
|
37
49
|
if (e === !1) {
|
|
38
|
-
if (
|
|
39
|
-
|
|
50
|
+
if (b) return;
|
|
51
|
+
b = !0, g?.opt_out_capturing(), W();
|
|
40
52
|
return;
|
|
41
53
|
}
|
|
42
|
-
let t =
|
|
43
|
-
if (
|
|
54
|
+
let t = b;
|
|
55
|
+
if (b = !1, !g && !_) {
|
|
44
56
|
let t = Object.fromEntries(Object.entries(e).filter(([, e]) => e !== void 0));
|
|
45
|
-
|
|
46
|
-
...
|
|
57
|
+
y = {
|
|
58
|
+
...y,
|
|
47
59
|
...t
|
|
48
60
|
};
|
|
49
61
|
}
|
|
50
|
-
t && (
|
|
62
|
+
t && (g && (A(g), M(g)), W());
|
|
51
63
|
}
|
|
52
|
-
function
|
|
53
|
-
return
|
|
54
|
-
apiKey:
|
|
55
|
-
apiHost:
|
|
56
|
-
uiHost:
|
|
64
|
+
function F() {
|
|
65
|
+
return b ? null : {
|
|
66
|
+
apiKey: y.apiKey || ee,
|
|
67
|
+
apiHost: y.apiHost || m,
|
|
68
|
+
uiHost: y.uiHost || h
|
|
57
69
|
};
|
|
58
70
|
}
|
|
59
|
-
function
|
|
71
|
+
function I() {
|
|
60
72
|
return typeof window < "u" && typeof localStorage < "u";
|
|
61
73
|
}
|
|
62
|
-
async function
|
|
63
|
-
if (!
|
|
64
|
-
if (
|
|
74
|
+
async function L() {
|
|
75
|
+
if (!I()) return null;
|
|
76
|
+
if (g) return g;
|
|
65
77
|
try {
|
|
66
78
|
let { default: e } = await import("../node_modules/posthog-js/dist/module.js");
|
|
67
79
|
return e;
|
|
@@ -69,21 +81,21 @@ async function N() {
|
|
|
69
81
|
return null;
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
|
-
function
|
|
73
|
-
return !!(
|
|
84
|
+
function R() {
|
|
85
|
+
return !!(b || typeof process < "u" && process.env?.DO_NOT_TRACK === "1" || typeof navigator < "u" && (navigator.doNotTrack === "1" || typeof window < "u" && window.doNotTrack === "1"));
|
|
74
86
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
87
|
+
function z(e) {
|
|
88
|
+
g || (v = e);
|
|
77
89
|
}
|
|
78
|
-
async function
|
|
90
|
+
async function B(e = !1) {
|
|
91
|
+
if (g) return g;
|
|
79
92
|
if (_) return _;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
let t = j();
|
|
93
|
+
_ = (async () => {
|
|
94
|
+
let t = F();
|
|
83
95
|
if (!t) return null;
|
|
84
|
-
let n = await
|
|
96
|
+
let n = await L();
|
|
85
97
|
if (!n) return null;
|
|
86
|
-
let r =
|
|
98
|
+
let r = n.init(t.apiKey, {
|
|
87
99
|
api_host: t.apiHost,
|
|
88
100
|
ui_host: t.uiHost,
|
|
89
101
|
opt_out_capturing_by_default: !e,
|
|
@@ -94,145 +106,180 @@ async function I(e = !1) {
|
|
|
94
106
|
capture_pageview: p,
|
|
95
107
|
autocapture: !0,
|
|
96
108
|
disable_session_recording: !0,
|
|
97
|
-
bootstrap:
|
|
98
|
-
before_send:
|
|
109
|
+
bootstrap: v,
|
|
110
|
+
before_send: k
|
|
99
111
|
}, f);
|
|
100
|
-
return
|
|
112
|
+
return r ? (g = r, v = void 0, b ? g.opt_out_capturing() : V() === "granted" ? (g.opt_in_capturing(), M(g)) : e || g.opt_out_capturing(), g) : null;
|
|
101
113
|
})();
|
|
102
114
|
try {
|
|
103
|
-
return await
|
|
115
|
+
return await _;
|
|
104
116
|
} finally {
|
|
105
|
-
|
|
117
|
+
g || (_ = null);
|
|
106
118
|
}
|
|
107
119
|
}
|
|
108
|
-
function
|
|
109
|
-
if (!
|
|
110
|
-
if (
|
|
120
|
+
function V() {
|
|
121
|
+
if (!I()) return "pending";
|
|
122
|
+
if (R()) return "denied";
|
|
111
123
|
if (e() === "cookie") return "granted";
|
|
112
124
|
try {
|
|
113
|
-
let e = localStorage.getItem(
|
|
125
|
+
let e = localStorage.getItem(o);
|
|
114
126
|
if (e === "granted" || e === "denied") return e;
|
|
115
127
|
} catch {}
|
|
116
128
|
return "pending";
|
|
117
129
|
}
|
|
118
|
-
function
|
|
119
|
-
if (!
|
|
130
|
+
function H() {
|
|
131
|
+
if (!I()) return null;
|
|
132
|
+
try {
|
|
133
|
+
return localStorage.getItem(c);
|
|
134
|
+
} catch {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function U(e) {
|
|
139
|
+
if (!I()) return () => {};
|
|
120
140
|
let t = (t) => {
|
|
121
|
-
(t.key ===
|
|
141
|
+
(t.key === o || t.key === s) && e();
|
|
122
142
|
};
|
|
123
143
|
return window.addEventListener(l, e), window.addEventListener("storage", t), () => {
|
|
124
144
|
window.removeEventListener(l, e), window.removeEventListener("storage", t);
|
|
125
145
|
};
|
|
126
146
|
}
|
|
127
|
-
function
|
|
128
|
-
|
|
147
|
+
function W() {
|
|
148
|
+
I() && window.dispatchEvent(new Event(l));
|
|
149
|
+
}
|
|
150
|
+
function G(e) {
|
|
151
|
+
if (I()) try {
|
|
152
|
+
localStorage.setItem(s, e);
|
|
153
|
+
} catch {}
|
|
129
154
|
}
|
|
130
|
-
function
|
|
131
|
-
if (
|
|
155
|
+
function K(e) {
|
|
156
|
+
if (!(!I() || !e)) try {
|
|
132
157
|
localStorage.setItem(c, e);
|
|
133
158
|
} catch {}
|
|
134
159
|
}
|
|
135
|
-
function
|
|
136
|
-
if (
|
|
137
|
-
if (
|
|
138
|
-
localStorage.removeItem(c)
|
|
160
|
+
function q(e) {
|
|
161
|
+
if (I()) try {
|
|
162
|
+
if (localStorage.getItem(c) !== e) return;
|
|
163
|
+
localStorage.removeItem(c);
|
|
139
164
|
} catch {}
|
|
140
165
|
}
|
|
141
|
-
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
166
|
+
function J(e) {
|
|
167
|
+
if (I()) try {
|
|
168
|
+
if (e !== void 0 && localStorage.getItem(s) !== e) return;
|
|
169
|
+
localStorage.removeItem(s), W();
|
|
170
|
+
} catch {}
|
|
171
|
+
}
|
|
172
|
+
async function Y(e, { syncToCloud: t = !0 } = {}) {
|
|
173
|
+
if (I()) try {
|
|
174
|
+
let t = V() === e;
|
|
175
|
+
if (localStorage.setItem(o, e), b || t) return;
|
|
176
|
+
let n = g ?? await B();
|
|
146
177
|
if (!n) return;
|
|
147
|
-
e === "granted" ? n.opt_in_capturing() : n.get_property?.("$user_id") == null ? n.opt_out_capturing() :
|
|
178
|
+
e === "granted" ? (n.opt_in_capturing(), M(n)) : (K(n.get_distinct_id?.() ?? null), n.get_property?.("$user_id") == null ? n.opt_out_capturing() : j(n));
|
|
148
179
|
} catch {} finally {
|
|
149
|
-
t &&
|
|
180
|
+
t && G(e), W();
|
|
150
181
|
}
|
|
151
182
|
}
|
|
152
|
-
function
|
|
153
|
-
|
|
183
|
+
async function X(e, t = {}) {
|
|
184
|
+
let n = e === null ? null : {
|
|
185
|
+
distinctId: e,
|
|
186
|
+
properties: t
|
|
187
|
+
};
|
|
188
|
+
if (x === n || x != null && n !== null && x.distinctId === n.distinctId && N(x.properties, t) || (x = n, S += 1, C = -1, !Z())) return;
|
|
189
|
+
let r = g ?? await B();
|
|
190
|
+
r && Z() && M(r);
|
|
191
|
+
}
|
|
192
|
+
function Z() {
|
|
193
|
+
return V() === "granted";
|
|
154
194
|
}
|
|
155
|
-
function
|
|
156
|
-
if (!
|
|
195
|
+
function Q() {
|
|
196
|
+
if (!I()) return !1;
|
|
157
197
|
try {
|
|
158
198
|
return localStorage.getItem(u) === "true";
|
|
159
199
|
} catch {
|
|
160
200
|
return !1;
|
|
161
201
|
}
|
|
162
202
|
}
|
|
163
|
-
function
|
|
164
|
-
if (
|
|
203
|
+
function te() {
|
|
204
|
+
if (I()) try {
|
|
165
205
|
localStorage.setItem(u, "true");
|
|
166
206
|
} catch {}
|
|
167
207
|
}
|
|
168
|
-
async function
|
|
169
|
-
if (
|
|
170
|
-
let e = await
|
|
171
|
-
!e ||
|
|
208
|
+
async function ne() {
|
|
209
|
+
if (R() || Q()) return;
|
|
210
|
+
let e = await B(!0);
|
|
211
|
+
!e || R() || ((e.has_opted_out_capturing?.() ?? !1) && e.opt_in_capturing(), e.capture("canvas_install", {
|
|
172
212
|
platform: typeof navigator < "u" ? navigator.platform : "unknown",
|
|
173
213
|
user_agent: typeof navigator < "u" ? navigator.userAgent : "unknown",
|
|
174
214
|
referrer: typeof document < "u" ? document.referrer : "",
|
|
175
215
|
url_origin: typeof window < "u" ? window.location.origin : "",
|
|
176
216
|
embedded: typeof window < "u" && window.self !== window.top
|
|
177
|
-
}),
|
|
217
|
+
}), te(), V() !== "granted" && e.opt_out_capturing());
|
|
178
218
|
}
|
|
179
|
-
function
|
|
180
|
-
if (!
|
|
219
|
+
function re() {
|
|
220
|
+
if (!I()) return !1;
|
|
181
221
|
try {
|
|
182
222
|
return sessionStorage.getItem(d) === "true";
|
|
183
223
|
} catch {
|
|
184
224
|
return !1;
|
|
185
225
|
}
|
|
186
226
|
}
|
|
187
|
-
function
|
|
188
|
-
if (
|
|
227
|
+
function ie() {
|
|
228
|
+
if (I()) try {
|
|
189
229
|
sessionStorage.setItem(d, "true");
|
|
190
230
|
} catch {}
|
|
191
231
|
}
|
|
192
|
-
async function
|
|
193
|
-
if (!
|
|
194
|
-
let e = await
|
|
195
|
-
return !e || !
|
|
232
|
+
async function $() {
|
|
233
|
+
if (!Z() || V() !== "granted") return null;
|
|
234
|
+
let e = await B();
|
|
235
|
+
return !e || !Z() ? null : (e.has_opted_out_capturing?.() && e.opt_in_capturing(), M(e), e);
|
|
196
236
|
}
|
|
197
|
-
async function
|
|
198
|
-
if (
|
|
199
|
-
let e = await
|
|
200
|
-
e && (e.capture("canvas_new_session", { is_first_use: !
|
|
237
|
+
async function ae() {
|
|
238
|
+
if (re()) return;
|
|
239
|
+
let e = await $();
|
|
240
|
+
e && (e.capture("canvas_new_session", { is_first_use: !Q() }), ie());
|
|
201
241
|
}
|
|
202
|
-
async function
|
|
203
|
-
return (await
|
|
242
|
+
async function oe() {
|
|
243
|
+
return (await $())?.get_distinct_id?.() ?? null;
|
|
204
244
|
}
|
|
205
|
-
async function
|
|
206
|
-
|
|
245
|
+
async function se() {
|
|
246
|
+
if (!I()) return null;
|
|
247
|
+
if (V() !== "granted") {
|
|
248
|
+
let e = H();
|
|
249
|
+
if (e) return e;
|
|
250
|
+
}
|
|
251
|
+
return b || R() ? null : (await B())?.get_distinct_id?.() ?? null;
|
|
207
252
|
}
|
|
208
|
-
async function
|
|
209
|
-
let n = await
|
|
253
|
+
async function ce(e, t = {}) {
|
|
254
|
+
let n = await $();
|
|
210
255
|
n && n.capture(e, t);
|
|
211
256
|
}
|
|
212
|
-
async function
|
|
213
|
-
let n = await
|
|
257
|
+
async function le(e, t = {}) {
|
|
258
|
+
let n = await $();
|
|
214
259
|
n && n.captureException(e, t);
|
|
215
260
|
}
|
|
216
|
-
async function
|
|
217
|
-
if (
|
|
261
|
+
async function ue() {
|
|
262
|
+
if (I()) {
|
|
218
263
|
try {
|
|
219
|
-
localStorage.removeItem(
|
|
264
|
+
K(g?.get_distinct_id?.() ?? null), localStorage.removeItem(o), localStorage.removeItem(u);
|
|
220
265
|
} catch {}
|
|
221
|
-
|
|
266
|
+
J();
|
|
222
267
|
try {
|
|
223
268
|
sessionStorage.removeItem(d);
|
|
224
269
|
} catch {}
|
|
225
|
-
|
|
270
|
+
T = i({}), E = a(), x = null, S += 1, C = -1;
|
|
226
271
|
try {
|
|
227
|
-
|
|
272
|
+
g && j(g, !0);
|
|
228
273
|
} catch {
|
|
229
274
|
try {
|
|
230
|
-
|
|
275
|
+
g?.opt_out_capturing();
|
|
231
276
|
} catch {}
|
|
277
|
+
} finally {
|
|
278
|
+
W();
|
|
232
279
|
}
|
|
233
280
|
}
|
|
234
281
|
}
|
|
235
282
|
//#endregion
|
|
236
|
-
export {
|
|
283
|
+
export { q as clearPendingLocalTelemetryRevocation, ue as clearTelemetryData, z as configurePostHogBootstrap, P as configureTelemetry, V as getTelemetryConsent, oe as getTelemetryDistinctId, se as getTelemetryDistinctIdForConsentSync, B as initializePostHogClient, Z as isTelemetryEnabled, D as setTelemetryBackendContext, O as setTelemetryCloudContext, Y as setTelemetryConsent, X as setTelemetryIdentity, U as subscribeTelemetryConsent, ce as trackEvent, le as trackException, ne as trackInstall, ae as trackSessionStart };
|
|
237
284
|
|
|
238
285
|
//# sourceMappingURL=telemetry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.js","names":[],"sources":["../../src/services/telemetry.ts"],"sourcesContent":["/**\n * Telemetry service for tracking library usage.\n *\n * This module handles anonymous telemetry for the @openhands/agent-canvas package\n * using the PostHog SDK for reliable event delivery with batching, retry logic,\n * and offline support.\n *\n * TRACKING PHILOSOPHY:\n * - Install event (canvas_install): Sent immediately on first use, regardless of consent.\n * This is anonymous and contains no PII - just basic browser info and a random ID.\n * - Session/custom events: Only sent after user grants consent via the consent modal.\n * - Users can opt out of all future tracking by declining consent.\n *\n * AD BLOCKER BYPASS:\n * By default, telemetry is routed through OpenHands' reverse proxy (z.openhands.dev)\n * to avoid being blocked by ad blockers. Library consumers can override this with:\n * - VITE_POSTHOG_HOST: Custom proxy URL or direct PostHog URL\n * - VITE_POSTHOG_UI_HOST: PostHog UI host (defaults to https://us.posthog.com)\n *\n * IMPORTANT: By default, telemetry is sent to the OpenHands PostHog project.\n * Source builds can override this with VITE_POSTHOG_API_KEY. Precompiled\n * library consumers can pass the same settings to configureTelemetry().\n *\n * Users can disable all telemetry (including install tracking) via:\n * - Setting VITE_DO_NOT_TRACK=1 environment variable\n * - Browser's Do Not Track setting\n */\n\nimport type { BootstrapConfig, CaptureResult, PostHog } from \"posthog-js\";\nimport { getLockedCloudAuthMode } from \"#/api/agent-server-config\";\nimport defaults from \"../../config/defaults.json\";\n\nimport packageJson from \"../../package.json\";\nimport {\n AGENT_CANVAS_CLIENT_SOURCE,\n AGENT_CANVAS_CLIENT_VERSION,\n} from \"#/api/client-source\";\nimport {\n getBackendTelemetryProperties,\n getCloudTelemetryProperties,\n type BackendTelemetryContextInput,\n type CloudTelemetryContextInput,\n} from \"#/services/telemetry-context\";\n\nconst TELEMETRY_CONSENT_KEY = \"openhands-telemetry-consent\";\nconst TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY =\n \"openhands-telemetry-consent-pending-cloud-sync\";\nconst TELEMETRY_CONSENT_CHANGE_EVENT = \"openhands-telemetry-consent-change\";\nconst TELEMETRY_FIRST_USE_KEY = \"openhands-telemetry-first-use\";\nconst TELEMETRY_SESSION_KEY = \"openhands-telemetry-session\";\nconst POSTHOG_INSTANCE_NAME = \"agent-canvas\";\nconst POSTHOG_PAGEVIEW_CAPTURE_MODE = \"history_change\";\n\n// Unconfigured source builds use staging. Production release workflows pass\n// VITE_POSTHOG_API_KEY explicitly for both the app and library artifacts.\nconst DEFAULT_POSTHOG_API_KEY: string =\n (import.meta.env.VITE_POSTHOG_API_KEY as string | undefined) ||\n defaults.telemetry.posthogApiKey;\n\n// Default to OpenHands' reverse proxy to bypass ad blockers.\n// The proxy at z.openhands.dev routes to PostHog's US region.\n// Library consumers can override this with their own proxy or direct PostHog URL.\nconst DEFAULT_POSTHOG_HOST =\n import.meta.env.VITE_POSTHOG_HOST || \"https://z.openhands.dev\";\n\n// UI host is needed for PostHog features like toolbar to work correctly\n// when using a reverse proxy. Defaults to US region.\nconst DEFAULT_POSTHOG_UI_HOST =\n import.meta.env.VITE_POSTHOG_UI_HOST || \"https://us.posthog.com\";\n\nexport interface TelemetryConfig {\n /** PostHog project key. Useful for precompiled library consumers. */\n apiKey?: string;\n /** Event ingestion host or reverse proxy. */\n apiHost?: string;\n /** PostHog UI host used by toolbar links and other UI features. */\n uiHost?: string;\n}\n\nexport type TelemetryConfiguration = TelemetryConfig | false;\n\nexport type TelemetryConsent = \"granted\" | \"denied\" | \"pending\";\nexport type ResolvedTelemetryConsent = Exclude<TelemetryConsent, \"pending\">;\n\nexport interface SetTelemetryConsentOptions {\n /** Do not persist a value mirrored from backend settings back to Cloud. */\n syncToCloud?: boolean;\n}\n\nlet posthogInstance: PostHog | null = null;\nlet initializationPromise: Promise<PostHog | null> | null = null;\nlet pendingBootstrap: BootstrapConfig | undefined;\nlet telemetryConfig: TelemetryConfig = {};\nlet telemetryDisabled = false;\n\nconst CANVAS_EVENT_PROPERTIES = Object.freeze({\n client_source: AGENT_CANVAS_CLIENT_SOURCE,\n client_version: AGENT_CANVAS_CLIENT_VERSION,\n package_name: packageJson.name,\n package_version: packageJson.version,\n});\n\nlet telemetryBackendContext = getBackendTelemetryProperties({});\nlet telemetryCloudContext = getCloudTelemetryProperties();\n\nexport function setTelemetryBackendContext(\n context: BackendTelemetryContextInput,\n): void {\n telemetryBackendContext = getBackendTelemetryProperties(context);\n}\n\nexport function setTelemetryCloudContext(\n context: CloudTelemetryContextInput | null,\n): void {\n telemetryCloudContext = getCloudTelemetryProperties(context);\n}\n\nfunction addCanvasEventProperties(\n event: CaptureResult | null,\n): CaptureResult | null {\n if (!event) return null;\n\n return {\n ...event,\n properties: {\n ...telemetryBackendContext,\n ...telemetryCloudContext,\n ...event.properties,\n ...CANVAS_EVENT_PROPERTIES,\n },\n };\n}\n\nfunction restorePostHogConsent(posthog: PostHog): void {\n if (telemetryDisabled || getTelemetryConsent() !== \"granted\") {\n posthog.opt_out_capturing();\n } else {\n posthog.opt_in_capturing();\n }\n}\n\nfunction resetPostHogIdentity(posthog: PostHog, resetDeviceId = false): void {\n posthog.reset(resetDeviceId);\n // PostHog reset clears its own consent persistence, so immediately restore\n // the canonical Canvas decision kept in localStorage.\n restorePostHogConsent(posthog);\n}\n\nfunction clearLegacyIdentifiedUser(posthog: PostHog): void {\n if (posthog.get_property?.(\"$user_id\") != null) {\n resetPostHogIdentity(posthog);\n }\n}\n\n/**\n * Configure the single Canvas telemetry client before its first use.\n * Passing false disables telemetry and install tracking for embedded hosts.\n */\nexport function configureTelemetry(config: TelemetryConfiguration): void {\n if (config === false) {\n if (telemetryDisabled) return;\n telemetryDisabled = true;\n posthogInstance?.opt_out_capturing();\n notifyTelemetryConsentListeners();\n return;\n }\n\n const wasDisabled = telemetryDisabled;\n telemetryDisabled = false;\n\n if (!posthogInstance && !initializationPromise) {\n const definedConfig = Object.fromEntries(\n Object.entries(config).filter(([, value]) => value !== undefined),\n ) as TelemetryConfig;\n telemetryConfig = { ...telemetryConfig, ...definedConfig };\n }\n\n if (wasDisabled) {\n if (posthogInstance) {\n restorePostHogConsent(posthogInstance);\n }\n notifyTelemetryConsentListeners();\n }\n}\n\nfunction getResolvedTelemetryConfig(): Required<TelemetryConfig> | null {\n if (telemetryDisabled) return null;\n\n return {\n apiKey: telemetryConfig.apiKey || DEFAULT_POSTHOG_API_KEY,\n apiHost: telemetryConfig.apiHost || DEFAULT_POSTHOG_HOST,\n uiHost: telemetryConfig.uiHost || DEFAULT_POSTHOG_UI_HOST,\n };\n}\n\n/**\n * Check if we're in a browser environment\n */\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof localStorage !== \"undefined\";\n}\n\n/**\n * Lazily load PostHog to avoid SSR/Node.js issues.\n * PostHog is a browser-only library, so we dynamically import it only when needed.\n */\nasync function getPostHog(): Promise<PostHog | null> {\n if (!isBrowser()) {\n return null;\n }\n\n if (posthogInstance) {\n return posthogInstance;\n }\n\n try {\n const { default: posthog } = await import(\"posthog-js\");\n return posthog;\n } catch {\n // Failed to load PostHog - telemetry will be disabled\n return null;\n }\n}\n\n/**\n * Check if telemetry is disabled via environment variable or browser setting.\n * Works in both Node.js and browser (Vite) environments.\n */\nfunction isDoNotTrackEnabled(): boolean {\n if (telemetryDisabled) {\n return true;\n }\n\n // Check Vite environment variable (browser)\n if (\n typeof import.meta !== \"undefined\" &&\n import.meta.env?.VITE_DO_NOT_TRACK === \"1\"\n ) {\n return true;\n }\n\n // Check Node.js environment variable (SSR/testing)\n if (typeof process !== \"undefined\" && process.env?.DO_NOT_TRACK === \"1\") {\n return true;\n }\n\n // Check browser's navigator.doNotTrack standard\n if (\n typeof navigator !== \"undefined\" &&\n (navigator.doNotTrack === \"1\" ||\n // @ts-expect-error - Some browsers use window.doNotTrack\n (typeof window !== \"undefined\" && window.doNotTrack === \"1\"))\n ) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Initialize PostHog SDK.\n *\n * @param enableCapturing - If true, enable capturing immediately (for install tracking).\n * If false, start with capturing disabled (for consent-gated tracking).\n */\nexport function configurePostHogBootstrap(\n bootstrap: BootstrapConfig | undefined,\n): void {\n if (!posthogInstance) {\n pendingBootstrap = bootstrap;\n }\n}\n\nexport async function initializePostHogClient(\n enableCapturing = false,\n): Promise<PostHog | null> {\n if (posthogInstance) {\n return posthogInstance;\n }\n\n if (initializationPromise) {\n return initializationPromise;\n }\n\n initializationPromise = (async () => {\n const config = getResolvedTelemetryConfig();\n if (!config) {\n return null;\n }\n\n const posthog = await getPostHog();\n if (!posthog) {\n return null;\n }\n\n // A named instance isolates Canvas configuration, consent, identity, and\n // persistence from a host application's default PostHog singleton.\n const bootstrap = pendingBootstrap;\n const initializedPostHog = posthog.init(\n config.apiKey,\n {\n api_host: config.apiHost,\n ui_host: config.uiHost,\n opt_out_capturing_by_default: !enableCapturing,\n persistence: \"localStorage\",\n persistence_name: POSTHOG_INSTANCE_NAME,\n consent_persistence_name: `${POSTHOG_INSTANCE_NAME}-consent`,\n person_profiles: \"always\",\n capture_pageview: POSTHOG_PAGEVIEW_CAPTURE_MODE,\n autocapture: true,\n disable_session_recording: true,\n bootstrap,\n before_send: addCanvasEventProperties,\n },\n POSTHOG_INSTANCE_NAME,\n );\n if (!initializedPostHog) return null;\n\n posthogInstance = initializedPostHog;\n pendingBootstrap = undefined;\n if (!bootstrap) {\n clearLegacyIdentifiedUser(posthogInstance);\n }\n\n if (telemetryDisabled) {\n posthogInstance.opt_out_capturing();\n } else if (getTelemetryConsent() === \"granted\") {\n posthogInstance.opt_in_capturing();\n } else if (!enableCapturing) {\n posthogInstance.opt_out_capturing();\n }\n\n return posthogInstance;\n })();\n\n try {\n return await initializationPromise;\n } finally {\n if (!posthogInstance) {\n initializationPromise = null;\n }\n }\n}\n\n/**\n * Get user's telemetry consent preference\n */\nexport function getTelemetryConsent(): TelemetryConsent {\n if (!isBrowser()) {\n return \"pending\";\n }\n\n // Check environment variable for opt-out\n if (isDoNotTrackEnabled()) {\n return \"denied\";\n }\n\n if (getLockedCloudAuthMode() === \"cookie\") {\n return \"granted\";\n }\n\n try {\n const consent = localStorage.getItem(TELEMETRY_CONSENT_KEY);\n if (consent === \"granted\" || consent === \"denied\") {\n return consent;\n }\n } catch {\n // Ignore storage errors\n }\n\n return \"pending\";\n}\n\n/**\n * Return an explicit browser choice that still needs to survive a Cloud login.\n * It remains pending across local backends so their settings cannot consume a\n * decision that must still be applied after the user connects to Cloud.\n */\nexport function getPendingCloudTelemetryConsent(): ResolvedTelemetryConsent | null {\n if (!isBrowser()) return null;\n\n try {\n const consent = localStorage.getItem(\n TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY,\n );\n return consent === \"granted\" || consent === \"denied\" ? consent : null;\n } catch {\n return null;\n }\n}\n\nexport function subscribeTelemetryConsent(listener: () => void): () => void {\n if (!isBrowser()) return () => {};\n const handleStorage = (event: StorageEvent) => {\n if (\n event.key === TELEMETRY_CONSENT_KEY ||\n event.key === TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY\n ) {\n listener();\n }\n };\n window.addEventListener(TELEMETRY_CONSENT_CHANGE_EVENT, listener);\n window.addEventListener(\"storage\", handleStorage);\n\n return () => {\n window.removeEventListener(TELEMETRY_CONSENT_CHANGE_EVENT, listener);\n window.removeEventListener(\"storage\", handleStorage);\n };\n}\n\nfunction notifyTelemetryConsentListeners(): void {\n if (isBrowser())\n window.dispatchEvent(new Event(TELEMETRY_CONSENT_CHANGE_EVENT));\n}\n\nfunction markTelemetryConsentForCloudSync(\n consent: ResolvedTelemetryConsent,\n): void {\n if (!isBrowser()) return;\n\n try {\n localStorage.setItem(TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY, consent);\n } catch {\n // Ignore storage errors; the in-browser consent decision still applies.\n }\n}\n\nexport function clearPendingCloudTelemetryConsent(\n expected?: ResolvedTelemetryConsent,\n): void {\n if (!isBrowser()) return;\n\n try {\n if (\n expected !== undefined &&\n localStorage.getItem(TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY) !==\n expected\n ) {\n return;\n }\n localStorage.removeItem(TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY);\n notifyTelemetryConsentListeners();\n } catch {\n // Ignore storage errors.\n }\n}\n\n/**\n * Set user's telemetry consent preference\n */\nexport async function setTelemetryConsent(\n consent: ResolvedTelemetryConsent,\n { syncToCloud = true }: SetTelemetryConsentOptions = {},\n): Promise<void> {\n if (!isBrowser()) {\n return;\n }\n\n try {\n const previousConsent = getTelemetryConsent();\n const unchanged = previousConsent === consent;\n localStorage.setItem(TELEMETRY_CONSENT_KEY, consent);\n if (telemetryDisabled) return;\n if (unchanged) return;\n\n // Reuse an initialized client synchronously so a same-flush identify()\n // cannot run before consent is applied. Only the cold path awaits import.\n const posthog = posthogInstance ?? (await initializePostHogClient());\n if (!posthog) {\n return;\n }\n\n if (consent === \"granted\") {\n posthog.opt_in_capturing();\n } else {\n if (posthog.get_property?.(\"$user_id\") != null) {\n resetPostHogIdentity(posthog);\n } else {\n posthog.opt_out_capturing();\n }\n }\n } catch {\n // Ignore storage errors\n } finally {\n // Notify UI/backend/identity reconcilers only after the browser capture state\n // reflects this decision. Otherwise a pre-login grant can trigger an\n // identify while PostHog is still opted out and lose funnel continuity.\n if (syncToCloud) {\n markTelemetryConsentForCloudSync(consent);\n }\n notifyTelemetryConsentListeners();\n }\n}\n\n/**\n * Check if telemetry is enabled (user has granted consent)\n */\nexport function isTelemetryEnabled(): boolean {\n return getTelemetryConsent() === \"granted\";\n}\n\n/**\n * Check if first use event has already been sent\n */\nfunction hasFirstUseSent(): boolean {\n if (!isBrowser()) {\n return false;\n }\n\n try {\n return localStorage.getItem(TELEMETRY_FIRST_USE_KEY) === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Mark first use event as sent\n */\nfunction markFirstUseSent(): void {\n if (!isBrowser()) {\n return;\n }\n\n try {\n localStorage.setItem(TELEMETRY_FIRST_USE_KEY, \"true\");\n } catch {\n // Ignore storage errors\n }\n}\n\n/**\n * Track the initial install of the library.\n *\n * IMPORTANT: This is sent immediately on first use, regardless of consent status.\n * This allows us to track library adoption even if users haven't made a consent choice yet.\n *\n * The event is:\n * - Completely anonymous (no PII, just a random PostHog distinct_id)\n * - Sent only once per installation (tracked via localStorage, persists across sessions)\n * - Still respects DO_NOT_TRACK environment variable and browser setting\n *\n * Users who want complete privacy can:\n * - Set VITE_DO_NOT_TRACK=1 or browser's Do Not Track\n * - Later deny consent to prevent all future tracking\n */\nexport async function trackInstall(): Promise<void> {\n // Respect hard opt-out via environment variable or browser setting\n if (isDoNotTrackEnabled()) {\n return;\n }\n\n // Already sent install event (persisted in localStorage - survives app relaunches)\n if (hasFirstUseSent()) {\n return;\n }\n\n // Initialize PostHog with capturing enabled (for this one event)\n const posthog = await initializePostHogClient(true);\n if (!posthog || isDoNotTrackEnabled()) {\n return;\n }\n\n // Temporarily enable capturing if it was disabled\n const wasOptedOut = posthog.has_opted_out_capturing?.() ?? false;\n if (wasOptedOut) {\n posthog.opt_in_capturing();\n }\n\n // Capture the install event\n posthog.capture(\"canvas_install\", {\n platform: typeof navigator !== \"undefined\" ? navigator.platform : \"unknown\",\n user_agent:\n typeof navigator !== \"undefined\" ? navigator.userAgent : \"unknown\",\n referrer: typeof document !== \"undefined\" ? document.referrer : \"\",\n url_origin: typeof window !== \"undefined\" ? window.location.origin : \"\",\n embedded: typeof window !== \"undefined\" && window.self !== window.top,\n });\n\n // Mark as sent (stored in localStorage - persists across browser sessions)\n markFirstUseSent();\n\n // Restore opt-out state if user hasn't granted consent yet\n // This ensures we only send the install event, not subsequent events\n const currentConsent = getTelemetryConsent();\n if (currentConsent !== \"granted\") {\n posthog.opt_out_capturing();\n }\n}\n\n/**\n * Check if session start event has already been sent (this browser session)\n */\nfunction hasSessionSent(): boolean {\n if (!isBrowser()) {\n return false;\n }\n\n try {\n return sessionStorage.getItem(TELEMETRY_SESSION_KEY) === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Mark session start event as sent (uses sessionStorage so it resets on new tabs/sessions)\n */\nfunction markSessionSent(): void {\n if (!isBrowser()) {\n return;\n }\n\n try {\n sessionStorage.setItem(TELEMETRY_SESSION_KEY, \"true\");\n } catch {\n // Ignore storage errors\n }\n}\n\n/** Return the shared client only when a consented capture is safe to emit. */\nasync function getPostHogForConsentedCapture(): Promise<PostHog | null> {\n if (!isTelemetryEnabled() || getTelemetryConsent() !== \"granted\") return null;\n\n const posthog = await initializePostHogClient();\n if (!posthog || !isTelemetryEnabled()) return null;\n\n // The browser preference is the canonical capture decision. PostHog may\n // still carry an older opt-out marker while backend consent is loading or\n // after a previous backend temporarily reported a stale value. Heal that\n // drift at the event boundary so capture() cannot silently discard an event\n // that the user has explicitly allowed.\n if (posthog.has_opted_out_capturing?.()) {\n posthog.opt_in_capturing();\n }\n\n return posthog;\n}\n\n/**\n * Track a session start event.\n * Called each time a new browser session starts (respects consent).\n * Uses sessionStorage for deduplication - only sends once per browser session.\n */\nexport async function trackSessionStart(): Promise<void> {\n // Already sent session event this browser session\n if (hasSessionSent()) {\n return;\n }\n\n const posthog = await getPostHogForConsentedCapture();\n if (!posthog) return;\n\n posthog.capture(\"canvas_new_session\", {\n is_first_use: !hasFirstUseSent(),\n });\n\n // Mark as sent for this session\n markSessionSent();\n}\n\n/** Return the active PostHog distinct ID when consent allows capture. */\nexport async function getTelemetryDistinctId(): Promise<string | null> {\n const posthog = await getPostHogForConsentedCapture();\n return posthog?.get_distinct_id?.() ?? null;\n}\n\n/** Return the PostHog distinct ID for local consent sync without emitting capture. */\nexport async function getTelemetryDistinctIdForConsentSync(): Promise<\n string | null\n> {\n if (!isBrowser() || telemetryDisabled || isDoNotTrackEnabled()) return null;\n\n const posthog = await initializePostHogClient();\n return posthog?.get_distinct_id?.() ?? null;\n}\n\n/**\n * Track a custom event (respects consent).\n */\nexport async function trackEvent(\n eventName: string,\n properties: Record<string, unknown> = {},\n): Promise<void> {\n const posthog = await getPostHogForConsentedCapture();\n if (!posthog) return;\n\n posthog.capture(eventName, properties);\n}\n\n/** Track an exception through the same consent-aware client as custom events. */\nexport async function trackException(\n error: unknown,\n properties: Record<string, unknown> = {},\n): Promise<void> {\n const posthog = await getPostHogForConsentedCapture();\n if (!posthog) return;\n\n posthog.captureException(error, properties);\n}\n\n/**\n * Clear all telemetry data (for privacy/GDPR requests)\n */\nexport async function clearTelemetryData(): Promise<void> {\n if (!isBrowser()) {\n return;\n }\n\n try {\n localStorage.removeItem(TELEMETRY_CONSENT_KEY);\n localStorage.removeItem(TELEMETRY_FIRST_USE_KEY);\n } catch {\n // Continue clearing the in-memory and SDK identity if storage is blocked.\n }\n clearPendingCloudTelemetryConsent();\n try {\n sessionStorage.removeItem(TELEMETRY_SESSION_KEY);\n } catch {\n // Continue clearing the in-memory and SDK identity if storage is blocked.\n }\n\n telemetryBackendContext = getBackendTelemetryProperties({});\n telemetryCloudContext = getCloudTelemetryProperties();\n\n try {\n if (posthogInstance) {\n resetPostHogIdentity(posthogInstance, true);\n }\n } catch {\n // A reset failure must not leave capture enabled after a privacy clear.\n try {\n posthogInstance?.opt_out_capturing();\n } catch {\n // Telemetry failures must not break the application.\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"telemetry.js","names":[],"sources":["../../src/services/telemetry.ts"],"sourcesContent":["/**\n * Telemetry service for tracking library usage.\n *\n * This module handles anonymous telemetry for the @openhands/agent-canvas package\n * using the PostHog SDK for reliable event delivery with batching, retry logic,\n * and offline support.\n *\n * TRACKING PHILOSOPHY:\n * - Install event (canvas_install): Sent immediately on first use, regardless of consent.\n * This is anonymous and contains no PII - just basic browser info and a random ID.\n * - Session/custom events: Only sent after user grants consent via the consent modal.\n * - Users can opt out of all future tracking by declining consent.\n *\n * AD BLOCKER BYPASS:\n * By default, telemetry is routed through OpenHands' reverse proxy (z.openhands.dev)\n * to avoid being blocked by ad blockers. Library consumers can override this with:\n * - VITE_POSTHOG_HOST: Custom proxy URL or direct PostHog URL\n * - VITE_POSTHOG_UI_HOST: PostHog UI host (defaults to https://us.posthog.com)\n *\n * IMPORTANT: By default, telemetry is sent to the OpenHands PostHog project.\n * Source builds can override this with VITE_POSTHOG_API_KEY. Precompiled\n * library consumers can pass the same settings to configureTelemetry().\n *\n * Users can disable all telemetry (including install tracking) via:\n * - Setting VITE_DO_NOT_TRACK=1 environment variable\n * - Browser's Do Not Track setting\n */\n\nimport type { BootstrapConfig, CaptureResult, PostHog } from \"posthog-js\";\nimport { getLockedCloudAuthMode } from \"#/api/agent-server-config\";\nimport defaults from \"../../config/defaults.json\";\n\nimport packageJson from \"../../package.json\";\nimport {\n AGENT_CANVAS_CLIENT_SOURCE,\n AGENT_CANVAS_CLIENT_VERSION,\n} from \"#/api/client-source\";\nimport {\n getBackendTelemetryProperties,\n getCloudTelemetryProperties,\n type BackendTelemetryContextInput,\n type CloudTelemetryContextInput,\n} from \"#/services/telemetry-context\";\n\nconst TELEMETRY_CONSENT_KEY = \"openhands-telemetry-consent\";\nconst TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY =\n \"openhands-telemetry-consent-pending-cloud-sync\";\nconst TELEMETRY_CONSENT_PENDING_LOCAL_REVOCATION_KEY =\n \"openhands-telemetry-consent-pending-local-revocation\";\nconst TELEMETRY_CONSENT_CHANGE_EVENT = \"openhands-telemetry-consent-change\";\nconst TELEMETRY_FIRST_USE_KEY = \"openhands-telemetry-first-use\";\nconst TELEMETRY_SESSION_KEY = \"openhands-telemetry-session\";\nconst POSTHOG_INSTANCE_NAME = \"agent-canvas\";\nconst POSTHOG_PAGEVIEW_CAPTURE_MODE = \"history_change\";\n\n// Unconfigured source builds use staging. Production release workflows pass\n// VITE_POSTHOG_API_KEY explicitly for both the app and library artifacts.\nconst DEFAULT_POSTHOG_API_KEY: string =\n (import.meta.env.VITE_POSTHOG_API_KEY as string | undefined) ||\n defaults.telemetry.posthogApiKey;\n\n// Default to OpenHands' reverse proxy to bypass ad blockers.\n// The proxy at z.openhands.dev routes to PostHog's US region.\n// Library consumers can override this with their own proxy or direct PostHog URL.\nconst DEFAULT_POSTHOG_HOST =\n import.meta.env.VITE_POSTHOG_HOST || \"https://z.openhands.dev\";\n\n// UI host is needed for PostHog features like toolbar to work correctly\n// when using a reverse proxy. Defaults to US region.\nconst DEFAULT_POSTHOG_UI_HOST =\n import.meta.env.VITE_POSTHOG_UI_HOST || \"https://us.posthog.com\";\n\nexport interface TelemetryConfig {\n /** PostHog project key. Useful for precompiled library consumers. */\n apiKey?: string;\n /** Event ingestion host or reverse proxy. */\n apiHost?: string;\n /** PostHog UI host used by toolbar links and other UI features. */\n uiHost?: string;\n}\n\nexport type TelemetryConfiguration = TelemetryConfig | false;\n\nexport type TelemetryConsent = \"granted\" | \"denied\" | \"pending\";\nexport type ResolvedTelemetryConsent = Exclude<TelemetryConsent, \"pending\">;\n\nexport interface SetTelemetryConsentOptions {\n /** Do not persist a value mirrored from backend settings back to Cloud. */\n syncToCloud?: boolean;\n}\n\nlet posthogInstance: PostHog | null = null;\nlet initializationPromise: Promise<PostHog | null> | null = null;\nlet pendingBootstrap: BootstrapConfig | undefined;\nlet telemetryConfig: TelemetryConfig = {};\nlet telemetryDisabled = false;\n\ninterface TelemetryIdentity {\n distinctId: string;\n properties: Record<string, unknown>;\n}\n\n// undefined means that Cloud identity has not resolved yet; null means that it\n// resolved without a user. This distinction prevents startup from resetting a\n// persisted identity while the current account is still loading.\nlet desiredTelemetryIdentity: TelemetryIdentity | null | undefined;\nlet desiredIdentityRevision = 0;\nlet appliedIdentityRevision = -1;\n\nconst CANVAS_EVENT_PROPERTIES = Object.freeze({\n client_source: AGENT_CANVAS_CLIENT_SOURCE,\n client_version: AGENT_CANVAS_CLIENT_VERSION,\n package_name: packageJson.name,\n package_version: packageJson.version,\n});\n\nlet telemetryBackendContext = getBackendTelemetryProperties({});\nlet telemetryCloudContext = getCloudTelemetryProperties();\n\nexport function setTelemetryBackendContext(\n context: BackendTelemetryContextInput,\n): void {\n telemetryBackendContext = getBackendTelemetryProperties(context);\n}\n\nexport function setTelemetryCloudContext(\n context: CloudTelemetryContextInput | null,\n): void {\n telemetryCloudContext = getCloudTelemetryProperties(context);\n}\n\nfunction addCanvasEventProperties(\n event: CaptureResult | null,\n): CaptureResult | null {\n if (!event) return null;\n\n return {\n ...event,\n properties: {\n ...telemetryBackendContext,\n ...telemetryCloudContext,\n ...event.properties,\n ...CANVAS_EVENT_PROPERTIES,\n },\n };\n}\n\nfunction restorePostHogConsent(posthog: PostHog): void {\n if (telemetryDisabled || getTelemetryConsent() !== \"granted\") {\n posthog.opt_out_capturing();\n } else {\n posthog.opt_in_capturing();\n }\n}\n\nfunction resetPostHogIdentity(posthog: PostHog, resetDeviceId = false): void {\n posthog.reset(resetDeviceId);\n appliedIdentityRevision = -1;\n // PostHog reset clears its own consent persistence, so immediately restore\n // the canonical Canvas decision kept in localStorage.\n restorePostHogConsent(posthog);\n}\n\nfunction applyDesiredTelemetryIdentity(posthog: PostHog): void {\n if (desiredTelemetryIdentity === undefined || !isTelemetryEnabled()) return;\n\n const desiredId = desiredTelemetryIdentity?.distinctId;\n const currentId = posthog.get_property(\"$user_id\");\n if (currentId != null && currentId !== desiredId) {\n resetPostHogIdentity(posthog);\n }\n\n if (desiredTelemetryIdentity === null) {\n appliedIdentityRevision = desiredIdentityRevision;\n return;\n }\n\n if (\n posthog.get_property(\"$user_id\") !== desiredTelemetryIdentity.distinctId ||\n appliedIdentityRevision !== desiredIdentityRevision\n ) {\n posthog.identify(\n desiredTelemetryIdentity.distinctId,\n desiredTelemetryIdentity.properties,\n );\n appliedIdentityRevision = desiredIdentityRevision;\n }\n}\n\nfunction propertiesEqual(\n left: Record<string, unknown>,\n right: Record<string, unknown>,\n): boolean {\n const keys = Object.keys(left);\n return (\n keys.length === Object.keys(right).length &&\n keys.every((key) => left[key] === right[key])\n );\n}\n\n/**\n * Configure the single Canvas telemetry client before its first use.\n * Passing false disables telemetry and install tracking for embedded hosts.\n */\nexport function configureTelemetry(config: TelemetryConfiguration): void {\n if (config === false) {\n if (telemetryDisabled) return;\n telemetryDisabled = true;\n posthogInstance?.opt_out_capturing();\n notifyTelemetryConsentListeners();\n return;\n }\n\n const wasDisabled = telemetryDisabled;\n telemetryDisabled = false;\n\n if (!posthogInstance && !initializationPromise) {\n const definedConfig = Object.fromEntries(\n Object.entries(config).filter(([, value]) => value !== undefined),\n ) as TelemetryConfig;\n telemetryConfig = { ...telemetryConfig, ...definedConfig };\n }\n\n if (wasDisabled) {\n if (posthogInstance) {\n restorePostHogConsent(posthogInstance);\n applyDesiredTelemetryIdentity(posthogInstance);\n }\n notifyTelemetryConsentListeners();\n }\n}\n\nfunction getResolvedTelemetryConfig(): Required<TelemetryConfig> | null {\n if (telemetryDisabled) return null;\n\n return {\n apiKey: telemetryConfig.apiKey || DEFAULT_POSTHOG_API_KEY,\n apiHost: telemetryConfig.apiHost || DEFAULT_POSTHOG_HOST,\n uiHost: telemetryConfig.uiHost || DEFAULT_POSTHOG_UI_HOST,\n };\n}\n\n/**\n * Check if we're in a browser environment\n */\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof localStorage !== \"undefined\";\n}\n\n/**\n * Lazily load PostHog to avoid SSR/Node.js issues.\n * PostHog is a browser-only library, so we dynamically import it only when needed.\n */\nasync function getPostHog(): Promise<PostHog | null> {\n if (!isBrowser()) {\n return null;\n }\n\n if (posthogInstance) {\n return posthogInstance;\n }\n\n try {\n const { default: posthog } = await import(\"posthog-js\");\n return posthog;\n } catch {\n // Failed to load PostHog - telemetry will be disabled\n return null;\n }\n}\n\n/**\n * Check if telemetry is disabled via environment variable or browser setting.\n * Works in both Node.js and browser (Vite) environments.\n */\nfunction isDoNotTrackEnabled(): boolean {\n if (telemetryDisabled) {\n return true;\n }\n\n // Check Vite environment variable (browser)\n if (\n typeof import.meta !== \"undefined\" &&\n import.meta.env?.VITE_DO_NOT_TRACK === \"1\"\n ) {\n return true;\n }\n\n // Check Node.js environment variable (SSR/testing)\n if (typeof process !== \"undefined\" && process.env?.DO_NOT_TRACK === \"1\") {\n return true;\n }\n\n // Check browser's navigator.doNotTrack standard\n if (\n typeof navigator !== \"undefined\" &&\n (navigator.doNotTrack === \"1\" ||\n // @ts-expect-error - Some browsers use window.doNotTrack\n (typeof window !== \"undefined\" && window.doNotTrack === \"1\"))\n ) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Initialize PostHog SDK.\n *\n * @param enableCapturing - If true, enable capturing immediately (for install tracking).\n * If false, start with capturing disabled (for consent-gated tracking).\n */\nexport function configurePostHogBootstrap(\n bootstrap: BootstrapConfig | undefined,\n): void {\n if (!posthogInstance) {\n pendingBootstrap = bootstrap;\n }\n}\n\nexport async function initializePostHogClient(\n enableCapturing = false,\n): Promise<PostHog | null> {\n if (posthogInstance) {\n return posthogInstance;\n }\n\n if (initializationPromise) {\n return initializationPromise;\n }\n\n initializationPromise = (async () => {\n const config = getResolvedTelemetryConfig();\n if (!config) {\n return null;\n }\n\n const posthog = await getPostHog();\n if (!posthog) {\n return null;\n }\n\n // A named instance isolates Canvas configuration, consent, identity, and\n // persistence from a host application's default PostHog singleton.\n const initializedPostHog = posthog.init(\n config.apiKey,\n {\n api_host: config.apiHost,\n ui_host: config.uiHost,\n opt_out_capturing_by_default: !enableCapturing,\n persistence: \"localStorage\",\n persistence_name: POSTHOG_INSTANCE_NAME,\n consent_persistence_name: `${POSTHOG_INSTANCE_NAME}-consent`,\n person_profiles: \"always\",\n capture_pageview: POSTHOG_PAGEVIEW_CAPTURE_MODE,\n autocapture: true,\n disable_session_recording: true,\n bootstrap: pendingBootstrap,\n before_send: addCanvasEventProperties,\n },\n POSTHOG_INSTANCE_NAME,\n );\n if (!initializedPostHog) return null;\n\n posthogInstance = initializedPostHog;\n pendingBootstrap = undefined;\n\n if (telemetryDisabled) {\n posthogInstance.opt_out_capturing();\n } else if (getTelemetryConsent() === \"granted\") {\n posthogInstance.opt_in_capturing();\n applyDesiredTelemetryIdentity(posthogInstance);\n } else if (!enableCapturing) {\n posthogInstance.opt_out_capturing();\n }\n\n return posthogInstance;\n })();\n\n try {\n return await initializationPromise;\n } finally {\n if (!posthogInstance) {\n initializationPromise = null;\n }\n }\n}\n\n/**\n * Get user's telemetry consent preference\n */\nexport function getTelemetryConsent(): TelemetryConsent {\n if (!isBrowser()) {\n return \"pending\";\n }\n\n // Check environment variable for opt-out\n if (isDoNotTrackEnabled()) {\n return \"denied\";\n }\n\n if (getLockedCloudAuthMode() === \"cookie\") {\n return \"granted\";\n }\n\n try {\n const consent = localStorage.getItem(TELEMETRY_CONSENT_KEY);\n if (consent === \"granted\" || consent === \"denied\") {\n return consent;\n }\n } catch {\n // Ignore storage errors\n }\n\n return \"pending\";\n}\n\n/**\n * Return an explicit browser choice that still needs to survive a Cloud login.\n * It remains pending across local backends so their settings cannot consume a\n * decision that must still be applied after the user connects to Cloud.\n */\nexport function getPendingCloudTelemetryConsent(): ResolvedTelemetryConsent | null {\n if (!isBrowser()) return null;\n\n try {\n const consent = localStorage.getItem(\n TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY,\n );\n return consent === \"granted\" || consent === \"denied\" ? consent : null;\n } catch {\n return null;\n }\n}\n\n/** Return the pre-reset actor whose local Automation consent must be revoked. */\nexport function getPendingLocalTelemetryRevocationId(): string | null {\n if (!isBrowser()) return null;\n\n try {\n return localStorage.getItem(TELEMETRY_CONSENT_PENDING_LOCAL_REVOCATION_KEY);\n } catch {\n return null;\n }\n}\n\nexport function subscribeTelemetryConsent(listener: () => void): () => void {\n if (!isBrowser()) return () => {};\n const handleStorage = (event: StorageEvent) => {\n if (\n event.key === TELEMETRY_CONSENT_KEY ||\n event.key === TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY\n ) {\n listener();\n }\n };\n window.addEventListener(TELEMETRY_CONSENT_CHANGE_EVENT, listener);\n window.addEventListener(\"storage\", handleStorage);\n\n return () => {\n window.removeEventListener(TELEMETRY_CONSENT_CHANGE_EVENT, listener);\n window.removeEventListener(\"storage\", handleStorage);\n };\n}\n\nfunction notifyTelemetryConsentListeners(): void {\n if (isBrowser())\n window.dispatchEvent(new Event(TELEMETRY_CONSENT_CHANGE_EVENT));\n}\n\nfunction markTelemetryConsentForCloudSync(\n consent: ResolvedTelemetryConsent,\n): void {\n if (!isBrowser()) return;\n\n try {\n localStorage.setItem(TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY, consent);\n } catch {\n // Ignore storage errors; the in-browser consent decision still applies.\n }\n}\n\nfunction markPendingLocalTelemetryRevocation(distinctId: string | null): void {\n if (!isBrowser() || !distinctId) return;\n\n try {\n localStorage.setItem(\n TELEMETRY_CONSENT_PENDING_LOCAL_REVOCATION_KEY,\n distinctId,\n );\n } catch {\n // Ignore storage errors; browser capture is still disabled below.\n }\n}\n\nexport function clearPendingLocalTelemetryRevocation(\n expectedDistinctId: string,\n): void {\n if (!isBrowser()) return;\n\n try {\n if (\n localStorage.getItem(TELEMETRY_CONSENT_PENDING_LOCAL_REVOCATION_KEY) !==\n expectedDistinctId\n ) {\n return;\n }\n localStorage.removeItem(TELEMETRY_CONSENT_PENDING_LOCAL_REVOCATION_KEY);\n } catch {\n // Ignore storage errors.\n }\n}\n\nexport function clearPendingCloudTelemetryConsent(\n expected?: ResolvedTelemetryConsent,\n): void {\n if (!isBrowser()) return;\n\n try {\n if (\n expected !== undefined &&\n localStorage.getItem(TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY) !==\n expected\n ) {\n return;\n }\n localStorage.removeItem(TELEMETRY_CONSENT_PENDING_CLOUD_SYNC_KEY);\n notifyTelemetryConsentListeners();\n } catch {\n // Ignore storage errors.\n }\n}\n\n/**\n * Set user's telemetry consent preference\n */\nexport async function setTelemetryConsent(\n consent: ResolvedTelemetryConsent,\n { syncToCloud = true }: SetTelemetryConsentOptions = {},\n): Promise<void> {\n if (!isBrowser()) {\n return;\n }\n\n try {\n const previousConsent = getTelemetryConsent();\n const unchanged = previousConsent === consent;\n localStorage.setItem(TELEMETRY_CONSENT_KEY, consent);\n if (telemetryDisabled) return;\n if (unchanged) return;\n\n // Reuse an initialized client synchronously so a same-flush identify()\n // cannot run before consent is applied. Only the cold path awaits import.\n const posthog = posthogInstance ?? (await initializePostHogClient());\n if (!posthog) {\n return;\n }\n\n if (consent === \"granted\") {\n posthog.opt_in_capturing();\n applyDesiredTelemetryIdentity(posthog);\n } else {\n markPendingLocalTelemetryRevocation(posthog.get_distinct_id?.() ?? null);\n if (posthog.get_property?.(\"$user_id\") != null) {\n resetPostHogIdentity(posthog);\n } else {\n posthog.opt_out_capturing();\n }\n }\n } catch {\n // Ignore storage errors\n } finally {\n // Notify UI/backend/identity reconcilers only after the browser capture state\n // reflects this decision. Otherwise a pre-login grant can trigger an\n // identify while PostHog is still opted out and lose funnel continuity.\n if (syncToCloud) {\n markTelemetryConsentForCloudSync(consent);\n }\n notifyTelemetryConsentListeners();\n }\n}\n\n/**\n * Declare the current Cloud identity. The telemetry service applies it only\n * after consent and owns all reset/account-switch semantics.\n */\nexport async function setTelemetryIdentity(\n distinctId: string | null,\n properties: Record<string, unknown> = {},\n): Promise<void> {\n const nextIdentity = distinctId === null ? null : { distinctId, properties };\n const unchanged =\n desiredTelemetryIdentity === nextIdentity ||\n (desiredTelemetryIdentity !== undefined &&\n desiredTelemetryIdentity !== null &&\n nextIdentity !== null &&\n desiredTelemetryIdentity.distinctId === nextIdentity.distinctId &&\n propertiesEqual(desiredTelemetryIdentity.properties, properties));\n if (unchanged) return;\n\n desiredTelemetryIdentity = nextIdentity;\n desiredIdentityRevision += 1;\n appliedIdentityRevision = -1;\n\n if (!isTelemetryEnabled()) return;\n const posthog = posthogInstance ?? (await initializePostHogClient());\n if (posthog && isTelemetryEnabled()) {\n // Read the desired identity after the await so a newer account always wins\n // if identity changes while the SDK is loading.\n applyDesiredTelemetryIdentity(posthog);\n }\n}\n\n/**\n * Check if telemetry is enabled (user has granted consent)\n */\nexport function isTelemetryEnabled(): boolean {\n return getTelemetryConsent() === \"granted\";\n}\n\n/**\n * Check if first use event has already been sent\n */\nfunction hasFirstUseSent(): boolean {\n if (!isBrowser()) {\n return false;\n }\n\n try {\n return localStorage.getItem(TELEMETRY_FIRST_USE_KEY) === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Mark first use event as sent\n */\nfunction markFirstUseSent(): void {\n if (!isBrowser()) {\n return;\n }\n\n try {\n localStorage.setItem(TELEMETRY_FIRST_USE_KEY, \"true\");\n } catch {\n // Ignore storage errors\n }\n}\n\n/**\n * Track the initial install of the library.\n *\n * IMPORTANT: This is sent immediately on first use, regardless of consent status.\n * This allows us to track library adoption even if users haven't made a consent choice yet.\n *\n * The event is:\n * - Completely anonymous (no PII, just a random PostHog distinct_id)\n * - Sent only once per installation (tracked via localStorage, persists across sessions)\n * - Still respects DO_NOT_TRACK environment variable and browser setting\n *\n * Users who want complete privacy can:\n * - Set VITE_DO_NOT_TRACK=1 or browser's Do Not Track\n * - Later deny consent to prevent all future tracking\n */\nexport async function trackInstall(): Promise<void> {\n // Respect hard opt-out via environment variable or browser setting\n if (isDoNotTrackEnabled()) {\n return;\n }\n\n // Already sent install event (persisted in localStorage - survives app relaunches)\n if (hasFirstUseSent()) {\n return;\n }\n\n // Initialize PostHog with capturing enabled (for this one event)\n const posthog = await initializePostHogClient(true);\n if (!posthog || isDoNotTrackEnabled()) {\n return;\n }\n\n // Temporarily enable capturing if it was disabled\n const wasOptedOut = posthog.has_opted_out_capturing?.() ?? false;\n if (wasOptedOut) {\n posthog.opt_in_capturing();\n }\n\n // Capture the install event\n posthog.capture(\"canvas_install\", {\n platform: typeof navigator !== \"undefined\" ? navigator.platform : \"unknown\",\n user_agent:\n typeof navigator !== \"undefined\" ? navigator.userAgent : \"unknown\",\n referrer: typeof document !== \"undefined\" ? document.referrer : \"\",\n url_origin: typeof window !== \"undefined\" ? window.location.origin : \"\",\n embedded: typeof window !== \"undefined\" && window.self !== window.top,\n });\n\n // Mark as sent (stored in localStorage - persists across browser sessions)\n markFirstUseSent();\n\n // Restore opt-out state if user hasn't granted consent yet\n // This ensures we only send the install event, not subsequent events\n const currentConsent = getTelemetryConsent();\n if (currentConsent !== \"granted\") {\n posthog.opt_out_capturing();\n }\n}\n\n/**\n * Check if session start event has already been sent (this browser session)\n */\nfunction hasSessionSent(): boolean {\n if (!isBrowser()) {\n return false;\n }\n\n try {\n return sessionStorage.getItem(TELEMETRY_SESSION_KEY) === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Mark session start event as sent (uses sessionStorage so it resets on new tabs/sessions)\n */\nfunction markSessionSent(): void {\n if (!isBrowser()) {\n return;\n }\n\n try {\n sessionStorage.setItem(TELEMETRY_SESSION_KEY, \"true\");\n } catch {\n // Ignore storage errors\n }\n}\n\n/** Return the shared client only when a consented capture is safe to emit. */\nasync function getPostHogForConsentedCapture(): Promise<PostHog | null> {\n if (!isTelemetryEnabled() || getTelemetryConsent() !== \"granted\") return null;\n\n const posthog = await initializePostHogClient();\n if (!posthog || !isTelemetryEnabled()) return null;\n\n // The browser preference is the canonical capture decision. PostHog may\n // still carry an older opt-out marker while backend consent is loading or\n // after a previous backend temporarily reported a stale value. Heal that\n // drift at the event boundary so capture() cannot silently discard an event\n // that the user has explicitly allowed.\n if (posthog.has_opted_out_capturing?.()) {\n posthog.opt_in_capturing();\n }\n\n applyDesiredTelemetryIdentity(posthog);\n\n return posthog;\n}\n\n/**\n * Track a session start event.\n * Called each time a new browser session starts (respects consent).\n * Uses sessionStorage for deduplication - only sends once per browser session.\n */\nexport async function trackSessionStart(): Promise<void> {\n // Already sent session event this browser session\n if (hasSessionSent()) {\n return;\n }\n\n const posthog = await getPostHogForConsentedCapture();\n if (!posthog) return;\n\n posthog.capture(\"canvas_new_session\", {\n is_first_use: !hasFirstUseSent(),\n });\n\n // Mark as sent for this session\n markSessionSent();\n}\n\n/** Return the active PostHog distinct ID when consent allows capture. */\nexport async function getTelemetryDistinctId(): Promise<string | null> {\n const posthog = await getPostHogForConsentedCapture();\n return posthog?.get_distinct_id?.() ?? null;\n}\n\n/** Return the PostHog distinct ID for local consent sync without emitting capture. */\nexport async function getTelemetryDistinctIdForConsentSync(): Promise<\n string | null\n> {\n if (!isBrowser()) return null;\n\n if (getTelemetryConsent() !== \"granted\") {\n const pendingRevocationId = getPendingLocalTelemetryRevocationId();\n if (pendingRevocationId) return pendingRevocationId;\n }\n\n if (telemetryDisabled || isDoNotTrackEnabled()) return null;\n\n const posthog = await initializePostHogClient();\n return posthog?.get_distinct_id?.() ?? null;\n}\n\n/**\n * Track a custom event (respects consent).\n */\nexport async function trackEvent(\n eventName: string,\n properties: Record<string, unknown> = {},\n): Promise<void> {\n const posthog = await getPostHogForConsentedCapture();\n if (!posthog) return;\n\n posthog.capture(eventName, properties);\n}\n\n/** Track an exception through the same consent-aware client as custom events. */\nexport async function trackException(\n error: unknown,\n properties: Record<string, unknown> = {},\n): Promise<void> {\n const posthog = await getPostHogForConsentedCapture();\n if (!posthog) return;\n\n posthog.captureException(error, properties);\n}\n\n/**\n * Clear all telemetry data (for privacy/GDPR requests)\n */\nexport async function clearTelemetryData(): Promise<void> {\n if (!isBrowser()) {\n return;\n }\n\n try {\n markPendingLocalTelemetryRevocation(\n posthogInstance?.get_distinct_id?.() ?? null,\n );\n localStorage.removeItem(TELEMETRY_CONSENT_KEY);\n localStorage.removeItem(TELEMETRY_FIRST_USE_KEY);\n } catch {\n // Continue clearing the in-memory and SDK identity if storage is blocked.\n }\n clearPendingCloudTelemetryConsent();\n try {\n sessionStorage.removeItem(TELEMETRY_SESSION_KEY);\n } catch {\n // Continue clearing the in-memory and SDK identity if storage is blocked.\n }\n\n telemetryBackendContext = getBackendTelemetryProperties({});\n telemetryCloudContext = getCloudTelemetryProperties();\n desiredTelemetryIdentity = null;\n desiredIdentityRevision += 1;\n appliedIdentityRevision = -1;\n\n try {\n if (posthogInstance) {\n resetPostHogIdentity(posthogInstance, true);\n }\n } catch {\n // A reset failure must not leave capture enabled after a privacy clear.\n try {\n posthogInstance?.opt_out_capturing();\n } catch {\n // Telemetry failures must not break the application.\n }\n } finally {\n notifyTelemetryConsentListeners();\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { BaseEvent } from "../base/event";
|
|
2
2
|
import { ExecutionStatus } from "../base/common";
|
|
3
|
+
import type { ConversationErrorEvent } from "@openhands/typescript-client";
|
|
4
|
+
export type { ConversationErrorEvent };
|
|
3
5
|
/**
|
|
4
6
|
* Token usage metrics for LLM calls
|
|
5
7
|
*/
|
|
@@ -122,24 +124,6 @@ export interface ConversationStateUpdateEventGoal extends ConversationStateUpdat
|
|
|
122
124
|
value: GoalStatus;
|
|
123
125
|
}
|
|
124
126
|
export type ConversationStateUpdateEvent = ConversationStateUpdateEventFullState | ConversationStateUpdateEventAgentStatus | ConversationStateUpdateEventStats | ConversationStateUpdateEventGoal;
|
|
125
|
-
export interface ConversationErrorEvent extends BaseEvent {
|
|
126
|
-
/**
|
|
127
|
-
* Discriminator field for type guards
|
|
128
|
-
*/
|
|
129
|
-
kind: "ConversationErrorEvent";
|
|
130
|
-
/**
|
|
131
|
-
* The source is always "environment" for conversation error events
|
|
132
|
-
*/
|
|
133
|
-
source: "environment";
|
|
134
|
-
/**
|
|
135
|
-
* Error code (e.g., "AuthenticationError")
|
|
136
|
-
*/
|
|
137
|
-
code: string;
|
|
138
|
-
/**
|
|
139
|
-
* Detailed error message
|
|
140
|
-
*/
|
|
141
|
-
detail: string;
|
|
142
|
-
}
|
|
143
127
|
export interface ServerErrorEvent extends BaseEvent {
|
|
144
128
|
/**
|
|
145
129
|
* Discriminator field for type guards
|
|
@@ -158,4 +142,3 @@ export interface ServerErrorEvent extends BaseEvent {
|
|
|
158
142
|
*/
|
|
159
143
|
detail: string;
|
|
160
144
|
}
|
|
161
|
-
export {};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { EventID, ToolCallID } from "../base/common";
|
|
2
2
|
import { BaseEvent } from "../base/event";
|
|
3
3
|
import { Observation } from "../base/observation";
|
|
4
|
+
import type { AgentErrorEvent } from "@openhands/typescript-client";
|
|
5
|
+
export type { AgentErrorEvent };
|
|
4
6
|
export interface ObservationBaseEvent extends BaseEvent {
|
|
5
7
|
/**
|
|
6
8
|
* The source is always "environment" for observation events
|
|
@@ -35,21 +37,3 @@ export interface UserRejectObservation extends ObservationBaseEvent {
|
|
|
35
37
|
*/
|
|
36
38
|
action_id: EventID;
|
|
37
39
|
}
|
|
38
|
-
export interface AgentErrorEvent extends BaseEvent {
|
|
39
|
-
/**
|
|
40
|
-
* The source is always "agent" for agent error events
|
|
41
|
-
*/
|
|
42
|
-
source: "agent";
|
|
43
|
-
/**
|
|
44
|
-
* The tool name that this observation is responding to
|
|
45
|
-
*/
|
|
46
|
-
tool_name: string;
|
|
47
|
-
/**
|
|
48
|
-
* The tool call id that this observation is responding to
|
|
49
|
-
*/
|
|
50
|
-
tool_call_id: ToolCallID;
|
|
51
|
-
/**
|
|
52
|
-
* The error message from the scaffold
|
|
53
|
-
*/
|
|
54
|
-
error: string;
|
|
55
|
-
}
|
|
@@ -43,20 +43,24 @@ export interface Automation {
|
|
|
43
43
|
last_triggered_at?: string | null;
|
|
44
44
|
}
|
|
45
45
|
export type AutomationSpec = Omit<Automation, "id" | "created_at" | "updated_at" | "last_triggered_at">;
|
|
46
|
+
/** The envelope constants come from the interface manifest's import/export spec. */
|
|
46
47
|
export interface AutomationExportFile {
|
|
47
|
-
version:
|
|
48
|
-
kind:
|
|
48
|
+
version: number;
|
|
49
|
+
kind: string;
|
|
49
50
|
spec: AutomationSpec;
|
|
50
51
|
}
|
|
51
52
|
export interface AutomationsResponse {
|
|
52
53
|
automations: Automation[];
|
|
53
54
|
total: number;
|
|
54
55
|
}
|
|
56
|
+
/** Mirrors `RunStatus` in the automation service's OpenAPI schema. */
|
|
55
57
|
export declare enum AutomationRunStatus {
|
|
56
58
|
PENDING = "PENDING",
|
|
57
59
|
RUNNING = "RUNNING",
|
|
58
60
|
COMPLETED = "COMPLETED",
|
|
59
|
-
FAILED = "FAILED"
|
|
61
|
+
FAILED = "FAILED",
|
|
62
|
+
CANCELLED = "CANCELLED",
|
|
63
|
+
SKIPPED = "SKIPPED"
|
|
60
64
|
}
|
|
61
65
|
export interface AutomationRun {
|
|
62
66
|
id: string;
|