package public import ( "ai_scheduler/internal/config" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg" "ai_scheduler/internal/pkg/utils_ollama" "context" "encoding/json" "fmt" "github.com/ollama/ollama/api" "github.com/coze-dev/coze-go" ) type CozeExpress struct { cozeApi coze.CozeAPI config config.ToolConfig llm *utils_ollama.Client } // NewCozeExpress 创建 CozeExpress 实例 func NewCozeExpress(config config.ToolConfig, llm *utils_ollama.Client) *CozeExpress { return &CozeExpress{ cozeApi: newCozeApi(config), config: config, llm: llm, } } // newCozeExpressClient 创建 CozeExpress 客户端 func newCozeExpressApi(config config.ToolConfig) coze.CozeAPI { authCli := coze.NewTokenAuth(config.APISecret) cozeApi := coze.NewCozeAPI(authCli, coze.WithBaseURL(config.BaseURL)) return cozeApi } // Name 返回工具名称 func (c *CozeExpress) Name() string { return "coze_express" } // Description 返回工具描述 func (c *CozeExpress) Description() string { return "查询快递物流信息" } // Definition 返回工具定义 func (c *CozeExpress) Definition() entitys.ToolDefinition { return entitys.ToolDefinition{ Type: "function", Function: entitys.FunctionDef{ Name: c.Name(), Description: c.Description(), Parameters: map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "express_id": map[string]interface{}{ "type": "string", "description": "快递单号", }, }, "required": []string{"express_id"}, }, }, } } // Execute 执行查询 func (c *CozeExpress) Execute(ctx context.Context, requireData *entitys.Recognize) error { var req map[string]interface{} if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { return fmt.Errorf("invalid express request: %w", err) } if req["express_id"] == "" { return fmt.Errorf("express_id is required") } // 调用 Coze 工作流查询快递物流信息 rsp, err := c.callWorkflow(ctx, req) if err != nil { return fmt.Errorf("failed to get real weather: %w", err) } err = c.llm.ChatStream(ctx, requireData.Ch, []api.Message{ { Role: "system", Content: "你是一个快递查询助手。用户可能会提供快递单号,你需要分析快递单号,根据快递单号查询物流信息并反馈给我", }, { Role: "assistant", Content: fmt.Sprintf("聊天记录:%s", pkg.JsonStringIgonErr(requireData.ChatHis)), }, { Role: "assistant", Content: fmt.Sprintf("需要分析的快递单号:%s", rsp.Data), }, { Role: "user", Content: requireData.UserContent.Text, }, }, c.Name(), "") if err != nil { return fmt.Errorf("failed to get express info: %w", err) } //entitys.ResText(requireData.Ch, "", rsp.Data) return nil } // CallWorkflow 调用 Coze 工作流 // 参数: // - ctx: 上下文,用于控制超时和取消 // - workflowId: 工作流 ID // - params: 工作流参数 // 返回: // - interface{}: 工作流执行结果 // - error: 错误信息 func (c *CozeExpress) callWorkflow(ctx context.Context, params map[string]interface{}) (*coze.RunWorkflowsResp, error) { // 准备工作流请求参数 workflowReq := &coze.RunWorkflowsReq{ WorkflowID: c.config.APIKey, Parameters: params, } // 调用工作流 resp, err := c.cozeApi.Workflows.Runs.Create(ctx, workflowReq) if err != nil { return nil, fmt.Errorf("工作流调用失败: %w", err) } // 处理工作流响应 if resp == nil { return nil, fmt.Errorf("工作流响应为空") } // 返回工作流执行结果 return resp, nil }