Skip to content

Commit 4bf483d

Browse files
Merge remote-tracking branch 'origin/main' into t3code/context-window-meter
2 parents ef47eaa + 48481aa commit 4bf483d

94 files changed

Lines changed: 8694 additions & 3137 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/server/integration/OrchestrationEngineHarness.integration.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,10 @@ export const makeOrchestrationIntegrationHarness = (
290290
);
291291

292292
const checkpointStoreLayer = CheckpointStoreLive.pipe(Layer.provide(GitCoreLive));
293+
const projectionSnapshotQueryLayer = OrchestrationProjectionSnapshotQueryLive;
293294
const runtimeServicesLayer = Layer.mergeAll(
294-
orchestrationLayer,
295-
OrchestrationProjectionSnapshotQueryLive,
295+
projectionSnapshotQueryLayer,
296+
orchestrationLayer.pipe(Layer.provide(projectionSnapshotQueryLayer)),
296297
ProjectionCheckpointRepositoryLive,
297298
ProjectionPendingApprovalRepositoryLive,
298299
ProjectionTurnRepositoryLive,
@@ -335,7 +336,9 @@ export const makeOrchestrationIntegrationHarness = (
335336
Layer.provideMerge(providerCommandReactorLayer),
336337
Layer.provideMerge(checkpointReactorLayer),
337338
);
338-
const layer = orchestrationReactorLayer.pipe(
339+
const layer = Layer.empty.pipe(
340+
Layer.provideMerge(runtimeServicesLayer),
341+
Layer.provideMerge(orchestrationReactorLayer),
339342
Layer.provide(persistenceLayer),
340343
Layer.provideMerge(ServerSettingsService.layerTest()),
341344
Layer.provideMerge(ServerConfig.layerTest(workspaceDir, rootDir)),

apps/server/src/checkpointing/Layers/CheckpointDiffQuery.test.ts

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,38 @@
1-
import {
2-
CheckpointRef,
3-
DEFAULT_PROVIDER_INTERACTION_MODE,
4-
ProjectId,
5-
ThreadId,
6-
TurnId,
7-
type OrchestrationReadModel,
8-
} from "@t3tools/contracts";
9-
import { Effect, Layer } from "effect";
1+
import { CheckpointRef, ProjectId, ThreadId, TurnId } from "@t3tools/contracts";
2+
import { Effect, Layer, Option } from "effect";
103
import { describe, expect, it } from "vitest";
114

12-
import { ProjectionSnapshotQuery } from "../../orchestration/Services/ProjectionSnapshotQuery.ts";
5+
import {
6+
ProjectionSnapshotQuery,
7+
type ProjectionThreadCheckpointContext,
8+
} from "../../orchestration/Services/ProjectionSnapshotQuery.ts";
139
import { checkpointRefForThreadTurn } from "../Utils.ts";
1410
import { CheckpointDiffQueryLive } from "./CheckpointDiffQuery.ts";
1511
import { CheckpointStore, type CheckpointStoreShape } from "../Services/CheckpointStore.ts";
1612
import { CheckpointDiffQuery } from "../Services/CheckpointDiffQuery.ts";
1713

18-
function makeSnapshot(input: {
14+
function makeThreadCheckpointContext(input: {
1915
readonly projectId: ProjectId;
2016
readonly threadId: ThreadId;
2117
readonly workspaceRoot: string;
2218
readonly worktreePath: string | null;
2319
readonly checkpointTurnCount: number;
2420
readonly checkpointRef: CheckpointRef;
25-
}): OrchestrationReadModel {
21+
}): ProjectionThreadCheckpointContext {
2622
return {
27-
snapshotSequence: 0,
28-
updatedAt: "2026-01-01T00:00:00.000Z",
29-
projects: [
30-
{
31-
id: input.projectId,
32-
title: "Project",
33-
workspaceRoot: input.workspaceRoot,
34-
defaultModelSelection: null,
35-
scripts: [],
36-
createdAt: "2026-01-01T00:00:00.000Z",
37-
updatedAt: "2026-01-01T00:00:00.000Z",
38-
deletedAt: null,
39-
},
40-
],
41-
threads: [
23+
threadId: input.threadId,
24+
projectId: input.projectId,
25+
workspaceRoot: input.workspaceRoot,
26+
worktreePath: input.worktreePath,
27+
checkpoints: [
4228
{
43-
id: input.threadId,
44-
projectId: input.projectId,
45-
title: "Thread",
46-
modelSelection: {
47-
provider: "codex",
48-
model: "gpt-5-codex",
49-
},
50-
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
51-
runtimeMode: "full-access",
52-
branch: null,
53-
worktreePath: input.worktreePath,
54-
latestTurn: {
55-
turnId: TurnId.makeUnsafe("turn-1"),
56-
state: "completed",
57-
requestedAt: "2026-01-01T00:00:00.000Z",
58-
startedAt: "2026-01-01T00:00:00.000Z",
59-
completedAt: "2026-01-01T00:00:00.000Z",
60-
assistantMessageId: null,
61-
},
62-
createdAt: "2026-01-01T00:00:00.000Z",
63-
updatedAt: "2026-01-01T00:00:00.000Z",
64-
archivedAt: null,
65-
deletedAt: null,
66-
messages: [],
67-
activities: [],
68-
proposedPlans: [],
69-
checkpoints: [
70-
{
71-
turnId: TurnId.makeUnsafe("turn-1"),
72-
checkpointTurnCount: input.checkpointTurnCount,
73-
checkpointRef: input.checkpointRef,
74-
status: "ready",
75-
files: [],
76-
assistantMessageId: null,
77-
completedAt: "2026-01-01T00:00:00.000Z",
78-
},
79-
],
80-
session: null,
29+
turnId: TurnId.makeUnsafe("turn-1"),
30+
checkpointTurnCount: input.checkpointTurnCount,
31+
checkpointRef: input.checkpointRef,
32+
status: "ready",
33+
files: [],
34+
assistantMessageId: null,
35+
completedAt: "2026-01-01T00:00:00.000Z",
8136
},
8237
],
8338
};
@@ -95,7 +50,7 @@ describe("CheckpointDiffQueryLive", () => {
9550
readonly cwd: string;
9651
}> = [];
9752

98-
const snapshot = makeSnapshot({
53+
const threadCheckpointContext = makeThreadCheckpointContext({
9954
projectId,
10055
threadId,
10156
workspaceRoot: "/tmp/workspace",
@@ -125,7 +80,12 @@ describe("CheckpointDiffQueryLive", () => {
12580
Layer.provideMerge(Layer.succeed(CheckpointStore, checkpointStore)),
12681
Layer.provideMerge(
12782
Layer.succeed(ProjectionSnapshotQuery, {
128-
getSnapshot: () => Effect.succeed(snapshot),
83+
getSnapshot: () =>
84+
Effect.die("CheckpointDiffQuery should not request the full orchestration snapshot"),
85+
getCounts: () => Effect.succeed({ projectCount: 0, threadCount: 0 }),
86+
getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()),
87+
getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()),
88+
getThreadCheckpointContext: () => Effect.succeed(Option.some(threadCheckpointContext)),
12989
}),
13090
),
13191
);
@@ -175,12 +135,11 @@ describe("CheckpointDiffQueryLive", () => {
175135
Layer.provideMerge(
176136
Layer.succeed(ProjectionSnapshotQuery, {
177137
getSnapshot: () =>
178-
Effect.succeed({
179-
snapshotSequence: 0,
180-
projects: [],
181-
threads: [],
182-
updatedAt: "2026-01-01T00:00:00.000Z",
183-
} satisfies OrchestrationReadModel),
138+
Effect.die("CheckpointDiffQuery should not request the full orchestration snapshot"),
139+
getCounts: () => Effect.succeed({ projectCount: 0, threadCount: 0 }),
140+
getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()),
141+
getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()),
142+
getThreadCheckpointContext: () => Effect.succeed(Option.none()),
184143
}),
185144
),
186145
);

apps/server/src/checkpointing/Layers/CheckpointDiffQuery.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import {
44
type OrchestrationGetFullThreadDiffResult,
55
type OrchestrationGetTurnDiffResult as OrchestrationGetTurnDiffResultType,
66
} from "@t3tools/contracts";
7-
import { Effect, Layer, Schema } from "effect";
7+
import { Effect, Layer, Option, Schema } from "effect";
88

99
import { ProjectionSnapshotQuery } from "../../orchestration/Services/ProjectionSnapshotQuery.ts";
1010
import { CheckpointInvariantError, CheckpointUnavailableError } from "../Errors.ts";
11-
import { checkpointRefForThreadTurn, resolveThreadWorkspaceCwd } from "../Utils.ts";
11+
import { checkpointRefForThreadTurn } from "../Utils.ts";
1212
import { CheckpointStore } from "../Services/CheckpointStore.ts";
1313
import {
1414
CheckpointDiffQuery,
@@ -21,8 +21,8 @@ const make = Effect.gen(function* () {
2121
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
2222
const checkpointStore = yield* CheckpointStore;
2323

24-
const getTurnDiff: CheckpointDiffQueryShape["getTurnDiff"] = (input) =>
25-
Effect.gen(function* () {
24+
const getTurnDiff: CheckpointDiffQueryShape["getTurnDiff"] = Effect.fn("getTurnDiff")(
25+
function* (input) {
2626
const operation = "CheckpointDiffQuery.getTurnDiff";
2727

2828
if (input.fromTurnCount === input.toTurnCount) {
@@ -41,16 +41,17 @@ const make = Effect.gen(function* () {
4141
return emptyDiff;
4242
}
4343

44-
const snapshot = yield* projectionSnapshotQuery.getSnapshot();
45-
const thread = snapshot.threads.find((entry) => entry.id === input.threadId);
46-
if (!thread) {
44+
const threadContext = yield* projectionSnapshotQuery.getThreadCheckpointContext(
45+
input.threadId,
46+
);
47+
if (Option.isNone(threadContext)) {
4748
return yield* new CheckpointInvariantError({
4849
operation,
4950
detail: `Thread '${input.threadId}' not found.`,
5051
});
5152
}
5253

53-
const maxTurnCount = thread.checkpoints.reduce(
54+
const maxTurnCount = threadContext.value.checkpoints.reduce(
5455
(max, checkpoint) => Math.max(max, checkpoint.checkpointTurnCount),
5556
0,
5657
);
@@ -62,10 +63,7 @@ const make = Effect.gen(function* () {
6263
});
6364
}
6465

65-
const workspaceCwd = resolveThreadWorkspaceCwd({
66-
thread,
67-
projects: snapshot.projects,
68-
});
66+
const workspaceCwd = threadContext.value.worktreePath ?? threadContext.value.workspaceRoot;
6967
if (!workspaceCwd) {
7068
return yield* new CheckpointInvariantError({
7169
operation,
@@ -76,7 +74,7 @@ const make = Effect.gen(function* () {
7674
const fromCheckpointRef =
7775
input.fromTurnCount === 0
7876
? checkpointRefForThreadTurn(input.threadId, 0)
79-
: thread.checkpoints.find(
77+
: threadContext.value.checkpoints.find(
8078
(checkpoint) => checkpoint.checkpointTurnCount === input.fromTurnCount,
8179
)?.checkpointRef;
8280
if (!fromCheckpointRef) {
@@ -87,7 +85,7 @@ const make = Effect.gen(function* () {
8785
});
8886
}
8987

90-
const toCheckpointRef = thread.checkpoints.find(
88+
const toCheckpointRef = threadContext.value.checkpoints.find(
9189
(checkpoint) => checkpoint.checkpointTurnCount === input.toTurnCount,
9290
)?.checkpointRef;
9391
if (!toCheckpointRef) {
@@ -149,7 +147,8 @@ const make = Effect.gen(function* () {
149147
}
150148

151149
return turnDiff;
152-
});
150+
},
151+
);
153152

154153
const getFullThreadDiff: CheckpointDiffQueryShape["getFullThreadDiff"] = (
155154
input: OrchestrationGetFullThreadDiffInput,

0 commit comments

Comments
 (0)