Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
01358d1
Persist provider-aware model selections
juliusmarminge Mar 24, 2026
fa0a1c1
Merge branch 'main' into t3code/provider-kind-model
juliusmarminge Mar 24, 2026
340634e
Preserve composer model options across provider changes
juliusmarminge Mar 24, 2026
8cad01a
Keep model selections in composer drafts
juliusmarminge Mar 24, 2026
71ff626
Persist first sticky model snapshot from provider options
juliusmarminge Mar 24, 2026
07e86e9
Preserve null model options in projections and restarts
juliusmarminge Mar 24, 2026
97ff0ac
Canonicalize legacy model selections
juliusmarminge Mar 24, 2026
96d6160
Unify provider model selection across orchestration and UI
juliusmarminge Mar 24, 2026
8cb3995
Merge branch 'main' into t3code/provider-kind-model
juliusmarminge Mar 24, 2026
e12d290
Update sidebar test fixtures for provider-aware model selection
juliusmarminge Mar 24, 2026
c44d17f
simplify migrations
juliusmarminge Mar 24, 2026
3003850
migration test harness
juliusmarminge Mar 24, 2026
2cadee4
json
juliusmarminge Mar 24, 2026
6348bea
kewl
juliusmarminge Mar 24, 2026
cc7245e
kewl
juliusmarminge Mar 24, 2026
1040a2a
rm unnecessary effect
juliusmarminge Mar 24, 2026
7984a23
update test
juliusmarminge Mar 24, 2026
e0d4388
kewl
juliusmarminge Mar 24, 2026
fb03276
explicit
juliusmarminge Mar 24, 2026
0a1e9b0
rm unneceesary
juliusmarminge Mar 24, 2026
23dfe7d
Remove legacy orchestration payload coercions
juliusmarminge Mar 24, 2026
f03289e
rm cursor probe
juliusmarminge Mar 24, 2026
ce0315c
rm unnecessary map
juliusmarminge Mar 24, 2026
0a81215
Preserve session model when switching is unsupported
juliusmarminge Mar 24, 2026
4fe00a5
Persist provider-specific composer model options
juliusmarminge Mar 25, 2026
3c56663
kewl
juliusmarminge Mar 25, 2026
5635f3d
rev
juliusmarminge Mar 25, 2026
2767215
kewl
juliusmarminge Mar 25, 2026
2eb1665
rm unused
juliusmarminge Mar 25, 2026
cfe745c
whops
juliusmarminge Mar 25, 2026
bedce21
fix test
juliusmarminge Mar 25, 2026
fc938c8
simplify
juliusmarminge Mar 25, 2026
3c61f4b
Preserve explicit model overrides in draft selection
juliusmarminge Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 43 additions & 11 deletions apps/server/integration/orchestrationEngine.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ProjectId,
ProviderKind,
ThreadId,
ModelSelection,
} from "@t3tools/contracts";
import { assert, it } from "@effect/vitest";
import { Effect, Option, Schema } from "effect";
Expand Down Expand Up @@ -115,7 +116,10 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) =>
projectId: PROJECT_ID,
title: "Integration Project",
workspaceRoot: harness.workspaceDir,
defaultModel,
defaultModelSelection: {
provider,
model: defaultModel,
},
createdAt,
});

Expand All @@ -125,7 +129,10 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) =>
threadId: THREAD_ID,
projectId: PROJECT_ID,
title: "Integration Thread",
model: defaultModel,
modelSelection: {
provider,
model: defaultModel,
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand All @@ -139,7 +146,7 @@ const startTurn = (input: {
readonly commandId: string;
readonly messageId: string;
readonly text: string;
readonly provider?: IntegrationProvider;
readonly modelSelection?: ModelSelection;
}) =>
input.harness.engine.dispatch({
type: "thread.turn.start",
Expand All @@ -151,7 +158,11 @@ const startTurn = (input: {
text: input.text,
attachments: [],
},
...(input.provider !== undefined ? { provider: input.provider } : {}),
...(input.modelSelection !== undefined
? {
modelSelection: input.modelSelection,
}
: {}),
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
createdAt: nowIso(),
Expand Down Expand Up @@ -254,7 +265,10 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)(
projectId: PROJECT_ID,
title: "Integration Project",
workspaceRoot: harness.workspaceDir,
defaultModel: "gpt-5.3-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5.3-codex",
},
createdAt,
});

Expand All @@ -264,7 +278,10 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)(
threadId: THREAD_ID,
projectId: PROJECT_ID,
title: "Integration Thread",
model: "gpt-5.3-codex",
modelSelection: {
provider: "codex",
model: "gpt-5.3-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "full-access",
branch: null,
Expand Down Expand Up @@ -922,7 +939,10 @@ it.live("starts a claudeAgent session on first turn when provider is requested",
commandId: "cmd-turn-start-claude-initial",
messageId: "msg-user-claude-initial",
text: "Use Claude",
provider: "claudeAgent",
modelSelection: {
provider: "claudeAgent",
model: "claude-sonnet-4-6",
},
});

const thread = yield* harness.waitForThread(
Expand Down Expand Up @@ -976,7 +996,10 @@ it.live("recovers claudeAgent sessions after provider stopAll using persisted re
commandId: "cmd-turn-start-claude-recover-1",
messageId: "msg-user-claude-recover-1",
text: "Before restart",
provider: "claudeAgent",
modelSelection: {
provider: "claudeAgent",
model: "claude-sonnet-4-6",
},
});

yield* harness.waitForThread(
Expand Down Expand Up @@ -1083,7 +1106,10 @@ it.live("forwards claudeAgent approval responses to the provider session", () =>
commandId: "cmd-turn-start-claude-approval",
messageId: "msg-user-claude-approval",
text: "Need approval",
provider: "claudeAgent",
modelSelection: {
provider: "claudeAgent",
model: "claude-sonnet-4-6",
},
});

const thread = yield* harness.waitForThread(THREAD_ID, (entry) =>
Expand Down Expand Up @@ -1152,7 +1178,10 @@ it.live("forwards thread.turn.interrupt to claudeAgent provider sessions", () =>
commandId: "cmd-turn-start-claude-interrupt",
messageId: "msg-user-claude-interrupt",
text: "Start long turn",
provider: "claudeAgent",
modelSelection: {
provider: "claudeAgent",
model: "claude-sonnet-4-6",
},
});

const thread = yield* harness.waitForThread(
Expand Down Expand Up @@ -1222,7 +1251,10 @@ it.live("reverts claudeAgent turns and rolls back provider conversation state",
commandId: "cmd-turn-start-claude-revert-1",
messageId: "msg-user-claude-revert-1",
text: "First Claude edit",
provider: "claudeAgent",
modelSelection: {
provider: "claudeAgent",
model: "claude-sonnet-4-6",
},
});

yield* harness.waitForThread(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function makeSnapshot(input: {
id: input.projectId,
title: "Project",
workspaceRoot: input.workspaceRoot,
defaultModel: null,
defaultModelSelection: null,
scripts: [],
createdAt: "2026-01-01T00:00:00.000Z",
updatedAt: "2026-01-01T00:00:00.000Z",
Expand All @@ -43,7 +43,10 @@ function makeSnapshot(input: {
id: input.threadId,
projectId: input.projectId,
title: "Thread",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "full-access",
branch: null,
Expand Down
10 changes: 8 additions & 2 deletions apps/server/src/orchestration/Layers/CheckpointReactor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,10 @@ describe("CheckpointReactor", () => {
projectId: asProjectId("project-1"),
title: "Test Project",
workspaceRoot: options?.projectWorkspaceRoot ?? cwd,
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -293,7 +296,10 @@ describe("CheckpointReactor", () => {
threadId: ThreadId.makeUnsafe("thread-1"),
projectId: asProjectId("project-1"),
title: "Thread",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down
90 changes: 72 additions & 18 deletions apps/server/src/orchestration/Layers/OrchestrationEngine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-1"),
title: "Project 1",
workspaceRoot: "/tmp/project-1",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -83,7 +86,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-1"),
projectId: asProjectId("project-1"),
title: "Thread",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down Expand Up @@ -126,7 +132,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-replay"),
title: "Replay Project",
workspaceRoot: "/tmp/project-replay",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -137,7 +146,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-replay"),
projectId: asProjectId("project-replay"),
title: "replay",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down Expand Up @@ -178,7 +190,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-stream"),
title: "Stream Project",
workspaceRoot: "/tmp/project-stream",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -199,7 +214,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-stream"),
projectId: asProjectId("project-stream"),
title: "domain-stream",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down Expand Up @@ -233,7 +251,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-turn-diff"),
title: "Turn Diff Project",
workspaceRoot: "/tmp/project-turn-diff",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -244,7 +265,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-turn-diff"),
projectId: asProjectId("project-turn-diff"),
title: "Turn diff thread",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down Expand Up @@ -344,7 +368,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-flaky"),
title: "Flaky Project",
workspaceRoot: "/tmp/project-flaky",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -357,7 +384,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-flaky-fail"),
projectId: asProjectId("project-flaky"),
title: "flaky-fail",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand All @@ -374,7 +404,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-flaky-ok"),
projectId: asProjectId("project-flaky"),
title: "flaky-ok",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down Expand Up @@ -428,7 +461,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-atomic"),
title: "Atomic Project",
workspaceRoot: "/tmp/project-atomic",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -439,7 +475,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-atomic"),
projectId: asProjectId("project-atomic"),
title: "atomic",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down Expand Up @@ -563,7 +602,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-sync"),
title: "Sync Project",
workspaceRoot: "/tmp/project-sync",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -574,7 +616,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-sync"),
projectId: asProjectId("project-sync"),
title: "sync-before",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down Expand Up @@ -642,7 +687,10 @@ describe("OrchestrationEngine", () => {
projectId: asProjectId("project-duplicate"),
title: "Duplicate Project",
workspaceRoot: "/tmp/project-duplicate",
defaultModel: "gpt-5-codex",
defaultModelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
createdAt,
}),
);
Expand All @@ -654,7 +702,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-duplicate"),
projectId: asProjectId("project-duplicate"),
title: "duplicate",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand All @@ -671,7 +722,10 @@ describe("OrchestrationEngine", () => {
threadId: ThreadId.makeUnsafe("thread-duplicate"),
projectId: asProjectId("project-duplicate"),
title: "duplicate",
model: "gpt-5-codex",
modelSelection: {
provider: "codex",
model: "gpt-5-codex",
},
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down
Loading