diff --git a/internal/bot/bot.go b/internal/bot/bot.go index a9d65b5..7c21e05 100644 --- a/internal/bot/bot.go +++ b/internal/bot/bot.go @@ -138,6 +138,11 @@ func (b *Bot) Tools() []string { return b.toolRegistry.List() } +// ClearHistory 清空内存中的会话历史,开启新对话(系统提示词保留)。 +func (b *Bot) ClearHistory() { + b.history = nil +} + func (b *Bot) ContextWindow() int64 { if m := config.FindModel(b.provider, b.model); m != nil { return m.ContextWindow diff --git a/internal/bot/session_test.go b/internal/bot/session_test.go index e5dda1a..8dee110 100644 --- a/internal/bot/session_test.go +++ b/internal/bot/session_test.go @@ -85,3 +85,15 @@ func TestRestoreTrimsHistory(t *testing.T) { t.Errorf("history 应截断到 %d, got %d", maxHistory, len(b.history)) } } + +func TestClearHistory(t *testing.T) { + b := newTestBot(t) + b.history = append(b.history, openai.UserMessage("hi")) + b.ClearHistory() + if len(b.history) != 0 { + t.Errorf("history 应清空, got %d", len(b.history)) + } + if b.systemPrompt != "测试系统提示" { + t.Errorf("systemPrompt 应保留: %q", b.systemPrompt) + } +} diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 2cb41dc..9c36e3e 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -20,6 +20,26 @@ func New(b *bot.Bot, db *sql.DB) *Handler { return &Handler{bot: b, db: db} } +// saveSessionAndReset 将当前内存会话存档为新的会话行,并清空内存开启新对话。 +func (h *Handler) saveSessionAndReset() { + msgs := h.bot.SessionMessages() + if len(msgs) == 0 { + return + } + provider, model := h.bot.Current() + sess := &store.Session{ + Provider: provider, + Model: model, + Messages: msgs, + } + if _, err := store.SaveSession(h.db, sess); err != nil { + fmt.Printf("⚠️ 保存会话失败: %v\n", err) + return + } + h.bot.ClearHistory() + fmt.Printf("💾 会话已存档 (%d 条消息),已开启新对话\n", len(msgs)) +} + func formatWindow(n int64) string { switch { case n <= 0: @@ -63,7 +83,8 @@ func (h *Handler) Handle(input string) bool { fmt.Println(" /effort 设置思考强度") fmt.Println(" /context 打印当前聊天上下文") fmt.Println(" /tools 列出可用工具") - fmt.Println(" /dream 从对话中提取长期记忆") + fmt.Println(" /dream 从对话中提取长期记忆并开启新对话") + fmt.Println(" /forge 直接清空对话,不提取记忆不存档") fmt.Println(" /memories 列出已提取的记忆") fmt.Println(" /sessions 列出历史会话") fmt.Println(" /session 切换到历史会话,如 /session 3") @@ -141,6 +162,7 @@ func (h *Handler) Handle(input string) bool { } if len(ms) == 0 { fmt.Println("🧠 没有新的记忆") + h.saveSessionAndReset() return true } if _, err := store.SaveMemories(h.db, ms); err != nil { @@ -151,6 +173,10 @@ func (h *Handler) Handle(input string) bool { for _, m := range ms { fmt.Printf(" [%s %d] %s\n", m.Category, m.Importance, m.Content) } + h.saveSessionAndReset() + case "/forge": + h.bot.ClearHistory() + fmt.Println("💬 会话已清空,已开启新对话") case "/memories": list, err := store.ListMemories(h.db) if err != nil { diff --git a/internal/cli/complete.go b/internal/cli/complete.go index 2f855ac..41e1aba 100644 --- a/internal/cli/complete.go +++ b/internal/cli/complete.go @@ -2,7 +2,7 @@ package cli import "strings" -var commands = []string{"/exit", "/quit", "/help", "/models", "/use", "/think", "/effort", "/context", "/tools", "/dream", "/memories", "/sessions", "/session", "/info"} +var commands = []string{"/exit", "/quit", "/help", "/models", "/use", "/think", "/effort", "/context", "/tools", "/dream", "/forge", "/memories", "/sessions", "/session", "/info"} func Complete(line string, models []string) []string { fields := strings.Fields(line)