/cont logic

This commit is contained in:
Luxferre
2026-09-01 09:46:13 +03:00
parent 0eb05354df
commit 872414e6fb
3 changed files with 103 additions and 47 deletions
+52 -22
View File
@@ -7,6 +7,8 @@ import (
"bufio"
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
@@ -1316,14 +1318,25 @@ func fileExists(p string) bool {
return err == nil
}
func saveSession(msgs []Message) (string, string) {
d := sdir()
base := time.Now().Format("20060102-150405")
sid, path := base, filepath.Join(d, base+".json")
for i := 1; fileExists(path); i++ {
sid = fmt.Sprintf("%s-%d", base, i)
path = filepath.Join(d, sid+".json")
func projectID() string {
dir, err := os.Getwd()
if err != nil {
dir = "."
}
if abs, err := filepath.Abs(dir); err == nil {
dir = abs
}
h := md5.Sum([]byte(dir))
return hex.EncodeToString(h[:])
}
func saveSession(msgs []Message, sid string) (string, string) {
sid = strings.TrimSpace(sid)
if sid == "" {
sid = projectID()
}
d := sdir()
path := filepath.Join(d, sid+".json")
s := Session{sid, time.Now().Format("2006-01-02 15:04:05"), summary(msgs), msgs}
b, err := json.MarshalIndent(s, "", " ")
if err != nil {
@@ -1375,15 +1388,7 @@ func loadSession(sid string) ([]Message, error) {
}
func autosave(msgs []Message) {
s := Session{"autosave", time.Now().Format("2006-01-02 15:04:05"), summary(msgs), msgs}
b, err := json.MarshalIndent(s, "", " ")
if err != nil {
fmt.Fprintf(os.Stderr, "autosave: marshal error: %v\n", err)
return
}
if err := os.WriteFile(filepath.Join(sdir(), "autosave.json"), b, 0644); err != nil {
fmt.Fprintf(os.Stderr, "autosave: write error: %v\n", err)
}
saveSession(msgs, projectID())
}
const compactionPrompt = "You are now acting as a compaction engine. Summarize the preceding conversation concisely but completely, preserving all important facts, decisions, code snippets, tool outputs, errors, and current task state so work can seamlessly continue. Output only the summary."
@@ -1717,19 +1722,32 @@ func main() {
msgs = []Message{{Role: "system", Content: strp(sp)}}
autosave(msgs)
continue
case u == "/save":
sid, sm := saveSession(msgs)
case u == "/save" || strings.HasPrefix(u, "/save "):
name := strings.TrimSpace(strings.TrimPrefix(u, "/save"))
sid, sm := saveSession(msgs, name)
fmt.Println(c("[session saved: "+sid+"]", 32) + " " + c(sm, 2))
continue
case u == "/continue" || u == "/cont":
pid := projectID()
lm, err := loadSession(pid)
if err != nil {
fmt.Println(c("No session found for current project: "+err.Error(), 31))
continue
}
msgs = lm
autosave(msgs)
fmt.Println(c("[session continued: "+pid+"]", 32) + " " + c(summary(msgs), 2))
continue
case u == "/list":
ss := sessions()
if len(ss) == 0 {
fmt.Println(c("No sessions saved yet.", 33))
continue
}
pid := projectID()
for _, s := range ss {
mk := c(" (autosave)", 33)
if s.ID != "autosave" { mk = "" }
mk := ""
if s.ID == pid { mk = c(" (current project)", 33) }
fmt.Println(c(s.ID, 32) + mk + c(fmt.Sprintf(" %s [%d msgs]", s.Created, len(s.Messages)), 2))
fmt.Println(" " + c(s.Summary, 2))
}
@@ -1791,8 +1809,20 @@ func main() {
continue
case u == "/help":
fmt.Println(c("Bantam commands:", 1, 36))
for _, kv := range [][2]string{{"/quit", "exit"}, {"/clear", "reset to system prompt"}, {"/save", "save session"}, {"/list", "list sessions"}, {"/load <id>", "load session"}, {"/compact", "compact context"}, {"/cfg <k> [v]", "get/set config"}, {"!<cmd>", "run shell command directly"}, {"/models", "list models at endpoint"}, {"/help", "show help"}} {
fmt.Println(c(fmt.Sprintf(" %-15s", kv[0]), 1, 32) + kv[1])
for _, kv := range [][2]string{
{"/quit", "exit"},
{"/clear", "reset to system prompt"},
{"/save [name]", "save session (default: project MD5)"},
{"/continue", "continue project session (alias: /cont)"},
{"/list", "list sessions"},
{"/load <id>", "load session"},
{"/compact", "compact context"},
{"/cfg <k> [v]", "get/set config"},
{"!<cmd>", "run shell command directly"},
{"/models", "list models at endpoint"},
{"/help", "show help"},
} {
fmt.Println(c(fmt.Sprintf(" %-18s", kv[0]), 1, 32) + kv[1])
}
continue
}