From 53ad7bf878cced6d9d547e2fc6d8c12db1d98fef Mon Sep 17 00:00:00 2001 From: ppaaddeehh Date: Sat, 7 Mar 2026 03:51:58 +0000 Subject: [PATCH 1/2] fixed thread title icon resizing. --- apps/web/src/components/ChatView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx index 46231694d2dcc..5167aa79ac530 100644 --- a/apps/web/src/components/ChatView.tsx +++ b/apps/web/src/components/ChatView.tsx @@ -3950,7 +3950,7 @@ const ChatHeader = memo(function ChatHeader({ )} -
+
{activeProjectScripts && ( Date: Sat, 7 Mar 2026 04:07:14 +0000 Subject: [PATCH 2/2] Fixed checkpoint diff being unavailable --- .../Layers/CheckpointDiffQuery.test.ts | 56 ++++++++++++++++++- .../Layers/CheckpointDiffQuery.ts | 54 ++++++++++++------ .../Layers/ProviderRuntimeIngestion.test.ts | 19 ++++--- .../Layers/ProviderRuntimeIngestion.ts | 41 ++++++-------- 4 files changed, 120 insertions(+), 50 deletions(-) diff --git a/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.test.ts b/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.test.ts index 2f79ea9d5a536..be356475ae5ac 100644 --- a/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.test.ts +++ b/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.test.ts @@ -22,6 +22,7 @@ function makeSnapshot(input: { readonly worktreePath: string | null; readonly checkpointTurnCount: number; readonly checkpointRef: CheckpointRef; + readonly checkpointStatus?: "ready" | "missing" | "error"; }): OrchestrationReadModel { return { snapshotSequence: 0, @@ -67,7 +68,7 @@ function makeSnapshot(input: { turnId: TurnId.makeUnsafe("turn-1"), checkpointTurnCount: input.checkpointTurnCount, checkpointRef: input.checkpointRef, - status: "ready", + status: input.checkpointStatus ?? "ready", files: [], assistantMessageId: null, completedAt: "2026-01-01T00:00:00.000Z", @@ -194,4 +195,57 @@ describe("CheckpointDiffQueryLive", () => { ), ).rejects.toThrow("Thread 'thread-missing' not found."); }); + + it("returns an empty diff when a non-ready checkpoint ref is absent on disk", async () => { + const projectId = ProjectId.makeUnsafe("project-1"); + const threadId = ThreadId.makeUnsafe("thread-1"); + const toCheckpointRef = CheckpointRef.makeUnsafe("provider-diff:evt-turn-diff-updated"); + + const snapshot = makeSnapshot({ + projectId, + threadId, + workspaceRoot: "/tmp/workspace", + worktreePath: null, + checkpointTurnCount: 1, + checkpointRef: toCheckpointRef, + checkpointStatus: "missing", + }); + + const checkpointStore: CheckpointStoreShape = { + isGitRepository: () => Effect.succeed(true), + captureCheckpoint: () => Effect.void, + hasCheckpointRef: ({ checkpointRef }) => + Effect.succeed(checkpointRef !== toCheckpointRef), + restoreCheckpoint: () => Effect.succeed(true), + diffCheckpoints: () => Effect.succeed("diff should not be read"), + deleteCheckpointRefs: () => Effect.void, + }; + + const layer = CheckpointDiffQueryLive.pipe( + Layer.provideMerge(Layer.succeed(CheckpointStore, checkpointStore)), + Layer.provideMerge( + Layer.succeed(ProjectionSnapshotQuery, { + getSnapshot: () => Effect.succeed(snapshot), + }), + ), + ); + + const result = await Effect.runPromise( + Effect.gen(function* () { + const query = yield* CheckpointDiffQuery; + return yield* query.getTurnDiff({ + threadId, + fromTurnCount: 0, + toTurnCount: 1, + }); + }).pipe(Effect.provide(layer)), + ); + + expect(result).toEqual({ + threadId, + fromTurnCount: 0, + toTurnCount: 1, + diff: "", + }); + }); }); diff --git a/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.ts b/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.ts index 5cf26c86da924..b26b8c37b7fa4 100644 --- a/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.ts +++ b/apps/server/src/checkpointing/Layers/CheckpointDiffQuery.ts @@ -24,21 +24,28 @@ const make = Effect.gen(function* () { const getTurnDiff: CheckpointDiffQueryShape["getTurnDiff"] = (input) => Effect.gen(function* () { const operation = "CheckpointDiffQuery.getTurnDiff"; + const emptyTurnDiffResult = ( + fromTurnCount: number, + toTurnCount: number, + ): Effect.Effect => + Effect.gen(function* () { + const emptyDiff: OrchestrationGetTurnDiffResultType = { + threadId: input.threadId, + fromTurnCount, + toTurnCount, + diff: "", + }; + if (!isTurnDiffResult(emptyDiff)) { + return yield* new CheckpointInvariantError({ + operation, + detail: "Computed turn diff result does not satisfy contract schema.", + }); + } + return emptyDiff; + }); if (input.fromTurnCount === input.toTurnCount) { - const emptyDiff: OrchestrationGetTurnDiffResultType = { - threadId: input.threadId, - fromTurnCount: input.fromTurnCount, - toTurnCount: input.toTurnCount, - diff: "", - }; - if (!isTurnDiffResult(emptyDiff)) { - return yield* new CheckpointInvariantError({ - operation, - detail: "Computed turn diff result does not satisfy contract schema.", - }); - } - return emptyDiff; + return yield* emptyTurnDiffResult(input.fromTurnCount, input.toTurnCount); } const snapshot = yield* projectionSnapshotQuery.getSnapshot(); @@ -73,12 +80,16 @@ const make = Effect.gen(function* () { }); } - const fromCheckpointRef = + const fromCheckpoint = input.fromTurnCount === 0 - ? checkpointRefForThreadTurn(input.threadId, 0) + ? undefined : thread.checkpoints.find( (checkpoint) => checkpoint.checkpointTurnCount === input.fromTurnCount, - )?.checkpointRef; + ); + const fromCheckpointRef = + input.fromTurnCount === 0 + ? checkpointRefForThreadTurn(input.threadId, 0) + : fromCheckpoint?.checkpointRef; if (!fromCheckpointRef) { return yield* new CheckpointUnavailableError({ threadId: input.threadId, @@ -87,9 +98,10 @@ const make = Effect.gen(function* () { }); } - const toCheckpointRef = thread.checkpoints.find( + const toCheckpoint = thread.checkpoints.find( (checkpoint) => checkpoint.checkpointTurnCount === input.toTurnCount, - )?.checkpointRef; + ); + const toCheckpointRef = toCheckpoint?.checkpointRef; if (!toCheckpointRef) { return yield* new CheckpointUnavailableError({ threadId: input.threadId, @@ -113,6 +125,9 @@ const make = Effect.gen(function* () { ); if (!fromExists) { + if (input.fromTurnCount > 0 && fromCheckpoint && fromCheckpoint.status !== "ready") { + return yield* emptyTurnDiffResult(input.fromTurnCount, input.toTurnCount); + } return yield* new CheckpointUnavailableError({ threadId: input.threadId, turnCount: input.fromTurnCount, @@ -121,6 +136,9 @@ const make = Effect.gen(function* () { } if (!toExists) { + if (toCheckpoint && toCheckpoint.status !== "ready") { + return yield* emptyTurnDiffResult(input.fromTurnCount, input.toTurnCount); + } return yield* new CheckpointUnavailableError({ threadId: input.threadId, turnCount: input.toTurnCount, diff --git a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts index eb230e5202dec..237b9fee9e689 100644 --- a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts +++ b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts @@ -104,7 +104,6 @@ type ProviderRuntimeTestThread = ProviderRuntimeTestReadModel["threads"][number] type ProviderRuntimeTestMessage = ProviderRuntimeTestThread["messages"][number]; type ProviderRuntimeTestProposedPlan = ProviderRuntimeTestThread["proposedPlans"][number]; type ProviderRuntimeTestActivity = ProviderRuntimeTestThread["activities"][number]; -type ProviderRuntimeTestCheckpoint = ProviderRuntimeTestThread["checkpoints"][number]; describe("ProviderRuntimeIngestion", () => { let runtime: ManagedRuntime.ManagedRuntime< @@ -1214,8 +1213,8 @@ describe("ProviderRuntimeIngestion", () => { entry.activities.some( (activity: ProviderRuntimeTestActivity) => activity.kind === "runtime.warning", ) && - entry.checkpoints.some( - (checkpoint: ProviderRuntimeTestCheckpoint) => checkpoint.turnId === "turn-p1", + entry.activities.some( + (activity: ProviderRuntimeTestActivity) => activity.kind === "turn.diff.updated", ), ); @@ -1252,12 +1251,16 @@ describe("ProviderRuntimeIngestion", () => { expect(warning?.kind).toBe("runtime.warning"); expect(warningPayload?.message).toBe("Provider got slow"); - const checkpoint = thread.checkpoints.find( - (entry: ProviderRuntimeTestCheckpoint) => entry.turnId === "turn-p1", + const turnDiffActivity = thread.activities.find( + (activity: ProviderRuntimeTestActivity) => activity.id === "evt-turn-diff-updated", ); - expect(checkpoint?.status).toBe("missing"); - expect(checkpoint?.assistantMessageId).toBe("assistant:item-p1-assistant"); - expect(checkpoint?.checkpointRef).toBe("provider-diff:evt-turn-diff-updated"); + const turnDiffPayload = + turnDiffActivity?.payload && typeof turnDiffActivity.payload === "object" + ? (turnDiffActivity.payload as Record) + : undefined; + expect(turnDiffActivity?.kind).toBe("turn.diff.updated"); + expect(turnDiffPayload?.diffBytes).toBe(40); + expect(thread.checkpoints).toHaveLength(0); }); it("projects Codex task lifecycle chunks into thread activities", async () => { diff --git a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts index 04f6d85234373..b2f797ef7769d 100644 --- a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts +++ b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts @@ -4,7 +4,6 @@ import { CommandId, MessageId, type OrchestrationEvent, - CheckpointRef, ThreadId, TurnId, type OrchestrationThreadActivity, @@ -304,6 +303,24 @@ function runtimeEventToActivities( ]; } + case "turn.diff.updated": { + const diffBytes = event.payload.unifiedDiff.length; + return [ + { + id: event.eventId, + createdAt: event.createdAt, + tone: "info", + kind: "turn.diff.updated", + summary: diffBytes > 0 ? "Turn diff updated" : "Turn diff cleared", + payload: { + diffBytes, + }, + turnId: toTurnId(event.turnId) ?? null, + ...maybeSequence, + }, + ]; + } + case "user-input.requested": { return [ { @@ -1039,28 +1056,6 @@ const make = Effect.gen(function* () { }); } - if (event.type === "turn.diff.updated") { - const turnId = toTurnId(event.turnId); - if (turnId) { - const assistantMessageId = MessageId.makeUnsafe( - `assistant:${event.itemId ?? event.turnId ?? event.eventId}`, - ); - yield* orchestrationEngine.dispatch({ - type: "thread.turn.diff.complete", - commandId: providerCommandId(event, "thread-turn-diff-complete"), - threadId: thread.id, - turnId, - completedAt: now, - checkpointRef: CheckpointRef.makeUnsafe(`provider-diff:${event.eventId}`), - status: "missing", - files: [], - assistantMessageId, - checkpointTurnCount: thread.checkpoints.length + 1, - createdAt: now, - }); - } - } - const activities = runtimeEventToActivities(event); yield* Effect.forEach(activities, (activity) => orchestrationEngine.dispatch({