Enhance chat update functionality and introduce chat title generation in Neo API
- Updated handleChatUpdate method to include content field in the request body, allowing for dynamic chat title generation based on user input. - Implemented GenerateChatTitle method to create a concise title for chats, improving user experience and interaction. - Modified JSON response structure in handleChatDetail and handleChatUpdate methods for better clarity and consistency. - Enhanced error handling for chat updates, ensuring robust validation and feedback for users.
This commit is contained in:
parent
869ed3717a
commit
b3bc843235
2 changed files with 114 additions and 3 deletions
21
neo/api.go
21
neo/api.go
|
|
@ -338,7 +338,7 @@ func (neo *DSL) handleChatDetail(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.JSON(200, chat)
|
||||
c.JSON(200, map[string]interface{}{"data": chat})
|
||||
c.Done()
|
||||
}
|
||||
|
||||
|
|
@ -382,7 +382,8 @@ func (neo *DSL) handleChatUpdate(c *gin.Context) {
|
|||
|
||||
// Get title from request body
|
||||
var body struct {
|
||||
Title string `json:"title"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
if err := c.BindJSON(&body); err != nil {
|
||||
c.JSON(400, gin.H{"message": "invalid request body", "code": 400})
|
||||
|
|
@ -390,6 +391,20 @@ func (neo *DSL) handleChatUpdate(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// If content is not empty, Generate the chat title
|
||||
if body.Content != "" {
|
||||
ctx, cancel := NewContextWithCancel(sid, c.Query("chat_id"), "")
|
||||
defer cancel()
|
||||
|
||||
title, err := neo.GenerateChatTitle(ctx, body.Content, c)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
body.Title = title
|
||||
}
|
||||
|
||||
if body.Title == "" {
|
||||
c.JSON(400, gin.H{"message": "title is required", "code": 400})
|
||||
c.Done()
|
||||
|
|
@ -403,6 +418,6 @@ func (neo *DSL) handleChatUpdate(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"message": "success"})
|
||||
c.JSON(200, gin.H{"message": "ok", "title": body.Title, "chat_id": chatID})
|
||||
c.Done()
|
||||
}
|
||||
|
|
|
|||
96
neo/neo.go
96
neo/neo.go
|
|
@ -58,6 +58,102 @@ func (neo *DSL) GetMentions(keywords string) ([]Mention, error) {
|
|||
return neo.HookMention(context.Background(), keywords)
|
||||
}
|
||||
|
||||
// GenerateChatTitle generate the chat title
|
||||
func (neo *DSL) GenerateChatTitle(ctx Context, input string, c *gin.Context) (string, error) {
|
||||
|
||||
prompts := `
|
||||
Help me generate a title for the chat
|
||||
1. The title should be a short and concise description of the chat.
|
||||
2. The title should be a single sentence.
|
||||
3. The title should be in same language as the chat.
|
||||
4. The title should be no more than 50 characters.
|
||||
`
|
||||
|
||||
messages := []map[string]interface{}{
|
||||
{"role": "system", "content": prompts},
|
||||
{"role": "user", "content": input},
|
||||
}
|
||||
|
||||
res, err := neo.HookCreate(ctx, messages, c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Select Assistant
|
||||
ast, err := neo.selectAssistant(res.AssistantID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if ast == nil {
|
||||
msg := message.New().Error("assistant is not initialized").Done()
|
||||
msg.Write(c.Writer)
|
||||
return "", fmt.Errorf("assistant is not initialized")
|
||||
}
|
||||
|
||||
clientBreak := make(chan bool, 1)
|
||||
done := make(chan bool, 1)
|
||||
fail := make(chan error, 1)
|
||||
|
||||
content := []byte{}
|
||||
|
||||
// Chat with AI in background
|
||||
go func() {
|
||||
err := ast.Chat(c.Request.Context(), messages, neo.Option, func(data []byte) int {
|
||||
select {
|
||||
case <-clientBreak:
|
||||
return 0 // break
|
||||
|
||||
default:
|
||||
msg := message.NewOpenAI(data)
|
||||
if msg == nil {
|
||||
return 1 // continue
|
||||
}
|
||||
|
||||
// Handle error
|
||||
if msg.Type == "error" {
|
||||
fail <- fmt.Errorf("%s", msg.Message.Text)
|
||||
return 0 // break
|
||||
}
|
||||
|
||||
// Append content and send message
|
||||
content = msg.Append(content)
|
||||
|
||||
// Complete the stream
|
||||
if msg.Message.Done {
|
||||
done <- true
|
||||
return 0 // break
|
||||
}
|
||||
|
||||
return 1 // continue
|
||||
}
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("Chat error: %s", err.Error())
|
||||
message.New().Error(err).Done().Write(c.Writer)
|
||||
}
|
||||
|
||||
// Save chat history
|
||||
if len(content) > 0 {
|
||||
neo.saveHistory(ctx.Sid, ctx.ChatID, content, messages)
|
||||
}
|
||||
|
||||
done <- true
|
||||
}()
|
||||
|
||||
// Wait for completion or client disconnect
|
||||
select {
|
||||
case <-done:
|
||||
return string(content), nil
|
||||
case err := <-fail:
|
||||
return "", err
|
||||
case <-c.Writer.CloseNotify():
|
||||
clientBreak <- true
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
|
||||
// Upload upload a file
|
||||
func (neo *DSL) Upload(ctx Context, c *gin.Context) (*assistant.File, error) {
|
||||
// Get the file
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue