@openhands/agent-canvas 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{acp-providers-BQwoUBpe.js → acp-providers-DerAmTyY.js} +1 -1
- package/build/assets/{active-backend-context-BCXRv5pm.js → active-backend-context-DHhm10VS.js} +1 -1
- package/build/assets/{add-backend-modal-BKHzq5no.js → add-backend-modal-BoMkMyLB.js} +1 -1
- package/build/assets/{agent-profiles-settings-CEp5CIz8.js → agent-profiles-settings-CYPloKYK.js} +1 -1
- package/build/assets/{agent-server-compatibility-D6DSanlx.js → agent-server-compatibility-C0MtTTwb.js} +1 -1
- package/build/assets/{agent-server-conversation-service.api-cylugfDz.js → agent-server-conversation-service.api-lzc8dabY.js} +4 -4
- package/build/assets/{agent-settings-C-tann3x.js → agent-settings-GwiXe_6k.js} +1 -1
- package/build/assets/agent-settings-OdsyI2gX.js +1 -0
- package/build/assets/{alert-banner-Dd4woGbm.js → alert-banner-Dh51WURQ.js} +1 -1
- package/build/assets/{api-key-entry-screen-Bll_CkuQ.js → api-key-entry-screen-2gsoZAOK.js} +1 -1
- package/build/assets/app-settings-CD9euh81.js +1 -0
- package/build/assets/{automation-detail-Z9dN2f5l.js → automation-detail-Bn8q0AG3.js} +1 -1
- package/build/assets/{automation-export-D5uL0Tf8.js → automation-export-Djc8Tf0M.js} +1 -1
- package/build/assets/{automations-list-BMOWcqzZ.js → automations-list-Dtiolk1h.js} +1 -1
- package/build/assets/{back-nav-button-ZUDTMOTB.js → back-nav-button-DVknCcSP.js} +1 -1
- package/build/assets/backend-form-modal-B8GtBA-J.js +1 -0
- package/build/assets/{backend-synced-settings-badge-Db_REKVw.js → backend-synced-settings-badge-yVh6Kf4E.js} +1 -1
- package/build/assets/{base-modal-Cb0C6m0Q.js → base-modal-CIF_785P.js} +1 -1
- package/build/assets/{brand-button-2Tp3aXk1.js → brand-button-B1izLAdR.js} +1 -1
- package/build/assets/{browser-QYLVr1kS.js → browser-DKaeq_sT.js} +2 -2
- package/build/assets/browser-store-BI6uklCG.js +1 -0
- package/build/assets/{browser-tab-BTTP1OE2.js → browser-tab-qb_ftCxW.js} +1 -1
- package/build/assets/{circle-plus-check-toggle-QQJKUnF6.js → circle-plus-check-toggle-DoFIjVE0.js} +1 -1
- package/build/assets/client-source-CtQjJEy6.js +1 -0
- package/build/assets/cloud-funnel-analytics-uzzLlLuj.js +1 -0
- package/build/assets/{color-themes-bVMmJJG6.js → color-themes-CHizm1xF.js} +1 -1
- package/build/assets/{combobox-caret-A5jMVHgE.js → combobox-caret-CxZpqoSR.js} +1 -1
- package/build/assets/{command-menu-BMVEme4H.js → command-menu-oTvKDU3Y.js} +1 -1
- package/build/assets/{command-store-jrWX_CcW.js → command-store-D8J5LMW1.js} +1 -1
- package/build/assets/{condenser-settings-CIa6eyB4.js → condenser-settings-Q1rHh4Qe.js} +1 -1
- package/build/assets/{confirmation-modal-4n_944zq.js → confirmation-modal-DGBWM2Ls.js} +1 -1
- package/build/assets/{context-menu-list-item-DvfFic5I.js → context-menu-list-item-6psNyl7X.js} +1 -1
- package/build/assets/conversation-B8d8_Upd.js +1 -0
- package/build/assets/{conversation-D4o4dG2t.js → conversation-Lmqm6VJC.js} +20 -20
- package/build/assets/conversation-panel-B8n40Swu.js +1 -0
- package/build/assets/{conversation-service.api-0JG_fF9d.js → conversation-service.api-D8QU-BiL.js} +1 -1
- package/build/assets/conversation-state-store-B2Bp32XI.js +1 -0
- package/build/assets/{conversation-store-BCSpLuEf.js → conversation-store-LptbOvKa.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-Dp4Q_hXi.js → copy-to-clipboard-button-CFzH_NOX.js} +1 -1
- package/build/assets/{device-verify-CM086oKs.js → device-verify-WBSjJBLH.js} +1 -1
- package/build/assets/{dropdown-classes-DZq0BQjb.js → dropdown-classes-D3wMJlXT.js} +1 -1
- package/build/assets/{ellipsis-button-TPJdyxnK.js → ellipsis-button-CbNnHlIq.js} +1 -1
- package/build/assets/{entry.client-DypYHsYm.js → entry.client-Dnnak-Hq.js} +2 -2
- package/build/assets/{enum-filter-dropdown-CW_mBg0e.js → enum-filter-dropdown-JLYv1t8L.js} +1 -1
- package/build/assets/{environment-switch-overlay-6laJch-9.js → environment-switch-overlay-B1PFO8P8.js} +1 -1
- package/build/assets/{extensions-hub-BJFbFfKS.js → extensions-hub-DqvwvpCi.js} +1 -1
- package/build/assets/{extensions-navigation-DqSl7CJw.js → extensions-navigation-BMc9Nluv.js} +1 -1
- package/build/assets/{files-tab-c316dKAq.js → files-tab-BAkaV4aO.js} +1 -1
- package/build/assets/{files-tab-store-tfCav6bB.js → files-tab-store-DJsPxYdg.js} +1 -1
- package/build/assets/{git-provider-icon-DUb2pEos.js → git-provider-icon-xvbukHaT.js} +1 -1
- package/build/assets/{home-D7ds4Jyw.js → home-D01kSnmo.js} +1 -1
- package/build/assets/home-NZO2bF4N.js +1 -0
- package/build/assets/index-home-BsI6i0TC.js +1 -0
- package/build/assets/{install-server-modal-CvHvzZj3.js → install-server-modal-BYjqoRyX.js} +1 -1
- package/build/assets/{launch-A47TK2Me.js → launch-DlXspDku.js} +1 -1
- package/build/assets/lesson-plan-cNUjpdFx.js +4 -0
- package/build/assets/{llm-not-configured-banner-B7DR8SPs.js → llm-not-configured-banner-DUPyoFIZ.js} +7 -7
- package/build/assets/{llm-settings-Cvi7q4ox.js → llm-settings-Cs_iieFY.js} +1 -1
- package/build/assets/llm-settings-J2ke2foG.js +1 -0
- package/build/assets/{llm-subscription-service-Cz1yBBvE.js → llm-subscription-service-C0zN0-rH.js} +1 -1
- package/build/assets/{manage-backends-modal-DAVhNUCe.js → manage-backends-modal-nMoCZ2a0.js} +1 -1
- package/build/assets/manifest-f1b46f62.js +1 -0
- package/build/assets/{map-provider-XSFHmdDs.js → map-provider-BbIb12oh.js} +1 -1
- package/build/assets/{markdown-renderer-B6cJJ_MN.js → markdown-renderer-B4V2OMFP.js} +1 -1
- package/build/assets/{mcp-BwssgMpg.js → mcp-kZM-cAZw.js} +1 -1
- package/build/assets/{messages-D8MeG2ZQ.js → messages-CJAv5n4j.js} +1 -1
- package/build/assets/{model-selector-BxTbbKub.js → model-selector-D51W2Q9b.js} +1 -1
- package/build/assets/{navigation-link-imH6S7h2.js → navigation-link-D8hfwvxI.js} +1 -1
- package/build/assets/{onboarding-CyicadGt.js → onboarding-Dx8n8HFr.js} +1 -1
- package/build/assets/onboarding-modal-Bxuxpfdz.js +1 -0
- package/build/assets/{organization-service.api-QknzKDh3.js → organization-service.api-Da2jiuBS.js} +1 -1
- package/build/assets/{path-utils-BECGet7G.js → path-utils-D53ZHUQU.js} +1 -1
- package/build/assets/{planner-tab-DPKHmMAX.js → planner-tab-BM-pKx0z.js} +1 -1
- package/build/assets/{plugins-management-service-DuTTxquo.js → plugins-management-service-DISfOL13.js} +1 -1
- package/build/assets/{profiles-service.api-D6jvZOWu.js → profiles-service.api-DWetW2TL.js} +1 -1
- package/build/assets/providers-C7lMslCi.js +1 -0
- package/build/assets/{proxy-CuhhyjdX.js → proxy-G4ce0fnQ.js} +1 -1
- package/build/assets/{recommended-automations-launcher-DA6DWS7V.js → recommended-automations-launcher-BWRRvMPE.js} +1 -1
- package/build/assets/root-layout-ClEl-JlJ.js +2 -0
- package/build/assets/root-oT83qVlk.js +2 -0
- package/build/assets/{runtime-waiting-state-DeD9G7yJ.js → runtime-waiting-state-CnyVhX4T.js} +1 -1
- package/build/assets/{schema-field-BOLdL_U7.js → schema-field-CwdqUOnE.js} +1 -1
- package/build/assets/{sdk-section-page-ZIltERxf.js → sdk-section-page-Cwj0T4gF.js} +1 -1
- package/build/assets/{sdk-settings-schema-Ba_Pa9uf.js → sdk-settings-schema-CLR01YIK.js} +1 -1
- package/build/assets/{secrets-service-50DElFny.js → secrets-service-Ch7RH8eH.js} +1 -1
- package/build/assets/{secrets-settings-Digl7JLe.js → secrets-settings-Bc_pBX6F.js} +1 -1
- package/build/assets/{settings-dropdown-input-BD5C9fBn.js → settings-dropdown-input-Dhx9ErGd.js} +1 -1
- package/build/assets/{settings-index-CODBijya.js → settings-index-BzSIM1-N.js} +1 -1
- package/build/assets/{settings-input-CzNOq-Pj.js → settings-input-BsgQWS5R.js} +1 -1
- package/build/assets/{settings-list-classes-CuxH9ZoR.js → settings-list-classes-DSJJX99U.js} +1 -1
- package/build/assets/{settings-modal-BcSWpKI0.js → settings-modal-BnZ7mMu7.js} +1 -1
- package/build/assets/settings-n9a395O0.js +1 -0
- package/build/assets/{settings-service.api-Bsu1PvYO.js → settings-service.api-DPTFyRXL.js} +1 -1
- package/build/assets/{settings-switch-DqmHAfWJ.js → settings-switch-Bes8dIlV.js} +1 -1
- package/build/assets/{settings-utils-B1lBErvV.js → settings-utils-DzCVfiR3.js} +1 -1
- package/build/assets/{shared-conversation-CDskdmrb.js → shared-conversation-CIDDti9I.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-DmCmZgq1.js → sidebar-mobile-menu-toggle-CTX7J4wM.js} +1 -1
- package/build/assets/{sidebar-nav-link-DMc8AIe7.js → sidebar-nav-link-CHqyFXwV.js} +1 -1
- package/build/assets/{sidebar-store-DXWSCFpa.js → sidebar-store-uiUXBU1N.js} +1 -1
- package/build/assets/{skill-card-pill-row-DOIWjiMF.js → skill-card-pill-row-BPYKQ3IN.js} +1 -1
- package/build/assets/{skills-plugins-DLgINYuY.js → skills-plugins-HZEbNDmX.js} +1 -1
- package/build/assets/{skills-settings-DPiCWalR.js → skills-settings-BdqijFlC.js} +1 -1
- package/build/assets/{task-list-tab-CuhcDycu.js → task-list-tab-DyfgG4MC.js} +1 -1
- package/build/assets/telemetry-SHxpVxk8.js +2 -0
- package/build/assets/{terminal-CVqF-tCD.js → terminal-BDTa1HEr.js} +1 -1
- package/build/assets/{typography-CQn9wyEX.js → typography-CzfoD9DY.js} +1 -1
- package/build/assets/{use-acp-credential-form-LlfZO_DD.js → use-acp-credential-form-DHd_Id-q.js} +1 -1
- package/build/assets/{use-activate-agent-profile-DpQjsXM0.js → use-activate-agent-profile-BRDdSwQ0.js} +1 -1
- package/build/assets/{use-active-agent-profile-Gw_uJujV.js → use-active-agent-profile-BMDTXsay.js} +1 -1
- package/build/assets/{use-active-conversation-B0sttISF.js → use-active-conversation-BbeVgedA.js} +1 -1
- package/build/assets/{use-agent-profiles-LHZEK0Gg.js → use-agent-profiles-Dn_S_Tkz.js} +1 -1
- package/build/assets/{use-agent-state-C5uA0bRj.js → use-agent-state-5qM3X30V.js} +1 -1
- package/build/assets/{use-backends-health-DKt1SmiU.js → use-backends-health-BagmAE_W.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-BAtqsbCi.js → use-can-manage-org-profiles-CyYqfzeo.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-C8m1oBy4.js → use-cloud-current-user-id-BwMX7jHW.js} +1 -1
- package/build/assets/use-config-B39iHYFi.js +1 -0
- package/build/assets/{use-create-conversation-CWQGNQ9J.js → use-create-conversation-CkKUQVbP.js} +1 -1
- package/build/assets/{use-create-secret-BIrsX3OB.js → use-create-secret-DEgM0MXZ.js} +1 -1
- package/build/assets/{use-event-store-CsD17BKu.js → use-event-store-Bbaz51GR.js} +1 -1
- package/build/assets/{use-handle-plan-click-DEuO7Byo.js → use-handle-plan-click-BFcE0Xms.js} +1 -1
- package/build/assets/{use-launch-skill-in-chat-CdHOoQGM.js → use-launch-skill-in-chat-DJWEfVc5.js} +1 -1
- package/build/assets/{use-llm-profiles-DQpQxVOD.js → use-llm-profiles-CgRtnj74.js} +1 -1
- package/build/assets/{use-plugins-marketplace-Bkk07W_M.js → use-plugins-marketplace-DOJp9rlE.js} +1 -1
- package/build/assets/use-runtime-is-ready-ziHQvXZQ.js +1 -0
- package/build/assets/{use-save-agent-profile-BxEsjnW0.js → use-save-agent-profile-i4FcEP98.js} +1 -1
- package/build/assets/{use-save-settings-ioSUMqbE.js → use-save-settings-DiDEbIJw.js} +1 -1
- package/build/assets/{use-settings-DNJC4gqu.js → use-settings-BeJap6YL.js} +1 -1
- package/build/assets/{use-settings-nav-items-BUsrDbVR.js → use-settings-nav-items-D5JJjFHJ.js} +1 -1
- package/build/assets/{use-skills-BsmKm23M.js → use-skills-Blpg2BqE.js} +1 -1
- package/build/assets/{use-task-list-rs7Xbzl8.js → use-task-list-CfisapBW.js} +1 -1
- package/build/assets/use-tracking-DFoPQUSU.js +1 -0
- package/build/assets/{use-user-conversation-B337kUKB.js → use-user-conversation-BrN2xeQU.js} +1 -1
- package/build/assets/{vendor~browser-tab-Xn94EtUo.js → vendor~browser-tab-CsMb-pta.js} +1 -1
- package/build/assets/{vendor~browser-5Njjw1Cl.js → vendor~browser-wXQ-WZEC.js} +1 -1
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dhilvkxv-BIieS_OD.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dhilvkxv-eGLBu60s.js} +2 -2
- package/build/assets/{vendor~files-tab-CiC3-lGh.js → vendor~files-tab-B-5fBohe.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DWteoTyr.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BD7v71DM.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-tlf6AnDe.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BT05Osu4.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-B8XNNEQZ.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-COhHANvV.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-Dc5nKwLO.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DgzWSMRc.js} +1 -1
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-CnJRLn5s.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-DqZatR3B.js} +1 -1
- package/build/assets/{vendor~launch-28DK5Rsl.js → vendor~launch-_Km3J77E.js} +1 -1
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~g9hift2g-DmmpG9SI.js → vendor~module-D5a_AClf.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation~shared-conversation-lYNG9C1U.js → vendor~root-layout~conversation-panel~conversation~shared-conversation-BrguKXCn.js} +1 -1
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation-Zhq6xAxR.js → vendor~root-layout~index-home~home~conversation-panel~conversation-BTvhGHHG.js} +1 -1
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation~aler~gfu7qdtz-B81b08bw.js → vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation~aler~gfu7qdtz-BOKQkbc6.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~ftka0fnu-jpyLM1Nn.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~ftka0fnu-cFNmfAE6.js} +1 -1
- package/build/assets/{verification-settings-HRgEM-_3.js → verification-settings-C8KzAdAX.js} +1 -1
- package/build/index.html +4 -4
- package/config/defaults.json +1 -1
- package/dist/api/cloud/conversation-service.api.cjs +1 -1
- package/dist/api/cloud/conversation-service.api.js +4 -4
- package/dist/api/option-service/option-service.api.cjs +1 -1
- package/dist/api/option-service/option-service.api.cjs.map +1 -1
- package/dist/api/option-service/option-service.api.js +0 -1
- package/dist/api/option-service/option-service.api.js.map +1 -1
- package/dist/api/option-service/option.types.d.ts +0 -1
- package/dist/components/features/backends/backend-form-modal.cjs +1 -1
- package/dist/components/features/backends/backend-form-modal.cjs.map +1 -1
- package/dist/components/features/backends/backend-form-modal.d.ts +1 -1
- package/dist/components/features/backends/backend-form-modal.js +137 -144
- package/dist/components/features/backends/backend-form-modal.js.map +1 -1
- package/dist/components/providers/agent-server-ui-providers.cjs +1 -1
- package/dist/components/providers/agent-server-ui-providers.cjs.map +1 -1
- package/dist/components/providers/agent-server-ui-providers.d.ts +4 -2
- package/dist/components/providers/agent-server-ui-providers.js +9 -2
- package/dist/components/providers/agent-server-ui-providers.js.map +1 -1
- package/dist/components/providers/index.cjs +1 -1
- package/dist/components/providers/index.d.ts +1 -2
- package/dist/components/providers/index.js +0 -1
- package/dist/components/providers/telemetry-provider.cjs +2 -0
- package/dist/components/providers/telemetry-provider.cjs.map +1 -0
- package/dist/components/providers/telemetry-provider.d.ts +6 -0
- package/dist/components/providers/telemetry-provider.js +64 -0
- package/dist/components/providers/telemetry-provider.js.map +1 -0
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/contexts/conversation-websocket-context.cjs +3 -3
- package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
- package/dist/contexts/conversation-websocket-context.js +197 -204
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/hooks/mutation/use-save-settings.cjs +1 -1
- package/dist/hooks/mutation/use-save-settings.cjs.map +1 -1
- package/dist/hooks/mutation/use-save-settings.d.ts +3 -1
- package/dist/hooks/mutation/use-save-settings.js +6 -5
- package/dist/hooks/mutation/use-save-settings.js.map +1 -1
- package/dist/hooks/query/use-task-polling.cjs +1 -1
- package/dist/hooks/query/use-task-polling.cjs.map +1 -1
- package/dist/hooks/query/use-task-polling.d.ts +19 -3
- package/dist/hooks/query/use-task-polling.js +36 -35
- package/dist/hooks/query/use-task-polling.js.map +1 -1
- package/dist/hooks/use-telemetry.cjs +1 -1
- package/dist/hooks/use-telemetry.cjs.map +1 -1
- package/dist/hooks/use-telemetry.d.ts +3 -3
- package/dist/hooks/use-telemetry.js +16 -22
- package/dist/hooks/use-telemetry.js.map +1 -1
- package/dist/hooks/use-tracking.cjs +1 -1
- package/dist/hooks/use-tracking.cjs.map +1 -1
- package/dist/hooks/use-tracking.d.ts +3 -4
- package/dist/hooks/use-tracking.js +37 -37
- package/dist/hooks/use-tracking.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/lib/index.d.ts +2 -2
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +2 -2
- package/dist/package.js.map +1 -1
- package/dist/routes/app-settings.cjs +1 -1
- package/dist/routes/app-settings.cjs.map +1 -1
- package/dist/routes/app-settings.js +66 -68
- package/dist/routes/app-settings.js.map +1 -1
- package/dist/routes/conversation.cjs +1 -1
- package/dist/routes/conversation.cjs.map +1 -1
- package/dist/routes/conversation.js +1 -1
- package/dist/routes/conversation.js.map +1 -1
- package/dist/routes/llm-settings.cjs +1 -1
- package/dist/routes/llm-settings.cjs.map +1 -1
- package/dist/routes/llm-settings.js +4 -1
- package/dist/routes/llm-settings.js.map +1 -1
- package/dist/services/cloud-funnel-analytics.cjs +1 -1
- package/dist/services/cloud-funnel-analytics.cjs.map +1 -1
- package/dist/services/cloud-funnel-analytics.d.ts +3 -11
- package/dist/services/cloud-funnel-analytics.js +16 -30
- package/dist/services/cloud-funnel-analytics.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 +46 -9
- package/dist/services/telemetry.js +181 -72
- package/dist/services/telemetry.js.map +1 -1
- package/dist/themes/color-themes.cjs.map +1 -1
- package/dist/themes/color-themes.d.ts +3 -6
- package/dist/themes/color-themes.js.map +1 -1
- package/dist/utils/error-handler.cjs +1 -1
- package/dist/utils/error-handler.cjs.map +1 -1
- package/dist/utils/error-handler.d.ts +1 -4
- package/dist/utils/error-handler.js +6 -7
- package/dist/utils/error-handler.js.map +1 -1
- package/dist/utils/map-provider.cjs +1 -1
- package/dist/utils/map-provider.cjs.map +1 -1
- package/dist/utils/map-provider.d.ts +1 -0
- package/dist/utils/map-provider.js +2 -1
- package/dist/utils/map-provider.js.map +1 -1
- package/package.json +2 -2
- package/build/assets/agent-settings-DGUKNSnU.js +0 -1
- package/build/assets/app-settings-BpViWwpC.js +0 -1
- package/build/assets/backend-form-modal-DhBT8P4g.js +0 -1
- package/build/assets/browser-store-BGXOGo-R.js +0 -1
- package/build/assets/client-source-Biqarhgr.js +0 -1
- package/build/assets/cloud-funnel-analytics-D-27T5Ao.js +0 -1
- package/build/assets/conversation-CHnEXGRM.js +0 -1
- package/build/assets/conversation-panel-11FjLCId.js +0 -1
- package/build/assets/conversation-state-store-JiUQp02U.js +0 -1
- package/build/assets/handle-capture-consent-DDnXMC9Y.js +0 -1
- package/build/assets/home-BQ-DC06B.js +0 -1
- package/build/assets/index-home-BRFDWs_4.js +0 -1
- package/build/assets/lesson-plan-DSf95kQ2.js +0 -4
- package/build/assets/llm-settings-Ch4ZbW3c.js +0 -1
- package/build/assets/manifest-958c741a.js +0 -1
- package/build/assets/onboarding-modal-DQwihcTz.js +0 -1
- package/build/assets/option-service.api-DAkg_F7p.js +0 -1
- package/build/assets/package-Dk_VtWJ4.js +0 -1
- package/build/assets/providers-B8pxQK8x.js +0 -1
- package/build/assets/root-BhP6bTBB.js +0 -2
- package/build/assets/root-layout-oBaHHW4s.js +0 -2
- package/build/assets/settings-BfgLHsgd.js +0 -1
- package/build/assets/telemetry-DHiTRl5_.js +0 -2
- package/build/assets/use-config-CXy4vD0H.js +0 -1
- package/build/assets/use-runtime-is-ready-D4pkGT6E.js +0 -1
- package/build/assets/use-tracking-poxQHMwR.js +0 -1
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ljq5gbus-B2XD4bi2.js +0 -1
- package/dist/components/providers/posthog-wrapper.cjs +0 -2
- package/dist/components/providers/posthog-wrapper.cjs.map +0 -1
- package/dist/components/providers/posthog-wrapper.d.ts +0 -4
- package/dist/components/providers/posthog-wrapper.js +0 -49
- package/dist/components/providers/posthog-wrapper.js.map +0 -1
- package/dist/node_modules/posthog-js/react/dist/esm/index.cjs +0 -2
- package/dist/node_modules/posthog-js/react/dist/esm/index.cjs.map +0 -1
- package/dist/node_modules/posthog-js/react/dist/esm/index.js +0 -113
- package/dist/node_modules/posthog-js/react/dist/esm/index.js.map +0 -1
- package/dist/utils/handle-capture-consent.cjs +0 -2
- package/dist/utils/handle-capture-consent.cjs.map +0 -1
- package/dist/utils/handle-capture-consent.d.ts +0 -7
- package/dist/utils/handle-capture-consent.js +0 -8
- package/dist/utils/handle-capture-consent.js.map +0 -1
- /package/build/assets/{__vite-browser-external-DU-Cb_sT.js → __vite-browser-external-BQUj0sYu.js} +0 -0
- /package/build/assets/{agent-server-ui-style-scope-COnDHTm5.js → agent-server-ui-style-scope-qhnhZHBV.js} +0 -0
- /package/build/assets/{automation-BVEmGghX.js → automation-LZB0MjdV.js} +0 -0
- /package/build/assets/{canvas-ui-BhxjoA1f.js → canvas-ui-COgjltGz.js} +0 -0
- /package/build/assets/{checkmark-DhcMGwtO.js → checkmark-h7udgXMM.js} +0 -0
- /package/build/assets/{close-DO5Rq_CS.js → close-DLFb5kfv.js} +0 -0
- /package/build/assets/{code-tag-BvjtzUsr.js → code-tag-DYlAhEQY.js} +0 -0
- /package/build/assets/{conversation-local-storage-B31voBg7.js → conversation-local-storage-F6zVMM--.js} +0 -0
- /package/build/assets/{conversation-tab-empty-state-BUhKVwoi.js → conversation-tab-empty-state-CNUmIms2.js} +0 -0
- /package/build/assets/{copy-DLUw2us-.js → copy-BLmGeJcd.js} +0 -0
- /package/build/assets/{dist-Dj01FXbZ.js → dist-CodhvuAP.js} +0 -0
- /package/build/assets/{environment-switch-store-D9hB9PvY.js → environment-switch-store-DkjlKWzN.js} +0 -0
- /package/build/assets/{extension-module-card-classes-BlO4w702.js → extension-module-card-classes-9V3J9J_b.js} +0 -0
- /package/build/assets/{folder-ynxP2EIL.js → folder-Bk311brm.js} +0 -0
- /package/build/assets/{form-control-classes-CvUaw8_L.js → form-control-classes-CbdN5aO3.js} +0 -0
- /package/build/assets/{get-language-from-path-rWEQrOGU.js → get-language-from-path-DBqBsCWH.js} +0 -0
- /package/build/assets/{git-status-mapper-C3rfzUex.js → git-status-mapper-DnL9OC8_.js} +0 -0
- /package/build/assets/{iconBase-CuvxAQZ5.js → iconBase-Dz51Zn5x.js} +0 -0
- /package/build/assets/{link-external-BVDiJfZt.js → link-external-CaBmUEs_.js} +0 -0
- /package/build/assets/{llm-subscription-BkdHwtQe.js → llm-subscription-DtsX5Lhg.js} +0 -0
- /package/build/assets/{loading-spinner-Txxx1I1p.js → loading-spinner-BcdnT0mN.js} +0 -0
- /package/build/assets/{middleware-CWYDMVuG.js → middleware-DYHYNAnP.js} +0 -0
- /package/build/assets/{modal-backdrop-Dsmzgr5s.js → modal-backdrop-zVwfOJZr.js} +0 -0
- /package/build/assets/{modal-body-CDZdZ-eT.js → modal-body-Cc2zp0xb.js} +0 -0
- /package/build/assets/{modal-classes-B4oit_4c.js → modal-classes-3qT9Ap7Q.js} +0 -0
- /package/build/assets/{modal-close-button-DQElFMPo.js → modal-close-button-BcIBUdSq.js} +0 -0
- /package/build/assets/{navigation-context-SjzfpygH.js → navigation-context-DPs2G0X8.js} +0 -0
- /package/build/assets/{objectWithoutPropertiesLoose-CQwg6tC0.js → objectWithoutPropertiesLoose-BgYIAs2y.js} +0 -0
- /package/build/assets/{openhands-logo-C-gDp1wr.js → openhands-logo-bcNw5bkY.js} +0 -0
- /package/build/assets/{plan-components-CgPHWz3E.js → plan-components-BdZXPyZU.js} +0 -0
- /package/build/assets/{react-ao3tWj6K.js → react-DPDgL6du.js} +0 -0
- /package/build/assets/{search-pb4UKTfK.js → search-BgOCR7_c.js} +0 -0
- /package/build/assets/{segmented-toggle-C1-ZVyr5.js → segmented-toggle-kzwZkLaj.js} +0 -0
- /package/build/assets/{settings-gear-D_HVvE5L.js → settings-gear-MXCyZW0x.js} +0 -0
- /package/build/assets/{settings-like-page-layout-classes-DLrsPCaI.js → settings-like-page-layout-classes-Cdl6jOe5.js} +0 -0
- /package/build/assets/{settings-DksoDv5z.js → settings-mQUckT0g.js} +0 -0
- /package/build/assets/{settings-section-header-context-C2MUIG88.js → settings-section-header-context-COMOIaxV.js} +0 -0
- /package/build/assets/{sidebar-layout-Cn6eQaEI.js → sidebar-layout-Bm7pa3Vk.js} +0 -0
- /package/build/assets/{skills-CH4xgIh-.js → skills-EqzxYBvT.js} +0 -0
- /package/build/assets/{styled-tooltip-CvsjHuIf.js → styled-tooltip-B14i_Uac.js} +0 -0
- /package/build/assets/{switch-skeleton-BpSOvZ-n.js → switch-skeleton-DqQwalyu.js} +0 -0
- /package/build/assets/{terminal-Dokfkxn0.js → terminal-Cgf___rK.js} +0 -0
- /package/build/assets/{toggle-switch-CS0ClOy2.js → toggle-switch-DX_k418f.js} +0 -0
- /package/build/assets/{u-check-circle-DPWVO-9N.js → u-check-circle-BqoIxNz_.js} +0 -0
- /package/build/assets/{u-check-circle-half-BGNAAjOW.js → u-check-circle-half-MsShT8Ec.js} +0 -0
- /package/build/assets/{u-edit-BIskOoEG.js → u-edit-DL5LgKon.js} +0 -0
- /package/build/assets/{use-breakpoint-OjLm94cF.js → use-breakpoint-BP3lqLMx.js} +0 -0
- /package/build/assets/{use-click-outside-element-Jpt2WWd7.js → use-click-outside-element-D9BYdANT.js} +0 -0
- /package/build/assets/{use-is-authed-Dvbpiu3B.js → use-is-authed-BezEyfeh.js} +0 -0
- /package/build/assets/{use-onboarding-completion-DkRpDTsD.js → use-onboarding-completion-C_Swglzp.js} +0 -0
- /package/build/assets/{v4-DPgam_jW.js → v4-DbCkTSoU.js} +0 -0
- /package/build/assets/{vendor~browser-BvEKaLBz.js → vendor~browser-By2MVv_N.js} +0 -0
- /package/build/assets/{vendor~conversation-panel~conversation~alert-banner-CznX01nZ.js → vendor~conversation-panel~conversation~alert-banner-CxfzCmkN.js} +0 -0
- /package/build/assets/{vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-BuL5kjfS.js → vendor~index-home~home~conversation-panel~conversation~shared-conversation~planner-tab~files-tab-FghQ3Z1a.js} +0 -0
- /package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~j2jlu22h-DUYl8gbZ.js → vendor~root-layout~index-home~home~conversation-panel~conversation~launch~skills-settings~a~j2jlu22h-mC0v44WR.js} +0 -0
- /package/build/assets/{vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-pIgQDxTc.js → vendor~root-layout~index-home~home~mcp~automations-list~onboarding-modal-C4-GDgiF.js} +0 -0
- /package/build/assets/{vendor~terminal-jAaNQWS9.js → vendor~terminal-CnKZILnC.js} +0 -0
- /package/build/assets/{x-mark-C5przfXl.js → x-mark-Batp6gXa.js} +0 -0
package/dist/package.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.cjs","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.5.
|
|
1
|
+
{"version":3,"file":"package.cjs","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.5.2\",\n \"description\": \"Agent Canvas UI for OpenHands - run AI coding agents with a visual interface\",\n \"license\": \"MIT\",\n \"private\": false,\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/OpenHands/agent-canvas\"\n },\n \"homepage\": \"https://github.com/OpenHands/agent-canvas#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/OpenHands/agent-canvas/issues\"\n },\n \"bin\": {\n \"agent-canvas\": \"bin/agent-canvas.mjs\"\n },\n \"engines\": {\n \"node\": \">=22.12.0\"\n },\n \"dependencies\": {\n \"@heroui/react\": \"2.8.10\",\n \"@microlink/react-json-view\": \"1.31.20\",\n \"@monaco-editor/react\": \"4.7.0\",\n \"@openhands/extensions\": \"0.9.0\",\n \"@openhands/typescript-client\": \"1.34.0\",\n \"@react-router/node\": \"7.17.0\",\n \"@react-router/serve\": \"7.17.0\",\n \"@tailwindcss/vite\": \"4.2.4\",\n \"@tanstack/react-query\": \"5.100.9\",\n \"@types/shell-quote\": \"1.7.5\",\n \"@uidotdev/usehooks\": \"2.4.1\",\n \"@xterm/addon-fit\": \"0.11.0\",\n \"@xterm/xterm\": \"6.0.0\",\n \"axios\": \"1.16.0\",\n \"class-variance-authority\": \"0.7.1\",\n \"clsx\": \"2.1.1\",\n \"downshift\": \"9.3.2\",\n \"framer-motion\": \"12.38.0\",\n \"httpxy\": \"0.5.3\",\n \"i18next\": \"26.0.8\",\n \"i18next-browser-languagedetector\": \"8.2.1\",\n \"i18next-http-backend\": \"4.0.0\",\n \"isbot\": \"5.1.39\",\n \"lucide-react\": \"1.14.0\",\n \"monaco-editor\": \"0.55.1\",\n \"posthog-js\": \"1.372.6\",\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-hot-toast\": \"2.6.0\",\n \"react-i18next\": \"17.0.6\",\n \"react-icons\": \"5.6.0\",\n \"react-markdown\": \"10.1.0\",\n \"react-router\": \"7.17.0\",\n \"react-syntax-highlighter\": \"16.1.1\",\n \"rehype-raw\": \"7.0.0\",\n \"rehype-sanitize\": \"6.0.0\",\n \"remark-breaks\": \"4.0.0\",\n \"remark-gfm\": \"4.0.1\",\n \"shell-quote\": \"1.8.4\",\n \"sirv\": \"3.0.2\",\n \"sirv-cli\": \"3.0.1\",\n \"socket.io-client\": \"4.8.3\",\n \"tailwind-merge\": \"3.5.0\",\n \"tailwind-scrollbar\": \"4.0.2\",\n \"unist-util-visit\": \"5.1.0\",\n \"uuid\": \"14.0.0\",\n \"vite\": \"8.0.10\",\n \"winston\": \"3.19.0\",\n \"winston-daily-rotate-file\": \"5.0.0\",\n \"zustand\": \"5.0.12\"\n },\n \"scripts\": {\n \"dev\": \"node --env-file-if-exists=.env scripts/dev-with-automation.mjs\",\n \"dev:static\": \"node --env-file-if-exists=.env scripts/dev-static.mjs\",\n \"dev:extra-backend\": \"node --env-file-if-exists=.env scripts/dev-extra-backend.mjs\",\n \"dev:minimal\": \"node --env-file-if-exists=.env scripts/dev-safe.mjs\",\n \"dev:frontend\": \"npm run make-i18n && cross-env VITE_MOCK_API=false react-router dev\",\n \"dev:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router dev\",\n \"build\": \"npm run build:app\",\n \"build:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router build\",\n \"start\": \"npx sirv-cli build/ --single\",\n \"test\": \"npm run make-i18n && vitest run\",\n \"test:e2e\": \"playwright test --pass-with-no-tests\",\n \"test:e2e:live\": \"node --env-file-if-exists=.env tests/e2e/live/scripts/run-live-e2e.mjs\",\n \"test:e2e:mock-llm\": \"playwright test --config=playwright.mock-llm.config.ts\",\n \"test:e2e:mock-llm:docker\": \"playwright test --config=playwright.mock-llm-docker.config.ts\",\n \"test:coverage\": \"npm run make-i18n && vitest run --coverage\",\n \"dev_wsl\": \"VITE_WATCH_USE_POLLING=true vite\",\n \"preview\": \"vite preview\",\n \"make-i18n\": \"node scripts/make-i18n-translations.cjs\",\n \"prelint\": \"npm run make-i18n\",\n \"lint\": \"npm run typecheck && eslint src && prettier --check src/**/*.{ts,tsx}\",\n \"lint:fix\": \"eslint src --fix && prettier --write src/**/*.{ts,tsx}\",\n \"prepare\": \"husky\",\n \"typecheck\": \"react-router typegen && tsc\",\n \"typecheck:staged\": \"react-router typegen && npx tsc --noEmit --skipLibCheck\",\n \"check-translation-completeness\": \"node scripts/check-translation-completeness.cjs\",\n \"build:app\": \"npm run make-i18n && react-router build\",\n \"build:lib\": \"npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true vite build && tsc -p tsconfig.lib.json\",\n \"build:docker\": \"node scripts/docker-build.mjs\",\n \"example:acp-docker:env\": \"node scripts/gen-acp-docker-env.mjs\"\n },\n \"lint-staged\": {\n \"src/**/*.{ts,tsx,js}\": [\n \"eslint --fix\",\n \"prettier --write\"\n ],\n \"src/**/*.{ts,tsx}\": [\n \"node scripts/run-staged-typecheck.mjs\"\n ],\n \"src/**/*\": [\n \"npm run check-translation-completeness\"\n ]\n },\n \"devDependencies\": {\n \"@eslint/eslintrc\": \"3.3.1\",\n \"@eslint/js\": \"9.39.4\",\n \"@mswjs/socket.io-binding\": \"0.2.0\",\n \"@playwright/test\": \"1.59.1\",\n \"@react-router/dev\": \"7.17.0\",\n \"@tailwindcss/typography\": \"0.5.19\",\n \"@tanstack/eslint-plugin-query\": \"5.100.9\",\n \"@testing-library/dom\": \"10.4.1\",\n \"@testing-library/jest-dom\": \"6.9.1\",\n \"@testing-library/react\": \"16.3.2\",\n \"@testing-library/user-event\": \"14.6.1\",\n \"@types/mdast\": \"4.0.4\",\n \"@types/node\": \"25.6.0\",\n \"@types/react\": \"19.2.14\",\n \"@types/react-dom\": \"19.2.3\",\n \"@types/react-syntax-highlighter\": \"15.5.13\",\n \"@typescript-eslint/eslint-plugin\": \"8.59.2\",\n \"@typescript-eslint/parser\": \"8.59.2\",\n \"@vercel/react-router\": \"1.3.0\",\n \"@vitest/coverage-v8\": \"4.1.5\",\n \"cross-env\": \"10.1.0\",\n \"eslint\": \"9.39.4\",\n \"eslint-config-prettier\": \"10.1.8\",\n \"eslint-import-resolver-typescript\": \"4.4.4\",\n \"eslint-plugin-i18next\": \"6.1.4\",\n \"eslint-plugin-import-x\": \"4.16.2\",\n \"eslint-plugin-jsx-a11y\": \"6.10.2\",\n \"eslint-plugin-prettier\": \"5.5.5\",\n \"eslint-plugin-react\": \"7.37.5\",\n \"eslint-plugin-react-hooks\": \"7.1.1\",\n \"eslint-plugin-unused-imports\": \"4.4.1\",\n \"globals\": \"16.5.0\",\n \"husky\": \"9.1.7\",\n \"jsdom\": \"29.1.1\",\n \"lint-staged\": \"16.4.0\",\n \"msw\": \"2.14.2\",\n \"postcss-prefix-selector\": \"2.1.1\",\n \"prettier\": \"3.8.3\",\n \"tailwindcss\": \"4.2.4\",\n \"typescript\": \"6.0.3\",\n \"vite-plugin-svgr\": \"5.2.0\",\n \"vitest\": \"4.1.5\"\n },\n \"packageManager\": \"npm@10.5.0\",\n \"volta\": {\n \"node\": \"22.12.0\"\n },\n \"msw\": {\n \"workerDirectory\": [\n \"public\"\n ]\n },\n \"overrides\": {\n \"@vercel/static-config\": {\n \"ajv\": \"8.20.0\"\n },\n \"dompurify\": \"3.4.7\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"bin\",\n \"build\",\n \"config\",\n \"scripts\",\n \"tools\"\n ],\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./browser\": {\n \"types\": \"./dist/components/browser/index.d.ts\",\n \"import\": \"./dist/components/browser/index.js\",\n \"require\": \"./dist/components/browser/index.cjs\"\n },\n \"./conversation\": {\n \"types\": \"./dist/components/conversation/index.d.ts\",\n \"import\": \"./dist/components/conversation/index.js\",\n \"require\": \"./dist/components/conversation/index.cjs\"\n },\n \"./files\": {\n \"types\": \"./dist/components/files/index.d.ts\",\n \"import\": \"./dist/components/files/index.js\",\n \"require\": \"./dist/components/files/index.cjs\"\n },\n \"./settings\": {\n \"types\": \"./dist/components/settings/index.d.ts\",\n \"import\": \"./dist/components/settings/index.js\",\n \"require\": \"./dist/components/settings/index.cjs\"\n },\n \"./sidebar\": {\n \"types\": \"./dist/components/sidebar/index.d.ts\",\n \"import\": \"./dist/components/sidebar/index.js\",\n \"require\": \"./dist/components/sidebar/index.cjs\"\n },\n \"./terminal\": {\n \"types\": \"./dist/components/terminal/index.d.ts\",\n \"import\": \"./dist/components/terminal/index.js\",\n \"require\": \"./dist/components/terminal/index.cjs\"\n },\n \"./i18n\": {\n \"types\": \"./dist/i18n/index.d.ts\",\n \"import\": \"./dist/i18n/index.js\",\n \"require\": \"./dist/i18n/index.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"peerDependencies\": {\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-router\": \"7.17.0\"\n }\n}\n"],"mappings":""}
|
package/dist/package.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var e = {
|
|
2
2
|
name: "@openhands/agent-canvas",
|
|
3
|
-
version: "1.5.
|
|
3
|
+
version: "1.5.2",
|
|
4
4
|
description: "Agent Canvas UI for OpenHands - run AI coding agents with a visual interface",
|
|
5
5
|
license: "MIT",
|
|
6
6
|
private: !1,
|
|
@@ -92,7 +92,7 @@ var e = {
|
|
|
92
92
|
"typecheck:staged": "react-router typegen && npx tsc --noEmit --skipLibCheck",
|
|
93
93
|
"check-translation-completeness": "node scripts/check-translation-completeness.cjs",
|
|
94
94
|
"build:app": "npm run make-i18n && react-router build",
|
|
95
|
-
"build:lib": "npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true
|
|
95
|
+
"build:lib": "npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true vite build && tsc -p tsconfig.lib.json",
|
|
96
96
|
"build:docker": "node scripts/docker-build.mjs",
|
|
97
97
|
"example:acp-docker:env": "node scripts/gen-acp-docker-env.mjs"
|
|
98
98
|
},
|
package/dist/package.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.js","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.5.
|
|
1
|
+
{"version":3,"file":"package.js","names":[],"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@openhands/agent-canvas\",\n \"version\": \"1.5.2\",\n \"description\": \"Agent Canvas UI for OpenHands - run AI coding agents with a visual interface\",\n \"license\": \"MIT\",\n \"private\": false,\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/OpenHands/agent-canvas\"\n },\n \"homepage\": \"https://github.com/OpenHands/agent-canvas#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/OpenHands/agent-canvas/issues\"\n },\n \"bin\": {\n \"agent-canvas\": \"bin/agent-canvas.mjs\"\n },\n \"engines\": {\n \"node\": \">=22.12.0\"\n },\n \"dependencies\": {\n \"@heroui/react\": \"2.8.10\",\n \"@microlink/react-json-view\": \"1.31.20\",\n \"@monaco-editor/react\": \"4.7.0\",\n \"@openhands/extensions\": \"0.9.0\",\n \"@openhands/typescript-client\": \"1.34.0\",\n \"@react-router/node\": \"7.17.0\",\n \"@react-router/serve\": \"7.17.0\",\n \"@tailwindcss/vite\": \"4.2.4\",\n \"@tanstack/react-query\": \"5.100.9\",\n \"@types/shell-quote\": \"1.7.5\",\n \"@uidotdev/usehooks\": \"2.4.1\",\n \"@xterm/addon-fit\": \"0.11.0\",\n \"@xterm/xterm\": \"6.0.0\",\n \"axios\": \"1.16.0\",\n \"class-variance-authority\": \"0.7.1\",\n \"clsx\": \"2.1.1\",\n \"downshift\": \"9.3.2\",\n \"framer-motion\": \"12.38.0\",\n \"httpxy\": \"0.5.3\",\n \"i18next\": \"26.0.8\",\n \"i18next-browser-languagedetector\": \"8.2.1\",\n \"i18next-http-backend\": \"4.0.0\",\n \"isbot\": \"5.1.39\",\n \"lucide-react\": \"1.14.0\",\n \"monaco-editor\": \"0.55.1\",\n \"posthog-js\": \"1.372.6\",\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-hot-toast\": \"2.6.0\",\n \"react-i18next\": \"17.0.6\",\n \"react-icons\": \"5.6.0\",\n \"react-markdown\": \"10.1.0\",\n \"react-router\": \"7.17.0\",\n \"react-syntax-highlighter\": \"16.1.1\",\n \"rehype-raw\": \"7.0.0\",\n \"rehype-sanitize\": \"6.0.0\",\n \"remark-breaks\": \"4.0.0\",\n \"remark-gfm\": \"4.0.1\",\n \"shell-quote\": \"1.8.4\",\n \"sirv\": \"3.0.2\",\n \"sirv-cli\": \"3.0.1\",\n \"socket.io-client\": \"4.8.3\",\n \"tailwind-merge\": \"3.5.0\",\n \"tailwind-scrollbar\": \"4.0.2\",\n \"unist-util-visit\": \"5.1.0\",\n \"uuid\": \"14.0.0\",\n \"vite\": \"8.0.10\",\n \"winston\": \"3.19.0\",\n \"winston-daily-rotate-file\": \"5.0.0\",\n \"zustand\": \"5.0.12\"\n },\n \"scripts\": {\n \"dev\": \"node --env-file-if-exists=.env scripts/dev-with-automation.mjs\",\n \"dev:static\": \"node --env-file-if-exists=.env scripts/dev-static.mjs\",\n \"dev:extra-backend\": \"node --env-file-if-exists=.env scripts/dev-extra-backend.mjs\",\n \"dev:minimal\": \"node --env-file-if-exists=.env scripts/dev-safe.mjs\",\n \"dev:frontend\": \"npm run make-i18n && cross-env VITE_MOCK_API=false react-router dev\",\n \"dev:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router dev\",\n \"build\": \"npm run build:app\",\n \"build:mock\": \"npm run make-i18n && cross-env VITE_MOCK_API=true react-router build\",\n \"start\": \"npx sirv-cli build/ --single\",\n \"test\": \"npm run make-i18n && vitest run\",\n \"test:e2e\": \"playwright test --pass-with-no-tests\",\n \"test:e2e:live\": \"node --env-file-if-exists=.env tests/e2e/live/scripts/run-live-e2e.mjs\",\n \"test:e2e:mock-llm\": \"playwright test --config=playwright.mock-llm.config.ts\",\n \"test:e2e:mock-llm:docker\": \"playwright test --config=playwright.mock-llm-docker.config.ts\",\n \"test:coverage\": \"npm run make-i18n && vitest run --coverage\",\n \"dev_wsl\": \"VITE_WATCH_USE_POLLING=true vite\",\n \"preview\": \"vite preview\",\n \"make-i18n\": \"node scripts/make-i18n-translations.cjs\",\n \"prelint\": \"npm run make-i18n\",\n \"lint\": \"npm run typecheck && eslint src && prettier --check src/**/*.{ts,tsx}\",\n \"lint:fix\": \"eslint src --fix && prettier --write src/**/*.{ts,tsx}\",\n \"prepare\": \"husky\",\n \"typecheck\": \"react-router typegen && tsc\",\n \"typecheck:staged\": \"react-router typegen && npx tsc --noEmit --skipLibCheck\",\n \"check-translation-completeness\": \"node scripts/check-translation-completeness.cjs\",\n \"build:app\": \"npm run make-i18n && react-router build\",\n \"build:lib\": \"npm run make-i18n && react-router typegen && cross-env BUILD_LIB=true vite build && tsc -p tsconfig.lib.json\",\n \"build:docker\": \"node scripts/docker-build.mjs\",\n \"example:acp-docker:env\": \"node scripts/gen-acp-docker-env.mjs\"\n },\n \"lint-staged\": {\n \"src/**/*.{ts,tsx,js}\": [\n \"eslint --fix\",\n \"prettier --write\"\n ],\n \"src/**/*.{ts,tsx}\": [\n \"node scripts/run-staged-typecheck.mjs\"\n ],\n \"src/**/*\": [\n \"npm run check-translation-completeness\"\n ]\n },\n \"devDependencies\": {\n \"@eslint/eslintrc\": \"3.3.1\",\n \"@eslint/js\": \"9.39.4\",\n \"@mswjs/socket.io-binding\": \"0.2.0\",\n \"@playwright/test\": \"1.59.1\",\n \"@react-router/dev\": \"7.17.0\",\n \"@tailwindcss/typography\": \"0.5.19\",\n \"@tanstack/eslint-plugin-query\": \"5.100.9\",\n \"@testing-library/dom\": \"10.4.1\",\n \"@testing-library/jest-dom\": \"6.9.1\",\n \"@testing-library/react\": \"16.3.2\",\n \"@testing-library/user-event\": \"14.6.1\",\n \"@types/mdast\": \"4.0.4\",\n \"@types/node\": \"25.6.0\",\n \"@types/react\": \"19.2.14\",\n \"@types/react-dom\": \"19.2.3\",\n \"@types/react-syntax-highlighter\": \"15.5.13\",\n \"@typescript-eslint/eslint-plugin\": \"8.59.2\",\n \"@typescript-eslint/parser\": \"8.59.2\",\n \"@vercel/react-router\": \"1.3.0\",\n \"@vitest/coverage-v8\": \"4.1.5\",\n \"cross-env\": \"10.1.0\",\n \"eslint\": \"9.39.4\",\n \"eslint-config-prettier\": \"10.1.8\",\n \"eslint-import-resolver-typescript\": \"4.4.4\",\n \"eslint-plugin-i18next\": \"6.1.4\",\n \"eslint-plugin-import-x\": \"4.16.2\",\n \"eslint-plugin-jsx-a11y\": \"6.10.2\",\n \"eslint-plugin-prettier\": \"5.5.5\",\n \"eslint-plugin-react\": \"7.37.5\",\n \"eslint-plugin-react-hooks\": \"7.1.1\",\n \"eslint-plugin-unused-imports\": \"4.4.1\",\n \"globals\": \"16.5.0\",\n \"husky\": \"9.1.7\",\n \"jsdom\": \"29.1.1\",\n \"lint-staged\": \"16.4.0\",\n \"msw\": \"2.14.2\",\n \"postcss-prefix-selector\": \"2.1.1\",\n \"prettier\": \"3.8.3\",\n \"tailwindcss\": \"4.2.4\",\n \"typescript\": \"6.0.3\",\n \"vite-plugin-svgr\": \"5.2.0\",\n \"vitest\": \"4.1.5\"\n },\n \"packageManager\": \"npm@10.5.0\",\n \"volta\": {\n \"node\": \"22.12.0\"\n },\n \"msw\": {\n \"workerDirectory\": [\n \"public\"\n ]\n },\n \"overrides\": {\n \"@vercel/static-config\": {\n \"ajv\": \"8.20.0\"\n },\n \"dompurify\": \"3.4.7\"\n },\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"bin\",\n \"build\",\n \"config\",\n \"scripts\",\n \"tools\"\n ],\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./browser\": {\n \"types\": \"./dist/components/browser/index.d.ts\",\n \"import\": \"./dist/components/browser/index.js\",\n \"require\": \"./dist/components/browser/index.cjs\"\n },\n \"./conversation\": {\n \"types\": \"./dist/components/conversation/index.d.ts\",\n \"import\": \"./dist/components/conversation/index.js\",\n \"require\": \"./dist/components/conversation/index.cjs\"\n },\n \"./files\": {\n \"types\": \"./dist/components/files/index.d.ts\",\n \"import\": \"./dist/components/files/index.js\",\n \"require\": \"./dist/components/files/index.cjs\"\n },\n \"./settings\": {\n \"types\": \"./dist/components/settings/index.d.ts\",\n \"import\": \"./dist/components/settings/index.js\",\n \"require\": \"./dist/components/settings/index.cjs\"\n },\n \"./sidebar\": {\n \"types\": \"./dist/components/sidebar/index.d.ts\",\n \"import\": \"./dist/components/sidebar/index.js\",\n \"require\": \"./dist/components/sidebar/index.cjs\"\n },\n \"./terminal\": {\n \"types\": \"./dist/components/terminal/index.d.ts\",\n \"import\": \"./dist/components/terminal/index.js\",\n \"require\": \"./dist/components/terminal/index.cjs\"\n },\n \"./i18n\": {\n \"types\": \"./dist/i18n/index.d.ts\",\n \"import\": \"./dist/i18n/index.js\",\n \"require\": \"./dist/i18n/index.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"peerDependencies\": {\n \"react\": \"19.2.5\",\n \"react-dom\": \"19.2.5\",\n \"react-router\": \"7.17.0\"\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../i18n/declaration.cjs`),r=require(`../i18n/index.cjs`),i=require(`../utils/retrieve-axios-error-message.cjs`),a=require(`../utils/custom-toast-handlers.cjs`),o=require(`../
|
|
1
|
+
const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../i18n/declaration.cjs`),r=require(`../i18n/index.cjs`),i=require(`../utils/retrieve-axios-error-message.cjs`),a=require(`../utils/custom-toast-handlers.cjs`),o=require(`../services/telemetry.cjs`),s=require(`../services/settings.cjs`),c=require(`../hooks/query/use-settings.cjs`),l=require(`../components/features/settings/brand-button.cjs`),u=require(`../hooks/mutation/use-save-settings.cjs`),d=require(`../components/features/settings/settings-switch.cjs`),f=require(`../components/features/settings/settings-input.cjs`),p=require(`../components/features/settings/app-settings/language-input.cjs`),m=require(`../components/features/settings/app-settings/theme-input.cjs`),h=require(`../components/features/settings/app-settings/app-settings-inputs-skeleton.cjs`);let g=require(`react`);g=e.__toESM(g,1);let _=require(`react/jsx-runtime`);function v(){let{t:e}=t.useTranslation(`openhands`),{mutate:v,isPending:y}=u.useSaveSettings(),{data:b,isLoading:x}=c.useSettings(),[S,C]=g.default.useState(!1),[w,T]=g.default.useState(!1),[E,D]=g.default.useState(!1),[O,k]=g.default.useState(!1),[A,j]=g.default.useState(!1),M=t=>{let c=t.get(`language-input`)?.toString(),l=r.AvailableLanguages.find(({label:e})=>e===c)?.value||s.DEFAULT_SETTINGS.language,u=t.get(`enable-analytics-switch`)?.toString()===`on`;v({language:l,user_consents_to_analytics:u,enable_sound_notifications:t.get(`enable-sound-notifications-switch`)?.toString()===`on`,git_user_name:t.get(`git-user-name-input`)?.toString()||s.DEFAULT_SETTINGS.git_user_name,git_user_email:t.get(`git-user-email-input`)?.toString()||s.DEFAULT_SETTINGS.git_user_email},{onSuccess:()=>{o.setTelemetryConsent(u?`granted`:`denied`),a.displaySuccessToast(e(n.I18nKey.SETTINGS$SAVED))},onError:t=>{a.displayErrorToast(i.retrieveAxiosErrorMessage(t)||e(n.I18nKey.ERROR$GENERIC))},onSettled:()=>{C(!1),T(!1),D(!1),k(!1),j(!1)}})},N=e=>{let t=r.AvailableLanguages.find(({label:t})=>t===e)?.label,n=r.AvailableLanguages.find(({value:e})=>e===b?.language)?.label;C(t!==n)},P=e=>{T(e!==(b?.user_consents_to_analytics??!0))},F=e=>{D(e!==!!b?.enable_sound_notifications)},I=e=>{let t=b?.git_user_name;k(e!==t)},L=e=>{let t=b?.git_user_email;j(e!==t)},R=!S&&!w&&!E&&!O&&!A,z=!b||x||y;return(0,_.jsxs)(`form`,{"data-testid":`app-settings-screen`,action:M,className:`flex flex-col gap-6`,children:[z&&(0,_.jsx)(h.AppSettingsInputsSkeleton,{}),!z&&(0,_.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,_.jsx)(p.LanguageInput,{name:`language-input`,defaultKey:b.language,onChange:N}),(0,_.jsx)(m.ThemeInput,{}),(0,_.jsx)(d.SettingsSwitch,{testId:`enable-analytics-switch`,name:`enable-analytics-switch`,defaultIsToggled:b.user_consents_to_analytics??!0,onToggle:P,children:e(n.I18nKey.ANALYTICS$SEND_ANONYMOUS_DATA)}),(0,_.jsx)(d.SettingsSwitch,{testId:`enable-sound-notifications-switch`,name:`enable-sound-notifications-switch`,defaultIsToggled:!!b.enable_sound_notifications,onToggle:F,children:e(n.I18nKey.SETTINGS$SOUND_NOTIFICATIONS)}),(0,_.jsxs)(`div`,{className:`border-t border-[var(--oh-border)] pt-6 mt-2`,children:[(0,_.jsx)(`h3`,{className:`text-lg font-medium mb-2`,children:e(n.I18nKey.SETTINGS$GIT_SETTINGS)}),(0,_.jsx)(`p`,{className:`mb-4 text-sm leading-5 text-tertiary-light`,children:e(n.I18nKey.SETTINGS$GIT_SETTINGS_DESCRIPTION)}),(0,_.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,_.jsx)(f.SettingsInput,{testId:`git-user-name-input`,name:`git-user-name-input`,type:`text`,label:e(n.I18nKey.SETTINGS$GIT_USERNAME),defaultValue:b.git_user_name||``,onChange:I,placeholder:e(n.I18nKey.SETTINGS$GIT_USERNAME_PLACEHOLDER),className:`w-full min-w-0`}),(0,_.jsx)(f.SettingsInput,{testId:`git-user-email-input`,name:`git-user-email-input`,type:`email`,label:e(n.I18nKey.SETTINGS$GIT_EMAIL),defaultValue:b.git_user_email||``,onChange:L,placeholder:e(n.I18nKey.SETTINGS$GIT_EMAIL_PLACEHOLDER),className:`w-full min-w-0`})]}),(0,_.jsx)(`div`,{className:`flex justify-start pt-4`,children:(0,_.jsxs)(l.BrandButton,{testId:`submit-button`,variant:`primary`,type:`submit`,isDisabled:y||R,children:[!y&&e(n.I18nKey.SETTINGS$SAVE_CHANGES),y&&e(n.I18nKey.SETTINGS$SAVING)]})})]})]})]})}exports.default=v;
|
|
2
2
|
//# sourceMappingURL=app-settings.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-settings.cjs","names":[],"sources":["../../src/routes/app-settings.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { usePostHog } from \"posthog-js/react\";\nimport { useSaveSettings } from \"#/hooks/mutation/use-save-settings\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { AvailableLanguages } from \"#/i18n\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { setTelemetryConsent } from \"#/services/telemetry\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsSwitch } from \"#/components/features/settings/settings-switch\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { LanguageInput } from \"#/components/features/settings/app-settings/language-input\";\nimport { ThemeInput } from \"#/components/features/settings/app-settings/theme-input\";\nimport { handleCaptureConsent } from \"#/utils/handle-capture-consent\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\nimport { AppSettingsInputsSkeleton } from \"#/components/features/settings/app-settings/app-settings-inputs-skeleton\";\n\nexport function AppSettingsScreen() {\n const posthog = usePostHog();\n const { t } = useTranslation(\"openhands\");\n\n const { mutate: saveSettings, isPending } = useSaveSettings();\n const { data: settings, isLoading } = useSettings();\n\n const [languageInputHasChanged, setLanguageInputHasChanged] =\n React.useState(false);\n const [analyticsSwitchHasChanged, setAnalyticsSwitchHasChanged] =\n React.useState(false);\n const [\n soundNotificationsSwitchHasChanged,\n setSoundNotificationsSwitchHasChanged,\n ] = React.useState(false);\n const [gitUserNameHasChanged, setGitUserNameHasChanged] =\n React.useState(false);\n const [gitUserEmailHasChanged, setGitUserEmailHasChanged] =\n React.useState(false);\n\n const formAction = (formData: FormData) => {\n const languageLabel = formData.get(\"language-input\")?.toString();\n const languageValue = AvailableLanguages.find(\n ({ label }) => label === languageLabel,\n )?.value;\n const language = languageValue || DEFAULT_SETTINGS.language;\n\n const enableAnalytics =\n formData.get(\"enable-analytics-switch\")?.toString() === \"on\";\n const enableSoundNotifications =\n formData.get(\"enable-sound-notifications-switch\")?.toString() === \"on\";\n\n const gitUserName =\n formData.get(\"git-user-name-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_name;\n const gitUserEmail =\n formData.get(\"git-user-email-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_email;\n\n saveSettings(\n {\n language,\n user_consents_to_analytics: enableAnalytics,\n enable_sound_notifications: enableSoundNotifications,\n git_user_name: gitUserName,\n git_user_email: gitUserEmail,\n },\n {\n onSuccess: () => {\n handleCaptureConsent(posthog, enableAnalytics);\n void setTelemetryConsent(enableAnalytics ? \"granted\" : \"denied\");\n displaySuccessToast(t(I18nKey.SETTINGS$SAVED));\n },\n onError: (error) => {\n const errorMessage = retrieveAxiosErrorMessage(error);\n displayErrorToast(errorMessage || t(I18nKey.ERROR$GENERIC));\n },\n onSettled: () => {\n setLanguageInputHasChanged(false);\n setAnalyticsSwitchHasChanged(false);\n setSoundNotificationsSwitchHasChanged(false);\n setGitUserNameHasChanged(false);\n setGitUserEmailHasChanged(false);\n },\n },\n );\n };\n\n const checkIfLanguageInputHasChanged = (value: string) => {\n const selectedLanguage = AvailableLanguages.find(\n ({ label: langValue }) => langValue === value,\n )?.label;\n const currentLanguage = AvailableLanguages.find(\n ({ value: langValue }) => langValue === settings?.language,\n )?.label;\n\n setLanguageInputHasChanged(selectedLanguage !== currentLanguage);\n };\n\n const checkIfAnalyticsSwitchHasChanged = (checked: boolean) => {\n // Treat null as true since analytics is opt-in by default\n const currentAnalytics = settings?.user_consents_to_analytics ?? true;\n setAnalyticsSwitchHasChanged(checked !== currentAnalytics);\n };\n\n const checkIfSoundNotificationsSwitchHasChanged = (checked: boolean) => {\n const currentSoundNotifications = !!settings?.enable_sound_notifications;\n setSoundNotificationsSwitchHasChanged(\n checked !== currentSoundNotifications,\n );\n };\n\n const checkIfGitUserNameHasChanged = (value: string) => {\n const currentValue = settings?.git_user_name;\n setGitUserNameHasChanged(value !== currentValue);\n };\n\n const checkIfGitUserEmailHasChanged = (value: string) => {\n const currentValue = settings?.git_user_email;\n setGitUserEmailHasChanged(value !== currentValue);\n };\n\n const formIsClean =\n !languageInputHasChanged &&\n !analyticsSwitchHasChanged &&\n !soundNotificationsSwitchHasChanged &&\n !gitUserNameHasChanged &&\n !gitUserEmailHasChanged;\n\n const shouldBeLoading = !settings || isLoading || isPending;\n\n return (\n <form\n data-testid=\"app-settings-screen\"\n action={formAction}\n className=\"flex flex-col gap-6\"\n >\n {shouldBeLoading && <AppSettingsInputsSkeleton />}\n {!shouldBeLoading && (\n <div className=\"flex flex-col gap-6\">\n <LanguageInput\n name=\"language-input\"\n defaultKey={settings.language}\n onChange={checkIfLanguageInputHasChanged}\n />\n\n <ThemeInput />\n\n <SettingsSwitch\n testId=\"enable-analytics-switch\"\n name=\"enable-analytics-switch\"\n defaultIsToggled={settings.user_consents_to_analytics ?? true}\n onToggle={checkIfAnalyticsSwitchHasChanged}\n >\n {t(I18nKey.ANALYTICS$SEND_ANONYMOUS_DATA)}\n </SettingsSwitch>\n\n <SettingsSwitch\n testId=\"enable-sound-notifications-switch\"\n name=\"enable-sound-notifications-switch\"\n defaultIsToggled={!!settings.enable_sound_notifications}\n onToggle={checkIfSoundNotificationsSwitchHasChanged}\n >\n {t(I18nKey.SETTINGS$SOUND_NOTIFICATIONS)}\n </SettingsSwitch>\n\n <div className=\"border-t border-[var(--oh-border)] pt-6 mt-2\">\n <h3 className=\"text-lg font-medium mb-2\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS)}\n </h3>\n <p className=\"mb-4 text-sm leading-5 text-tertiary-light\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS_DESCRIPTION)}\n </p>\n <div className=\"flex flex-col gap-6\">\n <SettingsInput\n testId=\"git-user-name-input\"\n name=\"git-user-name-input\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$GIT_USERNAME)}\n defaultValue={settings.git_user_name || \"\"}\n onChange={checkIfGitUserNameHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_USERNAME_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n <SettingsInput\n testId=\"git-user-email-input\"\n name=\"git-user-email-input\"\n type=\"email\"\n label={t(I18nKey.SETTINGS$GIT_EMAIL)}\n defaultValue={settings.git_user_email || \"\"}\n onChange={checkIfGitUserEmailHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_EMAIL_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n </div>\n <div className=\"flex justify-start pt-4\">\n <BrandButton\n testId=\"submit-button\"\n variant=\"primary\"\n type=\"submit\"\n isDisabled={isPending || formIsClean}\n >\n {!isPending && t(I18nKey.SETTINGS$SAVE_CHANGES)}\n {isPending && t(I18nKey.SETTINGS$SAVING)}\n </BrandButton>\n </div>\n </div>\n </div>\n )}\n </form>\n );\n}\n\nexport default AppSettingsScreen;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-settings.cjs","names":[],"sources":["../../src/routes/app-settings.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSaveSettings } from \"#/hooks/mutation/use-save-settings\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { AvailableLanguages } from \"#/i18n\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { setTelemetryConsent } from \"#/services/telemetry\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsSwitch } from \"#/components/features/settings/settings-switch\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { LanguageInput } from \"#/components/features/settings/app-settings/language-input\";\nimport { ThemeInput } from \"#/components/features/settings/app-settings/theme-input\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\nimport { AppSettingsInputsSkeleton } from \"#/components/features/settings/app-settings/app-settings-inputs-skeleton\";\n\nexport function AppSettingsScreen() {\n const { t } = useTranslation(\"openhands\");\n\n const { mutate: saveSettings, isPending } = useSaveSettings();\n const { data: settings, isLoading } = useSettings();\n\n const [languageInputHasChanged, setLanguageInputHasChanged] =\n React.useState(false);\n const [analyticsSwitchHasChanged, setAnalyticsSwitchHasChanged] =\n React.useState(false);\n const [\n soundNotificationsSwitchHasChanged,\n setSoundNotificationsSwitchHasChanged,\n ] = React.useState(false);\n const [gitUserNameHasChanged, setGitUserNameHasChanged] =\n React.useState(false);\n const [gitUserEmailHasChanged, setGitUserEmailHasChanged] =\n React.useState(false);\n\n const formAction = (formData: FormData) => {\n const languageLabel = formData.get(\"language-input\")?.toString();\n const languageValue = AvailableLanguages.find(\n ({ label }) => label === languageLabel,\n )?.value;\n const language = languageValue || DEFAULT_SETTINGS.language;\n\n const enableAnalytics =\n formData.get(\"enable-analytics-switch\")?.toString() === \"on\";\n const enableSoundNotifications =\n formData.get(\"enable-sound-notifications-switch\")?.toString() === \"on\";\n\n const gitUserName =\n formData.get(\"git-user-name-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_name;\n const gitUserEmail =\n formData.get(\"git-user-email-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_email;\n\n saveSettings(\n {\n language,\n user_consents_to_analytics: enableAnalytics,\n enable_sound_notifications: enableSoundNotifications,\n git_user_name: gitUserName,\n git_user_email: gitUserEmail,\n },\n {\n onSuccess: () => {\n void setTelemetryConsent(enableAnalytics ? \"granted\" : \"denied\");\n displaySuccessToast(t(I18nKey.SETTINGS$SAVED));\n },\n onError: (error) => {\n const errorMessage = retrieveAxiosErrorMessage(error);\n displayErrorToast(errorMessage || t(I18nKey.ERROR$GENERIC));\n },\n onSettled: () => {\n setLanguageInputHasChanged(false);\n setAnalyticsSwitchHasChanged(false);\n setSoundNotificationsSwitchHasChanged(false);\n setGitUserNameHasChanged(false);\n setGitUserEmailHasChanged(false);\n },\n },\n );\n };\n\n const checkIfLanguageInputHasChanged = (value: string) => {\n const selectedLanguage = AvailableLanguages.find(\n ({ label: langValue }) => langValue === value,\n )?.label;\n const currentLanguage = AvailableLanguages.find(\n ({ value: langValue }) => langValue === settings?.language,\n )?.label;\n\n setLanguageInputHasChanged(selectedLanguage !== currentLanguage);\n };\n\n const checkIfAnalyticsSwitchHasChanged = (checked: boolean) => {\n // Treat null as true since analytics is opt-in by default\n const currentAnalytics = settings?.user_consents_to_analytics ?? true;\n setAnalyticsSwitchHasChanged(checked !== currentAnalytics);\n };\n\n const checkIfSoundNotificationsSwitchHasChanged = (checked: boolean) => {\n const currentSoundNotifications = !!settings?.enable_sound_notifications;\n setSoundNotificationsSwitchHasChanged(\n checked !== currentSoundNotifications,\n );\n };\n\n const checkIfGitUserNameHasChanged = (value: string) => {\n const currentValue = settings?.git_user_name;\n setGitUserNameHasChanged(value !== currentValue);\n };\n\n const checkIfGitUserEmailHasChanged = (value: string) => {\n const currentValue = settings?.git_user_email;\n setGitUserEmailHasChanged(value !== currentValue);\n };\n\n const formIsClean =\n !languageInputHasChanged &&\n !analyticsSwitchHasChanged &&\n !soundNotificationsSwitchHasChanged &&\n !gitUserNameHasChanged &&\n !gitUserEmailHasChanged;\n\n const shouldBeLoading = !settings || isLoading || isPending;\n\n return (\n <form\n data-testid=\"app-settings-screen\"\n action={formAction}\n className=\"flex flex-col gap-6\"\n >\n {shouldBeLoading && <AppSettingsInputsSkeleton />}\n {!shouldBeLoading && (\n <div className=\"flex flex-col gap-6\">\n <LanguageInput\n name=\"language-input\"\n defaultKey={settings.language}\n onChange={checkIfLanguageInputHasChanged}\n />\n\n <ThemeInput />\n\n <SettingsSwitch\n testId=\"enable-analytics-switch\"\n name=\"enable-analytics-switch\"\n defaultIsToggled={settings.user_consents_to_analytics ?? true}\n onToggle={checkIfAnalyticsSwitchHasChanged}\n >\n {t(I18nKey.ANALYTICS$SEND_ANONYMOUS_DATA)}\n </SettingsSwitch>\n\n <SettingsSwitch\n testId=\"enable-sound-notifications-switch\"\n name=\"enable-sound-notifications-switch\"\n defaultIsToggled={!!settings.enable_sound_notifications}\n onToggle={checkIfSoundNotificationsSwitchHasChanged}\n >\n {t(I18nKey.SETTINGS$SOUND_NOTIFICATIONS)}\n </SettingsSwitch>\n\n <div className=\"border-t border-[var(--oh-border)] pt-6 mt-2\">\n <h3 className=\"text-lg font-medium mb-2\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS)}\n </h3>\n <p className=\"mb-4 text-sm leading-5 text-tertiary-light\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS_DESCRIPTION)}\n </p>\n <div className=\"flex flex-col gap-6\">\n <SettingsInput\n testId=\"git-user-name-input\"\n name=\"git-user-name-input\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$GIT_USERNAME)}\n defaultValue={settings.git_user_name || \"\"}\n onChange={checkIfGitUserNameHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_USERNAME_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n <SettingsInput\n testId=\"git-user-email-input\"\n name=\"git-user-email-input\"\n type=\"email\"\n label={t(I18nKey.SETTINGS$GIT_EMAIL)}\n defaultValue={settings.git_user_email || \"\"}\n onChange={checkIfGitUserEmailHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_EMAIL_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n </div>\n <div className=\"flex justify-start pt-4\">\n <BrandButton\n testId=\"submit-button\"\n variant=\"primary\"\n type=\"submit\"\n isDisabled={isPending || formIsClean}\n >\n {!isPending && t(I18nKey.SETTINGS$SAVE_CHANGES)}\n {isPending && t(I18nKey.SETTINGS$SAVING)}\n </BrandButton>\n </div>\n </div>\n </div>\n )}\n </form>\n );\n}\n\nexport default AppSettingsScreen;\n"],"mappings":"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"}
|
|
@@ -3,25 +3,23 @@ import { I18nKey as t } from "../i18n/declaration.js";
|
|
|
3
3
|
import { AvailableLanguages as n } from "../i18n/index.js";
|
|
4
4
|
import { retrieveAxiosErrorMessage as r } from "../utils/retrieve-axios-error-message.js";
|
|
5
5
|
import { displayErrorToast as i, displaySuccessToast as a } from "../utils/custom-toast-handlers.js";
|
|
6
|
-
import {
|
|
6
|
+
import { setTelemetryConsent as o } from "../services/telemetry.js";
|
|
7
7
|
import { DEFAULT_SETTINGS as s } from "../services/settings.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import v from "react";
|
|
19
|
-
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
8
|
+
import { useSettings as c } from "../hooks/query/use-settings.js";
|
|
9
|
+
import { BrandButton as l } from "../components/features/settings/brand-button.js";
|
|
10
|
+
import { useSaveSettings as u } from "../hooks/mutation/use-save-settings.js";
|
|
11
|
+
import { SettingsSwitch as d } from "../components/features/settings/settings-switch.js";
|
|
12
|
+
import { SettingsInput as f } from "../components/features/settings/settings-input.js";
|
|
13
|
+
import { LanguageInput as p } from "../components/features/settings/app-settings/language-input.js";
|
|
14
|
+
import { ThemeInput as m } from "../components/features/settings/app-settings/theme-input.js";
|
|
15
|
+
import { AppSettingsInputsSkeleton as h } from "../components/features/settings/app-settings/app-settings-inputs-skeleton.js";
|
|
16
|
+
import g from "react";
|
|
17
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
20
18
|
//#region src/routes/app-settings.tsx
|
|
21
|
-
function
|
|
22
|
-
let
|
|
23
|
-
let
|
|
24
|
-
|
|
19
|
+
function y() {
|
|
20
|
+
let { t: y } = e("openhands"), { mutate: b, isPending: x } = u(), { data: S, isLoading: C } = c(), [w, T] = g.useState(!1), [E, D] = g.useState(!1), [O, k] = g.useState(!1), [A, j] = g.useState(!1), [M, N] = g.useState(!1), P = (e) => {
|
|
21
|
+
let c = e.get("language-input")?.toString(), l = n.find(({ label: e }) => e === c)?.value || s.language, u = e.get("enable-analytics-switch")?.toString() === "on";
|
|
22
|
+
b({
|
|
25
23
|
language: l,
|
|
26
24
|
user_consents_to_analytics: u,
|
|
27
25
|
enable_sound_notifications: e.get("enable-sound-notifications-switch")?.toString() === "on",
|
|
@@ -29,97 +27,97 @@ function x() {
|
|
|
29
27
|
git_user_email: e.get("git-user-email-input")?.toString() || s.git_user_email
|
|
30
28
|
}, {
|
|
31
29
|
onSuccess: () => {
|
|
32
|
-
|
|
30
|
+
o(u ? "granted" : "denied"), a(y(t.SETTINGS$SAVED));
|
|
33
31
|
},
|
|
34
32
|
onError: (e) => {
|
|
35
|
-
i(r(e) ||
|
|
33
|
+
i(r(e) || y(t.ERROR$GENERIC));
|
|
36
34
|
},
|
|
37
35
|
onSettled: () => {
|
|
38
|
-
|
|
36
|
+
T(!1), D(!1), k(!1), j(!1), N(!1);
|
|
39
37
|
}
|
|
40
38
|
});
|
|
39
|
+
}, F = (e) => {
|
|
40
|
+
let t = n.find(({ label: t }) => t === e)?.label, r = n.find(({ value: e }) => e === S?.language)?.label;
|
|
41
|
+
T(t !== r);
|
|
42
|
+
}, I = (e) => {
|
|
43
|
+
D(e !== (S?.user_consents_to_analytics ?? !0));
|
|
44
|
+
}, L = (e) => {
|
|
45
|
+
k(e !== !!S?.enable_sound_notifications);
|
|
41
46
|
}, R = (e) => {
|
|
42
|
-
let t =
|
|
43
|
-
|
|
47
|
+
let t = S?.git_user_name;
|
|
48
|
+
j(e !== t);
|
|
44
49
|
}, z = (e) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
let t = T?.git_user_name;
|
|
50
|
-
P(e !== t);
|
|
51
|
-
}, H = (e) => {
|
|
52
|
-
let t = T?.git_user_email;
|
|
53
|
-
I(e !== t);
|
|
54
|
-
}, U = !D && !k && !j && !N && !F, W = !T || E || w;
|
|
55
|
-
return /* @__PURE__ */ b("form", {
|
|
50
|
+
let t = S?.git_user_email;
|
|
51
|
+
N(e !== t);
|
|
52
|
+
}, B = !w && !E && !O && !A && !M, V = !S || C || x;
|
|
53
|
+
return /* @__PURE__ */ v("form", {
|
|
56
54
|
"data-testid": "app-settings-screen",
|
|
57
|
-
action:
|
|
55
|
+
action: P,
|
|
58
56
|
className: "flex flex-col gap-6",
|
|
59
|
-
children: [
|
|
57
|
+
children: [V && /* @__PURE__ */ _(h, {}), !V && /* @__PURE__ */ v("div", {
|
|
60
58
|
className: "flex flex-col gap-6",
|
|
61
59
|
children: [
|
|
62
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ _(p, {
|
|
63
61
|
name: "language-input",
|
|
64
|
-
defaultKey:
|
|
65
|
-
onChange:
|
|
62
|
+
defaultKey: S.language,
|
|
63
|
+
onChange: F
|
|
66
64
|
}),
|
|
67
|
-
/* @__PURE__ */
|
|
68
|
-
/* @__PURE__ */
|
|
65
|
+
/* @__PURE__ */ _(m, {}),
|
|
66
|
+
/* @__PURE__ */ _(d, {
|
|
69
67
|
testId: "enable-analytics-switch",
|
|
70
68
|
name: "enable-analytics-switch",
|
|
71
|
-
defaultIsToggled:
|
|
72
|
-
onToggle:
|
|
73
|
-
children:
|
|
69
|
+
defaultIsToggled: S.user_consents_to_analytics ?? !0,
|
|
70
|
+
onToggle: I,
|
|
71
|
+
children: y(t.ANALYTICS$SEND_ANONYMOUS_DATA)
|
|
74
72
|
}),
|
|
75
|
-
/* @__PURE__ */
|
|
73
|
+
/* @__PURE__ */ _(d, {
|
|
76
74
|
testId: "enable-sound-notifications-switch",
|
|
77
75
|
name: "enable-sound-notifications-switch",
|
|
78
|
-
defaultIsToggled: !!
|
|
79
|
-
onToggle:
|
|
80
|
-
children:
|
|
76
|
+
defaultIsToggled: !!S.enable_sound_notifications,
|
|
77
|
+
onToggle: L,
|
|
78
|
+
children: y(t.SETTINGS$SOUND_NOTIFICATIONS)
|
|
81
79
|
}),
|
|
82
|
-
/* @__PURE__ */
|
|
80
|
+
/* @__PURE__ */ v("div", {
|
|
83
81
|
className: "border-t border-[var(--oh-border)] pt-6 mt-2",
|
|
84
82
|
children: [
|
|
85
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ _("h3", {
|
|
86
84
|
className: "text-lg font-medium mb-2",
|
|
87
|
-
children:
|
|
85
|
+
children: y(t.SETTINGS$GIT_SETTINGS)
|
|
88
86
|
}),
|
|
89
|
-
/* @__PURE__ */
|
|
87
|
+
/* @__PURE__ */ _("p", {
|
|
90
88
|
className: "mb-4 text-sm leading-5 text-tertiary-light",
|
|
91
|
-
children:
|
|
89
|
+
children: y(t.SETTINGS$GIT_SETTINGS_DESCRIPTION)
|
|
92
90
|
}),
|
|
93
|
-
/* @__PURE__ */
|
|
91
|
+
/* @__PURE__ */ v("div", {
|
|
94
92
|
className: "flex flex-col gap-6",
|
|
95
|
-
children: [/* @__PURE__ */
|
|
93
|
+
children: [/* @__PURE__ */ _(f, {
|
|
96
94
|
testId: "git-user-name-input",
|
|
97
95
|
name: "git-user-name-input",
|
|
98
96
|
type: "text",
|
|
99
|
-
label:
|
|
100
|
-
defaultValue:
|
|
101
|
-
onChange:
|
|
102
|
-
placeholder:
|
|
97
|
+
label: y(t.SETTINGS$GIT_USERNAME),
|
|
98
|
+
defaultValue: S.git_user_name || "",
|
|
99
|
+
onChange: R,
|
|
100
|
+
placeholder: y(t.SETTINGS$GIT_USERNAME_PLACEHOLDER),
|
|
103
101
|
className: "w-full min-w-0"
|
|
104
|
-
}), /* @__PURE__ */
|
|
102
|
+
}), /* @__PURE__ */ _(f, {
|
|
105
103
|
testId: "git-user-email-input",
|
|
106
104
|
name: "git-user-email-input",
|
|
107
105
|
type: "email",
|
|
108
|
-
label:
|
|
109
|
-
defaultValue:
|
|
110
|
-
onChange:
|
|
111
|
-
placeholder:
|
|
106
|
+
label: y(t.SETTINGS$GIT_EMAIL),
|
|
107
|
+
defaultValue: S.git_user_email || "",
|
|
108
|
+
onChange: z,
|
|
109
|
+
placeholder: y(t.SETTINGS$GIT_EMAIL_PLACEHOLDER),
|
|
112
110
|
className: "w-full min-w-0"
|
|
113
111
|
})]
|
|
114
112
|
}),
|
|
115
|
-
/* @__PURE__ */
|
|
113
|
+
/* @__PURE__ */ _("div", {
|
|
116
114
|
className: "flex justify-start pt-4",
|
|
117
|
-
children: /* @__PURE__ */
|
|
115
|
+
children: /* @__PURE__ */ v(l, {
|
|
118
116
|
testId: "submit-button",
|
|
119
117
|
variant: "primary",
|
|
120
118
|
type: "submit",
|
|
121
|
-
isDisabled:
|
|
122
|
-
children: [!
|
|
119
|
+
isDisabled: x || B,
|
|
120
|
+
children: [!x && y(t.SETTINGS$SAVE_CHANGES), x && y(t.SETTINGS$SAVING)]
|
|
123
121
|
})
|
|
124
122
|
})
|
|
125
123
|
]
|
|
@@ -129,6 +127,6 @@ function x() {
|
|
|
129
127
|
});
|
|
130
128
|
}
|
|
131
129
|
//#endregion
|
|
132
|
-
export {
|
|
130
|
+
export { y as default };
|
|
133
131
|
|
|
134
132
|
//# sourceMappingURL=app-settings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-settings.js","names":[],"sources":["../../src/routes/app-settings.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { usePostHog } from \"posthog-js/react\";\nimport { useSaveSettings } from \"#/hooks/mutation/use-save-settings\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { AvailableLanguages } from \"#/i18n\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { setTelemetryConsent } from \"#/services/telemetry\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsSwitch } from \"#/components/features/settings/settings-switch\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { LanguageInput } from \"#/components/features/settings/app-settings/language-input\";\nimport { ThemeInput } from \"#/components/features/settings/app-settings/theme-input\";\nimport { handleCaptureConsent } from \"#/utils/handle-capture-consent\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\nimport { AppSettingsInputsSkeleton } from \"#/components/features/settings/app-settings/app-settings-inputs-skeleton\";\n\nexport function AppSettingsScreen() {\n const posthog = usePostHog();\n const { t } = useTranslation(\"openhands\");\n\n const { mutate: saveSettings, isPending } = useSaveSettings();\n const { data: settings, isLoading } = useSettings();\n\n const [languageInputHasChanged, setLanguageInputHasChanged] =\n React.useState(false);\n const [analyticsSwitchHasChanged, setAnalyticsSwitchHasChanged] =\n React.useState(false);\n const [\n soundNotificationsSwitchHasChanged,\n setSoundNotificationsSwitchHasChanged,\n ] = React.useState(false);\n const [gitUserNameHasChanged, setGitUserNameHasChanged] =\n React.useState(false);\n const [gitUserEmailHasChanged, setGitUserEmailHasChanged] =\n React.useState(false);\n\n const formAction = (formData: FormData) => {\n const languageLabel = formData.get(\"language-input\")?.toString();\n const languageValue = AvailableLanguages.find(\n ({ label }) => label === languageLabel,\n )?.value;\n const language = languageValue || DEFAULT_SETTINGS.language;\n\n const enableAnalytics =\n formData.get(\"enable-analytics-switch\")?.toString() === \"on\";\n const enableSoundNotifications =\n formData.get(\"enable-sound-notifications-switch\")?.toString() === \"on\";\n\n const gitUserName =\n formData.get(\"git-user-name-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_name;\n const gitUserEmail =\n formData.get(\"git-user-email-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_email;\n\n saveSettings(\n {\n language,\n user_consents_to_analytics: enableAnalytics,\n enable_sound_notifications: enableSoundNotifications,\n git_user_name: gitUserName,\n git_user_email: gitUserEmail,\n },\n {\n onSuccess: () => {\n handleCaptureConsent(posthog, enableAnalytics);\n void setTelemetryConsent(enableAnalytics ? \"granted\" : \"denied\");\n displaySuccessToast(t(I18nKey.SETTINGS$SAVED));\n },\n onError: (error) => {\n const errorMessage = retrieveAxiosErrorMessage(error);\n displayErrorToast(errorMessage || t(I18nKey.ERROR$GENERIC));\n },\n onSettled: () => {\n setLanguageInputHasChanged(false);\n setAnalyticsSwitchHasChanged(false);\n setSoundNotificationsSwitchHasChanged(false);\n setGitUserNameHasChanged(false);\n setGitUserEmailHasChanged(false);\n },\n },\n );\n };\n\n const checkIfLanguageInputHasChanged = (value: string) => {\n const selectedLanguage = AvailableLanguages.find(\n ({ label: langValue }) => langValue === value,\n )?.label;\n const currentLanguage = AvailableLanguages.find(\n ({ value: langValue }) => langValue === settings?.language,\n )?.label;\n\n setLanguageInputHasChanged(selectedLanguage !== currentLanguage);\n };\n\n const checkIfAnalyticsSwitchHasChanged = (checked: boolean) => {\n // Treat null as true since analytics is opt-in by default\n const currentAnalytics = settings?.user_consents_to_analytics ?? true;\n setAnalyticsSwitchHasChanged(checked !== currentAnalytics);\n };\n\n const checkIfSoundNotificationsSwitchHasChanged = (checked: boolean) => {\n const currentSoundNotifications = !!settings?.enable_sound_notifications;\n setSoundNotificationsSwitchHasChanged(\n checked !== currentSoundNotifications,\n );\n };\n\n const checkIfGitUserNameHasChanged = (value: string) => {\n const currentValue = settings?.git_user_name;\n setGitUserNameHasChanged(value !== currentValue);\n };\n\n const checkIfGitUserEmailHasChanged = (value: string) => {\n const currentValue = settings?.git_user_email;\n setGitUserEmailHasChanged(value !== currentValue);\n };\n\n const formIsClean =\n !languageInputHasChanged &&\n !analyticsSwitchHasChanged &&\n !soundNotificationsSwitchHasChanged &&\n !gitUserNameHasChanged &&\n !gitUserEmailHasChanged;\n\n const shouldBeLoading = !settings || isLoading || isPending;\n\n return (\n <form\n data-testid=\"app-settings-screen\"\n action={formAction}\n className=\"flex flex-col gap-6\"\n >\n {shouldBeLoading && <AppSettingsInputsSkeleton />}\n {!shouldBeLoading && (\n <div className=\"flex flex-col gap-6\">\n <LanguageInput\n name=\"language-input\"\n defaultKey={settings.language}\n onChange={checkIfLanguageInputHasChanged}\n />\n\n <ThemeInput />\n\n <SettingsSwitch\n testId=\"enable-analytics-switch\"\n name=\"enable-analytics-switch\"\n defaultIsToggled={settings.user_consents_to_analytics ?? true}\n onToggle={checkIfAnalyticsSwitchHasChanged}\n >\n {t(I18nKey.ANALYTICS$SEND_ANONYMOUS_DATA)}\n </SettingsSwitch>\n\n <SettingsSwitch\n testId=\"enable-sound-notifications-switch\"\n name=\"enable-sound-notifications-switch\"\n defaultIsToggled={!!settings.enable_sound_notifications}\n onToggle={checkIfSoundNotificationsSwitchHasChanged}\n >\n {t(I18nKey.SETTINGS$SOUND_NOTIFICATIONS)}\n </SettingsSwitch>\n\n <div className=\"border-t border-[var(--oh-border)] pt-6 mt-2\">\n <h3 className=\"text-lg font-medium mb-2\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS)}\n </h3>\n <p className=\"mb-4 text-sm leading-5 text-tertiary-light\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS_DESCRIPTION)}\n </p>\n <div className=\"flex flex-col gap-6\">\n <SettingsInput\n testId=\"git-user-name-input\"\n name=\"git-user-name-input\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$GIT_USERNAME)}\n defaultValue={settings.git_user_name || \"\"}\n onChange={checkIfGitUserNameHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_USERNAME_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n <SettingsInput\n testId=\"git-user-email-input\"\n name=\"git-user-email-input\"\n type=\"email\"\n label={t(I18nKey.SETTINGS$GIT_EMAIL)}\n defaultValue={settings.git_user_email || \"\"}\n onChange={checkIfGitUserEmailHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_EMAIL_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n </div>\n <div className=\"flex justify-start pt-4\">\n <BrandButton\n testId=\"submit-button\"\n variant=\"primary\"\n type=\"submit\"\n isDisabled={isPending || formIsClean}\n >\n {!isPending && t(I18nKey.SETTINGS$SAVE_CHANGES)}\n {isPending && t(I18nKey.SETTINGS$SAVING)}\n </BrandButton>\n </div>\n </div>\n </div>\n )}\n </form>\n );\n}\n\nexport default AppSettingsScreen;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-settings.js","names":[],"sources":["../../src/routes/app-settings.tsx"],"sourcesContent":["import React from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useSaveSettings } from \"#/hooks/mutation/use-save-settings\";\nimport { useSettings } from \"#/hooks/query/use-settings\";\nimport { AvailableLanguages } from \"#/i18n\";\nimport { DEFAULT_SETTINGS } from \"#/services/settings\";\nimport { setTelemetryConsent } from \"#/services/telemetry\";\nimport { BrandButton } from \"#/components/features/settings/brand-button\";\nimport { SettingsSwitch } from \"#/components/features/settings/settings-switch\";\nimport { SettingsInput } from \"#/components/features/settings/settings-input\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { LanguageInput } from \"#/components/features/settings/app-settings/language-input\";\nimport { ThemeInput } from \"#/components/features/settings/app-settings/theme-input\";\nimport {\n displayErrorToast,\n displaySuccessToast,\n} from \"#/utils/custom-toast-handlers\";\nimport { retrieveAxiosErrorMessage } from \"#/utils/retrieve-axios-error-message\";\nimport { AppSettingsInputsSkeleton } from \"#/components/features/settings/app-settings/app-settings-inputs-skeleton\";\n\nexport function AppSettingsScreen() {\n const { t } = useTranslation(\"openhands\");\n\n const { mutate: saveSettings, isPending } = useSaveSettings();\n const { data: settings, isLoading } = useSettings();\n\n const [languageInputHasChanged, setLanguageInputHasChanged] =\n React.useState(false);\n const [analyticsSwitchHasChanged, setAnalyticsSwitchHasChanged] =\n React.useState(false);\n const [\n soundNotificationsSwitchHasChanged,\n setSoundNotificationsSwitchHasChanged,\n ] = React.useState(false);\n const [gitUserNameHasChanged, setGitUserNameHasChanged] =\n React.useState(false);\n const [gitUserEmailHasChanged, setGitUserEmailHasChanged] =\n React.useState(false);\n\n const formAction = (formData: FormData) => {\n const languageLabel = formData.get(\"language-input\")?.toString();\n const languageValue = AvailableLanguages.find(\n ({ label }) => label === languageLabel,\n )?.value;\n const language = languageValue || DEFAULT_SETTINGS.language;\n\n const enableAnalytics =\n formData.get(\"enable-analytics-switch\")?.toString() === \"on\";\n const enableSoundNotifications =\n formData.get(\"enable-sound-notifications-switch\")?.toString() === \"on\";\n\n const gitUserName =\n formData.get(\"git-user-name-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_name;\n const gitUserEmail =\n formData.get(\"git-user-email-input\")?.toString() ||\n DEFAULT_SETTINGS.git_user_email;\n\n saveSettings(\n {\n language,\n user_consents_to_analytics: enableAnalytics,\n enable_sound_notifications: enableSoundNotifications,\n git_user_name: gitUserName,\n git_user_email: gitUserEmail,\n },\n {\n onSuccess: () => {\n void setTelemetryConsent(enableAnalytics ? \"granted\" : \"denied\");\n displaySuccessToast(t(I18nKey.SETTINGS$SAVED));\n },\n onError: (error) => {\n const errorMessage = retrieveAxiosErrorMessage(error);\n displayErrorToast(errorMessage || t(I18nKey.ERROR$GENERIC));\n },\n onSettled: () => {\n setLanguageInputHasChanged(false);\n setAnalyticsSwitchHasChanged(false);\n setSoundNotificationsSwitchHasChanged(false);\n setGitUserNameHasChanged(false);\n setGitUserEmailHasChanged(false);\n },\n },\n );\n };\n\n const checkIfLanguageInputHasChanged = (value: string) => {\n const selectedLanguage = AvailableLanguages.find(\n ({ label: langValue }) => langValue === value,\n )?.label;\n const currentLanguage = AvailableLanguages.find(\n ({ value: langValue }) => langValue === settings?.language,\n )?.label;\n\n setLanguageInputHasChanged(selectedLanguage !== currentLanguage);\n };\n\n const checkIfAnalyticsSwitchHasChanged = (checked: boolean) => {\n // Treat null as true since analytics is opt-in by default\n const currentAnalytics = settings?.user_consents_to_analytics ?? true;\n setAnalyticsSwitchHasChanged(checked !== currentAnalytics);\n };\n\n const checkIfSoundNotificationsSwitchHasChanged = (checked: boolean) => {\n const currentSoundNotifications = !!settings?.enable_sound_notifications;\n setSoundNotificationsSwitchHasChanged(\n checked !== currentSoundNotifications,\n );\n };\n\n const checkIfGitUserNameHasChanged = (value: string) => {\n const currentValue = settings?.git_user_name;\n setGitUserNameHasChanged(value !== currentValue);\n };\n\n const checkIfGitUserEmailHasChanged = (value: string) => {\n const currentValue = settings?.git_user_email;\n setGitUserEmailHasChanged(value !== currentValue);\n };\n\n const formIsClean =\n !languageInputHasChanged &&\n !analyticsSwitchHasChanged &&\n !soundNotificationsSwitchHasChanged &&\n !gitUserNameHasChanged &&\n !gitUserEmailHasChanged;\n\n const shouldBeLoading = !settings || isLoading || isPending;\n\n return (\n <form\n data-testid=\"app-settings-screen\"\n action={formAction}\n className=\"flex flex-col gap-6\"\n >\n {shouldBeLoading && <AppSettingsInputsSkeleton />}\n {!shouldBeLoading && (\n <div className=\"flex flex-col gap-6\">\n <LanguageInput\n name=\"language-input\"\n defaultKey={settings.language}\n onChange={checkIfLanguageInputHasChanged}\n />\n\n <ThemeInput />\n\n <SettingsSwitch\n testId=\"enable-analytics-switch\"\n name=\"enable-analytics-switch\"\n defaultIsToggled={settings.user_consents_to_analytics ?? true}\n onToggle={checkIfAnalyticsSwitchHasChanged}\n >\n {t(I18nKey.ANALYTICS$SEND_ANONYMOUS_DATA)}\n </SettingsSwitch>\n\n <SettingsSwitch\n testId=\"enable-sound-notifications-switch\"\n name=\"enable-sound-notifications-switch\"\n defaultIsToggled={!!settings.enable_sound_notifications}\n onToggle={checkIfSoundNotificationsSwitchHasChanged}\n >\n {t(I18nKey.SETTINGS$SOUND_NOTIFICATIONS)}\n </SettingsSwitch>\n\n <div className=\"border-t border-[var(--oh-border)] pt-6 mt-2\">\n <h3 className=\"text-lg font-medium mb-2\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS)}\n </h3>\n <p className=\"mb-4 text-sm leading-5 text-tertiary-light\">\n {t(I18nKey.SETTINGS$GIT_SETTINGS_DESCRIPTION)}\n </p>\n <div className=\"flex flex-col gap-6\">\n <SettingsInput\n testId=\"git-user-name-input\"\n name=\"git-user-name-input\"\n type=\"text\"\n label={t(I18nKey.SETTINGS$GIT_USERNAME)}\n defaultValue={settings.git_user_name || \"\"}\n onChange={checkIfGitUserNameHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_USERNAME_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n <SettingsInput\n testId=\"git-user-email-input\"\n name=\"git-user-email-input\"\n type=\"email\"\n label={t(I18nKey.SETTINGS$GIT_EMAIL)}\n defaultValue={settings.git_user_email || \"\"}\n onChange={checkIfGitUserEmailHasChanged}\n placeholder={t(I18nKey.SETTINGS$GIT_EMAIL_PLACEHOLDER)}\n className=\"w-full min-w-0\"\n />\n </div>\n <div className=\"flex justify-start pt-4\">\n <BrandButton\n testId=\"submit-button\"\n variant=\"primary\"\n type=\"submit\"\n isDisabled={isPending || formIsClean}\n >\n {!isPending && t(I18nKey.SETTINGS$SAVE_CHANGES)}\n {isPending && t(I18nKey.SETTINGS$SAVING)}\n </BrandButton>\n </div>\n </div>\n </div>\n )}\n </form>\n );\n}\n\nexport default AppSettingsScreen;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../i18n/declaration.cjs`),r=require(`../types/agent-state.cjs`),i=require(`../hooks/use-conversation-id.cjs`),a=require(`../stores/command-store.cjs`),o=require(`../stores/conversation-store.cjs`),s=require(`../stores/agent-store.cjs`),c=require(`../stores/conversation-state-store.cjs`),l=require(`../utils/custom-toast-handlers.cjs`),u=require(`../contexts/active-backend-context.cjs`),d=require(`../api/backend-registry/last-conversation-store.cjs`),f=require(`../stores/error-message-store.cjs`),p=require(`../api/cloud/conversation-service.api.cjs`),m=require(`../hooks/query/use-active-conversation.cjs`),h=require(`../wrapper/event-handler.cjs`),g=require(`../hooks/query/use-task-polling.cjs`),_=require(`../hooks/query/use-is-authed.cjs`),v=require(`../components/features/conversation/conversation-main/conversation-main.cjs`),y=require(`../components/features/conversation/conversation-main/conversation-mobile-panel-page.cjs`),b=require(`../contexts/websocket-provider-wrapper.cjs`);let x=require(`react`);x=e.__toESM(x,1);let S=require(`react/jsx-runtime`),C=require(`react-router`);function w(){let{t:e}=t.useTranslation(`openhands`),{conversationId:w}=i.useConversationId(),T=(0,C.useMatch)(`/conversations/:conversationId/panel`),{isTask:E,taskStatus:D,taskDetail:O}=g.
|
|
1
|
+
const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../node_modules/react-i18next/dist/es/useTranslation.cjs`),n=require(`../i18n/declaration.cjs`),r=require(`../types/agent-state.cjs`),i=require(`../hooks/use-conversation-id.cjs`),a=require(`../stores/command-store.cjs`),o=require(`../stores/conversation-store.cjs`),s=require(`../stores/agent-store.cjs`),c=require(`../stores/conversation-state-store.cjs`),l=require(`../utils/custom-toast-handlers.cjs`),u=require(`../contexts/active-backend-context.cjs`),d=require(`../api/backend-registry/last-conversation-store.cjs`),f=require(`../stores/error-message-store.cjs`),p=require(`../api/cloud/conversation-service.api.cjs`),m=require(`../hooks/query/use-active-conversation.cjs`),h=require(`../wrapper/event-handler.cjs`),g=require(`../hooks/query/use-task-polling.cjs`),_=require(`../hooks/query/use-is-authed.cjs`),v=require(`../components/features/conversation/conversation-main/conversation-main.cjs`),y=require(`../components/features/conversation/conversation-main/conversation-mobile-panel-page.cjs`),b=require(`../contexts/websocket-provider-wrapper.cjs`);let x=require(`react`);x=e.__toESM(x,1);let S=require(`react/jsx-runtime`),C=require(`react-router`);function w(){let{t:e}=t.useTranslation(`openhands`),{conversationId:w}=i.useConversationId(),T=(0,C.useMatch)(`/conversations/:conversationId/panel`),{isTask:E,taskStatus:D,taskDetail:O}=g.useTaskPollingController(),k=u.useActiveBackend(),A=x.default.useRef(k.backend.id),j=x.default.useRef(k.orgId),M=A.current!==k.backend.id||j.current!==k.orgId,{data:N,isFetched:P}=m.useActiveConversation(),{data:F}=_.useIsAuthed(),{resetConversationState:I}=o.useConversationStore(),L=(0,C.useNavigate)(),R=(0,C.useLocation)(),z=a.useCommandStore(e=>e.clearTerminal),B=c.useConversationStateStore(e=>e.reset),V=s.useAgentStore(e=>e.setCurrentAgentState),H=f.useErrorMessageStore(e=>e.removeErrorMessage);x.default.useEffect(()=>{z(),I(),B(),V(r.AgentState.LOADING),H()},[w,z,I,B,V,H]),x.default.useEffect(()=>{if(E&&D===`ERROR`){l.displayErrorToast(O||e(n.I18nKey.CONVERSATION$FAILED_TO_START_FROM_TASK));let t=R.state?.resumedFromConversationId;L(t?`/conversations/${t}`:`/conversations`,{replace:!0})}},[E,D,O,e,L,R.state]),x.default.useEffect(()=>{!P||!F||M||N||(d.clearLastConversationId(k.backend.id,k.orgId),l.displayErrorToast(e(n.I18nKey.CONVERSATION$NOT_EXIST_OR_NO_PERMISSION)),L(`/conversations`))},[N,P,F,L,e,M,k.backend.id,k.orgId]),x.default.useEffect(()=>{M||w&&(w.startsWith(`task-`)||d.setLastConversationId(k.backend.id,k.orgId,w))},[w,M,k.backend.id,k.orgId]);let U=x.default.useRef(null);return x.default.useEffect(()=>{!P||!N||k.backend.kind===`cloud`&&N.sandbox_status===`PAUSED`&&N.sandbox_id&&U.current!==N.id&&(U.current=N.id,p.resumeCloudSandbox(N.sandbox_id).catch(()=>{l.displayErrorToast(e(n.I18nKey.CONVERSATION$FAILED_TO_START_FROM_TASK))}))},[P,N?.id,N?.sandbox_status,N?.sandbox_id,k.backend.kind,e]),M?null:(0,S.jsx)(b.WebSocketProviderWrapper,{conversationId:w,children:(0,S.jsx)(h.EventHandler,{children:(0,S.jsx)(`div`,{"data-testid":`app-route`,className:`flex h-full flex-col`,children:T?(0,S.jsx)(y.ConversationMobilePanelPage,{onNavigateBack:()=>L(`/conversations/${w}`)}):(0,S.jsx)(v.ConversationMain,{})})})})}function T(){return(0,S.jsx)(w,{})}exports.default=T;
|
|
2
2
|
//# sourceMappingURL=conversation.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.cjs","names":[],"sources":["../../src/routes/conversation.tsx"],"sourcesContent":["import React from \"react\";\nimport { useNavigate, useLocation, useMatch } from \"react-router\";\nimport { useTranslation } from \"react-i18next\";\n\nimport { useConversationId } from \"#/hooks/use-conversation-id\";\nimport { useCommandStore } from \"#/stores/command-store\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useAgentStore } from \"#/stores/agent-store\";\nimport { useConversationStateStore } from \"#/stores/conversation-state-store\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport {\n clearLastConversationId,\n setLastConversationId,\n} from \"#/api/backend-registry/last-conversation-store\";\nimport { AgentState } from \"#/types/agent-state\";\n\nimport { EventHandler } from \"../wrapper/event-handler\";\n\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useTaskPolling } from \"#/hooks/query/use-task-polling\";\n\nimport { displayErrorToast } from \"#/utils/custom-toast-handlers\";\nimport { useIsAuthed } from \"#/hooks/query/use-is-authed\";\nimport { ConversationMain } from \"#/components/features/conversation/conversation-main/conversation-main\";\nimport { ConversationMobilePanelPage } from \"#/components/features/conversation/conversation-main/conversation-mobile-panel-page\";\n\nimport { WebSocketProviderWrapper } from \"#/contexts/websocket-provider-wrapper\";\nimport { useErrorMessageStore } from \"#/stores/error-message-store\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { resumeCloudSandbox } from \"#/api/cloud/conversation-service.api\";\n\nfunction AppContent() {\n const { t } = useTranslation(\"openhands\");\n const { conversationId } = useConversationId();\n const panelViewMatch = useMatch(\"/conversations/:conversationId/panel\");\n\n const { isTask, taskStatus, taskDetail } = useTaskPolling();\n\n // The conversationId in the URL belongs to whichever backend was\n // active when the route first mounted. If the user switches backends\n // while this route is still mounted, the id is meaningless under the\n // new backend — disable the active-conversation fetch (and its 404\n // toast) so we don't fire a request that the BackendSelector's\n // redirect will immediately navigate away from anyway. Mirrors the\n // same guard in `routes/automation-detail.tsx`.\n const active = useActiveBackend();\n const mountedBackendId = React.useRef(active.backend.id);\n const mountedOrgId = React.useRef(active.orgId);\n const backendChanged =\n mountedBackendId.current !== active.backend.id ||\n mountedOrgId.current !== active.orgId;\n\n const { data: conversation, isFetched } = useActiveConversation();\n const { data: isAuthed } = useIsAuthed();\n const { resetConversationState } = useConversationStore();\n const navigate = useNavigate();\n const location = useLocation();\n const clearTerminal = useCommandStore((state) => state.clearTerminal);\n const resetConversationRuntimeState = useConversationStateStore(\n (state) => state.reset,\n );\n const setCurrentAgentState = useAgentStore(\n (state) => state.setCurrentAgentState,\n );\n const removeErrorMessage = useErrorMessageStore(\n (state) => state.removeErrorMessage,\n );\n\n // Per-conversation UI/runtime resets. The event store is cleared separately,\n // inside ConversationWebSocketProvider, so the clear is ordered *before* the\n // preloaded-history re-seed (see the note there) — clearing it here would run\n // too late and wipe the freshly seeded history on a conversation switch.\n React.useEffect(() => {\n clearTerminal();\n resetConversationState();\n resetConversationRuntimeState();\n setCurrentAgentState(AgentState.LOADING);\n removeErrorMessage();\n }, [\n conversationId,\n clearTerminal,\n resetConversationState,\n resetConversationRuntimeState,\n setCurrentAgentState,\n removeErrorMessage,\n ]);\n\n React.useEffect(() => {\n if (isTask && taskStatus === \"ERROR\") {\n displayErrorToast(\n taskDetail || t(I18nKey.CONVERSATION$FAILED_TO_START_FROM_TASK),\n );\n // Navigate back to the original conversation when a resume task fails so\n // the user isn't stranded at the dead task-{id} URL. The resume effect's\n // ref prevents it from immediately retrying once we land there.\n const resumedFrom = (location.state as Record<string, unknown> | null)\n ?.resumedFromConversationId as string | undefined;\n navigate(\n resumedFrom ? `/conversations/${resumedFrom}` : \"/conversations\",\n { replace: true },\n );\n }\n }, [isTask, taskStatus, taskDetail, t, navigate, location.state]);\n\n React.useEffect(() => {\n if (!isFetched || !isAuthed) return;\n // The BackendSelector is in the middle of redirecting us away from\n // this route — don't toast/navigate based on a 404 that's just\n // \"this id doesn't exist on the new backend\".\n if (backendChanged) return;\n\n if (!conversation) {\n // Clear the per-backend \"last selected\" slot so the next switch\n // to this backend doesn't try to revisit a stale id.\n clearLastConversationId(active.backend.id, active.orgId);\n displayErrorToast(t(I18nKey.CONVERSATION$NOT_EXIST_OR_NO_PERMISSION));\n navigate(\"/conversations\");\n }\n }, [\n conversation,\n isFetched,\n isAuthed,\n navigate,\n t,\n backendChanged,\n active.backend.id,\n active.orgId,\n ]);\n\n // Remember the most recently selected conversation for the current\n // (backend, org) so flipping back to this backend later restores the\n // user to where they left off. Skip while a backend switch is in\n // flight: the id in the URL is from the previous backend and would\n // otherwise overwrite the new backend's memory.\n React.useEffect(() => {\n if (backendChanged) return;\n if (!conversationId) return;\n if (conversationId.startsWith(\"task-\")) return;\n setLastConversationId(active.backend.id, active.orgId, conversationId);\n }, [conversationId, backendChanged, active.backend.id, active.orgId]);\n\n // Cloud conversation resume: mirrors OpenHands' useSandboxRecovery.\n //\n // When the cloud API reports sandbox_status === \"PAUSED\" the sandbox is\n // sleeping. The correct wake-up call is POST /api/v1/sandboxes/{id}/resume\n // (a lightweight unpause). The previous approach — creating a new start task\n // via POST /api/v1/app-conversations — was wrong: it tries to provision a\n // fresh conversation in the sandbox and is subject to a 120-second cold-start\n // timeout that can fail. The resume endpoint simply unpauses the existing one.\n //\n // After calling resume we stay on the current URL. The 3-second refetch\n // interval in useActiveConversation (active while conversation_url is null)\n // polls until conversation_url populates, then the WebSocket connects.\n //\n // A ref guards against duplicate triggers per unique conversation.id within\n // the same route-mount lifetime.\n const resumeTriggeredForRef = React.useRef<string | null>(null);\n React.useEffect(() => {\n if (!isFetched || !conversation) return;\n if (active.backend.kind !== \"cloud\") return;\n if (conversation.sandbox_status !== \"PAUSED\") return; // only resume PAUSED sandboxes\n if (!conversation.sandbox_id) return; // no sandbox to resume\n if (resumeTriggeredForRef.current === conversation.id) return; // already sent\n\n resumeTriggeredForRef.current = conversation.id;\n\n resumeCloudSandbox(conversation.sandbox_id).catch(() => {\n displayErrorToast(t(I18nKey.CONVERSATION$FAILED_TO_START_FROM_TASK));\n });\n }, [\n isFetched,\n conversation?.id,\n conversation?.sandbox_status,\n conversation?.sandbox_id,\n active.backend.kind,\n t,\n ]);\n\n // A backend switch is in flight (BackendSelector flips the active backend\n // and redirects to /conversations on the next tick). The conversationId in\n // the URL belongs to the *previous* backend, so unmount the whole\n // conversation subtree now — before any per-conversation query (history,\n // metrics, sub-conversations, runtime info, …) re-fires against a backend\n // the id is foreign to. Those foreign fetches fail response validation and\n // surface \"agent server returned data this UI does not understand\". This is\n // deterministic regardless of the navigate-vs-setActive render race: React\n // re-renders this parent before its children, so returning null removes them\n // before they can issue the request.\n if (backendChanged) {\n return null;\n }\n\n const content = (\n <EventHandler>\n <div data-testid=\"app-route\" className=\"flex h-full flex-col\">\n {panelViewMatch ? (\n <ConversationMobilePanelPage\n onNavigateBack={() => navigate(`/conversations/${conversationId}`)}\n />\n ) : (\n <ConversationMain />\n )}\n </div>\n </EventHandler>\n );\n\n return (\n <WebSocketProviderWrapper conversationId={conversationId}>\n {content}\n </WebSocketProviderWrapper>\n );\n}\n\nexport function ConversationView() {\n return <AppContent />;\n}\n\nexport default ConversationView;\n"],"mappings":"8sCA+BA,SAAS,GAAa,CACpB,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,CAAE,kBAAmB,EAAA,mBAAmB,CACxC,GAAA,EAAA,EAAA,UAA0B,uCAAuC,CAEjE,CAAE,SAAQ,aAAY,cAAe,EAAA,gBAAgB,CASrD,EAAS,EAAA,kBAAkB,CAC3B,EAAmB,EAAA,QAAM,OAAO,EAAO,QAAQ,GAAG,CAClD,EAAe,EAAA,QAAM,OAAO,EAAO,MAAM,CACzC,EACJ,EAAiB,UAAY,EAAO,QAAQ,IAC5C,EAAa,UAAY,EAAO,MAE5B,CAAE,KAAM,EAAc,aAAc,EAAA,uBAAuB,CAC3D,CAAE,KAAM,GAAa,EAAA,aAAa,CAClC,CAAE,0BAA2B,EAAA,sBAAsB,CACnD,GAAA,EAAA,EAAA,cAAwB,CACxB,GAAA,EAAA,EAAA,cAAwB,CACxB,EAAgB,EAAA,gBAAiB,GAAU,EAAM,cAAc,CAC/D,EAAgC,EAAA,0BACnC,GAAU,EAAM,MAClB,CACK,EAAuB,EAAA,cAC1B,GAAU,EAAM,qBAClB,CACK,EAAqB,EAAA,qBACxB,GAAU,EAAM,mBAClB,CAMD,EAAA,QAAM,cAAgB,CACpB,GAAe,CACf,GAAwB,CACxB,GAA+B,CAC/B,EAAqB,EAAA,WAAW,QAAQ,CACxC,GAAoB,EACnB,CACD,EACA,EACA,EACA,EACA,EACA,EACD,CAAC,CAEF,EAAA,QAAM,cAAgB,CACpB,GAAI,GAAU,IAAe,QAAS,CACpC,EAAA,kBACE,GAAc,EAAE,EAAA,QAAQ,uCAAuC,CAChE,CAID,IAAM,EAAe,EAAS,OAC1B,0BACJ,EACE,EAAc,kBAAkB,IAAgB,iBAChD,CAAE,QAAS,GAAM,CAClB,GAEF,CAAC,EAAQ,EAAY,EAAY,EAAG,EAAU,EAAS,MAAM,CAAC,CAEjE,EAAA,QAAM,cAAgB,CAChB,CAAC,GAAa,CAAC,GAIf,GAEC,IAGH,EAAA,wBAAwB,EAAO,QAAQ,GAAI,EAAO,MAAM,CACxD,EAAA,kBAAkB,EAAE,EAAA,QAAQ,wCAAwC,CAAC,CACrE,EAAS,iBAAiB,GAE3B,CACD,EACA,EACA,EACA,EACA,EACA,EACA,EAAO,QAAQ,GACf,EAAO,MACR,CAAC,CAOF,EAAA,QAAM,cAAgB,CAChB,GACC,IACD,EAAe,WAAW,QAAQ,EACtC,EAAA,sBAAsB,EAAO,QAAQ,GAAI,EAAO,MAAO,EAAe,GACrE,CAAC,EAAgB,EAAgB,EAAO,QAAQ,GAAI,EAAO,MAAM,CAAC,CAiBrE,IAAM,EAAwB,EAAA,QAAM,OAAsB,KAAK,CAkD/D,OAjDA,EAAA,QAAM,cAAgB,CAChB,CAAC,GAAa,CAAC,GACf,EAAO,QAAQ,OAAS,SACxB,EAAa,iBAAmB,UAC/B,EAAa,YACd,EAAsB,UAAY,EAAa,KAEnD,EAAsB,QAAU,EAAa,GAE7C,EAAA,mBAAmB,EAAa,WAAW,CAAC,UAAY,CACtD,EAAA,kBAAkB,EAAE,EAAA,QAAQ,uCAAuC,CAAC,EACpE,GACD,CACD,EACA,GAAc,GACd,GAAc,eACd,GAAc,WACd,EAAO,QAAQ,KACf,EACD,CAAC,CAYE,EACK,MAkBP,EAAA,EAAA,KAAC,EAAA,yBAAD,CAA0C,2BACvC,EAAA,EAAA,KAfF,EAAA,aAAD,CAAA,UACE,EAAA,EAAA,KAAC,MAAD,CAAK,cAAY,YAAY,UAAU,gCACpC,GACC,EAAA,EAAA,KAAC,EAAA,4BAAD,CACE,mBAAsB,EAAS,kBAAkB,IAAiB,CAClE,CAAA,EAEF,EAAA,EAAA,KAAC,EAAA,iBAAD,EAAoB,CAAA,CAElB,CAAA,CACO,CAKZ,CACwB,CAAA,CAI/B,SAAgB,GAAmB,CACjC,OAAO,EAAA,EAAA,KAAC,EAAD,EAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"conversation.cjs","names":[],"sources":["../../src/routes/conversation.tsx"],"sourcesContent":["import React from \"react\";\nimport { useNavigate, useLocation, useMatch } from \"react-router\";\nimport { useTranslation } from \"react-i18next\";\n\nimport { useConversationId } from \"#/hooks/use-conversation-id\";\nimport { useCommandStore } from \"#/stores/command-store\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useAgentStore } from \"#/stores/agent-store\";\nimport { useConversationStateStore } from \"#/stores/conversation-state-store\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport {\n clearLastConversationId,\n setLastConversationId,\n} from \"#/api/backend-registry/last-conversation-store\";\nimport { AgentState } from \"#/types/agent-state\";\n\nimport { EventHandler } from \"../wrapper/event-handler\";\n\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useTaskPollingController } from \"#/hooks/query/use-task-polling\";\n\nimport { displayErrorToast } from \"#/utils/custom-toast-handlers\";\nimport { useIsAuthed } from \"#/hooks/query/use-is-authed\";\nimport { ConversationMain } from \"#/components/features/conversation/conversation-main/conversation-main\";\nimport { ConversationMobilePanelPage } from \"#/components/features/conversation/conversation-main/conversation-mobile-panel-page\";\n\nimport { WebSocketProviderWrapper } from \"#/contexts/websocket-provider-wrapper\";\nimport { useErrorMessageStore } from \"#/stores/error-message-store\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { resumeCloudSandbox } from \"#/api/cloud/conversation-service.api\";\n\nfunction AppContent() {\n const { t } = useTranslation(\"openhands\");\n const { conversationId } = useConversationId();\n const panelViewMatch = useMatch(\"/conversations/:conversationId/panel\");\n\n const { isTask, taskStatus, taskDetail } = useTaskPollingController();\n\n // The conversationId in the URL belongs to whichever backend was\n // active when the route first mounted. If the user switches backends\n // while this route is still mounted, the id is meaningless under the\n // new backend — disable the active-conversation fetch (and its 404\n // toast) so we don't fire a request that the BackendSelector's\n // redirect will immediately navigate away from anyway. Mirrors the\n // same guard in `routes/automation-detail.tsx`.\n const active = useActiveBackend();\n const mountedBackendId = React.useRef(active.backend.id);\n const mountedOrgId = React.useRef(active.orgId);\n const backendChanged =\n mountedBackendId.current !== active.backend.id ||\n mountedOrgId.current !== active.orgId;\n\n const { data: conversation, isFetched } = useActiveConversation();\n const { data: isAuthed } = useIsAuthed();\n const { resetConversationState } = useConversationStore();\n const navigate = useNavigate();\n const location = useLocation();\n const clearTerminal = useCommandStore((state) => state.clearTerminal);\n const resetConversationRuntimeState = useConversationStateStore(\n (state) => state.reset,\n );\n const setCurrentAgentState = useAgentStore(\n (state) => state.setCurrentAgentState,\n );\n const removeErrorMessage = useErrorMessageStore(\n (state) => state.removeErrorMessage,\n );\n\n // Per-conversation UI/runtime resets. The event store is cleared separately,\n // inside ConversationWebSocketProvider, so the clear is ordered *before* the\n // preloaded-history re-seed (see the note there) — clearing it here would run\n // too late and wipe the freshly seeded history on a conversation switch.\n React.useEffect(() => {\n clearTerminal();\n resetConversationState();\n resetConversationRuntimeState();\n setCurrentAgentState(AgentState.LOADING);\n removeErrorMessage();\n }, [\n conversationId,\n clearTerminal,\n resetConversationState,\n resetConversationRuntimeState,\n setCurrentAgentState,\n removeErrorMessage,\n ]);\n\n React.useEffect(() => {\n if (isTask && taskStatus === \"ERROR\") {\n displayErrorToast(\n taskDetail || t(I18nKey.CONVERSATION$FAILED_TO_START_FROM_TASK),\n );\n // Navigate back to the original conversation when a resume task fails so\n // the user isn't stranded at the dead task-{id} URL. The resume effect's\n // ref prevents it from immediately retrying once we land there.\n const resumedFrom = (location.state as Record<string, unknown> | null)\n ?.resumedFromConversationId as string | undefined;\n navigate(\n resumedFrom ? `/conversations/${resumedFrom}` : \"/conversations\",\n { replace: true },\n );\n }\n }, [isTask, taskStatus, taskDetail, t, navigate, location.state]);\n\n React.useEffect(() => {\n if (!isFetched || !isAuthed) return;\n // The BackendSelector is in the middle of redirecting us away from\n // this route — don't toast/navigate based on a 404 that's just\n // \"this id doesn't exist on the new backend\".\n if (backendChanged) return;\n\n if (!conversation) {\n // Clear the per-backend \"last selected\" slot so the next switch\n // to this backend doesn't try to revisit a stale id.\n clearLastConversationId(active.backend.id, active.orgId);\n displayErrorToast(t(I18nKey.CONVERSATION$NOT_EXIST_OR_NO_PERMISSION));\n navigate(\"/conversations\");\n }\n }, [\n conversation,\n isFetched,\n isAuthed,\n navigate,\n t,\n backendChanged,\n active.backend.id,\n active.orgId,\n ]);\n\n // Remember the most recently selected conversation for the current\n // (backend, org) so flipping back to this backend later restores the\n // user to where they left off. Skip while a backend switch is in\n // flight: the id in the URL is from the previous backend and would\n // otherwise overwrite the new backend's memory.\n React.useEffect(() => {\n if (backendChanged) return;\n if (!conversationId) return;\n if (conversationId.startsWith(\"task-\")) return;\n setLastConversationId(active.backend.id, active.orgId, conversationId);\n }, [conversationId, backendChanged, active.backend.id, active.orgId]);\n\n // Cloud conversation resume: mirrors OpenHands' useSandboxRecovery.\n //\n // When the cloud API reports sandbox_status === \"PAUSED\" the sandbox is\n // sleeping. The correct wake-up call is POST /api/v1/sandboxes/{id}/resume\n // (a lightweight unpause). The previous approach — creating a new start task\n // via POST /api/v1/app-conversations — was wrong: it tries to provision a\n // fresh conversation in the sandbox and is subject to a 120-second cold-start\n // timeout that can fail. The resume endpoint simply unpauses the existing one.\n //\n // After calling resume we stay on the current URL. The 3-second refetch\n // interval in useActiveConversation (active while conversation_url is null)\n // polls until conversation_url populates, then the WebSocket connects.\n //\n // A ref guards against duplicate triggers per unique conversation.id within\n // the same route-mount lifetime.\n const resumeTriggeredForRef = React.useRef<string | null>(null);\n React.useEffect(() => {\n if (!isFetched || !conversation) return;\n if (active.backend.kind !== \"cloud\") return;\n if (conversation.sandbox_status !== \"PAUSED\") return; // only resume PAUSED sandboxes\n if (!conversation.sandbox_id) return; // no sandbox to resume\n if (resumeTriggeredForRef.current === conversation.id) return; // already sent\n\n resumeTriggeredForRef.current = conversation.id;\n\n resumeCloudSandbox(conversation.sandbox_id).catch(() => {\n displayErrorToast(t(I18nKey.CONVERSATION$FAILED_TO_START_FROM_TASK));\n });\n }, [\n isFetched,\n conversation?.id,\n conversation?.sandbox_status,\n conversation?.sandbox_id,\n active.backend.kind,\n t,\n ]);\n\n // A backend switch is in flight (BackendSelector flips the active backend\n // and redirects to /conversations on the next tick). The conversationId in\n // the URL belongs to the *previous* backend, so unmount the whole\n // conversation subtree now — before any per-conversation query (history,\n // metrics, sub-conversations, runtime info, …) re-fires against a backend\n // the id is foreign to. Those foreign fetches fail response validation and\n // surface \"agent server returned data this UI does not understand\". This is\n // deterministic regardless of the navigate-vs-setActive render race: React\n // re-renders this parent before its children, so returning null removes them\n // before they can issue the request.\n if (backendChanged) {\n return null;\n }\n\n const content = (\n <EventHandler>\n <div data-testid=\"app-route\" className=\"flex h-full flex-col\">\n {panelViewMatch ? (\n <ConversationMobilePanelPage\n onNavigateBack={() => navigate(`/conversations/${conversationId}`)}\n />\n ) : (\n <ConversationMain />\n )}\n </div>\n </EventHandler>\n );\n\n return (\n <WebSocketProviderWrapper conversationId={conversationId}>\n {content}\n </WebSocketProviderWrapper>\n );\n}\n\nexport function ConversationView() {\n return <AppContent />;\n}\n\nexport default ConversationView;\n"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ import { useErrorMessageStore as f } from "../stores/error-message-store.js";
|
|
|
13
13
|
import { resumeCloudSandbox as p } from "../api/cloud/conversation-service.api.js";
|
|
14
14
|
import { useActiveConversation as m } from "../hooks/query/use-active-conversation.js";
|
|
15
15
|
import { EventHandler as h } from "../wrapper/event-handler.js";
|
|
16
|
-
import {
|
|
16
|
+
import { useTaskPollingController as g } from "../hooks/query/use-task-polling.js";
|
|
17
17
|
import { useIsAuthed as _ } from "../hooks/query/use-is-authed.js";
|
|
18
18
|
import { ConversationMain as v } from "../components/features/conversation/conversation-main/conversation-main.js";
|
|
19
19
|
import { ConversationMobilePanelPage as y } from "../components/features/conversation/conversation-main/conversation-mobile-panel-page.js";
|