fix(provider): make OpenAI-compatible reasoning field name configurable per channel (#9783) - #9829
Open
wwwwyy1 wants to merge 2 commits into
Open
fix(provider): make OpenAI-compatible reasoning field name configurable per channel (#9783)#9829wwwwyy1 wants to merge 2 commits into
wwwwyy1 wants to merge 2 commits into
Conversation
…le per channel, fixes AstrBotDevs#9783
Contributor
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="astrbot/core/provider/sources/openai_source.py" line_range="1047" />
<code_context>
- message["reasoning_content"] = reasoning_content
+ # Emit the thinking history under the configured key so
+ # channels that expect `reasoning` (issue #9783) accept it.
+ message[self.reasoning_key] = reasoning_content
if (
</code_context>
<issue_to_address>
**issue (broader_impact):** When `reasoning_key` is configured as `reasoning`, `_finally_convert_payload` writes a think-only assistant history message under `reasoning` with empty `content`, but the later `_sanitize_assistant_messages` check only recognizes `reasoning_content` and removes the message as empty. The relay therefore loses assistant reasoning history on subsequent turns.
**Triggers:** When a configured alias channel sends a subsequent request containing an assistant history message made entirely of think blocks.
**Suggested fix:** Make `_sanitize_assistant_messages` use the configured reasoning key, and invoke it as an instance method or pass `self.reasoning_key` into it.
</issue_to_address>Sourcery assessment
Approval pending. 1 finding to address first.
Blocking findings: astrbot/core/provider/sources/openai_source.py:1047
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
_sanitize_assistant_messages still hardcoded the reasoning_content field name, so think-only assistant history was dropped as garbage when the provider configured a different reasoning_key (AstrBotDevs#9783). Pass the configured key through (falling back to reasoning_content for legacy history) and cover it with tests. Address PR AstrBotDevs#9829 review feedback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #9783
Problem / 问题
The generic OpenAI-compatible provider hard-codes the thinking field name in
astrbot/core/provider/sources/openai_source.py:Different upstreams name this field differently: DeepSeek / Moonshot and most OpenAI-compatible providers use
reasoning_content, while OpenRouter and OpenRouter-style relay channels (e.g. cline-pass) usereasoning. As a result, when such a relay serves kimi-k3, thinking content is silently dropped in AstrBot even though the same API key works fine in other frontends. The repo already adapts specific sources by subclass overrides (groq_source.py/openrouter_source.pysetreasoning_key = "reasoning"), but the genericopenai_chat_completionchannel has no way to benefit.问题:openai_source.py 将思考内容字段名硬编码为 reasoning_content,而 OpenRouter 系中转渠道使用 reasoning 字段,导致思考内容完全丢失。
Solution / 修复方案
Implements Option 1 from the issue (per-channel config item, minimal change and most flexible):
self.reasoning_key = provider_config.get("reasoning_key") or "reasoning_content"— reads the field name from provider config; the default is unchanged, so existing users see zero behavior changereasoning_keyentry in the WebUI config schema (default.py, CONFIG_METADATA_2) with description / type / hint方案:按 issue 方案 1 新增渠道配置项 reasoning_key,默认值不变(存量用户零回归),WebUI 配置档可见可填。
Notable detail (hidden fix) / 隐藏点修复
_finally_convert_payloadre-emitted assistant think history asmessage["reasoning_content"]— also hard-coded. With only the extraction side fixed, a relay expectingreasoningwould still receive the next-turn history under the wrong key. This PR emits history under the same configuredself.reasoning_key.隐藏点:多轮对话历史回传同样硬编码了 reasoning_content——只修提取侧时,第二轮起上游仍收到错误字段名的思考历史。本 PR 让历史回传使用同一配置字段名。
Scope notes / 范围说明
reasoning_contenthandling in the DeepSeek-v4 / MiMo branches is intentionally untouched — that is the official DeepSeek API protocol (missing the field causes HTTP 400), unrelated to relay field dialects.Testing / 测试
3 new tests in
tests/test_openai_source.py:test_reasoning_key_configurable_extracts_alias_field— withreasoning_key: reasoning, thinking content is extracted from the alias fieldtest_reasoning_key_default_keeps_reasoning_content_behavior— without the config, behavior is unchanged (alias ignored,reasoning_contentstill works)test_reasoning_key_applied_to_assistant_history_payload— assistant think history is emitted under the configured key (andreasoning_contentis not)pytest results:
The 3 failures are the pre-existing
test_file_uri_to_path_*Windows-only path tests — verified identical on the unmodified baseline viagit stash; project CI runs on Linux.Changes / 改动文件
astrbot/core/provider/sources/openai_source.py— configurable reasoning_key for extraction + history round-tripastrbot/core/config/default.py— reasoning_key config schematests/test_openai_source.py— 3 new tests3 files, +85 / -3.
Summary by Sourcery
Make the OpenAI-compatible provider’s reasoning field configurable per channel while retaining the existing default behavior.
New Features:
Bug Fixes:
reasoninginstead ofreasoning_content, including across multi-turn assistant history.Tests: