Version: 0.9.15.dev.260412

后端:
1. 排程工具从 tools/ 根目录拆分为 tools/schedule 独立子包
- 12 个排程工具文件等价迁入 tools/schedule/,tools/ 根目录仅保留 registry.go 作为统一注册入口
- 所有依赖方(conv / model / node / prompt / service)import 统一切到 schedule 子包
2. Web 搜索工具链落地(tools/web 子包)
- 新增 web_search(结构化检索)与 web_fetch(正文抓取)两个读工具,支持博查 API / mock 降级
- 启动流程按配置选择 provider,未识别类型自动降级为 mock,不阻断主流程
- 执行提示补齐 web 工具使用约束与返回值示例
- config.example.yaml 补齐 websearch 配置段
前端:无
仓库:无
This commit is contained in:
Losita
2026-04-12 19:02:54 +08:00
parent bf1f1defa5
commit 070d4c3459
34 changed files with 1033 additions and 205 deletions

View File

@@ -0,0 +1,61 @@
package schedule
import (
"fmt"
"sort"
"strings"
)
// validateToolArgsStrict 校验工具参数是否全部命中 schema 白名单。
//
// 职责边界:
// 1. 只做“字段名是否允许”的校验,不校验字段值合法性;
// 2. 发现未知字段时直接报错,避免静默忽略导致范围漂移;
// 3. 该函数不做别名兼容,调用方应自行传入 schema 中允许的字段。
func validateToolArgsStrict(args map[string]any, allowedKeys []string) error {
if len(args) == 0 {
return nil
}
allowed := make(map[string]struct{}, len(allowedKeys))
for _, key := range allowedKeys {
allowed[strings.TrimSpace(key)] = struct{}{}
}
unknown := make([]string, 0, len(args))
for key := range args {
trimmed := strings.TrimSpace(key)
if trimmed == "" {
continue
}
if _, ok := allowed[trimmed]; ok {
continue
}
unknown = append(unknown, trimmed)
}
if len(unknown) == 0 {
return nil
}
sort.Strings(unknown)
hint := "请仅使用当前工具 schema 中声明的参数字段。"
if containsAnyUnknownArg(unknown, "day_from", "day_to") {
hint = "请仅使用当前工具 schema 中声明的参数字段day_from/day_to 不受支持,请改用 day_start/day_end。"
}
return fmt.Errorf("参数非法:%s。%s", strings.Join(unknown, "、"), hint)
}
func containsAnyUnknownArg(keys []string, targets ...string) bool {
if len(keys) == 0 || len(targets) == 0 {
return false
}
targetSet := make(map[string]struct{}, len(targets))
for _, target := range targets {
targetSet[strings.TrimSpace(target)] = struct{}{}
}
for _, key := range keys {
if _, ok := targetSet[strings.TrimSpace(key)]; ok {
return true
}
}
return false
}