Enhance assistant management in Neo API and conversation module
- Added new endpoints for managing assistants: list, detail, save, and delete. - Implemented filtering capabilities for assistants based on keywords, tags, mentionable status, and automation. - Refactored the assistant structure to include new fields for better management and filtering. - Removed obsolete test data file, streamlining the codebase. - Updated tests to cover new assistant functionalities and filtering options, ensuring robust functionality.
This commit is contained in:
parent
b17778afea
commit
8fafdc5855
5 changed files with 398 additions and 89 deletions
160
neo/api.go
160
neo/api.go
|
|
@ -40,6 +40,8 @@ func (neo *DSL) API(router *gin.Engine, path string) error {
|
|||
router.OPTIONS(path+"/generate/title", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/generate/prompts", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/dangerous/clear_chats", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants", neo.optionsHandler)
|
||||
router.OPTIONS(path+"/assistants/:id", neo.optionsHandler)
|
||||
|
||||
// Register endpoints with middlewares
|
||||
router.GET(path, append(middlewares, neo.handleChat)...)
|
||||
|
|
@ -48,6 +50,12 @@ func (neo *DSL) API(router *gin.Engine, path string) error {
|
|||
// Status check
|
||||
router.GET(path+"/status", append(middlewares, neo.handleStatus)...)
|
||||
|
||||
// Assistant API
|
||||
router.GET(path+"/assistants", append(middlewares, neo.handleAssistantList)...)
|
||||
router.GET(path+"/assistants/:id", append(middlewares, neo.handleAssistantDetail)...)
|
||||
router.POST(path+"/assistants", append(middlewares, neo.handleAssistantSave)...)
|
||||
router.DELETE(path+"/assistants/:id", append(middlewares, neo.handleAssistantDelete)...)
|
||||
|
||||
// Chat api
|
||||
router.GET(path+"/chats", append(middlewares, neo.handleChatList)...)
|
||||
router.GET(path+"/chats/:id", append(middlewares, neo.handleChatDetail)...)
|
||||
|
|
@ -394,28 +402,37 @@ func (neo *DSL) handleMentions(c *gin.Context) {
|
|||
|
||||
// Get keywords from query parameter
|
||||
keywords := strings.ToLower(c.Query("keywords"))
|
||||
mentions, err := neo.GetMentions(keywords)
|
||||
mentionable := true
|
||||
|
||||
// Query mentionable assistants
|
||||
filter := conversation.AssistantFilter{
|
||||
Keywords: keywords,
|
||||
Mentionable: &mentionable,
|
||||
Page: 1,
|
||||
PageSize: 20,
|
||||
}
|
||||
|
||||
response, err := neo.Conversation.GetAssistants(filter)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
// Filter mentions by keywords
|
||||
testMentions := TestMentions
|
||||
if keywords != "" {
|
||||
filtered := []Mention{}
|
||||
for _, m := range testMentions {
|
||||
if strings.Contains(strings.ToLower(m.Name), keywords) {
|
||||
filtered = append(filtered, m)
|
||||
// Convert assistants to mentions
|
||||
mentions := []Mention{}
|
||||
for _, item := range response.Items {
|
||||
if assistant, ok := item.(map[string]interface{}); ok {
|
||||
mention := Mention{
|
||||
ID: assistant["assistant_id"].(string),
|
||||
Name: assistant["name"].(string),
|
||||
Type: assistant["type"].(string),
|
||||
Avatar: assistant["avatar"].(string),
|
||||
}
|
||||
mentions = append(mentions, mention)
|
||||
}
|
||||
testMentions = filtered
|
||||
}
|
||||
|
||||
// Append test data to actual mentions
|
||||
mentions = append(mentions, testMentions...)
|
||||
|
||||
c.JSON(200, map[string]interface{}{"data": mentions})
|
||||
c.Done()
|
||||
}
|
||||
|
|
@ -751,3 +768,122 @@ func (neo *DSL) handleGenerateCustom(c *gin.Context) {
|
|||
resp.result, resp.err = neo.GenerateWithAI(ctx, resp.content, genType, systemPrompt, c, silent)
|
||||
resp.send("result")
|
||||
}
|
||||
|
||||
// handleAssistantList handles listing assistants
|
||||
func (neo *DSL) handleAssistantList(c *gin.Context) {
|
||||
// Parse filter parameters
|
||||
filter := conversation.AssistantFilter{
|
||||
Page: 1,
|
||||
PageSize: 20,
|
||||
}
|
||||
|
||||
// Parse page and pagesize
|
||||
if page := c.Query("page"); page != "" {
|
||||
if n, err := strconv.Atoi(page); err == nil {
|
||||
filter.Page = n
|
||||
}
|
||||
}
|
||||
|
||||
if pageSize := c.Query("pagesize"); pageSize != "" {
|
||||
if n, err := strconv.Atoi(pageSize); err == nil {
|
||||
filter.PageSize = n
|
||||
}
|
||||
}
|
||||
|
||||
// Parse tags
|
||||
if tags := c.Query("tags"); tags != "" {
|
||||
filter.Tags = strings.Split(tags, ",")
|
||||
}
|
||||
|
||||
response, err := neo.Conversation.GetAssistants(filter)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, map[string]interface{}{"data": response})
|
||||
c.Done()
|
||||
}
|
||||
|
||||
// handleAssistantDetail handles getting a single assistant's details
|
||||
func (neo *DSL) handleAssistantDetail(c *gin.Context) {
|
||||
assistantID := c.Param("id")
|
||||
if assistantID == "" {
|
||||
c.JSON(400, gin.H{"message": "assistant id is required", "code": 400})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
filter := conversation.AssistantFilter{
|
||||
Page: 1,
|
||||
PageSize: 1,
|
||||
}
|
||||
|
||||
response, err := neo.Conversation.GetAssistants(filter)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
// Find the assistant by ID
|
||||
var assistant map[string]interface{}
|
||||
for _, item := range response.Items {
|
||||
if a, ok := item.(map[string]interface{}); ok {
|
||||
if id, ok := a["id"].(string); ok && id == assistantID {
|
||||
assistant = a
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if assistant == nil {
|
||||
c.JSON(404, gin.H{"message": "assistant not found", "code": 404})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, map[string]interface{}{"data": assistant})
|
||||
c.Done()
|
||||
}
|
||||
|
||||
// handleAssistantSave handles creating or updating an assistant
|
||||
func (neo *DSL) handleAssistantSave(c *gin.Context) {
|
||||
var assistant map[string]interface{}
|
||||
if err := c.BindJSON(&assistant); err != nil {
|
||||
c.JSON(400, gin.H{"message": "invalid request body", "code": 400})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
err := neo.Conversation.SaveAssistant(assistant)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"message": "ok", "data": assistant})
|
||||
c.Done()
|
||||
}
|
||||
|
||||
// handleAssistantDelete handles deleting an assistant
|
||||
func (neo *DSL) handleAssistantDelete(c *gin.Context) {
|
||||
assistantID := c.Param("id")
|
||||
if assistantID == "" {
|
||||
c.JSON(400, gin.H{"message": "assistant id is required", "code": 400})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
err := neo.Conversation.DeleteAssistant(assistantID)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"message": err.Error(), "code": 500})
|
||||
c.Done()
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"message": "ok"})
|
||||
c.Done()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,66 +2,126 @@ package conversation
|
|||
|
||||
import "github.com/yaoapp/xun"
|
||||
|
||||
// Setting the conversation config
|
||||
// Setting represents the conversation configuration structure
|
||||
// Used to configure basic conversation parameters including connector, user field, table name, etc.
|
||||
type Setting struct {
|
||||
Connector string `json:"connector,omitempty"`
|
||||
UserField string `json:"user_field,omitempty"` // the user id field name, default is user_id
|
||||
Table string `json:"table,omitempty"`
|
||||
MaxSize int `json:"max_size,omitempty" yaml:"max_size,omitempty"`
|
||||
TTL int `json:"ttl,omitempty" yaml:"ttl,omitempty"`
|
||||
Connector string `json:"connector,omitempty"` // Name of the connector used to specify data storage method
|
||||
UserField string `json:"user_field,omitempty"` // User ID field name, defaults to "user_id"
|
||||
Table string `json:"table,omitempty"` // Database table name
|
||||
MaxSize int `json:"max_size,omitempty" yaml:"max_size,omitempty"` // Maximum storage size limit
|
||||
TTL int `json:"ttl,omitempty" yaml:"ttl,omitempty"` // Time To Live in seconds
|
||||
}
|
||||
|
||||
// ChatInfo represents the chat information and its history
|
||||
// ChatInfo represents the chat information structure
|
||||
// Contains basic information and history for a single chat
|
||||
type ChatInfo struct {
|
||||
Chat map[string]interface{} `json:"chat"`
|
||||
History []map[string]interface{} `json:"history"`
|
||||
Chat map[string]interface{} `json:"chat"` // Basic chat information
|
||||
History []map[string]interface{} `json:"history"` // Chat history records
|
||||
}
|
||||
|
||||
// ChatFilter represents the filter parameters for GetChats
|
||||
// ChatFilter represents the chat filter structure
|
||||
// Used for filtering and pagination when retrieving chat lists
|
||||
type ChatFilter struct {
|
||||
Keywords string `json:"keywords,omitempty"`
|
||||
Page int `json:"page,omitempty"` // 页码,从1开始
|
||||
PageSize int `json:"pagesize,omitempty"` // 每页数量
|
||||
Order string `json:"order,omitempty"` // desc/asc
|
||||
Keywords string `json:"keywords,omitempty"` // Keyword search
|
||||
Page int `json:"page,omitempty"` // Page number, starting from 1
|
||||
PageSize int `json:"pagesize,omitempty"` // Number of items per page
|
||||
Order string `json:"order,omitempty"` // Sort order: desc/asc
|
||||
}
|
||||
|
||||
// ChatGroup represents a group of chats by date
|
||||
// ChatGroup represents the chat group structure
|
||||
// Groups chats by date
|
||||
type ChatGroup struct {
|
||||
Label string `json:"label"`
|
||||
Chats []map[string]interface{} `json:"chats"`
|
||||
Label string `json:"label"` // Group label (typically a date)
|
||||
Chats []map[string]interface{} `json:"chats"` // List of chats in this group
|
||||
}
|
||||
|
||||
// ChatGroupResponse represents paginated chat groups
|
||||
// ChatGroupResponse represents the paginated chat group response
|
||||
// Contains paginated chat group information
|
||||
type ChatGroupResponse struct {
|
||||
Groups []ChatGroup `json:"groups"`
|
||||
Page int `json:"page"` // 当前页码
|
||||
PageSize int `json:"pagesize"` // 每页数量
|
||||
Total int64 `json:"total"` // 总记录数
|
||||
LastPage int `json:"last_page"` // 最后一页页码
|
||||
Groups []ChatGroup `json:"groups"` // List of chat groups
|
||||
Page int `json:"page"` // Current page number
|
||||
PageSize int `json:"pagesize"` // Items per page
|
||||
Total int64 `json:"total"` // Total number of records
|
||||
LastPage int `json:"last_page"` // Last page number
|
||||
}
|
||||
|
||||
// AssistantFilter represents the filter parameters for GetAssistants
|
||||
// AssistantFilter represents the assistant filter structure
|
||||
// Used for filtering and pagination when retrieving assistant lists
|
||||
type AssistantFilter struct {
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Page int `json:"page,omitempty"` // Page number, starting from 1
|
||||
PageSize int `json:"pagesize,omitempty"` // Items per page
|
||||
Tags []string `json:"tags,omitempty"` // Filter by tags
|
||||
Keywords string `json:"keywords,omitempty"` // Search in name and description
|
||||
Connector string `json:"connector,omitempty"` // Filter by connector
|
||||
Mentionable *bool `json:"mentionable,omitempty"` // Filter by mentionable status
|
||||
Automated *bool `json:"automated,omitempty"` // Filter by automation status
|
||||
Page int `json:"page,omitempty"` // Page number, starting from 1
|
||||
PageSize int `json:"pagesize,omitempty"` // Items per page
|
||||
}
|
||||
|
||||
// AssistantResponse represents paginated assistant results
|
||||
// AssistantResponse represents the assistant response structure
|
||||
// Inherits from xun.P, used for returning paginated assistant lists
|
||||
type AssistantResponse struct {
|
||||
xun.P
|
||||
}
|
||||
|
||||
// Conversation the store interface
|
||||
// Conversation defines the conversation storage interface
|
||||
// Provides basic operations required for conversation management
|
||||
type Conversation interface {
|
||||
// GetChats retrieves a list of chats
|
||||
// sid: Session ID
|
||||
// filter: Filter conditions
|
||||
// Returns: Grouped chat list and potential error
|
||||
GetChats(sid string, filter ChatFilter) (*ChatGroupResponse, error)
|
||||
|
||||
// GetChat retrieves a single chat's information
|
||||
// sid: Session ID
|
||||
// cid: Chat ID
|
||||
// Returns: Chat information and potential error
|
||||
GetChat(sid string, cid string) (*ChatInfo, error)
|
||||
|
||||
// GetHistory retrieves chat history
|
||||
// sid: Session ID
|
||||
// cid: Chat ID
|
||||
// Returns: History record list and potential error
|
||||
GetHistory(sid string, cid string) ([]map[string]interface{}, error)
|
||||
|
||||
// SaveHistory saves chat history
|
||||
// sid: Session ID
|
||||
// messages: Message list
|
||||
// cid: Chat ID
|
||||
// context: Context information
|
||||
// Returns: Potential error
|
||||
SaveHistory(sid string, messages []map[string]interface{}, cid string, context map[string]interface{}) error
|
||||
|
||||
// DeleteChat deletes a single chat
|
||||
// sid: Session ID
|
||||
// cid: Chat ID
|
||||
// Returns: Potential error
|
||||
DeleteChat(sid string, cid string) error
|
||||
|
||||
// DeleteAllChats deletes all chats
|
||||
// sid: Session ID
|
||||
// Returns: Potential error
|
||||
DeleteAllChats(sid string) error
|
||||
|
||||
// UpdateChatTitle updates chat title
|
||||
// sid: Session ID
|
||||
// cid: Chat ID
|
||||
// title: New title
|
||||
// Returns: Potential error
|
||||
UpdateChatTitle(sid string, cid string, title string) error
|
||||
|
||||
// SaveAssistant saves assistant information
|
||||
// assistant: Assistant information
|
||||
// Returns: Potential error
|
||||
SaveAssistant(assistant map[string]interface{}) error
|
||||
|
||||
// DeleteAssistant deletes an assistant
|
||||
// assistantID: Assistant ID
|
||||
// Returns: Potential error
|
||||
DeleteAssistant(assistantID string) error
|
||||
|
||||
// GetAssistants retrieves a list of assistants
|
||||
// filter: Filter conditions
|
||||
// Returns: Paginated assistant list and potential error
|
||||
GetAssistants(filter AssistantFilter) (*AssistantResponse, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,22 +16,34 @@ import (
|
|||
"github.com/yaoapp/xun/dbal/schema"
|
||||
)
|
||||
|
||||
// Xun Database conversation
|
||||
// Package conversation provides functionality for managing chat conversations and assistants.
|
||||
|
||||
// Xun implements the Conversation interface using a database backend.
|
||||
// It provides functionality for:
|
||||
// - Managing chat conversations and their message histories
|
||||
// - Organizing chats with pagination and date-based grouping
|
||||
// - Handling chat metadata like titles and creation dates
|
||||
// - Managing AI assistants with their configurations and metadata
|
||||
// - Supporting data expiration through TTL settings
|
||||
type Xun struct {
|
||||
query query.Query
|
||||
schema schema.Schema
|
||||
setting Setting
|
||||
}
|
||||
|
||||
// Public interface methods and constructor remain exported:
|
||||
// - NewXun
|
||||
// - UpdateChatTitle
|
||||
// - GetChats
|
||||
// - GetChat
|
||||
// - GetHistory
|
||||
// - SaveHistory
|
||||
// - GetRequest
|
||||
// - SaveRequest
|
||||
// Public interface methods:
|
||||
//
|
||||
// NewXun creates a new conversation instance with the given settings
|
||||
// UpdateChatTitle updates the title of a specific chat
|
||||
// GetChats retrieves a paginated list of chats grouped by date
|
||||
// GetChat retrieves a specific chat and its message history
|
||||
// GetHistory retrieves the message history for a specific chat
|
||||
// SaveHistory saves new messages to a chat's history
|
||||
// DeleteChat deletes a specific chat and its history
|
||||
// DeleteAllChats deletes all chats and their histories for a user
|
||||
// SaveAssistant creates or updates an assistant
|
||||
// DeleteAssistant deletes an assistant by assistant_id
|
||||
// GetAssistants retrieves a paginated list of assistants with filtering
|
||||
|
||||
// NewXun create a new conversation
|
||||
func NewXun(setting Setting) (*Xun, error) {
|
||||
|
|
@ -696,20 +708,45 @@ func (conv *Xun) DeleteAssistant(assistantID string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// GetAssistants retrieves assistants with pagination and tag filtering
|
||||
// GetAssistants retrieves assistants with pagination and filtering
|
||||
func (conv *Xun) GetAssistants(filter AssistantFilter) (*AssistantResponse, error) {
|
||||
qb := conv.query.New().
|
||||
Table(conv.getAssistantTable())
|
||||
|
||||
// Apply tag filter if provided
|
||||
if filter.Tags != nil && len(filter.Tags) > 0 {
|
||||
for i, tag := range filter.Tags {
|
||||
if i == 0 {
|
||||
qb.Where("tags", "like", fmt.Sprintf("%%\"%s\"%%", tag))
|
||||
} else {
|
||||
qb.OrWhere("tags", "like", fmt.Sprintf("%%\"%s\"%%", tag))
|
||||
qb.Where(func(qb query.Query) {
|
||||
for i, tag := range filter.Tags {
|
||||
if i == 0 {
|
||||
qb.Where("tags", "like", fmt.Sprintf("%%\"%s\"%%", tag))
|
||||
} else {
|
||||
qb.OrWhere("tags", "like", fmt.Sprintf("%%\"%s\"%%", tag))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Apply keyword filter if provided
|
||||
if filter.Keywords != "" {
|
||||
qb.Where(func(qb query.Query) {
|
||||
qb.Where("name", "like", fmt.Sprintf("%%%s%%", filter.Keywords)).
|
||||
OrWhere("description", "like", fmt.Sprintf("%%%s%%", filter.Keywords))
|
||||
})
|
||||
}
|
||||
|
||||
// Apply connector filter if provided
|
||||
if filter.Connector != "" {
|
||||
qb.Where("connector", filter.Connector)
|
||||
}
|
||||
|
||||
// Apply mentionable filter if provided
|
||||
if filter.Mentionable != nil {
|
||||
qb.Where("mentionable", *filter.Mentionable)
|
||||
}
|
||||
|
||||
// Apply automated filter if provided
|
||||
if filter.Automated != nil {
|
||||
qb.Where("automated", *filter.Automated)
|
||||
}
|
||||
|
||||
// Set defaults for pagination
|
||||
|
|
|
|||
|
|
@ -483,6 +483,9 @@ func TestXunAssistantCRUD(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mentionable := true
|
||||
automated := true
|
||||
|
||||
assistant := map[string]interface{}{
|
||||
"name": "Test Assistant",
|
||||
"type": "assistant",
|
||||
|
|
@ -491,6 +494,8 @@ func TestXunAssistantCRUD(t *testing.T) {
|
|||
"description": "Test Description",
|
||||
"tags": tagsJSON,
|
||||
"options": optionsJSON,
|
||||
"mentionable": mentionable,
|
||||
"automated": automated,
|
||||
}
|
||||
|
||||
// Test SaveAssistant (Create)
|
||||
|
|
@ -525,6 +530,45 @@ func TestXunAssistantCRUD(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, len(resp.P.Items))
|
||||
|
||||
// Test GetAssistants with keyword filter
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Keywords: "Test",
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(resp.P.Items))
|
||||
|
||||
// Test GetAssistants with connector filter
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Connector: "openai",
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(resp.P.Items))
|
||||
|
||||
// Test GetAssistants with mentionable filter
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Mentionable: &mentionable,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(resp.P.Items))
|
||||
|
||||
// Test GetAssistants with automated filter
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Automated: &automated,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(resp.P.Items))
|
||||
|
||||
// Test GetAssistants with combined filters
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Keywords: "Test",
|
||||
Connector: "openai",
|
||||
Mentionable: &mentionable,
|
||||
Automated: &automated,
|
||||
Tags: []string{"tag1"},
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(resp.P.Items))
|
||||
|
||||
// Test SaveAssistant (Update)
|
||||
assistant["name"] = "Updated Assistant"
|
||||
err = conv.SaveAssistant(assistant)
|
||||
|
|
@ -566,18 +610,30 @@ func TestXunAssistantPagination(t *testing.T) {
|
|||
}
|
||||
|
||||
// Create multiple assistants for pagination testing
|
||||
mentionable := true
|
||||
automated := true
|
||||
for i := 0; i < 25; i++ {
|
||||
tagsJSON, err := jsoniter.MarshalToString([]string{fmt.Sprintf("tag%d", i%5)})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Alternate mentionable and automated flags
|
||||
if i%2 == 0 {
|
||||
mentionable = !mentionable
|
||||
}
|
||||
if i%3 == 0 {
|
||||
automated = !automated
|
||||
}
|
||||
|
||||
assistant := map[string]interface{}{
|
||||
"name": fmt.Sprintf("Assistant %d", i),
|
||||
"type": "assistant",
|
||||
"connector": "openai",
|
||||
"connector": fmt.Sprintf("connector%d", i%3),
|
||||
"description": fmt.Sprintf("Description %d", i),
|
||||
"tags": tagsJSON,
|
||||
"mentionable": mentionable,
|
||||
"automated": automated,
|
||||
}
|
||||
err = conv.SaveAssistant(assistant)
|
||||
assert.Nil(t, err)
|
||||
|
|
@ -617,4 +673,54 @@ func TestXunAssistantPagination(t *testing.T) {
|
|||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 5, len(resp.P.Items))
|
||||
|
||||
// Test filtering with keywords
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Keywords: "Assistant 1",
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Greater(t, len(resp.P.Items), 0)
|
||||
|
||||
// Test filtering with connector
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Connector: "connector0",
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Greater(t, len(resp.P.Items), 0)
|
||||
|
||||
// Test filtering with mentionable
|
||||
mentionableTrue := true
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Mentionable: &mentionableTrue,
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Greater(t, len(resp.P.Items), 0)
|
||||
|
||||
// Test filtering with automated
|
||||
automatedTrue := true
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Automated: &automatedTrue,
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Greater(t, len(resp.P.Items), 0)
|
||||
|
||||
// Test combined filters
|
||||
resp, err = conv.GetAssistants(AssistantFilter{
|
||||
Tags: []string{"tag0"},
|
||||
Keywords: "Assistant",
|
||||
Connector: "connector0",
|
||||
Mentionable: &mentionableTrue,
|
||||
Automated: &automatedTrue,
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
package neo
|
||||
|
||||
// TestMentions contains test data for mentions
|
||||
var TestMentions = []Mention{
|
||||
{
|
||||
ID: "assistant_1",
|
||||
Name: "Alice AI",
|
||||
Type: "assistant",
|
||||
Avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Alice",
|
||||
},
|
||||
{
|
||||
ID: "assistant_2",
|
||||
Name: "Bob Bot",
|
||||
Type: "assistant",
|
||||
Avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Bob",
|
||||
},
|
||||
{
|
||||
ID: "assistant_3",
|
||||
Name: "Carol AI",
|
||||
Type: "assistant",
|
||||
Avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Carol",
|
||||
},
|
||||
// ... 其他测试数据 ...
|
||||
{
|
||||
ID: "assistant_20",
|
||||
Name: "Tara Tech",
|
||||
Type: "assistant",
|
||||
Avatar: "https://api.dicebear.com/7.x/avataaars/svg?seed=Tara",
|
||||
},
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue