A safe, simple, extensible, and fast agent harness
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update the project README

+63 -21
+63 -21
README.md
··· 3 3 Ein is a Rust-based AI agent framework. A gRPC server drives an LLM agent loop and executes tools implemented as pluggable WASM modules. Multiple model backends are supported (OpenRouter, Anthropic, OpenAI, Ollama). A terminal UI client connects to the server and provides an interactive chat interface. Sessions are persisted to SQLite so conversations can be resumed across reconnects. 4 4 5 5 ``` 6 - ┌─────────────────────────┐ ┌──────────────────────────────┐ 7 - │ ein-tui │ gRPC │ ein-server │ 8 - │ │◄────────►│ │ 9 - │ Interactive chat UI │ │ LLM agent loop │ 10 - │ Connection retry │ │ WASM tool executor │ 11 - │ Slash command hints │ │ Pluggable model clients │ 12 - │ Animated thinking UI │ │ Per-session sandboxing │ 13 - │ │ │ SQLite session persistence │ 14 - └─────────────────────────┘ └──────────────────────────────┘ 6 + ┌─────────────────────────────┐ ┌──────────────────────────────┐ 7 + │ ein-tui │ gRPC │ ein-server │ 8 + │ │ (proto) │ │ 9 + │ Ratatui terminal UI │◄────────►│ Agent loop + tool executor │ 10 + │ Session picker on startup │ │ WASM plugin host │ 11 + │ Slash command autocomplete │ │ Pluggable model clients │ 12 + │ Animated thinking spinner │ │ Per-session sandboxing │ 13 + │ Syntax-highlighted diffs │ │ SQLite session persistence │ 14 + └─────────────────────────────┘ └──────────────────────────────┘ 15 15 ``` 16 16 17 17 ## Getting Started ··· 111 111 cargo run -p ein-tui 112 112 ``` 113 113 114 - On first launch a floating dialog asks whether to grant the agent access to your current working directory for that session. The TUI connects to `localhost:50051` by default. To connect to a different address: 114 + The TUI connects to `localhost:50051` by default. To connect to a different address: 115 115 116 116 ```bash 117 117 cargo run -p ein-tui -- http://my-server:50051 118 118 ``` 119 119 120 + To enable debug logging to `~/.ein/tui.log`: 121 + 122 + ```bash 123 + cargo run -p ein-tui -- --debug 124 + ``` 125 + 126 + On first connection a **session picker** modal appears. Use `↑`/`↓` to navigate, `Enter` to select: 127 + - **New Session** — starts a fresh conversation; a follow-up modal asks whether to grant the agent access to your current working directory for that session 128 + - **Existing session** — resumes a prior conversation from where it left off 129 + 120 130 ## Configuration 121 131 122 132 The TUI stores its configuration at `~/.ein/config.json`. The file is created with defaults on first run. ··· 145 155 | `allowed_paths` | Filesystem paths all WASM plugins may read/write (preopened for every session) | 146 156 | `allowed_hosts` | Hostnames all WASM plugins may connect to (empty = deny all; `"*"` = allow all) | 147 157 148 - In addition, at startup the TUI asks whether to add the current working directory to `allowed_paths` for that session only — this is never written back to `config.json`. 158 + When starting a new session, the TUI asks whether to add the current working directory to `allowed_paths` for that session only — this is never written back to `config.json`. 149 159 150 160 ### Per-plugin configuration (`plugin_configs`) 151 161 ··· 185 195 | Key | Action | 186 196 |-----|--------| 187 197 | `Enter` | Send message / run slash command | 188 - | `↑` / `↓` | Scroll conversation history | 198 + | `↑` / `↓` | Scroll conversation history (also navigate session picker) | 189 199 | `Ctrl-C` | Force quit | 190 200 | `/exit` + `Enter` | Exit the TUI | 201 + | `/config` + `Enter` | Open `~/.ein/config.json` in `$EDITOR` | 191 202 192 - While the agent is working, an animated indicator appears in the chat panel. Tool invocations are shown inline as the agent uses them: 203 + While the agent is working, an animated thinking spinner appears in the conversation pane. Tool invocations are shown inline as the agent uses them: 193 204 194 205 ``` 195 206 ▸ Bash ls -la ··· 198 209 ▸ Edit src/main.rs 199 210 ``` 200 211 201 - `Edit` calls display a syntax-highlighted diff showing the removed and added lines. 212 + `Edit` calls display a syntax-highlighted diff showing the removed and added lines (up to 5 each), with line numbers. 202 213 203 - The status bar at the bottom shows the active model and cumulative token usage for the session. 214 + The status bar at the bottom shows the active model and cumulative token usage on the left, and the current session UUID on the right. 204 215 205 216 ### Connection behaviour 206 217 207 - The TUI starts immediately regardless of whether the server is running. While disconnected, a red `●` icon and animated spinner appear in the conversation pane. The TUI reconnects automatically every 3 seconds. If the server goes away mid-session, an error message is shown and the TUI resumes connecting in the background. 218 + The TUI connects in the background immediately on startup. While disconnected, a red `●` icon and animated spinner appear in the conversation pane. The TUI reconnects automatically every 3 seconds. If the server goes away mid-session, an error message is shown and the TUI resumes connecting in the background — the session picker reappears on the next successful reconnect. 208 219 209 220 ## Tools 210 221 211 - Tools are WASM components loaded at startup. Three are included out of the box: 222 + Tools are WASM components loaded at startup. Four are included out of the box: 212 223 213 224 | Tool | Description | 214 225 |------|-------------| 215 - | `Bash` | Execute shell commands | 226 + | `Bash` | Execute shell commands (streams stdout in real time) | 216 227 | `Read` | Read a file from the filesystem | 217 228 | `Write` | Write content to a file | 218 229 | `Edit` | Replace a specific string in a file with new content | ··· 231 242 ein-server/ gRPC server — agent loop, WASM plugin host, session persistence 232 243 ein-tui/ Terminal UI client 233 244 packages/ 234 - ein_plugin/ WASM plugin interface (ToolPlugin trait, ToolDef, syscalls) 245 + ein_tool/ WASM tool plugin interface (ToolPlugin trait, ToolDef, syscalls) 235 246 ein_bash/ Bash tool plugin 236 247 ein_read/ Read tool plugin 237 248 ein_write/ Write tool plugin ··· 244 255 ein_ollama/ Ollama model client plugin 245 256 ``` 246 257 247 - The protocol (`crates/ein-proto/proto/ein.proto`) defines a bidirectional streaming RPC. Each session opens with a `SessionConfig` message (global sandbox constraints + per-plugin config map + optional `session_id` for resume), followed by `UserInput` prompt messages. The server streams back `AgentEvent` messages as the agent thinks, calls tools, and produces output — starting with a `SessionStarted` event carrying the session's UUID and whether it was resumed. A `config_update` message variant allows the TUI to push plugin config changes to a live session without reconnecting. 258 + ### Protocol 259 + 260 + The protocol (`crates/ein-proto/proto/ein.proto`) defines a bidirectional streaming RPC (`AgentSession`) and a unary `ListSessions` RPC. Each session opens with a `SessionConfig` message (global sandbox constraints + per-plugin config map + optional `session_id` for resume), followed by `UserInput` prompt messages. The server streams back `AgentEvent` messages as the agent thinks, calls tools, and produces output — starting with a `SessionStarted` event carrying the session's UUID, a `resumed` boolean, and the prior conversation history when resuming. A `config_update` message variant allows the TUI to push plugin config changes to a live session without reconnecting. 261 + 262 + `ListSessions` returns a list of `SessionSummary` records (newest-first), each containing the session ID, creation timestamp, a preview of the first user message, and the stored `SessionConfig` JSON needed to reconstruct the session on resume. 263 + 264 + ### Session persistence 248 265 249 - Sessions are persisted to `~/.ein/sessions.db`. Supplying a previously assigned `session_id` in `SessionConfig` causes the server to restore the conversation history and resume as if the session never disconnected. 266 + Sessions are persisted to `~/.ein/sessions.db`. Supplying a previously assigned `session_id` in `SessionConfig` causes the server to restore the full conversation history and resume as if the session never disconnected. 267 + 268 + ### TUI modules (`crates/ein-tui/src/`) 269 + 270 + | File | Role | 271 + |------|------| 272 + | `main.rs` | Entry point, CLI args, event loop, terminal lifecycle | 273 + | `app.rs` | `App` state struct, `DisplayMessage` variants, session picker / CWD modal state | 274 + | `config.rs` | `ClientConfig` — load, save, and migrate `~/.ein/config.json` | 275 + | `connection.rs` | `connection_manager` — background reconnect loop, `ListSessions` handshake, config file watcher | 276 + | `input.rs` | Slash command registry (`COMMANDS`), key event handler, server event handler | 277 + | `render.rs` | Full render pass — conversation pane, input area, autocomplete, session picker and CWD modals, status bar | 278 + 279 + Uses **Ratatui** (v0.29) for rendering and **crossterm** for keyboard events. The conversation pane renders a corgi pixel-art header on startup. Edit diffs are syntax-highlighted using `syntect` with the `base16-ocean.dark` theme. 280 + 281 + ### Server modules (`crates/ein-server/src/`) 282 + 283 + | File | Role | 284 + |------|------| 285 + | `main.rs` | CLI arg parsing, `EinConfig`, `HarnessState`, `ModelClientHarnessState` (HTTP host filtering), server startup | 286 + | `grpc.rs` | `AgentServer` — tonic `Agent` impl; `AgentSession` and `ListSessions` handlers; session persistence; `ConfigUpdate` mid-session | 287 + | `agent.rs` | `run_agent` — the LLM ↔ tool loop | 288 + | `model_client.rs` | `ModelClientSessionManager`, WASM model client compilation and instantiation | 289 + | `persistence.rs` | `SessionStore` — SQLite-backed session storage; create, save, and load message history | 290 + | `tools.rs` | `ToolRegistry` + `WasmTool` — loads and calls WASM plugins | 291 + | `syscalls.rs` | Host functions exposed to WASM tool plugins (spawn, log, …) | 250 292 251 293 ## License 252 294