fix(agents): scope context windows to agent

This commit is contained in:
Dallin Romney
2026-08-20 22:29:01 -07:00
parent 0ff2701e70
commit 3b9bee7fea
13 changed files with 55 additions and 10 deletions
+1
View File
@@ -843,6 +843,7 @@ export async function prepareCliRunContext(
provider: params.provider,
modelProvider: backendResolved.modelProvider,
model: contextModelId,
agentId: sessionAgentId,
modelContextWindow: params.modelContextWindow,
modelContextTokens: params.modelContextTokens,
allowAsyncLoad: false,
+11 -10
View File
@@ -11,7 +11,7 @@ import {
minPositiveContextTokens,
providerContextTokenCacheKey,
} from "./context-cache.js";
import { resolveModelExtraParamSources } from "./model-extra-params.js";
import { resolveModelExtraParamValue } from "./model-extra-params.js";
import { normalizeProviderId } from "./model-selection.js";
type ConfigModelEntry = { id?: string; contextWindow?: number; contextTokens?: number };
@@ -27,6 +27,7 @@ export type ContextTokenResolutionParams = {
provider?: string;
modelProvider?: string;
model?: string;
agentId?: string;
fallbackContextTokens?: number;
modelContextWindow?: number;
modelContextTokens?: number;
@@ -211,15 +212,15 @@ export function resolveContextTokensForModelFromCache(
params.modelProvider,
ref.model,
);
const extraParamSources = resolveModelExtraParamSources({
config: params.cfg,
provider: ref.provider,
modelId: ref.model,
});
const effectiveContext1M =
extraParamSources.modelParams && Object.hasOwn(extraParamSources.modelParams, "context1m")
? extraParamSources.modelParams.context1m
: extraParamSources.defaultParams?.context1m;
const effectiveContext1M = resolveModelExtraParamValue(
{
config: params.cfg,
provider: ref.provider,
modelId: ref.model,
agentId: params.agentId,
},
"context1m",
);
const fixedContextWindow = resolveAnthropicFixedContextWindow(ref.provider, ref.model, {
claudeCli1M: effectiveContext1M === true,
});
+30
View File
@@ -393,6 +393,36 @@ describe("resolveContextTokensForModel", () => {
expect(result).toBe(ANTHROPIC_CONTEXT_1M_TOKENS);
});
it("honors an agent model context1m override", () => {
const result = resolveContextTokensForModel({
cfg: {
agents: {
defaults: {
params: { context1m: false },
models: {
"claude-cli/claude-opus-4-7": { params: { context1m: false } },
},
},
list: [
{
id: "research",
models: {
"claude-cli/claude-opus-4-7": { params: { context1m: true } },
},
},
],
},
},
provider: "claude-cli",
model: "claude-opus-4-7",
agentId: "research",
fallbackContextTokens: 200_000,
allowAsyncLoad: false,
});
expect(result).toBe(ANTHROPIC_CONTEXT_1M_TOKENS);
});
it("returns 1M context when claude-cli context1m is enabled for a GA 1M model", () => {
const result = resolveContextTokensForModel({
cfg: {
@@ -76,6 +76,7 @@ function resolveContextWindowForHint(params: {
cfg: params.cfg,
provider: params.ref.provider,
model: params.ref.model,
agentId: params.agentId,
allowAsyncLoad: false,
});
return modelContextTokens ?? sessionContextTokens;
@@ -781,6 +781,7 @@ export async function runPreflightCompactionIfNeeded(params: {
runtimePolicySessionKey: params.runtimePolicySessionKey,
}),
modelId: params.followupRun.run.model ?? params.defaultModel,
agentId: compactionAgentId,
});
const memoryFlushPlan = resolveMemoryFlushPlan({ cfg: params.cfg });
const reserveTokensFloor = memoryFlushPlan?.reserveTokensFloor ?? 20_000;
@@ -1160,6 +1161,7 @@ export async function runMemoryFlushIfNeeded(params: {
runtimePolicySessionKey: params.runtimePolicySessionKey,
}),
modelId: params.followupRun.run.model ?? params.defaultModel,
agentId: params.followupRun.run.agentId,
});
const promptTokenEstimate = estimatePromptTokensForMemoryFlush(
@@ -236,6 +236,7 @@ export async function accountAgentTurn(context: AgentTurnAccountingContext) {
cfg,
provider: providerUsed,
model: modelUsed,
agentId: followupRun.run.agentId,
allowAsyncLoad: false,
})
: undefined;
+1
View File
@@ -130,6 +130,7 @@ function resolveManualCompactContextTokenBudget(params: {
contextConfigProvider,
model,
}),
agentId: params.agentId,
allowAsyncLoad: false,
});
if (typeof configuredContextTokens === "number" && configuredContextTokens > 0) {
@@ -522,6 +522,7 @@ export async function applyInlineDirectiveOverrides(params: {
config: cfg,
}),
model,
agentId: resolveSessionAgentId({ sessionKey, config: cfg }),
modelContextWindow: selectedCatalogEntry?.contextWindow,
modelContextTokens: selectedCatalogEntry?.contextTokens,
});
@@ -481,6 +481,7 @@ export async function resolveReplyDirectives(params: {
cfg,
provider,
model,
agentId,
modelContextWindow: modelState.modelContextWindow,
modelContextTokens: modelState.modelContextTokens,
});
@@ -384,6 +384,7 @@ export async function maybeResolveNativeSlashCommandFastReply(params: {
cfg: params.cfg,
provider: params.provider,
model: params.model,
agentId: params.agentId,
}),
isGroup: sessionState.isGroup,
loadSkillCommands: loadNativeSkillCommands,
+2
View File
@@ -18,12 +18,14 @@ export function resolveMemoryFlushContextWindowTokens(params: {
modelId?: string;
cfg?: OpenClawConfig;
provider?: string;
agentId?: string;
}): number {
return (
resolveContextTokensForModel({
cfg: params.cfg,
provider: params.provider,
model: params.modelId,
agentId: params.agentId,
allowAsyncLoad: false,
}) ?? DEFAULT_CONTEXT_TOKENS
);
@@ -7,6 +7,7 @@ export function resolveContextTokens(params: {
cfg: OpenClawConfig;
provider: string;
model: string;
agentId?: string;
modelContextWindow?: number;
modelContextTokens?: number;
}): number {
@@ -15,6 +16,7 @@ export function resolveContextTokens(params: {
cfg: params.cfg,
provider: params.provider,
model: params.model,
agentId: params.agentId,
modelContextWindow: params.modelContextWindow,
modelContextTokens: params.modelContextTokens,
allowAsyncLoad: false,
+1
View File
@@ -107,6 +107,7 @@ export async function finalizeCronRun(params: {
cfg: prepared.cfgWithAgentDefaults,
provider: providerUsed,
model: modelUsed,
agentId: prepared.agentId,
allowAsyncLoad: false,
});
const agentHarnessId = normalizeOptionalString(finalRunResult.meta?.agentMeta?.agentHarnessId);