71f0a1abdb
- 所有Go模块路径从 github.com/yourname/cyrene-ai 迁移到 git.yeij.top/AskaEth/Cyrene - 5个Go Dockerfile添加 GOPROXY=https://goproxy.cn,direct 解决国内构建问题 - ai-core go.mod 添加 pkg/plugins replace 指令 - Caddyfile 简化为 http:// 通配 + handle 保留 /api 前缀 - ethend Dockerfile 适配 (npm install + 仅 COPY package.json) - ethend 新增 RUNNING_IN_DOCKER 环境变量,健康检查改用Docker服务名 - ethend 数据库状态检查支持Docker hostname (postgres/redis/qdrant/minio) - process-manager 新增 CONTAINER_SVC_MAP + Docker模式自动检测 - 统一 docker-compose.dev.db.yml 卷名 (pg_data/redis_data/qdrant_data/minio_data) - docker-compose.yml ethend服务挂载docker.sock + 端口变量化 - 清理 .env 统一后的残留文件与提示信息 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
157 lines
3.7 KiB
Go
157 lines
3.7 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.yeij.top/AskaEth/Cyrene/ai-core/internal/rag"
|
|
)
|
|
|
|
// KnowledgeSearchTool searches the knowledge base.
|
|
type KnowledgeSearchTool struct {
|
|
retriever *rag.Retriever
|
|
}
|
|
|
|
// NewKnowledgeSearchTool creates a knowledge search tool.
|
|
func NewKnowledgeSearchTool(retriever *rag.Retriever) *KnowledgeSearchTool {
|
|
return &KnowledgeSearchTool{retriever: retriever}
|
|
}
|
|
|
|
func (t *KnowledgeSearchTool) Definition() ToolDefinition {
|
|
return ToolDefinition{
|
|
Name: "knowledge_search",
|
|
Description: "搜索本地知识库。从文档、代码、笔记等中检索相关信息,支持语义搜索和关键词匹配。",
|
|
Parameters: map[string]interface{}{
|
|
"type": "object",
|
|
"properties": map[string]interface{}{
|
|
"query": map[string]interface{}{
|
|
"type": "string",
|
|
"description": "搜索查询",
|
|
},
|
|
"top_k": map[string]interface{}{
|
|
"type": "integer",
|
|
"description": "返回结果数量,默认5条,最大10条",
|
|
},
|
|
},
|
|
"required": []string{"query"},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (t *KnowledgeSearchTool) Execute(ctx context.Context, args map[string]interface{}) (*ToolResult, error) {
|
|
query, _ := args["query"].(string)
|
|
if query == "" {
|
|
return &ToolResult{
|
|
ToolName: "knowledge_search",
|
|
Success: false,
|
|
Error: "query 参数不能为空",
|
|
}, nil
|
|
}
|
|
|
|
topK := 5
|
|
if v, ok := args["top_k"].(float64); ok {
|
|
topK = int(v)
|
|
if topK > 10 {
|
|
topK = 10
|
|
}
|
|
}
|
|
|
|
result, err := t.retriever.Retrieve(ctx, query, topK)
|
|
if err != nil {
|
|
return &ToolResult{
|
|
ToolName: "knowledge_search",
|
|
Success: false,
|
|
Error: fmt.Sprintf("知识库搜索失败: %v", err),
|
|
}, nil
|
|
}
|
|
|
|
count := 0
|
|
if result.Results != nil {
|
|
count = len(result.Results)
|
|
}
|
|
|
|
data, _ := json.Marshal(map[string]interface{}{
|
|
"query": result.Query,
|
|
"summary": result.Summary,
|
|
"count": count,
|
|
})
|
|
|
|
return &ToolResult{
|
|
ToolName: "knowledge_search",
|
|
Success: true,
|
|
Data: string(data),
|
|
}, nil
|
|
}
|
|
|
|
// KnowledgeIngestTool allows ingesting documents into the knowledge base.
|
|
type KnowledgeIngestTool struct {
|
|
store *rag.KnowledgeStore
|
|
}
|
|
|
|
// NewKnowledgeIngestTool creates a knowledge ingestion tool.
|
|
func NewKnowledgeIngestTool(store *rag.KnowledgeStore) *KnowledgeIngestTool {
|
|
return &KnowledgeIngestTool{store: store}
|
|
}
|
|
|
|
func (t *KnowledgeIngestTool) Definition() ToolDefinition {
|
|
return ToolDefinition{
|
|
Name: "knowledge_ingest",
|
|
Description: "将文件导入知识库。支持 .md .txt .go .py .js .ts .json 等常见文件格式。",
|
|
Parameters: map[string]interface{}{
|
|
"type": "object",
|
|
"properties": map[string]interface{}{
|
|
"path": map[string]interface{}{
|
|
"type": "string",
|
|
"description": "文件路径或目录路径",
|
|
},
|
|
},
|
|
"required": []string{"path"},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (t *KnowledgeIngestTool) Execute(ctx context.Context, args map[string]interface{}) (*ToolResult, error) {
|
|
path, _ := args["path"].(string)
|
|
if path == "" {
|
|
return &ToolResult{
|
|
ToolName: "knowledge_ingest",
|
|
Success: false,
|
|
Error: "path 参数不能为空",
|
|
}, nil
|
|
}
|
|
|
|
count, err := t.store.IngestFile(ctx, path)
|
|
if err != nil {
|
|
return &ToolResult{
|
|
ToolName: "knowledge_ingest",
|
|
Success: false,
|
|
Error: fmt.Sprintf("知识导入失败: %v", err),
|
|
}, nil
|
|
}
|
|
|
|
if count == 0 {
|
|
// Try directory
|
|
count, err = t.store.IngestDirectory(ctx)
|
|
if err != nil {
|
|
return &ToolResult{
|
|
ToolName: "knowledge_ingest",
|
|
Success: false,
|
|
Error: fmt.Sprintf("目录导入失败: %v", err),
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
data, _ := json.Marshal(map[string]interface{}{
|
|
"path": path,
|
|
"chunks_indexed": count,
|
|
"status": "ok",
|
|
})
|
|
|
|
return &ToolResult{
|
|
ToolName: "knowledge_ingest",
|
|
Success: true,
|
|
Data: string(data),
|
|
}, nil
|
|
}
|