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:
@@ -5,7 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"github.com/yourname/cyrene-ai/pkg/logger"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -66,7 +66,7 @@ func (h *BriefingHandler) GetBriefing(c *gin.Context) {
|
||||
|
||||
briefing, err := h.briefingStore.GetBriefingByDate(userID, date)
|
||||
if err != nil {
|
||||
log.Printf("[briefing] 查询简报失败: user=%s date=%s err=%v", userID, date, err)
|
||||
logger.Printf("[briefing] 查询简报失败: user=%s date=%s err=%v", userID, date, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询简报失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
@@ -106,7 +106,7 @@ func (h *BriefingHandler) GetLatestBriefings(c *gin.Context) {
|
||||
|
||||
briefings, err := h.briefingStore.GetLatestBriefings(userID, limit)
|
||||
if err != nil {
|
||||
log.Printf("[briefing] 查询简报列表失败: user=%s err=%v", userID, err)
|
||||
logger.Printf("[briefing] 查询简报列表失败: user=%s err=%v", userID, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询简报列表失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func (h *BriefingHandler) Generate(c *gin.Context) {
|
||||
|
||||
result, err := h.GenerateDailyBriefing(req.UserID)
|
||||
if err != nil {
|
||||
log.Printf("[briefing] 生成简报失败: user=%s err=%v", req.UserID, err)
|
||||
logger.Printf("[briefing] 生成简报失败: user=%s err=%v", req.UserID, err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "生成简报失败: " + err.Error(),
|
||||
"success": false,
|
||||
@@ -173,10 +173,10 @@ func (h *BriefingHandler) GenerateDailyBriefing(userID string) (*store.Briefing,
|
||||
}
|
||||
|
||||
// 1. 获取天气数据
|
||||
log.Printf("[briefing] 获取天气数据...")
|
||||
logger.Printf("[briefing] 获取天气数据...")
|
||||
weather, err := h.fetchWeather("Shanghai")
|
||||
if err != nil {
|
||||
log.Printf("[briefing] 天气获取失败 (降级): %v", err)
|
||||
logger.Printf("[briefing] 天气获取失败 (降级): %v", err)
|
||||
weather = &store.WeatherData{
|
||||
Location: "未知",
|
||||
Temp: 0,
|
||||
@@ -185,13 +185,13 @@ func (h *BriefingHandler) GenerateDailyBriefing(userID string) (*store.Briefing,
|
||||
}
|
||||
}
|
||||
briefing.Weather = weather
|
||||
log.Printf("[briefing] 天气: %s %.1f°C %s", weather.Location, weather.Temp, weather.Condition)
|
||||
logger.Printf("[briefing] 天气: %s %.1f°C %s", weather.Location, weather.Temp, weather.Condition)
|
||||
|
||||
// 2. 获取今日待办提醒
|
||||
log.Printf("[briefing] 获取待办提醒...")
|
||||
logger.Printf("[briefing] 获取待办提醒...")
|
||||
reminders, err := h.reminderStore.GetRemindersByUser(userID, "pending", 10, 0)
|
||||
if err != nil {
|
||||
log.Printf("[briefing] 获取提醒失败: %v", err)
|
||||
logger.Printf("[briefing] 获取提醒失败: %v", err)
|
||||
} else {
|
||||
now := time.Now()
|
||||
endOfDay := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location())
|
||||
@@ -205,22 +205,22 @@ func (h *BriefingHandler) GenerateDailyBriefing(userID string) (*store.Briefing,
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Printf("[briefing] 今日待办: %d 项", len(briefing.Reminders))
|
||||
logger.Printf("[briefing] 今日待办: %d 项", len(briefing.Reminders))
|
||||
|
||||
// 3. 获取新闻摘要(通过 tool-engine web_search)
|
||||
log.Printf("[briefing] 获取新闻摘要...")
|
||||
logger.Printf("[briefing] 获取新闻摘要...")
|
||||
news, err := h.fetchNews()
|
||||
if err != nil {
|
||||
log.Printf("[briefing] 新闻获取失败 (降级): %v", err)
|
||||
logger.Printf("[briefing] 新闻获取失败 (降级): %v", err)
|
||||
}
|
||||
briefing.News = news
|
||||
log.Printf("[briefing] 新闻: %d 条", len(news))
|
||||
logger.Printf("[briefing] 新闻: %d 条", len(news))
|
||||
|
||||
// 4. 生成 AI 摘要
|
||||
log.Printf("[briefing] 生成 AI 摘要...")
|
||||
logger.Printf("[briefing] 生成 AI 摘要...")
|
||||
summary, err := h.generateAISummary(briefing)
|
||||
if err != nil {
|
||||
log.Printf("[briefing] AI 摘要生成失败 (降级): %v", err)
|
||||
logger.Printf("[briefing] AI 摘要生成失败 (降级): %v", err)
|
||||
summary = h.buildFallbackSummary(briefing)
|
||||
briefing.SummarySource = "fallback"
|
||||
} else {
|
||||
@@ -238,7 +238,7 @@ func (h *BriefingHandler) GenerateDailyBriefing(userID string) (*store.Briefing,
|
||||
return nil, fmt.Errorf("保存简报失败: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("[briefing] 简报已生成: user=%s date=%s", userID, today)
|
||||
logger.Printf("[briefing] 简报已生成: user=%s date=%s", userID, today)
|
||||
return briefing, nil
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ func (h *BriefingHandler) fetchNews() ([]store.NewsItem, error) {
|
||||
}
|
||||
|
||||
if result.Error != "" {
|
||||
log.Printf("[briefing] 新闻搜索失败: %s", result.Error)
|
||||
logger.Printf("[briefing] 新闻搜索失败: %s", result.Error)
|
||||
// 返回降级新闻
|
||||
return []store.NewsItem{
|
||||
{
|
||||
@@ -585,7 +585,7 @@ func (h *BriefingHandler) pushBriefingNotification(userID string, b *store.Brief
|
||||
|
||||
data, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
log.Printf("[briefing] 序列化简报通知失败: %v", err)
|
||||
logger.Printf("[briefing] 序列化简报通知失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -596,10 +596,10 @@ func (h *BriefingHandler) pushBriefingNotification(userID string, b *store.Brief
|
||||
b.Status = "delivered"
|
||||
b.DeliveredAt = &now
|
||||
if err := h.briefingStore.CreateOrUpdateBriefing(b); err != nil {
|
||||
log.Printf("[briefing] 更新简报送达状态失败: %v", err)
|
||||
logger.Printf("[briefing] 更新简报送达状态失败: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("[briefing] 简报通知已推送: user=%s date=%s", userID, b.Date)
|
||||
logger.Printf("[briefing] 简报通知已推送: user=%s date=%s", userID, b.Date)
|
||||
}
|
||||
|
||||
// StartBriefingScheduler 启动简报调度器
|
||||
@@ -614,7 +614,7 @@ func StartBriefingScheduler(handler *BriefingHandler, briefingStore *store.Brief
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
log.Printf("[BriefingScheduler] 简报调度器已启动 (简报时间: %s)", briefingTime)
|
||||
logger.Printf("[BriefingScheduler] 简报调度器已启动 (简报时间: %s)", briefingTime)
|
||||
|
||||
// 记录今天是否已触发
|
||||
lastTriggeredDate := ""
|
||||
@@ -626,13 +626,13 @@ func StartBriefingScheduler(handler *BriefingHandler, briefingStore *store.Brief
|
||||
|
||||
// 检查是否到达简报时间且今天尚未触发
|
||||
if currentTime == briefingTime && currentDate != lastTriggeredDate {
|
||||
log.Printf("[BriefingScheduler] 触发每日简报生成: %s", currentDate)
|
||||
logger.Printf("[BriefingScheduler] 触发每日简报生成: %s", currentDate)
|
||||
lastTriggeredDate = currentDate
|
||||
|
||||
// 获取所有用户
|
||||
users, err := briefingStore.GetAllUsers()
|
||||
if err != nil {
|
||||
log.Printf("[BriefingScheduler] 获取用户列表失败: %v", err)
|
||||
logger.Printf("[BriefingScheduler] 获取用户列表失败: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -642,21 +642,21 @@ func StartBriefingScheduler(handler *BriefingHandler, briefingStore *store.Brief
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
log.Println("[BriefingScheduler] 没有找到用户,跳过简报生成")
|
||||
logger.Println("[BriefingScheduler] 没有找到用户,跳过简报生成")
|
||||
continue
|
||||
}
|
||||
|
||||
for _, userID := range users {
|
||||
log.Printf("[BriefingScheduler] 为用户 %s 生成简报...", userID)
|
||||
logger.Printf("[BriefingScheduler] 为用户 %s 生成简报...", userID)
|
||||
result, err := handler.GenerateDailyBriefing(userID)
|
||||
if err != nil {
|
||||
log.Printf("[BriefingScheduler] 生成简报失败: user=%s err=%v", userID, err)
|
||||
logger.Printf("[BriefingScheduler] 生成简报失败: user=%s err=%v", userID, err)
|
||||
continue
|
||||
}
|
||||
handler.pushBriefingNotification(userID, result)
|
||||
}
|
||||
|
||||
log.Printf("[BriefingScheduler] 每日简报已生成完毕,共 %d 个用户", len(users))
|
||||
logger.Printf("[BriefingScheduler] 每日简报已生成完毕,共 %d 个用户", len(users))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
Reference in New Issue
Block a user