Keep older chat history and image previews stable (#2490)
* fix(app): keep timeline history and previews stable Treat persisted timeline replicas as display-only so authoritative pagination always comes from the daemon. Require renewed user intent between older-history pages unless the viewport genuinely remains at the history edge. Model assistant image acquisition as loading, loaded, or failed so recreating a preview URL cannot be rendered as an error. * fix(app): keep file image previews current * fix(app): stabilize history pagination edges * fix(app): recover transient timeline loads * fix(app): retain assistant image previews * Stabilize history pagination lifecycle * Stabilize history settlement and image previews * Retry file images after reconnect * Keep active previews and pagination requests alive * Replace image hook tests with typed ports * Integrate timeline hydration with submission authority * Harden pre-hydration timeline reconciliation * Make rewind E2E use real scroll intent * Preserve live timeline state through hydration * Keep mounted image attachments retained * Protect preview persistence and lifecycle hydration * Preserve idless live assistant continuations * Preserve timeline rows across delayed hydration * test(app): cover real assistant image files * Preserve assistant tool ordering during hydration
This commit is contained in:
@@ -3,7 +3,6 @@ import {
|
||||
clearAssistantImageMetadataCache,
|
||||
estimateAssistantMessageHeightFromCache,
|
||||
extractAssistantImageSources,
|
||||
getAssistantImageLoadStateFromMetadata,
|
||||
getAssistantImageMetadata,
|
||||
setAssistantImageMetadata,
|
||||
} from "./assistant-image-metadata";
|
||||
@@ -42,23 +41,6 @@ describe("assistant image metadata", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("maps missing metadata to the image loading state", () => {
|
||||
expect(getAssistantImageLoadStateFromMetadata(null)).toEqual({ status: "loading" });
|
||||
});
|
||||
|
||||
it("maps cached metadata to the image ready state", () => {
|
||||
expect(
|
||||
getAssistantImageLoadStateFromMetadata({
|
||||
width: 900,
|
||||
height: 1600,
|
||||
aspectRatio: 9 / 16,
|
||||
}),
|
||||
).toEqual({
|
||||
status: "ready",
|
||||
aspectRatio: 9 / 16,
|
||||
});
|
||||
});
|
||||
|
||||
it("estimates assistant message height from cached image metadata", () => {
|
||||
setAssistantImageMetadata(
|
||||
{
|
||||
|
||||
@@ -8,11 +8,6 @@ export interface AssistantImageMetadata {
|
||||
aspectRatio: number;
|
||||
}
|
||||
|
||||
export type AssistantImageLoadState =
|
||||
| { status: "loading" }
|
||||
| { status: "ready"; aspectRatio: number }
|
||||
| { status: "error" };
|
||||
|
||||
const assistantImageMetadataCache = new Map<string, AssistantImageMetadata>();
|
||||
const assistantImageParseCache = new Map<string, { sources: string[]; hasNonImageText: boolean }>();
|
||||
const ASSISTANT_IMAGE_METADATA_CACHE_LIMIT = 500;
|
||||
@@ -131,15 +126,6 @@ export function getAssistantImageMetadata(input: {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getAssistantImageLoadStateFromMetadata(
|
||||
metadata: AssistantImageMetadata | null,
|
||||
): AssistantImageLoadState {
|
||||
if (!metadata) {
|
||||
return { status: "loading" };
|
||||
}
|
||||
return { status: "ready", aspectRatio: metadata.aspectRatio };
|
||||
}
|
||||
|
||||
export function setAssistantImageMetadata(
|
||||
input: {
|
||||
source: string;
|
||||
|
||||
Reference in New Issue
Block a user