package main // 本文件装配 io 工具集(plugins/tools/io)的选项:知识检索器、日志,以及 // **web-search 的端点与超时**(切片 WS1-A)。 // // 为什么单独成文件而不是塞在 wire_runtime.go 里:那条装配线本就接近文件行数上限, // 而本片新增的裁决(端点关闭/非法 ⇒ 工具不进注册面)需要一个能单测的落点。 // // 三条口径: // // 1. **端点默认开箱即用**:`WEB_SEARCH_ENDPOINT` 未配置时取 config 标签默认值 // (本机兜底 http://127.0.0.1:38471,配套服务见 scripts/searxng/settings.yml)。 // 2. **拿不到可用端点就不注册工具**(诚意要求,主人 2026-10-05 报障的核心诉求): // 端点显式关闭(空串 / off / none)或不是 http(s) 绝对地址时,web-search // **不进注册面** —— 模型根本看不见它,而不是看得见、一调就报错。 // 3. **超时不另造默认值**:`WEB_SEARCH_TIMEOUT` 未配置(0)时沿用 io 包既有超时; // 负值是笔误,按未配置处理并记一条带 env 键名的 WARN(不静默)。 import ( "git.yeij.top/AskaEth/Cyrene_v2/internal/logger" iotools "git.yeij.top/AskaEth/Cyrene_v2/plugins/tools/io" ) // web-search 的两个 env 键名:必须与 `.env.example` 逐字一致(AGENTS §10 的 E6 条目), // 由 wire_web_search_test.go 逐字核对。 const ( webSearchEndpointEnv = "WEB_SEARCH_ENDPOINT" webSearchTimeoutEnv = "WEB_SEARCH_TIMEOUT" ) // ioLogSource 是本文件日志的来源标签(项目规范 §10:禁止无来源裸日志)。 const ioLogSource = "cmd/cyrene/wire_io_tools" // ioToolOptions 组装 io 工具集的全部选项。wire_runtime 把它原样交给 iotools.New, // 因此「注册面里有哪些 io 工具」只由这一处决定。 func (a *app) ioToolOptions() []iotools.Option { opts := []iotools.Option{ iotools.WithKnowledgeRetriever(a.retriever), iotools.WithLogger(a.log), } return append(opts, a.webSearchOptions()...) } // webSearchOptions 把 web-search 的配置翻译成 io 选项。端点裁决见 // config.WebSearchConfig.ResolveEndpoint(关闭 / 非法 / 可用三种去处都在那里定死)。 func (a *app) webSearchOptions() []iotools.Option { log := logger.WithSource(a.log, ioLogSource) decision := a.cfg.WebSearch.ResolveEndpoint() if !decision.Enabled { // 端点的值**绝不写进日志**(URL 里可能带凭据),只记键名与原因。 log.Warn("web-search tool not registered", "env", webSearchEndpointEnv, "reason", decision.Reason, "effect", "the model will not see a web-search tool at all") return []iotools.Option{iotools.WithoutSearch()} } opts := []iotools.Option{iotools.WithSearchEndpoint(decision.URL)} switch { case a.cfg.WebSearch.Timeout > 0: opts = append(opts, iotools.WithSearchTimeout(a.cfg.WebSearch.Timeout)) case a.cfg.WebSearch.Timeout < 0: log.Warn("web-search timeout is negative, treated as unset", "env", webSearchTimeoutEnv, "effect", "io package default timeout applies") } return opts }