package app import ( "bufio" "context" "fmt" "os" "strings" "agentu/internal/agent" "agentu/internal/session" "agentu/internal/skills" ) 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) fmt.Println("agentu") fmt.Println("Type /exit to quit, /clear to reset context, /compact to compress context, /btw for a side question.") for { fmt.Print("> ") if !scanner.Scan() { if err := scanner.Err(); err != nil { return err } fmt.Println() printExitSession(modelManager) return nil } input := strings.TrimSpace(scanner.Text()) fields := strings.Fields(input) switch input { case "": continue case "/exit", "/quit": printExitSession(modelManager) return nil case "/clear": assistant.Clear() fmt.Println("context cleared") continue case "/compact": if err := assistant.Compact(ctx); err != nil { fmt.Fprintln(os.Stderr, "compact error:", err) } else { fmt.Println("context compacted") if modelManager != nil { _ = modelManager.Save() } } continue } if len(fields) > 0 && fields[0] == "/btw" { question := strings.TrimSpace(strings.TrimPrefix(input, "/btw")) if question == "" { fmt.Fprintln(os.Stderr, "usage: /btw ") continue } fmt.Print("[btw] ") if err := assistant.BTW(ctx, question, os.Stdout); err != nil { fmt.Fprintln(os.Stderr, "\nbtw error:", err) } else { fmt.Println() } continue } if input == "/skills" || input == "/skills list" { items, err := skills.LoadGlobal() if err != nil { fmt.Fprintln(os.Stderr, "skills error:", err) } else { fmt.Println(skills.FormatList(items)) } continue } if len(fields) >= 3 && fields[0] == "/skills" && fields[1] == "install" { result, err := skills.InstallGlobal(ctx, strings.Join(fields[2:], " ")) if err != nil { fmt.Fprintln(os.Stderr, "skills error:", err) } else { assistant.AddSystemInstructions(skills.FormatForSystemPrompt([]skills.Skill{result.Skill})) fmt.Printf("installed skill %q; active in this conversation\n", result.Skill.Name) } continue } if err := assistant.RunTurn(ctx, input, os.Stdout, os.Stderr); err != nil { fmt.Fprintln(os.Stderr, "\nerror:", err) } _ = modelManager.Save() fmt.Println() } }