agent

package module
v1.14.7 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: Apache-2.0 Imports: 29 Imported by: 2

README

go-agent

Go Version CI Status Go Reference Go Report Card

go-agent is a Go framework for building AI agents with pluggable LLM providers, memory, file context, guardrails, UTCP tool orchestration, and multi-agent coordination.

Use it when you want agent runtime pieces that stay idiomatic in Go:

  • A small agent.Agent core with Generate, GenerateWithFiles, and GenerateStream
  • Provider adapters for Gemini, OpenAI, Anthropic, Ollama, and a local dummy model
  • Short-term memory plus vector-store backed long-term memory
  • ADK modules for wiring models, memory, tools, sub-agents, CodeMode, and UTCP
  • Agent-as-tool patterns for specialist agents and hierarchical workflows
  • Input/output guardrails and checkpoint/restore support
  • Composable retry, timeout, rate-limit, and token-budget model middleware

Local Skills

Agents automatically load local instructions from .skills in the process working directory. Use either the conventional SKILL.md layout or Markdown files directly in .skills:

.skills/
├── code-review/
│   └── SKILL.md
└── release.md

Each skill is added to the system instructions for normal, streaming, file-backed, and tool-planning requests. SKILL.md may include optional YAML-style front matter:

---
name: release
description: Prepare safe releases
---
Run the full test suite before proposing a release.

Set Options.SkillsDir to use another directory, call agent.ReloadSkills() after editing a long-running agent's files, or set DisableSkills: true to opt out.

Install

go get github.com/Protocol-Lattice/go-agent

For this repository:

git clone https://github.com/Protocol-Lattice/go-agent.git
cd go-agent
go test ./...

The module currently targets Go 1.25.10.

Quick Start

This example runs without API keys. It uses the dummy model and in-memory storage, so it is safe for tests and local wiring checks.

package main

import (
	"context"
	"fmt"
	"log"

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

func main() {
	ctx := context.Background()

	mem := memory.NewSessionMemory(
		memory.NewMemoryBankWithStore(memory.NewInMemoryStore()),
		8,
	)

	a, err := agent.New(agent.Options{
		Model:        models.NewDummyLLM("local:"),
		Memory:       mem,
		SystemPrompt: "You are concise and helpful.",
	})
	if err != nil {
		log.Fatal(err)
	}

	out, err := a.Generate(ctx, "demo-session", "Say hello in one sentence.")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(out)
}

Real Model Providers

Use models.NewLLMProvider when you want provider selection from configuration or flags.

model, err := models.NewLLMProvider(ctx, "openai", "gpt-4o-mini", "")
if err != nil {
	log.Fatal(err)
}

Supported provider names:

Provider Aliases Required environment
Gemini gemini, google GOOGLE_API_KEY or GEMINI_API_KEY
Vertex AI vertex, vertexai, vertex-ai GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_LOCATION (or GOOGLE_CLOUD_REGION), and Application Default Credentials
OpenAI openai OPENAI_API_KEY or OPENAI_KEY
Anthropic anthropic, claude ANTHROPIC_API_KEY
Ollama ollama optional OLLAMA_HOST, defaults to http://localhost:11434
OpenRouter openrouter OPENROUTER_API_KEY or OPENROUTER_KEY

Embeddings are selected with memory.AutoEmbedder().

Variable Purpose
ADK_EMBED_PROVIDER openai, google, gemini, ollama, claude, anthropic, or fastembed
ADK_EMBED_MODEL Provider-specific embedding model

If no embedding provider can be created, Lattice falls back to DummyEmbedder.

Vertex AI uses the Google GenAI SDK and Application Default Credentials. For local development, authenticate with gcloud auth application-default login, then set the project and location before selecting the vertex provider:

export GOOGLE_CLOUD_PROJECT="my-project"
export GOOGLE_CLOUD_LOCATION="global"

Model Middleware

Wrap any models.Agent with production policies before passing it to agent.New or returning it from an ADK model provider.

package main

import (
	"context"
	"log"
	"time"

	"github.com/Protocol-Lattice/go-agent/src/models"
	modelmw "github.com/Protocol-Lattice/go-agent/src/models/middleware"
)

func buildModel(ctx context.Context) models.Agent {
	base, err := models.NewLLMProvider(ctx, "openai", "gpt-4o-mini", "")
	if err != nil {
		log.Fatal(err)
	}

	budget, err := modelmw.NewTokenBudget(50_000, nil)
	if err != nil {
		log.Fatal(err)
	}

	model, err := modelmw.Wrap(
		base,
		modelmw.TimeoutPolicy{Duration: 30 * time.Second},
		modelmw.RetryPolicy{
			MaxAttempts:    3,
			InitialBackoff: 200 * time.Millisecond,
			MaxBackoff:     2 * time.Second,
		},
		modelmw.RateLimitPolicy{
			Requests: 60,
			Per:      time.Minute,
			Burst:    5,
			Mode:     modelmw.RateLimitWait,
		},
		modelmw.TokenBudgetPolicy{Budget: budget},
	)
	if err != nil {
		log.Fatal(err)
	}
	return model
}

Middleware is listed outermost first. In the order above, the timeout covers the complete operation, including retry backoff. Every retry consumes a rate limit permit and an estimated input-token charge.

RateLimitWait waits for capacity and respects context cancellation; RateLimitReject returns middleware.ErrRateLimitExceeded immediately. Retry middleware retries stream setup failures only, because restarting a stream after chunks have been delivered could duplicate output.

Token budgets are concurrency-safe. Associate a budget with one request or workflow through its context to override the policy's fallback budget:

requestBudget, _ := modelmw.NewTokenBudget(8_000, nil)
runCtx := modelmw.ContextWithTokenBudget(ctx, requestBudget)

The default estimator uses approximately one token per four UTF-8 bytes. Pass a provider-specific modelmw.TokenEstimator when exact tokenizer behavior is required. Until provider usage metadata is normalized, budgets are estimates: input is rejected before a call, streaming stops before forwarding the chunk that crosses the budget, and an oversized non-streaming response is accounted for but returned as middleware.ErrTokenBudgetExceeded.

ADK Setup

For applications, prefer the ADK when you want dependency injection around model, memory, tools, and runtime features.

package main

import (
	"context"
	"log"

	"github.com/Protocol-Lattice/go-agent/src/adk"
	"github.com/Protocol-Lattice/go-agent/src/adk/modules"
	"github.com/Protocol-Lattice/go-agent/src/memory"
	"github.com/Protocol-Lattice/go-agent/src/models"
)

func main() {
	ctx := context.Background()
	memOpts := memory.DefaultOptions()

	kit, err := adk.New(ctx,
		adk.WithDefaultSystemPrompt("You coordinate a helpful assistant."),
		adk.WithModules(
			modules.NewModelModule("llm", func(ctx context.Context) (models.Agent, error) {
				return models.NewLLMProvider(ctx, "openai", "gpt-4o-mini", "")
			}),
			modules.InMemoryMemoryModule(8, memory.AutoEmbedder(), &memOpts),
		),
	)
	if err != nil {
		log.Fatal(err)
	}

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

	_, _ = a.Generate(ctx, "user-123", "Draft a short project update.")
}

Use direct agent.New for small programs and tests. Use adk.New once you need reusable modules, shared sessions, provider selection, or UTCP runtime wiring.

Graph Workflows

Graph workflows give you ADK Go v2-style deterministic control flow: define nodes, wire them with edges, and pass each node's output to the next node. Function nodes, emitting router nodes, session-aware agent nodes, and agent.Tool nodes can be mixed in the same graph.

For fan-out work, use NewJoinNode as a barrier: it waits for one output from each direct predecessor, then gives the reducer a map[string]any keyed by node name. Set GraphConfig.JoinTimeout to bound how long a partially-filled join may wait; graph cancellation is also respected.

package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/Protocol-Lattice/go-agent/src/adk/workflow"
	"github.com/Protocol-Lattice/go-agent/src/adk/workflowagent"
)

func main() {
	classify := workflow.NewEmittingFunctionNode[string, any]("classify",
		func(_ workflow.Context, input string, emit workflow.EmitFunc) (any, error) {
			route := "LOGISTICS"
			if strings.Contains(strings.ToLower(input), "bug") {
				route = "BUG"
			}
			return nil, emit(&workflow.Event{Output: input, Routes: []any{route}})
		},
		workflow.NodeConfig{},
	)

	bug := workflow.NewFunctionNode[string, string]("bug",
		func(_ workflow.Context, input string) (string, error) {
			return "Handling bug: " + input, nil
		},
		workflow.NodeConfig{},
	)

	fallback := workflow.NewFunctionNode[string, string]("fallback",
		func(_ workflow.Context, input string) (string, error) {
			return "Handling request: " + input, nil
		},
		workflow.NodeConfig{},
	)

	root, err := workflowagent.New(workflowagent.Config{
		Name: "routing_workflow",
		Edges: workflow.Concat(
			workflow.Chain(workflow.Start, classify),
			[]workflow.Edge{
				{From: classify, To: bug, Route: workflow.StringRoute("BUG")},
				{From: classify, To: fallback, Route: workflow.Default},
			},
		),
	})
	if err != nil {
		panic(err)
	}

	out, err := root.Generate(context.Background(), "demo-session", "bug in checkout")
	if err != nil {
		panic(err)
	}
	fmt.Println(out)
}

See cmd/example/graph_workflow for a runnable no-key example.

Durable Workflow Runs

For multi-step work that must survive a process restart or a transient node failure, execute the graph through a workflow.RunStore. Each completed node transition is checkpointed. Resume the same run ID to continue from its saved queue; a completed run returns its saved result without invoking nodes again.

store, err := workflow.NewFileRunStore("./workflow-runs")
if err != nil {
	log.Fatal(err)
}

out, err := graph.StartRun(ctx, store, "invoice-1042", "customer-7", input)
if err != nil {
	// Resolve transient dependencies, restart the process, then continue.
	out, err = graph.ResumeRun(ctx, store, "invoice-1042")
}
if err != nil {
	log.Fatal(err)
}
fmt.Println(out)

workflow.NewInMemoryRunStore() is available for tests. FileRunStore uses one atomically replaced JSON file per run; production applications can provide a database-backed workflow.RunStore. Persisted inputs, outputs, join values, and workflow.Context.State must be JSON-serializable. Execution is at-least-once: a crash after a node side effect but before its checkpoint may invoke that node again, so side-effecting nodes should be idempotent.

Memory

Every agent needs a *memory.SessionMemory. The session layer keeps recent conversation turns and can retrieve long-term records from a vector store.

Common backends:

Backend Constructor or module
In-memory memory.NewInMemoryStore() or modules.InMemoryMemoryModule(...)
PostgreSQL + pgvector memory.NewPostgresStore(...) or modules.InPostgresMemory(...)
Qdrant memory.NewQdrantStore(...) or modules.InQdrantMemory(...)
MongoDB memory.NewMongoStore(...) or modules.InMongoMemory(...)
Neo4j memory.NewNeo4jStore(...) or modules.InNeo4jMemory(...)

Minimal in-memory setup:

mem := memory.NewSessionMemory(
	memory.NewMemoryBankWithStore(memory.NewInMemoryStore()),
	8,
)

Persistent stores that support schema setup implement memory.SchemaInitializer.

store, err := memory.NewPostgresStore(ctx, connStr)
if err != nil {
	log.Fatal(err)
}
defer store.Close()

if err := store.CreateSchema(ctx, ""); err != nil {
	log.Fatal(err)
}

File Context

Use GenerateWithFiles when you already have file bytes in memory. Text files are included in the prompt context; supported image/video MIME types are passed through provider-specific paths where available.

files := []models.File{
	{
		Name: "notes.md",
		MIME: "text/markdown",
		Data: []byte("# Notes\nShip the README update."),
	},
}

out, err := a.GenerateWithFiles(ctx, "demo-session", "Summarize this file.", files)

Tools

Tools are small Go interfaces with a JSON-schema-like spec and an invocation function.

type EchoTool struct{}

func (EchoTool) Spec() agent.ToolSpec {
	return agent.ToolSpec{
		Name:        "echo",
		Description: "Returns the input text.",
		InputSchema: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"input": map[string]any{
					"type": "string",
				},
			},
			"required": []string{"input"},
		},
	}
}

func (EchoTool) Invoke(ctx context.Context, req agent.ToolRequest) (agent.ToolResponse, error) {
	return agent.ToolResponse{Content: fmt.Sprint(req.Arguments["input"])}, nil
}

Register tools directly when constructing an agent to keep them in the agent catalog and expose them through a.Tools() or ADK tool bundles:

a, err := agent.New(agent.Options{
	Model:  model,
	Memory: mem,
	Tools:  []agent.Tool{EchoTool{}},
})

For model-selected tool execution across providers and processes, wire execution through UTCP. Agents can also be exposed as UTCP tools.

Models that implement models.ToolCallingAgent use provider-native tool calls automatically. The OpenAI adapter supports this path; other models continue through the prompt-based planner. Native tool calls are not cached because they may execute side effects.

Agents As Tools

Any *agent.Agent can be wrapped as a local agent.Tool.

researcher, _ := agent.New(agent.Options{
	Model:        researcherModel,
	Memory:       researcherMemory,
	SystemPrompt: "You are a research specialist.",
})

manager, _ := agent.New(agent.Options{
	Model:        managerModel,
	Memory:       managerMemory,
	SystemPrompt: "You delegate research work.",
	Tools: []agent.Tool{
		researcher.AsTool("researcher", "Delegates research to a specialist agent."),
	},
})

You can also register an agent as a UTCP provider:

client, err := utcp.NewUTCPClient(ctx, &utcp.UtcpClientConfig{}, nil, nil)
if err != nil {
	log.Fatal(err)
}

if err := researcher.RegisterAsUTCPProvider(
	ctx,
	client,
	"agent.researcher",
	"Specialist research agent",
); err != nil {
	log.Fatal(err)
}

result, err := client.CallTool(ctx, "agent.researcher", map[string]any{
	"instruction": "Find three facts about pgvector.",
})

Guardrails

Input guardrails validate or transform user input before the model call. Output guardrails validate or repair model responses before they are returned.

inputGuardrails := &agent.InputGuardrails{
	SafetyPolicies: []agent.InputSafetyPolicy{
		agent.NewPromptInjectionDetectorPolicy(nil),
	},
	Transformers: []agent.InputTransformer{
		agent.NewPIIMaskerTransformer(true, true, false, false),
	},
}

outputPolicy, err := agent.NewRegexBlocklistPolicy([]string{
	`(?i)\bpassword\s*=`,
})
if err != nil {
	log.Fatal(err)
}

a, err := agent.New(agent.Options{
	Model:           model,
	Memory:          mem,
	InputGuardrails: inputGuardrails,
	Guardrails: &agent.OutputGuardrails{
		SafetyPolicies: []agent.SafetyPolicy{outputPolicy},
	},
})

See cmd/example/guardrails for a complete runnable example.

Checkpoint And Restore

Checkpointing serializes the agent system prompt, short-term memory, shared-space memberships, and timestamp.

data, err := a.Checkpoint()
if err != nil {
	log.Fatal(err)
}

restored, err := agent.New(agent.Options{
	Model:  model,
	Memory: freshMemory,
})
if err != nil {
	log.Fatal(err)
}

if err := restored.Restore(data); err != nil {
	log.Fatal(err)
}

See cmd/example/checkpoint for a disk-backed example.

CodeMode

Lattice can integrate with UTCP CodeMode and chain execution:

  • adk.WithUTCP(client) makes remote/discovered UTCP tools available to the agent.
  • adk.WithCodeModeUtcp(client, model) enables Go-code tool orchestration through CodeMode.
  • Agent.AllowUnsafeTools must be enabled before codemode.run_code can execute.

Use these features only in trusted environments. CodeMode executes generated Go snippets through the configured UTCP runtime.

Examples

No-key examples:

go run ./cmd/example/composability
go run ./cmd/example/guardrails
go run ./cmd/example/checkpoint

Provider-backed examples:

# Requires GOOGLE_API_KEY or GEMINI_API_KEY by default.
go run ./cmd/example/codemode

# Requires provider credentials and a Qdrant instance unless flags are changed.
go run ./cmd/app -provider openai -model gpt-4o-mini -message "Summarize this project"

# Requires provider credentials and PostgreSQL + pgvector unless flags are changed.
go run ./cmd/example -provider openai -model gpt-4o-mini -message "Summarize this project"

Specialized workflows:

Path Demonstrates
cmd/example/agent_as_tool Registering an agent as a UTCP tool
cmd/example/agent_as_utcp_codemode Orchestrating agent tools through CodeMode
cmd/example/codemode_utcp_workflow Analyst/writer/reviewer workflow
cmd/example/autonomous_agent Configurable multi-agent coordinator
cmd/example/autonomous_cron Autonomous periodic task pattern
cmd/example/claw_cron Task store, permission gateway, and specialist agents
cmd/codemode CodeMode CLI wiring

Repository Layout

.
|-- agent.go                 # Core Agent runtime
|-- agent_stream.go          # Streaming responses
|-- agent_tool.go            # Agent-as-tool and UTCP provider adapters
|-- input_guardrails.go      # Input validation and transforms
|-- safety_policies.go       # Output safety policies
|-- catalog.go               # Tool and sub-agent registries
|-- src/
|   |-- adk/                 # Agent Development Kit and modules
|   |-- cache/               # LRU cache utilities
|   |-- concurrent/          # Worker pool helpers
|   |-- helpers/             # Small CLI/config helpers
|   |-- memory/              # Session memory, engine, stores, embedders
|   |-- models/              # LLM provider adapters
|   |-- subagents/           # Built-in specialist agents
|   `-- swarm/               # Multi-agent coordination primitives
`-- cmd/
    |-- app/                 # Qdrant-backed CLI
    |-- codemode/            # CodeMode CLI
    `-- example/             # Runnable examples

Development

# Run all tests.
go test ./...

# Run one package.
go test ./src/memory/engine

# Run one test.
go test ./... -run TestCheckpoint

# Format changed Go files.
gofmt -w path/to/file.go

FastEmbed support is behind the fastembed build tag:

go test -tags fastembed ./src/memory/embed

Adding Components

Add a model provider by implementing src/models.Agent:

type Agent interface {
	Generate(context.Context, string) (any, error)
	GenerateWithFiles(context.Context, string, []File) (any, error)
	GenerateStream(context.Context, string) (<-chan StreamChunk, error)
}

Add a memory backend by implementing memory.VectorStore. Add memory.SchemaInitializer if the backend needs schema/bootstrap support.

Add a tool by implementing agent.Tool, then register it through agent.Options, an ADK tool provider, or a UTCP provider depending on how it should be discovered and executed.

Add a model policy by implementing middleware.Middleware; use middleware.MiddlewareFunc for small wrappers.

Workspace intelligence

go-agent includes a repository-aware Workspace Intelligence layer for coding agents. It builds a structural index of the codebase and can combine symbol search, imports, dependencies, embeddings, and source context into a bounded context for an agent.

Repository
   │
   ├── AST parser
   ├── Symbol index
   ├── Import/dependency graph
   ├── Embeddings (optional)
   └── File metadata
          │
          ▼
    Hybrid Context Builder
          │
          ▼
        Agent

Basic usage

Build an index for a Go repository:

package main

import (
    "context"
    "fmt"
    "log"

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

func main() {
    ctx := context.Background()

    index := workspace.NewIndex(workspace.DefaultConfig("."))
    if err := index.Build(ctx); err != nil {
        log.Fatal(err)
    }

    results := index.SearchSymbols(ctx, "Authenticate", 10)
    for _, result := range results {
        fmt.Printf("%s %s:%d (score=%d)\n",
            result.Symbol.Kind,
            result.Symbol.File,
            result.Symbol.StartLine,
            result.Score,
        )
    }
}

The default configuration indexes Go files and ignores .git, vendor, node_modules, dist, build, and tmp directories.

Building agent context

BuildContext turns a natural-language task into a bounded set of relevant source files. Structural symbol matches are used first, and semantic retrieval can be enabled when an embedder is configured.

ctx, err := index.BuildContext(context.Background(), workspace.ContextRequest{
    Query:      "Fix the authentication timeout bug",
    MaxBytes:   32 << 10,
    MaxFiles:   8,
    MaxResults: 20,
    Semantic:   true,
})
if err != nil {
    log.Fatal(err)
}

for _, file := range ctx.Files {
    fmt.Printf("--- %s ---\n%s\n", file.Path, file.Content)
}

The context builder:

  1. searches indexed symbols;
  2. optionally performs semantic/vector search;
  3. selects relevant files;
  4. expands the selection by one dependency hop;
  5. enforces a deterministic file and byte budget.

This lets a coding agent retrieve focused repository context instead of loading the whole workspace.

Embeddings are optional. The workspace package uses a small Embedder interface, so an application can connect any embedding provider without coupling the index to a particular vendor.

type Embedder interface {
    Embed(context.Context, string) ([]float32, error)
}

Configure the embedder before building the index:

index := workspace.NewIndex(workspace.DefaultConfig("."))
index.SetEmbedder(myEmbedder)

if err := index.Build(ctx); err != nil {
    log.Fatal(err)
}

results, err := index.SearchSemantic(ctx, "authentication timeout", 10)
if err != nil {
    log.Fatal(err)
}

Semantic search is optional; symbol and structural search continue to work without an embedding provider.

Incremental updates

For long-running coding agents, re-index only changed files:

err := index.Update(ctx, []workspace.FileChange{
    {
        Path: "internal/auth/service.go",
        Kind: workspace.ChangeModified,
    },
})
if err != nil {
    log.Fatal(err)
}

Deleted files are removed from the file, symbol, import, and embedding indexes:

err := index.Update(ctx, []workspace.FileChange{
    {
        Path: "internal/auth/legacy.go",
        Kind: workspace.ChangeDeleted,
    },
})

Only modified files are parsed and, when semantic indexing is enabled, re-embedded.

Live workspace watcher

Use workspace.Watcher to keep the index synchronized with a working tree:

watcher := &workspace.Watcher{
    Index:    index,
    Interval: 500 * time.Millisecond,
}

go func() {
    if err := watcher.Run(ctx); err != nil && !errors.Is(err, context.Canceled) {
        log.Printf("workspace watcher: %v", err)
    }
}()

The watcher uses dependency-free polling. It detects created, modified, and deleted files and forwards changes to Index.Update.

Dependencies

The index also exposes imports and module-aware dependency relationships:

imports := index.Imports("internal/auth/service.go")

for _, path := range imports {
    fmt.Println(path)
}

for _, dependency := range index.Dependencies("internal/auth/service.go") {
    fmt.Println("depends on:", dependency)
}

This structural graph can be used by higher-level context ranking to expand from a matched symbol into the implementation and its directly related packages.

For coding agents, the intended architecture is:

User task
   │
   ▼
Workspace Index
   ├── symbols
   ├── imports
   ├── dependencies
   └── embeddings
   │
   ▼
Context Builder
   ├── lexical relevance
   ├── semantic relevance
   ├── dependency expansion
   └── token/byte budget
   │
   ▼
Agent
   │
   ├── plan
   ├── edit
   ├── test
   └── validate

For production coding agents, keep the index alive for the lifetime of the agent and run the watcher alongside the agent execution loop. This avoids rebuilding the repository index after every request.

Autonomous UTCP agent CLI

This project provides an OpenClaw-like CLI on top of github.com/Protocol-Lattice/go-agent:

  • UTCP codemode via WithCodeModeUtcp(...)
  • Specialist agents registered as UTCP tools via RegisterAsUTCPProvider(...)
  • Command-driven UX: agent, loop, chat, tools, doctor

Commands

  • agent: single-turn execution (default target is coordinator)
  • loop: autonomous multi-step execution until AUTONOMOUS_DONE, with bounded self-healing recovery after execution failures
  • chat: interactive REPL with runtime agent switching
  • tools: list configured tools or live registered UTCP tools
  • doctor: validate provider/model/env setup

Specialist UTCP Tools

Default tools are prefixed with local_ and registered at runtime:

  • local_researcher.run
  • local_builder.run
  • local_reviewer.run

Common Flags

  • --provider (default from LLM_PROVIDER, fallback gemini)
  • --model (default from LLM_MODEL, fallback gemini-3-flash-preview)
  • --session-id (default from AGENT_SESSION, fallback autonomous-session)
  • --context-window (default 20)
  • --max-recoveries (default 2; total self-healing recovery budget for the loop, 0 disables recovery)
  • --tool-prefix (default from UTCP_TOOL_PREFIX, fallback local.)

Usage

# Single turn through coordinator
go run ./cmd/example/autonomous_agent agent \
  --message "Draft rollout plan for UTCP migration"

# Single turn through specialist
go run ./cmd/example/autonomous_agent agent \
  --agent reviewer \
  --message "What could fail in this deploy plan?"

# Autonomous loop
go run ./cmd/example/autonomous_agent loop \
  --goal "Design and verify a UTCP-based repository triage workflow" \
  --max-steps 8

# Interactive mode
go run ./cmd/example/autonomous_agent chat --goal "Prepare release plan"

# Tools
go run ./cmd/example/autonomous_agent tools
go run ./cmd/example/autonomous_agent tools --live

# Environment checks
go run ./cmd/example/autonomous_agent doctor

Chat Commands

Inside chat:

  • /help
  • /tools
  • /agent <name>
  • /exit

Notes

  • You must provide provider credentials through environment variables expected by your selected provider.
  • Runtime now validates provider credentials before bootstrapping agents and reports missing keys explicitly.
  • If ADK_EMBED_PROVIDER is unset, it is inferred for known providers (gemini, openai, ollama); otherwise set it manually.
  • loop completes when the model emits AUTONOMOUS_DONE; otherwise it exits at --max-steps. Failed iterations consume the loop's --max-recoveries budget without consuming another step. Each recovery includes the failure in the scratchpad so the coordinator can choose a different approach. Context cancellation and deadline errors are never retried.
  • agent --thinking, agent --local, and agent --deliver are included for OpenClaw-like UX compatibility.

Next steps

  • Run the no-key graph workflow to learn the node and edge model.
  • Use the autonomous CLI when you want a ready-made coordinator and specialist setup.
  • Read docs/workspace-intelligence.md before building a repository-aware coding agent.
  • Browse cmd/example for runnable patterns rather than copying partial snippets, then run go test ./... before upgrading dependencies or changing runtime behavior.

Troubleshooting

Missing API Key

Provider constructors fail when required keys are missing. Set the matching environment variable or use models.NewDummyLLM for local tests.

No Long-Term Memory Results

Check that the session uses a store-backed MemoryBank, an embedder is configured, and records have been flushed or stored through the memory engine.

PostgreSQL Vector Errors

For pgvector-backed memory, enable the extension:

CREATE EXTENSION IF NOT EXISTS vector;

Then run the store schema initializer:

_ = store.CreateSchema(ctx, "")
Tool Not Found

Confirm the tool name exactly matches the registered UTCP tool name. Fully qualified names such as agent.researcher are preferred when multiple providers expose similar tools.

License

See LICENSE.

Documentation

Index

Constants

View Source
const DefaultSkillsDir = ".skills"

DefaultSkillsDir is the directory scanned automatically when an Agent is created. A missing directory is treated as an empty skill set.

Variables

This section is empty.

Functions

func NewObservedUTCPClient added in v1.14.7

func NewObservedUTCPClient(client utcp.UtcpClientInterface) utcp.UtcpClientInterface

func SaveSkill added in v1.14.4

func SaveSkill(dir string, skill SkillDefinition) (string, error)

SaveSkill persists a v2 skill in the existing human-editable SKILL.md format.

func SkillPrompt added in v1.14.4

func SkillPrompt(routing SkillRouting) string

func ValidateSkill added in v1.14.4

func ValidateSkill(skill SkillDefinition) error

func WithSkillRouting added in v1.14.4

func WithSkillRouting(ctx context.Context, routing SkillRouting) context.Context

func WithToolExecutionObserver added in v1.14.7

func WithToolExecutionObserver(ctx context.Context, observer func(ToolExecutionEvent)) context.Context

WithToolExecutionObserver attaches a per-request observer to the context. Observers are request-scoped and therefore safe when the same Agent serves multiple concurrent WebUI sessions.

Types

type Agent

type Agent struct {
	UTCPClient utcp.UtcpClientInterface

	Shared   *memory.SharedSession
	CodeMode *codemode.CodeModeUTCP

	AllowUnsafeTools bool
	Guardrails       *OutputGuardrails
	InputGuardrails  *InputGuardrails
	// 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) ActiveToolSpecs added in v1.14.4

func (a *Agent) ActiveToolSpecs(routing SkillRouting) []tools.Tool

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. GenerateWithFiles runs the full orchestration pipeline (direct tool → subagent → CodeMode → UTCP tool loop) before falling back to a file-aware model call. Files are forwarded to the planner so tools can be selected with attachment context, but tool execution still uses the normal UTCP arguments.

func (*Agent) GenerateWithSkillRouting added in v1.14.4

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

GenerateWithSkillRouting runs one request with an isolated skill/tool scope.

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) ReloadSkills added in v1.14.4

func (a *Agent) ReloadSkills() error

ReloadSkills reloads the configured local skills directory. It is useful for long-running agents whose .skills files are edited after startup.

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) RouteSkills added in v1.14.4

func (a *Agent) RouteSkills(input string, limit int) (SkillRouting, error)

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) SkillRegistry added in v1.14.4

func (a *Agent) SkillRegistry() (*SkillRegistry, error)

func (*Agent) Skills added in v1.14.4

func (a *Agent) Skills() []Skill

Skills returns a snapshot of the skills currently loaded by the Agent.

func (*Agent) SubAgents

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

func (*Agent) ToolSpecs

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

func (*Agent) Tools

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

func (*Agent) WebUISkills added in v1.14.7

func (a *Agent) WebUISkills() []SkillDefinition

WebUISkills returns the skills currently loaded by the Agent as SkillDefinition values suitable for the Web UI. The runtime Agent stores legacy Skill documents, while SkillDefinition is the richer declarative Skill System 2.0 type, so the legacy fields are wrapped without inventing v2 metadata that is not present at runtime.

func (*Agent) WebUITools added in v1.14.7

func (a *Agent) WebUITools() []ToolSpec

WebUITools returns tool metadata currently visible to the Agent. Invocation remains inside the agent runtime.

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 InputGuardrails added in v1.11.4

type InputGuardrails struct {
	SafetyPolicies []InputSafetyPolicy
	Transformers   []InputTransformer
}

InputGuardrails holds the input safety policies and transformers.

func (*InputGuardrails) ValidateAndTransform added in v1.11.4

func (g *InputGuardrails) ValidateAndTransform(ctx context.Context, input string) (string, error)

ValidateAndTransform applies safety checks and transformers to the input.

type InputSafetyPolicy added in v1.11.4

type InputSafetyPolicy interface {
	Validate(ctx context.Context, input string) error
}

InputSafetyPolicy defines an interface for validating LLM inputs.

type InputTransformer added in v1.11.4

type InputTransformer interface {
	Transform(ctx context.Context, input string) (string, error)
}

InputTransformer defines an interface for modifying or sanitizing LLM inputs.

type LLMEvaluatorInputPolicy added in v1.11.4

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

LLMEvaluatorInputPolicy uses a secondary language model to evaluate the safety of the proposed input query.

func NewLLMEvaluatorInputPolicy added in v1.11.4

func NewLLMEvaluatorInputPolicy(model models.Agent, promptTemplate string) *LLMEvaluatorInputPolicy

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

func (*LLMEvaluatorInputPolicy) Validate added in v1.11.4

func (p *LLMEvaluatorInputPolicy) Validate(ctx context.Context, input string) error

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

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 ObservedUTCPClient added in v1.14.7

type ObservedUTCPClient struct {
	utcp.UtcpClientInterface
}

ObservedUTCPClient wraps a UTCP client without changing its behavior. Tool calls made directly by the Agent and calls made from CodeMode both pass through this wrapper, which gives us one canonical execution event stream.

func (*ObservedUTCPClient) CallTool added in v1.14.7

func (c *ObservedUTCPClient) CallTool(ctx context.Context, toolName string, args map[string]any) (any, error)

func (*ObservedUTCPClient) CallToolStream added in v1.14.7

func (c *ObservedUTCPClient) CallToolStream(ctx context.Context, toolName string, args map[string]any) (transports.StreamResult, error)

type Options

type Options struct {
	Model        models.Agent
	Memory       *memory.SessionMemory
	SystemPrompt string
	ContextLimit int
	// SkillsDir is scanned for local skill instructions. When empty, .skills
	// in the process working directory is used.
	SkillsDir string
	// DisableSkills prevents automatic loading of local skill instructions.
	DisableSkills     bool
	Tools             []Tool
	SubAgents         []SubAgent
	ToolCatalog       ToolCatalog
	SubAgentDirectory SubAgentDirectory
	UTCPClient        utcp.UtcpClientInterface
	CodeMode          *codemode.CodeModeUTCP
	Shared            *memory.SharedSession
	AllowUnsafeTools  bool
	Guardrails        *OutputGuardrails
	InputGuardrails   *InputGuardrails
}

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 PIIMaskerTransformer added in v1.11.4

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

PIIMaskerTransformer automatically detects personal data and replaces it with generic descriptors like [EMAIL] or [PHONE].

func NewPIIMaskerTransformer added in v1.11.4

func NewPIIMaskerTransformer(maskEmail, maskPhone, maskSSN, maskCards bool) *PIIMaskerTransformer

NewPIIMaskerTransformer creates a new PII masker transformer configuring the categories to mask.

func (*PIIMaskerTransformer) Transform added in v1.11.4

func (t *PIIMaskerTransformer) Transform(ctx context.Context, input string) (string, error)

Transform processes the input string and masks matches for selected categories.

type PromptInjectionDetectorPolicy added in v1.11.4

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

PromptInjectionDetectorPolicy scans the user query for common phrases associated with prompt injection attacks (heuristics).

func NewPromptInjectionDetectorPolicy added in v1.11.4

func NewPromptInjectionDetectorPolicy(customPatterns []string) *PromptInjectionDetectorPolicy

NewPromptInjectionDetectorPolicy creates a new injection detector policy. If customPatterns is provided, they are converted to lowercase and appended to the default patterns list.

func (*PromptInjectionDetectorPolicy) Validate added in v1.11.4

func (p *PromptInjectionDetectorPolicy) Validate(ctx context.Context, input string) error

Validate checks the input for potential prompt injection attempts.

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 RegexInputBlocklistPolicy added in v1.11.4

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

RegexInputBlocklistPolicy validates that the input does not match a configurable list of regular expression patterns.

func NewRegexInputBlocklistPolicy added in v1.11.4

func NewRegexInputBlocklistPolicy(patterns []string) (*RegexInputBlocklistPolicy, error)

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

func (*RegexInputBlocklistPolicy) Validate added in v1.11.4

func (p *RegexInputBlocklistPolicy) Validate(ctx context.Context, input string) error

Validate checks the input against all configured regex patterns.

type RegexInputReplaceTransformer added in v1.11.4

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

RegexInputReplaceTransformer replaces occurrences of a regular expression pattern with a specified replacement string.

func NewRegexInputReplaceTransformer added in v1.11.4

func NewRegexInputReplaceTransformer(pattern string, replacement string) (*RegexInputReplaceTransformer, error)

NewRegexInputReplaceTransformer creates a new regex replace transformer.

func (*RegexInputReplaceTransformer) Transform added in v1.11.4

func (t *RegexInputReplaceTransformer) Transform(ctx context.Context, input string) (string, error)

Transform replaces all matched patterns in the input with the replacement string.

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 Skill added in v1.14.4

type Skill struct {
	Name         string
	Description  string
	Instructions string
	Path         string
}

Skill is a local instruction document available to an Agent. Instructions are loaded from Markdown, while the optional name and description front matter fields make the rendered prompt easier for a model to navigate.

func LoadSkills added in v1.14.4

func LoadSkills(dir string) ([]Skill, error)

LoadSkills discovers skill documents below dir. It supports the conventional .skills/<name>/SKILL.md layout as well as Markdown files placed directly in .skills. The returned order is stable by path.

A missing skills directory is not an error, so applications can opt in by simply creating it. Symlinks are ignored to keep a skills directory from unexpectedly reading instructions outside its configured root.

type SkillDefinition added in v1.14.4

type SkillDefinition struct {
	Skill
	Version      string
	Tags         []string
	Triggers     []string
	Dependencies []string
	Tools        []string
	Evaluator    SkillEvaluator
	Enabled      bool
}

SkillDefinition is the declarative Skill System 2.0 representation.

func LoadSkillDefinitions added in v1.14.4

func LoadSkillDefinitions(dir string) ([]SkillDefinition, error)

LoadSkillDefinitions upgrades the existing .skills format without breaking it.

type SkillEvaluation added in v1.14.4

type SkillEvaluation struct {
	SkillName string
	Input     string
	Output    string
	Metadata  map[string]any
}

type SkillEvaluationResult added in v1.14.4

type SkillEvaluationResult struct {
	Score    float64
	Passed   bool
	Feedback string
}

type SkillEvaluator added in v1.14.4

type SkillEvaluator interface {
	Evaluate(context.Context, SkillEvaluation) (SkillEvaluationResult, error)
}

type SkillMatch added in v1.14.4

type SkillMatch struct {
	Skill  SkillDefinition
	Score  float64
	Reason string
}

type SkillRegistry added in v1.14.4

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

func NewSkillRegistry added in v1.14.4

func NewSkillRegistry() *SkillRegistry

func (*SkillRegistry) Get added in v1.14.4

func (r *SkillRegistry) Get(name string) (SkillDefinition, bool)

func (*SkillRegistry) List added in v1.14.4

func (r *SkillRegistry) List() []SkillDefinition

func (*SkillRegistry) Match added in v1.14.4

func (r *SkillRegistry) Match(input string, limit int) []SkillMatch

Match performs deterministic lightweight routing before the model call.

func (*SkillRegistry) Register added in v1.14.4

func (r *SkillRegistry) Register(skill SkillDefinition) error

func (*SkillRegistry) Remove added in v1.14.4

func (r *SkillRegistry) Remove(name string)

func (*SkillRegistry) ResolveDependencies added in v1.14.4

func (r *SkillRegistry) ResolveDependencies(names []string) ([]SkillDefinition, error)

ResolveDependencies returns dependency-first order and detects cycles.

type SkillRouting added in v1.14.4

type SkillRouting struct {
	Matches []SkillMatch
	Skills  []SkillDefinition
	Tools   map[string]struct{}
}

func (SkillRouting) ActiveSkillNames added in v1.14.4

func (r SkillRouting) ActiveSkillNames() []string

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"`
	FinalAnswer string         `json:"final_answer"`
}

type ToolExecutionEvent added in v1.14.7

type ToolExecutionEvent struct {
	Type      string         `json:"type"`
	Tool      string         `json:"tool"`
	Arguments map[string]any `json:"arguments,omitempty"`
	Result    any            `json:"result,omitempty"`
	Error     string         `json:"error,omitempty"`
}

ToolExecutionEvent describes one real UTCP tool execution. It is emitted from the same client used by the agent and CodeMode, so the WebUI can render the actual execution order instead of inferring tool calls from model text.

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.

type WorkspaceAgent added in v1.14.5

type WorkspaceAgent struct {
	Agent   *Agent
	Index   *workspace.Index
	Context workspace.ContextRequest
}

WorkspaceAgent decorates an Agent with repository-aware context retrieval. The underlying Agent remains responsible for tools, skills, memory, CodeMode, sub-agents, guardrails, and model execution.

func NewWorkspaceAgent added in v1.14.5

func NewWorkspaceAgent(a *Agent, index *workspace.Index) (*WorkspaceAgent, error)

NewWorkspaceAgent attaches Workspace Intelligence to an existing Agent. The index should normally be built once and kept alive for the lifetime of the agent. If an Embedder is configured, set Context.Semantic to true.

func (*WorkspaceAgent) Generate added in v1.14.5

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

Generate retrieves repository context for the request and injects it into the underlying Agent prompt. Tool execution and all other Agent behavior are delegated unchanged to the wrapped Agent.

func (*WorkspaceAgent) GenerateWithFiles added in v1.14.5

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

GenerateWithFiles preserves normal Agent file handling while also adding repository context selected from the workspace index.

Directories

Path Synopsis
Package arena provides a small, deterministic evaluation harness for go-agent.
Package arena provides a small, deterministic evaluation harness for go-agent.
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.
example/internal/filestore
Package filestore provides the lightweight JSON-backed memory used by the autonomous examples.
Package filestore provides the lightweight JSON-backed memory used by the autonomous examples.
gateway command
src
adk
models/middleware
Package middleware provides composable policies for model calls.
Package middleware provides composable policies for model calls.

Jump to

Keyboard shortcuts

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