Skip to content

Commit

Permalink
Merge pull request #852 from trheyi/main
Browse files Browse the repository at this point in the history
Refactor chat history and message processing
  • Loading branch information
trheyi authored Feb 6, 2025
2 parents 47ea370 + dabba1a commit c338086
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 80 deletions.
139 changes: 59 additions & 80 deletions neo/assistant/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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
}()

Expand Down Expand Up @@ -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,
Expand All @@ -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
}
Expand Down Expand Up @@ -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())
Expand Down
1 change: 1 addition & 0 deletions neo/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c338086

Please sign in to comment.