diff --git a/contributors/emails/68141859@qq.com b/contributors/emails/68141859@qq.com new file mode 100644 index 0000000000..ccb579f3ed --- /dev/null +++ b/contributors/emails/68141859@qq.com @@ -0,0 +1 @@ +lyswty diff --git a/plugins/web/openai_native/plugin.yaml b/plugins/web/openai_native/plugin.yaml index cc621c0751..a00054eacd 100644 --- a/plugins/web/openai_native/plugin.yaml +++ b/plugins/web/openai_native/plugin.yaml @@ -1,6 +1,6 @@ name: web-openai-native version: 1.0.0 -description: "OpenAI native web search — declares the Responses API server-side ``web_search`` built-in instead of running a client-side search. Requires the Codex Responses transport plus openai-codex OAuth (``hermes auth --provider openai-codex``)." +description: "OpenAI native web search — declares the Responses API server-side ``web_search`` built-in instead of running a client-side search. Requires the Codex Responses transport plus openai-codex OAuth (``hermes auth add openai-codex``)." author: NousResearch kind: backend provides_web_providers: diff --git a/plugins/web/openai_native/provider.py b/plugins/web/openai_native/provider.py index 4bbb7331e3..c9d2a07ae0 100644 --- a/plugins/web/openai_native/provider.py +++ b/plugins/web/openai_native/provider.py @@ -1,7 +1,7 @@ """OpenAI native web search — declares the Responses API server-side ``web_search`` built-in. Config: ``web.search_backend: openai-native`` (or ``web.backend``). -Auth: openai-codex OAuth (``hermes auth --provider openai-codex``); no API key of its own. +Auth: openai-codex OAuth (``hermes auth add openai-codex``); no API key of its own. Unlike every other provider here, this one never executes a search itself. Selecting it tells the Codex Responses transport to declare the provider-executed ``web_search`` tool @@ -83,6 +83,6 @@ class OpenAINativeWebSearchProvider(BaseWebSearchProvider): return setup_schema( self.DISPLAY_NAME, "native", - "由模型服务端执行搜索(需 Codex Responses transport + openai-codex 登录);仅搜索,提取仍用其他后端", + "Search runs on the provider side (needs the Codex Responses transport + an openai-codex login); search only, extraction still uses another backend", "", ) diff --git a/tests/plugins/web/test_web_search_provider_plugins.py b/tests/plugins/web/test_web_search_provider_plugins.py index 5377243340..446ff719b8 100644 --- a/tests/plugins/web/test_web_search_provider_plugins.py +++ b/tests/plugins/web/test_web_search_provider_plugins.py @@ -82,6 +82,7 @@ class TestBundledPluginsRegister: "exa", "firecrawl", "keenable", + "openai-native", "parallel", "perplexity", "searxng", @@ -103,6 +104,9 @@ class TestBundledPluginsRegister: ("firecrawl", True, True), # xai: search-only via Grok's agentic web_search tool. ("xai", True, False), + # openai-native: marker for the Codex Responses server-side web_search swap; + # search-only, so web_extract keeps its own backend (#19320). + ("openai-native", True, False), ], ) def test_capability_flags_match_spec( @@ -121,7 +125,7 @@ class TestBundledPluginsRegister: @pytest.mark.parametrize( "plugin_name", - ["brave-free", "ddgs", "searxng", "exa", "parallel", "tavily", "perplexity", "firecrawl", "keenable", "xai"], + ["brave-free", "ddgs", "searxng", "exa", "parallel", "tavily", "perplexity", "firecrawl", "keenable", "xai", "openai-native"], ) def test_each_plugin_has_name_and_display_name(self, plugin_name: str) -> None: _ensure_plugins_loaded() diff --git a/website/docs/user-guide/features/web-search.md b/website/docs/user-guide/features/web-search.md index 37f458932e..caabfcb24f 100644 --- a/website/docs/user-guide/features/web-search.md +++ b/website/docs/user-guide/features/web-search.md @@ -28,7 +28,7 @@ Both are configured through a single backend selection. Providers are chosen via | **Perplexity** | `PERPLEXITY_API_KEY` | ✔ | ✔ (query-relevant snippets) | Paid (per-request Search API pricing) | | **Keenable** | `KEENABLE_API_KEY` (optional) | ✔ | ✔ | ✔ Keyless ring member · paid with key | | **xAI (Grok)** | `XAI_API_KEY` or `hermes auth add xai-oauth` | ✔ | — | Paid (SuperGrok or per-token) | -| **OpenAI Native (Codex)** | `hermes auth --provider openai-codex` | ✔ | — | Requires a ChatGPT/Codex subscription | +| **OpenAI Native (Codex)** | `hermes auth add openai-codex` | ✔ | — | Requires a ChatGPT/Codex subscription | Brave Search, DDGS, xAI, and OpenAI Native are **search-only** — pair any of them with Firecrawl/Tavily/Perplexity/Keenable/Exa/Parallel when you also need `web_extract`. DDGS uses the [`ddgs` Python package](https://pypi.org/project/ddgs/) under the hood; if it isn't already installed, run `pip install ddgs` (or let Hermes lazy-install it on first use). xAI runs Grok's server-side `web_search` tool on the Responses API — results are LLM-generated rather than index-backed, so titles, descriptions, and URL choice are all model output (see the [trust-model caveat](#xai-grok) below). OpenAI Native declares the same kind of provider-executed tool on the Codex Responses endpoint (see [below](#openai-native)). @@ -388,7 +388,7 @@ web: Requirements and scope: -- **Credentials**: an openai-codex OAuth login (`hermes auth --provider openai-codex`). This backend has no API key of its own; without a login it is simply unavailable. +- **Credentials**: an openai-codex OAuth login (`hermes auth add openai-codex`). This backend has no API key of its own; without a login it is simply unavailable. - **Transport**: only the Codex Responses endpoint exposes the built-in. On any other transport — a custom OpenAI-compatible `base_url`, or a non-OpenAI model — the client-side `web_search` function is left untouched, because the endpoint cannot be relied on to host the tool. Point `web.search_backend` at an ordinary provider for those. - **Search only**: the built-in covers search, not extraction. Pair it with Firecrawl (or another extract-capable backend) through `web.extract_backend` when you also need `web_extract`.