capability

package
v0.7.0-rc.3 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

README

Capability Catalogue

capability and wire can be imported without importing the root SDK package.

defs, err := capability.Catalog(manifest, capability.Discovery{
    MCPSchemas: schemas,
})

Each Definition has Path, Target, Access, Description, LLMHint, InputSchema, OutputSchema, TextOutput, and InputExamples. TextOutput keeps plain-text file results as JS strings even when they contain valid JSON. Path.ID() is the transport identity: <kind>/<escaped canonical namespace>/<escaped canonical operation>. Examples: air//file_read, tool//calculate, conn/mail/request_json. Path.JSParts(), Path.JS(), and Path.Direct() give presentation names for the same identity. Aliases, normalization, and name truncation never change IDs. Path.Kind(), CanonicalNamespace(), and CanonicalOperation() expose dispatch components without parsing an ID. The shared chat runtime uses these identities for both JavaScript bindings and direct tools.

Build the complete catalogue before selecting definitions. Catalogue construction rejects duplicate IDs and JS/direct aliases, including conflicting access levels. Only manifest-declared external MCP servers admit discovery schemas. Catalog excludes MCP servers with empty access and all task-private tools. DefinitionCatalog(manifest, wire.RuntimeAgentDefinition{Slug: slug, ContractHash: hash}, discovery) validates the exact task contract and replaces global tools with its private inventory. Only that definition's bound MCP servers are included, including servers without chat access. Fixed operations, connections, and topics retain their normal policy. A catalogue is not proof of run authority. Definitions describe capabilities, not authorization grants. AccessPublic on file operations means directory-specific policy must still be checked.

Inventory

Fixed() contains 30 entries. Builtin input contracts live in inputs.go and are shared with the app/direct executors. No selected-definition list can add an executor to an app.

Target Operations
App, 18 file_read, file_read_bytes, file_read_range_bytes, file_grep, file_head, file_tail, file_lines, file_stat, file_exists, file_write, file_delete, file_list, file_encode, file_decode, file_decode_text, file_edit_lines, file_sed, query_db
Platform, 11 output, file_share_url, http_request, web_search, attach_to_context, analyze_image, transcribe_audio, generate_image, speak, embed, request_upgrade
Executor, 1 air.log; console methods are JS intrinsics, not app RPCs

Catalog adds registered app tools, two platform operations per connection (request, request_json), two per topic (subscribe, unsubscribe), discovered MCP operations. Jobs, connectors, environment variables, routes, model slots, and lifecycle hooks are author APIs/declarations, not implicitly exposed model tools. Registered tools may use their author APIs.

App Invocation

Send wire.RuntimeInvokeRequest as JSON to POST /__air/runtime/invoke (wire.RuntimeInvokePath) using Authorization: Bearer <target-agent-token>. Do not expose this credential or forward this internal route through public ingress. There is no authentication fallback and no trust in user headers.

The broker loads an active run from shared storage, verifies that it belongs to the target agent, applies the run's capability/registration policy, and fills RuntimeContext from authoritative run records. This is a trusted internal protocol, not a public API for clients to choose their own identity or access. The app checks the token, matching agent ID, canonical run/context UUIDs, explicit access, full manifest inventory, and registered-tool access. It executes only registered tools and the fixed app operations. The broker handles platform operations directly, without an app hop. Input is the canonical JSON tool input object; the JS adapter accepts one object argument and unwraps its positional array.

RuntimeContext carries AgentID, RunID, InvocationToken, BridgeID, ConversationID, Caller, SupportedModalities, optional Job (ID, Attempt, LeaseToken), and optional Definition (Slug, ContractHash). The host populates Definition from the admitted application-owned task run. Scoped callbacks require an application/admin caller without a human initiator or job fence. The app resolves tools only from the matching immutable definition; neither an unknown tool nor an incompatible hash can fall back to global tools. Execution borrows this run, honors HTTP cancellation and a bounded timeout, and never creates or completes the run. Job progress and SDK API requests retain the run and job attribution. Invocation-local file caches are cleaned up on return.

The response is one wire.RuntimeInvokeResponse JSON object, not NDJSON. It retains Output, Title, Metadata, Warnings, Attachments, Logs, Actions, and Error. Ordinary tool failures and panics return HTTP 200 with Error; authentication, authorization, and protocol failures return non-2xx. Airlock owns merging invocation telemetry into the active run and completing that run.

Attachments contain only Path, MimeType, and Filename. Existing s3ref: attachments retain the checked object path without loading bytes; inline goai attachments are persisted to object storage and returned as references. Failed attachments produce warnings without discarding successful result fields. The broker can turn these paths into the platform's attachment references for model/session handling. Sensitive values, including agent and job credentials, are redacted from response strings and nested metadata before serialization.

Documentation

Overview

Package capability defines the manifest-based capability catalogue shared by Airlock's broker and agent runtimes. It does not import the root SDK package.

Index

Constants

View Source
const (
	Air                 = binding.Air
	Tool                = binding.Tool
	Connection          = binding.Connection
	Topic               = binding.Topic
	MCP                 = binding.MCP
	MaxDirectNameLength = binding.MaxDirectNameLength
)

Variables

This section is empty.

Functions

func External

func External(kind Kind, namespace, alias string, operations []string) (map[string]Path, error)

Types

type AnalyzeImageInput

type AnalyzeImageInput struct {
	Path     string `json:"path"`
	Question string `json:"question,omitempty"`
}

type ConnectionRequestInput

type ConnectionRequestInput struct {
	Method  string            `json:"method" jsonschema:"description=HTTP method (GET, POST, ...)."`
	Path    string            `json:"path" jsonschema:"description=Path appended to the connection's base URL."`
	Body    any               `` /* 152-byte string literal not displayed */
	Headers map[string]string `json:"headers,omitempty"`
}

type Definition

type Definition struct {
	Path         Path
	Target       Target
	Access       wire.Access
	Description  string
	LLMHint      string
	InputSchema  json.RawMessage
	OutputSchema json.RawMessage
	// TextOutput marks plain-text tool results that must remain strings in JS,
	// even when their contents happen to be valid JSON (for example file_read).
	TextOutput    bool
	InputExamples []json.RawMessage
}

Definition is a capability contract, not a grant. The broker intersects the catalogue with the authenticated run's policy before exposing either alias.

func Catalog

func Catalog(manifest wire.AgentManifest, discovery Discovery) ([]Definition, error)

Catalog constructs identities from declarations, never presentation aliases. It rejects collisions across the entire catalogue before policy selection so selecting a subset cannot hide a conflicting definition and escalate access. Declared tools retain their manifest schemas and examples verbatim.

func DefinitionCatalog

func DefinitionCatalog(manifest wire.AgentManifest, scope wire.RuntimeAgentDefinition, discovery Discovery) ([]Definition, error)

DefinitionCatalog constructs the private tool and bound MCP inventory for an exact task contract. It excludes global app tools and unbound MCPs. Fixed platform operations, connections and topics retain their normal access rules. The host must authenticate scope from a persisted application-owned run.

func Fixed

func Fixed() []Definition

Fixed returns the complete fixed inventory, never a caller-selected subset. Directory-specific read/write/list checks still apply at execution time.

type Discovery

type Discovery struct {
	MCPSchemas map[string][]wire.MCPToolSchema
}

Discovery contains platform-resolved schemas for declared external MCP servers.

type EmbedInput

type EmbedInput struct {
	Text  string   `json:"text,omitempty" jsonschema:"description=A single text input. Mutually exclusive with 'texts'."`
	Texts []string `json:"texts,omitempty"`
}

type FileEditLinesInput

type FileEditLinesInput struct {
	Src   string          `json:"src"`
	Edits []LineEditInput `` /* 156-byte string literal not displayed */
	Dst   string          `json:"dst,omitempty" jsonschema:"description=Optional destination. Pass src to edit in place; omit for an auto scratch path."`
}

type FileGrepInput

type FileGrepInput struct {
	Path        string `json:"path" jsonschema:"description=Storage path."`
	Pattern     string `json:"pattern" jsonschema:"description=Regex pattern (RE2)."`
	IgnoreCase  bool   `json:"ignoreCase,omitempty"`
	Invert      bool   `json:"invert,omitempty"`
	LineNumbers bool   `json:"lineNumbers,omitempty"`
	Max         int    `json:"max,omitempty" jsonschema:"description=Cap matched lines; 0 = default."`
}

type FileLinesInput

type FileLinesInput struct {
	Path  string `json:"path"`
	Start int    `json:"start,omitempty" jsonschema:"description=1-based line offset; 0 = default 1."`
	Count int    `json:"count,omitempty" jsonschema:"description=Line count; 0 = default 10."`
}

type FileListInput

type FileListInput struct {
	Path      string `json:"path" jsonschema:"description=Directory path (trailing slash optional)."`
	Recursive bool   `json:"recursive,omitempty"`
}

type FileNLinesInput

type FileNLinesInput struct {
	Path string `json:"path"`
	N    int    `json:"n,omitempty" jsonschema:"description=Line count; 0 = default 10."`
}

type FileReadRangeInput

type FileReadRangeInput struct {
	Path   string `json:"path" jsonschema:"description=Storage path."`
	Start  int64  `json:"start" jsonschema:"description=Byte offset (0-based)."`
	Length int64  `json:"length" jsonschema:"description=Number of bytes to read."`
}

type FileSedInput

type FileSedInput struct {
	Src    string `json:"src"`
	Script string `` /* 184-byte string literal not displayed */
	Dst    string `json:"dst,omitempty"`
}

type FileShareURLInput

type FileShareURLInput struct {
	Path             string `json:"path"`
	ExpiresInMinutes int    `json:"expiresInMinutes,omitempty" jsonschema:"description=URL TTL; defaults to 60, capped at 1440 (24h)."`
}

type FileWriteInput

type FileWriteInput struct {
	Path        string `json:"path"`
	Data        string `json:"data" jsonschema:"description=UTF-8 text contents. For binary, set base64 instead."`
	Base64      string `json:"base64,omitempty" jsonschema:"description=Base64-encoded contents. Mutually exclusive with data."`
	ContentType string `json:"contentType,omitempty"`
}

type GenerateImageInput

type GenerateImageInput struct {
	Prompt      string `json:"prompt"`
	SaveAs      string `json:"saveAs,omitempty" jsonschema:"description=Storage path; defaults to an auto scratch path."`
	Size        string `json:"size,omitempty"`
	AspectRatio string `json:"aspectRatio,omitempty"`
	Seed        *int64 `json:"seed,omitempty"`
}

type HTTPRequestInput

type HTTPRequestInput struct {
	URL        string            `json:"url"`
	Method     string            `json:"method,omitempty" jsonschema:"description=Defaults to GET."`
	Headers    map[string]string `json:"headers,omitempty"`
	Body       string            `json:"body,omitempty" jsonschema:"description=Request body. JSON-encode objects yourself; Content-Type is not auto-set."`
	Timeout    int               `json:"timeout,omitempty"`
	SaveAs     string            `` /* 143-byte string literal not displayed */
	Raw        bool              `json:"raw,omitempty" jsonschema:"description=Skip HTML to markdown conversion (default is to convert HTML)."`
	AllHeaders bool              `json:"allHeaders,omitempty"`
}

type Kind

type Kind = binding.Kind

type LineEditInput

type LineEditInput struct {
	From   int    `json:"from,omitempty" jsonschema:"description=1-based start line. Required unless 'append' is set."`
	Count  int    `json:"count,omitempty" jsonschema:"description=Lines from 'from' to operate on. 0 with text = insert before 'from'."`
	Text   string `json:"text,omitempty" jsonschema:"description=Replacement / insertion text."`
	Append string `json:"append,omitempty" jsonschema:"description=When set, append this text to the end of the file."`
}

type OutputInput

type OutputInput struct {
	Parts []wire.DisplayPart `` /* 241-byte string literal not displayed */
}

type Path

type Path = binding.Path

Path gives one canonical identity both JS and direct-tool presentations.

func Local

func Local(kind Kind, namespace, operation string) Path

type PathInput

type PathInput struct {
	Path string `` /* 157-byte string literal not displayed */
}

These input contracts are shared by catalogue schemas and app executors.

type QueryDBInput

type QueryDBInput struct {
	SQL    string `json:"sql"`
	Params []any  `json:"params,omitempty" jsonschema:"description=Positional parameters bound as $1, $2, ..."`
}

type RequestUpgradeInput

type RequestUpgradeInput struct {
	Description string `json:"description"`
}

type SpeakInput

type SpeakInput struct {
	Text         string   `json:"text"`
	SaveAs       string   `json:"saveAs,omitempty"`
	Voice        string   `json:"voice,omitempty"`
	OutputFormat string   `json:"outputFormat,omitempty"`
	Speed        *float64 `json:"speed,omitempty"`
}

type Target

type Target string
const (
	App      Target = "app"
	Platform Target = "platform"
	// Executor is a JS intrinsic, not an app or platform RPC.
	Executor Target = "executor"
)

type TranscribeAudioInput

type TranscribeAudioInput struct {
	Path     string `json:"path"`
	Language string `json:"language,omitempty" jsonschema:"description=ISO-639 hint, optional."`
	Prompt   string `json:"prompt,omitempty" jsonschema:"description=Optional prior-context hint for the transcriber."`
}

type TransformInput

type TransformInput struct {
	Src   string `json:"src" jsonschema:"description=Source storage path."`
	Codec string `json:"codec" jsonschema:"description=Codec name (base64, base64url, hex, gzip; or a charset for fileDecodeText)."`
	Dst   string `json:"dst,omitempty" jsonschema:"description=Optional destination path. Omit for an auto scratch path. Must differ from src."`
}

type WebSearchInput

type WebSearchInput struct {
	Query string `json:"query"`
	Count int    `json:"count,omitempty" jsonschema:"description=Default 5."`
}

Jump to

Keyboard shortcuts

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