fix(chat): prevent duplicate renderer requests and thinking messages (#870)
Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Haze <hazeone@users.noreply.github.com>
This commit is contained in:
@@ -491,6 +491,7 @@ export function ChatInput({ onSend, onStop, disabled = false, sending = false, i
|
||||
onPaste={handlePaste}
|
||||
placeholder={disabled ? t('composer.gatewayDisconnectedPlaceholder') : ''}
|
||||
disabled={disabled}
|
||||
data-testid="chat-composer-input"
|
||||
className="min-h-[40px] max-h-[200px] resize-none border-0 focus-visible:ring-0 focus-visible:ring-offset-0 shadow-none bg-transparent py-2.5 px-2 text-[15px] placeholder:text-muted-foreground/60 leading-relaxed"
|
||||
rows={1}
|
||||
/>
|
||||
@@ -501,6 +502,7 @@ export function ChatInput({ onSend, onStop, disabled = false, sending = false, i
|
||||
onClick={sending ? handleStop : handleSend}
|
||||
disabled={sending ? !canStop : !canSend}
|
||||
size="icon"
|
||||
data-testid="chat-composer-send"
|
||||
className={`shrink-0 h-10 w-10 rounded-full transition-colors ${
|
||||
(sending || canSend)
|
||||
? 'bg-black/5 dark:bg-white/10 text-foreground hover:bg-black/10 dark:hover:bg-white/20'
|
||||
|
||||
@@ -25,6 +25,44 @@ function cleanUserText(text: string): string {
|
||||
.trim();
|
||||
}
|
||||
|
||||
function normalizeProgressiveText(text: string | undefined): string {
|
||||
return typeof text === 'string' ? text.replace(/\r\n/g, '\n').trim() : '';
|
||||
}
|
||||
|
||||
function compactProgressiveParts(parts: string[]): string[] {
|
||||
const compacted: string[] = [];
|
||||
|
||||
for (const part of parts) {
|
||||
const current = normalizeProgressiveText(part);
|
||||
if (!current) continue;
|
||||
|
||||
const previous = compacted.at(-1);
|
||||
if (!previous) {
|
||||
compacted.push(part);
|
||||
continue;
|
||||
}
|
||||
|
||||
const normalizedPrevious = normalizeProgressiveText(previous);
|
||||
if (!normalizedPrevious) {
|
||||
compacted[compacted.length - 1] = part;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current === normalizedPrevious || normalizedPrevious.startsWith(current)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current.startsWith(normalizedPrevious)) {
|
||||
compacted[compacted.length - 1] = part;
|
||||
continue;
|
||||
}
|
||||
|
||||
compacted.push(part);
|
||||
}
|
||||
|
||||
return compacted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract displayable text from a message's content field.
|
||||
* Handles both string content and array-of-blocks content.
|
||||
@@ -49,7 +87,7 @@ export function extractText(message: RawMessage | unknown): string {
|
||||
}
|
||||
}
|
||||
}
|
||||
const combined = parts.join('\n\n');
|
||||
const combined = compactProgressiveParts(parts).join('\n\n');
|
||||
result = combined.trim().length > 0 ? combined : '';
|
||||
} else if (typeof msg.text === 'string') {
|
||||
// Fallback: try .text field
|
||||
@@ -85,7 +123,7 @@ export function extractThinking(message: RawMessage | unknown): string | null {
|
||||
}
|
||||
}
|
||||
|
||||
const combined = parts.join('\n\n').trim();
|
||||
const combined = compactProgressiveParts(parts).join('\n\n').trim();
|
||||
return combined.length > 0 ? combined : null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user