sdk

package module
v0.9.20 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: Apache-2.0 Imports: 7 Imported by: 2

Documentation

Overview

Package sdk provides the public interface for building Roobai agentic apps.

Developers implement the AgentPlugin interface and export it as a symbol named "Agent" in their Go plugin:

var Agent sdk.AgentPlugin = &MyApp{}

Package sdk provides the public interface for building Roobai agentic apps.

Design Philosophy

The SDK follows an interface-only design. Plugin developers see only interfaces and types - never implementation details. All functionality is accessed through PlatformContext, which is injected by the runtime:

  • [PlatformContext.LLM] - Language model access
  • [PlatformContext.RAG] - Document storage and retrieval
  • [PlatformContext.Router] - Inter-agent communication
  • [PlatformContext.Logger] - Structured logging
  • [PlatformContext.SDK] - High-level agentic utilities (RunLoop, Memory, etc.)

This design enables:

  • Clean separation between SDK (FOSS) and platform (may be proprietary)
  • Easy mocking for tests
  • Implementation flexibility without breaking plugins

Quick Start

Create a Go file that exports an Agent variable implementing AgentPlugin:

package main

import (
    "context"
    "codeberg.org/roobai/roobai-sdk/sdk"
)

var Agent sdk.AgentPlugin = &MyApp{}

type MyApp struct{}

func (a *MyApp) Spec() sdk.AgenticAppSpec {
    return sdk.AgenticAppSpec{
        Name:        "my-app",
        Description: "My first agentic app",
        Version:     "1.0.0",
        Avatar:      sdk.MustEmoji("🤖"),
        Actions: []sdk.ActionSpec{
            {
                Name:        "greet",
                Description: "Greet a user by name",
                Input: sdk.ToolInput(
                    sdk.WithString("name", sdk.Required(), sdk.Description("User's name")),
                ),
            },
        },
    }
}

func (a *MyApp) New(pctx sdk.PlatformContext) (sdk.AgentInstance, error) {
    return &MyInstance{pctx: pctx}, nil
}

type MyInstance struct {
    pctx sdk.PlatformContext
}

func (i *MyInstance) Handle(ctx context.Context, msg sdk.Message) (sdk.Response, error) {
    name, _ := msg.Params["name"].(string)
    return sdk.Response{Content: "Hello, " + name + "!"}, nil
}

func (i *MyInstance) Start() error { return nil }
func (i *MyInstance) Stop() error  { return nil }

Build as a Go plugin:

go build -buildmode=plugin -o agent.so .

Using the Agentic Loop

For complex tasks that require tool orchestration, use [SDK.RunLoop]:

func (i *MyInstance) Handle(ctx context.Context, msg sdk.Message) (sdk.Response, error) {
    result, err := i.pctx.SDK().RunLoop(ctx, sdk.LoopConfig{
        SystemPrompt:  "You are a helpful assistant with access to weather and news tools.",
        MaxIterations: 5,
        Model:         "", // uses gateway default
    }, msg.Content)
    if err != nil {
        return sdk.Response{Error: err.Error()}, nil
    }
    return sdk.Response{Content: result.Content}, nil
}

Direct LLM Access

For simple LLM calls without tool orchestration:

func (i *MyInstance) Handle(ctx context.Context, msg sdk.Message) (sdk.Response, error) {
    resp, err := i.pctx.LLM().Chat(ctx, []sdk.ChatMessage{
        {Role: "system", Content: "You are a helpful assistant."},
        {Role: "user", Content: msg.Content},
    }, sdk.WithMaxTokens(500))
    if err != nil {
        return sdk.Response{Error: err.Error()}, nil
    }
    return sdk.Response{Content: resp.Content}, nil
}

App Lifecycle

  1. Plugin is loaded and Agent symbol is looked up
  2. [AgentPlugin.Spec] is called to get capabilities and register with gateway
  3. [AgentPlugin.New] is called with PlatformContext to create an instance
  4. [AgentInstance.Start] is called to initialize the instance
  5. [AgentInstance.Handle] is called for each incoming message
  6. [AgentInstance.Stop] is called during shutdown

Security

App code runs in a sandboxed environment. Direct network access and system calls are restricted. All external communication should go through the SDK interfaces (LLM, RAG, Router).

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidEmoji = errors.New("avatar must be a single emoji")

ErrInvalidEmoji is returned when the avatar is not a valid emoji.

Functions

func IsEmoji

func IsEmoji(s string) bool

IsEmoji checks if the given string is a valid emoji. Deprecated: Use NewEmoji() for validated emoji creation.

func PartsToText added in v0.3.0

func PartsToText(parts []Part) string

PartsToText extracts the concatenated text content from parts. Non-text parts are ignored.

func ValidateSpec

func ValidateSpec(spec AgenticAppSpec) error

ValidateSpec validates an AgenticAppSpec and returns an error if invalid. Note: Avatar validation happens at the type level via the Emoji type. This function is provided for additional spec validation if needed.

Types

type ActionSpec

type ActionSpec struct {
	// Name is the identifier for this action (e.g., "get_tides").
	Name string

	// Description explains what this action does.
	Description string

	// Input is the JSON schema for the action's input parameters.
	Input Schema

	// Output is the JSON schema for the action's response.
	Output Schema
}

ActionSpec describes a single action that an agent can perform.

type AgentDiscoveryConfig added in v0.3.0

type AgentDiscoveryConfig struct {
	// Enabled activates agent discovery in the loop.
	Enabled bool

	// MaxAgents is the maximum number of agents to discover per iteration (default: 3).
	MaxAgents int

	// MinScore is the minimum similarity score for agent inclusion (default: 0.5).
	MinScore float64

	// ShareContext sends caller conversation context to delegates.
	ShareContext bool

	// Budget limits resource consumption for each delegation.
	Budget *TaskBudget

	// AgentFilter excludes agents from discovery.
	// Called for each discovered agent; return false to exclude.
	AgentFilter func(agent AgentMatch) bool

	// OnDelegateEvent is called for each streaming event during agent delegation.
	// When set, the loop uses DelegateToAgentStream instead of DelegateToAgent,
	// enabling real-time visibility into the sub-agent's internal activity.
	// The agentName parameter identifies which agent produced the event.
	OnDelegateEvent func(agentName string, event DelegateEvent)
}

AgentDiscoveryConfig configures agent discovery in the agentic loop. When enabled, the loop discovers delegatable agents alongside tools and presents them to the LLM as callable functions with "agent:" prefix.

type AgentInfo

type AgentInfo struct {
	// Name is the agent's unique identifier.
	Name string

	// Description explains what the agent does.
	Description string

	// Capabilities lists the agent's capability tags.
	Capabilities []string

	// Actions lists available actions.
	Actions []ActionSpec

	// Stats contains performance statistics.
	Stats AgentStats
}

AgentInfo contains information about a discovered agent.

type AgentInstance

type AgentInstance interface {
	// Handle processes an incoming message and returns a response.
	// This is the main entry point for agentic logic.
	Handle(ctx context.Context, msg Message) (Response, error)

	// Start is called when the app instance is initialized.
	// Use this for any setup that needs to happen before handling messages.
	Start() error

	// Stop is called when the app instance is being shut down.
	// Use this for cleanup operations.
	Stop() error
}

AgentInstance represents a running instance of an agentic app.

type AgentMatch

type AgentMatch struct {
	// Agent contains the agent information.
	AgentInfo

	// Score is the semantic similarity score (0.0-1.0, higher is more relevant).
	Score float64
}

AgentMatch represents an agent found via semantic search with a relevance score.

type AgentModeSpec added in v0.3.0

type AgentModeSpec struct {
	// Instruction describes what this agent does when delegated to.
	// Shown to calling LLMs for routing decisions.
	Instruction string

	// Skills are discrete capabilities the agent offers for delegation.
	Skills []AgentSkill

	// AcceptsContext signals that this agent uses caller conversation context.
	AcceptsContext bool

	// Streaming signals that this agent streams output during processing.
	Streaming bool

	// InputSchema defines optional structured parameters on top of the prompt.
	InputSchema *Schema

	// OutputSchema defines guaranteed output structure (if any).
	OutputSchema *Schema

	// MaxDuration is the estimated maximum processing time.
	MaxDuration time.Duration
}

AgentModeSpec declares that an agent is available for delegation. When set on AgenticAppSpec.AgentMode, the agent appears in delegation searches and can be invoked via router.Delegate* methods.

type AgentPlugin

type AgentPlugin interface {
	// Spec returns the app's specification including name, description,
	// capabilities, and available actions.
	Spec() AgenticAppSpec

	// New creates a new instance of the app with the given platform context.
	// The platform context provides access to LLM, RAG, routing, and logging.
	New(ctx PlatformContext) (AgentInstance, error)
}

AgentPlugin is the main interface that agentic app developers implement. The plugin must export a variable named "Agent" of this type.

type AgentRouter

type AgentRouter interface {
	// Call invokes another agent by capability or name.
	// The router selects the best available agent based on relevance,
	// reputation, latency, and cost.
	Call(ctx context.Context, query string, content string, opts ...CallOption) (Response, error)

	// CallWithTrace invokes an agent and returns detailed call metadata.
	// Use this when you need to track agent calls for debugging or auditing.
	CallWithTrace(ctx context.Context, query string, content string, opts ...CallOption) (CallResult, error)

	// CallAgent invokes a specific agent by name.
	// Use this when you need a specific agent rather than capability-based routing.
	CallAgent(ctx context.Context, agentName string, msg Message) (Response, error)

	// Discover finds agents matching a capability query.
	// Returns agent information without invoking them.
	Discover(ctx context.Context, query string, opts ...DiscoverOption) ([]AgentInfo, error)

	// Search performs semantic search to find agents matching a natural language query.
	// Uses embeddings to find semantically similar agents based on their description,
	// capabilities, and actions. Returns agents ranked by relevance score.
	Search(ctx context.Context, query string, opts ...DiscoverOption) ([]AgentMatch, error)

	// SearchTools performs semantic search to find tools (agent actions) matching a query.
	// Unlike Search which returns agents, this returns individual tools that can be
	// used for LLM function calling. Tools from multiple agents may be returned.
	SearchTools(ctx context.Context, query string, opts ...DiscoverOption) ([]ToolMatch, error)

	// CallTool invokes a specific tool by its ID (format: "agent_name/action_name").
	// This is used by the agentic loop to execute tool calls from the LLM.
	CallTool(ctx context.Context, toolID string, args map[string]any) (Response, error)

	// Delegate submits a task to the best matching agent.
	// Returns immediately with a Task in "submitted" state.
	// Use Events() or Tasks() to track progress.
	Delegate(ctx context.Context, req DelegateRequest) (*Task, error)

	// DelegateSync submits a task and blocks until completion.
	// Convenience wrapper around Delegate + wait.
	DelegateSync(ctx context.Context, req DelegateRequest) (*Task, error)

	// DelegateToAgent submits a task to a specific agent by name.
	DelegateToAgent(ctx context.Context, agentName string, req DelegateRequest) (*Task, error)

	// DelegateToAgentStream submits a task to a specific agent and streams
	// intermediate events (tool calls, LLM usage) back to the caller via handler.
	// Falls back to DelegateToAgent if the gateway doesn't support streaming.
	DelegateToAgentStream(ctx context.Context, agentName string, req DelegateRequest, handler DelegateEventHandler) (*Task, error)

	// SearchAgents finds agents available for delegation (AgentMode != nil).
	// Uses semantic search over agent instructions and skills.
	SearchAgents(ctx context.Context, query string, opts ...DiscoverOption) ([]AgentMatch, error)

	// RespondToTask sends additional input to a task in "input_needed" state.
	RespondToTask(ctx context.Context, taskID string, input []Part) error

	// CancelTask requests cancellation of a running task.
	CancelTask(ctx context.Context, taskID string) error

	// ReportToolFeedback sends a usage feedback signal for a tool.
	// outcome is "useful" or "irrelevant". This is fire-and-forget;
	// implementations should not block on errors.
	ReportToolFeedback(ctx context.Context, toolID string, outcome string)
}

AgentRouter provides access to other agents in the platform. The router handles discovery, load balancing, and request forwarding.

type AgentSkill added in v0.3.0

type AgentSkill struct {
	// Name is a short identifier (e.g., "web-search", "weather-forecast").
	Name string `json:"name"`

	// Description explains what this skill does (shown to LLMs).
	Description string `json:"description"`

	// Tags are optional labels for filtering (e.g., ["search", "web"]).
	Tags []string `json:"tags,omitempty"`
}

AgentSkill is a discrete capability an agent offers for delegation.

type AgentStats

type AgentStats struct {
	// SuccessRate is the percentage of successful calls (0.0-1.0).
	SuccessRate float64

	// AvgLatencyMs is the average response time in milliseconds.
	AvgLatencyMs float64

	// AvgCost is the average cost per request (in platform credits).
	AvgCost float64
}

AgentStats contains agent performance metrics.

type AgenticAppSpec

type AgenticAppSpec struct {
	// AppId is the Roobai app instance identifier (e.g., "citron-benet-21").
	// This is set automatically by the platform at runtime and should not be
	// set by the developer. It's used for agent registration and routing.
	AppId string

	// Name is the unique identifier for this app (e.g., "tide-finder").
	Name string

	// Description is a human-readable description of what the app does.
	Description string

	// Version is the semantic version of the app (e.g., "1.0.0").
	Version string

	// Avatar is an emoji that represents this agent (e.g., "🌤️", "📰", "🤖").
	// Must be a single emoji. Used in UIs like PocketChat for visual identification.
	// Use sdk.MustEmoji("🤖") to create, or leave empty for default.
	Avatar Emoji

	// Capabilities is a list of capability tags for discovery (e.g., ["websearch", "weather"]).
	Capabilities []string

	// Actions is the list of actions this app can perform.
	Actions []ActionSpec

	// CustomUI indicates the app provides its own web UI at "/".
	// If false, the platform provides a default landing page.
	CustomUI bool

	// AgentMode declares this agent as available for delegation.
	// When non-nil, the agent appears in delegation searches and can be
	// invoked via router.Delegate* methods. See AgentModeSpec for details.
	// Nil means the agent is tool-only (existing behavior).
	AgentMode *AgentModeSpec
}

AgenticAppSpec describes an agentic app's capabilities and available actions.

type Artifact added in v0.3.0

type Artifact struct {
	// ID is the platform-assigned artifact identifier.
	ID string `json:"id"`

	// Name is a human-readable name for this artifact (e.g., "market-analysis").
	Name string `json:"name"`

	// Parts is the artifact's content.
	Parts []Part `json:"parts"`

	// Metadata carries additional artifact-level key-value pairs.
	Metadata map[string]string `json:"metadata,omitempty"`

	// TaskID is the ID of the task that produced this artifact.
	TaskID string `json:"taskId"`

	// Index is the artifact's position within the task (0-based).
	Index int `json:"index"`
}

Artifact is a named, typed output produced during task execution. Unlike task output (the "answer"), artifacts are discrete deliverables: files, datasets, reports, generated images.

type ArtifactBuilder added in v0.3.0

type ArtifactBuilder struct {
	// Name is a human-readable name for the artifact.
	Name string

	// Parts is the artifact's content.
	Parts []Part

	// Metadata carries additional artifact-level key-value pairs.
	Metadata map[string]string
}

ArtifactBuilder is used by agents to construct and emit artifacts during task execution via TaskContext.EmitArtifact().

type BlobInfo added in v0.9.10

type BlobInfo struct {
	// Name is the blob identifier.
	Name string

	// Size is the blob size in bytes.
	Size int64

	// MimeType is the content type (e.g., "image/png").
	MimeType string

	// CreatedAt is when the blob was stored.
	CreatedAt time.Time

	// Metadata carries user-defined key-value pairs.
	Metadata map[string]string
}

BlobInfo describes a stored blob.

type BlobOption added in v0.9.10

type BlobOption func(*BlobOptions)

BlobOption configures blob storage behavior.

func WithBlobMetadata added in v0.9.10

func WithBlobMetadata(meta map[string]string) BlobOption

WithBlobMetadata sets user-defined metadata on the blob.

func WithBlobMimeType added in v0.9.10

func WithBlobMimeType(mime string) BlobOption

WithBlobMimeType sets the MIME type of the blob.

func WithBlobTTL added in v0.9.10

func WithBlobTTL(ttl time.Duration) BlobOption

WithBlobTTL sets the time-to-live for the blob.

type BlobOptions added in v0.9.10

type BlobOptions struct {
	// MimeType sets the content type of the blob.
	MimeType string

	// TTL sets the time-to-live. Zero means no expiration.
	TTL time.Duration

	// Metadata sets user-defined key-value pairs on the blob.
	Metadata map[string]string
}

BlobOptions holds all configurable options for blob operations.

func ApplyBlobOptions added in v0.9.10

func ApplyBlobOptions(opts ...BlobOption) BlobOptions

ApplyBlobOptions applies the given options to a BlobOptions struct.

type BlobStore added in v0.9.10

type BlobStore interface {
	// Put stores a blob and returns its metadata.
	// The name must be unique within the store.
	Put(ctx context.Context, name string, reader io.Reader, opts ...BlobOption) (*BlobInfo, error)

	// Get retrieves a blob by name.
	// Returns the content reader and metadata.
	// The caller must close the reader when done.
	Get(ctx context.Context, name string) (io.ReadCloser, *BlobInfo, error)

	// Delete removes a blob by name.
	Delete(ctx context.Context, name string) error

	// List returns metadata for all blobs in the store.
	List(ctx context.Context) ([]BlobInfo, error)
}

BlobStore provides binary object storage backed by NATS Object Store.

Used for transferring large payloads (files, images, audio) between agents that exceed NATS message size limits. Agents store blobs and pass lightweight references in messages.

Access via [PlatformContext.Blobs].

type CallOption

type CallOption func(*CallOptions)

CallOption configures agent call behavior.

func WithAction

func WithAction(action string) CallOption

WithAction specifies the action to invoke.

func WithMaxCost

func WithMaxCost(cost float64) CallOption

WithMaxCost sets the maximum acceptable cost.

func WithMaxLatency

func WithMaxLatency(ms int) CallOption

WithMaxLatency sets the maximum acceptable latency.

func WithTimeout

func WithTimeout(ms int) CallOption

WithTimeout sets the call timeout.

type CallOptions

type CallOptions struct {
	// Action specifies which action to invoke on the target agent.
	Action string

	// MaxLatencyMs sets the maximum acceptable latency for agent selection.
	MaxLatencyMs int

	// MaxCost sets the maximum acceptable cost for agent selection.
	MaxCost float64

	// Timeout overrides the default call timeout.
	TimeoutMs int
}

CallOptions contains all configurable options for agent calls.

func ApplyCallOptions

func ApplyCallOptions(opts ...CallOption) CallOptions

ApplyCallOptions applies the given options to a CallOptions struct.

type CallResult

type CallResult struct {
	// Response is the agent's response.
	Response Response

	// Agent is the name of the agent that handled the request.
	Agent string

	// Query is the query/capability used to route the request.
	Query string

	// Duration is how long the call took.
	Duration time.Duration

	// Request contains the original request parameters.
	Request map[string]any
}

CallResult contains the response from an agent call along with call metadata. Use this for debugging, auditing, or displaying call traces to users.

type ChatMessage

type ChatMessage struct {
	// Role is the message role: "system", "user", "assistant", or "tool".
	Role string

	// Content is the text content of the message.
	Content string

	// ToolCalls contains tool invocations when role is "assistant".
	// Only set when the model wants to call tools.
	ToolCalls []ToolCall

	// ToolCallID is set when role is "tool" to link the response to a tool call.
	ToolCallID string

	// Name is set when role is "tool" to identify which tool this response is from.
	Name string
}

ChatMessage represents a single message in an LLM conversation.

type ChatOption

type ChatOption func(*ChatOptions)

ChatOption configures chat request behavior.

func WithMaxTokens

func WithMaxTokens(max int) ChatOption

WithMaxTokens sets the maximum response tokens.

func WithModel

func WithModel(model string) ChatOption

WithModel sets the preferred model for the request.

func WithProvider added in v0.6.0

func WithProvider(provider string) ChatOption

WithProvider sets the LLM provider for the request (e.g. "copilot", "ovh").

func WithResponseFormat

func WithResponseFormat(rf *ResponseFormat) ChatOption

WithResponseFormat sets the response format for structured output. Use ResponseFormatJSONSchemaFrom to enforce a specific JSON schema.

func WithStop

func WithStop(sequences ...string) ChatOption

WithStop sets stop sequences for the request.

func WithStreamCallback

func WithStreamCallback(callback StreamCallback) ChatOption

WithStreamCallback enables streaming mode and sets the callback. The callback is called for each chunk of content as it arrives. Return an error from the callback to abort the stream.

func WithTemperature

func WithTemperature(temp float64) ChatOption

WithTemperature sets the temperature for the request.

func WithToolChoice

func WithToolChoice(choice string) ChatOption

WithToolChoice controls how the model uses tools. "auto" = model decides, "none" = disable, "required" = must use a tool.

func WithTools

func WithTools(tools []Tool) ChatOption

WithTools sets the tools available for the model to call.

func WithTopP

func WithTopP(p float64) ChatOption

WithTopP sets the top-p (nucleus sampling) value.

type ChatOptions

type ChatOptions struct {
	// Model specifies a preferred model (may be overridden by platform).
	Model string

	// Provider specifies which LLM provider to use (e.g. "copilot", "ovh").
	// If empty, the platform uses the user's configured default provider.
	Provider string

	// MaxTokens limits the response length.
	MaxTokens int

	// Temperature controls randomness (0.0 = deterministic, 1.0 = creative).
	Temperature float64

	// TopP controls nucleus sampling probability.
	TopP float64

	// Stop sequences that will halt generation.
	Stop []string

	// Tools is a list of tools the model can call.
	Tools []Tool

	// ToolChoice controls how the model uses tools.
	// "auto" (default) = model decides, "none" = disable tools, "required" = must use a tool.
	ToolChoice string

	// StreamCallback is called for each chunk during streaming.
	// If set, the Chat method will use streaming mode.
	StreamCallback StreamCallback

	// ResponseFormat controls the format of the LLM's response.
	// Use this to enforce structured output via JSON schema.
	ResponseFormat *ResponseFormat
}

ChatOptions contains all configurable options for chat requests.

func ApplyChatOptions

func ApplyChatOptions(opts ...ChatOption) ChatOptions

ApplyChatOptions applies the given options to a ChatOptions struct.

type ChatResponse

type ChatResponse struct {
	// Content is the assistant's response text.
	// May be empty if the response contains only tool calls.
	Content string

	// ToolCalls contains tool invocations requested by the model.
	// When non-empty, the caller should execute these tools and send results back.
	ToolCalls []ToolCall

	// FinishReason indicates why the response ended.
	// "stop" = normal completion, "tool_calls" = model wants to call tools, "length" = max tokens reached.
	FinishReason string

	// Usage contains token usage statistics.
	Usage TokenUsage
}

ChatResponse represents the LLM's response to a chat request.

type ContentPrefs added in v0.3.0

type ContentPrefs struct {
	Accept []ContentType `json:"accept,omitempty"`
}

ContentPrefs declares which content types a caller accepts. The callee SHOULD respect these or fall back to text.

type ContentType added in v0.3.0

type ContentType string

ContentType identifies the kind of content in a Part.

const (
	ContentText    ContentType = "text"
	ContentJSON    ContentType = "json"
	ContentFile    ContentType = "file"
	ContentImage   ContentType = "image"
	ContentAudio   ContentType = "audio"
	ContentDataRef ContentType = "data_ref"
)

type DelegateEvent added in v0.4.0

type DelegateEvent struct {
	Type   DelegateEventType `json:"type"`
	TaskID string            `json:"task_id"`
	Data   map[string]any    `json:"data"`
}

DelegateEvent is a streaming event emitted during delegation.

type DelegateEventHandler added in v0.4.0

type DelegateEventHandler func(event DelegateEvent)

DelegateEventHandler processes streaming events during delegation.

type DelegateEventType added in v0.4.0

type DelegateEventType string

DelegateEventType identifies the kind of streaming delegation event.

const (
	DelegateEventToolStart DelegateEventType = "task.tool.start"
	DelegateEventToolEnd   DelegateEventType = "task.tool.end"
	DelegateEventLLMStart  DelegateEventType = "task.llm.start"
	DelegateEventLLMEnd    DelegateEventType = "task.llm.end"
	DelegateEventProgress  DelegateEventType = "task.progress"
	DelegateEventOutput    DelegateEventType = "task.output"
	DelegateEventComplete  DelegateEventType = "task.complete"
)

type DelegateRequest added in v0.3.0

type DelegateRequest struct {
	// Prompt is the task description in natural language.
	Prompt string

	// Parts allows multipart input (alternative to Prompt for rich content).
	// If both are set, Prompt is prepended as a text Part.
	Parts []Part

	// ContextID links this task to an existing conversation context.
	ContextID string

	// Params are optional structured parameters (matched against InputSchema).
	Params map[string]any

	// Context provides conversation context from the caller to the delegate.
	Context *DelegationContext

	// ContentPrefs declares which output content types the caller accepts.
	ContentPrefs *ContentPrefs

	// Budget limits the delegate's resource consumption.
	Budget *TaskBudget

	// Async controls whether the task runs asynchronously.
	// When true, Delegate returns immediately with a submitted task.
	// When false (default for DelegateSync), blocks until completion.
	Async bool
}

DelegateRequest describes a task to delegate to another agent.

type DelegationContext added in v0.3.0

type DelegationContext struct {
	// Summary of the caller's ongoing conversation.
	Summary string

	// RecentMessages from the caller's conversation.
	RecentMessages []ChatMessage

	// Constraints imposed by the caller.
	Constraints map[string]string
}

DelegationContext carries caller context to a delegate agent.

type DiscoverOption

type DiscoverOption func(*DiscoverOptions)

DiscoverOption configures discovery behavior.

func WithCapabilities

func WithCapabilities(caps ...string) DiscoverOption

WithCapabilities filters discovery to agents with specific capabilities.

func WithDiscoverLimit

func WithDiscoverLimit(n int) DiscoverOption

WithDiscoverLimit sets the maximum number of agents to discover.

func WithExcludeTools added in v0.4.0

func WithExcludeTools(tools ...string) DiscoverOption

WithExcludeTools excludes specific tool IDs from discovery results. Used to prevent the loop from re-discovering tools it has already tried.

func WithRecentTools

func WithRecentTools(tools ...string) DiscoverOption

WithRecentTools provides recently used tool IDs to bias search toward complementary tools, reducing redundant suggestions.

func WithSearchContext

func WithSearchContext(searchCtx string) DiscoverOption

WithSearchContext provides conversation context to enrich search queries. The context is combined with the query to produce a richer embedding that captures the user's intent more accurately.

type DiscoverOptions

type DiscoverOptions struct {
	// Limit is the maximum number of agents to return.
	Limit int

	// Capabilities filters to agents with specific capabilities.
	Capabilities []string

	// Context provides conversation context to enrich the search embedding.
	// When set, the search query is augmented with this context to improve
	// relevance (e.g., the ongoing conversation summary or user intent).
	Context string

	// RecentTools lists tool IDs that were recently used. The search engine
	// uses this to bias results toward complementary tools, avoiding
	// redundant suggestions.
	RecentTools []string

	// ExcludeTools lists tool IDs (or agent: prefixed agent names) to exclude
	// from results. Used to prevent re-discovery of tools already tried in
	// the current loop iteration.
	ExcludeTools []string
}

DiscoverOptions contains all configurable options for agent discovery.

func ApplyDiscoverOptions

func ApplyDiscoverOptions(opts ...DiscoverOption) DiscoverOptions

ApplyDiscoverOptions applies the given options to a DiscoverOptions struct.

type Document

type Document struct {
	// ID is a unique identifier for the document.
	// If empty, one will be generated.
	ID string

	// Content is the document text to be embedded and searched.
	Content string

	// Metadata contains additional fields for filtering and display.
	Metadata map[string]string
}

Document represents a document to store in RAG.

type DocumentMeta

type DocumentMeta struct {
	// ID is the document identifier.
	ID string

	// Metadata contains the document's metadata fields.
	Metadata map[string]string

	// CreatedAt is when the document was stored.
	CreatedAt int64
}

DocumentMeta contains document metadata without content.

type Emoji

type Emoji string

Emoji is a type-safe wrapper for emoji strings. It validates that the value is a valid emoji on creation and unmarshaling.

func MustEmoji

func MustEmoji(s string) Emoji

MustEmoji creates a validated Emoji from a string, panicking if invalid. Use this for compile-time constant emojis where you're certain of validity.

func NewEmoji

func NewEmoji(s string) (Emoji, error)

NewEmoji creates a validated Emoji from a string. Returns an error if the string is not a valid emoji. An empty string is allowed (represents no avatar).

func (Emoji) IsEmpty

func (e Emoji) IsEmpty() bool

IsEmpty returns true if no emoji is set.

func (Emoji) MarshalJSON

func (e Emoji) MarshalJSON() ([]byte, error)

MarshalJSON serializes the emoji to JSON.

func (Emoji) String

func (e Emoji) String() string

String returns the emoji as a string.

func (*Emoji) UnmarshalJSON

func (e *Emoji) UnmarshalJSON(data []byte) error

UnmarshalJSON validates the emoji when deserializing from JSON.

type ErrorHandler

type ErrorHandler struct {
	// MaxConsecutiveErrors stops the loop after N consecutive tool errors.
	// Default: 3
	MaxConsecutiveErrors int

	// FormatError transforms error messages before adding to conversation.
	// If nil, uses default formatting.
	FormatError func(err error) string

	// FallbackResponse is returned if max iterations or errors reached.
	// If empty, returns an error instead.
	FallbackResponse string
}

ErrorHandler configures graceful error recovery.

type Event added in v0.3.0

type Event struct {
	// ID is a unique event identifier.
	ID string `json:"id"`

	// Type identifies the kind of event.
	Type EventType `json:"type"`

	// Source is the agent that produced this event.
	Source string `json:"source"`

	// TaskID is the associated task (empty for agent lifecycle events).
	TaskID string `json:"taskId,omitempty"`

	// Timestamp is the Unix timestamp (seconds) when the event was created.
	Timestamp int64 `json:"timestamp"`

	// Data carries the event-specific payload.
	Data any `json:"data"`
}

Event is the envelope for all platform events published over NATS.

type EventType added in v0.3.0

type EventType string

EventType identifies the kind of event.

const (
	EventTaskStatusChanged EventType = "task.status.changed"
	EventTaskProgress      EventType = "task.progress"
	EventTaskArtifact      EventType = "task.artifact"
	EventTaskOutput        EventType = "task.output"
	EventAgentStarted      EventType = "agent.started"
	EventAgentStopped      EventType = "agent.stopped"
	EventAgentSignal       EventType = "agent.signal"

	// Sub-agent loop events — published by TaskEventCallbacks during delegation.
	EventTaskToolStart EventType = "task.tool.start"
	EventTaskToolEnd   EventType = "task.tool.end"
	EventTaskLLMStart  EventType = "task.llm.start"
	EventTaskLLMEnd    EventType = "task.llm.end"
)

type Field

type Field struct {
	Key   string
	Value any
}

Field represents a key-value pair for structured logging.

func Bool

func Bool(key string, value bool) Field

Bool creates a bool field.

func Err

func Err(err error) Field

Err creates an error field with the key "error".

func F

func F(key string, value any) Field

F creates a logging field with the given key and value.

func Float64

func Float64(key string, value float64) Field

Float64 creates a float64 field.

func Int

func Int(key string, value int) Field

Int creates an int field.

func Int64

func Int64(key string, value int64) Field

Int64 creates an int64 field.

func String

func String(key, value string) Field

String creates a string field.

type FileRef added in v0.3.0

type FileRef struct {
	// FileID is the platform-assigned file identifier.
	FileID string `json:"fileId"`

	// FileName is the original file name.
	FileName string `json:"fileName,omitempty"`

	// MimeType is the file's MIME type.
	MimeType string `json:"mimeType,omitempty"`

	// Size is the file size in bytes.
	Size int64 `json:"size,omitempty"`
}

FileRef references a file stored on the platform.

type FinishReason

type FinishReason string

FinishReason indicates why the agentic loop ended.

const (
	FinishReasonComplete  FinishReason = "complete"       // LLM gave final response
	FinishReasonMaxIter   FinishReason = "max_iterations" // Hit MaxIterations
	FinishReasonMaxErrors FinishReason = "max_errors"     // Too many consecutive errors
	FinishReasonNoTools   FinishReason = "no_tools"       // No tools available
	FinishReasonCanceled  FinishReason = "canceled"       // Context canceled
)

type FunctionCall

type FunctionCall struct {
	// Name is the function/tool name to invoke.
	Name string

	// Arguments is a JSON string containing the function arguments.
	Arguments string
}

FunctionCall contains the function name and arguments for a tool call.

type FunctionDef

type FunctionDef struct {
	// Name is the function name (should match action names).
	Name string

	// Description explains what the function does.
	Description string

	// Parameters is the JSON Schema for the function's parameters.
	Parameters map[string]any
}

FunctionDef defines a function that the LLM can call.

type InputOption

type InputOption func(*Schema)

InputOption is a function that configures a Schema (used with ToolInput).

func WithArray

func WithArray(name string, items Schema, opts ...PropertyOption) InputOption

WithArray adds an array property to the schema.

func WithBoolean

func WithBoolean(name string, opts ...PropertyOption) InputOption

WithBoolean adds a boolean property to the schema.

func WithInteger

func WithInteger(name string, opts ...PropertyOption) InputOption

WithInteger adds an integer property to the schema.

func WithNumber

func WithNumber(name string, opts ...PropertyOption) InputOption

WithNumber adds a number property to the schema.

func WithObject

func WithObject(name string, nested Schema, opts ...PropertyOption) InputOption

WithObject adds a nested object property to the schema.

func WithSchema

func WithSchema(name string, schema Schema, opts ...PropertyOption) InputOption

WithSchema adds a property with an arbitrary schema.

func WithString

func WithString(name string, opts ...PropertyOption) InputOption

WithString adds a string property to the schema.

type LLMClient

type LLMClient interface {
	// Chat sends a conversation to the LLM and returns the response.
	// If [WithStreamCallback] is provided, the response is streamed chunk by chunk.
	Chat(ctx context.Context, messages []ChatMessage, opts ...ChatOption) (ChatResponse, error)

	// ChatStream sends a conversation to the LLM and streams the response.
	// Each chunk of content is passed to the callback as it arrives.
	// Returns the complete response after streaming finishes.
	ChatStream(ctx context.Context, messages []ChatMessage, callback StreamCallback, opts ...ChatOption) (ChatResponse, error)

	// Complete generates a completion for the given prompt.
	// This is a convenience method equivalent to a single-message chat.
	Complete(ctx context.Context, prompt string, opts ...ChatOption) (string, error)

	// Embed generates vector embeddings for the given texts.
	// Useful for semantic search and RAG applications.
	Embed(ctx context.Context, texts []string) ([][]float64, error)
}

LLMClient provides access to language model capabilities.

The platform handles model selection, credentials, and rate limiting. Access via [PlatformContext.LLM]:

resp, err := pctx.LLM().Chat(ctx, messages, sdk.WithMaxTokens(500))

type Logger

type Logger interface {
	// Debug logs a debug-level message.
	Debug(msg string, fields ...Field)

	// Info logs an info-level message.
	Info(msg string, fields ...Field)

	// Warn logs a warning-level message.
	Warn(msg string, fields ...Field)

	// Error logs an error-level message.
	Error(msg string, fields ...Field)

	// With returns a logger with the given fields added to all messages.
	With(fields ...Field) Logger
}

Logger provides structured logging for agents. Log output is captured by the platform for monitoring and debugging.

type LoopCallbacks

type LoopCallbacks interface {
	// OnLoopStart is called when the loop begins.
	OnLoopStart(ctx context.Context, input string, tools []Tool)

	// OnLoopEnd is called when the loop completes (success or failure).
	OnLoopEnd(ctx context.Context, result *LoopResult, err error)

	// OnIteration is called at the start of each loop iteration.
	OnIteration(ctx context.Context, iteration int, steps []Step)

	// OnToolStart is called before executing a tool.
	OnToolStart(ctx context.Context, action ToolAction)

	// OnToolEnd is called after a tool completes (success or failure).
	OnToolEnd(ctx context.Context, action ToolAction, result string, err error, duration time.Duration)

	// OnLLMStart is called before sending messages to the LLM.
	OnLLMStart(ctx context.Context, messages []ChatMessage)

	// OnLLMEnd is called after receiving an LLM response.
	OnLLMEnd(ctx context.Context, response string, usage TokenUsage)

	// OnStreamChunk is called for each streaming chunk from the LLM.
	// Return an error to abort streaming.
	OnStreamChunk(ctx context.Context, chunk []byte) error
}

LoopCallbacks provides hooks for observability during the agentic loop.

All methods are optional - implement only what you need. Use NoopCallbacks as a base to avoid implementing unused methods:

type MyCallbacks struct {
    sdk.NoopCallbacks
    logger sdk.Logger
}

func (c *MyCallbacks) OnToolStart(ctx context.Context, action sdk.ToolAction) {
    c.logger.Info("Calling tool", sdk.String("tool", action.ToolID))
}

For standard logging, use [SDK.NewLoggingCallbacks]:

callbacks := pctx.SDK().NewLoggingCallbacks(pctx.Logger())

func ComposeCallbacks added in v0.4.0

func ComposeCallbacks(a, b LoopCallbacks) LoopCallbacks

ComposeCallbacks combines two LoopCallbacks so each callback method fires on both. If either is nil, the other is returned directly.

type LoopConfig

type LoopConfig struct {
	// SystemPrompt sets the system instructions for the LLM.
	// Tool instructions will be appended automatically.
	SystemPrompt string

	// Tools are the tools available for the LLM to call.
	// If empty, tools are discovered via semantic search using the prompt.
	Tools []Tool

	// MaxIterations limits the number of loop iterations (default: 10).
	// Each iteration may include multiple tool calls.
	MaxIterations int

	// MaxTokens limits the response length per LLM call.
	MaxTokens int

	// Temperature controls LLM randomness (0.0 = deterministic, 1.0 = creative).
	Temperature float64

	// ToolSearchQuery is used to discover tools if Tools is empty.
	// If empty, the user prompt is used for tool discovery.
	ToolSearchQuery string

	// MinToolScore filters tools below this similarity threshold (default: 0.3).
	MinToolScore float64

	// Model specifies which LLM model to use.
	// If empty, the gateway applies its configured default (see /v1/preferences).
	Model string

	// Memory for conversation persistence.
	// If provided, previous messages are loaded and new messages are saved.
	Memory Memory

	// MaxHistoryMessages limits how many history messages to load (default: 10 pairs).
	// Only used when Memory is provided.
	MaxHistoryMessages int

	// ToolFilter excludes tools from discovery.
	// Called for each discovered tool; return false to exclude.
	// Useful for excluding the agent's own tools to prevent recursion.
	ToolFilter ToolFilter

	// Callbacks for observability and streaming.
	Callbacks LoopCallbacks

	// ErrorHandler for graceful error recovery.
	ErrorHandler *ErrorHandler

	// ParallelToolCalls enables concurrent tool execution (default: true).
	ParallelToolCalls *bool

	// MaxParallelCalls limits concurrent tool executions (default: 5).
	MaxParallelCalls int

	// ReturnIntermediateSteps includes Steps in result.
	ReturnIntermediateSteps bool

	// Stream enables streaming mode for LLM responses.
	// When enabled, chunks are passed to Callbacks.OnStreamChunk as they arrive.
	Stream bool

	// ConfidenceThreshold is the minimum confidence (0-100) required to end the loop
	// with a final response. If the LLM's confidence is below this and no tool calls
	// are made, the loop will prompt the LLM to use tools.
	// Default: 80
	ConfidenceThreshold int

	// AgentDiscovery configures discovery and delegation of other agents
	// within the agentic loop. When enabled, discovered agents are presented
	// to the LLM as callable functions alongside tools.
	// Nil means tool-only discovery (existing behavior).
	AgentDiscovery *AgentDiscoveryConfig
}

LoopConfig configures the agentic tool-use loop.

Use with [SDK.RunLoop]:

result, err := pctx.SDK().RunLoop(ctx, sdk.LoopConfig{
    SystemPrompt:  "You are a helpful assistant.",
    MaxIterations: 5,
    Model:         "", // uses gateway default
}, userMessage)

type LoopResult

type LoopResult struct {
	// Content is the final response from the LLM.
	Content string

	// ToolCalls records all tool invocations during the loop.
	ToolCalls []ToolCallResult

	// Iterations is the number of loop iterations executed.
	Iterations int

	// Usage contains aggregated token usage across all LLM calls.
	Usage TokenUsage

	// Duration is the total time spent in the loop.
	Duration time.Duration

	// Steps contains all intermediate steps (if ReturnIntermediateSteps=true).
	Steps []Step

	// FinishReason indicates why the loop ended.
	FinishReason FinishReason
}

LoopResult contains the final result and execution trace of an agentic loop.

type Memory

type Memory interface {
	// LoadMessages returns previous conversation messages.
	LoadMessages(ctx context.Context) ([]ChatMessage, error)

	// SaveMessages appends new messages to memory.
	SaveMessages(ctx context.Context, messages []ChatMessage) error

	// Clear resets the memory.
	Clear(ctx context.Context) error
}

Memory provides conversation persistence for agentic loops.

Memory implementations store and retrieve conversation history, enabling context-aware responses across multiple interactions.

Create memory instances via SDK:

memory := pctx.SDK().NewWindowMemory(5)
memory := pctx.SDK().NewSummaryBufferMemory(sdk.SummaryBufferConfig{...})

type Message

type Message struct {
	// ID is a unique identifier for this message.
	ID string

	// Action is the name of the action being invoked (from ActionSpec.Name).
	// May be empty for general messages.
	Action string

	// Content is the main payload of the message.
	Content string

	// Params contains structured input parameters (JSON-decoded from Input schema).
	Params map[string]any

	// Metadata contains additional context about the message.
	Metadata map[string]string

	// Parts carries rich, typed content. When non-empty, this is the
	// primary content and Content is ignored. When empty, Content is
	// treated as a single text Part for backward compatibility.
	Parts []Part
}

Message represents an incoming request to an agent.

type MessageBus added in v0.9.10

type MessageBus interface {
	// Request sends a message and waits for a single reply.
	// Used for synchronous RPC (tool calls, discovery, delegation).
	// Returns ErrTimeout if no reply arrives within timeout.
	Request(ctx context.Context, subject string, data []byte, timeout time.Duration) ([]byte, error)

	// Publish sends a fire-and-forget message to a subject.
	// Used for events, signals, and notifications.
	Publish(ctx context.Context, subject string, data []byte) error

	// Subscribe listens for messages on a subject pattern.
	// Supports NATS wildcards: * (single token), > (multiple tokens).
	Subscribe(ctx context.Context, subject string, handler MsgHandler) (Subscription, error)

	// QueueSubscribe listens with load balancing across a named group.
	// Only one subscriber in the queue group receives each message.
	// Used by agents to distribute incoming RPC across instances.
	QueueSubscribe(ctx context.Context, subject string, queue string, handler MsgHandler) (Subscription, error)
}

MessageBus provides unified messaging over NATS for inter-agent communication, event streaming, and request/reply patterns.

All agent-to-agent traffic is routed through the gateway. Agents publish RPC requests to a shared subject; the gateway validates identity/quota/RPS then forwards to the target agent's service subject. NATS user permissions enforce this at the protocol level.

Access via [PlatformContext.MessageBus].

type Msg added in v0.9.10

type Msg struct {
	// Subject the message was published to.
	Subject string

	// Data is the raw payload.
	Data []byte

	// Reply is the reply subject for request/reply patterns.
	// Empty for pub/sub messages.
	Reply string

	// Header carries metadata (trace IDs, caller identity, etc.).
	Header map[string][]string
}

Msg is a message received from the bus.

type MsgHandler added in v0.9.10

type MsgHandler func(msg Msg)

MsgHandler processes a message from the bus.

type NoopCallbacks

type NoopCallbacks struct{}

NoopCallbacks provides empty implementations for all callback methods. Embed this in your callbacks struct to only implement the methods you need.

Example:

type MyCallbacks struct {
    sdk.NoopCallbacks
    logger Logger
}

func (c *MyCallbacks) OnToolStart(ctx context.Context, action sdk.ToolAction) {
    c.logger.Info("Calling tool", sdk.String("tool", action.ToolID))
}

func (NoopCallbacks) OnIteration

func (NoopCallbacks) OnIteration(ctx context.Context, iteration int, steps []Step)

func (NoopCallbacks) OnLLMEnd

func (NoopCallbacks) OnLLMEnd(ctx context.Context, response string, usage TokenUsage)

func (NoopCallbacks) OnLLMStart

func (NoopCallbacks) OnLLMStart(ctx context.Context, messages []ChatMessage)

func (NoopCallbacks) OnLoopEnd

func (NoopCallbacks) OnLoopEnd(ctx context.Context, result *LoopResult, err error)

func (NoopCallbacks) OnLoopStart

func (NoopCallbacks) OnLoopStart(ctx context.Context, input string, tools []Tool)

func (NoopCallbacks) OnStreamChunk

func (NoopCallbacks) OnStreamChunk(ctx context.Context, chunk []byte) error

func (NoopCallbacks) OnToolEnd

func (NoopCallbacks) OnToolEnd(ctx context.Context, action ToolAction, result string, err error, duration time.Duration)

func (NoopCallbacks) OnToolStart

func (NoopCallbacks) OnToolStart(ctx context.Context, action ToolAction)

type Part added in v0.3.0

type Part struct {
	// Type identifies the kind of content this part carries.
	Type ContentType `json:"type"`

	// MimeType is the MIME type of the content (e.g., "application/json", "image/png").
	MimeType string `json:"mimeType,omitempty"`

	// Text is the content for text parts.
	Text string `json:"text,omitempty"`

	// Data is structured content for json parts.
	Data map[string]any `json:"data,omitempty"`

	// FileRef references a platform-stored file.
	FileRef *FileRef `json:"fileRef,omitempty"`

	// Inline carries small binary content (e.g., small images) as raw bytes.
	// JSON-encoded as base64.
	Inline []byte `json:"inline,omitempty"`

	// Metadata carries additional key-value pairs about the content.
	Metadata map[string]string `json:"metadata,omitempty"`
}

Part is the atomic unit of content. All messages, task inputs, task outputs, and artifacts are composed of []Part.

func FilePart added in v0.3.0

func FilePart(ref FileRef) Part

FilePart creates a Part referencing a platform-stored file.

func ImagePart added in v0.3.0

func ImagePart(mimeType string, data []byte) Part

ImagePart creates a Part with an inline image.

func JSONPart added in v0.3.0

func JSONPart(data map[string]any) Part

JSONPart creates a Part with structured JSON data.

func PartsFromText added in v0.3.0

func PartsFromText(text string) []Part

PartsFromText converts a plain string to []Part for backward compatibility. If the string is empty, returns nil.

func TextPart added in v0.3.0

func TextPart(text string) Part

TextPart creates a Part with text content.

type PlatformContext

type PlatformContext interface {
	// LLM returns a client for interacting with language models.
	LLM() LLMClient

	// RAG returns a client for retrieval-augmented generation storage.
	RAG() RAGClient

	// Router returns a client for calling other agents.
	Router() AgentRouter

	// Logger returns a structured logger for the agent.
	Logger() Logger

	// Config returns configuration values set for this agent.
	Config() map[string]string

	// App returns the PocketBase app instance for direct database/route access.
	// Use this to create collections, register custom routes, and query data.
	// Returns nil if not running in PocketBase context.
	App() any

	// SDK returns the SDK instance for high-level agentic functionality.
	// Use this for RunLoop, memory creation, and other SDK utilities.
	SDK() SDK

	// MessageBus returns the NATS message bus for inter-agent communication,
	// events, and request/reply patterns. This is the unified transport for
	// all internal platform messaging.
	MessageBus() MessageBus

	// Blobs returns the blob store for transferring large binary objects
	// (files, images, audio) between agents via NATS Object Store.
	Blobs() BlobStore

	// Tasks returns the task store for querying task history.
	// Backed by the agent's PocketBase database.
	Tasks() TaskStore
}

PlatformContext provides access to platform services.

The context is injected by the runtime when creating agent instances. All platform functionality is accessed through this interface, ensuring plugin code remains decoupled from implementation details.

Example usage:

func (a *MyApp) New(pctx sdk.PlatformContext) (sdk.AgentInstance, error) {
    pctx.Logger().Info("Creating instance")
    return &MyInstance{pctx: pctx}, nil
}

func (i *MyInstance) Handle(ctx context.Context, msg sdk.Message) (sdk.Response, error) {
    // Use LLM
    resp, _ := i.pctx.LLM().Chat(ctx, messages)

    // Use agentic loop
    result, _ := i.pctx.SDK().RunLoop(ctx, config, msg.Content)

    // Call other agents
    agentResp, _ := i.pctx.Router().Call(ctx, "weather", "Paris")
}

type Progress added in v0.3.0

type Progress struct {
	// Stage is a short label for the current stage (e.g., "searching", "analyzing").
	Stage string `json:"stage"`

	// Percent is the completion percentage (0.0–1.0).
	Percent float64 `json:"percent,omitempty"`

	// Message is a human-readable progress description.
	Message string `json:"message,omitempty"`
}

Progress reports incremental progress during task execution.

type PropertyOption

type PropertyOption func(*propertyBuilder)

PropertyOption is a function that configures a property being added.

func Default

func Default(value any) PropertyOption

Default sets the default value for a property.

func Description

func Description(desc string) PropertyOption

Description sets the description for a property.

func Enum

func Enum(values ...any) PropertyOption

Enum restricts a property to specific values.

func ExclusiveMax

func ExclusiveMax(n float64) PropertyOption

ExclusiveMax sets the exclusive maximum numeric value.

func ExclusiveMin

func ExclusiveMin(n float64) PropertyOption

ExclusiveMin sets the exclusive minimum numeric value.

func Format

func Format(format string) PropertyOption

Format sets semantic validation format (e.g., "email", "uri", "date-time", "uuid").

func Max

func Max(n float64) PropertyOption

Max sets the maximum numeric value (inclusive).

func MaxItems

func MaxItems(n int) PropertyOption

MaxItems sets the maximum number of array items.

func MaxLength

func MaxLength(n int) PropertyOption

MaxLength sets the maximum string length.

func Min

func Min(n float64) PropertyOption

Min sets the minimum numeric value (inclusive).

func MinItems

func MinItems(n int) PropertyOption

MinItems sets the minimum number of array items.

func MinLength

func MinLength(n int) PropertyOption

MinLength sets the minimum string length.

func Pattern

func Pattern(pattern string) PropertyOption

Pattern sets a regex pattern for string validation.

func Required

func Required() PropertyOption

Required marks a property as required.

func Title

func Title(title string) PropertyOption

Title sets the title for a property.

func UniqueItems

func UniqueItems() PropertyOption

UniqueItems requires all array items to be unique.

type QueryOption

type QueryOption func(*QueryOptions)

QueryOption configures query behavior.

func WithFilter

func WithFilter(metadata map[string]string) QueryOption

WithFilter restricts results to documents with matching metadata.

func WithLimit

func WithLimit(n int) QueryOption

WithLimit sets the maximum number of results.

func WithMinScore

func WithMinScore(score float64) QueryOption

WithMinScore sets the minimum similarity threshold.

type QueryOptions

type QueryOptions struct {
	// Limit is the maximum number of results to return.
	Limit int

	// MinScore filters out results below this similarity threshold.
	MinScore float64

	// Filter restricts results to documents matching these metadata fields.
	Filter map[string]string
}

QueryOptions contains all configurable options for RAG queries.

func ApplyQueryOptions

func ApplyQueryOptions(opts ...QueryOption) QueryOptions

ApplyQueryOptions applies the given options to a QueryOptions struct.

type RAGClient

type RAGClient interface {
	// Store adds a document to the RAG store.
	// The document will be automatically chunked and embedded.
	Store(ctx context.Context, doc Document) error

	// Query performs a semantic search and returns relevant documents.
	// Results are ordered by relevance (most relevant first).
	Query(ctx context.Context, query string, opts ...QueryOption) ([]SearchResult, error)

	// Delete removes a document by ID.
	Delete(ctx context.Context, id string) error

	// List returns all documents (without content, for indexing purposes).
	List(ctx context.Context) ([]DocumentMeta, error)
}

RAGClient provides access to the agent's retrieval-augmented generation store. Each agent has its own isolated document store with vector embeddings.

type Response

type Response struct {
	// Content is the main response payload.
	Content string

	// Data contains structured response data (will be JSON-encoded).
	Data map[string]any

	// Metadata contains additional context about the response.
	Metadata map[string]string

	// Error is set if the agent encountered an error processing the message.
	// When set, Content and Data may be empty.
	Error string

	// Parts carries rich, typed output content. When non-empty, this is
	// the primary output and Content is ignored. When empty, Content is
	// treated as a single text Part for backward compatibility.
	Parts []Part

	// Artifacts are named outputs produced during handling.
	Artifacts []Artifact
}

Response represents an agent's response to a message.

type ResponseFormat

type ResponseFormat struct {
	// Type is the response format type.
	// - "text": Default, plain text response
	// - "json_object": Basic JSON mode (any valid JSON)
	// - "json_schema": Strict schema-enforced JSON
	Type string `json:"type"`

	// JSONSchema is required when Type is "json_schema".
	// Defines the exact structure the LLM must output.
	JSONSchema *ResponseFormatJSONSchema `json:"json_schema,omitempty"`
}

ResponseFormat controls the format of the LLM's response. Use this to enforce structured output via JSON schema.

func ResponseFormatJSON

func ResponseFormatJSON() *ResponseFormat

ResponseFormatJSON returns a ResponseFormat for basic JSON output. The LLM will output valid JSON, but the structure is not enforced.

func ResponseFormatJSONSchemaFrom

func ResponseFormatJSONSchemaFrom(name string, schema map[string]any, strict bool) *ResponseFormat

ResponseFormatJSONSchemaFrom returns a ResponseFormat with strict JSON schema enforcement. The LLM's output is guaranteed to match the provided schema.

func ResponseFormatText

func ResponseFormatText() *ResponseFormat

ResponseFormatText returns a ResponseFormat for plain text output.

type ResponseFormatJSONSchema

type ResponseFormatJSONSchema struct {
	// Name is a unique identifier for the schema.
	Name string `json:"name"`

	// Strict enables strict schema enforcement.
	// When true, the output MUST match the schema exactly.
	Strict bool `json:"strict"`

	// Schema is the JSON Schema definition.
	Schema map[string]any `json:"schema"`

	// Description provides context about what this schema represents.
	Description string `json:"description,omitempty"`
}

ResponseFormatJSONSchema defines a JSON schema for structured output. When provided, the LLM's output is guaranteed to match this schema.

type SDK

type SDK interface {
	// RunLoop executes an agentic tool-use loop.
	//
	// The loop orchestrates LLM calls and tool execution:
	//  1. Discovers tools via semantic search (if not provided in config)
	//  2. Sends prompt to LLM with tool descriptions
	//  3. Parses tool calls from LLM response
	//  4. Executes tools (parallel or sequential)
	//  5. Sends results back to LLM
	//  6. Repeats until LLM provides final response or max iterations
	//
	// Example:
	//
	//	result, err := pctx.SDK().RunLoop(ctx, sdk.LoopConfig{
	//	    SystemPrompt:  "You are a helpful assistant.",
	//	    MaxIterations: 5,
	//	    Model:         "", // uses gateway default
	//	}, userMessage)
	RunLoop(ctx context.Context, config LoopConfig, userPrompt string) (LoopResult, error)

	// NewSimpleMemory creates an in-memory message store.
	// Messages are kept until explicitly cleared.
	NewSimpleMemory() Memory

	// NewWindowMemory creates a windowed memory that keeps the last N message pairs.
	// Older messages are discarded when the window is exceeded.
	NewWindowMemory(windowSize int) Memory

	// NewSummaryBufferMemory creates a hybrid memory that keeps recent messages
	// in full and summarizes older messages via LLM.
	// Returns [SummaryMemory] which has additional methods for summary access.
	NewSummaryBufferMemory(config SummaryBufferConfig) SummaryMemory

	// NewLoggingCallbacks creates callbacks that log loop events to the provided logger.
	// Useful for debugging and development.
	NewLoggingCallbacks(logger Logger) LoopCallbacks

	// NewSessionMemory creates a session-scoped memory store.
	//
	// When running inside PocketBase, messages are persisted to
	// agentic_conversations + agentic_messages collections and survive
	// app restarts. When PocketBase is not available, falls back to
	// in-memory storage (same as NewSimpleMemory).
	//
	// The sessionID groups messages into a conversation. Use a stable
	// identifier (e.g., user ID, chat thread ID) so the same session
	// can be resumed across requests.
	NewSessionMemory(sessionID string) Memory

	// NewSessionWindowMemory creates a session-scoped windowed memory.
	//
	// Like NewSessionMemory but only loads the last windowSize message
	// pairs (user + assistant). Older messages are still persisted but
	// not returned by LoadMessages.
	NewSessionWindowMemory(sessionID string, windowSize int) Memory

	// NewSessionSummaryMemory creates a session-scoped summary buffer memory.
	//
	// Combines persistence with LLM-powered summarization. Recent messages
	// are kept in full, older messages are summarized. Both the summary
	// and recent messages are persisted across restarts.
	NewSessionSummaryMemory(sessionID string, config SummaryBufferConfig) SummaryMemory
}

SDK provides high-level functionality for building agentic applications.

The SDK interface is implemented by the platform runtime and injected via PlatformContext. This design keeps implementation details hidden while providing a clean, testable API for plugin developers.

Access the SDK via PlatformContext:

func (i *MyInstance) Handle(ctx context.Context, msg sdk.Message) (sdk.Response, error) {
    result, err := i.pctx.SDK().RunLoop(ctx, sdk.LoopConfig{...}, msg.Content)
    // ...
}

type Schema

type Schema struct {
	// Type is the JSON Schema type (e.g., "object", "string", "number", "array", "boolean", "integer").
	Type string `json:"type,omitempty"`

	// Title provides a short title for the schema.
	Title string `json:"title,omitempty"`

	// Description provides human-readable documentation for the schema.
	Description string `json:"description,omitempty"`

	// Properties defines the fields for object types.
	// Keys are property names, values are their schemas.
	Properties map[string]Schema `json:"properties,omitempty"`

	// Required lists the names of required properties for object types.
	Required []string `json:"required,omitempty"`

	// Items defines the schema for array element types.
	Items *Schema `json:"items,omitempty"`

	// Enum restricts the value to one of the specified options.
	Enum []any `json:"enum,omitempty"`

	// Default specifies the default value for this schema.
	Default any `json:"default,omitempty"`

	// Pattern is a regex pattern for string validation.
	Pattern string `json:"pattern,omitempty"`

	// MinLength is the minimum string length.
	MinLength *int `json:"minLength,omitempty"`

	// MaxLength is the maximum string length.
	MaxLength *int `json:"maxLength,omitempty"`

	// Minimum is the minimum numeric value (inclusive).
	Minimum *float64 `json:"minimum,omitempty"`

	// Maximum is the maximum numeric value (inclusive).
	Maximum *float64 `json:"maximum,omitempty"`

	// ExclusiveMinimum is the exclusive minimum numeric value.
	ExclusiveMinimum *float64 `json:"exclusiveMinimum,omitempty"`

	// ExclusiveMaximum is the exclusive maximum numeric value.
	ExclusiveMaximum *float64 `json:"exclusiveMaximum,omitempty"`

	// MinItems is the minimum number of array items.
	MinItems *int `json:"minItems,omitempty"`

	// MaxItems is the maximum number of array items.
	MaxItems *int `json:"maxItems,omitempty"`

	// UniqueItems requires all array items to be unique.
	UniqueItems bool `json:"uniqueItems,omitempty"`

	// Format specifies semantic validation (e.g., "email", "uri", "date-time").
	Format string `json:"format,omitempty"`

	// AdditionalProperties controls whether extra properties are allowed in objects.
	// nil = not specified, true = allowed, false = not allowed
	AdditionalProperties *bool `json:"additionalProperties,omitempty"`
}

Schema represents a JSON Schema for action inputs and outputs. Fully compatible with JSON Schema draft-07 and MCP tool input schemas.

func Array deprecated

func Array(items Schema) Schema

Array creates an array schema with the given item type.

Deprecated: Use WithArray in ToolInput for fluent API.

func Boolean deprecated

func Boolean() Schema

Boolean creates a boolean schema.

Deprecated: Use WithBoolean in ToolInput for fluent API.

func Integer deprecated

func Integer() Schema

Integer creates an integer schema.

Deprecated: Use WithInteger in ToolInput for fluent API.

func Number deprecated

func Number() Schema

Number creates a number schema.

Deprecated: Use WithNumber in ToolInput for fluent API.

func Object deprecated

func Object(properties ...string) Schema

Object creates an object schema with the given property names. Properties ending with "?" are optional; others are required.

Example:

sdk.Object("name", "date?")

Creates an object with required "name" and optional "date" properties.

Deprecated: Use ToolInput with WithString/WithNumber/etc. for better type control.

func ObjectSchema deprecated

func ObjectSchema(properties map[string]Schema, required ...string) Schema

ObjectSchema creates an object schema with explicitly typed properties.

Example:

sdk.ObjectSchema(map[string]sdk.Schema{
    "name": sdk.StringSchema(),
    "age":  sdk.Integer(),
}, "name")

Deprecated: Use ToolInput with WithSchema for fluent API.

func StringSchema deprecated

func StringSchema() Schema

StringSchema creates a string schema.

Deprecated: Use WithString in ToolInput for fluent API.

func ToolInput

func ToolInput(opts ...InputOption) Schema

ToolInput creates an object schema for tool/action inputs using a fluent API.

Example:

sdk.ToolInput(
    sdk.WithString("location", sdk.Required(), sdk.Description("City name")),
    sdk.WithNumber("days", sdk.Default(7), sdk.Min(1), sdk.Max(14)),
    sdk.WithString("unit", sdk.Enum("celsius", "fahrenheit")),
)

func (Schema) ToMap

func (s Schema) ToMap() map[string]any

ToMap converts a Schema to a map[string]any for JSON serialization. This is useful when interfacing with libraries that expect map representations.

func (Schema) WithDefault

func (s Schema) WithDefault(value any) Schema

WithDefault sets the default value for a schema. This is a method-chaining style helper for the legacy API.

func (Schema) WithDescription

func (s Schema) WithDescription(desc string) Schema

WithDescription adds a description to a schema. This is a method-chaining style helper for the legacy API.

func (Schema) WithEnum

func (s Schema) WithEnum(values ...any) Schema

WithEnum restricts a schema to the given enum values. This is a method-chaining style helper for the legacy API.

func (Schema) WithTitle

func (s Schema) WithTitle(title string) Schema

WithTitle sets the title for a schema. This is a method-chaining style helper for the legacy API.

type SearchResult

type SearchResult struct {
	// Document is the matching document.
	Document Document

	// Score is the similarity score (higher = more relevant).
	Score float64

	// Chunk is the specific text chunk that matched, if chunking was used.
	Chunk string
}

SearchResult represents a document returned from a RAG query.

type Step

type Step struct {
	Action      ToolAction    // What the LLM wanted to do
	Observation string        // What happened (result)
	Error       string        // Error message if failed
	Duration    time.Duration // How long the tool call took
}

Step tracks a single tool invocation and its result.

type StreamCallback

type StreamCallback func(chunk string) error

StreamCallback is called for each chunk of content during streaming. Return an error to abort the stream.

type Subscription added in v0.3.0

type Subscription interface {
	// Unsubscribe stops receiving messages and releases resources.
	Unsubscribe() error
}

Subscription represents an active message subscription.

type SummaryBufferConfig

type SummaryBufferConfig struct {
	// WindowSize is the number of recent conversation turns to keep in full.
	// A turn is a user+assistant message pair.
	// Default: 3 (keeps last 6 messages)
	WindowSize int

	// Model to use for summarization.
	// Default: "gpt-4o-mini" (fast and cost-effective)
	Model string

	// InitialSummary allows starting with an existing conversation summary.
	// Useful for resuming conversations from persistent storage.
	InitialSummary string
}

SummaryBufferConfig configures summary buffer memory creation.

Summary buffer memory keeps recent messages in full and summarizes older messages via LLM, balancing context preservation with token efficiency.

type SummaryMemory

type SummaryMemory interface {
	Memory

	// GetSummary returns the current conversation summary.
	GetSummary() string

	// SetSummary sets the conversation summary.
	SetSummary(summary string)

	// SetMessages replaces all messages (useful for initializing from existing conversation).
	SetMessages(messages []ChatMessage)
}

SummaryMemory extends Memory with summary-specific methods. Returned by [SDK.NewSummaryBufferMemory].

type Task added in v0.3.0

type Task struct {
	// ID is the unique task identifier.
	ID string `json:"id"`

	// ContextID groups related tasks into a conversation.
	// Optional; when empty, the task is standalone.
	ContextID string `json:"contextId,omitempty"`

	// CallerAgent is the name of the agent (or "user") that created this task.
	CallerAgent string `json:"callerAgent"`

	// TargetAgent is the name of the agent executing this task.
	TargetAgent string `json:"targetAgent"`

	// Status is the current task status.
	Status TaskStatus `json:"status"`

	// Input is the task's input content.
	Input []Part `json:"input"`

	// Output is the task's output content (set on completion).
	Output []Part `json:"output,omitempty"`

	// Artifacts are named outputs produced during execution.
	Artifacts []Artifact `json:"artifacts,omitempty"`

	// Metadata carries additional task-level key-value pairs.
	Metadata map[string]string `json:"metadata,omitempty"`

	// DelegationChain is the ordered list of agent names in the delegation path.
	// Used for cycle detection.
	DelegationChain []string `json:"delegationChain,omitempty"`

	// DelegationDepth is the current depth in the delegation chain.
	DelegationDepth int `json:"delegationDepth,omitempty"`

	// CreatedAt is the Unix timestamp (seconds) when the task was created.
	CreatedAt int64 `json:"createdAt"`

	// UpdatedAt is the Unix timestamp (seconds) of the last status change.
	UpdatedAt int64 `json:"updatedAt"`

	// CompletedAt is the Unix timestamp (seconds) when the task reached a terminal state.
	CompletedAt *int64 `json:"completedAt,omitempty"`
}

Task represents a unit of work between a caller and a target agent. Every interaction — tool call, agent delegation, user message — creates a Task.

type TaskBudget added in v0.3.0

type TaskBudget struct {
	// MaxTokens limits total LLM tokens the delegate may consume.
	MaxTokens int `json:"maxTokens,omitempty"`

	// MaxCredits limits platform credits the delegate may spend.
	MaxCredits float64 `json:"maxCredits,omitempty"`

	// MaxCalls limits the number of sub-calls (tool or delegation) the delegate may make.
	MaxCalls int `json:"maxCalls,omitempty"`

	// TimeoutMs is the maximum wall-clock time in milliseconds.
	TimeoutMs int `json:"timeoutMs,omitempty"`
}

TaskBudget limits a delegate's resource consumption.

type TaskContext added in v0.3.0

type TaskContext interface {
	// SetProgress updates the task's progress. Publishes a task.progress event.
	SetProgress(stage string, percent float64, message string) error

	// RequestInput transitions the task to input_needed and sends a prompt
	// to the caller. Use WaitForInput to block until the caller responds.
	RequestInput(prompt []Part) error

	// WaitForInput blocks until the caller provides additional input
	// (after the task was set to input_needed via RequestInput).
	WaitForInput(ctx context.Context) ([]Part, error)

	// StreamOutput sends incremental output parts to subscribers.
	// Publishes a task.output event. The final output is set when
	// HandleTask returns without error.
	StreamOutput(parts []Part) error

	// EmitArtifact stores an artifact and publishes a task.artifact event.
	// Returns the platform-assigned artifact ID.
	EmitArtifact(artifact ArtifactBuilder) (string, error)

	// TaskID returns the current task's ID.
	TaskID() string

	// ContextID returns the conversation context ID (may be empty).
	ContextID() string

	// CallerAgent returns the name of the agent that created this task.
	CallerAgent() string

	// DelegationChain returns the ordered list of agent names
	// in the delegation path leading to this task.
	DelegationChain() []string

	// RemainingBudget returns the remaining budget for this task, if any.
	RemainingBudget() *TaskBudget

	// DelegationCallbacks returns LoopCallbacks that should be composed
	// into any RunLoop executed during HandleTask. This enables the caller
	// to observe the sub-agent's internal loop events (tool calls, LLM usage).
	// Returns nil when no external observer is attached.
	DelegationCallbacks() LoopCallbacks
}

TaskContext is the agent's handle to interact with a task during execution. It is provided by the runtime when calling HandleTask.

type TaskFilter added in v0.3.0

type TaskFilter struct {
	// ContextID filters by conversation context.
	ContextID string

	// CallerAgent filters by who created the task.
	CallerAgent string

	// TargetAgent filters by who executed the task.
	TargetAgent string

	// State filters by current state. Nil means any state.
	State *TaskState

	// Limit is the maximum number of tasks to return.
	Limit int

	// Before filters to tasks created before this Unix timestamp (for pagination).
	Before *int64
}

TaskFilter specifies criteria for listing tasks.

type TaskHandler added in v0.3.0

type TaskHandler interface {
	// HandleTask processes an asynchronous task with full lifecycle control.
	// The TaskContext provides methods to update status, emit artifacts,
	// stream output, and request input from the caller.
	HandleTask(ctx context.Context, task Task, tc TaskContext) error
}

TaskHandler is implemented by agents that want full task lifecycle control. The runtime checks for this interface at startup. If present, delegation requests and complex calls are routed to HandleTask instead of Handle.

Implementing TaskHandler is opt-in. Agents that only implement AgentInstance continue to work via the transparent task wrapper.

type TaskState added in v0.3.0

type TaskState string

TaskState represents the current state of a task.

const (
	TaskStateSubmitted   TaskState = "submitted"
	TaskStateWorking     TaskState = "working"
	TaskStateInputNeeded TaskState = "input_needed"
	TaskStateCompleted   TaskState = "completed"
	TaskStateFailed      TaskState = "failed"
	TaskStateCanceled    TaskState = "canceled"
)

func (TaskState) IsTerminal added in v0.3.0

func (s TaskState) IsTerminal() bool

IsTerminal returns true if the task state is a terminal state (completed, failed, or canceled).

type TaskStatus added in v0.3.0

type TaskStatus struct {
	// State is the current lifecycle state.
	State TaskState `json:"state"`

	// Message is an optional human-readable status message.
	Message string `json:"message,omitempty"`

	// Progress is optional progress information.
	Progress *Progress `json:"progress,omitempty"`
}

TaskStatus describes the current state and optional progress of a task.

type TaskStore added in v0.3.0

type TaskStore interface {
	// Get retrieves a task by ID.
	Get(ctx context.Context, taskID string) (*Task, error)

	// List returns tasks matching the given filter.
	List(ctx context.Context, filter TaskFilter) ([]Task, error)

	// GetArtifacts returns all artifacts for a task.
	GetArtifacts(ctx context.Context, taskID string) ([]Artifact, error)

	// GetArtifact returns a specific artifact by ID.
	GetArtifact(ctx context.Context, artifactID string) (*Artifact, error)
}

TaskStore provides read access to task history for observability and multi-turn flows. Backed by the agent's PocketBase database.

type TokenUsage

type TokenUsage struct {
	// PromptTokens is the number of tokens in the prompt.
	PromptTokens int

	// CompletionTokens is the number of tokens in the response.
	CompletionTokens int

	// TotalTokens is the sum of prompt and completion tokens.
	TotalTokens int
}

TokenUsage contains token consumption information.

type Tool

type Tool struct {
	// Type is always "function" for function tools.
	Type string

	// Function contains the function definition.
	Function FunctionDef
}

Tool represents a tool that can be provided to the LLM for function calling.

type ToolAction

type ToolAction struct {
	ToolID    string         // Tool identifier (format: "agent/action")
	Arguments map[string]any // Arguments to pass to the tool
	Thought   string         // LLM's reasoning (for debugging)
}

ToolAction represents an LLM's decision to call a tool.

type ToolCall

type ToolCall struct {
	// ID is a unique identifier for this tool call (used to match tool responses).
	ID string

	// Type is always "function" for function calls.
	Type string

	// Function contains the function name and arguments.
	Function FunctionCall
}

ToolCall represents a tool invocation requested by the LLM.

type ToolCallResult

type ToolCallResult struct {
	// ToolID is the tool identifier (format: "agent_name/action_name").
	ToolID string

	// Arguments is the parsed JSON arguments passed to the tool.
	Arguments map[string]any

	// Result is the tool's response content.
	Result string

	// Error is set if the tool call failed.
	Error string

	// Duration is how long the tool call took.
	Duration time.Duration
}

ToolCallResult records a single tool invocation during the loop.

type ToolFilter

type ToolFilter func(toolID string, score float64) bool

ToolFilter decides which tools to include during discovery. Return true to include the tool, false to exclude it.

type ToolMatch

type ToolMatch struct {
	// ToolID is the unique identifier (format: "agent_name/action_name").
	ToolID string

	// AgentName is the name of the agent that provides this tool.
	AgentName string

	// AgentAvatar is the emoji avatar of the agent (e.g., "🤖", "🌤️").
	AgentAvatar string

	// ActionName is the name of the action/tool.
	ActionName string

	// Description explains what this tool does.
	Description string

	// InputSchema is the JSON Schema for the tool's parameters.
	InputSchema map[string]any

	// Score is the semantic similarity score (0.0-1.0, higher is more relevant).
	Score float64
}

ToolMatch represents a tool found via semantic search with a relevance score.

Jump to

Keyboard shortcuts

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