A minimal, modern C++23 agentic CLI runner. A faithful port of eunice (Rust), stripped to its essential features.
Sophisticated simplicity. One binary, zero config files, smart defaults.
- 4 providers: Gemini, Anthropic, OpenAI, Ollama
- Model aliases:
flash,sonnet,opus,haiku,pro - 6 built-in tools: bash, read, write, image_analyze, web_search, get_output
- Streaming: Real-time SSE streaming for Gemini
- Image understanding: Vision analysis via any supported provider
- Web search: Gemini grounded search with source attributions
- Context compaction: Automatic 3-phase compaction when context window fills
- Output truncation: Large tool outputs truncated with on-demand retrieval
# Set at least one API key
export GEMINI_API_KEY="..."
# or
export ANTHROPIC_API_KEY="..."
# or
export OPENAI_API_KEY="..."
# Build and install
make install # installs to ~/local/bin/eunice.cpp
# Run
eunice.cpp "explain what this project does"# Single-shot with default model (picks best available)
eunice.cpp "write a fizzbuzz in python"
# Choose a specific model
eunice.cpp -m sonnet "refactor this function for clarity"
eunice.cpp -m flash "summarize this file"
# Interactive chat mode
eunice.cpp --chat
eunice.cpp -m opus --chat
# Auto-enters chat when no prompt given
eunice.cpp
# Pipe input
cat error.log | eunice.cpp "explain this error"
git diff | eunice.cpp "review this diff"
# Image analysis (LLM decides when to use the tool)
eunice.cpp -m flash "read the text in screenshot.png and summarize it"
eunice.cpp -m haiku --model-image flash "describe what you see in diagram.jpg"
# Web search (Gemini models search autonomously)
eunice.cpp -m flash "what are the latest changes in C++26?"
# List available models across all providers
eunice.cpp --list-models
# List built-in tools
eunice.cpp --list-tools
# Use a system prompt file
eunice.cpp -p system_prompt.md "do the thing"
# Verbose/debug logging
eunice.cpp -v "hello"In interactive chat mode (--chat):
- Type your message and press Enter
/clear— reset conversation history/exit,/quit,exit,quit— quitCtrl+D— quit
eunice.cpp [OPTIONS] [PROMPT...]
Positionals:
prompt TEXT ... Prompt text (enters chat if omitted on TTY)
Options:
-m, --model TEXT Model name or alias
--model-image TEXT Override model for image understanding
-p, --system-prompt TEXT System prompt from file
--chat Force interactive chat mode
-v, -d, --verbose, --debug Enable verbose logging
--list-models List available models and exit
--list-tools List built-in tools and exit
-h, --help Print help
-V, --version Print version
| Alias | Resolves To |
|---|---|
flash |
gemini-3-flash-preview |
pro |
gemini-3.1-pro-preview |
sonnet |
claude-sonnet-4-20250514 |
opus |
claude-opus-4-5-20251101 |
haiku |
claude-haiku-4-5-20251001 |
| Tool | Description |
|---|---|
bash |
Execute shell commands with timeout |
read |
Read file contents (detects binary) |
write |
Write content to files (auto-creates dirs) |
image_analyze |
Analyze images with a vision-capable model |
web_search |
Search the web via Gemini grounded search |
get_output |
Retrieve sections of truncated tool output |
Requires Bazel and a C++ compiler with C++23 support.
make # show help
make build # debug build
make release # optimized build
make test # run all 18 test suites
make install # install to ~/local/bin/eunice.cpp
make binary-size # show release binary sizesrc/
├── main.cc # CLI entry point
├── agent/ # Agent loop, chat REPL, context compaction, output store
├── provider/ # Provider detection, HTTP client, format adapters
│ ├── gemini.cc # Gemini native API + streaming
│ ├── anthropic.cc # Anthropic Messages API
│ └── openai.cc # OpenAI / Ollama (compatible)
├── tools/ # Tool interface + 5 built-in tools
├── models/ # Data types (header-only)
├── display/ # Terminal output (spinner, colors, streaming)
└── util/ # HTTP, base64, JSON helpers
MIT