后端: - ♻️ 将 `taskquery` 模块迁移至 `agent2`,并完成与 `agent2` 业务链路及整体结构的正式接入 前端: - 🧱 已完成基础框架搭建,并完成了登录、注册、主页等页面并对接了对应接口;但整体功能实现仍在完善中
75 lines
2.5 KiB
Go
75 lines
2.5 KiB
Go
package agentnode
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/cloudwego/eino/components/tool"
|
|
"github.com/cloudwego/eino/schema"
|
|
)
|
|
|
|
// collectToolInfos 负责批量提取工具元信息,供模型注册与工具索引复用。
|
|
//
|
|
// 职责边界:
|
|
// 1. 只负责调用 tool.Info 并聚合返回结果。
|
|
// 2. 不负责校验工具是否可执行,也不负责按名称检索工具。
|
|
func collectToolInfos(ctx context.Context, tools []tool.BaseTool) ([]*schema.ToolInfo, error) {
|
|
infos := make([]*schema.ToolInfo, 0, len(tools))
|
|
for _, currentTool := range tools {
|
|
info, err := currentTool.Info(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("读取工具信息失败: %w", err)
|
|
}
|
|
infos = append(infos, info)
|
|
}
|
|
return infos, nil
|
|
}
|
|
|
|
// buildInvokableToolMap 负责把工具列表转换成“工具名 -> 可执行工具”的索引表。
|
|
//
|
|
// 步骤说明:
|
|
// 1. 先校验 tools 与 infos 是否一一对应,避免后续按下标取值时出现错配。
|
|
// 2. 再校验每个工具都带有合法名字,并且确实实现了 InvokableTool 接口。
|
|
// 3. 任一步失败都立即返回错误,避免 graph 在运行期拿到半残缺的工具集合。
|
|
func buildInvokableToolMap(tools []tool.BaseTool, infos []*schema.ToolInfo) (map[string]tool.InvokableTool, error) {
|
|
if len(tools) == 0 || len(infos) == 0 {
|
|
return nil, errors.New("tool bundle is empty")
|
|
}
|
|
if len(tools) != len(infos) {
|
|
return nil, errors.New("tool bundle mismatch")
|
|
}
|
|
|
|
result := make(map[string]tool.InvokableTool, len(tools))
|
|
for idx, currentTool := range tools {
|
|
info := infos[idx]
|
|
if info == nil || strings.TrimSpace(info.Name) == "" {
|
|
return nil, errors.New("tool info is invalid")
|
|
}
|
|
invokable, ok := currentTool.(tool.InvokableTool)
|
|
if !ok {
|
|
return nil, fmt.Errorf("tool %s is not invokable", info.Name)
|
|
}
|
|
result[info.Name] = invokable
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// getInvokableToolByName 负责从工具集合中提取指定名称的可执行工具。
|
|
//
|
|
// 职责边界:
|
|
// 1. 负责复用统一索引逻辑,避免各业务链路重复写名称查找代码。
|
|
// 2. 不负责兜底选择其他工具;未命中时直接返回错误,由上层决定如何处理。
|
|
func getInvokableToolByName(tools []tool.BaseTool, infos []*schema.ToolInfo, name string) (tool.InvokableTool, error) {
|
|
invokableMap, err := buildInvokableToolMap(tools, infos)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
invokable, ok := invokableMap[name]
|
|
if !ok {
|
|
return nil, fmt.Errorf("tool %s not found", name)
|
|
}
|
|
return invokable, nil
|
|
}
|