接入位表六家扩到八家,端点形状与错误码一字未改(契约 v0.87,仅两处名单)。 - tencent_wsa:POST {base}/SearchPro + Authorization Bearer,零签名。 两条官方口径决定实现:HTTP 状态码恒 200(判失败只能读 Response.Error.Code); Pages 是「JSON 字符串数组」需二次解析。错误码按官方表分类 (UnauthorizedOperation/AuthFailure.* = 凭据、ResourceUnavailable = 欠费、 RequestLimitExceeded* = 限流),文案只带 code 不带上游 Message。 - metaso:POST {base}/api/v1/search,响应 schema 仅第三方来源且互相打架, 实现走宽松解析(数组候选与字段名回退),逐处标「未实测」。 - 零新 env 键:两家只走 $DATA_DIR/config/plugins/web-search.json, .env / .env.example 未动;组合根 websearch_providers.go 零功能改动。 - 契约 v0.87:values.provider 合法闭集与 plugin.providers 候选各加两条, 计数不变(14 + 25 + 40 = 79)。
主人报障:「为什么中文搜索接口……下拉菜单里全给的英文名?你甚至不愿意带个括号 把中文名写上去」。根因不是漏写文案,而是整条链路没有「显示名」的位置:字段 声明只有 optionsFrom,候选动作回的就是 KnownNames() 的纯 id 数组。 - 后端:候选改为对象数组 {value,label};label 表与接入位表同源(键用 NameSearXNG 等常量),未知 id 原样回。value 逐字等于 KnownNames()。 - 前端:下拉/多选「显示 label、写 value」;表格单元格按 value→label 索引显示, 查不到回落显示原值。多选从裸输入框改成「候选开关 + 落盘值输入框」。 解码器本就兼容裸字符串/{value,label}/{id} 三形状 ⇒ 其他插件零影响。 中文名逐字:SearXNG 本地兜底(searxng)/ 智谱 BigModel(zhipu)/ 阿里云 IQS 信息查询(aliyun_iqs)/ 博查 Bocha(bocha)/ 火山引擎·豆包搜索(volcengine)/ 百度千帆 AI 搜索(baidu_qianfan)。 验收(主会话复跑 + 亲自变异):go build ./... + vet 绿;search 包测试绿; tsc --noEmit 0 错;新渲染测试 26 checks + 既有 plugin panel 55 / data 90 / schema values 40 / channel config 70 全绿。我用 sed 把 values.ts 的 option.value 全换成 option.label ⇒ 渲染测试红(「点选把候选项的 id 追加到 降级链末尾」got="bocha, 智谱 BigModel(zhipu)")—— 这正是会把配置文件写坏的 错法;还原后 md5 一致且绿。 ⚠️ 契约面变更(我在 Docs/api-client.md 登记):plugin.providers 候选响应形状 字符串数组 → 对象数组;label 仅供显示、value 才是落盘值。 ⚠️ 已知边界:viewer 角色看不到 form 区块 ⇒ 表格对 viewer 仍显示裸 id(未做)。 ⚠️ 真机浏览器点击未跑(项目无 jsdom)⇒ 建议刷新管理页点一次确认观感。
- 新增 $DATA_DIR/config/plugins/web-search.json(0600 + temp+rename,文件名 = 插件 id) - 组合根改「先读可变源、缺失回落 .env 播种」;**不新增任何 env 键**(.env 已冻结) - 多实例:每家 provider 独立 key/baseURL/启用态 + 「测试连通」探针 - 用 PLG-1 的声明库给出该面板的 adminPanels 声明;动作名交给 PLG-2 的通用动作端点分发 (本片自己不开路由) ⚠️ 本片自认越界:改了 cmd/cyrene/wire_web_search_test.go(既有测试,为适配 DataDir); 另有 design/28 的相关注册留给主会话。