fix(h5-chat): queue main-session submits while agent is busy
Memind CI / Test, build, and release guards (push) Successful in 4m1s

Prevent silent drops when users send follow-up instructions during waiting or streaming by showing the message immediately, notifying them it is queued, and auto-flushing after the composer returns to idle.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-13 08:51:30 +08:00
parent 53b0d2c62f
commit 558c4ef2ee
4 changed files with 280 additions and 96 deletions
+15 -15
View File
@@ -492,6 +492,7 @@ export function ChatPanel({
chatState === 'connecting' ||
chatState === 'waiting';
const offlineBlocked = !online;
const inputBlocked = !!pendingTool || chatState === 'error' || offlineBlocked;
const publishSkillName = user?.publishSkillName ?? 'static-page-publish';
const hasPublishSkill = grantedSkills?.includes(publishSkillName) ?? false;
const hasPageDataCollectSkill = grantedSkills?.includes('page-data-collect') ?? false;
@@ -525,9 +526,9 @@ export function ChatPanel({
? '上传中…'
: chatState === 'connecting'
? '连接中…'
: chatState === 'waiting'
? '提交中…'
: null;
: busy && canSubmit
? '排队发送'
: null;
const applyTemplatePrefill = useCallback((prompt: string, skillId: string, label: string) => {
pendingSkillRef.current = skillId;
@@ -577,7 +578,7 @@ export function ChatPanel({
setVoiceNotice('已识别,可编辑后发送');
};
const voiceDisabled = busy || !!pendingTool || chatState === 'error' || offlineBlocked;
const voiceDisabled = inputBlocked || uploadingImage || uploadingFile;
const canSubmit = input.trim() || pendingImages.length > 0 || pendingFiles.length > 0;
const uploadDisabled = !canUpload || busy || uploadingImage || uploadingFile || offlineBlocked || !!pendingTool;
@@ -719,7 +720,7 @@ export function ChatPanel({
skillIdOverride ?? pendingSkillRef.current ?? templateSelection?.skillId ?? undefined;
pendingSkillRef.current = null;
setActiveTemplatePrefill(null);
if ((!trimmed && pendingImages.length === 0 && pendingFiles.length === 0) || voiceDisabled) return;
if ((!trimmed && pendingImages.length === 0 && pendingFiles.length === 0) || inputBlocked) return;
if (pendingImages.length > 0 && !onUploadImage) {
setImageError('当前会话暂不支持图片发送');
return;
@@ -1462,16 +1463,15 @@ export function ChatPanel({
<button type="button" className="danger-btn chat-input-action" onClick={() => void onStop()}>
</button>
) : (
<button
type="button"
className={`send-btn chat-input-action${showHomeWelcome ? ' chat-input-action-home' : ''}`}
disabled={!canSubmit || voiceDisabled || uploadingImage || uploadingFile}
onClick={() => void handleSubmit()}
>
{sendButtonLabel ?? '发送'}
</button>
)}
) : null}
<button
type="button"
className={`send-btn chat-input-action${showHomeWelcome ? ' chat-input-action-home' : ''}`}
disabled={!canSubmit || inputBlocked || uploadingImage || uploadingFile}
onClick={() => void handleSubmit()}
>
{sendButtonLabel ?? '发送'}
</button>
</div>
{compact && onClose && (
<button type="button" className="space-chat-panel-dismiss" onClick={onClose}>