[eric] chat: prefill caret parks at end (not pos 0) + skip the background reconcile-fetch while streaming so a mid-stream reopen stops wiping the user bubble

This commit is contained in:
ciregenz
2026-06-11 03:52:42 -07:00
parent 7d5df5f016
commit cdaec3b7c8
2 changed files with 26 additions and 3 deletions
@@ -344,7 +344,15 @@ const AgentChat: React.FC<AgentChatProps> = ({ sessionId: sessionIdProp, onClose
// let the fetch reconcile in the background; awaiting serialized a slow
// round trip in front of the live stream on every reopen.
const warm = !!store.getState().agents.sessions[id]?.messages?.length;
if (warm) {
// Mid-stream reopen: the server snapshot predates the just-sent user turn
// (not persisted until the turn ends), and the WS echo already cleared the
// bubble's optimistic flag, so the background reconcile would DROP the user
// message until the stream finishes. The warm store + the kept-alive socket
// are authoritative here, so skip the fetch; stream-end persists everything.
const streamingNow = !!store.getState().streaming.bySession[id];
if (warm && streamingNow) {
// no fetch: don't let a stale snapshot wipe the in-flight turn
} else if (warm) {
dispatch(fetchSession(id));
} else {
try {
+17 -2
View File
@@ -70,8 +70,23 @@ const ChatInput = forwardRef<ChatInputHandle, Props>(({ onSend, disabled, mode,
if (!prefillPrompt || prefilledRef.current === prefillPrompt) return;
const editor = editorRef.current;
if (!editor) return;
if (editor.tagName === 'TEXTAREA') (editor as unknown as HTMLTextAreaElement).value = prefillPrompt;
else editor.textContent = prefillPrompt;
if (editor.tagName === 'TEXTAREA') {
const ta = editor as unknown as HTMLTextAreaElement;
ta.value = prefillPrompt;
ta.setSelectionRange(prefillPrompt.length, prefillPrompt.length);
} else {
editor.textContent = prefillPrompt;
// Park the caret AFTER the seeded text, not at position 0 (the default for a
// freshly-set textContent), so the user types/sends from the end.
const sel = window.getSelection();
if (sel) {
const range = document.createRange();
range.selectNodeContents(editor);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
}
}
setHasContent(true);
prefilledRef.current = prefillPrompt;
editor.style.opacity = '0.5';