diff --git a/src/agents/context.lookup.test.ts b/src/agents/context.lookup.test.ts index 87792534270..8f3ba6ee176 100644 --- a/src/agents/context.lookup.test.ts +++ b/src/agents/context.lookup.test.ts @@ -358,6 +358,25 @@ describe("lookupContextTokens", () => { expect(result).toBe(200_000); }); + it("resolveContextTokensForModel treats explicit config as authoritative for read-only misses", async () => { + const loadConfig = vi.fn(() => { + throw new Error("runtime config should not be loaded"); + }); + mockContextModuleDeps(loadConfig); + const resolveContextTokensForModel = await importResolveContextTokensForModel(); + + const result = resolveContextTokensForModel({ + cfg: { agents: { defaults: {} } } as never, + provider: "openai", + model: "unknown-test-model", + fallbackContextTokens: 123_000, + allowAsyncLoad: false, + }); + + expect(result).toBe(123_000); + expect(loadConfig).not.toHaveBeenCalled(); + }); + it("resolveContextTokensForModel: config direct scan prevents OpenRouter qualified key collision for Google provider", async () => { // When provider is explicitly "google" and cfg has a Google contextWindow // override, the config direct scan returns it before any cache lookup — diff --git a/src/agents/context.ts b/src/agents/context.ts index fe956d151ca..09643fd8588 100644 --- a/src/agents/context.ts +++ b/src/agents/context.ts @@ -269,11 +269,14 @@ function ensureContextWindowCacheLoaded(): Promise { export function lookupContextTokens( modelId?: string, - options?: { allowAsyncLoad?: boolean }, + options?: { allowAsyncLoad?: boolean; skipRuntimeConfigLoad?: boolean }, ): number | undefined { if (!modelId) { return undefined; } + if (options?.skipRuntimeConfigLoad) { + return lookupCachedContextTokens(modelId); + } if (options?.allowAsyncLoad === false) { // Read-only callers still need synchronous config-backed overrides, but they // should not start background model discovery or models.json writes. @@ -515,7 +518,10 @@ export function resolveContextTokensForModel(params: { if (params.provider && ref && !ref.model.includes("/")) { const qualifiedResult = lookupContextTokens( `${normalizeProviderId(ref.provider)}/${ref.model}`, - { allowAsyncLoad: params.allowAsyncLoad }, + { + allowAsyncLoad: params.allowAsyncLoad, + skipRuntimeConfigLoad: Boolean(params.cfg), + }, ); if (qualifiedResult !== undefined) { return qualifiedResult; @@ -526,6 +532,7 @@ export function resolveContextTokensForModel(params: { // (e.g. "google/gemini-2.5-pro") this IS the raw discovery cache key. const bareResult = lookupContextTokens(params.model, { allowAsyncLoad: params.allowAsyncLoad, + skipRuntimeConfigLoad: Boolean(params.cfg), }); if (bareResult !== undefined) { return bareResult; @@ -537,7 +544,10 @@ export function resolveContextTokensForModel(params: { if (!params.provider && ref && !ref.model.includes("/")) { const qualifiedResult = lookupContextTokens( `${normalizeProviderId(ref.provider)}/${ref.model}`, - { allowAsyncLoad: params.allowAsyncLoad }, + { + allowAsyncLoad: params.allowAsyncLoad, + skipRuntimeConfigLoad: Boolean(params.cfg), + }, ); if (qualifiedResult !== undefined) { return qualifiedResult; diff --git a/src/status/status-message.ts b/src/status/status-message.ts index 4ba78c3cdb3..a65c56f9a55 100644 --- a/src/status/status-message.ts +++ b/src/status/status-message.ts @@ -869,15 +869,16 @@ export function buildStatusMessage(args: StatusArgs): string { ? activeAuthMode : (selectedAuthMode ?? activeAuthMode); const showCost = effectiveCostAuthMode === "api-key" || effectiveCostAuthMode === "mixed"; - const costConfig = showCost - ? resolveModelCostConfig({ - provider: activeProvider, - model: activeModel, - config: args.config, - allowPluginNormalization: false, - }) - : undefined; const hasUsage = typeof inputTokens === "number" || typeof outputTokens === "number"; + const costConfig = + showCost && hasUsage + ? resolveModelCostConfig({ + provider: activeProvider, + model: activeModel, + config: args.config, + allowPluginNormalization: false, + }) + : undefined; const cost = showCost && hasUsage ? estimateUsageCost({