- Replaced the custom context creation functions with a new context package, enhancing consistency and maintainability across the API. - Updated multiple methods in the DSL to utilize the new context package, ensuring a unified approach to context management. - Removed the obsolete context.go file, streamlining the codebase and reducing redundancy. These changes improve the overall structure and clarity of the Neo API, paving the way for future enhancements in context handling and assistant functionalities.
151 lines
3.2 KiB
Go
151 lines
3.2 KiB
Go
package neo
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"github.com/yaoapp/gou/process"
|
|
chatctx "github.com/yaoapp/yao/neo/context"
|
|
)
|
|
|
|
// HookCreate create the assistant
|
|
func (neo *DSL) HookCreate(ctx chatctx.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
|
|
}
|
|
|
|
// HookPrepare executes the prepare hook before AI is called
|
|
func (neo *DSL) HookPrepare(ctx chatctx.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 chatctx.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
|
|
}
|