diff --git a/src/workspaces/officerdev/src/apps/Chat/EmbeddableChat/useEmbeddableChat.ts b/src/workspaces/officerdev/src/apps/Chat/EmbeddableChat/useEmbeddableChat.ts index a081cbcb..0887039a 100644 --- a/src/workspaces/officerdev/src/apps/Chat/EmbeddableChat/useEmbeddableChat.ts +++ b/src/workspaces/officerdev/src/apps/Chat/EmbeddableChat/useEmbeddableChat.ts @@ -80,9 +80,6 @@ export function useEmbeddableChat(params: UseEmbeddableChatParams, onMessageComp // the list growing under an animation or a row measuring taller than its estimate, and reading it as // intent is what used to switch auto-scroll off mid-turn and leave it off. const gestureAtRef = useRef(0); - // The prompt currently in flight, kept verbatim so a stop can put it back in the composer. - const lastSentRef = useRef(''); - // Latest values for the (once-attached) scroll listener, without re-subscribing on every page load. const loadOlderRef = useRef(loadOlder); loadOlderRef.current = loadOlder; @@ -125,26 +122,25 @@ export function useEmbeddableChat(params: UseEmbeddableChatParams, onMessageComp ); attachmentManager.clearAttachments(); - lastSentRef.current = input; // verbatim, not the trimmed prompt — this is what comes back on a stop setInput(''); userScrolledRef.current = false; if (textareaRef.current) textareaRef.current.style.height = 'auto'; }; /** - * Stop, and hand the prompt back. Interrupting almost always means "not like that" — you want to say - * it differently — and retyping it from the transcript is busywork. The text returns exactly as typed, - * newlines and all. + * Stop the turn, and leave the composer alone. * - * It never overwrites: if you've started composing something else while it ran, that wins and the old - * prompt is dropped. Losing what you just typed to a stop you pressed would be the worse failure. + * This used to hand the sent prompt back, on the theory — carried over from Claude Code's terminal — + * that interrupting means the agent never read it, so you should get it back to say differently. That + * is not what happens here. The prompt is delivered and read before Escape can land; the transcript + * keeps it and the agent answers it on the next turn. Restoring it therefore refilled the composer + * with something already sent, and sending it again sent it twice. + * + * Escape means one of two things — "stop, I'll say it differently" or just "stop" — and neither wants + * the old text back. Focus returns to the composer, which serves both. */ const stopGeneration = () => { stopTurn(); - const sent = lastSentRef.current; - lastSentRef.current = ''; - if (!sent || input.trim()) return; - setInput(sent); requestAnimationFrame(() => textareaRef.current?.focus()); };