- Introduced new endpoints for retrieving chat details and mentions, enhancing the API's functionality. - Implemented handleChatDetail method to fetch details of a specific chat by ID, including error handling for missing parameters. - Added handleMentions method to retrieve mentions based on keywords, improving user interaction with chat content. - Updated existing GetChats method to support keyword filtering, allowing for more refined chat list retrieval. - Enhanced the DSL structure to include new methods for managing mentions and chat details, improving overall code organization and maintainability.
253 lines
5.2 KiB
Go
253 lines
5.2 KiB
Go
package neo
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"github.com/yaoapp/gou/process"
|
|
"github.com/yaoapp/yao/neo/assistant"
|
|
)
|
|
|
|
// HookCreate create the assistant
|
|
func (neo *DSL) HookCreate(ctx Context, messages []map[string]interface{}, c *gin.Context) (CreateResponse, error) {
|
|
|
|
// Default assistant
|
|
assistantID := neo.Use
|
|
if ctx.AssistantID != "" {
|
|
assistantID = ctx.AssistantID
|
|
}
|
|
|
|
// Empty hook
|
|
if neo.Create == "" {
|
|
return CreateResponse{AssistantID: assistantID, ChatID: ctx.ChatID}, nil
|
|
}
|
|
|
|
// Create a context with 10 second timeout
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
|
defer cancel()
|
|
|
|
p, err := process.Of(neo.Create, ctx, messages, c.Writer)
|
|
if err != nil {
|
|
return CreateResponse{}, err
|
|
}
|
|
|
|
err = p.WithContext(timeoutCtx).Execute()
|
|
if err != nil {
|
|
return CreateResponse{}, err
|
|
}
|
|
defer p.Release()
|
|
|
|
// Check if context was canceled
|
|
if timeoutCtx.Err() != nil {
|
|
return CreateResponse{}, timeoutCtx.Err()
|
|
}
|
|
|
|
value := p.Value()
|
|
switch v := value.(type) {
|
|
case CreateResponse:
|
|
return v, nil
|
|
|
|
case map[string]interface{}:
|
|
if id, ok := v["assistant_id"].(string); ok {
|
|
assistantID = id
|
|
}
|
|
|
|
chatID := ""
|
|
if id, ok := v["chat_id"].(string); ok {
|
|
chatID = id
|
|
}
|
|
|
|
if chatID == "" {
|
|
chatID = ctx.ChatID
|
|
}
|
|
|
|
return CreateResponse{AssistantID: assistantID, ChatID: chatID}, nil
|
|
}
|
|
|
|
return CreateResponse{AssistantID: assistantID, ChatID: ctx.ChatID}, nil
|
|
}
|
|
|
|
// HookAssistants query the assistant list from the assistant list hook
|
|
func (neo *DSL) HookAssistants(ctx context.Context, param assistant.QueryParam) ([]assistant.Assistant, error) {
|
|
if neo.AssistantListHook == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
// Create a context with 10 second timeout
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
|
defer cancel()
|
|
|
|
p, err := process.Of(neo.AssistantListHook, param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = p.WithContext(timeoutCtx).Execute()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer p.Release()
|
|
|
|
// Check if context was canceled
|
|
if timeoutCtx.Err() != nil {
|
|
return nil, timeoutCtx.Err()
|
|
}
|
|
|
|
value := p.Value()
|
|
if value == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
var list []assistant.Assistant
|
|
bytes, err := jsoniter.Marshal(value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = jsoniter.Unmarshal(bytes, &list)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return list, nil
|
|
}
|
|
|
|
// HookPrepare executes the prepare hook before AI is called
|
|
func (neo *DSL) HookPrepare(ctx Context, messages []map[string]interface{}) ([]map[string]interface{}, error) {
|
|
if neo.Prepare == "" {
|
|
return messages, nil
|
|
}
|
|
|
|
// Create a context with 10 second timeout
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
|
defer cancel()
|
|
|
|
p, err := process.Of(neo.Prepare, ctx, messages)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = p.WithContext(timeoutCtx).Execute()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer p.Release()
|
|
|
|
// Check if context was canceled
|
|
if timeoutCtx.Err() != nil {
|
|
return nil, timeoutCtx.Err()
|
|
}
|
|
|
|
value := p.Value()
|
|
if value == nil {
|
|
return messages, nil
|
|
}
|
|
|
|
var result []map[string]interface{}
|
|
bytes, err := jsoniter.Marshal(value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = jsoniter.Unmarshal(bytes, &result)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// HookWrite executes the write hook when response is received from AI
|
|
func (neo *DSL) HookWrite(ctx Context, messages []map[string]interface{}, response map[string]interface{}, content string, writer *gin.ResponseWriter) ([]map[string]interface{}, error) {
|
|
if neo.Write == "" {
|
|
return []map[string]interface{}{response}, nil
|
|
}
|
|
|
|
p, err := process.Of(neo.Write, ctx, messages, response, content, writer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = p.WithContext(ctx).Execute()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer p.Release()
|
|
|
|
value := p.Value()
|
|
if value == nil {
|
|
return []map[string]interface{}{response}, nil
|
|
}
|
|
|
|
var result []map[string]interface{}
|
|
bytes, err := jsoniter.Marshal(value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = jsoniter.Unmarshal(bytes, &result)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// HookMention query the mention list
|
|
func (neo *DSL) HookMention(ctx context.Context, keywords string) ([]Mention, error) {
|
|
|
|
// Default Get the assistant list
|
|
if neo.MentionHook == "" {
|
|
var mentions []Mention
|
|
assistants := neo.GetAssistants()
|
|
for _, assistant := range assistants {
|
|
mentions = append(mentions, Mention{
|
|
ID: assistant.ID,
|
|
Name: assistant.Name,
|
|
Type: "assistant",
|
|
})
|
|
}
|
|
|
|
return mentions, nil
|
|
}
|
|
|
|
// Create a context with 10 second timeout
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
|
defer cancel()
|
|
|
|
p, err := process.Of(neo.MentionHook, keywords)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = p.WithContext(timeoutCtx).Execute()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer p.Release()
|
|
|
|
// Check if context was canceled
|
|
if timeoutCtx.Err() != nil {
|
|
return nil, timeoutCtx.Err()
|
|
}
|
|
|
|
value := p.Value()
|
|
if value == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
var list []Mention
|
|
bytes, err := jsoniter.Marshal(value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = jsoniter.Unmarshal(bytes, &list)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return list, nil
|
|
}
|