From 860bfd1d0d5002f117036b92445c2d8e9166bb34 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 14 Jan 2025 16:13:14 +0800 Subject: [PATCH] Enhance Neo API assistant with new action execution capabilities - Introduced a new Execute method for handling next actions in the Assistant struct, allowing for dynamic execution of various actions such as "process" and "assistant". - Improved error handling by validating payloads and providing meaningful error messages for missing or incorrect data. - Streamlined the flow of next actions in the Execute method, enhancing the assistant's ability to manage complex interactions and responses. - Updated the streamChat method to utilize the new Execute method, improving the handling of next actions during chat streaming. These changes enhance the robustness and maintainability of the Neo API, paving the way for more flexible and powerful assistant functionalities. --- neo/assistant/api.go | 96 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/neo/assistant/api.go b/neo/assistant/api.go index eda682bd..56426014 100644 --- a/neo/assistant/api.go +++ b/neo/assistant/api.go @@ -8,6 +8,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yaoapp/gou/fs" + "github.com/yaoapp/gou/process" chatctx "github.com/yaoapp/yao/neo/context" "github.com/yaoapp/yao/neo/message" chatMessage "github.com/yaoapp/yao/neo/message" @@ -69,11 +70,7 @@ func (ast *Assistant) Execute(c *gin.Context, ctx chatctx.Context, input string, // Handle next action if res.Next != nil { - switch res.Next.Action { - case "exit": - return nil - // Add other actions here if needed - } + return res.Next.Execute(c, ctx) } // Update options if provided @@ -90,6 +87,78 @@ func (ast *Assistant) Execute(c *gin.Context, ctx chatctx.Context, input string, return ast.handleChatStream(c, ctx, messages, options) } +// Execute the next action +func (next *NextAction) Execute(c *gin.Context, ctx chatctx.Context) error { + switch next.Action { + + case "process": + if next.Payload == nil { + return fmt.Errorf("payload is required") + } + + name, ok := next.Payload["name"].(string) + if !ok { + return fmt.Errorf("process name should be string") + } + + args := []interface{}{} + if v, ok := next.Payload["args"].([]interface{}); ok { + args = v + } + + // Add context and writer to args + args = append(args, ctx, c.Writer) + p, err := process.Of(name, args...) + if err != nil { + return fmt.Errorf("get process error: %s", err.Error()) + } + + err = p.Execute() + if err != nil { + return fmt.Errorf("execute process error: %s", err.Error()) + } + defer p.Release() + + return nil + + case "assistant": + if next.Payload == nil { + return fmt.Errorf("payload is required") + } + + // Get assistant id + id, ok := next.Payload["assistant_id"].(string) + if !ok { + return fmt.Errorf("assistant id should be string") + } + + // Get assistant + assistant, err := Get(id) + if err != nil { + return fmt.Errorf("get assistant error: %s", err.Error()) + } + + // Input + input, ok := next.Payload["input"].(string) + if !ok { + return fmt.Errorf("input should be string") + } + + // Options + options := map[string]interface{}{} + if v, ok := next.Payload["options"].(map[string]interface{}); ok { + options = v + } + return assistant.Execute(c, ctx, input, options) + + case "exit": + return nil + + default: + return fmt.Errorf("unknown action: %s", next.Action) + } +} + // handleChatStream manages the streaming chat interaction with the AI func (ast *Assistant) handleChatStream(c *gin.Context, ctx chatctx.Context, messages []message.Message, options map[string]interface{}) error { clientBreak := make(chan bool, 1) @@ -156,10 +225,17 @@ func (ast *Assistant) streamChat(c *gin.Context, ctx chatctx.Context, messages [ if res.Output != "" { value = res.Output } - if res.Next != nil && res.Next.Action == "exit" { + + if res.Next != nil { + err = res.Next.Execute(c, ctx) + if err != nil { + chatMessage.New().Error(err.Error()).Done().Write(c.Writer) + } + done <- true return 0 // break } + if res.Silent { return 1 // continue } @@ -190,10 +266,16 @@ func (ast *Assistant) streamChat(c *gin.Context, ctx chatctx.Context, messages [ }). Write(c.Writer) } - if res.Next != nil && res.Next.Action == "exit" { + + if res.Next != nil { + err := res.Next.Execute(c, ctx) + if err != nil { + chatMessage.New().Error(err.Error()).Done().Write(c.Writer) + } done <- true return 0 // break } + } else if value != "" { chatMessage.New(). Map(map[string]interface{}{