mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-28 20:22:45 +00:00
Keep conversation turns distinct and history stable (#7990)
* fix(app): keep autonomous turns distinct and readable Hidden system prompts merged autonomous work into the previous response and reopened completed turns. Preserve canonical turn boundaries and expose their triggers, while making received messages attributable and expanded turn details readable in one step. * fix(timeline): mount history at actual run boundaries * fix(timeline): load and retain complete available turns * fix(app): summarize actions and preserve conversation events * test(timeline): verify whole-turn paging stays responsive * fix(app): group reasoning according to thinking preference * test(app): align history journeys with whole-turn loading
This commit is contained in:
@@ -306,6 +306,21 @@ async function expectLegacyWorkspaceRefresh({
|
||||
}
|
||||
|
||||
describe("ReplicaCache", () => {
|
||||
it("persists the complete newest turn beyond the cache item target", async () => {
|
||||
const storage = new MemoryStorage();
|
||||
const writer = createCache(storage);
|
||||
const items = Array.from({ length: 60 }, (_, index) => ({
|
||||
...timelineItem(`item-${index}`),
|
||||
id: `item-${index}`,
|
||||
turnId: "long-run",
|
||||
}));
|
||||
writer.commitTimeline(SERVER_ID, "agent-1", { ...timeline(), items });
|
||||
await writer.flush();
|
||||
const restored = await createCache(storage).readTimeline(SERVER_ID, "agent-1");
|
||||
expect(restored?.items.map((item) => item.id)).toEqual(items.map((item) => item.id));
|
||||
expect(restored?.range).toBeNull();
|
||||
});
|
||||
|
||||
it("preserves workspace sorting timestamps across cache reopen", async () => {
|
||||
const storage = new MemoryStorage();
|
||||
const writer = createCache(storage);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { findMountedWindowStart } from "@/agent-stream/history-window";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
AgentStatusSchema,
|
||||
@@ -766,7 +767,14 @@ function serializeTimeline(timeline: CachedTimeline): StoredTimeline | null {
|
||||
const canonicalItems = timeline.items.filter(
|
||||
(item) => item.kind !== "user_message" || !isUnreconciledLocalUserMessage(item),
|
||||
);
|
||||
const items = canonicalItems.map(serializeTimelineItem).filter((item) => item !== null);
|
||||
const start = findMountedWindowStart({
|
||||
items: canonicalItems,
|
||||
minMountedCount: MAX_TIMELINE_ITEMS,
|
||||
});
|
||||
const items = canonicalItems
|
||||
.slice(start)
|
||||
.map(serializeTimelineItem)
|
||||
.filter((item) => item !== null);
|
||||
const range = timeline.range;
|
||||
const canPersistCoverage =
|
||||
range !== null &&
|
||||
@@ -783,7 +791,7 @@ function serializeTimeline(timeline: CachedTimeline): StoredTimeline | null {
|
||||
canonicalItems.some((item) => item.timelineCursor?.seq === range.endSeq);
|
||||
return {
|
||||
agentId: timeline.agentId,
|
||||
items: items.slice(-MAX_TIMELINE_ITEMS),
|
||||
items,
|
||||
range: canPersistCoverage
|
||||
? { epoch: range.epoch, startSeq: range.startSeq, endSeq: range.endSeq }
|
||||
: null,
|
||||
|
||||
Reference in New Issue
Block a user