Add chat detail and mentions handling in Neo API
- 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.
This commit is contained in:
parent
2da7c30ac5
commit
eadc550980
9 changed files with 373 additions and 94 deletions
58
neo/api.go
58
neo/api.go
|
|
@ -28,18 +28,22 @@ func (neo *DSL) API(router *gin.Engine, path string) error {
|
|||
router.OPTIONS(path, neo.optionsHandler)
|
||||
router.OPTIONS(path+"/status", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/chats", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/chats/:id", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/history", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/upload", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/download", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/mentions", neo.optionsHandler)
|
||||
|
||||
// Register endpoints with middlewares
|
||||
router.GET(path, append(middlewares, neo.handleChat)...)
|
||||
router.POST(path, append(middlewares, neo.handleChat)...)
|
||||
router.GET(path+"/status", append(middlewares, neo.handleStatus)...)
|
||||
router.GET(path+"/chats", append(middlewares, neo.handleChatList)...)
|
||||
router.GET(path+"/chats/:id", append(middlewares, neo.handleChatDetail)...)
|
||||
router.GET(path+"/history", append(middlewares, neo.handleChatHistory)...)
|
||||
router.POST(path+"/upload", append(middlewares, neo.handleUpload)...)
|
||||
router.GET(path+"/download", append(middlewares, neo.handleDownload)...)
|
||||
router.GET(path+"/mentions", append(middlewares, neo.handleMentions)...)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +111,10 @@ func (neo *DSL) handleChatList(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
list, err := neo.Conversation.GetChats(sid)
|
||||
// Get keywords from query parameter
|
||||
keywords := c.Query("keywords")
|
||||
|
||||
list, err := neo.Conversation.GetChats(sid, keywords)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
|
|
@ -295,3 +302,52 @@ func (neo *DSL) defaultGuard(c *gin.Context) {
|
|||
c.Set("__sid", user.SID)
|
||||
c.Next()
|
||||
}
|
||||
|
||||
// handleChatDetail handles getting a single chat's details
|
||||
func (neo *DSL) handleChatDetail(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
chatID := c.Param("id")
|
||||
if chatID == "" {
|
||||
c.JSON(400, gin.H{"message": "chat id is required", "code": 400})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
chat, err := neo.Conversation.GetChat(sid, chatID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, chat)
|
||||
c.Done()
|
||||
}
|
||||
|
||||
// handleMentions handles getting mentions for a chat
|
||||
func (neo *DSL) handleMentions(c *gin.Context) {
|
||||
sid := c.GetString("__sid")
|
||||
if sid == "" {
|
||||
c.JSON(400, gin.H{"message": "sid is required", "code": 400})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
// Get keywords from query parameter
|
||||
keywords := c.Query("keywords")
|
||||
mentions, err := neo.GetMentions(keywords)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, map[string]interface{}{"data": mentions})
|
||||
c.Done()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ func (conv *Mongo) UpdateChatTitle(sid string, cid string, title string) error {
|
|||
}
|
||||
|
||||
// GetChats get the chat list
|
||||
func (conv *Mongo) GetChats(sid string) ([]map[string]interface{}, error) {
|
||||
func (conv *Mongo) GetChats(sid string, keywords ...string) ([]map[string]interface{}, error) {
|
||||
return []map[string]interface{}{}, nil
|
||||
}
|
||||
|
||||
|
|
@ -37,3 +37,8 @@ func (conv *Mongo) GetRequest(sid string, rid string) ([]map[string]interface{},
|
|||
func (conv *Mongo) SaveRequest(sid string, rid string, cid string, messages []map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetChat get the chat info and its history
|
||||
func (conv *Mongo) GetChat(sid string, cid string) (*ChatInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ func (conv *Redis) UpdateChatTitle(sid string, cid string, title string) error {
|
|||
}
|
||||
|
||||
// GetChats get the chat list
|
||||
func (conv *Redis) GetChats(sid string) ([]map[string]interface{}, error) {
|
||||
func (conv *Redis) GetChats(sid string, keywords ...string) ([]map[string]interface{}, error) {
|
||||
return []map[string]interface{}{}, nil
|
||||
}
|
||||
|
||||
|
|
@ -37,3 +37,8 @@ func (conv *Redis) GetRequest(sid string, rid string) ([]map[string]interface{},
|
|||
func (conv *Redis) SaveRequest(sid string, rid string, cid string, messages []map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetChat get the chat info and its history
|
||||
func (conv *Redis) GetChat(sid string, cid string) (*ChatInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,17 @@ type Setting struct {
|
|||
TTL int `json:"ttl,omitempty" yaml:"ttl,omitempty"`
|
||||
}
|
||||
|
||||
// ChatInfo represents the chat information and its history
|
||||
type ChatInfo struct {
|
||||
Chat map[string]interface{} `json:"chat"`
|
||||
History []map[string]interface{} `json:"history"`
|
||||
}
|
||||
|
||||
// Conversation the store interface
|
||||
type Conversation interface {
|
||||
UpdateChatTitle(sid string, cid string, title string) error
|
||||
GetChats(sid string) ([]map[string]interface{}, error)
|
||||
GetChats(sid string, keywords ...string) ([]map[string]interface{}, error)
|
||||
GetChat(sid string, cid string) (*ChatInfo, error)
|
||||
GetHistory(sid string, cid string) ([]map[string]interface{}, error)
|
||||
SaveHistory(sid string, messages []map[string]interface{}, cid string) error
|
||||
GetRequest(sid string, rid string) ([]map[string]interface{}, error)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ func (conv *Weaviate) UpdateChatTitle(sid string, cid string, title string) erro
|
|||
}
|
||||
|
||||
// GetChats get the chat list
|
||||
func (conv *Weaviate) GetChats(sid string) ([]map[string]interface{}, error) {
|
||||
func (conv *Weaviate) GetChats(sid string, keywords ...string) ([]map[string]interface{}, error) {
|
||||
return []map[string]interface{}{}, nil
|
||||
}
|
||||
|
||||
|
|
@ -37,3 +37,8 @@ func (conv *Weaviate) GetRequest(sid string, rid string) ([]map[string]interface
|
|||
func (conv *Weaviate) SaveRequest(sid string, rid string, cid string, messages []map[string]interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetChat get the chat info and its history
|
||||
func (conv *Weaviate) GetChat(sid string, cid string) (*ChatInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package conversation
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/yaoapp/gou/connector"
|
||||
|
|
@ -29,16 +30,23 @@ type row struct {
|
|||
ExpiredAt interface{} `json:"expired_at"`
|
||||
}
|
||||
|
||||
// Public interface methods and constructor remain exported:
|
||||
// - NewXun
|
||||
// - UpdateChatTitle
|
||||
// - GetChats
|
||||
// - GetChat
|
||||
// - GetHistory
|
||||
// - SaveHistory
|
||||
// - GetRequest
|
||||
// - SaveRequest
|
||||
|
||||
// NewXun create a new conversation
|
||||
func NewXun(setting Setting) (*Xun, error) {
|
||||
|
||||
conv := &Xun{setting: setting}
|
||||
if setting.Connector == "default" {
|
||||
conv.query = capsule.Global.Query()
|
||||
conv.schema = capsule.Global.Schema()
|
||||
|
||||
} else {
|
||||
|
||||
conn, err := connector.Select(setting.Connector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -55,7 +63,7 @@ func NewXun(setting Setting) (*Xun, error) {
|
|||
}
|
||||
}
|
||||
|
||||
err := conv.Init()
|
||||
err := conv.initialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -63,43 +71,175 @@ func NewXun(setting Setting) (*Xun, error) {
|
|||
return conv, nil
|
||||
}
|
||||
|
||||
// NewQuery create a new query
|
||||
func (conv *Xun) NewQuery() query.Query {
|
||||
// Rename the following functions to start with lowercase letters to make them private:
|
||||
|
||||
func (conv *Xun) newQuery() query.Query {
|
||||
qb := conv.query.New()
|
||||
qb.Table(conv.setting.Table)
|
||||
qb.Table(conv.getHistoryTable())
|
||||
return qb
|
||||
}
|
||||
|
||||
func (conv *Xun) newQueryChat() query.Query {
|
||||
qb := conv.query.New()
|
||||
qb.Table(conv.getChatTable())
|
||||
return qb
|
||||
}
|
||||
|
||||
func (conv *Xun) clean() {
|
||||
nums, err := conv.newQuery().Where("expired_at", "<=", time.Now()).Delete()
|
||||
if err != nil {
|
||||
log.Error("Clean the conversation table error: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if nums > 0 {
|
||||
log.Trace("Clean the conversation table: %s %d", conv.setting.Table, nums)
|
||||
}
|
||||
}
|
||||
|
||||
// Rename Init to initialize to avoid conflicts
|
||||
func (conv *Xun) initialize() error {
|
||||
// Initialize history table
|
||||
if err := conv.initHistoryTable(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize chat table
|
||||
if err := conv.initChatTable(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (conv *Xun) initHistoryTable() error {
|
||||
historyTable := conv.getHistoryTable()
|
||||
has, err := conv.schema.HasTable(historyTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the history table
|
||||
if !has {
|
||||
err = conv.schema.CreateTable(historyTable, func(table schema.Blueprint) {
|
||||
table.ID("id")
|
||||
table.String("sid", 255).Index()
|
||||
table.String("rid", 255).Null().Index()
|
||||
table.String("cid", 200).Null().Index()
|
||||
table.String("role", 200).Null().Index()
|
||||
table.String("name", 200).Null().Index()
|
||||
table.Text("content").Null()
|
||||
table.TimestampTz("created_at").SetDefaultRaw("NOW()").Index()
|
||||
table.TimestampTz("updated_at").Null().Index()
|
||||
table.TimestampTz("expired_at").Null().Index()
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Trace("Create the conversation history table: %s", historyTable)
|
||||
}
|
||||
|
||||
// Validate the table
|
||||
tab, err := conv.schema.GetTable(historyTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fields := []string{"id", "sid", "rid", "cid", "role", "name", "content", "created_at", "updated_at", "expired_at"}
|
||||
for _, field := range fields {
|
||||
if !tab.HasColumn(field) {
|
||||
return fmt.Errorf("%s is required", field)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (conv *Xun) initChatTable() error {
|
||||
chatTable := conv.getChatTable()
|
||||
has, err := conv.schema.HasTable(chatTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the chat table
|
||||
if !has {
|
||||
err = conv.schema.CreateTable(chatTable, func(table schema.Blueprint) {
|
||||
table.ID("id")
|
||||
table.String("chat_id", 200).Unique().Index()
|
||||
table.String("title", 200).Null()
|
||||
table.String("sid", 255).Index()
|
||||
table.TimestampTz("created_at").SetDefaultRaw("NOW()").Index()
|
||||
table.TimestampTz("updated_at").Null().Index()
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Trace("Create the chat table: %s", chatTable)
|
||||
}
|
||||
|
||||
// Validate the table
|
||||
tab, err := conv.schema.GetTable(chatTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fields := []string{"id", "chat_id", "title", "sid", "created_at", "updated_at"}
|
||||
for _, field := range fields {
|
||||
if !tab.HasColumn(field) {
|
||||
return fmt.Errorf("%s is required", field)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (conv *Xun) getHistoryTable() string {
|
||||
return conv.setting.Table
|
||||
}
|
||||
|
||||
func (conv *Xun) getChatTable() string {
|
||||
return conv.setting.Table + "_chat"
|
||||
}
|
||||
|
||||
// UpdateChatTitle update the chat title
|
||||
func (conv *Xun) UpdateChatTitle(sid string, cid string, title string) error {
|
||||
_, err := conv.NewQuery().
|
||||
Where("sid", sid).Where("cid", cid).
|
||||
Update(map[string]interface{}{"title": title})
|
||||
_, err := conv.newQueryChat().
|
||||
Where("sid", sid).
|
||||
Where("chat_id", cid).
|
||||
Update(map[string]interface{}{
|
||||
"title": title,
|
||||
"updated_at": time.Now(),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetChats get the chat list
|
||||
func (conv *Xun) GetChats(sid string) ([]map[string]interface{}, error) {
|
||||
qb := conv.NewQuery().
|
||||
Select("cid").
|
||||
Where("sid", sid).
|
||||
GroupBy("cid")
|
||||
func (conv *Xun) GetChats(sid string, keywords ...string) ([]map[string]interface{}, error) {
|
||||
qb := conv.newQueryChat().
|
||||
Select("chat_id", "title").
|
||||
Where("sid", sid)
|
||||
|
||||
if conv.setting.TTL > 0 {
|
||||
qb.Where("expired_at", ">", time.Now())
|
||||
// Add title search if keywords provided
|
||||
if len(keywords) > 0 && keywords[0] != "" {
|
||||
keyword := strings.TrimSpace(keywords[0]) // Trim whitespace from keyword
|
||||
if keyword != "" {
|
||||
qb.Where("title", "like", "%"+keyword+"%")
|
||||
}
|
||||
}
|
||||
|
||||
res := []map[string]interface{}{}
|
||||
|
||||
rows, err := qb.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := []map[string]interface{}{}
|
||||
for _, row := range rows {
|
||||
res = append(res, map[string]interface{}{
|
||||
"chat_id": row.Get("cid"),
|
||||
"title": row.Get("cid"),
|
||||
"chat_id": row.Get("chat_id"),
|
||||
"title": row.Get("title"),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +249,7 @@ func (conv *Xun) GetChats(sid string) ([]map[string]interface{}, error) {
|
|||
// GetHistory get the history
|
||||
func (conv *Xun) GetHistory(sid string, cid string) ([]map[string]interface{}, error) {
|
||||
|
||||
qb := conv.NewQuery().
|
||||
qb := conv.newQuery().
|
||||
Select("role", "name", "content").
|
||||
Where("sid", sid).
|
||||
Where("cid", cid).
|
||||
|
|
@ -143,7 +283,31 @@ func (conv *Xun) GetHistory(sid string, cid string) ([]map[string]interface{}, e
|
|||
|
||||
// SaveHistory save the history
|
||||
func (conv *Xun) SaveHistory(sid string, messages []map[string]interface{}, cid string) error {
|
||||
// First ensure chat record exists
|
||||
exists, err := conv.newQueryChat().
|
||||
Where("chat_id", cid).
|
||||
Where("sid", sid).
|
||||
Exists()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
// Create new chat record
|
||||
err = conv.newQueryChat().
|
||||
Insert(map[string]interface{}{
|
||||
"chat_id": cid,
|
||||
"sid": sid,
|
||||
"created_at": time.Now(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Save message history
|
||||
defer conv.clean()
|
||||
var expiredAt interface{} = nil
|
||||
values := []row{}
|
||||
|
|
@ -167,13 +331,13 @@ func (conv *Xun) SaveHistory(sid string, messages []map[string]interface{}, cid
|
|||
values = append(values, value)
|
||||
}
|
||||
|
||||
return conv.NewQuery().Insert(values)
|
||||
return conv.newQuery().Insert(values)
|
||||
}
|
||||
|
||||
// GetRequest get the request history
|
||||
func (conv *Xun) GetRequest(sid string, rid string) ([]map[string]interface{}, error) {
|
||||
|
||||
qb := conv.NewQuery().
|
||||
qb := conv.newQuery().
|
||||
Select("role", "name", "content", "sid").
|
||||
Where("rid", rid).
|
||||
Where("sid", sid).
|
||||
|
|
@ -232,75 +396,35 @@ func (conv *Xun) SaveRequest(sid string, rid string, cid string, messages []map[
|
|||
values = append(values, value)
|
||||
}
|
||||
|
||||
return conv.NewQuery().Insert(values)
|
||||
return conv.newQuery().Insert(values)
|
||||
}
|
||||
|
||||
func (conv *Xun) clean() {
|
||||
nums, err := conv.NewQuery().Where("expired_at", "<=", time.Now()).Delete()
|
||||
// GetChat get the chat info and its history
|
||||
func (conv *Xun) GetChat(sid string, cid string) (*ChatInfo, error) {
|
||||
// Get chat info
|
||||
qb := conv.newQueryChat().
|
||||
Select("chat_id", "title").
|
||||
Where("sid", sid).
|
||||
Where("chat_id", cid)
|
||||
|
||||
row, err := qb.First()
|
||||
if err != nil {
|
||||
log.Error("Clean the conversation table error: %s", err.Error())
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if nums > 0 {
|
||||
log.Trace("Clean the conversation table: %s %d", conv.setting.Table, nums)
|
||||
chat := map[string]interface{}{
|
||||
"chat_id": row.Get("chat_id"),
|
||||
"title": row.Get("title"),
|
||||
}
|
||||
}
|
||||
|
||||
// Init init the conversation
|
||||
func (conv *Xun) Init() error {
|
||||
|
||||
has, err := conv.schema.HasTable(conv.setting.Table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create the table
|
||||
if !has {
|
||||
err = conv.schema.CreateTable(conv.setting.Table, func(table schema.Blueprint) {
|
||||
|
||||
table.ID("id") // The ID field
|
||||
table.String("sid", 255).Index() // The Session ID
|
||||
table.String("rid", 255).Null().Index() // The request ID
|
||||
table.String("cid", 200).Null().Index() // The Chat ID
|
||||
table.String("role", 200).Null().Index() // The Message role
|
||||
table.String("name", 200).Null().Index() // The User name
|
||||
table.String("title", 200).Null().Index() // The Chat title
|
||||
table.Text("content").Null()
|
||||
|
||||
table.TimestampTz("created_at").SetDefaultRaw("NOW()").Index()
|
||||
table.TimestampTz("updated_at").Null().Index()
|
||||
table.TimestampTz("expired_at").Null().Index()
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Trace("Create the conversation table: %s", conv.setting.Table)
|
||||
}
|
||||
|
||||
// validate the table
|
||||
tab, err := conv.schema.GetTable(conv.setting.Table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fields := []string{"id", "sid", "rid", "cid", "role", "name", "content", "created_at", "updated_at", "expired_at"}
|
||||
for _, field := range fields {
|
||||
if !tab.HasColumn(field) {
|
||||
return fmt.Errorf("%s is required", field)
|
||||
}
|
||||
}
|
||||
|
||||
// Auto update the title
|
||||
if !tab.HasColumn("title") {
|
||||
err = conv.schema.AlterTable(conv.setting.Table, func(table schema.Blueprint) {
|
||||
table.String("title", 200).Null().Index()
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
// Get chat history
|
||||
history, err := conv.GetHistory(sid, cid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ChatInfo{
|
||||
Chat: chat,
|
||||
History: history,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
57
neo/hooks.go
57
neo/hooks.go
|
|
@ -194,3 +194,60 @@ func (neo *DSL) HookWrite(ctx Context, messages []map[string]interface{}, respon
|
|||
|
||||
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
|
||||
}
|
||||
|
|
|
|||
11
neo/neo.go
11
neo/neo.go
|
|
@ -1,6 +1,7 @@
|
|||
package neo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
|
@ -47,6 +48,16 @@ func (neo *DSL) Answer(ctx Context, question string, c *gin.Context) error {
|
|||
return neo.chat(ast, ctx, messages, c)
|
||||
}
|
||||
|
||||
// GetAssistants returns the list of assistants
|
||||
func (neo *DSL) GetAssistants() []assistant.Assistant {
|
||||
return neo.AssistantList
|
||||
}
|
||||
|
||||
// GetMentions returns the mention list
|
||||
func (neo *DSL) GetMentions(keywords string) ([]Mention, error) {
|
||||
return neo.HookMention(context.Background(), keywords)
|
||||
}
|
||||
|
||||
// Upload upload a file
|
||||
func (neo *DSL) Upload(ctx Context, c *gin.Context) (*assistant.File, error) {
|
||||
// Get the file
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ type DSL struct {
|
|||
Create string `json:"create,omitempty" yaml:"create,omitempty"`
|
||||
Write string `json:"write,omitempty" yaml:"write,omitempty"`
|
||||
AssistantListHook string `json:"assistants,omitempty" yaml:"assistants,omitempty"` // Get the assistant list from the hook
|
||||
MentionHook string `json:"mentions,omitempty"` // Get the mention list from the hook
|
||||
Prompts []assistant.Prompt `json:"prompts,omitempty" yaml:"prompts,omitempty"`
|
||||
Allows []string `json:"allows,omitempty" yaml:"allows,omitempty"`
|
||||
Assistant assistant.API `json:"-" yaml:"-"` // The default assistant
|
||||
|
|
@ -30,6 +31,14 @@ type DSL struct {
|
|||
AssistantMaps map[string]assistant.Assistant `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
// Mention list
|
||||
type Mention struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Context the context
|
||||
type Context struct {
|
||||
Sid string `json:"sid" yaml:"-"` // Session ID
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue