fix(coding): reconcile snapshot after abort
This commit is contained in:
@@ -170,6 +170,10 @@ export function CodingChatPanel({
|
||||
? `new:${activeProject.id}:${selectedAgent.id}`
|
||||
: null;
|
||||
const draftKey = targetConversationId ?? provisionalDraftKey;
|
||||
const abortConversation = useCallback(async (conversationId: string) => {
|
||||
await abortCodingConversation(conversationId);
|
||||
await loadConversationSnapshot(conversationId, 'silent');
|
||||
}, [loadConversationSnapshot]);
|
||||
const promptMode = draftKey ? modesByDraftKey[draftKey] ?? 'prompt' : 'prompt';
|
||||
const provisionalDraft = provisionalDraftKey ? provisionalDrafts[provisionalDraftKey] ?? '' : '';
|
||||
const submissionError = draftKey ? submissionErrors[draftKey] ?? null : null;
|
||||
@@ -598,6 +602,9 @@ export function CodingChatPanel({
|
||||
onRename={async (title) => {
|
||||
if (targetConversationId) await patchConversation(targetConversationId, { title });
|
||||
}}
|
||||
onAbort={async () => {
|
||||
if (targetConversationId) await abortConversation(targetConversationId);
|
||||
}}
|
||||
onRecover={async () => {
|
||||
if (targetConversationId) await recoverConversation(targetConversationId);
|
||||
}}
|
||||
@@ -698,13 +705,15 @@ export function CodingChatPanel({
|
||||
onSubmit={handleSubmit}
|
||||
onAbort={() => {
|
||||
if (!targetConversationId) return;
|
||||
void abortCodingConversation(targetConversationId).catch((error) => {
|
||||
if (!draftKey) return;
|
||||
setSubmissionErrors((current) => ({
|
||||
...current,
|
||||
[draftKey]: localSubmissionError(error),
|
||||
}));
|
||||
});
|
||||
const conversationId = targetConversationId;
|
||||
void abortConversation(conversationId)
|
||||
.catch((error) => {
|
||||
if (!draftKey) return;
|
||||
setSubmissionErrors((current) => ({
|
||||
...current,
|
||||
[draftKey]: localSubmissionError(error),
|
||||
}));
|
||||
});
|
||||
}}
|
||||
onRecover={() => {
|
||||
if (targetConversationId) {
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { abortCodingConversation } from '@/lib/coding-conversations';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import type { ConversationSnapshot } from '@/types/coding-conversation';
|
||||
@@ -54,11 +53,13 @@ export function CodingConversationHeader({
|
||||
conversation,
|
||||
snapshot,
|
||||
onRename,
|
||||
onAbort,
|
||||
onRecover,
|
||||
}: {
|
||||
conversation: CodingConversationMetadata | null;
|
||||
snapshot: ConversationSnapshot | null;
|
||||
onRename(title: string): Promise<void>;
|
||||
onAbort(): Promise<void>;
|
||||
onRecover(): Promise<void>;
|
||||
}) {
|
||||
const sidebarCollapsed = useSettingsStore((state) => state.sidebarCollapsed);
|
||||
@@ -128,7 +129,7 @@ export function CodingConversationHeader({
|
||||
disabled={Boolean(busyAction) || !conversation}
|
||||
aria-label="中止"
|
||||
title="中止"
|
||||
onClick={() => perform('abort', async () => abortCodingConversation(conversation!.id))}
|
||||
onClick={() => perform('abort', onAbort)}
|
||||
>
|
||||
{busyAction === 'abort'
|
||||
? <LoaderCircle className="h-4 w-4 animate-spin" aria-hidden="true" />
|
||||
|
||||
Reference in New Issue
Block a user