ext

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package ext holds optional sandbox.Pack implementations that are generically useful but don't belong in the core sandbox package.

sandbox's built-in packs (require, http, fetch, markdown, ai, help, skills) are the minimal set every agentloop deployment needs. The packs here — email, secret, document search, a document store — are common but optional: most of the applications this was extracted from use two or three of them, never all four, and a new deployment starts with none.

Each pack follows the same decoupling the core packs use: it takes a callback or a small interface (EmailPack's send func, SecretPack's get func, SearchPack's search func, StoresPack's StoresBackend) rather than a concrete dependency, so this package stays free of any mail/secrets/search-backend import. An application wires its own backend in when it builds the agentloop.Capability that installs the pack — see the package examples and DefaultCapabilities in the agentloop package for the pattern.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EmailPack

func EmailPack(ctx context.Context, send func(to, subject, body string) error) sandbox.Pack

EmailPack exposes a synchronous `sendEmail({to, subject, body})` primitive. It takes a send callback rather than a concrete mailer so this package stays transport-agnostic — the application's Capability closes the callback over its configured sender + from address.

Every call is policy-gated with toolName "sendEmail"; sandbox.DefaultPolicy denies it unless granted via DefaultPolicy.AllowTools. ctx is the per-session context the check shares with the run.

The argument is an object so the call site is self-documenting and resilient to added optional fields. Returns true on success; a send error surfaces as a catchable JS throw.

func OpenAPIPack

func OpenAPIPack(spec *openapi3.T, cfg OpenAPIConfig) (sandbox.Pack, error)

OpenAPIPack turns an OpenAPI 3 document into a require()-able skill: one JS function per operation (path + method), named after the operation's operationId (sanitized) or derived from the method and path when it has none.

Each generated function calls the sandbox's own internal _http primitive — the same one require('http') wraps (see pack_fetch.go in the sandbox package) — rather than a new HTTP client. That's the whole design: OpenAPIPack only generates JavaScript source (a string), so every call a generated function makes is still policy-gated exactly like fetch()/require('http') already are, with no new Go-side networking code to audit. _http is used directly rather than require('http')'s get/post/put/del because it uniformly supports every method via its `method` option, including PATCH, which the http module has no wrapper for.

Following the skill-lazy-loading pattern the rest of agentloop's skill mechanism uses (see sandbox.SkillDiscoveryPack's doc comment), the returned Pack's Prompt is a single short line — the API's name, operation count, and a pointer to skillGet(name)/require(name) — not the full API surface; a spec can have far more operations than are worth inlining into every turn. The full per-operation documentation is TypeScript ambient declarations (`declare function ...`), in the same style the core packs' Prompt fields already use, registered as a HelpEntry under Name so skillGet(name) returns it on demand.

Parameters are passed as a single options object rather than positionally — `functionName(params)`, with params.<name> for each path/query parameter and params.body for the request body — since OpenAPI operations vary too much in parameter count and optionality for a positional signature to stay readable. Required-ness is documented but not enforced client-side; the server is still free to reject a missing required parameter.

Returns an error if the spec resolves to zero generated operations (no BaseURL and no servers, no paths, or every operation filtered out by Methods) — a skill with nothing callable is a config mistake, not something to silently install.

func SearchPack

func SearchPack(search func(query string, topK int) ([]SearchHit, error)) sandbox.Pack

SearchPack exposes a synchronous `documentSearch(query, topK?)` primitive backed by a semantic-search / RAG retriever. It takes a search callback rather than a concrete retriever so this package stays free of that dependency — the application's Capability closes the callback over its own retriever and the per-session scope.

topK defaults to 5 when omitted or <= 0.

func SecretPack

func SecretPack(ctx context.Context, get func(name string) (string, error)) sandbox.Pack

SecretPack exposes a synchronous `secret(name)` primitive that reads a decrypted secret by name. It takes a getter callback rather than a concrete secrets service so this package stays free of that dependency — the application's Capability closes the getter over its own secrets backend and the per-session scope.

Every read is policy-gated with toolName "secret"; sandbox.DefaultPolicy denies it unless granted via DefaultPolicy.AllowTools. ctx is the per-session context the check shares with the run.

Lookup failures (unknown name, decrypt error) surface as a thrown JS error so a skill can try/catch; they do not crash the run.

func StoresPack

func StoresPack(backend StoresBackend) sandbox.Pack

StoresPack exposes a `stores` object with `list()` and `read(id)` for inspecting the indexed document corpus from inside the sandbox.

Types

type OpenAPIConfig

type OpenAPIConfig struct {
	// Name is the skill's name — the string passed to require(name) and
	// shown in skillList(). Defaults to a slug of spec.Info.Title, or
	// "api" if the spec has no title.
	Name string

	// Description is the skillList() one-liner. Defaults to
	// spec.Info.Title, or a generic fallback if the spec has none.
	Description string

	// BaseURL overrides the spec's first `servers` entry. Required if
	// the spec declares no servers.
	BaseURL string

	// Headers are applied to every request this skill's functions
	// make — the place to put a static API key or bearer token.
	// OpenAPI's securitySchemes are not interpreted; this is the whole
	// auth story OpenAPIPack has.
	Headers map[string]string

	// Methods restricts which HTTP methods become functions. Nil
	// generates GET, POST, PUT, PATCH, DELETE (the common REST verbs);
	// HEAD/OPTIONS/TRACE/CONNECT are never generated regardless.
	Methods []string
}

OpenAPIConfig configures OpenAPIPack.

type SearchHit

type SearchHit struct {
	DocumentID    string  `json:"documentId"`
	DocumentTitle string  `json:"documentTitle"`
	ChunkIndex    int     `json:"chunkIndex"`
	Content       string  `json:"content"`
	Score         float64 `json:"score"`
}

SearchHit is one semantic-search result surfaced to the sandbox. The JSON tags drive the JS-side key names (the pack converts hits to plain maps so the runtime sees camelCase keys).

type StoreDoc

type StoreDoc struct {
	ID         string `json:"id"`
	Title      string `json:"title"`
	ChunkCount int64  `json:"chunkCount"`
}

StoreDoc is one indexed document surfaced to the sandbox by the stores primitive.

type StoresBackend

type StoresBackend interface {
	// List returns every indexed document in the current scope.
	List() ([]StoreDoc, error)
	// Read returns the full text of one document (its chunks joined in
	// source order). An unknown id yields an empty string, no error.
	Read(documentID string) (string, error)
}

StoresBackend is the read surface the stores primitive needs. An application adapts its own document catalog to it (scoped to the session); this keeps this package free of that dependency.

Jump to

Keyboard shortcuts

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