Enhance Neo API assistant message handling and response structure

- Added nil checks for response objects in the Execute method to prevent potential nil pointer dereferences.
- Updated the streamChat method to include assistant identification details (ID, name, avatar) in the message structure, improving context for messages.
- Introduced a new field in the Message struct to mark messages as new, enhancing message tracking capabilities.

These changes improve the robustness and maintainability of the Neo API, paving the way for better message handling and assistant functionalities.
This commit is contained in:
Max 2025-01-18 11:20:55 +08:00
parent d43b7b8927
commit 228e8cf482
2 changed files with 39 additions and 15 deletions

View file

@ -60,7 +60,7 @@ func (ast *Assistant) Execute(c *gin.Context, ctx chatctx.Context, input string,
} }
// Switch to the new assistant if necessary // Switch to the new assistant if necessary
if res.AssistantID != ctx.AssistantID { if res != nil && res.AssistantID != ctx.AssistantID {
newAst, err := Get(res.AssistantID) newAst, err := Get(res.AssistantID)
if err != nil { if err != nil {
return err return err
@ -69,17 +69,17 @@ func (ast *Assistant) Execute(c *gin.Context, ctx chatctx.Context, input string,
} }
// Handle next action // Handle next action
if res.Next != nil { if res != nil && res.Next != nil {
return res.Next.Execute(c, ctx) return res.Next.Execute(c, ctx)
} }
// Update options if provided // Update options if provided
if res.Options != nil { if res != nil && res.Options != nil {
options = res.Options options = res.Options
} }
// messages // messages
if res.Input != nil { if res != nil && res.Input != nil {
messages = res.Input messages = res.Input
} }
@ -263,17 +263,20 @@ func (ast *Assistant) streamChat(
chatMessage.New(). chatMessage.New().
Map(map[string]interface{}{ Map(map[string]interface{}{
"text": value, "assistant_id": ast.ID,
"done": msg.IsDone, "assistant_name": ast.Name,
"assistant_avatar": ast.Avatar,
"text": value,
"done": msg.IsDone,
}). }).
Write(c.Writer) Write(c.Writer)
} }
// Complete the stream // Complete the stream
if msg.IsDone { if msg.IsDone {
// if value == "" { if value == "" {
// msg.Write(c.Writer) msg.Write(c.Writer)
// } }
// Call HookDone // Call HookDone
content.SetStatus(chatMessage.ContentStatusDone) content.SetStatus(chatMessage.ContentStatusDone)
@ -300,8 +303,11 @@ func (ast *Assistant) streamChat(
} else if value != "" { } else if value != "" {
chatMessage.New(). chatMessage.New().
Map(map[string]interface{}{ Map(map[string]interface{}{
"text": value, "assistant_id": ast.ID,
"done": true, "assistant_name": ast.Name,
"assistant_avatar": ast.Avatar,
"text": value,
"done": true,
}). }).
Write(c.Writer) Write(c.Writer)
} }

View file

@ -16,10 +16,11 @@ import (
// Message the message // Message the message
type Message struct { type Message struct {
Text string `json:"text,omitempty"` // text content Text string `json:"text,omitempty"` // text content
Type string `json:"type,omitempty"` // error, text, plan, table, form, page, file, video, audio, image, markdown, json ... Type string `json:"type,omitempty"` // error, text, plan, table, form, page, file, video, audio, image, markdown, json ...
Props map[string]interface{} `json:"props,omitempty"` // props for the types Props map[string]interface{} `json:"props,omitempty"` // props for the types
IsDone bool `json:"done,omitempty"` IsDone bool `json:"done,omitempty"` // Mark as a done message from neo
IsNew bool `json:"is_new,omitempty"` // Mark as a new message from neo
Actions []Action `json:"actions,omitempty"` // Conversation Actions for frontend Actions []Action `json:"actions,omitempty"` // Conversation Actions for frontend
Attachments []Attachment `json:"attachments,omitempty"` // File attachments Attachments []Attachment `json:"attachments,omitempty"` // File attachments
Role string `json:"role,omitempty"` // user, assistant, system ... Role string `json:"role,omitempty"` // user, assistant, system ...
@ -244,6 +245,23 @@ func (m *Message) Map(msg map[string]interface{}) *Message {
if done, ok := msg["done"].(bool); ok { if done, ok := msg["done"].(bool); ok {
m.IsDone = done m.IsDone = done
} }
if isNew, ok := msg["is_new"].(bool); ok {
m.IsNew = isNew
}
if assistantID, ok := msg["assistant_id"].(string); ok {
m.AssistantID = assistantID
}
if assistantName, ok := msg["assistant_name"].(string); ok {
m.AssistantName = assistantName
}
if assistantAvatar, ok := msg["assistant_avatar"].(string); ok {
m.AssistantAvatar = assistantAvatar
}
if actions, ok := msg["actions"].([]interface{}); ok { if actions, ok := msg["actions"].([]interface{}); ok {
for _, action := range actions { for _, action := range actions {
if v, ok := action.(map[string]interface{}); ok { if v, ok := action.(map[string]interface{}); ok {