Repository navigation
feat(websearch): #1445 重写后 AC —— 无 key 三种结局钉在模型面,信封结构记录只记录不判决 - #1459
Merged
Merged
Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1445
用户会看到什么
你没有自带 Exa key、本地搜网走出厂的免费额度时,不管这次搜网的结局是「额度用尽(429)」、「托管端发回一句不带任何契约信号的提示」还是「真的没搜到」,模型拿到的都是三句不同的话——它不会把「没搜」说成「我查了,没查到」。这一点今天就成立;本 PR 把它钉成闸门,没有改任何放行/拒绝的判决。另外,每次本地搜网的响应现在会在日志里留下一条只有结构字段、没有正文的记录;托管端哪天再发出那种无信号的失败,我们就有信封可看,而不是再猜一次。
三条 AC 各怎么落的(重写后 AC,票面 2026-09-26 那条评论)
AC1 —— 先量再改:今天已可区分,交付的是闸,不是修法
把四种负载(全部读库里的实抓件,不手拼)喂进两份生产传输(含状态码分支),模型面拿到的话:
packages/opencode(叶子output/ToolFailure.message)packages/core(text ?? NO_RESULTS/ToolFailure.message)arms.jsonnokey-search)Web search failed: unexpected HTTP status (HTTP 429). Cause: {"jsonrpc":"2.0","id":1,"error":{"code":-32000,…ticket-payload.json)You've hit Exa's free MCP rate limit. To continue using without limits, create your own Exa API key. …No search results found. Please try a different query.content: []Web search failed: no usable result. …(#489)NO_RESULTS(#1449AC3;与 Z 同一句)opencode 4 格 → 4 句;core 4 格 → 3 句(Z ≡ Z2,两者都是「没搜到」)。D 到模型面的是 vendor 自己那句 rate limit,不是我们编的「没搜到」——「没搜」与「没搜到」不是同一句话。所以 AC1 不改生产代码;两份闸门文件把这张表钉住(传输半场 + 真叶子半场:opencode 走
Tool.init → execute,core 走真ToolRegistry.materialize → settle)。AC2 —— 信封结构记录:只记录、不判决
两份传输各加一个纯函数
envelopeShape(tool, status, headers, body),响应到手后Effect.logInfo("websearch envelope", …)。字段:status/jsonrpc(result | error | unparsed)/isError/structuredContent/contentBlocks/contentMetaKeys(content[0]._meta键名)/resultMetaKeys/textLength/ 四个限流头;不含正文。call()/callMcp()里没有一个分支读它。缺省开着(绊线不预先拉上就绊不到人,D 是 1/13 的间歇形态);ALPHA_WEBSEARCH_ENVELOPE_DIAG=0关。D 的记录样本(实跑):
C 记下四个限流头逐字(
retry-after: 44016…),A 记下contentMetaKeys: ["searchTime"],P 记下isError: false+structuredContent: present+resultMetaKeys: ["parallel/usage"]。对照臂(逐字节):同一六种负载(C/D/Z/Z2/A/P),开关关闭 ⇒ 零记录,模型面输出
Buffer.compare == 0(失败臂比kind+message);开关缺省开 ⇒ 每种恰一条记录、输出仍逐字节相同。另一条独立证据:改动前跑的探针输出与改动后ALPHA_WEBSEARCH_ENVELOPE_DIAG=0的探针输出diff为空;开关开着时diff只多出 12 段 INFO 记录,没有一行原有输出变化。AC3 —— 不匹配文案、不押无契约字段
rate limit+API key+ URL 的散文)⇒ 三条全部原样放行;content[0]._meta摘掉 ⇒ 模型面输出逐字节不变(记录里contentMetaKeys从["searchTime"]变"absent")——缺席即放行;detailOf的/\s+/g,零includes/indexOf/match/search/test,startsWith只认"{"与"data: ";普查自检往源码里塞text.includes("rate limit") || /API key/i.test(text)必须抓到(否则上一条空对空)。已知的坏 → 红(变异实测,每次
git checkout --还原,树清)parsePayload改成「无_meta即零命中」(勘破点名的假闸门;D 变成「我查了,没查到」)NO_RESULTS同句 —— 分辨力在 D 臂)_meta即拒)门
bun run --cwd packages/opencode typecheck0 条;packages/core0 条。bun-test-floor.sh "=23"/"=22"各自「实际通过 = 登记精确条数」。alpha-websearch-failure+websearch+alpha-mcp-websearch-gate62/62;corealpha-websearch-failure+alpha-websearch-sovereignty+tool-websearch49/49;ui-macgate-file-registry+websearch-copies+network-egress-registry+stream-read-hygiene+cloud-web-search63/63。scripts/alpha-check.sh:见下方(合并前由主 session 本地复跑)。本机全量
bash scripts/alpha-check.sh(worktree1445b-no-silent-degrade,HEAD472e7df44,2026-09-28 01:50:17Z → 02:01:53Z,串行、本机无其它alpha-check):process-fence-engine.test.ts没有再红(#1454修复在 base 上)。与 base fail-set 的差:0(ui-mac 全量 0 fail,known-fails.tsv未动)。主动没做的
Title:/URL:行判成功):票面明写是 owner 的偏好裁决,未裁,不做。ALPHA_WEBSEARCH_ENVELOPE_DIAG没有登进packages/ui-mac/src/main/sidecar-env.ts白名单:它只关一条诊断日志,不是运行判决;打包实例要关可走ALPHA_ENV_ALLOWLIST_EXTRA。两包各写一份的常量名也没有加跨包逐字一致闸(cloud-web-search.test.ts那种):两份漂开的后果只是日志字段名不同,不是判决不同。要不要补,主 session 定。scripts/known-fails.tsv。Effect.logInfo,Info 级,引擎缺省OPENCODE_LOG_LEVEL就是 Info),没有进 toolmetadata/ UI —— 进了就不是「输出逐字节不变」。顺带看到、没改的
packages/core的NO_RESULTS常量与 exa-mcp-server 四个发行版的零命中散文逐字相同——所以在 core 侧,vendor 的真零命中与我们编的NO_RESULTS在模型面不可区分,这是#1449AC3 的既定语义,不是本票的洞;但它意味着 core 侧「无_meta即零命中」这类假闸门只会被 D 臂抓到,Z 臂抓不到(上表 M1 那格)。mcp-websearch.ts的call()有一个叫headers的请求头形参,响应头在同一作用域里不能再叫headers(TDZ,实测整条传输塌成 transport failure);已用responseHeaders避开并留注释。🤖 Generated with Claude Code