Compare commits
2 Commits
ff81cddc46
...
3b91505a12
Author | SHA1 | Date |
---|---|---|
|
3b91505a12 | |
|
2da5e15a99 |
|
@ -30,5 +30,5 @@ db:
|
|||
tools:
|
||||
zltxOrderDetail:
|
||||
enabled: true
|
||||
base_url: "https://gateway.dev.cdlsxd.cn/zltx_api/admin/direct/ai/"
|
||||
base_url: "https://gateway.dev.cdlsxd.cn/"
|
||||
api_key: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1c2VyQ2VudGVyIiwiZXhwIjoxNzU2MTgyNTM1LCJuYmYiOjE3NTYxODA3MzUsImp0aSI6IjEiLCJQaG9uZSI6IjE4MDAwMDAwMDAwIiwiVXNlck5hbWUiOiJsc3hkIiwiUmVhbE5hbWUiOiLotoXnuqfnrqHnkIblkZgiLCJBY2NvdW50VHlwZSI6MSwiR3JvdXBDb2RlcyI6IlZDTF9DQVNISUVSLFZDTF9PUEVSQVRFLFZDTF9BRE1JTixWQ0xfQUFBLFZDTF9WQ0xfT1BFUkFULFZDTF9JTlZPSUNFLENSTV9BRE1JTixMSUFOTElBTl9BRE1JTixNQVJLRVRNQUcyX0FETUlOLFBIT05FQklMTF9BRE1JTixRSUFOWkhVX1NVUFBFUl9BRE0sTUFSS0VUSU5HU0FBU19TVVBFUkFETUlOLENBUkRfQ09ERSxDQVJEX1BST0NVUkVNRU5ULE1BUktFVElOR1NZU1RFTV9TVVBFUixTVEFUSVNUSUNBTFNZU1RFTV9BRE1JTixaTFRYX0FETUlOLFpMVFhfT1BFUkFURSIsIkRpbmdVc2VySWQiOiIxNjIwMjYxMjMwMjg5MzM4MzQifQ.N1xv1PYbcO8_jR5adaczc16YzGsr4z101gwEZdulkRaREBJNYTOnFrvRxTFx3RJTooXsqTqroE1MR84v_1WPX6BS6kKonA-kC1Jgot6yrt5rFWhGNGb2Cpr9rKIFCCQYmiGd3AUgDazEeaQ0_sodv3E-EXg9VfE1SX8nMcck9Yjnc8NCy7RTWaBIaSeOdZcEl-JfCD0S6GSx3oErp_hk-U9FKGwf60wAuDGTY1R0BP4BYpcEqS-C2LSnsSGyURi54Cuk5xH8r1WuF0Dm5bwAj5d7Hvs77-N_sUF-C5ONqyZJRAEhYLgcmN9RX_WQZfizdQJxizlTczdpzYfy-v-1eQ"
|
||||
|
|
|
@ -202,7 +202,9 @@ func (r *AiRouterBiz) RouteWithSocket(c *websocket.Conn, req *entitys.ChatSockRe
|
|||
}
|
||||
|
||||
func (r *AiRouterBiz) handleMatch(c *websocket.Conn, matchJson *entitys.Match, tasks []model.AiTask) (err error) {
|
||||
var resChan = make(chan []byte, 10)
|
||||
defer func() {
|
||||
close(resChan)
|
||||
if err != nil {
|
||||
c.WriteMessage(websocket.TextMessage, []byte(err.Error()))
|
||||
}
|
||||
|
@ -219,30 +221,35 @@ func (r *AiRouterBiz) handleMatch(c *websocket.Conn, matchJson *entitys.Match, t
|
|||
break
|
||||
}
|
||||
}
|
||||
if pointTask == nil || pointTask.Index == "other" {
|
||||
return r.handleOtherTask(c, matchJson)
|
||||
}
|
||||
|
||||
if pointTask == nil || pointTask.Index == "other" {
|
||||
return r.handleOtherTask(resChan, c, matchJson)
|
||||
}
|
||||
switch pointTask.Type {
|
||||
case constant.TaskTypeApi:
|
||||
err = r.handleApiTask(c, matchJson, pointTask)
|
||||
err = r.handleApiTask(resChan, c, matchJson, pointTask)
|
||||
case constant.TaskTypeFunc:
|
||||
err = r.handleTask(c, matchJson, pointTask)
|
||||
err = r.handleTask(resChan, c, matchJson, pointTask)
|
||||
default:
|
||||
return r.handleOtherTask(c, matchJson)
|
||||
return r.handleOtherTask(resChan, c, matchJson)
|
||||
}
|
||||
select {
|
||||
case v := <-resChan: // 尝试接收
|
||||
fmt.Println("接收到值:", v)
|
||||
default:
|
||||
fmt.Println("无数据可接收")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *AiRouterBiz) handleTask(c *websocket.Conn, matchJson *entitys.Match, task *model.AiTask) (err error) {
|
||||
func (r *AiRouterBiz) handleTask(channel chan []byte, c *websocket.Conn, matchJson *entitys.Match, task *model.AiTask) (err error) {
|
||||
|
||||
var configData entitys.ConfigDataTool
|
||||
err = json.Unmarshal([]byte(task.Config), &configData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = r.toolManager.ExecuteTool(c, configData.Tool, []byte(matchJson.Parameters))
|
||||
err = r.toolManager.ExecuteTool(channel, c, configData.Tool, []byte(matchJson.Parameters))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -250,14 +257,12 @@ func (r *AiRouterBiz) handleTask(c *websocket.Conn, matchJson *entitys.Match, ta
|
|||
return
|
||||
}
|
||||
|
||||
func (r *AiRouterBiz) handleOtherTask(c *websocket.Conn, matchJson *entitys.Match) (err error) {
|
||||
|
||||
c.WriteMessage(1, []byte(matchJson.Reasoning))
|
||||
|
||||
func (r *AiRouterBiz) handleOtherTask(channel chan []byte, c *websocket.Conn, matchJson *entitys.Match) (err error) {
|
||||
channel <- []byte(matchJson.Reasoning)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *AiRouterBiz) handleApiTask(c *websocket.Conn, matchJson *entitys.Match, task *model.AiTask) (err error) {
|
||||
func (r *AiRouterBiz) handleApiTask(channels chan []byte, c *websocket.Conn, matchJson *entitys.Match, task *model.AiTask) (err error) {
|
||||
var (
|
||||
request l_request.Request
|
||||
auth = c.Headers("X-Authorization", "")
|
||||
|
|
|
@ -32,7 +32,15 @@ type configData struct {
|
|||
|
||||
func Test_Order(t *testing.T) {
|
||||
routerBiz := in()
|
||||
err := routerBiz.handleTask(nil, &entitys.Match{Index: "order_diagnosis", Parameters: `{"order_number":"12312312312"}`}, &model.AiTask{Config: `{"tool": "zltxOrderDetail", "param": {"type": "object", "optional": [], "required": ["order_number"], "properties": {"order_number": {"type": "string", "description": "订单编号/流水号"}}}}`})
|
||||
ch := make(chan []byte, 5)
|
||||
defer close(ch)
|
||||
err := routerBiz.handleTask(ch, nil, &entitys.Match{Index: "order_diagnosis", Parameters: `{"order_number":"822895927188791297"}`}, &model.AiTask{Config: `{"tool": "zltxOrderDetail", "param": {"type": "object", "optional": [], "required": ["order_number"], "properties": {"order_number": {"type": "string", "description": "订单编号/流水号"}}}}`})
|
||||
select {
|
||||
case v := <-ch: // 尝试接收
|
||||
fmt.Println("接收到值:", v)
|
||||
default:
|
||||
fmt.Println("无数据可接收")
|
||||
}
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ type Tool interface {
|
|||
Name() string
|
||||
Description() string
|
||||
Definition() ToolDefinition
|
||||
Execute(c *websocket.Conn, args json.RawMessage) error
|
||||
Execute(channel chan []byte, c *websocket.Conn, args json.RawMessage) error
|
||||
}
|
||||
|
||||
type ConfigDataHttp struct {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"ai_scheduler/internal/config"
|
||||
"ai_scheduler/internal/data/constants"
|
||||
"ai_scheduler/internal/entitys"
|
||||
"ai_scheduler/internal/pkg/utils_ollama"
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -14,12 +15,14 @@ import (
|
|||
// Manager 工具管理器
|
||||
type Manager struct {
|
||||
tools map[string]entitys.Tool
|
||||
llm *utils_ollama.UtilOllama
|
||||
}
|
||||
|
||||
// NewManager 创建工具管理器
|
||||
func NewManager(config *config.Config) *Manager {
|
||||
func NewManager(config *config.Config, llm *utils_ollama.UtilOllama) *Manager {
|
||||
m := &Manager{
|
||||
tools: make(map[string]entitys.Tool),
|
||||
llm: llm,
|
||||
}
|
||||
|
||||
// 注册天气工具
|
||||
|
@ -81,13 +84,13 @@ func (m *Manager) GetToolDefinitions(caller constants.Caller) []entitys.ToolDefi
|
|||
}
|
||||
|
||||
// ExecuteTool 执行工具
|
||||
func (m *Manager) ExecuteTool(c *websocket.Conn, name string, args json.RawMessage) error {
|
||||
func (m *Manager) ExecuteTool(channel chan []byte, c *websocket.Conn, name string, args json.RawMessage) error {
|
||||
tool, exists := m.GetTool(name)
|
||||
if !exists {
|
||||
return fmt.Errorf("tool not found: %s", name)
|
||||
}
|
||||
|
||||
return tool.Execute(c, args)
|
||||
return tool.Execute(channel, c, args)
|
||||
}
|
||||
|
||||
// ExecuteToolCalls 执行多个工具调用
|
||||
|
|
|
@ -3,7 +3,6 @@ package tools
|
|||
import (
|
||||
"ai_scheduler/internal/config"
|
||||
"ai_scheduler/internal/entitys"
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
|
@ -64,6 +63,12 @@ type ZltxOrderDetailResponse struct {
|
|||
Data ZltxOrderDetailData `json:"data"`
|
||||
}
|
||||
|
||||
type ZltxOrderLogResponse struct {
|
||||
Code int `json:"code"`
|
||||
Error string `json:"error"`
|
||||
Data any `json:"data"`
|
||||
}
|
||||
|
||||
// ZltxOrderDetailData 直连天下订单详情数据
|
||||
type ZltxOrderDetailData struct {
|
||||
Direct map[string]any `json:"direct"`
|
||||
|
@ -71,7 +76,7 @@ type ZltxOrderDetailData struct {
|
|||
}
|
||||
|
||||
// Execute 执行直连天下订单详情查询
|
||||
func (w *ZltxOrderDetailTool) Execute(c *websocket.Conn, args json.RawMessage) error {
|
||||
func (w *ZltxOrderDetailTool) Execute(channel chan []byte, c *websocket.Conn, args json.RawMessage) error {
|
||||
var req ZltxOrderDetailRequest
|
||||
if err := json.Unmarshal(args, &req); err != nil {
|
||||
return fmt.Errorf("invalid zltxOrderDetail request: %w", err)
|
||||
|
@ -82,11 +87,11 @@ func (w *ZltxOrderDetailTool) Execute(c *websocket.Conn, args json.RawMessage) e
|
|||
}
|
||||
|
||||
// 这里可以集成真实的直连天下订单详情API
|
||||
return w.getZltxOrderDetail(c, req.OrderNumber)
|
||||
return w.getZltxOrderDetail(channel, c, req.OrderNumber)
|
||||
}
|
||||
|
||||
// getMockZltxOrderDetail 获取模拟直连天下订单详情数据
|
||||
func (w *ZltxOrderDetailTool) getZltxOrderDetail(c *websocket.Conn, number string) (err error) {
|
||||
func (w *ZltxOrderDetailTool) getZltxOrderDetail(ch chan []byte, c *websocket.Conn, number string) (err error) {
|
||||
//查询订单详情
|
||||
var auth string
|
||||
if c != nil {
|
||||
|
@ -96,7 +101,7 @@ func (w *ZltxOrderDetailTool) getZltxOrderDetail(c *websocket.Conn, number strin
|
|||
auth = w.config.APIKey
|
||||
}
|
||||
req := l_request.Request{
|
||||
Url: fmt.Sprintf("%s%s", w.config.BaseURL, number),
|
||||
Url: fmt.Sprintf("%szltx_api/admin/direct/ai/%s", w.config.BaseURL, number),
|
||||
Headers: map[string]string{
|
||||
"Authorization": fmt.Sprintf("Bearer %s", auth),
|
||||
},
|
||||
|
@ -107,7 +112,36 @@ func (w *ZltxOrderDetailTool) getZltxOrderDetail(c *websocket.Conn, number strin
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
c.WriteMessage(websocket.TextMessage, res.Content)
|
||||
var resData ZltxOrderDetailResponse
|
||||
if err = json.Unmarshal(res.Content, &resData); err != nil {
|
||||
return
|
||||
}
|
||||
if resData.Code != 200 {
|
||||
return fmt.Errorf("订单查询失败:%s", resData.Error)
|
||||
}
|
||||
ch <- res.Content
|
||||
if resData.Data.Direct != nil && resData.Data.Direct["needAi"].(bool) {
|
||||
ch <- []byte("orderErrorChecking")
|
||||
req = l_request.Request{
|
||||
Url: fmt.Sprintf("%szltx_api/admin/direct/log/%s/%s", w.config.BaseURL, resData.Data.Direct["orderOrderNumber"].(string), resData.Data.Direct["serialNumber"].(string)),
|
||||
Headers: map[string]string{
|
||||
"Authorization": fmt.Sprintf("Bearer %s", auth),
|
||||
},
|
||||
Method: "GET",
|
||||
}
|
||||
res, err = req.Send()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var orderLog ZltxOrderLogResponse
|
||||
if err = json.Unmarshal(res.Content, &orderLog); err != nil {
|
||||
return
|
||||
}
|
||||
if orderLog.Code != 200 {
|
||||
return fmt.Errorf("订单日志查询失败:%s", orderLog.Error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue