@openhands/agent-canvas 1.16.0 → 1.18.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-CX3Lh9gj.js → acp-providers-DcY_mKYa.js} +1 -1
- package/build/assets/active-backend-context-BnH4-L8h.js +2 -0
- package/build/assets/{agent-context-settings-DSZlXrLj.js → agent-context-settings-D3peZkjX.js} +1 -1
- package/build/assets/agent-profiles-service.api-DkeZaqIl.js +1 -0
- package/build/assets/agent-profiles-settings-7yMWYjGF.js +1 -0
- package/build/assets/agent-server-client-options-EHB23gyx.js +1 -0
- package/build/assets/agent-server-config-C_x8Otd9.js +1 -0
- package/build/assets/agent-server-conversation-service.api-jiCopc2E.js +88 -0
- package/build/assets/agent-settings-BF8hM6wb.js +2 -0
- package/build/assets/agent-settings-YPutBAeR.js +1 -0
- package/build/assets/alert-banner-eYyqvHL3.js +1 -0
- package/build/assets/{api-error-message-B-XdSk3b.js → api-error-message-BXo0lCI5.js} +1 -1
- package/build/assets/api-key-entry-screen-CCBvBD8u.js +1 -0
- package/build/assets/app-settings-BtYDs-Be.js +1 -0
- package/build/assets/automation-detail-BxXhb_m2.js +3 -0
- package/build/assets/{automation-export-D3a3of4G.js → automation-export-BJsfi7n2.js} +1 -1
- package/build/assets/automation-git-sync-B7o_Nbl-.js +1 -0
- package/build/assets/automation-setup-route-qaJ6lLCf.js +3 -0
- package/build/assets/{automation-templates-BRppNh99.js → automation-templates-Bb98r-kx.js} +1 -1
- package/build/assets/automations-list-DEPVNud3.js +1 -0
- package/build/assets/{back-nav-button-Cjl_hoxq.js → back-nav-button-B2yBiVMB.js} +1 -1
- package/build/assets/backend-form-modal-DxisQV_6.js +1 -0
- package/build/assets/backend-synced-settings-badge-DLEp6cq7.js +1 -0
- package/build/assets/badge-ehL-kgeO.js +1 -0
- package/build/assets/{base-modal-D_L0oEbG.js → base-modal-C1a0TsSx.js} +1 -1
- package/build/assets/bot-ByolqPEr.js +1 -0
- package/build/assets/{brand-button-BAfk4wGP.js → brand-button-CUMfjb99.js} +1 -1
- package/build/assets/browser-SE24Tk8g.js +46 -0
- package/build/assets/browser-tab-HjJxHA0V.js +1 -0
- package/build/assets/canvas-extension-page-BsUGBb1T.js +1 -0
- package/build/assets/canvas-extensions-C9Tm6s_E.js +1 -0
- package/build/assets/{canvas-extensions-runtime-2_x5Ezmi.js → canvas-extensions-runtime-B8kxM4rO.js} +1 -1
- package/build/assets/{chat-send-button-MUQqCZCS.js → chat-send-button-CGvc2wpE.js} +1 -1
- package/build/assets/check-Bo8s5Ylg.js +1 -0
- package/build/assets/chevron-down-Cr6Fn_wS.js +1 -0
- package/build/assets/chevron-right-CfdfRn-8.js +1 -0
- package/build/assets/circle-check-5pH3qCji.js +1 -0
- package/build/assets/circle-plus-check-toggle-BDX_ctNs.js +1 -0
- package/build/assets/{cloud-funnel-analytics-CztBCCPp.js → cloud-funnel-analytics-D5uJ_4JE.js} +1 -1
- package/build/assets/{cog-D-MPQW6G.js → cog-CAEugqtV.js} +1 -1
- package/build/assets/command-menu-CQxs4mtX.js +1 -0
- package/build/assets/commits-tab-D0xgjipP.js +1 -0
- package/build/assets/{condenser-settings-DmEOje-7.js → condenser-settings-D63NJRBT.js} +1 -1
- package/build/assets/confirmation-modal-78sd9Vny.js +1 -0
- package/build/assets/{context-menu-list-item-I86vKcmM.js → context-menu-list-item-Cm7-7Y-7.js} +1 -1
- package/build/assets/conversation-B_nweu5p.js +93 -0
- package/build/assets/conversation-edjzrv5w.js +1 -0
- package/build/assets/conversation-panel-edjzrv5w.js +1 -0
- package/build/assets/conversation-state-store-9D_3P7q4.js +1 -0
- package/build/assets/conversation-store-DC-JlJuq.js +6 -0
- package/build/assets/{conversation-tab-empty-state-FIbh_lc8.js → conversation-tab-empty-state-B3dpJXX0.js} +1 -1
- package/build/assets/copy-to-clipboard-button-B1ljgNxO.js +1 -0
- package/build/assets/device-verify-D5QRIS_x.js +1 -0
- package/build/assets/{dropdown-classes-Bc1djN0-.js → dropdown-classes-BGvOvW2_.js} +1 -1
- package/build/assets/edit-automation-modal-D_JWSmxT.js +1 -0
- package/build/assets/empty-state-FK_s1B60.js +1 -0
- package/build/assets/{entry.client-CqyPPjOq.js → entry.client-BMafTpjO.js} +2 -2
- package/build/assets/enum-filter-dropdown-UNaom12H.js +1 -0
- package/build/assets/environment-switch-overlay-COibRUA-.js +1 -0
- package/build/assets/error-state-Cf8LRuuY.js +1 -0
- package/build/assets/extensions-hub-C_6ahIua.js +1 -0
- package/build/assets/extensions-navigation-C5GfpzFe.js +1 -0
- package/build/assets/external-link-Bd7Tga-1.js +1 -0
- package/build/assets/files-tab-D5PPIWI1.js +1 -0
- package/build/assets/{form-control-classes-Bkh5FGrD.js → form-control-classes-Dbq-7YP_.js} +1 -1
- package/build/assets/format-model-name-Dfh9Udrx.js +1 -0
- package/build/assets/get-git-path-jU2zjqIB.js +1 -0
- package/build/assets/git-repo-dropdown-BoDDWXfX.js +1 -0
- package/build/assets/git-repo-dropdown-uxlFw2gn.js +1 -0
- package/build/assets/highlighted-source-view-C7pAXrT0.js +1 -0
- package/build/assets/home-BM5_Wz_R.js +1 -0
- package/build/assets/home-Ivfm7KC4.js +1 -0
- package/build/assets/home-automation-run-tooltip-B1N2uO9p.js +1 -0
- package/build/assets/home-store-DCbei3DX.js +1 -0
- package/build/assets/hooks-service-Dnmhqc0Z.js +1 -0
- package/build/assets/index-home-td9BN2T3.js +1 -0
- package/build/assets/info-BcajzHn1.js +1 -0
- package/build/assets/install-server-modal-B81I-5OE.js +1 -0
- package/build/assets/kebab-menu-item-content-SCJBwZnp.js +1 -0
- package/build/assets/{key-BmVyxs-2.js → key-O84CMFHb.js} +1 -1
- package/build/assets/launch-ZLxI4opd.js +1 -0
- package/build/assets/list-filter-B8PQk3RA.js +1 -0
- package/build/assets/{list-todo-apgLVjMw.js → list-todo-Caa8E1X_.js} +1 -1
- package/build/assets/llm-not-configured-banner-Dh_ajcM8.js +27 -0
- package/build/assets/llm-settings-CODhjQzy.js +1 -0
- package/build/assets/llm-settings-CZaXYgtw.js +1 -0
- package/build/assets/llm-subscription-service-CgIDc38n.js +1 -0
- package/build/assets/loader-circle-BxJgk73D.js +1 -0
- package/build/assets/{loading-spinner-BY9N3pOe.js → loading-spinner-BeLV0IXf.js} +1 -1
- package/build/assets/manage-backends-modal-cMXqCb-B.js +1 -0
- package/build/assets/manifest-bfeccb98.js +1 -0
- package/build/assets/manifest-subpage-layout-CVZgVKoY.js +1 -0
- package/build/assets/{map-provider-Cu3Zgumb.js → map-provider-iRs80q_6.js} +1 -1
- package/build/assets/markdown-renderer-DyFl9-mL.js +8 -0
- package/build/assets/mcp-CraxoXQv.js +1 -0
- package/build/assets/{mcp-marketplace-utils-AIBzzHTO.js → mcp-marketplace-utils-C7PYr293.js} +1 -1
- package/build/assets/mcp-page-CteH_K0N.js +9 -0
- package/build/assets/messages-Bk1xhbU2.js +41 -0
- package/build/assets/{modal-body-BxZjsju9.js → modal-body-C24WsdFb.js} +1 -1
- package/build/assets/{modal-classes-C8eycCwG.js → modal-classes-B0b9eiL8.js} +1 -1
- package/build/assets/modal-close-button-DfqfB2Nj.js +1 -0
- package/build/assets/{mouse-pointer-click-Co2uyaPA.js → mouse-pointer-click-BXlRN92t.js} +1 -1
- package/build/assets/onboarding-DXFBRqEy.js +1 -0
- package/build/assets/onboarding-modal-BT3Gx_sZ.js +1 -0
- package/build/assets/organization-service.api-B5CvmnYQ.js +1 -0
- package/build/assets/pencil-q-ihqDYv.js +1 -0
- package/build/assets/pin-BdroVQdN.js +1 -0
- package/build/assets/planner-tab-CstoOlAB.js +1 -0
- package/build/assets/plug-7ACOEbMs.js +1 -0
- package/build/assets/plugins-management-service-5rqVPEGN.js +1 -0
- package/build/assets/plus-C2e21TFC.js +1 -0
- package/build/assets/profiles-service.api-D1XKMgr0.js +1 -0
- package/build/assets/providers-XmZ9HM4Q.js +1 -0
- package/build/assets/proxy-XP6U1Dhv.js +1 -0
- package/build/assets/{puzzle-JM_QaRm0.js → puzzle-LJYnuxKe.js} +1 -1
- package/build/assets/react-BX7IV650.js +1 -0
- package/build/assets/recommended-automations-launcher-DEHRKIAg.js +1 -0
- package/build/assets/refresh-cw-BtdC3T8P.js +1 -0
- package/build/assets/root-CM6IZHlg.css +1 -0
- package/build/assets/root-DdFkodKW.js +2 -0
- package/build/assets/root-layout-DUquNZTU.js +2 -0
- package/build/assets/schema-field-Y3F8JvXd.js +1 -0
- package/build/assets/scroll-fade-state-Dt_fx2kf.js +1 -0
- package/build/assets/sdk-section-page-CNZTLwH9.js +1 -0
- package/build/assets/secret-form-9-BoGA40.js +1 -0
- package/build/assets/secrets-service-BOIsfD9j.js +1 -0
- package/build/assets/secrets-settings-CBJgFr42.js +1 -0
- package/build/assets/settings-D4hdToD4.js +1 -0
- package/build/assets/settings-dropdown-input-DBvsZ7-Q.js +1 -0
- package/build/assets/settings-index-DeQphyBK.js +1 -0
- package/build/assets/settings-input-dVuzapBA.js +1 -0
- package/build/assets/{settings-list-classes-BzeSZbF2.js → settings-list-classes-DhAPuXm6.js} +1 -1
- package/build/assets/settings-modal-tHiJ8iYV.js +1 -0
- package/build/assets/settings-nav-GAQjW1a-.js +16 -0
- package/build/assets/settings-service.api-C1vZH9Vh.js +1 -0
- package/build/assets/settings-switch-DDd1cQ8t.js +1 -0
- package/build/assets/{settings-utils-UYpEdPuD.js → settings-utils-BTaaRhLZ.js} +1 -1
- package/build/assets/shared-conversation-Cyg7m7ns.js +1 -0
- package/build/assets/shield-check-C3Rl0NF8.js +1 -0
- package/build/assets/{sidebar-layout-D6fS8-Gl.js → sidebar-layout-DH0E-5KW.js} +1 -1
- package/build/assets/sidebar-mobile-menu-toggle-CQ4iky__.js +1 -0
- package/build/assets/{sidebar-nav-link-DQQcMf1A.js → sidebar-nav-link-oLQiKUBu.js} +1 -1
- package/build/assets/{sidebar-onboarding-checklist-storage-BBkeI6Bp.js → sidebar-onboarding-checklist-storage-TfvNNnnr.js} +1 -1
- package/build/assets/sidebar-store-DAZVH-DR.js +1 -0
- package/build/assets/skill-card-pill-row-DfjIfj0K.js +1 -0
- package/build/assets/{skill-filter-w__3UCEE.js → skill-filter-DsNLmn76.js} +2 -2
- package/build/assets/{skill-icon-badge-RQkq8wvl.js → skill-icon-badge-0MK_68Nc.js} +1 -1
- package/build/assets/skill-scope-BE-H9TSZ.js +1 -0
- package/build/assets/skills-plugins-vzSdxSk_.js +1 -0
- package/build/assets/skills-settings-BiPOH9H9.js +1 -0
- package/build/assets/styled-tooltip-CejG0rqv.js +1 -0
- package/build/assets/task-list-tab-OkZSqnTp.js +1 -0
- package/build/assets/{terminal-CNElN42a.js → terminal-Dph60VFZ.js} +2 -2
- package/build/assets/toggle-switch-B2uXaAUS.js +1 -0
- package/build/assets/trash-2-Bb40zQzs.js +1 -0
- package/build/assets/trash-Ckh7yCaB.js +1 -0
- package/build/assets/triangle-alert-DEdu-b_L.js +1 -0
- package/build/assets/{typography-v1KN0tzi.js → typography-DgcLGdHk.js} +1 -1
- package/build/assets/usage-tab-MCmNRAnR.js +1 -0
- package/build/assets/use-acp-credential-form-ychoGqjC.js +1 -0
- package/build/assets/use-activate-agent-profile-8L8Xdghy.js +1 -0
- package/build/assets/use-agent-profiles-Bi8hSkze.js +1 -0
- package/build/assets/{use-automation-health-E6NZi9rb.js → use-automation-health-U99vvHxx.js} +1 -1
- package/build/assets/use-automation-permissions-Buus0R6h.js +1 -0
- package/build/assets/{use-automations-xijQKIl9.js → use-automations-Bq5hVuv0.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-CrJP5262.js → use-can-manage-org-profiles-MzIeEV8F.js} +1 -1
- package/build/assets/use-canvas-extensions-Ca9KoVEm.js +1 -0
- package/build/assets/{use-cloud-current-user-id-CDfAHpPX.js → use-cloud-current-user-id-B4ZLUZSa.js} +1 -1
- package/build/assets/use-config-l5tkDHyD.js +1 -0
- package/build/assets/use-create-conversation-i_PdFdIs.js +1 -0
- package/build/assets/use-create-secret-CjWq0J4O.js +1 -0
- package/build/assets/use-free-models-gCsJ5BV0.js +1 -0
- package/build/assets/{use-get-secrets-K3jmk-LH.js → use-get-secrets-CMTuWEp_.js} +1 -1
- package/build/assets/use-is-authed-A2Yinlt0.js +1 -0
- package/build/assets/{use-launch-skill-in-chat-BYjYihBP.js → use-launch-skill-in-chat-QbXDhiHr.js} +1 -1
- package/build/assets/use-llm-configured-Dl4zg8ht.js +1 -0
- package/build/assets/use-llm-profiles-SWsuFmFu.js +1 -0
- package/build/assets/use-manifest-capabilities-CdqYfUAC.js +1 -0
- package/build/assets/use-onboarding-completion-Xl63ZvzQ.js +1 -0
- package/build/assets/use-pinned-home-route-BXDIUaxQ.js +1 -0
- package/build/assets/use-plugins-marketplace-BIIaPiaB.js +1 -0
- package/build/assets/use-save-agent-profile-D-ZHHE94.js +1 -0
- package/build/assets/{use-save-settings-DYqkKv7T.js → use-save-settings-Dapkf4cC.js} +1 -1
- package/build/assets/use-settings-C2KKQKVC.js +1 -0
- package/build/assets/use-settings-nav-items-TOc0Rsfd.js +1 -0
- package/build/assets/use-tracking-j4uo9VEW.js +3 -0
- package/build/assets/{use-user-conversation-B9Gebw_g.js → use-user-conversation-5UFqMoO4.js} +1 -1
- package/build/assets/{useInfiniteQuery-C926xzY4.js → useInfiniteQuery-CtSRG7uW.js} +1 -1
- package/build/assets/{useMutation-B-qc391N.js → useMutation-Cszf8mKy.js} +1 -1
- package/build/assets/useQueries-pUohFMSP.js +1 -0
- package/build/assets/useQuery-DAAacS7O.js +1 -0
- package/build/assets/useTranslation-CCgUjPJF.js +1 -0
- package/build/assets/utils-BgLSZdyy.js +1 -0
- package/build/assets/{vendor~conversation-panel~conversation-C8Fn4XOf.js → vendor~conversation-panel~conversation-C22sJuWZ.js} +1 -1
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~b0x1wrp2-Z0lly3FE.js +2 -0
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-BXXGJNDU.js +185 -0
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-40UR63Gt.js +1 -0
- package/build/assets/{vendor~index-home~home~conversation-panel~conversation-hWywRBaR.js → vendor~index-home~home~conversation-panel~conversation-UTl7gUo9.js} +1 -1
- package/build/assets/vendor~root-layout-CcdIqs-C.js +1 -0
- package/build/assets/{vendor~root-layout~conversation-panel~conversation-BMbMgaGu.js → vendor~root-layout~conversation-panel~conversation-C3EBV3kp.js} +1 -1
- package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-BCe0JJVy.js +1 -0
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation-j5MFqfSy.js → vendor~root-layout~index-home~home~conversation-panel~conversation-BGGbPcYh.js} +1 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-CxhwKuAd.js +1 -0
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~nj1hli3r-DP9wmsjo.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~inibp4qe-CnsDDzeE.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-CUmIwQCN.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~skills-setti~eo2nf80n-3eJ4ExtV.js} +12 -6
- package/build/assets/{verification-settings-gw_q6vkL.js → verification-settings-DdBpaVPz.js} +1 -1
- package/build/assets/{wrench-CUEI1krB.js → wrench-B8Wg_nbp.js} +1 -1
- package/build/assets/x-CX8lVGwm.js +1 -0
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +79 -22
- package/build/locales/ca/openhands.json +79 -22
- package/build/locales/de/openhands.json +79 -22
- package/build/locales/en/openhands.json +79 -22
- package/build/locales/es/openhands.json +79 -22
- package/build/locales/fr/openhands.json +79 -22
- package/build/locales/it/openhands.json +79 -22
- package/build/locales/ja/openhands.json +79 -22
- package/build/locales/ko-KR/openhands.json +79 -22
- package/build/locales/no/openhands.json +79 -22
- package/build/locales/pt/openhands.json +79 -22
- package/build/locales/tr/openhands.json +79 -22
- package/build/locales/uk/openhands.json +79 -22
- package/build/locales/zh-CN/openhands.json +79 -22
- package/build/locales/zh-TW/openhands.json +79 -22
- package/config/defaults.json +3 -3
- 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 +72 -12
- package/dist/api/agent-server-adapter.js +234 -132
- package/dist/api/agent-server-adapter.js.map +1 -1
- package/dist/api/agent-server-config.cjs +1 -1
- package/dist/api/agent-server-config.cjs.map +1 -1
- package/dist/api/agent-server-config.d.ts +6 -0
- package/dist/api/agent-server-config.js +6 -3
- package/dist/api/agent-server-config.js.map +1 -1
- package/dist/api/automation-service/automation-service.api.cjs +1 -1
- package/dist/api/automation-service/automation-service.api.cjs.map +1 -1
- package/dist/api/automation-service/automation-service.api.d.ts +2 -2
- package/dist/api/automation-service/automation-service.api.js +7 -7
- package/dist/api/automation-service/automation-service.api.js.map +1 -1
- package/dist/api/cloud/organization-service.api.cjs.map +1 -1
- package/dist/api/cloud/organization-service.api.d.ts +9 -1
- package/dist/api/cloud/organization-service.api.js.map +1 -1
- package/dist/api/cloud/provider-connections-service.api.cjs +2 -0
- package/dist/api/cloud/provider-connections-service.api.cjs.map +1 -0
- package/dist/api/cloud/provider-connections-service.api.d.ts +5 -0
- package/dist/api/cloud/provider-connections-service.api.js +50 -0
- package/dist/api/cloud/provider-connections-service.api.js.map +1 -0
- package/dist/api/cloud/skills-service.api.cjs +1 -1
- package/dist/api/cloud/skills-service.api.cjs.map +1 -1
- package/dist/api/cloud/skills-service.api.d.ts +10 -0
- package/dist/api/cloud/skills-service.api.js +11 -1
- package/dist/api/cloud/skills-service.api.js.map +1 -1
- package/dist/api/config-service/config-service.api.cjs +1 -1
- package/dist/api/config-service/config-service.api.cjs.map +1 -1
- package/dist/api/config-service/config-service.api.js +6 -2
- package/dist/api/config-service/config-service.api.js.map +1 -1
- package/dist/api/config-service/config-service.types.d.ts +13 -0
- package/dist/api/conversation-metadata-store.cjs +1 -1
- package/dist/api/conversation-metadata-store.cjs.map +1 -1
- package/dist/api/conversation-metadata-store.d.ts +24 -0
- package/dist/api/conversation-metadata-store.js +10 -2
- package/dist/api/conversation-metadata-store.js.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +20 -0
- package/dist/api/conversation-service/agent-server-conversation-service.api.js +126 -77
- package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
- package/dist/api/hooks-service.cjs +2 -0
- package/dist/api/hooks-service.cjs.map +1 -0
- package/dist/api/hooks-service.d.ts +13 -0
- package/dist/api/hooks-service.js +20 -0
- package/dist/api/hooks-service.js.map +1 -0
- package/dist/api/provider-connections-service/provider-connections-service.api.cjs +1 -1
- package/dist/api/provider-connections-service/provider-connections-service.api.cjs.map +1 -1
- package/dist/api/provider-connections-service/provider-connections-service.api.js +25 -16
- package/dist/api/provider-connections-service/provider-connections-service.api.js.map +1 -1
- package/dist/api/settings-service/settings-service.api.cjs +1 -1
- package/dist/api/settings-service/settings-service.api.cjs.map +1 -1
- package/dist/api/settings-service/settings-service.api.d.ts +2 -0
- package/dist/api/settings-service/settings-service.api.js +18 -10
- package/dist/api/settings-service/settings-service.api.js.map +1 -1
- package/dist/api/skills-service.cjs +1 -1
- package/dist/api/skills-service.cjs.map +1 -1
- package/dist/api/skills-service.d.ts +7 -0
- package/dist/api/skills-service.js +11 -8
- package/dist/api/skills-service.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/critic-result-display.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/critic-result-display.js +5 -5
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.js +2 -1
- package/dist/components/conversation-events/chat/event-message-components/finish-event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.d.ts +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js +28 -28
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.js +2 -1
- package/dist/components/conversation-events/chat/event-message-components/thought-event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.d.ts +1 -1
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js +37 -37
- package/dist/components/conversation-events/chat/event-message-components/user-assistant-event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message.cjs +2 -2
- package/dist/components/conversation-events/chat/event-message.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message.js +79 -70
- package/dist/components/conversation-events/chat/event-message.js.map +1 -1
- package/dist/components/conversation-events/chat/messages.cjs +1 -1
- package/dist/components/conversation-events/chat/messages.cjs.map +1 -1
- package/dist/components/conversation-events/chat/messages.js +28 -27
- package/dist/components/conversation-events/chat/messages.js.map +1 -1
- package/dist/components/features/automations/automation-card.cjs +1 -1
- package/dist/components/features/automations/automation-card.cjs.map +1 -1
- package/dist/components/features/automations/automation-card.js +104 -97
- package/dist/components/features/automations/automation-card.js.map +1 -1
- package/dist/components/features/automations/automation-list-row.cjs +1 -1
- package/dist/components/features/automations/automation-list-row.cjs.map +1 -1
- package/dist/components/features/automations/automation-list-row.js +89 -77
- package/dist/components/features/automations/automation-list-row.js.map +1 -1
- package/dist/components/features/automations/build-automation-menu-items.cjs +1 -1
- package/dist/components/features/automations/build-automation-menu-items.cjs.map +1 -1
- package/dist/components/features/automations/build-automation-menu-items.d.ts +3 -1
- package/dist/components/features/automations/build-automation-menu-items.js +12 -11
- package/dist/components/features/automations/build-automation-menu-items.js.map +1 -1
- package/dist/components/features/automations/detail/configuration-section.d.ts +7 -1
- package/dist/components/features/automations/detail/detail-header.d.ts +10 -5
- package/dist/components/features/automations/detail/run-status-badge.cjs +1 -1
- package/dist/components/features/automations/detail/run-status-badge.cjs.map +1 -1
- package/dist/components/features/automations/detail/run-status-badge.d.ts +2 -2
- package/dist/components/features/automations/detail/run-status-badge.js +82 -53
- package/dist/components/features/automations/detail/run-status-badge.js.map +1 -1
- package/dist/components/features/automations/kebab-menu.cjs +1 -1
- package/dist/components/features/automations/kebab-menu.cjs.map +1 -1
- package/dist/components/features/automations/kebab-menu.js +9 -5
- package/dist/components/features/automations/kebab-menu.js.map +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.cjs +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.cjs.map +1 -1
- package/dist/components/features/automations/recommended-automations-launcher.js +12 -12
- package/dist/components/features/automations/recommended-automations-launcher.js.map +1 -1
- package/dist/components/features/automations/recommended-automations-section.cjs +1 -1
- package/dist/components/features/automations/recommended-automations-section.js +9 -9
- package/dist/components/features/backends/backend-selector.cjs +1 -1
- package/dist/components/features/backends/backend-selector.cjs.map +1 -1
- package/dist/components/features/backends/backend-selector.js +123 -112
- package/dist/components/features/backends/backend-selector.js.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs +1 -1
- package/dist/components/features/backends/manage-backends-modal.cjs.map +1 -1
- package/dist/components/features/backends/manage-backends-modal.js +29 -29
- package/dist/components/features/backends/manage-backends-modal.js.map +1 -1
- package/dist/components/features/chat/change-agent-button.cjs +1 -1
- package/dist/components/features/chat/change-agent-button.js +4 -4
- package/dist/components/features/chat/chat-interface.cjs +2 -2
- package/dist/components/features/chat/chat-interface.cjs.map +1 -1
- package/dist/components/features/chat/chat-interface.js +137 -137
- package/dist/components/features/chat/chat-interface.js.map +1 -1
- package/dist/components/features/chat/chat-message.cjs +1 -1
- package/dist/components/features/chat/chat-message.cjs.map +1 -1
- package/dist/components/features/chat/chat-message.d.ts +2 -1
- package/dist/components/features/chat/chat-message.js +88 -79
- package/dist/components/features/chat/chat-message.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 +62 -61
- package/dist/components/features/chat/components/chat-input-llm-profile-picker.js.map +1 -1
- package/dist/components/features/chat/components/context-window-meter.cjs +1 -1
- package/dist/components/features/chat/components/context-window-meter.js +4 -4
- package/dist/components/features/chat/confirmation-mode-enabled.cjs +1 -1
- package/dist/components/features/chat/confirmation-mode-enabled.js +4 -4
- package/dist/components/features/chat/generic-event-message.cjs +1 -1
- package/dist/components/features/chat/generic-event-message.cjs.map +1 -1
- package/dist/components/features/chat/generic-event-message.d.ts +2 -1
- package/dist/components/features/chat/generic-event-message.js +41 -22
- package/dist/components/features/chat/generic-event-message.js.map +1 -1
- package/dist/components/features/chat/interactive-chat-box.cjs +1 -1
- package/dist/components/features/chat/interactive-chat-box.cjs.map +1 -1
- package/dist/components/features/chat/interactive-chat-box.js +20 -19
- package/dist/components/features/chat/interactive-chat-box.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 +27 -26
- package/dist/components/features/chat/model-messages.js.map +1 -1
- package/dist/components/features/conversation/conversation-overview-git-section.cjs +1 -1
- package/dist/components/features/conversation/conversation-overview-git-section.js +4 -4
- package/dist/components/features/conversation/conversation-overview-skills-panel.cjs +1 -1
- package/dist/components/features/conversation/conversation-overview-skills-panel.js +4 -4
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +77 -78
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +88 -88
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.cjs +2 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.cjs.map +1 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.d.ts +21 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.js +239 -0
- package/dist/components/features/conversation-panel/advanced-conversation-options-modal.js.map +1 -0
- package/dist/components/features/conversation-panel/budget-display.cjs +1 -1
- package/dist/components/features/conversation-panel/budget-display.cjs.map +1 -1
- package/dist/components/features/conversation-panel/budget-display.d.ts +1 -2
- package/dist/components/features/conversation-panel/budget-display.js +12 -19
- package/dist/components/features/conversation-panel/budget-display.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.d.ts +28 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.js +69 -0
- package/dist/components/features/conversation-panel/conversation-active-tag-filters.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js +19 -18
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js +91 -80
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -1
- 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.js +45 -44
- 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-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.js +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-preview.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.d.ts +7 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.js +87 -81
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-chips.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js +2 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-tag-display.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-layouts-menu.cjs +2 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.cjs.map +1 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.d.ts +29 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.js +177 -0
- package/dist/components/features/conversation-panel/conversation-layouts-menu.js.map +1 -0
- 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 +37 -0
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +85 -45
- 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 +296 -290
- package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.cjs +2 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.cjs.map +1 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.d.ts +22 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.js +153 -0
- package/dist/components/features/conversation-panel/edit-conversation-tags-modal.js.map +1 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.cjs +2 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.cjs.map +1 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.d.ts +6 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.js +65 -0
- package/dist/components/features/conversation-panel/hide-older-conversations-row.js.map +1 -0
- package/dist/components/features/conversation-panel/menu-row.cjs +1 -1
- package/dist/components/features/conversation-panel/menu-row.cjs.map +1 -1
- package/dist/components/features/conversation-panel/menu-row.d.ts +11 -1
- package/dist/components/features/conversation-panel/menu-row.js +27 -16
- package/dist/components/features/conversation-panel/menu-row.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.js +1 -1
- package/dist/components/features/home/featured-automations/automation-health-indicator.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.d.ts +4 -3
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js +22 -25
- package/dist/components/features/home/featured-automations/automation-run-activity-metrics.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.d.ts +1 -1
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js +15 -15
- package/dist/components/features/home/featured-automations/automation-run-activity-sparkline.js.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-health.cjs +1 -1
- package/dist/components/features/home/featured-automations/automation-run-health.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/automation-run-health.d.ts +5 -3
- package/dist/components/features/home/featured-automations/automation-run-health.js +30 -23
- package/dist/components/features/home/featured-automations/automation-run-health.js.map +1 -1
- package/dist/components/features/home/featured-automations/build-home-automation-menu-items.d.ts +1 -2
- package/dist/components/features/home/featured-automations/build-pinned-automation-menu-items.d.ts +0 -1
- package/dist/components/features/home/featured-automations/home-automation-activity.d.ts +3 -2
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs +1 -1
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.cjs.map +1 -1
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.d.ts +1 -1
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js +42 -42
- package/dist/components/features/home/featured-automations/home-automation-run-tooltip.js.map +1 -1
- package/dist/components/features/images/image-lightbox.cjs +2 -0
- package/dist/components/features/images/image-lightbox.cjs.map +1 -0
- package/dist/components/features/images/image-lightbox.d.ts +11 -0
- package/dist/components/features/images/image-lightbox.js +37 -0
- package/dist/components/features/images/image-lightbox.js.map +1 -0
- package/dist/components/features/images/image-preview.cjs +1 -1
- package/dist/components/features/images/image-preview.cjs.map +1 -1
- package/dist/components/features/images/image-preview.d.ts +2 -1
- package/dist/components/features/images/image-preview.js +33 -13
- package/dist/components/features/images/image-preview.js.map +1 -1
- package/dist/components/features/manifest/manifest-form-field.d.ts +3 -1
- package/dist/components/features/manifest/manifest-review-step.d.ts +3 -1
- package/dist/components/features/onboarding/steps/setup-llm-step.d.ts +3 -4
- package/dist/components/features/settings/cloud-settings-link.cjs +1 -1
- package/dist/components/features/settings/cloud-settings-link.cjs.map +1 -1
- package/dist/components/features/settings/cloud-settings-link.d.ts +3 -1
- package/dist/components/features/settings/cloud-settings-link.js +22 -19
- package/dist/components/features/settings/cloud-settings-link.js.map +1 -1
- package/dist/components/features/settings/integrations-settings-link.cjs +1 -1
- package/dist/components/features/settings/integrations-settings-link.cjs.map +1 -1
- package/dist/components/features/settings/integrations-settings-link.d.ts +3 -1
- package/dist/components/features/settings/integrations-settings-link.js +20 -17
- package/dist/components/features/settings/integrations-settings-link.js.map +1 -1
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/llm-settings-local-view.js +3 -2
- package/dist/components/features/settings/llm-profiles/profile-row.cjs +1 -1
- package/dist/components/features/settings/llm-profiles/profile-row.js +1 -1
- package/dist/components/features/settings/llm-profiles/profiles-body.d.ts +2 -2
- package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs +1 -1
- package/dist/components/features/settings/sdk-settings/sdk-section-page.cjs.map +1 -1
- package/dist/components/features/settings/sdk-settings/sdk-section-page.d.ts +8 -7
- package/dist/components/features/settings/sdk-settings/sdk-section-page.js +172 -142
- package/dist/components/features/settings/sdk-settings/sdk-section-page.js.map +1 -1
- package/dist/components/features/settings/secrets-settings/secret-form.cjs +1 -1
- package/dist/components/features/settings/secrets-settings/secret-form.cjs.map +1 -1
- package/dist/components/features/settings/secrets-settings/secret-form.js +38 -25
- package/dist/components/features/settings/secrets-settings/secret-form.js.map +1 -1
- package/dist/components/features/settings/settings-dropdown-input.cjs +1 -1
- package/dist/components/features/settings/settings-dropdown-input.js +6 -6
- 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.d.ts +4 -1
- package/dist/components/features/sidebar/sidebar-rail-body.js +157 -139
- package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
- package/dist/components/features/sidebar/sidebar.cjs +1 -1
- package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar.js +28 -26
- package/dist/components/features/sidebar/sidebar.js.map +1 -1
- package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.cjs +1 -1
- package/dist/components/features/sidebar/use-sidebar-onboarding-checklist.js +3 -3
- 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 +3 -3
- package/dist/components/features/skills/extensions-navigation.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.js +33 -29
- package/dist/components/providers/agent-server-ui-providers.js.map +1 -1
- package/dist/components/shared/buttons/remove-button.cjs +1 -1
- package/dist/components/shared/buttons/remove-button.cjs.map +1 -1
- package/dist/components/shared/buttons/remove-button.d.ts +2 -1
- package/dist/components/shared/buttons/remove-button.js +2 -1
- package/dist/components/shared/buttons/remove-button.js.map +1 -1
- package/dist/components/shared/buttons/styled-tooltip.cjs +1 -1
- package/dist/components/shared/buttons/styled-tooltip.cjs.map +1 -1
- package/dist/components/shared/buttons/styled-tooltip.d.ts +2 -1
- package/dist/components/shared/buttons/styled-tooltip.js +2 -1
- package/dist/components/shared/buttons/styled-tooltip.js.map +1 -1
- package/dist/components/shared/filters/enum-filter-dropdown.cjs +1 -1
- package/dist/components/shared/filters/enum-filter-dropdown.cjs.map +1 -1
- package/dist/components/shared/filters/enum-filter-dropdown.d.ts +5 -1
- package/dist/components/shared/filters/enum-filter-dropdown.js +14 -14
- package/dist/components/shared/filters/enum-filter-dropdown.js.map +1 -1
- package/dist/components/shared/free-models-note.cjs +2 -0
- package/dist/components/shared/free-models-note.cjs.map +1 -0
- package/dist/components/shared/free-models-note.d.ts +3 -0
- package/dist/components/shared/free-models-note.js +20 -0
- package/dist/components/shared/free-models-note.js.map +1 -0
- package/dist/components/shared/modals/confirmation-modal.cjs +1 -1
- package/dist/components/shared/modals/confirmation-modal.cjs.map +1 -1
- package/dist/components/shared/modals/confirmation-modal.d.ts +2 -1
- package/dist/components/shared/modals/confirmation-modal.js +8 -8
- package/dist/components/shared/modals/confirmation-modal.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 +102 -112
- 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 +3 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/constants/acp-providers.cjs.map +1 -1
- package/dist/constants/acp-providers.d.ts +12 -0
- package/dist/constants/acp-providers.js.map +1 -1
- package/dist/constants/settings-nav.d.ts +8 -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.d.ts +5 -0
- package/dist/contexts/conversation-websocket-context.js +194 -198
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/contexts/websocket-provider-wrapper.cjs +1 -1
- package/dist/contexts/websocket-provider-wrapper.cjs.map +1 -1
- package/dist/contexts/websocket-provider-wrapper.js +31 -15
- package/dist/contexts/websocket-provider-wrapper.js.map +1 -1
- package/dist/hooks/chat/record-model-switch-message.cjs +1 -1
- package/dist/hooks/chat/record-model-switch-message.cjs.map +1 -1
- package/dist/hooks/chat/record-model-switch-message.d.ts +31 -0
- package/dist/hooks/chat/record-model-switch-message.js +25 -12
- package/dist/hooks/chat/record-model-switch-message.js.map +1 -1
- package/dist/hooks/chat/use-plan-mode-interceptor.cjs +2 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.cjs.map +1 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.d.ts +16 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.js +43 -0
- package/dist/hooks/chat/use-plan-mode-interceptor.js.map +1 -0
- 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 +63 -62
- 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.cjs.map +1 -1
- package/dist/hooks/mutation/use-create-conversation.js +5 -1
- package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
- package/dist/hooks/mutation/use-read-conversation-file.cjs +1 -1
- package/dist/hooks/mutation/use-read-conversation-file.cjs.map +1 -1
- package/dist/hooks/mutation/use-read-conversation-file.js +11 -4
- package/dist/hooks/mutation/use-read-conversation-file.js.map +1 -1
- package/dist/hooks/mutation/use-save-settings.cjs +1 -1
- package/dist/hooks/mutation/use-save-settings.js +3 -3
- package/dist/hooks/mutation/use-switch-llm-profile.cjs +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.cjs.map +1 -1
- package/dist/hooks/mutation/use-switch-llm-profile.js +13 -25
- package/dist/hooks/mutation/use-switch-llm-profile.js.map +1 -1
- package/dist/hooks/mutation/use-update-conversation-tags.cjs +2 -0
- package/dist/hooks/mutation/use-update-conversation-tags.cjs.map +1 -0
- package/dist/hooks/mutation/use-update-conversation-tags.d.ts +8 -0
- package/dist/hooks/mutation/use-update-conversation-tags.js +45 -0
- package/dist/hooks/mutation/use-update-conversation-tags.js.map +1 -0
- package/dist/hooks/query/query-keys.cjs +1 -1
- package/dist/hooks/query/query-keys.cjs.map +1 -1
- package/dist/hooks/query/query-keys.d.ts +6 -0
- package/dist/hooks/query/query-keys.js +2 -2
- package/dist/hooks/query/query-keys.js.map +1 -1
- package/dist/hooks/query/use-automation-sdk-version.cjs +1 -1
- package/dist/hooks/query/use-automation-sdk-version.cjs.map +1 -1
- package/dist/hooks/query/use-automation-sdk-version.d.ts +0 -1
- package/dist/hooks/query/use-automation-sdk-version.js +30 -55
- package/dist/hooks/query/use-automation-sdk-version.js.map +1 -1
- package/dist/hooks/query/use-conversation-skills.cjs +1 -1
- package/dist/hooks/query/use-conversation-skills.cjs.map +1 -1
- package/dist/hooks/query/use-conversation-skills.d.ts +14 -5
- package/dist/hooks/query/use-conversation-skills.js +20 -4
- package/dist/hooks/query/use-conversation-skills.js.map +1 -1
- package/dist/hooks/query/use-free-models.cjs +2 -0
- package/dist/hooks/query/use-free-models.cjs.map +1 -0
- package/dist/hooks/query/use-free-models.d.ts +23 -0
- package/dist/hooks/query/use-free-models.js +67 -0
- package/dist/hooks/query/use-free-models.js.map +1 -0
- package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
- package/dist/hooks/query/use-local-git-info.js.map +1 -1
- package/dist/hooks/query/use-provider-connections.cjs +1 -1
- package/dist/hooks/query/use-provider-connections.cjs.map +1 -1
- package/dist/hooks/query/use-provider-connections.d.ts +6 -3
- package/dist/hooks/query/use-provider-connections.js +7 -3
- package/dist/hooks/query/use-provider-connections.js.map +1 -1
- package/dist/hooks/query/use-provider-models.cjs +1 -1
- package/dist/hooks/query/use-provider-models.cjs.map +1 -1
- package/dist/hooks/query/use-provider-models.js +34 -25
- package/dist/hooks/query/use-provider-models.js.map +1 -1
- package/dist/hooks/query/use-search-providers.cjs +1 -1
- package/dist/hooks/query/use-search-providers.cjs.map +1 -1
- package/dist/hooks/query/use-search-providers.js +31 -19
- package/dist/hooks/query/use-search-providers.js.map +1 -1
- package/dist/hooks/query/use-sub-conversations.cjs +1 -1
- package/dist/hooks/query/use-sub-conversations.cjs.map +1 -1
- package/dist/hooks/query/use-sub-conversations.js +16 -16
- package/dist/hooks/query/use-sub-conversations.js.map +1 -1
- package/dist/hooks/use-acp-model-context.cjs +1 -1
- package/dist/hooks/use-acp-model-context.js +3 -3
- package/dist/hooks/use-agent-state.cjs +1 -1
- package/dist/hooks/use-agent-state.cjs.map +1 -1
- package/dist/hooks/use-agent-state.d.ts +17 -1
- package/dist/hooks/use-agent-state.js +19 -9
- package/dist/hooks/use-agent-state.js.map +1 -1
- package/dist/hooks/use-automation-permissions.cjs +2 -0
- package/dist/hooks/use-automation-permissions.cjs.map +1 -0
- package/dist/hooks/use-automation-permissions.d.ts +43 -0
- package/dist/hooks/use-automation-permissions.js +52 -0
- package/dist/hooks/use-automation-permissions.js.map +1 -0
- package/dist/hooks/use-chat-input-model-state.cjs +1 -1
- package/dist/hooks/use-chat-input-model-state.js +3 -3
- package/dist/hooks/use-handle-plan-click.cjs +1 -1
- package/dist/hooks/use-handle-plan-click.cjs.map +1 -1
- package/dist/hooks/use-handle-plan-click.d.ts +3 -1
- package/dist/hooks/use-handle-plan-click.js +85 -26
- package/dist/hooks/use-handle-plan-click.js.map +1 -1
- package/dist/hooks/use-home-automation-actions.cjs +1 -1
- package/dist/hooks/use-home-automation-actions.cjs.map +1 -1
- package/dist/hooks/use-home-automation-actions.d.ts +1 -2
- package/dist/hooks/use-home-automation-actions.js +1 -1
- package/dist/hooks/use-home-automation-actions.js.map +1 -1
- package/dist/hooks/use-llm-configured.cjs +1 -1
- package/dist/hooks/use-llm-configured.js +3 -3
- package/dist/hooks/use-manifest-preflight.d.ts +1 -1
- package/dist/hooks/use-unified-websocket-status.cjs +1 -1
- package/dist/hooks/use-unified-websocket-status.cjs.map +1 -1
- package/dist/hooks/use-unified-websocket-status.d.ts +7 -0
- package/dist/hooks/use-unified-websocket-status.js +5 -1
- package/dist/hooks/use-unified-websocket-status.js.map +1 -1
- package/dist/i18n/declaration.cjs +1 -1
- package/dist/i18n/declaration.cjs.map +1 -1
- package/dist/i18n/declaration.d.ts +71 -14
- 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 +1281 -312
- package/dist/i18n/translation.js.map +1 -1
- package/dist/locales/ar/openhands.json +79 -22
- package/dist/locales/ca/openhands.json +79 -22
- package/dist/locales/de/openhands.json +79 -22
- package/dist/locales/en/openhands.json +79 -22
- package/dist/locales/es/openhands.json +79 -22
- package/dist/locales/fr/openhands.json +79 -22
- package/dist/locales/it/openhands.json +79 -22
- package/dist/locales/ja/openhands.json +79 -22
- package/dist/locales/ko-KR/openhands.json +79 -22
- package/dist/locales/no/openhands.json +79 -22
- package/dist/locales/pt/openhands.json +79 -22
- package/dist/locales/tr/openhands.json +79 -22
- package/dist/locales/uk/openhands.json +79 -22
- package/dist/locales/zh-CN/openhands.json +79 -22
- package/dist/locales/zh-TW/openhands.json +79 -22
- package/dist/manifests/automation-insights.cjs.map +1 -1
- package/dist/manifests/automation-insights.d.ts +10 -2
- package/dist/manifests/automation-insights.js.map +1 -1
- package/dist/manifests/automation-setup.cjs +1 -1
- package/dist/manifests/automation-setup.cjs.map +1 -1
- package/dist/manifests/automation-setup.d.ts +9 -16
- package/dist/manifests/automation-setup.js +17 -7
- package/dist/manifests/automation-setup.js.map +1 -1
- package/dist/manifests/manifest-actions.d.ts +1 -1
- package/dist/manifests/manifest-capabilities.d.ts +3 -1
- package/dist/manifests/manifest-local-validation.cjs +2 -0
- package/dist/manifests/manifest-local-validation.cjs.map +1 -0
- package/dist/manifests/manifest-local-validation.d.ts +15 -11
- package/dist/manifests/manifest-local-validation.js +8 -0
- package/dist/manifests/manifest-local-validation.js.map +1 -0
- package/dist/manifests/manifest-template.cjs +2 -0
- package/dist/manifests/manifest-template.cjs.map +1 -0
- package/dist/manifests/manifest-template.d.ts +4 -4
- package/dist/manifests/manifest-template.js +12 -0
- package/dist/manifests/manifest-template.js.map +1 -0
- package/dist/manifests/manifest-validation.cjs +1 -1
- package/dist/manifests/manifest-validation.cjs.map +1 -1
- package/dist/manifests/manifest-validation.js +106 -28
- package/dist/manifests/manifest-validation.js.map +1 -1
- package/dist/manifests/types.cjs.map +1 -1
- package/dist/manifests/types.d.ts +39 -4
- package/dist/manifests/types.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.cjs +8 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.cjs.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.js +221 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/custom-automation/manifest.js.map +1 -0
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-issue-to-pr/manifest.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/github-pr-reviewer/manifest.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog/qa-changes/manifest.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js +22 -20
- package/dist/node_modules/@openhands/extensions/automations/catalog-index.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.js +2 -1
- package/dist/node_modules/@openhands/extensions/automations/interface.js.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.cjs.map +1 -1
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js +24 -5
- package/dist/node_modules/@openhands/extensions/integrations/catalog/gitlab.js.map +1 -1
- package/dist/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.cjs +1 -1
- package/dist/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js +1 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.js +21 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/circle-question-mark.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/shrink.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.js +43 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/sliders-horizontal.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.js +22 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/tags.js.map +1 -0
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +4 -4
- package/dist/package.js.map +1 -1
- package/dist/routes/agent-settings.d.ts +2 -0
- package/dist/routes/app-settings.cjs +1 -1
- package/dist/routes/app-settings.cjs.map +1 -1
- package/dist/routes/app-settings.js +53 -48
- 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.d.ts +3 -1
- package/dist/routes/llm-settings.js +120 -127
- package/dist/routes/llm-settings.js.map +1 -1
- package/dist/routes/planner-tab.cjs +1 -1
- package/dist/routes/planner-tab.cjs.map +1 -1
- package/dist/routes/planner-tab.js +44 -28
- package/dist/routes/planner-tab.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 +5 -0
- package/dist/services/telemetry.js +122 -115
- package/dist/services/telemetry.js.map +1 -1
- 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 +32 -5
- package/dist/stores/conversation-panel-preferences-store.js +29 -12
- package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
- package/dist/stores/conversation-state-store.cjs +1 -1
- package/dist/stores/conversation-state-store.cjs.map +1 -1
- package/dist/stores/conversation-state-store.d.ts +9 -3
- package/dist/stores/conversation-state-store.js +6 -3
- package/dist/stores/conversation-state-store.js.map +1 -1
- package/dist/stores/conversation-store.cjs +1 -1
- package/dist/stores/conversation-store.cjs.map +1 -1
- package/dist/stores/conversation-store.d.ts +2 -0
- package/dist/stores/conversation-store.js +3 -0
- package/dist/stores/conversation-store.js.map +1 -1
- package/dist/stores/free-models-store.cjs +2 -0
- package/dist/stores/free-models-store.cjs.map +1 -0
- package/dist/stores/free-models-store.d.ts +30 -0
- package/dist/stores/free-models-store.js +22 -0
- package/dist/stores/free-models-store.js.map +1 -0
- package/dist/stores/model-store.cjs +1 -1
- package/dist/stores/model-store.cjs.map +1 -1
- package/dist/stores/model-store.d.ts +7 -0
- package/dist/stores/model-store.js +4 -0
- package/dist/stores/model-store.js.map +1 -1
- package/dist/types/automation.cjs.map +1 -1
- package/dist/types/automation.d.ts +46 -1
- package/dist/types/automation.js.map +1 -1
- package/dist/ui/context-menu.d.ts +1 -1
- package/dist/ui/toggle-switch.cjs +1 -1
- package/dist/ui/toggle-switch.cjs.map +1 -1
- package/dist/ui/toggle-switch.d.ts +4 -1
- package/dist/ui/toggle-switch.js +4 -3
- package/dist/ui/toggle-switch.js.map +1 -1
- package/dist/utils/automation-catalog.cjs +1 -1
- package/dist/utils/automation-catalog.cjs.map +1 -1
- package/dist/utils/automation-catalog.d.ts +12 -1
- package/dist/utils/automation-catalog.js +42 -12
- package/dist/utils/automation-catalog.js.map +1 -1
- package/dist/utils/automation-run-display.cjs +2 -0
- package/dist/utils/automation-run-display.cjs.map +1 -0
- package/dist/utils/automation-run-display.d.ts +20 -0
- package/dist/utils/automation-run-display.js +85 -0
- package/dist/utils/automation-run-display.js.map +1 -0
- package/dist/utils/automation-schedule.cjs +1 -1
- package/dist/utils/automation-schedule.cjs.map +1 -1
- package/dist/utils/automation-schedule.d.ts +16 -0
- package/dist/utils/automation-schedule.js +2 -0
- package/dist/utils/automation-schedule.js.map +1 -1
- package/dist/utils/constants.cjs +1 -1
- package/dist/utils/constants.cjs.map +1 -1
- package/dist/utils/constants.d.ts +4 -0
- package/dist/utils/constants.js +23 -3
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/format-event-timestamp.cjs +2 -0
- package/dist/utils/format-event-timestamp.cjs.map +1 -0
- package/dist/utils/format-event-timestamp.d.ts +1 -0
- package/dist/utils/format-event-timestamp.js +13 -0
- package/dist/utils/format-event-timestamp.js.map +1 -0
- 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 +27 -6
- package/dist/utils/format-model-name.js +14 -6
- package/dist/utils/format-model-name.js.map +1 -1
- package/dist/utils/git-diff-stats.cjs +2 -2
- package/dist/utils/git-diff-stats.cjs.map +1 -1
- package/dist/utils/git-diff-stats.d.ts +4 -0
- package/dist/utils/git-diff-stats.js +12 -2
- package/dist/utils/git-diff-stats.js.map +1 -1
- package/dist/utils/plan-file.cjs +4 -0
- package/dist/utils/plan-file.cjs.map +1 -0
- package/dist/utils/plan-file.d.ts +18 -0
- package/dist/utils/plan-file.js +58 -0
- package/dist/utils/plan-file.js.map +1 -0
- package/dist/utils/recommended-automation-rail.cjs +1 -1
- package/dist/utils/recommended-automation-rail.cjs.map +1 -1
- package/dist/utils/recommended-automation-rail.js +1 -0
- package/dist/utils/recommended-automation-rail.js.map +1 -1
- package/dist/utils/scroll-fade-state.cjs +1 -1
- package/dist/utils/scroll-fade-state.cjs.map +1 -1
- package/dist/utils/scroll-fade-state.d.ts +6 -0
- package/dist/utils/scroll-fade-state.js +8 -1
- package/dist/utils/scroll-fade-state.js.map +1 -1
- package/dist/utils/sdk-settings-schema.cjs +1 -1
- package/dist/utils/sdk-settings-schema.cjs.map +1 -1
- package/dist/utils/sdk-settings-schema.d.ts +1 -0
- package/dist/utils/sdk-settings-schema.js +25 -22
- package/dist/utils/sdk-settings-schema.js.map +1 -1
- package/dist/utils/utils.cjs +1 -1
- package/dist/utils/utils.cjs.map +1 -1
- package/dist/utils/utils.js +11 -11
- package/dist/utils/utils.js.map +1 -1
- package/package.json +4 -4
- package/scripts/check-sdk-version-sync.mjs +6 -6
- package/scripts/dev-safe.mjs +1 -1
- package/scripts/dev-with-automation.mjs +1 -1
- package/scripts/static-server.mjs +33 -1
- package/build/assets/active-backend-context-CrHTlgvN.js +0 -2
- package/build/assets/agent-profiles-settings-Dzgb7G9z.js +0 -1
- package/build/assets/agent-server-conversation-service.api-tnqNjbpE.js +0 -86
- package/build/assets/agent-settings-DLtsqaOs.js +0 -2
- package/build/assets/agent-settings-fFvR-XC2.js +0 -1
- package/build/assets/alert-banner-HP6mX-Vr.js +0 -1
- package/build/assets/api-key-entry-screen-qTzrmJcr.js +0 -1
- package/build/assets/app-settings-dbnneVaV.js +0 -1
- package/build/assets/automation-detail-BmwlCUAB.js +0 -3
- package/build/assets/automation-git-sync-CprN5DcU.js +0 -1
- package/build/assets/automation-setup-route-C40kXjMY.js +0 -1
- package/build/assets/automations-list-DuNcRawl.js +0 -1
- package/build/assets/backend-form-modal-lhGwzXFI.js +0 -1
- package/build/assets/backend-synced-settings-badge-DPkz30BE.js +0 -1
- package/build/assets/badge-BU3S0VtE.js +0 -1
- package/build/assets/bot-dMYHVfYM.js +0 -1
- package/build/assets/browser-DSAo0tz1.js +0 -46
- package/build/assets/browser-tab-C9vy56R5.js +0 -1
- package/build/assets/canvas-extension-page-dx1gFrfW.js +0 -1
- package/build/assets/canvas-extensions-8A-XhpgP.js +0 -1
- package/build/assets/check-CS0vmpQQ.js +0 -1
- package/build/assets/chevron-down-e1QBpjVy.js +0 -1
- package/build/assets/chevron-right-ZG4R5G4Q.js +0 -1
- package/build/assets/circle-check-DzWLNsbE.js +0 -1
- package/build/assets/circle-plus-check-toggle-BO_kFZt3.js +0 -1
- package/build/assets/command-menu--UIlGL72.js +0 -1
- package/build/assets/commits-tab-AnZwLvh-.js +0 -1
- package/build/assets/confirmation-modal-Dv1ktp8K.js +0 -1
- package/build/assets/conversation-BbGrAO4Z.js +0 -93
- package/build/assets/conversation-mYT6NAoj.js +0 -1
- package/build/assets/conversation-panel-mYT6NAoj.js +0 -1
- package/build/assets/conversation-state-store-B0ImPLHO.js +0 -1
- package/build/assets/conversation-store-Ca3ghXap.js +0 -6
- package/build/assets/copy-to-clipboard-button-Ca8iSkkA.js +0 -1
- package/build/assets/device-verify-Bhn2e_Ye.js +0 -1
- package/build/assets/edit-automation-modal-DadGbJ2u.js +0 -1
- package/build/assets/empty-state-BoGVDecT.js +0 -1
- package/build/assets/enum-filter-dropdown-Bgca129f.js +0 -1
- package/build/assets/environment-switch-overlay-BmBRT7gv.js +0 -1
- package/build/assets/error-state-Body8Ngd.js +0 -1
- package/build/assets/extensions-hub-CcDqq_vR.js +0 -1
- package/build/assets/extensions-navigation-Cr4yzYk4.js +0 -1
- package/build/assets/external-link-DKUlnCQV.js +0 -1
- package/build/assets/files-tab-D4o2VyE_.js +0 -1
- package/build/assets/format-model-name-CasAP3nd.js +0 -1
- package/build/assets/get-git-path-ChKDVHZp.js +0 -1
- package/build/assets/git-repo-dropdown-4ROKl2cB.js +0 -1
- package/build/assets/git-repo-dropdown-BkqzkMmM.js +0 -1
- package/build/assets/highlighted-source-view-BFRxGT_Q.js +0 -1
- package/build/assets/home-ChpSuepX.js +0 -1
- package/build/assets/home-DIsB440S.js +0 -1
- package/build/assets/home-automation-run-tooltip-BVNDWjAH.js +0 -1
- package/build/assets/home-store-CY9Ej0ux.js +0 -1
- package/build/assets/index-home-BdlrFIif.js +0 -1
- package/build/assets/info-B6RQawoW.js +0 -1
- package/build/assets/install-server-modal-Dpy89p4g.js +0 -1
- package/build/assets/kebab-menu-item-content-D8hSNGmm.js +0 -1
- package/build/assets/launch-IrTDEFCs.js +0 -1
- package/build/assets/list-filter-DsEK7NFC.js +0 -1
- package/build/assets/llm-not-configured-banner-CIFABh3K.js +0 -27
- package/build/assets/llm-settings-B9juXhIa.js +0 -1
- package/build/assets/llm-settings-De1d5dfr.js +0 -1
- package/build/assets/llm-subscription-service-BpJ0ouQo.js +0 -1
- package/build/assets/loader-circle-CC1au6hc.js +0 -1
- package/build/assets/manage-backends-modal-BrPV3oB-.js +0 -1
- package/build/assets/manifest-80fb1c29.js +0 -1
- package/build/assets/manifest-subpage-layout-CAOYzrYp.js +0 -1
- package/build/assets/markdown-renderer-BzTlxI8x.js +0 -8
- package/build/assets/mcp-BTs_SXfZ.js +0 -1
- package/build/assets/mcp-page-BEBYqH_K.js +0 -9
- package/build/assets/messages-DKV9cRc2.js +0 -41
- package/build/assets/modal-close-button-DDzdRvCs.js +0 -1
- package/build/assets/onboarding-DV_OXoeP.js +0 -1
- package/build/assets/onboarding-modal-rkyBYkeQ.js +0 -1
- package/build/assets/organization-service.api-DrYNkEN_.js +0 -1
- package/build/assets/pencil-47jAZH_V.js +0 -1
- package/build/assets/pin-By41Vl5J.js +0 -1
- package/build/assets/planner-tab-C9uZmhme.js +0 -1
- package/build/assets/plug-CG5HFcNG.js +0 -1
- package/build/assets/plugins-management-service-BMJgC3Ga.js +0 -1
- package/build/assets/plus-C7Slq-0I.js +0 -1
- package/build/assets/profiles-service.api-ChoKrL0l.js +0 -1
- package/build/assets/providers-BhMcY5nv.js +0 -1
- package/build/assets/proxy-9Fe1v5na.js +0 -1
- package/build/assets/recommended-automations-launcher-6ABrI9Cy.js +0 -1
- package/build/assets/refresh-cw-3q3Frrii.js +0 -1
- package/build/assets/root-Dc8YmC9F.js +0 -2
- package/build/assets/root-VDaypvK4.css +0 -1
- package/build/assets/root-layout-CXkhSPYh.js +0 -2
- package/build/assets/schema-field-D-y9-LDb.js +0 -1
- package/build/assets/scroll-fade-state-Dw-i4SGq.js +0 -1
- package/build/assets/sdk-section-page-BlFiizlG.js +0 -1
- package/build/assets/secret-form-BB7the8W.js +0 -1
- package/build/assets/secrets-service-ByZVENbp.js +0 -1
- package/build/assets/secrets-settings-B_GpxKW2.js +0 -1
- package/build/assets/settings-C0EWuBtA.js +0 -1
- package/build/assets/settings-dropdown-input-BcwylHs2.js +0 -1
- package/build/assets/settings-index-5w5UW2K3.js +0 -1
- package/build/assets/settings-input-Db-1g8Ql.js +0 -1
- package/build/assets/settings-modal-DfJ3tcJQ.js +0 -1
- package/build/assets/settings-service.api-DJ1r62Zr.js +0 -1
- package/build/assets/settings-switch-CS-dJDmA.js +0 -1
- package/build/assets/shared-conversation-CA5ISEDy.js +0 -1
- package/build/assets/shield-check-D2aCRd16.js +0 -1
- package/build/assets/sidebar-mobile-menu-toggle-C_fb0Jki.js +0 -1
- package/build/assets/sidebar-store-DGqHkVLw.js +0 -1
- package/build/assets/skill-card-pill-row-B27-xyig.js +0 -1
- package/build/assets/skill-scope-B42H-XOc.js +0 -1
- package/build/assets/skills-plugins-tgF8EiXC.js +0 -1
- package/build/assets/skills-settings-BgJ9PaOe.js +0 -1
- package/build/assets/styled-tooltip-C4jf5Fv9.js +0 -1
- package/build/assets/task-list-tab-C5zcaktH.js +0 -1
- package/build/assets/toggle-switch-ChOLXv2n.js +0 -1
- package/build/assets/trash-2-D7K26eDO.js +0 -1
- package/build/assets/trash-D-HYiVYM.js +0 -1
- package/build/assets/triangle-alert-CtdXWHUI.js +0 -1
- package/build/assets/usage-tab-CVDffLPt.js +0 -1
- package/build/assets/use-acp-credential-form-XIQmpX6M.js +0 -1
- package/build/assets/use-activate-agent-profile-BLfmvDiG.js +0 -1
- package/build/assets/use-agent-profiles-Bd9Bvvp1.js +0 -1
- package/build/assets/use-canvas-extensions-Bi693ujJ.js +0 -1
- package/build/assets/use-config-A9QovgXO.js +0 -1
- package/build/assets/use-create-conversation-Dx3l7mFZ.js +0 -1
- package/build/assets/use-create-secret-B9cUFWRG.js +0 -1
- package/build/assets/use-has-permission-B3C8rQmR.js +0 -1
- package/build/assets/use-is-authed-nTBcM7dE.js +0 -1
- package/build/assets/use-llm-configured-BV9nZ1_j.js +0 -1
- package/build/assets/use-llm-profiles-BO-P4Oyo.js +0 -1
- package/build/assets/use-manifest-capabilities-Cw_flwEz.js +0 -1
- package/build/assets/use-onboarding-completion-D8U7k4Qb.js +0 -1
- package/build/assets/use-pinned-home-route-CckOZrmb.js +0 -1
- package/build/assets/use-plugins-marketplace-7i94Zu3Z.js +0 -1
- package/build/assets/use-save-agent-profile-BUjSsDXK.js +0 -1
- package/build/assets/use-settings-DSXLbvBl.js +0 -1
- package/build/assets/use-settings-nav-items-CwRw-CmX.js +0 -16
- package/build/assets/use-tracking-D53y3TH9.js +0 -3
- package/build/assets/useQueries-DlbhlH9I.js +0 -1
- package/build/assets/useQuery-BSTgq1rl.js +0 -1
- package/build/assets/utils-CN5ZfZy1.js +0 -1
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~czjee3a3-DqZDXfg2.js +0 -186
- package/build/assets/vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~ew9ih1s8-rfV8mQ9m.js +0 -1
- package/build/assets/vendor~root-layout-C9Ju9DQg.js +0 -1
- package/build/assets/vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-BWir3rJs.js +0 -1
- package/build/assets/vendor~root-layout~index-home~home~conversation-panel~conversation~mcp~automations-list~aut~ibfbmr9f-cDuKr-WD.js +0 -1
- package/build/assets/vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~iyia17eu-Chf7vmKB.js +0 -1
- package/build/assets/x-DJdhbdmt.js +0 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +0 -2
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +0 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +0 -35
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +0 -247
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +0 -1
- package/dist/hooks/query/use-skills.cjs +0 -2
- package/dist/hooks/query/use-skills.cjs.map +0 -1
- package/dist/hooks/query/use-skills.d.ts +0 -7
- package/dist/hooks/query/use-skills.js +0 -13
- package/dist/hooks/query/use-skills.js.map +0 -1
- package/dist/hooks/use-has-permission.cjs +0 -2
- package/dist/hooks/use-has-permission.cjs.map +0 -1
- package/dist/hooks/use-has-permission.d.ts +0 -1
- package/dist/hooks/use-has-permission.js +0 -8
- package/dist/hooks/use-has-permission.js.map +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.cjs +0 -2
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.cjs.map +0 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.js +0 -14
- package/dist/node_modules/lucide-react/dist/esm/icons/eye.js.map +0 -1
|
@@ -693,6 +693,7 @@
|
|
|
693
693
|
"SETTINGS$RESET": "設置已重置",
|
|
694
694
|
"SETTINGS$API_KEYS": "API金鑰",
|
|
695
695
|
"SETTINGS$API_KEYS_DESCRIPTION": "API密鑰允許您以編程方式驗證OpenHands API。請確保您的API密鑰安全;任何擁有您API密鑰的人都可以訪問您的賬戶。有關如何使用API的更多信息,請參閱我們的<a>API文檔</a>。",
|
|
696
|
+
"SETTINGS$OPENHANDS_FREE_MODELS_NOTE": "免費的 OpenHands 模型:{{ids}}。其他供應商中名稱相似的模型端點可能需要另外付費。",
|
|
696
697
|
"SETTINGS$OPENHANDS_API_KEY_HELP_TEXT": "您可以在",
|
|
697
698
|
"SETTINGS$OPENHANDS_API_KEY_HELP_LINK": "OpenHands LLM Key",
|
|
698
699
|
"SETTINGS$OPENHANDS_API_KEY_HELP_SUFFIX": "區塊中找到您的 OpenHands Provider LLM Key -",
|
|
@@ -797,7 +798,9 @@
|
|
|
797
798
|
"AUTOMATIONS$ERROR_TIMEOUT_INVALID_NUMBER": "超時必須是有效數字",
|
|
798
799
|
"AUTOMATIONS$ERROR_TIMEOUT_POSITIVE": "超時必須為正數",
|
|
799
800
|
"AUTOMATIONS$ERROR_TIMEOUT_MAX_EXCEEDED": "超時不能超過{{max}}秒",
|
|
800
|
-
"AUTOMATIONS$
|
|
801
|
+
"AUTOMATIONS$CRON_EXPRESSION": "Cron 運算式",
|
|
802
|
+
"AUTOMATIONS$ERROR_CRON_INVALID": "請輸入有效的 cron 運算式",
|
|
803
|
+
"AUTOMATIONS$ERROR_CRON_UNREACHABLE": "此 cron 運算式永遠不會執行",
|
|
801
804
|
"AUTOMATIONS$EDIT_SUCCESS": "自動化已更新",
|
|
802
805
|
"AUTOMATIONS$EDIT_ERROR": "無法更新自動化",
|
|
803
806
|
"AUTOMATIONS$RUN_NOW_SUCCESS": "自動化已觸發",
|
|
@@ -817,6 +820,18 @@
|
|
|
817
820
|
"AUTOMATIONS$DETAIL$RUNNING": "執行中",
|
|
818
821
|
"AUTOMATIONS$DETAIL$CANCELLED": "已取消",
|
|
819
822
|
"AUTOMATIONS$DETAIL$SKIPPED": "已略過",
|
|
823
|
+
"AUTOMATIONS$DETAIL$BLOCKED": "受阻",
|
|
824
|
+
"AUTOMATIONS$DETAIL$PARTIAL": "部分完成",
|
|
825
|
+
"AUTOMATIONS$DETAIL$NEEDS_REVIEW": "需要審查",
|
|
826
|
+
"AUTOMATIONS$DETAIL$RUN_LABEL": "執行",
|
|
827
|
+
"AUTOMATIONS$DETAIL$TASK_LABEL": "任務",
|
|
828
|
+
"AUTOMATIONS$DETAIL$SYSTEM_LABEL": "系統",
|
|
829
|
+
"AUTOMATIONS$DETAIL$NO_TASK_OUTCOME": "未回報任務結果。",
|
|
830
|
+
"AUTOMATIONS$DETAIL$NO_SYSTEM_ISSUES": "未回報系統問題。",
|
|
831
|
+
"AUTOMATIONS$DETAIL$STATUS_DETAIL": "狀態詳細資訊",
|
|
832
|
+
"AUTOMATIONS$DETAIL$TASK_METADATA": "任務中繼資料",
|
|
833
|
+
"AUTOMATIONS$DETAIL$CUSTOM_TASK_METADATA": "已回報自訂任務中繼資料。",
|
|
834
|
+
"AUTOMATIONS$DETAIL$VIEW_CONVERSATION_FOR_RUN": "查看 {{timestamp}} 執行的對話",
|
|
820
835
|
"AUTOMATIONS$DETAIL$PHASE": "階段",
|
|
821
836
|
"AUTOMATIONS$DETAIL$PHASE_QUEUED": "排隊中",
|
|
822
837
|
"AUTOMATIONS$DETAIL$PHASE_SANDBOX_PROVISIONING": "正在設定沙盒",
|
|
@@ -861,6 +876,7 @@
|
|
|
861
876
|
"AUTOMATIONS$DETAIL$PLUGINS": "外掛",
|
|
862
877
|
"AUTOMATIONS$DETAIL$PROMPT": "提示",
|
|
863
878
|
"AUTOMATIONS$DETAIL$REPOSITORIES": "存放庫",
|
|
879
|
+
"AUTOMATIONS$DETAIL$RUNS_AS": "自動化執行身分",
|
|
864
880
|
"AUTOMATIONS$DETAIL$SCHEDULE": "排程",
|
|
865
881
|
"AUTOMATIONS$DETAIL$SUCCESSFUL": "成功",
|
|
866
882
|
"AUTOMATIONS$DETAIL$TRIGGER": "觸發器",
|
|
@@ -1034,27 +1050,48 @@
|
|
|
1034
1050
|
"CONVERSATION_PANEL$ORGANIZE": "整理",
|
|
1035
1051
|
"CONVERSATION_PANEL$BY_WORKSPACE": "依工作區",
|
|
1036
1052
|
"CONVERSATION_PANEL$BY_REPOSITORY": "依存放庫",
|
|
1037
|
-
"CONVERSATION_PANEL$CHRONOLOGICAL": "
|
|
1053
|
+
"CONVERSATION_PANEL$CHRONOLOGICAL": "依日期",
|
|
1054
|
+
"CONVERSATION_PANEL$CLEAR_FILTERS": "全部清除",
|
|
1038
1055
|
"CONVERSATION_PANEL$SORT_BY": "排序依據",
|
|
1039
1056
|
"CONVERSATION_PANEL$SORT_CREATED": "建立時間",
|
|
1040
1057
|
"CONVERSATION_PANEL$SORT_UPDATED": "更新時間",
|
|
1041
1058
|
"CONVERSATION_PANEL$OLDER_SECTION": "較舊的對話",
|
|
1042
1059
|
"CONVERSATION_PANEL$OLDER_OVER_ONE_HOUR": "超過 1 小時",
|
|
1043
|
-
"CONVERSATION_PANEL$
|
|
1060
|
+
"CONVERSATION_PANEL$OLDER_OVER_ONE_DAY": "超過 1 天",
|
|
1061
|
+
"CONVERSATION_PANEL$OLDER_OVER_ONE_WEEK": "超過 1 週",
|
|
1062
|
+
"CONVERSATION_PANEL$OLDER_OVER_THIRTY_DAYS": "超過 30 天",
|
|
1063
|
+
"CONVERSATION_PANEL$HIDE_CONVERSATIONS": "隱藏舊對話",
|
|
1064
|
+
"CONVERSATION_PANEL$OLDER_CUTOFF_LABEL": "隱藏早於此時間的對話",
|
|
1065
|
+
"CONVERSATION_PANEL$SHOW": "其他",
|
|
1066
|
+
"CONVERSATION_PANEL$THREADS": "對話串",
|
|
1044
1067
|
"CONVERSATION_PANEL$ALL_THREADS": "所有對話串",
|
|
1045
|
-
"CONVERSATION_PANEL$RELEVANT_THREADS": "
|
|
1068
|
+
"CONVERSATION_PANEL$RELEVANT_THREADS": "僅作用中",
|
|
1046
1069
|
"CONVERSATION_PANEL$SHOW_ARCHIVED": "顯示已封存",
|
|
1047
1070
|
"CONVERSATION_PANEL$METADATA": "中繼資料",
|
|
1048
1071
|
"CONVERSATION_PANEL$LLM_MODEL": "代理 / 模型",
|
|
1049
1072
|
"CONVERSATION_PANEL$REPO_BRANCH": "存放庫與分支",
|
|
1050
1073
|
"CONVERSATION_PANEL$TAGS": "標籤",
|
|
1074
|
+
"CONVERSATION_PANEL$SHOW_TAGS": "顯示 {{count}} 個標籤",
|
|
1075
|
+
"CONVERSATION_PANEL$HIDE_TAGS": "隱藏標籤",
|
|
1076
|
+
"CONVERSATION_PANEL$TAG_CHIPS": "顯示標籤",
|
|
1077
|
+
"CONVERSATION_PANEL$LAYOUTS_HEADING": "檢視",
|
|
1078
|
+
"CONVERSATION_PANEL$LAYOUT_RECENT_ACTIVITY": "最近",
|
|
1079
|
+
"CONVERSATION_PANEL$LAYOUT_FOCUSED": "作用中",
|
|
1080
|
+
"CONVERSATION_PANEL$LAYOUT_MINIMAL": "精簡",
|
|
1081
|
+
"CONVERSATION_PANEL$TAG_FILTERS": "依標籤篩選",
|
|
1082
|
+
"CONVERSATION_PANEL$NO_VISIBLE_TAGS": "尚無標籤",
|
|
1083
|
+
"CONVERSATION_PANEL$ADVANCED_OPTIONS": "更多選項",
|
|
1084
|
+
"CONVERSATION_PANEL$ADVANCED_OPTIONS_CUSTOM": "自訂",
|
|
1085
|
+
"CONVERSATION_PANEL$ADVANCED_OPTIONS_DESCRIPTION": "選擇對話如何分組以及每列顯示什麼。變更會自動儲存。",
|
|
1086
|
+
"CONVERSATION_PANEL$SHOW_OLDER_CONVERSATIONS": "顯示較早的對話",
|
|
1051
1087
|
"CONVERSATION_PANEL$AUTOMATIONS": "自動化",
|
|
1052
|
-
"CONVERSATION_PANEL$AUTOMATIONS_ALL": "
|
|
1088
|
+
"CONVERSATION_PANEL$AUTOMATIONS_ALL": "與全部一起顯示",
|
|
1053
1089
|
"CONVERSATION_PANEL$AUTOMATIONS_HIDE": "隱藏自動化執行",
|
|
1054
1090
|
"CONVERSATION_PANEL$AUTOMATIONS_ONLY": "僅自動化執行",
|
|
1055
1091
|
"CONVERSATION_PANEL$AUTOMATION_UNNAMED": "未命名自動化",
|
|
1056
1092
|
"CONVERSATION_PANEL$NO_AUTOMATION_MATCHES": "沒有對話符合自動化篩選條件",
|
|
1057
|
-
"CONVERSATION_PANEL$
|
|
1093
|
+
"CONVERSATION_PANEL$NO_TAG_MATCHES": "沒有對話符合標籤篩選條件",
|
|
1094
|
+
"CONVERSATION_PANEL$HOVER_METADATA": "懸停時顯示詳情",
|
|
1058
1095
|
"CONVERSATION_PANEL$NO_WORKSPACE": "無工作區",
|
|
1059
1096
|
"CONVERSATION_PANEL$NO_REPOSITORY": "無存放庫",
|
|
1060
1097
|
"CONVERSATION_PANEL$NEW_THREAD_FOLDER_ARIA": "建立對話資料夾 — 選擇工作區或存放庫",
|
|
@@ -1112,7 +1149,6 @@
|
|
|
1112
1149
|
"CONVERSATION$TOTAL_COST": "總成本",
|
|
1113
1150
|
"CONVERSATION$BUDGET": "預算",
|
|
1114
1151
|
"CONVERSATION$BUDGET_USAGE": "% 已使用",
|
|
1115
|
-
"CONVERSATION$NO_BUDGET_LIMIT": "無預算限制",
|
|
1116
1152
|
"CONVERSATION$INPUT": "輸入",
|
|
1117
1153
|
"CONVERSATION$OUTPUT": "輸出",
|
|
1118
1154
|
"CONVERSATION$TOTAL": "總計",
|
|
@@ -1220,7 +1256,7 @@
|
|
|
1220
1256
|
"SETTINGS$FAILED_TO_SAVE_EMAIL": "儲存郵箱失敗",
|
|
1221
1257
|
"SETTINGS$SENDING": "發送中",
|
|
1222
1258
|
"SETTINGS$VERIFICATION_EMAIL_SENT": "驗證郵件已發送",
|
|
1223
|
-
"SETTINGS$EMAIL_VERIFICATION_REQUIRED": "使用
|
|
1259
|
+
"SETTINGS$EMAIL_VERIFICATION_REQUIRED": "使用OpenHands前,您必須驗證您的電子郵件地址",
|
|
1224
1260
|
"SETTINGS$INVALID_EMAIL_FORMAT": "請輸入有效的電子郵件地址",
|
|
1225
1261
|
"SETTINGS$EMAIL_VERIFICATION_RESTRICTION_MESSAGE": "在驗證您的電子郵件之前,您的訪問權限受到限制。您只能訪問此設置頁面。",
|
|
1226
1262
|
"SETTINGS$RESEND_VERIFICATION": "重新發送驗證",
|
|
@@ -1286,7 +1322,7 @@
|
|
|
1286
1322
|
"API$TVLY_KEY_EXAMPLE": "tvly-...",
|
|
1287
1323
|
"SECRETS$CONNECT_GIT_PROVIDER": "連接Git提供商以管理密鑰",
|
|
1288
1324
|
"SETTINGS$OPENHANDS_API_KEYS": "OpenHands API密鑰",
|
|
1289
|
-
"CONVERSATION$BUDGET_USAGE_FORMAT": "
|
|
1325
|
+
"CONVERSATION$BUDGET_USAGE_FORMAT": "{{currentCost}} / {{maxBudget}} ({{usagePercentage}}% {{used}})",
|
|
1290
1326
|
"CONVERSATION$CACHE_HIT": "緩存命中",
|
|
1291
1327
|
"CONVERSATION$CACHE_WRITE": "緩存寫入",
|
|
1292
1328
|
"BUTTON$CONFIRM": "確認",
|
|
@@ -1880,7 +1916,8 @@
|
|
|
1880
1916
|
"THINKING$COLLAPSE": "摺疊思考",
|
|
1881
1917
|
"MCP$LIBRARY_TITLE": "資料庫",
|
|
1882
1918
|
"NAV$CUSTOMIZE": "自訂",
|
|
1883
|
-
"NAV$EXTENSIONS": "
|
|
1919
|
+
"NAV$EXTENSIONS": "應用程式",
|
|
1920
|
+
"SETTINGS$APPS_PAGE_TITLE": "Agent Canvas 應用程式",
|
|
1884
1921
|
"NAV$COMING_SOON": "即將推出",
|
|
1885
1922
|
"SETTINGS$PLUGINS_TITLE": "外掛程式",
|
|
1886
1923
|
"SETTINGS$PLUGINS_DESCRIPTION": "外掛程式設定選項將顯示於此。",
|
|
@@ -1907,17 +1944,21 @@
|
|
|
1907
1944
|
"SETTINGS$PLUGINS_UNINSTALL_SUCCESS": "外掛程式已解除安裝。",
|
|
1908
1945
|
"SETTINGS$PLUGINS_REFRESH_SUCCESS": "外掛程式已更新。",
|
|
1909
1946
|
"SETTINGS$PLUGINS_SKILLS_IN_BUNDLE": "此外掛程式套件中的技能",
|
|
1910
|
-
"SETTINGS$
|
|
1911
|
-
"SETTINGS$
|
|
1912
|
-
"SETTINGS$
|
|
1913
|
-
"SETTINGS$
|
|
1914
|
-
"SETTINGS$
|
|
1915
|
-
"SETTINGS$
|
|
1916
|
-
"SETTINGS$
|
|
1917
|
-
"SETTINGS$
|
|
1918
|
-
"SETTINGS$
|
|
1919
|
-
"SETTINGS$
|
|
1920
|
-
"SETTINGS$
|
|
1947
|
+
"SETTINGS$APPS_PAGE_DESCRIPTION": "應用程式使用 Canvas Extensions API 建置",
|
|
1948
|
+
"SETTINGS$APPS_BUILD_LINK": "建置應用程式",
|
|
1949
|
+
"SETTINGS$APPS_ADD_BUTTON": "新增應用程式",
|
|
1950
|
+
"SETTINGS$APPS_INSTALLED": "已安裝的應用程式",
|
|
1951
|
+
"SETTINGS$APPS_SOURCE_LABEL": "應用程式來源",
|
|
1952
|
+
"SETTINGS$APPS_EMPTY": "此後端未安裝任何應用程式。",
|
|
1953
|
+
"SETTINGS$APPS_TRUST_NOTICE": "此應用程式會在 Agent Canvas 中執行受信任的 JavaScript,並可向目前的 Agent Server 發出經過驗證的請求。啟用前請檢查其原始碼和修訂版本。",
|
|
1954
|
+
"SETTINGS$APPS_ENABLE_ACTION": "啟用受信任的應用程式",
|
|
1955
|
+
"SETTINGS$APPS_ADD_MODAL_INTRO": "從 Git 來源或目前 Agent Server 上的路徑安裝。應用程式安裝後將保持停用。",
|
|
1956
|
+
"SETTINGS$APPS_INSTALL_SUCCESS": "應用程式已安裝。請在此檢查,準備好後再啟用。",
|
|
1957
|
+
"SETTINGS$APPS_UNINSTALL_SUCCESS": "應用程式已解除安裝。",
|
|
1958
|
+
"SETTINGS$APPS_ENABLE_CONFIRM": "此應用程式會在 Agent Canvas 中執行受信任的 JavaScript,並可向目前的 Agent Server 發出經過驗證的請求。啟用前請檢查其原始碼和修訂版本。",
|
|
1959
|
+
"SETTINGS$APPS_UNINSTALL_CONFIRM": "要從此後端解除安裝 {{name}} 嗎?",
|
|
1960
|
+
"SETTINGS$APPS_PAGES": "頁面",
|
|
1961
|
+
"SETTINGS$APPS_PAGE_UNAVAILABLE": "此應用程式已停用、缺少或未提供此頁面。",
|
|
1921
1962
|
"SETTINGS$SKILLS_PAGE_DESCRIPTION": "探索要加入工作區的技能。開啟卡片以查看提示、curl 和安裝流程。從側邊欄搜尋以篩選清單。啟用或停用預設技能。停用的技能不會載入到代理上下文中。",
|
|
1922
1963
|
"SETTINGS$SKILLS_ADD_BUTTON": "新增技能",
|
|
1923
1964
|
"SETTINGS$SKILLS_USE_SKILL_BUTTON": "使用技能",
|
|
@@ -2161,6 +2202,9 @@
|
|
|
2161
2202
|
"SETUP$VALIDATION_INVALID_OPTION": "請從可用選項中選擇。",
|
|
2162
2203
|
"SETUP$VALIDATION_UNSAFE_VALUE": "不允許使用引號和反斜線。",
|
|
2163
2204
|
"SETUP$REVIEW_TITLE": "確認",
|
|
2205
|
+
"SETUP$ACTION_LABEL": "動作",
|
|
2206
|
+
"SETUP$TRIGGER_LABEL": "觸發條件",
|
|
2207
|
+
"SETUP$TRIGGER_HELP": "選擇自動化要依排程執行,還是在事件到達時執行。",
|
|
2164
2208
|
"SETUP$CONFIRM": "確認並建立",
|
|
2165
2209
|
"SETUP$FALLBACK_CONVERSATION": "在對話中設定",
|
|
2166
2210
|
"SETUP$EMPTY_VALUE": "未設定",
|
|
@@ -2267,6 +2311,16 @@
|
|
|
2267
2311
|
"CHAT_INTERFACE$CONTEXT_WINDOW_METER_LABEL": "上下文視窗用量",
|
|
2268
2312
|
"CHAT_INTERFACE$SHOW_CONTEXT": "顯示上下文",
|
|
2269
2313
|
"CONVERSATION$TAGS_OVERFLOW_ARIA": "顯示另外 {{count}} 個標籤",
|
|
2314
|
+
"CONVERSATION$EDIT_TAGS": "編輯標籤",
|
|
2315
|
+
"CONVERSATION$EDIT_TAGS_DESCRIPTION": "為此對話新增或刪除標籤。",
|
|
2316
|
+
"CONVERSATION$TAG_KEY_PLACEHOLDER": "名稱",
|
|
2317
|
+
"CONVERSATION$TAG_VALUE_PLACEHOLDER": "值(選填)",
|
|
2318
|
+
"CONVERSATION$REMOVE_TAG": "刪除標籤",
|
|
2319
|
+
"CONVERSATION$TAG_KEY_INVALID": "標籤名稱只能包含小寫字母和數字",
|
|
2320
|
+
"CONVERSATION$TAG_KEY_RESERVED": "此標籤名稱已被保留",
|
|
2321
|
+
"CONVERSATION$TAG_KEY_DUPLICATE": "此標籤名稱已被使用",
|
|
2322
|
+
"CONVERSATION$TAG_VALUE_INVALID": "標籤值不能超過 256 個字元",
|
|
2323
|
+
"CONVERSATION$TAGS_UPDATED": "標籤已更新",
|
|
2270
2324
|
"CONVERSATION_PANEL$PREVIEW_GIT": "Git",
|
|
2271
2325
|
"CONVERSATION_PANEL$PREVIEW_REPO": "倉庫",
|
|
2272
2326
|
"CONVERSATION_PANEL$PREVIEW_BRANCH": "分支",
|
|
@@ -2398,5 +2452,8 @@
|
|
|
2398
2452
|
"SETTINGS$PROVIDER_CONNECTION_PROVIDER": "提供者",
|
|
2399
2453
|
"SETTINGS$PROVIDER_CONNECTION_ROTATE_HINT": "留空以保留目前的金鑰。",
|
|
2400
2454
|
"SETTINGS$PROVIDER_CONNECTION_SELECT_LABEL": "提供者連線",
|
|
2401
|
-
"SETTINGS$PROVIDER_CONNECTION_UPDATED": "已更新連線「{{name}}」"
|
|
2455
|
+
"SETTINGS$PROVIDER_CONNECTION_UPDATED": "已更新連線「{{name}}」",
|
|
2456
|
+
"BUTTON$VIEW_FULL_SIZE_IMAGE": "檢視原始尺寸圖片",
|
|
2457
|
+
"BUTTON$REMOVE_IMAGE": "移除圖片",
|
|
2458
|
+
"IMAGE$FULL_SIZE_PREVIEW": "原始尺寸圖片預覽"
|
|
2402
2459
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-insights.cjs","names":[],"sources":["../../src/manifests/automation-insights.ts"],"sourcesContent":["/**\n * The dashboard's automation knowledge, and the only module beside\n * `automation-setup.ts` that has any.\n *\n * The interface manifest's dashboard surface names metrics, filter predicates,\n * and sort comparators from closed sets; the one implementation of each name\n * is here, over the automation service's list and runs responses, so the rest\n * of `src/manifests/` stays about composition rather than about automations.\n *\n * Summaries are derived from the newest page of runs (the sample the runs\n * hook fetches); `total` alone is the response's lifetime count. Success rate\n * and durations consider only COMPLETED and FAILED runs — a cancelled or\n * skipped run says nothing about either.\n */\n\nimport {\n AutomationRunStatus,\n type Automation,\n type AutomationRun,\n type AutomationRunsResponse,\n} from \"#/types/automation\";\nimport type {\n DashboardSortValue,\n DashboardStatusValue,\n DashboardTriggerValue,\n InterfaceListInsights,\n OverviewMetric,\n} from \"./types\";\n\nexport type AutomationHealth =\n | \"healthy\"\n | \"failing\"\n | \"running\"\n | \"disabled\"\n | \"never-run\"\n | \"unknown\";\n\n/** Which caption of the manifest's `insights.health` block names each state. */\nexport const HEALTH_LABEL_KEYS: Record<\n AutomationHealth,\n keyof InterfaceListInsights[\"health\"]\n> = {\n healthy: \"healthy\",\n failing: \"failing\",\n running: \"running\",\n disabled: \"disabled\",\n \"never-run\": \"neverRun\",\n unknown: \"checking\",\n};\n\nexport interface AutomationRunSummary {\n /** Lifetime run count, from the response — not the sample's length. */\n total: number;\n latestRun: AutomationRun | null;\n /** Newest-first sample used by the list sparkline (same page as the summary). */\n recentRuns: AutomationRun[];\n /** COMPLETED over COMPLETED+FAILED in the sample. Null with no terminal runs. */\n recentSuccessRate: number | null;\n /** Mean completed_at − started_at over the sample's terminal runs. */\n averageDurationMs: number | null;\n}\n\n/** One automation's summary alongside its query state. */\nexport interface RunSummaryState {\n summary: AutomationRunSummary | null;\n isLoading: boolean;\n isError: boolean;\n}\n\ntype Summaries = ReadonlyMap<string, RunSummaryState>;\n\nconst TERMINAL_STATUSES = new Set<AutomationRunStatus>([\n AutomationRunStatus.COMPLETED,\n AutomationRunStatus.FAILED,\n]);\n\nexport function summarizeAutomationRuns(\n response: AutomationRunsResponse,\n): AutomationRunSummary {\n const terminal = response.runs.filter((run) =>\n TERMINAL_STATUSES.has(run.status),\n );\n const completed = terminal.filter(\n (run) => run.status === AutomationRunStatus.COMPLETED,\n ).length;\n\n const durations = terminal.flatMap((run) => {\n if (!run.completed_at) return [];\n const ms =\n new Date(run.completed_at).getTime() - new Date(run.started_at).getTime();\n return Number.isFinite(ms) && ms >= 0 ? [ms] : [];\n });\n\n return {\n total: response.total,\n latestRun: response.runs[0] ?? null,\n recentRuns: response.runs,\n recentSuccessRate:\n terminal.length === 0 ? null : completed / terminal.length,\n averageDurationMs:\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length,\n };\n}\n\n/**\n * A disabled automation is disabled no matter its history; while the summary\n * is unsettled nothing is claimed; after that the latest run speaks.\n */\nexport function deriveAutomationHealth(\n automation: Automation,\n state: RunSummaryState | undefined,\n): AutomationHealth {\n if (!automation.enabled) return \"disabled\";\n if (!state || state.isError || state.isLoading || !state.summary) {\n return \"unknown\";\n }\n const latest = state.summary.latestRun;\n if (!latest) return \"never-run\";\n if (latest.status === AutomationRunStatus.FAILED) return \"failing\";\n if (\n latest.status === AutomationRunStatus.PENDING ||\n latest.status === AutomationRunStatus.RUNNING\n ) {\n return \"running\";\n }\n return \"healthy\";\n}\n\n/** \"—\" unknown, seconds under a minute, minutes under an hour, else \"1.5h\". */\nexport function formatCompactDuration(ms: number | null): string {\n if (ms === null || !Number.isFinite(ms)) return \"—\";\n if (ms < 60_000) return `${Math.max(1, Math.round(ms / 1000))}s`;\n if (ms < 3_600_000) return `${Math.max(1, Math.round(ms / 60_000))}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n/** The list page's search predicate: name, prompt, repository, or model. */\nexport function matchesAutomationSearch(\n automation: Automation,\n query: string,\n): boolean {\n const q = query.toLowerCase();\n if (!q) return true;\n return (\n automation.name.toLowerCase().includes(q) ||\n (automation.prompt ?? \"\").toLowerCase().includes(q) ||\n automation.repository?.toLowerCase().includes(q) === true ||\n automation.model?.toLowerCase().includes(q) === true\n );\n}\n\nconst STATUS_PREDICATES: Record<\n Exclude<DashboardStatusValue, \"all\">,\n (automation: Automation, health: AutomationHealth) => boolean\n> = {\n active: (automation) => automation.enabled,\n failing: (_automation, health) => health === \"failing\",\n disabled: (automation) => !automation.enabled,\n};\n\nconst TRIGGER_PREDICATES: Record<\n Exclude<DashboardTriggerValue, \"all\">,\n (automation: Automation) => boolean\n> = {\n // The backend emits several scheduled-trigger aliases, so \"event\" is the\n // one exact kind and everything else is a schedule.\n event: (automation) => automation.trigger.type === \"event\",\n schedule: (automation) => automation.trigger.type !== \"event\",\n};\n\nfunction runCount(automation: Automation, byId: Summaries): number {\n return byId.get(automation.id)?.summary?.total ?? 0;\n}\n\nfunction lastRunTime(automation: Automation, byId: Summaries): number {\n const startedAt =\n byId.get(automation.id)?.summary?.latestRun?.started_at ??\n automation.last_triggered_at;\n if (!startedAt) return 0;\n const time = new Date(startedAt).getTime();\n return Number.isFinite(time) ? time : 0;\n}\n\nconst SORT_COMPARATORS: Record<\n DashboardSortValue,\n (a: Automation, b: Automation, byId: Summaries) => number\n> = {\n \"last-run\": (a, b, byId) => lastRunTime(b, byId) - lastRunTime(a, byId),\n runs: (a, b, byId) => runCount(b, byId) - runCount(a, byId),\n name: (a, b) => a.name.localeCompare(b.name),\n};\n\nexport interface DashboardViewState {\n search: string;\n status: DashboardStatusValue;\n trigger: DashboardTriggerValue;\n sort: DashboardSortValue;\n}\n\n/** The automations the dashboard shows, filtered and ordered. */\nexport function applyDashboardView(\n automations: readonly Automation[],\n view: DashboardViewState,\n byId: Summaries,\n): Automation[] {\n return automations\n .filter((automation) => {\n if (!matchesAutomationSearch(automation, view.search)) return false;\n if (\n view.status !== \"all\" &&\n !STATUS_PREDICATES[view.status](\n automation,\n deriveAutomationHealth(automation, byId.get(automation.id)),\n )\n ) {\n return false;\n }\n if (\n view.trigger !== \"all\" &&\n !TRIGGER_PREDICATES[view.trigger](automation)\n ) {\n return false;\n }\n return true;\n })\n .sort((a, b) => SORT_COMPARATORS[view.sort](a, b, byId));\n}\n\nexport interface OverviewTileValue {\n /** The formatted value the tile displays. */\n display: string;\n /** True when the metric's value is zero, which swaps in `zeroDetail`. */\n isZero: boolean;\n /** Values the tile's copy may substitute via `{{name}}`. */\n placeholderValues: Record<string, string | number>;\n}\n\nfunction loadedSummaries(\n automations: readonly Automation[],\n byId: Summaries,\n): AutomationRunSummary[] {\n return automations.flatMap((automation) => {\n const state = byId.get(automation.id);\n return state?.summary && !state.isLoading && !state.isError\n ? [state.summary]\n : [];\n });\n}\n\nconst TILE_COMPUTATIONS: Record<\n OverviewMetric,\n (automations: readonly Automation[], byId: Summaries) => OverviewTileValue\n> = {\n automations: (automations) => ({\n display: automations.length.toLocaleString(),\n isZero: automations.length === 0,\n placeholderValues: {\n active: automations.filter((automation) => automation.enabled).length,\n },\n }),\n \"needs-attention\": (automations, byId) => {\n const failing = automations.filter(\n (automation) =>\n deriveAutomationHealth(automation, byId.get(automation.id)) ===\n \"failing\",\n ).length;\n return {\n display: failing.toLocaleString(),\n isZero: failing === 0,\n placeholderValues: {},\n };\n },\n \"total-runs\": (automations, byId) => {\n const loaded = loadedSummaries(automations, byId);\n if (loaded.length === 0 && automations.length > 0) {\n return { display: \"—\", isZero: false, placeholderValues: {} };\n }\n const total = loaded.reduce((sum, summary) => sum + summary.total, 0);\n return {\n display: total.toLocaleString(),\n isZero: total === 0,\n placeholderValues: {},\n };\n },\n \"average-duration\": (automations, byId) => {\n const durations = loadedSummaries(automations, byId).flatMap((summary) =>\n summary.averageDurationMs === null ? [] : [summary.averageDurationMs],\n );\n const mean =\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length;\n return {\n display: formatCompactDuration(mean),\n isZero: false,\n placeholderValues: {},\n };\n },\n};\n\n/** The value behind one manifest-declared tile. */\nexport function computeOverviewTile(\n metric: OverviewMetric,\n automations: readonly Automation[],\n byId: Summaries,\n): OverviewTileValue {\n return TILE_COMPUTATIONS[metric](automations, byId);\n}\n"],"mappings":"wFAuE0B,IAAI,IAAyB,CACrD,EAAA,oBAAoB,UACpB,EAAA,oBAAoB,MACtB,CAAC,EAyDD,SAAgB,EAAsB,EAA2B,CAI/D,OAHI,IAAO,MAAQ,CAAC,OAAO,SAAS,CAAE,EAAU,IAC5C,EAAK,IAAe,GAAG,KAAK,IAAI,EAAG,KAAK,MAAM,EAAK,GAAI,CAAC,EAAE,GAC1D,EAAK,KAAkB,GAAG,KAAK,IAAI,EAAG,KAAK,MAAM,EAAK,GAAM,CAAC,EAAE,GAC5D,IAAI,EAAK,MAAW,QAAQ,CAAC,EAAE,EACxC"}
|
|
1
|
+
{"version":3,"file":"automation-insights.cjs","names":[],"sources":["../../src/manifests/automation-insights.ts"],"sourcesContent":["/**\n * The dashboard's automation knowledge, and the only module beside\n * `automation-setup.ts` that has any.\n *\n * The interface manifest's dashboard surface names metrics, filter predicates,\n * and sort comparators from closed sets; the one implementation of each name\n * is here, over the automation service's list and runs responses, so the rest\n * of `src/manifests/` stays about composition rather than about automations.\n *\n * Summaries are derived from the newest page of runs (the sample the runs\n * hook fetches); `total` alone is the response's lifetime count. Success rate\n * and durations consider only terminal lifecycle runs; the success numerator\n * uses task-aware display status so completed-but-blocked work is not counted\n * as successful.\n */\n\nimport {\n AutomationRunStatus,\n type Automation,\n type AutomationRun,\n type AutomationRunsResponse,\n} from \"#/types/automation\";\nimport { getAutomationRunDisplay } from \"#/utils/automation-run-display\";\nimport type {\n DashboardSortValue,\n DashboardStatusValue,\n DashboardTriggerValue,\n InterfaceListInsights,\n OverviewMetric,\n} from \"./types\";\n\nexport type AutomationHealth =\n | \"healthy\"\n | \"failing\"\n | \"running\"\n | \"disabled\"\n | \"never-run\"\n | \"unknown\";\n\n/** Which caption of the manifest's `insights.health` block names each state. */\nexport const HEALTH_LABEL_KEYS: Record<\n AutomationHealth,\n keyof InterfaceListInsights[\"health\"]\n> = {\n healthy: \"healthy\",\n failing: \"failing\",\n running: \"running\",\n disabled: \"disabled\",\n \"never-run\": \"neverRun\",\n unknown: \"checking\",\n};\n\nexport interface AutomationRunSummary {\n /** Lifetime run count, from the response — not the sample's length. */\n total: number;\n /**\n * Lifetime COMPLETED-run count. From the response's `status_counts` when\n * the service reports it; an older service leaves that out, so the sample\n * stands in exactly when it holds the whole history (`total` ≤ its length)\n * and the count is null — unknowable, never guessed — otherwise.\n */\n completedTotal: number | null;\n latestRun: AutomationRun | null;\n /** Newest-first sample used by the list sparkline (same page as the summary). */\n recentRuns: AutomationRun[];\n /** COMPLETED over COMPLETED+FAILED in the sample. Null with no terminal runs. */\n recentSuccessRate: number | null;\n /** Mean completed_at − started_at over the sample's terminal runs. */\n averageDurationMs: number | null;\n}\n\n/** One automation's summary alongside its query state. */\nexport interface RunSummaryState {\n summary: AutomationRunSummary | null;\n isLoading: boolean;\n isError: boolean;\n}\n\ntype Summaries = ReadonlyMap<string, RunSummaryState>;\n\nconst TERMINAL_STATUSES = new Set<AutomationRunStatus>([\n AutomationRunStatus.COMPLETED,\n AutomationRunStatus.FAILED,\n]);\n\nfunction isTaskSuccessful(run: AutomationRun): boolean {\n const { badgeStatus } = getAutomationRunDisplay(run);\n return (\n badgeStatus === AutomationRunStatus.COMPLETED || badgeStatus === \"success\"\n );\n}\n\nfunction isTaskFailing(run: AutomationRun): boolean {\n const { badgeStatus } = getAutomationRunDisplay(run);\n return (\n badgeStatus === AutomationRunStatus.FAILED ||\n badgeStatus === \"failed\" ||\n badgeStatus === \"blocked\"\n );\n}\n\nexport function summarizeAutomationRuns(\n response: AutomationRunsResponse,\n): AutomationRunSummary {\n const terminal = response.runs.filter((run) =>\n TERMINAL_STATUSES.has(run.status),\n );\n const completed = terminal.filter(isTaskSuccessful).length;\n\n let completedTotal: number | null;\n if (response.status_counts) {\n completedTotal = response.status_counts[AutomationRunStatus.COMPLETED] ?? 0;\n } else if (response.total <= response.runs.length) {\n completedTotal = completed;\n } else {\n completedTotal = null;\n }\n\n const durations = terminal.flatMap((run) => {\n if (!run.completed_at) return [];\n const ms =\n new Date(run.completed_at).getTime() - new Date(run.started_at).getTime();\n return Number.isFinite(ms) && ms >= 0 ? [ms] : [];\n });\n\n return {\n total: response.total,\n completedTotal,\n latestRun: response.runs[0] ?? null,\n recentRuns: response.runs,\n recentSuccessRate:\n terminal.length === 0 ? null : completed / terminal.length,\n averageDurationMs:\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length,\n };\n}\n\n/**\n * A disabled automation is disabled no matter its history; while the summary\n * is unsettled nothing is claimed; after that the latest run speaks.\n */\nexport function deriveAutomationHealth(\n automation: Automation,\n state: RunSummaryState | undefined,\n): AutomationHealth {\n if (!automation.enabled) return \"disabled\";\n if (!state || state.isError || state.isLoading || !state.summary) {\n return \"unknown\";\n }\n const latest = state.summary.latestRun;\n if (!latest) return \"never-run\";\n if (isTaskFailing(latest)) return \"failing\";\n if (\n latest.status === AutomationRunStatus.PENDING ||\n latest.status === AutomationRunStatus.RUNNING\n ) {\n return \"running\";\n }\n return isTaskSuccessful(latest) ? \"healthy\" : \"unknown\";\n}\n\n/** \"—\" unknown, seconds under a minute, minutes under an hour, else \"1.5h\". */\nexport function formatCompactDuration(ms: number | null): string {\n if (ms === null || !Number.isFinite(ms)) return \"—\";\n if (ms < 60_000) return `${Math.max(1, Math.round(ms / 1000))}s`;\n if (ms < 3_600_000) return `${Math.max(1, Math.round(ms / 60_000))}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n/** The list page's search predicate: name, prompt, repository, or model. */\nexport function matchesAutomationSearch(\n automation: Automation,\n query: string,\n): boolean {\n const q = query.toLowerCase();\n if (!q) return true;\n return (\n automation.name.toLowerCase().includes(q) ||\n (automation.prompt ?? \"\").toLowerCase().includes(q) ||\n automation.repository?.toLowerCase().includes(q) === true ||\n automation.model?.toLowerCase().includes(q) === true\n );\n}\n\nconst STATUS_PREDICATES: Record<\n Exclude<DashboardStatusValue, \"all\">,\n (automation: Automation, health: AutomationHealth) => boolean\n> = {\n active: (automation) => automation.enabled,\n failing: (_automation, health) => health === \"failing\",\n disabled: (automation) => !automation.enabled,\n};\n\nconst TRIGGER_PREDICATES: Record<\n Exclude<DashboardTriggerValue, \"all\">,\n (automation: Automation) => boolean\n> = {\n // The backend emits several scheduled-trigger aliases, so \"event\" is the\n // one exact kind and everything else is a schedule.\n event: (automation) => automation.trigger.type === \"event\",\n schedule: (automation) => automation.trigger.type !== \"event\",\n};\n\nfunction runCount(automation: Automation, byId: Summaries): number {\n return byId.get(automation.id)?.summary?.total ?? 0;\n}\n\nfunction lastRunTime(automation: Automation, byId: Summaries): number {\n const startedAt =\n byId.get(automation.id)?.summary?.latestRun?.started_at ??\n automation.last_triggered_at;\n if (!startedAt) return 0;\n const time = new Date(startedAt).getTime();\n return Number.isFinite(time) ? time : 0;\n}\n\nconst SORT_COMPARATORS: Record<\n DashboardSortValue,\n (a: Automation, b: Automation, byId: Summaries) => number\n> = {\n \"last-run\": (a, b, byId) => lastRunTime(b, byId) - lastRunTime(a, byId),\n runs: (a, b, byId) => runCount(b, byId) - runCount(a, byId),\n name: (a, b) => a.name.localeCompare(b.name),\n};\n\nexport interface DashboardViewState {\n search: string;\n status: DashboardStatusValue;\n trigger: DashboardTriggerValue;\n sort: DashboardSortValue;\n}\n\n/** The automations the dashboard shows, filtered and ordered. */\nexport function applyDashboardView(\n automations: readonly Automation[],\n view: DashboardViewState,\n byId: Summaries,\n): Automation[] {\n return automations\n .filter((automation) => {\n if (!matchesAutomationSearch(automation, view.search)) return false;\n if (\n view.status !== \"all\" &&\n !STATUS_PREDICATES[view.status](\n automation,\n deriveAutomationHealth(automation, byId.get(automation.id)),\n )\n ) {\n return false;\n }\n if (\n view.trigger !== \"all\" &&\n !TRIGGER_PREDICATES[view.trigger](automation)\n ) {\n return false;\n }\n return true;\n })\n .sort((a, b) => SORT_COMPARATORS[view.sort](a, b, byId));\n}\n\nexport interface OverviewTileValue {\n /** The formatted value the tile displays. */\n display: string;\n /** True when the metric's value is zero, which swaps in `zeroDetail`. */\n isZero: boolean;\n /** Values the tile's copy may substitute via `{{name}}`. */\n placeholderValues: Record<string, string | number>;\n}\n\nfunction loadedSummaries(\n automations: readonly Automation[],\n byId: Summaries,\n): AutomationRunSummary[] {\n return automations.flatMap((automation) => {\n const state = byId.get(automation.id);\n return state?.summary && !state.isLoading && !state.isError\n ? [state.summary]\n : [];\n });\n}\n\nconst TILE_COMPUTATIONS: Record<\n OverviewMetric,\n (automations: readonly Automation[], byId: Summaries) => OverviewTileValue\n> = {\n automations: (automations) => ({\n display: automations.length.toLocaleString(),\n isZero: automations.length === 0,\n placeholderValues: {\n active: automations.filter((automation) => automation.enabled).length,\n },\n }),\n \"needs-attention\": (automations, byId) => {\n const failing = automations.filter(\n (automation) =>\n deriveAutomationHealth(automation, byId.get(automation.id)) ===\n \"failing\",\n ).length;\n return {\n display: failing.toLocaleString(),\n isZero: failing === 0,\n placeholderValues: {},\n };\n },\n \"total-runs\": (automations, byId) => {\n const loaded = loadedSummaries(automations, byId);\n if (loaded.length === 0 && automations.length > 0) {\n return { display: \"—\", isZero: false, placeholderValues: {} };\n }\n const total = loaded.reduce((sum, summary) => sum + summary.total, 0);\n return {\n display: total.toLocaleString(),\n isZero: total === 0,\n placeholderValues: {},\n };\n },\n \"average-duration\": (automations, byId) => {\n const durations = loadedSummaries(automations, byId).flatMap((summary) =>\n summary.averageDurationMs === null ? [] : [summary.averageDurationMs],\n );\n const mean =\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length;\n return {\n display: formatCompactDuration(mean),\n isZero: false,\n placeholderValues: {},\n };\n },\n};\n\n/** The value behind one manifest-declared tile. */\nexport function computeOverviewTile(\n metric: OverviewMetric,\n automations: readonly Automation[],\n byId: Summaries,\n): OverviewTileValue {\n return TILE_COMPUTATIONS[metric](automations, byId);\n}\n"],"mappings":"wFAgF0B,IAAI,IAAyB,CACrD,EAAA,oBAAoB,UACpB,EAAA,oBAAoB,MACtB,CAAC,EAiFD,SAAgB,EAAsB,EAA2B,CAI/D,OAHI,IAAO,MAAQ,CAAC,OAAO,SAAS,CAAE,EAAU,IAC5C,EAAK,IAAe,GAAG,KAAK,IAAI,EAAG,KAAK,MAAM,EAAK,GAAI,CAAC,EAAE,GAC1D,EAAK,KAAkB,GAAG,KAAK,IAAI,EAAG,KAAK,MAAM,EAAK,GAAM,CAAC,EAAE,GAC5D,IAAI,EAAK,MAAW,QAAQ,CAAC,EAAE,EACxC"}
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Summaries are derived from the newest page of runs (the sample the runs
|
|
11
11
|
* hook fetches); `total` alone is the response's lifetime count. Success rate
|
|
12
|
-
* and durations consider only
|
|
13
|
-
*
|
|
12
|
+
* and durations consider only terminal lifecycle runs; the success numerator
|
|
13
|
+
* uses task-aware display status so completed-but-blocked work is not counted
|
|
14
|
+
* as successful.
|
|
14
15
|
*/
|
|
15
16
|
import { type Automation, type AutomationRun, type AutomationRunsResponse } from "#/types/automation";
|
|
16
17
|
import type { DashboardSortValue, DashboardStatusValue, DashboardTriggerValue, InterfaceListInsights, OverviewMetric } from "./types";
|
|
@@ -20,6 +21,13 @@ export declare const HEALTH_LABEL_KEYS: Record<AutomationHealth, keyof Interface
|
|
|
20
21
|
export interface AutomationRunSummary {
|
|
21
22
|
/** Lifetime run count, from the response — not the sample's length. */
|
|
22
23
|
total: number;
|
|
24
|
+
/**
|
|
25
|
+
* Lifetime COMPLETED-run count. From the response's `status_counts` when
|
|
26
|
+
* the service reports it; an older service leaves that out, so the sample
|
|
27
|
+
* stands in exactly when it holds the whole history (`total` ≤ its length)
|
|
28
|
+
* and the count is null — unknowable, never guessed — otherwise.
|
|
29
|
+
*/
|
|
30
|
+
completedTotal: number | null;
|
|
23
31
|
latestRun: AutomationRun | null;
|
|
24
32
|
/** Newest-first sample used by the list sparkline (same page as the summary). */
|
|
25
33
|
recentRuns: AutomationRun[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-insights.js","names":[],"sources":["../../src/manifests/automation-insights.ts"],"sourcesContent":["/**\n * The dashboard's automation knowledge, and the only module beside\n * `automation-setup.ts` that has any.\n *\n * The interface manifest's dashboard surface names metrics, filter predicates,\n * and sort comparators from closed sets; the one implementation of each name\n * is here, over the automation service's list and runs responses, so the rest\n * of `src/manifests/` stays about composition rather than about automations.\n *\n * Summaries are derived from the newest page of runs (the sample the runs\n * hook fetches); `total` alone is the response's lifetime count. Success rate\n * and durations consider only COMPLETED and FAILED runs — a cancelled or\n * skipped run says nothing about either.\n */\n\nimport {\n AutomationRunStatus,\n type Automation,\n type AutomationRun,\n type AutomationRunsResponse,\n} from \"#/types/automation\";\nimport type {\n DashboardSortValue,\n DashboardStatusValue,\n DashboardTriggerValue,\n InterfaceListInsights,\n OverviewMetric,\n} from \"./types\";\n\nexport type AutomationHealth =\n | \"healthy\"\n | \"failing\"\n | \"running\"\n | \"disabled\"\n | \"never-run\"\n | \"unknown\";\n\n/** Which caption of the manifest's `insights.health` block names each state. */\nexport const HEALTH_LABEL_KEYS: Record<\n AutomationHealth,\n keyof InterfaceListInsights[\"health\"]\n> = {\n healthy: \"healthy\",\n failing: \"failing\",\n running: \"running\",\n disabled: \"disabled\",\n \"never-run\": \"neverRun\",\n unknown: \"checking\",\n};\n\nexport interface AutomationRunSummary {\n /** Lifetime run count, from the response — not the sample's length. */\n total: number;\n latestRun: AutomationRun | null;\n /** Newest-first sample used by the list sparkline (same page as the summary). */\n recentRuns: AutomationRun[];\n /** COMPLETED over COMPLETED+FAILED in the sample. Null with no terminal runs. */\n recentSuccessRate: number | null;\n /** Mean completed_at − started_at over the sample's terminal runs. */\n averageDurationMs: number | null;\n}\n\n/** One automation's summary alongside its query state. */\nexport interface RunSummaryState {\n summary: AutomationRunSummary | null;\n isLoading: boolean;\n isError: boolean;\n}\n\ntype Summaries = ReadonlyMap<string, RunSummaryState>;\n\nconst TERMINAL_STATUSES = new Set<AutomationRunStatus>([\n AutomationRunStatus.COMPLETED,\n AutomationRunStatus.FAILED,\n]);\n\nexport function summarizeAutomationRuns(\n response: AutomationRunsResponse,\n): AutomationRunSummary {\n const terminal = response.runs.filter((run) =>\n TERMINAL_STATUSES.has(run.status),\n );\n const completed = terminal.filter(\n (run) => run.status === AutomationRunStatus.COMPLETED,\n ).length;\n\n const durations = terminal.flatMap((run) => {\n if (!run.completed_at) return [];\n const ms =\n new Date(run.completed_at).getTime() - new Date(run.started_at).getTime();\n return Number.isFinite(ms) && ms >= 0 ? [ms] : [];\n });\n\n return {\n total: response.total,\n latestRun: response.runs[0] ?? null,\n recentRuns: response.runs,\n recentSuccessRate:\n terminal.length === 0 ? null : completed / terminal.length,\n averageDurationMs:\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length,\n };\n}\n\n/**\n * A disabled automation is disabled no matter its history; while the summary\n * is unsettled nothing is claimed; after that the latest run speaks.\n */\nexport function deriveAutomationHealth(\n automation: Automation,\n state: RunSummaryState | undefined,\n): AutomationHealth {\n if (!automation.enabled) return \"disabled\";\n if (!state || state.isError || state.isLoading || !state.summary) {\n return \"unknown\";\n }\n const latest = state.summary.latestRun;\n if (!latest) return \"never-run\";\n if (latest.status === AutomationRunStatus.FAILED) return \"failing\";\n if (\n latest.status === AutomationRunStatus.PENDING ||\n latest.status === AutomationRunStatus.RUNNING\n ) {\n return \"running\";\n }\n return \"healthy\";\n}\n\n/** \"—\" unknown, seconds under a minute, minutes under an hour, else \"1.5h\". */\nexport function formatCompactDuration(ms: number | null): string {\n if (ms === null || !Number.isFinite(ms)) return \"—\";\n if (ms < 60_000) return `${Math.max(1, Math.round(ms / 1000))}s`;\n if (ms < 3_600_000) return `${Math.max(1, Math.round(ms / 60_000))}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n/** The list page's search predicate: name, prompt, repository, or model. */\nexport function matchesAutomationSearch(\n automation: Automation,\n query: string,\n): boolean {\n const q = query.toLowerCase();\n if (!q) return true;\n return (\n automation.name.toLowerCase().includes(q) ||\n (automation.prompt ?? \"\").toLowerCase().includes(q) ||\n automation.repository?.toLowerCase().includes(q) === true ||\n automation.model?.toLowerCase().includes(q) === true\n );\n}\n\nconst STATUS_PREDICATES: Record<\n Exclude<DashboardStatusValue, \"all\">,\n (automation: Automation, health: AutomationHealth) => boolean\n> = {\n active: (automation) => automation.enabled,\n failing: (_automation, health) => health === \"failing\",\n disabled: (automation) => !automation.enabled,\n};\n\nconst TRIGGER_PREDICATES: Record<\n Exclude<DashboardTriggerValue, \"all\">,\n (automation: Automation) => boolean\n> = {\n // The backend emits several scheduled-trigger aliases, so \"event\" is the\n // one exact kind and everything else is a schedule.\n event: (automation) => automation.trigger.type === \"event\",\n schedule: (automation) => automation.trigger.type !== \"event\",\n};\n\nfunction runCount(automation: Automation, byId: Summaries): number {\n return byId.get(automation.id)?.summary?.total ?? 0;\n}\n\nfunction lastRunTime(automation: Automation, byId: Summaries): number {\n const startedAt =\n byId.get(automation.id)?.summary?.latestRun?.started_at ??\n automation.last_triggered_at;\n if (!startedAt) return 0;\n const time = new Date(startedAt).getTime();\n return Number.isFinite(time) ? time : 0;\n}\n\nconst SORT_COMPARATORS: Record<\n DashboardSortValue,\n (a: Automation, b: Automation, byId: Summaries) => number\n> = {\n \"last-run\": (a, b, byId) => lastRunTime(b, byId) - lastRunTime(a, byId),\n runs: (a, b, byId) => runCount(b, byId) - runCount(a, byId),\n name: (a, b) => a.name.localeCompare(b.name),\n};\n\nexport interface DashboardViewState {\n search: string;\n status: DashboardStatusValue;\n trigger: DashboardTriggerValue;\n sort: DashboardSortValue;\n}\n\n/** The automations the dashboard shows, filtered and ordered. */\nexport function applyDashboardView(\n automations: readonly Automation[],\n view: DashboardViewState,\n byId: Summaries,\n): Automation[] {\n return automations\n .filter((automation) => {\n if (!matchesAutomationSearch(automation, view.search)) return false;\n if (\n view.status !== \"all\" &&\n !STATUS_PREDICATES[view.status](\n automation,\n deriveAutomationHealth(automation, byId.get(automation.id)),\n )\n ) {\n return false;\n }\n if (\n view.trigger !== \"all\" &&\n !TRIGGER_PREDICATES[view.trigger](automation)\n ) {\n return false;\n }\n return true;\n })\n .sort((a, b) => SORT_COMPARATORS[view.sort](a, b, byId));\n}\n\nexport interface OverviewTileValue {\n /** The formatted value the tile displays. */\n display: string;\n /** True when the metric's value is zero, which swaps in `zeroDetail`. */\n isZero: boolean;\n /** Values the tile's copy may substitute via `{{name}}`. */\n placeholderValues: Record<string, string | number>;\n}\n\nfunction loadedSummaries(\n automations: readonly Automation[],\n byId: Summaries,\n): AutomationRunSummary[] {\n return automations.flatMap((automation) => {\n const state = byId.get(automation.id);\n return state?.summary && !state.isLoading && !state.isError\n ? [state.summary]\n : [];\n });\n}\n\nconst TILE_COMPUTATIONS: Record<\n OverviewMetric,\n (automations: readonly Automation[], byId: Summaries) => OverviewTileValue\n> = {\n automations: (automations) => ({\n display: automations.length.toLocaleString(),\n isZero: automations.length === 0,\n placeholderValues: {\n active: automations.filter((automation) => automation.enabled).length,\n },\n }),\n \"needs-attention\": (automations, byId) => {\n const failing = automations.filter(\n (automation) =>\n deriveAutomationHealth(automation, byId.get(automation.id)) ===\n \"failing\",\n ).length;\n return {\n display: failing.toLocaleString(),\n isZero: failing === 0,\n placeholderValues: {},\n };\n },\n \"total-runs\": (automations, byId) => {\n const loaded = loadedSummaries(automations, byId);\n if (loaded.length === 0 && automations.length > 0) {\n return { display: \"—\", isZero: false, placeholderValues: {} };\n }\n const total = loaded.reduce((sum, summary) => sum + summary.total, 0);\n return {\n display: total.toLocaleString(),\n isZero: total === 0,\n placeholderValues: {},\n };\n },\n \"average-duration\": (automations, byId) => {\n const durations = loadedSummaries(automations, byId).flatMap((summary) =>\n summary.averageDurationMs === null ? [] : [summary.averageDurationMs],\n );\n const mean =\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length;\n return {\n display: formatCompactDuration(mean),\n isZero: false,\n placeholderValues: {},\n };\n },\n};\n\n/** The value behind one manifest-declared tile. */\nexport function computeOverviewTile(\n metric: OverviewMetric,\n automations: readonly Automation[],\n byId: Summaries,\n): OverviewTileValue {\n return TILE_COMPUTATIONS[metric](automations, byId);\n}\n"],"mappings":";AAuE0B,IAAI,IAAyB,CACrD,EAAoB,WACpB,EAAoB,MACtB,CAAC;AAyDD,SAAgB,EAAsB,GAA2B;CAI/D,OAHI,MAAO,QAAQ,CAAC,OAAO,SAAS,CAAE,IAAU,MAC5C,IAAK,MAAe,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,IAAK,GAAI,CAAC,EAAE,KAC1D,IAAK,OAAkB,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,IAAK,GAAM,CAAC,EAAE,KAC5D,IAAI,IAAK,MAAW,QAAQ,CAAC,EAAE;AACxC"}
|
|
1
|
+
{"version":3,"file":"automation-insights.js","names":[],"sources":["../../src/manifests/automation-insights.ts"],"sourcesContent":["/**\n * The dashboard's automation knowledge, and the only module beside\n * `automation-setup.ts` that has any.\n *\n * The interface manifest's dashboard surface names metrics, filter predicates,\n * and sort comparators from closed sets; the one implementation of each name\n * is here, over the automation service's list and runs responses, so the rest\n * of `src/manifests/` stays about composition rather than about automations.\n *\n * Summaries are derived from the newest page of runs (the sample the runs\n * hook fetches); `total` alone is the response's lifetime count. Success rate\n * and durations consider only terminal lifecycle runs; the success numerator\n * uses task-aware display status so completed-but-blocked work is not counted\n * as successful.\n */\n\nimport {\n AutomationRunStatus,\n type Automation,\n type AutomationRun,\n type AutomationRunsResponse,\n} from \"#/types/automation\";\nimport { getAutomationRunDisplay } from \"#/utils/automation-run-display\";\nimport type {\n DashboardSortValue,\n DashboardStatusValue,\n DashboardTriggerValue,\n InterfaceListInsights,\n OverviewMetric,\n} from \"./types\";\n\nexport type AutomationHealth =\n | \"healthy\"\n | \"failing\"\n | \"running\"\n | \"disabled\"\n | \"never-run\"\n | \"unknown\";\n\n/** Which caption of the manifest's `insights.health` block names each state. */\nexport const HEALTH_LABEL_KEYS: Record<\n AutomationHealth,\n keyof InterfaceListInsights[\"health\"]\n> = {\n healthy: \"healthy\",\n failing: \"failing\",\n running: \"running\",\n disabled: \"disabled\",\n \"never-run\": \"neverRun\",\n unknown: \"checking\",\n};\n\nexport interface AutomationRunSummary {\n /** Lifetime run count, from the response — not the sample's length. */\n total: number;\n /**\n * Lifetime COMPLETED-run count. From the response's `status_counts` when\n * the service reports it; an older service leaves that out, so the sample\n * stands in exactly when it holds the whole history (`total` ≤ its length)\n * and the count is null — unknowable, never guessed — otherwise.\n */\n completedTotal: number | null;\n latestRun: AutomationRun | null;\n /** Newest-first sample used by the list sparkline (same page as the summary). */\n recentRuns: AutomationRun[];\n /** COMPLETED over COMPLETED+FAILED in the sample. Null with no terminal runs. */\n recentSuccessRate: number | null;\n /** Mean completed_at − started_at over the sample's terminal runs. */\n averageDurationMs: number | null;\n}\n\n/** One automation's summary alongside its query state. */\nexport interface RunSummaryState {\n summary: AutomationRunSummary | null;\n isLoading: boolean;\n isError: boolean;\n}\n\ntype Summaries = ReadonlyMap<string, RunSummaryState>;\n\nconst TERMINAL_STATUSES = new Set<AutomationRunStatus>([\n AutomationRunStatus.COMPLETED,\n AutomationRunStatus.FAILED,\n]);\n\nfunction isTaskSuccessful(run: AutomationRun): boolean {\n const { badgeStatus } = getAutomationRunDisplay(run);\n return (\n badgeStatus === AutomationRunStatus.COMPLETED || badgeStatus === \"success\"\n );\n}\n\nfunction isTaskFailing(run: AutomationRun): boolean {\n const { badgeStatus } = getAutomationRunDisplay(run);\n return (\n badgeStatus === AutomationRunStatus.FAILED ||\n badgeStatus === \"failed\" ||\n badgeStatus === \"blocked\"\n );\n}\n\nexport function summarizeAutomationRuns(\n response: AutomationRunsResponse,\n): AutomationRunSummary {\n const terminal = response.runs.filter((run) =>\n TERMINAL_STATUSES.has(run.status),\n );\n const completed = terminal.filter(isTaskSuccessful).length;\n\n let completedTotal: number | null;\n if (response.status_counts) {\n completedTotal = response.status_counts[AutomationRunStatus.COMPLETED] ?? 0;\n } else if (response.total <= response.runs.length) {\n completedTotal = completed;\n } else {\n completedTotal = null;\n }\n\n const durations = terminal.flatMap((run) => {\n if (!run.completed_at) return [];\n const ms =\n new Date(run.completed_at).getTime() - new Date(run.started_at).getTime();\n return Number.isFinite(ms) && ms >= 0 ? [ms] : [];\n });\n\n return {\n total: response.total,\n completedTotal,\n latestRun: response.runs[0] ?? null,\n recentRuns: response.runs,\n recentSuccessRate:\n terminal.length === 0 ? null : completed / terminal.length,\n averageDurationMs:\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length,\n };\n}\n\n/**\n * A disabled automation is disabled no matter its history; while the summary\n * is unsettled nothing is claimed; after that the latest run speaks.\n */\nexport function deriveAutomationHealth(\n automation: Automation,\n state: RunSummaryState | undefined,\n): AutomationHealth {\n if (!automation.enabled) return \"disabled\";\n if (!state || state.isError || state.isLoading || !state.summary) {\n return \"unknown\";\n }\n const latest = state.summary.latestRun;\n if (!latest) return \"never-run\";\n if (isTaskFailing(latest)) return \"failing\";\n if (\n latest.status === AutomationRunStatus.PENDING ||\n latest.status === AutomationRunStatus.RUNNING\n ) {\n return \"running\";\n }\n return isTaskSuccessful(latest) ? \"healthy\" : \"unknown\";\n}\n\n/** \"—\" unknown, seconds under a minute, minutes under an hour, else \"1.5h\". */\nexport function formatCompactDuration(ms: number | null): string {\n if (ms === null || !Number.isFinite(ms)) return \"—\";\n if (ms < 60_000) return `${Math.max(1, Math.round(ms / 1000))}s`;\n if (ms < 3_600_000) return `${Math.max(1, Math.round(ms / 60_000))}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n/** The list page's search predicate: name, prompt, repository, or model. */\nexport function matchesAutomationSearch(\n automation: Automation,\n query: string,\n): boolean {\n const q = query.toLowerCase();\n if (!q) return true;\n return (\n automation.name.toLowerCase().includes(q) ||\n (automation.prompt ?? \"\").toLowerCase().includes(q) ||\n automation.repository?.toLowerCase().includes(q) === true ||\n automation.model?.toLowerCase().includes(q) === true\n );\n}\n\nconst STATUS_PREDICATES: Record<\n Exclude<DashboardStatusValue, \"all\">,\n (automation: Automation, health: AutomationHealth) => boolean\n> = {\n active: (automation) => automation.enabled,\n failing: (_automation, health) => health === \"failing\",\n disabled: (automation) => !automation.enabled,\n};\n\nconst TRIGGER_PREDICATES: Record<\n Exclude<DashboardTriggerValue, \"all\">,\n (automation: Automation) => boolean\n> = {\n // The backend emits several scheduled-trigger aliases, so \"event\" is the\n // one exact kind and everything else is a schedule.\n event: (automation) => automation.trigger.type === \"event\",\n schedule: (automation) => automation.trigger.type !== \"event\",\n};\n\nfunction runCount(automation: Automation, byId: Summaries): number {\n return byId.get(automation.id)?.summary?.total ?? 0;\n}\n\nfunction lastRunTime(automation: Automation, byId: Summaries): number {\n const startedAt =\n byId.get(automation.id)?.summary?.latestRun?.started_at ??\n automation.last_triggered_at;\n if (!startedAt) return 0;\n const time = new Date(startedAt).getTime();\n return Number.isFinite(time) ? time : 0;\n}\n\nconst SORT_COMPARATORS: Record<\n DashboardSortValue,\n (a: Automation, b: Automation, byId: Summaries) => number\n> = {\n \"last-run\": (a, b, byId) => lastRunTime(b, byId) - lastRunTime(a, byId),\n runs: (a, b, byId) => runCount(b, byId) - runCount(a, byId),\n name: (a, b) => a.name.localeCompare(b.name),\n};\n\nexport interface DashboardViewState {\n search: string;\n status: DashboardStatusValue;\n trigger: DashboardTriggerValue;\n sort: DashboardSortValue;\n}\n\n/** The automations the dashboard shows, filtered and ordered. */\nexport function applyDashboardView(\n automations: readonly Automation[],\n view: DashboardViewState,\n byId: Summaries,\n): Automation[] {\n return automations\n .filter((automation) => {\n if (!matchesAutomationSearch(automation, view.search)) return false;\n if (\n view.status !== \"all\" &&\n !STATUS_PREDICATES[view.status](\n automation,\n deriveAutomationHealth(automation, byId.get(automation.id)),\n )\n ) {\n return false;\n }\n if (\n view.trigger !== \"all\" &&\n !TRIGGER_PREDICATES[view.trigger](automation)\n ) {\n return false;\n }\n return true;\n })\n .sort((a, b) => SORT_COMPARATORS[view.sort](a, b, byId));\n}\n\nexport interface OverviewTileValue {\n /** The formatted value the tile displays. */\n display: string;\n /** True when the metric's value is zero, which swaps in `zeroDetail`. */\n isZero: boolean;\n /** Values the tile's copy may substitute via `{{name}}`. */\n placeholderValues: Record<string, string | number>;\n}\n\nfunction loadedSummaries(\n automations: readonly Automation[],\n byId: Summaries,\n): AutomationRunSummary[] {\n return automations.flatMap((automation) => {\n const state = byId.get(automation.id);\n return state?.summary && !state.isLoading && !state.isError\n ? [state.summary]\n : [];\n });\n}\n\nconst TILE_COMPUTATIONS: Record<\n OverviewMetric,\n (automations: readonly Automation[], byId: Summaries) => OverviewTileValue\n> = {\n automations: (automations) => ({\n display: automations.length.toLocaleString(),\n isZero: automations.length === 0,\n placeholderValues: {\n active: automations.filter((automation) => automation.enabled).length,\n },\n }),\n \"needs-attention\": (automations, byId) => {\n const failing = automations.filter(\n (automation) =>\n deriveAutomationHealth(automation, byId.get(automation.id)) ===\n \"failing\",\n ).length;\n return {\n display: failing.toLocaleString(),\n isZero: failing === 0,\n placeholderValues: {},\n };\n },\n \"total-runs\": (automations, byId) => {\n const loaded = loadedSummaries(automations, byId);\n if (loaded.length === 0 && automations.length > 0) {\n return { display: \"—\", isZero: false, placeholderValues: {} };\n }\n const total = loaded.reduce((sum, summary) => sum + summary.total, 0);\n return {\n display: total.toLocaleString(),\n isZero: total === 0,\n placeholderValues: {},\n };\n },\n \"average-duration\": (automations, byId) => {\n const durations = loadedSummaries(automations, byId).flatMap((summary) =>\n summary.averageDurationMs === null ? [] : [summary.averageDurationMs],\n );\n const mean =\n durations.length === 0\n ? null\n : durations.reduce((sum, ms) => sum + ms, 0) / durations.length;\n return {\n display: formatCompactDuration(mean),\n isZero: false,\n placeholderValues: {},\n };\n },\n};\n\n/** The value behind one manifest-declared tile. */\nexport function computeOverviewTile(\n metric: OverviewMetric,\n automations: readonly Automation[],\n byId: Summaries,\n): OverviewTileValue {\n return TILE_COMPUTATIONS[metric](automations, byId);\n}\n"],"mappings":";AAgF0B,IAAI,IAAyB,CACrD,EAAoB,WACpB,EAAoB,MACtB,CAAC;AAiFD,SAAgB,EAAsB,GAA2B;CAI/D,OAHI,MAAO,QAAQ,CAAC,OAAO,SAAS,CAAE,IAAU,MAC5C,IAAK,MAAe,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,IAAK,GAAI,CAAC,EAAE,KAC1D,IAAK,OAAkB,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,IAAK,GAAM,CAAC,EAAE,KAC5D,IAAI,IAAK,MAAW,QAAQ,CAAC,EAAE;AACxC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs"),require("../i18n/index.cjs"),require("../utils/automation-catalog.cjs");const e=require("./automation-interface.cjs");function
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs"),require("../i18n/index.cjs"),require("../utils/automation-catalog.cjs");const e=require("./automation-interface.cjs"),t=require("./manifest-local-validation.cjs");function n(t,n){let r=o(t,n);return r===`plugin`?e.getAutomationEndpoint(`createPlugin`):r===`upload`||r===`bundle`?i(`createBundle`):e.getAutomationEndpoint(`createPrompt`)}function r(){return i(`uploads`)}function i(t){let n=e.getAutomationEndpoint(t);if(!n)throw Error(`The published automation interface declares no '${t}' endpoint, so this deployment cannot create an automation from a script bundle.`);return n}function a(e){return e.setup.mode===`direct`&&e.setup.bundle!==void 0}function o(e,n){if(!e)return`prompt`;if(a(e))return`bundle`;let r=e.setup.actions??{};if(n&&n in r)return n;let i=t.actionKinds(e.setup);return i.length===1?i[0]:`prompt`}exports.automationCreateEndpoint=n,exports.automationUploadEndpoint=r;
|
|
2
2
|
//# sourceMappingURL=automation-setup.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-setup.cjs","names":[],"sources":["../../src/manifests/automation-setup.ts"],"sourcesContent":["/**\n * The only module that knows a setup entry configures an *automation*.\n *\n * The published contract states just what varies between entries; everything\n * derivable is the host's to generate. That derivation is here, and nowhere\n * else, so the rest of `src/manifests/` stays about forms rather than about\n * automations.\n *\n * The algorithm mirrors `tests/test_automation_setup.py::_render_payload` in\n * `OpenHands/extensions`, which is the authoritative reference: it produces the\n * request bodies published in that repository's contract fixtures, and those\n * were verified against the live service. The create model is `extra=\"forbid\"`,\n * so any divergence is a hard 422 rather than a dropped field.\n */\n\nimport i18n from \"#/i18n\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { findAutomationCommand } from \"#/utils/automation-catalog\";\nimport { getAutomationEndpoint } from \"./automation-interface\";\nimport {\n collectFields,\n fieldText,\n fieldValues,\n} from \"./manifest-local-validation\";\nimport { interpolateText, interpolateValue } from \"./manifest-template\";\nimport type {\n SetupBlock,\n SetupBundleConfigValue,\n SetupEntry,\n SetupFormValues,\n SetupRequestBody,\n SetupTriggerKind,\n} from \"./types\";\n\n/**\n * The creation endpoint a derived draft would be posted to. Resolved on call\n * rather than at import, because the endpoint is the interface manifest's and\n * this module loads whether or not one was admitted.\n *\n * A bundle entry is created through the raw endpoint, because what it sends is\n * a tarball it uploaded rather than arguments to a preset. Called without an\n * entry - as the import path does - it answers for a prompt.\n */\nexport function automationCreateEndpoint(entry?: SetupEntry): string {\n if (entry && isBundleEntry(entry)) {\n return requireBundleEndpoint(\"createBundle\");\n }\n return getAutomationEndpoint(\"createPrompt\");\n}\n\n/** Where a bundle's tarball is uploaded, before the create call. */\nexport function automationUploadEndpoint(): string {\n return requireBundleEndpoint(\"uploads\");\n}\n\n/** The endpoints a bundle entry cannot be created without. */\nconst BUNDLE_ENDPOINTS = [\"createBundle\", \"uploads\"] as const;\n\n/**\n * An endpoint only a bundle needs. The interface manifest may predate bundles,\n * and the host holds no path of its own to fall back to, so this is where that\n * runs out rather than somewhere deep in a request.\n */\nfunction requireBundleEndpoint(\n name: (typeof BUNDLE_ENDPOINTS)[number],\n): string {\n const path = getAutomationEndpoint(name);\n if (!path) {\n throw new Error(\n `The published automation interface declares no '${name}' endpoint, ` +\n \"so this deployment cannot create an automation from a script bundle.\",\n );\n }\n return path;\n}\n\n/**\n * The endpoints this entry needs that the published interface does not declare.\n *\n * Asked before the form renders rather than discovered at the moment of\n * creating: a pinned package that predates bundles can never answer, and the\n * dialog can say so while nothing has been filled in yet. Empty for every\n * entry that is not a bundle, which needs nothing beyond what the block has\n * always declared.\n */\nexport function missingCreateEndpoints(entry: SetupEntry): string[] {\n if (!isBundleEntry(entry)) return [];\n return BUNDLE_ENDPOINTS.filter((name) => !getAutomationEndpoint(name));\n}\n\n/** Whether this entry ships a script tarball instead of a prompt. */\nexport function isBundleEntry(entry: SetupEntry): boolean {\n return entry.setup.mode === \"direct\" && entry.setup.bundle !== undefined;\n}\n\n/**\n * The `tarball_path` a preflight draft carries.\n *\n * Preflight runs on every field blur and the upload happens once, at submit,\n * so there is no real path to send yet. The service checks this field's scheme\n * at preflight and its ownership only at creation, so a well-formed stand-in\n * validates exactly what preflight is for - the rest of the body - without\n * uploading an archive per keystroke.\n */\nexport const PREFLIGHT_TARBALL_PATH =\n \"oh-internal://uploads/00000000-0000-0000-0000-000000000000\";\n\n/**\n * Trigger properties a form field may fill, per trigger kind. A field under a\n * trigger kind whose name is listed here fills the trigger property of the same\n * name; anything else there, such as a phrase to match, is an input to `filter`.\n */\nconst TRIGGER_PROPERTIES: Record<SetupTriggerKind, readonly string[]> = {\n cron: [\"schedule\", \"timezone\"],\n event: [\"on\"],\n};\n\n/**\n * Repository properties a form field may fill, read the same way\n * {@link TRIGGER_PROPERTIES} is: a field whose name is listed here fills the\n * `repos[]` property of the same name. `url` and `provider` are absent because\n * neither is answered by a field of its own — they come from the repo-picker's\n * value and from its declared provider.\n *\n * These two lists are the only field names the derivation knows; everything\n * else it reads it finds by field type. An entry that wants a base branch in\n * its request therefore has to name that field `ref`.\n */\nconst REPO_PROPERTIES: readonly string[] = [\"ref\"];\n\nconst FORM_PLACEHOLDER_PATTERN = /\\{\\{form\\.([A-Za-z0-9_.]+)\\}\\}/g;\n\n/** The repository input, which supplies `repos` and an event trigger's source. */\nfunction findRepoPickerField(setup: SetupBlock) {\n const match = Object.entries(collectFields(setup)).find(\n ([, field]) => field.type === \"repo-picker\",\n );\n return match ? { name: match[0], field: match[1] } : null;\n}\n\n/** Every repository the form collected, whether the picker takes one or many. */\nfunction repositories(setup: SetupBlock, values: SetupFormValues): string[] {\n const picker = findRepoPickerField(setup);\n return picker ? fieldValues(values[picker.name]) : [];\n}\n\n/**\n * The created automation's name.\n *\n * One repository is worth naming; several are not, so the count stands in\n * rather than a list of names that would not fit.\n */\nfunction deriveName(entry: SetupEntry, values: SetupFormValues): string {\n const repos = repositories(entry.setup, values);\n if (repos.length === 0) return entry.name;\n if (repos.length === 1) return `${entry.name} - ${repos[0]}`;\n // The count is the one word here the host writes rather than reads off the\n // entry, so it is translated. There is no translator to pass in: the\n // derivation runs from a memo, an upload and a test alike.\n const count = i18n.t(I18nKey.SETUP$REPOSITORY_COUNT, {\n total: repos.length,\n });\n return `${entry.name} - ${count}`;\n}\n\n/** The single trigger kind a direct entry declares, with its fields. */\nfunction getTrigger(setup: SetupBlock) {\n const entries = Object.entries(setup.form.triggers ?? {});\n if (entries.length === 0) return null;\n const [kind, fields] = entries[0];\n return { kind: kind as SetupTriggerKind, fields: fields ?? {} };\n}\n\n/**\n * The create request body these form values produce.\n *\n * No entry declares it: `name` comes from the entry, `repos` from the\n * repo-picker field and its declared provider, and `trigger` from the key and\n * fields under `form.triggers`. Only `prompt` and an event `filter` are\n * declared, because only they cannot be read off the form.\n *\n * Returns null for an assisted entry, which hands setup to a conversation\n * instead of sending a body.\n */\nexport function buildCreatePayload(\n entry: SetupEntry,\n values: SetupFormValues,\n /** Bundle entries only: what the upload returned. */\n tarballPath: string = PREFLIGHT_TARBALL_PATH,\n): SetupRequestBody | null {\n const { setup } = entry;\n if (setup.mode !== \"direct\") return null;\n if (setup.bundle) return buildBundlePayload(entry, values, tarballPath);\n if (!setup.prompt) return null;\n\n const scope = { form: values, automation: entry };\n const repoPicker = findRepoPickerField(setup);\n const repos = repositories(setup, values);\n\n const payload: SetupRequestBody = {\n name: deriveName(entry, values),\n prompt: interpolateText(setup.prompt, scope),\n };\n\n if (repos.length > 0 && repoPicker?.field.provider) {\n const declared = REPO_PROPERTIES.filter((name) => name in values);\n payload.repos = repos.map((url) => ({\n url,\n ...Object.fromEntries(\n declared.map((name) => [name, fieldText(values[name])]),\n ),\n provider: repoPicker.field.provider as string,\n }));\n }\n\n // A filter is optional: an entry that declares none accepts every delivered\n // event, so the key is left off rather than sent empty.\n const trigger = buildTrigger(entry, values);\n if (trigger) payload.trigger = trigger;\n\n const template = buildTemplate(entry, values);\n if (template) payload.template = template;\n\n return payload;\n}\n\n/**\n * The `template` provenance a prompt entry sends, or undefined for one that\n * publishes no version.\n *\n * It is what lets the service recognise a second setup of the same entry as\n * the automation it already holds. The bundle path derives the same block from\n * the config the bundle declares; a prompt entry declares none, so the answer\n * to \"what was this created from\" is the form as submitted.\n */\nfunction buildTemplate(\n entry: SetupEntry,\n values: SetupFormValues,\n): SetupRequestBody | undefined {\n if (!entry.version) return undefined;\n return {\n id: entry.id,\n version: entry.version,\n config: { ...values },\n };\n}\n\n/**\n * The `trigger` object, read off the key and fields under `form.triggers`.\n *\n * Identical for both kinds of direct entry: only the create endpoint and what\n * the automation is told to do differ between a prompt and a bundle.\n */\nfunction buildTrigger(\n entry: SetupEntry,\n values: SetupFormValues,\n): SetupRequestBody | undefined {\n const trigger = getTrigger(entry.setup);\n if (!trigger) return undefined;\n\n const properties = TRIGGER_PROPERTIES[trigger.kind];\n const declared = Object.keys(trigger.fields).filter((name) =>\n properties.includes(name),\n );\n const repoPicker = findRepoPickerField(entry.setup);\n\n return {\n type: trigger.kind,\n ...Object.fromEntries(\n declared.map((name) => [name, fieldText(values[name])]),\n ),\n ...(trigger.kind === \"event\" && {\n source: repoPicker?.field.provider ?? \"\",\n ...(entry.setup.filter && {\n filter: interpolateText(entry.setup.filter, {\n form: values,\n automation: entry,\n }),\n }),\n }),\n };\n}\n\n/**\n * The raw create body a bundle entry produces.\n *\n * `tarball_path` is the one value neither declared nor derived: the host packs\n * and uploads the bundle first, and creates from what came back. `template` is\n * the provenance that makes enabling the same entry twice return the\n * automation that already exists rather than a second one.\n *\n * There is no `repos`: the raw endpoint has no such field, and a bundle's\n * script fetches what it needs itself.\n */\nfunction buildBundlePayload(\n entry: SetupEntry,\n values: SetupFormValues,\n tarballPath: string,\n): SetupRequestBody {\n const bundle = entry.setup.bundle!;\n const scope = { form: values, automation: entry };\n\n const payload: SetupRequestBody = {\n name: deriveName(entry, values),\n };\n\n const trigger = buildTrigger(entry, values);\n if (trigger) payload.trigger = trigger;\n\n payload.tarball_path = tarballPath;\n payload.entrypoint = bundle.entrypoint;\n if (bundle.setupScript) payload.setup_script_path = bundle.setupScript;\n if (bundle.timeout !== undefined) payload.timeout = bundle.timeout;\n payload.template = {\n id: entry.id,\n version: bundle.version,\n config: interpolateConfig(bundle.config, scope) as SetupRequestBody,\n };\n\n return payload;\n}\n\n/**\n * Placeholder substitution over the config tree. Only string leaves are\n * templated; a number, a boolean or a null is written through as itself, so an\n * entry can state a value the script reads as the type it expects.\n */\nfunction interpolateConfig(\n node: SetupBundleConfigValue,\n scope: Parameters<typeof interpolateText>[1],\n): SetupBundleConfigValue {\n if (typeof node === \"string\") {\n return interpolateValue(node, scope);\n }\n if (Array.isArray(node)) {\n return node.map((item) => interpolateConfig(item, scope));\n }\n if (typeof node === \"object\" && node !== null) {\n return Object.fromEntries(\n Object.entries(node).map(([key, value]) => [\n key,\n interpolateConfig(value, scope),\n ]),\n );\n }\n return node;\n}\n\n/**\n * The preflight body the host sends. The same shape for every entry, so no\n * entry declares it.\n */\nexport function buildPreflightBody(\n entry: SetupEntry,\n values: SetupFormValues,\n): SetupRequestBody | null {\n const draft = buildCreatePayload(entry, values);\n if (!draft) return null;\n\n return {\n automationId: entry.id,\n endpoint: automationCreateEndpoint(entry),\n draft,\n };\n}\n\n/**\n * What an assisted entry sends into the conversation that finishes setup.\n *\n * The command is not declared either: it lives once, in the owning skill's own\n * `triggers` frontmatter, and the skill defaults to the entry's id. An entry\n * whose skill is invoked by description rather than by command contributes\n * nothing here, and the answers alone open the conversation.\n */\nexport function buildAssistedMessage(\n entry: SetupEntry,\n values: SetupFormValues,\n): string {\n const command = findAutomationCommand(entry);\n const message = entry.setup.message\n ? interpolateText(entry.setup.message, { form: values, automation: entry })\n : \"\";\n\n return [command, message].filter(Boolean).join(\"\\n\\n\");\n}\n\nfunction collectPlaceholderFields(value: string): string[] {\n const names = Array.from(\n value.matchAll(FORM_PLACEHOLDER_PATTERN),\n (match) => match[1],\n );\n return Array.from(new Set(names));\n}\n\n/**\n * Which form fields built each payload path.\n *\n * Preflight and the create endpoint reject a draft by payload path, and the\n * host has to turn that back into a highlighted input. Building the body with\n * each field standing in for its own value recovers the mapping exactly, so an\n * entry does not declare it.\n */\nexport function deriveErrorMap(entry: SetupEntry): Record<string, string[]> {\n const mapping: Record<string, string[]> = {};\n\n const standIns = Object.fromEntries(\n Object.keys(collectFields(entry.setup)).map((name) => [\n name,\n `{{form.${name}}}`,\n ]),\n );\n const template = buildCreatePayload(entry, standIns);\n if (!template) return mapping;\n\n const walk = (node: unknown, path: string): void => {\n if (Array.isArray(node)) {\n node.forEach((item, index) => walk(item, `${path}[${index}]`));\n return;\n }\n if (typeof node === \"object\" && node !== null) {\n Object.entries(node).forEach(([key, item]) =>\n walk(item, path ? `${path}.${key}` : key),\n );\n return;\n }\n if (typeof node === \"string\") {\n const names = collectPlaceholderFields(node);\n if (names.length > 0) mapping[path] = names;\n }\n };\n\n walk(template, \"\");\n return mapping;\n}\n"],"mappings":"mKA2CA,SAAgB,EAAyB,EAA4B,CAInE,OAHI,GAAS,EAAc,CAAK,EACvB,EAAsB,cAAc,EAEtC,EAAA,sBAAsB,cAAc,CAC7C,CAGA,SAAgB,GAAmC,CACjD,OAAO,EAAsB,SAAS,CACxC,CAUA,SAAS,EACP,EACQ,CACR,IAAM,EAAO,EAAA,sBAAsB,CAAI,EACvC,GAAI,CAAC,EACH,MAAU,MACR,mDAAmD,EAAK,iFAE1D,EAEF,OAAO,CACT,CAiBA,SAAgB,EAAc,EAA4B,CACxD,OAAO,EAAM,MAAM,OAAS,UAAY,EAAM,MAAM,SAAW,IAAA,EACjE"}
|
|
1
|
+
{"version":3,"file":"automation-setup.cjs","names":[],"sources":["../../src/manifests/automation-setup.ts"],"sourcesContent":["/**\n * The only module that knows a setup entry configures an *automation*.\n *\n * The published contract states just what varies between entries; everything\n * derivable is the host's to generate. That derivation is here, and nowhere\n * else, so the rest of `src/manifests/` stays about forms rather than about\n * automations.\n *\n * The algorithm mirrors `tests/test_automation_setup.py::_render_payload` in\n * `OpenHands/extensions`, which is the authoritative reference: it produces the\n * request bodies published in that repository's contract fixtures, and those\n * were verified against the live service. The create model is `extra=\"forbid\"`,\n * so any divergence is a hard 422 rather than a dropped field.\n */\n\nimport i18n from \"#/i18n\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { findAutomationCommand } from \"#/utils/automation-catalog\";\nimport { getAutomationEndpoint } from \"./automation-interface\";\nimport {\n actionKinds,\n collectFields,\n fieldText,\n fieldValues,\n} from \"./manifest-local-validation\";\nimport { interpolateText, interpolateValue } from \"./manifest-template\";\nimport type {\n SetupActionKind,\n SetupBlock,\n SetupBundleConfigValue,\n SetupEntry,\n SetupFormValues,\n SetupRequestBody,\n SetupTriggerKind,\n} from \"./types\";\n\n/**\n * The creation endpoint a derived draft would be posted to. Resolved on call\n * rather than at import, because the endpoint is the interface manifest's and\n * this module loads whether or not one was admitted.\n *\n * A bundle entry is created through the raw endpoint, because what it sends is\n * a tarball it uploaded rather than arguments to a preset. Called without an\n * entry - as the import path does - it answers for a prompt.\n */\nexport function automationCreateEndpoint(\n entry?: SetupEntry,\n selectedAction?: string | null,\n): string {\n const kind = selectedActionKind(entry, selectedAction);\n if (kind === \"plugin\") return getAutomationEndpoint(\"createPlugin\");\n if (kind === \"upload\" || kind === \"bundle\") {\n return requireBundleEndpoint(\"createBundle\");\n }\n return getAutomationEndpoint(\"createPrompt\");\n}\n\n/** Where a bundle's tarball is uploaded, before the create call. */\nexport function automationUploadEndpoint(): string {\n return requireBundleEndpoint(\"uploads\");\n}\n\n/** The endpoints a bundle entry cannot be created without. */\nconst BUNDLE_ENDPOINTS = [\"createBundle\", \"uploads\"] as const;\n\n/**\n * An endpoint only a bundle needs. The interface manifest may predate bundles,\n * and the host holds no path of its own to fall back to, so this is where that\n * runs out rather than somewhere deep in a request.\n */\nfunction requireBundleEndpoint(\n name: (typeof BUNDLE_ENDPOINTS)[number],\n): string {\n const path = getAutomationEndpoint(name);\n if (!path) {\n throw new Error(\n `The published automation interface declares no '${name}' endpoint, ` +\n \"so this deployment cannot create an automation from a script bundle.\",\n );\n }\n return path;\n}\n\n/**\n * The endpoints this entry needs that the published interface does not declare.\n *\n * Asked before the form renders rather than discovered at the moment of\n * creating: a pinned package that predates bundles can never answer, and the\n * dialog can say so while nothing has been filled in yet. Empty for every\n * entry that is not a bundle, which needs nothing beyond what the block has\n * always declared.\n */\nfunction missingEndpointsForAction(kind: SetupActionKind | \"bundle\"): string[] {\n return kind === \"upload\" || kind === \"bundle\"\n ? BUNDLE_ENDPOINTS.filter((name) => !getAutomationEndpoint(name))\n : [];\n}\n\nexport function missingCreateEndpoints(\n entry: SetupEntry,\n selectedAction?: string | null,\n): string[] {\n if (isBundleEntry(entry)) return missingEndpointsForAction(\"bundle\");\n if (!entry.setup.actions) return [];\n\n if (selectedAction && selectedAction in entry.setup.actions) {\n return missingEndpointsForAction(selectedAction as SetupActionKind);\n }\n\n const missingByAction = actionKinds(entry.setup).map(\n missingEndpointsForAction,\n );\n if (missingByAction.some((missing) => missing.length === 0)) return [];\n return Array.from(new Set(missingByAction.flat()));\n}\n\n/** Whether this entry ships a script tarball instead of a prompt. */\nexport function isBundleEntry(entry: SetupEntry): boolean {\n return entry.setup.mode === \"direct\" && entry.setup.bundle !== undefined;\n}\n\nexport function isUploadAction(\n entry: SetupEntry,\n selectedAction?: string | null,\n): boolean {\n return selectedActionKind(entry, selectedAction) === \"upload\";\n}\n\nexport function selectedActionKind(\n entry: SetupEntry | undefined,\n selectedAction?: string | null,\n): SetupActionKind | \"bundle\" | \"prompt\" {\n if (!entry) return \"prompt\";\n if (isBundleEntry(entry)) return \"bundle\";\n const actions = entry.setup.actions ?? {};\n if (selectedAction && selectedAction in actions) {\n return selectedAction as SetupActionKind;\n }\n const keys = actionKinds(entry.setup);\n if (keys.length === 1) return keys[0];\n return \"prompt\";\n}\n\n/**\n * The `tarball_path` a preflight draft carries.\n *\n * Preflight runs on every field blur and the upload happens once, at submit,\n * so there is no real path to send yet. The service checks this field's scheme\n * at preflight and its ownership only at creation, so a well-formed stand-in\n * validates exactly what preflight is for - the rest of the body - without\n * uploading an archive per keystroke.\n */\nexport const PREFLIGHT_TARBALL_PATH =\n \"oh-internal://uploads/00000000-0000-0000-0000-000000000000\";\n\n/**\n * Trigger properties a form field may fill, per trigger kind. A field under a\n * trigger kind whose name is listed here fills the trigger property of the same\n * name; anything else there, such as a phrase to match, is an input to `filter`.\n */\nconst TRIGGER_PROPERTIES: Record<SetupTriggerKind, readonly string[]> = {\n cron: [\"schedule\", \"timezone\"],\n event: [\"source\", \"on\"],\n};\n\nconst OPTIONAL_CREATE_PROPERTIES = [\"model\", \"timeout\"] as const;\n\n/**\n * Repository properties a form field may fill, read the same way\n * {@link TRIGGER_PROPERTIES} is: a field whose name is listed here fills the\n * `repos[]` property of the same name. `url` and `provider` are absent because\n * neither is answered by a field of its own — they come from the repo-picker's\n * value and from its declared provider.\n *\n * These two lists are the only field names the derivation knows; everything\n * else it reads it finds by field type. An entry that wants a base branch in\n * its request therefore has to name that field `ref`.\n */\nconst REPO_PROPERTIES: readonly string[] = [\"ref\"];\n\nconst FORM_PLACEHOLDER_PATTERN = /\\{\\{form\\.([A-Za-z0-9_.]+)\\}\\}/g;\n\n/** The repository input, which supplies `repos` and an event trigger's source. */\nfunction findRepoPickerField(\n setup: SetupBlock,\n selectedAction?: string | null,\n) {\n const match = Object.entries(collectFields(setup, null, selectedAction)).find(\n ([, field]) => field.type === \"repo-picker\",\n );\n return match ? { name: match[0], field: match[1] } : null;\n}\n\n/** Every repository the form collected, whether the picker takes one or many. */\nfunction repositories(\n setup: SetupBlock,\n values: SetupFormValues,\n selectedAction?: string | null,\n): string[] {\n const picker = findRepoPickerField(setup, selectedAction);\n return picker ? fieldValues(values[picker.name]) : [];\n}\n\n/**\n * The created automation's name.\n *\n * One repository is worth naming; several are not, so the count stands in\n * rather than a list of names that would not fit.\n */\nfunction deriveName(\n entry: SetupEntry,\n values: SetupFormValues,\n selectedAction?: string | null,\n): string {\n if (\n \"name\" in collectFields(entry.setup, null, selectedAction) &&\n \"name\" in values\n ) {\n return fieldText(values.name);\n }\n\n const repos = repositories(entry.setup, values, selectedAction);\n if (repos.length === 0) return entry.name;\n if (repos.length === 1) return `${entry.name} - ${repos[0]}`;\n // The count is the one word here the host writes rather than reads off the\n // entry, so it is translated. There is no translator to pass in: the\n // derivation runs from a memo, an upload and a test alike.\n const count = i18n.t(I18nKey.SETUP$REPOSITORY_COUNT, {\n total: repos.length,\n });\n return `${entry.name} - ${count}`;\n}\n\n/** The active trigger kind for a direct entry, with its fields. */\nfunction getTrigger(setup: SetupBlock, selectedTrigger?: string | null) {\n const triggers = setup.form.triggers ?? {};\n const entries = Object.entries(triggers);\n if (entries.length === 0) return null;\n const match =\n selectedTrigger && selectedTrigger in triggers\n ? [selectedTrigger, triggers[selectedTrigger as SetupTriggerKind]]\n : entries.length === 1\n ? entries[0]\n : null;\n if (!match) return null;\n const [kind, fields] = match;\n return { kind: kind as SetupTriggerKind, fields: fields ?? {} };\n}\n\nfunction hasPayloadValue(\n value: SetupRequestBody[string] | undefined,\n): value is SetupRequestBody[string] {\n return value !== undefined && value !== null && value !== \"\";\n}\n\nfunction fieldPayloadValue(\n fieldType: string | undefined,\n value: SetupFormValues[string],\n) {\n if (fieldType === \"number\") {\n const text = fieldText(value);\n return text === \"\" ? undefined : Number(text);\n }\n return fieldText(value);\n}\n\nfunction optionalCreateProperties(\n setup: SetupBlock,\n values: SetupFormValues,\n selectedAction?: string | null,\n): SetupRequestBody {\n return Object.fromEntries(\n OPTIONAL_CREATE_PROPERTIES.flatMap((name) => {\n const field = collectFields(setup, null, selectedAction)[name];\n const value = fieldPayloadValue(field?.type, values[name]);\n return hasPayloadValue(value) ? [[name, value]] : [];\n }),\n ) as SetupRequestBody;\n}\n\nfunction repositoryProperty(\n setup: SetupBlock,\n values: SetupFormValues,\n selectedAction?: string | null,\n): SetupRequestBody {\n const repoPicker = findRepoPickerField(setup, selectedAction);\n const repos = repositories(setup, values, selectedAction);\n if (repos.length === 0 || !repoPicker?.field.provider) return {};\n\n const declared = REPO_PROPERTIES.filter((name) =>\n hasPayloadValue(fieldText(values[name])),\n );\n return {\n repos: repos.map((url) => ({\n url,\n ...Object.fromEntries(\n declared.map((name) => [name, fieldText(values[name])]),\n ),\n provider: repoPicker.field.provider as string,\n })),\n };\n}\n\nfunction parsePluginSources(\n value: SetupRequestBody[string],\n): SetupRequestBody[string] {\n if (!hasPayloadValue(value) || typeof value !== \"string\") return value;\n const trimmed = value.trim();\n if (!trimmed) return [];\n if (trimmed.startsWith(\"[\")) {\n try {\n return JSON.parse(trimmed) as SetupRequestBody[string];\n } catch {\n return [{ source: trimmed }];\n }\n }\n return trimmed\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => {\n const [source, ...parts] = line.split(/\\s+/);\n const plugin: Record<string, string> = { source };\n parts.forEach((part) => {\n const [key, ...raw] = part.split(\"=\");\n const valuePart = raw.join(\"=\");\n if ((key === \"ref\" || key === \"repo_path\") && valuePart) {\n plugin[key] = valuePart;\n }\n });\n return plugin;\n });\n}\n\n/**\n * The create request body these form values produce.\n *\n * No entry declares it: `name` comes from the entry, `repos` from the\n * repo-picker field and its declared provider, and `trigger` from the key and\n * fields under `form.triggers`. Only `prompt` and an event `filter` are\n * declared, because only they cannot be read off the form.\n *\n * Returns null for an assisted entry, which hands setup to a conversation\n * instead of sending a body.\n */\nexport function buildCreatePayload(\n entry: SetupEntry,\n values: SetupFormValues,\n /** Bundle/upload entries only: what the upload returned. */\n tarballPath: string = PREFLIGHT_TARBALL_PATH,\n selectedTrigger?: string | null,\n selectedActionKey?: string | null,\n): SetupRequestBody | null {\n const { setup } = entry;\n if (setup.mode !== \"direct\") return null;\n if (setup.bundle) {\n return buildBundlePayload(entry, values, tarballPath, selectedTrigger);\n }\n if (setup.actions) {\n return buildActionPayload(\n entry,\n values,\n tarballPath,\n selectedTrigger,\n selectedActionKey,\n );\n }\n if (!setup.prompt) return null;\n\n const scope = { form: values, automation: entry };\n\n const payload: SetupRequestBody = {\n name: deriveName(entry, values),\n prompt: interpolateText(setup.prompt, scope),\n ...optionalCreateProperties(setup, values),\n ...repositoryProperty(setup, values),\n };\n\n const trigger = buildTrigger(entry, values, selectedTrigger);\n if (trigger) payload.trigger = trigger;\n\n const template = buildTemplate(entry, values);\n if (template) payload.template = template;\n\n return payload;\n}\n\nfunction buildActionPayload(\n entry: SetupEntry,\n values: SetupFormValues,\n tarballPath: string,\n selectedTrigger?: string | null,\n selectedActionKey?: string | null,\n): SetupRequestBody | null {\n const kind = selectedActionKind(entry, selectedActionKey);\n if (kind === \"bundle\") return null;\n\n const setup = entry.setup;\n const scope = { form: values, automation: entry };\n const payload: SetupRequestBody = {\n name: deriveName(entry, values, selectedActionKey),\n };\n\n const trigger = buildTrigger(\n entry,\n values,\n selectedTrigger,\n selectedActionKey,\n );\n if (trigger) payload.trigger = trigger;\n\n Object.assign(\n payload,\n optionalCreateProperties(setup, values, selectedActionKey),\n );\n\n if (kind === \"upload\") {\n const action = setup.actions?.upload;\n if (!action) return null;\n payload.tarball_path =\n tarballPath || interpolateText(action.tarballPath, scope);\n payload.entrypoint = interpolateText(action.entrypoint, scope);\n if (action.setupScript) {\n const setupScript = interpolateText(action.setupScript, scope);\n if (hasPayloadValue(setupScript)) payload.setup_script_path = setupScript;\n }\n return payload;\n }\n\n const action =\n kind === \"plugin\" ? setup.actions?.plugin : setup.actions?.prompt;\n if (!action) return null;\n payload.prompt = interpolateText(action.prompt, scope);\n Object.assign(payload, repositoryProperty(setup, values, selectedActionKey));\n\n if (kind === \"plugin\") {\n const pluginAction = setup.actions?.plugin;\n if (!pluginAction) return null;\n payload.plugins = parsePluginSources(\n interpolateValue(pluginAction.plugins, scope),\n );\n }\n\n const template = buildTemplate(entry, values);\n if (template) payload.template = template;\n\n return payload;\n}\n\n/**\n * The `template` provenance a prompt entry sends, or undefined for one that\n * publishes no version.\n *\n * It is what lets the service recognise a second setup of the same entry as\n * the automation it already holds. The bundle path derives the same block from\n * the config the bundle declares; a prompt entry declares none, so the answer\n * to \"what was this created from\" is the form as submitted.\n */\nfunction buildTemplate(\n entry: SetupEntry,\n values: SetupFormValues,\n): SetupRequestBody | undefined {\n if (!entry.version) return undefined;\n return {\n id: entry.id,\n version: entry.version,\n config: { ...values } as SetupRequestBody,\n };\n}\n\n/**\n * The `trigger` object, read off the key and fields under `form.triggers`.\n *\n * Identical for both kinds of direct entry: only the create endpoint and what\n * the automation is told to do differ between a prompt and a bundle.\n */\nfunction buildTrigger(\n entry: SetupEntry,\n values: SetupFormValues,\n selectedTrigger?: string | null,\n selectedAction?: string | null,\n): SetupRequestBody | undefined {\n const trigger = getTrigger(entry.setup, selectedTrigger);\n if (!trigger) return undefined;\n\n const properties = TRIGGER_PROPERTIES[trigger.kind];\n const declared = Object.keys(trigger.fields).filter((name) =>\n properties.includes(name),\n );\n const repoPicker = findRepoPickerField(entry.setup, selectedAction);\n const derived = Object.fromEntries(\n declared\n .map((name) => [name, fieldText(values[name])])\n .filter(([, value]) => hasPayloadValue(value)),\n );\n\n const filter = entry.setup.filter\n ? interpolateText(entry.setup.filter, {\n form: values,\n automation: entry,\n })\n : undefined;\n\n return {\n type: trigger.kind,\n ...derived,\n ...(trigger.kind === \"event\" && {\n ...(!(\"source\" in derived) && {\n source: repoPicker?.field.provider ?? \"\",\n }),\n ...(hasPayloadValue(filter) && { filter }),\n }),\n };\n}\n\n/**\n * The raw create body a bundle entry produces.\n *\n * `tarball_path` is the one value neither declared nor derived: the host packs\n * and uploads the bundle first, and creates from what came back. `template` is\n * the provenance that makes enabling the same entry twice return the\n * automation that already exists rather than a second one.\n *\n * There is no `repos`: the raw endpoint has no such field, and a bundle's\n * script fetches what it needs itself.\n */\nfunction buildBundlePayload(\n entry: SetupEntry,\n values: SetupFormValues,\n tarballPath: string,\n selectedTrigger?: string | null,\n): SetupRequestBody {\n const bundle = entry.setup.bundle!;\n const scope = { form: values, automation: entry };\n\n const payload: SetupRequestBody = {\n name: deriveName(entry, values),\n };\n\n const trigger = buildTrigger(entry, values, selectedTrigger);\n if (trigger) payload.trigger = trigger;\n\n payload.tarball_path = tarballPath;\n payload.entrypoint = bundle.entrypoint;\n if (bundle.setupScript) payload.setup_script_path = bundle.setupScript;\n if (bundle.timeout !== undefined) payload.timeout = bundle.timeout;\n payload.template = {\n id: entry.id,\n version: bundle.version,\n config: interpolateConfig(bundle.config, scope) as SetupRequestBody,\n };\n\n return payload;\n}\n\n/**\n * Placeholder substitution over the config tree. Only string leaves are\n * templated; a number, a boolean or a null is written through as itself, so an\n * entry can state a value the script reads as the type it expects.\n */\nfunction interpolateConfig(\n node: SetupBundleConfigValue,\n scope: Parameters<typeof interpolateText>[1],\n): SetupBundleConfigValue {\n if (typeof node === \"string\") {\n return interpolateValue(node, scope);\n }\n if (Array.isArray(node)) {\n return node.map((item) => interpolateConfig(item, scope));\n }\n if (typeof node === \"object\" && node !== null) {\n return Object.fromEntries(\n Object.entries(node).map(([key, value]) => [\n key,\n interpolateConfig(value, scope),\n ]),\n );\n }\n return node;\n}\n\n/**\n * The preflight body the host sends. The same shape for every entry, so no\n * entry declares it.\n */\nexport function buildPreflightBody(\n entry: SetupEntry,\n values: SetupFormValues,\n selectedTrigger?: string | null,\n selectedAction?: string | null,\n): SetupRequestBody | null {\n const draft = buildCreatePayload(\n entry,\n values,\n PREFLIGHT_TARBALL_PATH,\n selectedTrigger,\n selectedAction,\n );\n if (!draft) return null;\n\n return {\n automationId: entry.id,\n endpoint: automationCreateEndpoint(entry, selectedAction),\n draft,\n };\n}\n\n/**\n * What an assisted entry sends into the conversation that finishes setup.\n *\n * The command is not declared either: it lives once, in the owning skill's own\n * `triggers` frontmatter, and the skill defaults to the entry's id. An entry\n * whose skill is invoked by description rather than by command contributes\n * nothing here, and the answers alone open the conversation.\n */\nexport function buildAssistedMessage(\n entry: SetupEntry,\n values: SetupFormValues,\n): string {\n const command = findAutomationCommand(entry);\n const message = entry.setup.message\n ? interpolateText(entry.setup.message, { form: values, automation: entry })\n : \"\";\n\n return [command, message].filter(Boolean).join(\"\\n\\n\");\n}\n\nfunction collectPlaceholderFields(value: string): string[] {\n const names = Array.from(\n value.matchAll(FORM_PLACEHOLDER_PATTERN),\n (match) => match[1],\n );\n return Array.from(new Set(names));\n}\n\n/**\n * Which form fields built each payload path.\n *\n * Preflight and the create endpoint reject a draft by payload path, and the\n * host has to turn that back into a highlighted input. Building the body with\n * each field standing in for its own value recovers the mapping exactly, so an\n * entry does not declare it.\n */\nexport function deriveErrorMap(\n entry: SetupEntry,\n selectedTrigger?: string | null,\n selectedAction?: string | null,\n): Record<string, string[]> {\n const mapping: Record<string, string[]> = {};\n\n const triggerEntries = Object.keys(entry.setup.form.triggers ?? {});\n const triggerVariants = selectedTrigger\n ? [selectedTrigger]\n : triggerEntries.length > 1\n ? triggerEntries\n : [null];\n\n const actionEntries = actionKinds(entry.setup);\n const actionVariants = selectedAction\n ? [selectedAction]\n : actionEntries.length > 1\n ? actionEntries\n : [null];\n\n const walk = (node: unknown, path: string): void => {\n if (Array.isArray(node)) {\n node.forEach((item, index) => walk(item, `${path}[${index}]`));\n return;\n }\n if (typeof node === \"object\" && node !== null) {\n Object.entries(node).forEach(([key, item]) =>\n walk(item, path ? `${path}.${key}` : key),\n );\n return;\n }\n if (typeof node === \"string\") {\n const names = collectPlaceholderFields(node);\n if (names.length > 0) {\n mapping[path] = Array.from(\n new Set([...(mapping[path] ?? []), ...names]),\n );\n }\n }\n };\n\n actionVariants.forEach((actionVariant) => {\n triggerVariants.forEach((triggerVariant) => {\n const names = Object.keys(\n collectFields(entry.setup, triggerVariant, actionVariant),\n );\n const variantStandIns = Object.fromEntries(\n names.map((name) => [name, `{{form.${name}}}`]),\n );\n const template = buildCreatePayload(\n entry,\n variantStandIns,\n actionVariant === \"upload\" ? \"\" : PREFLIGHT_TARBALL_PATH,\n triggerVariant,\n actionVariant,\n );\n if (template) walk(template, \"\");\n });\n });\n return mapping;\n}\n"],"mappings":"gNA6CA,SAAgB,EACd,EACA,EACQ,CACR,IAAM,EAAO,EAAmB,EAAO,CAAc,EAKrD,OAJI,IAAS,SAAiB,EAAA,sBAAsB,cAAc,EAC9D,IAAS,UAAY,IAAS,SACzB,EAAsB,cAAc,EAEtC,EAAA,sBAAsB,cAAc,CAC7C,CAGA,SAAgB,GAAmC,CACjD,OAAO,EAAsB,SAAS,CACxC,CAUA,SAAS,EACP,EACQ,CACR,IAAM,EAAO,EAAA,sBAAsB,CAAI,EACvC,GAAI,CAAC,EACH,MAAU,MACR,mDAAmD,EAAK,iFAE1D,EAEF,OAAO,CACT,CAoCA,SAAgB,EAAc,EAA4B,CACxD,OAAO,EAAM,MAAM,OAAS,UAAY,EAAM,MAAM,SAAW,IAAA,EACjE,CASA,SAAgB,EACd,EACA,EACuC,CACvC,GAAI,CAAC,EAAO,MAAO,SACnB,GAAI,EAAc,CAAK,EAAG,MAAO,SACjC,IAAM,EAAU,EAAM,MAAM,SAAW,CAAC,EACxC,GAAI,GAAkB,KAAkB,EACtC,OAAO,EAET,IAAM,EAAO,EAAA,YAAY,EAAM,KAAK,EAEpC,OADI,EAAK,SAAW,EAAU,EAAK,GAC5B,QACT"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* were verified against the live service. The create model is `extra="forbid"`,
|
|
13
13
|
* so any divergence is a hard 422 rather than a dropped field.
|
|
14
14
|
*/
|
|
15
|
-
import type { SetupEntry, SetupFormValues, SetupRequestBody } from "./types";
|
|
15
|
+
import type { SetupActionKind, SetupEntry, SetupFormValues, SetupRequestBody } from "./types";
|
|
16
16
|
/**
|
|
17
17
|
* The creation endpoint a derived draft would be posted to. Resolved on call
|
|
18
18
|
* rather than at import, because the endpoint is the interface manifest's and
|
|
@@ -22,21 +22,14 @@ import type { SetupEntry, SetupFormValues, SetupRequestBody } from "./types";
|
|
|
22
22
|
* a tarball it uploaded rather than arguments to a preset. Called without an
|
|
23
23
|
* entry - as the import path does - it answers for a prompt.
|
|
24
24
|
*/
|
|
25
|
-
export declare function automationCreateEndpoint(entry?: SetupEntry): string;
|
|
25
|
+
export declare function automationCreateEndpoint(entry?: SetupEntry, selectedAction?: string | null): string;
|
|
26
26
|
/** Where a bundle's tarball is uploaded, before the create call. */
|
|
27
27
|
export declare function automationUploadEndpoint(): string;
|
|
28
|
-
|
|
29
|
-
* The endpoints this entry needs that the published interface does not declare.
|
|
30
|
-
*
|
|
31
|
-
* Asked before the form renders rather than discovered at the moment of
|
|
32
|
-
* creating: a pinned package that predates bundles can never answer, and the
|
|
33
|
-
* dialog can say so while nothing has been filled in yet. Empty for every
|
|
34
|
-
* entry that is not a bundle, which needs nothing beyond what the block has
|
|
35
|
-
* always declared.
|
|
36
|
-
*/
|
|
37
|
-
export declare function missingCreateEndpoints(entry: SetupEntry): string[];
|
|
28
|
+
export declare function missingCreateEndpoints(entry: SetupEntry, selectedAction?: string | null): string[];
|
|
38
29
|
/** Whether this entry ships a script tarball instead of a prompt. */
|
|
39
30
|
export declare function isBundleEntry(entry: SetupEntry): boolean;
|
|
31
|
+
export declare function isUploadAction(entry: SetupEntry, selectedAction?: string | null): boolean;
|
|
32
|
+
export declare function selectedActionKind(entry: SetupEntry | undefined, selectedAction?: string | null): SetupActionKind | "bundle" | "prompt";
|
|
40
33
|
/**
|
|
41
34
|
* The `tarball_path` a preflight draft carries.
|
|
42
35
|
*
|
|
@@ -59,13 +52,13 @@ export declare const PREFLIGHT_TARBALL_PATH = "oh-internal://uploads/00000000-00
|
|
|
59
52
|
* instead of sending a body.
|
|
60
53
|
*/
|
|
61
54
|
export declare function buildCreatePayload(entry: SetupEntry, values: SetupFormValues,
|
|
62
|
-
/** Bundle entries only: what the upload returned. */
|
|
63
|
-
tarballPath?: string): SetupRequestBody | null;
|
|
55
|
+
/** Bundle/upload entries only: what the upload returned. */
|
|
56
|
+
tarballPath?: string, selectedTrigger?: string | null, selectedActionKey?: string | null): SetupRequestBody | null;
|
|
64
57
|
/**
|
|
65
58
|
* The preflight body the host sends. The same shape for every entry, so no
|
|
66
59
|
* entry declares it.
|
|
67
60
|
*/
|
|
68
|
-
export declare function buildPreflightBody(entry: SetupEntry, values: SetupFormValues): SetupRequestBody | null;
|
|
61
|
+
export declare function buildPreflightBody(entry: SetupEntry, values: SetupFormValues, selectedTrigger?: string | null, selectedAction?: string | null): SetupRequestBody | null;
|
|
69
62
|
/**
|
|
70
63
|
* What an assisted entry sends into the conversation that finishes setup.
|
|
71
64
|
*
|
|
@@ -83,4 +76,4 @@ export declare function buildAssistedMessage(entry: SetupEntry, values: SetupFor
|
|
|
83
76
|
* each field standing in for its own value recovers the mapping exactly, so an
|
|
84
77
|
* entry does not declare it.
|
|
85
78
|
*/
|
|
86
|
-
export declare function deriveErrorMap(entry: SetupEntry): Record<string, string[]>;
|
|
79
|
+
export declare function deriveErrorMap(entry: SetupEntry, selectedTrigger?: string | null, selectedAction?: string | null): Record<string, string[]>;
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import "../i18n/index.js";
|
|
2
2
|
import "../utils/automation-catalog.js";
|
|
3
3
|
import { getAutomationEndpoint as e } from "./automation-interface.js";
|
|
4
|
+
import { actionKinds as t } from "./manifest-local-validation.js";
|
|
4
5
|
//#region src/manifests/automation-setup.ts
|
|
5
|
-
function
|
|
6
|
-
|
|
6
|
+
function n(t, n) {
|
|
7
|
+
let r = o(t, n);
|
|
8
|
+
return r === "plugin" ? e("createPlugin") : r === "upload" || r === "bundle" ? i("createBundle") : e("createPrompt");
|
|
7
9
|
}
|
|
8
|
-
function
|
|
9
|
-
return
|
|
10
|
+
function r() {
|
|
11
|
+
return i("uploads");
|
|
10
12
|
}
|
|
11
|
-
function
|
|
13
|
+
function i(t) {
|
|
12
14
|
let n = e(t);
|
|
13
15
|
if (!n) throw Error(`The published automation interface declares no '${t}' endpoint, so this deployment cannot create an automation from a script bundle.`);
|
|
14
16
|
return n;
|
|
15
17
|
}
|
|
16
|
-
function
|
|
18
|
+
function a(e) {
|
|
17
19
|
return e.setup.mode === "direct" && e.setup.bundle !== void 0;
|
|
18
20
|
}
|
|
21
|
+
function o(e, n) {
|
|
22
|
+
if (!e) return "prompt";
|
|
23
|
+
if (a(e)) return "bundle";
|
|
24
|
+
let r = e.setup.actions ?? {};
|
|
25
|
+
if (n && n in r) return n;
|
|
26
|
+
let i = t(e.setup);
|
|
27
|
+
return i.length === 1 ? i[0] : "prompt";
|
|
28
|
+
}
|
|
19
29
|
//#endregion
|
|
20
|
-
export {
|
|
30
|
+
export { n as automationCreateEndpoint, r as automationUploadEndpoint };
|
|
21
31
|
|
|
22
32
|
//# sourceMappingURL=automation-setup.js.map
|