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
+16 -16
View File
@@ -6,7 +6,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"log"
"github.com/yourname/cyrene-ai/pkg/logger"
"net/http"
"os"
"strings"
@@ -91,7 +91,7 @@ func (e *RuleEngine) Start() {
e.mu.Unlock()
go e.loop()
log.Printf("[RuleEngine] 规则引擎已启动 (IoT服务地址: %s)", e.iotServiceURL)
logger.Printf("[RuleEngine] 规则引擎已启动 (IoT服务地址: %s)", e.iotServiceURL)
}
// Stop 停止规则引擎
@@ -104,7 +104,7 @@ func (e *RuleEngine) Stop() {
}
close(e.stopCh)
e.running = false
log.Println("[RuleEngine] 规则引擎已停止")
logger.Println("[RuleEngine] 规则引擎已停止")
}
// loop 规则引擎主循环
@@ -129,7 +129,7 @@ func (e *RuleEngine) loop() {
func (e *RuleEngine) evaluateAllRules() {
rules, err := e.store.GetEnabledRules()
if err != nil {
log.Printf("[RuleEngine] 获取启用的规则失败: %v", err)
logger.Printf("[RuleEngine] 获取启用的规则失败: %v", err)
return
}
@@ -162,7 +162,7 @@ func (e *RuleEngine) evaluateRule(rule *store.AutomationRule) bool {
var triggerCfg TriggerConfig
if rule.TriggerConfig != nil {
if err := json.Unmarshal(*rule.TriggerConfig, &triggerCfg); err != nil {
log.Printf("[RuleEngine] 解析触发器配置失败: rule=%s err=%v", rule.ID, err)
logger.Printf("[RuleEngine] 解析触发器配置失败: rule=%s err=%v", rule.ID, err)
return false
}
}
@@ -189,7 +189,7 @@ func (e *RuleEngine) evaluateRule(rule *store.AutomationRule) bool {
var conditions []Condition
if rule.Conditions != nil {
if err := json.Unmarshal(*rule.Conditions, &conditions); err != nil {
log.Printf("[RuleEngine] 解析条件失败: rule=%s err=%v", rule.ID, err)
logger.Printf("[RuleEngine] 解析条件失败: rule=%s err=%v", rule.ID, err)
return false
}
}
@@ -240,7 +240,7 @@ func (e *RuleEngine) evaluateDeviceStateTrigger(cfg TriggerConfig) bool {
// 从 IoT 服务获取设备状态
devices, err := e.fetchIoTDevices()
if err != nil {
log.Printf("[RuleEngine] 获取设备状态失败: %v", err)
logger.Printf("[RuleEngine] 获取设备状态失败: %v", err)
return false
}
@@ -340,12 +340,12 @@ func (e *RuleEngine) ExecuteRuleActions(rule *store.AutomationRule) {
var actions []Action
if rule.Actions != nil {
if err := json.Unmarshal(*rule.Actions, &actions); err != nil {
log.Printf("[RuleEngine] 解析动作失败: rule=%s err=%v", rule.ID, err)
logger.Printf("[RuleEngine] 解析动作失败: rule=%s err=%v", rule.ID, err)
return
}
}
log.Printf("[RuleEngine] 执行规则 %s (%s) 的 %d 个动作", rule.ID, rule.Name, len(actions))
logger.Printf("[RuleEngine] 执行规则 %s (%s) 的 %d 个动作", rule.ID, rule.Name, len(actions))
for _, action := range actions {
switch action.Type {
@@ -354,7 +354,7 @@ func (e *RuleEngine) ExecuteRuleActions(rule *store.AutomationRule) {
case "notify":
e.executeNotify(action, rule.UserID)
default:
log.Printf("[RuleEngine] 未知动作类型: %s", action.Type)
logger.Printf("[RuleEngine] 未知动作类型: %s", action.Type)
}
}
}
@@ -366,7 +366,7 @@ func (e *RuleEngine) ExecuteScene(sceneID, userID string) error {
return fmt.Errorf("获取场景规则失败: %w", err)
}
log.Printf("[RuleEngine] 执行场景 %s,共 %d 条关联规则", sceneID, len(rules))
logger.Printf("[RuleEngine] 执行场景 %s,共 %d 条关联规则", sceneID, len(rules))
for _, rule := range rules {
if rule.Enabled {
@@ -393,17 +393,17 @@ func (e *RuleEngine) executeSetDevice(action Action) {
resp, err := e.httpClient.Post(url, "application/json", bytes.NewReader(bodyBytes))
if err != nil {
log.Printf("[RuleEngine] 设备控制请求失败: device=%s property=%s err=%v",
logger.Printf("[RuleEngine] 设备控制请求失败: device=%s property=%s err=%v",
action.DeviceID, action.Property, err)
return
}
defer resp.Body.Close()
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
log.Printf("[RuleEngine] 设备控制成功: device=%s property=%s value=%v",
logger.Printf("[RuleEngine] 设备控制成功: device=%s property=%s value=%v",
action.DeviceID, action.Property, action.Value)
} else {
log.Printf("[RuleEngine] 设备控制失败: device=%s property=%s status=%d",
logger.Printf("[RuleEngine] 设备控制失败: device=%s property=%s status=%d",
action.DeviceID, action.Property, resp.StatusCode)
}
}
@@ -427,12 +427,12 @@ func (e *RuleEngine) executeNotify(action Action, userID string) {
data, err := json.Marshal(msg)
if err != nil {
log.Printf("[RuleEngine] 序列化通知失败: %v", err)
logger.Printf("[RuleEngine] 序列化通知失败: %v", err)
return
}
e.hub.SendToUser(userID, data)
log.Printf("[RuleEngine] 通知已发送: user=%s title=%s", userID, action.Title)
logger.Printf("[RuleEngine] 通知已发送: user=%s title=%s", userID, action.Title)
}
// ========== 辅助方法 ==========