From dabba1a7443c88e01051e86bfe234505da79ee68 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 6 Feb 2025 16:39:31 +0800 Subject: [PATCH] Refactor chat history and message processing - Added `Hidden` flag to `Message` struct for controlling message visibility - Modified `saveChatHistory` to conditionally save messages based on hidden status - Simplified stream chat processing by removing debug print statements - Restructured message output and next action handling in stream chat - Commented out unused process action execution method --- neo/assistant/api.go | 139 +++++++++++++++++------------------------ neo/message/message.go | 1 + 2 files changed, 60 insertions(+), 80 deletions(-) diff --git a/neo/assistant/api.go b/neo/assistant/api.go index c947af6b7f..8b86d0ba93 100644 --- a/neo/assistant/api.go +++ b/neo/assistant/api.go @@ -9,8 +9,6 @@ import ( "github.com/gin-gonic/gin" jsoniter "github.com/json-iterator/go" "github.com/yaoapp/gou/fs" - "github.com/yaoapp/gou/process" - "github.com/yaoapp/kun/utils" chatctx "github.com/yaoapp/yao/neo/context" chatMessage "github.com/yaoapp/yao/neo/message" ) @@ -115,35 +113,37 @@ func (ast *Assistant) execute(c *gin.Context, ctx chatctx.Context, input []chatM func (next *NextAction) Execute(c *gin.Context, ctx chatctx.Context, contents *chatMessage.Contents) 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 + // It's not used, because the process could be executed in the hook script + // It may remove in the future + // 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 { @@ -201,6 +201,7 @@ func (next *NextAction) Execute(c *gin.Context, ctx chatctx.Context, contents *c options = v } + input.Hidden = true // not show in the history messages, err := assistant.withHistory(ctx, input) if err != nil { return fmt.Errorf("with history error: %s", err.Error()) @@ -263,9 +264,6 @@ func (ast *Assistant) handleChatStream(c *gin.Context, ctx chatctx.Context, mess if err != nil { chatMessage.New().Error(err).Done().Write(c.Writer) } - - ast.saveChatHistory(ctx, messages, contents) - fmt.Printf("saveChatHistory %v\n", ctx.ChatID) done <- true }() @@ -418,30 +416,8 @@ func (ast *Assistant) streamChat( // Complete the stream if msg.IsDone { - // if value == "" { - // msg.Write(c.Writer) - // } - - // Remove the last empty data - contents.RemoveLastEmpty() - - res, hookErr := ast.HookDone(c, ctx, messages, contents) - if hookErr == nil && res != nil { - if res.Next != nil { - - fmt.Println("---- Execute Next ---") - utils.Dump(res.Next) - fmt.Println("---- Execute Next end ---") - err := res.Next.Execute(c, ctx, contents) - if err != nil { - chatMessage.New().Error(err.Error()).Done().Write(c.Writer) - } - - done <- true - return 0 // break - } - - } else if delta != "" { + // Send the last message to the client + if delta != "" { chatMessage.New(). Map(map[string]interface{}{ "assistant_id": ast.ID, @@ -455,22 +431,36 @@ func (ast *Assistant) streamChat( Write(c.Writer) } - // Hook execute error + // Remove the last empty data + contents.RemoveLastEmpty() + res, hookErr := ast.HookDone(c, ctx, messages, contents) + + // Some error occurred in the hook, return the error if hookErr != nil { chatMessage.New().Error(hookErr.Error()).Done().Write(c.Writer) done <- true return 0 // break } - msg := chatMessage.New().Done() + // Save the chat history + ast.saveChatHistory(ctx, messages, contents) + + // If the hook is successful, execute the next action + if res != nil && res.Next != nil { + err := res.Next.Execute(c, ctx, contents) + if err != nil { + chatMessage.New().Error(err.Error()).Done().Write(c.Writer) + } + done <- true + return 0 // break + } + + // The default output + output := chatMessage.New().Done() if res != nil && res.Output != nil { - msg = chatMessage.New(). - Map(map[string]interface{}{ - "text": res.Input, - "done": true, - }) + output = chatMessage.New().Map(map[string]interface{}{"text": res.Output, "done": true}) } - msg.Write(c.Writer) + output.Write(c.Writer) done <- true return 0 // break } @@ -516,20 +506,9 @@ func (ast *Assistant) saveChatHistory(ctx chatctx.Context, messages []chatMessag }, } - // contents - fmt.Println("---contents ---") - if contents.Data != nil { - fmt.Println("---contents.Data ---") - for _, content := range contents.Data { - fmt.Println(content.Map()) - } - fmt.Println("---contents.Data end ---") - } - fmt.Println("---contents end ---") - - // Add mentions - if userMessage.Mentions != nil { - data[0]["mentions"] = userMessage.Mentions + // if the user message is hidden, just save the assistant message + if userMessage.Hidden { + data = []map[string]interface{}{data[1]} } storage.SaveHistory(ctx.Sid, data, ctx.ChatID, ctx.Map()) diff --git a/neo/message/message.go b/neo/message/message.go index 9f5e96e3ba..79f3fa0e45 100644 --- a/neo/message/message.go +++ b/neo/message/message.go @@ -33,6 +33,7 @@ type Message struct { Mentions []Mention `json:"menions,omitempty"` // Mentions for the message ( for user role = user ) Data map[string]interface{} `json:"-"` // data for the message Pending bool `json:"-"` // pending for the message + Hidden bool `json:"hidden,omitempty"` // hidden for the message (not show in the UI and history) } // Mention represents a mention