fix(completion): auto-bridge web_search_options to Responses API

When a model has supports_web_search=True and supported_endpoints
includes /v1/responses, automatically bridge to the Responses API
when web_search_options is present. The bridge converts
web_search_options into a web_search_preview tool.

Also allow web_search_options through param validation when the
Responses API bridge is active, since the bridge handles it.

Changes:
- main.py: add auto-bridge in responses_api_bridge_check based on
  model registry fields; add web_search_options to allowed_openai_params
  when mode=responses
- types/utils.py: add supported_endpoints to ModelInfo TypedDict
- utils.py: read supported_endpoints in _get_model_info_helper
This commit is contained in:
Vigilans 2026-04-14 22:32:59 +08:00
parent 1d43f14695
commit cb8b128e2f
3 changed files with 29 additions and 0 deletions

View file

@ -981,6 +981,19 @@ def responses_api_bridge_check(
model_info["mode"] = "responses"
model = model.replace("responses/", "")
# Auto-bridge to Responses API when web_search_options is requested
# and the model supports web search and the /v1/responses endpoint,
# but its current mode is not already "responses". The bridge
# converts web_search_options into a web_search_preview tool.
if (
web_search_options is not None
and model_info.get("mode") != "responses"
and model_info.get("supports_web_search") is True
and "/v1/responses"
in (model_info.get("supported_endpoints") or [])
):
model_info["mode"] = "responses"
except Exception as e:
verbose_logger.debug("Error getting model info: {}".format(e))
@ -1554,6 +1567,20 @@ def completion( # type: ignore # noqa: PLR0915
"allowed_openai_params": kwargs.get("allowed_openai_params"),
"base_model": base_model,
}
# If the model will be bridged to the Responses API, allow params
# that the bridge can handle (e.g. web_search_options) even if the
# provider's chat/completions config doesn't list them.
if responses_api_model_info.get("mode") == "responses":
_bridge_params = []
if web_search_options is not None:
_bridge_params.append("web_search_options")
if _bridge_params:
existing = optional_param_args.get("allowed_openai_params") or []
optional_param_args["allowed_openai_params"] = list(
set(existing + _bridge_params)
)
optional_params = get_optional_params(
**optional_param_args, **non_default_params
)

View file

@ -151,6 +151,7 @@ class ProviderSpecificModelInfo(TypedDict, total=False):
bedrock_output_config_effort_ceiling: Optional[
Literal["low", "medium", "high", "max", "xhigh"]
]
supported_endpoints: Optional[list]
class SearchContextCostPerQuery(TypedDict, total=False):

View file

@ -6063,6 +6063,7 @@ def _get_model_info_helper( # noqa: PLR0915
bedrock_output_config_effort_ceiling=_model_info.get(
"bedrock_output_config_effort_ceiling", None
),
supported_endpoints=_model_info.get("supported_endpoints", None),
supports_computer_use=_model_info.get("supports_computer_use", None),
search_context_cost_per_query=_model_info.get(
"search_context_cost_per_query", None