agent

package module
v1.11.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2026 License: Apache-2.0 Imports: 25 Imported by: 1

README

Go Version CI Status Go Reference Go Report Card

Lattice helps you build AI agents in Go with clean abstractions for LLMs, tool calling, retrieval-augmented memory, and multi-agent coordination. Focus on your domain logic while Lattice handles the orchestration plumbing.

Why Lattice?

Building production AI agents requires more than just LLM calls. You need:

  • Pluggable LLM providers that swap without rewriting logic
  • Tool calling that works across different model APIs
  • Memory systems that remember context across conversations
  • Multi-agent coordination for complex workflows
  • Testing infrastructure that doesn't hit external APIs

Lattice provides all of this with idiomatic Go interfaces and minimal dependencies.

Features

  • 🧩 Modular Architecture – Compose agents from reusable modules with declarative configuration
  • 🤖 Multi-Agent Support – Coordinate specialist agents through a shared catalog and delegation system
  • 🔧 Rich Tooling – Implement the Tool interface once, use everywhere automatically
  • 🧠 Smart Memory – RAG-powered memory with importance scoring, MMR retrieval, and automatic pruning
  • 🔌 Model Agnostic – Adapters for Gemini, Anthropic, Ollama, or bring your own
  • 📡 UTCP Ready – First-class Universal Tool Calling Protocol support
  • High Performance – Optimized with LRU caching, pre-allocated buffers, and concurrent operations

⚡ Performance Optimizations

Lattice is built for production speed:

  • 10-50x faster MIME normalization with pre-computed lookup tables and caching
  • 40-60% fewer allocations in prompt building through buffer pre-allocation
  • LRU cache infrastructure for sub-millisecond cached operations (184 ns/op)
  • Concurrent utilities for parallel processing with configurable worker pools
  • Optimized string operations reduce overhead by 30-50%

See PERFORMANCE_SUMMARY.md for detailed benchmarks.

Quick Start

Installation

git clone https://github.com/Protocol-Lattice/go-agent.git
cd lattice-agent
go mod download

Basic Usage

package main

import (
	"context"
	"flag"
	"log"

	"github.com/Protocol-Lattice/go-agent/src/adk"
	adkmodules "github.com/Protocol-Lattice/go-agent/src/adk/modules"
	"github.com/Protocol-Lattice/go-agent"
	"github.com/Protocol-Lattice/go-agent/src/subagents"

	"github.com/Protocol-Lattice/go-agent/src/memory"
	"github.com/Protocol-Lattice/go-agent/src/memory/engine"
	"github.com/Protocol-Lattice/go-agent/src/models"
	"github.com/Protocol-Lattice/go-agent/src/tools"
)

func main() {
	qdrantURL := flag.String("qdrant-url", "http://localhost:6333", "Qdrant base URL")
	qdrantCollection := flag.String("qdrant-collection", "adk_memories", "Qdrant collection name")
	flag.Parse()
	ctx := context.Background()

	// --- Shared runtime
	researcherModel, err := models.NewGeminiLLM(ctx, "gemini-2.5-pro", "Research summary:")
	if err != nil {
		log.Fatalf("create researcher model: %v", err)
	}
	memOpts := engine.DefaultOptions()

	adkAgent, err := adk.New(ctx,
		adk.WithDefaultSystemPrompt("You orchestrate a helpful assistant team."),
		adk.WithSubAgents(subagents.NewResearcher(researcherModel)),
		adk.WithModules(
			adkmodules.NewModelModule("gemini-model", func(_ context.Context) (models.Agent, error) {
				return models.NewGeminiLLM(ctx, "gemini-2.5-pro", "Swarm orchestration:")
			}),
			adkmodules.InQdrantMemory(100000, *qdrantURL, *qdrantCollection, memory.AutoEmbedder(), &memOpts),
		),
	)
	if err != nil {
		log.Fatal(err)
	}

	agent, err := adkAgent.BuildAgent(ctx)
	if err != nil {
		log.Fatal(err)
	}

	// Use the agent
	resp, err := agent.Generate(ctx, "SessionID", "What is pgvector")
	if err != nil {
		log.Fatal(err)
	}

	log.Println(resp)
}

Running Examples

# Interactive CLI demo
go run cmd/demo/main.go

# Multi-agent coordination
go run cmd/team/main.go

# Quick start example
go run cmd/quickstart/main.go

# CodeMode + Agent as UTCP Tool
go run cmd/example/codemode/main.go

# Multi-Agent Workflow Orchestration
go run cmd/example/codemode_utcp_workflow/main.go

# Agent-to-Agent Communication via UTCP
go run cmd/example/agent_as_tool/main.go
go run cmd/example/agent_as_utcp_codemode/main.go

# Agent State Persistence (Checkpoint/Restore)
go run cmd/example/checkpoint/main.go
Example Descriptions
  • cmd/example/codemode/main.go: Demonstrates how to use CodeMode to enable agents to call UTCP tools (including other agents) via generated Go code. Shows the pattern: User Input → LLM generates codemode.CallTool() → UTCP executes tool.

  • cmd/example/codemode_utcp_workflow/main.go: Shows orchestrating multi-step workflows where multiple specialist agents (analyst, writer, reviewer) work together through UTCP tool calls.

  • cmd/example/agent_as_tool/main.go: Demonstrates exposing agents as UTCP tools using RegisterAsUTCPProvider(), enabling agent-to-agent communication and hierarchical agent architectures.

  • cmd/example/agent_as_utcp_codemode/main.go: Shows an agent exposed as a UTCP tool and orchestrated via CodeMode, illustrating natural language to tool call generation.

  • cmd/example/checkpoint/main.go: Demonstrates how to checkpoint an agent's state to disk and restore it later, preserving conversation history and shared space memberships.

Project Structure

lattice-agent/
├── cmd/
│   ├── demo/          # Interactive CLI with tools, delegation, and memory
│   ├── quickstart/    # Minimal getting-started example
│   └── team/          # Multi-agent coordination demos
├── pkg/
│   ├── adk/           # Agent Development Kit and module system
│   ├── memory/        # Memory engine and vector store adapters
│   ├── models/        # LLM provider adapters (Gemini, Ollama, Anthropic)
│   ├── subagents/     # Pre-built specialist agent personas
├── └── tools/         # Built-in tools (echo, calculator, time, etc.)

Configuration

Environment Variables

Variable Description Required
GOOGLE_API_KEY Gemini API credentials For Gemini models
GEMINI_API_KEY Alternative to GOOGLE_API_KEY For Gemini models
DATABASE_URL PostgreSQL connection string For persistent memory
ADK_EMBED_PROVIDER Embedding provider override No (defaults to Gemini)

Example Configuration

export GOOGLE_API_KEY="your-api-key-here"
export DATABASE_URL="postgres://user:pass@localhost:5432/lattice?sslmode=disable"
export ADK_EMBED_PROVIDER="gemini"

Core Concepts

Memory Engine

Lattice includes a sophisticated memory system with retrieval-augmented generation (RAG):

store := memory.NewInMemoryStore() // or PostgreSQL/Qdrant
engine := memory.NewEngine(store, memory.Options{}).
    WithEmbedder(yourEmbedder)

sessionMemory := memory.NewSessionMemory(
    memory.NewMemoryBankWithStore(store), 
    8, // context window size
).WithEngine(engine)

Features:

  • Importance Scoring – Automatically weights memories by relevance
  • MMR Retrieval – Maximal Marginal Relevance for diverse results
  • Auto-Pruning – Removes stale or low-value memories
  • Multiple Backends – In-memory, PostgreSQL+pgvector,mongodb, neo4j or Qdrant

Tool System

Create custom tools by implementing a simple interface:

package tools

import (
        "context"
        "fmt"
        "strings"

        "github.com/Protocol-Lattice/go-agent"
)

// EchoTool repeats the provided input. Useful for testing tool wiring.
type EchoTool struct{}

func (e *EchoTool) Spec() agent.ToolSpec {
        return agent.ToolSpec{
                Name:        "echo",
                Description: "Echoes the provided text back to the caller.",
                InputSchema: map[string]any{
                        "type": "object",
                        "properties": map[string]any{
                                "input": map[string]any{
                                        "type":        "string",
                                        "description": "Text to echo back.",
                                },
                        },
                        "required": []any{"input"},
                },
        }
}

func (e *EchoTool) Invoke(_ context.Context, req agent.ToolRequest) (agent.ToolResponse, error) {
        raw := req.Arguments["input"]
        if raw == nil {
                return agent.ToolResponse{Content: ""}, nil
        }
        return agent.ToolResponse{Content: strings.TrimSpace(fmt.Sprint(raw))}, nil
}

Register tools with the module system and they're automatically available to all agents.

Multi-Agent Coordination

Use Shared Spaces to coordinate multiple agents with shared memory

Perfect for:

  • Team-based workflows where agents need shared context
  • Complex tasks requiring specialist coordination
  • Projects with explicit access control requirements

Agent Composability

Lattice treats Agents as first-class Tools. This allows you to expose any agent as a tool to another agent, enabling powerful hierarchical or mesh architectures.

Why use this?

  • Specialization: Create small, focused agents (e.g., "Researcher", "Coder", "Reviewer") and orchestrate them with a "Manager" agent.
  • Encapsulation: Hide complex multi-step workflows behind a simple natural language interface.
  • Scalability: Build complex systems by composing simple, testable agents.

How It Works

When you wrap an agent as a tool:

  1. Context Isolation: The sub-agent runs in its own session (namespaced like parent_session.sub.tool_name). It has its own memory and history, preventing the parent's context window from being polluted with the sub-agent's internal thought process.
  2. Recursive Capability: Since a sub-agent is just a tool, it can have its own tools—including other agents. This allows for arbitrarily deep hierarchies (e.g., CEO -> CTO -> Lead Dev -> Coder).
  3. Standard Interface: The parent agent doesn't know it's talking to another AI. It simply sees a tool that takes an instruction and returns a result. This means you can swap a "Researcher Agent" with a "Google Search Tool" without changing the parent's logic.
// 1. Create a specialist agent
researcher, _ := agent.New(agent.Options{
    SystemPrompt: "You are a researcher. Search for facts.",
    // ...
})

// 2. Create a manager agent that uses the researcher
manager, _ := agent.New(agent.Options{
    SystemPrompt: "You are a manager. Delegate tasks.",
    Tools: []agent.Tool{
        // Expose the researcher as a tool!
        researcher.AsTool("researcher", "Delegates research tasks to the specialist."),
    },
})

// 3. The manager can now call the researcher tool
// User: "Find out why the sky is blue"
// Manager -> calls tool "researcher" -> Researcher Agent runs -> returns result -> Manager answers

Exposing Agents as UTCP Tools

In addition to the internal Tool interface, Lattice agents can be exposed as Universal Tool Calling Protocol (UTCP) tools. This allows them to be consumed by any UTCP-compliant client, enabling cross-language and cross-platform agent orchestration.

Key Functions:

  • agent.AsUTCPTool(name, description): Wraps an agent as a standalone UTCP tools.Tool struct.
  • agent.RegisterAsUTCPProvider(ctx, client, name, description): Automatically registers the agent as a tool provider on a UTCP client.

Example:

// 1. Create your specialist agent
researcher, _ := agent.New(agent.Options{
    SystemPrompt: "You are a researcher.",
})

// 2. Initialize a UTCP client
client, err := utcp.NewUTCPClient(ctx, nil, nil, nil)
if err != nil {
    log.Fatal(err)
}

// 3. Register the agent as a UTCP provider
// This makes the agent available as a tool named "researcher.agent"
err := researcher.RegisterAsUTCPProvider(ctx, client, "researcher.agent", "Deep research agent")
if err != nil {
    log.Fatal(err)
}

// 4. Call the agent via UTCP
// The tool accepts 'instruction' and optional 'session_id'
result, err := client.CallTool(ctx, "researcher.agent", map[string]any{
    "instruction": "Analyze the latest trends in AI agents",
}, "researcher", nil)

fmt.Println(result["response"])

Benefits:

  • Interoperability: Your Go agents can be called by Python scripts, CLI tools, or other systems using UTCP.
  • Standardization: Uses the standard UTCP schema for inputs and outputs.
  • Zero Overhead: Uses an in-process transport when running within the same Go application, avoiding network latency.

Agent State Persistence

Lattice supports Checkpointing and Restoration, allowing you to pause agents mid-task, persist their state to disk or a database, and resume them later (even after a crash or restart).

Key Methods:

  • agent.Checkpoint(): Serializes the agent's state (system prompt, short-term memory, shared space memberships) to a []byte.
  • agent.Restore(data []byte): Rehydrates an agent instance from a checkpoint.

Example:

// 1. Checkpoint the agent
data, err := agent.Checkpoint()
if err != nil {
    log.Fatal(err)
}
// Save 'data' to file/DB...

// 2. Restore the agent (later or after crash)
// Create a fresh agent instance first
newAgent, err := agent.New(opts) 
if err != nil {
    log.Fatal(err)
}

// Restore state
if err := newAgent.Restore(data); err != nil {
    log.Fatal(err)
}
// newAgent now has the same memory and context as the original

Why Use TOON?

Token-Oriented Object Notation (TOON) is integrated into Lattice to dramatically reduce token consumption when passing structured data to and from LLMs. This is especially critical for AI agent workflows where context windows are precious and API costs scale with token usage.

The Problem with JSON

Traditional JSON is verbose and wastes tokens on repetitive syntax. Consider passing agent memory or tool responses:

{
  "memories": [
    { "id": 1, "content": "User prefers Python", "importance": 0.9, "timestamp": "2025-01-15" },
    { "id": 2, "content": "User is building CLI tools", "importance": 0.85, "timestamp": "2025-01-14" },
    { "id": 3, "content": "User works with PostgreSQL", "importance": 0.8, "timestamp": "2025-01-13" }
  ]
}

Token count: ~180 tokens

The TOON Solution

TOON compresses the same data by eliminating redundancy:

memories[3]{id,content,importance,timestamp}:
1,User prefers Python,0.9,2025-01-15
2,User is building CLI tools,0.85,2025-01-14
3,User works with PostgreSQL,0.8,2025-01-13

Token count: ~85 tokens

Savings: ~53% fewer tokens

Why This Matters for AI Agents

  1. Larger Context Windows – Fit more memories, tool results, and conversation history into the same context limit
  2. Lower API Costs – Reduce your LLM API bills by up to 50% on structured data
  3. Faster Processing – Fewer tokens mean faster inference times and lower latency
  4. Better Memory Systems – Store and retrieve more historical context without hitting token limits
  5. Multi-Agent Communication – Pass more information between coordinating agents efficiently

When TOON Shines

TOON is particularly effective for:

  • Agent Memory Banks – Retrieving and formatting conversation history
  • Tool Responses – Returning structured data from database queries or API calls
  • Multi-Agent Coordination – Sharing state between specialist agents
  • Batch Operations – Processing multiple similar records (users, tasks, logs)
  • RAG Contexts – Injecting retrieved documents with metadata

Example: Memory Retrieval

When your agent queries its memory system, TOON can encode dozens of memories in the space where JSON would fit only a handful:

// Retrieve memories
memories := sessionMemory.Retrieve(ctx, "user preferences", 20)

// Encode with TOON for LLM context
encoded, _ := toon.Marshal(memories, toon.WithLengthMarkers(true))

// Pass to LLM with 40-60% fewer tokens than JSON
prompt := fmt.Sprintf("Based on these memories:\n%s\n\nAnswer the user's question.", encoded)

Human-Readable Format

Despite its compactness, TOON remains readable for debugging and development. The format explicitly declares its schema, making it self-documenting:

users[2]{id,name,role}:
1,Alice,admin
2,Bob,user

You can immediately see: 2 users, with fields id/name/role, followed by their values.

Getting Started with TOON

Lattice automatically uses TOON for internal data serialization. To use it in your custom tools or memory adapters:

import "github.com/toon-format/toon-go"

// Encode your structs
encoded, err := toon.Marshal(data, toon.WithLengthMarkers(true))

// Decode back to structs
var result MyStruct
err = toon.Unmarshal(encoded, &result)

// Or decode to dynamic maps
var doc map[string]any
err = toon.Unmarshal(encoded, &doc)

For more details, see the TOON specification.


Bottom Line: TOON helps your agents do more with less, turning token budgets into a competitive advantage rather than a constraint.

🧠 Tool Orchestrator (LLM-Driven UTCP Tool Selection)

The Tool Orchestrator is an intelligent decision engine that lets the LLM choose when and how to call UTCP tools. It analyzes user input, evaluates available tools, and returns a structured JSON plan describing the next action.

This brings go-agent to the same capability tier as OpenAI’s tool choice, but with fully pluggable UTCP backends and Go-native execution.


🎯 What It Does

  • Interprets the user’s request

  • Loads and renders all available UTCP tools

  • Allows the LLM to reason using TOON-Go

  • Produces a strict JSON decision object:

    {
      "use_tool": true,
      "tool_name": "search.files",
      "arguments": { "query": "config" },
      "reason": "User asked to look for configuration files"
    }
    
  • Executes the chosen tool deterministically


⚙️ How It Works

  1. Collect Tool Definitions

    rendered := a.renderUtcpToolsForPrompt()
    
  2. Build the Orchestration Prompt

    choicePrompt := fmt.Sprintf(`
      You are a UTCP tool selection engine.
    
      A user asked:
      %q
    
      You have access to these UTCP tools:
      %s
    
      You can also discover tools dynamically using:
      search_tools("<query>", <limit>)
    
      Return ONLY JSON:
      { "use_tool": ..., "tool_name": "...", "arguments": { }, "reason": "..." }
    `, userInput, rendered)
    
  3. LLM Makes a Decision (via TOON)

    • Coordinator executes reasoning
    • Assistant returns the final JSON only
  4. Agent Executes the Tool

    • CallTool
    • SearchTools
    • CallToolStream
  5. The result becomes the agent’s final response


🧩 Why TOON-Go Improves Tool Selection

The orchestrator uses TOON as its structured reasoning layer:

  • Coordinator → analyzes tool options
  • Assistant → returns the strict JSON
  • No hallucinated formatting
  • Easy to debug via TOON traces
  • Session memory stores the entire reasoning trajectory

This yields stable, deterministic tool choice behavior.


🚀 Example

User

find all files containing “db connection” in the workspace

LLM Output

{
  "use_tool": true,
  "tool_name": "search.files",
  "arguments": {
    "query": "db connection",
    "limit": 20
  },
  "reason": "User wants to search through the workspace files"
}

Agent Execution

The search.files UTCP tool is invoked, and its direct output is returned to the user.



🧵 Works Seamlessly with CodeMode + Chain

CodeMode

UTCP tool calls can run inside the Go DSL:

r, _ := codemode.CallTool("echo", map[string]any{"input": "hi"})

ChainStep

The orchestrator can:

  • call a tool
  • run a chain step
  • discover tools dynamically
  • combine reasoning + execution

This makes go-agent one of the first Go frameworks with multi-step, LLM-driven tool-routing.

Development

Running Tests

# Run all tests
go test ./...

# Run with coverage
go test -cover ./...

# Run specific package tests
go test ./pkg/memory/...

Code Style

We follow standard Go conventions:

  • Use gofmt for formatting
  • Follow Effective Go guidelines
  • Add tests for new features
  • Update documentation when adding capabilities

Adding New Components

New LLM Provider:

  1. Implement the models.LLM interface in pkg/models/
  2. Add provider-specific configuration
  3. Update documentation and examples

New Tool:

  1. Implement agent.Tool interface in pkg/tools/
  2. Register with the tool module system
  3. Add tests and usage examples

New Memory Backend:

  1. Implement memory.VectorStore interface
  2. Add migration scripts if needed
  3. Update configuration documentation

Prerequisites

  • Go 1.22+ (1.25 recommended)
  • PostgreSQL 15+ with pgvector extension (optional, for persistent memory)
  • API Keys for your chosen LLM provider

PostgreSQL Setup (Optional)

For persistent memory with vector search:

CREATE EXTENSION IF NOT EXISTS vector;

The memory module handles schema migrations automatically.

Troubleshooting

Common Issues

Missing pgvector extension

ERROR: type "vector" does not exist

Solution: Run CREATE EXTENSION vector; in your PostgreSQL database.

API key errors

ERROR: authentication failed

Solution: Verify your API key is correctly set in the environment where you run the application.

Tool not found

ERROR: tool "xyz" not registered

Solution: Ensure tool names are unique and properly registered in your tool catalog.

Getting Help

Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with tests
  4. Update documentation
  5. Submit a pull request

Please ensure:

  • Tests pass (go test ./...)
  • Code is formatted (gofmt)
  • Documentation is updated
  • Commit messages are clear

License

This project is licensed under the Apache 2.0 License.

Acknowledgments


Star us on GitHub if you find Lattice useful! ⭐

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

type Agent struct {
	UTCPClient utcp.UtcpClientInterface

	Shared    *memory.SharedSession
	CodeMode  *codemode.CodeModeUTCP
	CodeChain *chain.UtcpChainClient

	AllowUnsafeTools bool
	Guardrails       *OutputGuardrails
	// contains filtered or unexported fields
}

Agent orchestrates model calls, memory, tools, and sub-agents.

func New

func New(opts Options) (*Agent, error)

New creates an Agent with the provided options.

func (*Agent) AsTool added in v1.0.9

func (a *Agent) AsTool(name, description string) Tool

AsTool returns a Tool representation of the Agent.

func (*Agent) AsUTCPTool added in v1.10.0

func (a *Agent) AsUTCPTool(name, description string) tools.Tool

AsUTCPTool exposes the agent as a UTCP tool with an in-process handler. The tool accepts: - instruction (required): user query for the agent - session_id (optional): custom session id; defaults to a namespaced value derived from the tool name

func (*Agent) Checkpoint added in v1.10.3

func (a *Agent) Checkpoint() ([]byte, error)

Checkpoint serializes the agent's current state (system prompt and short-term memory) to a byte slice. This can be saved to disk or a database to pause the agent.

func (*Agent) EnsureSpaceGrants

func (a *Agent) EnsureSpaceGrants(sessionID string, spaces []string)

EnsureSpaceGrants gives the provided sessionID writer access to each space. This mirrors how tests set up spaces: mem.Spaces.Grant(space, session, role, ttl).

func (*Agent) Flush

func (a *Agent) Flush(ctx context.Context, sessionID string) error

Flush persists session memory into the long-term store.

func (*Agent) Generate

func (a *Agent) Generate(ctx context.Context, sessionID, userInput string) (any, error)

func (*Agent) GenerateStream added in v1.10.6

func (a *Agent) GenerateStream(ctx context.Context, sessionID, userInput string) (<-chan models.StreamChunk, error)

GenerateStream provides a streaming interface for the agent's generation process. It follows the same logic as Generate but returns a channel of chunks.

func (*Agent) GenerateWithFiles

func (a *Agent) GenerateWithFiles(
	ctx context.Context,
	sessionID string,
	userInput string,
	files []models.File,
) (string, error)

GenerateWithFiles sends the user message plus in-memory files to the model without ingesting them into long-term memory. Use this when you already have file bytes (e.g., uploaded via API) and want the model to consider them ephemerally for this turn only.

func (*Agent) RegisterAsUTCPProvider added in v1.10.0

func (a *Agent) RegisterAsUTCPProvider(ctx context.Context, client utcp.UtcpClientInterface, name, description string) error

RegisterAsUTCPProvider registers the agent as a UTCP tool on the provided client. It installs a lightweight in-process transport under the "text" provider type to route CallTool invocations directly to the agent's Generate method.

func (*Agent) Restore added in v1.10.3

func (a *Agent) Restore(data []byte) error

Restore rehydrates the agent's state from a checkpoint. It restores the system prompt and short-term memory.

func (*Agent) RetrieveAttachmentFiles

func (a *Agent) RetrieveAttachmentFiles(ctx context.Context, sessionID string, limit int) ([]models.File, error)

RetrieveAttachmentFiles returns attachment files stored for the session. It reconstructs the original bytes from base64-encoded metadata, making it suitable for binary assets such as images and videos.

func (*Agent) Save

func (agent *Agent) Save(ctx context.Context, role, content string)

Save stores a conversation turn into all shared spaces. role should be "user" or "agent".

func (*Agent) SessionMemory

func (a *Agent) SessionMemory() *memory.SessionMemory

SessionMemory exposes the underlying session memory (useful for advanced setup/tests).

func (*Agent) SetSharedSpaces

func (a *Agent) SetSharedSpaces(shared *memory.SharedSession)

func (*Agent) SubAgents

func (a *Agent) SubAgents() []SubAgent

SubAgents returns all registered sub-agents in deterministic order.

func (*Agent) ToolSpecs

func (a *Agent) ToolSpecs() []tools.Tool

ToolSpecs returns the registered tool specifications in deterministic order.

func (*Agent) Tools

func (a *Agent) Tools() []Tool

Tools returns the registered tools in deterministic order.

type AgentState added in v1.10.3

type AgentState struct {
	SystemPrompt string                          `json:"system_prompt"`
	ShortTerm    map[string][]model.MemoryRecord `json:"short_term"`
	JoinedSpaces []string                        `json:"joined_spaces,omitempty"`
	Timestamp    time.Time                       `json:"timestamp"`
}

AgentState represents the serializable state of an agent for checkpointing.

type AgentToolAdapter added in v1.0.9

type AgentToolAdapter struct {
	// contains filtered or unexported fields
}

AgentToolAdapter adapts an Agent to the Tool interface.

func (*AgentToolAdapter) Invoke added in v1.0.9

func (*AgentToolAdapter) Spec added in v1.0.9

func (t *AgentToolAdapter) Spec() ToolSpec

type FormatEnforcer added in v1.11.0

type FormatEnforcer interface {
	Enforce(ctx context.Context, response string) (string, error)
}

FormatEnforcer defines an interface for validating or repairing the format of LLM responses.

type LLMEvaluatorPolicy added in v1.11.1

type LLMEvaluatorPolicy struct {
	// contains filtered or unexported fields
}

LLMEvaluatorPolicy uses a secondary language model to evaluate the safety of the proposed response.

func NewLLMEvaluatorPolicy added in v1.11.1

func NewLLMEvaluatorPolicy(model models.Agent, promptTemplate string) *LLMEvaluatorPolicy

NewLLMEvaluatorPolicy creates a new safety policy that uses an LLM to evaluate responses. If promptTemplate is empty, a default evaluation prompt is used.

func (*LLMEvaluatorPolicy) Validate added in v1.11.1

func (p *LLMEvaluatorPolicy) Validate(ctx context.Context, response string) error

Validate sends the response to the evaluating LLM and checks its verdict.

type Options

type Options struct {
	Model             models.Agent
	Memory            *memory.SessionMemory
	SystemPrompt      string
	ContextLimit      int
	Tools             []Tool
	SubAgents         []SubAgent
	ToolCatalog       ToolCatalog
	SubAgentDirectory SubAgentDirectory
	UTCPClient        utcp.UtcpClientInterface
	CodeMode          *codemode.CodeModeUTCP
	Shared            *memory.SharedSession
	CodeChain         *chain.UtcpChainClient
	AllowUnsafeTools  bool
	Guardrails        *OutputGuardrails
}

Options configure a new Agent.

type OutputGuardrails added in v1.11.0

type OutputGuardrails struct {
	SafetyPolicies  []SafetyPolicy
	FormatEnforcers []FormatEnforcer
}

OutputGuardrails holds the policy engines and formatting rules.

func (*OutputGuardrails) ValidateAndRepair added in v1.11.0

func (g *OutputGuardrails) ValidateAndRepair(ctx context.Context, response string) (string, error)

ValidateAndRepair applies safety checks and format enforcing to the response.

type QueryType

type QueryType int
const (
	QueryComplex QueryType = iota
	QueryShortFactoid
	QueryMath
)

type RegexBlocklistPolicy added in v1.11.1

type RegexBlocklistPolicy struct {
	// contains filtered or unexported fields
}

RegexBlocklistPolicy enforces that a configurable list of regular expressions are not matched within the LLM output.

func NewRegexBlocklistPolicy added in v1.11.1

func NewRegexBlocklistPolicy(patterns []string) (*RegexBlocklistPolicy, error)

NewRegexBlocklistPolicy creates a new policy with the given string regex patterns. It returns an error if any of the patterns fail to compile.

func (*RegexBlocklistPolicy) Validate added in v1.11.1

func (p *RegexBlocklistPolicy) Validate(ctx context.Context, response string) error

Validate checks the response against all configured regex patterns.

type SafetyPolicy added in v1.11.0

type SafetyPolicy interface {
	Validate(ctx context.Context, response string) error
}

SafetyPolicy defines an interface for validating LLM responses.

type StaticSubAgentDirectory

type StaticSubAgentDirectory struct {
	// contains filtered or unexported fields
}

StaticSubAgentDirectory is the default SubAgentDirectory implementation.

func NewStaticSubAgentDirectory

func NewStaticSubAgentDirectory(subagents []SubAgent) *StaticSubAgentDirectory

NewStaticSubAgentDirectory constructs a directory from the provided sub-agents.

func (*StaticSubAgentDirectory) All

func (d *StaticSubAgentDirectory) All() []SubAgent

All returns the registered sub-agents in registration order.

func (*StaticSubAgentDirectory) Lookup

func (d *StaticSubAgentDirectory) Lookup(name string) (SubAgent, bool)

Lookup retrieves a sub-agent by name.

func (*StaticSubAgentDirectory) Register

func (d *StaticSubAgentDirectory) Register(subAgent SubAgent) error

Register adds a sub-agent to the directory. Duplicate names return an error.

type StaticToolCatalog

type StaticToolCatalog struct {
	// contains filtered or unexported fields
}

StaticToolCatalog is the default in-memory implementation of ToolCatalog used by the runtime.

func NewStaticToolCatalog

func NewStaticToolCatalog(tools []Tool) *StaticToolCatalog

NewStaticToolCatalog constructs a catalog seeded with the provided tools.

func (*StaticToolCatalog) Lookup

func (c *StaticToolCatalog) Lookup(name string) (Tool, ToolSpec, bool)

Lookup returns the tool and its specification if present.

func (*StaticToolCatalog) Register

func (c *StaticToolCatalog) Register(tool Tool) error

Register adds a tool to the catalog using a lower-cased key. Duplicate names return an error.

func (*StaticToolCatalog) Specs

func (c *StaticToolCatalog) Specs() []ToolSpec

Specs returns a snapshot of the tool specifications in registration order.

func (*StaticToolCatalog) Tools

func (c *StaticToolCatalog) Tools() []Tool

Tools returns the registered tools in order.

type SubAgent

type SubAgent interface {
	Name() string
	Description() string
	Run(ctx context.Context, input string) (string, error)
}

SubAgent represents a specialist agent that can be delegated work.

type SubAgentDirectory

type SubAgentDirectory interface {
	Register(subAgent SubAgent) error
	Lookup(name string) (SubAgent, bool)
	All() []SubAgent
}

SubAgentDirectory stores sub-agents by name while preserving insertion order.

type SubAgentTool added in v1.0.9

type SubAgentTool struct {
	// contains filtered or unexported fields
}

SubAgentTool adapts a SubAgent to the Tool interface.

func (*SubAgentTool) Invoke added in v1.0.9

func (t *SubAgentTool) Invoke(ctx context.Context, req ToolRequest) (ToolResponse, error)

func (*SubAgentTool) Spec added in v1.0.9

func (t *SubAgentTool) Spec() ToolSpec

type Tool

type Tool interface {
	Spec() ToolSpec
	Invoke(ctx context.Context, req ToolRequest) (ToolResponse, error)
}

Tool exposes structured metadata and an invocation handler.

func NewAgentTool added in v1.0.9

func NewAgentTool(name, description string, agent *Agent) Tool

NewAgentTool creates a new tool that wraps an Agent.

func NewSubAgentTool added in v1.0.9

func NewSubAgentTool(sa SubAgent) Tool

NewSubAgentTool creates a new tool that wraps a SubAgent.

type ToolCatalog

type ToolCatalog interface {
	Register(tool Tool) error
	Lookup(name string) (Tool, ToolSpec, bool)
	Specs() []ToolSpec
	Tools() []Tool
}

ToolCatalog maintains an ordered set of tools and provides lookup by name.

type ToolChoice added in v0.7.5

type ToolChoice struct {
	UseTool   bool           `json:"use_tool"`
	ToolName  string         `json:"tool_name"`
	Arguments map[string]any `json:"arguments"`
	Reason    string         `json:"reason"`
	Answer    string         `json:"answer"` // Added for one-turn resolution
}

type ToolRequest

type ToolRequest struct {
	SessionID string
	Arguments map[string]any
}

ToolRequest captures an invocation request for a tool.

type ToolResponse

type ToolResponse struct {
	Content  string
	Metadata map[string]string
}

ToolResponse represents the structured response returned by a tool.

type ToolSpec

type ToolSpec struct {
	Name        string           `json:"name"`
	Description string           `json:"description"`
	InputSchema map[string]any   `json:"input_schema"`
	Examples    []map[string]any `json:"examples,omitempty"`
}

ToolSpec describes how the agent should present a tool to the model.

Directories

Path Synopsis
cmd
app command
main.go — fixed agent-mode with provider flag Runs your Agent with optional file context using GenerateWithFiles.
main.go — fixed agent-mode with provider flag Runs your Agent with optional file context using GenerateWithFiles.
codemode command
example command
main.go — fixed agent-mode with provider flag, Postgres memory + CreateSchema Runs your Agent with optional file context using GenerateWithFiles.
main.go — fixed agent-mode with provider flag, Postgres memory + CreateSchema Runs your Agent with optional file context using GenerateWithFiles.
src
adk

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL