stax
Composition layer

Defining an Agent

How to define an agent using defineAgent()

The agent manifest is the root definition of an agent artifact. It declares identity, layer sources, runtime hints, package dependencies, secret requirements, and the adapter used to materialize the artifact for a target environment.

Agents are authored in TypeScript using defineAgent() and compiled to JSON for the OCI config blob.

defineAgent()

Single Root Definition

A project must contain exactly one root agent definition file, typically agent.ts. All relative paths are resolved relative to the directory containing this file.

agent.ts
import { defineAgent } from "stax";
import claudeCode from "@stax/claude-code";

export default defineAgent({
  name: "backend-engineer",
  version: "3.1.0",
  description: "Senior backend engineer with Go and distributed systems expertise.",
  author: "myorg",
  license: "MIT",
  tags: ["code-review", "architecture", "golang"],
  url: "https://github.com/myorg/backend-engineer",

  adapter: claudeCode({
    model: "claude-opus-4-1",
    modelParams: { temperature: 0.3 },
  }),

  persona: "./personas/maya-chen.ts",
  prompt: "./SYSTEM_PROMPT.md",
  mcp: "./mcp-servers.ts",
  skills: "./skills/",
  rules: "./rules/",
  knowledge: "./knowledge/",
  memory: "./memory/",
  surfaces: "./surfaces/",

  hints: {
    isolation: "microvm",
    capabilities: {
      shell: true,
      network: {
        mode: "restricted",
        allowlist: ["api.anthropic.com", "api.github.com"],
      },
      filesystem: {
        workspace: "/workspace",
        writable: ["/workspace"],
        denyRead: ["**/.env", "**/*credentials*"],
      },
    },
  },

  secrets: [
    { key: "ANTHROPIC_API_KEY", required: true, kind: "api-key" },
    { key: "GITHUB_TOKEN", required: true, kind: "token" },
    { key: "SLACK_WEBHOOK", required: false, kind: "url" },
  ],

  packages: [
    "ghcr.io/myorg/packages/github-workflow:2.0.0",
    "ghcr.io/myorg/packages/org-standards@sha256:0123456789abcdef...",
    "./packages/local-team-overrides",
  ],
});

Identity Fields

FieldTypeRequiredDescription
namestringYesAgent identifier. Must match ^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$
versionstringYesValid semver version
descriptionstringYesHuman-readable description
authorstringNoAuthor or organization
licensestringNoSPDX license identifier
urlstringNoProject URL
tagsstring[]NoUnique, case-sensitive tags

Layer Source Paths

These fields point to the files or directories that define each layer of your agent.

FieldPoints toDescription
personaFilePersona definition (definePersona())
promptFileSystem prompt (Markdown)
mcpFileMCP server configuration
subagentsFileSubagent definitions
skillsDirectorySkill definitions
rulesDirectoryRule files
knowledgeDirectoryKnowledge documents
memoryDirectoryMemory files
surfacesDirectorySurface files for exact runtime materialization
instructionTreeDirectoryInstruction tree files

Path Resolution

All paths are resolved relative to agent.ts. Missing optional paths cause a validation error if explicitly declared.

Adapter

The adapter field declares the intended runtime for your agent. Adapters are provided as typed functions from adapter packages (e.g., @stax/claude-code).

adapter-config.ts
adapter: claudeCode({
  model: "claude-opus-4-1",
  modelParams: { temperature: 0.3 },
}),

You can also provide adapterFallback as an array of alternate adapter configs in descending preference order. If the primary adapter is not compatible with a consumer, fallbacks are tried in order.

Runtime Hints

Hints communicate non-binding runtime requirements to consumers.

hints-config.ts
hints: {
  isolation: "process" | "container" | "gvisor" | "microvm",
  capabilities: {
    shell: boolean,
    processes: boolean,
    docker: boolean,
    network: { mode: "none" | "restricted" | "full", allowlist: string[] },
    filesystem: { workspace: string, writable: string[], denyRead: string[] },
  },
}

Secrets

Declare secrets your agent needs at runtime. Values are never stored in the artifact.

secrets-config.ts
secrets: [
  { key: "ANTHROPIC_API_KEY", required: true, kind: "api-key" },
  { key: "GITHUB_TOKEN", required: true, kind: "token" },
  { key: "SLACK_WEBHOOK", required: false, kind: "url" },
];

Security

Secret values are never stored in the artifact. Only declarations (key names, kinds, and requirements) are included. The runtime or consumer is responsible for resolving actual secret values.

Available kinds: api-key, token, password, certificate, connection-string, url, opaque.

You can control how secrets are exposed using exposeAs:

{ key: "DB_PASSWORD", required: true, kind: "password", exposeAs: { env: "DATABASE_PASSWORD" } }

Package References

Each entry in packages must be one of:

  • A relative local path: ./packages/local-overrides
  • An OCI reference with an explicit tag: ghcr.io/myorg/packages/github-workflow:2.0.0
  • An OCI digest reference: ghcr.io/myorg/packages/org-standards@sha256:0123...

Pinned References

Semver ranges and floating selectors like latest should not be used in committed manifests. The builder resolves them into stax.lock.

Workspace Sources

Declare shared repository or workspace dependencies that consumers should make available.

workspace-sources.ts
workspaceSources: [
  {
    id: "backend-repo",
    ref: "ghcr.io/myorg/sources/backend@sha256:abcdef123456...",
    mountPath: "/workspace/backend",
    writable: true,
    required: true,
  },
];

Each entry must have a unique id, reference an OCI source artifact by digest or exact tag, and specify an absolute mountPath.

Directory Structure

agent.ts
SYSTEM_PROMPT.md
persona.ts
mcp-servers.ts
_base.ts
maya-chen.ts
alex-rivera.ts
instructions.md
persona.md
tools.md
.staxignore
stax.lock

On this page