mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-08 03:30:34 +00:00
* feat(frontend): add side conversations for quoted follow-ups * style(frontend): apply prettier formatting to sidecar-chat files * fix(frontend): surface sidecar cascade cleanup failures via console.warn Previously deleteSidecarThreadsForParent silently swallowed both lookup errors and per-thread deletion failures, so parent thread deletions could succeed while orphaning sidecar threads with no signal to the caller. Log a warning that includes the parent id and the failed thread ids/reasons so the leak is discoverable in telemetry, matching the existing console.warn/error pattern in this file. * fix(frontend): address all sidecar review feedback Resolve every reviewer comment on PR #3934: - input-box/hooks/sidecar-panel: clear quoted references only via an `onSent` callback that fires after the in-flight guard, so a dropped send no longer silently discards quotes (willem-bd #3550). - message-list: flip the selection toolbar below the selection when it would clip above the viewport (willem-bd #3551). - reference-metadata/thread/input-box: keep referenced ids, roles, and count arrays 1:1 parallel instead of deduping ids (willem-bd #3552). - message-list: widen selection containment to the shared assistant-turn container and hint when a selection crosses messages (willem-bd #3553). - sidecar/api: coalesce concurrent sidecar creates for one parent behind a single in-flight promise to prevent duplicates (willem-bd #3554). - sidecar-trigger/context: force-restore on trigger click so a sidecar deleted elsewhere self-heals instead of opening a dead thread (willem-bd #3555). - threads/hooks: surface sidecar cascade cleanup failures via console.warn for both lookup and per-thread deletes (Copilot). Add unit + e2e coverage for parallel metadata, atomic create, and trigger self-healing.
56 lines
1.3 KiB
TypeScript
56 lines
1.3 KiB
TypeScript
import type { SidecarContext } from "./context";
|
|
|
|
export type SidecarReferenceStateItem = {
|
|
id: number;
|
|
context: SidecarContext;
|
|
};
|
|
|
|
export function isSameSidecarContext(
|
|
left: SidecarContext,
|
|
right: SidecarContext,
|
|
) {
|
|
return (
|
|
left.type === right.type &&
|
|
left.role === right.role &&
|
|
left.messageId === right.messageId &&
|
|
left.content === right.content
|
|
);
|
|
}
|
|
|
|
export function appendSidecarReference<
|
|
TReference extends SidecarReferenceStateItem,
|
|
>(references: TReference[], nextReference: TReference) {
|
|
if (
|
|
references.some((reference) =>
|
|
isSameSidecarContext(reference.context, nextReference.context),
|
|
)
|
|
) {
|
|
return references;
|
|
}
|
|
return [...references, nextReference];
|
|
}
|
|
|
|
export function getNextSidecarOpenState<
|
|
TReference extends SidecarReferenceStateItem,
|
|
>({
|
|
open,
|
|
sidecarThreadId,
|
|
activeReferences,
|
|
nextReference,
|
|
}: {
|
|
open: boolean;
|
|
sidecarThreadId: string | null;
|
|
activeReferences: TReference[];
|
|
nextReference: TReference;
|
|
}) {
|
|
const shouldAppendToCurrentSidecar =
|
|
open && (Boolean(sidecarThreadId) || activeReferences.length > 0);
|
|
|
|
return {
|
|
sidecarThreadId,
|
|
activeReferences: shouldAppendToCurrentSidecar
|
|
? appendSidecarReference(activeReferences, nextReference)
|
|
: [nextReference],
|
|
};
|
|
}
|