agents-sdk

module
v0.0.0-...-a80ce91 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: MIT

README

Go Agents SDK

A Go SDK for building AI agents, reimagined around a filesystem-first design inspired by Vercel's Eve. Core agent capabilities live in conventional files and folders, so projects are easy to inspect, extend, and operate — while the underlying engine remains a plain Go library with multi-provider support, tools, skills, handoffs, guardrails, memory, and tracing.

Go Reference

The filesystem is the authoring interface

An agent is a directory. Conventional files describe its behaviour:

myagent/
  agent.yaml            # model, provider, temperature, tools
  instructions.md       # system prompt
  skills/
    refunds.md          # on-demand knowledge (YAML front-matter + markdown body)
  subagents/
    billing/            # a delegated agent (handoff), same layout recursively
      agent.yaml
      instructions.md
  schedules/
    nightly.yaml        # cron triggers
  channels/             # integration adapters (HTTP is built in)
Path Purpose
agent.yaml Model, provider, sampling params, and the tools the agent may use
instructions.md The system prompt
skills/*.md Procedures/knowledge surfaced to the model and loaded on demand
subagents/<n>/ Specialized agents the parent can hand off to
schedules/*.yaml Cron expressions that trigger the agent autonomously
agent.yaml
name: assistant
provider: openai          # openai | anthropic | gemini | ollama
model: gpt-4o
temperature: 0.7
max_tokens: 1024
tools:
  - current_time
  - add
A skill (skills/weather.md)
---
name: weather
description: How to answer questions about the weather using a public API.
---
1. Determine the location the user is asking about.
2. Use the `http_get` tool to fetch https://wttr.in/<location>?format=3.
3. Summarize the result in one friendly sentence.

Skills are not dumped into the prompt. Instead the model sees a catalog of skill names and descriptions and pulls a skill's full body only when needed, via the built-in load_skill tool.

Remote skills (pinned by commit SHA)

Skills can be shared across projects — like a plugin marketplace — by declaring remote sources in agent.yaml. They're resolved at load time (never by the model at runtime), pinned to an immutable commit SHA, integrity-checked against an optional sha256, restricted to an allowlisted host, and cached locally. This gives you marketplace ergonomics without the prompt-injection/SSRF risk of fetching model-supplied URLs.

# agent.yaml — local skills/ are loaded too, in addition to these
skills:
  - source: github.com/acme/agent-skills/refunds.md
    ref: a1b2c3d4         # commit SHA — required for github.com sources
    sha256: 9f86d0…       # optional integrity pin
  - source: https://example.com/pinned/skill.md
    sha256: 0b1c2d…

Defaults are safe: only raw.githubusercontent.com / gist.githubusercontent.com are allowed unless you widen the allowlist via loader.LoadWithOptions.

Subagent handoffs: three context modes

Each subagent handoff can carry context in one of three ways, set per subagent in the parent's agent.yaml:

subagents:
  researcher: forked   # shared (default) | fresh | forked
Mode Subagent sees Returns to parent? Use case
shared the full live history no (transfers control) routing/triage
fresh only the task yes clean delegation, no context bleed
forked a copy of the history yes independent exploration; parent resumes unaffected

In code: agents.WithHandoffs(sub) (shared) or agents.WithHandoff(sub, agents.ContextFresh|ContextForked). The model triggers a handoff by calling the auto-generated handoff_<name> tool; the runner intercepts it and applies the configured mode.

MCP servers (Model Context Protocol)

Agents gain real, dynamic tools by connecting to MCP servers declared in agent.yaml. Servers are connected at load time over stdio (local subprocess) or streamable-HTTP (remote), their tools are listed and adapted into the SDK's tool interface, and they're closed when the agent is. This is also how a CLI-run agent gets tools beyond the three builtins — without recompiling.

# agent.yaml
mcp:
  - name: github             # tools are exposed to the model as github_<tool>
    transport: stdio
    command: ["npx", "-y", "@modelcontextprotocol/server-github"]
    env: { GITHUB_TOKEN: "${GITHUB_TOKEN}" }   # $VARs are expanded
  - name: search
    transport: http
    url: https://mcp.example.com
    headers: { Authorization: "Bearer ${SEARCH_KEY}" }
    tools: [web_search]      # optional allowlist of tool names

Built on the official modelcontextprotocol/go-sdk. Servers are declared in config, never chosen by the model; tool names are namespaced by server to avoid collisions. From code, use mcp.ConnectAll and add manager.Tools() to an agent, or just let the loader do it. Remember to defer agent.Close() to release MCP connections.

Observability: logging & tracing

Every run is instrumented. The runner emits structured logs (log/slog) and a span tree covering the run, each turn, every LLM call, tool execution (including skills' load_skill and MCP tools), guardrails, and handoffs/ delegations.

runner := agents.NewRunner(
    agents.WithProvider(p),
    agents.WithLogger(tracing.NewLogger(os.Stderr, slog.LevelDebug)), // structured logs
    agents.WithTracer(tracing.NewConsoleTracer()),                    // indented span tree
)
result, _ := runner.Run(ctx, agent, "hello")

// The full trace tree is always captured programmatically, regardless of tracer:
for _, span := range result.Traces {
    fmt.Printf("%*s%s %s\n", span.Depth*2, "", span.Name, span.Duration)
}

Console trace output looks like:

[trace] agent.run (12.4ms) agent=assistant turns=2 tokens=345
[trace]   turn (8.1ms) n=0 agent=assistant
[trace]     llm.complete (6.0ms) model=gpt-4o tokens=210 tool_calls=1
[trace]     tool.execute (1.2ms) tool=add args={"a":5,"b":3} result_chars=1
[trace]   turn (3.9ms) n=1 agent=assistant
[trace]     llm.complete (3.8ms) model=gpt-4o tokens=135 tool_calls=0

Tracers available in pkg/tracing: NewConsoleTracer, NewSlogTracer, NewRecorder (programmatic capture), and NewTee to combine them. With the CLI, enable both with -v/--verbose, or set EVE_LOG=debug / EVE_TRACE=1.

The eve CLI

go build -o eve ./cmd/eve

eve init myagent                     # scaffold a new agent directory
eve validate myagent                 # load and report what was found (no API key needed)
eve run myagent "what time is it?"   # run a single turn
eve dev myagent                      # serve over HTTP: POST /chat {"input": "..."}
eve schedules myagent                # run the agent's cron schedules

Provider credentials come from the environment:

export PROVIDER=openai            # optional; otherwise auto-detected
export OPENAI_API_KEY=...         # or ANTHROPIC_API_KEY / GEMINI_API_KEY / OLLAMA_HOST

Because Go tools are compiled functions, agent.yaml references tools by name. The CLI ships a small builtin registry (current_time, add, http_get). To use your own Go tools, load the agent from your own program with a custom registry (see below).

Library API

The CLI is a thin shell over the library. Load a filesystem agent with your own tools and run it:

package main

import (
	"context"
	"fmt"

	"github.com/ryanhill4L/agents-sdk/pkg/agents"
	"github.com/ryanhill4L/agents-sdk/pkg/loader"
	"github.com/ryanhill4L/agents-sdk/pkg/providers"
	"github.com/ryanhill4L/agents-sdk/pkg/tools"
)

func main() {
	// 1. Register your Go tools by name.
	reg := tools.NewRegistry()
	reg.MustRegister(tools.NewTool("add", "Adds two numbers",
		func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
			return args["a"].(float64) + args["b"].(float64), nil
		},
		tools.Param{Name: "a", Type: "number", Required: true},
		tools.Param{Name: "b", Type: "number", Required: true},
	))

	// 2. Load the agent from the filesystem.
	agent, err := loader.Load("myagent", reg)
	if err != nil {
		panic(err)
	}

	// 3. Run it with a provider resolved from the environment.
	provider, _ := providers.Resolve(agent.Provider)
	runner := agents.NewRunner(agents.WithProvider(provider))

	result, err := runner.Run(context.Background(), agent, "What is 21 + 21?")
	if err != nil {
		panic(err)
	}
	fmt.Println(result.FinalOutput)
}

You can also build agents entirely in code with functional options (agents.NewAgent, agents.WithInstructions, agents.WithTools, agents.WithSkills, agents.WithHandoffs, …) — the loader simply translates files into those calls.

Packages

Package Responsibility
pkg/agents Agent, Runner, the turn loop, handoffs, skills wiring
pkg/loader Builds an Agent from a directory (agent.yaml, instructions.md, …)
pkg/skills Skill parsing, the catalog, and the load_skill builtin tool
pkg/tools Tool interface, Registry, FunctionTool (reflection), SimpleTool
pkg/mcp Connects MCP servers (stdio/HTTP) and adapts their tools to tools.Tool
pkg/channels Integration adapters; built-in HTTP channel (powers eve dev)
pkg/schedules Cron parsing and a dependency-free scheduler
pkg/providers OpenAI, Anthropic, Gemini, and Ollama integrations + Resolve
pkg/memory SQLite-backed session persistence
pkg/guardrails Pluggable input validation
pkg/tracing Span-based observability (no-op and console tracers)

Providers

Provider Env var Notes
OpenAI OPENAI_API_KEY GPT-4o and friends
Anthropic ANTHROPIC_API_KEY Claude models
Gemini GEMINI_API_KEY Google Gemini
Ollama OLLAMA_HOST Local models (default :11434)

Examples

Development

make build          # build all packages
make build-cli      # build the eve CLI into bin/eve
make test           # run tests
make run-fs-example # validate the filesystem-first example
make check          # fmt + vet + tidy

License

MIT — see LICENSE.

Directories

Path Synopsis
cmd
eve command
Command eve is the CLI for the Eve-inspired, filesystem-first agent framework.
Command eve is the CLI for the Eve-inspired, filesystem-first agent framework.
pkg
channels
Package channels provides integration adapters that connect an agent to the outside world.
Package channels provides integration adapters that connect an agent to the outside world.
loader
Package loader builds agents from the filesystem.
Package loader builds agents from the filesystem.
mcp
Package mcp connects an agent to Model Context Protocol (MCP) servers and exposes their tools through the SDK's tools.Tool interface.
Package mcp connects an agent to Model Context Protocol (MCP) servers and exposes their tools through the SDK's tools.Tool interface.
schedules
Package schedules implements Eve-style scheduled triggers: an agent can be woken on a cron expression with a fixed input.
Package schedules implements Eve-style scheduled triggers: an agent can be woken on a cron expression with a fixed input.
skills
Package skills implements Eve-style on-demand skills: units of knowledge or procedure stored as markdown files.
Package skills implements Eve-style on-demand skills: units of knowledge or procedure stored as markdown files.
tracing
Package tracing provides span-based tracing and structured logging for agent runs.
Package tracing provides span-based tracing and structured logging for agent runs.

Jump to

Keyboard shortcuts

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