fix: close presentation visual pass review findings

This commit is contained in:
lda
2026-07-12 21:46:55 +07:00 Verified
parent 26efa88817
commit 1602f6946f
6 changed files with 178 additions and 106 deletions
@@ -217,6 +217,34 @@ describe("AssistantOperatorThread", () => {
}
});
it("can show the latest response in a static comparison transcript", async () => {
const setScrollTop = vi.fn();
const descriptors = {
scrollTop: Object.getOwnPropertyDescriptor(HTMLDivElement.prototype, "scrollTop"),
scrollHeight: Object.getOwnPropertyDescriptor(HTMLDivElement.prototype, "scrollHeight"),
clientHeight: Object.getOwnPropertyDescriptor(HTMLDivElement.prototype, "clientHeight"),
};
try {
Object.defineProperties(HTMLDivElement.prototype, {
scrollTop: { configurable: true, get: () => 0, set: setScrollTop },
scrollHeight: { configurable: true, get: () => 240 },
clientHeight: { configurable: true, get: () => 80 },
});
render(<AssistantOperatorThread mode="dock" messages={[]} scrollMode="end" />);
await waitFor(() => expect(setScrollTop).toHaveBeenCalledWith(160));
} finally {
for (const [name, descriptor] of Object.entries(descriptors)) {
if (descriptor) {
Object.defineProperty(HTMLDivElement.prototype, name, descriptor);
} else {
delete (HTMLDivElement.prototype as unknown as Record<string, unknown>)[name];
}
}
}
});
it("pairs a lone tool call with its result", () => {
const messages: ReadonlyArray<AgentMessage> = [
{
@@ -23,7 +23,7 @@ import {
type AssistantOperatorThreadProps = {
readonly mode: "hidden" | "full" | "rail" | "dock";
readonly messages: ReadonlyArray<AgentMessage>;
readonly scrollMode?: "active" | "start" | undefined;
readonly scrollMode?: "active" | "start" | "end" | undefined;
readonly submitApproval?: (() => void) | undefined;
readonly requestRevision?: (() => void) | undefined;
readonly ariaLabel?: string | undefined;
@@ -273,13 +273,22 @@ export const AssistantOperatorThread = ({
}, [activeToolGroupId, toolGroupOverrides]);
useEffect(() => {
const viewport = viewportRef.current;
if (!viewport) return;
// Static comparison transcripts should show their final answer; live
// presentation docks instead keep the beat-owned tool group in view.
if (!activeToolGroupId && scrollMode === "end") {
viewport.scrollTop = Math.max(0, viewport.scrollHeight - viewport.clientHeight);
return;
}
if (!activeToolGroupId) return;
// The same transcript can be much taller than the Scene 9 dock. Keep the
// beat-owned group visible without maintaining a second scroll-state model.
const viewport = viewportRef.current;
const activeGroup = viewport
?.querySelector<HTMLElement>(`[data-tool-group-id="${activeToolGroupId}"]`);
if (!viewport || !activeGroup) return;
if (!activeGroup) return;
const bottomAlignedTop = activeGroup.offsetTop + activeGroup.offsetHeight - viewport.clientHeight;
const dockCenteredTop = activeGroup.offsetTop - (viewport.clientHeight - activeGroup.offsetHeight) / 2;
const requestedTop = scrollMode === "start"