Reusable Go library for building LLM agents
Bug found while building rony-harness's "Edited Files" info panel: it
scanned the transcript for tool-call messages carrying write/edit
arguments, but those messages never appeared — not even for a plain,
successful top-level write with no delegation involved.
Root cause: RunStream's content-streaming gate (`if !hasToolCalls &&
(hasContent || hasUsage) { yield(chunk, nil) }`) suppresses yielding
*any* chunk once a tool call is seen in that iteration, including the
chunk carrying the tool call itself. So chunk.ToolCalls was executed
internally (hence approvals and results worked) but never yielded to
the caller. Every caller-side "which tool got called" hook depending on
the stream (not the Approver callback) was therefore dead code.
Fix: yield a dedicated chunk carrying just the executed ToolCalls right
after running them, independent of the content-streaming gate below.
Updated TestRun_Stream_WithToolCalls, which asserted the old (buggy)
1-chunk behavior.
|
||
|---|---|---|
| .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