skill

package
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package skill is the consumer-facing vocabulary for agent skills.

A skill is a directory containing SKILL.md (plus optional reference files) that teaches an agent a repeatable workflow. This package provides constructors that produce Ref values accepted by adaptor.WithSkills:

adaptor.WithSkills(
    skill.Dir("./skills/write-proof"),         // local directory
    skill.Key("code-review"),                  // provider-side catalogue key
    skill.Inline("greet", "# Greeting\n..."),  // literal SKILL.md content
    skill.Archive("kit", skill.ArchiveFile("./kit.tgz")), // zip / tar / tar.gz bundle
)

Dir, FS, Inline, and Archive build self-contained skill definitions; Key references a skill resolved at run time by the host-installed Provider. Provider and Materializer are the two host extension points: a Provider translates catalogue keys into concrete skill definitions (and may inject tenant-mandatory required skills), while a Materializer controls how skill sources are written to disk before a driver consumes them.

This package also owns the host extension contracts, source values, default materializer, and skill-specific error identities used by errors.Is and errors.As.

Index

Constants

View Source
const (
	// MetadataRuntimeName is the metadata key for the provider-visible directory name.
	MetadataRuntimeName = driver.SkillMetadataRuntimeName
	// MetadataDisplayName is the metadata key for a human-readable skill name.
	MetadataDisplayName = driver.SkillMetadataDisplayName
)

Reserved Metadata keys interpreted by the SDK and drivers. Setting MetadataRuntimeName on a Skill overrides the directory name the materializer writes and drivers mount. MetadataDisplayName provides a human-readable label for inspection and user interfaces.

View Source
const SkillCacheRootEnv = "AGENT_ADAPTOR_SKILL_CACHE_ROOT"

SkillCacheRootEnv names the AGENT_ADAPTOR_SKILL_CACHE_ROOT environment variable. It overrides the default materializer's cache root. Drivers use the same location to determine which materialized directories they may manage, so hosts should set it consistently for the whole process.

Variables

View Source
var (
	// ErrSkillKeyConflict identifies conflicting declarations of one skill key.
	ErrSkillKeyConflict = errors.New("agentadaptor: skill key defined with conflicting sources")
	// ErrSkillMaterializationFailed identifies a failure to stage a skill.
	ErrSkillMaterializationFailed = errors.New("agentadaptor: skill materialization failed")
	// ErrSkillSourceMissing identifies a skill declaration without a source.
	ErrSkillSourceMissing = errors.New("agentadaptor: skill source is required")
	// ErrSkillKeyMissing identifies a skill declaration without a key.
	ErrSkillKeyMissing = errors.New("agentadaptor: skill key is required")
	// ErrSkillNotFound identifies a catalogue key that a Provider cannot resolve.
	ErrSkillNotFound = errors.New("agentadaptor: skill not found in provider")
)

Functions

This section is empty.

Types

type ArchiveHTTPOption

type ArchiveHTTPOption func(*archiveHTTPConfig)

ArchiveHTTPOption configures the http.Request issued by ArchiveURL.

func WithArchiveHTTPClient

func WithArchiveHTTPClient(client *http.Client) ArchiveHTTPOption

WithArchiveHTTPClient overrides the http.Client used by the ArchiveURL opener. Defaults to http.DefaultClient.

func WithArchiveHeader

func WithArchiveHeader(key, value string) ArchiveHTTPOption

WithArchiveHeader adds a header to every request the ArchiveURL opener issues. Multiple WithArchiveHeader options accumulate.

type ArchiveOption

type ArchiveOption func(*archiveConfig)

ArchiveOption configures the archive source built by Archive.

func WithFingerprint

func WithFingerprint(fingerprint string) ArchiveOption

WithFingerprint supplies an opaque, stable source revision or identity. It is used to decide whether independently declared archive sources refer to the same logical revision and may also participate in Thread compatibility. It is not a cache key and is not an integrity check: the built-in materializer always keys its cache from the extracted content. Hosts that need authenticity or integrity verification must perform it in the Opener before returning the reader.

func WithFormat

func WithFormat(f Format) ArchiveOption

WithFormat pins the archive format instead of relying on magic-byte sniffing. Explicit formats surface mismatches as decompression errors, which is preferable when the host already knows what it serves.

func WithSubpath

func WithSubpath(subpath string) ArchiveOption

WithSubpath declares the prefix inside the archive where SKILL.md lives. Empty means the archive root. Entries that resolve outside the subpath are rejected during extraction.

type ArchiveSource

type ArchiveSource struct {
	// Archive opens the archive from its beginning for each materialization.
	Archive Opener
	// Format selects archive decoding; its zero value enables detection.
	Format Format
	// Subpath locates the skill root within the archive.
	Subpath string
	// Fingerprint is an optional stable source revision or identity.
	Fingerprint string
}

ArchiveSource is the public archive-origin value stored in [Skill.Source]. Independently declared ArchiveSource values without a non-empty Fingerprint are intentionally not assumed equal because Go functions have no stable content identity.

func (ArchiveSource) SkillArchive

func (s ArchiveSource) SkillArchive() (Opener, string, string, string)

SkillArchive returns the values consumed by a compatible materializer.

func (ArchiveSource) SkillSource

func (ArchiveSource) SkillSource()

SkillSource implements Source.

type Catalog

type Catalog interface {
	Provider
	// Catalogue returns the skills available from the provider.
	Catalogue(ctx context.Context) ([]Skill, error)
}

Catalog extends Provider with deterministic catalogue enumeration.

type DefaultMaterializerOption

type DefaultMaterializerOption func(*defaultMaterializerConfig)

DefaultMaterializerOption configures the materializer returned by NewDefaultSkillMaterializer.

func WithMaxArchiveEntries

func WithMaxArchiveEntries(n int) DefaultMaterializerOption

WithMaxArchiveEntries caps the number of entries (files + dirs) in a single archive. Archives with more entries surface as an error before any file is written. Default 10000; values <= 0 are treated as the default.

func WithMaxArchiveSize

func WithMaxArchiveSize(bytes int64) DefaultMaterializerOption

WithMaxArchiveSize caps the total compressed bytes the materializer reads from an Archive source. Streams that exceed the cap surface as an error before any extraction begins. Default 256 MiB; values <= 0 are treated as the default.

func WithMaxFileSize

func WithMaxFileSize(bytes int64) DefaultMaterializerOption

WithMaxFileSize caps the uncompressed bytes a single archive entry may occupy. Decompression bombs surface as an error mid-extraction and the partially extracted temporary directory is removed. Default 64 MiB; values <= 0 are treated as the default.

func WithSkillCacheRoot

func WithSkillCacheRoot(path string) DefaultMaterializerOption

WithSkillCacheRoot overrides the cache root the default materializer writes to. Empty input falls back to SkillCacheRootEnv, then os.UserCacheDir(), then os.TempDir().

type DirScanOption

type DirScanOption func(*dirScanConfig)

DirScanOption configures LocalSkillsFromDir. Hosts that need non-default behaviour (custom key prefix, exact-name exclusions, custom SKILL.md filename) chain options into the call.

func WithDirIgnore

func WithDirIgnore(names ...string) DirScanOption

WithDirIgnore declares directory names that the scan must skip. Useful for filtering generated or dependency directories such as "node_modules".

Multiple WithDirIgnore options accumulate; matching is exact (case-sensitive), not glob-style.

func WithDirSkillFile

func WithDirSkillFile(name string) DirScanOption

WithDirSkillFile overrides the per-directory marker file name. Default "SKILL.md". Setting it to, for example, "AGENT.md" lets the scan identify directories that follow a different convention. This option only changes discovery; callers remain responsible for ensuring each returned directory has the files required by its eventual consumer.

func WithDirSkillKeyPrefix

func WithDirSkillKeyPrefix(prefix string) DirScanOption

WithDirSkillKeyPrefix prepends prefix to every Skill.Key produced by the scan. A prefix of "team/" turns a directory named "code-review" into key "team/code-review". Prefixes that already end with "/" are honoured verbatim; other prefixes get a "/" separator appended.

Empty prefix is the default and produces bare directory names.

type FSSource

type FSSource struct {
	// FS contains the skill tree.
	FS fs.FS
	// Root locates the skill directory within FS. Empty and "." mean the FS root.
	Root string
}

FSSource sources a skill from an io/fs.FS tree rooted at Root.

func (FSSource) SkillFS

func (s FSSource) SkillFS() (fs.FS, string)

SkillFS returns the filesystem and root consumed by a compatible materializer.

func (FSSource) SkillSource

func (FSSource) SkillSource()

SkillSource implements Source.

type Format

type Format string

Format selects the decompressor applied to an Archive source. FormatAuto (the zero value) triggers magic-byte sniffing.

const (
	// FormatAuto leaves format detection to the materializer's
	// magic-byte sniffing (zip local-file header, gzip magic, ustar
	// magic at offset 257).
	FormatAuto Format = ""
	// FormatZip is a ZIP archive (PKZIP format).
	FormatZip Format = "zip"
	// FormatTar is an uncompressed POSIX tar archive.
	FormatTar Format = "tar"
	// FormatTarGz is a tar archive wrapped in a gzip stream
	// (canonical .tar.gz / .tgz).
	FormatTarGz Format = "tar.gz"
)

Supported archive formats accepted by the built-in materializer.

type InlineSource

type InlineSource struct {
	// SkillMD is the complete SKILL.md content.
	SkillMD string
}

InlineSource carries a single SKILL.md document.

func (InlineSource) InlineSkillMD

func (s InlineSource) InlineSkillMD() string

InlineSkillMD returns the SKILL.md content consumed by a compatible materializer.

func (InlineSource) SkillSource

func (InlineSource) SkillSource()

SkillSource implements Source.

type Materializer

type Materializer interface {
	// Materialize makes s available in a directory containing SKILL.md and
	// returns that directory.
	Materialize(ctx context.Context, s Skill) (sourcePath string, err error)
}

Materializer writes a skill source to a directory containing SKILL.md.

func NewDefaultSkillMaterializer

func NewDefaultSkillMaterializer(opts ...DefaultMaterializerOption) Materializer

NewDefaultSkillMaterializer returns the SDK's built-in materializer, which handles the sources produced by Dir, FS, Inline, and Archive. Agents install it automatically; construct one explicitly only to tune the options above or to compose a chain-of-responsibility around it:

type storeMaterializer struct {
    fallback skill.Materializer
    store    *MyStoreClient
}

func (m *storeMaterializer) Materialize(ctx context.Context, s skill.Skill) (string, error) {
    if src, ok := s.Source.(myCustomSource); ok {
        return m.store.Fetch(ctx, src)
    }
    return m.fallback.Materialize(ctx, s)
}

type Opener

type Opener = func(ctx context.Context) (io.ReadCloser, error)

Opener produces a fresh reader over the archive bytes. It is invoked at materialization time and read to completion (subject to the configured size cap), so implementations MUST be idempotent: a second invocation should produce the same content. Build one with ArchiveBytes, ArchiveFile, or ArchiveURL, or supply your own.

func ArchiveBytes

func ArchiveBytes(data []byte) Opener

ArchiveBytes returns an Opener that serves the given data from memory. The slice is captured by reference; callers MUST NOT mutate it afterwards.

func ArchiveFile

func ArchiveFile(path string) Opener

ArchiveFile returns an Opener that opens the given file each time the materializer needs to read it. Useful when the host has already downloaded the archive to disk.

func ArchiveURL

func ArchiveURL(url string, opts ...ArchiveHTTPOption) Opener

ArchiveURL returns an Opener that GETs the URL with the configured headers and HTTP client. Non-2xx responses surface as errors. It performs no integrity checking, and WithFingerprint is only a declared source identity—it does not add integrity verification. The opener itself must verify authenticity when required. ArchiveURL imposes no default timeout: either supply an http.Client with a Timeout via WithArchiveHTTPClient or make sure the run context carries a deadline.

type PathSource

type PathSource struct {
	// Path is the skill directory.
	Path string
}

PathSource sources a skill from a local directory containing SKILL.md.

func (PathSource) SkillPath

func (s PathSource) SkillPath() string

SkillPath returns the directory consumed by a compatible materializer.

func (PathSource) SkillSource

func (PathSource) SkillSource()

SkillSource implements Source.

type Provider

type Provider interface {
	// GetSkills resolves the requested catalogue keys. Implementations may also
	// include skills marked Required.
	GetSkills(ctx context.Context, keys []string) (map[string]Skill, error)
}

Provider resolves catalogue keys into concrete skills for a run. Providers may additionally return Required skills that were not explicitly requested.

type Ref

type Ref = driver.SkillRef

Ref is what adaptor.WithSkills accepts: either a provider catalogue key (built with Key) or a fully-defined Skill value (built with Dir, FS, Inline, or Archive).

func Key

func Key(k string) Ref

Key returns a Ref that references a provider-side skill by its catalogue key. The key is resolved by the Provider installed on the agent; unknown keys fail the run before the driver is invoked.

func SkillsAsRefs

func SkillsAsRefs(skills []Skill) []Ref

SkillsAsRefs converts a []Skill into a []Ref so hosts can pass a scanned skill set into variadic options:

adaptor.WithSkills(skill.SkillsAsRefs(skills)...)

The conversion preserves order and does not deep-clone nested values such as Metadata.

type Set

type Set map[string]Skill

Set is a static map-backed Catalog.

func (Set) Catalogue

func (s Set) Catalogue(_ context.Context) ([]Skill, error)

Catalogue implements Catalog and returns entries ordered by key.

func (Set) GetSkills

func (s Set) GetSkills(_ context.Context, keys []string) (map[string]Skill, error)

GetSkills implements Provider. Required entries are always returned.

type Skill

type Skill = driver.Skill

Skill is the full description of one skill: identity (Key), origin (Source), Required marker, human-readable Reason, and optional Metadata. Skill values act as Ref, so constructor results can be passed straight to adaptor.WithSkills.

func Archive

func Archive(key string, open Opener, opts ...ArchiveOption) Skill

Archive builds a Skill sourced from an archive stream (zip, tar, or tar.gz). The archive must contain SKILL.md at its root, or under the prefix declared via WithSubpath. Key is required; open supplies the archive bytes and is typically built with ArchiveBytes, ArchiveFile, or ArchiveURL:

skill.Archive("deploy-kit", skill.ArchiveFile("./deploy-kit.tgz"))
skill.Archive("deploy-kit",
    skill.ArchiveURL("https://store.example.com/kits/deploy.zip",
        skill.WithArchiveHeader("Authorization", "Bearer "+token)),
    skill.WithFingerprint(knownDigest),
)

Format defaults to FormatAuto (magic-byte sniffing); use WithFormat to pin it explicitly.

func Dir

func Dir(path string) Skill

Dir builds a Skill sourced from a local directory that contains SKILL.md (and optional reference files). The skill key defaults to the directory basename; callers may override it by assigning to the returned Skill's Key field.

func FS

func FS(fsys fs.FS, root string) Skill

FS builds a Skill sourced from an io/fs.FS tree rooted at root. The root entry must contain SKILL.md; "" or "." mean the FS root. The skill key defaults to the basename of root ("skill" when root is empty); callers may override it by assigning to the returned Skill's Key field.

func Inline

func Inline(key, skillMD string) Skill

Inline builds a Skill whose entire content is the given SKILL.md string. Key is required. Skills that need auxiliary reference files should use FS or Archive instead.

func LocalSkillsFromDir

func LocalSkillsFromDir(root string, opts ...DirScanOption) ([]Skill, error)

LocalSkillsFromDir scans root and produces one Skill per subdirectory that contains the SKILL marker file (default "SKILL.md"). The scan is deterministic: subdirectories are processed in lexical order, so the returned slice is stable across runs on the same filesystem.

Each produced Skill has:

  • Key: directory basename, optionally prefixed via WithDirSkillKeyPrefix
  • Source: the same local-directory source Dir builds, pointing at the absolute path of the subdirectory
  • Required / Reason / Metadata: zero values (the scan does NOT parse SKILL.md frontmatter; hosts that need that should post-process the slice)

Subdirectories without a SKILL marker file are silently skipped so the scan tolerates a mixed root (some skills, some plain directories). Hidden entries (starting with ".") are skipped by default; pass WithDirIgnore to skip additional names.

Error semantics:

  • root doesn't exist or isn't a directory → error
  • root is unreadable (permission) → error
  • individual subdirectory unreadable → error (better to fail loudly than silently miss a skill the host expected)

The returned []Skill feeds the skill options via SkillsAsRefs:

skills, err := skill.LocalSkillsFromDir("/opt/skills")
if err != nil { return err }
agent := adaptor.New(drv,
    adaptor.WithSkills(skill.SkillsAsRefs(skills)...),
)

func Require

func Require(s Skill, reason string) Skill

Require returns a copy of s marked Required=true with the given human-readable reason. Required skills join the selected set of every run that sees them, regardless of what the caller passed to WithSkills.

type SkillKeyConflictError

type SkillKeyConflictError struct {
	// Key is the conflicting skill key.
	Key string
	// Sources describes the declarations that conflict.
	Sources []string
	// Detail contains optional diagnostic context.
	Detail string
}

SkillKeyConflictError reports two structurally different declarations with the same skill key.

func (*SkillKeyConflictError) Error

func (e *SkillKeyConflictError) Error() string

Error implements error.

func (*SkillKeyConflictError) Unwrap

func (e *SkillKeyConflictError) Unwrap() error

Unwrap exposes ErrSkillKeyConflict for errors.Is.

type SkillMaterializationError

type SkillMaterializationError struct {
	// Key is the logical skill key.
	Key string
	// RuntimeName is the provider-visible directory name, when known.
	RuntimeName string
	// Cause is the underlying materialization failure.
	Cause error
}

SkillMaterializationError reports a failure to stage a resolved skill into a provider-visible directory.

func (*SkillMaterializationError) Error

func (e *SkillMaterializationError) Error() string

Error implements error.

func (*SkillMaterializationError) Is

func (e *SkillMaterializationError) Is(target error) bool

Is also classifies the error as ErrSkillMaterializationFailed.

func (*SkillMaterializationError) Unwrap

func (e *SkillMaterializationError) Unwrap() error

Unwrap preserves the underlying materializer cause.

type Source

type Source = driver.SkillSource

Source is the open marker interface for a Skill's origin. Hosts may define custom Source types as long as a matching Materializer is installed to handle them.

Jump to

Keyboard shortcuts

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