v0.0.4: add sessions and refine tui
This commit is contained in:
+51
-4
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user