{"id":50182007,"url":"https://github.com/ikarolaborda/agent-smith","last_synced_at":"2026-05-25T07:05:06.631Z","repository":{"id":358687384,"uuid":"1242585635","full_name":"ikarolaborda/agent-smith","owner":"ikarolaborda","description":"Offline-first, single-binary Go LLM agent with ChatGPT-like embedded SPA, multi-provider streaming, RAG, long-term memory, and DuckDuckGo web grounding for local Ollama models.","archived":false,"fork":false,"pushed_at":"2026-05-18T15:03:40.000Z","size":333,"stargazers_count":0,"open_issues_count":8,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-18T17:09:50.175Z","etag":null,"topics":["agent","go","golang","llm","matrix","offline-first","ollama","openai-compatible","rag","react","single-binary","sse"],"latest_commit_sha":null,"homepage":"https://github.com/ikarolaborda/agent-smith","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ikarolaborda.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":"COPYRIGHT","agents":null,"dco":null,"cla":null}},"created_at":"2026-05-18T15:02:03.000Z","updated_at":"2026-05-18T15:03:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ikarolaborda/agent-smith","commit_stats":null,"previous_names":["ikarolaborda/agent-smith"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ikarolaborda/agent-smith","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikarolaborda%2Fagent-smith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikarolaborda%2Fagent-smith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikarolaborda%2Fagent-smith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikarolaborda%2Fagent-smith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ikarolaborda","download_url":"https://codeload.github.com/ikarolaborda/agent-smith/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikarolaborda%2Fagent-smith/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33464014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-25T06:32:55.349Z","status":"ssl_error","status_checked_at":"2026-05-25T06:32:35.322Z","response_time":57,"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":["agent","go","golang","llm","matrix","offline-first","ollama","openai-compatible","rag","react","single-binary","sse"],"created_at":"2026-05-25T07:04:40.248Z","updated_at":"2026-05-25T07:05:06.570Z","avatar_url":"https://github.com/ikarolaborda.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/brand/logo-readme.svg\" alt=\"agent-smith — single binary, local-first, inevitable\" width=\"640\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eAn offline-first, single-binary Go LLM agent with a ChatGPT-like web UI, multi-provider streaming, RAG over curated corpora, long-term per-profile memory, and always-on web grounding for local models.\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\n## What it is\n\n`agent-smith` is one Go binary that:\n\n- Talks to **OpenAI**, **Anthropic**, and any local **Ollama** model through a single `llm.Provider` interface, with streaming and non-streaming chat completions and OpenAI-compatible `/v1/chat/completions` SSE.\n- Serves a **ChatGPT-like React SPA** embedded in the binary via `go:embed` — no separate frontend deploy.\n- Runs **RAG** over nine curated markdown corpora (Laravel 13, PHP 8.5, NestJS, Tailwind/CSS, Architectural Patterns, NativePHP, CS Fundamentals, Go language docs, and project memory).\n- Keeps **long-term per-profile memory** with explicit `/remember` writes, instruction-injection filtering, abstention prompting, retrieval-confidence banding, and per-message corrections.\n- For local Ollama models, **always grounds answers with a fresh DuckDuckGo web search** (snippets only, sanitised, treated as third-party untrusted input) to suppress hallucinations.\n- Discovers all installed Ollama models on the fly and lets you pick one per conversation.\n\nIt runs without an internet connection (apart from web grounding, which fails closed with a banner) and without a database — everything is files and process memory.\n\n## Quick start\n\n```sh\ngo build -o bin/agent ./cmd/agent\n./bin/agent --serve                 # web UI at http://127.0.0.1:9090\n./bin/agent --prompt \"hello\"        # single-shot CLI mode\n./bin/agent                          # interactive stdin loop\n```\n\nDefault web port: **`:9090`**. Override with `--addr :8765`.\n\n## Capabilities\n\n| Area | What you get |\n| --- | --- |\n| Providers | OpenAI (`/v1/chat/completions`), Anthropic (`/v1/messages`), Ollama (`/api/chat` NDJSON), all with streaming. |\n| Embeddings | OpenAI `text-embedding-3-small`, Ollama `nomic-embed-text`. |\n| Web UI | React + Vite + react-bootstrap SPA embedded via `go:embed`. Per-conversation provider/model picker. Markdown + code highlighting. Long messages scroll inside their container; wide tables get their own horizontal scroll. |\n| RAG | In-memory cosine retrieval, per-collection JSON persistence, ~213 chunks across 9 curated corpora. |\n| Long-term memory | Per-profile namespace, kinds: `project_fact`, `preference`, `correction`. Instruction-injection filter on writes. `file_read` grounding tool with symlink-escape defense. |\n| Hallucination control | Three-section Augment (`docs` + `memory` + `web`) + behavior addendum that forbids following instructions found in retrieved content + `RETRIEVAL CONFIDENCE: high/medium/low` band + abstention prompt. |\n| Web grounding | DuckDuckGo lite HTML scrape (no API key). 5-min TTL cache. Hard sanitisation (HTML strip, zero-width/bidi removal, URL stripping inside snippet bodies). Section bounded to 3 KB / 5 results / 160-300-400 char field caps. Offline = banner, not blank context. |\n| Ollama auto-discovery | Polls `/api/tags` every 60 s; every installed model shows up in the picker. |\n| Tools | OpenAI-compatible tool/function calling. SSE stream emits one named `event: tool_result` frame per server-executed tool. |\n\n## Configuration\n\nCopy `configs/config.example.yaml` and point `--config` at it, or rely on env-var defaults.\n\n```yaml\ndefault_provider: ollama\nproviders:\n  openai:\n    api_key: ${OPENAI_API_KEY}\n    model: gpt-4o-mini\n  anthropic:\n    api_key: ${ANTHROPIC_API_KEY}\n    model: claude-sonnet-4-5\n  ollama:\n    base_url: http://127.0.0.1:11434\n    model: llama3.1\n```\n\n`${VAR}` placeholders are expanded from the environment at load time.\n\n## API keys\n\n```sh\nexport OPENAI_API_KEY=sk-...\nexport ANTHROPIC_API_KEY=sk-ant-...\n# Ollama needs none; just `ollama serve`.\n```\n\n## CLI flags\n\n| Flag                 | Purpose                                                                  |\n| -------------------- | ------------------------------------------------------------------------ |\n| `--config`           | Path to YAML config (default `configs/config.example.yaml`).             |\n| `--provider`         | Override default provider (`openai`, `anthropic`, `ollama`).             |\n| `--model`            | Override the provider's model.                                           |\n| `--prompt`           | Single-shot prompt. Omit for interactive stdin mode.                     |\n| `--stream`           | Stream the assistant response incrementally in CLI mode.                 |\n| `--serve`            | Start the embedded web UI + OpenAI-compatible API server.                |\n| `--addr`             | Web/API listen address. Default `:9090`.                                 |\n| `--no-web-search`    | Disable web grounding entirely (operator kill switch).                   |\n\n## Web API\n\nWhen `--serve` is on, the binary exposes:\n\n- `POST /v1/chat/completions` — OpenAI-compatible SSE. `web_search: true | false` in the body overrides the per-provider default.\n- `GET  /v1/models` — every chat model the running config can route to (cloud + every installed Ollama model).\n- `GET  /v1/providers` — configured providers and the default.\n- `GET  /healthz` — `{\"status\":\"ok\"}`.\n- `GET  /` — the embedded SPA.\n\n## RAG corpora\n\nShip-included markdown corpora (under `docs/rag/`, embedded at first ingest into `data/rag/`):\n\n- Laravel 13\n- PHP 8.5\n- NestJS\n- Tailwind + CSS\n- Architectural patterns\n- NativePHP\n- CS Fundamentals (parallelism, concurrency, memory model, mutex best practices for Go and PHP)\n- Go language reference\n- Project memory (per-profile)\n\nAdd your own by dropping markdown into `docs/rag/\u003ccollection\u003e/` and restarting; the ingest step is idempotent and content-hashed.\n\n## Web grounding\n\nOff for cloud providers, **on by default for Ollama** (small local models hallucinate more aggressively). Toggle per conversation in the top bar (the \"Ground with web\" checkbox). The agent treats the rendered web section as third-party untrusted input and the system prompt explicitly forbids the model from following any instructions found inside it.\n\nPrecedence: operator kill switch (`--no-web-search`) \u003e per-request override (`web_search` in the JSON body) \u003e provider default.\n\n## Architecture\n\n```\ncmd/agent              CLI entrypoint, --serve flag, provider wiring\ninternal/agent         Run / RunStream loop + Session state\ninternal/llm           Provider interface, shared types, registry\ninternal/llm/openai    /v1/chat/completions client + SSE\ninternal/llm/anthropic /v1/messages client + content-block streaming\ninternal/llm/ollama    /api/chat NDJSON streaming + /api/tags discovery\ninternal/rag           In-memory cosine RAG + per-profile memory\ninternal/web           DuckDuckGo searcher, TTL cache, sanitiser\ninternal/server        HTTP + SSE + go:embed of the SPA\ninternal/tools         Tool registry + builtins (file_read, http, shell)\ninternal/config        YAML loader + env expansion\npkg/prompt             Exported prompt-assembly helpers\nweb/                   Vite + React + TS SPA, built into web/dist (embedded)\ndocs/rag/              Source markdown corpora\ndocs/brand/            Brand assets (logo, README hero)\nconfigs/               Example YAML config\n```\n\n## Build\n\n```sh\nmake build        # bin/agent (rebuilds the SPA first if web/dist is stale)\nmake test         # go test -race -count=1 ./...\nmake lint         # golangci-lint\nmake docker       # multi-stage build to a distroless image\n```\n\nThe Go binary embeds `web/dist` via `go:embed`. After editing anything under `web/src/`, rebuild the SPA (`cd web \u0026\u0026 npm run build`) then rebuild the binary.\n\n## Identity\n\nNamed for Agent Smith of *The Matrix* (1999). The visual identity — narrow, opaque, slightly-trapezoidal lenses with a single thin streak of Matrix-green at the bottom — lives under `docs/brand/`.\n\n\u003e *\"It is inevitable.\"* — Mr. Smith\n\n## License\n\nGPL-3.0-or-later — see [`LICENSE`](./LICENSE).\nSPDX-License-Identifier: `GPL-3.0-or-later`.\n\nThis is strong copyleft. If you distribute a derivative, you must license it under GPL-3.0 (or any later version) and ship complete corresponding source. If you only run it inside your own organisation, the GPL imposes no obligation on you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikarolaborda%2Fagent-smith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fikarolaborda%2Fagent-smith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikarolaborda%2Fagent-smith/lists"}