From bebfab40f0f0942c9a421233f3e6f1e57f2a5876 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 24 Feb 2026 03:47:32 +0000 Subject: [PATCH] fix: harden custom-provider verification probes (#24743) (thanks @Glucksberg) --- CHANGELOG.md | 1 + src/commands/onboard-custom.test.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99db9758816..0bfe497393a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Onboarding/Custom providers: raise verification probe token budgets for OpenAI and Anthropic compatibility checks to avoid false negatives on strict provider defaults. (#24743) Thanks @Glucksberg. - WhatsApp/Logging: redact outbound recipient identifiers in WhatsApp outbound + heartbeat logs and remove message/poll preview text from those log lines. (#24980) Thanks @coygeek. - Telegram/Media SSRF: keep RFC2544 benchmark range (`198.18.0.0/15`) blocked by default, add an explicit SSRF-policy opt-in for Telegram media downloads, and keep other channels/URL fetch paths blocked. (#24982) Thanks @stakeswky. - Security/Shell env fallback: remove trusted-prefix shell-path fallback and only trust login shells explicitly registered in `/etc/shells`, defaulting to `/bin/sh` when `SHELL` is not registered. This ships in the next npm release. Thanks @tdjackey for reporting. diff --git a/src/commands/onboard-custom.test.ts b/src/commands/onboard-custom.test.ts index c1bf8aa0d8d..c79c30daff2 100644 --- a/src/commands/onboard-custom.test.ts +++ b/src/commands/onboard-custom.test.ts @@ -116,6 +116,35 @@ describe("promptCustomApiConfig", () => { expectOpenAiCompatResult({ prompter, textCalls: 5, selectCalls: 1, result }); }); + it("uses expanded max_tokens for openai verification probes", async () => { + const prompter = createTestPrompter({ + text: ["https://example.com/v1", "test-key", "detected-model", "custom", "alias"], + select: ["openai"], + }); + const fetchMock = stubFetchSequence([{ ok: true }]); + + await runPromptCustomApi(prompter); + + const firstCall = fetchMock.mock.calls[0]?.[1] as { body?: string } | undefined; + expect(firstCall?.body).toBeDefined(); + expect(JSON.parse(firstCall?.body ?? "{}")).toMatchObject({ max_tokens: 1024 }); + }); + + it("uses expanded max_tokens for anthropic verification probes", async () => { + const prompter = createTestPrompter({ + text: ["https://example.com", "test-key", "detected-model", "custom", "alias"], + select: ["unknown"], + }); + const fetchMock = stubFetchSequence([{ ok: false, status: 404 }, { ok: true }]); + + await runPromptCustomApi(prompter); + + expect(fetchMock).toHaveBeenCalledTimes(2); + const secondCall = fetchMock.mock.calls[1]?.[1] as { body?: string } | undefined; + expect(secondCall?.body).toBeDefined(); + expect(JSON.parse(secondCall?.body ?? "{}")).toMatchObject({ max_tokens: 1024 }); + }); + it("re-prompts base url when unknown detection fails", async () => { const prompter = createTestPrompter({ text: [