@openhands/agent-canvas 1.0.0-alpha.6 → 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.
- package/README.md +41 -7
- package/bin/agent-canvas.mjs +9 -2
- package/build/assets/automation-detail-D7GEU0vR.js +1 -0
- package/build/assets/automations-list-CkVNsgzm.js +1 -0
- package/build/assets/conversation-COZAKz_K.js +1 -0
- package/build/assets/{conversation-D8scXOe7.js → conversation-DWcvnmds.js} +3 -1
- package/build/assets/conversation-panel-CZDStT0b.js +1 -0
- package/build/assets/conversation-websocket-context-DulnrIHh.js +3 -0
- package/build/assets/edit-automation-modal-C3bFxS2f.js +1 -0
- package/build/assets/git-control-bar-branch-button-Bm6rzSpo.js +27 -0
- package/build/assets/{home-D9fJfhQA.js → home-DR11ejqB.js} +1 -1
- package/build/assets/{manifest-6400820c.js → manifest-f041e61a.js} +1 -1
- package/build/assets/{messages-BfaEAG2q.js → messages-v-q35ObG.js} +1 -1
- package/build/assets/{root-6AdVEJBT.js → root-D2PVd51i.js} +1 -1
- package/build/assets/root-layout-B4QioBS6.js +2 -0
- package/build/assets/{shared-conversation-BfZNCsvo.js → shared-conversation-DQlzwdpo.js} +1 -1
- package/build/index.html +3 -3
- 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 +95 -95
- package/dist/components/features/backends/backend-selector.js.map +1 -1
- package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
- package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
- package/dist/components/features/chat/components/chat-input-actions.js +118 -118
- package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
- package/dist/components/features/chat/components/slash-command-menu.cjs +1 -1
- package/dist/components/features/chat/components/slash-command-menu.cjs.map +1 -1
- package/dist/components/features/chat/components/slash-command-menu.js +1 -1
- package/dist/components/features/chat/components/slash-command-menu.js.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.cjs.map +1 -1
- package/dist/components/features/sidebar/sidebar-rail-body.d.ts +1 -2
- package/dist/components/features/sidebar/sidebar-rail-body.js +104 -104
- 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 +82 -83
- package/dist/components/features/sidebar/sidebar.js.map +1 -1
- package/dist/contexts/conversation-websocket-context.cjs +3 -3
- package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
- package/dist/contexts/conversation-websocket-context.js +36 -36
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/hooks/query/use-local-git-info.cjs +3 -1
- package/dist/hooks/query/use-local-git-info.cjs.map +1 -1
- package/dist/hooks/query/use-local-git-info.d.ts +2 -2
- package/dist/hooks/query/use-local-git-info.js +27 -24
- package/dist/hooks/query/use-local-git-info.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/dist/stores/error-message-store.cjs +1 -1
- package/dist/stores/error-message-store.cjs.map +1 -1
- package/dist/stores/error-message-store.d.ts +10 -1
- package/dist/stores/error-message-store.js +16 -3
- package/dist/stores/error-message-store.js.map +1 -1
- package/package.json +1 -1
- package/scripts/dev-static.mjs +6 -0
- package/scripts/dev-with-automation.mjs +6 -0
- package/scripts/static-server.mjs +85 -4
- package/build/assets/automation-detail-CQrtk33s.js +0 -1
- package/build/assets/automations-list-COmogz0S.js +0 -1
- package/build/assets/conversation-CeGMBOyB.js +0 -1
- package/build/assets/conversation-panel-DMz46ji-.js +0 -1
- package/build/assets/conversation-websocket-context-B0Gd3yiT.js +0 -3
- package/build/assets/edit-automation-modal-DnTHJrf1.js +0 -1
- package/build/assets/git-control-bar-branch-button-DhpPgadK.js +0 -27
- 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":"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"}
|
|
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
|
|
21
|
-
import { ChangeAgentButton as
|
|
22
|
-
import { useAcpModelContext as
|
|
23
|
-
import
|
|
24
|
-
import { NavigationLink as
|
|
25
|
-
import { Divider as
|
|
26
|
-
import { ChatInputModel as
|
|
27
|
-
import { SwitchProfileButton as
|
|
28
|
-
import { useUnifiedPauseConversation as
|
|
29
|
-
import
|
|
30
|
-
import { ToolsContextMenuIconText as
|
|
31
|
-
import { ChatAddFileButton as
|
|
32
|
-
import { ChatSendButton as
|
|
33
|
-
import
|
|
34
|
-
import { usePauseConversation as
|
|
35
|
-
import { useResumeConversation as
|
|
36
|
-
import
|
|
37
|
-
import { jsx as
|
|
38
|
-
import
|
|
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
|
|
41
|
-
let { t:
|
|
42
|
-
|
|
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 ||
|
|
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 &&
|
|
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 &&
|
|
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
|
-
}, [
|
|
56
|
-
let
|
|
57
|
-
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
},
|
|
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
|
|
65
|
+
return k && t >= L && (n.showCodeInline = !0, t -= L + 12), t >= R && (n.showModelInline = !0), n;
|
|
66
66
|
}, [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
]),
|
|
71
|
-
|
|
72
|
-
Z || (
|
|
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
|
|
75
|
-
|
|
76
|
-
}), Q =
|
|
77
|
-
|
|
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
|
-
|
|
80
|
-
if (!
|
|
79
|
+
g.useLayoutEffect(() => {
|
|
80
|
+
if (!z || !F.current) return;
|
|
81
81
|
let e = F.current, t = () => {
|
|
82
82
|
let t = e.getBoundingClientRect();
|
|
83
|
-
|
|
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
|
-
}, [
|
|
95
|
-
let
|
|
96
|
-
ref:
|
|
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: [
|
|
101
|
+
children: [k && !J && /* @__PURE__ */ v("div", {
|
|
102
102
|
className: "relative group/overflow-agent",
|
|
103
|
-
children: [/* @__PURE__ */
|
|
103
|
+
children: [/* @__PURE__ */ _(f, {
|
|
104
104
|
testId: "overflow-agent-button",
|
|
105
|
-
onClick: () =>
|
|
105
|
+
onClick: () => H((e) => e === "agent" ? null : "agent"),
|
|
106
106
|
isDisabled: Q,
|
|
107
|
-
children: /* @__PURE__ */
|
|
108
|
-
icon: /* @__PURE__ */
|
|
109
|
-
text:
|
|
110
|
-
rightIcon: /* @__PURE__ */
|
|
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__ */
|
|
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",
|
|
117
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
120
|
+
children: [/* @__PURE__ */ _(f, {
|
|
121
121
|
testId: "overflow-agent-code",
|
|
122
122
|
onClick: (e) => {
|
|
123
|
-
e.preventDefault(), e.stopPropagation(),
|
|
123
|
+
e.preventDefault(), e.stopPropagation(), Ae("code"), $();
|
|
124
124
|
},
|
|
125
|
-
children: /* @__PURE__ */
|
|
126
|
-
icon: /* @__PURE__ */
|
|
127
|
-
text:
|
|
125
|
+
children: /* @__PURE__ */ _(m, {
|
|
126
|
+
icon: /* @__PURE__ */ _(u, { className: "h-[11px] w-[11px]" }),
|
|
127
|
+
text: b(t.COMMON$CODE)
|
|
128
128
|
})
|
|
129
|
-
}), /* @__PURE__ */
|
|
129
|
+
}), /* @__PURE__ */ _(f, {
|
|
130
130
|
testId: "overflow-agent-plan",
|
|
131
131
|
onClick: (e) => {
|
|
132
|
-
|
|
132
|
+
je(e), $();
|
|
133
133
|
},
|
|
134
|
-
children: /* @__PURE__ */
|
|
135
|
-
icon: /* @__PURE__ */
|
|
134
|
+
children: /* @__PURE__ */ _(m, {
|
|
135
|
+
icon: /* @__PURE__ */ _(l, {
|
|
136
136
|
width: 16,
|
|
137
137
|
height: 16,
|
|
138
138
|
color: "currentColor"
|
|
139
139
|
}),
|
|
140
|
-
text:
|
|
140
|
+
text: b(t.COMMON$PLAN)
|
|
141
141
|
})
|
|
142
142
|
})]
|
|
143
143
|
})
|
|
144
144
|
})]
|
|
145
|
-
}), !
|
|
145
|
+
}), !Y && /* @__PURE__ */ v("div", {
|
|
146
146
|
className: "relative group/overflow-model",
|
|
147
|
-
children: [/* @__PURE__ */
|
|
147
|
+
children: [/* @__PURE__ */ _(f, {
|
|
148
148
|
testId: "overflow-model-button",
|
|
149
|
-
onClick: () =>
|
|
150
|
-
children: /* @__PURE__ */
|
|
151
|
-
icon: /* @__PURE__ */
|
|
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__ */
|
|
158
|
+
rightIcon: /* @__PURE__ */ _(p, {
|
|
159
159
|
width: 10,
|
|
160
160
|
height: 10
|
|
161
161
|
})
|
|
162
162
|
})
|
|
163
|
-
}), /* @__PURE__ */
|
|
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",
|
|
165
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
169
|
+
/* @__PURE__ */ _("li", {
|
|
170
170
|
className: "text-sm",
|
|
171
|
-
children: /* @__PURE__ */
|
|
171
|
+
children: /* @__PURE__ */ _("div", {
|
|
172
172
|
className: "p-2 leading-5 text-[var(--oh-foreground)] break-all",
|
|
173
|
-
children:
|
|
173
|
+
children: Ee
|
|
174
174
|
})
|
|
175
175
|
}),
|
|
176
|
-
/* @__PURE__ */
|
|
177
|
-
/* @__PURE__ */
|
|
176
|
+
/* @__PURE__ */ _(ue, { inset: "menu" }),
|
|
177
|
+
/* @__PURE__ */ _("li", {
|
|
178
178
|
className: "text-sm",
|
|
179
|
-
children: /* @__PURE__ */
|
|
180
|
-
to:
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
199
|
+
children: [/* @__PURE__ */ _("div", {
|
|
200
200
|
className: "flex min-w-0 items-center gap-1",
|
|
201
|
-
children: /* @__PURE__ */
|
|
201
|
+
children: /* @__PURE__ */ v("div", {
|
|
202
202
|
className: "flex min-w-0 items-center gap-3",
|
|
203
203
|
children: [
|
|
204
|
-
/* @__PURE__ */
|
|
204
|
+
/* @__PURE__ */ _("div", {
|
|
205
205
|
ref: M,
|
|
206
206
|
className: r(!1),
|
|
207
|
-
children: /* @__PURE__ */
|
|
208
|
-
disabled:
|
|
209
|
-
handleFileIconClick:
|
|
207
|
+
children: /* @__PURE__ */ _(me, {
|
|
208
|
+
disabled: y,
|
|
209
|
+
handleFileIconClick: be
|
|
210
210
|
})
|
|
211
211
|
}),
|
|
212
|
-
|
|
212
|
+
k && /* @__PURE__ */ _("div", {
|
|
213
213
|
ref: N,
|
|
214
|
-
className: r(!
|
|
215
|
-
children: /* @__PURE__ */
|
|
214
|
+
className: r(!J && "hidden"),
|
|
215
|
+
children: /* @__PURE__ */ _(oe, {})
|
|
216
216
|
}),
|
|
217
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ _("div", {
|
|
218
218
|
ref: P,
|
|
219
|
-
className: r(!
|
|
220
|
-
children:
|
|
219
|
+
className: r(!Y && "hidden"),
|
|
220
|
+
children: _(T || E ? de : fe, {})
|
|
221
221
|
}),
|
|
222
|
-
Z && /* @__PURE__ */
|
|
222
|
+
Z && /* @__PURE__ */ v("div", {
|
|
223
223
|
className: "relative shrink-0",
|
|
224
|
-
children: [/* @__PURE__ */
|
|
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":
|
|
229
|
+
"aria-expanded": z,
|
|
230
230
|
"aria-haspopup": "menu",
|
|
231
231
|
onClick: (e) => {
|
|
232
|
-
e.preventDefault(), e.stopPropagation(),
|
|
232
|
+
e.preventDefault(), e.stopPropagation(), B((e) => !e);
|
|
233
233
|
},
|
|
234
|
-
children: /* @__PURE__ */
|
|
234
|
+
children: /* @__PURE__ */ _(ge, {
|
|
235
235
|
width: 16,
|
|
236
236
|
height: 16,
|
|
237
237
|
color: "currentColor"
|
|
238
238
|
})
|
|
239
|
-
}),
|
|
240
|
-
style:
|
|
241
|
-
children:
|
|
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__ */
|
|
246
|
+
}), /* @__PURE__ */ v("div", {
|
|
247
247
|
ref: j,
|
|
248
248
|
className: "ml-auto flex shrink-0 items-center gap-2",
|
|
249
|
-
children: [
|
|
250
|
-
handleStop:
|
|
251
|
-
handleResumeAgent:
|
|
252
|
-
disabled:
|
|
253
|
-
isPausing:
|
|
254
|
-
}),
|
|
255
|
-
buttonClassName:
|
|
256
|
-
handleSubmit:
|
|
257
|
-
disabled:
|
|
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 {
|
|
263
|
+
export { y as ChatInputActions };
|
|
264
264
|
|
|
265
265
|
//# sourceMappingURL=chat-input-actions.js.map
|