Remove deprecated studio package and refactor agent integration - Deleted the studio package, which is no longer in use, to streamline the codebase. - Updated references in the agent and chat modules to utilize the new agent package instead of the deprecated neo package. - Ensured that all related middleware and routing functionalities are now aligned with the agent architecture, enhancing overall system coherence.
757 lines
24 KiB
Markdown
757 lines
24 KiB
Markdown
# YAO Agent Store
|
|
|
|
YAO Agent Store is a comprehensive storage abstraction layer for managing conversations, assistants, attachments, and knowledge collections in the YAO Agent platform. It provides a unified interface that supports multiple storage backends including databases (via Xun), Redis, and MongoDB.
|
|
|
|
## Table of Contents
|
|
|
|
- [Architecture](#architecture)
|
|
- [Storage Backends](#storage-backends)
|
|
- [Configuration](#configuration)
|
|
- [Initialization](#initialization)
|
|
- [API Reference](#api-reference)
|
|
- [Data Models](#data-models)
|
|
- [Usage Examples](#usage-examples)
|
|
- [Testing](#testing)
|
|
|
|
## Architecture
|
|
|
|
The store package provides a unified `Store` interface that abstracts different storage implementations:
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ Store API │ ← Unified Interface
|
|
├─────────────────┤
|
|
│ Xun (Database) │ ← Primary Implementation
|
|
│ Redis │ ← Cache/Memory Store
|
|
│ MongoDB │ ← Document Store
|
|
└─────────────────┘
|
|
```
|
|
|
|
### Core Entities
|
|
|
|
1. **Conversations & Chat History** - Manage chat sessions and message history
|
|
2. **Assistants** - AI assistant configurations and metadata
|
|
3. **Attachments** - File attachments with metadata and access control
|
|
4. **Knowledge Collections** - Knowledge bases for AI assistants
|
|
|
|
## Storage Backends
|
|
|
|
### 1. Xun (Database) - Primary Backend
|
|
|
|
The main implementation using SQL databases with automatic schema management:
|
|
|
|
- **Supported Databases**: MySQL, PostgreSQL, SQLite, etc.
|
|
- **Features**: ACID transactions, complex queries, automatic migrations
|
|
- **Use Case**: Production environments requiring data consistency
|
|
|
|
### 2. Redis - Cache Backend
|
|
|
|
Redis implementation for high-performance caching:
|
|
|
|
- **Features**: In-memory storage, pub/sub capabilities
|
|
- **Use Case**: Session management, temporary data, real-time features
|
|
|
|
### 3. MongoDB - Document Backend
|
|
|
|
MongoDB implementation for document-based storage:
|
|
|
|
- **Features**: Schema flexibility, horizontal scaling
|
|
- **Use Case**: Large-scale deployments, unstructured data
|
|
|
|
## Configuration
|
|
|
|
### Setting Structure
|
|
|
|
```go
|
|
type Setting struct {
|
|
Connector string `json:"connector,omitempty"` // Storage connector name
|
|
UserField string `json:"user_field,omitempty"` // User ID field name (default: "user_id")
|
|
Prefix string `json:"prefix,omitempty"` // Database table name prefix
|
|
MaxSize int `json:"max_size,omitempty" yaml:"max_size,omitempty"` // Maximum history size limit
|
|
TTL int `json:"ttl,omitempty" yaml:"ttl,omitempty"` // Time To Live in seconds
|
|
}
|
|
```
|
|
|
|
### Configuration Examples
|
|
|
|
#### Database Configuration
|
|
|
|
```yaml
|
|
# agent.yml
|
|
agent:
|
|
store:
|
|
connector: "mysql" # or "postgresql", "sqlite", "default"
|
|
prefix: "agent_" # Table prefix
|
|
max_size: 100 # Maximum chat history size
|
|
ttl: 7200 # 2 hours TTL for conversations
|
|
user_field: "user_id" # User identification field
|
|
```
|
|
|
|
#### Redis Configuration
|
|
|
|
```yaml
|
|
agent:
|
|
store:
|
|
connector: "redis"
|
|
prefix: "agent:"
|
|
ttl: 3600
|
|
```
|
|
|
|
#### MongoDB Configuration
|
|
|
|
```yaml
|
|
agent:
|
|
store:
|
|
connector: "mongodb"
|
|
prefix: "agent_"
|
|
ttl: 7200
|
|
```
|
|
|
|
## Initialization
|
|
|
|
### Automatic Initialization (Recommended)
|
|
|
|
The store is automatically initialized when the Agent system starts:
|
|
|
|
```go
|
|
// From yao/agent/load.go
|
|
func initStore() error {
|
|
var err error
|
|
if Agent.StoreSetting.Connector == "default" || Agent.StoreSetting.Connector == "" {
|
|
Agent.Store, err = store.NewXun(Agent.StoreSetting)
|
|
return err
|
|
}
|
|
|
|
// Other connector types
|
|
conn, err := connector.Select(Agent.StoreSetting.Connector)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if conn.Is(connector.DATABASE) {
|
|
Agent.Store, err = store.NewXun(Agent.StoreSetting)
|
|
return err
|
|
} else if conn.Is(connector.REDIS) {
|
|
Agent.Store = store.NewRedis()
|
|
return nil
|
|
} else if conn.Is(connector.MONGO) {
|
|
Agent.Store = store.NewMongo()
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("%s store connector %s not support", Agent.ID, Agent.StoreSetting.Connector)
|
|
}
|
|
```
|
|
|
|
### Manual Initialization
|
|
|
|
```go
|
|
import "github.com/yaoapp/yao/agent/store"
|
|
|
|
// Database backend
|
|
setting := store.Setting{
|
|
Connector: "mysql",
|
|
Prefix: "agent_",
|
|
MaxSize: 100,
|
|
TTL: 3600,
|
|
}
|
|
store, err := store.NewXun(setting)
|
|
|
|
// Redis backend
|
|
redisStore := store.NewRedis()
|
|
|
|
// MongoDB backend
|
|
mongoStore := store.NewMongo()
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Store Interface
|
|
|
|
```go
|
|
type Store interface {
|
|
// Chat Management
|
|
GetChats(sid string, filter ChatFilter, locale ...string) (*ChatGroupResponse, error)
|
|
GetChat(sid string, cid string, locale ...string) (*ChatInfo, error)
|
|
GetChatWithFilter(sid string, cid string, filter ChatFilter, locale ...string) (*ChatInfo, error)
|
|
UpdateChatTitle(sid string, cid string, title string) error
|
|
DeleteChat(sid string, cid string) error
|
|
DeleteAllChats(sid string) error
|
|
|
|
// Message History
|
|
GetHistory(sid string, cid string, locale ...string) ([]map[string]interface{}, error)
|
|
GetHistoryWithFilter(sid string, cid string, filter ChatFilter, locale ...string) ([]map[string]interface{}, error)
|
|
SaveHistory(sid string, messages []map[string]interface{}, cid string, context map[string]interface{}) error
|
|
|
|
// Assistant Management
|
|
SaveAssistant(assistant map[string]interface{}) (interface{}, error)
|
|
GetAssistants(filter AssistantFilter, locale ...string) (*AssistantResponse, error)
|
|
GetAssistant(assistantID string, locale ...string) (map[string]interface{}, error)
|
|
DeleteAssistant(assistantID string) error
|
|
DeleteAssistants(filter AssistantFilter) (int64, error)
|
|
GetAssistantTags(locale ...string) ([]Tag, error)
|
|
|
|
// Attachment Management
|
|
SaveAttachment(attachment map[string]interface{}) (interface{}, error)
|
|
GetAttachments(filter AttachmentFilter, locale ...string) (*AttachmentResponse, error)
|
|
GetAttachment(fileID string, locale ...string) (map[string]interface{}, error)
|
|
DeleteAttachment(fileID string) error
|
|
DeleteAttachments(filter AttachmentFilter) (int64, error)
|
|
|
|
// Knowledge Management
|
|
SaveKnowledge(knowledge map[string]interface{}) (interface{}, error)
|
|
GetKnowledges(filter KnowledgeFilter, locale ...string) (*KnowledgeResponse, error)
|
|
GetKnowledge(collectionID string, locale ...string) (map[string]interface{}, error)
|
|
DeleteKnowledge(collectionID string) error
|
|
DeleteKnowledges(filter KnowledgeFilter) (int64, error)
|
|
|
|
// Resource Management
|
|
Close() error
|
|
}
|
|
```
|
|
|
|
## Data Models
|
|
|
|
### Database Schema
|
|
|
|
#### 1. History Table (Conversations)
|
|
|
|
```sql
|
|
CREATE TABLE agent_history (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
sid VARCHAR(255) INDEX, -- Session ID
|
|
cid VARCHAR(200) INDEX, -- Chat ID
|
|
uid VARCHAR(255) INDEX, -- User ID
|
|
role VARCHAR(200) INDEX, -- Message role (user/assistant/system)
|
|
name VARCHAR(200), -- Message sender name
|
|
content TEXT, -- Message content
|
|
context JSON, -- Message context
|
|
assistant_id VARCHAR(200) INDEX, -- Associated assistant ID
|
|
assistant_name VARCHAR(200), -- Assistant name
|
|
assistant_avatar VARCHAR(200), -- Assistant avatar URL
|
|
mentions JSON, -- Mentions in the message
|
|
silent BOOLEAN DEFAULT FALSE INDEX, -- Silent message flag
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP INDEX,
|
|
updated_at TIMESTAMP INDEX,
|
|
expired_at TIMESTAMP INDEX -- TTL expiration
|
|
);
|
|
```
|
|
|
|
#### 2. Chat Table
|
|
|
|
```sql
|
|
CREATE TABLE agent_chat (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
chat_id VARCHAR(200) UNIQUE INDEX, -- Unique chat identifier
|
|
title VARCHAR(200), -- Chat title
|
|
assistant_id VARCHAR(200) INDEX, -- Associated assistant
|
|
sid VARCHAR(255) INDEX, -- Session ID
|
|
silent BOOLEAN DEFAULT FALSE INDEX, -- Silent chat flag
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP INDEX,
|
|
updated_at TIMESTAMP INDEX
|
|
);
|
|
```
|
|
|
|
#### 3. Assistant Table
|
|
|
|
```sql
|
|
CREATE TABLE agent_assistant (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
assistant_id VARCHAR(200) UNIQUE INDEX, -- Unique assistant identifier
|
|
type VARCHAR(200) DEFAULT 'assistant' INDEX, -- Assistant type
|
|
name VARCHAR(200), -- Assistant name
|
|
avatar VARCHAR(200), -- Avatar URL
|
|
connector VARCHAR(200) NOT NULL, -- LLM connector
|
|
description VARCHAR(600) INDEX, -- Description (searchable)
|
|
path VARCHAR(200), -- Storage path
|
|
sort INTEGER DEFAULT 9999 INDEX, -- Sort order
|
|
built_in BOOLEAN DEFAULT FALSE INDEX, -- Built-in assistant flag
|
|
placeholder JSON, -- UI placeholder text
|
|
options JSON, -- Assistant options
|
|
prompts JSON, -- System prompts
|
|
workflow JSON, -- Workflow configuration
|
|
knowledge JSON, -- Knowledge base references
|
|
tools JSON, -- Available tools
|
|
tags JSON, -- Assistant tags
|
|
readonly BOOLEAN DEFAULT FALSE INDEX, -- Read-only flag
|
|
permissions JSON, -- Access permissions
|
|
locales JSON, -- Internationalization data
|
|
automated BOOLEAN DEFAULT TRUE INDEX, -- Automation enabled
|
|
mentionable BOOLEAN DEFAULT TRUE INDEX, -- Can be mentioned in chats
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP INDEX,
|
|
updated_at TIMESTAMP INDEX
|
|
);
|
|
```
|
|
|
|
#### 4. Attachment Table
|
|
|
|
```sql
|
|
CREATE TABLE agent_attachment (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
file_id VARCHAR(255) UNIQUE INDEX, -- Unique file identifier
|
|
uid VARCHAR(255) INDEX, -- Owner user ID
|
|
guest BOOLEAN DEFAULT FALSE INDEX, -- Guest upload flag
|
|
manager VARCHAR(200) INDEX, -- Storage manager
|
|
content_type VARCHAR(200) INDEX, -- MIME type
|
|
name VARCHAR(500) INDEX, -- File name (searchable)
|
|
public BOOLEAN DEFAULT FALSE INDEX, -- Public access flag
|
|
scope JSON, -- Access scope
|
|
gzip BOOLEAN DEFAULT FALSE INDEX, -- Compression flag
|
|
bytes BIGINT INDEX, -- File size
|
|
collection_id VARCHAR(200) INDEX, -- Associated knowledge collection
|
|
status ENUM('uploading', 'uploaded', 'indexing', 'indexed', 'upload_failed', 'index_failed') DEFAULT 'uploading' INDEX, -- Processing status
|
|
progress VARCHAR(200), -- Progress information (nullable)
|
|
error VARCHAR(600), -- Error message (nullable)
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP INDEX,
|
|
updated_at TIMESTAMP INDEX
|
|
);
|
|
```
|
|
|
|
#### 5. Knowledge Table
|
|
|
|
```sql
|
|
CREATE TABLE agent_knowledge (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
collection_id VARCHAR(200) UNIQUE INDEX, -- Unique collection identifier
|
|
name VARCHAR(200) INDEX, -- Collection name (searchable)
|
|
description VARCHAR(600) INDEX, -- Description (searchable)
|
|
uid VARCHAR(255) INDEX, -- Owner user ID
|
|
public BOOLEAN DEFAULT FALSE INDEX, -- Public access flag
|
|
scope JSON, -- Access scope
|
|
readonly BOOLEAN DEFAULT FALSE INDEX, -- Read-only flag
|
|
option JSON, -- Collection options
|
|
system BOOLEAN DEFAULT FALSE INDEX, -- System collection flag
|
|
sort INTEGER DEFAULT 9999 INDEX, -- Sort order
|
|
cover VARCHAR(500), -- Cover image URL
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP INDEX,
|
|
updated_at TIMESTAMP INDEX
|
|
);
|
|
```
|
|
|
|
### Filter Structures
|
|
|
|
#### ChatFilter
|
|
|
|
```go
|
|
type ChatFilter struct {
|
|
Keywords string `json:"keywords,omitempty"` // Search keywords
|
|
Page int `json:"page,omitempty"` // Page number (starts from 1)
|
|
PageSize int `json:"pagesize,omitempty"` // Items per page
|
|
Order string `json:"order,omitempty"` // Sort order (desc/asc)
|
|
Silent *bool `json:"silent,omitempty"` // Include silent messages
|
|
}
|
|
```
|
|
|
|
#### AssistantFilter
|
|
|
|
```go
|
|
type AssistantFilter struct {
|
|
Tags []string `json:"tags,omitempty"` // Filter by tags
|
|
Type string `json:"type,omitempty"` // Filter by type
|
|
Keywords string `json:"keywords,omitempty"` // Search keywords
|
|
Connector string `json:"connector,omitempty"` // Filter by connector
|
|
AssistantID string `json:"assistant_id,omitempty"` // Specific assistant ID
|
|
AssistantIDs []string `json:"assistant_ids,omitempty"` // Multiple assistant IDs
|
|
Mentionable *bool `json:"mentionable,omitempty"` // Mentionable status
|
|
Automated *bool `json:"automated,omitempty"` // Automation status
|
|
BuiltIn *bool `json:"built_in,omitempty"` // Built-in status
|
|
Page int `json:"page,omitempty"` // Page number
|
|
PageSize int `json:"pagesize,omitempty"` // Items per page
|
|
Select []string `json:"select,omitempty"` // Fields to return
|
|
}
|
|
```
|
|
|
|
#### AttachmentFilter
|
|
|
|
```go
|
|
type AttachmentFilter struct {
|
|
UID string `json:"uid,omitempty"` // Filter by user ID
|
|
Guest *bool `json:"guest,omitempty"` // Filter by guest status
|
|
Manager string `json:"manager,omitempty"` // Filter by upload manager
|
|
ContentType string `json:"content_type,omitempty"` // Filter by content type
|
|
Name string `json:"name,omitempty"` // Filter by filename
|
|
Public *bool `json:"public,omitempty"` // Filter by public status
|
|
Gzip *bool `json:"gzip,omitempty"` // Filter by gzip compression
|
|
CollectionID string `json:"collection_id,omitempty"` // Filter by knowledge collection ID
|
|
Status string `json:"status,omitempty"` // Filter by processing status
|
|
Keywords string `json:"keywords,omitempty"` // Search in filename
|
|
Page int `json:"page,omitempty"` // Page number
|
|
PageSize int `json:"pagesize,omitempty"` // Items per page
|
|
Select []string `json:"select,omitempty"` // Fields to return
|
|
}
|
|
```
|
|
|
|
#### KnowledgeFilter
|
|
|
|
```go
|
|
type KnowledgeFilter struct {
|
|
UID string `json:"uid,omitempty"` // Filter by user ID
|
|
Name string `json:"name,omitempty"` // Filter by collection name
|
|
Keywords string `json:"keywords,omitempty"` // Search in name and description
|
|
Public *bool `json:"public,omitempty"` // Filter by public status
|
|
Readonly *bool `json:"readonly,omitempty"` // Filter by readonly status
|
|
System *bool `json:"system,omitempty"` // Filter by system status
|
|
Page int `json:"page,omitempty"` // Page number
|
|
PageSize int `json:"pagesize,omitempty"` // Items per page
|
|
Select []string `json:"select,omitempty"` // Fields to return
|
|
}
|
|
```
|
|
|
|
## Usage Examples
|
|
|
|
### 1. Chat Management
|
|
|
|
```go
|
|
// Save chat history
|
|
messages := []map[string]interface{}{
|
|
{"role": "user", "content": "Hello, how are you?"},
|
|
{"role": "assistant", "content": "I'm doing well, thank you!"},
|
|
}
|
|
context := map[string]interface{}{
|
|
"assistant_id": "gpt-4",
|
|
"silent": false,
|
|
}
|
|
err := store.SaveHistory("user123", messages, "chat456", context)
|
|
|
|
// Get chat history
|
|
history, err := store.GetHistory("user123", "chat456")
|
|
|
|
// Get chat list with pagination
|
|
filter := ChatFilter{
|
|
Page: 1,
|
|
PageSize: 20,
|
|
Order: "desc",
|
|
}
|
|
chats, err := store.GetChats("user123", filter)
|
|
|
|
// Update chat title
|
|
err = store.UpdateChatTitle("user123", "chat456", "New Chat Title")
|
|
```
|
|
|
|
### 2. Assistant Management
|
|
|
|
```go
|
|
// Create an assistant
|
|
assistant := map[string]interface{}{
|
|
"name": "Code Helper",
|
|
"type": "assistant",
|
|
"connector": "gpt-4",
|
|
"description": "A helpful coding assistant",
|
|
"tags": []string{"coding", "development"},
|
|
"sort": 100,
|
|
"options": map[string]interface{}{
|
|
"temperature": 0.7,
|
|
"max_tokens": 2000,
|
|
},
|
|
"prompts": []string{
|
|
"You are a helpful coding assistant.",
|
|
},
|
|
"mentionable": true,
|
|
"automated": true,
|
|
}
|
|
assistantID, err := store.SaveAssistant(assistant)
|
|
|
|
// Get assistants with filtering
|
|
filter := AssistantFilter{
|
|
Tags: []string{"coding"},
|
|
Keywords: "helper",
|
|
Page: 1,
|
|
PageSize: 10,
|
|
}
|
|
assistants, err := store.GetAssistants(filter)
|
|
|
|
// Get specific assistant
|
|
assistant, err := store.GetAssistant("assistant123")
|
|
```
|
|
|
|
### 3. Attachment Management
|
|
|
|
```go
|
|
// Save attachment metadata
|
|
attachment := map[string]interface{}{
|
|
"file_id": "file123",
|
|
"uid": "user123",
|
|
"manager": "local",
|
|
"content_type": "image/jpeg",
|
|
"name": "profile.jpg",
|
|
"public": false,
|
|
"bytes": 102400,
|
|
"collection_id": "knowledge456",
|
|
"scope": []string{"user", "admin"},
|
|
"status": "uploaded", // Status: uploading, uploaded, indexing, indexed, upload_failed, index_failed
|
|
"progress": "Upload completed", // Progress information (optional)
|
|
"error": nil, // Error message (optional, for failed statuses)
|
|
}
|
|
fileID, err := store.SaveAttachment(attachment)
|
|
|
|
// Update attachment status during processing workflow
|
|
attachment["status"] = "indexing"
|
|
attachment["progress"] = "Processing file for indexing..."
|
|
_, err = store.SaveAttachment(attachment)
|
|
|
|
// Handle failed upload
|
|
attachment["status"] = "upload_failed"
|
|
attachment["progress"] = nil
|
|
attachment["error"] = "Network connection timeout"
|
|
_, err = store.SaveAttachment(attachment)
|
|
|
|
// Complete indexing
|
|
attachment["status"] = "indexed"
|
|
attachment["progress"] = "File indexed successfully"
|
|
attachment["error"] = nil
|
|
_, err = store.SaveAttachment(attachment)
|
|
|
|
// Get attachments with filtering
|
|
filter := AttachmentFilter{
|
|
UID: "user123",
|
|
ContentType: "image/jpeg",
|
|
Status: "indexed", // Filter by status
|
|
Page: 1,
|
|
PageSize: 20,
|
|
}
|
|
attachments, err := store.GetAttachments(filter)
|
|
|
|
// Get all failed uploads
|
|
failedFilter := AttachmentFilter{
|
|
UID: "user123",
|
|
Status: "upload_failed",
|
|
Page: 1,
|
|
PageSize: 10,
|
|
}
|
|
failedUploads, err := store.GetAttachments(failedFilter)
|
|
```
|
|
|
|
#### Attachment Status Workflow
|
|
|
|
The attachment system supports a complete file processing workflow with the following status values:
|
|
|
|
- **`uploading`** (default): File upload is in progress
|
|
- **`uploaded`**: File upload completed successfully
|
|
- **`indexing`**: File is being processed for search indexing
|
|
- **`indexed`**: File has been indexed and is ready for use
|
|
- **`upload_failed`**: File upload failed (check `error` field for details)
|
|
- **`index_failed`**: File indexing failed (check `error` field for details)
|
|
|
|
#### Additional Fields
|
|
|
|
- **`progress`**: Human-readable progress information (string, nullable)
|
|
- **`error`**: Error message for failed operations (string, nullable, max 600 characters)
|
|
|
|
### 4. Knowledge Collection Management
|
|
|
|
```go
|
|
// Create knowledge collection
|
|
knowledge := map[string]interface{}{
|
|
"collection_id": "kb123",
|
|
"name": "Programming Guide",
|
|
"description": "Comprehensive programming tutorials and examples",
|
|
"uid": "user123",
|
|
"public": true,
|
|
"readonly": false,
|
|
"sort": 100,
|
|
"option": map[string]interface{}{
|
|
"embedding": "openai",
|
|
"chunk_size": 1000,
|
|
},
|
|
"scope": []string{"developers", "students"},
|
|
}
|
|
collectionID, err := store.SaveKnowledge(knowledge)
|
|
|
|
// Get knowledge collections with filtering
|
|
filter := KnowledgeFilter{
|
|
UID: "user123",
|
|
Keywords: "programming",
|
|
Public: &[]bool{true}[0],
|
|
Page: 1,
|
|
PageSize: 10,
|
|
}
|
|
collections, err := store.GetKnowledges(filter)
|
|
|
|
// Get system knowledge collections
|
|
systemFilter := KnowledgeFilter{
|
|
System: &[]bool{true}[0],
|
|
Page: 1,
|
|
PageSize: 20,
|
|
}
|
|
systemCollections, err := store.GetKnowledges(systemFilter)
|
|
|
|
// Get readonly knowledge collections with specific fields
|
|
readonlyFilter := KnowledgeFilter{
|
|
Readonly: &[]bool{true}[0],
|
|
Select: []string{"collection_id", "name", "description", "sort"},
|
|
Page: 1,
|
|
PageSize: 15,
|
|
}
|
|
readonlyCollections, err := store.GetKnowledges(readonlyFilter)
|
|
```
|
|
|
|
### 5. Internationalization Support
|
|
|
|
```go
|
|
// Get assistants with locale
|
|
assistants, err := store.GetAssistants(filter, "zh-CN")
|
|
|
|
// Get chat with locale
|
|
chat, err := store.GetChat("user123", "chat456", "en-US")
|
|
```
|
|
|
|
### 6. Advanced Filtering and Sorting
|
|
|
|
```go
|
|
// Complex assistant filtering
|
|
filter := AssistantFilter{
|
|
Tags: []string{"ai", "assistant"},
|
|
Keywords: "helpful",
|
|
Connector: "gpt-4",
|
|
Mentionable: &[]bool{true}[0],
|
|
BuiltIn: &[]bool{false}[0],
|
|
Select: []string{"assistant_id", "name", "description", "tags"},
|
|
Page: 1,
|
|
PageSize: 50,
|
|
}
|
|
assistants, err := store.GetAssistants(filter)
|
|
|
|
// Results are automatically sorted by:
|
|
// 1. sort field (ASC) - lower numbers appear first
|
|
// 2. created_at/updated_at (DESC) - newer items appear first
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
# Run all tests
|
|
go test -v
|
|
|
|
# Run specific test
|
|
go test -run TestXunKnowledgeCRUD -v
|
|
|
|
# Run with coverage
|
|
go test -cover
|
|
```
|
|
|
|
### Test Structure
|
|
|
|
The test suite includes comprehensive coverage for:
|
|
|
|
- **CRUD Operations**: Create, Read, Update, Delete for all entities
|
|
- **Filtering**: Various filter combinations and edge cases
|
|
- **Sorting**: Verify sort order and pagination
|
|
- **Error Handling**: Invalid inputs and edge cases
|
|
- **Internationalization**: Locale-specific operations
|
|
- **Concurrency**: Multiple concurrent operations
|
|
|
|
### Test Database Setup
|
|
|
|
Tests use isolated table prefixes to avoid conflicts:
|
|
|
|
```go
|
|
store, err := NewXun(Setting{
|
|
Connector: "default",
|
|
Prefix: "__unit_test_conversation_",
|
|
TTL: 3600,
|
|
})
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
### Database Optimization
|
|
|
|
1. **Indexes**: All frequently queried fields have indexes
|
|
2. **TTL**: Automatic cleanup of expired data
|
|
3. **Pagination**: All list operations support pagination
|
|
4. **Connection Pooling**: Efficient database connection management
|
|
|
|
### Caching Strategy
|
|
|
|
1. **Redis Backend**: For high-frequency read operations
|
|
2. **Memory Caching**: In-application caching for static data
|
|
3. **Query Optimization**: Efficient filtering and sorting
|
|
|
|
### Scaling
|
|
|
|
1. **Horizontal Scaling**: MongoDB support for distributed deployments
|
|
2. **Read Replicas**: Database read/write splitting
|
|
3. **Sharding**: Data partitioning strategies
|
|
|
|
## Migration and Upgrades
|
|
|
|
### Schema Evolution
|
|
|
|
The Xun backend automatically handles schema migrations:
|
|
|
|
- New tables are created automatically
|
|
- New fields are added with default values
|
|
- Indexes are created during initialization
|
|
|
|
### Data Migration
|
|
|
|
When switching between backends:
|
|
|
|
1. Export data from source backend
|
|
2. Transform data format if necessary
|
|
3. Import to target backend
|
|
4. Verify data integrity
|
|
|
|
## Security
|
|
|
|
### Access Control
|
|
|
|
1. **User Isolation**: All operations are user-scoped
|
|
2. **Permission System**: Fine-grained access control
|
|
3. **Public/Private Flags**: Content visibility management
|
|
|
|
### Data Protection
|
|
|
|
1. **Input Validation**: All inputs are validated and sanitized
|
|
2. **SQL Injection Prevention**: Parameterized queries
|
|
3. **XSS Protection**: Content encoding and sanitization
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Connection Errors**: Check connector configuration
|
|
2. **Schema Errors**: Verify database permissions
|
|
3. **Performance Issues**: Check indexes and query patterns
|
|
4. **Memory Issues**: Monitor TTL and cleanup processes
|
|
|
|
### Debugging
|
|
|
|
Enable debug logging:
|
|
|
|
```go
|
|
import "github.com/yaoapp/kun/log"
|
|
|
|
log.SetLevel(log.DebugLevel)
|
|
```
|
|
|
|
### Monitoring
|
|
|
|
Key metrics to monitor:
|
|
|
|
- Database connection pool usage
|
|
- Query performance and slow queries
|
|
- Memory usage and garbage collection
|
|
- TTL cleanup effectiveness
|
|
|
|
## Contributing
|
|
|
|
### Development Setup
|
|
|
|
1. Clone the repository
|
|
2. Install dependencies: `go mod download`
|
|
3. Run tests: `go test -v`
|
|
4. Follow Go coding standards
|
|
|
|
### Adding New Features
|
|
|
|
1. Update the Store interface
|
|
2. Implement in all backends (Xun, Redis, MongoDB)
|
|
3. Add comprehensive tests
|
|
4. Update documentation
|
|
|
|
## License
|
|
|
|
This project is part of the Yao App Engine and follows the same license terms.
|