golem

package module
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2026 License: MIT Imports: 9 Imported by: 0

README

golem

Golem

Golem is a Go-first framework for building dependable AI agents: typed dependencies and outputs, explicit tools, composable models, and an observable execution loop.

It takes inspiration from the ergonomics of Python agent frameworks such as Pydantic AI, but follows Go's strengths instead: compile-time contracts, context.Context, explicit error handling, small interfaces, and standard-library-friendly integrations.

Status

v0.7.2 — the core execution contract includes typed agents, evidence-preserving runs — successful and failed alike, via RunError.Partial — self-correction, retries with fallback models, streaming on every adapter including Bedrock, structured output, explicit tool deadlines and choice, opt-in ordered parallel tool execution, multimodal image input, thinking content carried end to end with provider signatures, deferred tools that pause a run for human approval or external results, bounded history, token/request/tool-call usage bounds, request tuning, run events, and agent delegation. The common tools (web fetch, file read, command execution, agent skills) ship alongside an MCP client that bridges server tools over stdio or streamable HTTP, with provider adapters for OpenAI-compatible APIs (twelve services plus the local Ollama and LM Studio runtimes), Anthropic, Google Gemini, Azure OpenAI, and AWS Bedrock. The guides publish as a documentation site. The public API remains intentionally small; additive changes only until v1.

Direction

  • Make a useful agent the shortest path: configure a model, declare tools, run with dependencies, get a typed result.
  • Make important behavior explicit: model calls, tool execution, iteration limits, usage, and validation are visible in the run result.
  • Keep infrastructure replaceable: applications choose models, tracing, storage, and transport through narrow interfaces.
  • Prefer Go-native composition over ports of Python metaprogramming.

Read the foundation brief before proposing a new public abstraction. Contributor and coding-agent rules live in AGENTS.md, and the development roadmap lives in docs/ROADMAP.md.

Installation

go get github.com/abubakarsiddik31/golem

Golem needs Go 1.26.5 or newer and depends only on the Go standard library.

Quick start

client, err := openai.New(openai.Config{
    APIKey: os.Getenv("OPENAI_API_KEY"),
    Model:  "gpt-4o-mini",
})
agent, err := golem.New[struct{}, string](client,
    golem.DecodeFunc[string](func(_ context.Context, r model.Response) (string, error) {
        return r.Message.Content, nil
    }),
)
result, err := agent.Run(ctx, golem.RunContext[struct{}]{}, "Reply with exactly the word: pong")

Every run returns the typed output, the full normalized conversation (result.Messages, durable additive-only JSON), and cumulative usage — and fails with a RunError carrying an inspectable stage (model, tool, decode, loop, usage) that preserves the cause for errors.Is and errors.As.

Documentation

Guides are the source of truth for each capability; this README only indexes them.

Guide Covers
Getting started The smallest agent, result shape, error stages
Providers OpenAI-compatible and Anthropic adapters, error classification
Tools and dependencies Typed tools, dependencies, and controlled parallel execution
Web fetch The webfetch common tool: URLs as agent-readable text
File read The fileread common tool: workspace files as agent-readable text
Command execution The shell common tool: one command, combined output
Agent skills The skills common tool: standard SKILL.md folders loaded on demand
MCP client Bridging Model Context Protocol servers into agent tools
Agent delegation One agent exposed as another agent's tool
Tool timeouts Context-aware deadlines for individual tool calls
Conversations and history Multi-turn runs, durable message JSON, history trimming
Multimodal input Images in prompts, per-provider mapping
Structured output Output schemas, tool-mode output, DecodeJSON
Self-correction Output and tool rejection budgets (ModelRetry)
Retries Transient model failures, backoff, fallback models
Streaming RunStream, the streaming capability port, SSE adapters
Thinking Reasoning models: requesting thinking, keeping signatures, replay
Run events Observing attempts, tool calls, and corrections as they happen
Usage limits Bounding tokens, requests, and tool calls
Testing without a provider Deterministic fakes, contract assertions
Deferred tools Approvals and external results: pausing a run and resuming it

Design decisions live in docs/adr/; each guide links the ADR that decided its behavior.

Examples

Runnable programs live in examples/; provider-backed ones print instructions and exit unless their API key is set.

Example Shows
minimal Smallest agent against an OpenAI-compatible API
tools Typed tool with a run dependency
web-fetch The webfetch common tool fetching a local test page
file-read The fileread common tool reading a workspace file
command-execution The shell common tool running one local command
skills The skills common tool loading a standard SKILL.md folder
mcp-client MCP server bridged into agent tools over stdio
mcp-http MCP server bridged over streamable HTTP
delegation A specialist agent delegated to as a tool
structured-output Output schema + JSON decoding
structured-output-tool Tool-mode structured output
streaming RunStream printing fragments as they arrive
run-events WithRunEvents printing the event sequence of a run
partial-evidence A failed run's RunError.Partial evidence resumed with history, offline
thinking Adaptive thinking with reasoning blocks and signatures
conversation Interactive multi-turn chat with history
self-correction Tool rejecting correctable arguments
fallback Primary model with a fallback and a request bound
anthropic Anthropic Messages API adapter
gemini Google Gemini GenerateContent adapter
azure Azure OpenAI deployment adapter
bedrock AWS Bedrock Converse adapter with SigV4
local-models Ollama or LM Studio through the OpenAI-compatible adapter
testing-without-a-provider Scripted fake model, offline and deterministic
OPENAI_API_KEY=sk-... go run ./examples/minimal
GOLEM_LOCAL_BASE_URL=http://localhost:11434/v1 go run ./examples/local-models   # Ollama or LM Studio
go run ./examples/testing-without-a-provider   # no credentials needed
go run ./examples/partial-evidence             # no credentials needed

Package shape

golem/        Agent configuration and typed run API
model/        Provider-neutral model request/response contract
tool/         Tool declarations and execution contracts
webfetch/     Common tool: fetch a URL as agent-readable text
fileread/     Common tool: read a file as agent-readable text
shell/        Common tool: run one command, return combined output
mcp/          Model Context Protocol client bridging servers into tools
providers/    Stdlib-only adapters implementing model.Model
internal/     Execution loop and non-public mechanics
examples/     Runnable programs per capability
docs/guides/  Feature guides (source of truth for behavior)
docs/adr/     Decisions that shape the public contracts

Development

go test ./...
go vet ./...

The guides double as the published documentation site; preview it with mkdocs serve — see docs/website.md. Logo usage guidelines and brand assets live in assets/brand/.

Community

License

Released under the MIT License.

Documentation

Overview

Package golem provides typed building blocks for AI agents in Go.

Index

Examples

Constants

View Source
const (
	// EventModelStart precedes one provider call attempt.
	EventModelStart = runner.EventModelStart
	// EventModelEnd follows one provider call attempt, carrying the
	// attempt's usage and error.
	EventModelEnd = runner.EventModelEnd
	// EventToolStart precedes one tool execution.
	EventToolStart = runner.EventToolStart
	// EventToolEnd follows one tool execution, carrying the result or the
	// error; a correction rejection carries a *model.ModelRetry error.
	EventToolEnd = runner.EventToolEnd
	// EventOutputRejected marks a decoder rejection starting a correction
	// round; its Attempt numbers the round that follows, and turn numbers
	// restart with it.
	EventOutputRejected = runner.EventOutputRejected
	// EventDeferred marks a tool call that deferred instead of executing;
	// the run pauses with the call pending on Result.Pending. It replaces
	// the call's tool-end event.
	EventDeferred = runner.EventDeferred
)
View Source
const DefaultMaxIterations = 10

DefaultMaxIterations bounds model turns per run when no explicit limit is configured.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

type Agent[Deps any, Output any] struct {
	// contains filtered or unexported fields
}

Agent combines a model, instructions, tools, and a typed output boundary. Deps is the dependency value tools receive on every run.

Example

ExampleAgent demonstrates an agent that executes a typed tool with an explicit dependency value and returns the full run evidence.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
	"github.com/abubakarsiddik31/golem/tool"
)

// diceModel scripts the tool exchange: it requests the player-name tool
// once, then produces a final answer. Real applications implement
// model.Model with a provider adapter.
type diceModel struct{ requests []model.Request }

func (m *diceModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	m.requests = append(m.requests, request)
	for _, message := range request.Messages {
		if message.Role == model.RoleTool {
			return model.Response{
				Message: model.Message{Role: model.RoleAssistant, Content: fmt.Sprintf("winner: %s", message.Content)},
				Usage:   model.Usage{InputTokens: 54, OutputTokens: 2},
			}, nil
		}
	}
	return model.Response{
		Message: model.Message{Role: model.RoleAssistant, ToolCalls: []model.ToolCall{
			{ID: "call-1", Name: "get_player_name", Args: json.RawMessage(`{}`)},
		}},
		Usage: model.Usage{InputTokens: 54, OutputTokens: 2},
	}, nil
}

func main() {
	getPlayerName := tool.MustNew(tool.Tool[string]{
		Name:        "get_player_name",
		Description: "Get the player's name.",
		Schema:      json.RawMessage(`{"type":"object"}`),
		Exec: func(ctx context.Context, playerName string, args json.RawMessage) (string, error) {
			return playerName, nil
		},
	})

	agent, err := golem.New[string, string](
		&diceModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}),
		golem.WithTools[string, string](getPlayerName),
	)
	if err != nil {
		log.Fatal(err)
	}

	result, err := agent.Run(context.Background(), golem.RunContext[string]{Deps: "Anne"}, "My guess is 4")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Output)
	fmt.Println(len(result.Messages), "messages,", result.Usage.OutputTokens, "output tokens")
}
Output:
winner: Anne
4 messages, 4 output tokens

func New

func New[Deps any, Output any](
	modelClient model.Model,
	decoder OutputDecoder[Output],
	options ...Option[Deps, Output],
) (*Agent[Deps, Output], error)

New creates an Agent. A model and decoder are both required: Golem never guesses how untrusted model output becomes a typed application value.

func (*Agent[Deps, Output]) AsTool added in v0.6.0

func (a *Agent[Deps, Output]) AsTool(name, description string, options ...AgentToolOption[Deps, Output]) (tool.Tool[Deps], error)

AsTool exposes the agent as a tool another agent can request: the model passes a prompt, the agent runs it with the delegating run's dependency value, and the typed output is rendered to text as the tool result.

Both agents must share the Deps type — the tool carries the delegating run's dependency value into the sub-agent's RunContext unchanged. The sub-agent sees nothing else of the delegating conversation: the prompt argument is its entire input.

A string output is rendered as-is; every other type is JSON-encoded; WithAgentResult replaces either. Malformed or empty prompt arguments are rejected with *model.ModelRetry, so the delegating run's tool retry budget governs correction. Every other sub-agent failure fails the delegating run at the tool stage with the inner RunError preserved in the chain; cancellation keeps its identity through the chain for errors.Is. The sub-agent's own messages and usage are not part of the delegating run's evidence — only the rendered result is.

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// delegatingModel hands the question to the researcher tool, then answers
// from its result. It stands in for the planner's provider.
type delegatingModel struct{}

func (m *delegatingModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	for _, message := range request.Messages {
		if message.Role == model.RoleTool {
			return model.Response{
				Message: model.Message{Role: model.RoleAssistant,
					Content: fmt.Sprintf("the researcher says: %s", message.Content)},
			}, nil
		}
	}
	return model.Response{
		Message: model.Message{Role: model.RoleAssistant, ToolCalls: []model.ToolCall{
			{ID: "call-1", Name: "researcher", Args: json.RawMessage(`{"prompt":"capital of France?"}`)},
		}},
	}, nil
}

// factModel stands in for the specialist's provider: one run, one fact.
type factModel struct{}

func (m *factModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	return model.Response{Message: model.Message{Role: model.RoleAssistant, Content: "Paris"}}, nil
}

func main() {
	specialist, err := golem.New[struct{}, string](&factModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}))
	if err != nil {
		log.Fatal(err)
	}
	research, err := specialist.AsTool("researcher", "Answers one geography question.")
	if err != nil {
		log.Fatal(err)
	}
	planner, err := golem.New[struct{}, string](&delegatingModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}),
		golem.WithTools[struct{}, string](research))
	if err != nil {
		log.Fatal(err)
	}

	result, err := planner.Run(context.Background(), golem.RunContext[struct{}]{}, "I need the capital of France.")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Output)
}
Output:
the researcher says: Paris

func (*Agent[Deps, Output]) Run

func (a *Agent[Deps, Output]) Run(ctx context.Context, runCtx RunContext[Deps], prompt string, opts ...RunOption) (Result[Output], error)

Run executes the agent: it asks the configured model to answer prompt, executing requested tools along the way, and decodes the final response. Model calls are attempted up to the configured attempt limit; exhausted retries fail with the model stage, preserving the provider cause. Output the decoder rejects with *model.ModelRetry is fed back for correction up to the configured output retry budget, and tool calls a tool rejects with *model.ModelRetry are fed back up to the tool retry budget.

Errors are wrapped in RunError with the failing stage. A run that had begun producing evidence — completed model turns, reported usage, executed tools — carries it as RunError.Partial; a failure before any activity leaves Partial nil. Cancellation and deadline errors are wrapped like every other failure and remain matchable with errors.Is through RunError.Unwrap.

func (*Agent[Deps, Output]) RunStream

func (a *Agent[Deps, Output]) RunStream(ctx context.Context, runCtx RunContext[Deps], prompt string, onDelta func(model.Delta) error, opts ...RunOption) (Result[Output], error)

RunStream executes the agent like Run while streaming progress: every model fragment — text, tool-call arguments, and re-streamed correction rounds — is forwarded to onDelta in arrival order, across tool turns. The returned Result is identical in shape to Run's; deltas are advisory progress on top of the canonical run.

The model must implement model.StreamingModel; otherwise RunStream fails up front with a plain error, before any stage runs — there is no silent fallback to non-streaming generation. Streamed model turns are single-attempt: retryable failures fail the run at the model stage instead of being retried, because a retried stream would replay fragments the caller already saw. An error returned from onDelta stops the run and surfaces at the model stage with the original error reachable via errors.Is. A nil onDelta is allowed and discards fragments. Failures carry RunError.Partial evidence like Run's.

Example

ExampleAgent_RunStream shows a run that streams every fragment to the callback while producing the same typed result as Run.

package main

import (
	"context"
	"fmt"
	"log"
	"strings"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// morningModel streams its answer as two fragments.
type morningModel struct{}

func (m *morningModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	return model.Response{Message: model.Message{Role: model.RoleAssistant, Content: "good morning"}}, nil
}

func (m *morningModel) GenerateStream(ctx context.Context, request model.Request, onDelta func(model.Delta) error) (model.Response, error) {
	for _, fragment := range []string{"good ", "morning"} {
		if err := onDelta(model.Delta{Content: fragment}); err != nil {
			return model.Response{}, err
		}
	}
	return model.Response{Message: model.Message{Role: model.RoleAssistant, Content: "good morning"}}, nil
}

func main() {
	agent, err := golem.New[struct{}, string](&morningModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}))
	if err != nil {
		log.Fatal(err)
	}

	var fragments []string
	result, err := agent.RunStream(context.Background(), golem.RunContext[struct{}]{}, "greet me",
		func(d model.Delta) error {
			fragments = append(fragments, d.Content)
			return nil
		})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(strings.Join(fragments, "|"))
	fmt.Println(result.Output)
}
Output:
good |morning
good morning

func (*Agent[Deps, Output]) RunStreamWithHistory

func (a *Agent[Deps, Output]) RunStreamWithHistory(ctx context.Context, runCtx RunContext[Deps], history []model.Message, prompt string, onDelta func(model.Delta) error, opts ...RunOption) (Result[Output], error)

RunStreamWithHistory continues a conversation like RunWithHistory while streaming progress; see RunStream for the streaming contract.

func (*Agent[Deps, Output]) RunWithDeferredResults added in v0.7.0

func (a *Agent[Deps, Output]) RunWithDeferredResults(ctx context.Context, runCtx RunContext[Deps], history []model.Message, results DeferredResults, prompt string, opts ...RunOption) (Result[Output], error)

RunWithDeferredResults resumes a run that paused on deferred tool calls. history is the paused run's Result.Messages; results resolves every pending call; prompt optionally continues the conversation with a new user message — an empty prompt resumes on the resolutions alone.

Approved calls re-execute their tool with the approved marker set (see tool.CallApproved) under the configured tool timeout; a re-run that fails — or defers again — fails the resume run at the tool stage. Denied calls and external results become the calls' tool results, in the model's emission order. The resumed run continues through the ordinary loop and may itself pause again.

func (*Agent[Deps, Output]) RunWithHistory

func (a *Agent[Deps, Output]) RunWithHistory(ctx context.Context, runCtx RunContext[Deps], history []model.Message, prompt string, opts ...RunOption) (Result[Output], error)

RunWithHistory continues a conversation. history — typically the Result.Messages of a previous run — is sent before a fresh user prompt, and the result carries the full reconstructed conversation so runs chain. The agent's current instructions govern the request: any system messages in history are replaced by them, so guidance is re-evaluated per run and never duplicated.

History is repaired before the request is built so it keeps the call/result pairing providers require: a tool call that never received a result — from a crashed or cancelled run, or hand-built history — gets a synthesized result stating no outcome was produced, and a result whose call is absent is dropped.

Example

ExampleAgent_RunWithHistory continues a conversation across two runs: the first result's messages become the second run's history, and the second result carries the full chained conversation.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// conversationModel answers with the last user prompt it has seen.
type conversationModel struct{}

func (m *conversationModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	last := ""
	for _, message := range request.Messages {
		if message.Role == model.RoleUser {
			last = message.Content
		}
	}
	return model.Response{
		Message: model.Message{Role: model.RoleAssistant, Content: fmt.Sprintf("heard: %s", last)},
	}, nil
}

func main() {
	agent, err := golem.New[struct{}, string](&conversationModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}))
	if err != nil {
		log.Fatal(err)
	}
	runCtx := golem.RunContext[struct{}]{}

	first, err := agent.Run(context.Background(), runCtx, "hello")
	if err != nil {
		log.Fatal(err)
	}
	second, err := agent.RunWithHistory(context.Background(), runCtx, first.Messages, "goodbye")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(first.Output)
	fmt.Println(second.Output)
	fmt.Println(len(second.Messages), "messages in the chained conversation")
}
Output:
heard: hello
heard: goodbye
4 messages in the chained conversation

type AgentToolOption added in v0.6.0

type AgentToolOption[Deps any, Output any] func(*agentToolConfig[Deps, Output])

AgentToolOption configures a tool built by Agent.AsTool.

func WithAgentResult added in v0.6.0

func WithAgentResult[Deps any, Output any](fn func(ctx context.Context, output Output) (string, error)) AgentToolOption[Deps, Output]

WithAgentResult replaces how a successful sub-agent output is rendered for the delegating model. fn runs inside the tool execution: honor ctx and return an error to fail the delegating run at the tool stage. It is also the hook for capturing the inner run's typed result or evidence.

type Approval added in v0.7.0

type Approval struct {
	// Approved re-executes the tool with the approved marker set, so the
	// gated action happens inside the run that holds the approval.
	Approved bool
	// Reason is shown to the model when Approved is false; empty falls
	// back to a plain denial message. It is ignored on approval.
	Reason string
}

Approval is the decision on one deferred approval request, keyed by call ID in DeferredResults.Approvals.

type DecodeFunc

type DecodeFunc[Output any] func(context.Context, model.Response) (Output, error)

DecodeFunc adapts a function to an OutputDecoder.

func (DecodeFunc[Output]) Decode

func (f DecodeFunc[Output]) Decode(ctx context.Context, response model.Response) (Output, error)

Decode converts response using f.

type DeferredRequests added in v0.7.0

type DeferredRequests struct {
	Approvals []PendingToolCall
	External  []PendingToolCall
}

DeferredRequests enumerates the tool calls that paused a run, grouped by what resolving them requires. Approvals wait for a human decision; External wait for a result produced outside the run.

type DeferredResults added in v0.7.0

type DeferredResults struct {
	// Approvals carries the human decision per approval request.
	Approvals map[string]Approval
	// External carries the result per externally executed call, handed
	// to the model verbatim as the call's tool result.
	External map[string]string
}

DeferredResults resolves the pending calls of a paused run, keyed by call ID. Every pending call must be resolved exactly once and no unknown call ID is accepted; validation fails the resume run before any model call.

type EventKind added in v0.6.0

type EventKind = runner.EventKind

EventKind identifies which RunEvent fields carry meaning.

type HistoryProcessor

type HistoryProcessor func(ctx context.Context, history []model.Message) ([]model.Message, error)

HistoryProcessor rewrites the history of one run before the request is built. It receives the history exactly as the caller supplied it — before validation and repair — and returns the history to send; the returned messages are then part-validated, repaired, and sent. The processor runs once per run; an error fails the run before any model call. Processors must be deterministic enough for their caller's purposes: nothing re-runs them.

func TrimHistory

func TrimHistory(maxMessages int) HistoryProcessor

TrimHistory returns a HistoryProcessor that keeps the newest maxMessages messages of a conversation. After the cut it advances past messages that cannot open a request: tool results whose requesting call was trimmed, and assistant turns carrying tool calls whose results were trimmed — repair would otherwise reattach synthesized results, paying tokens for evidence the trim meant to drop. A budget below 1, or a history with nothing left after the boundary rule, fails the run.

type InstructionsFunc

type InstructionsFunc[Deps any] func(ctx context.Context, runCtx RunContext[Deps]) string

InstructionsFunc builds the instructions of one run. ctx is the caller's run context, so a builder that consults external state can honor cancellation.

type Option

type Option[Deps any, Output any] func(*Agent[Deps, Output])

Option configures an Agent during construction.

func WithHistoryProcessor

func WithHistoryProcessor[Deps any, Output any](processor HistoryProcessor) Option[Deps, Output]

WithHistoryProcessor configures a processor applied to the history of every run, before validation and repair, on Run and its history-aware and streaming variants. See TrimHistory for a builtin.

func WithInstructions

func WithInstructions[Deps any, Output any](instructions string) Option[Deps, Output]

WithInstructions configures stable system instructions for every run.

func WithInstructionsFunc

func WithInstructionsFunc[Deps any, Output any](fn InstructionsFunc[Deps]) Option[Deps, Output]

WithInstructionsFunc configures instructions evaluated at the start of every run, so guidance can depend on runtime state such as the run's dependency value. The result joins static instructions — static text first, separated by a blank line — and an empty result contributes nothing. History system messages are replaced by the resolved instructions of the current run, exactly as for static instructions. Register one function; compose closures when several sources apply.

Example

ExampleWithInstructionsFunc shows instructions resolved per run: the function's result joins the static instructions, and both flow to the model as the run's system guidance.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// instructedModel echoes the instructions it was given, if any.
type instructedModel struct{}

func (m *instructedModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	for _, message := range request.Messages {
		if message.Role == model.RoleSystem {
			return model.Response{
				Message: model.Message{Role: model.RoleAssistant, Content: message.Content},
			}, nil
		}
	}
	return model.Response{Message: model.Message{Role: model.RoleAssistant, Content: ""}}, nil
}

func main() {
	type player struct{ Name string }
	agent, err := golem.New[player, string](&instructedModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}),
		golem.WithInstructions[player, string]("Always greet the player."),
		golem.WithInstructionsFunc[player, string](
			func(ctx context.Context, runCtx golem.RunContext[player]) string {
				return "The player's name is " + runCtx.Deps.Name + "."
			}),
	)
	if err != nil {
		log.Fatal(err)
	}

	result, err := agent.Run(context.Background(), golem.RunContext[player]{Deps: player{Name: "Anne"}}, "greet")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Output)
}
Output:
Always greet the player.

The player's name is Anne.

func WithMaxAttempts

func WithMaxAttempts[Deps any, Output any](attempts int) Option[Deps, Output]

WithMaxAttempts bounds how many times each model call may be attempted, including the first, when the model reports a retryable failure (408, 429, 5xx, transport faults). Tool and decode failures are never retried. The default is 1 — retries are opt-in — and values below 1 fail New.

func WithMaxIterations

func WithMaxIterations[Deps any, Output any](iterations int) Option[Deps, Output]

WithMaxIterations bounds model turns per run. It must be at least 1; otherwise New fails.

func WithOutputRetries

func WithOutputRetries[Deps any, Output any](retries int) Option[Deps, Output]

WithOutputRetries sets how many correction rounds a decoder may request by returning *model.ModelRetry: each round appends the rejection reason to the conversation and asks the model again. The default is 0 — self-correction is opt-in — and negative values fail New.

Example

ExampleWithOutputRetries shows a decoder rejecting a correctable response: the run feeds the rejection back to the model, which answers again within the configured budget.

package main

import (
	"context"
	"fmt"
	"log"
	"strconv"
	"strings"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// pickyModel answers with a word first, then with the digit once corrected.
type pickyModel struct{ calls int }

func (m *pickyModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	m.calls++
	content := "seven"
	if m.calls > 1 {
		content = "7"
	}
	return model.Response{Message: model.Message{Role: model.RoleAssistant, Content: content}}, nil
}

func main() {
	agent, err := golem.New[struct{}, int](&pickyModel{},
		golem.DecodeFunc[int](func(ctx context.Context, response model.Response) (int, error) {
			value, err := strconv.Atoi(strings.TrimSpace(response.Message.Content))
			if err != nil {
				return 0, &model.ModelRetry{Err: fmt.Errorf("answer must be an integer, got %q", response.Message.Content)}
			}
			return value, nil
		}),
		golem.WithOutputRetries[struct{}, int](2),
	)
	if err != nil {
		log.Fatal(err)
	}

	result, err := agent.Run(context.Background(), golem.RunContext[struct{}]{}, "pick a number")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Output)
	fmt.Println(len(result.Messages), "messages in the corrected conversation")
}
Output:
7
4 messages in the corrected conversation

func WithOutputSchema

func WithOutputSchema[Deps any, Output any](schema json.RawMessage) Option[Deps, Output]

WithOutputSchema declares the JSON Schema document describing the agent's expected final answer. Adapters that support structured output map it to their native mechanism; adapters that do not ignore it. The schema describes the expected shape to the model — the decoder remains the validation boundary. An empty schema disables the behavior; a non-empty schema that is not valid JSON fails New. Mutually exclusive with WithOutputTool, which expresses the same intent through an output tool call.

Example

ExampleWithOutputSchema pairs a declared output schema — sent to the model as structured-output instructions by adapters that support them — with the JSON decoder that validates the response content.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// forecastModel answers with JSON shaped by the output schema.
type forecastModel struct{}

func (m *forecastModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	return model.Response{
		Message: model.Message{Role: model.RoleAssistant, Content: `{"city":"Lagos","celsius":31}`},
		Usage:   model.Usage{InputTokens: 20, OutputTokens: 6},
	}, nil
}

func main() {
	type weather struct {
		City    string `json:"city"`
		Celsius int    `json:"celsius"`
	}
	agent, err := golem.New[struct{}, weather](&forecastModel{}, golem.DecodeJSON[weather](),
		golem.WithOutputSchema[struct{}, weather](json.RawMessage(`{
			"type": "object",
			"properties": {"city": {"type": "string"}, "celsius": {"type": "integer"}},
			"required": ["city", "celsius"],
			"additionalProperties": false
		}`)),
	)
	if err != nil {
		log.Fatal(err)
	}

	result, err := agent.Run(context.Background(), golem.RunContext[struct{}]{}, "forecast for Lagos")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s: %d°C\n", result.Output.City, result.Output.Celsius)
}
Output:
Lagos: 31°C

func WithOutputTool

func WithOutputTool[Deps any, Output any](name, description string, schema json.RawMessage) Option[Deps, Output]

WithOutputTool declares tool-mode structured output: schema becomes the parameters of a synthesized output tool offered to the model, and the run ends on the model's first call to it. The call's arguments reach the decoder as the final response content, so DecodeJSON validates them like any other response — the decoder remains the validation boundary.

Tool mode reaches every model with tool calling, including those without native JSON-schema output support. Calls co-emitted with the output call are not executed; they are closed with an interrupted result so the conversation keeps the call/result pairing providers require. The output call itself is closed in the result evidence after decoding: a recorded result on success, a rejection bound to the call when the decoder asks for correction. Mutually exclusive with WithOutputSchema. name must not collide with a registered tool; description may be empty; schema must be a non-empty valid JSON document.

Example

ExampleWithOutputTool declares tool-mode structured output: the schema becomes the parameters of a synthesized output tool, the run ends on the model's first call to it, and the call's arguments reach the decoder as the final response content.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// reportingModel calls the output tool with its final arguments.
type reportingModel struct{}

func (m *reportingModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	return model.Response{
		Message: model.Message{Role: model.RoleAssistant, ToolCalls: []model.ToolCall{
			{ID: "out-1", Name: "record_weather", Args: json.RawMessage(`{"city":"Lagos","celsius":31}`)},
		}},
		Usage: model.Usage{InputTokens: 20, OutputTokens: 6},
	}, nil
}

func main() {
	type weather struct {
		City    string `json:"city"`
		Celsius int    `json:"celsius"`
	}
	agent, err := golem.New[struct{}, weather](&reportingModel{}, golem.DecodeJSON[weather](),
		golem.WithOutputTool[struct{}, weather]("record_weather",
			"Record the final weather report.", json.RawMessage(`{
				"type": "object",
				"properties": {"city": {"type": "string"}, "celsius": {"type": "integer"}},
				"required": ["city", "celsius"],
				"additionalProperties": false
			}`)),
	)
	if err != nil {
		log.Fatal(err)
	}

	result, err := agent.Run(context.Background(), golem.RunContext[struct{}]{}, "forecast for Lagos")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s: %d°C\n", result.Output.City, result.Output.Celsius)
}
Output:
Lagos: 31°C

func WithParallelToolCalls

func WithParallelToolCalls[Deps any, Output any]() Option[Deps, Output]

WithParallelToolCalls lets independent calls returned in one model response run concurrently. Result messages remain in model emission order. A tool marked Sequential is a barrier: earlier calls finish, it runs alone, then later calls begin. The default is false for compatibility and predictable side effects.

func WithRetryBackoff

func WithRetryBackoff[Deps any, Output any](backoff func(attempt int) time.Duration) Option[Deps, Output]

WithRetryBackoff overrides the wait between retried model calls. backoff receives the 1-based number of the attempt that just failed. When attempts are enabled without an explicit backoff, runs wait with exponential backoff: 500 ms doubling, capped at 30 s.

func WithRunEvents added in v0.6.0

func WithRunEvents[Deps any, Output any](onEvent func(RunEvent)) Option[Deps, Output]

WithRunEvents registers an observer invoked for every observable point of each run: provider call attempts — retried attempts included —, tool executions, and decoder correction boundaries. The observer runs inline with execution: it must not block, it cannot fail the run, and an observer that must stop the run cancels the run context. Run and its history and streaming variants emit the same events. Events are advisory observation; the canonical record remains the run Result.

func WithToolChoice

func WithToolChoice[Deps any, Output any](name string) Option[Deps, Output]

WithToolChoice restricts this agent's advertised tools to name. It is a provider-neutral availability boundary: the selected tool is the only function sent to the model, so models that do not support a provider-native forced-choice flag still cannot request another registered tool. An empty or unregistered name fails New.

func WithToolRetries

func WithToolRetries[Deps any, Output any](retries int) Option[Deps, Output]

WithToolRetries sets how many tool rejections a run feeds back to the model: a tool signals correctable arguments by returning an error wrapping *model.ModelRetry, and the run delivers the rejection as the call's tool result so the model can try again. The default is 0 — self-correction is opt-in — and negative values fail New. The budget counts total rejections per run and is additionally bounded by the model turn limit.

Example

ExampleWithToolRetries shows a tool rejecting correctable arguments: the run delivers the rejection as the call's tool result, and the model calls again with fixed arguments within the configured budget.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"strings"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
	"github.com/abubakarsiddik31/golem/tool"
)

// learningModel requests the roll tool with an invalid argument first,
// then corrects the call once it sees the rejection come back.
type learningModel struct{ calls int }

func (m *learningModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	last := request.Messages[len(request.Messages)-1]
	if last.Role == model.RoleTool && !strings.Contains(last.Content, "rejected") {
		return model.Response{
			Message: model.Message{Role: model.RoleAssistant, Content: fmt.Sprintf("the die %s", last.Content)},
		}, nil
	}
	m.calls++
	n := 0
	if m.calls > 1 {
		n = 4
	}
	return model.Response{Message: model.Message{Role: model.RoleAssistant, ToolCalls: []model.ToolCall{
		{ID: fmt.Sprintf("call-%d", m.calls), Name: "roll", Args: json.RawMessage(fmt.Sprintf(`{"n":%d}`, n))},
	}}}, nil
}

func main() {
	roll := tool.MustNew(tool.Tool[struct{}]{
		Name:        "roll",
		Description: "Roll a die; n must be positive.",
		Schema:      json.RawMessage(`{"type":"object","properties":{"n":{"type":"integer"}}}`),
		Exec: func(ctx context.Context, deps struct{}, args json.RawMessage) (string, error) {
			var input struct {
				N int `json:"n"`
			}
			if err := json.Unmarshal(args, &input); err != nil {
				return "", err
			}
			if input.N <= 0 {
				return "", &model.ModelRetry{Err: fmt.Errorf("n must be positive, got %d", input.N)}
			}
			return fmt.Sprintf("rolled %d", input.N), nil
		},
	})

	agent, err := golem.New[struct{}, string](&learningModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}),
		golem.WithTools[struct{}, string](roll),
		golem.WithToolRetries[struct{}, string](2),
	)
	if err != nil {
		log.Fatal(err)
	}

	result, err := agent.Run(context.Background(), golem.RunContext[struct{}]{}, "roll a 4")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Output)
	fmt.Println(len(result.Messages), "messages in the corrected run")
}
Output:
the die rolled 4
6 messages in the corrected run

func WithToolTimeout

func WithToolTimeout[Deps any, Output any](timeout time.Duration) Option[Deps, Output]

WithToolTimeout sets the default deadline for one tool execution. A tool's non-zero Timeout takes precedence. The zero value disables the default; negative values fail New. Tools must honor their context so work ends when the deadline expires.

func WithTools

func WithTools[Deps any, Output any](tools ...tool.Tool[Deps]) Option[Deps, Output]

WithTools registers tools the model may request. Tools should be built with tool.New; New rejects invalid or duplicate declarations.

func WithUsageLimit

func WithUsageLimit[Deps any, Output any](limit UsageLimit) Option[Deps, Output]

WithUsageLimit bounds the tokens a single run may consume and the model requests and tool executions it may make, counted across every model turn, retried call, and correction round. The check runs after each model response against the run's cumulative usage: the response that crosses a bound fails the run at the usage stage, even when it would have decoded successfully. Negative values fail New.

Example

ExampleWithUsageLimit shows a run stopped at the usage stage: the response that crosses the bound fails the run, with the crossed dimension inspectable through the typed cause.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"

	"github.com/abubakarsiddik31/golem"
	"github.com/abubakarsiddik31/golem/model"
)

// verboseModel reports heavy usage on every response.
type verboseModel struct{}

func (m *verboseModel) Generate(ctx context.Context, request model.Request) (model.Response, error) {
	return model.Response{
		Message: model.Message{Role: model.RoleAssistant, Content: "an expensive answer"},
		Usage:   model.Usage{InputTokens: 1200, OutputTokens: 800},
	}, nil
}

func main() {
	agent, err := golem.New[struct{}, string](&verboseModel{},
		golem.DecodeFunc[string](func(ctx context.Context, response model.Response) (string, error) {
			return response.Message.Content, nil
		}),
		golem.WithUsageLimit[struct{}, string](golem.UsageLimit{TotalTokens: 1000}),
	)
	if err != nil {
		log.Fatal(err)
	}

	_, err = agent.Run(context.Background(), golem.RunContext[struct{}]{}, "answer")
	var runErr *golem.RunError
	if !errors.As(err, &runErr) {
		log.Fatal(err)
	}
	fmt.Println(runErr.Stage)
	fmt.Println(runErr.Err)
}
Output:
usage
run exceeded the total token limit of 1000 (used 2000)

type OutputDecoder

type OutputDecoder[Output any] interface {
	Decode(ctx context.Context, response model.Response) (Output, error)
}

OutputDecoder validates and converts a provider response to the agent's declared result type. It is the boundary at which model-produced data becomes application data. Returning *model.ModelRetry rejects a response the model can correct; with an output retry budget configured, the run feeds the rejection back to the model.

func DecodeJSON

func DecodeJSON[Output any]() OutputDecoder[Output]

DecodeJSON returns an OutputDecoder that decodes the final response's message content as JSON into Output. Content that is not valid JSON for Output is rejected as *model.ModelRetry — a correctable rejection — so with an output retry budget configured the run asks the model to fix the response instead of failing. Pair it with WithOutputSchema so the model is told the expected shape up front.

type PartialResult added in v0.7.1

type PartialResult struct {
	// Messages is the ordered conversation evidence, ending at the last
	// completed model turn.
	Messages []model.Message
	// Usage sums the provider-reported consumption of completed turns.
	Usage model.Usage
	// Requests counts model calls the run made, failed attempts included.
	Requests int
	// ToolCalls counts tool executions the run attempted.
	ToolCalls int
}

PartialResult is the evidence of a failed run: the conversation through its last completed model turn, the usage completed turns reported, and the run's activity counts. A failure inside a tool batch leaves Messages ending at the assistant turn that requested the batch — its executed results are observable through run events — and any tool call left without a result is repaired on resume, exactly as for a crashed run. Feed Partial.Messages to RunWithHistory to continue a failed conversation.

type PendingToolCall added in v0.7.0

type PendingToolCall struct {
	// CallID identifies the call; resolution results are keyed by it.
	CallID string
	// ToolName and Args identify what the model asked for. Args is
	// model-produced JSON — validate before trusting it.
	ToolName string
	Args     json.RawMessage
	// Reason is the tool's explanation to whoever resolves the request,
	// such as the approval prompt text or a correlation key.
	Reason string
}

PendingToolCall is one deferred call awaiting resolution.

type Result

type Result[Output any] struct {
	Output   Output
	Messages []model.Message
	Usage    model.Usage
	// Pending is non-nil when the run paused awaiting deferred tool
	// calls; see DeferredRequests for the resolution contract.
	Pending *DeferredRequests
}

Result preserves the typed output and the normalized model evidence that produced it, including every tool-call exchange in execution order. This makes testing and observability possible without a tracing backend.

A run that pauses on deferred tool calls reports Pending and skips decoding: Output is the zero value and Messages ends with the executed calls' results only. Check Pending before relying on Output.

type RunContext

type RunContext[Deps any] struct {
	Deps Deps
}

RunContext carries explicit application dependencies for a run. Its Deps value flows to every tool executed during the run.

type RunError

type RunError struct {
	Stage Stage
	Err   error
	// Partial preserves the evidence the run accumulated before the
	// error ended it; see PartialResult. It is nil when the run failed
	// before producing any: no model turn completed, no usage was
	// reported, and no tool executed.
	Partial *PartialResult
}

RunError adds an inspectable execution stage while preserving the source error for errors.Is and errors.As.

func (*RunError) Error

func (e *RunError) Error() string

func (*RunError) Unwrap

func (e *RunError) Unwrap() error

Unwrap exposes the originating model or decoder error.

type RunEvent added in v0.6.0

type RunEvent = runner.Event

RunEvent is one observation of an executing run: a provider call attempt, a tool execution, or a correction boundary. Events are delivered synchronously and in deterministic execution order — the contract and its ordering rules live with the execution loop and are re-exported here.

type RunOption

type RunOption func(*runOptions)

RunOption customizes a single run. Options are evaluated once, at run start; invalid input fails the run before any model call.

func WithPromptImageData

func WithPromptImageData(mediaType string, data []byte) RunOption

WithPromptImageData attaches one inline image with its media type, such as "image/png". Data is application-owned: treat it as immutable once attached.

func WithPromptImageURL

func WithPromptImageURL(url string) RunOption

WithPromptImageURL attaches one image reachable at url; the provider fetches it. See the multimodal support each adapter documents — not every provider accepts image URLs.

func WithPromptParts

func WithPromptParts(parts ...model.Part) RunOption

WithPromptParts appends non-text parts, such as images, after the prompt text of this run's user message. Parts must be well-formed (see model.Part.Validate); a malformed part, or parts on a history message other than a user message, fails the run up front.

func WithRunObserver added in v0.7.1

func WithRunObserver(onEvent func(RunEvent)) RunOption

WithRunObserver registers a run-scoped event observer for a single run: the same events WithRunEvents delivers, under the same contract, but bound to one run instead of the agent. It is how a shared agent — a server handling many requests — routes each request's events separately without rebuilding the agent. A run's observer composes with the agent's: the construction-scoped observer fires first, then the run's. Accepted by Run and its history, streaming, and deferred-resume variants; a nil observer observes nothing.

type Stage

type Stage string

Stage identifies the run phase that returned an error.

const (
	// StageModel means the model could not generate a response.
	StageModel Stage = "model"
	// StageDecode means a generated response could not become the declared type.
	StageDecode Stage = "decode"
	// StageTool means a tool execution failed; the run aborted.
	StageTool Stage = "tool"
	// StageLoop means the run exceeded its model-turn limit before producing
	// a final response.
	StageLoop Stage = "loop"
	// StageUsage means the run crossed a configured usage bound.
	StageUsage Stage = "usage"
)

type UsageLimit

type UsageLimit struct {
	InputTokens  int
	OutputTokens int
	TotalTokens  int
	// Requests bounds model calls, retried attempts included.
	Requests int
	// ToolCalls bounds tool executions.
	ToolCalls int
}

UsageLimit bounds a run's provider-recorded token consumption and its model-request and tool-execution activity. The zero value disables the limit; each dimension is independent, and zero within a set limit means that dimension is unbounded. Providers that do not report usage count as zero tokens, so a token limit never trips without provider-reported usage; requests and tool executions are counted by the run itself.

type UsageLimitError

type UsageLimitError struct {
	// Kind names the crossed dimension, e.g. "output token".
	Kind string
	// Limit is the configured bound.
	Limit int
	// Actual is the run's cumulative value when the run failed.
	Actual int
}

UsageLimitError reports that a run's cumulative usage crossed one of its configured bounds. It is wrapped in a RunError with the usage stage.

func (*UsageLimitError) Error

func (e *UsageLimitError) Error() string

Directories

Path Synopsis
examples
anthropic command
Command anthropic runs a minimal agent against the Anthropic Messages API: explicit configuration, including the MaxTokens bound the API requires.
Command anthropic runs a minimal agent against the Anthropic Messages API: explicit configuration, including the MaxTokens bound the API requires.
azure command
Command azure runs a minimal agent against Azure OpenAI: the wire format matches OpenAI chat completions, but requests target a named deployment with an explicit API version and the api-key header.
Command azure runs a minimal agent against Azure OpenAI: the wire format matches OpenAI chat completions, but requests target a named deployment with an explicit API version and the api-key header.
bedrock command
Command bedrock runs a minimal agent against the AWS Bedrock Runtime Converse API, with requests signed using AWS Signature Version 4.
Command bedrock runs a minimal agent against the AWS Bedrock Runtime Converse API, with requests signed using AWS Signature Version 4.
command-execution command
Command command-execution shows the shell common tool in action: a scripted fake model asks to run one local command — no network, no credentials, fully deterministic.
Command command-execution shows the shell common tool in action: a scripted fake model asks to run one local command — no network, no credentials, fully deterministic.
conversation command
Command conversation chains runs into a multi-turn chat: each result's messages become the next run's history, and instructions are re-applied per run.
Command conversation chains runs into a multi-turn chat: each result's messages become the next run's history, and instructions are re-applied per run.
deferred-tools command
Command deferred-tools runs the full deferred-tool cycle offline against a scripted model: no network, no credentials, deterministic.
Command deferred-tools runs the full deferred-tool cycle offline against a scripted model: no network, no credentials, deterministic.
delegation command
Command delegation runs a planner agent whose only tool is another agent: the model delegates a claim to the fact-checking specialist, Golem runs it as a sub-agent with the shared dependency value, and the planner answers from the rendered result.
Command delegation runs a planner agent whose only tool is another agent: the model delegates a claim to the fact-checking specialist, Golem runs it as a sub-agent with the shared dependency value, and the planner answers from the rendered result.
fallback command
Command fallback runs a prompt against a primary model with a backup model behind it: when the primary fails with a retryable error — rate limits, 5xx, transport faults — the run continues on the backup instead of failing.
Command fallback runs a prompt against a primary model with a backup model behind it: when the primary fails with a retryable error — rate limits, 5xx, transport faults — the run continues on the backup instead of failing.
file-read command
Command file-read shows the fileread common tool in action: a local temp directory stands in for a workspace and a scripted fake model requests the read — no network, no credentials, fully deterministic.
Command file-read shows the fileread common tool in action: a local temp directory stands in for a workspace and a scripted fake model requests the read — no network, no credentials, fully deterministic.
gemini command
Command gemini runs a minimal agent against the Google Gemini GenerateContent API.
Command gemini runs a minimal agent against the Google Gemini GenerateContent API.
local-models command
Command local-models runs an agent against a local OpenAI-compatible runtime — Ollama or LM Studio — through the standard openai adapter, with one typed tool.
Command local-models runs an agent against a local OpenAI-compatible runtime — Ollama or LM Studio — through the standard openai adapter, with one typed tool.
mcp-client command
Command mcp-client shows the mcp package bridging a Model Context Protocol server into agent tools.
Command mcp-client shows the mcp package bridging a Model Context Protocol server into agent tools.
mcp-http command
Command mcp-http shows the mcp package over the streamable-HTTP transport: a local HTTP server stands in for a remote MCP endpoint — no external network, no credentials, fully deterministic.
Command mcp-http shows the mcp package over the streamable-HTTP transport: a local HTTP server stands in for a remote MCP endpoint — no external network, no credentials, fully deterministic.
minimal command
Command minimal runs the smallest agent: an OpenAI-compatible model, a decoder that takes the response text, and one run.
Command minimal runs the smallest agent: an OpenAI-compatible model, a decoder that takes the response text, and one run.
multimodal-input command
Command multimodal-input attaches an inline image to a run's prompt and asks the model to describe it.
Command multimodal-input attaches an inline image to a run's prompt and asks the model to describe it.
partial-evidence command
Command partial-evidence shows a failed run keeping its evidence: a model failure after a completed tool turn carries RunError.Partial — the conversation so far, the usage completed turns reported, and the activity counts — and the partial messages resume through RunWithHistory.
Command partial-evidence shows a failed run keeping its evidence: a model failure after a completed tool turn carries RunError.Partial — the conversation so far, the usage completed turns reported, and the activity counts — and the partial messages resume through RunWithHistory.
run-events command
Command run-events observes an executing run through WithRunEvents: every provider call attempt and tool execution reported as it happens.
Command run-events observes an executing run through WithRunEvents: every provider call attempt and tool execution reported as it happens.
self-correction command
Command self-correction shows a tool that rejects correctable arguments: the die roll requires a positive count, and when the model gets it wrong the run feeds the rejection back so the model calls again within the configured budget.
Command self-correction shows a tool that rejects correctable arguments: the die roll requires a positive count, and when the model gets it wrong the run feeds the rejection back so the model calls again within the configured budget.
skills command
Command skills shows the skills common tool in action: a temp directory laid out in the standard .agents/skills shape stands in for a skill pack, and a scripted fake model loads one skill — no network, no credentials, fully deterministic.
Command skills shows the skills common tool in action: a temp directory laid out in the standard .agents/skills shape stands in for a skill pack, and a scripted fake model loads one skill — no network, no credentials, fully deterministic.
streaming command
Command streaming prints a response as it arrives: RunStream forwards every model fragment across tool turns and correction rounds while producing the same Result as Run.
Command streaming prints a response as it arrives: RunStream forwards every model fragment across tool turns and correction rounds while producing the same Result as Run.
structured-output command
Command structured-output extracts a typed value: the agent declares a JSON Schema the adapter sends as structured-output instructions, and DecodeJSON turns the response content into the declared type.
Command structured-output extracts a typed value: the agent declares a JSON Schema the adapter sends as structured-output instructions, and DecodeJSON turns the response content into the declared type.
structured-output-tool command
Command structured-output-tool extracts a typed value through tool-mode structured output: the schema becomes the parameters of a synthesized output tool, and the run ends on the model's first call to it.
Command structured-output-tool extracts a typed value through tool-mode structured output: the schema becomes the parameters of a synthesized output tool, and the run ends on the model's first call to it.
testing-without-a-provider command
Command testing-without-a-provider runs an agent against a scripted fake model: no network, no credentials, fully deterministic.
Command testing-without-a-provider runs an agent against a scripted fake model: no network, no credentials, fully deterministic.
thinking command
Command thinking runs an agent with adaptive thinking enabled and shows where the model's reasoning lands in the run result.
Command thinking runs an agent with adaptive thinking enabled and shows where the model's reasoning lands in the run result.
tools command
Command tools runs an agent whose tool receives a typed dependency value: the model requests the lookup, Golem executes it with the run's Deps, and the model answers from the result.
Command tools runs an agent whose tool receives a typed dependency value: the model requests the lookup, Golem executes it with the run's Deps, and the model answers from the result.
web-fetch command
Command web-fetch shows the webfetch common tool in action: a local test server stands in for the web and a scripted fake model requests the fetch — no network, no credentials, fully deterministic.
Command web-fetch shows the webfetch common tool in action: a local test server stands in for the web and a scripted fake model requests the fetch — no network, no credentials, fully deterministic.
Package fileread provides a common tool that reads a file inside a configured root directory and returns its text for the model.
Package fileread provides a common tool that reads a file inside a configured root directory and returns its text for the model.
internal
runner
Package runner orchestrates the sequential model/tool execution loop.
Package runner orchestrates the sequential model/tool execution loop.
Package mcp connects Golem agents to Model Context Protocol servers: it speaks the JSON-RPC 2.0 protocol over a transport, performs the initialize handshake, discovers a server's tools, and bridges them into tool.Tool declarations any agent can register.
Package mcp connects Golem agents to Model Context Protocol servers: it speaks the JSON-RPC 2.0 protocol over a transport, performs the initialize handshake, discovers a server's tools, and bridges them into tool.Tool declarations any agent can register.
Package model defines the provider-neutral contract used by Golem agents.
Package model defines the provider-neutral contract used by Golem agents.
Package providers holds Golem's provider adapters and small shared helpers for configuring them.
Package providers holds Golem's provider adapters and small shared helpers for configuring them.
anthropic
Package anthropic adapts the Anthropic Messages API to Golem's provider-neutral model contract.
Package anthropic adapts the Anthropic Messages API to Golem's provider-neutral model contract.
azure
Package azure adapts Azure OpenAI chat completions to Golem's provider-neutral model contract.
Package azure adapts Azure OpenAI chat completions to Golem's provider-neutral model contract.
bedrock
Package bedrock adapts the AWS Bedrock Runtime Converse API to Golem's provider-neutral model contract.
Package bedrock adapts the AWS Bedrock Runtime Converse API to Golem's provider-neutral model contract.
gemini
Package gemini adapts the Google Gemini GenerateContent API to Golem's provider-neutral model contract.
Package gemini adapts the Google Gemini GenerateContent API to Golem's provider-neutral model contract.
openai
Package openai adapts OpenAI-compatible chat-completions APIs to Golem's provider-neutral model contract.
Package openai adapts OpenAI-compatible chat-completions APIs to Golem's provider-neutral model contract.
Package shell provides a common tool that runs one shell command and returns its combined output for the model.
Package shell provides a common tool that runs one shell command and returns its combined output for the model.
Package skills provides a common tool that loads Agent Skills from standard skill directories and returns a chosen skill's instructions to the model.
Package skills provides a common tool that loads Agent Skills from standard skill directories and returns a chosen skill's instructions to the model.
Package testmodel provides model implementations for testing agents without provider credentials or network access.
Package testmodel provides model implementations for testing agents without provider credentials or network access.
Package tool defines Golem's typed tool declaration and execution contract.
Package tool defines Golem's typed tool declaration and execution contract.
Package webfetch provides Golem's first common tool: fetch an http or https URL with GET and return the response body as text a model can read.
Package webfetch provides Golem's first common tool: fetch an http or https URL with GET and return the response body as text a model can read.

Jump to

Keyboard shortcuts

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