Documentation
¶
Overview ¶
Package tantra provides a minimal, type-safe agent framework for LLMs.
The core abstraction is Agent, which wraps an LLM provider (Completer) and optional Tool functions. For multi-agent workflows, use Swarm for dynamic handoffs or Graph for predefined execution flows.
Example:
agent := &tantra.Agent{
Name: "assistant",
Completer: tantra.NewOpenAI(tantra.WithAPIKey(key)),
}
result, err := agent.Run(ctx, "Hello!")
Example (Basic) ¶
This example shows how to create a simple agent.
package main
import (
"context"
"fmt"
"github.com/tantra-run/tantra-go"
)
func main() {
agent := &tantra.Agent{
Name: "assistant",
Completer: &mockCompleter{response: "Hello, human!"},
SystemPrompt: "You are a helpful assistant.",
}
result, err := agent.Run(context.Background(), "Hi there")
if err != nil {
panic(err)
}
fmt.Println(result.Output)
}
// mockCompleter is a simple completer for examples.
type mockCompleter struct {
response string
}
func (m *mockCompleter) Complete(ctx context.Context, msgs []tantra.Message, tools []map[string]any) (*tantra.Response, error) {
return &tantra.Response{Content: m.response}, nil
}
Output: Hello, human!
Example (Tool) ¶
This example shows how to create a type-safe tool.
package main
import (
"context"
"fmt"
"github.com/tantra-run/tantra-go"
)
func main() {
type WeatherArgs struct {
City string `json:"city" desc:"City name" required:"true"`
}
tool := tantra.NewTool("get_weather", "Get weather for a city",
func(ctx context.Context, state *tantra.ScopedState, args WeatherArgs) (tantra.ToolResult, error) {
return tantra.SimpleResult(fmt.Sprintf("Weather in %s: Sunny, 72°F", args.City)), nil
})
s := tantra.NewState()
scope := tantra.NewScopedState(s, "test::")
result, _ := tool.Execute(context.Background(), scope, map[string]any{"city": "Tokyo"})
fmt.Println(result.Output)
}
Output: Weather in Tokyo: Sunny, 72°F
Index ¶
- Constants
- Variables
- func EstimateCost(c Completer, promptTokens, outputTokens int) float64
- func Handler(agents ...*Agent) http.Handler
- func ListenAndServe(addr string, agents ...*Agent) error
- func NodeOutput(s *State, nodeID string) string
- func ScopeAgent(name string) string
- func ScopeNode(name string) string
- type Agent
- func (a *Agent) Resume(ctx context.Context, runID string, store CheckpointStore, opts ...RunOption) (*Result, error)
- func (a *Agent) Run(ctx context.Context, input string, opts ...RunOption) (*Result, error)
- func (a *Agent) Stream(ctx context.Context, input string, opts ...RunOption) <-chan StreamEvent
- type AgentCheckpoint
- type AgentNode
- type AgentNodeOption
- type Checkpoint
- type CheckpointStore
- type Completer
- type ContentPart
- func AudioPart(data, format string) ContentPart
- func FilePart(data, mediaType, filename string) ContentPart
- func ImageBase64Part(data, mediaType string, detail ...ImageDetail) ContentPart
- func ImageFilePart(path string, detail ...ImageDetail) (ContentPart, error)
- func ImageURLPart(url string, detail ...ImageDetail) ContentPart
- func TextPart(text string) ContentPart
- type ContentType
- type CostEstimator
- type Edge
- type EdgeCondition
- type EdgeOption
- type Event
- type EventType
- type FunctionNode
- type Graph
- func (g *Graph) AddEdge(source, target string, opts ...EdgeOption) *Graph
- func (g *Graph) AddNode(node Node) *Graph
- func (g *Graph) Resume(ctx context.Context, runID string, opts ...RunOption) (*GraphResult, error)
- func (g *Graph) Run(ctx context.Context, input string, opts ...RunOption) (*GraphResult, error)
- func (g *Graph) SetEntryPoint(nodeID string) *Graph
- func (g *Graph) SetFinishPoint(nodeID string) *Graph
- func (g *Graph) Stream(ctx context.Context, input string, opts ...RunOption) <-chan StreamEvent
- func (g *Graph) Validate() []string
- type GraphCheckpoint
- type GraphOption
- type GraphResult
- type HealthResponse
- type ImageDetail
- type MCPClient
- type MemoryCheckpointStore
- func (m *MemoryCheckpointStore) Delete(_ context.Context, runID string) error
- func (m *MemoryCheckpointStore) List(_ context.Context, runID string) ([]string, error)
- func (m *MemoryCheckpointStore) Load(_ context.Context, runID string) (Checkpoint, bool, error)
- func (m *MemoryCheckpointStore) Save(_ context.Context, cp Checkpoint) error
- type Message
- type Node
- type ObserveEvent
- type Observer
- type ObserverFunc
- type OpenAI
- type OpenAIOption
- type Param
- type Response
- type Result
- type Role
- type RouterNode
- type RunOption
- type RunRequest
- type RunResponse
- type ScopedState
- func (ss *ScopedState) Get(key string) (any, bool)
- func (ss *ScopedState) GetLocal(key string) (any, bool)
- func (ss *ScopedState) GetString(key string) string
- func (ss *ScopedState) Prefix() string
- func (ss *ScopedState) Raw() *State
- func (ss *ScopedState) Session() *ScopedState
- func (ss *ScopedState) Set(key string, value any)
- type Server
- type Skill
- type State
- type StreamEvent
- type Streamer
- type Swarm
- type SwarmCheckpoint
- type SwarmResult
- type SwarmStep
- type Tool
- type ToolCall
- type ToolResult
Examples ¶
Constants ¶
const ( CheckpointAgent = "agent" CheckpointSwarm = "swarm" CheckpointGraph = "graph" )
Checkpoint type constants.
const ( StatusRunning = "running" StatusCompleted = "completed" StatusFailed = "failed" )
Checkpoint status constants.
const ( ScopeSession = "session::" ScopeGraph = "graph::" )
Scope prefix constants. Use these instead of string literals.
const DefaultMaxGraphIterations = 50
DefaultMaxGraphIterations prevents infinite loops in cyclic graphs.
const DefaultMaxHandoffs = 10
DefaultMaxHandoffs is the default limit for agent handoffs.
const DefaultMaxIterations = 10
DefaultMaxIterations limits agent loops to prevent runaway costs.
Variables ¶
var ( ErrNoCompleter = errors.New("no completer configured") ErrMaxIterations = errors.New("max iterations exceeded") ErrToolNotFound = errors.New("tool not found") ErrAgentNotFound = errors.New("agent not found") ErrInvalidSession = errors.New("invalid session ID") )
Sentinel errors returned by tantra functions. Use errors.Is to check for these errors.
Functions ¶
func EstimateCost ¶
EstimateCost calculates the cost of a completion if the provider implements CostEstimator. Returns 0 otherwise.
func Handler ¶
Handler returns an http.Handler for the given agents. Use this with your own server or middleware.
func ListenAndServe ¶
ListenAndServe starts an HTTP server on the given address.
func NodeOutput ¶
NodeOutput reads a node's output from state.
func ScopeAgent ¶
ScopeAgent returns the prefix for a named agent, e.g. "agent::billing::".
Types ¶
type Agent ¶
type Agent struct {
Name string // identifies the agent (required for [Server])
Completer Completer // LLM provider (required)
Tools []Tool // available tools (optional)
SystemPrompt string // behavior instructions (optional)
MaxIterations int // loop limit; 0 means DefaultMaxIterations
MaxContextTokens int // compact older messages when estimated tokens exceed this; 0 means no compaction
Skills []*Skill // domain-specific knowledge and tools (optional)
}
Agent is an AI agent that uses an LLM to process input and optionally call tools. The zero value is not usable; at minimum, set Agent.Completer.
func (*Agent) Resume ¶
func (a *Agent) Resume(ctx context.Context, runID string, store CheckpointStore, opts ...RunOption) (*Result, error)
Resume loads the latest checkpoint for the given run and continues execution.
func (*Agent) Run ¶
Run executes the agent with the given input. It returns when the agent produces a final response or an error occurs. The context can be used for cancellation and timeouts.
func (*Agent) Stream ¶
Stream executes the agent with the given input and streams events as they occur. It returns a channel that emits StreamEvent values. The channel is closed when the agent finishes or an error occurs. If the Completer does not implement Streamer, it falls back to [Complete] and emits the full response as a single token.
type AgentCheckpoint ¶
type AgentCheckpoint struct {
AgentName string `json:"agent_name"`
Messages []Message `json:"messages"`
Iteration int `json:"iteration"`
PromptTokens int `json:"prompt_tokens"`
OutputTokens int `json:"output_tokens"`
ToolCalls int `json:"tool_calls"`
ToolResults []string `json:"tool_results"`
}
AgentCheckpoint captures agent loop state at a clean boundary.
type AgentNode ¶
type AgentNode struct {
// contains filtered or unexported fields
}
AgentNode wraps an Agent for graph execution. The graph's State is passed to the agent via WithRunState, so the agent's tools can read/write graph and node state.
func NewAgentNode ¶
func NewAgentNode(id string, agent *Agent, opts ...AgentNodeOption) *AgentNode
NewAgentNode creates a node that runs an agent.
type AgentNodeOption ¶
type AgentNodeOption func(*AgentNode)
AgentNodeOption configures an AgentNode.
func WithInputTransform ¶
func WithInputTransform(fn func(*State) string) AgentNodeOption
WithInputTransform sets a function to derive input from state.
type Checkpoint ¶
type Checkpoint struct {
ID string `json:"id"`
RunID string `json:"run_id"`
Seq int `json:"seq"`
Type string `json:"type"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
StateData map[string]any `json:"state_data"`
Agent *AgentCheckpoint `json:"agent,omitempty"`
Swarm *SwarmCheckpoint `json:"swarm,omitempty"`
Graph *GraphCheckpoint `json:"graph,omitempty"`
}
Checkpoint captures execution state at a clean boundary. It is JSON-serializable and self-contained for resumption.
type CheckpointStore ¶
type CheckpointStore interface {
// Save persists a checkpoint. If a checkpoint with the same ID exists, it is overwritten.
Save(ctx context.Context, cp Checkpoint) error
// Load retrieves the latest checkpoint for a run.
// Returns the checkpoint and true, or a zero Checkpoint and false if not found.
Load(ctx context.Context, runID string) (Checkpoint, bool, error)
// List returns all checkpoint IDs for a run, ordered by sequence number.
List(ctx context.Context, runID string) ([]string, error)
// Delete removes all checkpoints for a run.
Delete(ctx context.Context, runID string) error
}
CheckpointStore persists checkpoints for durable execution. Implementations must be safe for concurrent use.
type Completer ¶
type Completer interface {
// Complete sends messages to the LLM and returns a response.
// The tools parameter contains JSON schemas for available tools.
Complete(ctx context.Context, messages []Message, tools []map[string]any) (*Response, error)
}
Completer is the core interface for LLM providers. Implement this interface to add support for new LLM backends.
type ContentPart ¶
type ContentPart struct {
Type ContentType `json:"type"`
Text string `json:"text,omitempty"` // ContentText
URL string `json:"url,omitempty"` // ContentImage (URL source)
Data string `json:"data,omitempty"` // base64-encoded binary
MediaType string `json:"media_type,omitempty"` // MIME type for Data
Detail ImageDetail `json:"detail,omitempty"` // ContentImage resolution
AudioFormat string `json:"audio_format,omitempty"` // "wav", "mp3"
Filename string `json:"filename,omitempty"` // ContentFile
}
ContentPart is one piece of a multimodal message. Use the constructors TextPart, ImageURLPart, ImageBase64Part, AudioPart, and FilePart to create parts.
func AudioPart ¶
func AudioPart(data, format string) ContentPart
AudioPart creates an audio content part from base64-encoded data. Format should be "wav" or "mp3".
func FilePart ¶
func FilePart(data, mediaType, filename string) ContentPart
FilePart creates a file content part from base64-encoded data.
func ImageBase64Part ¶
func ImageBase64Part(data, mediaType string, detail ...ImageDetail) ContentPart
ImageBase64Part creates an image content part from base64-encoded data.
func ImageFilePart ¶
func ImageFilePart(path string, detail ...ImageDetail) (ContentPart, error)
ImageFilePart reads an image file and creates a base64-encoded content part. Supported formats: JPEG, PNG, GIF, WebP.
func ImageURLPart ¶
func ImageURLPart(url string, detail ...ImageDetail) ContentPart
ImageURLPart creates an image content part from a URL. The optional detail parameter controls resolution ("auto", "low", "high").
type ContentType ¶
type ContentType string
ContentType identifies the kind of content in a ContentPart.
const ( ContentText ContentType = "text" ContentImage ContentType = "image" ContentAudio ContentType = "audio" ContentFile ContentType = "file" )
type CostEstimator ¶
CostEstimator is an optional interface for cost calculation. Implement this to enable automatic cost tracking in Result.
type Edge ¶
type Edge struct {
Source string
Target string
Condition EdgeCondition
ConditionFn func(*State) bool // For Custom condition
TargetFn func(*State) string // For Conditional edges
Priority int // Higher = evaluated first
}
Edge connects two nodes with optional conditions.
func (*Edge) ResolveTarget ¶
ResolveTarget returns the target node ID.
type EdgeCondition ¶
type EdgeCondition int
EdgeCondition defines when an edge should be traversed.
const ( // Always traverses the edge unconditionally. Always EdgeCondition = iota // OnSuccess traverses only if the previous node succeeded. OnSuccess // OnFailure traverses only if the previous node failed. OnFailure // OnToolCall traverses only if the previous node called a tool. OnToolCall // Custom uses a custom condition function. Custom // Conditional dynamically resolves the target node. Conditional )
type EdgeOption ¶
type EdgeOption func(*Edge)
EdgeOption configures an Edge.
func WithCondition ¶
func WithCondition(cond EdgeCondition) EdgeOption
WithCondition sets the edge condition.
func WithConditionFn ¶
func WithConditionFn(fn func(*State) bool) EdgeOption
WithConditionFn sets a custom condition function.
func WithPriority ¶
func WithPriority(p int) EdgeOption
WithPriority sets the edge evaluation priority.
func WithTargetFn ¶
func WithTargetFn(fn func(*State) string) EdgeOption
WithTargetFn sets a dynamic target function (makes edge Conditional).
type Event ¶
type Event struct {
Type string // "token", "tool_call", "tool_result", "complete", "error"
Content string
Err error
}
Event represents a provider-level streaming event (internal).
type EventType ¶
type EventType string
EventType identifies what happened at an observation point.
const ( EventAgentStart EventType = "agent.start" // emitted before Agent.Run begins EventAgentDone EventType = "agent.done" // emitted after Agent.Run completes EventLLMStart EventType = "llm.start" // emitted before each LLM call EventLLMDone EventType = "llm.done" // emitted after each LLM call EventToolStart EventType = "tool.start" // emitted before tool execution EventToolDone EventType = "tool.done" // emitted after tool execution EventSwarmStart EventType = "swarm.start" // emitted before swarm orchestration begins EventSwarmDone EventType = "swarm.done" // emitted after swarm orchestration completes EventSwarmHandoff EventType = "swarm.handoff" // emitted when an agent transfers to another EventGraphStart EventType = "graph.start" // emitted before graph execution begins EventGraphDone EventType = "graph.done" // emitted after graph execution completes EventGraphNodeStart EventType = "graph.node.start" // emitted before a graph node executes EventGraphNodeDone EventType = "graph.node.done" // emitted after a graph node executes EventGraphEdge EventType = "graph.edge" // emitted when a graph edge is traversed EventCompactStart EventType = "compact.start" // emitted before context compaction EventCompactDone EventType = "compact.done" // emitted after context compaction )
type FunctionNode ¶
type FunctionNode struct {
// contains filtered or unexported fields
}
FunctionNode executes a custom function.
func NewFunctionNode ¶
NewFunctionNode creates a node that runs a function.
type Graph ¶
type Graph struct {
// contains filtered or unexported fields
}
Graph orchestrates workflow execution with conditional edges. All nodes share a single State, and [AgentNode]s pass that state to their agent's tools via WithRunState.
func NewGraph ¶
func NewGraph(name string, opts ...GraphOption) *Graph
NewGraph creates a graph with the given options.
func (*Graph) AddEdge ¶
func (g *Graph) AddEdge(source, target string, opts ...EdgeOption) *Graph
AddEdge adds an edge between nodes.
func (*Graph) Resume ¶
Resume loads the latest checkpoint for the given run and continues execution.
func (*Graph) Run ¶
Run executes the graph with the given input. A single State is created (or provided via WithRunState) and passed to every node. [AgentNode]s forward this state to their agent's tools.
func (*Graph) SetEntryPoint ¶
SetEntryPoint sets the starting node.
func (*Graph) SetFinishPoint ¶
SetFinishPoint marks a node as an exit point.
type GraphCheckpoint ¶
type GraphCheckpoint struct {
GraphName string `json:"graph_name"`
CurrentNode string `json:"current_node"`
Iteration int `json:"iteration"`
ExecutionPath []string `json:"execution_path"`
NodesExecuted []string `json:"nodes_executed"`
Success bool `json:"success"`
}
GraphCheckpoint captures graph loop state at a clean boundary.
type GraphOption ¶
type GraphOption func(*Graph)
GraphOption configures a Graph.
func WithGraphCheckpointStore ¶
func WithGraphCheckpointStore(store CheckpointStore) GraphOption
WithGraphCheckpointStore enables checkpointing for graph execution.
func WithGraphObserver ¶
func WithGraphObserver(o Observer) GraphOption
WithGraphObserver attaches an observer that receives events during graph execution.
func WithMaxIterations ¶
func WithMaxIterations(max int) GraphOption
WithMaxIterations sets the maximum iterations for cyclic graphs.
type GraphResult ¶
type GraphResult struct {
Output string
State *State
ExecutionPath []string
NodesExecuted []string
Iterations int
Success bool
DurationMS int64
}
GraphResult contains the outcome of a graph run.
type HealthResponse ¶
HealthResponse is returned by GET /health.
type ImageDetail ¶
type ImageDetail string
ImageDetail controls image resolution for vision models.
const ( ImageDetailAuto ImageDetail = "auto" ImageDetailLow ImageDetail = "low" ImageDetailHigh ImageDetail = "high" )
type MCPClient ¶
type MCPClient struct {
// contains filtered or unexported fields
}
MCPClient connects to an MCP server, discovers its tools, and exposes them as tantra Tool implementations. Tools returned by MCPClient.Tools work seamlessly with Agent, Swarm, Graph, and Agent.Stream.
The client must be closed when no longer needed to release resources (especially for stdio servers, which run as child processes).
func NewMCPHTTP ¶
NewMCPHTTP connects to an MCP server via streamable HTTP transport. The baseURL should be the root URL of the MCP server endpoint.
The client initializes the connection and discovers all available tools. Call MCPClient.Close when done.
func NewMCPStdio ¶
NewMCPStdio connects to an MCP server via stdio transport. The command is started as a child process with the given arguments. Environment variables are specified as "KEY=VALUE" strings; pass nil to inherit the current process environment.
The client initializes the connection and discovers all available tools. Call MCPClient.Close when done.
func (*MCPClient) ServerName ¶
ServerName returns the name reported by the MCP server during initialization.
type MemoryCheckpointStore ¶
type MemoryCheckpointStore struct {
// contains filtered or unexported fields
}
MemoryCheckpointStore is an in-memory CheckpointStore for testing. Checkpoints are lost on process restart.
func NewMemoryCheckpointStore ¶
func NewMemoryCheckpointStore() *MemoryCheckpointStore
NewMemoryCheckpointStore creates an in-memory checkpoint store.
func (*MemoryCheckpointStore) Delete ¶
func (m *MemoryCheckpointStore) Delete(_ context.Context, runID string) error
Delete removes all checkpoints for a run.
func (*MemoryCheckpointStore) Load ¶
func (m *MemoryCheckpointStore) Load(_ context.Context, runID string) (Checkpoint, bool, error)
Load returns the latest checkpoint for a run. Returns false if none exist.
func (*MemoryCheckpointStore) Save ¶
func (m *MemoryCheckpointStore) Save(_ context.Context, cp Checkpoint) error
Save persists a checkpoint, replacing any existing one with the same ID.
type Message ¶
type Message struct {
Role Role `json:"role"`
Content string `json:"content,omitempty"`
Parts []ContentPart `json:"parts,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
}
Message represents a message in the conversation history. If [Parts] is non-empty, providers use it instead of [Content].
func (Message) IsMultimodal ¶
IsMultimodal returns true if the message has non-text content parts.
func (Message) TextContent ¶
TextContent returns the text content of the message. If Parts is set, it concatenates all text parts. Otherwise returns Content.
type Node ¶
type Node interface {
// ID returns the unique identifier for this node.
ID() string
// Execute runs the node and returns (output, success, toolCalled, error).
Execute(ctx context.Context, state *State) (string, bool, bool, error)
}
Node is the interface for graph nodes. Nodes receive the shared State and can read/write to it freely.
type ObserveEvent ¶
type ObserveEvent struct {
Type EventType
Agent string // agent name (empty for graph-only events)
SpanID int64 // unique ID for this span
ParentID int64 // parent span (0 = root)
Data map[string]any // event-specific payload
Error error // non-nil if the operation failed
Timestamp time.Time
Duration time.Duration // set on "done" events
}
ObserveEvent is emitted at each decision point during execution. Start events are emitted before the operation; done events after. SpanID/ParentID form a tree: agent spans contain llm and tool spans, swarm spans contain agent spans, etc.
type Observer ¶
type Observer interface {
Handle(ObserveEvent)
}
Observer receives events during execution. Implementations must be safe for concurrent use.
type ObserverFunc ¶
type ObserverFunc func(ObserveEvent)
ObserverFunc adapts a plain function to the Observer interface.
func (ObserverFunc) Handle ¶
func (f ObserverFunc) Handle(e ObserveEvent)
Handle calls the underlying function.
type OpenAI ¶
type OpenAI struct {
// contains filtered or unexported fields
}
OpenAI implements Completer, Streamer, and CostEstimator using the OpenAI API.
func NewOpenAI ¶
func NewOpenAI(opts ...OpenAIOption) *OpenAI
NewOpenAI creates an OpenAI provider. By default, it reads OPENAI_API_KEY from environment and uses gpt-4o.
func (*OpenAI) Complete ¶
func (o *OpenAI) Complete(ctx context.Context, messages []Message, tools []map[string]any) (*Response, error)
Complete implements the Completer interface.
func (*OpenAI) InputCostPer1K ¶
InputCostPer1K implements the CostEstimator interface.
func (*OpenAI) OutputCostPer1K ¶
OutputCostPer1K implements the CostEstimator interface.
type OpenAIOption ¶
type OpenAIOption func(*openaiConfig)
OpenAIOption configures an OpenAI provider.
func WithAPIKey ¶
func WithAPIKey(key string) OpenAIOption
WithAPIKey sets the API key (alternative to OPENAI_API_KEY env var).
func WithBaseURL ¶
func WithBaseURL(url string) OpenAIOption
WithBaseURL sets a custom base URL (for Azure or compatible APIs).
func WithCost ¶
func WithCost(inputPer1K, outputPer1K float64) OpenAIOption
WithCost sets the cost per 1K tokens for estimation.
func WithModel ¶
func WithModel(model string) OpenAIOption
WithModel sets the model to use (default: gpt-4o).
type Param ¶
type Param struct {
Name string
Type string // "string", "integer", "number", "boolean"
Description string
Required bool
}
Param describes a tool parameter for SimpleTool.
type Response ¶
type Response struct {
Content string `json:"content,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
PromptTokens int `json:"prompt_tokens"`
OutputTokens int `json:"output_tokens"`
}
Response represents a response from an LLM provider.
type Result ¶
type Result struct {
Output string
Messages []Message // full conversation history (pass back via WithMessages for multi-turn)
PromptTokens int
OutputTokens int
ToolCalls int
Iterations int
DurationMS int64
Cost float64
ToolResults []string // Results from tool executions (for swarm handoff detection)
}
Result contains the outcome of an agent run.
type RouterNode ¶
type RouterNode struct {
// contains filtered or unexported fields
}
RouterNode routes to different nodes based on conditions.
func NewRouterNode ¶
NewRouterNode creates a router that selects the next node.
type RunOption ¶
type RunOption func(*runConfig)
RunOption configures a single Run call.
func WithCheckpointStore ¶
func WithCheckpointStore(store CheckpointStore) RunOption
WithCheckpointStore enables checkpointing for this run. After each iteration boundary, the agent saves its state to the store. Use Agent.Resume to continue a checkpointed run.
func WithMessages ¶
WithMessages provides conversation history for multi-turn interactions. The agent prepends its system prompt (if set and not already present), appends the new user message (from input or WithParts), and continues the loop. The final message history is returned in Result.Messages.
func WithObserver ¶
WithObserver attaches an observer that receives events during the run. If the context already carries an observer (e.g. from a Swarm or Graph), this option overrides it for this agent run.
func WithParts ¶
func WithParts(parts ...ContentPart) RunOption
WithParts sets multimodal content parts for the initial user message. When set, parts are used instead of the plain text input.
func WithRunID ¶
WithRunID sets the run ID for checkpoint grouping. If not set, a random ID is generated.
func WithRunState ¶
WithRunState provides an existing State to share across agents or runs.
type RunRequest ¶
type RunRequest struct {
Message string `json:"message"`
Parts []ContentPart `json:"parts,omitempty"`
}
RunRequest is the request body for POST /{name}/run. Provide either Message for text-only or Parts for multimodal input.
type RunResponse ¶
type RunResponse struct {
Output string `json:"output,omitempty"`
PromptTokens int `json:"prompt_tokens,omitempty"`
OutputTokens int `json:"output_tokens,omitempty"`
ToolCalls int `json:"tool_calls,omitempty"`
DurationMS int64 `json:"duration_ms,omitempty"`
Cost float64 `json:"cost,omitempty"`
Error string `json:"error,omitempty"`
}
RunResponse is returned by POST /{name}/run.
type ScopedState ¶
type ScopedState struct {
// contains filtered or unexported fields
}
ScopedState provides a restricted view of a State. Writes go to a specific prefix; reads check own prefix, then readable prefixes, then global (no prefix).
func NewScopedState ¶
func NewScopedState(state *State, prefix string, readablePrefixes ...string) *ScopedState
NewScopedState creates a scoped view of a state.
func (*ScopedState) Get ¶
func (ss *ScopedState) Get(key string) (any, bool)
Get reads a value, checking own scope -> readable scopes -> global.
func (*ScopedState) GetLocal ¶
func (ss *ScopedState) GetLocal(key string) (any, bool)
GetLocal reads a value from this scope only, without waterfall lookup. Use this when you need to be certain the value came from your own scope.
func (*ScopedState) GetString ¶
func (ss *ScopedState) GetString(key string) string
GetString retrieves a string value from scoped lookup.
func (*ScopedState) Prefix ¶
func (ss *ScopedState) Prefix() string
Prefix returns the write prefix for this scope.
func (*ScopedState) Raw ¶
func (ss *ScopedState) Raw() *State
Raw returns the underlying State for orchestrator-level access.
func (*ScopedState) Session ¶
func (ss *ScopedState) Session() *ScopedState
Session returns a ScopedState that writes to the session namespace.
func (*ScopedState) Set ¶
func (ss *ScopedState) Set(key string, value any)
Set writes a value to this scope's namespace.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server serves agents over HTTP with JSON request/response. Routes: GET /health, POST /{name}/run
type Skill ¶
type Skill struct {
Name string // unique identifier (from SKILL.md frontmatter)
Description string // what this skill does (from SKILL.md frontmatter)
Instructions string // markdown body (appended to agent system prompt)
Tools []Tool // skill-provided tools (merged with agent tools)
Dir string // source directory (empty for programmatic skills)
}
Skill packages domain-specific instructions and tools for an agent. Load skills from disk with LoadSkill or LoadSkills, or construct programmatically for testing.
A skill directory follows the standard SKILL.md convention:
my-skill/
SKILL.md # name, description, instructions
references/ # optional reference files (auto-generates tools)
api-spec.md
examples.txt
func LoadSkill ¶
LoadSkill reads a skill from a directory containing a SKILL.md file. If the directory contains a references/ subdirectory, tools for listing and reading reference files are auto-generated.
The skill's Tools field is populated only with reference tools (if any). To add programmatic tools, append to the returned Skill's Tools field.
func LoadSkills ¶
LoadSkills reads all skills from subdirectories of parentDir. Each subdirectory must contain a SKILL.md file. Subdirectories without SKILL.md are silently skipped. Returns an error only if parentDir cannot be read or a skill with SKILL.md fails to parse.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State is a thread-safe key-value store shared across agents, tools, and orchestrators. It replaces both the old StateFromContext map and GraphState.
State uses a flat map with scope prefixes by convention:
- "session::" — visible to all agents in a session
- "agent::<name>::" — scoped to a single agent's tools
- "node::<id>::" — output of a graph node
- "graph::" — graph-level metadata
- no prefix — global
func StateFromContext ¶
StateFromContext retrieves the State from context. Returns nil if none.
func (*State) GetString ¶
GetString retrieves a string value. Returns "" if not found or not a string.
type StreamEvent ¶
type StreamEvent struct {
Type string `json:"type"`
Content string `json:"content,omitempty"` // token text
Agent string `json:"agent,omitempty"` // current agent name
Data map[string]any `json:"data,omitempty"` // event-specific payload
Error string `json:"error,omitempty"` // serializable error string
Err error `json:"-"` // Go-side error (not serialized)
}
StreamEvent is an orchestrator-level streaming event for callers and UIs.
Agent events: "token", "tool_call.start", "tool_call.done", "done", "error" Swarm adds: "agent.start", "agent.done", "handoff" Graph adds: "node.start", "node.done", "edge"
type Streamer ¶
type Streamer interface {
// Stream returns a channel that emits events as the LLM generates output.
Stream(ctx context.Context, messages []Message, tools []map[string]any) <-chan Event
}
Streamer is an optional interface for streaming responses token by token.
type Swarm ¶
type Swarm struct {
Name string // swarm identifier
Agents map[string]*Agent // available agents by name
Handoffs map[string][]string // allowed transfers: agent -> targets (nil = all-to-all)
EntryPoint string // starting agent (defaults to first agent)
MaxHandoffs int // loop limit; 0 means DefaultMaxHandoffs
Observer Observer // receives events during execution (optional)
CheckpointStore CheckpointStore // enables durable execution (optional)
}
Swarm orchestrates multiple agents with dynamic handoffs. Each agent can transfer control to another agent mid-conversation using auto-generated transfer_to_<agent> tools.
All agents in a swarm share a single State, enabling structured data to flow across handoffs without serialization loss.
func (*Swarm) Resume ¶
Resume loads the latest checkpoint for the given run and continues execution.
func (*Swarm) Run ¶
Run executes the swarm starting from the entry point agent. A single State is shared across all agents, enabling cross-agent data flow through scoped state access.
func (*Swarm) Stream ¶
func (s *Swarm) Stream(ctx context.Context, input string) <-chan StreamEvent
Stream executes the swarm and streams events as they occur. It returns a channel that emits StreamEvent values. The channel is closed when the swarm finishes. Events include agent.start, agent.done, handoff, and all forwarded agent events (token, tool_call.start, tool_call.done).
type SwarmCheckpoint ¶
type SwarmCheckpoint struct {
SwarmName string `json:"swarm_name"`
OriginalInput string `json:"original_input"`
CurrentAgent string `json:"current_agent"`
CurrentInput string `json:"current_input"`
HandoffChain []string `json:"handoff_chain"`
HandoffCount int `json:"handoff_count"`
Steps []SwarmStep `json:"steps"`
PromptTokens int `json:"prompt_tokens"`
OutputTokens int `json:"output_tokens"`
ToolCalls int `json:"tool_calls"`
}
SwarmCheckpoint captures swarm loop state at a clean boundary.
type SwarmResult ¶
type SwarmResult struct {
Output string
Steps []SwarmStep
HandoffChain []string
PromptTokens int
OutputTokens int
ToolCalls int
DurationMS int64
Cost float64
}
SwarmResult contains the outcome of a swarm run.
type SwarmStep ¶
type SwarmStep struct {
Agent string
Input string
Output string
HandoffTo string
HandoffReason string
PromptTokens int
OutputTokens int
ToolCalls int
DurationMS int64
}
SwarmStep records one agent's execution in the swarm.
type Tool ¶
type Tool interface {
Name() string
Description() string
Schema() map[string]any
// Execute runs the tool. State provides scoped read/write access.
Execute(ctx context.Context, state *ScopedState, args map[string]any) (ToolResult, error)
}
Tool is the interface for agent tools. Use NewTool for type-safe tools or SimpleTool for quick definitions.
func BashTool ¶
func BashTool() Tool
BashTool creates a tool that executes shell commands. Commands run via "sh -c" and inherit the context for cancellation. Output is truncated at 64KB.
func CodeTools ¶
func CodeTools() []Tool
CodeTools returns the standard set of coding tools: read, write, edit, bash, think.
func EditTool ¶
func EditTool() Tool
EditTool creates a tool that performs find-and-replace edits on files. The old_string must appear exactly once in the file (edits must be unambiguous).
func NewTool ¶
func NewTool[T any](name, description string, fn func(context.Context, *ScopedState, T) (ToolResult, error)) Tool
NewTool creates a type-safe tool from a function. The function must have the signature:
func(context.Context, *ScopedState, T) (ToolResult, error)
where T is a struct with json tags defining the parameters.
Example:
type WeatherArgs struct {
City string `json:"city" desc:"City name" required:"true"`
}
tool := tantra.NewTool("get_weather", "Get weather for a city",
func(ctx context.Context, state *tantra.ScopedState, args WeatherArgs) (tantra.ToolResult, error) {
return tantra.SimpleResult(fmt.Sprintf("Weather in %s: Sunny", args.City)), nil
})
func SimpleTool ¶
func SimpleTool(name, description string, params []Param, fn func(ctx context.Context, state *ScopedState, args map[string]any) (ToolResult, error)) Tool
SimpleTool creates a tool with explicit parameters (no generics).
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Arguments map[string]any `json:"arguments"`
}
ToolCall represents a tool invocation requested by the LLM.
type ToolResult ¶
type ToolResult struct {
// Output is what the LLM sees as the tool response.
Output string
// Next optionally names the next tool to call without an LLM round-trip.
// If empty, normal LLM-driven flow continues.
Next string
// NextArgs are arguments for the chained tool call. Ignored if Next is empty.
NextArgs map[string]any
}
ToolResult is the structured return from a tool execution. To mutate state, tools should call ScopedState.Set directly.
func ChainResult ¶
func ChainResult(output, nextTool string, nextArgs map[string]any) ToolResult
ChainResult creates a ToolResult that triggers a follow-up tool call.
func SimpleResult ¶
func SimpleResult(output string) ToolResult
SimpleResult creates a ToolResult with just an output string.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
autonomous
command
Autonomous agent: uses CodeTools to reason, write scripts, and execute them.
|
Autonomous agent: uses CodeTools to reason, write scripts, and execute them. |
|
chain
command
Tool chaining: deterministic tool-to-tool calls without LLM round-trips.
|
Tool chaining: deterministic tool-to-tool calls without LLM round-trips. |
|
checkpoint
command
Checkpointing: save and resume agent execution.
|
Checkpointing: save and resume agent execution. |
|
graph
command
Example: Content pipeline using Graph orchestration
|
Example: Content pipeline using Graph orchestration |
|
graph-router
command
Example: Graph with Router node for dynamic routing Demonstrates tool usage within graph nodes.
|
Example: Graph with Router node for dynamic routing Demonstrates tool usage within graph nodes. |
|
mcp
command
MCP integration: connect to external tool servers.
|
MCP integration: connect to external tool servers. |
|
multi-turn
command
Multi-turn conversation: pass message history between runs.
|
Multi-turn conversation: pass message history between runs. |
|
multimodal
command
Multimodal input: images, audio, and files alongside text.
|
Multimodal input: images, audio, and files alongside text. |
|
observe
command
Observability: structured events from every decision point.
|
Observability: structured events from every decision point. |
|
real
command
A real agent example using the OpenAI API.
|
A real agent example using the OpenAI API. |
|
serve
command
Example: HTTP server serving multiple agents
|
Example: HTTP server serving multiple agents |
|
skills
command
Skills: load domain-specific knowledge from SKILL.md directories.
|
Skills: load domain-specific knowledge from SKILL.md directories. |
|
state
command
State sharing: scoped state across agents and tool calls.
|
State sharing: scoped state across agents and tool calls. |
|
stream
command
Streaming: real-time token delivery from Agent, Swarm, and Graph.
|
Streaming: real-time token delivery from Agent, Swarm, and Graph. |
|
swarm
command
A swarm example with triage, billing, and support agents.
|
A swarm example with triage, billing, and support agents. |