From 12828d748ff98c40cb927cff6c65f2cae552454e Mon Sep 17 00:00:00 2001 From: alectimison-maker Date: Sun, 2 Aug 2026 14:34:13 +0800 Subject: [PATCH 1/2] agent: add adapter for Baidu Search --- src/chrome/src/agent/adapters.js | 15 +++++++++++ src/firefox/src/agent/adapters.js | 15 +++++++++++ test/run.js | 45 +++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/src/chrome/src/agent/adapters.js b/src/chrome/src/agent/adapters.js index 75dbeb806..ac0f055cf 100644 --- a/src/chrome/src/agent/adapters.js +++ b/src/chrome/src/agent/adapters.js @@ -15815,6 +15815,21 @@ const ADAPTERS = [ - Put constraints in the query instead of post-filtering: \`site:\`, \`filetype:\`, \`intitle:\`, \`"exact phrase"\`, \`-exclude\`, and \`before:\`/\`after:\` for dates. - Do NOT rely on \`&num=100\` to load more results per page — Google removed that in 2025; paginate via the "Next" link / \`&start=10\` (20, 30…). - Results are personalized and localized (location, sign-in, history); you can't fully neutralize that from the URL, so flag it when the user needs unbiased results.`, + }, + { + name: 'baidu-search', + category: 'general', + matches: (url) => /^https?:\/\/(?:(?:www|m|image|video|passport|wappass)\.)?baidu\.com\//.test(url), + notes: ` +- Treat baidu.com, www.baidu.com, m.baidu.com, image.baidu.com, video.baidu.com, passport.baidu.com, and wappass.baidu.com as Baidu search surfaces as of 2026-08. Enter the query in the main field and activate "百度一下"; preserve the exact query when a login or interstitial interrupts navigation. +- Switch deliberately among "网页", "资讯", "视频", and "图片" because each tab changes the result type and may move to another matched host. Re-read the result list after switching instead of reusing card positions or labels. +- Treat results marked "广告" or "商业推广" as paid placements. Do not report the first visible card as the top organic result, and do not treat a claimed "官方" label as proof without checking the destination domain. +- Treat "文心助手" and other AI-generated answer blocks as synthesized content, not independent search results or primary evidence. Follow and verify their cited source links before using factual claims, especially for medical, legal, financial, or safety-sensitive questions. +- Follow the page's actual href when a result uses www.baidu.com/link?url=... and record the final destination after the redirect. Do not infer the target domain from the title, snippet, favicon, or displayed URL alone. +- Collect each result's title, snippet, and final link before selecting "下一页". Result positions can change with location, history, experiments, and time; use query operators such as site:, filetype:, quoted phrases, and exclusions when the user needs reproducible constraints. +- Use image or video cards only after opening the source page or detail view; thumbnails, captions, and neighboring card text can be mismatched or truncated, and lazy-loaded card indices are not stable after scrolling. +- Read-only web search and result opening do not require sign-in. If "登录" or "扫码登录" appears, ask the user to authenticate only for an explicitly requested account feature; do not block ordinary search, loop on the dialog, or claim that login is required for public results. +- If wappass.baidu.com/static/captcha shows "百度安全验证", stop and ask the user to complete it manually. After completion, continue the encoded backurl and re-read the results; do not bypass the challenge, discard the query, or loop on the search URL.`, }, { name: 'slack', diff --git a/src/firefox/src/agent/adapters.js b/src/firefox/src/agent/adapters.js index 711de3248..c5c7002e5 100644 --- a/src/firefox/src/agent/adapters.js +++ b/src/firefox/src/agent/adapters.js @@ -15814,6 +15814,21 @@ const ADAPTERS = [ - Put constraints in the query instead of post-filtering: \`site:\`, \`filetype:\`, \`intitle:\`, \`"exact phrase"\`, \`-exclude\`, and \`before:\`/\`after:\` for dates. - Do NOT rely on \`&num=100\` to load more results per page — Google removed that in 2025; paginate via the "Next" link / \`&start=10\` (20, 30…). - Results are personalized and localized (location, sign-in, history); you can't fully neutralize that from the URL, so flag it when the user needs unbiased results.`, + }, + { + name: 'baidu-search', + category: 'general', + matches: (url) => /^https?:\/\/(?:(?:www|m|image|video|passport|wappass)\.)?baidu\.com\//.test(url), + notes: ` +- Treat baidu.com, www.baidu.com, m.baidu.com, image.baidu.com, video.baidu.com, passport.baidu.com, and wappass.baidu.com as Baidu search surfaces as of 2026-08. Enter the query in the main field and activate "百度一下"; preserve the exact query when a login or interstitial interrupts navigation. +- Switch deliberately among "网页", "资讯", "视频", and "图片" because each tab changes the result type and may move to another matched host. Re-read the result list after switching instead of reusing card positions or labels. +- Treat results marked "广告" or "商业推广" as paid placements. Do not report the first visible card as the top organic result, and do not treat a claimed "官方" label as proof without checking the destination domain. +- Treat "文心助手" and other AI-generated answer blocks as synthesized content, not independent search results or primary evidence. Follow and verify their cited source links before using factual claims, especially for medical, legal, financial, or safety-sensitive questions. +- Follow the page's actual href when a result uses www.baidu.com/link?url=... and record the final destination after the redirect. Do not infer the target domain from the title, snippet, favicon, or displayed URL alone. +- Collect each result's title, snippet, and final link before selecting "下一页". Result positions can change with location, history, experiments, and time; use query operators such as site:, filetype:, quoted phrases, and exclusions when the user needs reproducible constraints. +- Use image or video cards only after opening the source page or detail view; thumbnails, captions, and neighboring card text can be mismatched or truncated, and lazy-loaded card indices are not stable after scrolling. +- Read-only web search and result opening do not require sign-in. If "登录" or "扫码登录" appears, ask the user to authenticate only for an explicitly requested account feature; do not block ordinary search, loop on the dialog, or claim that login is required for public results. +- If wappass.baidu.com/static/captcha shows "百度安全验证", stop and ask the user to complete it manually. After completion, continue the encoded backurl and re-read the results; do not bypass the challenge, discard the query, or loop on the search URL.`, }, { name: 'slack', diff --git a/test/run.js b/test/run.js index be502ef6e..28e8d8319 100644 --- a/test/run.js +++ b/test/run.js @@ -2271,6 +2271,51 @@ test('matches google search across TLDs and includes udm=14, without hijacking o assert.match(a?.notes || '', /udm=14/); }); +test('matches Baidu search surfaces without hijacking other Baidu products', () => { + const trustedUrls = [ + 'https://baidu.com/', + 'https://www.baidu.com/', + 'https://www.baidu.com/s?wd=webbrain', + 'https://www.baidu.com/link?url=opaque-result', + 'https://m.baidu.com/s?word=webbrain', + 'https://image.baidu.com/search/index?tn=baiduimage&word=webbrain', + 'https://video.baidu.com/v?word=webbrain', + 'https://passport.baidu.com/v2/?login', + 'https://wappass.baidu.com/static/captcha/tuxing_v2.html?backurl=https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3Dwebbrain', + ]; + for (const url of trustedUrls) { + assert.equal(getActiveAdapter(url)?.name, 'baidu-search'); + assert.equal(getActiveAdapterFx(url)?.name, 'baidu-search'); + } + + const rejectedUrls = [ + 'https://map.baidu.com/', + 'https://tieba.baidu.com/', + 'https://pan.baidu.com/', + 'https://baike.baidu.com/', + 'https://www.baidu.com.phishing.example/s?wd=webbrain', + 'https://example.com/?next=https://www.baidu.com/s?wd=webbrain', + ]; + for (const url of rejectedUrls) { + assert.notEqual(getActiveAdapter(url)?.name, 'baidu-search'); + assert.notEqual(getActiveAdapterFx(url)?.name, 'baidu-search'); + } + + const adapter = getActiveAdapter('https://www.baidu.com/s?wd=webbrain'); + const firefoxAdapter = getActiveAdapterFx('https://image.baidu.com/search/index?word=webbrain'); + assert.match(adapter?.notes || '', /2026-08/); + assert.match(adapter?.notes || '', /百度一下/); + assert.match(adapter?.notes || '', /网页.*资讯.*视频.*图片/s); + assert.match(adapter?.notes || '', /广告|商业推广/); + assert.match(adapter?.notes || '', /文心助手|AI/); + assert.match(adapter?.notes || '', /www\.baidu\.com\/link\?url=/); + assert.match(adapter?.notes || '', /下一页/); + assert.match(adapter?.notes || '', /登录.*扫码|扫码.*登录/s); + assert.match(adapter?.notes || '', /wappass\.baidu\.com.*百度安全验证.*backurl/s); + assert.match(adapter?.notes || '', /do not require sign-in/i); + assert.equal(firefoxAdapter?.notes, adapter?.notes); +}); + test('matches twitter.com and x.com', () => { assert.equal(getActiveAdapter('https://twitter.com/elonmusk')?.name, 'twitter'); assert.equal(getActiveAdapter('https://x.com/elonmusk')?.name, 'twitter'); From ca91fa4c17a5afaef86c239ddf42016f501d5f65 Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Sun, 2 Aug 2026 10:01:47 +0300 Subject: [PATCH 2/2] fix(adapters): scope Baidu search handoffs --- src/chrome/src/agent/adapters.js | 41 +++++++++++++++++++++++++++++-- src/firefox/src/agent/adapters.js | 41 +++++++++++++++++++++++++++++-- test/run.js | 11 ++++++++- 3 files changed, 88 insertions(+), 5 deletions(-) diff --git a/src/chrome/src/agent/adapters.js b/src/chrome/src/agent/adapters.js index ac0f055cf..dd79d9fa4 100644 --- a/src/chrome/src/agent/adapters.js +++ b/src/chrome/src/agent/adapters.js @@ -15702,6 +15702,43 @@ function isMastodonUrl(url) { || hasMastodonInteractionSignal(u, path); } +function isDirectBaiduSearchUrl(url) { + let parts; + try { + parts = adapterUrlParts(url); + } catch (e) { + return false; + } + if (!parts) return false; + const host = parts.parsed.hostname.toLowerCase(); + const { path } = parts; + if (host === 'baidu.com' || host === 'www.baidu.com') { + return path === '/' || /^\/(?:s|link)(?:\/|$)/.test(path); + } + if (host === 'm.baidu.com') return path === '/' || /^\/s(?:\/|$)/.test(path); + if (host === 'image.baidu.com') return path === '/' || /^\/search(?:\/|$)/.test(path); + if (host === 'video.baidu.com') return path === '/' || /^\/v(?:\/|$)/.test(path); + return host === 'news.baidu.com' && /^\/ns(?:\/|$)/.test(path); +} + +function isBaiduSearchUrl(url) { + if (isDirectBaiduSearchUrl(url)) return true; + let parts; + try { + parts = adapterUrlParts(url); + } catch (e) { + return false; + } + if (!parts) return false; + const host = parts.parsed.hostname.toLowerCase(); + if (host !== 'passport.baidu.com' && host !== 'wappass.baidu.com') return false; + const targets = []; + for (const param of ['backurl', 'u']) { + targets.push(...parts.parsed.searchParams.getAll(param)); + } + return targets.length > 0 && targets.every(isDirectBaiduSearchUrl); +} + const ADAPTERS = [ // ─── Code & Dev Tools ───────────────────────────────────────────────── { @@ -15819,9 +15856,9 @@ const ADAPTERS = [ { name: 'baidu-search', category: 'general', - matches: (url) => /^https?:\/\/(?:(?:www|m|image|video|passport|wappass)\.)?baidu\.com\//.test(url), + matches: isBaiduSearchUrl, notes: ` -- Treat baidu.com, www.baidu.com, m.baidu.com, image.baidu.com, video.baidu.com, passport.baidu.com, and wappass.baidu.com as Baidu search surfaces as of 2026-08. Enter the query in the main field and activate "百度一下"; preserve the exact query when a login or interstitial interrupts navigation. +- Treat baidu.com, www.baidu.com, m.baidu.com, image.baidu.com, video.baidu.com, and news.baidu.com/ns as Baidu search surfaces as of 2026-08. Match passport.baidu.com or wappass.baidu.com only when its encoded return target is one of those search surfaces. Enter the query in the main field and activate "百度一下"; preserve the exact query when a login or interstitial interrupts navigation. - Switch deliberately among "网页", "资讯", "视频", and "图片" because each tab changes the result type and may move to another matched host. Re-read the result list after switching instead of reusing card positions or labels. - Treat results marked "广告" or "商业推广" as paid placements. Do not report the first visible card as the top organic result, and do not treat a claimed "官方" label as proof without checking the destination domain. - Treat "文心助手" and other AI-generated answer blocks as synthesized content, not independent search results or primary evidence. Follow and verify their cited source links before using factual claims, especially for medical, legal, financial, or safety-sensitive questions. diff --git a/src/firefox/src/agent/adapters.js b/src/firefox/src/agent/adapters.js index c5c7002e5..dc0956fe2 100644 --- a/src/firefox/src/agent/adapters.js +++ b/src/firefox/src/agent/adapters.js @@ -15702,6 +15702,43 @@ function isMastodonUrl(url) { || hasMastodonInteractionSignal(u, path); } +function isDirectBaiduSearchUrl(url) { + let parts; + try { + parts = adapterUrlParts(url); + } catch (e) { + return false; + } + if (!parts) return false; + const host = parts.parsed.hostname.toLowerCase(); + const { path } = parts; + if (host === 'baidu.com' || host === 'www.baidu.com') { + return path === '/' || /^\/(?:s|link)(?:\/|$)/.test(path); + } + if (host === 'm.baidu.com') return path === '/' || /^\/s(?:\/|$)/.test(path); + if (host === 'image.baidu.com') return path === '/' || /^\/search(?:\/|$)/.test(path); + if (host === 'video.baidu.com') return path === '/' || /^\/v(?:\/|$)/.test(path); + return host === 'news.baidu.com' && /^\/ns(?:\/|$)/.test(path); +} + +function isBaiduSearchUrl(url) { + if (isDirectBaiduSearchUrl(url)) return true; + let parts; + try { + parts = adapterUrlParts(url); + } catch (e) { + return false; + } + if (!parts) return false; + const host = parts.parsed.hostname.toLowerCase(); + if (host !== 'passport.baidu.com' && host !== 'wappass.baidu.com') return false; + const targets = []; + for (const param of ['backurl', 'u']) { + targets.push(...parts.parsed.searchParams.getAll(param)); + } + return targets.length > 0 && targets.every(isDirectBaiduSearchUrl); +} + const ADAPTERS = [ // ─── Code & Dev Tools ───────────────────────────────────────────────── { @@ -15818,9 +15855,9 @@ const ADAPTERS = [ { name: 'baidu-search', category: 'general', - matches: (url) => /^https?:\/\/(?:(?:www|m|image|video|passport|wappass)\.)?baidu\.com\//.test(url), + matches: isBaiduSearchUrl, notes: ` -- Treat baidu.com, www.baidu.com, m.baidu.com, image.baidu.com, video.baidu.com, passport.baidu.com, and wappass.baidu.com as Baidu search surfaces as of 2026-08. Enter the query in the main field and activate "百度一下"; preserve the exact query when a login or interstitial interrupts navigation. +- Treat baidu.com, www.baidu.com, m.baidu.com, image.baidu.com, video.baidu.com, and news.baidu.com/ns as Baidu search surfaces as of 2026-08. Match passport.baidu.com or wappass.baidu.com only when its encoded return target is one of those search surfaces. Enter the query in the main field and activate "百度一下"; preserve the exact query when a login or interstitial interrupts navigation. - Switch deliberately among "网页", "资讯", "视频", and "图片" because each tab changes the result type and may move to another matched host. Re-read the result list after switching instead of reusing card positions or labels. - Treat results marked "广告" or "商业推广" as paid placements. Do not report the first visible card as the top organic result, and do not treat a claimed "官方" label as proof without checking the destination domain. - Treat "文心助手" and other AI-generated answer blocks as synthesized content, not independent search results or primary evidence. Follow and verify their cited source links before using factual claims, especially for medical, legal, financial, or safety-sensitive questions. diff --git a/test/run.js b/test/run.js index 28e8d8319..8c65d3fcd 100644 --- a/test/run.js +++ b/test/run.js @@ -2280,7 +2280,8 @@ test('matches Baidu search surfaces without hijacking other Baidu products', () 'https://m.baidu.com/s?word=webbrain', 'https://image.baidu.com/search/index?tn=baiduimage&word=webbrain', 'https://video.baidu.com/v?word=webbrain', - 'https://passport.baidu.com/v2/?login', + 'https://news.baidu.com/ns?word=webbrain&tn=news', + 'https://passport.baidu.com/v2/?login&u=https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3Dwebbrain', 'https://wappass.baidu.com/static/captcha/tuxing_v2.html?backurl=https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3Dwebbrain', ]; for (const url of trustedUrls) { @@ -2293,6 +2294,14 @@ test('matches Baidu search surfaces without hijacking other Baidu products', () 'https://tieba.baidu.com/', 'https://pan.baidu.com/', 'https://baike.baidu.com/', + 'https://news.baidu.com/', + 'https://news.baidu.com/guonei', + 'https://passport.baidu.com/v2/?login', + 'https://passport.baidu.com/v2/?login&tpl=mn&u=https%3A%2F%2Fmap.baidu.com%2F', + 'https://wappass.baidu.com/passport/?login&tpl=tb&u=https%3A%2F%2Ftieba.baidu.com%2F', + 'https://wappass.baidu.com/static/captcha/tuxing_v2.html?backurl=https%3A%2F%2Fmap.baidu.com%2F', + 'https://wappass.baidu.com/static/captcha/tuxing_v2.html?backurl=https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3Dwebbrain&u=https%3A%2F%2Ftieba.baidu.com%2F', + 'https://passport.baidu.com/v2/?login&u=https%3A%2F%2Fwww.baidu.com.phishing.example%2Fs%3Fwd%3Dwebbrain', 'https://www.baidu.com.phishing.example/s?wd=webbrain', 'https://example.com/?next=https://www.baidu.com/s?wd=webbrain', ];