From b050ef4ab792dc9304931e3a41843cd7bd0994f6 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sun, 19 Jul 2026 00:10:05 +0200 Subject: [PATCH] 9p: replay last 20 messages into chat log on session restore --- session/session.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/session/session.go b/session/session.go index 93bffcb..e5d61eb 100644 --- a/session/session.go +++ b/session/session.go @@ -814,6 +814,10 @@ func (s *Manager) restoreSession(ps *agent.PersistedSession) error { sessPtr = sess sess.uname = uname + // Replay tail of persisted messages into the chat log so the GUI + // and `chat` file show recent history on restore. + replayMessagesToLog(sess, ps.Messages) + s.mu.Lock() s.sessions[sessID] = sess s.mu.Unlock() @@ -1138,6 +1142,39 @@ func squashWhitespace(s string) string { return strings.Join(strings.Fields(s), " ") } +// replayMessagesToLog renders the tail of a persisted message list into the +// session's chat log so that restored sessions show recent history. +func replayMessagesToLog(sess *Session, messages []backend.Message) { + const maxReplay = 20 + start := len(messages) - maxReplay + if start < 0 { + start = 0 + } + // Skip system messages at the start of the replay window. + for start < len(messages) && messages[start].Role == "system" { + start++ + } + for _, m := range messages[start:] { + switch m.Role { + case "system": + // skip + case "user": + sess.AppendLog([]byte("[user]\n" + m.Content + "\n")) + case "assistant": + sess.AppendLog([]byte("[assistant]\n")) + if m.Content != "" { + sess.AppendLog([]byte(m.Content + "\n")) + } + for _, tc := range m.ToolCalls { + args := squashWhitespace(string(tc.Arguments)) + sess.AppendLog([]byte("[call:" + tc.Name + "]\n" + args + "\n")) + } + case "tool": + sess.AppendLog([]byte("[tool]\n" + strings.TrimRight(m.Content, "\n") + "\n")) + } + } +} + // --- Code Completion --- // Complete performs a stateless one-shot code completion via backend.Generate.