Interactive Mode (REPL)

Interactive mode is the default when you run yoyo in a terminal. It gives you a read-eval-print loop where you can have a multi-turn conversation with the agent.

Starting

yoyo
# or
cargo run

The prompt

The prompt shows your current git branch (if you're in a git repo):

main πŸ™ β€Ί _

If you're not in a git repo, you get a plain prompt:

πŸ™ β€Ί _

Line editing & history

yoyo uses rustyline for a full readline experience:

  • Arrow keys: Navigate within the current line (← β†’) and through command history (↑ ↓)
  • Inline hints: As you type a slash command, a dimmed suggestion appears after the cursor showing the completion and a short description β€” e.g. typing /he shows lp β€” Show help for commands. Press Tab or β†’ to accept.
  • Tab completion: Type / and press Tab to see available slash commands with descriptions β€” each command is shown alongside a short summary of what it does. Partial matches work too β€” /he<Tab> suggests /help and /health. After typing a command + space, argument-aware completions kick in:
    • /model <Tab> β€” suggests known model names (Claude, GPT, Gemini, etc.)
    • /provider <Tab> β€” suggests known provider names (anthropic, openai, google, etc.)
    • /think <Tab> β€” suggests thinking levels (off, minimal, low, medium, high)
    • /git <Tab> β€” suggests git subcommands (status, log, add, diff, branch, stash)
    • /pr <Tab> β€” suggests PR subcommands (list, view, diff, comment, create, checkout)
    • /save <Tab> and /load <Tab> β€” suggest .json session files in the current directory
    • File paths also complete β€” type src/ma<Tab> to get src/main.rs, or Cargo<Tab> to get Cargo.toml. Directories complete with a trailing / for easy continued navigation.
  • History recall: Previous inputs are saved across sessions
  • Keyboard shortcuts: Ctrl-A (start of line), Ctrl-E (end of line), Ctrl-K (kill to end), Ctrl-W (delete word back)
  • History file: Stored at $XDG_DATA_HOME/yoyo/history (defaults to ~/.local/share/yoyo/history)

How it works

  1. You type a message
  2. yoyo sends it to the LLM along with conversation history
  3. The LLM may call tools (read files, run commands, etc.)
  4. Tool results are streamed back β€” you see each tool as it executes
  5. The final text response is printed
  6. Token usage and cost are shown after each turn

Auto-continue

If the model stops mid-work (e.g., it says "Next, I'll fix the tests..." but stops), yoyo automatically sends a follow-up prompt to continue. You'll see:

  ⚑ auto-continuing (1/3 β€” response appears incomplete)...

This happens up to 3 times per user turn. Auto-continue won't fire if:

  • The model encountered an error
  • The session budget is exhausted
  • The response doesn't show clear signs of being incomplete

Shell passthrough

Prefix a line with ! to run a shell command directly β€” no API call, no tokens, no confirmation prompt:

πŸ™ β€Ί !git status
πŸ™ β€Ί !ls -la src/

Output streams live to your terminal (via sh -c on Unix, cmd /C on Windows), and the exit code is shown only when non-zero. A bare ! prints a usage hint.

!? β€” ask about the last command's output

! commands never enter the conversation, but sometimes you want yoyo to look at what just happened. Type !? to feed the last ! command β€” its command line, exit code, and output tail (last ~200 lines / 8KB, captured as a tee while it streamed) β€” into the conversation:

πŸ™ β€Ί !cargo test
   ... (output streams live) ...
   exit 101
   command failed (exit 101) β€” type !? to ask yoyo about the output
πŸ™ β€Ί !? why did the second test fail
  • Bare !? uses a default question: after a failure, "explain what went wrong and how to fix it"; after a success, "summarize this output".
  • !? <question> asks your own question about the output.
  • Works after successful commands too (the failure hint just doesn't appear).
  • If no ! command has run yet, !? prints a one-liner and does nothing.
  • The capture is non-consuming β€” you can ask !? follow-ups about the same output more than once.

This is fully opt-in: nothing enters the conversation (and no tokens are spent) unless you type !?.

Tool output

When yoyo uses tools, you'll see status indicators:

  β–Ά $ cargo test βœ“ (2.1s)
  β–Ά read src/main.rs βœ“ (42ms)
  β–Ά edit src/lib.rs βœ“ (15ms)
  β–Ά $ cargo test βœ— (1.8s)
  • βœ“ means the tool succeeded
  • βœ— means the tool returned an error
  • The duration shows how long the tool took

Token usage

After each response, you'll see a compact token summary:

  ↳ 3.2s Β· 1523β†’842 tokens Β· $0.0234

Use --verbose (or -v) for the full breakdown including session totals and cache info.

This shows:

  • Wall-clock time for the response
  • Inputβ†’output tokens for this turn
  • Estimated cost for this turn

Interrupting

Press Ctrl+C to cancel the current response. The agent will stop and you can type a new prompt. Press Ctrl+C again to exit.

Completion notifications

When a prompt takes more than a few seconds, yoyo rings the terminal bell so you notice the finish even if you switched windows (disable with no_bell = true or --no-bell).

For an actionable desktop alert, set the opt-in notify_command config key β€” a shell command yoyo runs (fire-and-forget) whenever a long prompt finishes, at the same threshold as the bell:

# .yoyo.toml β€” Linux
notify_command = "notify-send 'yoyo' 'done'"

# macOS
notify_command = "osascript -e 'display notification \"done\" with title \"yoyo\"'"

Or set it from inside the REPL:

/config set notify_command notify-send 'yoyo' 'done'

Details:

  • Opt-in and inert by default β€” when the key is absent (or empty), nothing is spawned and no tools are probed.
  • Runs via sh -c on Unix and cmd /C on Windows, fully detached: yoyo never waits on it and its output is discarded, so it can never block the REPL.
  • The command receives two environment variables so one script can serve multiple purposes: YOYO_EVENT=prompt_completed and YOYO_ELAPSED_SECS=<seconds>.
  • If the command fails to spawn, yoyo stays silent by default (one-line warning with --verbose).
  • Setting it to an empty string clears it: /config set notify_command "".

Inline @file mentions

You can reference files directly in your prompts using @path syntax. The file content is automatically read and injected into the conversation β€” no need for a separate /add command.

> explain @src/main.rs
  βœ“ added src/main.rs (250 lines)
  (1 file inlined from @mentions)

> refactor @src/cli.rs:50-100
  βœ“ added src/cli.rs (lines 50-100) (51 lines)
  (1 file inlined from @mentions)

> compare @Cargo.toml and @README.md
  βœ“ added Cargo.toml (35 lines)
  βœ“ added README.md (120 lines)
  (2 files inlined from @mentions)

How it works:

  • @path β€” injects the entire file
  • @path:start-end β€” injects a specific line range
  • If the path doesn't exist, the @mention is left as-is (it might be a username)
  • Email-like patterns (user@example.com) are not treated as file mentions
  • Images work too: @screenshot.png inlines the image into the conversation