Skip to content

fix(agents): normalize SiliconFlow Pro thinking=off payload to avoid 400 loop / 修复 SiliconFlow Pro thinking=off 触发 400#25435

Closed
Zjianru wants to merge 1 commit intoopenclaw:mainfrom
Zjianru:codex/siliconflow-thinking-off-compat
Closed

fix(agents): normalize SiliconFlow Pro thinking=off payload to avoid 400 loop / 修复 SiliconFlow Pro thinking=off 触发 400#25435
Zjianru wants to merge 1 commit intoopenclaw:mainfrom
Zjianru:codex/siliconflow-thinking-off-compat

Conversation

@Zjianru
Copy link
Contributor

@Zjianru Zjianru commented Feb 24, 2026

Summary

  • Problem: SiliconFlow Pro/* models reject payloads containing thinking: "off" with HTTP 400 (code: 20015), and embedded runs then fall into compaction/retry loops.
  • Why it matters: users see "compact every turn" behavior in fresh sessions, with misleading context-overflow symptoms.
  • What changed: added a SiliconFlow compatibility wrapper that normalizes payload thinking: "off" to thinking: null for siliconflow/Pro/* models.
  • What did NOT change (scope boundary): no model routing changes, no fallback policy changes, no behavior change for non-SiliconFlow or non-Pro/* model IDs.

中文摘要

  • 问题:SiliconFlow Pro/* 模型会拒绝 thinking: "off"(HTTP 400,code: 20015),并导致 embedded run 进入 compaction/retry 循环。
  • 影响:用户在 fresh session 也会出现“每轮都 compact”的误导性现象。
  • 改动:增加 SiliconFlow 兼容包装器,对 siliconflow/Pro/*thinking=off 的请求将 payload 归一为 thinking: null
  • 范围外:不改模型路由、不改 fallback 策略、不影响非 SiliconFlow 或非 Pro/* 模型。

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

  • For SiliconFlow Pro/* models, thinking=off no longer triggers immediate 400 + compaction loop.
  • Non-Pro/* SiliconFlow model IDs keep existing behavior.

中文(用户可见行为)

  • 对 SiliconFlow Pro/* 模型,thinking=off 不再触发 400 + compaction 循环。
  • Pro/* SiliconFlow model ID 保持现有行为。

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local pnpm test
  • Model/provider: siliconflow Pro/* models via openai-completions
  • Integration/channel (if any): embedded run path (WebUI symptom)
  • Relevant config (redacted): thinkingDefault: "off"

Steps

  1. Set primary model to a SiliconFlow Pro/* model.
  2. Keep thinking level off.
  3. Send a normal message.

Expected

  • Request should not fail due to thinking: "off" payload incompatibility.

Actual (before fix)

  • HTTP 400 followed by compaction retry loops.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Tests

  • pnpm test src/agents/pi-embedded-runner-extraparams.test.ts
  • Added:
    • normalizes thinking=off to null for SiliconFlow Pro models
    • keeps thinking=off unchanged for non-Pro SiliconFlow model IDs

Human Verification (required)

  • Verified scenarios: wrapper rewrites thinking: "off" to null only for siliconflow/Pro/*; existing OpenRouter and Bedrock tests remain green.
  • Edge cases checked: non-Pro/* SiliconFlow IDs are not rewritten.
  • What you did not verify: full live gateway end-to-end on remote deployment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this commit.
  • Files/config to restore: src/agents/pi-embedded-runner/extra-params.ts and related test file.
  • Known bad symptoms reviewers should watch for: if a SiliconFlow Pro/* endpoint starts requiring string thinking enums, this normalization would need reevaluation.

Risks and Mitigations

  • Risk: behavior divergence between Pro/* and non-Pro/* SiliconFlow model IDs could confuse operators.
    • Mitigation: logic is explicitly gated and covered by tests; rationale is documented inline.

Greptile Summary

Adds a targeted compatibility fix for SiliconFlow Pro/* models that reject thinking: "off" payloads with HTTP 400 errors. The implementation wraps the stream function to normalize thinking: "off" to thinking: null for affected models, preventing compaction/retry loops in embedded runs.

The fix is narrowly scoped with proper guard conditions (provider = siliconflow, model starts with Pro/, thinking level = off) and follows established wrapper patterns. Test coverage includes both the positive case (Pro models get normalization) and negative case (non-Pro models unchanged).

Confidence Score: 5/5

  • Safe to merge with minimal risk
  • The PR implements a narrowly-scoped compatibility fix with proper guard conditions, follows established patterns, includes comprehensive test coverage for both affected and unaffected cases, and does not change behavior for any other providers or model types. The fix directly addresses a documented API incompatibility without introducing side effects.
  • No files require special attention

Last reviewed commit: 26a79a6

@Zjianru
Copy link
Contributor Author

Zjianru commented Feb 24, 2026

中文

Hi maintainers,

此 PR 已完成修复并通过所有 CI 检查(见上方 Greptile Review 5/5 评分)。修复内容:

  • 对 SiliconFlow Pro/* 模型的 thinking=off 归一化为 thinking: null
  • 避免了 HTTP 400 错误和后续的 compaction/retry 循环
  • 测试覆盖了正向和负向 case

请求审核合并,感谢!


English

Hi maintainers,

This PR is ready with all CI checks passing (see Greptile Review 5/5 score above). Changes:

  • Normalizes thinking=off to thinking: null for SiliconFlow Pro/* models
  • Avoids HTTP 400 errors and subsequent compaction/retry loops
  • Test coverage for both positive and negative cases

Requesting review and merge. Thank you!

steipete added a commit that referenced this pull request Feb 25, 2026
Land PR #25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
@steipete
Copy link
Contributor

Landed manually via /landpr flow after maintainer re-review and full local gate.

What was validated:

  • Read call path in applyExtraParamsToAgent + embedded run wiring.
  • Confirmed wrapper only applies to siliconflow + Pro/* + thinking=off.
  • Ran full gate on landing branch: pnpm lint && pnpm build && pnpm test.

What landed:

  • Landed commit on main: bd213cf2ad05a5443df96364c4ff0afa7c8a4bf0
  • Based on contributor PR commit: 26a79a6b6e0dffb65aec23a9568401b8a2d1f91d
  • Included changelog line in 2026.2.24 (Unreleased) with PR+author credit.

Thanks for the fix and tests, @Zjianru.

@steipete steipete closed this Feb 25, 2026
gavinwxx-vybers added a commit to Vybers-AI/openclaw that referenced this pull request Feb 25, 2026
* ui: block svg data image opens and harden tests

* changelog: credit both chat-image fix contributors

* test(ui): reject base64 SVG data URLs

* changelog: include openclaw#25847 in chat image safety entry (openclaw#25847) (thanks @shakkernerd)

* refactor(ios): drop legacy talk payload and keychain fallbacks

* chore: sync plugin versions to 2026.2.24

* chore: refresh lockfile after plugin devDependency cleanup

* fix(config): soften antigravity removal fallout (openclaw#25538)

Land openclaw#25538 by @chilu18 to keep legacy google-antigravity-auth config entries non-fatal after removal (see openclaw#25862).

Co-authored-by: chilu18 <chilu.machona@icloud.com>

* fix(security): lock sandbox tmp media paths to openclaw roots

* docs(security): document openclaw temp-folder boundary

* fix(security): restrict default safe-bin trusted dirs

* fix: enforce local media root checks for attachment hydration

* fix(synology-chat): fail closed empty allowlist

* docs(changelog): add synology-chat allowlist fail-closed note

* fix: harden routing/session isolation for followups and heartbeat

* feat(sandbox): block container namespace joins by default

* refactor(sandbox): centralize network mode policy helpers

* fix(channels,sandbox): land hard breakage cluster from reviewed PR bases

Lands reviewed fixes based on openclaw#25839 (@pewallin), openclaw#25841 (@joshjhall), and openclaw#25737/@25713 (@DennisGoldfinger/@peteragility), with additional hardening + regression tests for queue cleanup and shell script safety.

Fixes openclaw#25836
Fixes openclaw#25840
Fixes openclaw#25824
Fixes openclaw#25868

Co-authored-by: Peter Wallin <pwallin@gmail.com>
Co-authored-by: Joshua Hall <josh@yaplabs.com>
Co-authored-by: Dennis Goldfinger <dennisgoldfinger@gmail.com>
Co-authored-by: peteragility <peteragility@users.noreply.github.com>

* refactor(synology-chat): centralize DM auth and fail fast startup

* test: add routing/session isolation edge-case regressions

* refactor: centralize followup origin routing helpers

* refactor(outbound): centralize attachment media policy

* refactor: harden safe-bin trusted dir diagnostics

* fix(zalo): enforce group sender policy in groups

* docs: update changelog for safe-bin hardening

* test(line): align tmp-root expectation after sandbox hardening

* fix(web-search): reduce provider auto-detect log noise

* test(matrix,discord,sandbox): expand breakage regression coverage

* refactor(matrix,tests): extract helpers and inject send-queue timing

* refactor(zalo): split monitor access and webhook logic

* Gateway/Security: protect /api/channels plugin root

* fix(telegram): block unauthorized DM media downloads

* Security: sanitize inherited host exec env

* Changelog: add entry for exec env sanitization

* fix(security): classify hook sessions case-insensitively

* refactor(outbound): unify attachment hydration flow

* refactor(telegram): simplify DM media auth precheck flow

* fix(automation): harden announce delivery + cron coding profile (openclaw#25813 openclaw#25821 openclaw#25822)

Co-authored-by: Shawn <shenghuikevin@shenghuideMac-mini.local>
Co-authored-by: 不做了睡大觉 <user@example.com>
Co-authored-by: Marcus Widing <widing.marcus@gmail.com>

* security(voice-call): detect Telnyx webhook replay

* Auto-reply: add exact stop trigger for do not do that

* Auto-reply tests: assert exact do not do that behavior

* Gateway tests: cover exact do not do that stop matching

* Telegram tests: route exact do not do that to control lane

* Changelog: note exact do not do that stop trigger

* refactor(tmp): harden temp boundary guardrails

* fix(whatsapp): stop retry loop on non-retryable 440 close

* test(types): fix ts narrowing regressions in followup and matrix queue tests

* fix(onboard): avoid false 'telegram plugin not available' block

* fix: normalize "bedrock" provider ID to "amazon-bedrock"

Add "bedrock" and "aws-bedrock" as aliases for the canonical
"amazon-bedrock" provider ID in normalizeProviderId().

Without this mapping, configuring a model as "bedrock/..." causes
the auth resolution fallback to miss the Bedrock-specific AWS SDK
path, since the fallback check requires normalized === "amazon-bedrock".
This primarily affects the main agent when the explicit auth override
is not preserved through config merging.

Fixes openclaw#15716

* docs(changelog): backfill landed fix PR entries

* fix(security): harden system.run companion command binding

* fix(discord): land proxy/media/reaction/model-picker regressions

Reimplements core Discord fixes from openclaw#25277 openclaw#25523 openclaw#25575 openclaw#25588 openclaw#25731 with expanded tests.

- thread proxy-aware fetch into inbound attachment/sticker downloads
- fetch /gateway/bot via proxy dispatcher before ws connect
- wire statusReactions emojis/timing overrides into controller
- compact model-picker custom_id keys with backward-compatible parsing

Co-authored-by: openperf <openperf@users.noreply.github.com>
Co-authored-by: chilu18 <chilu18@users.noreply.github.com>
Co-authored-by: Yipsh <Yipsh@users.noreply.github.com>
Co-authored-by: lbo728 <lbo728@users.noreply.github.com>
Co-authored-by: s1korrrr <s1korrrr@users.noreply.github.com>

* docs(changelog): add reporter credit for exec companion hardening

* fix(macos): guard voice audio paths with no input device (openclaw#25817)

Co-authored-by: Stefan Förster <103369858+sfo2001@users.noreply.github.com>

* fix(macos): prefer openclaw binary while keeping pnpm fallback (openclaw#25512)

Co-authored-by: Peter Machona <7957943+chilu18@users.noreply.github.com>

* Auth: bypass cooldown tracking for OpenRouter

* Auth: use cooldown helper in explicit profile order

* Tests: cover OpenRouter cooldown display bypass

* Tests: skip OpenRouter failure cooldown persistence

* Tests: keep OpenRouter runnable with legacy cooldown markers

* Tests: preserve OpenRouter explicit auth order under cooldown fields

* Changelog: note OpenRouter cooldown bypass

* Changelog: remove unrelated session entries from PR

* Update CHANGELOG.md

* fix(macos): default voice wake forwarding to webchat (openclaw#25440)

Co-authored-by: Peter Machona <7957943+chilu18@users.noreply.github.com>

* fix(macos): keep Return for IME marked text commit (openclaw#25178)

Co-authored-by: jft0m <9837901+bottotl@users.noreply.github.com>

* fix(security): block env depth-overflow approval bypass

* fix(macos): resolve webchat panel corner clipping (openclaw#22458)

Co-authored-by: apethree <3081182+apethree@users.noreply.github.com>
Co-authored-by: agisilaos <3073709+agisilaos@users.noreply.github.com>

* Agents: trust explicit allowlist refs beyond catalog

* Tests: cover allowlist refs missing from catalog

* Gateway tests: accept allowlisted refs absent from catalog

* Gateway tests: include synthetic allowlist models in models.list

* Changelog: note allowlist stale-catalog model selection fix

* fix(discord): harden voice DAVE receive reliability (openclaw#25861)

Reimplements and consolidates related work:
- openclaw#24339 stale disconnect/destroyed session guards
- openclaw#25312 voice listener cleanup on stop
- openclaw#23036 restore @snazzah/davey runtime dependency

Adds Discord voice DAVE config passthrough, repeated decrypt failure
rejoin recovery, regression tests, docs, and changelog updates.

Co-authored-by: Frank Yang <frank.ekn@gmail.com>
Co-authored-by: Do Cao Hieu <admin@docaohieu.com>

* fix(macos): clean warnings and harden gateway/talk config parsing

* docs(discord): document DAVE defaults and decrypt recovery

* test: bridge discord voice private casts via unknown

* docs(changelog): remove next-release shipping sentence

* refactor(exec): split system.run phases and align ts/swift validator contracts

* fix(windows): skip unreliable dev comparison in fs-safe openVerifiedLocalFile

On Windows, device IDs (dev) returned by handle.stat() and fs.lstat()
may differ even for the same file, causing false-positive 'path-mismatch'
errors when reading local media files.

This fix introduces a statsMatch() helper that:
- Always compares inode (ino) values
- Skips device ID (dev) comparison on Windows where it's unreliable
- Maintains full comparison on Unix platforms

Fixes openclaw#25699

* fix: align windows safe-open file identity checks

* refactor: dedupe exec wrapper denial plan and test setup

* fix: harden iMessage echo dedupe and reasoning suppression (openclaw#25897)

* test(media): add win32 dev=0 local media regression

* refactor: extract iMessage echo cache and unify suppression guards

* test: normalize tmp media path assertion for windows

* fix(render): seed Control UI origin config on first boot

The gateway requires controlUi.allowedOrigins when binding to LAN.
On Render, the persistent disk starts empty with no openclaw.json.
Seed a minimal config with dangerouslyAllowHostHeaderOriginFallback
on first boot (safe behind Render's HTTPS reverse proxy).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(deps): update dependencies except carbon

* fix(agents): normalize SiliconFlow Pro thinking=off payload (openclaw#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>

* fix(telegram): refresh global undici dispatcher for autoSelectFamily (openclaw#25682)

Land PR openclaw#25682 from @lairtonlelis after maintainer rework:
track dispatcher updates when network decision changes to avoid stale global fetch behavior.

Co-authored-by: Ailton <lairton@telnyx.com>

* fix(synology-chat): land @bmendonca3 fail-closed allowlist follow-up (openclaw#25827)

Carry fail-closed empty-allowlist guard clarity and changelog attribution for PR openclaw#25827.

Co-authored-by: Brian Mendonca <brianmendonca@Brians-MacBook-Air.local>

* fix(agents): reduce billing false positives on long text (openclaw#25680)

Land PR openclaw#25680 from @lairtonlelis.
Retain explicit status/code/http 402 detection for oversized structured payloads.

Co-authored-by: Ailton <lairton@telnyx.com>

* fix(render): add docker entrypoint script for config seeding

The inline shell command in render.yaml's dockerCommand wasn't
reliably creating the seed config. Replace with a proper entrypoint
script that creates a minimal openclaw.json with
dangerouslyAllowHostHeaderOriginFallback on first boot, then starts
the gateway bound to LAN on the PORT env var.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ui): inherit default model fallbacks in agents overview (openclaw#25729)

Land PR openclaw#25729 from @Suko.
Use shared fallback-resolution helper and add regression coverage for default, override, and explicit-empty cases.

Co-authored-by: suko <miha.sukic@gmail.com>

* fix(heartbeat): default target none and internalize relay prompts

* test(windows): normalize risky-path assertions

---------

Co-authored-by: Shakker <shakkerdroid@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: chilu18 <chilu.machona@icloud.com>
Co-authored-by: Peter Wallin <pwallin@gmail.com>
Co-authored-by: Joshua Hall <josh@yaplabs.com>
Co-authored-by: Dennis Goldfinger <dennisgoldfinger@gmail.com>
Co-authored-by: peteragility <peteragility@users.noreply.github.com>
Co-authored-by: Brian Mendonca <brianmendonca@Brians-MacBook-Air.local>
Co-authored-by: Shawn <shenghuikevin@shenghuideMac-mini.local>
Co-authored-by: 不做了睡大觉 <user@example.com>
Co-authored-by: Marcus Widing <widing.marcus@gmail.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Mark Musson <mark@musson.co.za>
Co-authored-by: suko <miha.sukic@gmail.com>
Co-authored-by: Fred White <fwhite13@users.noreply.github.com>
Co-authored-by: openperf <openperf@users.noreply.github.com>
Co-authored-by: chilu18 <chilu18@users.noreply.github.com>
Co-authored-by: Yipsh <Yipsh@users.noreply.github.com>
Co-authored-by: lbo728 <lbo728@users.noreply.github.com>
Co-authored-by: s1korrrr <s1korrrr@users.noreply.github.com>
Co-authored-by: Stefan Förster <103369858+sfo2001@users.noreply.github.com>
Co-authored-by: Peter Machona <7957943+chilu18@users.noreply.github.com>
Co-authored-by: jft0m <9837901+bottotl@users.noreply.github.com>
Co-authored-by: apethree <3081182+apethree@users.noreply.github.com>
Co-authored-by: agisilaos <3073709+agisilaos@users.noreply.github.com>
Co-authored-by: Frank Yang <frank.ekn@gmail.com>
Co-authored-by: Do Cao Hieu <admin@docaohieu.com>
Co-authored-by: Gavin X. Wang <gavinvybers@Gavins-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: codez <codezhujr@gmail.com>
Co-authored-by: Ailton <lairton@telnyx.com>
joshavant pushed a commit that referenced this pull request Feb 25, 2026
Land PR #25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
margulans pushed a commit to margulans/Neiron-AI-assistant that referenced this pull request Feb 25, 2026
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
Jackson3195 pushed a commit to Jackson3195/openclaw-with-a-personal-touch that referenced this pull request Feb 25, 2026
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
brianleach pushed a commit to brianleach/openclaw that referenced this pull request Feb 26, 2026
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
execute008 pushed a commit to execute008/openclaw that referenced this pull request Feb 27, 2026
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
thebenjaminlee pushed a commit to escape-velocity-ventures/openclaw that referenced this pull request Mar 7, 2026
…#25435)

Land PR openclaw#25435 from @Zjianru.
Changelog: add 2026.2.24 fix entry with contributor credit.

Co-authored-by: codez <codezhujr@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

2 participants