Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 6 additions & 5 deletions apps/server/src/provider/Layers/ClaudeAdapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3042,7 +3042,7 @@ describe("ClaudeAdapterLive", () => {
attachments: [],
});

assert.deepEqual(harness.query.setModelCalls, ["claude-opus-4-6"]);
assert.deepEqual(harness.query.setModelCalls, ["claude-opus-4-6[1m]"]);
}).pipe(
Effect.provideService(Random.Random, makeDeterministicRandomService()),
Effect.provide(harness.layer),
Expand Down Expand Up @@ -3140,10 +3140,11 @@ describe("ClaudeAdapterLive", () => {
yield* adapter.sendTurn({
threadId: session.threadId,
input: "hello again",
modelSelection: {
instanceId: ProviderInstanceId.make("claudeAgent"),
model: "claude-opus-4-6",
},
modelSelection: createModelSelection(
ProviderInstanceId.make("claudeAgent"),
"claude-opus-4-6",
[{ id: "contextWindow", value: "200k" }],
),
attachments: [],
});

Expand Down
23 changes: 9 additions & 14 deletions apps/server/src/provider/Layers/ClaudeAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import {
isClaudeUltracodeEffort,
normalizeClaudeCliEffort,
resolveClaudeApiModelId,
resolveClaudeContextWindow,
resolveClaudeEffort,
} from "./ClaudeProvider.ts";
import {
Expand Down Expand Up @@ -340,24 +341,18 @@ function selectedClaudeContextWindow(
switch (modelSelection?.model) {
case "claude-opus-4-8":
case "claude-opus-4-7":
// Always 1M at the API; these models expose no contextWindow option.
return 1_000_000;
}

const optionValue = getModelSelectionStringOptionValue(modelSelection, "contextWindow");
if (optionValue === "1m") {
return 1_000_000;
}
if (optionValue === "200k") {
return 200_000;
}
const caps = getClaudeModelCapabilities(modelSelection?.model);
const hasContextWindowOption = getProviderOptionDescriptors({ caps }).some(
(descriptor) => descriptor.type === "select" && descriptor.id === "contextWindow",
);
if (hasContextWindowOption) {
return 200_000;
switch (resolveClaudeContextWindow(modelSelection)) {
case "1m":
return 1_000_000;
case "200k":
return 200_000;
default:
return undefined;
}
return undefined;
}

function finiteNonNegativeInteger(value: unknown): number | undefined {
Expand Down
32 changes: 23 additions & 9 deletions apps/server/src/provider/Layers/ClaudeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
id: "contextWindow",
label: "Context Window",
options: [
{ value: "200k", label: "200k", isDefault: true },
{ value: "1m", label: "1M" },
{ value: "200k", label: "200k" },
{ value: "1m", label: "1M", isDefault: true },
],
}),
],
Expand Down Expand Up @@ -163,8 +163,8 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
id: "contextWindow",
label: "Context Window",
options: [
{ value: "200k", label: "200k", isDefault: true },
{ value: "1m", label: "1M" },
{ value: "200k", label: "200k" },
{ value: "1m", label: "1M", isDefault: true },
],
}),
],
Expand Down Expand Up @@ -216,8 +216,8 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
id: "contextWindow",
label: "Context Window",
options: [
{ value: "200k", label: "200k", isDefault: true },
{ value: "1m", label: "1M" },
{ value: "200k", label: "200k" },
{ value: "1m", label: "1M", isDefault: true },
],
}),
],
Expand Down Expand Up @@ -245,8 +245,8 @@ const BUILT_IN_MODELS: ReadonlyArray<ServerProviderModel> = [
id: "contextWindow",
label: "Context Window",
options: [
{ value: "200k", label: "200k", isDefault: true },
{ value: "1m", label: "1M" },
{ value: "200k", label: "200k" },
{ value: "1m", label: "1M", isDefault: true },
],
}),
],
Expand Down Expand Up @@ -370,8 +370,22 @@ export function isClaudeUltracodeEffort(effort: string | null | undefined): bool
return effort === "ultracode";
}

export function resolveClaudeContextWindow(
modelSelection: ModelSelection | undefined,
): string | undefined {
const caps = getClaudeModelCapabilities(modelSelection?.model);
const raw = getModelSelectionStringOptionValue(modelSelection, "contextWindow");
const descriptors = getProviderOptionDescriptors({
caps,
...(raw ? { selections: [{ id: "contextWindow", value: raw }] } : {}),
});
const descriptor = descriptors.find((candidate) => candidate.id === "contextWindow");
const value = getProviderOptionCurrentValue(descriptor);
return typeof value === "string" ? value : undefined;
}

export function resolveClaudeApiModelId(modelSelection: ModelSelection): string {
switch (getModelSelectionStringOptionValue(modelSelection, "contextWindow")) {
switch (resolveClaudeContextWindow(modelSelection)) {
case "1m":
return `${modelSelection.model}[1m]`;
default:
Expand Down
Loading