Reusable Go library for building LLM agents
- llamacpp: 4MB SSE scanner buffer (the 64KB bufio.Scanner default killed streams whose single line exceeded it, e.g. a write tool call carrying a whole file) and an empty-choices guard in toResponse instead of a panic; request payload now uses bytes.NewReader (drops a full string copy). - anthropic: Capabilities() reported a 1M-token context window for any non-haiku model. Callers use that number to decide when to compact, so compaction would have fired far too late and requests overflowed the real window. Default is now the standard 200k, configurable via Config.ContextWindow for extended-window models/plans. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| .agents/skills/add-feature | ||
| docs | ||
| examples | ||
| pkg | ||
| .gitignore | ||
| AGENTS.md | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.es.md | ||
| README.md | ||
rony-llm-agent
🔑 Reusable core library for building LLM agents in Go.
This library is the heart of several Victor Vargas projects:
harness— AI agent harness for software development (TUI)chat-bot— HTTP chatbot for portfolios and websites
It provides all the generic logic of an LLM agent:
| Component | Location | Responsibility |
|---|---|---|
| Agent loop | pkg/agent/ |
Iterative loop with guardrails |
| LLM clients | pkg/llm/ |
Multi-provider abstraction (OpenAI, Anthropic, Ollama) |
| RAG / memory | pkg/rag/ |
Short and long-term memory with semantic search |
| Persona system | pkg/persona/ |
Configurable system prompts + AGENTS.md discovery |
| Tool registry | pkg/tools/ |
JSON Schema + execution sandbox |
| Config loading | pkg/config/ |
YAML loading with hierarchical precedence |
🎯 Philosophy
- Reusable, not opinionated. Does not force a UI type, deployment, or use case.
- Pure Hexagonal. Ports & adapters — every external dependency is behind an interface.
- Streaming-first. Uses
iter.Seq2from Go 1.23+ for natural streaming without callbacks. - Secure by default. Filesystem path sandbox with
os.Root(Go 1.24+). - Zero magic. No reflection, no codegen, no DSLs. Idiomatic and explicit Go.
- YAML configurable. Everything that affects behavior is declarative.
📦 Installation
go get github.com/VictorVargas/rony-llm-agent
🚀 Basic usage
package main
import (
"context"
"fmt"
"github.com/VictorVargas/rony-llm-agent/pkg/agent"
"github.com/VictorVargas/rony-llm-agent/pkg/llm"
"github.com/VictorVargas/rony-llm-agent/pkg/persona"
)
func main() {
// 1. Create LLM client
llmClient, _ := llm.NewAnthropicClient(llm.AnthropicConfig{
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
Model: "claude-sonnet-4.5",
})
// 2. Load persona
p := persona.Load("./persona.yaml")
// 3. Create agent loop
loop := agent.New(agent.Config{
LLM: llmClient,
Persona: p,
MaxIters: 50,
Sandbox: agent.NewSandbox("./workspace"),
})
// 4. Run
resp, err := loop.Run(context.Background(), "Refactor auth.go")
if err != nil { panic(err) }
fmt.Println(resp.Content)
}
🔌 Included adapters
LLM Providers (pkg/llm/providers/)
| Provider | Import | Models |
|---|---|---|
| OpenAI | providers/openai |
gpt-4o, gpt-4o-mini, gpt-4-turbo |
| Anthropic | providers/anthropic |
claude-sonnet-4.5, claude-haiku-4 |
| Ollama | providers/ollama |
llama3.1, qwen2.5, mistral, etc. |
| llama.cpp | providers/llamacpp |
Custom GGUF models |
Vector DBs (pkg/rag/backends/)
| Backend | Status |
|---|---|
| ChromaDB embedded | ✅ Stable |
| Qdrant embedded | 🚧 In development |
| SQLite + sqlite-vec | 📋 Planned |
Embeddings (pkg/rag/embeddings/)
- Ollama embeddings (nomic-embed-text, bge-m3, etc.)
- Local sentence-transformers via ONNX
🧪 Testing
go test ./...
go test -race ./...
go test -bench=. ./pkg/agent/
Includes MockLLMClient for deterministic tests without burning API calls.
📐 Versions
- Go minimum: 1.26 (uses
os.Root,iter.Seq,unique.Handle, container-aware GOMAXPROCS) - Versioning policy: Strict semver. API breaking changes only on MAJOR.
📄 License
MIT — see LICENSE.
🔗 Projects that use this library
VictorVargas/rony-harness— TUI agent for software devVictorVargas/rony-chat-bot— HTTP chatbot