From faa1c6f9728f3f8aef38f82241861199db7d4ac9 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 10 May 2026 09:46:22 +0100 Subject: [PATCH] fix: preserve custom provider context limits (#79911) --- CHANGELOG.md | 1 + src/commands/onboard-custom-config.test.ts | 7 ++++++- src/commands/onboard-custom-config.ts | 17 +++++++++-------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb4cb77f3db..73938ac91b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- CLI/onboarding: give non-Azure custom providers a safe generated context window and heal legacy 4k wizard entries without overwriting explicit valid small model limits, preventing first-turn compaction loops. Fixes #79428. (#79911) Thanks @Jefsky. - Ollama: stop native `/api/chat` requests from copying catalog `contextWindow` or `maxTokens` into `options.num_ctx` unless `params.num_ctx` is explicitly configured, avoiding pathological prompt-ingestion latency on local large-context models. Fixes #62267. Thanks @BenSHPD. - Ollama: keep the model idle watchdog enabled for `*:cloud` models routed through a local Ollama host, so cloud-backed tool-loop stalls fail over visibly instead of inheriting local-model no-idle behavior. Fixes #79350. Thanks @geek111. - Voice/Ollama: honor routed voice agent `tools.allow` for classic embedded voice responses, including empty allowlists, so no-tool Ollama agents do not receive tool schemas. Fixes #79506. Thanks @donkeykong91. diff --git a/src/commands/onboard-custom-config.test.ts b/src/commands/onboard-custom-config.test.ts index 576e9e7943d..e990ba9a102 100644 --- a/src/commands/onboard-custom-config.test.ts +++ b/src/commands/onboard-custom-config.test.ts @@ -117,10 +117,15 @@ describe("applyCustomApiConfig", () => { expectedContextWindow: CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS, }, { - name: "raises context window below stable default compaction floor (#79428)", + name: "raises legacy generated hard-min context window (#79428)", existingContextWindow: CONTEXT_WINDOW_HARD_MIN_TOKENS, expectedContextWindow: CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS, }, + { + name: "preserves explicit small context window when already valid", + existingContextWindow: 8192, + expectedContextWindow: 8192, + }, { name: "preserves existing custom model context window when already above minimum", existingContextWindow: 131072, diff --git a/src/commands/onboard-custom-config.ts b/src/commands/onboard-custom-config.ts index ff800b8f7bd..f1255113dd9 100644 --- a/src/commands/onboard-custom-config.ts +++ b/src/commands/onboard-custom-config.ts @@ -15,10 +15,10 @@ import { normalizeAlias } from "./models/alias-name.js"; /** * Wizard default for non-Azure custom APIs when context length is unknown. - * Must exceed the compaction `reserveTokensFloor` default (20000 tokens) in - * `agent-runner-memory.ts`, or the first turns enter an infinite compact loop (#79428). + * Mirrors the generic persisted custom-model catalog fallback and leaves enough + * room above the default compaction reserve floor in `pi-settings.ts`. */ -export const CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS = 32_768; +export const CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS = 128_000; const DEFAULT_CONTEXT_WINDOW = CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS; const DEFAULT_MAX_TOKENS = 4096; // Azure OpenAI uses the Responses API which supports larger defaults @@ -32,11 +32,12 @@ export type CustomModelImageInputInference = { function normalizeContextWindowForCustomModel(value: unknown): number { const parsed = typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : 0; - const atLeastHardMin = - parsed >= CONTEXT_WINDOW_HARD_MIN_TOKENS - ? parsed - : CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS; - return Math.max(atLeastHardMin, CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS); + if (parsed <= 0 || parsed === CONTEXT_WINDOW_HARD_MIN_TOKENS) { + return CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS; + } + return parsed >= CONTEXT_WINDOW_HARD_MIN_TOKENS + ? parsed + : CUSTOM_PROVIDER_DEFAULT_CONTEXT_WINDOW_TOKENS; } function customModelInputs(supportsImageInput: boolean): CustomModelInput[] {