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
@@ -4,7 +4,7 @@ import (
"crypto/rand"
"database/sql"
"fmt"
"log"
"github.com/yourname/cyrene-ai/pkg/logger"
"strings"
"time"
"unicode/utf8"
@@ -73,7 +73,7 @@ func NewKnowledgeStore(db *sql.DB) (*KnowledgeStore, error) {
return nil, fmt.Errorf("知识库表迁移失败: %w", err)
}
log.Println("[KnowledgeStore] 知识库持久化存储已初始化")
logger.Println("[KnowledgeStore] 知识库持久化存储已初始化")
return store, nil
}
@@ -133,7 +133,7 @@ func (s *KnowledgeStore) migrate() error {
// 尝试创建 GIN 索引(可能因权限或扩展问题失败,但不影响功能)
_, err := s.db.Exec(`CREATE INDEX IF NOT EXISTS idx_kc_tsv_gin ON knowledge_chunks USING GIN(tsv)`)
if err != nil {
log.Printf("[KnowledgeStore] ⚠ GIN索引创建失败(将使用ILIKE降级搜索): %v", err)
logger.Printf("[KnowledgeStore] ⚠ GIN索引创建失败(将使用ILIKE降级搜索): %v", err)
}
return nil
@@ -260,7 +260,7 @@ func (s *KnowledgeStore) AddDocument(doc *KnowledgeDocument) error {
// 更新知识库统计
if err := s.updateKBStats(doc.KBID); err != nil {
log.Printf("[KnowledgeStore] 更新知识库统计失败: %v", err)
logger.Printf("[KnowledgeStore] 更新知识库统计失败: %v", err)
}
return nil
@@ -340,7 +340,7 @@ func (s *KnowledgeStore) DeleteDocument(id string) error {
// 更新知识库统计
if err := s.updateKBStats(kbID); err != nil {
log.Printf("[KnowledgeStore] 更新知识库统计失败: %v", err)
logger.Printf("[KnowledgeStore] 更新知识库统计失败: %v", err)
}
return nil
@@ -452,12 +452,12 @@ func (s *KnowledgeStore) ChunkDocument(docID string) (int, error) {
// 更新文档的分块计数
if err := s.UpdateDocumentChunkCount(docID, len(chunks)); err != nil {
log.Printf("[KnowledgeStore] 更新文档分块计数失败: %v", err)
logger.Printf("[KnowledgeStore] 更新文档分块计数失败: %v", err)
}
// 更新知识库统计
if err := s.updateKBStats(doc.KBID); err != nil {
log.Printf("[KnowledgeStore] 更新知识库统计失败: %v", err)
logger.Printf("[KnowledgeStore] 更新知识库统计失败: %v", err)
}
return len(chunks), nil
@@ -474,7 +474,7 @@ func (s *KnowledgeStore) SearchChunks(kbID, query string, limit int) ([]SearchCh
// 尝试使用 PostgreSQL 全文搜索
results, err := s.searchWithFullText(kbID, query, limit)
if err != nil {
log.Printf("[KnowledgeStore] 全文搜索失败,降级为ILIKE: %v", err)
logger.Printf("[KnowledgeStore] 全文搜索失败,降级为ILIKE: %v", err)
// 降级为 ILIKE
results, err = s.searchWithILike(kbID, query, limit)
if err != nil {