feat: Phase 1+2 架构进化 — 连续思考链/主动消息决策/情感状态机/离线自主思考 (86文件)

Phase 1 (基础设施):
- ThinkChain 思考链连续性 + 差异化思考提示词 (persistent)
- AutonomousToolPolicy 工具安全策略 (safe/unsafe/conditional)
- MessageScheduler 自适应消息节奏 (Idle/Available/Busy)
- SessionEnrichmentStore 渐进式上下文丰富 (5层)
- ConversationBus 事件总线 + ResponseCache (dedup)
- pkg/logger 统一日志 + 所有 handler 替换 fmt.Printf
- NPE 守卫/链路优化/数据库表修复/Go workspace

Phase 2 (人格交互):
- EmotionState/EmotionTracker 情感状态机 (5种心情, 情绪衰减)
- ProactiveGuard 主动消息多维决策 (静默时段/紧急度/频率/校验)
- Gateway↔ai-core 在线状态感知链路 (presence notification)
- 离线思考频率控制 + 重连问候 + 离线消息排队

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 15:25:12 +08:00
parent b123a36aae
commit 87214b9441
86 changed files with 3085 additions and 582 deletions
@@ -2,7 +2,7 @@ package handler
import (
"html"
"log"
"github.com/yourname/cyrene-ai/pkg/logger"
"net/http"
"os"
"strings"
@@ -83,7 +83,7 @@ func (h *KnowledgeHandler) CreateKB(c *gin.Context) {
}
if err := h.store.CreateKB(kb); err != nil {
log.Printf("[KnowledgeHandler] 创建知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 创建知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "创建知识库失败", "errorType": "db_error"})
return
}
@@ -101,7 +101,7 @@ func (h *KnowledgeHandler) ListKBs(c *gin.Context) {
kbs, err := h.store.GetKBsByUser(userID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询知识库列表失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询知识库列表失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询知识库列表失败", "errorType": "db_error"})
return
}
@@ -120,7 +120,7 @@ func (h *KnowledgeHandler) GetKB(c *gin.Context) {
kb, err := h.store.GetKB(kbID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询知识库失败", "errorType": "db_error"})
return
}
@@ -136,7 +136,7 @@ func (h *KnowledgeHandler) GetKB(c *gin.Context) {
// 获取文档列表
docs, err := h.store.GetDocumentsByKB(kbID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询文档列表失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询文档列表失败: %v", err)
docs = []store.KnowledgeDocument{}
}
@@ -163,7 +163,7 @@ func (h *KnowledgeHandler) UpdateKB(c *gin.Context) {
kb, err := h.store.GetKB(kbID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询知识库失败", "errorType": "db_error"})
return
}
@@ -177,7 +177,7 @@ func (h *KnowledgeHandler) UpdateKB(c *gin.Context) {
}
if err := h.store.UpdateKB(kbID, html.EscapeString(req.Name), html.EscapeString(req.Description)); err != nil {
log.Printf("[KnowledgeHandler] 更新知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 更新知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "更新知识库失败", "errorType": "db_error"})
return
}
@@ -196,7 +196,7 @@ func (h *KnowledgeHandler) DeleteKB(c *gin.Context) {
kb, err := h.store.GetKB(kbID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询知识库失败", "errorType": "db_error"})
return
}
@@ -210,7 +210,7 @@ func (h *KnowledgeHandler) DeleteKB(c *gin.Context) {
}
if err := h.store.DeleteKB(kbID); err != nil {
log.Printf("[KnowledgeHandler] 删除知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 删除知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除知识库失败", "errorType": "db_error"})
return
}
@@ -230,7 +230,7 @@ func (h *KnowledgeHandler) AddDocument(c *gin.Context) {
// 检查知识库是否存在且属于当前用户
kb, err := h.store.GetKB(kbID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询知识库失败", "errorType": "db_error"})
return
}
@@ -324,7 +324,7 @@ func (h *KnowledgeHandler) AddDocument(c *gin.Context) {
}
if err := h.store.AddDocument(doc); err != nil {
log.Printf("[KnowledgeHandler] 添加文档失败: %v", err)
logger.Printf("[KnowledgeHandler] 添加文档失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "添加文档失败", "errorType": "db_error"})
return
}
@@ -332,7 +332,7 @@ func (h *KnowledgeHandler) AddDocument(c *gin.Context) {
// 自动分块
chunkCount, err := h.store.ChunkDocument(doc.ID)
if err != nil {
log.Printf("[KnowledgeHandler] 文档分块失败: %v", err)
logger.Printf("[KnowledgeHandler] 文档分块失败: %v", err)
// 分块失败不影响文档创建
}
@@ -353,7 +353,7 @@ func (h *KnowledgeHandler) ListDocuments(c *gin.Context) {
// 检查权限
kb, err := h.store.GetKB(kbID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询知识库失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询知识库失败", "errorType": "db_error"})
return
}
@@ -368,7 +368,7 @@ func (h *KnowledgeHandler) ListDocuments(c *gin.Context) {
docs, err := h.store.GetDocumentsByKB(kbID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询文档列表失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询文档列表失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询文档列表失败", "errorType": "db_error"})
return
}
@@ -387,7 +387,7 @@ func (h *KnowledgeHandler) GetDocument(c *gin.Context) {
doc, err := h.store.GetDocument(docID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询文档失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询文档失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询文档失败", "errorType": "db_error"})
return
}
@@ -403,7 +403,7 @@ func (h *KnowledgeHandler) GetDocument(c *gin.Context) {
// 获取分块
chunks, err := h.store.GetChunksByDocID(docID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询分块失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询分块失败: %v", err)
chunks = []store.KnowledgeChunk{}
}
@@ -424,7 +424,7 @@ func (h *KnowledgeHandler) DeleteDocument(c *gin.Context) {
doc, err := h.store.GetDocument(docID)
if err != nil {
log.Printf("[KnowledgeHandler] 查询文档失败: %v", err)
logger.Printf("[KnowledgeHandler] 查询文档失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询文档失败", "errorType": "db_error"})
return
}
@@ -438,7 +438,7 @@ func (h *KnowledgeHandler) DeleteDocument(c *gin.Context) {
}
if err := h.store.DeleteDocument(docID); err != nil {
log.Printf("[KnowledgeHandler] 删除文档失败: %v", err)
logger.Printf("[KnowledgeHandler] 删除文档失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除文档失败", "errorType": "db_error"})
return
}
@@ -483,7 +483,7 @@ func (h *KnowledgeHandler) Search(c *gin.Context) {
}
kbResults, searchErr := h.store.SearchChunks(kbID, req.Query, req.Limit)
if searchErr != nil {
log.Printf("[KnowledgeHandler] 搜索知识库 %s 失败: %v", kbID, searchErr)
logger.Printf("[KnowledgeHandler] 搜索知识库 %s 失败: %v", kbID, searchErr)
continue
}
results = append(results, kbResults...)
@@ -496,7 +496,7 @@ func (h *KnowledgeHandler) Search(c *gin.Context) {
}
if err != nil {
log.Printf("[KnowledgeHandler] 搜索失败: %v", err)
logger.Printf("[KnowledgeHandler] 搜索失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "搜索失败", "errorType": "db_error"})
return
}