mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-12 18:26:26 +00:00
Several restoration paths return a failed prompt's text to the composer by prepending it above the current draft: failed queue submits, failed mid-turn inserts, and queue clears. More than one of them can fire for the same prompt across reconnects and refreshes, and a user retrying an identical message produces identical text — each pass stacked another copy, which surfaced as multiple sent messages concatenated back into the input box after a page refresh (#7128). Extract the merge into mergeRestoredPromptText() and make it idempotent: restoring text that is already at the top of the editor is a no-op. Restoring different text still prepends above the draft. This addresses the text-stacking defect (bug 3 in the triage analysis). The SSE-reconnect-on-prompt question (bug 1) is a behavioral decision left to maintainers. Fixes #7128 Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
44 lines
1.6 KiB
TypeScript
44 lines
1.6 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { mergeRestoredPromptText } from './useQueuedPrompts';
|
|
|
|
// Regression for #7128: restoration paths can fire more than once for the
|
|
// same prompt (failed submit + reconnect/refresh, queue clear racing an
|
|
// abort), and a user retrying an identical message restores identical text.
|
|
// Stacking those copies is what surfaced as "sent messages concatenated back
|
|
// into the input box after refresh".
|
|
describe('mergeRestoredPromptText', () => {
|
|
it('fills an empty editor with the restored text', () => {
|
|
expect(mergeRestoredPromptText('', 'hello')).toBe('hello');
|
|
expect(mergeRestoredPromptText(' ', 'hello')).toBe('hello');
|
|
});
|
|
|
|
it('prepends above a different draft the user is typing', () => {
|
|
expect(mergeRestoredPromptText('draft', 'restored')).toBe(
|
|
'restored\ndraft',
|
|
);
|
|
});
|
|
|
|
it('is a no-op when the same text was already restored', () => {
|
|
expect(mergeRestoredPromptText('hello', 'hello')).toBe('hello');
|
|
});
|
|
|
|
it('is a no-op when the text already sits at the top of the editor', () => {
|
|
expect(mergeRestoredPromptText('hello\ndraft', 'hello')).toBe(
|
|
'hello\ndraft',
|
|
);
|
|
});
|
|
|
|
it('stays idempotent across repeated restores of the same prompt', () => {
|
|
let editor = '';
|
|
for (let i = 0; i < 3; i++) {
|
|
editor = mergeRestoredPromptText(editor, '用python写一个hello world');
|
|
}
|
|
expect(editor).toBe('用python写一个hello world');
|
|
});
|
|
|
|
it('does not treat a same-prefix but different first line as a duplicate', () => {
|
|
expect(mergeRestoredPromptText('hello world\ndraft', 'hello')).toBe(
|
|
'hello\nhello world\ndraft',
|
|
);
|
|
});
|
|
});
|