feat(search): web-search 接线本机 SearXNG 兜底 + 显式开关(她不再拿一把用不了的锤子)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

主人报的故障:她调 web-search 必失败(no search endpoint configured)。根因两条:组合根从未注入 WithSearchEndpoint + 配置层根本没有搜索配置项。
- internal/config/websearch.go:WEB_SEARCH_ENDPOINT(默认本机兜底 http://127.0.0.1:38471)+ WEB_SEARCH_TIMEOUT;ResolveEndpoint() 三态裁决(可用/显式关闭/非法),非法值启动即报错
- cmd/cyrene/wire_io_tools.go:组合根唯一的 io 选项装配点;端点不可用 ⇒ WithoutSearch() + 带 source 的 WARN(只记键名与原因,不打印 URL 值)
- plugins/tools/io:新增 WithoutSearch()(**根本不进注册面** ⇒ 模型看不见)+ WithSearchTimeout();协议解析逻辑一字未动
- 隐蔽坑(额外查出并修):SearXNG 对 /?q= 回 308 → /search,重定向那一跳走**共享 SSRF 白名单** ⇒ 只注入端点照样被拦。改为**只给 web-search 一件**加宽自己的客户端与白名单,共享白名单与 http/web-fetch 客户端一字未动(有测试钉住它仍拒绝本机网关地址)
- .env.example 新增 2 键 + 注释说明「空串/off/none = 不注册」
- 真机 e2e 两次绿(SearXNG 返回 9 条);变异:不注入端点 / 关闭态仍注册 / 默认值改错 / 不并入端点主机 / 重定向用共享白名单 ⇒ 5 条全红
This commit is contained in:
AskaEth committed 2026-10-05 20:29:21 +08:00
1 parent 8e56163418
commit 8e6c77ad10
11 files changed
+1137 -20

No files matched your search

+15
View File
@@ -223,6 +223,21 @@ STT_PROVIDER=dashscope
# ⚠️ 建音色必须公网可访问的参考音频 URL(create_voice 只收 input.url,不收 base64);
# 待主人提供参考音频公网 URL 方能真建音色。
# ---- 网络搜索(web-search 工具) ----
# WEB_SEARCH_ENDPOINT = web-search 工具查询的 SearXNG 兼容端点(GET + format=json)。
# 默认值 http://127.0.0.1:38471 是**本机兜底**:scripts/searxng/settings.yml 就是它的
# 配套配置(docker 起法见该文件头注释),无需任何第三方 API key、开箱即用 —— 默认指向
# 本机而不是某个云搜索服务,原因就在这。要换云 provider 就把新地址写在这里。
WEB_SEARCH_ENDPOINT=http://127.0.0.1:38471
# 显式关闭:把上面这行写成空串 / off / none(大小写不敏感)⇒ **web-search 不注册**,
# 模型根本看不见它(不给一把一调就报错的锤子)。值不是 http(s) 绝对地址时同样不注册,
# 启动日志会有一条带键名的 WARN 说明原因(绝不静默半开)。
# WEB_SEARCH_ENDPOINT=off
# WEB_SEARCH_TIMEOUT = 单次搜索请求的超时(Go duration,如 20s)。
# 不配置时**沿用 io 包既有超时(15s)** —— 这里刻意不写第二个默认值。
# 它只影响 web-search 一次调用,不改 http / web-fetch 用的那个共享客户端。
# WEB_SEARCH_TIMEOUT=20s
# ---- 后台思考 ----
ENABLE_BACKGROUND_THINKING=true
# 自主思考心跳周期(秒)。默认 900(15 分钟一次);数值越小越频繁打扰。