From dd5701b1bb75d3eab64063becb137793e8d0f4db Mon Sep 17 00:00:00 2001 From: Ollie Agent Date: Thu, 30 Jul 2026 20:02:14 +0200 Subject: [PATCH] readme: bring up to date after Great Flattening MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Frame olliesrv as single binary with two surfaces (9P + D-Bus) - Fix repository layout table: no core/, 9p/, remote/ submodules - Fix all namespace paths: session/{id}/agent/{aid}/ - Fix architecture diagram labels (agent.Agent, toolsrv.Server) - Fix httpgw description (HTTP→9P, not D-Bus) - Replace verbose features list with concise capability table - Remove outdated development/pull.sh sections --- README.md | 363 ++++++++++++++++++------------------------------------ 1 file changed, 119 insertions(+), 244 deletions(-) diff --git a/README.md b/README.md index c5dbe04..d3393f9 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,22 @@ # ollie -Ollie is an AI agent runtime. A small Go core handles the agent loop, tool dispatch, sandboxing, and multi-backend routing; frontends (terminal, acme, Emacs, KDE, browser) and orchestration (shell scripts, multi-agent workflows, cron) are external. The core is deliberately minimal — capabilities come from composing small pieces rather than building a monolithic framework. +Ollie is an AI agent runtime. A single binary (`olliesrv`) exposes agent sessions +over two surfaces: a **9P2000 filesystem** (the canonical interface) and a +**D-Bus service** (`org.ollie.SessionManager`). Both are thin adapters over the +same core — the agent loop, tool dispatch, sandboxing, and multi-backend routing. +Choice of surface is per-deployment: 9P for its Unix composability, D-Bus for +desktop integration, or both. + +The core is deliberately minimal. Capabilities come from composing small pieces — +shell scripts, tool scripts, skill files — rather than building a monolithic +framework. ## Getting started -Clone with submodules: - ```sh git clone --recurse-submodules https://git.lneely.de/lkn/ollie.git -``` - -Or after cloning: - -```sh -git submodule update --init --recursive -``` - -Build and install: - -```sh -just # builds core, 9p, acme, kde, httpgw, webui, emacs +cd ollie +just ``` Requires [just](https://github.com/casey/just): @@ -43,144 +40,44 @@ OLLIE_ANTHROPIC_KEY=sk-ant-... OLLIE_COPILOT_TOKEN=... OLLIE_KIRO_TOKEN=... # bearer token or sqlite:// path (auto-detected from Kiro CLI if unset) OLLIE_MODEL=qwen/qwen3-235b-a22b -OLLIE_TOOLS_PATH=~/.config/ollie/tools # directory for tool scripts ({tool} steps) -OLLIE_MEMORY_PATH=~/.config/ollie/memory # directory for memory files (ollie/m) -OLLIE_ELEVATE_SOCKET=${XDG_RUNTIME_DIR}/ollie/elevate.sock # socket path for x/elevate adapter -OLLIE_COMPLETE_BACKEND=ollama # backend for u/complete (required) -OLLIE_COMPLETE_MODEL=qwen3:latest # model for u/complete (required) +OLLIE_TOOLS_PATH=~/.config/ollie/tools # directory for tool scripts +OLLIE_MEMORY_PATH=~/.config/ollie/memory # directory for memory files +OLLIE_ELEVATE_SOCKET=${XDG_RUNTIME_DIR}/ollie/elevate.sock +OLLIE_COMPLETE_BACKEND=ollama # backend for u/complete +OLLIE_COMPLETE_MODEL=qwen3:latest # model for u/complete OLLIE_ENABLED_BACKENDS=openrouter,kiro # backends available for routing (comma-separated) - -# /route file configuration -OLLIE_ROUTE_BACKEND=ollama # backend for the classifier model -OLLIE_ROUTE_MODEL=qwen3:8b # model that classifies task complexity +OLLIE_ROUTE_BACKEND=ollama # backend for the /route classifier +OLLIE_ROUTE_MODEL=qwen3:8b # model for task routing ``` Shell environment variables take precedence over the env file. -## Development - -Pull latest across all submodules: - -```sh -./pull.sh -``` - -Run tests: - -```sh -just test -``` - ## Repository layout -Monorepo with Git submodules. Each submodule has its own Go module (except `el` which is Elisp and `kde` which is C++/Qt). +Single Go module with two Git submodules for frontends. | Directory | Language | Description | |-----------|----------|-------------| -| [core/](core/) | Go | Core library: agent loop, backends, tools, config, sandbox | -| [9p/](9p/) | Go | 9P filesystem server (`olliesrv`) | -| [remote/](remote/) | Go | Remote execution server (`ollie-remote`) for split-brain SSH mode | -| [acme/](acme/) | Go | Plan 9 acme editor frontend | -| [httpgw/](httpgw/) | Go | HTTP-to-D-Bus gateway (`ollie-httpgw`) | -| [webui/](webui/) | TypeScript | Preact SPA browser frontend | -| [kde/](kde/) | C++/Qt6 | KDE integration: plasmoid, standalone GUI, Kate plugin, KRunner, tray | -| [el/](el/) | Elisp | Emacs frontend (`ellie.el`) | -| [agents/](agents/) | JSON | Agent config files (loaded at runtime) | -| [prompts/](prompts/) | Markdown | System prompt templates | -| [tools/](tools/) | Python/Bash | Tool scripts (file_read, lsp_*, memory_*, etc.) | -| [scripts/](scripts/) | Shell | User-facing CLI scripts: session management, utilities, plumbing | -| [sandbox/](sandbox/) | YAML | Landlock sandbox config | -| [doc/](doc/) | Markdown | Architecture docs, usage guide | -| [contrib/](contrib/) | Mixed | Community scripts | -| [experiments/](experiments/) | Mixed | Trial notes | - -## Features - -### Sessions - -- **Create / kill / rename / list** — full lifecycle management of concurrent agent sessions -- **Prompt submission with FIFO queue** — prompts are queued and processed in order; multiple clients can submit without conflicts -- **State observation** — each session exposes its current state (`idle`, `thinking`, `calling: `) with a blocking-wait primitive for efficient polling -- **Chat streaming** — stream model output in real time via file tail or D-Bus signal -- **Session persistence** — active sessions survive server restarts; state is checkpointed to `~/.local/share/ollie/sessions/` -- **Plan / scratchpad** — per-session markdown checklist that survives context compaction and is visible to peer agents -- **Environment inspection** — read the effective environment variables for any session - -### Agent loop - -- **Streaming tool calls** — the core runs a turn loop: prompt the model, parse tool calls, dispatch them (in parallel where safe), feed results back, repeat until done -- **Automatic context compaction** — long conversations are summarized transparently when approaching the context limit -- **System prompt templating** — prompts are rendered from markdown templates with variable substitution; inspect the fully rendered prompt at any time - -### Backends - -- **Multi-backend routing** — Ollama (local), OpenAI-compatible, Anthropic, GitHub Copilot, Kiro; switch backends per-session -- **Model listing and switching** — enumerate available models from any backend; switch models mid-session -- **Connection pooling** — all sessions sharing the same API host multiplex over a single HTTP/2 connection; no redundant TLS handshakes -- **24-hour model cache** — model lists are cached at the backend level to avoid repeated API calls - -### Tools and sandboxing - -- **Sandboxed execution** — every tool call and every `shell` command runs inside a Landlock sandbox with per-profile filesystem access rules. Promoted tools are not exempt — they execute through the same sandbox path as inline shell commands. -- **Extensible tools** — tools are executable scripts with header metadata; add one by dropping a file in a directory -- **Dynamic tool registry** — tools are discoverable and hot-reloadable; add, modify, or remove tool scripts at any time without restarting the server. Only loaded tools are callable. Write a tool name to `s/{sid}/tools` to promote it to a native callable function — no MCP server, no SDK, no protocol boilerplate -- **Elevation** — commands that need to escape the sandbox can request elevation through a streaming protocol (frame-based, over unix socket) - -### Agents - -- **Agent definitions** — JSON configs that set personality, tools, backend preferences, and constraints -- **List and switch** — enumerate available agents and assign one to any session - -### Multi-agent - -- **Peer communication** — bidirectional links between sessions; peers can submit prompts to each other -- **Orchestrator/worker patterns** — subagent delegation, parallel fan-out, coordinated through session primitives -- **Domain skills** — teach the agent your project’s conventions with a markdown file; loaded on demand - -### Background processes - -- **Detach** — start a long-running command and immediately background it; the agent continues working -- **Monitor** — list running processes, read their output (64KB ring buffer), check status -- **Signal and dismiss** — send TERM/KILL to a detached process; remove finished processes from the list - -### Remote execution (split-brain) - -- **Local brain, remote hands** — the agent loop and LLM streaming stay local; tool execution happens on a remote host over SSH -- **Zero-setup deployment** — `ollie-remote` is bootstrapped automatically on first connect (binary + tools cached by hash) -- **Streaming output** — real-time command output over the SSH channel; builds and tests display as they run -- **Session persistence** — remote sessions survive server restarts; reconnect automatically on restore -- **Sandboxed remotely** — Landlock enforcement runs on the remote host; `landrun` is shipped alongside the binary -- **Convention over configuration** — sensible sandbox defaults; per-project overrides via `.ollie-sandbox.yaml` in the project root -- **GUI works unchanged** — D-Bus signals fire locally, so KDE GUI / web UI see real-time progress - -The split-brain model complements 9P's network transparency. 9P mounts a remote agent as a local filesystem (remote brain, local view); split-brain keeps the brain local and sends execution remote (local brain, remote hands). Use 9P for monitoring fleets of headless agents; use split-brain for interactive development on remote hosts. - -``` -9P remote mount: you ──9P──▶ remote olliesrv ──▶ remote tools -Split-brain: local olliesrv ──SSH──▶ remote ollie-remote ──▶ remote tools -``` - -See [doc/REMOTE_EXECUTION.md](doc/REMOTE_EXECUTION.md) for the design. - -### Stateless endpoints - -- **Code completion** — write cursor context (prefix, suffix, file path), read back code to insert; works from any editor or script -- **One-shot generation** — write a prompt, read back a full LLM response; no session, no agent loop, no tools; scriptable from any language -- **Task routing** — write a task description, the system classifies complexity against all available models and returns the best backend+model for the job - -### Frontends - -- **Terminal** — interactive CLI (`b`, `bfg`, `sh`) -- **Plan 9 acme** — editor integration for acme -- **Emacs** — `ellie.el` package -- **KDE** — plasmoid, standalone GUI, Kate plugin, KRunner, system tray -- **Web UI** — Preact SPA served by the HTTP gateway - -### Configuration - -- **Per-session config** — backend, model, agent, generation parameters; all readable and writable at runtime - ---- +| `agent/` | Go | Agent loop, history, hooks, prompt resolution, commands | +| `backend/` | Go | LLM providers (Anthropic, OpenAI, Ollama, Gemini, Copilot, CodeWhisperer) | +| `toolsrv/` | Go | Tool server, registry, sandboxed execution, remote execution | +| `session/` | Go | Session lifecycle, config, persistence | +| `fs/session/` | Go | 9P filesystem tree for session namespace | +| `dbus/` | Go | D-Bus adapter (`org.ollie.SessionManager`) | +| `detach/` | Go | Background process management | +| `elevate/` | Go | Elevation broker (privilege escalation) | +| `sandbox/` | Go | Landlock sandbox config | +| `cmd/olliesrv/` | Go | The main binary | +| `cmd/ollie-9p/` | Go | 9P client | +| `cmd/ollie-httpgw/` | Go | HTTP-to-9P gateway | +| `cmd/ollie-remote/` | Go | Remote execution binary | +| `kde/` | C++/Qt6 | KDE plasmoid, GUI, Kate plugin, KRunner, tray *(submodule)* | +| `webui/` | TypeScript | Preact SPA browser frontend *(submodule)* | +| `agents/` | JSON | Agent configs | +| `prompts/` | Markdown | System prompt templates | +| `tools/` | Python/Bash | Tool scripts (file_read, lsp_*, memory_*, etc.) | +| `scripts/` | Shell | Session management, utilities, plumbing | +| `doc/` | Markdown | Architecture docs, usage guide | ## Architecture @@ -195,12 +92,12 @@ graph TB end subgraph "olliesrv" - 9P[9P Filesystem] - DBUS[D-Bus Adapter] + P9[9P Filesystem
session/ namespace] + DBUS[D-Bus Adapter
org.ollie.SessionManager] SM[Session Manager] - CORE[Core Library
agent loop · compaction
prompt templates] + AG[agent.Agent
loop · compaction
prompt templates] ROUTE[Router
complete · generate · route] - TOOLS[Tool Registry
dynamic · lazy-load · dispatch] + TOOLS[toolsrv.Server
dynamic registry · dispatch] SB[Landlock Sandbox] end @@ -213,74 +110,59 @@ graph TB end subgraph Execution - LOCAL[Local Tools
file_read · lsp_* · shell
memory_* · gui_*] + LOCAL[Tool Scripts
file_* · lsp_* · memory_*
gui_* · subagent_*] REMOTE[ollie-remote
via SSH] RTOOL[Remote Tools] end - HTTPGW[ollie-httpgw
HTTP→D-Bus gateway] + HTTPGW[ollie-httpgw
HTTP→9P gateway] - %% Frontend connections - TER & ACME & EMACS -->|9P| 9P + TER & ACME & EMACS -->|9P| P9 KDE -->|D-Bus| DBUS - WEB --> HTTPGW --> DBUS + WEB --> HTTPGW --> P9 - %% Internal layers - 9P --> SM + P9 --> SM DBUS --> SM - SM --> CORE - CORE --> ROUTE - CORE --> TOOLS + SM --> AG + AG --> ROUTE + AG --> TOOLS TOOLS --> SB - %% Backend connections - CORE -->|streaming| OLL & OAI & ANT & COP & KIRO + AG -->|streaming| OLL & OAI & ANT & COP & KIRO - %% Tool execution SB --> LOCAL SB -->|SSH| REMOTE --> RTOOL ``` -`olliesrv` is a single binary that operates in three modes: +`olliesrv` is a single binary. Which surface it exposes is a flag: | Mode | Flags | Interface | Frontends | -|------|-------|-----------|----------| -| +9p +dbus | (default) | 9P filesystem + D-Bus signals | All (terminal, acme, Emacs, KDE, web) | +|------|-------|-----------|-----------| +| +9p +dbus | (default) | 9P filesystem + D-Bus signals | All | | +9p -dbus | `-nodbus` | 9P filesystem only | Terminal, acme, Emacs, web | | -9p +dbus | `-no9p` | D-Bus only | KDE (plasmoid, GUI, Kate, KRunner, tray) | -All modes embed the same core library and session manager. The 9P and D-Bus interfaces are thin adapters over the shared session pool. - ---- - ## 9P: everything is a file -The 9P server exposes the agent runtime as a synthetic filesystem. Every session is a directory; every operation is a read or write. In default mode, it also embeds a D-Bus adapter on `org.ollie.SessionManager` that streams `StateChanged`, `ChatUpdated`, and lifecycle signals to desktop clients. - -There is no client library, no SDK, no protocol buffer — `echo`, `cat`, `tail`, and `rm` are the API. +The 9P server exposes the agent runtime as a synthetic filesystem. Every session +is a directory; every operation is a read or write. There is no client library, +no SDK, no protocol buffer — `echo`, `cat`, `tail`, and `rm` are the API. ```sh # Create a session echo "name=worker" > /mnt/ollie/session/new # Submit a prompt -echo "fix the bug in main.go" > /mnt/ollie/session/worker/prompt +echo "fix the bug in main.go" > /mnt/ollie/session/worker/agent/0/prompt # Stream the response -tail -f /mnt/ollie/session/worker/chat +tail -f /mnt/ollie/session/worker/agent/0/chat # Check state -cat /mnt/ollie/session/worker/state - -# Kill a background process -echo "signal 12345 TERM" > /mnt/ollie/session/worker/ctl - -# Get completions -echo '{"language":"go","code":"func he"}' > /mnt/ollie/session/worker/complete -cat /mnt/ollie/session/worker/complete +cat /mnt/ollie/session/worker/agent/0/state # One-shot generation (no session needed) -exec 3<>/mnt/ollie/generate; echo 'explain monads in one sentence' >&3; cat <&3; exec 3>&- +exec 3<>/mnt/ollie/generate; echo 'explain monads' >&3; cat <&3; exec 3>&- # Route a task to the best model exec 3<>/mnt/ollie/route; echo 'redesign the auth system' >&3; cat <&3; exec 3>&- @@ -289,66 +171,52 @@ exec 3<>/mnt/ollie/route; echo 'redesign the auth system' >&3; cat <&3; exec 3>& ### Network transparency -9P is a network protocol. Mount the agent filesystem from any machine on the network: +9P is a network protocol. Mount the agent from any machine: ```sh 9pfuse 'tcp!server:5640' /mnt/ollie ``` -No SSH tunneling, no port forwarding for individual endpoints, no API gateway. One mount and every session, every tool, every config value is accessible as if local. - -### Container and headless deployment - -The 9P server embeds the core library directly — no display server, no desktop dependencies. It runs anywhere a Go binary runs: containers, cloud VMs, CI runners, embedded systems. - -The embedded D-Bus adapter is automatically disabled when using `-tcp` (remote listen mode). You can also disable it explicitly with `-nodbus`: - -```sh -olliesrv -tcp :5640 # TCP listener, no D-Bus (implied) -olliesrv -nodbus # Unix socket only, no D-Bus -``` +No SSH tunneling, no port forwarding, no API gateway. One mount and every +session, every tool, every config value is accessible as if local. ### Shell composability -Because operations are file I/O, they compose with the entire Unix toolkit: +Because operations are file I/O, they compose with the full Unix toolkit: ```sh -# Fan out a prompt to all sessions -for s in /mnt/ollie/session/*/prompt; do echo "run tests" > "$s"; done +# Fan out a prompt to all agents +for s in /mnt/ollie/session/*/agent/*/prompt; do echo "run tests" > "$s"; done # Wait for all agents to finish -for s in /mnt/ollie/session/*/statewait; do cat "$s" > /dev/null; done +for s in /mnt/ollie/session/*/agent/*/statewait; do cat "$s" > /dev/null; done # Grep all agent plans grep -r "TODO" /mnt/ollie/session/*/plan # Monitor costs -paste /mnt/ollie/session/*/cost +paste /mnt/ollie/session/*/agent/*/cost ``` -Pipe agents into `awk`. Filter with `grep`. Schedule with `cron`. Orchestrate with a 10-line shell script instead of a framework. - -### Multiplexing - -Multiple clients — terminals, editors, scripts, other agents — can mount the same server simultaneously. Each gets an independent view through 9P’s per-fid state model. No connection pools, no session affinity, no WebSocket juggling. +Pipe agents into `awk`. Filter with `grep`. Schedule with `cron`. Orchestrate +with a 10-line shell script instead of a framework. ### Plan 9 patterns -The design follows Plan 9 conventions directly: - -- **`/net/dns` pattern** — `/complete`, `/generate`, and `/route` are stateless per-fid: write a request, read back the result, like a DNS lookup -- **`ctl` files** — control operations (stop, kill, rename, compact) are writes to a control file, not method calls -- **Blocking reads** — `statewait` blocks until state changes, replacing event subscriptions with a simple `cat` - ---- +- **`/net/dns` pattern** — `/complete`, `/generate`, `/route` are stateless + per-fid: write a request, read back the result +- **`ctl` files** — control operations (stop, kill, rename, compact) are writes + to a control file, not method calls +- **Blocking reads** — `statewait` blocks until state changes, replacing event + subscriptions with a simple `cat` +- **Multiplexing** — multiple clients mount the same server simultaneously, + each with an independent view through per-fid state ## D-Bus: desktop integration -The D-Bus interface (`org.ollie.SessionManager`) is embedded in `olliesrv` (enabled by default, or exclusively via `-no9p`). The KDE frontends connect to it over the session bus. - -### Typed method calls - -D-Bus gives you introspectable, typed interfaces with proper error returns. No string parsing, no exit codes to check: +The D-Bus interface (`org.ollie.SessionManager`) is embedded in `olliesrv` +(enabled by default, or exclusively via `-no9p`). It provides typed method +calls and real-time signals. ```sh # Create a session @@ -359,53 +227,48 @@ dbus-send --session --dest=org.ollie.SessionManager --type=method_call --print-r # Submit a prompt dbus-send --session --dest=org.ollie.SessionManager --type=method_call \ /org/ollie/SessionManager org.ollie.SessionManager.Submit \ - string:"SESSION_ID" string:"fix the bug in main.go" + string:"SESSION_ID" string:"fix the bug" # Read state dbus-send --session --dest=org.ollie.SessionManager --type=method_call --print-reply \ - /org/ollie/SessionManager org.ollie.SessionManager.GetState \ - string:"SESSION_ID" + /org/ollie/SessionManager org.ollie.SessionManager.GetState string:"SESSION_ID" ``` -### Real-time signals - -D-Bus signals push events to subscribers without polling: +### Signals +D-Bus signals push events without polling: - **`ChatUpdated`** — new chat output (session_id, offset, text) -- **`StateChanged`** — transition notifications (`idle` → `thinking` → `calling: grep` → `idle`) -- **`SessionCreated` / `SessionKilled` / `SessionRenamed`** — lifecycle events for UIs +- **`StateChanged`** — transition notifications +- **`SessionCreated` / `SessionKilled` / `SessionRenamed`** — lifecycle events - **`ProcessDetached` / `ProcessExited`** — background process events -GUI frontends subscribe once and react to changes — no timers, no file watches, no busy loops. +GUI frontends subscribe once and react — no timers, no file watches, no busy loops. ### KDE integration -The D-Bus interface is what makes native desktop integration possible: - -- **Plasmoid** — embed an agent chat widget directly in the Plasma panel +- **Plasmoid** — embed an agent chat widget in the Plasma panel - **Kate plugin** — inline AI assistance in the text editor - **KRunner** — launch prompts from the desktop search bar - **System tray** — status indicator and quick actions - **Standalone GUI** — full-featured Qt6 chat application -All of these talk to `org.ollie.SessionManager` over D-Bus using Qt's native bindings — no IPC glue code, no subprocess management. +## Tool registry: dynamic native tools -### Tool registry: dynamic native tools - -Tools are scripts in `~/.config/ollie/tools/`. Write one, add a JSON schema header, and it's **discoverable** immediately — no server restart needed. Add, modify, or remove tools at any time; the registry re-reads from disk on every `tool_list` and `tool_load`. A tool is only **callable** when you promote it into your session. +Tools are executable scripts in `~/.config/ollie/tools/`. Each one declares its +metadata — JSON schema, documentation, concurrency class — in header comments. +No server restart needed. No MCP server. No protocol. Just a file with a header. ```bash -# Discover all available tools (always reflects current directory contents) -cat s/{sid}/tools +# Discover all available tools +cat session/{id}/tools -# Load one into your session — it becomes a native callable function -echo file_glob | 9p write s/{sid}/tools +# Load one into your session — becomes a native callable function +echo file_glob | 9p write session/{id}/tools # The model sees it as a first-class tool on the next turn. -# No MCP server. No protocol. No SDK. Just a script with a header. ``` -The tool header is minimal: +The header: ```bash #!/usr/bin/env bash @@ -416,20 +279,32 @@ The tool header is minimal: # ollie:end ``` -The `args_json` field is the JSON schema the model uses to call it. The `ollie:prompt` block is the documentation. Everything else is just a script. +Everything is sandboxed by default via Landlock. Tools that need to escape +request elevation explicitly (`"elevated": true`). -This is the anti-MCP. No subprocess servers, no protocol negotiation, no capability advertisement, no transport layer. A file. A header. A script. The model calls it natively. +## What you can do + +| Capability | How | +|---|---| +| **Run an agent** | `olliesrv` → `s/sh` or any frontend | +| **Remote execution** | Set `remote=user@host` in session config | +| **Multi-agent** | `subagent_spawn` from within a session, or shell scripts | +| **Code completion** | `u/complete` from acme, or read/write `/complete` | +| **One-shot LLM** | Write to `/generate`, read back the response | +| **Task routing** | Write to `/route`, read back `backend=X model=Y` | +| **Background jobs** | Detach via `shell({"elevated":true, "detach":true})` | +| **Custom tools** | Drop a script in `$OLLIE_TOOLS_PATH` | +| **Custom agents** | Write a JSON config in `agents/` | +| **Domain skills** | Write a markdown file in `skills/` | ## Credits -Many sources of inspiration: - - [Plan 9 from Bell Labs](https://9fans.net) — for an interesting system - [@9fans](https://github.com/9fans) — for the Plan 9 port - [Suckless](https://suckless.org) — for articulating good software development principles -- [@simonfxr](https://github.com/simonfxr) — for a solid agent baseline to "borrow" from, and other nifty ideas +- [@simonfxr](https://github.com/simonfxr) — for a solid agent baseline to "borrow" from - [@aws](https://github.com/aws/amazon-q-developer-cli) — for a solid open-source agent implementation ## License -GPLv3 +GPLv3 \ No newline at end of file