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
@@ -3,7 +3,7 @@ package handler
import (
"encoding/json"
"html"
"log"
"github.com/yourname/cyrene-ai/pkg/logger"
"net/http"
"strconv"
"time"
@@ -71,7 +71,7 @@ func (h *ReminderHandler) List(c *gin.Context) {
reminders, err := h.store.GetRemindersByUser(userID, status, limit, offset)
if err != nil {
log.Printf("[reminder] 获取提醒列表失败: %v", err)
logger.Printf("[reminder] 获取提醒列表失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取提醒列表失败"})
return
}
@@ -124,12 +124,12 @@ func (h *ReminderHandler) Create(c *gin.Context) {
}
if err := h.store.CreateReminder(reminder); err != nil {
log.Printf("[reminder] 创建提醒失败: %v", err)
logger.Printf("[reminder] 创建提醒失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "创建提醒失败"})
return
}
log.Printf("[reminder] 提醒已创建: id=%s user=%s title=%s remind_at=%s repeat=%s",
logger.Printf("[reminder] 提醒已创建: id=%s user=%s title=%s remind_at=%s repeat=%s",
reminder.ID, userID, reminder.Title, remindAt.Format(time.RFC3339), repeatType)
c.JSON(http.StatusCreated, gin.H{
@@ -204,12 +204,12 @@ func (h *ReminderHandler) Update(c *gin.Context) {
}
if err := h.store.UpdateReminder(id, existing); err != nil {
log.Printf("[reminder] 更新提醒失败: %v", err)
logger.Printf("[reminder] 更新提醒失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "更新提醒失败"})
return
}
log.Printf("[reminder] 提醒已更新: id=%s", id)
logger.Printf("[reminder] 提醒已更新: id=%s", id)
c.JSON(http.StatusOK, gin.H{
"success": true,
@@ -227,12 +227,12 @@ func (h *ReminderHandler) Delete(c *gin.Context) {
}
if err := h.store.DeleteReminder(id); err != nil {
log.Printf("[reminder] 删除提醒失败: %v", err)
logger.Printf("[reminder] 删除提醒失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除提醒失败"})
return
}
log.Printf("[reminder] 提醒已删除: id=%s", id)
logger.Printf("[reminder] 提醒已删除: id=%s", id)
c.JSON(http.StatusOK, gin.H{
"success": true,
@@ -247,7 +247,7 @@ func StartReminderScheduler(s *store.ReminderStore, hub *ws.Hub) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
log.Println("[ReminderScheduler] 提醒调度器已启动 (检查间隔: 30秒)")
logger.Println("[ReminderScheduler] 提醒调度器已启动 (检查间隔: 30秒)")
for range ticker.C {
checkAndNotify(s, hub)
@@ -259,7 +259,7 @@ func StartReminderScheduler(s *store.ReminderStore, hub *ws.Hub) {
func checkAndNotify(s *store.ReminderStore, hub *ws.Hub) {
reminders, err := s.GetDueReminders()
if err != nil {
log.Printf("[ReminderScheduler] 获取到期提醒失败: %v", err)
logger.Printf("[ReminderScheduler] 获取到期提醒失败: %v", err)
return
}
@@ -290,7 +290,7 @@ func checkAndNotify(s *store.ReminderStore, hub *ws.Hub) {
data, err := json.Marshal(msg)
if err != nil {
log.Printf("[ReminderScheduler] 序列化通知失败: %v", err)
logger.Printf("[ReminderScheduler] 序列化通知失败: %v", err)
continue
}
@@ -299,7 +299,7 @@ func checkAndNotify(s *store.ReminderStore, hub *ws.Hub) {
// 3. 标记为已通知
if err := s.MarkNotified(r.ID); err != nil {
log.Printf("[ReminderScheduler] 标记已通知失败: id=%s err=%v", r.ID, err)
logger.Printf("[ReminderScheduler] 标记已通知失败: id=%s err=%v", r.ID, err)
}
// 4. 处理重复提醒
@@ -308,9 +308,9 @@ func checkAndNotify(s *store.ReminderStore, hub *ws.Hub) {
r.RemindAt = nextTime
r.Notified = false
if err := s.UpdateReminder(r.ID, &r); err != nil {
log.Printf("[ReminderScheduler] 更新重复提醒失败: id=%s err=%v", r.ID, err)
logger.Printf("[ReminderScheduler] 更新重复提醒失败: id=%s err=%v", r.ID, err)
} else {
log.Printf("[ReminderScheduler] 重复提醒已更新: id=%s next=%s", r.ID, nextTime.Format(time.RFC3339))
logger.Printf("[ReminderScheduler] 重复提醒已更新: id=%s next=%s", r.ID, nextTime.Format(time.RFC3339))
}
} else {
// 非重复提醒:标记为已完成
@@ -318,11 +318,11 @@ func checkAndNotify(s *store.ReminderStore, hub *ws.Hub) {
r.Status = "completed"
r.CompletedAt = &now
if err := s.UpdateReminder(r.ID, &r); err != nil {
log.Printf("[ReminderScheduler] 标记提醒完成失败: id=%s err=%v", r.ID, err)
logger.Printf("[ReminderScheduler] 标记提醒完成失败: id=%s err=%v", r.ID, err)
}
}
log.Printf("[ReminderScheduler] 提醒已推送: user=%s title=%s id=%s", r.UserID, r.Title, r.ID)
logger.Printf("[ReminderScheduler] 提醒已推送: user=%s title=%s id=%s", r.UserID, r.Title, r.ID)
}
}