v0.0.4: add sessions and refine tui

This commit is contained in:
loveuer
2026-06-23 17:49:36 +08:00
parent 8dbcb1147f
commit e4c75c7c0e
12 changed files with 1333 additions and 110 deletions
+51 -4
View File
@@ -9,6 +9,7 @@ import (
"net/http"
"os"
"os/signal"
"path/filepath"
"strings"
"agentu/internal/agent"
@@ -31,6 +32,7 @@ func run() error {
yolo := flag.Bool("yolo", false, "also enable automatic file writes and shell execution")
plain := flag.Bool("plain", false, "use the simple line-based REPL instead of the TUI")
themeName := flag.String("theme", "light", "TUI theme: light or dark")
resumeID := flag.String("resume", "", "resume a specific session by ID")
flag.Parse()
themeMode, err := tui.ParseThemeMode(*themeName)
@@ -75,27 +77,52 @@ func run() error {
ToolRegistry: registry,
ToolTimeout: cfg.Agent.ToolTimeout,
})
modelManager, err := session.NewManager(cfg, assistant, http.DefaultClient)
// Initialize session store
home, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("resolve home dir: %w", err)
}
sessionsDir := filepath.Join(home, ".agentu", "sessions")
store, err := session.NewStore(sessionsDir)
if err != nil {
return fmt.Errorf("init session store: %w", err)
}
modelManager, err := session.NewManager(cfg, assistant, http.DefaultClient, store)
if err != nil {
return err
}
// Resume session
if *resumeID != "" {
if err := modelManager.Resume(*resumeID); err != nil {
return fmt.Errorf("resume session: %w", err)
}
} else {
if err := modelManager.ResumeLatest(); err != nil {
return fmt.Errorf("resume latest session: %w", err)
}
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
if !*plain {
return tui.Run(ctx, assistant, tui.Options{
err := tui.Run(ctx, assistant, tui.Options{
ModelName: providerConfig.Model,
Yolo: *yolo,
ThemeMode: themeMode,
ModelManager: modelManager,
})
printExitSession(modelManager)
return err
}
return repl(ctx, assistant)
return repl(ctx, assistant, modelManager)
}
func repl(ctx context.Context, assistant *agent.Agent) error {
func repl(ctx context.Context, assistant *agent.Agent, modelManager *session.Manager) error {
scanner := bufio.NewScanner(os.Stdin)
scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
@@ -108,6 +135,7 @@ func repl(ctx context.Context, assistant *agent.Agent) error {
return err
}
fmt.Println()
printExitSession(modelManager)
return nil
}
@@ -116,6 +144,7 @@ func repl(ctx context.Context, assistant *agent.Agent) error {
case "":
continue
case "/exit", "/quit":
printExitSession(modelManager)
return nil
case "/clear":
assistant.Clear()
@@ -126,6 +155,24 @@ func repl(ctx context.Context, assistant *agent.Agent) error {
if err := assistant.RunTurn(ctx, input, os.Stdout, os.Stderr); err != nil {
fmt.Fprintln(os.Stderr, "\nerror:", err)
}
_ = modelManager.Save()
fmt.Println()
}
}
func printExitSession(m *session.Manager) {
if m == nil {
return
}
_ = m.Save()
id := m.CurrentSessionID()
name := m.CurrentSessionName()
if id != "" {
if name != "" && name != id {
fmt.Fprintf(os.Stderr, "session: %s (%s)\n", id, name)
} else {
fmt.Fprintf(os.Stderr, "session: %s\n", id)
}
fmt.Fprintf(os.Stderr, "resume: agentu --resume %s\n", id)
}
}