feat: add Baidu AI Search backend for web_search#2371
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds Baidu AI Search as a new web search provider option. It implements the API client, result parsing, error handling, token redaction, configuration parsing, and comprehensive unit tests, alongside updating the relevant documentation. A review comment points out a discrepancy where DEEPSEEK_SEARCH_API_KEY is documented as an environment variable override but is not actually implemented in the configuration loading logic.
|
great idea - will work on getting this in soon |
Thanks Hunter! Really excited to see this move forward. Let me know if you need any changes. Happy to help with testing or updating the PR as needed :) |
|
Thanks @jimmyzhuu — an opt-in Baidu AI Search backend is directionally useful, especially for users working from China-network environments where the default web path can be brittle. I did not harvest this in today’s batch because it needs a current rebase and a very narrow provider boundary: no default search behavior change, no extra service unless explicitly configured, and mockable |
|
I rebased this onto current main and took care of the review nits while keeping the provider scope narrow:\n\n- kept Baidu as an explicit opt-in |
|
@Hmbown Thanks for handling the rebase and nits! LGTM for merge from my side. Appreciate your review :) |
Summary
This PR adds Baidu AI Search as an explicit
web_searchbackend so users in mainland China can choose a first-party, China-accessible search API instead of relying only on HTML scraping or providers that may be unreliable from Chinese networks.What changed:
SearchProvider::Baiduwith config/env selection through:[search] provider = "baidu"DEEPSEEK_SEARCH_PROVIDER=baidubaidu-searchandbaidu_ai_searchhttps://qianfan.baidubce.com/v2/ai_search/web_search.search_source: "baidu_search_v2"andresource_type_filter[].top_k.[search] api_keyDEEPSEEK_SEARCH_API_KEYBAIDU_SEARCH_API_KEYreferences[]items into the existing rankedWebSearchResponseshape.qianfan.baidubce.com.provider = "baidu"without a key returns a clear error instead of silently falling back to another provider and sending the query elsewhere.Related context:
Testing
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-featurescargo test --workspace --all-featurescargo test -p codewhale-tui baidusearch_sourcetobaidu_search_v2.cargo test -p codewhale-tui sanitize_error_body_redacts_bearer_tokenscargo test -p codewhale-tui tools::web_search::testscargo check --workspace --all-featuresBAIDU_SEARCH_API_KEY/v2/ai_search/web_searchsearch_source: "baidu_search_v2"Rust cargo workspacereferences[]returned.rg -n 'bce-v3|ALTAK|6edb0bd1c|BAIDU_SEARCH_API_KEY=.*[A-Za-z0-9]' . -SKnown baseline issue:
cargo clippy --workspace --all-targets --all-features -- -D warningscurrently fails on pre-existing warnings outside this PR:crates/tui/src/commands/config.rs:476uselessformat!crates/tui/src/runtime_log.rs:177redundant closureChecklist
Greptile Summary
This PR adds
SearchProvider::Baidubacked by the Baidu AI Search API atqianfan.baidubce.com, giving users in mainland China a first-party, API-backed search option. It also wires inDEEPSEEK_SEARCH_API_KEYviaapply_env_overrides(newly functional for all providers), fixes a pre-existing gap whereSearchProvider::parse("metaso")returnedNonesilently, and hardenssanitize_error_bodywith bearer-token redaction that now applies to all providers.run_baidu_search): resolves the API key through[search] api_key→DEEPSEEK_SEARCH_API_KEY→BAIDU_SEARCH_API_KEY, enforces network-policy checks againstqianfan.baidubce.com, and surfaces clear per-status-code error messages (401/403/429) instead of silent fallbacks.DEEPSEEK_SEARCH_API_KEYenv override added toapply_env_overrides— previously documented but not implemented — now correctly takes priority over the config-file key for all API-backed search providers.sanitize_error_bodyusing aOnceLock-compiled regex; this is a global improvement applied to Tavily, Bocha, and Metaso error paths in addition to Baidu.Confidence Score: 5/5
This PR is safe to merge. The new Baidu backend is well-isolated, fails explicitly on missing keys, and the global bearer-token redaction tightens existing error paths.
The Baidu search path correctly enforces network-policy checks, implements an explicit key-resolution chain, and returns clear errors rather than silent fallbacks. The bearer-token regex is compile-once and applied defensively. The only gap is a 401/403 error message that omits DEEPSEEK_SEARCH_API_KEY as a remediation step — easily fixed and does not affect correctness or security.
crates/tui/src/tools/web_search.rs — specifically the 401/403 error message for the Baidu provider.
Important Files Changed
Sequence Diagram
sequenceDiagram participant U as User / ToolContext participant W as WebSearchTool participant E as apply_env_overrides participant B as Baidu AI Search API Note over E: DEEPSEEK_SEARCH_API_KEY → config.search.api_key Note over E: DEEPSEEK_SEARCH_PROVIDER=baidu → SearchProvider::Baidu U->>W: "execute({query: "..."})" W->>W: check_policy("qianfan.baidubce.com") W->>W: "resolve api_key<br/>1. context.search_api_key<br/>2. BAIDU_SEARCH_API_KEY env" alt No key found W-->>U: ToolError (missing API key) end W->>B: "POST /v2/ai_search/web_search<br/>Authorization: Bearer {key}" B-->>W: "HTTP 200 {references: [...]}" W->>W: baidu_error_message() → None (success) W->>W: "parse_baidu_results() → Vec<WebSearchEntry>" W-->>U: "ToolResult {query, source:"baidu", results}"Comments Outside Diff (1)
crates/tui/src/tools/web_search.rs, line 9-10 (link)tavily/bocha/metasoand omitsbaidu. All other surfaces (tool description, config docs, TOOL_SURFACE.md) were updated — this one was missed.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reviews (3): Last reviewed commit: "Merge main into Baidu search provider" | Re-trigger Greptile