mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-24 02:02:42 +00:00
* fix(app): smooth chat history pagination and reserve image space Select the range at the pending reading offset before a prepend mounts rows. Reuse committed geometry for scroll input so a layout correction cannot hide the user's movement. Reserve image dimensions before loading and measure transient mounts in the browser regression. * fix(app): scope cached image dimensions to their source Raw file-path aliases let one workspace supply dimensions for another. Keep file metadata tied to its daemon and workspace, and close the delayed-image test server even when setup fails. * fix(app): retain local image context in row height estimates Pass the rendering server and workspace through height estimation so scoped image metadata remains usable before an older row mounts. * refactor(app): name row height estimate inputs
99 lines
2.8 KiB
TypeScript
99 lines
2.8 KiB
TypeScript
import type { AssistantImageContext } from "@/utils/assistant-image-metadata";
|
|
import type { StreamItem } from "@/types/stream";
|
|
import { estimateAssistantMessageHeightFromCache } from "@/utils/assistant-message-height-estimate";
|
|
import {
|
|
DEFAULT_MOUNTED_RECENT_STREAM_ITEMS,
|
|
findMountedWindowStart,
|
|
getMountedRecentStreamItems,
|
|
} from "./history-window";
|
|
|
|
export const DEFAULT_WEB_PARTIAL_VIRTUALIZATION_THRESHOLD = 100;
|
|
export const DEFAULT_WEB_MOUNTED_RECENT_STREAM_ITEMS = DEFAULT_MOUNTED_RECENT_STREAM_ITEMS;
|
|
const COLLAPSED_TOOL_SEQUENCE_ROW_HEIGHT_ESTIMATE = 40;
|
|
|
|
type BottomAnchorE2ETestGlobals = typeof globalThis & {
|
|
__PASEO_E2E_WEB_PARTIAL_VIRTUALIZATION_THRESHOLD?: unknown;
|
|
};
|
|
|
|
function readPositiveIntegerOverride(value: unknown): number | null {
|
|
if (!Number.isFinite(value)) {
|
|
return null;
|
|
}
|
|
const normalized = Math.trunc(value as number);
|
|
return normalized > 0 ? normalized : null;
|
|
}
|
|
|
|
export function getWebPartialVirtualizationThreshold(): number {
|
|
const override = readPositiveIntegerOverride(
|
|
(globalThis as BottomAnchorE2ETestGlobals).__PASEO_E2E_WEB_PARTIAL_VIRTUALIZATION_THRESHOLD,
|
|
);
|
|
return override ?? DEFAULT_WEB_PARTIAL_VIRTUALIZATION_THRESHOLD;
|
|
}
|
|
|
|
export function getWebMountedRecentStreamItems(): number {
|
|
return getMountedRecentStreamItems();
|
|
}
|
|
|
|
export interface IndexedStreamItem {
|
|
item: StreamItem;
|
|
index: number;
|
|
}
|
|
|
|
export interface WebVirtualizedHistoryWindow {
|
|
virtualizedEntries: IndexedStreamItem[];
|
|
mountedEntries: IndexedStreamItem[];
|
|
}
|
|
|
|
interface StreamItemHeightEstimateInput {
|
|
item: StreamItem;
|
|
contentMaxWidth: number;
|
|
imageContext?: AssistantImageContext;
|
|
}
|
|
|
|
export function estimateStreamItemHeight({
|
|
item,
|
|
contentMaxWidth,
|
|
imageContext,
|
|
}: StreamItemHeightEstimateInput): number {
|
|
switch (item.kind) {
|
|
case "user_message":
|
|
return item.images && item.images.length > 0 ? 220 : 96;
|
|
case "assistant_message":
|
|
return (
|
|
estimateAssistantMessageHeightFromCache({
|
|
markdown: item.text,
|
|
contentMaxWidth,
|
|
imageContext,
|
|
}) ?? 220
|
|
);
|
|
case "tool_call":
|
|
return COLLAPSED_TOOL_SEQUENCE_ROW_HEIGHT_ESTIMATE;
|
|
case "thought":
|
|
return COLLAPSED_TOOL_SEQUENCE_ROW_HEIGHT_ESTIMATE;
|
|
case "todo_list":
|
|
return 144;
|
|
case "notification":
|
|
return 88;
|
|
case "compaction":
|
|
return 72;
|
|
default:
|
|
return 120;
|
|
}
|
|
}
|
|
|
|
export { findMountedWindowStart };
|
|
|
|
export function splitWebVirtualizedHistory(input: {
|
|
entries: IndexedStreamItem[];
|
|
minMountedCount: number;
|
|
}): WebVirtualizedHistoryWindow {
|
|
const startIndex = findMountedWindowStart({
|
|
items: input.entries.map((entry) => entry.item),
|
|
minMountedCount: input.minMountedCount,
|
|
});
|
|
return {
|
|
virtualizedEntries: input.entries.slice(0, startIndex),
|
|
mountedEntries: input.entries.slice(startIndex),
|
|
};
|
|
}
|