Agent manifest (kind: Agent)¶
Package: mas-runtime · Schema: agent.schema.yaml · apiVersion: mas/v1
An agent manifest (agent.yaml) declares one LLM actor: tools, skills, design
pattern, governance/control, and observability settings. A MAS manifest references one or
more agents; overlays patch agents without duplicating the base file.
Terms: glossary.md · Hub: README.md.
Top-level fields¶
Every manifest starts with four required top-level fields.
| Field | Type | Required | Description |
|---|---|---|---|
apiVersion |
string |
yes | Must be mas/v1. |
kind |
string |
yes | Must be Agent. |
metadata |
object | yes | Identity and tagging. See metadata fields. |
spec |
object | yes | Runtime behaviour. See spec fields. |
Extension properties (x-*) are allowed at the top level and are ignored by the runtime (they carry UI metadata, canvas state, etc.).
Minimal example:
apiVersion: mas/v1
kind: Agent
metadata:
name: broker
spec:
description: "Broker agent. Routes requests to specialists."
metadata fields¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
yes | — | Agent ID — must match the workflow node id that references this agent. |
description |
string |
no | "" |
Human-readable description of this agent. |
version |
string |
no | "0.1.0" |
Semver string (major.minor.patch). |
tags |
string[] |
no | [] |
Free-form tags for filtering and grouping. |
Extension properties (x-*) are allowed and ignored by the runtime.
spec fields¶
spec.description is the only required field.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
description |
string |
yes | — | Routing-facing one-liner for delegation tools, AgentCard, and registry discovery. Written from the delegator's perspective. Not injected into the LLM system prompt — use context.* for prompt text. |
context |
object |
no | — | Named chunks injected into the system prompt. Keys are author-defined (role, intent, …). See ContextChunk. |
params |
object |
no | {} |
Free-form string key/value params forwarded to infra middleware — not consumed by the kernel. |
models |
ModelEntry[] |
no | [] |
Preferred models for this agent. See ModelEntry. |
design_pattern |
object | null | no | react |
Reasoning strategy. See DesignPattern. |
context_manager |
object | no | summarising |
Context window management. See ContextManager. |
assembler |
string | object | null | no | assembler |
Builds the LLM messages[] from context. |
memory_seed |
MemorySeedEntry[] |
no | — | Documents to pre-index into memory at startup. See MemorySeedEntry. |
memory |
string | string[] | object | no | — | Memory backend configuration. See MemoryConfig. |
working_memory |
object | no | — | Cross-turn history persistence for delegated agents. See WorkingMemory. |
checkpoint |
object | no | {mode: none} |
Session checkpoint cadence, retention, portability and automatic resume. See checkpoint.md. |
skills |
string[] |
no | [] |
Skills to activate. Name-only or @library/name. Resolution: app-local → libraries → packages. |
tools_ref |
string | null |
no | null |
Logical tool-set name resolved by the infra ToolRegistry (e.g. web-tools). No paths or extensions. |
tools |
Tool[] |
no | [] |
Per-agent tool declarations — three forms. Additive with tools_ref. See Tool. |
behavior |
object | no | — | Runtime capability flags. See Behavior. |
governance |
GovernanceBinding |
no | {} |
Governance plugin list. See GovernanceBinding. |
hitl_contract |
string |
no | registry |
Human-approval Protocol plugin. An explicit InstantiationOptions.hitl_contract instance overrides this binding, preserving interactive CLI adapters. |
user_io_contract |
string |
no | registry |
User progress-update Protocol plugin. Overridden the same way as hitl_contract. |
llm |
LlmBinding |
no | {} |
Engine overrides (model, temperature, …). See LlmBinding. |
budget |
object | no | {} |
Call-count ceilings (max_llm_calls, max_tool_calls) enforced by the engine. Omitted = no limit. See Budget. |
control |
ControlBinding |
no | {} |
Control-plane plugin configs. See ControlBinding. |
observability |
ObservabilityBinding |
no | null |
Observability sink plugin list. See ObservabilityBinding. |
context_sources |
ContextSourcesBinding |
no | null |
Context source plugins, including the skill-engine backend. |
Sub-schemas¶
Assembler¶
Used by: spec.assembler
The schema accepts a plugin-name string, null, or an object with type or
ref. Its optional params object is plugin-specific and currently defines
token_budget, always_reassemble, and emit_segments.
ContextSourcesBinding¶
Used by: spec.context_sources
An ordered list of context-source plugin ids (native, adk, or langchain).
An entry may be a bare id or a single-key object with base_dir,
auto_inject, pin_activated, allow_unload, and auto_load options.
auto_inject and allow_unload default to false. allow_unload is off
because activate_skill(name, unload=true) is not in the Agent Skills spec.
ContextChunk¶
Used by: spec.context.<key>
Each value under spec.context is a named chunk injected into the system prompt under [key]. Two forms:
| Form | Type | Description |
|---|---|---|
| Inline string | string |
Injected as literal text, unless the value resolves to an existing file path (e.g. prompts/role.md or ./prompts/role.md). |
| File reference | { ref: string } |
Always loads the file at ref. Raises ContextRefNotFoundError at bootstrap when the path is missing. |
Example:
context:
role: |
You are a telemetry analyst…
intent:
ref: "./prompts/intent.md"
ModelEntry¶
Used by: spec.models[]
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
model |
string |
yes | — | LiteLLM-style model string, e.g. vertex_ai/gemini-3-pro-preview. |
id |
string |
no | "main" |
Logical model ID within this agent. Use main for the primary model. |
temperature |
number [0.0–2.0] |
no | 0.7 |
Sampling temperature. |
max_tokens |
integer ≥ 1 |
no | unset | Output-token budget; omitted means no limit is sent. |
max_completion_tokens |
integer ≥ 1 |
no | unset | Explicit answer + reasoning cap; the request never carries both token-limit fields. |
on_truncation |
string or object | no | warn |
Action when the provider returns finish_reason: length; see Output-token limits. |
context_window |
integer ≥ 1 |
no | — | Input context-window size used for model-aware assembly. |
Do not put api_base or api_key_env here — those belong in the flavour/infra manifest.
Example:
models:
- model: vertex_ai/gemini-3-pro-preview
temperature: 0.3
max_tokens: 4096
Output-token limits¶
By default, requests send neither max_tokens nor max_completion_tokens; the
provider's server default applies. A configured budget is lowered per call so
the estimated prompt plus completion fits context_window. The effective cap
is also bounded by the lower of infra spec.models.generation.max_output_tokens
and the model catalog's max_output_tokens.
| Setting | Meaning |
|---|---|
max_tokens |
Output budget; reasoning models may map it to max_completion_tokens. |
max_completion_tokens |
Explicit answer + reasoning budget; takes precedence over max_tokens. |
on_truncation |
ignore, warn (default), error, or escalate. Object form accepts factor (default 2), max_tokens, and retries (default 1). Retries count against spec.budget.max_llm_calls. |
The CLI alias expands to agent:spec.models[*].max_tokens=N; for example,
mas-ctl chat agent.yaml --max-tokens 4096 is equivalent to
--override 'agent:spec.models[*].max_tokens=4096'. Explicit --override
arguments are applied afterward. Environment variables
MAS_LLM_MAX_TOKENS, MAS_LLM_MAX_COMPLETION_TOKENS, and
MAS_LLM_ON_TRUNCATION fill in settings not declared on the model row.
LLM traces include finish_reason, the final max_tokens budget, completion
token usage, and truncation_retries. See also infra.md — LLM output-token
policy and CLI overrides.
DesignPattern¶
Used by: spec.design_pattern
Selects the agent's reasoning strategy (defaults to react when absent).
| Field | Type | Required | Description |
|---|---|---|---|
type |
string |
mutually exclusive with ref |
Builtin shorthand: react | cot | cot_native | plan_execute | tree_of_thoughts | accumulator and role aliases. |
ref |
string |
mutually exclusive with type |
Unified plugin locator — bare name, ./local/path, module://pkg.Class, or oci://registry/img:tag. |
params |
object |
no | Plugin-specific parameters. |
config |
object |
no | Alias for params (overlay compatibility). |
Example:
design_pattern:
type: react
# or a custom plugin:
design_pattern:
ref: module://my_pkg.patterns.MyCoT
params:
max_steps: 10
ContextManager¶
Used by: spec.context_manager
Controls context window management strategy (defaults to summarising).
| Field | Type | Required | Description |
|---|---|---|---|
type |
string |
mutually exclusive with ref |
Builtin: stack | sliding-window | summarising | full-history. |
ref |
string |
mutually exclusive with type |
Plugin locator — same forms as design_pattern.ref. |
params |
ContextManagerParams |
no | Strategy-specific parameters. See ContextManagerParams. |
memory |
string[] |
no | Memory types whose content is auto-injected into the system prompt as context facets, e.g. [semantic]. |
Example:
context_manager:
type: sliding-window
params:
window_size: 20
ContextManagerParams¶
Used by: spec.context_manager.params
Constructor kwargs forwarded to the ContextManagerPlugin. All fields are optional.
| Field | Type | Description |
|---|---|---|
max_turns |
integer ≥ 1 |
Sliding-window — maximum prior user turns; alias for keep_turns. |
window_size |
integer ≥ 1 |
Sliding-window — alias for keep_turns. |
max_messages |
integer ≥ 1 |
Stack context manager — cap on total past messages. |
summary_threshold |
integer ≥ 0 |
Summarising — token estimate that triggers compaction; 0 uses the derived model context window. |
keep_turns |
integer ≥ 1, default 10 |
Summarising — recent user turns kept verbatim. |
hysteresis_ratio |
number [0–1], default 0.1 |
Summarising — reuse the cached summary until near the safety-bounded hard budget. |
summarizer |
string | object | Sub-plugin: llm or drop; object form can set model and instructions. |
working_memory_messages |
integer ≥ 1, default 20 |
Assembly cap on in-turn working-memory messages. |
max_in_turn_messages |
integer ≥ 1 |
Alias for working_memory_messages. |
trimmer |
object | Assembly-time token trimming; accepts max_tokens/token_budget, reserve_tokens, and safety_margin_ratio. |
working_memory_ref |
string |
no |
Nested trimmer and summarizer keys are defined in the
context-manager parameter schemas.
MemorySeedEntry¶
Used by: spec.memory_seed[]
Pre-indexes a document into the memory backend at startup. Useful for demos and tests that need pre-populated memory without a persistent store.
| Field | Type | Required | Description |
|---|---|---|---|
content |
string |
yes | Document text to index. |
key |
string |
no | Lookup key. |
source |
string |
no | Source label / filename. |
id |
string |
no | Explicit document ID. |
text |
string |
no | Alias for content. |
Example:
memory_seed:
- source: "runbook.md"
content: |
## Restart procedure
1. Drain traffic…
MemoryConfig¶
Used by: spec.memory
Three forms are accepted:
| Form | Example | Description |
|---|---|---|
| String shorthand | memory: semantic |
Resolves to the corresponding plugin bundle. |
| Array shorthand | memory: [semantic, episodic] |
Activates multiple named bundles. |
| Object form | memory: {enabled: true, types: [...]} |
Full configuration — described below. |
Object form fields:
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Master switch — false loads no memory plugins. |
types |
MemoryType[] |
[] |
Ordered list of memory layers. See MemoryType. |
persistence |
object | — | Session transcript persistence. See MemoryPersistence. |
search |
object | — | Semantic retrieval configuration. See MemorySearch. |
citations |
object | — | Citation formatting for search results. See MemoryCitations. |
sync |
object | — | File-watching and re-indexing policy. See MemorySync. |
overflow_retry |
object | — | Compaction retry on context overflow. See MemoryOverflowRetry. |
qmd |
object | — | QMD (Qualitative Memory Database) backend. See MemoryQMD. |
MemoryType¶
Used by: spec.memory.types[]
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
yes | — | Layer name: session | episodic | semantic | working | procedural. |
backend |
string |
no | "in-memory" |
Backend: in-memory | file | sqlite-vec | redis | remote_tool. |
params |
MemoryBackendParams |
no | {} |
Backend constructor kwargs. See MemoryBackendParams. |
MemoryBackendParams¶
Used by: spec.memory.types[].params
| Field | Type | Description |
|---|---|---|
path |
string |
Filesystem path (file backend). |
url |
string |
Connection URL (redis, remote_tool). |
collection |
string |
Collection / table name. |
host |
string |
Hostname. |
port |
integer |
Port number. |
database |
string |
Database name. |
MemoryPersistence¶
Used by: spec.memory.persistence
| Field | Type | Default | Description |
|---|---|---|---|
backend |
string |
"none" |
none | file | sqlite | redis. |
path |
string |
"" |
Base directory. Supports {agent_id} and {session_id} placeholders. Default: $XDG_DATA_HOME/mas/agents/{agent_id}/sessions/. |
auto_save |
boolean |
true |
Persist after each turn. |
auto_load |
boolean |
true |
Load session on bootstrap. |
MemorySearch¶
Used by: spec.memory.search
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable semantic search injection into context. |
max_results |
integer |
6 |
Maximum retrieved chunks per query. |
min_score |
number |
0.35 |
Minimum similarity score threshold. |
chunking.tokens |
integer |
400 |
Chunk size in tokens for indexing. |
chunking.overlap |
integer |
80 |
Overlap tokens between chunks. |
hybrid.enabled |
boolean |
true |
Enable hybrid search (vector + full-text). |
hybrid.vector_weight |
number |
0.7 |
Vector score weight in hybrid ranking. |
hybrid.text_weight |
number |
0.3 |
Full-text score weight in hybrid ranking. |
hybrid.mmr_enabled |
boolean |
false |
Max Marginal Relevance re-ranking. |
hybrid.mmr_lambda |
number |
0.7 |
MMR lambda (diversity vs relevance). |
hybrid.temporal_decay_enabled |
boolean |
false |
Apply time-decay to scores. |
hybrid.temporal_decay_half_life_days |
integer |
30 |
Half-life for temporal decay. |
cache.enabled |
boolean |
true |
Cache search results. |
cache.max_entries |
integer |
128 |
Maximum cached search results. |
MemoryCitations¶
Used by: spec.memory.citations
| Field | Type | Default | Description |
|---|---|---|---|
mode |
"auto" | "on" | "off" |
"auto" |
Citation mode: auto (include when useful), on (always), off (strip source info). |
max_snippet_chars |
integer |
700 |
Maximum characters per search result snippet. |
MemorySync¶
Used by: spec.memory.sync
Controls when workspace memory files (MEMORY.md, memory/*.md) are re-indexed.
| Field | Type | Default | Description |
|---|---|---|---|
on_session_start |
boolean |
true |
Re-index when a session begins. |
on_search |
boolean |
false |
Re-index before each search. |
interval_seconds |
integer |
300 |
Periodic re-index interval in seconds (0 = disabled). |
delta_messages |
integer |
50 |
Re-index after this many new messages. |
delta_bytes |
integer |
100000 |
Re-index after this many bytes of new content. |
post_compaction_force |
boolean |
true |
Force re-index after compaction. |
file_watch.enabled |
boolean |
true |
Enable file change detection. |
file_watch.patterns |
string[] |
["MEMORY.md","memory/*.md"] |
Glob patterns to watch. |
file_watch.debounce_ms |
integer |
1500 |
Debounce interval for file change events. |
MemoryOverflowRetry¶
Used by: spec.memory.overflow_retry
When an LLM call fails because the context exceeds the window, automatically compact and retry.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable overflow detection and retry. |
max_retries |
integer |
2 |
Maximum compaction + retry attempts. |
aggregate_timeout_seconds |
number |
60.0 |
Maximum total time across all retries. |
budget_reduction_factor |
number |
0.7 |
Multiply token budget by this factor on each retry. |
MemoryQMD¶
Used by: spec.memory.qmd
Alternative search via external qmd binary (Qualitative Memory Database).
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable QMD as a retriever backend. |
binary_path |
string |
"" |
Path to qmd binary (auto-detected if empty). |
index_path |
string |
"" |
Path to QMD index directory. |
search_mode |
string |
"search" |
QMD search mode. |
max_snippet_chars |
integer |
700 |
Maximum characters per snippet. |
timeout_seconds |
number |
4.0 |
Search timeout in seconds. |
WorkingMemory¶
Used by: spec.working_memory
Controls whether a delegated agent's committed conversation history (user/assistant turns) survives across separate delegation calls within the same mas-ctl session, keyed by (session_id, agent_id).
Distinct from spec.memory: that's the MemoryContract retrieval-store subsystem (semantic/episodic/procedural search); this is the raw turn buffer a delegated agent falls back on.
| Field | Type | Default | Description |
|---|---|---|---|
persistent |
boolean |
true |
true: reuse committed turn history across delegate calls within the same session. false: clear working memory before every delegate call — for agents that must be stateless per call (e.g. a formatter or translator). |
compaction |
WorkingMemoryCompaction |
— | How much history to keep as it grows. See WorkingMemoryCompaction. Facade over spec.context_manager — set context_manager directly instead for lower-level control (takes precedence if both are set). |
Context ID: the delegating agent may pass context_id alongside task on a delegate_to_<agent_id> call to select an independent working-memory bucket for that peer (e.g. "trip-paris" vs "trip-tokyo" within one session). Omit it to use the session's default bucket.
WorkingMemoryCompaction¶
Used by: spec.working_memory.compaction
| Field | Type | Default | Description |
|---|---|---|---|
strategy |
"keep_recent" | "sliding_window" | "summarize" |
"keep_recent" |
Compaction strategy (see below). |
max_messages |
integer ≥ 1 |
— | keep_recent — cap on total committed messages. |
window_size |
integer ≥ 1 |
— | sliding_window — number of recent exchange pairs to keep. |
summary_threshold |
integer ≥ 1 |
4000 |
summarize — estimated-token threshold before compaction triggers. |
keep_turns |
integer ≥ 1 |
10 |
summarize — recent exchange pairs kept verbatim alongside the summary. |
Strategies:
keep_recent— cap total messages atmax_messages, no LLM call.sliding_window— keep the lastwindow_sizeexchange pairs, no LLM call.summarize— compress older turns into one summary block via this agent's own model, keepingkeep_turnsrecent pairs verbatim. Degrades tokeep_recentwhen no live model is available.
Example:
working_memory:
persistent: true
compaction:
strategy: summarize
summary_threshold: 4000
keep_turns: 10
Tool¶
Used by: spec.tools[]
Three forms are accepted. All are additive with tools_ref.
Form A — manifest reference (recommended)¶
References a kind: Tool manifest file or a ToolBundle entry.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
ref |
string |
yes | — | Path to a kind: Tool manifest (./tools/calc.tool.yaml) or a ToolBundle entry (bundle://web-tools/fetch-page). |
priority |
integer |
no | 100 |
Registration priority (higher = loaded first). |
params |
object |
no | {} |
Init kwargs merged into the referenced tool's spec.impl.params. |
Form B — inline anonymous¶
Inline declaration for a Python class, remote tool, or OpenAPI endpoint.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
module_path |
string |
yes | — | Dotted Python module path or relative file path (./tools/my_tool.py). |
kind |
"python" | "remote_tool" | "openapi" |
no | "python" |
Implementation kind. |
class_name |
string |
no | — | Class name in the module. Auto-discovered when omitted. |
priority |
integer |
no | 100 |
Registration priority. |
params |
object |
no | {} |
Optional tool-specific init params. |
Form C — semantic name¶
A bare string resolved by the active infra/local tool catalog (e.g. web-search, calculator, memory-search).
Example:
tools:
- ref: ./tools/calculator.tool.yaml # Form A
- module_path: library-samples/tools/calc.py # Form B
class_name: CalcTool
- web-search # Form C
Behavior¶
Used by: spec.behavior
Structural/semantic flags that affect which system tools and capabilities are exposed to the agent's LLM at runtime.
| Field | Type | Default | Description |
|---|---|---|---|
share_reasoning |
boolean |
false |
When true, the send_to_caller tool exposes an optional reasoning_context parameter. The sub-agent may provide a concise summary of HOW it reached its answer (key evidence, decision points, confidence signals), forwarded to the orchestrator as result["reasoning"]. Enable only for trusted internal agents where context leakage is acceptable. |
delegation_style |
"typed" |
"typed" |
Controls which delegation tools are registered. typed: delegate_to_<id> tools derived from the MAS workflow. |
GovernanceBinding¶
Used by: spec.governance
Ordered plugin chain (BLOCK stops; ALLOW continues). Full page:
governance.md. Retry / circuit / error_policy defaults:
reliability.md.
Each entry is a bare plugin id or a single-key config object.
error_recovery_plugin is YAML sugar that installs that plugin on the
ingress chain (one classifier). error_policy is that plugin's
config — the kernel only applies the returned GovernanceAction.
governance:
- gov_no_undeclared_tool
- retry_on_error:
error_recovery_plugin: retry_on_error
error_policy:
transient: retry
fatal: block
LlmBinding¶
Used by: spec.llm
EngineContract / LiveLlmEngine overrides. These complement spec.models[] — prefer models for per-agent routing and use llm for env-level or overlay-level adjustments.
| Field | Type | Description |
|---|---|---|
model |
string |
LiteLLM-style model string override. |
provider |
string |
Engine provider hint (mock, openai, azure, …). |
temperature |
number [0–2] |
Sampling temperature override. |
max_tokens |
integer ≥ 1 |
Maximum output tokens override. |
Example:
llm:
provider: mock
Budget¶
Used by: spec.budget
Call-count ceilings enforced by the runtime engine (LiveLlmEngine /
BudgetTracker) during a run. Omit a field, or the whole object, for
no limit — this is the default. Typically left unset on the agent
manifest and set via an overlay instead (see
with-hardened) rather
than hardcoded per-agent. Distinct from spec.control.budget (token/cost
accounting — see ControlBinding — which is not yet
read by the engine).
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
max_llm_calls |
integer ≥ 0 |
no | unset | Maximum LLM calls allowed in a run. |
max_tool_calls |
integer ≥ 0 |
no | unset | Maximum tool calls allowed in a run. |
Example:
budget:
max_llm_calls: 50
max_tool_calls: 100
ControlBinding¶
Used by: spec.control
Control-plane knobs. retry is applied by the runtime reliability
layer (LLM HTTP + tool dispatch). circuit_breaker loads a library
plugin (default threshold). budget and rate_limiter remain plugin
configs. Set a key to null to disable. Full tables:
reliability.md.
| Key | Fields | Description |
|---|---|---|
budget |
max_tokens: integer, max_cost_usd: number |
Token or cost budget enforcement. |
retry |
llm / tools: max_attempts, backoff_s, backoff_multiplier, jitter, retry_on, require_idempotent, max_backoff_s |
Infra re-issue budget. LLM default 4 attempts on transient+unavailable (429/5xx, timeout, connect-refused); tools 2 attempts on transient+unavailable when idempotent. |
circuit_breaker |
plugin, enabled, failure_threshold, reset_timeout_s, on |
Off unless this key is present. Loads the threshold circuit-breaker plugin. |
rate_limiter |
requests_per_minute: integer |
Limit LLM call rate. |
Example:
control:
budget:
max_tokens: 50000
retry:
llm:
max_attempts: 4
retry_on: [transient, unavailable]
circuit_breaker:
failure_threshold: 5
reset_timeout_s: 30
"on": [unavailable]
rate_limiter:
requests_per_minute: 30
error_policy and error_recovery_plugin live on a governance stanza,
not under control — see reliability.md.
ObservabilityBinding¶
Used by: spec.observability
An ordered list of observability sink plugin ids. OSS sinks: native, otel.
Each entry is either a bare plugin id or a single-key config object:
observability:
- native # bare id — defaults
- native: # with config
path: ./traces
events_file: events.jsonl
- otel:
output_path: ./otel-traces
otel_file: spans.json
Unknown plugin ids fail at load time. Extended sinks (observe_sdk, etc.) are internal-only.
Schema source¶
# From installed package
python -c "from mas.lab.schemas.paths import runtime_schema_dir; print(runtime_schema_dir() / 'agent.schema.yaml')"
# From Web UI / controller (default port 8090)
curl http://localhost:8090/api/schemas/agent
See also¶
- Governance — chain and plugins (
spec.governance) - Reliability — retries, circuit breaker, defaults, logging
- MAS manifest — topology, transport, and delegation
- Overlay manifest — overrides
- Tutorial: building an agent
- Design patterns —
spec.design_patternon agents