diff --git a/agentex-ui/components/primary-content/prompt-input.tsx b/agentex-ui/components/primary-content/prompt-input.tsx index 45f0f9db..81738fd8 100644 --- a/agentex-ui/components/primary-content/prompt-input.tsx +++ b/agentex-ui/components/primary-content/prompt-input.tsx @@ -59,7 +59,7 @@ export function PromptInput({ prompt, setPrompt }: PromptInputProps) { const sendMessageMutation = useSendMessage({ agentexClient }); const { data: task } = useTask({ agentexClient, taskId: taskID ?? '' }); - const textInputRef = useRef(null); + const textInputRef = useRef(null); const codeMirrorViewRef = useRef(null); const isTaskTerminal = useMemo(() => { @@ -200,7 +200,7 @@ export function PromptInput({ prompt, setPrompt }: PromptInputProps) { )}
{isSendingJSON ? ( void; - inputRef: React.RefObject; + inputRef: React.RefObject; }) => { + // Auto-resize the textarea height to fit content up to the max, then scroll + // internally. Reset to 'auto' first so the height can shrink when the user + // deletes lines, not just grow. + useEffect(() => { + const el = inputRef.current; + if (!el) return; + el.style.height = 'auto'; + const next = Math.min(el.scrollHeight, TEXT_INPUT_MAX_HEIGHT_PX); + el.style.height = `${next}px`; + el.style.overflowY = + el.scrollHeight > TEXT_INPUT_MAX_HEIGHT_PX ? 'auto' : 'hidden'; + }, [prompt, inputRef]); + return ( - ) => + onChange={(e: React.ChangeEvent) => setPrompt(e.target.value) } - onKeyDown={(e: React.KeyboardEvent) => { - if (e.key === 'Enter' && !isDisabled && prompt.trim()) { - handleSendPrompt(); + onKeyDown={(e: React.KeyboardEvent) => { + // Enter sends; Shift+Enter inserts a newline. Ignore Enter while an + // IME composition is active so it can commit the candidate normally. + if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { + e.preventDefault(); + if (!isDisabled && prompt.trim()) { + handleSendPrompt(); + } } }} disabled={isDisabled} @@ -286,10 +309,11 @@ const TextInput = ({ ? 'Select an agent to start' : 'Enter your prompt' } - className="mr-2 flex-1 outline-none focus:ring-0 focus:outline-none" + className="mr-2 flex-1 resize-none py-2 leading-6 outline-none focus:ring-0 focus:outline-none" style={{ backgroundColor: 'inherit', cursor: 'inherit', + maxHeight: `${TEXT_INPUT_MAX_HEIGHT_PX}px`, }} /> );