agentsdk

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2026 License: Apache-2.0 Imports: 39 Imported by: 0

README

agentsdk

Go SDK for building cyborg agents — programs that are half code, half AI — that run on airlock.

Cyborg agents are deterministic Go where it makes sense (HTTP routes, webhooks, cron jobs, structured tool execution) and AI-driven where it helps (LLM reasoning, conversation handling, open-ended decisions). agentsdk is the contract your code uses to participate in the airlock platform: register routes, tools, webhooks, crons, and chat surfaces; access scoped storage and per-agent Postgres; and call LLMs through the platform's credential-managing proxy.

If you're not building on airlock, you don't need this — agentsdk is the glue, not the runtime.

[!WARNING] Alpha software. Early-stage code with bugs we haven't found yet — please open an issue for anything that breaks. Note: even though the SDK is alpha, the public API surface is intended to stay relatively stable and backwards-compatible even pre-1.0, because agents built against an older agentsdk version need to keep working against newer ones. Internal/unexported code can change freely. See Stability below.

Install

go get github.com/airlockrun/agentsdk

Requires Go 1.26+.

Hello-world agent

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/airlockrun/agentsdk"
)

func main() {
	agent := agentsdk.New(agentsdk.Config{
		Description: "Greets visitors. Replace once the agent does real work.",
	})

	agent.RegisterRoute("/", "GET", func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "hello from a cyborg agent")
	}, agentsdk.RouteOpts{
		Access:      agentsdk.AccessPublic,
		Description: "Greet anyone who hits the agent's home route.",
	})

	agent.Serve()
}

In a real agent you'd also call RegisterTool, RegisterWebhook, RegisterCron, RegisterConnection, and so on — see the airlock docs for the full surface.

Stability

agentsdk's public API is treated as a stability commitment: changes to exported types, functions, or runtime behavior are kept backwards-compatible across minor versions. Older built agents must continue to work against newer agentsdk releases.

Internal/unexported code can change freely. Non-trivial API changes go through a Discussion before any PR — see CONTRIBUTING.md.

Companion projects

  • airlock (AGPL-3.0) — the self-hosted platform that runs agents built with this SDK
  • goai (Apache-2.0) — Go port of the Vercel AI SDK
  • sol (Apache-2.0) — agent runtime / CLI utility

License

Apache-2.0.

Contributing

See CONTRIBUTING.md and CODE_OF_CONDUCT.md. A CLA Assistant bot will prompt you to sign on your first PR (one signature covers all airlockrun projects).

Security

Email security@airlock.run. Do not open public issues for vulnerabilities.

Documentation

Overview

Package agentsdk provides the Go SDK for building Airlock agents.

This package will contain the client library that agents use to communicate with the Airlock platform — registering connections, receiving triggers, and streaming run results.

Index

Constants

View Source
const (
	// ErrorKindPlatform: failure upstream of the agent's own code. LLM
	// provider 4xx, sol/goai stream errors, request transport (body read).
	// The agent's code couldn't have prevented or fixed this — the "Fix
	// this error" workflow on the run page is hidden for these.
	ErrorKindPlatform = "platform"

	// ErrorKindAgent: failure from agent-defined code paths. Webhook/cron
	// handlers returning err, panics in user code recovered by the SDK,
	// post-LLM bookkeeping that hit something the agent owns. The Fix
	// workflow targets exactly these.
	ErrorKindAgent = "agent"
)

Error kinds passed in RunCompleteRequest.ErrorKind. The agentsdk side classifies structurally — by call-site, not by error string — so airlock can avoid pattern-matching at all.

View Source
const Version = "0.1.1" // pre-release; bump when shipping breaking protocol changes

Version is the agentsdk API version. Reported to Airlock during sync. Bump on breaking changes — see CLAUDE.md for versioning rules.

Variables

This section is empty.

Functions

func GetDeps

func GetDeps[T any](ctx context.Context) T

GetDeps retrieves the typed Deps struct from the Agent bound to ctx. Panics if no agent is bound (must be called from inside a handler), if Deps is nil, or if the type doesn't match. Used by handlers that need the builder's pre-registered application state (connection/MCP handles, config, etc.) — particularly VM functions defined in separate packages where the `agent` variable isn't in scope.

func IsValidatingMigrations

func IsValidatingMigrations() bool

IsValidatingMigrations reports whether the agent is running in migration validation mode (AGENT_VALIDATE_MIGRATIONS=1). Go migrations that touch external services (S3, Airlock API, connection credentials) should return early when this is true — those services are not available during build-time validation.

func ResolveDisplayPart

func ResolveDisplayPart(p *DisplayPart)

resolveDisplayPart infers missing fields on a DisplayPart from available data. 1. If Data is set but MimeType is empty → detect from bytes. 2. If MimeType is set but Type is empty → infer from MIME prefix. 3. If Filename is empty and part has media → generate from type + mimeType.

Types

type Access

type Access string

Access defines who can reach a tool, connection, MCP, topic, or storage zone.

const (
	AccessAdmin  Access = "admin"
	AccessUser   Access = "user"
	AccessPublic Access = "public"
	// AccessInternal is the strictest level — builder Go code only. Items
	// registered with AccessInternal are never exposed to the JS runtime
	// and are never reachable from external callers regardless of role.
	// Use it when you have, say, a storage zone that holds builder-only
	// caches you don't want the LLM to discover, mutate, or list.
	AccessInternal Access = "internal"
)

type Action

type Action struct {
	Type       string    `json:"type"`
	Timestamp  time.Time `json:"timestamp"`
	DurationMs int64     `json:"durationMs"`
	Request    any       `json:"request,omitempty"`
	Response   any       `json:"response,omitempty"`
	Error      string    `json:"error,omitempty"`
}

Action records a single operation performed during a Run.

type Agent

type Agent struct {

	// Deps holds application-level dependencies (connection handles, MCP handles, etc.).
	// The builder defines their own typed struct and assigns it here.
	// Access from handlers via GetDeps[T](run).
	Deps any
	// contains filtered or unexported fields
}

Agent is a long-lived singleton, one per container. Created once at startup via New(), lives for the lifetime of the process.

func AgentFromContext

func AgentFromContext(ctx context.Context) *Agent

AgentFromContext returns the *Agent associated with a handler's ctx. Returns nil if ctx wasn't produced by a handler (e.g. a plain context.Background() in test code).

func AgentFromMigrationContext

func AgentFromMigrationContext(ctx context.Context) *Agent

AgentFromMigrationContext returns the Agent associated with a migration context. Panics if called outside of a migration — migrations receive the context via goose, which propagates it from autoMigrate.

func New

func New(cfg Config) *Agent

New creates an Agent by reading required environment variables. Panics if AIRLOCK_AGENT_ID, AIRLOCK_API_URL, or AIRLOCK_AGENT_TOKEN is missing. Panics if Config.Description is empty.

func (*Agent) AddExtraPrompt

func (a *Agent) AddExtraPrompt(p *ExtraPrompt)

AddExtraPrompt appends a system-prompt fragment that Airlock will include for callers whose resolved access on this agent matches one of the fragment's Access levels. An empty Access slice means the fragment applies to every caller.

Fragments accumulate in registration order and are joined with "\n\n" by Airlock at run dispatch, then appended to the sync-rendered system prompt. Only /prompt-triggered runs (web + bridge) receive extras — webhook and cron handlers run arbitrary Go code and build their own prompts.

func (*Agent) AddSensitive

func (a *Agent) AddSensitive(values ...string)

AddSensitive registers values that should be redacted from LLM messages.

func (*Agent) Attachment

func (a *Agent) Attachment(ctx context.Context, fileID string) (io.ReadCloser, error)

Attachment retrieves a conversation file attachment by its opaque fileID. Different surface from the zoned Storage handles — attachments are content the user uploaded to a chat message and aren't builder-keyed.

func (*Agent) DB

func (a *Agent) DB() *AgentDB

DB returns a lazily-initialized *AgentDB from AIRLOCK_DB_URL. Returns nil if the env var is not set (DB is optional).

AgentDB implements the same DBTX interface that sqlc-generated New() takes, so `mygen.New(agent.DB())` works unchanged. The wrapper is the extension point through which the framework can later record query activity onto the run carried by ctx.

func (*Agent) EmbeddingModel

func (a *Agent) EmbeddingModel(ctx context.Context, slug string, opts ModelOpts) model.EmbeddingModel

EmbeddingModel returns an embedding model proxied through Airlock.

func (*Agent) ImageModel

func (a *Agent) ImageModel(ctx context.Context, slug string, opts ModelOpts) model.ImageModel

ImageModel returns an image generation model proxied through Airlock.

func (*Agent) LLM

func (a *Agent) LLM(ctx context.Context, slug string, opts ModelOpts) stream.Model

LLM returns a streaming language model. Capability defaults to CapText if ModelOpts.Capability is empty. Pass the returned model the same ctx when calling Stream.

func (*Agent) Log

func (a *Agent) Log(ctx context.Context, level LogLevel, msg string)

Log records a message scoped to the current handler invocation at the given level. Visible in the Runs UI alongside the actions the handler performed; level controls how the UI surfaces it (color/filter).

Use LogLevelInfo for normal progress, LogLevelWarn for recoverable concerns, and LogLevelError for failures the handler chose not to raise. The argument shape is uniform — pick a level rather than reaching for severity-named methods.

func (*Agent) Logf

func (a *Agent) Logf(ctx context.Context, level LogLevel, format string, args ...any)

Logf is the printf-style sibling of Log — formats with fmt.Sprintf and records the result. Use Log for plain strings, Logf when you'd otherwise reach for fmt.Sprintf.

func (*Agent) RegisterConnection

func (a *Agent) RegisterConnection(c *Connection) *ConnectionHandle

RegisterConnection registers an outgoing service connection and returns a handle for proxied requests. Synced to Airlock on Serve(). Use the returned handle for compile-time-bound proxy calls:

gmail := agent.RegisterConnection(&agentsdk.Connection{
    Slug: "gmail", Name: "Gmail", BaseURL: "https://gmail.googleapis.com", ...,
})
body, err := gmail.Request(ctx, "GET", "/messages", nil)

func (*Agent) RegisterCron

func (a *Agent) RegisterCron(c *Cron)

RegisterCron installs a cron job. Schedule is a standard cron expression (e.g. "0 9 * * *"). Synced to Airlock on Serve() so the scheduler can fire it.

func (*Agent) RegisterMCP

func (a *Agent) RegisterMCP(m *MCP) *MCPHandle

RegisterMCP registers a remote MCP server dependency and returns a handle for calling its tools. Synced to Airlock on Serve(). Use the returned handle for compile-time-bound tool calls:

github := agent.RegisterMCP(&agentsdk.MCP{Slug: "github", URL: "https://api.github.com/mcp"})
result, err := github.CallTool(ctx, "search_repos", args)

func (*Agent) RegisterModel

func (a *Agent) RegisterModel(slot *ModelSlot)

RegisterModel declares a named model slot the agent will use at runtime via agent.LLM(ctx, slug, ...) / agent.ImageModel(...) / etc. The admin binds a specific model to each slot in the Airlock UI; if no model is bound, calls fall through to the agent's per-capability default and then to the system default. Call before Serve().

Registering a slot is optional — undeclared slugs still work, they just silently fall through to the capability default and won't appear in the admin UI's Models tab.

func (*Agent) RegisterRoute

func (a *Agent) RegisterRoute(r *Route)

RegisterRoute installs a custom HTTP route served by this agent and proxied via Airlock's subdomain routing.

func (*Agent) RegisterStorage

func (a *Agent) RegisterStorage(s *Storage) *StorageHandle

RegisterStorage declares an S3-backed storage zone scoped to an Access level. Returns a *StorageHandle for builder Go code and exposes a `storage_{slug}` JS object inside run_js (only to callers whose access satisfies the zone's Access; AccessInternal zones are never exposed to JS at all). Slug also becomes the S3 prefix.

The framework reserves the slug "tmp" for its own scratch storage (truncated tool output, generated media). Builders may pass Slug:"tmp" — the call returns a working handle to the framework's tmp zone but the supplied Access / Description are silently ignored.

uploads := agent.RegisterStorage(&agentsdk.Storage{
    Slug: "uploads", Access: agentsdk.AccessUser, Description: "User uploads",
})
err := uploads.Put(ctx, "doc.pdf", reader, "application/pdf")

func (*Agent) RegisterTool

func (a *Agent) RegisterTool(def AnyTool)

RegisterTool registers a typed, schema-bearing capability the LLM can invoke via run_js. The tool auto-binds as a global inside the goja VM; input from JS is JSON-marshaled and decoded into the author's In struct, Execute runs, and the Out struct is JSON-marshaled back to a native JS value. Input/output JSON schemas are rendered as a TypeScript declaration in the system prompt so the LLM sees typed signatures.

agent.RegisterTool(&agentsdk.Tool[SearchIn, SearchOut]{
    Name:        "search",
    Description: "Search the web.",
    Execute:     doSearch,
    Access:      agentsdk.AccessUser,
})

func (*Agent) RegisterTopic

func (a *Agent) RegisterTopic(t *Topic) *TopicHandle

RegisterTopic declares a topic the agent can publish notifications to. Synced to Airlock on Serve(). Use the returned *TopicHandle for compile-time-bound publishing:

alerts := agent.RegisterTopic(&agentsdk.Topic{Slug: "alerts", Description: "System alerts"})
alerts.Publish(ctx, []DisplayPart{{Type: "text", Text: "Server restarted"}})

func (*Agent) RegisterWebhook

func (a *Agent) RegisterWebhook(w *Webhook)

RegisterWebhook installs a webhook handler at /webhook/{Path}. Synced to Airlock on Serve() so external callers can reach it via the agent's webhook ingress endpoint.

func (*Agent) Serve

func (a *Agent) Serve()

Serve starts the agent HTTP server. Blocks until SIGINT/SIGTERM. Listens on AIRLOCK_ADDR env var or :8080. Before starting, syncs connections/webhooks/crons with Airlock.

func (*Agent) SpeechModel

func (a *Agent) SpeechModel(ctx context.Context, slug string, opts ModelOpts) model.SpeechModel

SpeechModel returns a text-to-speech model proxied through Airlock.

func (*Agent) TranscriptionModel

func (a *Agent) TranscriptionModel(ctx context.Context, slug string, opts ModelOpts) model.TranscriptionModel

TranscriptionModel returns a speech-to-text model proxied through Airlock.

type AgentDB

type AgentDB struct {
	// contains filtered or unexported fields
}

AgentDB wraps the agent's *sql.DB and is the type returned by Agent.DB(). It implements the same DBTX interface that sqlc-generated New() functions take, so builder code that does `mygen.New(agent.DB())` keeps compiling.

Today AgentDB is a thin pass-through. The reason it exists is so the framework can later intercept queries at this layer (record an action on the run carried by ctx, surface query timings in the Runs UI, redact sensitive arguments) without breaking builders or sqlc-generated code. Builders that need the underlying driver-level handle for advanced cases (Stats, Driver, custom drivers) can reach it via Underlying().

func (*AgentDB) BeginTx

func (a *AgentDB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*AgentTx, error)

BeginTx starts a transaction. The returned *AgentTx implements the same DBTX interface, so `mygen.New(tx)` and `q.WithTx(tx)` both work.

func (*AgentDB) ExecContext

func (a *AgentDB) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)

ExecContext satisfies sqlc's DBTX. Forwards to the underlying *sql.DB.

func (*AgentDB) PingContext

func (a *AgentDB) PingContext(ctx context.Context) error

PingContext checks database connectivity.

func (*AgentDB) PrepareContext

func (a *AgentDB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)

PrepareContext satisfies sqlc's DBTX. Forwards to the underlying *sql.DB.

func (*AgentDB) QueryContext

func (a *AgentDB) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)

QueryContext satisfies sqlc's DBTX. Forwards to the underlying *sql.DB.

func (*AgentDB) QueryRowContext

func (a *AgentDB) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row

QueryRowContext satisfies sqlc's DBTX. Forwards to the underlying *sql.DB.

func (*AgentDB) Underlying

func (a *AgentDB) Underlying() *sql.DB

Underlying returns the wrapped *sql.DB. Use this only when you need driver-level access that DBTX doesn't expose; otherwise stick to the AgentDB methods so future framework instrumentation applies to your code.

type AgentTx

type AgentTx struct {
	// contains filtered or unexported fields
}

AgentTx wraps a *sql.Tx with the same shape as AgentDB so sqlc's q.WithTx(tx) accepts it transparently.

func (*AgentTx) Commit

func (a *AgentTx) Commit() error

Commit commits the transaction.

func (*AgentTx) ExecContext

func (a *AgentTx) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)

ExecContext satisfies sqlc's DBTX.

func (*AgentTx) PrepareContext

func (a *AgentTx) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)

PrepareContext satisfies sqlc's DBTX.

func (*AgentTx) QueryContext

func (a *AgentTx) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)

QueryContext satisfies sqlc's DBTX.

func (*AgentTx) QueryRowContext

func (a *AgentTx) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row

QueryRowContext satisfies sqlc's DBTX.

func (*AgentTx) Rollback

func (a *AgentTx) Rollback() error

Rollback aborts the transaction. Idempotent — safe to defer.

func (*AgentTx) Underlying

func (a *AgentTx) Underlying() *sql.Tx

Underlying returns the wrapped *sql.Tx.

type AnyTool

type AnyTool interface {
	// contains filtered or unexported methods
}

AnyTool is the sealed interface produced by *Tool[In, Out]. The unexported toRegistered method means only generic Tool values can satisfy it — authors cannot roll their own AnyTool implementations. Used as the argument type for RegisterTool so a heterogeneous set of generic Tool values can share one entry point.

type AuthInjection

type AuthInjection struct {
	Type string `json:"type"`           // "bearer", "api_key_header", "bot_token_url_prefix"
	Name string `json:"name,omitempty"` // header name for api_key_header (default: "X-API-Key")
}

AuthInjection defines how auth credentials are injected into proxied requests.

type AuthRequiredError

type AuthRequiredError struct {
	Slug     string `json:"slug"`
	ConnName string `json:"connName"`
	AuthURL  string `json:"authUrl"`
}

AuthRequiredError is returned by ConnectionHandle.Request when a connection needs authorization.

func IsAuthRequired

func IsAuthRequired(err error) (*AuthRequiredError, bool)

IsAuthRequired checks whether err is an *AuthRequiredError.

func (*AuthRequiredError) Error

func (e *AuthRequiredError) Error() string

type Config

type Config struct {
	Description string // required — shown to users in the Airlock UI
}

Config holds configuration for creating an Agent.

type Connection

type Connection struct {
	Slug              string // unique per agent; binds as conn_{slug} in run_js
	Name              string
	Description       string
	BaseURL           string
	AuthMode          ConnectionAuth
	AuthURL           string
	TokenURL          string
	Scopes            []string
	AuthInjection     AuthInjection
	SetupInstructions string
	LLMHint           string // appended to the connection block in the system prompt
	Access            Access // who may invoke conn_{slug}; default AccessUser
}

Connection is the self-contained declaration registered via agent.RegisterConnection — an outgoing service Airlock proxies for the agent with credentials it manages.

type ConnectionAuth

type ConnectionAuth string

ConnectionAuth enumerates the supported authentication strategies for an outgoing service Connection.

const (
	ConnectionAuthOAuth ConnectionAuth = "oauth"
	ConnectionAuthToken ConnectionAuth = "token"
	ConnectionAuthNone  ConnectionAuth = "none"
)

type ConnectionDef

type ConnectionDef struct {
	Name              string         `json:"name"`
	Description       string         `json:"description"`
	BaseURL           string         `json:"baseUrl,omitempty"`
	AuthMode          ConnectionAuth `json:"authMode"`
	AuthURL           string         `json:"authUrl,omitempty"`
	TokenURL          string         `json:"tokenUrl,omitempty"`
	Scopes            []string       `json:"scopes,omitempty"`
	AuthInjection     AuthInjection  `json:"authInjection"`
	SetupInstructions string         `json:"setupInstructions,omitempty"`
	LLMHint           string         `json:"llmHint,omitempty"`
	Access            Access         `json:"access,omitempty"`
}

ConnectionDef is the wire format used by PUT /api/agent/connections/{slug}. Slug is sent in the URL, not the body.

type ConnectionHandle

type ConnectionHandle struct {
	// contains filtered or unexported fields
}

ConnectionHandle is a compile-time binding to a registered connection. Returned by RegisterConnection, used to make proxied HTTP requests.

func (*ConnectionHandle) Request

func (h *ConnectionHandle) Request(ctx context.Context, method, path string, body any) ([]byte, error)

Request sends an HTTP request through Airlock's credential-injecting proxy and returns the raw response body. Body encoding is chosen from its type:

nil            — no body
[]byte, string — sent as-is
io.Reader      — fully read, sent as-is
anything else  — JSON-marshalled

Returns *AuthRequiredError if the connection needs authorization.

type ConversationVM

type ConversationVM struct {
	// contains filtered or unexported fields
}

ConversationVM holds persistent state for a single conversation. The goja VM is recreated per-run, but the store map survives across prompts.

type ConversationVMConfig

type ConversationVMConfig struct {
	IdleTimeout     time.Duration // default: 72h
	MaxStoreSize    int64         // default: 4MB
	GCSweepInterval time.Duration // default: 1h
}

ConversationVMConfig configures conversation VM behavior.

func DefaultConversationVMConfig

func DefaultConversationVMConfig() ConversationVMConfig

DefaultConversationVMConfig returns sensible defaults.

type CreateRunRequest

type CreateRunRequest struct {
	TriggerType string `json:"triggerType"`
	TriggerRef  string `json:"triggerRef"`
}

CreateRunRequest is the body for POST /api/agent/run/create.

type CreateRunResponse

type CreateRunResponse struct {
	RunID string `json:"runId"`
}

CreateRunResponse is the response from POST /api/agent/run/create.

type Cron

type Cron struct {
	Name        string          // unique per agent
	Schedule    string          // standard cron expression, e.g. "0 9 * * *"
	Handler     CronHandlerFunc // required
	Timeout     time.Duration   // max execution time (default: 2 min)
	Description string
}

Cron is the self-contained declaration registered via agent.RegisterCron. Crons fire by schedule, never by user action — no Access field.

type CronDef

type CronDef struct {
	Name        string `json:"name"`
	Schedule    string `json:"schedule"`
	TimeoutMs   int64  `json:"timeoutMs"`
	Description string `json:"description,omitempty"`
}

CronDef is a cron job definition sent during sync.

type CronHandlerFunc

type CronHandlerFunc func(ctx context.Context, ew *EventWriter) error

CronHandlerFunc handles cron-triggered requests.

type DisplayPart

type DisplayPart struct {
	Type     string  `json:"type"`             // "text", "image", "file", "audio", "video"
	Text     string  `json:"text,omitempty"`   // body text, or caption for media types
	Source   string  `json:"source,omitempty"` // S3 key
	URL      string  `json:"url,omitempty"`    // external URL
	Data     []byte  `json:"data,omitempty"`   // raw bytes (base64 in JSON)
	Filename string  `json:"filename,omitempty"`
	MimeType string  `json:"mimeType,omitempty"`
	Alt      string  `json:"alt,omitempty"`      // accessibility text for images
	Duration float64 `json:"duration,omitempty"` // seconds, audio/video
}

DisplayPart is a single piece of rich content for user-facing output. Used by both printToUser (VM) and TopicHandle.Publish (Go).

type EventWriter

type EventWriter struct {
	// contains filtered or unexported fields
}

EventWriter streams NDJSON events to an HTTP response.

func (*EventWriter) WriteError

func (ew *EventWriter) WriteError(err error) error

WriteError writes an error event.

func (*EventWriter) WriteEvent

func (ew *EventWriter) WriteEvent(event stream.Event) error

WriteEvent serializes a GoAI stream.Event as an NDJSON line.

func (*EventWriter) WriteProgress

func (ew *EventWriter) WriteProgress(message string) error

WriteProgress writes a progress event (for webhook/cron handlers).

type ExtraPrompt

type ExtraPrompt struct {
	Text   string
	Access []Access
}

ExtraPrompt is the self-contained declaration passed to agent.AddExtraPrompt. The Text fragment is appended to the system prompt for runs whose caller access matches one of the listed Access levels. Empty Access slice means "applies to every access level."

type ExtraPromptDef

type ExtraPromptDef struct {
	Text   string   `json:"text"`
	Access []Access `json:"access,omitempty"`
}

ExtraPromptDef is the wire format sent in SyncRequest.

type FileRef

type FileRef struct {
	ID          string `json:"id"`
	Filename    string `json:"filename"`
	ContentType string `json:"contentType"`
	Size        int64  `json:"size"`
}

FileRef references a file attachment in a prompt.

type HTTPRequest

type HTTPRequest struct {
	URL     string            `json:"url"`
	Method  string            `json:"method,omitempty"` // default: GET
	Headers map[string]string `json:"headers,omitempty"`
	Body    string            `json:"body,omitempty"`
	Timeout int               `json:"timeout,omitempty"` // seconds, default: 30, max: 120
	SaveAs  string            `json:"saveAs,omitempty"`  // save response body to S3 at this key (binary-safe)
	Raw     bool              `json:"raw,omitempty"`     // skip HTML→markdown conversion for HTML responses
}

HTTPRequest is the body for POST /api/agent/http.

type HTTPResponse

type HTTPResponse struct {
	Status      int               `json:"status"`
	Headers     map[string]string `json:"headers"`
	Body        string            `json:"body,omitempty"`
	ContentType string            `json:"contentType"` // original upstream Content-Type
	Size        int               `json:"size"`
	SavedTo     string            `json:"savedTo,omitempty"` // S3 key if body was auto-saved
	Note        string            `json:"note,omitempty"`    // human-readable note about transformations applied (e.g. HTML→markdown conversion)
}

HTTPResponse is returned from POST /api/agent/http.

type HTTPSessionStore

type HTTPSessionStore struct {
	// contains filtered or unexported fields
}

HTTPSessionStore implements session.SessionStore by calling Airlock's API. It is pre-scoped to a single conversation at construction time.

func NewHTTPSessionStore

func NewHTTPSessionStore(client *airlockClient, convID, runID, source string) *HTTPSessionStore

NewHTTPSessionStore creates a store scoped to the given conversation.

func (*HTTPSessionStore) Append

func (s *HTTPSessionStore) Append(ctx context.Context, msgs []session.Message) error

func (*HTTPSessionStore) Compact

func (s *HTTPSessionStore) Compact(ctx context.Context, summary []session.Message, tokensFreed int) error

func (*HTTPSessionStore) Load

type LLMProxyRequest

type LLMProxyRequest struct {
	Slug       string          `json:"slug,omitempty"`
	Capability string          `json:"capability,omitempty"`
	Options    json.RawMessage `json:"options"`
}

LLMProxyRequest is the body for POST /api/agent/llm/stream.

type LogEntry

type LogEntry struct {
	Level   LogLevel `json:"level"`
	Message string   `json:"message"`
}

LogEntry is one builder-emitted line: a level and a message. The wire format used by /api/agent/run/complete; also the in-memory shape on the run.

type LogLevel

type LogLevel string

LogLevel categorizes a builder-emitted log line. UI can color/filter on it; the wire format stores it explicitly so the level isn't lost in a flat string.

const (
	LogLevelInfo  LogLevel = "info"
	LogLevelWarn  LogLevel = "warn"
	LogLevelError LogLevel = "error"
)

type MCP

type MCP struct {
	Slug     string // unique per agent; binds as mcp_{slug} in run_js
	Name     string
	URL      string
	AuthMode MCPAuth
	AuthURL  string
	TokenURL string
	Scopes   []string
	Access   Access // who may invoke mcp_{slug}; default AccessUser
}

MCP is the self-contained declaration registered via agent.RegisterMCP. Slug binds as mcp_{slug} in run_js; the builder uses the returned *MCPHandle to call tools from Go.

type MCPAuth

type MCPAuth string

MCPAuth enumerates the supported authentication strategies for an MCP server. MCPAuthOAuthDiscovery is MCP-specific (RFC 9728 server-advertised OAuth endpoints) and not available on Connection.

const (
	MCPAuthOAuth          MCPAuth = "oauth"
	MCPAuthOAuthDiscovery MCPAuth = "oauth_discovery"
	MCPAuthToken          MCPAuth = "token"
	MCPAuthNone           MCPAuth = "none"
)

type MCPAuthStatus

type MCPAuthStatus struct {
	Slug       string  `json:"slug"`
	AuthMode   MCPAuth `json:"authMode"`
	Authorized bool    `json:"authorized"`
	AuthURL    string  `json:"authUrl,omitempty"`
}

MCPAuthStatus reports auth state for an MCP server.

type MCPContent

type MCPContent struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
}

MCPContent is a single content block in an MCP tool response.

type MCPDef

type MCPDef struct {
	Slug     string   `json:"slug,omitempty"`
	Name     string   `json:"name"`
	URL      string   `json:"url"`
	AuthMode MCPAuth  `json:"authMode"`
	AuthURL  string   `json:"authUrl,omitempty"`
	TokenURL string   `json:"tokenUrl,omitempty"`
	Scopes   []string `json:"scopes,omitempty"`
	Access   Access   `json:"access,omitempty"`
}

MCPDef is the wire format used by PUT /api/agent/mcp-servers/{slug} and (with Slug populated) by SyncRequest.MCPServers. Slug is sent in the URL for the per-slug PUT and in the body for the bulk sync.

type MCPHandle

type MCPHandle struct {
	// contains filtered or unexported fields
}

MCPHandle is a compile-time binding to a registered MCP server. Returned by RegisterMCP, used to call tools and build tool sets.

func (*MCPHandle) CallTool

func (h *MCPHandle) CallTool(ctx context.Context, toolName string, args any) (*MCPToolCallResponse, error)

CallTool calls a tool on this MCP server via Airlock's proxy. Args encoding mirrors ConnectionHandle.Request:

nil                           — sent as {} (MCP requires a JSON object)
[]byte, string, json.RawMessage — assumed to be valid JSON, sent as-is
io.Reader                     — fully read, assumed JSON, sent as-is
anything else                 — JSON-marshalled

type MCPToolCallRequest

type MCPToolCallRequest struct {
	Tool      string          `json:"tool"`
	Arguments json.RawMessage `json:"arguments"`
}

MCPToolCallRequest is the body for POST /api/agent/mcp/{slug}/tools/call.

type MCPToolCallResponse

type MCPToolCallResponse struct {
	Content []MCPContent `json:"content"`
	IsError bool         `json:"isError"`
}

MCPToolCallResponse is returned from MCP tool call proxy.

type MCPToolSchema

type MCPToolSchema struct {
	ServerSlug  string          `json:"serverSlug"`
	Name        string          `json:"name"`
	Description string          `json:"description"`
	InputSchema json.RawMessage `json:"inputSchema"`
}

MCPToolSchema is a discovered MCP tool schema returned in SyncResponse.

type MockAirlock

type MockAirlock struct {
	Server *httptest.Server

	// LLMResponse is the NDJSON response returned by POST /api/agent/llm/stream.
	// Set this before making prompt requests.
	LLMResponse []byte
	// contains filtered or unexported fields
}

MockAirlock is an httptest server that implements the Airlock agent API. Use NewMockAirlock() to create one. Exported for agent developers' tests.

func NewMockAirlock

func NewMockAirlock() (*MockAirlock, string)

NewMockAirlock creates a mock Airlock server and returns it along with the base URL.

func (*MockAirlock) Close

func (m *MockAirlock) Close()

Close shuts down the mock server.

func (*MockAirlock) Requests

func (m *MockAirlock) Requests() []MockRequest

Requests returns all recorded requests.

func (*MockAirlock) RequestsByPath

func (m *MockAirlock) RequestsByPath(prefix string) []MockRequest

RequestsByPath returns requests matching the given path prefix.

func (*MockAirlock) Reset

func (m *MockAirlock) Reset()

Reset clears all recorded requests.

type MockRequest

type MockRequest struct {
	Method string
	Path   string
	Body   []byte
}

MockRequest records a request made to the mock Airlock server.

type ModelCapability

type ModelCapability string

ModelCapability describes what kind of model is needed.

const (
	CapText          ModelCapability = "text"          // any chat/language model
	CapVision        ModelCapability = "vision"        // chat model that accepts images
	CapEmbedding     ModelCapability = "embedding"     // vector embeddings
	CapImage         ModelCapability = "image"         // image generation
	CapSpeech        ModelCapability = "speech"        // text-to-speech
	CapTranscription ModelCapability = "transcription" // speech-to-text
)

type ModelOpts

type ModelOpts struct {
	// Capability selects the model sub-type. Only meaningful for run.LLM()
	// (distinguishes text vs vision). For other methods, the method name
	// determines the capability and this field is ignored.
	Capability ModelCapability `json:"capability,omitempty"`

	// Description is optional human-readable context for run logs/UI.
	Description string `json:"description,omitempty"`
}

ModelOpts configures a model request. Used with agent.LLM(), agent.ImageModel(), etc.

type ModelProxyRequest

type ModelProxyRequest struct {
	Slug       string          `json:"slug,omitempty"`
	Capability string          `json:"capability"`
	Options    json.RawMessage `json:"options"`
}

ModelProxyRequest is the body for non-streaming model endpoints (POST /api/agent/llm/{image,embedding,speech,transcription}).

type ModelSlot

type ModelSlot struct {
	Slug        string
	Capability  ModelCapability // required: CapText, CapVision, CapImage, CapSpeech, CapTranscription, CapEmbedding
	Description string          // human-readable hint shown in the admin UI
}

ModelSlot is the self-contained declaration registered via agent.RegisterModel.

type ModelSlotDef

type ModelSlotDef struct {
	Slug        string `json:"slug"`
	Capability  string `json:"capability"`
	Description string `json:"description,omitempty"`
}

ModelSlotDef is the wire format sent in SyncRequest. The agent uses Slug at runtime (e.g. `agent.LLM(ctx, slug, ...)`); the admin binds a specific model to the slug in the Airlock UI. When no model is bound, calls fall through to the agent's per-capability default and then to the system default for that capability.

type PrintRequest

type PrintRequest struct {
	Parts          []DisplayPart `json:"parts"`
	Topic          string        `json:"topic,omitempty"`          // empty = direct to conversation
	ConversationID string        `json:"conversationId,omitempty"` // set for direct prints
	RunID          string        `json:"runId,omitempty"`          // originating run, used to sort ephemerals after their run's assistant messages
}

PrintRequest is the body for POST /api/agent/print.

type PromptInput

type PromptInput struct {
	Messages            []message.Message `json:"messages"`
	Message             string            `json:"message,omitempty"` // New user message text (used with SessionStore)
	ConversationID      string            `json:"conversationId,omitempty"`
	ProviderID          string            `json:"providerId,omitempty"`
	ModelID             string            `json:"modelId,omitempty"`
	Temperature         *float64          `json:"temperature,omitempty"`
	MaxOutputTokens     *int              `json:"maxOutputTokens,omitempty"`
	ProviderOptions     json.RawMessage   `json:"providerOptions,omitempty"`
	Files               []FileRef         `json:"files,omitempty"`
	ResumeRunID         string            `json:"resumeRunId,omitempty"`
	Approved            *bool             `json:"approved,omitempty"`
	SupportedModalities []string          `json:"supportedModalities,omitempty"` // e.g. ["text", "image", "pdf", "audio", "video"]
	Source              string            `json:"source,omitempty"`              // "user" (default), "system" (injected by Airlock)

	// ExtraSystemPrompt is an access-filtered concatenation of the agent's
	// registered AddExtraPrompt fragments, composed by Airlock at run
	// dispatch. The agent appends this to its sync-cached system prompt.
	ExtraSystemPrompt string `json:"extraSystemPrompt,omitempty"`

	// CallerAccess is the resolved per-(agent, user) access level for the
	// triggering caller. agentsdk uses it to gate which conn_/mcp_/topic_/
	// storage_ JS bindings (and registered tools) are exposed to the run.
	// Airlock sets this from trigger.ResolveAgentAccess. For trusted server
	// triggers (webhooks, crons) Airlock sends AccessAdmin.
	CallerAccess Access `json:"callerAccess,omitempty"`

	// ForceCompact tells the agent to skip the thinking loop and run a
	// user-triggered compaction instead. Message is ignored when set. The
	// agent loads conversation history, asks the model to summarize it,
	// persists the summary via the SessionStore's Compact method, and emits
	// a short text-delta describing the outcome.
	ForceCompact bool `json:"forceCompact,omitempty"`
}

PromptInput is the request body for POST /prompt.

type ProxyRequest

type ProxyRequest struct {
	Method string `json:"method"`
	Path   string `json:"path"`
	Body   string `json:"body,omitempty"`
}

ProxyRequest is the body for POST /api/agent/proxy/{slug}.

type Route

type Route struct {
	Method      string           // "GET", "POST", ...
	Path        string           // e.g. "/spotify"
	Handler     RouteHandlerFunc // required
	Access      Access           // required: AccessAdmin, AccessUser, or AccessPublic
	Description string
}

Route is the self-contained declaration registered via agent.RegisterRoute. Custom HTTP routes served by the agent and proxied by Airlock via subdomain routing. The (Method, Path) pair must be unique per agent.

type RouteDef

type RouteDef struct {
	Path        string `json:"path"`
	Method      string `json:"method"`
	Access      Access `json:"access"`
	Description string `json:"description,omitempty"`
}

RouteDef is a custom HTTP route definition sent during sync.

type RouteHandlerFunc

type RouteHandlerFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request)

RouteHandlerFunc handles custom HTTP routes registered via RegisterRoute.

type RunCompleteRequest

type RunCompleteRequest struct {
	RunID string `json:"runId"`
	// Status is "success" | "error" | "suspended" | "timeout" | "tool_errors".
	Status string `json:"status"`
	Error  string `json:"error,omitempty"`
	// ErrorKind is set when Status == "error" and disambiguates platform
	// vs agent failure for the UI. Empty otherwise.
	ErrorKind  string          `json:"errorKind,omitempty"`
	PanicTrace string          `json:"panicTrace,omitempty"`
	Actions    json.RawMessage `json:"actions"`
	Logs       []LogEntry      `json:"logs,omitempty"`
	Checkpoint json.RawMessage `json:"checkpoint,omitempty"`
}

RunCompleteRequest is the body for POST /api/agent/run/complete.

type Storage

type Storage struct {
	Slug        string
	Read        Access // gates Get/Stat/List + the public route; default AccessUser
	Write       Access // gates Put/Delete/Copy/CopyTo; default AccessUser
	Description string // shown in the system prompt's storage zones section
}

Storage is the self-contained declaration registered via agent.RegisterStorage. Each zone owns an S3 prefix ("{Slug}/") and a JS binding (storage_{slug}); AccessInternal axes are reachable only from builder Go code and never surface in run_js. The framework auto-registers a reserved zone "tmp" at Read=Write=AccessUser; builder calls with Slug="tmp" silently no-op (returning the framework handle) so frameworks and builders share the same scratch area without conflict.

Read and Write are independent — "Read: AccessUser, Write: AccessAdmin" (admin-curated, user-readable) and "Read: AccessAdmin, Write: AccessUser" (user-fed inbox processed only by admins) are both valid. The JS `storage_{slug}` object exposes Get/Stat/List only when Read satisfies the caller, and Put/Delete/Copy only when Write does.

type StorageDef

type StorageDef struct {
	Slug        string `json:"slug"`
	Read        Access `json:"read"`
	Write       Access `json:"write"`
	Description string `json:"description"`
}

StorageDef is the wire format sent in SyncRequest.

type StorageHandle

type StorageHandle struct {
	// contains filtered or unexported fields
}

StorageHandle is a compile-time binding to a registered Storage zone. All keys passed to its methods are relative to the zone's prefix; the handle prepends "{slug}/" before talking to Airlock. List returns keys stripped of the prefix as well, so callers see relative paths.

func (*StorageHandle) Copy

func (h *StorageHandle) Copy(ctx context.Context, src, dst string) error

Copy server-side-copies a file within this zone. Both keys are relative.

func (*StorageHandle) CopyTo

func (h *StorageHandle) CopyTo(ctx context.Context, src string, dstZone *StorageHandle, dst string) error

CopyTo server-side-copies a file from this zone into another zone. dstKey is relative to dstZone; src is relative to this zone. Builders compose move = CopyTo + src.Delete.

func (*StorageHandle) Delete

func (h *StorageHandle) Delete(ctx context.Context, key string) error

Delete removes the file at `key` (relative to this zone). Idempotent — missing files do not error.

func (*StorageHandle) Get

func (h *StorageHandle) Get(ctx context.Context, key string) (io.ReadCloser, error)

Get returns a reader over the file at `key` (relative to this zone). The caller must Close the returned ReadCloser.

func (*StorageHandle) List

func (h *StorageHandle) List(ctx context.Context, prefix string) ([]StoredFile, error)

List enumerates files under `prefix` (relative to this zone). Returned StoredFile.Key values are also relative.

func (*StorageHandle) Put

func (h *StorageHandle) Put(ctx context.Context, key string, data io.Reader, contentType string) error

Put writes a file at `key` (relative to this zone) with the given Content-Type. data is fully read; large bodies are streamed.

func (*StorageHandle) ReadAccess

func (h *StorageHandle) ReadAccess() Access

ReadAccess returns the zone's required level for reads.

func (*StorageHandle) Ref

func (h *StorageHandle) Ref(key string) StorageRef

Ref returns a typed StorageRef for `key` in this zone. This is the only public way to construct a StorageRef — builder code that returns file references from tool Out structs goes through here, so a ref can never claim a zone that the handle doesn't represent.

func (*StorageHandle) Slug

func (h *StorageHandle) Slug() string

Slug returns the zone's slug. Useful when constructing public URLs (storage.airlock.example.com/storage/{agentID}/{slug}/{key}).

func (*StorageHandle) Stat

func (h *StorageHandle) Stat(ctx context.Context, key string) (StoredFile, error)

Stat returns metadata for `key` (relative to this zone). The returned StoredFile.Key is also relative.

func (*StorageHandle) URL

func (h *StorageHandle) URL(key string) string

URL returns the URL at which the given key is fetchable on the agent's subdomain. Whether a request to that URL succeeds depends on the zone's Read level and the caller's auth state:

  • AccessPublic: served unauthenticated.
  • AccessUser: requires a valid agent-subdomain session cookie + agent membership; the proxy redirects through the login flow when the cookie is absent (so a click in chat triggers sign-in and lands back on the file).
  • AccessAdmin: same, but requires admin role on the agent.
  • AccessInternal: the proxy 404s the URL — internal zones are builder-Go only. URL still composes a string so callers don't get silent empty hrefs, but a warning is logged so the mistake is visible.

Re-resolves on the next sync if the agent's slug or the configured domain changes.

func (*StorageHandle) WriteAccess

func (h *StorageHandle) WriteAccess() Access

WriteAccess returns the zone's required level for writes.

type StorageRef

type StorageRef struct {
	// contains filtered or unexported fields
}

StorageRef is a typed reference to a file in a registered Storage zone. The fields are unexported so refs can only come from a *StorageHandle — either via handle.Ref(key), or by JSON-unmarshaling a wire-format {"zone": "...", "key": "..."} that the framework hands back (e.g. httpRequest savedTo, generateImage result, builder tool returns).

Use it as the field type on builder Out structs so the LLM sees an unambiguous {zone, key} shape:

type FetchOut struct {
    File agentsdk.StorageRef `json:"file"`
}

The corresponding JS binding is `storage_<zone>` — JS code reads the referenced file with storage_X.get(ref) (the binding validates the ref's zone matches its own slug).

func (StorageRef) Key

func (r StorageRef) Key() string

Key returns the file key relative to the zone.

func (StorageRef) MarshalJSON

func (r StorageRef) MarshalJSON() ([]byte, error)

MarshalJSON encodes the ref as {"zone":"...","key":"..."}.

func (StorageRef) String

func (r StorageRef) String() string

String returns the composed "zone/key" form, useful for logging.

func (*StorageRef) UnmarshalJSON

func (r *StorageRef) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes {"zone":"...","key":"..."}. The framework trusts the input here — validation happens at use time (when a JS binding receives a ref, or when builder code looks the zone up).

func (StorageRef) Zone

func (r StorageRef) Zone() string

Zone returns the zone slug.

type StoredFile

type StoredFile struct {
	Key          string    `json:"key"`
	Size         int64     `json:"size"`
	ContentType  string    `json:"contentType"`
	LastModified time.Time `json:"lastModified"`
}

StoredFile describes a file in agent storage.

type SyncRequest

type SyncRequest struct {
	Version      string           `json:"version"`
	Description  string           `json:"description,omitempty"`
	Tools        []ToolDef        `json:"tools,omitempty"`
	Webhooks     []WebhookDef     `json:"webhooks"`
	Crons        []CronDef        `json:"crons"`
	Routes       []RouteDef       `json:"routes,omitempty"`
	Topics       []TopicDef       `json:"topics,omitempty"`
	MCPServers   []MCPDef         `json:"mcpServers,omitempty"`
	Storages     []StorageDef     `json:"storages,omitempty"`
	ExtraPrompts []ExtraPromptDef `json:"extraPrompts,omitempty"`
	ModelSlots   []ModelSlotDef   `json:"modelSlots,omitempty"`
}

SyncRequest is the body for PUT /api/agent/sync.

type SyncResponse

type SyncResponse struct {
	SystemPrompt  string          `json:"systemPrompt"`
	MCPAuthStatus []MCPAuthStatus `json:"mcpAuthStatus,omitempty"`
	// MCPSchemas carries discovered tool schemas per MCP server slug.
	// Airlock populates these from its server-side discovery cache so the
	// agent's VM can install one typed JS method per tool on each
	// `mcp_{slug}` object — no per-run discovery round-trips.
	MCPSchemas map[string][]MCPToolSchema `json:"mcpSchemas,omitempty"`
	// PublicStorageBase is the URL prefix at which storage zones are reachable
	// on the agent's subdomain, ending without a trailing slash;
	// *StorageHandle.URL appends "/{slug}/{key}". Of the form
	// https://{slug}.{agentDomain}/__air/storage. The proxy enforces the
	// zone's Read access at fetch time — public zones serve unauthenticated,
	// user/admin zones require subdomain login (redirect-on-missing-cookie).
	PublicStorageBase string `json:"publicStorageBase,omitempty"`
}

SyncResponse is the response from PUT /api/agent/sync.

type Tool

type Tool[In any, Out any] struct {
	Name          string
	Description   string
	Execute       func(ctx context.Context, input In) (Out, error)
	Access        Access
	InputExamples []In
}

Tool is the declarative description of a typed, schema-bearing capability the LLM can invoke via run_js. In and Out are Go structs whose JSON schemas are generated at registration time and rendered as TypeScript signatures in the system prompt. Execute receives the unmarshaled In and returns Out — the wrapper handles JSON boundaries on both sides.

Construct with a pointer literal:

agent.RegisterTool(&agentsdk.Tool[SearchIn, SearchOut]{
    Name:        "search",
    Description: "Search the web.",
    Execute:     doSearch,
    Access:      agentsdk.AccessUser,
})

type ToolDef

type ToolDef struct {
	Name          string            `json:"name"`
	Description   string            `json:"description"`
	Access        Access            `json:"access"`
	InputSchema   json.RawMessage   `json:"inputSchema,omitempty"`
	OutputSchema  json.RawMessage   `json:"outputSchema,omitempty"`
	InputExamples []json.RawMessage `json:"inputExamples,omitempty"`
}

ToolDef describes a registered tool sent during sync. Carries the JSON schemas for input and output so Airlock can render TypeScript signatures in the system prompt and surface them in the UI.

type Topic

type Topic struct {
	Slug        string
	Description string
	Access      Access // who may subscribe via topic_{slug}.subscribe(); default AccessUser
}

Topic is the self-contained declaration registered via agent.RegisterTopic. Conversations subscribe to a topic via topic_{slug}.subscribe() in run_js; builders publish via the *TopicHandle returned by RegisterTopic.

type TopicDef

type TopicDef struct {
	Slug        string `json:"slug"`
	Description string `json:"description"`
	Access      Access `json:"access"`
}

TopicDef is the wire format sent in SyncRequest.

type TopicHandle

type TopicHandle struct {
	// contains filtered or unexported fields
}

TopicHandle is a compile-time binding to a registered topic. Returned by Agent.RegisterTopic; used for type-safe publishing.

func (*TopicHandle) Publish

func (h *TopicHandle) Publish(ctx context.Context, parts []DisplayPart) error

Publish sends display parts to all conversations subscribed to this topic.

type Webhook

type Webhook struct {
	Path        string             // unique per agent
	Handler     WebhookHandlerFunc // required
	Verify      string             // "hmac" | "token" | "none" (default: "none")
	Header      string             // header carrying the signature/token (hmac/token modes)
	Timeout     time.Duration      // max execution time (default: 2 min)
	Description string
	Access      Access // who may invoke; default AccessUser
}

Webhook is the self-contained declaration registered via agent.RegisterWebhook. Agents serve incoming HTTP at /webhook/{Path} on their container.

type WebhookDef

type WebhookDef struct {
	Path        string `json:"path"`
	Verify      string `json:"verify"`
	Header      string `json:"header,omitempty"`
	TimeoutMs   int64  `json:"timeoutMs"`
	Description string `json:"description,omitempty"`
}

WebhookDef is a webhook definition sent during sync.

type WebhookHandlerFunc

type WebhookHandlerFunc func(ctx context.Context, data []byte, ew *EventWriter) error

WebhookHandlerFunc handles incoming webhook requests. Pass ctx to any agent.X(ctx, ...) call the body makes.

Directories

Path Synopsis
Package tsrender produces the TypeScript .d.ts blocks that Airlock embeds into the agent system prompt: typed signatures for registered tools, and per-server `declare const mcp_{slug}: {...}` namespaces for MCP tools.
Package tsrender produces the TypeScript .d.ts blocks that Airlock embeds into the agent system prompt: typed signatures for registered tools, and per-server `declare const mcp_{slug}: {...}` namespaces for MCP tools.

Jump to

Keyboard shortcuts

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