evva

module
v0.1.0-alpha.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: MIT

README

EVVAgent (evva)

A ReAct coding agent in your terminal. Multi-provider LLM, parallel tool dispatch, async sub-agents, swappable UI.


What is EVVAgent?

evva_logo.png

evva runs a tool-using LLM agent in your terminal. It speaks Anthropic Claude, DeepSeek, OpenAI, and Ollama through one llm.Client interface; dispatches multiple tool calls per turn in parallel; tracks tasks and sub-agents through an observable store; and renders into a bubbletea TUI or a plain-text CLI sink.

The architecture is small on purpose — adding a new LLM provider, panel, or UI implementation is roughly one package each.


Install

git clone https://github.com/johnny1110/evva
cd evva
make install

Default install target is $GOBIN (or $GOPATH/bin when GOBIN is unset) — usually already on a Go developer's PATH. The make install output tells you whether to add it.

Override the location if you want it elsewhere:

sudo make install PREFIX=/usr/local/bin     # system-wide
make install PREFIX=$HOME/.local/bin        # user-local

Verify:

which evva
evva --help-ish    # any flag triggers the usage line

Uninstall removes only the binary; your ~/.evva/ config is preserved:

make uninstall

First run

Just type evva from any directory. On the first launch evva auto-creates:

~/.evva/
├── config/
│   └── evva-config.yml      # user-tunable settings (auto-created with defaults)
└── skills/                  # optional skill scripts (your own)

A one-line stderr notice fires the first time only:

evva: wrote new config to ~/.evva/config/evva-config.yml — fill in your API keys to use cloud providers.

~/.evva/.env is optional. If you want to override deployment knobs (LOG_LEVEL, LOG_DIR, APP_ENV, LOG_FORMAT, SKILLS_DIR, USER_PROFILE), create it; otherwise the built-in defaults apply.

Adding an API key

Two ways:

  1. From inside the TUI: type /config, navigate to <provider>.api_key, press Enter, paste your key, press Enter again. Saved immediately.
  2. By hand: open ~/.evva/config/evva-config.yml and fill in providers.<provider>.api_key.

Cloud providers (Anthropic, DeepSeek, OpenAI) need a key; Ollama is local and key-less.


User Guide

Full usage documentation covering the TUI interface, slash commands, keybindings, yank mode, the permission system, sub-agents, and all configuration options:


Configuration

~/.evva/config/evva-config.yml

User-tunable settings. Created automatically on first launch. Edit live via /config in the TUI, or by hand:

# Agent loop
max_iterations: 30
max_tokens: 4096
auto_compact_threshold: 0.8
display_thinking: true

# Default model used at startup (overwritten by /model swap)
default_provider: deepseek
default_model: deepseek-v4-pro

# Permission stance at startup. Cycle at runtime with Shift+Tab; -permission-mode CLI flag overrides.
permission_mode: default     # default | accept_edits | plan | bypass

# Web tooling
fetch_max_bytes: 100000
tavily_api_key: ""

# Per-provider credentials. Empty api_url falls back to the constant's default.
providers:
  anthropic: { api_key: "", api_url: "" }
  deepseek:  { api_key: "", api_url: "" }
  openai:    { api_key: "", api_url: "" }
  ollama:    { api_url: "" }
.env (optional)

Place in your working directory or at ~/.evva/.env. Only used for deployment / logging knobs — never user preferences:

APP_ENV=dev            # dev | prod
LOG_LEVEL=info         # debug | info | warn | error
LOG_FORMAT=text        # text | json
LOG_DIR=               # unset → $EVVA_HOME/logs (default); path → custom dir; explicit empty → stdout-only
SKILLS_DIR=skills      # subpath under ~/.evva/
USER_PROFILE=user_profile.md
CLI flags
evva                                # interactive TUI (when stdout is a TTY)
evva -temp 0.7                      # sampling temperature (default unset)
evva -max-tokens 2048               # per-completion output cap (overrides YAML)
evva -max-iters 40                  # loop iteration cap (overrides YAML)
evva -permission-mode=plan          # boot in plan mode (read-only; see "Permission modes")
evva -permission-mode=bypass        # boot with the gate disabled
evva -no-tui "explain loop.go"      # one-shot plain-text mode
echo "list files in /tmp" | evva -no-tui   # piped prompt

Features

Agent loop

  • ReAct-style: LLM call → parallel tool dispatch → tool results → repeat.
  • Multiple tool_use blocks per turn, executed concurrently.
  • Iteration cap surfaces as a pausable state.
  • Cancellable via ctx; Esc / Ctrl+C honored end-to-end.

LLM providers

  • Anthropic Claude (extended thinking + cryptographic signature round-trip).
  • DeepSeek (OpenAI-compatible chat, reasoning_content echoed back).
  • OpenAI.
  • Ollama (local).
  • Per-provider option pattern (WithTemperature, WithEffort, ...).

Tools

  • File system: read_file, write_file, edit_file — strict-absolute paths, structured *FileDiff metadata for diff rendering.
  • Shell: bash, grep, tree.
  • Tasks (six tools sharing one observable *task.Store).
  • Meta: agent (sub-agents), tool_search (lazy schema loading), skill, schedule_wakeup.
  • Plus stubs for web_*, cron_*, notebook_edit, monitor, mode, ux.

Sub-agents

  • explore (read-only) and general-purpose presets.
  • Sync mode (parent blocks) and async mode (parent continues, result lands on next iteration).
  • Two-layer hierarchy: sub-agents can't spawn sub-agents.

Observable store framework (internal/observable)

  • One pub/sub primitive any store can embed. Adding a new panel costs zero edits to the agent or event packages.

Swappable UI (internal/ui)

  • Narrow UI and Controller interfaces. Reference bubbletea TUI under internal/ui/bubbletea/. -no-tui falls back to a plain CLI sink.

Streaming completions (chunked text + thinking).

2-level compaction

  • micro: compress tool-result blocks when context budget approaches threshold.
  • full: summarize the whole session into a single assistant brief.

Project structure

evva/
├── cmd/evva/                  # CLI entry point — wires agent + UI
├── configs/                   # config loading (.env + YAML)
├── docs/                      # design notes, tool docs, system prompts
├── internal/
│   ├── agent/                 # agent loop, profiles, spawn
│   │   ├── event/             # event types + sink contract
│   │   └── sysprompt/         # system prompt builder
│   ├── constant/              # provider / model / status enums
│   ├── llm/                   # llm.Client interface + shared params
│   │   ├── claude/  deepseek/  ollama/
│   ├── llmfactory/            # provider factory keyed by constant
│   ├── logger/                # structured slog wrapper + pretty fmt
│   ├── observable/            # pub/sub framework for stores
│   ├── session/               # conversation history + cumulative usage
│   ├── tools/                 # tool interface (Name/Schema/Execute)
│   │   ├── cron/  dev/  fs/  meta/  mode/  monitor/  notebook/
│   │   ├── shell/ task/ ux/   web/
│   ├── toolset/               # tool catalog + ToolState registry
│   └── ui/                    # UI plugin contract
│       └── bubbletea/         # reference TUI implementation
├── log/                       # per-agent runtime logs (gitignored)
├── pkg/common/                # small shared utilities (UUID, ...)
└── scripts/                   # demo / dev scripts

Key boundaries:

  • agent knows about event.Sink, never about a concrete UI.
  • tools/* packages produce tools.Result (text + opaque Metadata); the UI type-asserts on Metadata to render structured payloads.
  • observable has no dependencies on agent or UI.
  • ui defines two narrow interfaces; implementations live under it.

Roadmap

Planned
  • Multimodal Read: images, PDFs (with pages range), Jupyter notebooks.
  • Overwrite diffs: proper Myers/Hunt-McIlroy diff for write_file overwrites.
  • Per-agent LLM: sub-agent can use a different provider than its parent.
  • Veronica space: long-running local sandbox service on :8080.
  • Web UI: a second UI implementation served over WebSocket.
  • Session persistence: /resume to reload a session snapshot.
Known limitations
  • Sub-agent hierarchy is exactly two layers (no nested spawning).
  • Token counts depend on provider reporting — Ollama only reports prompt / eval, not cache or reasoning splits.
  • The TUI transcript grows unbounded in a long session; compaction is on the list above.

License

See LICENSE.

Directories

Path Synopsis
cmd
evva command
internal
agent
Package profiles supplies preset agent.Profile constructors.
Package profiles supplies preset agent.Profile constructors.
agent/attachments
Package attachments computes per-turn <system-reminder>-wrapped messages the agent loop prepends to the user's incoming prompts.
Package attachments computes per-turn <system-reminder>-wrapped messages the agent loop prepends to the user's incoming prompts.
agent/event
Package event defines the event stream the agent emits while running.
Package event defines the event stream the agent emits while running.
agent/loader
Package loader reads user-authored agent definitions from <EVVA_HOME>/agents/{name}/ at startup and turns them into sysprompt.AgentDefinition values the agent.Registry can merge with Go-defined built-ins (sysprompt.MainAgent, ExploreAgent, GeneralAgent).
Package loader reads user-authored agent definitions from <EVVA_HOME>/agents/{name}/ at startup and turns them into sysprompt.AgentDefinition values the agent.Registry can merge with Go-defined built-ins (sysprompt.MainAgent, ExploreAgent, GeneralAgent).
agent/sysprompt
Package sysprompt builds the system prompt for each kind of agent evva runs.
Package sysprompt builds the system prompt for each kind of agent evva runs.
hooks
Package hooks implements evva's lifecycle extension system.
Package hooks implements evva's lifecycle extension system.
llm
llmfactory
Package llmfactory wires LLM provider constants to concrete provider clients.
Package llmfactory wires LLM provider constants to concrete provider clients.
memdir
Package memdir loads the two on-disk memory files that seed the agent's system prompt at session start:
Package memdir loads the two on-disk memory files that seed the agent's system prompt at session start:
observable
Package observable is the framework primitive that lets backing stores (task list, subagent panel, future "notes" / "todos" / ...) publish state changes through a single uniform stream.
Package observable is the framework primitive that lets backing stores (task list, subagent panel, future "notes" / "todos" / ...) publish state changes through a single uniform stream.
permission
Package permission implements evva's tool-permission system.
Package permission implements evva's tool-permission system.
question
Package question provides the back-channel between the AskUserQuestion tool (blocked agent goroutine) and the TUI (user interaction).
Package question provides the back-channel between the AskUserQuestion tool (blocked agent goroutine) and the TUI (user interaction).
tools/cron
Package cron hosts scheduling tools: CronCreate, CronList, CronDelete, RemoteTrigger.
Package cron hosts scheduling tools: CronCreate, CronList, CronDelete, RemoteTrigger.
tools/fs
Package fs exposes filesystem tools (Read, Write, Edit) as stateless singletons.
Package fs exposes filesystem tools (Read, Write, Edit) as stateless singletons.
tools/meta
Package meta hosts agent-meta tools: Agent (spawn sub-agent), ToolSearch (load deferred-tool schemas), and ScheduleWakeup (self-pace /loop iterations).
Package meta hosts agent-meta tools: Agent (spawn sub-agent), ToolSearch (load deferred-tool schemas), and ScheduleWakeup (self-pace /loop iterations).
tools/mode
Package mode hosts agent-mode and isolation tools: EnterPlanMode / ExitPlanMode (read-only planning) and EnterWorktree / ExitWorktree (filesystem-isolated worktrees).
Package mode hosts agent-mode and isolation tools: EnterPlanMode / ExitPlanMode (read-only planning) and EnterWorktree / ExitWorktree (filesystem-isolated worktrees).
tools/monitor
Package monitor hosts the deferred Monitor tool — a background process watcher that streams stdout lines as notifications.
Package monitor hosts the deferred Monitor tool — a background process watcher that streams stdout lines as notifications.
tools/notebook
Package notebook hosts the NotebookEdit tool.
Package notebook hosts the NotebookEdit tool.
tools/shell
Package shell hosts shell-side tools: Bash, Ls, Grep, Tree.
Package shell hosts shell-side tools: Bash, Ls, Grep, Tree.
tools/skill
Package skill implements user-installed Markdown skills and the SKILL tool that invokes them.
Package skill implements user-installed Markdown skills and the SKILL tool that invokes them.
tools/todo
Package todo exposes the single todo_write tool.
Package todo exposes the single todo_write tool.
tools/util
Package util hosts miscellaneous stateless utility tools.
Package util hosts miscellaneous stateless utility tools.
tools/ux
Package ux hosts user-interaction tools: AskUserQuestion, PushNotification.
Package ux hosts user-interaction tools: AskUserQuestion, PushNotification.
tools/web
Package web hosts web tools: web_search (Tavily-backed) and web_fetch (HTTP GET + readable-text extraction).
Package web hosts web tools: web_search (Tavily-backed) and web_fetch (HTTP GET + readable-text extraction).
toolset
Package toolset is the catalog of every tool the agent can construct.
Package toolset is the catalog of every tool the agent can construct.
ui
Package ui defines the contract between evva's core agent and any UI implementation that drives it.
Package ui defines the contract between evva's core agent and any UI implementation that drives it.
ui/bubbletea
Package bubbletea is the reference TUI implementation of internal/ui.UI.
Package bubbletea is the reference TUI implementation of internal/ui.UI.
ui/bubbletea_v2
Package bubbleteav2 is the in-progress clean-architecture rewrite of internal/ui/bubbletea.
Package bubbleteav2 is the in-progress clean-architecture rewrite of internal/ui/bubbletea.
ui/bubbletea_v2/app
Package app is the v2 TUI's top-level tea.Model.
Package app is the v2 TUI's top-level tea.Model.
ui/bubbletea_v2/components/agents
Package agents renders the horizontal subagent chip strip that sits just above the input.
Package agents renders the horizontal subagent chip strip that sits just above the input.
ui/bubbletea_v2/components/diff
Package diff renders a *fs.FileDiff (the structured metadata write_file / edit_file attach to tools.Result) as a multi-line git-style string with a gutter / content split.
Package diff renders a *fs.FileDiff (the structured metadata write_file / edit_file attach to tools.Result) as a multi-line git-style string with a gutter / content split.
ui/bubbletea_v2/components/input
Package input owns the v2 TUI's bottom textarea: prompt composition, paste compaction, and history navigation.
Package input owns the v2 TUI's bottom textarea: prompt composition, paste compaction, and history navigation.
ui/bubbletea_v2/components/overlays
Package overlays implements the modal panels the App pushes onto its focus stack: /config (form), /model (picker), /compact (chooser).
Package overlays implements the modal panels the App pushes onto its focus stack: /config (form), /model (picker), /compact (chooser).
ui/bubbletea_v2/components/slash
Package slash renders the autocomplete suggestion panel that pops up when the user types "/" at the start of the input.
Package slash renders the autocomplete suggestion panel that pops up when the user types "/" at the start of the input.
ui/bubbletea_v2/components/status
Package status owns the v2 TUI's bottom HUD: the run-state pill, model + token cells, context-utilization meter, and the contextual hint line that sits above it.
Package status owns the v2 TUI's bottom HUD: the run-state pill, model + token cells, context-utilization meter, and the contextual hint line that sits above it.
ui/bubbletea_v2/components/todos
Package todos renders the bottom todo panel and the green "TODOS COMPLETE" snapshot folded into the transcript when every todo in the store finishes.
Package todos renders the bottom todo panel and the green "TODOS COMPLETE" snapshot folded into the transcript when every todo in the store finishes.
ui/bubbletea_v2/components/transcript
Package transcript owns the scrollback model of the v2 TUI.
Package transcript owns the scrollback model of the v2 TUI.
ui/bubbletea_v2/events
Package events declares the tea.Msg types the v2 TUI passes through its Update loop.
Package events declares the tea.Msg types the v2 TUI passes through its Update loop.
ui/bubbletea_v2/mouse
Package mouse owns mouse-capture wiring + clipboard integration.
Package mouse owns mouse-capture wiring + clipboard integration.
ui/bubbletea_v2/theme
Package theme owns every styled surface in the v2 TUI.
Package theme owns every styled surface in the v2 TUI.
pkg
banner
Package banner exposes the evva splash banner.
Package banner exposes the evva splash banner.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL