fix: 修复19个Bug (P0-P3) — 持续性调试第7轮发现的问题
P0 (5): crypto/rand session ID, TTS fallback可达性, goroutine defer recover, adminAuth前缀修正 P1 (5): 普通用户密码验证, context传递, priority clamp, 超时重试, 自主思考速率限制 P2 (4): Briefing AI降级, 前端消息类型渲染, Docker Compose补全, PWA 192图标 P3 (5): goroutine错误处理, .gitignore完善, reminder created_at, voice Dockerfile, Go版本更新
This commit is contained in:
@@ -220,6 +220,11 @@ func (t *Thinker) TriggerPostChatThink() {
|
||||
t.wg.Add(1)
|
||||
go func() {
|
||||
defer t.wg.Done()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("[后台思考] 对话后触发 panic 恢复: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
// 短暂延迟,让对话有个自然的停顿
|
||||
select {
|
||||
@@ -261,6 +266,11 @@ func (t *Thinker) resetSilenceTimer() {
|
||||
t.wg.Add(1)
|
||||
go func() {
|
||||
defer t.wg.Done()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("[后台思考] 静默定时器 panic 恢复: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-t.stopCh:
|
||||
@@ -316,16 +326,30 @@ func (t *Thinker) HasPendingThoughts() bool {
|
||||
// performThink 执行一次增强版后台思考(支持工具调用和记忆管理)
|
||||
//
|
||||
// triggerReason: "post_chat" (对话后) 或 "silence" (静默超时)
|
||||
//
|
||||
// 防御性速率限制:即使调用方未检查 minThinkGap,performThink 自身也会
|
||||
// 强制执行最小间隔,防止并发调用或 bug 导致 LLM 配额被快速消耗。
|
||||
func (t *Thinker) performThink(triggerReason string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
|
||||
defer cancel()
|
||||
|
||||
t.mu.Lock()
|
||||
gapSinceLast := time.Since(t.lastThinkTime)
|
||||
minGap := t.minThinkGap
|
||||
if minGap <= 0 {
|
||||
minGap = 5 * time.Second // 默认最小间隔 5 秒
|
||||
}
|
||||
if gapSinceLast < minGap {
|
||||
t.mu.Unlock()
|
||||
log.Printf("[后台思考] 距上次思考仅 %v,跳过 (最小间隔=%v, 触发原因=%s)", gapSinceLast.Round(time.Second), minGap, triggerReason)
|
||||
return
|
||||
}
|
||||
|
||||
t.lastThinkTime = time.Now()
|
||||
t.thinkCount++
|
||||
currentCount := t.thinkCount
|
||||
t.mu.Unlock()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
|
||||
defer cancel()
|
||||
|
||||
log.Printf("[后台思考] 开始思考周期 (触发原因=%s, 计数=%d)...", triggerReason, currentCount)
|
||||
|
||||
// 1. 加载人格配置
|
||||
@@ -356,7 +380,7 @@ func (t *Thinker) performThink(triggerReason string) {
|
||||
// 4. 查询 IoT 设备状态(每次都查询,无间隔限制)
|
||||
var deviceSummary string
|
||||
if t.iotClient != nil {
|
||||
devices := t.iotClient.GetDevicesForContext()
|
||||
devices := t.iotClient.GetDevicesForContext(ctx)
|
||||
if len(devices) > 0 {
|
||||
deviceSummary = formatDeviceContext(devices)
|
||||
}
|
||||
@@ -460,7 +484,14 @@ func (t *Thinker) performThink(triggerReason string) {
|
||||
|
||||
// 9. 从思考结果中提取记忆(异步)
|
||||
if t.memoryExtractor != nil {
|
||||
go t.extractMemoriesFromThinking(finalContent)
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("[后台思考] 提取记忆 panic 恢复: %v", r)
|
||||
}
|
||||
}()
|
||||
t.extractMemoriesFromThinking(finalContent)
|
||||
}()
|
||||
}
|
||||
|
||||
// 10. 周期性记忆维护(每 10 次思考触发一次,而非按时间)
|
||||
@@ -649,6 +680,11 @@ func (t *Thinker) storeThought(content string, toolCallsJSON string, toolCallCou
|
||||
// 异步持久化到 memory-service
|
||||
if t.memClient != nil {
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("[后台思考] 持久化思考日志 panic 恢复: %v", r)
|
||||
}
|
||||
}()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if err := t.memClient.SaveThinkingLog(ctx, t.adminUserID, content, toolCallsJSON, toolCallCount, len(content)); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user