From acb6057af0c6d70950e199ed04c8e57c03903329 Mon Sep 17 00:00:00 2001 From: lostf1sh Date: Thu, 14 May 2026 12:18:43 +0300 Subject: [PATCH] fix(server): force Claude 200k context when selected/(default) --- .../src/provider/Layers/ClaudeAdapter.test.ts | 75 +++++++++++++++++++ .../src/provider/Layers/ClaudeAdapter.ts | 39 +++++++++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/apps/server/src/provider/Layers/ClaudeAdapter.test.ts b/apps/server/src/provider/Layers/ClaudeAdapter.test.ts index 19ed1811760..b5044aff2ad 100644 --- a/apps/server/src/provider/Layers/ClaudeAdapter.test.ts +++ b/apps/server/src/provider/Layers/ClaudeAdapter.test.ts @@ -156,6 +156,7 @@ function makeHarness(config?: { readonly baseDir?: string; readonly claudeConfig?: Partial; readonly instanceId?: ProviderInstanceId; + readonly environment?: NodeJS.ProcessEnv; }) { const query = new FakeClaudeQuery(); let createInput: @@ -167,6 +168,7 @@ function makeHarness(config?: { const adapterOptions: ClaudeAdapterLiveOptions = { ...(config?.instanceId ? { instanceId: config.instanceId } : {}), + ...(config?.environment ? { environment: config.environment } : {}), createQuery: (input) => { createInput = input; return query; @@ -380,6 +382,79 @@ describe("ClaudeAdapterLive", () => { ); }); + it.effect("disables Claude Code automatic 1M context when Claude context window is 200k", () => { + const harness = makeHarness(); + return Effect.gen(function* () { + const adapter = yield* ClaudeAdapter; + yield* adapter.startSession({ + threadId: THREAD_ID, + provider: ProviderDriverKind.make("claudeAgent"), + modelSelection: createModelSelection( + ProviderInstanceId.make("claudeAgent"), + "claude-opus-4-6", + [{ id: "contextWindow", value: "200k" }], + ), + runtimeMode: "full-access", + }); + + const createInput = harness.getLastCreateQueryInput(); + assert.equal(createInput?.options.model, "claude-opus-4-6"); + assert.equal(createInput?.options.env?.CLAUDE_CODE_DISABLE_1M_CONTEXT, "1"); + }).pipe( + Effect.provideService(Random.Random, makeDeterministicRandomService()), + Effect.provide(harness.layer), + ); + }); + + it.effect("uses 200k as T3 Code's default Claude context window", () => { + const harness = makeHarness(); + return Effect.gen(function* () { + const adapter = yield* ClaudeAdapter; + yield* adapter.startSession({ + threadId: THREAD_ID, + provider: ProviderDriverKind.make("claudeAgent"), + modelSelection: createModelSelection( + ProviderInstanceId.make("claudeAgent"), + "claude-opus-4-6", + ), + runtimeMode: "full-access", + }); + + const createInput = harness.getLastCreateQueryInput(); + assert.equal(createInput?.options.model, "claude-opus-4-6"); + assert.equal(createInput?.options.env?.CLAUDE_CODE_DISABLE_1M_CONTEXT, "1"); + }).pipe( + Effect.provideService(Random.Random, makeDeterministicRandomService()), + Effect.provide(harness.layer), + ); + }); + + it.effect("allows explicit Claude 1M context even when the process env disables it", () => { + const harness = makeHarness({ + environment: { CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" }, + }); + return Effect.gen(function* () { + const adapter = yield* ClaudeAdapter; + yield* adapter.startSession({ + threadId: THREAD_ID, + provider: ProviderDriverKind.make("claudeAgent"), + modelSelection: createModelSelection( + ProviderInstanceId.make("claudeAgent"), + "claude-opus-4-6", + [{ id: "contextWindow", value: "1m" }], + ), + runtimeMode: "full-access", + }); + + const createInput = harness.getLastCreateQueryInput(); + assert.equal(createInput?.options.model, "claude-opus-4-6[1m]"); + assert.equal(createInput?.options.env?.CLAUDE_CODE_DISABLE_1M_CONTEXT, undefined); + }).pipe( + Effect.provideService(Random.Random, makeDeterministicRandomService()), + Effect.provide(harness.layer), + ); + }); + it.effect("runs Claude SDK sessions with the configured Claude HOME", () => { const harness = makeHarness({ claudeConfig: { homePath: "~/.claude-work" } }); return Effect.gen(function* () { diff --git a/apps/server/src/provider/Layers/ClaudeAdapter.ts b/apps/server/src/provider/Layers/ClaudeAdapter.ts index e9bd8fb7a16..703db1735fa 100644 --- a/apps/server/src/provider/Layers/ClaudeAdapter.ts +++ b/apps/server/src/provider/Layers/ClaudeAdapter.ts @@ -47,6 +47,7 @@ import { import { applyClaudePromptEffortPrefix, getModelSelectionBooleanOptionValue, + getProviderOptionCurrentValue, getModelSelectionStringOptionValue, getProviderOptionDescriptors, resolvePromptInjectedEffort, @@ -260,6 +261,35 @@ function getEffectiveClaudeAgentEffort(effort: string | null | undefined): Claud return normalized ? (normalized as ClaudeSdkEffort) : null; } +function resolveClaudeOneMillionContextDisabled( + descriptors: ReadonlyArray[number]>, +): boolean | undefined { + const contextWindowDescriptor = descriptors.find( + (descriptor) => descriptor.type === "select" && descriptor.id === "contextWindow", + ); + if (!contextWindowDescriptor) { + return undefined; + } + return getProviderOptionCurrentValue(contextWindowDescriptor) !== "1m"; +} + +function withClaudeContextWindowEnvironment( + env: NodeJS.ProcessEnv, + oneMillionContextDisabled: boolean | undefined, +): NodeJS.ProcessEnv { + if (oneMillionContextDisabled === true) { + return { + ...env, + CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", + }; + } + if (oneMillionContextDisabled === false) { + const { CLAUDE_CODE_DISABLE_1M_CONTEXT: _unused, ...rest } = env; + return rest; + } + return env; +} + function isClaudeInterruptedMessage(message: string): boolean { const normalized = message.toLowerCase(); return ( @@ -2871,10 +2901,14 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( const modelSelection = input.modelSelection?.instanceId === boundInstanceId ? input.modelSelection : undefined; const caps = getClaudeModelCapabilities(modelSelection?.model); - const descriptors = getProviderOptionDescriptors({ caps }); + const descriptors = getProviderOptionDescriptors({ + caps, + selections: modelSelection?.options, + }); const apiModelId = modelSelection ? resolveClaudeApiModelId(modelSelection) : undefined; const rawEffort = getModelSelectionStringOptionValue(modelSelection, "effort"); const effort = resolveClaudeEffort(caps, rawEffort) ?? null; + const oneMillionContextDisabled = resolveClaudeOneMillionContextDisabled(descriptors); const fastModeSupported = descriptors.some( (descriptor) => descriptor.type === "boolean" && descriptor.id === "fastMode", ); @@ -2919,7 +2953,7 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( ...(newSessionId ? { sessionId: newSessionId } : {}), includePartialMessages: true, canUseTool, - env: claudeEnvironment, + env: withClaudeContextWindowEnvironment(claudeEnvironment, oneMillionContextDisabled), ...(input.cwd ? { additionalDirectories: [input.cwd] } : {}), ...(Object.keys(extraArgs).length > 0 ? { extraArgs } : {}), }; @@ -2946,6 +2980,7 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( "claude.query.setting_sources": [...CLAUDE_SETTING_SOURCES], "claude.query.settings_json": encodeJsonStringForDiagnostics(settings) ?? "", "claude.query.extra_args_json": encodeJsonStringForDiagnostics(extraArgs) ?? "", + "claude.query.one_million_context_disabled": oneMillionContextDisabled ?? "", "claude.query.path_to_executable": claudeBinaryPath, });