@openhands/agent-canvas 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{acp-providers-DLe_gVDY.js → acp-providers-BkL3HWa3.js} +1 -1
- package/build/assets/{active-backend-context-B0wI7OzM.js → active-backend-context-B_bg5h9O.js} +1 -1
- package/build/assets/{agent-context-settings-CaQtdNA-.js → agent-context-settings-CzWS1DgR.js} +1 -1
- package/build/assets/{agent-profiles-settings-CvuErjp6.js → agent-profiles-settings-hd2cAIZM.js} +1 -1
- package/build/assets/agent-server-conversation-service.api-BheU4HX3.js +86 -0
- package/build/assets/{agent-settings-UE-U4Xii.js → agent-settings-D2J1dKVd.js} +1 -1
- package/build/assets/agent-settings-D_SVrWhI.js +1 -0
- package/build/assets/{alert-banner-BMaOtTCG.js → alert-banner-lrK-2_0Y.js} +1 -1
- package/build/assets/{api-key-entry-screen-Cy66vT4D.js → api-key-entry-screen-D70oJj2c.js} +1 -1
- package/build/assets/app-settings-D0OKHB3M.js +1 -0
- package/build/assets/{automation-detail-fuITm6i3.js → automation-detail-C0SxWTnQ.js} +3 -3
- package/build/assets/{automation-export-CRq40mux.js → automation-export-BjQa_fT6.js} +1 -1
- package/build/assets/{automation-setup-route-EXDazOHW.js → automation-setup-route-BzCNpljP.js} +1 -1
- package/build/assets/{automation-templates-BArZsaxP.js → automation-templates-D9gs6ihu.js} +1 -1
- package/build/assets/{automations-list-CG4HKOTn.js → automations-list-dZg8zOCl.js} +1 -1
- package/build/assets/{back-nav-button-BZB6H7xz.js → back-nav-button-B3pYwmUJ.js} +1 -1
- package/build/assets/{backend-form-modal-B_lXjOGa.js → backend-form-modal-HwclKrUS.js} +1 -1
- package/build/assets/{backend-synced-settings-badge-B_NXJ3u1.js → backend-synced-settings-badge-YI3k09Wr.js} +1 -1
- package/build/assets/{badge-C64c-7PO.js → badge-Dpn3-LTV.js} +1 -1
- package/build/assets/{base-modal-C0RQPug5.js → base-modal-3NmIOKDm.js} +1 -1
- package/build/assets/{brand-button-DJmFCyMK.js → brand-button-CJcwjnfb.js} +1 -1
- package/build/assets/{browser-D3gd2n83.js → browser--eoQOo4M.js} +1 -1
- package/build/assets/{browser-tab-BicAWuJ1.js → browser-tab-4CPdj3J3.js} +1 -1
- package/build/assets/{chat-send-button-CCrH1E8u.js → chat-send-button-B8n6-DQA.js} +1 -1
- package/build/assets/{circle-plus-check-toggle-CB_sNERY.js → circle-plus-check-toggle-BVzv5EkZ.js} +1 -1
- package/build/assets/{cloud-funnel-analytics-XynamQGU.js → cloud-funnel-analytics-CcSez21r.js} +1 -1
- package/build/assets/{combobox-caret-Bwiifgjs.js → combobox-caret-BlmRwiM8.js} +1 -1
- package/build/assets/command-menu-BKOLj-TC.js +1 -0
- package/build/assets/{condenser-settings-cNGy75gq.js → condenser-settings-DLQogFnB.js} +1 -1
- package/build/assets/{confirmation-modal-BATFmFyP.js → confirmation-modal-DAH0XtOp.js} +1 -1
- package/build/assets/{context-menu-list-item-DhJCcBA0.js → context-menu-list-item-BQhmFVEK.js} +1 -1
- package/build/assets/{conversation-Csdxh9Xt.js → conversation-Cmyw9bFh.js} +4 -4
- package/build/assets/conversation-CvoGZ5vC.js +1 -0
- package/build/assets/conversation-panel-CvoGZ5vC.js +1 -0
- package/build/assets/{conversation-state-store-C2QzhPaK.js → conversation-state-store-CtgILxWF.js} +1 -1
- package/build/assets/{conversation-tab-empty-state-D3fb5xIA.js → conversation-tab-empty-state-C9sfDOlt.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-c4MQwKGj.js → copy-to-clipboard-button-DatoElj8.js} +1 -1
- package/build/assets/{device-verify-oFpQoLgm.js → device-verify-BIjXeW9N.js} +1 -1
- package/build/assets/{dropdown-classes-f91ARMV1.js → dropdown-classes-zFW7qPSK.js} +1 -1
- package/build/assets/{entry.client-BCzY2Bf3.js → entry.client-EBn3ZtNP.js} +2 -2
- package/build/assets/{enum-filter-dropdown-HG3q3rkV.js → enum-filter-dropdown-CctILg5t.js} +1 -1
- package/build/assets/{environment-switch-overlay-CquZXolz.js → environment-switch-overlay-Cvmo6clk.js} +1 -1
- package/build/assets/{extensions-hub-BeweE0PW.js → extensions-hub-BZ3HYztk.js} +1 -1
- package/build/assets/{extensions-navigation-Dd58NlUF.js → extensions-navigation-Bnx32WAb.js} +1 -1
- package/build/assets/{files-tab-CLLG55-q.js → files-tab-D5zuU5TY.js} +1 -1
- package/build/assets/{form-control-classes-pHtZUI6K.js → form-control-classes-DLN3Qgub.js} +1 -1
- package/build/assets/format-model-name-BN_rx1Y3.js +1 -0
- package/build/assets/{format-relative-time-6-3uvOXe.js → format-relative-time-BerVamGl.js} +1 -1
- package/build/assets/{git-provider-icon-wg7ShB98.js → git-provider-icon-zuKz2cwo.js} +1 -1
- package/build/assets/{git-repo-dropdown-CWnaUyxL.js → git-repo-dropdown-B5VnMftu.js} +1 -1
- package/build/assets/git-repo-dropdown-Bo7ciSNX.js +1 -0
- package/build/assets/{highlighted-source-view-DBtI3por.js → highlighted-source-view-CgJfD5VT.js} +1 -1
- package/build/assets/home-DqyeeFA_.js +1 -0
- package/build/assets/{home-BpZQkDWM.js → home-Y0aDou-a.js} +1 -1
- package/build/assets/{home-store-DM4qw1lF.js → home-store-Cubdq0uP.js} +1 -1
- package/build/assets/index-home-DqyeeFA_.js +1 -0
- package/build/assets/install-server-modal-DW6dSyGr.js +1 -0
- package/build/assets/{kebab-menu-item-content-By16Tm_0.js → kebab-menu-item-content-CKydZrbH.js} +1 -1
- package/build/assets/{launch-C9uijypN.js → launch-c4GEP8oo.js} +1 -1
- package/build/assets/llm-not-configured-banner-DCE_0B4I.js +27 -0
- package/build/assets/llm-settings-8eWBF3Ij.js +1 -0
- package/build/assets/llm-settings-D9ko42Pi.js +1 -0
- package/build/assets/{llm-subscription-service-DwjJ8-_X.js → llm-subscription-service-B3K-97lP.js} +1 -1
- package/build/assets/{loading-spinner-6Yj-YyoS.js → loading-spinner-CN3riY7k.js} +1 -1
- package/build/assets/{manage-backends-modal-DrwErS0N.js → manage-backends-modal-DTCME_Pu.js} +1 -1
- package/build/assets/manifest-e1c3bc3b.js +1 -0
- package/build/assets/{manifest-subpage-layout-CtqVwIvJ.js → manifest-subpage-layout-Ds7G5GZ8.js} +1 -1
- package/build/assets/map-provider-7Bp2aih5.js +1 -0
- package/build/assets/markdown-renderer-DzvgdZey.js +8 -0
- package/build/assets/mcp-Da7wFU7A.js +9 -0
- package/build/assets/{mcp-marketplace-utils-BMnYz0Gc.js → mcp-marketplace-utils-DSLou4n7.js} +1 -1
- package/build/assets/messages-B2l0qLVk.js +40 -0
- package/build/assets/{modal-body-BHGCSAtj.js → modal-body-duRaxj_K.js} +1 -1
- package/build/assets/{modal-classes-DSTLuxkA.js → modal-classes-CLEXO6dj.js} +1 -1
- package/build/assets/{modal-close-button-dheWZ2ys.js → modal-close-button-D0aT02hs.js} +1 -1
- package/build/assets/npm-Cswluf6-.js +1 -0
- package/build/assets/{onboarding-5CZvRBbh.js → onboarding-BKbTYlW1.js} +1 -1
- package/build/assets/{onboarding-modal-CD2ehuxt.js → onboarding-modal-DrrGlEQq.js} +1 -1
- package/build/assets/{organization-service.api-Dsuoep0g.js → organization-service.api-DK8csGvK.js} +1 -1
- package/build/assets/{planner-tab-DeO7Thb0.js → planner-tab-D-mZ1I7n.js} +1 -1
- package/build/assets/{plugins-management-service-C9f75R6X.js → plugins-management-service-CywqyfLK.js} +1 -1
- package/build/assets/{profiles-service.api-Dl20_2IM.js → profiles-service.api-vcE_jJCe.js} +1 -1
- package/build/assets/{providers-CeuhK46N.js → providers-CdrPPm0z.js} +1 -1
- package/build/assets/{proxy-CIGI9zQC.js → proxy-b4aqL4SX.js} +1 -1
- package/build/assets/recommended-automations-launcher-DIYgUdMm.js +1 -0
- package/build/assets/{root-BQPNqNvD.js → root-CBBi6IAe.js} +2 -2
- package/build/assets/root-CRK9fOFd.css +1 -0
- package/build/assets/root-layout-BFN2rCOy.js +2 -0
- package/build/assets/{schema-field-z2vSLuLo.js → schema-field-Z-rMg9ti.js} +1 -1
- package/build/assets/{sdk-section-page-BnCXAytf.js → sdk-section-page-m_cjygxR.js} +1 -1
- package/build/assets/{secrets-service-DGUNlwQd.js → secrets-service-BHF4fxML.js} +1 -1
- package/build/assets/{secrets-settings-DUmML_dK.js → secrets-settings-aBGXtQhX.js} +1 -1
- package/build/assets/{segmented-toggle-eSofF7gn.js → segmented-toggle-SmvsR3jW.js} +1 -1
- package/build/assets/settings-CZPGNens.js +1 -0
- package/build/assets/{settings-dropdown-input-Cx4g7Xfl.js → settings-dropdown-input-TWIeiG02.js} +1 -1
- package/build/assets/{settings-index-BECdgecg.js → settings-index-Dtlegd6s.js} +1 -1
- package/build/assets/{settings-input-BQY115xH.js → settings-input-D61Vzp9e.js} +1 -1
- package/build/assets/{settings-list-classes-C9cLrrcc.js → settings-list-classes-sE0ASr1s.js} +1 -1
- package/build/assets/{settings-modal-ChBJNTdd.js → settings-modal-CalzJP2l.js} +1 -1
- package/build/assets/{settings-service.api-Dz9cZyvx.js → settings-service.api-DfPYaxZJ.js} +1 -1
- package/build/assets/{settings-switch-BIodMVz9.js → settings-switch-Drt-rF5s.js} +1 -1
- package/build/assets/{settings-utils-BL_Z9uIe.js → settings-utils-gw2ppAvw.js} +1 -1
- package/build/assets/{shared-conversation-CSF0aTuE.js → shared-conversation-BIAcuORk.js} +1 -1
- package/build/assets/{wrench-DRitTfwe.js → shield-check-D2cpEpv3.js} +1 -1
- package/build/assets/{sidebar-layout-DEycoFd_.js → sidebar-layout-Dxg6zc2K.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-DeRvTupV.js → sidebar-mobile-menu-toggle-C6HpQ55l.js} +1 -1
- package/build/assets/{sidebar-nav-link-BjpQ-NVc.js → sidebar-nav-link-CxLoG-dG.js} +1 -1
- package/build/assets/sidebar-store-BJeYY-E9.js +1 -0
- package/build/assets/{skill-card-pill-row-BH6fPGba.js → skill-card-pill-row-B_BYBONu.js} +1 -1
- package/build/assets/{skill-icon-badge-D4uznfjU.js → skill-icon-badge-CN41Hy9l.js} +1 -1
- package/build/assets/{skill-scope-DH_AUUUP.js → skill-scope-Dt1V5X2p.js} +1 -1
- package/build/assets/{skills-plugins-vfvOk34h.js → skills-plugins-B-H0cCOP.js} +1 -1
- package/build/assets/skills-settings-DthdIDUb.js +2 -0
- package/build/assets/{styled-tooltip-CQ9JEFiO.js → styled-tooltip-C5C07RQC.js} +1 -1
- package/build/assets/{task-list-tab-DeF_uXdw.js → task-list-tab-BTde81Iu.js} +1 -1
- package/build/assets/{terminal-DRc4rup7.js → terminal-DRrJo-cR.js} +1 -1
- package/build/assets/{toggle-switch--8n8NeV_.js → toggle-switch-CIioisto.js} +1 -1
- package/build/assets/{typography-BSbUhJPn.js → typography-D9tiHct7.js} +1 -1
- package/build/assets/{use-acp-credential-form-BGKFi1VL.js → use-acp-credential-form-DGyo0QvL.js} +1 -1
- package/build/assets/{use-activate-agent-profile-2nvALjC-.js → use-activate-agent-profile-DrPzIKJF.js} +1 -1
- package/build/assets/{use-agent-profiles-BlQA67MW.js → use-agent-profiles-B37XWDLq.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-Clw5Dh1s.js → use-can-manage-org-profiles-BzE28H3x.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-B8AQSQFM.js → use-cloud-current-user-id-U6HPjy50.js} +1 -1
- package/build/assets/{use-config-C3zGuUQI.js → use-config-DapX3pjC.js} +1 -1
- package/build/assets/{use-create-conversation-FaP0kUpg.js → use-create-conversation-CRf1dCm5.js} +1 -1
- package/build/assets/{use-create-secret-CgQ3pXd6.js → use-create-secret-DcpT3RPw.js} +1 -1
- package/build/assets/{use-llm-profiles-C-tDO6UB.js → use-llm-profiles-CHxqoHiN.js} +1 -1
- package/build/assets/{use-manifest-capabilities-DLP5wCxp.js → use-manifest-capabilities-zihHDbMW.js} +1 -1
- package/build/assets/{use-onboarding-completion-BiCdXvlU.js → use-onboarding-completion-6kWOW3ul.js} +1 -1
- package/build/assets/{use-plugins-marketplace-DRFNLBlr.js → use-plugins-marketplace-CqkR8kLE.js} +1 -1
- package/build/assets/{use-save-agent-profile-CaGVAudI.js → use-save-agent-profile-CH9_EXQG.js} +1 -1
- package/build/assets/{use-save-settings-C9B8Y-h3.js → use-save-settings-DIEurJ3D.js} +1 -1
- package/build/assets/{use-settings-3RcgdUuZ.js → use-settings-BmLzQjnC.js} +1 -1
- package/build/assets/use-settings-nav-items-DV9qgeu7.js +16 -0
- package/build/assets/{use-tracking-CTtkLAmx.js → use-tracking-salbPJxT.js} +1 -1
- package/build/assets/{use-user-conversation-Bei82QsZ.js → use-user-conversation-Dt-W6uNw.js} +1 -1
- package/build/assets/utils-DPQfkd-7.js +1 -0
- package/build/assets/{verification-settings-nD61Ijph.js → verification-settings-oi54wEc1.js} +1 -1
- package/build/assets/wrench-B1_H-tL1.js +1 -0
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +39 -2
- package/build/locales/ca/openhands.json +39 -2
- package/build/locales/de/openhands.json +39 -2
- package/build/locales/en/openhands.json +39 -2
- package/build/locales/es/openhands.json +39 -2
- package/build/locales/fr/openhands.json +39 -2
- package/build/locales/it/openhands.json +39 -2
- package/build/locales/ja/openhands.json +39 -2
- package/build/locales/ko-KR/openhands.json +39 -2
- package/build/locales/no/openhands.json +39 -2
- package/build/locales/pt/openhands.json +39 -2
- package/build/locales/tr/openhands.json +39 -2
- package/build/locales/uk/openhands.json +39 -2
- package/build/locales/zh-CN/openhands.json +39 -2
- package/build/locales/zh-TW/openhands.json +39 -2
- package/config/defaults.json +1 -1
- package/dist/api/agent-server-adapter.cjs +3 -3
- package/dist/api/agent-server-adapter.cjs.map +1 -1
- package/dist/api/agent-server-adapter.d.ts +32 -5
- package/dist/api/agent-server-adapter.js +120 -91
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/cloud/conversation-service.api.cjs +1 -1
- package/dist/api/cloud/conversation-service.api.cjs.map +1 -1
- package/dist/api/cloud/conversation-service.api.d.ts +19 -2
- package/dist/api/cloud/conversation-service.api.js +51 -47
- package/dist/api/cloud/conversation-service.api.js.map +1 -1
- package/dist/api/conversation-file-upload.api.cjs +1 -1
- package/dist/api/conversation-file-upload.api.js +10 -10
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.js +55 -61
- package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
- package/dist/api/event-service/event-service.api.cjs +1 -1
- package/dist/api/event-service/event-service.api.js +12 -12
- package/dist/api/launch-child-conversation-client-tool.cjs +47 -0
- package/dist/api/launch-child-conversation-client-tool.cjs.map +1 -0
- package/dist/api/launch-child-conversation-client-tool.d.ts +3 -0
- package/dist/api/launch-child-conversation-client-tool.js +93 -0
- package/dist/api/launch-child-conversation-client-tool.js.map +1 -0
- package/dist/api/open-hands.types.d.ts +1 -1
- package/dist/api/workspace-upload-path.cjs +1 -1
- package/dist/api/workspace-upload-path.js +8 -8
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js +24 -18
- package/dist/components/conversation-events/chat/event-content-helpers/get-action-event-title.js.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +5 -0
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs +2 -2
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js +11 -7
- package/dist/components/conversation-events/chat/event-content-helpers/should-render-event.js.map +1 -1
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs +1 -1
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.cjs.map +1 -1
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.js +61 -60
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.js.map +1 -1
- package/dist/components/features/chat/model-messages.cjs +1 -1
- package/dist/components/features/chat/model-messages.cjs.map +1 -1
- package/dist/components/features/chat/model-messages.js +26 -25
- package/dist/components/features/chat/model-messages.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -2
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +2 -8
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js +50 -53
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.d.ts +12 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.js +6 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-meta-chip.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.d.ts +16 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js +95 -78
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.js +40 -38
- package/dist/components/features/conversation-panel/conversation-card/conversation-repo-link.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.d.ts +14 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js +167 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.d.ts +63 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js +66 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.d.ts +15 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.js +117 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-icons.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/no-repository.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/no-repository.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/no-repository.js +30 -19
- package/dist/components/features/conversation-panel/conversation-card/no-repository.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +7 -2
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +146 -104
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.d.ts +20 -0
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +53 -27
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.js +226 -213
- package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
- package/dist/components/features/settings/agent-canvas-update-card.cjs +1 -1
- package/dist/components/features/settings/agent-canvas-update-card.cjs.map +1 -1
- package/dist/components/features/settings/agent-canvas-update-card.d.ts +10 -5
- package/dist/components/features/settings/agent-canvas-update-card.js +223 -149
- package/dist/components/features/settings/agent-canvas-update-card.js.map +1 -1
- package/dist/components/features/settings/agent-canvas-version-modal.cjs +2 -0
- package/dist/components/features/settings/agent-canvas-version-modal.cjs.map +1 -0
- package/dist/components/features/settings/agent-canvas-version-modal.d.ts +11 -0
- package/dist/components/features/settings/agent-canvas-version-modal.js +166 -0
- package/dist/components/features/settings/agent-canvas-version-modal.js.map +1 -0
- package/dist/components/features/settings/agent-canvas-version-tile.cjs +2 -0
- package/dist/components/features/settings/agent-canvas-version-tile.cjs.map +1 -0
- package/dist/components/features/settings/agent-canvas-version-tile.d.ts +13 -0
- package/dist/components/features/settings/agent-canvas-version-tile.js +60 -0
- package/dist/components/features/settings/agent-canvas-version-tile.js.map +1 -0
- package/dist/components/features/settings/llm-profiles/profile-row.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/profile-row.js +1 -0
- package/dist/components/features/settings/settings-desktop-sidebar.cjs +1 -1
- package/dist/components/features/settings/settings-desktop-sidebar.cjs.map +1 -1
- package/dist/components/features/settings/settings-desktop-sidebar.js +1 -1
- package/dist/components/features/settings/settings-desktop-sidebar.js.map +1 -1
- package/dist/components/features/settings/settings-mobile-drawer.cjs +1 -1
- package/dist/components/features/settings/settings-mobile-drawer.cjs.map +1 -1
- package/dist/components/features/settings/settings-mobile-drawer.js +1 -1
- package/dist/components/features/settings/settings-mobile-drawer.js.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.js +109 -108
- package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
- package/dist/components/features/skills/extensions-navigation.cjs +1 -1
- package/dist/components/features/skills/extensions-navigation.cjs.map +1 -1
- package/dist/components/features/skills/extensions-navigation.js +9 -9
- package/dist/components/features/skills/extensions-navigation.js.map +1 -1
- package/dist/components/shared/modals/settings/model-selector.cjs +1 -1
- package/dist/components/shared/modals/settings/model-selector.cjs.map +1 -1
- package/dist/components/shared/modals/settings/model-selector.js +154 -98
- package/dist/components/shared/modals/settings/model-selector.js.map +1 -1
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/constants/child-conversation.cjs +2 -0
- package/dist/constants/child-conversation.cjs.map +1 -0
- package/dist/constants/child-conversation.d.ts +29 -0
- package/dist/constants/child-conversation.js +6 -0
- package/dist/constants/child-conversation.js.map +1 -0
- 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 +189 -188
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/hooks/chat/use-model-interceptor.cjs +1 -1
- package/dist/hooks/chat/use-model-interceptor.js +6 -6
- package/dist/hooks/chat/use-slash-command.cjs +1 -1
- package/dist/hooks/chat/use-slash-command.cjs.map +1 -1
- package/dist/hooks/chat/use-slash-command.js +61 -60
- package/dist/hooks/chat/use-slash-command.js.map +1 -1
- package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
- package/dist/hooks/mutation/use-create-conversation.js +6 -6
- package/dist/i18n/declaration.cjs +1 -1
- package/dist/i18n/declaration.cjs.map +1 -1
- package/dist/i18n/declaration.d.ts +38 -1
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +2 -2
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +644 -15
- package/dist/i18n/translation.js.map +1 -1
- package/dist/icons/docker.cjs +2 -0
- package/dist/icons/docker.cjs.map +1 -0
- package/dist/icons/docker.js +19 -0
- package/dist/icons/docker.js.map +1 -0
- package/dist/icons/npm.cjs +2 -0
- package/dist/icons/npm.cjs.map +1 -0
- package/dist/icons/npm.js +19 -0
- package/dist/icons/npm.js.map +1 -0
- package/dist/locales/ar/openhands.json +39 -2
- package/dist/locales/ca/openhands.json +39 -2
- package/dist/locales/de/openhands.json +39 -2
- package/dist/locales/en/openhands.json +39 -2
- package/dist/locales/es/openhands.json +39 -2
- package/dist/locales/fr/openhands.json +39 -2
- package/dist/locales/it/openhands.json +39 -2
- package/dist/locales/ja/openhands.json +39 -2
- package/dist/locales/ko-KR/openhands.json +39 -2
- package/dist/locales/no/openhands.json +39 -2
- package/dist/locales/pt/openhands.json +39 -2
- package/dist/locales/tr/openhands.json +39 -2
- package/dist/locales/uk/openhands.json +39 -2
- package/dist/locales/zh-CN/openhands.json +39 -2
- package/dist/locales/zh-TW/openhands.json +39 -2
- package/dist/node_modules/@openhands/typescript-client/dist/index.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/index.js +1 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.js +16 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/briefcase.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/building-2.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/building-2.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/building-2.js +27 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/building-2.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.js +21 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-arrow-up.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-user-round.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.js +43 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/cloud-cog.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/earth.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/earth.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/earth.js +25 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/earth.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/flag.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/flag.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/flag.js +9 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/flag.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.js +27 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-git-2.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.js +25 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/folder-key.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.js +30 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/git-pull-request.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/hash.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/hash.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/hash.js +35 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/hash.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/house.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/house.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/house.js +12 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/house.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/id-card.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/id-card.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/id-card.js +33 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/id-card.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/key-round.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/key-round.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/key-round.js +15 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/key-round.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/layers.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/layers.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/layers.js +19 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/layers.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/link-2.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/link-2.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/link-2.js +22 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/link-2.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/mails.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/mails.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/mails.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/mails.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.js +12 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/messages-square.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/plug.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/plug.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/plug.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/plug.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.js +27 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/square-kanban.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/ticket.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/ticket.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/ticket.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/ticket.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/users-round.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/users-round.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/users-round.js +21 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/users-round.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.js +43 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/waypoints.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/webhook.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/webhook.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/webhook.js +19 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/webhook.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/workflow.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/workflow.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/workflow.js +27 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/workflow.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/wrench.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/wrench.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/wrench.js +9 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/wrench.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/zap.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/zap.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/zap.js +9 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/zap.js.map +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +6 -3
- 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 +94 -93
- package/dist/routes/app-settings.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 +131 -119
- package/dist/routes/llm-settings.js.map +1 -1
- package/dist/services/child-conversation-launch.cjs +2 -0
- package/dist/services/child-conversation-launch.cjs.map +1 -0
- package/dist/services/child-conversation-launch.d.ts +41 -0
- package/dist/services/child-conversation-launch.js +182 -0
- package/dist/services/child-conversation-launch.js.map +1 -0
- package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
- package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
- package/dist/stores/conversation-panel-preferences-store.d.ts +5 -1
- package/dist/stores/conversation-panel-preferences-store.js +8 -2
- package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
- package/dist/types/agent-server/core/base/action.d.ts +17 -1
- package/dist/types/agent-server/core/base/base.d.ts +2 -1
- package/dist/types/agent-server/type-guards.cjs +1 -1
- package/dist/types/agent-server/type-guards.cjs.map +1 -1
- package/dist/types/agent-server/type-guards.d.ts +8 -1
- package/dist/types/agent-server/type-guards.js +4 -3
- package/dist/types/agent-server/type-guards.js.map +1 -1
- package/dist/types/automation.d.ts +14 -0
- package/dist/utils/custom-toast-handlers.cjs +1 -1
- package/dist/utils/custom-toast-handlers.cjs.map +1 -1
- package/dist/utils/custom-toast-handlers.js +18 -1
- package/dist/utils/custom-toast-handlers.js.map +1 -1
- package/dist/utils/format-model-name.cjs +1 -1
- package/dist/utils/format-model-name.cjs.map +1 -1
- package/dist/utils/format-model-name.d.ts +11 -0
- package/dist/utils/format-model-name.js +11 -3
- package/dist/utils/format-model-name.js.map +1 -1
- package/package.json +6 -3
- package/scripts/brand-dev-electron.mjs +244 -0
- package/scripts/check-translation-completeness.cjs +4 -0
- package/scripts/generate-icons.mjs +109 -0
- package/build/assets/agent-server-conversation-service.api-km_8sOVf.js +0 -41
- package/build/assets/agent-settings-nmO-KSXr.js +0 -1
- package/build/assets/app-settings-9ok42bV6.js +0 -1
- package/build/assets/command-menu-CA3IjGNc.js +0 -1
- package/build/assets/conversation-B6t6EiVp.js +0 -1
- package/build/assets/conversation-panel-B6t6EiVp.js +0 -1
- package/build/assets/copy-DaHuDtG4.js +0 -1
- package/build/assets/git-repo-dropdown-TzOuG5Ef.js +0 -1
- package/build/assets/home-OEx0XtfP.js +0 -1
- package/build/assets/index-home-OEx0XtfP.js +0 -1
- package/build/assets/install-server-modal-DnjZrJUy.js +0 -1
- package/build/assets/list-filter-C86CBRDE.js +0 -1
- package/build/assets/llm-not-configured-banner-DrBrhfN0.js +0 -27
- package/build/assets/llm-settings-CRsLqxgu.js +0 -1
- package/build/assets/llm-settings-RBm_3kNm.js +0 -1
- package/build/assets/manifest-c352d453.js +0 -1
- package/build/assets/map-provider-CXU6issd.js +0 -1
- package/build/assets/markdown-renderer-lsvsp7jn.js +0 -8
- package/build/assets/mcp-DD4hPTRE.js +0 -9
- package/build/assets/messages-Dt77e0qi.js +0 -40
- package/build/assets/recommended-automations-launcher-6xmbf7lh.js +0 -1
- package/build/assets/root-BeuHFY2s.css +0 -1
- package/build/assets/root-layout-Dl_2CDoq.js +0 -3
- package/build/assets/settings-Co-M5bK9.js +0 -1
- package/build/assets/sidebar-store-B04sX8aP.js +0 -1
- package/build/assets/skills-settings-DnbIu2eO.js +0 -2
- package/build/assets/use-settings-nav-items-y-Oyc93G.js +0 -16
- package/build/assets/utils-BX9XJ0IE.js +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.cjs +0 -2
- package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.cjs.map +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.js +0 -9
- package/dist/node_modules/lucide-react/dist/esm/icons/chevron-up.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-slash-command.js","names":[],"sources":["../../../src/hooks/chat/use-slash-command.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { SkillInfo } from \"#/types/settings\";\nimport { Microagent } from \"#/api/open-hands.types\";\nimport { BUILT_IN_COMMANDS, MODEL_COMMAND } from \"#/utils/constants\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\n\nexport type SlashCommandSkill = SkillInfo | Microagent;\n\nexport interface SlashCommandItem {\n skill: SlashCommandSkill;\n /** The slash command string, e.g. \"/random-number\" */\n command: string;\n}\n\ntype SlashCompletionKind = \"command\" | \"model-profile\";\n\n/** Get the cursor's character offset within a contentEditable element. */\nfunction getCursorOffset(element: HTMLElement): number {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return -1;\n const range = selection.getRangeAt(0);\n const preRange = range.cloneRange();\n preRange.selectNodeContents(element);\n preRange.setEnd(range.startContainer, range.startOffset);\n return preRange.toString().length;\n}\n\n/**\n * Hook for managing slash command autocomplete in the chat input.\n * Detects when user types \"/\" and provides filtered skill suggestions.\n * Only skills with explicit \"/\" triggers (TaskTrigger) appear in the menu.\n */\nexport const useSlashCommand = (\n chatInputRef: React.RefObject<HTMLDivElement | null>,\n) => {\n // Scope the skill catalog to this conversation's attached workspace so the\n // slash menu lists the same project skills that were loaded into it.\n const { data: skills, isLoading: isSkillsLoading } = useConversationSkills();\n const isCloud = useActiveBackend().backend.kind === \"cloud\";\n const { data: profilesData, isLoading: isProfilesLoading } = useLlmProfiles();\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n const [filterText, setFilterText] = useState(\"\");\n const [completionKind, setCompletionKind] =\n useState<SlashCompletionKind>(\"command\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n // Build slash command items from built-in commands + skills:\n // - Built-in commands (like /new) are included for V1 conversations\n // - /new is cloud-only — local backends don't surface it\n // - /model lists/switches LLM profiles; both local and cloud support them\n // - Skills with explicit \"/\" triggers use those triggers\n // - AgentSkills without \"/\" triggers get a derived \"/<name>\" command\n const slashItems = useMemo(() => {\n const items: SlashCommandItem[] = BUILT_IN_COMMANDS.filter((cmd) => {\n if (cmd.command === \"/new\") return isCloud;\n return true;\n });\n\n // Wait for skills to finish initial load so all commands appear together\n if (isSkillsLoading) return items;\n\n if (!skills) return items;\n skills.forEach((skill) => {\n const triggers = skill.triggers || [];\n const slashTriggers = triggers.filter((t) => t.startsWith(\"/\"));\n\n if (slashTriggers.length > 0) {\n // Skill has explicit slash triggers\n slashTriggers.forEach((trigger) => {\n items.push({ skill, command: trigger });\n });\n } else if (skill.type === \"agentskills\") {\n // AgentSkills without slash triggers get a derived command\n items.push({ skill, command: `/${skill.name}` });\n }\n });\n return items;\n }, [skills, isSkillsLoading, isCloud]);\n\n const modelProfileItems = useMemo<SlashCommandItem[]>(() => {\n return (profilesData?.profiles ?? []).map((profile) => {\n const command = `${MODEL_COMMAND} ${profile.name}`;\n return {\n command,\n skill: {\n name: profile.name,\n type: \"agentskills\",\n content: profile.model\n ? `Switch to ${profile.model}`\n : \"Switch to this LLM profile\",\n triggers: [command],\n },\n };\n });\n }, [profilesData?.profiles]);\n\n // Filter items based on user input after \"/\"\n const filteredItems = useMemo(() => {\n const sourceItems =\n completionKind === \"model-profile\" ? modelProfileItems : slashItems;\n if (!filterText) return sourceItems;\n const lower = filterText.toLowerCase();\n return sourceItems.filter(\n (item) =>\n item.command.toLowerCase().includes(lower) ||\n item.skill.name.toLowerCase().includes(lower) ||\n item.skill.content?.toLowerCase().includes(lower),\n );\n }, [completionKind, modelProfileItems, slashItems, filterText]);\n\n // Keep refs in sync so handleSlashKeyDown always reads the latest values,\n // avoiding stale closures from React's batched state updates.\n const isMenuOpenRef = useRef(isMenuOpen);\n isMenuOpenRef.current = isMenuOpen;\n const filteredItemsRef = useRef(filteredItems);\n filteredItemsRef.current = filteredItems;\n const selectedIndexRef = useRef(selectedIndex);\n selectedIndexRef.current = selectedIndex;\n\n // Reset selected index when the filter text changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [filterText]);\n\n // Track the character range of the current slash word so selectItem can\n // replace only that portion instead of wiping the entire input.\n const slashRangeRef = useRef<{ start: number; end: number } | null>(null);\n\n // Detect a slash word at the cursor position.\n // Returns the filter text (characters after \"/\") and the range of the\n // slash word within the full input text, or null if no slash word found.\n const getSlashText = useCallback((): {\n kind: SlashCompletionKind;\n text: string;\n start: number;\n end: number;\n } | null => {\n const element = chatInputRef.current;\n if (!element) return null;\n\n // Strip trailing newlines that contentEditable can produce, but preserve\n // spaces so \"/command \" (after selection) won't re-trigger the menu.\n const text = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const cursor = getCursorOffset(element);\n if (cursor < 0) return null;\n\n const textBeforeCursor = text.slice(0, cursor);\n\n const modelMatch = textBeforeCursor.match(/(^|\\s)(\\/model(?:\\s+\\S*)?)$/);\n if (modelMatch) {\n const modelCommand = modelMatch[2];\n const start = textBeforeCursor.length - modelCommand.length;\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return {\n kind: \"model-profile\",\n text: modelCommand.replace(/^\\/model(?:\\s+)?/, \"\"),\n start,\n end,\n };\n }\n\n // Match a \"/\" preceded by whitespace or at position 0, followed by\n // non-whitespace characters, ending right at the cursor.\n const match = textBeforeCursor.match(/(^|\\s)(\\/\\S*)$/);\n if (!match) return null;\n\n const slashWord = match[2]; // e.g. \"/hel\"\n const start = textBeforeCursor.length - slashWord.length;\n // The end of the slash word extends past the cursor to include any\n // contiguous non-whitespace characters (covers the case where the\n // cursor sits in the middle of a word).\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return { kind: \"command\", text: slashWord.slice(1), start, end }; // strip leading \"/\"\n }, [chatInputRef]);\n\n // Update the menu state based on current input\n const updateSlashMenu = useCallback(() => {\n const result = getSlashText();\n const hasItems =\n result?.kind === \"model-profile\"\n ? modelProfileItems.length > 0 || isProfilesLoading\n : slashItems.length > 0;\n\n if (result !== null && hasItems) {\n setCompletionKind(result.kind);\n setFilterText(result.text);\n slashRangeRef.current = { start: result.start, end: result.end };\n setIsMenuOpen(true);\n } else {\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n slashRangeRef.current = null;\n }\n }, [\n getSlashText,\n isProfilesLoading,\n modelProfileItems.length,\n slashItems.length,\n ]);\n\n // Select an item and replace only the slash word with the command\n const selectItem = useCallback(\n (item: SlashCommandItem) => {\n const element = chatInputRef.current;\n if (!element) return;\n\n const slashRange = slashRangeRef.current;\n const currentText = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const replacement = `${item.command} `;\n\n if (slashRange) {\n // Splice the command into the text, replacing only the slash word\n element.textContent =\n currentText.slice(0, slashRange.start) +\n replacement +\n currentText.slice(slashRange.end);\n\n // Position cursor right after the inserted command + space\n const cursorPos = slashRange.start + replacement.length;\n const textNode = element.firstChild;\n if (textNode) {\n const range = document.createRange();\n const sel = window.getSelection();\n const offset = Math.min(cursorPos, textNode.textContent!.length);\n range.setStart(textNode, offset);\n range.collapse(true);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n } else {\n // Fallback: replace everything (e.g. if range tracking failed)\n element.textContent = replacement;\n const range = document.createRange();\n const sel = window.getSelection();\n range.selectNodeContents(element);\n range.collapse(false);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n setSelectedIndex(0);\n slashRangeRef.current = null;\n\n // Trigger a native InputEvent so React's onInput fires (for smartResize etc.)\n element.dispatchEvent(new InputEvent(\"input\", { bubbles: true }));\n\n // Restore focus so keyboard events (Enter to submit) work after selection\n element.focus();\n },\n [chatInputRef],\n );\n\n // Handle keyboard navigation in the menu.\n // Uses refs to always read the latest state, avoiding stale closures.\n const handleSlashKeyDown = useCallback(\n (e: React.KeyboardEvent): boolean => {\n const items = filteredItemsRef.current;\n if (!isMenuOpenRef.current || items.length === 0) return false;\n\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev < items.length - 1 ? prev + 1 : 0));\n return true;\n case \"ArrowUp\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : items.length - 1));\n return true;\n case \"Enter\":\n case \"Tab\": {\n const item = items[selectedIndexRef.current];\n if (!item) return false;\n e.preventDefault();\n selectItem(item);\n return true;\n }\n case \"Escape\":\n e.preventDefault();\n setIsMenuOpen(false);\n return true;\n // Cursor-movement keys: close the menu to avoid acting on a stale\n // slash-word range, but don't consume the event so the cursor moves.\n case \"ArrowLeft\":\n case \"ArrowRight\":\n case \"Home\":\n case \"End\":\n setIsMenuOpen(false);\n return false;\n default:\n return false;\n }\n },\n [selectItem],\n );\n\n const closeMenu = useCallback(() => setIsMenuOpen(false), []);\n\n return {\n isMenuOpen,\n filteredItems,\n selectedIndex,\n updateSlashMenu,\n selectItem,\n handleSlashKeyDown,\n closeMenu,\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-slash-command.js","names":[],"sources":["../../../src/hooks/chat/use-slash-command.ts"],"sourcesContent":["import { useState, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useConversationSkills } from \"#/hooks/query/use-conversation-skills\";\nimport { SkillInfo } from \"#/types/settings\";\nimport { Microagent } from \"#/api/open-hands.types\";\nimport { BUILT_IN_COMMANDS, MODEL_COMMAND } from \"#/utils/constants\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useLlmProfiles } from \"#/hooks/query/use-llm-profiles\";\nimport { formatModelNameForDisplay } from \"#/utils/format-model-name\";\n\nexport type SlashCommandSkill = SkillInfo | Microagent;\n\nexport interface SlashCommandItem {\n skill: SlashCommandSkill;\n /** The slash command string, e.g. \"/random-number\" */\n command: string;\n}\n\ntype SlashCompletionKind = \"command\" | \"model-profile\";\n\n/** Get the cursor's character offset within a contentEditable element. */\nfunction getCursorOffset(element: HTMLElement): number {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return -1;\n const range = selection.getRangeAt(0);\n const preRange = range.cloneRange();\n preRange.selectNodeContents(element);\n preRange.setEnd(range.startContainer, range.startOffset);\n return preRange.toString().length;\n}\n\n/**\n * Hook for managing slash command autocomplete in the chat input.\n * Detects when user types \"/\" and provides filtered skill suggestions.\n * Only skills with explicit \"/\" triggers (TaskTrigger) appear in the menu.\n */\nexport const useSlashCommand = (\n chatInputRef: React.RefObject<HTMLDivElement | null>,\n) => {\n // Scope the skill catalog to this conversation's attached workspace so the\n // slash menu lists the same project skills that were loaded into it.\n const { data: skills, isLoading: isSkillsLoading } = useConversationSkills();\n const isCloud = useActiveBackend().backend.kind === \"cloud\";\n const { data: profilesData, isLoading: isProfilesLoading } = useLlmProfiles();\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n const [filterText, setFilterText] = useState(\"\");\n const [completionKind, setCompletionKind] =\n useState<SlashCompletionKind>(\"command\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n\n // Build slash command items from built-in commands + skills:\n // - Built-in commands (like /new) are included for V1 conversations\n // - /new is cloud-only — local backends don't surface it\n // - /model lists/switches LLM profiles; both local and cloud support them\n // - Skills with explicit \"/\" triggers use those triggers\n // - AgentSkills without \"/\" triggers get a derived \"/<name>\" command\n const slashItems = useMemo(() => {\n const items: SlashCommandItem[] = BUILT_IN_COMMANDS.filter((cmd) => {\n if (cmd.command === \"/new\") return isCloud;\n return true;\n });\n\n // Wait for skills to finish initial load so all commands appear together\n if (isSkillsLoading) return items;\n\n if (!skills) return items;\n skills.forEach((skill) => {\n const triggers = skill.triggers || [];\n const slashTriggers = triggers.filter((t) => t.startsWith(\"/\"));\n\n if (slashTriggers.length > 0) {\n // Skill has explicit slash triggers\n slashTriggers.forEach((trigger) => {\n items.push({ skill, command: trigger });\n });\n } else if (skill.type === \"agentskills\") {\n // AgentSkills without slash triggers get a derived command\n items.push({ skill, command: `/${skill.name}` });\n }\n });\n return items;\n }, [skills, isSkillsLoading, isCloud]);\n\n const modelProfileItems = useMemo<SlashCommandItem[]>(() => {\n return (profilesData?.profiles ?? []).map((profile) => {\n const command = `${MODEL_COMMAND} ${profile.name}`;\n return {\n command,\n skill: {\n name: profile.name,\n type: \"agentskills\",\n content: profile.model\n ? `Switch to ${formatModelNameForDisplay(profile.model)}`\n : \"Switch to this LLM profile\",\n triggers: [command],\n },\n };\n });\n }, [profilesData?.profiles]);\n\n // Filter items based on user input after \"/\"\n const filteredItems = useMemo(() => {\n const sourceItems =\n completionKind === \"model-profile\" ? modelProfileItems : slashItems;\n if (!filterText) return sourceItems;\n const lower = filterText.toLowerCase();\n return sourceItems.filter(\n (item) =>\n item.command.toLowerCase().includes(lower) ||\n item.skill.name.toLowerCase().includes(lower) ||\n item.skill.content?.toLowerCase().includes(lower),\n );\n }, [completionKind, modelProfileItems, slashItems, filterText]);\n\n // Keep refs in sync so handleSlashKeyDown always reads the latest values,\n // avoiding stale closures from React's batched state updates.\n const isMenuOpenRef = useRef(isMenuOpen);\n isMenuOpenRef.current = isMenuOpen;\n const filteredItemsRef = useRef(filteredItems);\n filteredItemsRef.current = filteredItems;\n const selectedIndexRef = useRef(selectedIndex);\n selectedIndexRef.current = selectedIndex;\n\n // Reset selected index when the filter text changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [filterText]);\n\n // Track the character range of the current slash word so selectItem can\n // replace only that portion instead of wiping the entire input.\n const slashRangeRef = useRef<{ start: number; end: number } | null>(null);\n\n // Detect a slash word at the cursor position.\n // Returns the filter text (characters after \"/\") and the range of the\n // slash word within the full input text, or null if no slash word found.\n const getSlashText = useCallback((): {\n kind: SlashCompletionKind;\n text: string;\n start: number;\n end: number;\n } | null => {\n const element = chatInputRef.current;\n if (!element) return null;\n\n // Strip trailing newlines that contentEditable can produce, but preserve\n // spaces so \"/command \" (after selection) won't re-trigger the menu.\n const text = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const cursor = getCursorOffset(element);\n if (cursor < 0) return null;\n\n const textBeforeCursor = text.slice(0, cursor);\n\n const modelMatch = textBeforeCursor.match(/(^|\\s)(\\/model(?:\\s+\\S*)?)$/);\n if (modelMatch) {\n const modelCommand = modelMatch[2];\n const start = textBeforeCursor.length - modelCommand.length;\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return {\n kind: \"model-profile\",\n text: modelCommand.replace(/^\\/model(?:\\s+)?/, \"\"),\n start,\n end,\n };\n }\n\n // Match a \"/\" preceded by whitespace or at position 0, followed by\n // non-whitespace characters, ending right at the cursor.\n const match = textBeforeCursor.match(/(^|\\s)(\\/\\S*)$/);\n if (!match) return null;\n\n const slashWord = match[2]; // e.g. \"/hel\"\n const start = textBeforeCursor.length - slashWord.length;\n // The end of the slash word extends past the cursor to include any\n // contiguous non-whitespace characters (covers the case where the\n // cursor sits in the middle of a word).\n const afterCursor = text.slice(cursor);\n const trailing = afterCursor.match(/^\\S*/);\n const end = cursor + (trailing ? trailing[0].length : 0);\n\n return { kind: \"command\", text: slashWord.slice(1), start, end }; // strip leading \"/\"\n }, [chatInputRef]);\n\n // Update the menu state based on current input\n const updateSlashMenu = useCallback(() => {\n const result = getSlashText();\n const hasItems =\n result?.kind === \"model-profile\"\n ? modelProfileItems.length > 0 || isProfilesLoading\n : slashItems.length > 0;\n\n if (result !== null && hasItems) {\n setCompletionKind(result.kind);\n setFilterText(result.text);\n slashRangeRef.current = { start: result.start, end: result.end };\n setIsMenuOpen(true);\n } else {\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n slashRangeRef.current = null;\n }\n }, [\n getSlashText,\n isProfilesLoading,\n modelProfileItems.length,\n slashItems.length,\n ]);\n\n // Select an item and replace only the slash word with the command\n const selectItem = useCallback(\n (item: SlashCommandItem) => {\n const element = chatInputRef.current;\n if (!element) return;\n\n const slashRange = slashRangeRef.current;\n const currentText = (element.innerText || \"\").replace(/[\\n\\r]+$/, \"\");\n const replacement = `${item.command} `;\n\n if (slashRange) {\n // Splice the command into the text, replacing only the slash word\n element.textContent =\n currentText.slice(0, slashRange.start) +\n replacement +\n currentText.slice(slashRange.end);\n\n // Position cursor right after the inserted command + space\n const cursorPos = slashRange.start + replacement.length;\n const textNode = element.firstChild;\n if (textNode) {\n const range = document.createRange();\n const sel = window.getSelection();\n const offset = Math.min(cursorPos, textNode.textContent!.length);\n range.setStart(textNode, offset);\n range.collapse(true);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n } else {\n // Fallback: replace everything (e.g. if range tracking failed)\n element.textContent = replacement;\n const range = document.createRange();\n const sel = window.getSelection();\n range.selectNodeContents(element);\n range.collapse(false);\n sel?.removeAllRanges();\n sel?.addRange(range);\n }\n\n setIsMenuOpen(false);\n setFilterText(\"\");\n setCompletionKind(\"command\");\n setSelectedIndex(0);\n slashRangeRef.current = null;\n\n // Trigger a native InputEvent so React's onInput fires (for smartResize etc.)\n element.dispatchEvent(new InputEvent(\"input\", { bubbles: true }));\n\n // Restore focus so keyboard events (Enter to submit) work after selection\n element.focus();\n },\n [chatInputRef],\n );\n\n // Handle keyboard navigation in the menu.\n // Uses refs to always read the latest state, avoiding stale closures.\n const handleSlashKeyDown = useCallback(\n (e: React.KeyboardEvent): boolean => {\n const items = filteredItemsRef.current;\n if (!isMenuOpenRef.current || items.length === 0) return false;\n\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev < items.length - 1 ? prev + 1 : 0));\n return true;\n case \"ArrowUp\":\n e.preventDefault();\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : items.length - 1));\n return true;\n case \"Enter\":\n case \"Tab\": {\n const item = items[selectedIndexRef.current];\n if (!item) return false;\n e.preventDefault();\n selectItem(item);\n return true;\n }\n case \"Escape\":\n e.preventDefault();\n setIsMenuOpen(false);\n return true;\n // Cursor-movement keys: close the menu to avoid acting on a stale\n // slash-word range, but don't consume the event so the cursor moves.\n case \"ArrowLeft\":\n case \"ArrowRight\":\n case \"Home\":\n case \"End\":\n setIsMenuOpen(false);\n return false;\n default:\n return false;\n }\n },\n [selectItem],\n );\n\n const closeMenu = useCallback(() => setIsMenuOpen(false), []);\n\n return {\n isMenuOpen,\n filteredItems,\n selectedIndex,\n updateSlashMenu,\n selectItem,\n handleSlashKeyDown,\n closeMenu,\n };\n};\n"],"mappings":";;;;;;;AAoBA,SAAS,EAAgB,GAA8B;CACrD,IAAM,IAAY,OAAO,aAAa;CACtC,IAAI,CAAC,KAAa,EAAU,eAAe,GAAG,OAAO;CACrD,IAAM,IAAQ,EAAU,WAAW,CAAC,GAC9B,IAAW,EAAM,WAAW;CAGlC,OAFA,EAAS,mBAAmB,CAAO,GACnC,EAAS,OAAO,EAAM,gBAAgB,EAAM,WAAW,GAChD,EAAS,SAAS,EAAE;AAC7B;AAOA,IAAa,KACX,MACG;CAGH,IAAM,EAAE,MAAM,GAAQ,WAAW,MAAoB,EAAsB,GACrE,IAAU,EAAiB,EAAE,QAAQ,SAAS,SAC9C,EAAE,MAAM,GAAc,WAAW,MAAsB,EAAe,GACtE,CAAC,GAAY,KAAiB,EAAS,EAAK,GAC5C,CAAC,GAAY,KAAiB,EAAS,EAAE,GACzC,CAAC,GAAgB,KACrB,EAA8B,SAAS,GACnC,CAAC,GAAe,KAAoB,EAAS,CAAC,GAQ9C,IAAa,QAAc;EAC/B,IAAM,IAA4B,EAAkB,QAAQ,MACtD,EAAI,YAAY,SAAe,IAC5B,EACR;EAoBD,OAjBI,KAEA,CAAC,KACL,EAAO,SAAS,MAAU;GAExB,IAAM,KADW,EAAM,YAAY,CAAC,GACL,QAAQ,MAAM,EAAE,WAAW,GAAG,CAAC;GAE9D,AAAI,EAAc,SAAS,IAEzB,EAAc,SAAS,MAAY;IACjC,EAAM,KAAK;KAAE;KAAO,SAAS;IAAQ,CAAC;GACxC,CAAC,IACQ,EAAM,SAAS,iBAExB,EAAM,KAAK;IAAE;IAAO,SAAS,IAAI,EAAM;GAAO,CAAC;EAEnD,CAAC,GAdmB;CAgBtB,GAAG;EAAC;EAAQ;EAAiB;CAAO,CAAC,GAE/B,IAAoB,SAChB,GAAc,YAAY,CAAC,GAAG,KAAK,MAAY;EACrD,IAAM,IAAU,GAAG,EAAc,GAAG,EAAQ;EAC5C,OAAO;GACL;GACA,OAAO;IACL,MAAM,EAAQ;IACd,MAAM;IACN,SAAS,EAAQ,QACb,aAAa,EAA0B,EAAQ,KAAK,MACpD;IACJ,UAAU,CAAC,CAAO;GACpB;EACF;CACF,CAAC,GACA,CAAC,GAAc,QAAQ,CAAC,GAGrB,IAAgB,QAAc;EAClC,IAAM,IACJ,MAAmB,kBAAkB,IAAoB;EAC3D,IAAI,CAAC,GAAY,OAAO;EACxB,IAAM,IAAQ,EAAW,YAAY;EACrC,OAAO,EAAY,QAChB,MACC,EAAK,QAAQ,YAAY,EAAE,SAAS,CAAK,KACzC,EAAK,MAAM,KAAK,YAAY,EAAE,SAAS,CAAK,KAC5C,EAAK,MAAM,SAAS,YAAY,EAAE,SAAS,CAAK,CACpD;CACF,GAAG;EAAC;EAAgB;EAAmB;EAAY;CAAU,CAAC,GAIxD,IAAgB,EAAO,CAAU;CACvC,EAAc,UAAU;CACxB,IAAM,IAAmB,EAAO,CAAa;CAC7C,EAAiB,UAAU;CAC3B,IAAM,IAAmB,EAAO,CAAa;CAI7C,AAHA,EAAiB,UAAU,GAG3B,QAAgB;EACd,EAAiB,CAAC;CACpB,GAAG,CAAC,CAAU,CAAC;CAIf,IAAM,IAAgB,EAA8C,IAAI,GAKlE,IAAe,QAKT;EACV,IAAM,IAAU,EAAa;EAC7B,IAAI,CAAC,GAAS,OAAO;EAIrB,IAAM,KAAQ,EAAQ,aAAa,IAAI,QAAQ,YAAY,EAAE,GACvD,IAAS,EAAgB,CAAO;EACtC,IAAI,IAAS,GAAG,OAAO;EAEvB,IAAM,IAAmB,EAAK,MAAM,GAAG,CAAM,GAEvC,IAAa,EAAiB,MAAM,6BAA6B;EACvE,IAAI,GAAY;GACd,IAAM,IAAe,EAAW,IAC1B,IAAQ,EAAiB,SAAS,EAAa,QAE/C,IADc,EAAK,MAAM,CACd,EAAY,MAAM,MAAM,GACnC,IAAM,KAAU,IAAW,EAAS,GAAG,SAAS;GAEtD,OAAO;IACL,MAAM;IACN,MAAM,EAAa,QAAQ,oBAAoB,EAAE;IACjD;IACA;GACF;EACF;EAIA,IAAM,IAAQ,EAAiB,MAAM,gBAAgB;EACrD,IAAI,CAAC,GAAO,OAAO;EAEnB,IAAM,IAAY,EAAM,IAClB,IAAQ,EAAiB,SAAS,EAAU,QAK5C,IADc,EAAK,MAAM,CACd,EAAY,MAAM,MAAM,GACnC,IAAM,KAAU,IAAW,EAAS,GAAG,SAAS;EAEtD,OAAO;GAAE,MAAM;GAAW,MAAM,EAAU,MAAM,CAAC;GAAG;GAAO;EAAI;CACjE,GAAG,CAAC,CAAY,CAAC,GAGX,IAAkB,QAAkB;EACxC,IAAM,IAAS,EAAa,GACtB,IACJ,GAAQ,SAAS,kBACb,EAAkB,SAAS,KAAK,IAChC,EAAW,SAAS;EAE1B,AAAI,MAAW,QAAQ,KACrB,EAAkB,EAAO,IAAI,GAC7B,EAAc,EAAO,IAAI,GACzB,EAAc,UAAU;GAAE,OAAO,EAAO;GAAO,KAAK,EAAO;EAAI,GAC/D,EAAc,EAAI,MAElB,EAAc,EAAK,GACnB,EAAc,EAAE,GAChB,EAAkB,SAAS,GAC3B,EAAc,UAAU;CAE5B,GAAG;EACD;EACA;EACA,EAAkB;EAClB,EAAW;CACb,CAAC,GAGK,IAAa,GAChB,MAA2B;EAC1B,IAAM,IAAU,EAAa;EAC7B,IAAI,CAAC,GAAS;EAEd,IAAM,IAAa,EAAc,SAC3B,KAAe,EAAQ,aAAa,IAAI,QAAQ,YAAY,EAAE,GAC9D,IAAc,GAAG,EAAK,QAAQ;EAEpC,IAAI,GAAY;GAEd,EAAQ,cACN,EAAY,MAAM,GAAG,EAAW,KAAK,IACrC,IACA,EAAY,MAAM,EAAW,GAAG;GAGlC,IAAM,IAAY,EAAW,QAAQ,EAAY,QAC3C,IAAW,EAAQ;GACzB,IAAI,GAAU;IACZ,IAAM,IAAQ,SAAS,YAAY,GAC7B,IAAM,OAAO,aAAa,GAC1B,IAAS,KAAK,IAAI,GAAW,EAAS,YAAa,MAAM;IAI/D,AAHA,EAAM,SAAS,GAAU,CAAM,GAC/B,EAAM,SAAS,EAAI,GACnB,GAAK,gBAAgB,GACrB,GAAK,SAAS,CAAK;GACrB;EACF,OAAO;GAEL,EAAQ,cAAc;GACtB,IAAM,IAAQ,SAAS,YAAY,GAC7B,IAAM,OAAO,aAAa;GAIhC,AAHA,EAAM,mBAAmB,CAAO,GAChC,EAAM,SAAS,EAAK,GACpB,GAAK,gBAAgB,GACrB,GAAK,SAAS,CAAK;EACrB;EAYA,AAVA,EAAc,EAAK,GACnB,EAAc,EAAE,GAChB,EAAkB,SAAS,GAC3B,EAAiB,CAAC,GAClB,EAAc,UAAU,MAGxB,EAAQ,cAAc,IAAI,WAAW,SAAS,EAAE,SAAS,GAAK,CAAC,CAAC,GAGhE,EAAQ,MAAM;CAChB,GACA,CAAC,CAAY,CACf;CA+CA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA,oBAjDyB,GACxB,MAAoC;GACnC,IAAM,IAAQ,EAAiB;GAC/B,IAAI,CAAC,EAAc,WAAW,EAAM,WAAW,GAAG,OAAO;GAEzD,QAAQ,EAAE,KAAV;IACE,KAAK,aAGH,OAFA,EAAE,eAAe,GACjB,GAAkB,MAAU,IAAO,EAAM,SAAS,IAAI,IAAO,IAAI,CAAE,GAC5D;IACT,KAAK,WAGH,OAFA,EAAE,eAAe,GACjB,GAAkB,MAAU,IAAO,IAAI,IAAO,IAAI,EAAM,SAAS,CAAE,GAC5D;IACT,KAAK;IACL,KAAK,OAAO;KACV,IAAM,IAAO,EAAM,EAAiB;KAIpC,OAHK,KACL,EAAE,eAAe,GACjB,EAAW,CAAI,GACR,MAHW;IAIpB;IACA,KAAK,UAGH,OAFA,EAAE,eAAe,GACjB,EAAc,EAAK,GACZ;IAGT,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK,OAEH,OADA,EAAc,EAAK,GACZ;IACT,SACE,OAAO;GACX;EACF,GACA,CAAC,CAAU,CAWX;EACA,WATgB,QAAkB,EAAc,EAAK,GAAG,CAAC,CASzD;CACF;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../../_virtual/_rolldown/runtime.cjs");const e=require("../query/query-keys.cjs"),t=require("../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),n=require("../../node_modules/@tanstack/react-query/build/modern/useMutation.cjs"),r=require("../../contexts/active-backend-context.cjs"),i=require("../../api/
|
|
1
|
+
require("../../_virtual/_rolldown/runtime.cjs");const e=require("../query/query-keys.cjs"),t=require("../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs"),n=require("../../node_modules/@tanstack/react-query/build/modern/useMutation.cjs"),r=require("../../contexts/active-backend-context.cjs"),i=require("../../api/conversation-metadata-store.cjs"),a=require("../../api/profiles-service/profiles-service.api.cjs"),o=require("../../api/conversation-service/agent-server-conversation-service.api.cjs"),s=require("../use-tracking.cjs"),c=require("../query/use-llm-profiles.cjs"),l=require("../../api/agent-profiles-service/agent-profiles-service.api.cjs"),u=require("../query/use-agent-profiles.cjs"),d=require("../../api/plugins-management-service.cjs"),f=require("../../utils/plugin-display.cjs");var p=[`create-conversation`],m=()=>{let m=t.useQueryClient(),{trackConversationCreated:h}=s.useTracking(),{data:g}=c.useLlmProfiles(),{backend:_,orgId:v}=r.useActiveBackend();return u.useAgentProfiles(),n.useMutation({mutationKey:p,mutationFn:async t=>{let{query:n,conversationInstructions:r,plugins:s,repository:c,workingDir:u,workspaceMode:p,parentConversationId:h,agentType:y,agentProfileId:b}=t,x;try{x=await m.ensureQueryData({queryKey:[...e.AGENT_PROFILES_QUERY_KEYS.all,_.id,v],queryFn:l.default.listProfiles,...e.AGENT_PROFILES_RETRY_OPTIONS})}catch{}let S=b??x?.active_agent_profile_id??void 0,C=S?x?.profiles?.find(e=>e.id===S):void 0,w=_.kind===`cloud`,T=S;if(!w&&C?.name==="default"&&C?.agent_kind===`openhands`)T=void 0;else if(C?.agent_kind===`openhands`&&C.llm_profile_ref){let t=!1;try{t=(await m.ensureQueryData({queryKey:[...e.LLM_PROFILES_QUERY_KEYS.all,_.id,v],queryFn:a.default.listProfiles,retry:!1})).profiles.some(e=>e.name===C.llm_profile_ref)}catch{}t||(console.warn(`Agent profile "${C.name}" references missing LLM profile "${C.llm_profile_ref}"; launching from agent_settings instead.`),T=void 0)}let E=T?[void 0,T,C?.agent_kind]:[],D=await o.default.createConversation(n,r,s,c?{selected_repository:c.name,selected_branch:c.branch??null,git_provider:c.gitProvider}:null,u,p,h,y,...E),O=D.app_conversation_id,k=s?.map(i.toPluginCoordinates)??[],A=k;if(O){let t=[];try{t=await m.ensureQueryData({queryKey:e.PLUGINS_QUERY_KEYS.installed,queryFn:()=>d.default.listInstalledPlugins()})}catch{}let n=new Set(k.map(f.pluginReferenceKey)),r=t.filter(e=>e.enabled).map(e=>({source:e.source,ref:e.resolved_ref??null,repo_path:e.repo_path??null,name:e.name})).filter(e=>!n.has(f.pluginReferenceKey(e)));A=[...k,...r]}let j=T&&C?.agent_kind===`openhands`?C.llm_profile_ref:g?.active_profile??null;if(O&&(j||A.length)){let e=i.getStoredConversationMetadata(O);i.setStoredConversationMetadata(O,{selected_repository:e?.selected_repository??null,selected_branch:e?.selected_branch??null,git_provider:e?.git_provider??null,selected_workspace:e?.selected_workspace??null,workspace_mode:e?.workspace_mode??null,active_profile:j??e?.active_profile??null,plugins:A.length?A:e?.plugins??null})}return{conversation_id:D.app_conversation_id?D.app_conversation_id:`task-${D.id}`,session_api_key:null,url:D.agent_server_url,task_id:D.id}},onSuccess:async(e,t)=>{h({conversationId:e.conversation_id,taskId:e.task_id,hasRepository:!!t.repository,gitProvider:t.repository?.gitProvider,hasWorkspace:!!t.workingDir,workspaceMode:t.workspaceMode,hasInitialQuery:!!t.query,agentType:t.agentType,hasParentConversation:!!t.parentConversationId,entryPoint:t.entryPoint}),m.invalidateQueries({queryKey:[`user`,`conversations`]}),m.invalidateQueries({queryKey:[`start-tasks`]})}})};exports.CREATE_CONVERSATION_MUTATION_KEY=p,exports.useCreateConversation=m;
|
|
2
2
|
//# sourceMappingURL=use-create-conversation.cjs.map
|
|
@@ -2,8 +2,8 @@ import { AGENT_PROFILES_QUERY_KEYS as e, AGENT_PROFILES_RETRY_OPTIONS as t, LLM_
|
|
|
2
2
|
import { useQueryClient as i } from "../../node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js";
|
|
3
3
|
import { useMutation as a } from "../../node_modules/@tanstack/react-query/build/modern/useMutation.js";
|
|
4
4
|
import { useActiveBackend as o } from "../../contexts/active-backend-context.js";
|
|
5
|
-
import s from "../../api/
|
|
6
|
-
import
|
|
5
|
+
import { getStoredConversationMetadata as s, setStoredConversationMetadata as c, toPluginCoordinates as l } from "../../api/conversation-metadata-store.js";
|
|
6
|
+
import u from "../../api/profiles-service/profiles-service.api.js";
|
|
7
7
|
import d from "../../api/conversation-service/agent-server-conversation-service.api.js";
|
|
8
8
|
import { useTracking as f } from "../use-tracking.js";
|
|
9
9
|
import { useLlmProfiles as p } from "../query/use-llm-profiles.js";
|
|
@@ -40,7 +40,7 @@ var v = ["create-conversation"], y = () => {
|
|
|
40
40
|
S.id,
|
|
41
41
|
C
|
|
42
42
|
],
|
|
43
|
-
queryFn:
|
|
43
|
+
queryFn: u.listProfiles,
|
|
44
44
|
retry: !1
|
|
45
45
|
})).profiles.some((e) => e.name === O.llm_profile_ref);
|
|
46
46
|
} catch {}
|
|
@@ -54,7 +54,7 @@ var v = ["create-conversation"], y = () => {
|
|
|
54
54
|
selected_repository: p.name,
|
|
55
55
|
selected_branch: p.branch ?? null,
|
|
56
56
|
git_provider: p.gitProvider
|
|
57
|
-
} : null, h, v, b, w, ...j), N = M.app_conversation_id, P = f?.map(
|
|
57
|
+
} : null, h, v, b, w, ...j), N = M.app_conversation_id, P = f?.map(l) ?? [], F = P;
|
|
58
58
|
if (N) {
|
|
59
59
|
let e = [];
|
|
60
60
|
try {
|
|
@@ -73,8 +73,8 @@ var v = ["create-conversation"], y = () => {
|
|
|
73
73
|
}
|
|
74
74
|
let I = A && O?.agent_kind === "openhands" ? O.llm_profile_ref : x?.active_profile ?? null;
|
|
75
75
|
if (N && (I || F.length)) {
|
|
76
|
-
let e =
|
|
77
|
-
|
|
76
|
+
let e = s(N);
|
|
77
|
+
c(N, {
|
|
78
78
|
selected_repository: e?.selected_repository ?? null,
|
|
79
79
|
selected_branch: e?.selected_branch ?? null,
|
|
80
80
|
git_provider: e?.git_provider ?? null,
|