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:
Mohamed Boudra
2026-10-27 13:57:17 +07:00
committed by GitHub
parent 3a1b146690
commit b12eefb28f
72 changed files with 1690 additions and 409 deletions
@@ -1658,6 +1658,11 @@ test("honors explicit fetchAgentTimeline timeout below the session RPC default",
mock.triggerOpen();
await connectPromise;
await expect(client.fetchAgentTimeline("agent-1", { wholeTurns: true })).rejects.toThrow(
"Update the host to load complete conversation turns.",
);
expect(mock.sent).toHaveLength(0);
const responsePromise = client.fetchAgentTimeline("agent-1", {
requestId: "req-timeline-1",
direction: "tail",
+5
View File
@@ -686,6 +686,7 @@ export interface FetchAgentOptions {
}
type LegacyFetchAgentOptions = Omit<FetchAgentOptions, "agentId">;
export interface FetchAgentTimelineOptions {
wholeTurns?: boolean;
direction?: FetchAgentTimelineDirection;
cursor?: FetchAgentTimelineCursor;
limit?: number;
@@ -3548,9 +3549,13 @@ export class DaemonClient {
agentId: string,
options: FetchAgentTimelineOptions = {},
): Promise<FetchAgentTimelinePayload> {
if (options.wholeTurns && this.lastServerInfoMessage?.features?.wholeTurnTimeline !== true) {
throw new Error("Update the host to load complete conversation turns.");
}
const resolvedRequestId = this.createRequestId(options.requestId);
const message = SessionInboundMessageSchema.parse({
type: "fetch_agent_timeline_request",
...(options.wholeTurns !== undefined ? { wholeTurns: options.wholeTurns } : {}),
agentId,
requestId: resolvedRequestId,
...(options.direction ? { direction: options.direction } : {}),