{"id":49887955,"url":"https://github.com/mivinci/moo","last_synced_at":"2026-05-23T11:02:41.448Z","repository":{"id":330175499,"uuid":"1121797234","full_name":"mivinci/moo","owner":"mivinci","description":"An AI agent runtime, written in C.","archived":false,"fork":false,"pushed_at":"2026-05-23T03:31:37.000Z","size":14386,"stargazers_count":5,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-23T05:14:34.523Z","etag":null,"topics":["ai-agent","c","llm","moo"],"latest_commit_sha":null,"homepage":"http://le0.me/moo/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mivinci.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-23T15:12:59.000Z","updated_at":"2026-05-22T09:00:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mivinci/moo","commit_stats":null,"previous_names":["mivinci/downloadkit","mivinci/xkit","mivinci/moo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mivinci/moo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mivinci%2Fmoo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mivinci%2Fmoo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mivinci%2Fmoo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mivinci%2Fmoo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mivinci","download_url":"https://codeload.github.com/mivinci/moo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mivinci%2Fmoo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33392816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","c","llm","moo"],"created_at":"2026-05-15T19:05:56.555Z","updated_at":"2026-05-23T11:02:41.442Z","avatar_url":"https://github.com/mivinci.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable MD033 --\u003e\n\u003c!-- markdownlint-disable MD041 --\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/logo.png\" alt=\"moo\" height=\"160\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eAn AI agent, written in C.\u003c/b\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://le0.me/moo\"\u003eDocs\u003c/a\u003e\n  \u003cspan\u003e\u0026nbsp;\u0026nbsp;•\u0026nbsp;\u0026nbsp;\u003c/span\u003e\n  \u003ca href=\"STYLE.md\"\u003eStyle\u003c/a\u003e\n  \u003cspan\u003e\u0026nbsp;\u0026nbsp;•\u0026nbsp;\u0026nbsp;\u003c/span\u003e\n  \u003ca href=\"LICENSE\"\u003eLicense\u003c/a\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n\u003c/div\u003e\n\n**moo** is a small, self-contained AI agent runtime written in C — plus the\nfoundation libraries it rides on. It ships as a terminal app you build from\nsource and run against any OpenAI-compatible endpoint (Kimi, GLM, DeepSeek,\nOpenAI itself, …), with a streaming REPL, tool calls, token budgeting,\nsidecar queries, and a layered memory design. An Anthropic-compatible backend\nis on the roadmap — the provider layer is a vtable, adding one is a contained\nchange.\n\n- Designed and reviewed by [@mivinci](https://github.com/mivinci)\n- Coded by CodeBuddy (VSCode plugin) with claude-opus-4.7 and GLM-5.1\n\n\u003e **Status.** Active development. macOS and Linux are first-class; Windows is\n\u003e on the roadmap but not a near-term priority.\n\n## Highlights\n\n- **Agent core in C** — `xAgent` + `xAgentSession` + `xAgentQuery` +\n  `xAgentBudget` wired together into a non-blocking, single-loop runtime.\n  No GC, no green threads, no hidden allocations on the hot path.\n- **Streaming-first** — SSE is decoded incrementally; every token reaches\n  `on_text` the moment it leaves the wire.\n- **Tool calls with confirmation** — ships with a `shell` tool out of the\n  box; the REPL prompts for confirmation before anything is executed, and\n  a **sidecar query** watches long-running commands and can talk to them\n  (stdin injection) if they stall.\n- **Token budget that self-calibrates** — `xAgentBudget` estimates prompt\n  size before each round, trims old turns under `TruncateOldest`, and\n  learns a correction factor from the provider's real usage reports.\n- **Multi-model registry** — one `models.json` declares every backend;\n  `/model \u003cid\u003e` flips the active backend mid-conversation without tearing\n  the agent down. Today every entry is `\"provider\": \"openai\"` (covers any\n  OpenAI-compatible API); `\"provider\": \"anthropic\"` is planned.\n- **Layered memory (in design)** — conversation · session · agent tiers,\n  with JSONL persistence wired into each session. See\n  [docs/design/layered-memory.md](docs/design/layered-memory.md).\n\n## Quick Start\n\n```bash\n# 1. Configure + build the app (cli/ is off by default)\ncmake -S . -B build -DCMAKE_BUILD_TYPE=Release \\\n      -DMOO_BUILD_APPS=ON -DX_BUILD_TESTS=OFF -DX_BUILD_BENCHMARKS=OFF\ncmake --build build --parallel\n\n# 2. First run scaffolds a models.json template into the data dir\n#    (defaults to the current working directory; pass --data-dir to\n#    point somewhere else, e.g. ~/.moo)\n./build/cli/moo --data-dir ~/.moo\n# moo will write ~/.moo/models.json on first launch, then exit with a\n# \"please configure me\" hint. Edit the file in place.\n```\n\nThe scaffolded `models.json` looks like this — fill in the angle-bracket\nplaceholders to enable chat:\n\n```json\n{\n  \"default\": \"kimi\",\n  \"max_turns\": 64,\n  \"budget\": { \"context_window\": 8192 },\n  \"models\": [\n    { \"id\": \"kimi\", \"provider\": \"openai\",\n      \"model\": \"kimi-k2.6\",\n      \"api_key\": \"\u003cyour-api-key\u003e\",\n      \"base_url\": \"https://api.moonshot.cn/v1\",\n      \"budget\": { \"context_window\": 131072 } },\n    { \"id\": \"glm\",  \"provider\": \"openai\",\n      \"model\": \"glm-4.5\",\n      \"api_key\": \"\u003cyour-api-key\u003e\",\n      \"base_url\": \"https://open.bigmodel.cn/api/paas/v4\",\n      \"budget\": { \"context_window\": 131072 } }\n  ]\n}\n```\n\nRun again once `models.json` is filled in:\n\n```bash\n./build/cli/moo --data-dir ~/.moo\n```\n\nInside the REPL, slash commands are available:\n\n| Command | What it does |\n| ------- | ------------ |\n| `/help` | Show all commands |\n| `/model` / `/model \u003cid\u003e` | Show or switch the active model |\n| `/tokens` | Cumulative token usage for the session |\n| `/cancel` | Interrupt the active AI run |\n| `/history` | Dump input history |\n| `/clear` | Clear the terminal |\n| `/bypass on --yes \\| off` | Skip tool-call confirmation for the session (`--yes` is mandatory to enable) |\n| `/renderer md \\| raw` | Switch between markdown→ANSI and raw output |\n| `/verbose on \\| off` | Toggle full vs truncated tool-output display |\n| `/version` | Build version |\n| `/exit` | Quit |\n\nTab completes slash commands. `Ctrl-R` is a reverse-search over history.\n`Ctrl-C` cancels an in-flight run without killing the REPL.\n\nHere's what a session looks like:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/screenshot.png\" alt=\"moo in action\" width=\"760\"\u003e\n\u003c/p\u003e\n\n## Architecture\n\n```plain\n                     ┌─────────────────────────┐\n                     │   cli  (the `moo`      │\n                     │         REPL)           │\n                     └────────────┬────────────┘\n                                  │\n                     ┌────────────▼────────────┐\n                     │   xagent — the agent    │ ← the core\n                     │  agent / session /      │\n                     │  query / tool / budget  │\n                     │  provider(openai)       │\n                     └────────────┬────────────┘\n                                  │\n  ┌─────────┬─────────┬───────────┴────────┬─────────┬─────────┬─────────┐\n  │ xbase   │ xbuf    │ xnet / xhttp       │ xline   │ xlog    │ xtui    │\n  │ loop,   │ linear, │ DNS, TCP, TLS,     │ CJK-    │ async   │ stream  │\n  │ timer,  │ ring,   │ HTTP/1.1, HTTP/2,  │ aware   │ MPSC    │ md →    │\n  │ task,   │ chain   │ SSE, WebSocket     │ line    │ logger  │ ANSI    │\n  │ atomic… │ bufs    │                    │ editor  │         │         │\n  └─────────┴─────────┴────────────────────┴─────────┴─────────┴─────────┘\n\n   plus xcrypto (hashes/HMAC), xjs (QuickJS-ng), xp2p / xfer\n   (WebRTC + DataChannel file transfer) — supporting infra.\n```\n\n### The agent (`libx/x/agent`)\n\n| Module | Role |\n| ------ | ---- |\n| `agent.{h,c}` | Long-lived persona: provider/model, system prompt, tool set, limits. Mints sessions. |\n| `session.{h,c}` | Stateful conversation. Owns history, runs the tool-call loop, emits `on_text` / `on_thinking` / `on_tool` / `on_done`. |\n| `query.{h,c}` | One round-trip to the model, including streaming decode and sidecar supervision. |\n| `message.{h,c}` | Chat-message value type with tool-call envelopes. |\n| `model.{h,c}` | Model **registry** — map `{id → provider + wire-model + limits}`; powers runtime model switching. |\n| `provider.{h,c}` · `provider_openai.c` | Backend vtable + OpenAI-compatible implementation (chat/completions, SSE). Anthropic-compatible provider planned. |\n| `tool.{h,c}` · `tool_shell.{h,c}` | Tool definition ABI + a built-in shell tool with confirmation hooks. |\n| `budget.{h,c}` | Prompt-size estimator, rolling trimmer, auto-calibrator. |\n\nSee [`libx/x/agent/agent.h`](libx/x/agent/agent.h) for the entry point, and\n[`docs/design/`](docs/design) for the design notes\n(context budget, layered memory, three-layer conversation model).\n\n### The foundation libraries\n\nEverything in `libx/x/` outside `agent/` is shared, reusable, and independently\ntestable — you can link any of them into your own C project without\npulling in the agent.\n\n| Library | What you get |\n| ------- | ------------ |\n| **[xbase](https://le0.me/moo/libx/base)** | Event loop, timers, tasks, async sockets, lock-free structures |\n| **[xbuf](https://le0.me/moo/libx/buf)** | Linear, ring, and block-chain I/O buffers |\n| **[xnet](https://le0.me/moo/libx/net)** | URL parser, async DNS, TCP, shared TLS config |\n| **[xhttp](https://le0.me/moo/libx/http)** | libcurl multi-socket client with SSE; HTTP/1.1 + HTTP/2 server; WebSocket |\n| **[xline](https://github.com/mivinci/moo/tree/main/libx/x/line)** | CJK-aware line editor with persistent history and reverse search |\n| **[xlog](https://le0.me/moo/libx/log)** | Async MPSC logger with rotation |\n| **[xjs](https://le0.me/moo/libx/js)** | Embeddable JavaScript engine — QuickJS-ng backend, JSC-shaped API |\n| **[xcrypto](https://le0.me/moo/libx/crypto)** | SHA-1 / SHA-256 / MD5 / CRC-32 / HMAC |\n| **[xp2p](https://le0.me/moo/libx/p2p)** | ICE · STUN/TURN · SDP · DTLS · SCTP · DataChannel |\n| **[xfer](https://le0.me/moo/libx/fer)** | Zero-config P2P file transfer over WebRTC DataChannel |\n| **[xtui](https://github.com/mivinci/moo/tree/main/libx/x/tui)** | Streaming markdown → ANSI transformer for terminal output |\n\n**`libx++/xpp/`** is an optional C++14 RAII layer over libx — `Own\u003cT\u003e`,\n`NonNull\u003cT\u003e`, `Option\u003cT\u003e`, `Result\u003cT, E\u003e`, and a few thin wrappers around\nthe C event/timer/task primitives. The C side stands on its own; pull in\nlibx++ only if you want the C++ ergonomics. See\n[libx++/xpp/](libx%2B%2B/xpp/).\n\n## Prerequisites\n\n| Dependency | Required | Notes |\n| ---------- | -------- | ----- |\n| CMake ≥ 3.14 | ✅ | Build system |\n| C99 compiler | ✅ | GCC or Clang |\n| OpenSSL **or** MbedTLS | ✅ (pick one) | TLS backend for `xhttp` and `xp2p` DTLS |\n| libunwind | optional | Better backtraces on Linux |\n\nTransitive deps (libcurl, llhttp, nghttp2, cJSON, usrsctp, QuickJS-ng,\nlibuv for benches, GoogleTest, Google Benchmark) are fetched via CMake\n`FetchContent` when not found on the system — no manual setup required\nfor a first build.\n\n## Build\n\n```bash\n# Everything, Debug, with tests\ncmake -S . -B build -DCMAKE_BUILD_TYPE=Debug\ncmake --build build --parallel\n\n# App only, Release\ncmake -S . -B build -DCMAKE_BUILD_TYPE=Release \\\n      -DMOO_BUILD_APPS=ON -DX_BUILD_TESTS=OFF -DX_BUILD_BENCHMARKS=OFF\ncmake --build build --parallel\n```\n\nUseful options:\n\n| Option | Default | Purpose |\n| ------ | ------- | ------- |\n| `MOO_BUILD_APPS` | `OFF` | Build `cli/` (the `moo` CLI lives here) |\n| `X_BUILD_TESTS` | `ON` | Build unit tests |\n| `X_BUILD_BENCHMARKS` | `ON` | Build micro- and end-to-end benchmarks |\n| `X_BUILD_EXAMPLES` | `OFF` | Build example programs |\n| `X_BUILD_STATIC` | `OFF` | Build libraries as static archives |\n| `X_TLS_BACKEND` | `openssl` | TLS backend: `openssl` or `mbedtls` |\n| `MOO_ENABLE_ASAN` | `OFF` | AddressSanitizer |\n| `X_DEBUG_LEVEL` | `0` | Debug-log verbosity (0–3) |\n\n## Test\n\n### Local (macOS / Linux)\n\n```bash\nctest --test-dir build --output-on-failure --parallel 4\n```\n\nTo test both TLS backends in one session, configure two build dirs and\nrun ctest in each:\n\n```bash\ncmake -S . -B build-openssl -DX_TLS_BACKEND=openssl \u0026\u0026 \\\n  cmake --build build-openssl --parallel \u0026\u0026 \\\n  ctest --test-dir build-openssl --output-on-failure --parallel 4\n\ncmake -S . -B build-mbedtls -DX_TLS_BACKEND=mbedtls \u0026\u0026 \\\n  cmake --build build-mbedtls --parallel \u0026\u0026 \\\n  ctest --test-dir build-mbedtls --output-on-failure --parallel 4\n```\n\n### Affected-modules workflow\n\nFor a faster local iteration loop, the test scripts diff against a base\nref (default `origin/main`) and run only the tests for changed libx\nmodules and their dependents:\n\n```bash\n./scripts/test-mac.sh                    # macOS, openssl, vs origin/main\n./scripts/test-mac.sh -t mbedtls --all   # force-test every module, mbedTLS\n./scripts/test-linux.sh --ci --base-sha \u003cSHA\u003e   # CI mode, native Linux\n```\n\nPass `--detect-only` to print just the affected module names without\nbuilding or running anything.\n\n### Linux via container (macOS host)\n\nRequires macOS 26+ with\n[Apple Containerization](https://developer.apple.com/documentation/containerization):\n\n```bash\nbrew install container\ncontainer system start\n./scripts/test-linux.sh            # default: gcc:14, Debug, -j2\n./scripts/test-linux.sh -j4 -m 4G  # custom parallelism / memory\n```\n\n## Benchmark\n\nSee the [benchmark pages](https://le0.me/moo/bench/) for micro-benchmarks of the\nfoundation libraries and end-to-end HTTP server numbers.\n\n## License\n\n[MIT](LICENSE) © 2025-present [@mivinci](https://github.com/mivinci) and moo contributors\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmivinci%2Fmoo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmivinci%2Fmoo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmivinci%2Fmoo/lists"}