mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-08 08:57:09 +08:00
fix: use responses api for chatgpt reasoning models
This commit is contained in:
+38
-1
@@ -656,6 +656,38 @@ class LLMHelper:
|
|||||||
headers["User-Agent"] = normalized_user_agent
|
headers["User-Agent"] = normalized_user_agent
|
||||||
return headers or None
|
return headers or None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _should_use_openai_responses_api(
|
||||||
|
cls,
|
||||||
|
provider: str,
|
||||||
|
model: str | None,
|
||||||
|
runtime: dict[str, Any],
|
||||||
|
) -> bool | None:
|
||||||
|
"""
|
||||||
|
判断官方 ChatGPT API Key 模式是否应使用 Responses API。
|
||||||
|
|
||||||
|
GPT-5/o 系推理模型在 Chat Completions 中组合 function tools 与
|
||||||
|
reasoning_effort 时会被官方端点拒绝,因此 ChatGPT 官方 API Key
|
||||||
|
模式需要显式切到 Responses API;通用 OpenAI-compatible 入口保持
|
||||||
|
provider 目录解析出的默认行为,避免误伤第三方兼容服务。
|
||||||
|
"""
|
||||||
|
runtime_use_responses_api = runtime.get("use_responses_api")
|
||||||
|
if runtime_use_responses_api is not None:
|
||||||
|
return bool(runtime_use_responses_api)
|
||||||
|
|
||||||
|
provider_name = (provider or "").strip().lower()
|
||||||
|
if provider_name != "chatgpt":
|
||||||
|
return None
|
||||||
|
|
||||||
|
base_url = str(runtime.get("base_url") or "").strip().lower()
|
||||||
|
if "api.openai.com" not in base_url:
|
||||||
|
return None
|
||||||
|
|
||||||
|
model_name = cls._normalize_model_name(model)
|
||||||
|
if model_name.startswith(("gpt-5", "o1", "o3", "o4")):
|
||||||
|
return True
|
||||||
|
return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _resolve_thinking_level(
|
def _resolve_thinking_level(
|
||||||
cls,
|
cls,
|
||||||
@@ -760,6 +792,11 @@ class LLMHelper:
|
|||||||
model=model_name,
|
model=model_name,
|
||||||
thinking_level=normalized_thinking_level,
|
thinking_level=normalized_thinking_level,
|
||||||
)
|
)
|
||||||
|
use_responses_api = cls._should_use_openai_responses_api(
|
||||||
|
provider=provider_name,
|
||||||
|
model=model_name,
|
||||||
|
runtime=runtime,
|
||||||
|
)
|
||||||
|
|
||||||
if runtime["runtime"] == "google":
|
if runtime["runtime"] == "google":
|
||||||
# 修补 Gemini 2.5 思考模型的 thought_signature 兼容性
|
# 修补 Gemini 2.5 思考模型的 thought_signature 兼容性
|
||||||
@@ -832,7 +869,7 @@ class LLMHelper:
|
|||||||
stream_usage=True,
|
stream_usage=True,
|
||||||
openai_proxy=settings.PROXY_HOST,
|
openai_proxy=settings.PROXY_HOST,
|
||||||
default_headers=default_headers,
|
default_headers=default_headers,
|
||||||
use_responses_api=runtime.get("use_responses_api"),
|
use_responses_api=use_responses_api,
|
||||||
**thinking_kwargs,
|
**thinking_kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -599,6 +599,34 @@ class LlmHelperTestCallTest(unittest.TestCase):
|
|||||||
self.assertEqual(len(calls), 1)
|
self.assertEqual(len(calls), 1)
|
||||||
self.assertEqual(calls[0].get("reasoning_effort"), "xhigh")
|
self.assertEqual(calls[0].get("reasoning_effort"), "xhigh")
|
||||||
|
|
||||||
|
def test_get_llm_uses_responses_api_for_chatgpt_reasoning_models(self):
|
||||||
|
"""校验 ChatGPT 官方推理模型会切换到 Responses API。"""
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
class _FakeChatOpenAI:
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
calls.append(kwargs)
|
||||||
|
self.model = kwargs["model"]
|
||||||
|
self.profile = None
|
||||||
|
|
||||||
|
with patch.dict(
|
||||||
|
sys.modules,
|
||||||
|
{"langchain_openai": SimpleNamespace(ChatOpenAI=_FakeChatOpenAI)},
|
||||||
|
):
|
||||||
|
asyncio.run(
|
||||||
|
llm_module.LLMHelper.get_llm(
|
||||||
|
provider="chatgpt",
|
||||||
|
model="gpt-5.4",
|
||||||
|
thinking_level="max",
|
||||||
|
api_key="sk-test",
|
||||||
|
base_url="https://api.openai.com/v1",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(len(calls), 1)
|
||||||
|
self.assertTrue(calls[0].get("use_responses_api"))
|
||||||
|
self.assertEqual(calls[0].get("reasoning_effort"), "xhigh")
|
||||||
|
|
||||||
def test_get_llm_uses_gemini_builtin_thinking_controls(self):
|
def test_get_llm_uses_gemini_builtin_thinking_controls(self):
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user