diff --git a/internal/app.go b/internal/app.go index 30ab527..2812734 100644 --- a/internal/app.go +++ b/internal/app.go @@ -29,6 +29,7 @@ type Model struct { allSessionsCache []*Session // "全部" tab 会话切片缓存 allSessionsDirty bool // 缓存是否需要重建 cacheDirty bool // session-cache.json 是否需要写盘 + summaryCount int // 本次会话已生成的摘要数 } func NewModel() *Model { diff --git a/internal/history.go b/internal/history.go index 047e1c4..9ce7244 100644 --- a/internal/history.go +++ b/internal/history.go @@ -736,28 +736,40 @@ func recordFork(targetID, sourceID string) { // --- AI 摘要与收藏操作 --- func (m *Model) applySummary(sessionID, summary string, completed, pending []string) { - if summary == "" { - return - } for _, pd := range m.history.Projects { for _, s := range pd.Sessions { if s.ID == sessionID { - s.AISummary = summary - s.Completed = completed - s.Pending = pending - updateSummaryInCache(m.history.Cache, sessionID, summary, completed, pending) + if summary == "" { + // 标记为已尝试,防止 nextSummaryCmd 无限重试 + // 用 FirstMsg 作为兜底显示,避免显示空白 + s.AISummary = s.FirstMsg + if s.AISummary == "" { + s.AISummary = s.ID[:8] + } + } else { + s.AISummary = summary + s.Completed = completed + s.Pending = pending + } + updateSummaryInCache(m.history.Cache, sessionID, s.AISummary, s.Completed, s.Pending) return } } } } +const maxSummaryPerSession = 20 // 每次启动最多生成 N 个摘要 + func (m *Model) nextSummaryCmd() tea.Cmd { + if m.summaryCount >= maxSummaryPerSession { + return nil + } for _, pd := range m.history.Projects { for _, s := range pd.Sessions { needSummary := s.AISummary == "" && s.FirstMsg != "" needDetail := s.AISummary != "" && len(s.Completed) == 0 && len(s.Pending) == 0 if (needSummary || needDetail) && s.FilePath != "" { + m.summaryCount++ return generateSummaryCmd(s.FilePath, s.ID) } }