@openhands/agent-canvas 1.0.0-alpha.5 → 1.0.0-alpha.7

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.
Files changed (70) hide show
  1. package/README.md +41 -7
  2. package/bin/agent-canvas.mjs +9 -2
  3. package/build/assets/automation-detail-D7GEU0vR.js +1 -0
  4. package/build/assets/automations-list-CkVNsgzm.js +1 -0
  5. package/build/assets/conversation-COZAKz_K.js +1 -0
  6. package/build/assets/{conversation-D8scXOe7.js → conversation-DWcvnmds.js} +3 -1
  7. package/build/assets/conversation-panel-CZDStT0b.js +1 -0
  8. package/build/assets/conversation-websocket-context-DulnrIHh.js +3 -0
  9. package/build/assets/edit-automation-modal-C3bFxS2f.js +1 -0
  10. package/build/assets/git-control-bar-branch-button-Bm6rzSpo.js +27 -0
  11. package/build/assets/{home-D9fJfhQA.js → home-DR11ejqB.js} +1 -1
  12. package/build/assets/{manifest-f141dc70.js → manifest-f041e61a.js} +1 -1
  13. package/build/assets/{messages-BfaEAG2q.js → messages-v-q35ObG.js} +1 -1
  14. package/build/assets/{root-luPHQiBx.js → root-D2PVd51i.js} +1 -1
  15. package/build/assets/root-layout-B4QioBS6.js +2 -0
  16. package/build/assets/{shared-conversation-BfZNCsvo.js → shared-conversation-DQlzwdpo.js} +1 -1
  17. package/build/index.html +3 -3
  18. package/config/defaults.json +38 -0
  19. package/dist/components/features/backends/backend-selector.cjs +1 -1
  20. package/dist/components/features/backends/backend-selector.cjs.map +1 -1
  21. package/dist/components/features/backends/backend-selector.js +95 -95
  22. package/dist/components/features/backends/backend-selector.js.map +1 -1
  23. package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
  24. package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
  25. package/dist/components/features/chat/components/chat-input-actions.js +118 -118
  26. package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
  27. package/dist/components/features/chat/components/slash-command-menu.cjs +1 -1
  28. package/dist/components/features/chat/components/slash-command-menu.cjs.map +1 -1
  29. package/dist/components/features/chat/components/slash-command-menu.js +1 -1
  30. package/dist/components/features/chat/components/slash-command-menu.js.map +1 -1
  31. package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
  32. package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
  33. package/dist/components/features/sidebar/sidebar-rail-body.d.ts +1 -2
  34. package/dist/components/features/sidebar/sidebar-rail-body.js +104 -104
  35. package/dist/components/features/sidebar/sidebar-rail-body.js.map +1 -1
  36. package/dist/components/features/sidebar/sidebar.cjs +1 -1
  37. package/dist/components/features/sidebar/sidebar.cjs.map +1 -1
  38. package/dist/components/features/sidebar/sidebar.js +82 -83
  39. package/dist/components/features/sidebar/sidebar.js.map +1 -1
  40. package/dist/contexts/conversation-websocket-context.cjs +3 -3
  41. package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
  42. package/dist/contexts/conversation-websocket-context.js +36 -36
  43. package/dist/contexts/conversation-websocket-context.js.map +1 -1
  44. package/dist/hooks/query/use-local-git-info.cjs +3 -1
  45. package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
  46. package/dist/hooks/query/use-local-git-info.d.ts +2 -2
  47. package/dist/hooks/query/use-local-git-info.js +27 -24
  48. package/dist/hooks/query/use-local-git-info.js.map +1 -1
  49. package/dist/package.cjs +1 -1
  50. package/dist/package.cjs.map +1 -1
  51. package/dist/package.js +2 -1
  52. package/dist/package.js.map +1 -1
  53. package/dist/stores/error-message-store.cjs +1 -1
  54. package/dist/stores/error-message-store.cjs.map +1 -1
  55. package/dist/stores/error-message-store.d.ts +10 -1
  56. package/dist/stores/error-message-store.js +16 -3
  57. package/dist/stores/error-message-store.js.map +1 -1
  58. package/package.json +2 -1
  59. package/scripts/dev-static.mjs +8 -1
  60. package/scripts/dev-with-automation.mjs +30 -49
  61. package/scripts/static-build.mjs +2 -6
  62. package/scripts/static-server.mjs +85 -4
  63. package/build/assets/automation-detail-ZQs6D2d3.js +0 -1
  64. package/build/assets/automations-list-CqHXGwSw.js +0 -1
  65. package/build/assets/conversation-CeGMBOyB.js +0 -1
  66. package/build/assets/conversation-panel-DMz46ji-.js +0 -1
  67. package/build/assets/conversation-websocket-context-B0Gd3yiT.js +0 -3
  68. package/build/assets/edit-automation-modal-DgW0Q8vr.js +0 -1
  69. package/build/assets/git-control-bar-branch-button-DhpPgadK.js +0 -27
  70. package/build/assets/root-layout-DvYGxAnr.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"chat-input-actions.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-actions.tsx"],"sourcesContent":["import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { Cpu } from \"lucide-react\";\nimport { AgentStatus } from \"#/components/features/controls/agent-status\";\nimport { ChangeAgentButton } from \"../change-agent-button\";\nimport { ChatInputModel } from \"./chat-input-model\";\nimport { SwitchProfileButton } from \"../switch-profile-button\";\nimport { ChatAddFileButton } from \"../chat-add-file-button\";\nimport { ChatSendButton } from \"../chat-send-button\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CarretRightFillIcon from \"#/icons/carret-right-fill.svg?react\";\nimport LessonPlanIcon from \"#/icons/lesson-plan.svg?react\";\nimport ThreeDotsVerticalIcon from \"#/icons/three-dots-vertical.svg?react\";\nimport { CodePillIcon } from \"#/icons/code-pill\";\nimport { useUnifiedPauseConversation } from \"#/hooks/mutation/use-unified-stop-conversation\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { usePauseConversation } from \"#/hooks/mutation/use-pause-conversation\";\nimport { useResumeConversation } from \"#/hooks/mutation/use-resume-conversation\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useAcpModelContext } from \"#/hooks/use-acp-model-context\";\nimport { labelForAcpModel } from \"#/constants/acp-providers\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { useUnifiedWebSocketStatus } from \"#/hooks/use-unified-websocket-status\";\nimport { useHandlePlanClick } from \"#/hooks/use-handle-plan-click\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ToolsContextMenuIconText } from \"../../controls/tools-context-menu-icon-text\";\nimport { ContextMenuListItem } from \"../../context-menu/context-menu-list-item\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { Divider } from \"#/ui/divider\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\n\ninterface ChatInputActionsProps {\n disabled: boolean;\n canSubmit?: boolean;\n onAddFileClick?: () => void;\n showButton?: boolean;\n buttonClassName?: string;\n handleSubmit?: () => void;\n}\n\nexport function ChatInputActions({\n disabled,\n canSubmit = true,\n onAddFileClick = () => {},\n showButton = true,\n buttonClassName = \"\",\n handleSubmit = () => {},\n}: ChatInputActionsProps) {\n const { t } = useTranslation(\"openhands\");\n const unifiedPauseMutation = useUnifiedPauseConversation();\n const pauseConversationMutation = usePauseConversation();\n const resumeConversationMutation = useResumeConversation();\n const { conversationId } = useOptionalConversationId();\n const { data: conversation } = useActiveConversation();\n const { backend } = useActiveBackend();\n const isCloud = backend.kind === \"cloud\";\n // Shared with ChatInputModel: routes the model affordance to ChatInputModel\n // (which knows how to show the ACP model) instead of SwitchProfileButton for\n // ACP conversations — and for the home screen when Settings → Agent already\n // selects an ACP agent, since the next conversation will inherit it.\n const { isAcpContext, destinationPath, destinationLabel } =\n useAcpModelContext();\n // Mirror ChatInputModel: ACP conversations show the provider's human label\n // (e.g. \"Claude Opus 4.7\") in the overflow model submenu, not the raw\n // ``acp_model`` id. OpenHands keeps the raw model string.\n const overflowModelLabel = isAcpContext\n ? (labelForAcpModel(conversation?.acp_server, conversation?.llm_model) ??\n conversation?.llm_model)\n : conversation?.llm_model;\n const webSocketStatus = useUnifiedWebSocketStatus();\n const { curAgentState } = useAgentState();\n const { conversationMode, setConversationMode } = useConversationStore();\n const { handlePlanClick, isCreatingConversation } = useHandlePlanClick();\n\n const actionsRowRef = React.useRef<HTMLDivElement>(null);\n const rightSectionRef = React.useRef<HTMLDivElement>(null);\n const addFileRef = React.useRef<HTMLDivElement>(null);\n const codeRef = React.useRef<HTMLDivElement>(null);\n const modelRef = React.useRef<HTMLDivElement>(null);\n const overflowTriggerRef = React.useRef<HTMLButtonElement>(null);\n const [actionsRowWidth, setActionsRowWidth] = React.useState<number>(\n Number.POSITIVE_INFINITY,\n );\n const [rightSectionWidth, setRightSectionWidth] = React.useState(0);\n const [addFileWidth, setAddFileWidth] = React.useState(32);\n const [codeWidth, setCodeWidth] = React.useState(96);\n const [modelWidth, setModelWidth] = React.useState(120);\n const [isOverflowOpen, setIsOverflowOpen] = React.useState(false);\n const [activeSubmenu, setActiveSubmenu] = React.useState<\n \"agent\" | \"model\" | null\n >(null);\n const [overflowPortalStyle, setOverflowPortalStyle] =\n React.useState<React.CSSProperties>();\n\n React.useEffect(() => {\n const rowEl = actionsRowRef.current;\n const rightEl = rightSectionRef.current;\n const addEl = addFileRef.current;\n const codeEl = codeRef.current;\n const modelEl = modelRef.current;\n\n if (\n !rowEl ||\n !rightEl ||\n !addEl ||\n !modelEl ||\n (isCloud && !codeEl) ||\n typeof ResizeObserver === \"undefined\"\n ) {\n return;\n }\n\n const syncWidths = () => {\n const nextRowWidth = rowEl.getBoundingClientRect().width;\n const nextRightWidth = rightEl.getBoundingClientRect().width;\n const nextAddWidth = addEl.getBoundingClientRect().width;\n const nextModelWidth = modelEl.getBoundingClientRect().width;\n\n if (nextRowWidth > 0) setActionsRowWidth(nextRowWidth);\n if (nextRightWidth > 0) setRightSectionWidth(nextRightWidth);\n if (nextAddWidth > 0) setAddFileWidth(nextAddWidth);\n if (nextModelWidth > 0) setModelWidth(nextModelWidth);\n\n if (codeEl) {\n const nextCodeWidth = codeEl.getBoundingClientRect().width;\n if (nextCodeWidth > 0) setCodeWidth(nextCodeWidth);\n }\n };\n\n const observer = new ResizeObserver(() => {\n syncWidths();\n });\n\n observer.observe(rowEl);\n observer.observe(rightEl);\n observer.observe(addEl);\n observer.observe(modelEl);\n if (codeEl) {\n observer.observe(codeEl);\n }\n\n syncWidths();\n\n return () => observer.disconnect();\n }, [isCloud]);\n\n const handlePauseAgent = () => {\n if (!conversationId) return;\n pauseConversationMutation.mutate({ conversationId });\n };\n\n const handleResumeAgentClick = () => {\n if (!conversationId) return;\n resumeConversationMutation.mutate({ conversationId });\n };\n\n const isPausing =\n unifiedPauseMutation.isPending || pauseConversationMutation.isPending;\n\n const OVERFLOW_BUTTON_WIDTH = 28;\n const INLINE_GAP = 12;\n const ROOT_GAP = 8;\n\n const fitOptionalItems = React.useCallback(\n (availableWidth: number) => {\n let remaining = availableWidth;\n const next = {\n showCodeInline: false,\n showModelInline: false,\n };\n\n if (isCloud && remaining >= codeWidth) {\n next.showCodeInline = true;\n remaining -= codeWidth + INLINE_GAP;\n }\n\n if (remaining >= modelWidth) {\n next.showModelInline = true;\n }\n\n return next;\n },\n [isCloud, codeWidth, modelWidth],\n );\n\n const leftBaseWidth =\n actionsRowWidth - rightSectionWidth - ROOT_GAP - addFileWidth - INLINE_GAP;\n\n const fitWithoutOverflow = fitOptionalItems(leftBaseWidth);\n const allOptionalFit =\n (!isCloud || fitWithoutOverflow.showCodeInline) &&\n fitWithoutOverflow.showModelInline;\n\n const fitWithOverflow = allOptionalFit\n ? fitWithoutOverflow\n : fitOptionalItems(leftBaseWidth - OVERFLOW_BUTTON_WIDTH - INLINE_GAP);\n\n const showCodeInline = !isCloud ? false : fitWithOverflow.showCodeInline;\n const showModelInline = fitWithOverflow.showModelInline;\n const showAddFileInline = true;\n const showAgentStatusInline = actionsRowWidth >= 360;\n\n const hasOverflowItems =\n !showAddFileInline || (isCloud && !showCodeInline) || !showModelInline;\n\n React.useEffect(() => {\n if (!hasOverflowItems) {\n setIsOverflowOpen(false);\n setActiveSubmenu(null);\n }\n }, [hasOverflowItems]);\n\n const overflowMenuRef = useClickOutsideElement<HTMLUListElement>(() => {\n setIsOverflowOpen(false);\n setActiveSubmenu(null);\n });\n\n const isAgentSwitcherDisabled =\n curAgentState === AgentState.RUNNING ||\n isCreatingConversation ||\n webSocketStatus !== \"OPEN\";\n\n const closeOverflowMenus = () => {\n setActiveSubmenu(null);\n setIsOverflowOpen(false);\n };\n\n React.useLayoutEffect(() => {\n if (!isOverflowOpen || !overflowTriggerRef.current) {\n return;\n }\n\n const trigger = overflowTriggerRef.current;\n\n const updatePosition = () => {\n const rect = trigger.getBoundingClientRect();\n const GAP = 8;\n setOverflowPortalStyle({\n position: \"fixed\",\n top: rect.top - GAP,\n left: rect.left,\n transform: \"translateY(-100%)\",\n zIndex: 9999,\n });\n };\n\n updatePosition();\n window.addEventListener(\"resize\", updatePosition);\n window.addEventListener(\"scroll\", updatePosition, true);\n\n return () => {\n window.removeEventListener(\"resize\", updatePosition);\n window.removeEventListener(\"scroll\", updatePosition, true);\n };\n }, [isOverflowOpen]);\n\n const overflowMenu = (\n <ContextMenu\n ref={overflowMenuRef}\n testId=\"chat-input-overflow-menu\"\n position=\"top\"\n alignment=\"left\"\n className=\"!static !top-auto !bottom-auto !left-auto !right-auto !mt-0 overflow-visible min-w-[200px]\"\n >\n {isCloud && !showCodeInline && (\n <div className=\"relative group/overflow-agent\">\n <ContextMenuListItem\n testId=\"overflow-agent-button\"\n onClick={() =>\n setActiveSubmenu((current) =>\n current === \"agent\" ? null : \"agent\",\n )\n }\n isDisabled={isAgentSwitcherDisabled}\n >\n <ToolsContextMenuIconText\n icon={<CodePillIcon className=\"h-[11px] w-[11px]\" />}\n text={\n conversationMode === \"code\"\n ? t(I18nKey.COMMON$CODE)\n : t(I18nKey.COMMON$PLAN)\n }\n rightIcon={<CarretRightFillIcon width={10} height={10} />}\n />\n </ContextMenuListItem>\n {!isAgentSwitcherDisabled && (\n <div\n className={cn(\n \"absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]\",\n \"group-hover/overflow-agent:opacity-100 group-hover/overflow-agent:visible group-hover/overflow-agent:pointer-events-auto\",\n \"hover:opacity-100 hover:visible hover:pointer-events-auto\",\n activeSubmenu === \"agent\" &&\n \"opacity-100 visible pointer-events-auto\",\n )}\n >\n <ContextMenu\n testId=\"overflow-agent-submenu\"\n className=\"overflow-visible min-w-[195px] gap-0\"\n >\n <ContextMenuListItem\n testId=\"overflow-agent-code\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setConversationMode(\"code\");\n closeOverflowMenus();\n }}\n >\n <ToolsContextMenuIconText\n icon={<CodePillIcon className=\"h-[11px] w-[11px]\" />}\n text={t(I18nKey.COMMON$CODE)}\n />\n </ContextMenuListItem>\n <ContextMenuListItem\n testId=\"overflow-agent-plan\"\n onClick={(event) => {\n handlePlanClick(event);\n closeOverflowMenus();\n }}\n >\n <ToolsContextMenuIconText\n icon={\n <LessonPlanIcon\n width={16}\n height={16}\n color=\"currentColor\"\n />\n }\n text={t(I18nKey.COMMON$PLAN)}\n />\n </ContextMenuListItem>\n </ContextMenu>\n </div>\n )}\n </div>\n )}\n {!showModelInline && (\n <div className=\"relative group/overflow-model\">\n <ContextMenuListItem\n testId=\"overflow-model-button\"\n onClick={() =>\n setActiveSubmenu((current) =>\n current === \"model\" ? null : \"model\",\n )\n }\n >\n <ToolsContextMenuIconText\n icon={<Cpu width={16} height={16} strokeWidth={2} aria-hidden />}\n text=\"Model\"\n rightIcon={<CarretRightFillIcon width={10} height={10} />}\n />\n </ContextMenuListItem>\n <div\n className={cn(\n \"absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]\",\n \"group-hover/overflow-model:opacity-100 group-hover/overflow-model:visible group-hover/overflow-model:pointer-events-auto\",\n \"hover:opacity-100 hover:visible hover:pointer-events-auto\",\n activeSubmenu === \"model\" &&\n \"opacity-100 visible pointer-events-auto\",\n )}\n >\n <ContextMenu\n testId=\"overflow-model-submenu\"\n className=\"overflow-visible min-w-[220px] max-w-[320px] gap-0\"\n >\n <li className=\"text-sm\">\n <div className=\"p-2 leading-5 text-[var(--oh-foreground)] break-all\">\n {overflowModelLabel}\n </div>\n </li>\n <Divider inset=\"menu\" />\n <li className=\"text-sm\">\n <NavigationLink\n to={destinationPath}\n onClick={closeOverflowMenus}\n className={cn(\n \"group flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\",\n formControlTransitionClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\n \"shrink-0 text-[var(--oh-muted)] group-hover:text-[var(--oh-foreground)]\",\n formControlTransitionClassName,\n )}\n aria-hidden\n />\n <span>{destinationLabel}</span>\n </NavigationLink>\n </li>\n </ContextMenu>\n </div>\n </div>\n )}\n </ContextMenu>\n );\n\n return (\n <div\n ref={actionsRowRef}\n className=\"w-full min-w-0 flex items-center justify-between gap-2\"\n >\n <div className=\"flex min-w-0 items-center gap-1\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <div ref={addFileRef} className={cn(!showAddFileInline && \"hidden\")}>\n <ChatAddFileButton\n disabled={disabled}\n handleFileIconClick={onAddFileClick}\n />\n </div>\n {isCloud && (\n <div ref={codeRef} className={cn(!showCodeInline && \"hidden\")}>\n <ChangeAgentButton />\n </div>\n )}\n <div ref={modelRef} className={cn(!showModelInline && \"hidden\")}>\n {isCloud || isAcpContext ? (\n <ChatInputModel />\n ) : (\n <SwitchProfileButton />\n )}\n </div>\n\n {hasOverflowItems && (\n <div className=\"relative shrink-0\">\n <button\n ref={overflowTriggerRef}\n type=\"button\"\n className={cn(\n \"flex size-6 items-center justify-center rounded-full text-[var(--oh-muted)]\",\n formControlTransitionClassName,\n \"hover:bg-white/10 hover:text-white cursor-pointer\",\n )}\n aria-label=\"More input actions\"\n aria-expanded={isOverflowOpen}\n aria-haspopup=\"menu\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsOverflowOpen((open) => !open);\n }}\n >\n <ThreeDotsVerticalIcon\n width={16}\n height={16}\n color=\"currentColor\"\n />\n </button>\n\n {isOverflowOpen &&\n typeof document !== \"undefined\" &&\n overflowPortalStyle &&\n ReactDOM.createPortal(\n <div style={overflowPortalStyle}>{overflowMenu}</div>,\n document.body,\n )}\n </div>\n )}\n </div>\n </div>\n <div\n ref={rightSectionRef}\n className=\"ml-auto flex shrink-0 items-center gap-2\"\n >\n {showAgentStatusInline && conversationId && (\n <AgentStatus\n handleStop={handlePauseAgent}\n handleResumeAgent={handleResumeAgentClick}\n disabled={disabled}\n isPausing={isPausing}\n />\n )}\n {showButton && (\n <ChatSendButton\n buttonClassName={buttonClassName}\n handleSubmit={handleSubmit}\n disabled={disabled || !canSubmit}\n />\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"0hEA+CA,SAAgB,EAAiB,CAC/B,WACA,YAAY,GACZ,sBAAuB,GACvB,cAAa,GACb,mBAAkB,GAClB,oBAAqB,IACG,CACxB,GAAM,CAAE,KAAM,EAAA,eAAe,YAAY,CACnC,GAAuB,GAAA,6BAA6B,CACpD,EAA4B,GAAA,sBAAsB,CAClD,GAA6B,EAAA,uBAAuB,CACpD,CAAE,kBAAmB,EAAA,2BAA2B,CAChD,CAAE,KAAM,GAAiB,GAAA,uBAAuB,CAChD,CAAE,WAAY,EAAA,kBAAkB,CAChC,EAAU,EAAQ,OAAS,QAK3B,CAAE,eAAc,kBAAiB,oBACrC,GAAA,oBAAoB,CAIhB,EAAqB,EACtB,GAAA,iBAAiB,GAAc,WAAY,GAAc,UAAU,EACpE,GAAc,UACd,GAAc,UACZ,GAAkB,GAAA,2BAA2B,CAC7C,CAAE,kBAAkB,GAAA,eAAe,CACnC,CAAE,oBAAkB,wBAAwB,EAAA,sBAAsB,CAClE,CAAE,mBAAiB,2BAA2B,GAAA,oBAAoB,CAElE,EAAgB,EAAA,QAAM,OAAuB,KAAK,CAClD,EAAkB,EAAA,QAAM,OAAuB,KAAK,CACpD,EAAa,EAAA,QAAM,OAAuB,KAAK,CAC/C,EAAU,EAAA,QAAM,OAAuB,KAAK,CAC5C,EAAW,EAAA,QAAM,OAAuB,KAAK,CAC7C,EAAqB,EAAA,QAAM,OAA0B,KAAK,CAC1D,CAAC,EAAiB,IAAsB,EAAA,QAAM,SAClD,IACD,CACK,CAAC,GAAmB,IAAwB,EAAA,QAAM,SAAS,EAAE,CAC7D,CAAC,GAAc,IAAmB,EAAA,QAAM,SAAS,GAAG,CACpD,CAAC,EAAW,IAAgB,EAAA,QAAM,SAAS,GAAG,CAC9C,CAAC,EAAY,IAAiB,EAAA,QAAM,SAAS,IAAI,CACjD,CAAC,EAAgB,GAAqB,EAAA,QAAM,SAAS,GAAM,CAC3D,CAAC,EAAe,GAAoB,EAAA,QAAM,SAE9C,KAAK,CACD,CAAC,EAAqB,IAC1B,EAAA,QAAM,UAA+B,CAEvC,EAAA,QAAM,cAAgB,CACpB,IAAM,EAAQ,EAAc,QACtB,EAAU,EAAgB,QAC1B,EAAQ,EAAW,QACnB,EAAS,EAAQ,QACjB,EAAU,EAAS,QAEzB,GACE,CAAC,GACD,CAAC,GACD,CAAC,GACD,CAAC,GACA,GAAW,CAAC,GACb,OAAO,eAAmB,IAE1B,OAGF,IAAM,MAAmB,CACvB,IAAM,EAAe,EAAM,uBAAuB,CAAC,MAC7C,EAAiB,EAAQ,uBAAuB,CAAC,MACjD,EAAe,EAAM,uBAAuB,CAAC,MAC7C,EAAiB,EAAQ,uBAAuB,CAAC,MAOvD,GALI,EAAe,GAAG,GAAmB,EAAa,CAClD,EAAiB,GAAG,GAAqB,EAAe,CACxD,EAAe,GAAG,GAAgB,EAAa,CAC/C,EAAiB,GAAG,GAAc,EAAe,CAEjD,EAAQ,CACV,IAAM,EAAgB,EAAO,uBAAuB,CAAC,MACjD,EAAgB,GAAG,GAAa,EAAc,GAIhD,EAAW,IAAI,mBAAqB,CACxC,GAAY,EACZ,CAYF,OAVA,EAAS,QAAQ,EAAM,CACvB,EAAS,QAAQ,EAAQ,CACzB,EAAS,QAAQ,EAAM,CACvB,EAAS,QAAQ,EAAQ,CACrB,GACF,EAAS,QAAQ,EAAO,CAG1B,GAAY,KAEC,EAAS,YAAY,EACjC,CAAC,EAAQ,CAAC,CAEb,IAAM,OAAyB,CACxB,GACL,EAA0B,OAAO,CAAE,iBAAgB,CAAC,EAGhD,OAA+B,CAC9B,GACL,GAA2B,OAAO,CAAE,iBAAgB,CAAC,EAGjD,GACJ,GAAqB,WAAa,EAA0B,UAMxD,EAAmB,EAAA,QAAM,YAC5B,GAA2B,CAC1B,IAAI,EAAY,EACV,EAAO,CACX,eAAgB,GAChB,gBAAiB,GAClB,CAWD,OATI,GAAW,GAAa,IAC1B,EAAK,eAAiB,GACtB,GAAa,EAAY,IAGvB,GAAa,IACf,EAAK,gBAAkB,IAGlB,GAET,CAAC,EAAS,EAAW,EAAW,CACjC,CAEK,EACJ,EAAkB,GAAoB,EAAW,GAAe,GAE5D,EAAqB,EAAiB,EAAc,CAKpD,GAHH,CAAC,GAAW,EAAmB,iBAChC,EAAmB,gBAGjB,EACA,EAAiB,EAAgB,GAAwB,GAAW,CAElE,EAAkB,EAAkB,EAAgB,eAAxB,GAC5B,EAAkB,EAAgB,gBAElC,GAAwB,GAAmB,IAE3C,EACmB,GAAW,CAAC,GAAmB,CAAC,EAEzD,EAAA,QAAM,cAAgB,CACf,IACH,EAAkB,GAAM,CACxB,EAAiB,KAAK,GAEvB,CAAC,EAAiB,CAAC,CAEtB,IAAM,GAAkB,GAAA,2BAA+C,CACrE,EAAkB,GAAM,CACxB,EAAiB,KAAK,EACtB,CAEI,EACJ,KAAkB,EAAA,WAAW,SAC7B,IACA,KAAoB,OAEhB,MAA2B,CAC/B,EAAiB,KAAK,CACtB,EAAkB,GAAM,EAG1B,EAAA,QAAM,oBAAsB,CAC1B,GAAI,CAAC,GAAkB,CAAC,EAAmB,QACzC,OAGF,IAAM,EAAU,EAAmB,QAE7B,MAAuB,CAC3B,IAAM,EAAO,EAAQ,uBAAuB,CAE5C,GAAuB,CACrB,SAAU,QACV,IAAK,EAAK,IAAM,EAChB,KAAM,EAAK,KACX,UAAW,oBACX,OAAQ,KACT,CAAC,EAOJ,OAJA,GAAgB,CAChB,OAAO,iBAAiB,SAAU,EAAe,CACjD,OAAO,iBAAiB,SAAU,EAAgB,GAAK,KAE1C,CACX,OAAO,oBAAoB,SAAU,EAAe,CACpD,OAAO,oBAAoB,SAAU,EAAgB,GAAK,GAE3D,CAAC,EAAe,CAAC,CAEpB,IAAM,IACJ,EAAA,EAAA,MAAC,EAAA,YAAD,CACE,IAAK,GACL,OAAO,2BACP,SAAS,MACT,UAAU,OACV,UAAU,sGALZ,CAOG,GAAW,CAAC,IACX,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yCAAf,EACE,EAAA,EAAA,KAAC,EAAA,oBAAD,CACE,OAAO,wBACP,YACE,EAAkB,GAChB,IAAY,QAAU,KAAO,QAC9B,CAEH,WAAY,YAEZ,EAAA,EAAA,KAAC,EAAA,yBAAD,CACE,MAAM,EAAA,EAAA,KAAC,EAAA,aAAD,CAAc,UAAU,oBAAsB,CAAA,CACpD,KAEM,EADJ,KAAqB,OACf,EAAA,QAAQ,YACR,EAAA,QAAQ,YAAY,CAE5B,WAAW,EAAA,EAAA,KAAC,EAAA,QAAD,CAAqB,MAAO,GAAI,OAAQ,GAAM,CAAA,CACzD,CAAA,CACkB,CAAA,CACrB,CAAC,IACA,EAAA,EAAA,KAAC,MAAD,CACE,UAAW,EAAA,GACT,kHACA,2HACA,4DACA,IAAkB,SAChB,0CACH,WAED,EAAA,EAAA,MAAC,EAAA,YAAD,CACE,OAAO,yBACP,UAAU,gDAFZ,EAIE,EAAA,EAAA,KAAC,EAAA,oBAAD,CACE,OAAO,sBACP,QAAU,GAAU,CAClB,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,GAAoB,OAAO,CAC3B,GAAoB,YAGtB,EAAA,EAAA,KAAC,EAAA,yBAAD,CACE,MAAM,EAAA,EAAA,KAAC,EAAA,aAAD,CAAc,UAAU,oBAAsB,CAAA,CACpD,KAAM,EAAE,EAAA,QAAQ,YAAY,CAC5B,CAAA,CACkB,CAAA,EACtB,EAAA,EAAA,KAAC,EAAA,oBAAD,CACE,OAAO,sBACP,QAAU,GAAU,CAClB,GAAgB,EAAM,CACtB,GAAoB,YAGtB,EAAA,EAAA,KAAC,EAAA,yBAAD,CACE,MACE,EAAA,EAAA,KAAC,GAAA,QAAD,CACE,MAAO,GACP,OAAQ,GACR,MAAM,eACN,CAAA,CAEJ,KAAM,EAAE,EAAA,QAAQ,YAAY,CAC5B,CAAA,CACkB,CAAA,CACV,GACV,CAAA,CAEJ,GAEP,CAAC,IACA,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,yCAAf,EACE,EAAA,EAAA,KAAC,EAAA,oBAAD,CACE,OAAO,wBACP,YACE,EAAkB,GAChB,IAAY,QAAU,KAAO,QAC9B,WAGH,EAAA,EAAA,KAAC,EAAA,yBAAD,CACE,MAAM,EAAA,EAAA,KAAC,EAAA,IAAD,CAAK,MAAO,GAAI,OAAQ,GAAI,YAAa,EAAG,cAAA,GAAc,CAAA,CAChE,KAAK,QACL,WAAW,EAAA,EAAA,KAAC,EAAA,QAAD,CAAqB,MAAO,GAAI,OAAQ,GAAM,CAAA,CACzD,CAAA,CACkB,CAAA,EACtB,EAAA,EAAA,KAAC,MAAD,CACE,UAAW,EAAA,GACT,kHACA,2HACA,4DACA,IAAkB,SAChB,0CACH,WAED,EAAA,EAAA,MAAC,EAAA,YAAD,CACE,OAAO,yBACP,UAAU,8DAFZ,EAIE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,oBACZ,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+DACZ,EACG,CAAA,CACH,CAAA,EACL,EAAA,EAAA,KAAC,GAAA,QAAD,CAAS,MAAM,OAAS,CAAA,EACxB,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,oBACZ,EAAA,EAAA,MAAC,EAAA,eAAD,CACE,GAAI,EACJ,QAAS,EACT,UAAW,EAAA,GACT,kIAAA,2GAED,UANH,EAQE,EAAA,EAAA,KAAC,GAAA,QAAD,CACE,MAAO,GACP,OAAQ,GACR,UAAW,EAAA,GACT,0EAAA,2GAED,CACD,cAAA,GACA,CAAA,EACF,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAwB,CAAA,CAChB,GACd,CAAA,CACO,GACV,CAAA,CACF,GAEI,GAGhB,OACE,EAAA,EAAA,MAAC,MAAD,CACE,IAAK,EACL,UAAU,kEAFZ,EAIE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,4CACb,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,2CAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,EAAY,UAAW,EAAA,GAAG,GAA+B,WACjE,EAAA,EAAA,KAAC,GAAA,kBAAD,CACY,WACV,oBAAqB,GACrB,CAAA,CACE,CAAA,CACL,IACC,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,EAAS,UAAW,EAAA,GAAG,CAAC,GAAkB,SAAS,WAC3D,EAAA,EAAA,KAAC,GAAA,kBAAD,EAAqB,CAAA,CACjB,CAAA,EAER,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,EAAU,UAAW,EAAA,GAAG,CAAC,GAAmB,SAAS,UAC5D,GAAW,GACV,EAAA,EAAA,KAAC,GAAA,eAAD,EAAkB,CAAA,EAElB,EAAA,EAAA,KAAC,GAAA,oBAAD,EAAuB,CAAA,CAErB,CAAA,CAEL,IACC,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6BAAf,EACE,EAAA,EAAA,KAAC,SAAD,CACE,IAAK,EACL,KAAK,SACL,UAAW,EAAA,GACT,8EAAA,2GAEA,oDACD,CACD,aAAW,qBACX,gBAAe,EACf,gBAAc,OACd,QAAU,GAAU,CAClB,EAAM,gBAAgB,CACtB,EAAM,iBAAiB,CACvB,EAAmB,GAAS,CAAC,EAAK,YAGpC,EAAA,EAAA,KAAC,GAAA,QAAD,CACE,MAAO,GACP,OAAQ,GACR,MAAM,eACN,CAAA,CACK,CAAA,CAER,GACC,OAAO,SAAa,KACpB,GACA,EAAA,QAAS,cACP,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,WAAsB,GAAmB,CAAA,CACrD,SAAS,KACV,CACC,GAEJ,GACF,CAAA,EACN,EAAA,EAAA,MAAC,MAAD,CACE,IAAK,EACL,UAAU,oDAFZ,CAIG,IAAyB,IACxB,EAAA,EAAA,KAAC,EAAA,QAAD,CACE,WAAY,GACZ,kBAAmB,GACT,WACC,aACX,CAAA,CAEH,KACC,EAAA,EAAA,KAAC,GAAA,eAAD,CACmB,mBACH,gBACd,SAAU,GAAY,CAAC,EACvB,CAAA,CAEA,GACF"}
1
+ {"version":3,"file":"chat-input-actions.cjs","names":[],"sources":["../../../../../src/components/features/chat/components/chat-input-actions.tsx"],"sourcesContent":["import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { Cpu } from \"lucide-react\";\nimport { AgentStatus } from \"#/components/features/controls/agent-status\";\nimport { ChangeAgentButton } from \"../change-agent-button\";\nimport { ChatInputModel } from \"./chat-input-model\";\nimport { SwitchProfileButton } from \"../switch-profile-button\";\nimport { ChatAddFileButton } from \"../chat-add-file-button\";\nimport { ChatSendButton } from \"../chat-send-button\";\nimport { NavigationLink } from \"#/components/shared/navigation-link\";\nimport SettingsGearIcon from \"#/icons/settings-gear.svg?react\";\nimport CarretRightFillIcon from \"#/icons/carret-right-fill.svg?react\";\nimport LessonPlanIcon from \"#/icons/lesson-plan.svg?react\";\nimport ThreeDotsVerticalIcon from \"#/icons/three-dots-vertical.svg?react\";\nimport { CodePillIcon } from \"#/icons/code-pill\";\nimport { useUnifiedPauseConversation } from \"#/hooks/mutation/use-unified-stop-conversation\";\nimport { useOptionalConversationId } from \"#/hooks/use-conversation-id\";\nimport { usePauseConversation } from \"#/hooks/mutation/use-pause-conversation\";\nimport { useResumeConversation } from \"#/hooks/mutation/use-resume-conversation\";\nimport { useActiveBackend } from \"#/contexts/active-backend-context\";\nimport { useActiveConversation } from \"#/hooks/query/use-active-conversation\";\nimport { useAcpModelContext } from \"#/hooks/use-acp-model-context\";\nimport { labelForAcpModel } from \"#/constants/acp-providers\";\nimport { useConversationStore } from \"#/stores/conversation-store\";\nimport { useAgentState } from \"#/hooks/use-agent-state\";\nimport { AgentState } from \"#/types/agent-state\";\nimport { useUnifiedWebSocketStatus } from \"#/hooks/use-unified-websocket-status\";\nimport { useHandlePlanClick } from \"#/hooks/use-handle-plan-click\";\nimport { I18nKey } from \"#/i18n/declaration\";\nimport { ToolsContextMenuIconText } from \"../../controls/tools-context-menu-icon-text\";\nimport { ContextMenuListItem } from \"../../context-menu/context-menu-list-item\";\nimport { ContextMenu } from \"#/ui/context-menu\";\nimport { Divider } from \"#/ui/divider\";\nimport { useClickOutsideElement } from \"#/hooks/use-click-outside-element\";\nimport { cn } from \"#/utils/utils\";\nimport { formControlTransitionClassName } from \"#/utils/form-control-classes\";\n\ninterface ChatInputActionsProps {\n disabled: boolean;\n canSubmit?: boolean;\n onAddFileClick?: () => void;\n showButton?: boolean;\n buttonClassName?: string;\n handleSubmit?: () => void;\n}\n\nexport function ChatInputActions({\n disabled,\n canSubmit = true,\n onAddFileClick = () => {},\n showButton = true,\n buttonClassName = \"\",\n handleSubmit = () => {},\n}: ChatInputActionsProps) {\n const { t } = useTranslation(\"openhands\");\n const unifiedPauseMutation = useUnifiedPauseConversation();\n const pauseConversationMutation = usePauseConversation();\n const resumeConversationMutation = useResumeConversation();\n const { conversationId } = useOptionalConversationId();\n const { data: conversation } = useActiveConversation();\n const { backend } = useActiveBackend();\n const isCloud = backend.kind === \"cloud\";\n // Shared with ChatInputModel: routes the model affordance to ChatInputModel\n // (which knows how to show the ACP model) instead of SwitchProfileButton for\n // ACP conversations — and for the home screen when Settings → Agent already\n // selects an ACP agent, since the next conversation will inherit it.\n const { isAcpContext, destinationPath, destinationLabel } =\n useAcpModelContext();\n // Mirror ChatInputModel: ACP conversations show the provider's human label\n // (e.g. \"Claude Opus 4.7\") in the overflow model submenu, not the raw\n // ``acp_model`` id. OpenHands keeps the raw model string.\n const overflowModelLabel = isAcpContext\n ? (labelForAcpModel(conversation?.acp_server, conversation?.llm_model) ??\n conversation?.llm_model)\n : conversation?.llm_model;\n // The change-agent button can never be enabled on the home page (no\n // conversation → no WebSocket → permanently disabled), so hide it there\n // entirely. It is still shown inside a conversation on cloud backends.\n const showChangeAgentButton = isCloud && Boolean(conversationId);\n const webSocketStatus = useUnifiedWebSocketStatus();\n const { curAgentState } = useAgentState();\n const { conversationMode, setConversationMode } = useConversationStore();\n const { handlePlanClick, isCreatingConversation } = useHandlePlanClick();\n\n const actionsRowRef = React.useRef<HTMLDivElement>(null);\n const rightSectionRef = React.useRef<HTMLDivElement>(null);\n const addFileRef = React.useRef<HTMLDivElement>(null);\n const codeRef = React.useRef<HTMLDivElement>(null);\n const modelRef = React.useRef<HTMLDivElement>(null);\n const overflowTriggerRef = React.useRef<HTMLButtonElement>(null);\n const [actionsRowWidth, setActionsRowWidth] = React.useState<number>(\n Number.POSITIVE_INFINITY,\n );\n const [rightSectionWidth, setRightSectionWidth] = React.useState(0);\n const [addFileWidth, setAddFileWidth] = React.useState(32);\n const [codeWidth, setCodeWidth] = React.useState(96);\n const [modelWidth, setModelWidth] = React.useState(120);\n const [isOverflowOpen, setIsOverflowOpen] = React.useState(false);\n const [activeSubmenu, setActiveSubmenu] = React.useState<\n \"agent\" | \"model\" | null\n >(null);\n const [overflowPortalStyle, setOverflowPortalStyle] =\n React.useState<React.CSSProperties>();\n\n React.useEffect(() => {\n const rowEl = actionsRowRef.current;\n const rightEl = rightSectionRef.current;\n const addEl = addFileRef.current;\n const codeEl = codeRef.current;\n const modelEl = modelRef.current;\n\n if (\n !rowEl ||\n !rightEl ||\n !addEl ||\n !modelEl ||\n (showChangeAgentButton && !codeEl) ||\n typeof ResizeObserver === \"undefined\"\n ) {\n return;\n }\n\n const syncWidths = () => {\n const nextRowWidth = rowEl.getBoundingClientRect().width;\n const nextRightWidth = rightEl.getBoundingClientRect().width;\n const nextAddWidth = addEl.getBoundingClientRect().width;\n const nextModelWidth = modelEl.getBoundingClientRect().width;\n\n if (nextRowWidth > 0) setActionsRowWidth(nextRowWidth);\n if (nextRightWidth > 0) setRightSectionWidth(nextRightWidth);\n if (nextAddWidth > 0) setAddFileWidth(nextAddWidth);\n if (nextModelWidth > 0) setModelWidth(nextModelWidth);\n\n if (codeEl) {\n const nextCodeWidth = codeEl.getBoundingClientRect().width;\n if (nextCodeWidth > 0) setCodeWidth(nextCodeWidth);\n }\n };\n\n const observer = new ResizeObserver(() => {\n syncWidths();\n });\n\n observer.observe(rowEl);\n observer.observe(rightEl);\n observer.observe(addEl);\n observer.observe(modelEl);\n if (codeEl) {\n observer.observe(codeEl);\n }\n\n syncWidths();\n\n return () => observer.disconnect();\n }, [showChangeAgentButton]);\n\n const handlePauseAgent = () => {\n if (!conversationId) return;\n pauseConversationMutation.mutate({ conversationId });\n };\n\n const handleResumeAgentClick = () => {\n if (!conversationId) return;\n resumeConversationMutation.mutate({ conversationId });\n };\n\n const isPausing =\n unifiedPauseMutation.isPending || pauseConversationMutation.isPending;\n\n const OVERFLOW_BUTTON_WIDTH = 28;\n const INLINE_GAP = 12;\n const ROOT_GAP = 8;\n\n const fitOptionalItems = React.useCallback(\n (availableWidth: number) => {\n let remaining = availableWidth;\n const next = {\n showCodeInline: false,\n showModelInline: false,\n };\n\n if (showChangeAgentButton && remaining >= codeWidth) {\n next.showCodeInline = true;\n remaining -= codeWidth + INLINE_GAP;\n }\n\n if (remaining >= modelWidth) {\n next.showModelInline = true;\n }\n\n return next;\n },\n [showChangeAgentButton, codeWidth, modelWidth],\n );\n\n const leftBaseWidth =\n actionsRowWidth - rightSectionWidth - ROOT_GAP - addFileWidth - INLINE_GAP;\n\n const fitWithoutOverflow = fitOptionalItems(leftBaseWidth);\n const allOptionalFit =\n (!showChangeAgentButton || fitWithoutOverflow.showCodeInline) &&\n fitWithoutOverflow.showModelInline;\n\n const fitWithOverflow = allOptionalFit\n ? fitWithoutOverflow\n : fitOptionalItems(leftBaseWidth - OVERFLOW_BUTTON_WIDTH - INLINE_GAP);\n\n const showCodeInline = !showChangeAgentButton\n ? false\n : fitWithOverflow.showCodeInline;\n const showModelInline = fitWithOverflow.showModelInline;\n const showAddFileInline = true;\n const showAgentStatusInline = actionsRowWidth >= 360;\n\n const hasOverflowItems =\n !showAddFileInline ||\n (showChangeAgentButton && !showCodeInline) ||\n !showModelInline;\n\n React.useEffect(() => {\n if (!hasOverflowItems) {\n setIsOverflowOpen(false);\n setActiveSubmenu(null);\n }\n }, [hasOverflowItems]);\n\n const overflowMenuRef = useClickOutsideElement<HTMLUListElement>(() => {\n setIsOverflowOpen(false);\n setActiveSubmenu(null);\n });\n\n const isAgentSwitcherDisabled =\n curAgentState === AgentState.RUNNING ||\n isCreatingConversation ||\n webSocketStatus !== \"OPEN\";\n\n const closeOverflowMenus = () => {\n setActiveSubmenu(null);\n setIsOverflowOpen(false);\n };\n\n React.useLayoutEffect(() => {\n if (!isOverflowOpen || !overflowTriggerRef.current) {\n return;\n }\n\n const trigger = overflowTriggerRef.current;\n\n const updatePosition = () => {\n const rect = trigger.getBoundingClientRect();\n const GAP = 8;\n setOverflowPortalStyle({\n position: \"fixed\",\n top: rect.top - GAP,\n left: rect.left,\n transform: \"translateY(-100%)\",\n zIndex: 9999,\n });\n };\n\n updatePosition();\n window.addEventListener(\"resize\", updatePosition);\n window.addEventListener(\"scroll\", updatePosition, true);\n\n return () => {\n window.removeEventListener(\"resize\", updatePosition);\n window.removeEventListener(\"scroll\", updatePosition, true);\n };\n }, [isOverflowOpen]);\n\n const overflowMenu = (\n <ContextMenu\n ref={overflowMenuRef}\n testId=\"chat-input-overflow-menu\"\n position=\"top\"\n alignment=\"left\"\n className=\"!static !top-auto !bottom-auto !left-auto !right-auto !mt-0 overflow-visible min-w-[200px]\"\n >\n {showChangeAgentButton && !showCodeInline && (\n <div className=\"relative group/overflow-agent\">\n <ContextMenuListItem\n testId=\"overflow-agent-button\"\n onClick={() =>\n setActiveSubmenu((current) =>\n current === \"agent\" ? null : \"agent\",\n )\n }\n isDisabled={isAgentSwitcherDisabled}\n >\n <ToolsContextMenuIconText\n icon={<CodePillIcon className=\"h-[11px] w-[11px]\" />}\n text={\n conversationMode === \"code\"\n ? t(I18nKey.COMMON$CODE)\n : t(I18nKey.COMMON$PLAN)\n }\n rightIcon={<CarretRightFillIcon width={10} height={10} />}\n />\n </ContextMenuListItem>\n {!isAgentSwitcherDisabled && (\n <div\n className={cn(\n \"absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]\",\n \"group-hover/overflow-agent:opacity-100 group-hover/overflow-agent:visible group-hover/overflow-agent:pointer-events-auto\",\n \"hover:opacity-100 hover:visible hover:pointer-events-auto\",\n activeSubmenu === \"agent\" &&\n \"opacity-100 visible pointer-events-auto\",\n )}\n >\n <ContextMenu\n testId=\"overflow-agent-submenu\"\n className=\"overflow-visible min-w-[195px] gap-0\"\n >\n <ContextMenuListItem\n testId=\"overflow-agent-code\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setConversationMode(\"code\");\n closeOverflowMenus();\n }}\n >\n <ToolsContextMenuIconText\n icon={<CodePillIcon className=\"h-[11px] w-[11px]\" />}\n text={t(I18nKey.COMMON$CODE)}\n />\n </ContextMenuListItem>\n <ContextMenuListItem\n testId=\"overflow-agent-plan\"\n onClick={(event) => {\n handlePlanClick(event);\n closeOverflowMenus();\n }}\n >\n <ToolsContextMenuIconText\n icon={\n <LessonPlanIcon\n width={16}\n height={16}\n color=\"currentColor\"\n />\n }\n text={t(I18nKey.COMMON$PLAN)}\n />\n </ContextMenuListItem>\n </ContextMenu>\n </div>\n )}\n </div>\n )}\n {!showModelInline && (\n <div className=\"relative group/overflow-model\">\n <ContextMenuListItem\n testId=\"overflow-model-button\"\n onClick={() =>\n setActiveSubmenu((current) =>\n current === \"model\" ? null : \"model\",\n )\n }\n >\n <ToolsContextMenuIconText\n icon={<Cpu width={16} height={16} strokeWidth={2} aria-hidden />}\n text=\"Model\"\n rightIcon={<CarretRightFillIcon width={10} height={10} />}\n />\n </ContextMenuListItem>\n <div\n className={cn(\n \"absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]\",\n \"group-hover/overflow-model:opacity-100 group-hover/overflow-model:visible group-hover/overflow-model:pointer-events-auto\",\n \"hover:opacity-100 hover:visible hover:pointer-events-auto\",\n activeSubmenu === \"model\" &&\n \"opacity-100 visible pointer-events-auto\",\n )}\n >\n <ContextMenu\n testId=\"overflow-model-submenu\"\n className=\"overflow-visible min-w-[220px] max-w-[320px] gap-0\"\n >\n <li className=\"text-sm\">\n <div className=\"p-2 leading-5 text-[var(--oh-foreground)] break-all\">\n {overflowModelLabel}\n </div>\n </li>\n <Divider inset=\"menu\" />\n <li className=\"text-sm\">\n <NavigationLink\n to={destinationPath}\n onClick={closeOverflowMenus}\n className={cn(\n \"group flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]\",\n formControlTransitionClassName,\n )}\n >\n <SettingsGearIcon\n width={16}\n height={16}\n className={cn(\n \"shrink-0 text-[var(--oh-muted)] group-hover:text-[var(--oh-foreground)]\",\n formControlTransitionClassName,\n )}\n aria-hidden\n />\n <span>{destinationLabel}</span>\n </NavigationLink>\n </li>\n </ContextMenu>\n </div>\n </div>\n )}\n </ContextMenu>\n );\n\n return (\n <div\n ref={actionsRowRef}\n className=\"w-full min-w-0 flex items-center justify-between gap-2\"\n >\n <div className=\"flex min-w-0 items-center gap-1\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <div ref={addFileRef} className={cn(!showAddFileInline && \"hidden\")}>\n <ChatAddFileButton\n disabled={disabled}\n handleFileIconClick={onAddFileClick}\n />\n </div>\n {showChangeAgentButton && (\n <div ref={codeRef} className={cn(!showCodeInline && \"hidden\")}>\n <ChangeAgentButton />\n </div>\n )}\n <div ref={modelRef} className={cn(!showModelInline && \"hidden\")}>\n {isCloud || isAcpContext ? (\n <ChatInputModel />\n ) : (\n <SwitchProfileButton />\n )}\n </div>\n\n {hasOverflowItems && (\n <div className=\"relative shrink-0\">\n <button\n ref={overflowTriggerRef}\n type=\"button\"\n className={cn(\n \"flex size-6 items-center justify-center rounded-full text-[var(--oh-muted)]\",\n formControlTransitionClassName,\n \"hover:bg-white/10 hover:text-white cursor-pointer\",\n )}\n aria-label=\"More input actions\"\n aria-expanded={isOverflowOpen}\n aria-haspopup=\"menu\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n setIsOverflowOpen((open) => !open);\n }}\n >\n <ThreeDotsVerticalIcon\n width={16}\n height={16}\n color=\"currentColor\"\n />\n </button>\n\n {isOverflowOpen &&\n typeof document !== \"undefined\" &&\n overflowPortalStyle &&\n ReactDOM.createPortal(\n <div style={overflowPortalStyle}>{overflowMenu}</div>,\n document.body,\n )}\n </div>\n )}\n </div>\n </div>\n <div\n ref={rightSectionRef}\n className=\"ml-auto flex shrink-0 items-center gap-2\"\n >\n {showAgentStatusInline && conversationId && (\n <AgentStatus\n handleStop={handlePauseAgent}\n handleResumeAgent={handleResumeAgentClick}\n disabled={disabled}\n isPausing={isPausing}\n />\n )}\n {showButton && (\n <ChatSendButton\n buttonClassName={buttonClassName}\n handleSubmit={handleSubmit}\n disabled={disabled || !canSubmit}\n />\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -17,70 +17,70 @@ import { CodePillIcon as u } from "../../../../icons/code-pill.js";
17
17
  import { ContextMenu as d } from "../../../../ui/context-menu.js";
18
18
  import { ContextMenuListItem as f } from "../../context-menu/context-menu-list-item.js";
19
19
  import { useClickOutsideElement as ie } from "../../../../hooks/use-click-outside-element.js";
20
- import { useHandlePlanClick as p } from "../../../../hooks/use-handle-plan-click.js";
21
- import { ChangeAgentButton as m } from "../change-agent-button.js";
22
- import { useAcpModelContext as ae } from "../../../../hooks/use-acp-model-context.js";
23
- import oe from "../../../../icons/settings-gear.js";
24
- import { NavigationLink as se } from "../../../shared/navigation-link.js";
25
- import { Divider as ce } from "../../../../ui/divider.js";
26
- import { ChatInputModel as le } from "./chat-input-model.js";
27
- import { SwitchProfileButton as ue } from "../switch-profile-button.js";
28
- import { useUnifiedPauseConversation as de } from "../../../../hooks/mutation/use-unified-stop-conversation.js";
29
- import h from "../../../../icons/carret-right-fill.js";
30
- import { ToolsContextMenuIconText as g } from "../../controls/tools-context-menu-icon-text.js";
31
- import { ChatAddFileButton as fe } from "../chat-add-file-button.js";
32
- import { ChatSendButton as pe } from "../chat-send-button.js";
33
- import me from "../../../../icons/three-dots-vertical.js";
34
- import { usePauseConversation as he } from "../../../../hooks/mutation/use-pause-conversation.js";
35
- import { useResumeConversation as ge } from "../../../../hooks/mutation/use-resume-conversation.js";
36
- import _ from "react";
37
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
38
- import _e from "react-dom";
20
+ import { useHandlePlanClick as ae } from "../../../../hooks/use-handle-plan-click.js";
21
+ import { ChangeAgentButton as oe } from "../change-agent-button.js";
22
+ import { useAcpModelContext as se } from "../../../../hooks/use-acp-model-context.js";
23
+ import ce from "../../../../icons/settings-gear.js";
24
+ import { NavigationLink as le } from "../../../shared/navigation-link.js";
25
+ import { Divider as ue } from "../../../../ui/divider.js";
26
+ import { ChatInputModel as de } from "./chat-input-model.js";
27
+ import { SwitchProfileButton as fe } from "../switch-profile-button.js";
28
+ import { useUnifiedPauseConversation as pe } from "../../../../hooks/mutation/use-unified-stop-conversation.js";
29
+ import p from "../../../../icons/carret-right-fill.js";
30
+ import { ToolsContextMenuIconText as m } from "../../controls/tools-context-menu-icon-text.js";
31
+ import { ChatAddFileButton as me } from "../chat-add-file-button.js";
32
+ import { ChatSendButton as he } from "../chat-send-button.js";
33
+ import ge from "../../../../icons/three-dots-vertical.js";
34
+ import { usePauseConversation as _e } from "../../../../hooks/mutation/use-pause-conversation.js";
35
+ import { useResumeConversation as h } from "../../../../hooks/mutation/use-resume-conversation.js";
36
+ import g from "react";
37
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
38
+ import ve from "react-dom";
39
39
  //#region src/components/features/chat/components/chat-input-actions.tsx
40
- function b({ disabled: b, canSubmit: ve = !0, onAddFileClick: ye = () => {}, showButton: be = !0, buttonClassName: xe = "", handleSubmit: Se = () => {} }) {
41
- let { t: x } = e("openhands"), Ce = de(), S = he(), we = ge(), { conversationId: C } = i(), { data: w } = ee(), { backend: T } = o(), E = T.kind === "cloud", { isAcpContext: D, destinationPath: O, destinationLabel: k } = ae(), Te = D ? c(w?.acp_server, w?.llm_model) ?? w?.llm_model : w?.llm_model, Ee = ne(), { curAgentState: De } = te(), { conversationMode: Oe, setConversationMode: ke } = a(), { handlePlanClick: Ae, isCreatingConversation: je } = p(), A = _.useRef(null), j = _.useRef(null), M = _.useRef(null), N = _.useRef(null), P = _.useRef(null), F = _.useRef(null), [I, Me] = _.useState(Infinity), [L, Ne] = _.useState(0), [Pe, Fe] = _.useState(32), [R, Ie] = _.useState(96), [z, Le] = _.useState(120), [B, V] = _.useState(!1), [H, U] = _.useState(null), [W, Re] = _.useState();
42
- _.useEffect(() => {
40
+ function y({ disabled: y, canSubmit: ye = !0, onAddFileClick: be = () => {}, showButton: xe = !0, buttonClassName: Se = "", handleSubmit: Ce = () => {} }) {
41
+ let { t: b } = e("openhands"), we = pe(), x = _e(), Te = h(), { conversationId: S } = i(), { data: C } = ee(), { backend: w } = o(), T = w.kind === "cloud", { isAcpContext: E, destinationPath: D, destinationLabel: O } = se(), Ee = E ? c(C?.acp_server, C?.llm_model) ?? C?.llm_model : C?.llm_model, k = T && !!S, De = ne(), { curAgentState: Oe } = te(), { conversationMode: ke, setConversationMode: Ae } = a(), { handlePlanClick: je, isCreatingConversation: Me } = ae(), A = g.useRef(null), j = g.useRef(null), M = g.useRef(null), N = g.useRef(null), P = g.useRef(null), F = g.useRef(null), [I, Ne] = g.useState(Infinity), [Pe, Fe] = g.useState(0), [Ie, Le] = g.useState(32), [L, Re] = g.useState(96), [R, ze] = g.useState(120), [z, B] = g.useState(!1), [V, H] = g.useState(null), [U, Be] = g.useState();
42
+ g.useEffect(() => {
43
43
  let e = A.current, t = j.current, n = M.current, r = N.current, i = P.current;
44
- if (!e || !t || !n || !i || E && !r || typeof ResizeObserver > "u") return;
44
+ if (!e || !t || !n || !i || k && !r || typeof ResizeObserver > "u") return;
45
45
  let a = () => {
46
46
  let a = e.getBoundingClientRect().width, o = t.getBoundingClientRect().width, s = n.getBoundingClientRect().width, c = i.getBoundingClientRect().width;
47
- if (a > 0 && Me(a), o > 0 && Ne(o), s > 0 && Fe(s), c > 0 && Le(c), r) {
47
+ if (a > 0 && Ne(a), o > 0 && Fe(o), s > 0 && Le(s), c > 0 && ze(c), r) {
48
48
  let e = r.getBoundingClientRect().width;
49
- e > 0 && Ie(e);
49
+ e > 0 && Re(e);
50
50
  }
51
51
  }, o = new ResizeObserver(() => {
52
52
  a();
53
53
  });
54
54
  return o.observe(e), o.observe(t), o.observe(n), o.observe(i), r && o.observe(r), a(), () => o.disconnect();
55
- }, [E]);
56
- let ze = () => {
57
- C && S.mutate({ conversationId: C });
58
- }, Be = () => {
59
- C && we.mutate({ conversationId: C });
60
- }, Ve = Ce.isPending || S.isPending, G = _.useCallback((e) => {
55
+ }, [k]);
56
+ let Ve = () => {
57
+ S && x.mutate({ conversationId: S });
58
+ }, He = () => {
59
+ S && Te.mutate({ conversationId: S });
60
+ }, Ue = we.isPending || x.isPending, W = g.useCallback((e) => {
61
61
  let t = e, n = {
62
62
  showCodeInline: !1,
63
63
  showModelInline: !1
64
64
  };
65
- return E && t >= R && (n.showCodeInline = !0, t -= R + 12), t >= z && (n.showModelInline = !0), n;
65
+ return k && t >= L && (n.showCodeInline = !0, t -= L + 12), t >= R && (n.showModelInline = !0), n;
66
66
  }, [
67
- E,
68
- R,
69
- z
70
- ]), K = I - L - 8 - Pe - 12, q = G(K), J = (!E || q.showCodeInline) && q.showModelInline ? q : G(K - 28 - 12), Y = E ? J.showCodeInline : !1, X = J.showModelInline, He = I >= 360, Z = E && !Y || !X;
71
- _.useEffect(() => {
72
- Z || (V(!1), U(null));
67
+ k,
68
+ L,
69
+ R
70
+ ]), G = I - Pe - 8 - Ie - 12, K = W(G), q = (!k || K.showCodeInline) && K.showModelInline ? K : W(G - 28 - 12), J = k ? q.showCodeInline : !1, Y = q.showModelInline, X = I >= 360, Z = k && !J || !Y;
71
+ g.useEffect(() => {
72
+ Z || (B(!1), H(null));
73
73
  }, [Z]);
74
- let Ue = ie(() => {
75
- V(!1), U(null);
76
- }), Q = De === n.RUNNING || je || Ee !== "OPEN", $ = () => {
77
- U(null), V(!1);
74
+ let We = ie(() => {
75
+ B(!1), H(null);
76
+ }), Q = Oe === n.RUNNING || Me || De !== "OPEN", $ = () => {
77
+ H(null), B(!1);
78
78
  };
79
- _.useLayoutEffect(() => {
80
- if (!B || !F.current) return;
79
+ g.useLayoutEffect(() => {
80
+ if (!z || !F.current) return;
81
81
  let e = F.current, t = () => {
82
82
  let t = e.getBoundingClientRect();
83
- Re({
83
+ Be({
84
84
  position: "fixed",
85
85
  top: t.top - 8,
86
86
  left: t.left,
@@ -91,101 +91,101 @@ function b({ disabled: b, canSubmit: ve = !0, onAddFileClick: ye = () => {}, sho
91
91
  return t(), window.addEventListener("resize", t), window.addEventListener("scroll", t, !0), () => {
92
92
  window.removeEventListener("resize", t), window.removeEventListener("scroll", t, !0);
93
93
  };
94
- }, [B]);
95
- let We = /* @__PURE__ */ y(d, {
96
- ref: Ue,
94
+ }, [z]);
95
+ let Ge = /* @__PURE__ */ v(d, {
96
+ ref: We,
97
97
  testId: "chat-input-overflow-menu",
98
98
  position: "top",
99
99
  alignment: "left",
100
100
  className: "!static !top-auto !bottom-auto !left-auto !right-auto !mt-0 overflow-visible min-w-[200px]",
101
- children: [E && !Y && /* @__PURE__ */ y("div", {
101
+ children: [k && !J && /* @__PURE__ */ v("div", {
102
102
  className: "relative group/overflow-agent",
103
- children: [/* @__PURE__ */ v(f, {
103
+ children: [/* @__PURE__ */ _(f, {
104
104
  testId: "overflow-agent-button",
105
- onClick: () => U((e) => e === "agent" ? null : "agent"),
105
+ onClick: () => H((e) => e === "agent" ? null : "agent"),
106
106
  isDisabled: Q,
107
- children: /* @__PURE__ */ v(g, {
108
- icon: /* @__PURE__ */ v(u, { className: "h-[11px] w-[11px]" }),
109
- text: x(Oe === "code" ? t.COMMON$CODE : t.COMMON$PLAN),
110
- rightIcon: /* @__PURE__ */ v(h, {
107
+ children: /* @__PURE__ */ _(m, {
108
+ icon: /* @__PURE__ */ _(u, { className: "h-[11px] w-[11px]" }),
109
+ text: b(ke === "code" ? t.COMMON$CODE : t.COMMON$PLAN),
110
+ rightIcon: /* @__PURE__ */ _(p, {
111
111
  width: 10,
112
112
  height: 10
113
113
  })
114
114
  })
115
- }), !Q && /* @__PURE__ */ v("div", {
116
- className: r("absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]", "group-hover/overflow-agent:opacity-100 group-hover/overflow-agent:visible group-hover/overflow-agent:pointer-events-auto", "hover:opacity-100 hover:visible hover:pointer-events-auto", H === "agent" && "opacity-100 visible pointer-events-auto"),
117
- children: /* @__PURE__ */ y(d, {
115
+ }), !Q && /* @__PURE__ */ _("div", {
116
+ className: r("absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]", "group-hover/overflow-agent:opacity-100 group-hover/overflow-agent:visible group-hover/overflow-agent:pointer-events-auto", "hover:opacity-100 hover:visible hover:pointer-events-auto", V === "agent" && "opacity-100 visible pointer-events-auto"),
117
+ children: /* @__PURE__ */ v(d, {
118
118
  testId: "overflow-agent-submenu",
119
119
  className: "overflow-visible min-w-[195px] gap-0",
120
- children: [/* @__PURE__ */ v(f, {
120
+ children: [/* @__PURE__ */ _(f, {
121
121
  testId: "overflow-agent-code",
122
122
  onClick: (e) => {
123
- e.preventDefault(), e.stopPropagation(), ke("code"), $();
123
+ e.preventDefault(), e.stopPropagation(), Ae("code"), $();
124
124
  },
125
- children: /* @__PURE__ */ v(g, {
126
- icon: /* @__PURE__ */ v(u, { className: "h-[11px] w-[11px]" }),
127
- text: x(t.COMMON$CODE)
125
+ children: /* @__PURE__ */ _(m, {
126
+ icon: /* @__PURE__ */ _(u, { className: "h-[11px] w-[11px]" }),
127
+ text: b(t.COMMON$CODE)
128
128
  })
129
- }), /* @__PURE__ */ v(f, {
129
+ }), /* @__PURE__ */ _(f, {
130
130
  testId: "overflow-agent-plan",
131
131
  onClick: (e) => {
132
- Ae(e), $();
132
+ je(e), $();
133
133
  },
134
- children: /* @__PURE__ */ v(g, {
135
- icon: /* @__PURE__ */ v(l, {
134
+ children: /* @__PURE__ */ _(m, {
135
+ icon: /* @__PURE__ */ _(l, {
136
136
  width: 16,
137
137
  height: 16,
138
138
  color: "currentColor"
139
139
  }),
140
- text: x(t.COMMON$PLAN)
140
+ text: b(t.COMMON$PLAN)
141
141
  })
142
142
  })]
143
143
  })
144
144
  })]
145
- }), !X && /* @__PURE__ */ y("div", {
145
+ }), !Y && /* @__PURE__ */ v("div", {
146
146
  className: "relative group/overflow-model",
147
- children: [/* @__PURE__ */ v(f, {
147
+ children: [/* @__PURE__ */ _(f, {
148
148
  testId: "overflow-model-button",
149
- onClick: () => U((e) => e === "model" ? null : "model"),
150
- children: /* @__PURE__ */ v(g, {
151
- icon: /* @__PURE__ */ v(s, {
149
+ onClick: () => H((e) => e === "model" ? null : "model"),
150
+ children: /* @__PURE__ */ _(m, {
151
+ icon: /* @__PURE__ */ _(s, {
152
152
  width: 16,
153
153
  height: 16,
154
154
  strokeWidth: 2,
155
155
  "aria-hidden": !0
156
156
  }),
157
157
  text: "Model",
158
- rightIcon: /* @__PURE__ */ v(h, {
158
+ rightIcon: /* @__PURE__ */ _(p, {
159
159
  width: 10,
160
160
  height: 10
161
161
  })
162
162
  })
163
- }), /* @__PURE__ */ v("div", {
164
- className: r("absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]", "group-hover/overflow-model:opacity-100 group-hover/overflow-model:visible group-hover/overflow-model:pointer-events-auto", "hover:opacity-100 hover:visible hover:pointer-events-auto", H === "model" && "opacity-100 visible pointer-events-auto"),
165
- children: /* @__PURE__ */ y(d, {
163
+ }), /* @__PURE__ */ _("div", {
164
+ className: r("absolute left-full top-[-4px] z-60 opacity-0 invisible pointer-events-none transition-all duration-200 ml-[1px]", "group-hover/overflow-model:opacity-100 group-hover/overflow-model:visible group-hover/overflow-model:pointer-events-auto", "hover:opacity-100 hover:visible hover:pointer-events-auto", V === "model" && "opacity-100 visible pointer-events-auto"),
165
+ children: /* @__PURE__ */ v(d, {
166
166
  testId: "overflow-model-submenu",
167
167
  className: "overflow-visible min-w-[220px] max-w-[320px] gap-0",
168
168
  children: [
169
- /* @__PURE__ */ v("li", {
169
+ /* @__PURE__ */ _("li", {
170
170
  className: "text-sm",
171
- children: /* @__PURE__ */ v("div", {
171
+ children: /* @__PURE__ */ _("div", {
172
172
  className: "p-2 leading-5 text-[var(--oh-foreground)] break-all",
173
- children: Te
173
+ children: Ee
174
174
  })
175
175
  }),
176
- /* @__PURE__ */ v(ce, { inset: "menu" }),
177
- /* @__PURE__ */ v("li", {
176
+ /* @__PURE__ */ _(ue, { inset: "menu" }),
177
+ /* @__PURE__ */ _("li", {
178
178
  className: "text-sm",
179
- children: /* @__PURE__ */ y(se, {
180
- to: O,
179
+ children: /* @__PURE__ */ v(le, {
180
+ to: D,
181
181
  onClick: $,
182
182
  className: r("group flex h-[30px] items-center gap-2 rounded p-2 leading-5 text-[var(--oh-foreground)] hover:bg-[var(--oh-interactive-hover)]", "transition-[background-color,border-color,box-shadow,opacity] duration-150 motion-reduce:transition-none"),
183
- children: [/* @__PURE__ */ v(oe, {
183
+ children: [/* @__PURE__ */ _(ce, {
184
184
  width: 16,
185
185
  height: 16,
186
186
  className: r("shrink-0 text-[var(--oh-muted)] group-hover:text-[var(--oh-foreground)]", "transition-[background-color,border-color,box-shadow,opacity] duration-150 motion-reduce:transition-none"),
187
187
  "aria-hidden": !0
188
- }), /* @__PURE__ */ v("span", { children: k })]
188
+ }), /* @__PURE__ */ _("span", { children: O })]
189
189
  })
190
190
  })
191
191
  ]
@@ -193,73 +193,73 @@ function b({ disabled: b, canSubmit: ve = !0, onAddFileClick: ye = () => {}, sho
193
193
  })]
194
194
  })]
195
195
  });
196
- return /* @__PURE__ */ y("div", {
196
+ return /* @__PURE__ */ v("div", {
197
197
  ref: A,
198
198
  className: "w-full min-w-0 flex items-center justify-between gap-2",
199
- children: [/* @__PURE__ */ v("div", {
199
+ children: [/* @__PURE__ */ _("div", {
200
200
  className: "flex min-w-0 items-center gap-1",
201
- children: /* @__PURE__ */ y("div", {
201
+ children: /* @__PURE__ */ v("div", {
202
202
  className: "flex min-w-0 items-center gap-3",
203
203
  children: [
204
- /* @__PURE__ */ v("div", {
204
+ /* @__PURE__ */ _("div", {
205
205
  ref: M,
206
206
  className: r(!1),
207
- children: /* @__PURE__ */ v(fe, {
208
- disabled: b,
209
- handleFileIconClick: ye
207
+ children: /* @__PURE__ */ _(me, {
208
+ disabled: y,
209
+ handleFileIconClick: be
210
210
  })
211
211
  }),
212
- E && /* @__PURE__ */ v("div", {
212
+ k && /* @__PURE__ */ _("div", {
213
213
  ref: N,
214
- className: r(!Y && "hidden"),
215
- children: /* @__PURE__ */ v(m, {})
214
+ className: r(!J && "hidden"),
215
+ children: /* @__PURE__ */ _(oe, {})
216
216
  }),
217
- /* @__PURE__ */ v("div", {
217
+ /* @__PURE__ */ _("div", {
218
218
  ref: P,
219
- className: r(!X && "hidden"),
220
- children: v(E || D ? le : ue, {})
219
+ className: r(!Y && "hidden"),
220
+ children: _(T || E ? de : fe, {})
221
221
  }),
222
- Z && /* @__PURE__ */ y("div", {
222
+ Z && /* @__PURE__ */ v("div", {
223
223
  className: "relative shrink-0",
224
- children: [/* @__PURE__ */ v("button", {
224
+ children: [/* @__PURE__ */ _("button", {
225
225
  ref: F,
226
226
  type: "button",
227
227
  className: r("flex size-6 items-center justify-center rounded-full text-[var(--oh-muted)]", "transition-[background-color,border-color,box-shadow,opacity] duration-150 motion-reduce:transition-none", "hover:bg-white/10 hover:text-white cursor-pointer"),
228
228
  "aria-label": "More input actions",
229
- "aria-expanded": B,
229
+ "aria-expanded": z,
230
230
  "aria-haspopup": "menu",
231
231
  onClick: (e) => {
232
- e.preventDefault(), e.stopPropagation(), V((e) => !e);
232
+ e.preventDefault(), e.stopPropagation(), B((e) => !e);
233
233
  },
234
- children: /* @__PURE__ */ v(me, {
234
+ children: /* @__PURE__ */ _(ge, {
235
235
  width: 16,
236
236
  height: 16,
237
237
  color: "currentColor"
238
238
  })
239
- }), B && typeof document < "u" && W && _e.createPortal(/* @__PURE__ */ v("div", {
240
- style: W,
241
- children: We
239
+ }), z && typeof document < "u" && U && ve.createPortal(/* @__PURE__ */ _("div", {
240
+ style: U,
241
+ children: Ge
242
242
  }), document.body)]
243
243
  })
244
244
  ]
245
245
  })
246
- }), /* @__PURE__ */ y("div", {
246
+ }), /* @__PURE__ */ v("div", {
247
247
  ref: j,
248
248
  className: "ml-auto flex shrink-0 items-center gap-2",
249
- children: [He && C && /* @__PURE__ */ v(re, {
250
- handleStop: ze,
251
- handleResumeAgent: Be,
252
- disabled: b,
253
- isPausing: Ve
254
- }), be && /* @__PURE__ */ v(pe, {
255
- buttonClassName: xe,
256
- handleSubmit: Se,
257
- disabled: b || !ve
249
+ children: [X && S && /* @__PURE__ */ _(re, {
250
+ handleStop: Ve,
251
+ handleResumeAgent: He,
252
+ disabled: y,
253
+ isPausing: Ue
254
+ }), xe && /* @__PURE__ */ _(he, {
255
+ buttonClassName: Se,
256
+ handleSubmit: Ce,
257
+ disabled: y || !ye
258
258
  })]
259
259
  })]
260
260
  });
261
261
  }
262
262
  //#endregion
263
- export { b as ChatInputActions };
263
+ export { y as ChatInputActions };
264
264
 
265
265
  //# sourceMappingURL=chat-input-actions.js.map