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:
@@ -84,7 +84,7 @@ describe("loadOlderAgentHistory", () => {
|
||||
const client = createClient();
|
||||
const inFlight = createInFlight();
|
||||
|
||||
await loadOlderAgentHistory(agentId, {
|
||||
const started = await loadOlderAgentHistory(agentId, {
|
||||
client,
|
||||
cursor: undefined,
|
||||
hasOlder: true,
|
||||
@@ -94,13 +94,14 @@ describe("loadOlderAgentHistory", () => {
|
||||
|
||||
expect(client.calls).toEqual([]);
|
||||
expect(inFlight.values).toEqual([false]);
|
||||
expect(started).toBe(false);
|
||||
});
|
||||
|
||||
it("no-ops when the daemon says no older history exists", async () => {
|
||||
const client = createClient();
|
||||
const inFlight = createInFlight();
|
||||
|
||||
await loadOlderAgentHistory(agentId, {
|
||||
const started = await loadOlderAgentHistory(agentId, {
|
||||
client,
|
||||
cursor: someCursor,
|
||||
hasOlder: false,
|
||||
@@ -110,13 +111,14 @@ describe("loadOlderAgentHistory", () => {
|
||||
|
||||
expect(client.calls).toEqual([]);
|
||||
expect(inFlight.values).toEqual([false]);
|
||||
expect(started).toBe(false);
|
||||
});
|
||||
|
||||
it("no-ops when a request is already in flight", async () => {
|
||||
const client = createClient();
|
||||
const inFlight = createInFlight(true);
|
||||
|
||||
await loadOlderAgentHistory(agentId, {
|
||||
const started = await loadOlderAgentHistory(agentId, {
|
||||
client,
|
||||
cursor: someCursor,
|
||||
hasOlder: true,
|
||||
@@ -126,13 +128,14 @@ describe("loadOlderAgentHistory", () => {
|
||||
|
||||
expect(client.calls).toEqual([]);
|
||||
expect(inFlight.values).toEqual([true]);
|
||||
expect(started).toBe(true);
|
||||
});
|
||||
|
||||
it("requests the page before the current start cursor and clears in-flight on success", async () => {
|
||||
const client = createClient();
|
||||
const inFlight = createInFlight();
|
||||
|
||||
await loadOlderAgentHistory(agentId, {
|
||||
const started = await loadOlderAgentHistory(agentId, {
|
||||
client,
|
||||
cursor: someCursor,
|
||||
hasOlder: true,
|
||||
@@ -152,6 +155,7 @@ describe("loadOlderAgentHistory", () => {
|
||||
},
|
||||
]);
|
||||
expect(inFlight.values).toEqual([false, true, false]);
|
||||
expect(started).toBe(true);
|
||||
});
|
||||
|
||||
it("shows a panel toast, warns, and clears in-flight on failure", async () => {
|
||||
|
||||
Reference in New Issue
Block a user