fix(pi): settle delayed compact ownership
This commit is contained in:
@@ -48,6 +48,32 @@ const THINKING_OPTIONS: Array<{ value: ConversationThinkingLevel; label: string
|
||||
{ value: 'high', label: '高思考' },
|
||||
];
|
||||
|
||||
interface LocalActionError {
|
||||
message: string;
|
||||
backendCode?: string;
|
||||
startedGeneration: number;
|
||||
startedSeq: number;
|
||||
}
|
||||
|
||||
function localActionError(
|
||||
error: unknown,
|
||||
startedGeneration: number,
|
||||
startedSeq: number,
|
||||
): LocalActionError {
|
||||
const details = error && typeof error === 'object'
|
||||
&& 'details' in error
|
||||
&& error.details
|
||||
&& typeof error.details === 'object'
|
||||
? error.details as { backendCode?: unknown }
|
||||
: null;
|
||||
return {
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
...(typeof details?.backendCode === 'string' ? { backendCode: details.backendCode } : {}),
|
||||
startedGeneration,
|
||||
startedSeq,
|
||||
};
|
||||
}
|
||||
|
||||
function runLabel(snapshot: ConversationSnapshot | null): string {
|
||||
if (!snapshot) return '正在准备';
|
||||
const { run } = snapshot;
|
||||
@@ -90,7 +116,7 @@ export function CodingConversationHeader({
|
||||
const vendors = useProviderStore((state) => state.vendors);
|
||||
const options = useMemo(() => buildCodingModelOptions(accounts, vendors), [accounts, vendors]);
|
||||
const [busyAction, setBusyAction] = useState<string | null>(null);
|
||||
const [actionError, setActionError] = useState<string | null>(null);
|
||||
const [actionError, setActionError] = useState<LocalActionError | null>(null);
|
||||
const [renameOpen, setRenameOpen] = useState(false);
|
||||
const [titleDraft, setTitleDraft] = useState(conversation?.title ?? '');
|
||||
|
||||
@@ -110,13 +136,27 @@ export function CodingConversationHeader({
|
||||
? Math.min(100, Math.round((context.usedTokens / context.contextWindow) * 100))
|
||||
: 0;
|
||||
const recoverable = Boolean(snapshot?.run.error?.recoverable || snapshot?.worker.error?.recoverable);
|
||||
const runtimeErrorCode = snapshot?.run.error?.code ?? snapshot?.worker.error?.code;
|
||||
const cursorAdvancedPastAction = Boolean(actionError && snapshot && (
|
||||
snapshot.cursor.workerGeneration > actionError.startedGeneration
|
||||
|| (snapshot.cursor.workerGeneration === actionError.startedGeneration
|
||||
&& snapshot.cursor.seq > actionError.startedSeq)
|
||||
));
|
||||
const visibleActionError = actionError?.backendCode === 'CODING_REQUEST_UNCERTAIN'
|
||||
&& !running
|
||||
&& runtimeErrorCode !== 'CODING_REQUEST_UNCERTAIN'
|
||||
&& cursorAdvancedPastAction
|
||||
? null
|
||||
: actionError;
|
||||
|
||||
const perform = (key: string, action: () => Promise<void>) => {
|
||||
if (busyAction || !conversation) return;
|
||||
const startedGeneration = snapshot?.cursor.workerGeneration ?? 0;
|
||||
const startedSeq = snapshot?.cursor.seq ?? 0;
|
||||
setBusyAction(key);
|
||||
setActionError(null);
|
||||
void action()
|
||||
.catch((error) => setActionError(error instanceof Error ? error.message : String(error)))
|
||||
.catch((error) => setActionError(localActionError(error, startedGeneration, startedSeq)))
|
||||
.finally(() => setBusyAction((current) => current === key ? null : current));
|
||||
};
|
||||
|
||||
@@ -226,7 +266,7 @@ export function CodingConversationHeader({
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{actionError && <p className="border-t border-destructive/10 bg-destructive/5 px-5 py-2 text-xs text-destructive" role="alert">{actionError}</p>}
|
||||
{visibleActionError && <p className="border-t border-destructive/10 bg-destructive/5 px-5 py-2 text-xs text-destructive" role="alert">{visibleActionError.message}</p>}
|
||||
|
||||
<Dialog open={renameOpen} onOpenChange={setRenameOpen}>
|
||||
<DialogContent>
|
||||
|
||||
Reference in New Issue
Block a user