Compare commits

...

2 Commits

Author SHA1 Message Date
Peter Steinberger
bebfab40f0 fix: harden custom-provider verification probes (#24743) (thanks @Glucksberg) 2026-02-24 03:47:32 +00:00
Glucksberg
94a5086915 fix: increase verification max_tokens to 1024 for Poe API compatibility
Poe API's Extended Thinking models (e.g. claude-sonnet-4.6) require
budget_tokens >= 1024. The previous values (5 for OpenAI, 16 for
Anthropic) caused HTTP 400 errors during provider verification.

Fixes #23433

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:47:04 +00:00
3 changed files with 32 additions and 2 deletions

View File

@@ -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.

View File

@@ -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: [

View File

@@ -303,7 +303,7 @@ async function requestOpenAiVerification(params: {
body: {
model: params.modelId,
messages: [{ role: "user", content: "Hi" }],
max_tokens: 5,
max_tokens: 1024,
},
});
}
@@ -329,7 +329,7 @@ async function requestAnthropicVerification(params: {
headers: buildAnthropicHeaders(params.apiKey),
body: {
model: params.modelId,
max_tokens: 16,
max_tokens: 1024,
messages: [{ role: "user", content: "Hi" }],
},
});