| name | agentpg |
| description | Build Go applications using the AgentPG framework—event-driven, PostgreSQL-backed AI agents with Claude integration. Use when working with AgentPG clients, agents, tools, sessions, runs, tool.Tool interface, agent hierarchies, distributed workers, compaction, admin UI, run variables, RunOptions, MCP server tools, cancel/regenerate runs, or transaction-safe APIs. |
AgentPG
Event-driven Go framework for async AI agents using PostgreSQL for state management. Source at /home/youssef/projects/agentpg.
Workflow Decision Tree
- New project setup? -> See "Quick Start" below
- Adding tools? -> See references/tools.md
- MCP server tools? -> See references/mcp.md
- Agent hierarchies? -> See references/agents.md
- Cancel or regenerate runs? -> See "Cancel and Regenerate" below
- Tool call visibility / callbacks? -> See "Tool Call Visibility" below
- Distributed workers / transactions / compaction / UI? -> See references/advanced.md
Quick Start
Prerequisites
go get github.com/youssefsiam38/agentpg
go get github.com/youssefsiam38/agentpg/driver/pgxv5
psql $DATABASE_URL -f storage/migrations/001_agentpg_migration.up.sql
Minimal Application
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/youssefsiam38/agentpg"
"github.com/youssefsiam38/agentpg/driver/pgxv5"
)
func main() {
ctx := context.Background()
pool, _ := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
defer pool.Close()
client, _ := agentpg.NewClient(pgxv5.New(pool), &agentpg.ClientConfig{
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
})
client.Start(ctx)
defer client.Stop(context.Background())
agent, _ := client.GetOrCreateAgent(ctx, &agentpg.AgentDefinition{
Name: "assistant",
Model: "claude-sonnet-4-5-20250929",
SystemPrompt: "You are a helpful assistant.",
})
sessionID, _ := client.NewSession(ctx, nil, nil)
response, _ := client.RunFastSync(ctx, sessionID, agent.ID, "Hello!", nil)
fmt.Println(response.Text)
}
Lifecycle Order
RegisterTool() - before Start
agentmcp.RegisterServer() - MCP tools, before Start (optional)
client.Start(ctx) - starts background services
CreateAgent() / GetOrCreateAgent() - after Start (agents are DB entities)
NewSession() -> Run*() / RunFast*() - execute work
client.Stop(ctx) - graceful shutdown
Core Patterns
Run Execution
| Method | API | Behavior |
|---|
Run() | Batch | Async, returns run ID |
RunSync() | Batch | Blocks until complete |
RunTx() | Batch | With transaction |
RunFast() | Streaming | Async, real-time |
RunFastSync() | Streaming | Blocks, low latency |
RunFastTx() | Streaming | With transaction |
All Run methods take: (ctx, sessionID, agentID uuid.UUID, prompt string, opts *RunOptions).
Batch API = 50% cost discount, higher latency. Streaming = standard pricing, real-time.
RunOptions
type RunOptions struct {
Variables map[string]any
OverrideInstructions string
AppendInstructions string
OnToolStart func(ToolCallEvent)
OnToolComplete func(ToolCallEvent)
}
If OverrideInstructions is set, it replaces the system prompt entirely (and AppendInstructions is ignored). If only AppendInstructions is set, it's appended with \n\n. Pass nil for default behavior.
Response Handling
response, err := client.RunFastSync(ctx, sessionID, agent.ID, "Hello!", nil)
Run Variables and Instruction Overrides
Pass per-run data to tools and/or customize the system prompt:
response, _ := client.RunSync(ctx, sessionID, agent.ID, "Process order", &agentpg.RunOptions{
Variables: map[string]any{"order_id": "order-123", "tenant_id": "tenant-1"},
})
response, _ := client.RunFastSync(ctx, sessionID, agent.ID, "Respond in French", &agentpg.RunOptions{
OverrideInstructions: "You are a French-speaking assistant.",
})
response, _ := client.RunFastSync(ctx, sessionID, agent.ID, "Hello!", &agentpg.RunOptions{
AppendInstructions: "Always respond in bullet points.",
})
Variables are accessed in tools via context helpers - see references/tools.md.
Instruction overrides do NOT propagate to child runs; variables DO propagate.
Cancel and Regenerate
err := client.CancelRun(ctx, runID)
newRunID, err := client.RegenerateRun(ctx, runID)
response, _ := client.WaitForRun(ctx, newRunID)
newRunID, _ := client.RunFast(ctx, sessionID, agent.ID, "Do something else", nil)
CancelRun is idempotent (no-op on terminal runs), race-safe (SELECT FOR UPDATE), and unblocks WaitForRun callers. RegenerateRun only works on terminal runs.
Tool Call Visibility
Inspect tool calls after a run completes, in real-time via callbacks, or via query methods.
Post-run inspection:
response, _ := client.RunFastSync(ctx, sessionID, agent.ID, "What's the weather?", nil)
for _, tc := range response.ToolCalls {
fmt.Printf("%s: input=%s output=%s duration=%v\n", tc.Name, tc.Input, tc.Output, tc.Duration)
}
Real-time callbacks:
response, _ := client.RunFastSync(ctx, sessionID, agent.ID, "What's the weather?", &agentpg.RunOptions{
OnToolStart: func(event agentpg.ToolCallEvent) {
fmt.Printf("Tool started: %s\n", event.ToolName)
},
OnToolComplete: func(event agentpg.ToolCallEvent) {
fmt.Printf("Tool completed: %s (took %v, error=%v)\n", event.ToolName, event.Duration, event.IsError)
},
})
Query methods:
toolCalls, _ := client.GetRunToolCalls(ctx, runID)
toolCalls, _ := client.GetIterationToolCalls(ctx, iterID)
Callbacks fire in goroutines with panic recovery (never block tool execution). They are in-memory only — only fire on the instance that executes the tool. Callbacks propagate to child runs in agent-as-tool hierarchies.
Model Selection
"claude-opus-4-5-20251101"
"claude-sonnet-4-5-20250929"
"claude-3-5-haiku-20241022"
Key Types
type AgentDefinition struct {
ID uuid.UUID
Name string
Description string
Model string
SystemPrompt string
Tools []string
AgentIDs []uuid.UUID
MaxTokens *int
Temperature *float64
Metadata map[string]any
}
type Response struct {
Text string
StopReason string
Usage Usage
Message *Message
IterationCount int
ToolIterations int
ToolCalls []ToolCall
}
type ToolCall struct {
Name string
Input json.RawMessage
Output string
IsError bool
ErrorMessage string
IsAgentTool bool
AgentID *uuid.UUID
ChildRunID *uuid.UUID
Duration time.Duration
IterationNumber int
State ToolExecutionState
StartedAt *time.Time
CompletedAt *time.Time
}
type ToolCallEvent struct {
RunID uuid.UUID
SessionID uuid.UUID
ToolName string
ToolInput json.RawMessage
IsAgentTool bool
IterationNumber int
Output string
IsError bool
ErrorMessage string
Duration time.Duration
}
ClientConfig Defaults
MaxConcurrentRuns: 10
MaxConcurrentTools: 50
BatchPollInterval: 30s
RunPollInterval: 1s
ToolPollInterval: 500ms
HeartbeatInterval: 15s
LeaderTTL: 30s
StuckRunTimeout: 5min
Error Handling
Sentinel errors: ErrSessionNotFound, ErrRunNotFound, ErrAgentNotFound, ErrToolNotFound, ErrClientNotStarted, ErrInvalidStateTransition, ErrRunAlreadyFinalized, ErrRunNotCancellable, ErrToolExecutionFailed, ErrCompactionFailed, ErrStorageError.
Tool errors: tool.ToolCancel(err) (no retry), tool.ToolDiscard(err) (permanent), tool.ToolSnooze(duration, err) (retry without consuming attempt), regular error (retried up to MaxAttempts).
References
- references/tools.md - Tool interface, schemas, FuncTool, context helpers, error types, database-aware tools
- references/mcp.md - MCP server tool integration (stdio/HTTP transports, namespacing, error mapping)
- references/agents.md - Agent creation, delegation, multi-level hierarchies, agent-as-tool pattern
- references/advanced.md - Distributed workers, transactions, compaction, admin UI, monitoring, troubleshooting
Examples
Full source code for all examples organized by topic. Consult the relevant file when building a specific feature:
- references/examples-basic.md - Getting started: simple chat, shared tools, database/sql driver, distributed workers
- references/examples-tools.md - Tool patterns: struct tools, FuncTool, schema validation, parallel execution
- references/examples-agents.md - Agent hierarchies: basic delegation, specialist agents, multi-level PM->Lead->Worker
- references/examples-compaction.md - Context management: auto compaction, strategies, manual control, monitoring, extended context
- references/examples-ui.md - Admin UI: basic embedding, auth middleware, full-featured dashboard
- references/examples-retry.md - Error handling: instant retry, ToolCancel/Discard/Snooze error types, exponential backoff
- references/examples-cancel.md - Cancel and regenerate: stop running agents, regenerate failed runs, continuation after cancel
- references/examples-tool-calls.md - Tool call visibility: real-time callbacks, Response.ToolCalls inspection, GetRunToolCalls queries