Skip to content

buildwithgo/berrygem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Berrygem

A pure Go framework for building AI agents with tool calling, workflows, and multi-agent teams. Uses official SDKs from OpenAI, Anthropic, and Google.

Go Reference

Features

Core

  • Multi-Provider — OpenAI, Anthropic, Google Gemini, Fireworks, Ollama (all via official SDKs)
  • Tool Calling — interface-based tools with automatic JSON Schema generation
  • MCP Support — connect to any MCP server and use its tools, or expose your agents as MCP servers
  • Streaming — real-time token streaming with the same agent API
  • Chat — stateful multi-turn conversations with automatic history management, thread cloning, and branching
  • Structured Output — JSON schema-based typed responses from Go structs

Orchestration

  • Workflows — sequential, parallel, conditional, loop, router, DAG, fan-out/fan-in, and subgraph composition
  • Teams — multi-agent coordination (round-robin, orchestrator, network, supervisor, graph, LLM speaker selection) with streaming, event bus, hooks, and planning
  • Planning — structured plans with CRUD operations, agent assignment, TaskOutput with artifacts
  • A2A Protocol — Agent-to-Agent communication for cross-framework interoperability

Production

  • Checkpointing — durable state persistence (SQLite, PostgreSQL, Memory) with time-travel debugging and fork/replay
  • Context Compaction — sliding window, LLM summarization, and hybrid strategies for long sessions
  • Sandboxed Execution — Docker, local restricted, and cloud sandbox (E2B) for untrusted code
  • Rate Limiting — per-session request rate limits with configurable windows
  • Cost Limits — track and cap spending per session
  • Stream Redaction — strip API keys, PII, and sensitive data from streaming responses and traces
  • Cron Scheduling — time-aware execution with cron expressions, retries, timeouts, and timezone support
  • Health Monitoring — built-in health endpoints, memory stats, readiness/liveness probes

Intelligence

  • Memory — neuroscience-inspired tiered memory (sensory → working → short-term → long-term) with entity tracking
  • RAG / Knowledge Base — document ingestion, chunking, embedding, and retrieval with multiple vector backends
  • Learning — cross-session learning machine that improves agent behavior over time
  • Multi-Tenant Isolation — shared infrastructure with isolated memory, state, and retrieval per tenant

Safety & Governance

  • Guardrails — input/output safety (PII detection, prompt injection, moderation, token limits, LLM classifier, rate limiting, cost limits)
  • Hooks — lifecycle middleware (pre/post run, pre/post tool, stream hooks)
  • Plugin Architecture — aspect-oriented global interception (logging, context filters, global instructions)
  • Human-in-the-Loop — approval system with audit trails, state editing, suspend/resume

Developer Experience

  • YAML Configuration — define agents, teams, and workflows in YAML files
  • Server Adapters — embed in existing Go apps (net/http, gin, fiber, chi) with CORS and auth middleware
  • Observability — tracing with spans (agent, LLM, tool), token tracking
  • Events — pub/sub event bus for agent lifecycle
  • Evaluation — scorers (contains, length, exact match, tool use), batch evaluation, benchmarking
  • Provider Fallbacks — automatic failover between providers
  • Background Execution — non-blocking agent runs with cancellation
  • Response Caching — cache identical requests to reduce API calls
  • Zero hard-coded models — pass any model string

Installation

go get github.com/buildwithgo/berrygem

Quick Start

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/buildwithgo/berrygem/agent"
    "github.com/buildwithgo/berrygem/providers/openai"
    "github.com/buildwithgo/berrygem/tools/builtin"
)

func main() {
    provider := openai.New(os.Getenv("OPENAI_API_KEY"), "gpt-4o-mini")

    a, err := agent.New(
        agent.WithProvider(provider),
        agent.WithModel("gpt-4o-mini"),
        agent.WithInstructions("You are a helpful assistant."),
        agent.WithTools(builtin.Calculator(), builtin.CurrentTime()),
    )
    if err != nil {
        log.Fatal(err)
    }

    result, err := a.Run(context.Background(), "What is 42 * 137?")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(result.Content)
    fmt.Printf("Tokens: %d\n", result.Usage.TotalTokens)
}

Providers

All providers implement the same providers.Provider interface, so swapping providers only changes the constructor:

Provider Package SDK Constructor
OpenAI providers/openai openai-go/v3 openai.New(apiKey, model)
Anthropic providers/anthropic anthropic-sdk-go anthropic.New(apiKey, model)
Google providers/google go-genai google.New(apiKey, model)
Fireworks providers/fireworks openai-go (wrapper) fireworks.New(apiKey, model)
Ollama providers/ollama OpenAI-compat + native ollama.New(model)

OpenAI

provider := openai.New(os.Getenv("OPENAI_API_KEY"), "gpt-4o-mini")

Anthropic

provider := anthropic.New(os.Getenv("ANTHROPIC_API_KEY"), "claude-sonnet-4-20250514")

Google Gemini

provider := google.New(os.Getenv("GOOGLE_API_KEY"), "gemini-2.0-flash")

Fireworks

provider := fireworks.New(os.Getenv("FIREWORKS_API_KEY"), "accounts/fireworks/models/deepseek-v3")

Ollama (local)

// Default: localhost:11434
provider := ollama.New("qwen3:8b")

// Custom host
provider := ollama.New("llama3.1:8b", ollama.WithBaseURL("http://192.168.1.50:11434"))

// Model management
provider.ListModels(ctx)
provider.PullModel(ctx, "qwen3:8b")
provider.Version(ctx)

OpenAI-Compatible (any provider)

Any provider that exposes an OpenAI-compatible API works with the OpenAI package:

// Together AI
provider := openai.New(os.Getenv("TOGETHER_API_KEY"), "meta-llama/Llama-3-70b-chat-hf",
    openai.WithBaseURL("https://api.together.xyz/v1"),
)

// vLLM
provider := openai.New("", "my-model",
    openai.WithBaseURL("http://localhost:8000/v1"),
)

// Azure OpenAI
provider := openai.New(os.Getenv("AZURE_API_KEY"), "gpt-4o",
    openai.WithBaseURL("https://myresource.openai.azure.com/openai"),
)

Agent

The Agent is the core abstraction. It handles the tool-calling loop automatically:

a, err := agent.New(
    agent.WithProvider(provider),           // required
    agent.WithModel("gpt-4o-mini"),         // model ID
    agent.WithInstructions("You are..."),   // system prompt
    agent.WithTools(tool1, tool2),          // register tools
    agent.WithTemperature(0.7),             // sampling temperature
    agent.WithMaxTurns(10),                 // max tool-call loops
    agent.WithDebug(true),                  // log each turn
    agent.WithName("my-agent"),             // agent name
)

Run (blocking)

result, err := a.Run(ctx, "What's the weather in Paris?")
// result.Content  — final text response
// result.Messages — full message history
// result.Usage    — token usage

Stream

result, err := a.Stream(ctx, "Tell me a story")
defer result.Close()

for {
    select {
    case chunk, ok := <-result.C:
        if !ok { break }
        fmt.Print(chunk)
    case err := <-result.Err:
        log.Fatal(err)
    case done := <-result.Done:
        fmt.Printf("\nTokens: %d\n", done.Usage.TotalTokens)
        return
    }
}

Chat (Multi-Turn)

The Chat wrapper maintains conversation history automatically:

c := chat.New(a)

result, _ := c.Send(ctx, "My name is Alice.")
fmt.Println(result.Content) // "Nice to meet you, Alice!"

result, _ = c.Send(ctx, "What's my name?")
fmt.Println(result.Content) // "Your name is Alice."

// Get history
msgs := c.Messages()

// Clear history (keeps agent config)
c.Reset()

Streaming Chat

result, err := c.SendStream(ctx, "Tell me about Go")
defer result.Close()

var fullContent string
for chunk := range result.C {
    fmt.Print(chunk)
    fullContent += chunk
}

// Finalize history
c.CompleteStream(fullContent, nil)

Tools

Custom Tools

Implement the tools.Tool interface or use tools.NewFunc:

import (
    "context"
    "encoding/json"
    "github.com/buildwithgo/berrygem/providers"
    "github.com/buildwithgo/berrygem/tools"
)

// Using NewFunc (quick)
weatherTool := tools.NewFunc(
    "get_weather",
    "Get the current weather for a city.",
    map[string]providers.Property{
        "city": {Type: "string", Description: "City name."},
    },
    []string{"city"},
    func(_ context.Context, args string) (string, error) {
        var p struct { City string `json:"city"` }
        json.Unmarshal([]byte(args), &p)
        return fmt.Sprintf("72F and sunny in %s", p.City), nil
    },
)

// Using Tool interface (full control)
type MyTool struct{}
func (t *MyTool) Name() string                             { return "my_tool" }
func (t *MyTool) Description() string                      { return "Does something." }
func (t *MyTool) Schema() providers.ToolDefinition         { /* ... */ }
func (t *MyTool) Execute(ctx context.Context, args string) (string, error) {
    return "result", nil
}

Built-in Tools

import "github.com/buildwithgo/berrygem/tools/builtin"

a, _ := agent.New(
    agent.WithProvider(provider),
    agent.WithTools(
        builtin.Calculator(),    // math expressions
        builtin.CurrentTime(),   // current date/time
    ),
)

MCP Tools

Connect to any Model Context Protocol server:

import "github.com/buildwithgo/berrygem/tools/mcp"

// Stdio transport
mcpTools, err := mcp.NewStdio("npx", "@anthropic/mcp-server-filesystem", "/data")
if err != nil {
    log.Fatal(err)
}
defer mcpTools.Close()

// Discover tools from the MCP server
tools, err := mcpTools.Tools(ctx)

// Use them with an agent
a, _ := agent.New(
    agent.WithProvider(provider),
    agent.WithTools(tools...),
)

HTTP/SSE MCP Server

mcpTools, err := mcp.NewHTTP("http://localhost:3000/sse")
defer mcpTools.Close()

tools, _ := mcpTools.Tools(ctx)

Workflows

Sequential Pipeline

Steps run in order, each step's output becomes the next step's input:

import "github.com/buildwithgo/berrygem/workflow"

wf := workflow.New("research-pipeline",
    workflow.AgentStep("researcher", researchAgent),
    workflow.FuncStep("format", func(ctx context.Context, input string, state *workflow.State) (string, error) {
        return "## Report\n\n" + input, nil
    }),
    workflow.AgentStep("reviewer", reviewAgent),
)

result, err := wf.Run(ctx, "Research quantum computing trends")
fmt.Println(result.Output)

Parallel Execution

All steps run concurrently with the same input:

pw := workflow.NewParallel("fan-out",
    workflow.AgentStep("analyst1", analyst1),
    workflow.AgentStep("analyst2", analyst2),
    workflow.AgentStep("analyst3", analyst3),
)

result, _ := pw.Run(ctx, "Analyze this data...")
// result.Output contains all outputs combined

Conditional Branching

route := workflow.ConditionalStep("classify", func(ctx context.Context, state *workflow.State) string {
    if val, ok := state.Get("category"); ok && val == "billing" {
        return "billing"
    }
    return "technical"
}, map[string]workflow.Step{
    "billing":   workflow.AgentStep("billing", billingAgent),
    "technical": workflow.AgentStep("tech", techAgent),
})

wf := workflow.New("classifier", route)

Shared State Between Steps

Steps can read/write shared state:

step1 := workflow.FuncStep("extract", func(ctx context.Context, input string, state *workflow.State) (string, error) {
    state.Set("topic", "AI")
    return "extracted data", nil
})

step2 := workflow.FuncStep("summarize", func(ctx context.Context, input string, state *workflow.State) (string, error) {
    topic, _ := state.Get("topic")
    return fmt.Sprintf("Summary about %s: %s", topic, input), nil
})

Teams

Round Robin

Agents take turns, each receives the full conversation:

import "github.com/buildwithgo/berrygem/team"

t, _ := team.New("debate-team", []*agent.Agent{proAgent, conAgent},
    team.WithMode(team.ModeRoundRobin),
    team.WithMaxTurns(6),
)

result, _ := t.Run(ctx, "Debate: should AI be regulated?")

for _, turn := range result.AgentLog {
    fmt.Printf("[%s]: %s\n", turn.AgentName, turn.Output)
}

Orchestrator

A coordinator agent decides which agent to call next:

t, _ := team.New("support-team", []*agent.Agent{billingAgent, techAgent, salesAgent},
    team.WithMode(team.ModeOrchestrator),
    team.WithOrchestrator(coordinatorAgent),
    team.WithMaxTurns(8),
)

result, _ := t.Run(ctx, "Customer needs help with billing")

Network

Agents can transfer conversations to each other:

t, _ := team.New("network", []*agent.Agent{router, agent1, agent2},
    team.WithMode(team.ModeNetwork),
    team.WithMaxTurns(10),
)

result, _ := t.Run(ctx, "Help me with my request")

Guardrails

Input/output safety checks that run before and after agent execution:

import "github.com/buildwithgo/berrygem/guardrails"

chain := guardrails.NewChain(
    guardrails.PIIDetector(),           // redacts emails, phones, SSNs, credit cards
    guardrails.PromptInjectionDetector(), // blocks injection patterns
    guardrails.ModerationGuardrail(),   // warns/blocks harmful content
    guardrails.TokenLimiter(8000),      // blocks oversized inputs
)

a, _ := agent.New(
    agent.WithProvider(provider),
    agent.WithGuardrails(chain),
)

Actions: pass, warn, block, redact, rewrite

Hooks

Lifecycle middleware for agent execution:

import "github.com/buildwithgo/berrygem/hooks"

chain := hooks.NewChain(
    hooks.CallbackHook(func(ctx context.Context, phase hooks.HookPhase, data *hooks.HookData) error {
        log.Printf("phase=%s input=%s output=%s duration=%s",
            phase, data.Input, data.Output, data.Duration)
        return nil
    }, hooks.PhasePreRun, hooks.PhasePostRun, hooks.PhasePreTool, hooks.PhasePostTool),
)

a, _ := agent.New(agent.WithHooks(chain))

Phases: pre_run, post_run, pre_tool, post_tool, pre_stream, post_stream

Memory (Neuroscience-Based)

Tiered memory system inspired by human memory architecture:

import "github.com/buildwithgo/berrygem/memory"

db, _ := storage.NewSQLite("memory.db")
store := memory.NewGORMStore(db)

tm := memory.NewTieredMemory(store).
    WithAgent("researcher").
    WithSession("session-123").
    WithUser("user-456")

a, _ := agent.New(
    agent.WithProvider(provider),
    agent.WithTieredMemory(tm),
)

Tiers:

  • Sensory (~5s) — raw input buffer
  • Working (~30s, 7±2 items) — active processing
  • Short-Term (minutes-hours) — recent context
  • Long-Term (days-years) — consolidated knowledge

Long-Term Sub-Tiers:

  • Episodic — events, experiences, conversations
  • Semantic — facts, concepts, knowledge
  • Procedural — skills, patterns, how-to

Consolidation Engine:

  • Memories promote based on importance and access frequency
  • Unused memories decay over time (exponential decay)
  • Similar memories compete (interference detection)

Structured Output

Get typed/structured responses instead of plain text:

type WeatherResponse struct {
    City        string  `json:"city" description:"The city name"`
    Temperature float64 `json:"temperature" description:"Temperature in Celsius"`
    Condition   string  `json:"condition" description:"Weather condition"`
}

a, _ := agent.New(
    agent.WithProvider(provider),
    agent.WithResponseSchemaFromStruct(&WeatherResponse{}),
)

result, _ := a.Run(ctx, "What's the weather in Paris?")
resp := result.Structured.(*WeatherResponse)
fmt.Println(resp.City, resp.Temperature)

Human-in-the-Loop

Approval system with audit trails:

import "github.com/buildwithgo/berrygem/hitl"

db, _ := storage.NewSQLite("approvals.db")
approvalStore := hitl.NewApprovalStore(db)

// List pending approvals
approvals, _ := approvalStore.List(ctx, "", hitl.ApprovalPending)

// Approve or deny
approvalStore.Resolve(ctx, approvalID, true, "Looks good")

Observability & Tracing

Built-in tracing with spans for agent runs, LLM calls, and tool execution:

import "github.com/buildwithgo/berrygem/observability"

store := observability.NewInMemoryStore()
tracer := observability.NewTracer("my-agent", store)

a, _ := agent.New(
    agent.WithProvider(provider),
    agent.WithTracer(tracer),
)

result, _ := a.Run(ctx, "Hello")

// View trace
trace := tracer.Trace()
fmt.Println(tracer.Summary())

// Persist trace
tracer.EndTrace(ctx)

Events

Pub/sub event bus for agent lifecycle:

import "github.com/buildwithgo/berrygem/events"

bus := events.NewBus()
recorder := events.NewRecorder()

bus.On(events.EventAgentStart, recorder.Handler())
bus.On(events.EventAgentEnd, recorder.Handler())
bus.On(events.EventToolStart, recorder.Handler())
bus.On(events.EventToolEnd, recorder.Handler())

a, _ := agent.New(
    agent.WithProvider(provider),
    agent.WithEventBus(bus),
)

Event Types: agent.start, agent.end, agent.error, tool.start, tool.end, tool.error, stream.start, stream.chunk, stream.end, memory.encode, memory.retrieve, memory.consolidate, guardrail.block, guardrail.warn

Evaluation

Automated scoring for agent outputs:

import "github.com/buildwithgo/berrygem/eval"

e := eval.NewEvaluator(
    eval.ContainsScorer([]string{"Paris", "France"}),
    eval.LengthScorer(10, 100),
    eval.ExactMatchScorer(),
)

result, _ := e.Evaluate(ctx, eval.TestCase{
    Input:    "What is the capital of France?",
    Output:   "Paris is the capital of France.",
    Expected: "Paris",
})

fmt.Printf("Score: %.2f\n", result.AvgScore)

// Batch evaluation
results, _ := e.EvaluateBatch(ctx, []eval.TestCase{...})
summary := e.Summary()

Provider Fallbacks

Automatic failover between providers:

import "github.com/buildwithgo/berrygem/provider"

fp, _ := provider.NewFallback(
    []providers.Provider{openaiProvider, anthropicProvider, googleProvider},
    []string{"gpt-4o-mini", "claude-sonnet-4", "gemini-2.0-flash"},
    provider.WithMaxFailures(3),
)

a, _ := agent.New(agent.WithProvider(fp))

Strategies:

  • Fallback — tries providers in order, switches on failure
  • RoundRobin — cycles through providers on each call
  • Cached — caches identical requests to reduce API calls

Background Execution

Non-blocking agent runs:

bg := a.RunBackground(ctx, "Analyze this data...")

// Do other work...

select {
case result := <-bg.C:
    fmt.Println(result.Content)
case err := <-bg.Err:
    log.Fatal(err)
case <-bg.Done:
    // Execution complete
}

// Or cancel early
bg.Cancel()

Package Structure

berrygem/
├── agent/                    Agent + execution loop + tool calling
├── chat/                     Stateful conversations + thread cloning + branching
├── team/                     Multi-agent coordination + LLM speaker selection
├── workflow/                 Pipelines + DAG + fan-out/fan-in + subgraphs
├── tools/
│   ├── tool.go               Tool interface + Registry
│   ├── schema.go             NewFunc helper
│   ├── mcp/                  MCP client (consume) + server (expose)
│   ├── builtin/              Calculator, CurrentTime
│   ├── unix/                 50+ Unix commands
│   └── agent/                File operations
├── providers/                LLM providers (OpenAI, Anthropic, Google, etc.)
├── checkpoint/               Durable state persistence + time-travel debugging
├── compaction/               Context window management (sliding window, LLM summary)
├── sandbox/                  Sandboxed code execution (Docker, local, E2B)
├── redaction/                Stream & trace redaction (API keys, PII)
├── rag/                      RAG/knowledge base with document ingestion
├── learning/                 Cross-session learning machine
├── plugin/                   Plugin architecture (logging, context filters)
├── a2a/                      Agent-to-Agent protocol support
├── server/                   HTTP adapters (net/http, gin, fiber, chi)
├── scheduler/                Cron scheduling with retries and timeouts
├── config/                   YAML configuration + agent factory
├── health/                   Health endpoints + metrics + probes
├── benchmark/                Performance benchmarking suite
├── memory/                   Tiered memory + entity tracking
├── guardrails/               Input/output safety + rate limiting + cost limits
├── hooks/                    Lifecycle middleware
├── hitl/                     Human-in-the-loop + state editing
├── observability/            Tracing and observability
├── events/                   Event bus
├── eval/                     Evaluation + benchmarking
├── compression/              Context compression
├── session/                  Session state management
├── storage/                  Database layer (SQLite, PostgreSQL)
└── docs/                     Documentation

berrygem/ ├── agent/ Agent + execution loop + tool calling │ ├── agent.go Agent struct, New(), functional options │ ├── options.go WithModel, WithTools, WithProvider, etc. │ └── run.go Run, Stream, RunWithMessages, StreamWithMessages, RunBackground ├── chat/ Stateful multi-turn conversations │ └── chat.go Chat wrapper with auto history management ├── providers/ │ ├── types.go Unified Message, ChatRequest, ToolDefinition, etc. │ ├── provider.go Provider interface (Chat, Stream) │ ├── openai/ Official OpenAI SDK wrapper │ ├── anthropic/ Official Anthropic SDK wrapper │ ├── google/ Official Google GenAI SDK wrapper │ ├── fireworks/ OpenAI wrapper with Fireworks base URL │ └── ollama/ OpenAI-compat chat + native model management ├── tools/ │ ├── tool.go Tool interface + Registry │ ├── schema.go NewFunc helper │ ├── mcp/ MCP tool adapter (stdio, HTTP, SSE) │ └── builtin/ Calculator, CurrentTime ├── workflow/ Sequential, parallel, conditional pipelines │ └── workflow.go Workflow, Parallel, ConditionalStep ├── team/ Multi-agent coordination │ └── team.go RoundRobin, Orchestrator, Network ├── memory/ Neuroscience-inspired tiered memory │ ├── store.go GORM-backed memory store │ ├── memory.go Memory interface + types │ └── tiered.go Tiered memory (sensory → working → short → long) ├── guardrails/ Input/output safety │ └── guardrails.go PII, injection, moderation, token limiter ├── hooks/ Lifecycle middleware │ └── hooks.go Hook interface + chain + built-in hooks ├── hitl/ Human-in-the-loop │ └── approval.go Approval store + lifecycle ├── observability/ Tracing and observability │ └── trace.go Tracer, spans, in-memory and GORM stores ├── events/ Event bus │ └── events.go Pub/sub event bus + recorder ├── eval/ Evaluation system │ └── eval.go Scorers, evaluator, batch evaluation ├── provider/ Provider wrappers │ └── fallback.go Fallback, RoundRobin, Cached providers ├── compression/ Context compression for token limits │ └── compression.go Summary, truncate, tool call filter, chain ├── scheduler/ Cron-based job scheduling │ └── scheduler.go Scheduler with @every duration syntax ├── session/ Session state management │ └── session.go GORM-backed session state store ├── storage/ Database layer │ └── storage.go GORM init helpers (SQLite, PostgreSQL) ├── docs/ Documentation │ ├── README.md Documentation index │ ├── getting-started.md Installation and quick start │ ├── providers.md Provider setup and configuration │ ├── tools.md Tools, MCP, and built-in tools │ ├── memory.md Neuroscience memory system │ ├── workflows.md Workflow patterns and orchestration │ └── advanced.md Advanced features guide └── examples/ ├── basic/ Simple OpenAI agent ├── toolcalling/ Anthropic agent with tools ├── agent-with-memory/ Full agent with memory, guardrails, tracing, events, structured output ├── multi-agent-team/ Customer support team with orchestrator ├── workflow-pipeline/ Content generation pipeline with evaluation ├── streaming-chat/ Interactive streaming chat with history ├── structured-output/ Typed output from Go structs └── background-agent/ Concurrent non-blocking agent execution


## Documentation

Full documentation is available in the [`docs/`](docs/) directory:

- [Getting Started](docs/getting-started.md) — Installation, quick start, first agent
- [Providers](docs/providers.md) — OpenAI, Anthropic, Google, Fireworks, Ollama setup
- [Tools](docs/tools.md) — Custom tools, built-in tools, MCP integration
- [Memory](docs/memory.md) — Neuroscience-inspired tiered memory system
- [Workflows](docs/workflows.md) — Sequential, parallel, conditional, loop, router patterns

## Examples

Production-ready examples in the [`examples/`](examples/) directory:

| Example | Description |
|---------|-------------|
| [`basic`](examples/basic/) | Simple OpenAI agent |
| [`toolcalling`](examples/toolcalling/) | Anthropic agent with tools |
| [`agent-with-memory`](examples/agent-with-memory/) | Full agent with memory, guardrails, tracing, events, structured output |
| [`multi-agent-team`](examples/multi-agent-team/) | Customer support team with orchestrator routing |
| [`workflow-pipeline`](examples/workflow-pipeline/) | Content generation pipeline with evaluation |
| [`streaming-chat`](examples/streaming-chat/) | Interactive streaming chat with history |
| [`structured-output`](examples/structured-output/) | Typed output from Go struct schemas |
| [`background-agent`](examples/background-agent/) | Concurrent non-blocking agent execution |
| [`planning`](examples/planning/) | Plan CRUD, TaskOutput, agent assignment |
| [`unix-tools`](examples/unix-tools/) | File manipulation with 50+ Unix commands |
| [`agent-file-tools`](examples/agent-file-tools/) | Precision file read/edit/write/search/exec |
| [`team-streaming`](examples/team-streaming/) | Real-time team output streaming |
| [`team-graph-mode`](examples/team-graph-mode/) | Graph-based agent routing |
| [`team-supervisor`](examples/team-supervisor/) | Hierarchical supervision with sub-teams |

## Design Decisions

| Decision | Rationale |
|----------|-----------|
| Interface-based tools | More flexible, supports complex tools with config |
| Official SDKs per provider | Each API has quirks (Anthropic system param, Gemini content parts) |
| No hard-coded models | Models change constantly; users pass strings |
| `context.Context` everywhere | Enables cancellation and timeouts |
| Functional options | Clean API, extensible without breaking changes |
| MCP for external tools | Industry standard protocol, avoids custom integrations |
| GORM for persistence | Unified ORM for SQLite and PostgreSQL, pure Go SQLite driver |
| Neuroscience memory model | Human-like memory tiers with consolidation and decay |

## License

MIT

About

Another agentic framework, written in go...

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages