feat: Enhance OpenAI provider configuration with extraBody support and apiType validation

This commit is contained in:
outlook84
2026-05-25 01:23:36 +08:00
committed by Xubin Ren
parent d472595417
commit c433d60681
9 changed files with 230 additions and 29 deletions
+47 -5
View File
@@ -274,6 +274,47 @@ def _deep_merge(base: dict[str, Any], override: dict[str, Any]) -> dict[str, Any
return merged
def _merge_unique_list(base: Any, override: Any) -> Any:
"""Append list values while preserving order and removing duplicates."""
if not isinstance(base, list) or not isinstance(override, list):
return override
result: list[Any] = []
seen: set[str] = set()
for value in [*base, *override]:
try:
key = json.dumps(value, sort_keys=True, ensure_ascii=False)
except Exception:
key = repr(value)
if key in seen:
continue
seen.add(key)
result.append(value)
return result
def _merge_responses_extra_body(
body: dict[str, Any],
extra_body: dict[str, Any],
) -> dict[str, Any]:
"""Merge configured Responses API body fields without clobbering tools."""
reserved = {"include", "tools"}
regular_extra = {key: value for key, value in extra_body.items() if key not in reserved}
merged = _deep_merge(body, regular_extra)
if "include" in extra_body:
merged["include"] = _merge_unique_list(body.get("include"), extra_body["include"])
if "tools" in extra_body:
current_tools = body.get("tools")
configured_tools = extra_body["tools"]
if isinstance(current_tools, list) and isinstance(configured_tools, list):
merged["tools"] = [*current_tools, *configured_tools]
else:
merged["tools"] = configured_tools
return merged
class OpenAICompatProvider(LLMProvider):
"""Unified provider for all OpenAI-compatible APIs.
@@ -296,7 +337,7 @@ class OpenAICompatProvider(LLMProvider):
self.extra_headers = extra_headers or {}
self._spec = spec
self._extra_body = extra_body or {}
self._api_type = api_type
self._api_type = api_type if spec and spec.name == "openai" else "auto"
if api_key and spec and spec.env_key:
self._setup_env(api_key, api_base)
@@ -697,12 +738,9 @@ class OpenAICompatProvider(LLMProvider):
if self._api_type == "chat_completions":
return False
if self._spec and self._spec.name not in ("openai", "github_copilot"):
if self._api_type != "responses":
return False
return False
if self._api_type == "responses":
return self._responses_circuit_allows_probe(model, reasoning_effort)
if self._spec and self._spec.name not in ("openai", "github_copilot"):
return False
if self._spec is None or self._spec.name != "github_copilot":
if not _is_direct_openai_base(self._effective_base):
return False
@@ -815,6 +853,10 @@ class OpenAICompatProvider(LLMProvider):
body["tools"] = convert_tools(tools)
body["tool_choice"] = tool_choice or "auto"
extra_body = getattr(self, "_extra_body", {})
if extra_body:
body = _merge_responses_extra_body(body, extra_body)
return body
# ------------------------------------------------------------------