## Configuration !!! adr "Architecture Decision" The configuration system design principles, YAML-first approach, and config file conventions are defined in [ADR-024: Configuration System](adr/ADR-024-configuration-system.md). This section provides a complete reference for the YAML configuration files used to define the major configurable objects in CleverAgents: **Actors**, **Skills**, **Tools**, **Actions**, **Resource Types**, **Context Views**, and **Automation Profiles**. Projects are created via CLI commands rather than standalone configuration files, but their context views are configured through YAML and are documented here as well. It also documents the global configuration keys that control system-wide behavior. ### Global Configuration Keys !!! adr "Architecture Decision" Global configuration keys, hierarchical key structure, and config precedence are defined in [ADR-024: Configuration System](adr/ADR-024-configuration-system.md). Global configuration keys control system-wide defaults and behavior. They are stored in the global configuration file (default: `~/.cleveragents/config.toml`) and managed via the `agents config set`, `agents config get`, and `agents config list` commands. #### Hierarchical Key Structure Configuration keys use **dot-separated hierarchical names**, similar to `git config`. Each dot introduces a level of nesting, grouping related keys under a common parent. For example:
core.format # top-level "core" group, "format" key
core.log.level # "core" group, "log" subgroup, "level" key
index.text.backend # "index" group, "text" subgroup, "backend" key
$ agents config set core.format table
$ agents config get plan.budget.per-plan
$ agents config list plan.*
# Inline dot notation (convenient for single keys)
index.text.backend = "tantivy"
# Or as nested TOML tables (better for groups)
[index.text]
backend = "tantivy"
[index.vector]
backend = "faiss"
# Set a global default
$ agents config set core.automation-profile trusted
# Override for a specific project — same key, scoped to the project
$ agents config set core.automation-profile manual --project local/production-api
# Project-scoped keys under any group work the same way
$ agents config set plan.budget.per-plan 2.00 --project local/production-api
$ agents config set sandbox.strategy git_worktree --project local/production-api
$ agents config set context.hot.max-tokens 32000 --project local/large-codebase
# Show the full resolution chain for a single key
$ agents config get sandbox.checkpoint.enabled
# List all keys in a group
$ agents config list index.*
# List all keys with their current effective values
$ agents config list
# ~/.cleveragents/config.toml
[core]
data-dir = "/home/alex/.cleveragents"
format = "rich"
namespace = "local"
automation-profile = "supervised"
[core.log]
level = "FATAL"
terminal = "auto"
terminal-stream = "stderr"
file-enabled = true
retention-days = 30
[core.backup]
retention-days = 7
[server]
# url = "https://agents.example.com"
# token = "tok_01HXR..."
[actor.default]
strategy = "local/strategist"
execution = "local/executor"
invariant = "local/invariant-resolver"
# estimation = "local/estimator"
# orchestrator = "local/orchestrator"
[plan]
concurrency = 4
max-child-depth = 5
[plan.budget]
per-plan = 5.00
per-session = 25.00
warn-threshold = 0.8
[plan.tool]
max-calls-per-step = 25
max-retries = 3
retry-backoff = "exponential"
[sandbox]
strategy = "git_worktree"
cleanup = "on_apply"
[sandbox.checkpoint]
enabled = true
max-per-plan = 50
[index.text]
backend = "tantivy"
[index.vector]
backend = "faiss"
[index.graph]
backend = "none"
[index.embedding]
provider = "openai"
model = "text-embedding-3-small"
[context.hot]
max-tokens = 16000
[context.warm]
max-decisions = 100
[context.cold]
max-decisions = 500
[context.query]
limit = 20
min-relevance = 0.3
[context.file]
max-size = 1048576
max-total-size = 52428800
[context.summarize]
enabled = true
max-tokens = 1000
# Provider keys — prefer environment variables for secrets
[provider.openai]
# api-key = "sk-..."
[provider.anthropic]
# api-key = "sk-ant-..."
# Project-scoped overrides
[project."local/production-api"]
"core.automation-profile" = "manual"
"plan.budget.per-plan" = 2.00
"sandbox.strategy" = "git_worktree"
"sandbox.checkpoint.enabled" = true
[project."local/docs"]
"core.automation-profile" = "auto"
"plan.budget.per-plan" = 10.00
"context.hot.max-tokens" = 32000
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/actor-config.json",
"title": "CleverAgents Actor Configuration",
"description": "Configuration file schema for defining CleverAgents actors — intelligent agents composed of LLMs, tools, and graph topologies.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z0-9_-]+/[a-z0-9_-]+$",
"description": "Namespaced actor name in <namespace>/<name> format (e.g., 'local/reviewer', 'myorg/deploy-agent'). Required. When the actor is added via the CLI, this value is used as the registered name."
},
"cleveragents": {
"type": "object",
"description": "Metadata block containing schema version, logging, template engine, and safety settings.",
"properties": {
"version": {
"type": "string",
"description": "Schema version for this configuration file.",
"default": "3.0"
},
"logging": {
"type": "object",
"properties": {
"level": {
"type": "string",
"enum": ["DEBUG", "INFO", "WARNING", "ERROR"],
"default": "INFO",
"description": "Logging level."
}
},
"additionalProperties": false
},
"template_engine": {
"type": "string",
"enum": ["JINJA2", "NONE"],
"default": "JINJA2",
"description": "Template engine for string interpolation."
},
"unsafe": {
"type": "boolean",
"default": false,
"description": "When true, allows actors to perform operations flagged as unsafe. Requires --unsafe CLI flag."
},
"default_actor": {
"type": "string",
"description": "Name of the default actor when multiple actors are defined."
}
},
"additionalProperties": false
},
"actors": {
"$ref": "#/$defs/actorMap"
},
"agents": {
"$ref": "#/$defs/actorMap",
"description": "Alias for 'actors'. Both keys are accepted; use one or the other."
},
"routes": {
"type": "object",
"description": "Map of route names to their definitions. Routes connect actors via stream or graph topologies.",
"additionalProperties": {
"$ref": "#/$defs/route"
}
},
"merges": {
"type": "array",
"description": "Stream merge operations combining multiple streams into one.",
"items": {
"type": "object",
"properties": {
"sources": {
"type": "array",
"items": { "type": "string" },
"description": "Source stream names to merge."
},
"target": {
"type": "string",
"description": "Target stream name for merged output."
}
},
"required": ["sources", "target"],
"additionalProperties": false
}
},
"splits": {
"type": "array",
"description": "Stream split operations dividing one stream into multiple.",
"items": {
"type": "object",
"properties": {
"source": {
"type": "string",
"description": "Source stream name to split."
},
"targets": {
"type": "array",
"items": { "type": "string" },
"description": "Target stream names for split output."
}
},
"required": ["source", "targets"],
"additionalProperties": false
}
},
"templates": {
"type": "object",
"description": "Reusable template definitions for Jinja2 template inheritance.",
"additionalProperties": true
},
"instances": {
"type": "object",
"description": "Instantiated templates with bound parameters.",
"additionalProperties": true
},
"global_context": {
"type": "object",
"description": "Key-value pairs available to all actors via {{ context.key }} in templates.",
"additionalProperties": true
},
"prompts": {
"type": "object",
"description": "Named prompt templates that can be referenced by actors.",
"additionalProperties": { "type": "string" }
},
"pipelines": {
"type": "object",
"description": "Hybrid pipeline definitions combining stream and graph stages.",
"additionalProperties": {
"type": "object",
"properties": {
"stages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"type": { "type": "string" },
"config": { "type": "object", "additionalProperties": true }
},
"required": ["name", "type"]
}
},
"metadata": { "type": "object", "additionalProperties": true }
},
"required": ["stages"]
}
}
},
"required": ["name"],
"oneOf": [
{ "required": ["actors"] },
{ "required": ["agents"] }
],
"additionalProperties": false,
"$defs": {
"actorMap": {
"type": "object",
"description": "Map of actor names to their definitions.",
"additionalProperties": {
"$ref": "#/$defs/actorDefinition"
}
},
"actorDefinition": {
"type": "object",
"description": "A single actor definition.",
"properties": {
"type": {
"type": "string",
"enum": ["llm", "tool"],
"description": "Actor type: 'llm' for language model actors, 'tool' for tool-based actors."
},
"config": {
"type": "object",
"description": "Actor configuration. Fields depend on actor type.",
"properties": {
"provider": {
"type": "string",
"description": "LLM provider identifier: openai, anthropic, google, azure, openrouter, etc."
},
"model": {
"type": "string",
"description": "Model identifier within the provider: gpt-4, claude-3.5-sonnet, gemini-pro, etc."
},
"actor": {
"type": "string",
"description": "Combined provider/model format (e.g., 'anthropic/claude-3.5-sonnet'). Alternative to specifying provider and model separately."
},
"system_prompt": {
"type": "string",
"description": "System prompt text. Supports Jinja2 template syntax for dynamic content."
},
"temperature": {
"type": "number",
"minimum": 0.0,
"maximum": 2.0,
"description": "Sampling temperature. Lower values are more deterministic."
},
"max_tokens": {
"type": "integer",
"minimum": 1,
"description": "Maximum number of tokens in the generated response."
},
"memory_enabled": {
"type": "boolean",
"default": false,
"description": "Enable conversation memory for multi-turn interactions."
},
"max_history": {
"type": "integer",
"default": 50,
"minimum": 1,
"description": "Maximum number of conversation turns retained in memory."
},
"unsafe": {
"type": "boolean",
"default": false,
"description": "Allow this specific actor to perform unsafe operations."
},
"options": {
"type": "object",
"description": "Provider-specific options passed through to the underlying LLM API.",
"additionalProperties": true
},
"tools": {
"type": "array",
"description": "List of inline tool definitions for tool-type actors.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Tool name."
},
"code": {
"type": "string",
"description": "Inline Python code defining the tool's behavior."
}
},
"required": ["name", "code"],
"additionalProperties": false
}
},
"response_format": {
"type": "object",
"description": "JSON schema for structured output from the LLM. When set, the model is constrained to produce output matching this schema.",
"additionalProperties": true
}
},
"additionalProperties": false
},
"skills": {
"type": "array",
"description": "List of skill names this actor can use. Each entry is a namespaced skill name (e.g., 'local/file-ops'). Skills provide tool capabilities to the actor.",
"items": { "type": "string", "pattern": "^[a-z0-9_-]+/[a-z0-9_-]+$" }
},
"lsp": {
"description": "LSP server bindings for language intelligence. Can be a list of server names (explicit), an object with languages (language-based), or an object with auto: true (resource-auto).",
"oneOf": [
{
"type": "array",
"items": { "type": "string", "pattern": "^[a-z0-9_-]+/[a-z0-9_-]+$" },
"description": "Explicit binding: list of namespaced LSP server names."
},
{
"type": "object",
"properties": {
"languages": {
"type": "array",
"items": { "type": "string" },
"description": "Language-based binding: resolve LSP servers for these languages from the registry."
},
"auto": {
"type": "boolean",
"description": "Resource-auto binding: discover languages from project resources and resolve servers automatically."
}
},
"additionalProperties": false
}
]
},
"lsp_capabilities": {
"description": "Controls which LSP capabilities are exposed as tools. When 'all' or omitted, all capabilities are available.",
"oneOf": [
{
"type": "string",
"enum": ["all"]
},
{
"type": "array",
"items": {
"type": "string",
"enum": ["diagnostics", "hover", "completions", "definitions", "references", "rename", "code_actions", "formatting", "signature_help", "document_symbols", "workspace_symbols"]
}
}
]
},
"lsp_context_enrichment": {
"type": "object",
"description": "Controls automatic LSP context enrichment (diagnostic and type info injection into ACMS context).",
"properties": {
"diagnostics": { "type": "boolean", "default": true, "description": "Auto-inject LSP diagnostics into context." },
"type_annotations": { "type": "boolean", "default": false, "description": "Auto-inject type information into context." },
"max_diagnostics_per_file": { "type": "integer", "default": 50, "minimum": 1, "description": "Maximum diagnostics per file to avoid context bloat." }
},
"additionalProperties": false
}
},
"required": ["type", "config"],
"additionalProperties": false
},
"route": {
"type": "object",
"description": "A route definition — either a stream or a graph topology.",
"properties": {
"type": {
"type": "string",
"enum": ["stream", "graph"],
"description": "Route type."
},
"stream_type": {
"type": "string",
"enum": ["cold", "hot", "replay"],
"default": "cold",
"description": "Stream type (stream routes only)."
},
"operators": {
"type": "array",
"description": "Processing operators (stream routes).",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["map", "graph_execute"],
"description": "Operator type."
},
"params": {
"type": "object",
"properties": {
"agent": { "type": "string", "description": "Actor name for map operators." },
"graph": { "type": "string", "description": "Graph route name for graph_execute operators." }
},
"additionalProperties": true
}
},
"required": ["type"]
}
},
"subscriptions": {
"type": "array",
"items": { "type": "string" },
"description": "Input stream subscriptions."
},
"publications": {
"type": "array",
"items": { "type": "string" },
"description": "Output stream publications."
},
"agents": {
"type": "array",
"items": { "type": "string" },
"description": "Actor names used by this route."
},
"initial_value": {
"description": "Initial stream value."
},
"buffer_size": {
"type": "integer",
"default": 10,
"minimum": 1,
"description": "Stream buffer size."
},
"template_config": {
"type": "object",
"description": "Template-specific configuration.",
"additionalProperties": true
},
"bridge": {
"type": "object",
"description": "Bridge configuration for stream-to-graph upgrades.",
"properties": {
"upgrade_conditions": { "type": "object", "additionalProperties": true },
"downgrade_conditions": { "type": "object", "additionalProperties": true },
"state_extractor": { "type": "string" },
"state_flattener": { "type": "string" },
"preserve_subscriptions": { "type": "boolean", "default": true },
"preserve_checkpointing": { "type": "boolean", "default": true }
},
"additionalProperties": false
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"nodes": {
"type": "object",
"description": "Graph nodes (required for graph routes).",
"additionalProperties": {
"$ref": "#/$defs/graphNode"
}
},
"edges": {
"type": "array",
"description": "Graph edges (required for graph routes).",
"items": {
"$ref": "#/$defs/graphEdge"
}
},
"entry_point": {
"type": "string",
"description": "Entry point node name (required for graph routes)."
},
"checkpointing": {
"type": "boolean",
"default": false,
"description": "Enable graph checkpointing."
},
"checkpoint_dir": {
"type": "string",
"description": "Directory for checkpoint storage."
},
"enable_time_travel": {
"type": "boolean",
"default": false,
"description": "Enable time travel debugging."
},
"parallel_execution": {
"type": "boolean",
"default": false,
"description": "Allow parallel node execution."
},
"state_class": {
"type": "string",
"description": "Custom state class name."
}
},
"required": ["type"],
"additionalProperties": false
},
"graphNode": {
"type": "object",
"description": "A graph node definition.",
"properties": {
"type": {
"type": "string",
"enum": ["agent", "function", "tool", "conditional", "subgraph", "start", "end", "message_router"],
"description": "Node type."
},
"agent": { "type": "string", "description": "Actor name for agent nodes." },
"function": { "type": "string", "description": "Function name for function nodes." },
"tools": {
"type": "array",
"items": { "type": "string" },
"description": "Tool references for tool nodes."
},
"condition": { "type": "object", "additionalProperties": true, "description": "Condition for conditional nodes." },
"subgraph": { "type": "string", "description": "Route name for subgraph nodes." },
"retry_policy": { "type": "object", "additionalProperties": true, "description": "Retry configuration." },
"timeout": { "type": "integer", "minimum": 1, "description": "Timeout in seconds." },
"parallel": { "type": "boolean", "default": false, "description": "Allow parallel execution." },
"metadata": { "type": "object", "additionalProperties": true }
},
"required": ["type"],
"additionalProperties": false
},
"graphEdge": {
"type": "object",
"description": "A graph edge connecting two nodes.",
"properties": {
"source": { "type": "string", "description": "Source node name." },
"target": { "type": "string", "description": "Target node name." },
"condition": { "type": "object", "additionalProperties": true, "description": "Edge condition for conditional routing." },
"metadata": { "type": "object", "additionalProperties": true }
},
"required": ["source", "target"],
"additionalProperties": false
}
}
}
# ─── Name ───────────────────────────────────────────────────────────
name: <namespace>/<actor-name> # Namespaced actor name (required). Used as the registered name.
# Must follow <namespace>/<name> format (e.g., local/reviewer).
# ─── Metadata ───────────────────────────────────────────────────────
cleveragents:
version: "3.0" # Schema version (optional, default: latest)
logging:
level: "INFO" # Log level: DEBUG, INFO, WARNING, ERROR (optional)
template_engine: "JINJA2" # Template engine: JINJA2 or NONE (optional, default: JINJA2)
unsafe: false # Allow unsafe operations (optional, default: false)
default_actor: <actor_name> # Default actor to use when multiple are defined (optional)
# ─── Actor Definitions ──────────────────────────────────────────────
# The top-level key can be either "actors" or "agents" (both accepted).
actors:
<actor_name>:
type: llm | tool # Actor type (required)
config:
# ── For type: llm ──────────────────────────────────────────
provider: <string> # Provider identifier: openai, anthropic, google, azure, openrouter, etc. (required for LLM)
model: <string> # Model identifier: gpt-4, claude-3.5-sonnet, etc. (required for LLM)
# OR use the combined format:
actor: "<provider>/<model>" # Combined provider/model (alternative to provider + model)
system_prompt: | # System prompt text, supports Jinja2 templates (optional)
You are a helpful assistant.
Project: {{ context.project_name }}
temperature: 0.7 # Sampling temperature 0.0-2.0 (optional, default: provider default)
max_tokens: 4096 # Maximum output tokens (optional, default: provider default)
memory_enabled: true # Enable conversation memory (optional, default: false)
max_history: 50 # Maximum conversation turns to retain (optional, default: 50)
unsafe: false # Allow unsafe operations for this actor (optional, default: false)
options: # Additional provider-specific options (optional)
top_p: 1.0
frequency_penalty: 0.0
presence_penalty: 0.0
stop_sequences: ["END"]
seed: 42
# ── For type: tool ─────────────────────────────────────────
tools:
- name: <tool_name> # Tool name (required per tool)
code: | # Inline Python code (required per tool)
def run(input_data):
return {"result": input_data["query"]}
response_format: {} # JSON schema for structured LLM output (optional, LLM only)
# ── Skills (both LLM and tool actors) ────────────────────────
skills: # Skill references providing tool capabilities (optional)
- <namespace>/<skill-name> # e.g., local/file-ops, local/git-ops
# ── LSP Binding (language intelligence for actor nodes) ─────
# Three binding modes — pick one:
# Mode 1: Explicit — list specific registered LSP servers
lsp: # LSP server binding (optional)
- <namespace>/<server-name> # e.g., local/pyright, local/typescript-language-server
# Mode 2: Language-based — runtime resolves servers from registry
# lsp:
# languages: [python, typescript]
# Mode 3: Auto-discovery — detect languages from project resources
# lsp:
# auto: true
lsp_capabilities: all # Which LSP capabilities to expose (optional, default: all)
# "all" | list of: diagnostics, hover, completions, references,
# definitions, symbols, formatting, code_actions, rename
lsp_context_enrichment: # ACMS context enrichment from LSP (optional)
diagnostics: true # Auto-inject diagnostics into code context windows
type_annotations: true # Auto-inject inferred types into code context windows
max_diagnostics_per_file: 50 # Limit diagnostics per file (default: 50)
# ─── Routes ─────────────────────────────────────────────────────────
routes:
<route_name>:
type: stream | graph # Route type (required)
# ── Stream route fields ──────────────────────────────────────
stream_type: cold | hot | replay # Stream type (optional, default: cold)
operators: # Processing operators (optional)
- type: map | graph_execute # Operator type
params: # Operator parameters
agent: <actor_name> # Actor to use (for map)
graph: <route_name> # Graph to execute (for graph_execute)
subscriptions: # Input subscriptions (optional)
- <stream_name>
publications: # Output publications (optional)
- <stream_name>
agents: # Actors used by this route (optional)
- <actor_name>
initial_value: <any> # Initial stream value (optional)
buffer_size: 10 # Stream buffer size (optional, default: 10)
template_config: {} # Template-specific configuration (optional)
bridge: # Bridge configuration for stream↔graph upgrades (optional)
upgrade_conditions: {} # Conditions to upgrade from stream to graph
downgrade_conditions: {} # Conditions to downgrade from graph to stream
state_extractor: <string> # Function to extract state during upgrade
state_flattener: <string> # Function to flatten state during downgrade
preserve_subscriptions: true # Keep subscriptions during transition (optional)
preserve_checkpointing: true # Keep checkpoints during transition (optional)
metadata: {} # Arbitrary metadata (optional)
# ── Graph route fields ───────────────────────────────────────
nodes: # Graph nodes (required for graph routes)
<node_name>:
type: agent | function | tool | conditional | subgraph | start | end | message_router
agent: <actor_name> # Actor for agent nodes
function: <function_name> # Function for function nodes
tools: # Tools for tool nodes
- <tool_ref>
condition: {} # Condition for conditional nodes
subgraph: <route_name> # Subgraph for subgraph nodes
retry_policy: {} # Retry configuration (optional)
timeout: 30 # Timeout in seconds (optional)
parallel: false # Allow parallel execution (optional)
metadata: {} # Arbitrary metadata (optional)
edges: # Graph edges (required for graph routes)
- source: <node_name> # Source node (required)
target: <node_name> # Target node (required)
condition: {} # Edge condition (optional)
metadata: {} # Arbitrary metadata (optional)
entry_point: <node_name> # Entry point node (required for graph routes)
checkpointing: false # Enable graph checkpointing (optional, default: false)
checkpoint_dir: <path> # Checkpoint directory (optional)
enable_time_travel: false # Enable time travel debugging (optional, default: false)
parallel_execution: false # Allow parallel node execution (optional, default: false)
state_class: <string> # Custom state class name (optional)
metadata: {} # Arbitrary metadata (optional)
# ─── Merges & Splits ────────────────────────────────────────────────
merges: # Stream merge definitions (optional)
- sources: # Source streams to merge
- <stream_name>
target: <stream_name> # Target stream for merged output
splits: # Stream split definitions (optional)
- source: <stream_name> # Source stream to split
targets: # Target streams for split output
- <stream_name>
# ─── Templates & Context ────────────────────────────────────────────
templates: {} # Reusable template definitions (optional)
instances: {} # Template instances (optional)
global_context: {} # Global context available to all actors (optional)
prompts: {} # Named prompt templates (optional)
# ─── Pipelines ──────────────────────────────────────────────────────
pipelines: # Hybrid pipeline definitions (optional)
<pipeline_name>:
stages:
- name: <stage_name>
type: <stage_type>
config: {}
metadata: {}
# minimal-chat.yaml
# Register: agents actor add --config minimal-chat.yaml
name: local/chat
actors:
chat:
type: llm
config:
provider: anthropic
model: claude-3.5-sonnet
system_prompt: "You are a helpful assistant."
routes:
main:
type: stream
operators:
- type: map
params:
agent: chat
publications:
- output
merges:
- sources: [output]
target: final
# code-reviewer.yaml
# Register: agents actor add --config code-reviewer.yaml
name: local/reviewer
cleveragents:
version: "3.0"
logging:
level: "INFO"
actors:
reviewer:
type: llm
config:
provider: openai
model: gpt-4
temperature: 0.2
max_tokens: 4096
system_prompt: |
You are a senior code reviewer. Analyze code for:
- Security vulnerabilities
- Performance issues
- Code style violations
- Missing error handling
Provide specific, actionable feedback with file and line references.
file_reader:
type: tool
config:
tools:
- name: read_file
code: |
def run(input_data):
path = input_data.get("path", "")
with open(path, "r") as f:
return {"content": f.read(), "path": path}
routes:
review_graph:
type: graph
nodes:
analyze:
type: agent
agent: reviewer
read:
type: tool
tools: [read_file]
report:
type: agent
agent: reviewer
edges:
- source: analyze
target: read
- source: read
target: report
- source: analyze
target: report
condition:
no_files_needed: true
entry_point: analyze
checkpointing: false
output_stream:
type: stream
operators:
- type: graph_execute
params:
graph: review_graph
publications:
- review_output
merges:
- sources: [review_output]
target: final
# research-pipeline.yaml
# Register: agents actor add --config research-pipeline.yaml --unsafe
name: local/research
cleveragents:
version: "3.0"
logging:
level: "DEBUG"
template_engine: "JINJA2"
unsafe: true
default_actor: orchestrator
actors:
orchestrator:
type: llm
config:
provider: anthropic
model: claude-3.5-sonnet
temperature: 0.7
max_tokens: 8192
memory_enabled: true
max_history: 100
system_prompt: |
You are an orchestrator managing a research pipeline for {{ context.project_name }}.
Topic: {{ context.research_topic }}
Your job is to:
1. Break down the research question into sub-questions
2. Delegate to specialist researchers
3. Synthesize findings into a coherent report
{% if context.deadline %}
Deadline: {{ context.deadline }}. Prioritize breadth over depth.
{% endif %}
researcher:
type: llm
config:
provider: openai
model: gpt-4
temperature: 0.3
max_tokens: 4096
system_prompt: |
You are a domain expert researcher. Provide thorough, factual analysis.
Always cite sources and note confidence levels.
synthesizer:
type: llm
config:
provider: anthropic
model: claude-3.5-sonnet
temperature: 0.5
max_tokens: 16384
system_prompt: |
You are an expert at synthesizing multiple research reports into coherent narratives.
Resolve contradictions, highlight consensus, and note gaps.
web_searcher:
type: tool
config:
tools:
- name: search_web
code: |
import os, json
def run(input_data):
api_key = os.environ.get("SEARCH_API_KEY", "")
query = input_data.get("query", "")
# Simulated web search
return {"results": [], "query": query}
- name: fetch_url
code: |
def run(input_data):
url = input_data.get("url", "")
return {"content": f"Content from {url}", "url": url}
routes:
research_graph:
type: graph
nodes:
plan:
type: agent
agent: orchestrator
research_parallel:
type: agent
agent: researcher
parallel: true
search:
type: tool
tools: [search_web, fetch_url]
synthesize:
type: agent
agent: synthesizer
review:
type: agent
agent: orchestrator
edges:
- source: plan
target: research_parallel
- source: plan
target: search
- source: research_parallel
target: synthesize
- source: search
target: synthesize
- source: synthesize
target: review
- source: review
target: plan
condition:
needs_more_research: true
entry_point: plan
checkpointing: true
checkpoint_dir: "${CHECKPOINT_DIR:/tmp/research_checkpoints}"
enable_time_travel: true
parallel_execution: true
progress_stream:
type: stream
stream_type: hot
operators:
- type: map
params:
agent: orchestrator
subscriptions:
- research_updates
publications:
- progress_output
buffer_size: 50
output_stream:
type: stream
operators:
- type: graph_execute
params:
graph: research_graph
publications:
- research_output
merges:
- sources: [progress_output, research_output]
target: final
global_context:
project_name: "AI Safety Research"
research_topic: "Alignment techniques in large language models"
deadline: "2026-03-01"
prompts:
deep_dive: "Provide an in-depth analysis of {topic} with at least 5 sources."
summary: "Summarize the following research in 500 words: {content}"
templates:
research_section:
template: |
## {{ section_title }}
{{ section_content }}
**Confidence:** {{ confidence_level }}
**Sources:** {{ sources | join(', ') }}
# echo-actor.yaml
# Register: agents actor add --config echo-actor.yaml
name: local/echo
cleveragents:
version: "3.0"
actors:
echo:
type: tool
config:
tools:
- name: echo_tool
code: |
def run(input_data):
message = input_data.get("content", "")
return {"response": f"Echo: {message}"}
routes:
main:
type: stream
operators:
- type: map
params:
agent: echo
publications:
- output
merges:
- sources: [output]
target: final
# classifier-router.yaml
# Register: agents actor add --config classifier-router.yaml
name: local/smart-router
actors:
classifier:
type: llm
config:
provider: openai
model: gpt-4
temperature: 0.0
max_tokens: 100
system_prompt: |
Classify the user's request into exactly one category:
CODING, WRITING, ANALYSIS, or GENERAL.
Respond with only the category name.
coding_expert:
type: llm
config:
provider: anthropic
model: claude-3.5-sonnet
temperature: 0.2
system_prompt: "You are an expert software engineer. Write clean, well-tested code."
writing_expert:
type: llm
config:
provider: openai
model: gpt-4
temperature: 0.7
system_prompt: "You are a professional writer. Produce clear, engaging prose."
analyst:
type: llm
config:
provider: anthropic
model: claude-3.5-sonnet
temperature: 0.3
system_prompt: "You are a data analyst. Provide thorough, evidence-based analysis."
generalist:
type: llm
config:
provider: openai
model: gpt-4
temperature: 0.5
system_prompt: "You are a helpful general-purpose assistant."
routes:
router_graph:
type: graph
nodes:
classify:
type: agent
agent: classifier
code:
type: agent
agent: coding_expert
write:
type: agent
agent: writing_expert
analyze:
type: agent
agent: analyst
general:
type: agent
agent: generalist
edges:
- source: classify
target: code
condition:
category: "CODING"
- source: classify
target: write
condition:
category: "WRITING"
- source: classify
target: analyze
condition:
category: "ANALYSIS"
- source: classify
target: general
condition:
category: "GENERAL"
entry_point: classify
main:
type: stream
operators:
- type: graph_execute
params:
graph: router_graph
publications:
- output
merges:
- sources: [output]
target: final
# support-bot.yaml
# Register: agents actor add --config support-bot.yaml
#
# Jinja2 preprocessing (Phase 1) resolves {{ }} and {% %} at load time.
# Phase 2: env var interpolation resolves ${VAR} after parsing.
name: local/support-bot
cleveragents:
version: "3.0"
template_engine: "JINJA2"
actors:
support:
type: llm
config:
# Phase 2: environment variables with defaults and type coercion
provider: ${LLM_PROVIDER:anthropic}
model: ${LLM_MODEL:claude-3.5-sonnet}
temperature: 0.4
max_tokens: ${MAX_TOKENS:4096} # coerced to int automatically
memory_enabled: ${ENABLE_MEMORY:true} # coerced to bool automatically
system_prompt: |
You are a {{ context.role }} for {{ context.company }}.
{% if context.tier == "enterprise" %}
This is an enterprise customer. Provide priority support with
detailed technical explanations and offer to escalate issues
to the engineering team when needed.
{% else %}
Provide friendly, concise support. Direct complex issues to
the documentation at {{ context.docs_url }}.
{% endif %}
Always respond in {{ context.language | default("English") }}.
routes:
main:
type: stream
operators:
- type: map
params:
agent: support
publications:
- output
merges:
- sources: [output]
target: final
# global_context populates the {{ context.* }} namespace at load time
global_context:
company: "Acme Corp"
role: "technical support specialist"
tier: "enterprise"
docs_url: "https://docs.acme.example.com"
# paper-writer.yaml
# Register: agents actor add --config paper-writer.yaml
#
# IMPORTANT: This file is NOT valid YAML as written. Jinja2 directives
# ({% for %}, {% if %}, {% endif %}, {% endfor %}) appear at the structural
# level — where YAML keys and list items would normally be — making the
# raw file unparseable by any YAML parser. Phase 1 (Jinja2 preprocessing)
# renders these directives into static YAML text BEFORE the YAML parser
# ever sees the file. Jinja2 syntax inside system_prompt fields is
# preserved for deferred runtime rendering.
name: local/paper-writer
cleveragents:
version: "3.0"
template_engine: "JINJA2"
logging:
level: "${LOG_LEVEL:INFO}"
unsafe: ${ALLOW_UNSAFE:false} # Phase 2: coerced to bool
default_actor: orchestrator
{# ─── Template comment: stripped from output, never reaches YAML parser ─── #}
actors:
# ── Orchestrator: uses deferred Jinja2 in system_prompt ─────────────
orchestrator:
type: llm
config:
provider: ${LLM_PROVIDER:anthropic}
model: ${PRIMARY_MODEL:claude-3.5-sonnet}
temperature: 0.7
max_tokens: ${MAX_TOKENS:8192}
memory_enabled: true
max_history: ${MAX_HISTORY:100}
system_prompt: |
You are the lead orchestrator for a research paper.
Topic: {{ context.paper_details.topic | tojson }}
Audience: {{ context.paper_details.audience | tojson }}
Max length: {{ context.paper_details.length | tojson }} words
{# ── Vetted sources: for-loop with type test, .get(), slicing ── #}
{% if context.vetted_sources and context.vetted_sources|length > 0 %}
The following {{ context.vetted_sources|length }} vetted sources:
{% for source in context.vetted_sources %}
{{ loop.index }}.
{% if source is mapping %}
{{ source.get('citation', 'Untitled') }}
{% if source.get('summary') %}
— {{ source.get('summary')[:200] }}
{% if source.get('summary')|length > 200 %}
...
{% endif %}
{% endif %}
{% else %}
{{ source }}
{% endif %}
{% endfor %}
{% else %}
No vetted sources are available yet. Begin with the discovery phase.
{% endif %}
{% if context.deadline %}
DEADLINE: {{ context.deadline }}. Prioritize accordingly.
{% endif %}
{# ── Section plan: ternary expression highlights current section ── #}
Section plan:
{% for section in context.sections %}
{% set m = ">>> " if section == context.current_section else " " %}
{{ m }}{{ loop.index }}. {{ section }}
{% endfor %}
{# ── Arithmetic in expressions ── #}
Progress: section {{ context.current_section_index + 1 }}
of {{ context.sections|length }}.
# ── Writer: deferred templates with nested conditionals ─────────────
writer:
type: llm
config:
provider: ${LLM_PROVIDER:anthropic}
model: ${PRIMARY_MODEL:claude-3.5-sonnet}
temperature: 0.5
max_tokens: 16384
system_prompt: |
You are writing section "{{ context.current_section }}" of a paper
on {{ context.paper_details.topic }}.
{% if context.section_content %}
Previous draft:
{% set sec = context.current_section %}
{{ context.section_content.get(sec, 'No prior draft.') }}
{% endif %}
{# ── Nested: loop inside conditional ── #}
{% if context.review_feedback and context.review_feedback|length > 0 %}
Reviewer feedback to address:
{% for fb in context.review_feedback %}
[{{ fb.reviewer }}] ({{ fb.severity }}): {{ fb.comment }}
{% endfor %}
{% endif %}
Format: {{ context.paper_details.get('format', 'markdown') | upper }}
# ── STRUCTURAL {% if %}: the entire assembler actor definition — its YAML
# ── key and all nested content — is conditionally included. The {% if %}
# ── and {% endif %} lines occupy positions where YAML keys would be,
# ── making this raw text invalid YAML. After Phase 1 rendering, either
# ── the full assembler: block appears or nothing does.
{% if context.enable_assembly %}
assembler:
type: llm
config:
actor: anthropic/claude-3.5-sonnet
temperature: 0.3
max_tokens: 32768
system_prompt: |
Assemble the final paper from these completed sections:
{% for path in context.sections %}
--- {{ path }} ---
{{ context.section_content.get(path, '[MISSING]') }}
{% endfor %}
Total sections: {{ context.sections|length }}
Target length: {{ context.paper_details.length }} words
{% if context.latex_errors %}
Previous compilation errors (last 2000 chars):
{{ context.latex_errors[-2000:] }}
{% endif %}
{% endif %}
# ── STRUCTURAL {% for %}: GENERATE one reviewer actor per entry in
# ── context.reviewers. The {% for %} line sits where a YAML key would
# ── be — not inside any string value. A YAML parser would reject this.
# This {% for %} runs at Phase 1 and produces static YAML actor definitions.
# With 3 reviewers in global_context, the rendered YAML contains 3 actors:
# reviewer_methods, reviewer_domain, reviewer_style.
{% for reviewer in context.reviewers %}
reviewer_{{ reviewer.id }}:
type: llm
config:
provider: {{ reviewer.get('provider', 'openai') }}
model: {{ reviewer.get('model', 'gpt-4') }}
temperature: 0.2
max_tokens: 4096
system_prompt: |
You are {{ reviewer.name }}, an expert reviewer
specializing in {{ reviewer.specialty }}.
Evaluate the paper section for:
{# ── Nested loop: iterate criteria inside reviewer loop ── #}
{% for criterion in reviewer.criteria %}
- {{ criterion }}
{% endfor %}
Severity ratings: Critical, Major, Minor, Suggestion.
{% if context.review_mode == "strict" %}
Apply strict academic standards. Flag all unsupported claims.
{% else %}
Focus on substantive issues. Ignore minor style preferences.
{% endif %}
{% endfor %}
# ── Routes: load-time loop generates graph nodes and edges ──────────
routes:
writing_graph:
type: graph
nodes:
plan:
type: agent
agent: orchestrator
draft:
type: agent
agent: writer
# STRUCTURAL {% for %}: generates review_methods, review_domain,
# review_style as concrete YAML keys — invalid YAML until rendered
{% for reviewer in context.reviewers %}
review_{{ reviewer.id }}:
type: agent
agent: reviewer_{{ reviewer.id }}
{% endfor %}
# STRUCTURAL {% if %}: the assemble node only exists when assembly
# is enabled — matches the conditional assembler actor above
{% if context.enable_assembly %}
assemble:
type: agent
agent: assembler
{% endif %}
edges:
- source: plan
target: draft
# STRUCTURAL {% for %}: generates edge sets for each reviewer.
# Contains a NESTED STRUCTURAL {% if %} — the assemble edge only
# appears when enable_assembly is true. Both directives sit where
# YAML list items would be — completely invalid YAML until rendered.
{% for reviewer in context.reviewers %}
- source: draft
target: review_{{ reviewer.id }}
- source: review_{{ reviewer.id }}
target: draft
condition:
has_critical_feedback: true
# {% if %} NESTED inside {% for %}: each reviewer gets an edge
# to assemble only when the assembler exists
{% if context.enable_assembly %}
- source: review_{{ reviewer.id }}
target: assemble
condition:
review_passed: true
{% endif %}
{% endfor %}
entry_point: plan
checkpointing: true
checkpoint_dir: "${CHECKPOINT_DIR:/tmp/paper_checkpoints}"
parallel_execution: true
output_stream:
type: stream
operators:
- type: graph_execute
params:
graph: writing_graph
publications:
- paper_output
# ── STRUCTURAL {% if %}: this entire route definition — the YAML key
# ── "progress_stream:" and all its children — only exists in the
# ── rendered output when enable_monitoring is true. A YAML parser
# ── would choke on the bare {% if %} line sitting where it expects
# ── a mapping key.
{% if context.enable_monitoring %}
progress_stream:
type: stream
stream_type: hot
operators:
- type: map
params:
agent: orchestrator
subscriptions:
- writing_updates
publications:
- progress_output
buffer_size: 50
{% endif %}
merges:
- sources:
- paper_output
# STRUCTURAL {% if %} inside a YAML list: this list item only
# appears in the rendered YAML when the condition is true.
# The raw file has a {% if %} line where a "- value" is expected.
{% if context.enable_monitoring %}
- progress_output
{% endif %}
target: final
# ── global_context: deeply nested structures drive all template rendering ──
global_context:
paper_details:
topic: "Alignment techniques in large language models"
audience: "ML researchers"
length: 8000
publication: "NeurIPS 2026"
format: "latex"
sections:
- "Abstract"
- "Introduction"
- "Related Work"
- "Methodology"
- "Experiments"
- "Results > Quantitative"
- "Results > Qualitative"
- "Discussion"
- "Conclusion"
current_section: "Introduction"
current_section_index: 1
deadline: "2026-06-01"
review_mode: "strict"
# These flags drive the structural {% if %} conditionals above.
# Set to false to exclude the assembler actor and monitoring route entirely.
enable_assembly: true
enable_monitoring: true
# The reviewers list drives the structural {% for %} loops that generate
# actor definitions, graph nodes, and graph edges at load time.
reviewers:
- id: methods
name: "Dr. Methods"
specialty: "research methodology"
provider: "openai"
model: "gpt-4"
criteria:
- "Statistical validity"
- "Reproducibility of experiments"
- "Clarity of methodology description"
- id: domain
name: "Dr. Domain"
specialty: "AI alignment"
provider: "anthropic"
model: "claude-3.5-sonnet"
criteria:
- "Technical accuracy"
- "Completeness of literature review"
- "Novelty of contributions"
- id: style
name: "Prof. Style"
specialty: "academic writing"
criteria:
- "Clarity and readability"
- "Logical flow between sections"
- "Proper citation format"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/skill-config.json",
"title": "CleverAgents Skill Configuration",
"description": "Configuration file schema for defining CleverAgents skills — reusable, namespaced collections of tools.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified skill name in <namespace>/<name> format."
},
"description": {
"type": "string",
"description": "Human-readable description of what this skill provides."
},
"tools": {
"type": "array",
"description": "References to named tools from the Tool Registry.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified name of a tool registered in the Tool Registry."
},
"description": {
"type": "string",
"description": "Override the tool's registered description within this skill context."
},
"writes": {
"type": "boolean",
"description": "Override the tool's writes capability flag."
},
"checkpointable": {
"type": "boolean",
"description": "Override the tool's checkpointable capability flag."
}
},
"required": ["name"],
"additionalProperties": false
}
},
"inline_tools": {
"type": "array",
"description": "Anonymous tool definitions that exist only within this skill. Not registered in the Tool Registry.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Tool name, unique within this skill."
},
"description": {
"type": "string",
"description": "Human-readable description of the tool's purpose."
},
"source": {
"type": "string",
"const": "custom",
"description": "Source type. Always 'custom' for inline tools."
},
"code": {
"type": "string",
"description": "Python code defining the tool's behavior. Must contain a run(input_data) function."
},
"input_schema": {
"$ref": "https://json-schema.org/draft/2020-12/schema",
"description": "JSON Schema describing the tool's input parameters."
},
"writes": {
"type": "boolean",
"default": false,
"description": "Whether this tool performs write operations."
},
"checkpointable": {
"type": "boolean",
"default": false,
"description": "Whether this tool supports checkpointing."
},
"side_effects": {
"type": "array",
"items": { "type": "string" },
"default": [],
"description": "Descriptions of side effects (e.g., 'network_call', 'schema_mutation')."
}
},
"required": ["name", "source", "code"],
"additionalProperties": false
}
},
"includes": {
"type": "array",
"description": "Other skills whose tools are merged into this skill.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified skill name to include."
},
"description": {
"type": "string",
"description": "Override the included skill's description."
}
},
"required": ["name"],
"additionalProperties": false
}
},
"mcp_servers": {
"type": "array",
"description": "MCP server specifications for exposing remote tools.",
"items": {
"$ref": "#/$defs/mcpServer"
}
},
"agent_skill_folders": {
"type": "array",
"description": "Agent Skills Standard folders to include.",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Path to the folder containing SKILL.md."
},
"name": {
"type": "string",
"description": "Override the skill bundle name."
}
},
"required": ["path"],
"additionalProperties": false
}
}
},
"required": ["name"],
"additionalProperties": false,
"$defs": {
"mcpServer": {
"type": "object",
"description": "An MCP server specification.",
"properties": {
"name": {
"type": "string",
"description": "Identifier for the MCP server."
},
"transport": {
"type": "string",
"enum": ["stdio", "sse", "streamable-http"],
"description": "Transport protocol."
},
"command": {
"type": "string",
"description": "Command to start the server (required for stdio transport)."
},
"args": {
"type": "array",
"items": { "type": "string" },
"description": "Command-line arguments for the server command."
},
"env": {
"type": "object",
"additionalProperties": { "type": "string" },
"description": "Environment variables to set when starting the server."
},
"url": {
"type": "string",
"format": "uri",
"description": "Server URL (required for sse and streamable-http transports)."
},
"headers": {
"type": "object",
"additionalProperties": { "type": "string" },
"description": "HTTP headers for remote server connections."
},
"tool_filter": {
"type": "object",
"properties": {
"include": {
"type": "array",
"items": { "type": "string" },
"description": "Whitelist of tool names to expose."
},
"exclude": {
"type": "array",
"items": { "type": "string" },
"description": "Blacklist of tool names to hide."
}
},
"additionalProperties": false
}
},
"required": ["name", "transport"],
"additionalProperties": false
}
}
}
# ─── Skill Metadata ─────────────────────────────────────────────────
name: <namespace>/<name> # Fully qualified skill name (required)
description: <string> # Human-readable description (optional)
# ─── Tool References ────────────────────────────────────────────────
# Named tools from the Tool Registry, referenced by fully-qualified name.
tools:
- name: <namespace>/<tool_name> # Reference to a registered tool (required)
description: <string> # Override the tool's description (optional)
writes: <boolean> # Override the tool's writes flag (optional)
checkpointable: <boolean> # Override the tool's checkpointable flag (optional)
# ─── Inline (Anonymous) Tools ───────────────────────────────────────
# Tools defined directly within this skill. These are NOT registered
# in the Tool Registry and cannot be reused outside this skill.
inline_tools:
- name: <string> # Tool name (unique within this skill, required)
description: <string> # Tool description (optional)
source: custom # Source type (required, always "custom" for inline)
code: | # Inline Python code (required)
def run(input_data):
return {"result": "value"}
input_schema: # JSON Schema for tool inputs (optional)
type: object
properties:
param_name:
type: string
description: "Parameter description"
required: ["param_name"]
writes: false # Whether this tool writes (optional, default: false)
checkpointable: false # Whether this tool supports checkpointing (optional, default: false)
side_effects: [] # List of side effect descriptions (optional)
# ─── Included Skills ────────────────────────────────────────────────
# Other skills whose tools are merged into this skill.
includes:
- name: <namespace>/<skill_name> # Fully qualified skill name to include (required)
description: <string> # Override the included skill's description (optional)
# ─── MCP Server Specifications ──────────────────────────────────────
# MCP servers whose tools are exposed through this skill.
mcp_servers:
- name: <string> # Server name for identification (required)
transport: stdio | sse | streamable-http # Transport protocol (required)
command: <string> # Server command (required for stdio)
args: # Command arguments (optional)
- <string>
env: # Environment variables for the server (optional)
KEY: "value"
url: <string> # Server URL (required for sse/streamable-http)
headers: {} # HTTP headers (optional, for sse/streamable-http)
tool_filter: # Filter which tools to expose (optional)
include: # Include only these tools (optional)
- <tool_name>
exclude: # Exclude these tools (optional)
- <tool_name>
# ─── Agent Skills Standard Folders ──────────────────────────────────
# References to Agent Skills Standard (SKILL.md-based) tool bundles.
agent_skill_folders:
- path: <string> # Path to the folder containing SKILL.md (required)
name: <string> # Override the skill bundle name (optional)
# file-reader-skill.yaml
# Register: agents skill add --config file-reader-skill.yaml
name: local/file-reader
description: "Basic file reading operations"
tools:
- name: builtin/read_file
- name: builtin/list_directory
- name: builtin/search_files
# git-and-github-skill.yaml
# Register: agents skill add --config git-and-github-skill.yaml
name: local/git-github
description: "Git operations and GitHub integration"
tools:
- name: builtin/git_status
- name: builtin/git_diff
- name: builtin/git_log
- name: builtin/git_blame
includes:
- name: local/file-reader
mcp_servers:
- name: github
transport: stdio
command: npx
args:
- "-y"
- "@modelcontextprotocol/server-github"
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
tool_filter:
include:
- create_issue
- create_pull_request
- list_repos
- get_file_contents
# devops-toolkit.yaml
# Register: agents skill add --config devops-toolkit.yaml
name: local/devops-toolkit
description: "Full-stack development and operations toolkit"
tools:
- name: builtin/shell_execute
description: "Execute shell commands in the project sandbox"
- name: local/validate-api-compat
description: "Check API backward compatibility"
includes:
- name: local/file-reader
- name: local/git-github
- name: local/docker-tools
inline_tools:
- name: run_migrations
description: "Run database migrations with rollback support"
source: custom
code: |
import subprocess
def run(input_data):
direction = input_data.get("direction", "up")
count = input_data.get("count", 1)
result = subprocess.run(
["alembic", direction, str(count)],
capture_output=True, text=True
)
return {
"success": result.returncode == 0,
"stdout": result.stdout,
"stderr": result.stderr
}
input_schema:
type: object
properties:
direction:
type: string
enum: ["up", "down"]
description: "Migration direction"
count:
type: integer
default: 1
description: "Number of migrations to run"
required: ["direction"]
writes: true
checkpointable: true
side_effects: ["schema_mutation"]
- name: health_check
description: "Check service health endpoints"
source: custom
code: |
import urllib.request
def run(input_data):
url = input_data.get("url", "http://localhost:8000/health")
try:
resp = urllib.request.urlopen(url, timeout=10)
return {"status": resp.status, "healthy": resp.status == 200}
except Exception as e:
return {"status": 0, "healthy": False, "error": str(e)}
input_schema:
type: object
properties:
url:
type: string
description: "Health check URL"
writes: false
mcp_servers:
- name: linear
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-linear"]
env:
LINEAR_API_KEY: "${LINEAR_API_KEY}"
agent_skill_folders:
- path: ./skills/deploy-to-staging
name: deploy-staging
- path: ./skills/code-review-bundle
name: code-review
# text-processing-skill.yaml
# Register: agents skill add --config text-processing-skill.yaml
name: local/text-processing
description: "Simple text transformation utilities"
inline_tools:
- name: word_count
description: "Count words in text"
source: custom
code: |
def run(input_data):
text = input_data.get("text", "")
return {"count": len(text.split())}
input_schema:
type: object
properties:
text:
type: string
description: "Text to count words in"
required: ["text"]
writes: false
- name: to_uppercase
description: "Convert text to uppercase"
source: custom
code: |
def run(input_data):
return {"result": input_data.get("text", "").upper()}
input_schema:
type: object
properties:
text:
type: string
required: ["text"]
writes: false
- name: extract_urls
description: "Extract URLs from text"
source: custom
code: |
import re
def run(input_data):
text = input_data.get("text", "")
urls = re.findall(r'https?://[^\s<>"{}|\\^`\[\]]+', text)
return {"urls": urls, "count": len(urls)}
writes: false
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/action-config.json",
"title": "CleverAgents Action Configuration",
"description": "Configuration file schema for defining CleverAgents actions — reusable plan templates that specify work to be applied to projects.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified action name in <namespace>/<name> format."
},
"description": {
"type": "string",
"description": "Short (one-line) description of the action."
},
"long_description": {
"type": "string",
"description": "Detailed multi-line description explaining purpose, usage, and expected outcomes."
},
"strategy_actor": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Actor to use during the Strategize phase. Must reference a registered actor."
},
"execution_actor": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Actor to use during the Execute phase. Must reference a registered actor."
},
"estimation_actor": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Actor for effort and cost estimation before execution."
},
"review_actor": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Actor for reviewing execution results."
},
"apply_actor": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Actor to use during the Apply phase."
},
"invariant_actor": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Actor for reconciling conflicting invariants across scopes."
},
"definition_of_done": {
"type": "string",
"description": "Clear, measurable criteria that define when the action's work is complete."
},
"reusable": {
"type": "boolean",
"default": true,
"description": "Whether the action persists after being used."
},
"read_only": {
"type": "boolean",
"default": false,
"description": "Whether the action is restricted to read-only operations."
},
"state": {
"type": "string",
"enum": ["available", "archived"],
"default": "available",
"description": "State of the action."
},
"arguments": {
"type": "array",
"description": "Typed parameters that users supply when using the action via agents plan use --arg name=value.",
"items": {
"$ref": "#/$defs/argument"
}
},
"automation_profile": {
"type": "string",
"description": "Default automation profile for plans created from this action."
},
"invariants": {
"type": "array",
"items": { "type": "string" },
"description": "Constraints carried forward as plan-level invariants when the action is used."
}
},
"required": ["name", "description", "strategy_actor", "execution_actor", "definition_of_done"],
"additionalProperties": false,
"$defs": {
"argument": {
"type": "object",
"description": "A typed parameter for the action.",
"properties": {
"name": {
"type": "string",
"description": "Argument name. Used as the key in --arg name=value."
},
"type": {
"type": "string",
"enum": ["string", "integer", "float", "boolean", "list"],
"description": "Data type of the argument."
},
"required": {
"type": "boolean",
"default": false,
"description": "Whether the argument must be provided."
},
"description": {
"type": "string",
"description": "Human-readable description shown in help text."
},
"default": {
"description": "Default value when the argument is not provided. Type must match the 'type' field."
},
"validation_pattern": {
"type": "string",
"description": "Regex pattern for validating string arguments."
},
"min_value": {
"type": "number",
"description": "Minimum acceptable value for integer and float arguments."
},
"max_value": {
"type": "number",
"description": "Maximum acceptable value for integer and float arguments."
}
},
"required": ["name", "type"],
"additionalProperties": false
}
}
}
# ─── Action Identity ────────────────────────────────────────────────
name: <namespace>/<name> # Fully qualified action name (required)
description: <string> # Short description (required)
long_description: | # Detailed description (optional)
Multi-line detailed explanation of what this action does,
when to use it, and what outcomes to expect.
# ─── Lifecycle Actors ───────────────────────────────────────────────
strategy_actor: <namespace>/<name> # Actor for the Strategize phase (required)
execution_actor: <namespace>/<name> # Actor for the Execute phase (required)
estimation_actor: <namespace>/<name> # Actor for effort/cost estimation (optional)
review_actor: <namespace>/<name> # Actor for reviewing results (optional)
apply_actor: <namespace>/<name> # Actor for the Apply phase (optional)
invariant_actor: <namespace>/<name> # Invariant Reconciliation Actor (optional)
# ─── Completion Criteria ────────────────────────────────────────────
definition_of_done: | # Criteria for when the action is complete (required)
Clear, measurable criteria that define success.
Multiple criteria can be listed.
# ─── Action Properties ──────────────────────────────────────────────
reusable: true # Keep action after use (optional, default: true)
read_only: false # Restrict to read-only operations (optional, default: false)
state: available # State of the action: available or archived (optional, default: available)
# ─── Arguments ──────────────────────────────────────────────────────
# Arguments are typed parameters that must be supplied when using
# the action via `agents plan use --arg name=value`.
arguments:
- name: <string> # Argument name (required)
type: string | integer | float | boolean | list # Argument type (required)
required: true # Whether the argument must be provided (optional, default: false)
description: <string> # Human-readable description (optional)
default: <value> # Default value when not provided (optional)
validation_pattern: <regex> # Regex pattern for string validation (optional)
min_value: <number> # Minimum value for numeric types (optional)
max_value: <number> # Maximum value for numeric types (optional)
# ─── Automation ─────────────────────────────────────────────────────
automation_profile: <string> # Default automation profile name (optional)
# ─── Invariants ─────────────────────────────────────────────────────
# Invariants carried forward as plan-level invariants when this action is used.
invariants:
- <string> # Invariant text
# lint-check.yaml
# Create: agents action create --config lint-check.yaml
name: local/lint-check
description: "Run linting checks on the project"
strategy_actor: local/strategist
execution_actor: local/executor
definition_of_done: |
All linting checks pass with zero errors.
reusable: true
read_only: true
state: available
# code-coverage.yaml
# Create: agents action create --config code-coverage.yaml
name: local/code-coverage
description: "Increase test coverage to a target percentage"
long_description: |
Analyzes the current test coverage of a project, identifies
modules with low coverage, and generates comprehensive test
suites to meet the target coverage percentage.
The action prioritizes:
1. Business-critical modules (auth, payments)
2. Recently modified code
3. Error-prone areas based on git history
strategy_actor: local/strategist
execution_actor: local/executor
estimation_actor: local/estimator
definition_of_done: |
Test coverage reaches the target_coverage_percent threshold
across all specified modules. All generated tests pass.
No existing tests are broken by the changes.
reusable: true
read_only: false
arguments:
- name: target_coverage_percent
type: integer
required: true
description: "Target test coverage percentage (1-100)"
min_value: 1
max_value: 100
- name: test_command
type: string
required: false
description: "Test framework command to use"
default: "pytest --cov"
- name: exclude_patterns
type: list
required: false
description: "File patterns to exclude from coverage analysis"
default: ["**/migrations/**", "**/conftest.py"]
- name: focus_modules
type: list
required: false
description: "Specific modules to prioritize for coverage"
automation_profile: trusted
invariants:
- "Generated tests must not import production secrets or credentials"
- "Test files must follow the project's existing test naming conventions"
- "All database interactions in tests must use mocks or fixtures"
# security-audit.yaml
# Create: agents action create --config security-audit.yaml
name: local/security-audit
description: "Comprehensive security audit of a project"
long_description: |
Performs a thorough security audit covering:
- Dependency vulnerability scanning (CVEs)
- Static Application Security Testing (SAST)
- Authentication and authorization review
- Input validation and injection prevention
- Secrets detection and credential scanning
- API security (rate limiting, CORS, headers)
- Data handling and privacy compliance
Generates a detailed report with severity ratings (Critical,
High, Medium, Low, Informational) and remediation guidance.
Optionally creates fix plans for identified issues.
strategy_actor: local/security-strategist
execution_actor: local/security-scanner
estimation_actor: local/estimator
review_actor: local/security-reviewer
invariant_actor: local/invariant-resolver
definition_of_done: |
All critical and high severity findings have been identified.
A complete security report has been generated with:
- Severity classification for each finding
- Remediation steps for each finding
- Risk score for the overall project
If auto_fix is enabled, all critical findings have remediation
plans created as child plans.
reusable: true
read_only: false
state: available
arguments:
- name: severity_threshold
type: string
required: false
description: "Minimum severity to include in report"
default: "low"
validation_pattern: "^(critical|high|medium|low|informational)$"
- name: auto_fix
type: boolean
required: false
description: "Automatically create fix plans for critical findings"
default: false
- name: scan_dependencies
type: boolean
required: false
description: "Include dependency vulnerability scanning"
default: true
- name: compliance_frameworks
type: list
required: false
description: "Compliance frameworks to check against"
default: ["owasp-top-10"]
- name: max_findings
type: integer
required: false
description: "Maximum number of findings to report"
default: 100
min_value: 1
max_value: 1000
- name: ignore_paths
type: list
required: false
description: "Paths to exclude from scanning"
default: ["**/node_modules/**", "**/vendor/**", "**/.git/**"]
automation_profile: supervised
invariants:
- "Never modify production database schemas during audit"
- "Never execute discovered exploit code against live systems"
- "All findings must include reproducible steps"
- "Secrets found during scanning must be redacted in reports"
- "Remediation fixes must not break existing tests"
# db-migrate.yaml
# Create: agents action create --config db-migrate.yaml
name: local/db-migrate
description: "Plan and execute database schema migrations"
strategy_actor: local/db-strategist
execution_actor: local/db-executor
definition_of_done: |
All migration scripts are generated and pass dry-run validation.
Rollback scripts are generated for each migration.
The migration can be applied without data loss.
reusable: true
read_only: false
arguments:
- name: migration_tool
type: string
required: false
description: "Migration tool to use"
default: "alembic"
validation_pattern: "^(alembic|flyway|django|knex)$"
- name: dry_run
type: boolean
required: false
description: "Only generate and validate, do not apply"
default: true
- name: target_schema
type: string
required: false
description: "Target schema version identifier"
automation_profile: supervised
invariants:
- "All migrations must include corresponding rollback scripts"
- "Data migrations must preserve existing data integrity"
- "Schema changes must maintain backward compatibility for 24 hours"
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/tool-config.json",
"title": "CleverAgents Tool Configuration",
"description": "Configuration file schema for defining CleverAgents tools — namespaced, independently registered, callable operations.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified tool name in <namespace>/<name> format."
},
"description": {
"type": "string",
"description": "Human-readable description of the tool's purpose and behavior."
},
"source": {
"type": "string",
"enum": ["custom", "mcp", "agent_skill", "builtin"],
"description": "Tool source type. Determines which implementation fields are required."
},
"code": {
"type": "string",
"description": "Python code implementing the tool. Required when source is 'custom'. Must define a run(input_data) function."
},
"mcp_server": {
"type": "string",
"description": "Name of the MCP server exposing this tool. Required when source is 'mcp'."
},
"mcp_tool_name": {
"type": "string",
"description": "Name of the tool on the MCP server. Required when source is 'mcp'."
},
"agent_skill_path": {
"type": "string",
"description": "Path to the Agent Skills Standard folder containing SKILL.md. Required when source is 'agent_skill'."
},
"input_schema": {
"$ref": "https://json-schema.org/draft/2020-12/schema",
"description": "JSON Schema describing the tool's input parameters."
},
"output_schema": {
"$ref": "https://json-schema.org/draft/2020-12/schema",
"description": "JSON Schema describing the tool's output format."
},
"writes": {
"type": "boolean",
"default": false,
"description": "Whether the tool performs any write operations."
},
"write_scope": {
"type": "string",
"description": "Scope of write operations (e.g., 'filesystem', 'database:migrations', 'api:github')."
},
"checkpointable": {
"type": "boolean",
"default": false,
"description": "Whether the tool supports checkpointing — saving state before execution and restoring on failure."
},
"checkpoint_scope": {
"type": "string",
"enum": ["file", "transaction", "snapshot", "composite"],
"description": "The checkpointing strategy."
},
"side_effects": {
"type": "array",
"items": { "type": "string" },
"default": [],
"description": "Side effects that cannot be undone by checkpointing alone (e.g., 'network_call', 'schema_mutation', 'email_sent')."
},
"idempotent": {
"type": "boolean",
"default": false,
"description": "Whether the tool is safe to retry — calling it multiple times with the same input produces the same result."
},
"read_only": {
"type": "boolean",
"default": false,
"description": "Whether the tool only reads data without modifying anything."
},
"unsafe": {
"type": "boolean",
"default": false,
"description": "Whether the tool is flagged as unsafe. Requires allow_unsafe_tools: true in the automation profile."
},
"timeout": {
"type": "integer",
"default": 300,
"minimum": 1,
"description": "Default execution timeout in seconds."
},
"resource_slots": {
"type": "array",
"description": "Declared resource dependencies for this tool.",
"items": {
"$ref": "#/$defs/resourceSlot"
}
},
"lifecycle": {
"type": "object",
"description": "Lifecycle hook implementations.",
"properties": {
"discover": {
"type": "string",
"description": "Python code or function name run during tool discovery."
},
"activate": {
"type": "string",
"description": "Python code or function name run when the tool is activated."
},
"deactivate": {
"type": "string",
"description": "Python code or function name run when the tool is deactivated."
}
},
"additionalProperties": false
},
},
"required": ["name", "description", "source"],
"allOf": [
{
"if": { "properties": { "source": { "const": "custom" } } },
"then": { "required": ["code"] }
},
{
"if": { "properties": { "source": { "const": "mcp" } } },
"then": { "required": ["mcp_server", "mcp_tool_name"] }
},
{
"if": { "properties": { "source": { "const": "agent_skill" } } },
"then": { "required": ["agent_skill_path"] }
}
],
"additionalProperties": false,
"$defs": {
"resourceSlot": {
"type": "object",
"description": "A declared resource dependency slot.",
"properties": {
"name": {
"type": "string",
"description": "Identifier for this resource slot."
},
"resource_type": {
"type": "string",
"description": "The resource type this slot requires (e.g., 'git-checkout', 'fs-directory')."
},
"access": {
"type": "string",
"enum": ["read_only", "read_write"],
"description": "Access level needed."
},
"description": {
"type": "string",
"description": "Human-readable description of how the tool uses this resource."
},
"binding": {
"type": "string",
"enum": ["contextual", "static", "parameter"],
"default": "contextual",
"description": "How the slot is resolved at runtime."
},
"static_resource": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified name of a specific resource. Required when binding is 'static'."
}
},
"required": ["name", "resource_type", "access"],
"if": { "properties": { "binding": { "const": "static" } } },
"then": { "required": ["name", "resource_type", "access", "static_resource"] },
"additionalProperties": false
}
}
}
# ─── Tool Identity ──────────────────────────────────────────────────
name: <namespace>/<name> # Fully qualified tool name (required)
description: <string> # Human-readable description (required)
# ─── Source and Implementation ──────────────────────────────────────
source: custom | mcp | agent_skill | builtin # Tool source type (required)
# For source: custom — inline Python implementation
code: | # Python code with a run(input_data) function (required for custom)
def run(input_data):
param = input_data.get("param_name", "default")
# ... tool logic ...
return {"result": "value"}
# For source: mcp — tool exposed by an MCP server
mcp_server: <string> # MCP server name (required for mcp)
mcp_tool_name: <string> # Tool name on the MCP server (required for mcp)
# For source: agent_skill — tool from an Agent Skills Standard folder
agent_skill_path: <string> # Path to the SKILL.md folder (required for agent_skill)
# ─── Input/Output Schema ────────────────────────────────────────────
input_schema: # JSON Schema for tool inputs (optional but recommended)
type: object
properties:
param_name:
type: string
description: "Parameter description"
enum: ["value1", "value2"] # Enumerated valid values (optional)
default: "value1" # Default value (optional)
numeric_param:
type: integer
description: "A numeric parameter"
minimum: 0 # Minimum value (optional)
maximum: 100 # Maximum value (optional)
required: ["param_name"] # Required parameters
output_schema: # JSON Schema for tool outputs (optional)
type: object
properties:
result:
type: string
success:
type: boolean
# ─── Capability Metadata ────────────────────────────────────────────
writes: false # Whether the tool performs write operations (optional, default: false)
write_scope: <string> # Scope of writes, e.g. "filesystem", "database:migrations" (optional)
checkpointable: false # Whether the tool supports checkpointing (optional, default: false)
checkpoint_scope: <string> # Checkpointing strategy: "file", "transaction", "snapshot", "composite" (optional)
side_effects: # List of side effect types (optional)
- <string> # e.g. "network_call", "schema_mutation", "process_spawn"
idempotent: false # Whether the tool is safe to retry (optional, default: false)
read_only: false # Whether the tool only reads (optional, default: false)
unsafe: false # Whether the tool is flagged as unsafe (optional, default: false)
timeout: 300 # Default execution timeout in seconds (optional, default: 300)
# ─── Resource Bindings ──────────────────────────────────────────────
# Declare which resources this tool operates on.
resource_slots:
- name: <string> # Slot name for reference (required)
resource_type: <string> # Required resource type, e.g. "git-checkout", "fs-directory" (required)
access: read_only | read_write # Access level needed (required)
description: <string> # Description of how the resource is used (optional)
binding: contextual | static | parameter # How the slot is resolved (optional, default: contextual)
static_resource: <namespace>/<name> # Specific resource (required when binding is static)
# ─── Lifecycle Hooks ────────────────────────────────────────────────
lifecycle:
discover: <string> # Python function or code for tool discovery (optional)
activate: <string> # Python function or code run when tool is activated (optional)
deactivate: <string> # Python function or code run when tool is deactivated (optional)
# read-config-file.yaml
# Register: agents tool add --config read-config-file.yaml
name: local/read-config
description: "Read and parse a configuration file (JSON, YAML, or TOML)"
source: custom
code: |
import json, os
def run(input_data):
path = input_data["path"]
if not os.path.exists(path):
return {"error": f"File not found: {path}", "success": False}
with open(path, "r") as f:
content = f.read()
ext = os.path.splitext(path)[1].lower()
if ext == ".json":
parsed = json.loads(content)
elif ext in (".yaml", ".yml"):
import yaml
parsed = yaml.safe_load(content)
else:
parsed = None
return {"content": content, "parsed": parsed, "path": path, "success": True}
input_schema:
type: object
properties:
path:
type: string
description: "Path to the configuration file"
required: ["path"]
output_schema:
type: object
properties:
content:
type: string
parsed:
type: object
success:
type: boolean
writes: false
read_only: true
idempotent: true
# run-migrations.yaml
# Register: agents tool add --config run-migrations.yaml
name: local/run-migrations
description: "Run database migrations with direction control and rollback support"
source: custom
code: |
import subprocess
def run(input_data):
direction = input_data.get("direction", "up")
count = input_data.get("count", 1)
dry_run = input_data.get("dry_run", False)
cmd = ["alembic"]
if dry_run:
cmd.append("--sql")
cmd.extend([direction, str(count)])
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return {
"success": result.returncode == 0,
"stdout": result.stdout,
"stderr": result.stderr,
"direction": direction,
"count": count,
"dry_run": dry_run,
"return_code": result.returncode
}
input_schema:
type: object
properties:
direction:
type: string
enum: ["up", "down"]
description: "Migration direction: 'up' to apply, 'down' to rollback"
count:
type: integer
default: 1
minimum: 1
maximum: 50
description: "Number of migrations to run"
dry_run:
type: boolean
default: false
description: "Generate SQL without executing"
required: ["direction"]
writes: true
write_scope: "database:migrations"
checkpointable: true
checkpoint_scope: "transaction"
side_effects:
- "schema_mutation"
idempotent: false
timeout: 120
resource_slots:
- name: database
resource_type: "local/database"
access: read_write
description: "The database to run migrations against"
binding: contextual
# github-create-issue.yaml
# Register: agents tool add --config github-create-issue.yaml
name: local/github-create-issue
description: "Create a GitHub issue via the GitHub MCP server"
source: mcp
mcp_server: github
mcp_tool_name: create_issue
input_schema:
type: object
properties:
owner:
type: string
description: "Repository owner"
repo:
type: string
description: "Repository name"
title:
type: string
description: "Issue title"
body:
type: string
description: "Issue body (Markdown)"
labels:
type: array
items:
type: string
description: "Labels to apply"
required: ["owner", "repo", "title"]
writes: true
write_scope: "api:github"
checkpointable: false
side_effects:
- "network_call"
idempotent: false
# deploy-staging.yaml
# Register: agents tool add --config deploy-staging.yaml
name: local/deploy-staging
description: "Deploy the current build to the staging environment with health checks"
source: custom
code: |
import subprocess, time, urllib.request, json
def run(input_data):
service = input_data["service"]
version = input_data.get("version", "latest")
wait_healthy = input_data.get("wait_healthy", True)
health_timeout = input_data.get("health_timeout", 120)
# Build the deployment command
cmd = ["kubectl", "set", "image",
f"deployment/{service}",
f"{service}={service}:{version}",
"--namespace=staging"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
if result.returncode != 0:
return {"success": False, "error": result.stderr, "phase": "deploy"}
# Wait for rollout
rollout = subprocess.run(
["kubectl", "rollout", "status", f"deployment/{service}",
"--namespace=staging", f"--timeout={health_timeout}s"],
capture_output=True, text=True, timeout=health_timeout + 10
)
if rollout.returncode != 0:
return {"success": False, "error": rollout.stderr, "phase": "rollout"}
# Health check
if wait_healthy:
health_url = f"http://{service}.staging.svc.cluster.local/health"
start = time.time()
while time.time() - start < health_timeout:
try:
resp = urllib.request.urlopen(health_url, timeout=5)
if resp.status == 200:
body = json.loads(resp.read())
if body.get("status") == "healthy":
return {
"success": True,
"service": service,
"version": version,
"health": body
}
except Exception:
pass
time.sleep(5)
return {"success": False, "error": "Health check timeout", "phase": "health"}
return {"success": True, "service": service, "version": version}
input_schema:
type: object
properties:
service:
type: string
description: "Name of the service to deploy"
version:
type: string
default: "latest"
description: "Docker image version tag"
wait_healthy:
type: boolean
default: true
description: "Wait for health check to pass"
health_timeout:
type: integer
default: 120
minimum: 10
maximum: 600
description: "Health check timeout in seconds"
required: ["service"]
output_schema:
type: object
properties:
success:
type: boolean
service:
type: string
version:
type: string
error:
type: string
phase:
type: string
writes: true
write_scope: "infrastructure:kubernetes"
checkpointable: true
checkpoint_scope: "composite"
side_effects:
- "network_call"
- "process_spawn"
- "infrastructure_mutation"
idempotent: false
unsafe: true
timeout: 300
resource_slots:
- name: repo
resource_type: git-checkout
access: read_only
description: "Source repository for build artifacts"
binding: contextual
- name: cluster_config
resource_type: fs-file
access: read_only
description: "Kubernetes cluster configuration (kubeconfig)"
binding: static
static_resource: local/staging-kubeconfig
lifecycle:
activate: |
def activate(context):
import subprocess
result = subprocess.run(["kubectl", "cluster-info"], capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError("Cannot connect to Kubernetes cluster")
return {"cluster": "connected"}
deactivate: |
def deactivate(context):
pass # No cleanup needed
# validate-api-compat.yaml
# Register: agents tool add --config validate-api-compat.yaml
name: local/validate-api-compat
description: "Validate that API changes maintain backward compatibility with existing clients"
source: custom
code: |
import subprocess, json
def run(input_data):
spec_path = input_data.get("spec_path", "openapi.yaml")
base_branch = input_data.get("base_branch", "main")
# Get the base spec from the main branch
base_result = subprocess.run(
["git", "show", f"{base_branch}:{spec_path}"],
capture_output=True, text=True
)
if base_result.returncode != 0:
return {"compatible": True, "reason": "No base spec found (new API)", "changes": []}
# Run OpenAPI diff
diff_result = subprocess.run(
["oasdiff", "breaking", "--format", "json",
"--base", "/dev/stdin", "--revision", spec_path],
input=base_result.stdout,
capture_output=True, text=True
)
if diff_result.returncode == 0:
return {"compatible": True, "changes": [], "reason": "No breaking changes"}
try:
breaking = json.loads(diff_result.stdout)
except json.JSONDecodeError:
breaking = [{"description": diff_result.stdout}]
return {
"compatible": False,
"changes": breaking,
"reason": f"Found {len(breaking)} breaking change(s)"
}
input_schema:
type: object
properties:
spec_path:
type: string
default: "openapi.yaml"
description: "Path to the OpenAPI specification file"
base_branch:
type: string
default: "main"
description: "Branch to compare against for backward compatibility"
required: []
writes: false
read_only: true
checkpointable: false
idempotent: true
timeout: 60
resource_slots:
- name: repo
resource_type: git-checkout
access: read_only
description: "Git repository containing the API spec"
binding: contextual
# validations/run-tests.yaml
# Register: agents validation add --config validations/run-tests.yaml
name: local/run-tests
description: "Run unit tests with coverage and report pass/fail"
source: custom
code: |
import subprocess, json
def run(input_data):
threshold = input_data.get("coverage_threshold", 80)
result = subprocess.run(
["pytest", "--cov=src", f"--cov-fail-under={threshold}", "--tb=short", "-q"],
capture_output=True, text=True
)
passed = result.returncode == 0
return {
"passed": passed,
"message": "All tests passed" if passed else f"Tests failed (exit code {result.returncode})",
"data": {
"stdout": result.stdout,
"stderr": result.stderr,
"returncode": result.returncode,
"coverage_threshold": threshold
}
}
validation:
mode: required
input_schema:
type: object
properties:
coverage_threshold:
type: integer
default: 80
description: "Minimum coverage percentage required"
read_only: true
idempotent: true
timeout: 600
resource_slots:
- name: repo
resource_type: git-checkout
access: read_only
binding: contextual
# validations/lint-check.yaml
name: local/lint-check
description: "Run linter and report pass/fail"
source: custom
code: |
import subprocess
def run(input_data):
result = subprocess.run(["ruff", "check", "."], capture_output=True, text=True)
passed = result.returncode == 0
return {
"passed": passed,
"message": "Lint clean" if passed else f"Lint errors found",
"data": {"stdout": result.stdout, "stderr": result.stderr}
}
validation:
mode: required
read_only: true
idempotent: true
timeout: 300
# validations/check-bundle-size.yaml
name: local/check-bundle-size
description: "Check bundle size (advisory — does not block execution)"
source: custom
code: |
import subprocess, json
def run(input_data):
result = subprocess.run(["node", "scripts/check-bundle-size.js"], capture_output=True, text=True)
try:
size_data = json.loads(result.stdout)
except json.JSONDecodeError:
size_data = {"raw_output": result.stdout}
passed = result.returncode == 0
return {
"passed": passed,
"message": "Bundle size within limits" if passed else "Bundle size exceeds advisory threshold",
"data": size_data
}
validation:
mode: informational
read_only: true
timeout: 120
# validations/security-scan.yaml
name: local/security-scan
description: "Run security vulnerability scan via MCP"
source: mcp
mcp_server: "npx @security/mcp-scanner"
mcp_tool_name: scan_vulnerabilities
validation:
mode: required
read_only: true
timeout: 300
# validations/tests-pass.yaml
# Assumes local/run-tests is already registered as a Tool that runs
# the test suite and returns {returncode, tests_run, tests_passed, ...}
name: local/tests-pass
description: "Validate that all unit tests pass (wraps local/run-tests)"
wraps: local/run-tests
transform: |
def transform(tool_output):
passed = tool_output.get("returncode") == 0
tests_run = tool_output.get("tests_run", 0)
tests_passed = tool_output.get("tests_passed", 0)
return {
"passed": passed,
"message": f"{tests_passed}/{tests_run} tests passed" if passed
else f"{tests_run - tests_passed} tests failed",
"data": tool_output
}
validation:
mode: required
timeout: 600
# validations/coverage-check.yaml
name: local/coverage-check
description: "Check test coverage exceeds threshold (advisory)"
wraps: local/run-tests
transform: |
def transform(tool_output):
coverage = tool_output.get("coverage_percent", 0)
threshold = 80
return {
"passed": coverage >= threshold,
"message": f"Coverage: {coverage:.1f}% (threshold: {threshold}%)",
"data": {
"coverage_percent": coverage,
"threshold": threshold,
"above_threshold": coverage >= threshold
}
}
validation:
mode: informational
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/resource-type-config.json",
"title": "CleverAgents Resource Type Configuration",
"description": "Configuration file schema for defining custom resource types that extend the built-in resource types.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified resource type name in <namespace>/<name> format."
},
"description": {
"type": "string",
"description": "Human-readable description of what this resource type represents."
},
"physical": {
"type": "boolean",
"description": "true for physical types (concrete manifestations), false for virtual types (abstract identity linking equivalent physical resources)."
},
"user_addable": {
"type": "boolean",
"default": true,
"description": "Whether users can create instances directly via 'agents resource add <type>'."
},
"cli_args": {
"type": "array",
"description": "Arguments accepted by 'agents resource add <type>'.",
"items": {
"$ref": "#/$defs/cliArg"
}
},
"child_types": {
"type": "array",
"description": "Resource types that can be children of this type.",
"items": {
"$ref": "#/$defs/childType"
}
},
"parent_types": {
"type": "array",
"description": "Resource types that can be parents of this type. If omitted, the resource can be top-level.",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Parent resource type name."
},
"description": {
"type": "string",
"description": "Description of the parent-child relationship from the child's perspective."
}
},
"required": ["type"],
"additionalProperties": false
}
},
"sandbox_strategy": {
"type": "string",
"enum": ["git_worktree", "copy_on_write", "transaction_rollback", "snapshot", "none"],
"description": "Sandbox strategy for instances of this type."
},
"handler": {
"type": "object",
"description": "The Python handler class that implements resource operations.",
"properties": {
"class": {
"type": "string",
"description": "Python class name that implements the resource handler interface."
},
"module": {
"type": "string",
"description": "Python module path where the handler class is defined."
},
"config": {
"type": "object",
"description": "Arbitrary configuration passed to the handler constructor.",
"additionalProperties": true
}
},
"required": ["class", "module"],
"additionalProperties": false
},
"auto_discovery": {
"type": "object",
"description": "Controls automatic child resource discovery when a resource of this type is created.",
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Whether auto-discovery runs when a resource of this type is created."
},
"scan_depth": {
"type": "integer",
"default": 3,
"minimum": 1,
"description": "Maximum recursion depth for scanning."
},
"include_patterns": {
"type": "array",
"items": { "type": "string" },
"description": "Glob patterns for resources to discover."
},
"exclude_patterns": {
"type": "array",
"items": { "type": "string" },
"description": "Glob patterns for resources to skip during discovery."
}
},
"additionalProperties": false
},
"equivalence": {
"type": "object",
"description": "Equivalence criteria for virtual types. Only applicable when physical is false.",
"properties": {
"criteria": {
"type": "array",
"items": { "type": "string" },
"description": "Fields used to determine equivalence (e.g., 'content_hash', 'filename', 'permissions', 'url')."
},
"description": {
"type": "string",
"description": "Human-readable description of the equivalence rule."
}
},
"required": ["criteria"],
"additionalProperties": false
},
},
"required": ["name", "description", "physical", "sandbox_strategy", "handler"],
"if": {
"properties": { "physical": { "const": false } }
},
"then": {
"required": ["name", "description", "physical", "sandbox_strategy", "handler", "equivalence"]
},
"additionalProperties": false,
"$defs": {
"cliArg": {
"type": "object",
"description": "A CLI argument definition for 'agents resource add <type>'.",
"properties": {
"name": {
"type": "string",
"description": "Argument name. Becomes --<name> on the CLI."
},
"type": {
"type": "string",
"enum": ["string", "path", "integer", "boolean", "url"],
"description": "Argument type. 'path' validates that the path exists; 'url' validates URL format."
},
"required": {
"type": "boolean",
"default": false,
"description": "Whether the argument must be provided."
},
"description": {
"type": "string",
"description": "Description shown in --help."
},
"default": {
"description": "Default value when the argument is not provided."
},
"validation_pattern": {
"type": "string",
"description": "Regex pattern for validating string and url type arguments."
}
},
"required": ["name", "type"],
"additionalProperties": false
},
"childType": {
"type": "object",
"description": "An allowed child resource type relationship.",
"properties": {
"type": {
"type": "string",
"description": "Child resource type name."
},
"auto_discover": {
"type": "boolean",
"default": false,
"description": "Whether children of this type are automatically created when the parent resource is registered."
},
"manual_link": {
"type": "boolean",
"default": true,
"description": "Whether manual 'agents resource link-child' is allowed for this relationship."
},
"description": {
"type": "string",
"description": "Description of the parent-child relationship."
},
"max_count": {
"type": ["integer", "null"],
"minimum": 1,
"description": "Maximum number of children of this type. null or omitted means unlimited."
}
},
"required": ["type"],
"additionalProperties": false
}
}
}
# ─── Resource Type Identity ─────────────────────────────────────────
name: <namespace>/<name> # Fully qualified resource type name (required)
description: <string> # Human-readable description (required)
# ─── Type Classification ────────────────────────────────────────────
physical: true # Whether instances are physical or virtual (required)
# Physical: a specific, concrete manifestation (this file at this path)
# Virtual: an abstract identity linking equivalent physical resources
user_addable: true # Whether users can create instances directly (optional, default: true)
# ─── Type Inheritance ───────────────────────────────────────────────
inherits: <parent-type-name> # Parent resource type to inherit from (optional)
# Subtypes inherit all fields from the parent type.
# Only fields that differ from or extend the parent need to be declared.
# See ADR-042 for full inheritance semantics.
# ─── CLI Arguments ──────────────────────────────────────────────────
# Define the arguments accepted by `agents resource add <type>`.
cli_args:
- name: <string> # Argument name (becomes --<name> on CLI) (required)
type: string | path | integer | boolean | url # Argument type (required)
required: true # Whether the argument is required (optional, default: false)
description: <string> # Description shown in help text (optional)
default: <value> # Default value (optional)
validation_pattern: <regex> # Regex validation for string/url types (optional)
# ─── Parent/Child Type Relationships ────────────────────────────────
# Define which resource types can be children of this type.
child_types:
- type: <string> # Child resource type name (required)
auto_discover: true # Automatically create children when parent is created (optional, default: false)
manual_link: true # Allow manual parent-child linking (optional, default: true)
description: <string> # Description of the relationship (optional)
max_count: <integer> # Maximum number of children of this type (optional, null = unlimited)
# Define which resource types can be parents of this type.
parent_types:
- type: <string> # Parent resource type name (required)
description: <string> # Description of the relationship (optional)
# If parent_types is omitted, the resource can be top-level (no parent required).
# ─── Sandbox Strategy ──────────────────────────────────────────────
sandbox_strategy: <string> # Sandbox strategy for instances of this type (required)
# Built-in strategies: "git_worktree", "copy_on_write",
# "transaction_rollback", "snapshot", "none"
# ─── Handler Implementation ────────────────────────────────────────
handler:
class: <string> # Python class implementing the resource handler (required)
module: <string> # Python module path (required)
config: {} # Handler-specific configuration (optional)
# ─── Auto-Discovery Configuration ──────────────────────────────────
auto_discovery:
enabled: true # Whether child auto-discovery runs on creation (optional, default: true)
scan_depth: <integer> # Max depth for recursive scanning (optional, default: 3)
include_patterns: # Glob patterns for resources to auto-discover (optional)
- <string>
exclude_patterns: # Glob patterns to exclude from auto-discovery (optional)
- <string>
# ─── Virtual Type Configuration ─────────────────────────────────────
# Only applicable when physical: false (virtual types).
equivalence:
criteria: # Fields used to determine equivalence (required for virtual)
- <string> # e.g. "content_hash", "filename", "permissions", "url"
description: <string> # Human-readable description of the equivalence rule (optional)
# svn-type.yaml
# Register: agents resource type add --config svn-type.yaml
name: local/svn
description: "A Subversion (SVN) repository checkout"
physical: true
user_addable: true
cli_args:
- name: url
type: url
required: true
description: "SVN repository URL"
validation_pattern: "^svn(\\+ssh)?://.*|^https?://.*"
- name: checkout-path
type: path
required: true
description: "Local checkout directory"
- name: revision
type: string
required: false
description: "Specific revision to checkout"
default: "HEAD"
child_types:
- type: fs-directory
auto_discover: true
description: "Working copy directory tree"
- type: local/svn-revision
auto_discover: true
description: "SVN revision history"
sandbox_strategy: copy_on_write
handler:
class: SVNHandler
module: cleveragents.resource.handlers.svn
config:
svn_binary: "svn"
trust_server_cert: true
auto_discovery:
enabled: true
scan_depth: 2
exclude_patterns:
- "**/.svn/**"
# s3-bucket-type.yaml
# Register: agents resource type add --config s3-bucket-type.yaml
name: local/s3-bucket
description: "An Amazon S3 bucket with prefix-based object organization"
physical: true
user_addable: true
cli_args:
- name: bucket
type: string
required: true
description: "S3 bucket name"
validation_pattern: "^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$"
- name: region
type: string
required: false
description: "AWS region"
default: "us-east-1"
- name: prefix
type: string
required: false
description: "Key prefix to scope resource to a 'subdirectory'"
default: ""
- name: profile
type: string
required: false
description: "AWS CLI profile name"
default: "default"
child_types:
- type: local/s3-prefix
auto_discover: true
description: "S3 key prefixes (virtual directories)"
max_count: 1000
- type: local/s3-object
auto_discover: true
description: "S3 objects (files)"
sandbox_strategy: copy_on_write
handler:
class: S3BucketHandler
module: cleveragents.resource.handlers.s3
config:
max_object_size: 104857600 # 100 MB
default_acl: "private"
auto_discovery:
enabled: true
scan_depth: 3
include_patterns:
- "**/*.json"
- "**/*.yaml"
- "**/*.yml"
- "**/*.py"
- "**/*.sql"
exclude_patterns:
- "**/*.log"
- "**/*.tmp"
- "**/node_modules/**"
# database-type.yaml
# Register: agents resource type add --config database-type.yaml
name: local/database
description: "A relational database (PostgreSQL, MySQL, SQLite)"
physical: true
user_addable: true
cli_args:
- name: connection-string
type: string
required: true
description: "Database connection string (e.g., postgresql://user:pass@host/db)"
- name: engine
type: string
required: false
description: "Database engine"
default: "postgresql"
validation_pattern: "^(postgresql|mysql|sqlite|mssql)$"
- name: read-only
type: boolean
required: false
description: "Connect in read-only mode"
default: false
- name: schema
type: string
required: false
description: "Database schema to scope to"
default: "public"
child_types:
- type: local/db-table
auto_discover: true
description: "Database tables"
- type: local/db-view
auto_discover: true
description: "Database views"
- type: local/db-migration
auto_discover: false
manual_link: true
description: "Migration scripts linked to this database"
parent_types:
- type: git-checkout
description: "Repository containing the application that owns this database"
sandbox_strategy: transaction_rollback
handler:
class: DatabaseHandler
module: cleveragents.resource.handlers.database
config:
connection_pool_size: 5
statement_timeout: 30000 # 30 seconds
log_queries: true
auto_discovery:
enabled: true
scan_depth: 1
# virtual-config-file-type.yaml
# Register: agents resource type add --config virtual-config-file-type.yaml
name: local/config-file
description: "Virtual type linking equivalent configuration files across repositories"
physical: false
user_addable: false
child_types:
- type: fs-file
auto_discover: false
manual_link: true
description: "Physical file instances"
- type: git-tree-entry
auto_discover: false
manual_link: true
description: "Git tree entries representing the same config file"
sandbox_strategy: none
handler:
class: VirtualConfigFileHandler
module: cleveragents.resource.handlers.virtual_config
config:
track_content_drift: true
equivalence:
criteria:
- content_hash
- filename
description: "Two physical resources represent the same config file when they share the same filename and content hash"
# docker-registry-type.yaml
# Register: agents resource type add --config docker-registry-type.yaml
name: local/docker-registry
description: "A Docker container registry with image and tag discovery"
physical: true
user_addable: true
cli_args:
- name: registry-url
type: url
required: true
description: "Docker registry URL (e.g., registry.example.com, ghcr.io/org)"
validation_pattern: "^[a-zA-Z0-9][a-zA-Z0-9.-]+(:[0-9]+)?(/[a-zA-Z0-9._-]+)*$"
- name: username
type: string
required: false
description: "Registry username for authentication"
- name: password-env
type: string
required: false
description: "Environment variable name containing the registry password"
- name: namespace
type: string
required: false
description: "Image namespace or organization filter"
child_types:
- type: local/docker-image
auto_discover: true
description: "Docker images in the registry"
max_count: 500
- type: local/docker-tag
auto_discover: true
description: "Image tags"
sandbox_strategy: none
handler:
class: DockerRegistryHandler
module: cleveragents.resource.handlers.docker
config:
api_version: "v2"
page_size: 100
cache_ttl: 300
auto_discovery:
enabled: true
scan_depth: 2
include_patterns:
- "**/latest"
- "**/main"
- "**/release-*"
exclude_patterns:
- "**/sha256:*"
- "**/*-dirty"
# devcontainer-instance inherits from container-instance (ADR-039)
# See ADR-042 for inheritance rules, ADR-043 for devcontainer lifecycle
name: "devcontainer-instance"
inherits: "container-instance"
description: "A container instance defined by a devcontainer.json configuration file. Auto-discovered as a child of git-checkout resources containing a .devcontainer/ directory. Supports lazy activation — detected at discovery time but built only on first access."
physical_virtual: "physical"
fields:
# Inherited from container-instance: image, engine, ports, environment, volumes
# Additional fields specific to devcontainer semantics:
devcontainer_json_path:
type: "string"
required: true
description: "Relative path to devcontainer.json from the parent resource root (e.g., .devcontainer/devcontainer.json)"
workspace_folder:
type: "string"
required: false
default: "/workspaces/${localWorkspaceFolderBasename}"
description: "Container-side workspace path, parsed from devcontainer.json workspaceFolder field"
features:
type: "map<string, object>"
required: false
description: "Dev Container Features to install, parsed from devcontainer.json features field"
post_create_command:
type: "string | list<string>"
required: false
description: "Command(s) to run after container creation, from devcontainer.json postCreateCommand"
post_start_command:
type: "string | list<string>"
required: false
description: "Command(s) to run after container start, from devcontainer.json postStartCommand"
activation_state:
type: "enum(detected, building, running, stopping, stopped, failed)"
required: true
default: "detected"
description: "Lifecycle state. Starts as 'detected' (lazy); transitions to 'building' then 'running' on first access. The 'stopping' state tracks in-progress shutdown before reaching 'stopped'."
handler: "DevcontainerHandler"
sandbox_strategy: "container_snapshot"
# Overrides the parent's sandbox_strategy; devcontainers use container snapshots
# for checkpoint/rollback rather than the generic container strategy.
capabilities:
readable: true
writable: true
sandboxable: true
checkpointable: true
executable: true
auto_discovery:
enabled: true
parent_types:
- "git-checkout"
detection:
scan_paths:
- ".devcontainer/devcontainer.json"
- ".devcontainer.json"
activation: "lazy"
# Container is NOT built at discovery time.
# State remains "detected" until the execution environment router
# selects this devcontainer for tool execution.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/context-view-config.json",
"title": "CleverAgents Context View Configuration",
"description": "Configuration file schema for defining context views that control how project resources are filtered and presented to actors during plan phases.",
"type": "object",
"properties": {
"project": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified project name this view applies to."
},
"view": {
"type": "string",
"enum": ["default", "strategize", "execute", "apply"],
"description": "Phase view. 'default' is the fallback for all phases; phase-specific views override 'default'."
},
"include_resources": {
"type": "array",
"items": { "type": "string" },
"description": "Whitelist of resource names to include. When specified, only these resources provide context."
},
"exclude_resources": {
"type": "array",
"items": { "type": "string" },
"description": "Blacklist of resource names to exclude. Applied after include_resources."
},
"include_paths": {
"type": "array",
"items": { "type": "string" },
"description": "Glob patterns for file paths to include. When specified, only matching files are included."
},
"exclude_paths": {
"type": "array",
"items": { "type": "string" },
"description": "Glob patterns for file paths to exclude. Applied after include_paths."
},
"hot_max_tokens": {
"type": ["integer", "null"],
"minimum": 1,
"description": "Soft cap on the number of tokens in hot (immediate) context. null means no soft cap."
},
"warm_max_decisions": {
"type": "integer",
"minimum": 1,
"description": "Maximum number of decisions retained in warm context."
},
"cold_max_decisions": {
"type": "integer",
"minimum": 1,
"description": "Maximum number of decisions retained in cold context."
},
"query_limit": {
"type": "integer",
"default": 20,
"minimum": 1,
"description": "Maximum number of retrieval results per query against the cold tier."
},
"max_file_size": {
"type": "integer",
"default": 1048576,
"minimum": 1,
"description": "Maximum individual file size in bytes that will be included in context. Default: 1 MB."
},
"max_total_size": {
"type": "integer",
"default": 52428800,
"minimum": 1,
"description": "Maximum aggregate size in bytes across all included files. Default: 50 MB."
},
"summarize": {
"type": "boolean",
"default": false,
"description": "When true, large context segments are automatically summarized rather than excluded."
},
"summary_max_tokens": {
"type": "integer",
"minimum": 1,
"description": "Maximum tokens for each generated summary. Only applies when summarize is true."
},
"strategy": {
"type": "array",
"items": { "type": "string" },
"description": "Ordered list of ACMS context strategies to use for this view. Overrides the global strategy list. Valid built-in values: simple-keyword, semantic-embedding, breadth-depth-navigator, arce, temporal-archaeology, plan-decision-context."
},
"default_breadth": {
"type": "integer",
"minimum": 0,
"default": 2,
"description": "Default number of hops from focus nodes in the UKO graph for context expansion. 0 = focus nodes only."
},
"default_depth": {
"oneOf": [
{ "type": "integer", "minimum": 0 },
{ "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" }
],
"default": 3,
"description": "Default detail depth for context fragments. May be a non-negative integer or a named level string from the active domain's DetailLevelMap (e.g., 'SIGNATURES', 'FULL_SOURCE'). Named levels are resolved to integers via the DetailLevelMap inheritance chain. Default: 3."
},
"depth_gradient": {
"type": "object",
"additionalProperties": {
"oneOf": [
{ "type": "integer", "minimum": 0 },
{ "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" }
]
},
"description": "Per-hop detail depth overrides. Key is the hop distance (0 = focus node), value is an integer depth or named level string. Hops not listed use default_depth."
},
"skeleton_ratio": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"default": 0.15,
"description": "Fraction of the context budget reserved for inherited plan skeleton context. 0.0 = no skeleton inheritance; 1.0 = all budget to skeleton."
},
"temporal_scope": {
"type": "string",
"enum": ["current", "recent", "all"],
"default": "current",
"description": "Temporal scope for UKO node resolution. 'current' = only isCurrent nodes; 'recent' = current + nodes valid within warm retention window; 'all' = include historical versions."
},
"auto_refresh": {
"type": "boolean",
"default": true,
"description": "When true, the ACMS automatically re-assembles context when the available budget changes by more than the refresh threshold (default 30%). When false, context is only assembled on explicit request."
}
},
"required": ["project", "view"],
"additionalProperties": false
}
# ─── Context View Identity ──────────────────────────────────────────
project: <namespace>/<name> # Project this context view applies to (required)
view: default | strategize | execute | apply # Which phase view (required)
# ─── Resource Filtering ─────────────────────────────────────────────
include_resources: # Resources to include (whitelist, optional)
- <resource_name>
exclude_resources: # Resources to exclude (blacklist, optional)
- <resource_name>
# ─── Path Filtering ─────────────────────────────────────────────────
include_paths: # Glob patterns for files to include (optional)
- "src/**/*.py"
- "tests/**/*.py"
exclude_paths: # Glob patterns for files to exclude (optional)
- "**/node_modules/**"
- "**/__pycache__/**"
- "**/.git/**"
- "**/dist/**"
# ─── Token and Size Budgets ─────────────────────────────────────────
hot_max_tokens: <integer> # Soft cap on hot context tokens (optional, null = no limit)
warm_max_decisions: <integer> # Max decisions in warm context (optional)
cold_max_decisions: <integer> # Max decisions in cold context (optional)
query_limit: <integer> # Max retrieval results per query (optional, default: 20)
max_file_size: <integer> # Max file size in bytes to include (optional, default: 1048576)
max_total_size: <integer> # Max total size across all included files (optional, default: 52428800)
# ─── Summarization ──────────────────────────────────────────────────
summarize: true # Enable summarization for large context segments (optional)
summary_max_tokens: <integer> # Token limit for generated summaries (optional)
# ─── ACMS Strategy & Context Assembly ───────────────────────────────
strategy: # ACMS strategies to use (optional, overrides global list)
- simple-keyword
- semantic-embedding
- breadth-depth-navigator
default_breadth: <integer> # Default hop count for UKO graph expansion (optional, default: 2)
default_depth: 3 # Default detail depth — integer or named level (optional, default: 3)
depth_gradient: # Per-hop detail depth overrides (optional)
0: 9 # Focus nodes get depth 9 (FULL_SOURCE for code)
1: 4 # 1-hop neighbors get depth 4 (SIGNATURES for code)
2: 0 # 2-hop neighbors get depth 0 (MODULE_LISTING for code)
skeleton_ratio: <float> # Fraction of budget for inherited plan skeleton (optional, default: 0.15)
temporal_scope: current | recent | all # Temporal scope for UKO node resolution (optional, default: current)
auto_refresh: true # Auto re-assemble context on budget change (optional, default: true)
# context-default.yaml
# Apply: agents project context set --view default --include-path "src/**" \
# --exclude-path "**/node_modules/**" local/api-service
# Or import this file and apply via the CLI.
project: local/api-service
view: default
exclude_paths:
- "**/node_modules/**"
- "**/__pycache__/**"
- "**/.git/**"
max_file_size: 1048576 # 1 MB
# context-strategize.yaml
project: local/api-service
view: strategize
include_resources:
- local/api-repo
exclude_resources:
- local/staging-db
include_paths:
- "src/**/*.py"
- "docs/architecture/**"
- "README.md"
- "pyproject.toml"
exclude_paths:
- "**/node_modules/**"
- "**/test_fixtures/**"
- "**/__pycache__/**"
- "**/migrations/**"
hot_max_tokens: 12000
warm_max_decisions: 50
cold_max_decisions: 200
query_limit: 20
max_file_size: 524288 # 512 KB
max_total_size: 10485760 # 10 MB
summarize: true
summary_max_tokens: 800
# context-execute.yaml
project: local/api-service
view: execute
include_resources:
- local/api-repo
- local/staging-db
include_paths:
- "src/**"
- "tests/**"
- "config/**"
- "scripts/**"
- "Makefile"
- "pyproject.toml"
- "requirements*.txt"
exclude_paths:
- "**/node_modules/**"
- "**/__pycache__/**"
- "**/dist/**"
- "**/*.pyc"
hot_max_tokens: 24000
warm_max_decisions: 100
cold_max_decisions: 500
query_limit: 30
max_file_size: 2097152 # 2 MB
max_total_size: 104857600 # 100 MB
summarize: true
summary_max_tokens: 1200
# context-apply.yaml
project: local/api-service
view: apply
include_paths:
- "src/**"
- "tests/**"
exclude_paths:
- "**/__pycache__/**"
hot_max_tokens: 8000
warm_max_decisions: 20
cold_max_decisions: 50
summarize: false
# context-monorepo-strategize.yaml
project: local/platform
view: strategize
include_resources:
- local/platform-repo
include_paths:
- "packages/auth/**/*.ts"
- "packages/auth/**/*.tsx"
- "packages/shared/**/*.ts"
- "packages/api-gateway/**/*.ts"
- "docs/architecture/**"
- "package.json"
- "tsconfig.json"
- "lerna.json"
exclude_paths:
- "**/node_modules/**"
- "**/dist/**"
- "**/coverage/**"
- "**/*.test.ts"
- "**/*.spec.ts"
- "**/*.stories.tsx"
- "**/fixtures/**"
- "**/__snapshots__/**"
- "**/generated/**"
hot_max_tokens: 16000
warm_max_decisions: 30
cold_max_decisions: 150
query_limit: 15
max_file_size: 262144 # 256 KB - aggressive for a monorepo
max_total_size: 5242880 # 5 MB
summarize: true
summary_max_tokens: 600
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/automation-profile-config.json",
"title": "CleverAgents Automation Profile Configuration",
"description": "Configuration file schema for defining automation profiles — named collections of confidence thresholds (0.0-1.0) and boolean safety flags controlling which operations are automated vs. requiring human approval.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified profile name in <namespace>/<name> format."
},
"description": {
"type": "string",
"description": "Human-readable description of the profile's purpose and behavior."
},
"decompose_task": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically transitioning from Action to Strategize. 0.0 = always automatic, 1.0 = always manual."
},
"create_tool": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically transitioning from Strategize to Execute. 0.0 = always automatic, 1.0 = always manual."
},
"select_tool": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically applying changes after execution completes. 0.0 = always automatic, 1.0 = always manual."
},
"edit_code": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for autonomously making decisions during Strategize. 0.0 = always automatic, 1.0 = always manual."
},
"execute_command": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for autonomously making decisions during Execute. 0.0 = always automatic, 1.0 = always manual."
},
"create_file": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically attempting to fix validation failures. 0.0 = always automatic, 1.0 = always manual."
},
"delete_content": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically revising the strategy when execution reveals issues. 0.0 = always automatic, 1.0 = always manual."
},
"access_network": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically reverting from a constrained Apply phase to Strategize. 0.0 = always automatic, 1.0 = always manual."
},
"modify_config": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically retrying operations that fail due to transient errors. 0.0 = always automatic, 1.0 = always manual."
},
"approve_plan": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically restoring from the most recent checkpoint on failure. 0.0 = always automatic, 1.0 = always manual."
},
"install_dependency": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Confidence threshold (0.0-1.0) for automatically spawning child plans decided during Strategize. 0.0 = always automatic, 1.0 = always manual."
},
"require_sandbox": {
"type": "boolean",
"description": "When true, all write operations must execute within a sandbox. Execution fails if no sandbox strategy is available."
},
"require_checkpoints": {
"type": "boolean",
"description": "When true, checkpoints must be created before any write operation, enabling rollback."
},
"allow_unsafe_tools": {
"type": "boolean",
"description": "When true, tools flagged as unsafe can be invoked. When false, unsafe tool invocations are blocked."
}
},
"required": [
"name",
"description",
"decompose_task",
"create_tool",
"select_tool",
"edit_code",
"execute_command",
"create_file",
"delete_content",
"access_network",
"modify_config",
"approve_plan",
"install_dependency",
"require_sandbox",
"require_checkpoints",
"allow_unsafe_tools"
],
"additionalProperties": false
}
# ─── Profile Identity ───────────────────────────────────────────────
name: <namespace>/<name> # Fully qualified profile name (required)
description: <string> # Human-readable description (required)
# ─── Phase Transition Thresholds ────────────────────────────────────
# Confidence thresholds controlling phase transitions.
# 0.0 = always automatic, 1.0 = always manual.
decompose_task: <float: 0.0–1.0> # Confidence threshold for Action → Strategize (required, 0.0=auto, 1.0=manual)
create_tool: <float: 0.0–1.0> # Confidence threshold for Strategize → Execute (required, 0.0=auto, 1.0=manual)
select_tool: <float: 0.0–1.0> # Confidence threshold for Execute → Apply (required, 0.0=auto, 1.0=manual)
# ─── Decision Thresholds ────────────────────────────────────────────
# Confidence thresholds controlling decisions within each phase.
# 0.0 = always automatic, 1.0 = always manual.
edit_code: <float: 0.0–1.0> # Confidence threshold for decisions during Strategize (required, 0.0=auto, 1.0=manual)
execute_command: <float: 0.0–1.0> # Confidence threshold for decisions during Execute (required, 0.0=auto, 1.0=manual)
# ─── Self-Repair Thresholds ─────────────────────────────────────────
create_file: <float: 0.0–1.0> # Confidence threshold for auto-fixing validation failures (required, 0.0=auto, 1.0=manual)
delete_content: <float: 0.0–1.0> # Confidence threshold for auto-revising strategy when Execute hits constraints (required, 0.0=auto, 1.0=manual)
access_network: <float: 0.0–1.0> # Confidence threshold for auto-reverting from constrained Apply to Strategize (required, 0.0=auto, 1.0=manual)
modify_config: <float: 0.0–1.0> # Confidence threshold for auto-retrying transient errors (required, 0.0=auto, 1.0=manual)
approve_plan: <float: 0.0–1.0> # Confidence threshold for auto-restoring from checkpoints (required, 0.0=auto, 1.0=manual)
# ─── Execution Control Thresholds ──────────────────────────────────
install_dependency: <float: 0.0–1.0> # Confidence threshold for auto-spawning child plans (required, 0.0=auto, 1.0=manual)
# ─── Safety Requirements ────────────────────────────────────────────
require_sandbox: <boolean> # Require sandbox for all write operations (required)
require_checkpoints: <boolean> # Require checkpoint creation before write operations (required)
allow_unsafe_tools: <boolean> # Allow tools flagged as unsafe (required)
# careful-auto.yaml
# Register: agents automation-profile add --config careful-auto.yaml
name: local/careful-auto
description: "Autonomous execution with mandatory sandbox and manual apply"
decompose_task: 0.0
create_tool: 0.0
select_tool: 1.0
edit_code: 0.0
execute_command: 0.0
create_file: 0.0
delete_content: 1.0
access_network: 1.0
modify_config: 0.0
approve_plan: 0.0
install_dependency: 0.0
require_sandbox: true
require_checkpoints: true
allow_unsafe_tools: false
# ci-pipeline.yaml
# Register: agents automation-profile add --config ci-pipeline.yaml
name: local/ci-pipeline
description: "Full automation for CI/CD pipelines. All phases automated, sandbox required."
decompose_task: 0.0
create_tool: 0.0
select_tool: 0.0
edit_code: 0.0
execute_command: 0.0
create_file: 0.0
delete_content: 0.0
access_network: 0.0
modify_config: 0.0
approve_plan: 0.0
install_dependency: 0.0
require_sandbox: true
require_checkpoints: true
allow_unsafe_tools: false
# review-heavy.yaml
# Register: agents automation-profile add --config review-heavy.yaml
name: local/review-heavy
description: "Maximum human oversight. Every decision and phase requires approval."
decompose_task: 0.0
create_tool: 1.0
select_tool: 1.0
edit_code: 1.0
execute_command: 1.0
create_file: 1.0
delete_content: 1.0
access_network: 1.0
modify_config: 1.0
approve_plan: 1.0
install_dependency: 1.0
require_sandbox: true
require_checkpoints: true
allow_unsafe_tools: false
# dev-sandbox.yaml
# Register: agents automation-profile add --config dev-sandbox.yaml
name: local/dev-sandbox
description: "Fast iteration for local development. Relaxed safety, auto execution."
decompose_task: 0.0
create_tool: 0.0
select_tool: 1.0
edit_code: 0.0
execute_command: 0.0
create_file: 0.0
delete_content: 0.0
access_network: 1.0
modify_config: 0.0
approve_plan: 0.0
install_dependency: 0.0
require_sandbox: false
require_checkpoints: false
allow_unsafe_tools: true
# production-deploy.yaml
# Register: agents automation-profile add --config production-deploy.yaml
name: local/production-deploy
description: |
Production deployment profile. Fully autonomous execution
with maximum safety guarantees. All phases require sandbox
and checkpoint. Apply requires manual approval. Strategy
revision is enabled to adapt to deployment issues.
decompose_task: 0.0
create_tool: 0.0
select_tool: 1.0
edit_code: 0.0
execute_command: 0.0
create_file: 0.0
delete_content: 0.0
access_network: 1.0
modify_config: 0.0
approve_plan: 0.0
install_dependency: 0.0
require_sandbox: true
require_checkpoints: true
allow_unsafe_tools: false
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://cleveragents.dev/schemas/lsp-server-config.json",
"title": "CleverAgents LSP Server Configuration",
"description": "Configuration file schema for defining LSP servers registered in the LSP Registry and attached to actors for language intelligence.",
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^([a-zA-Z0-9_-]+:)?[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+$",
"description": "Fully qualified LSP server name in [[server:]namespace/]name format."
},
"description": {
"type": "string",
"description": "Human-readable description of the LSP server's purpose."
},
"languages": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"description": "Programming languages this server supports. Used for language-based and auto-discovery binding resolution."
},
"command": {
"type": "string",
"description": "Shell command to launch the LSP server process. Must support --stdio or equivalent for stdin/stdout JSON-RPC communication."
},
"args": {
"type": "array",
"items": { "type": "string" },
"default": [],
"description": "Additional arguments appended to the command."
},
"env": {
"type": "object",
"additionalProperties": { "type": "string" },
"default": {},
"description": "Environment variables set when launching the server process."
},
"root_path": {
"type": "string",
"default": "{{ project.root }}",
"description": "Workspace root path sent in the LSP initialize request. Supports Jinja2 template variables."
},
"init_options": {
"type": "object",
"additionalProperties": true,
"default": {},
"description": "Initialization options sent in the LSP initialize request. Server-specific; passed through verbatim."
},
"capabilities": {
"type": "array",
"items": {
"type": "string",
"enum": ["diagnostics", "hover", "completions", "references", "definitions", "symbols", "formatting", "code_actions", "rename"]
},
"default": ["diagnostics", "hover", "completions", "references", "definitions", "symbols", "formatting", "code_actions", "rename"],
"description": "LSP capabilities this server advertises. The runtime uses this to determine which tool adapters and context enrichment features are available. Defaults to all capabilities; restrict to a subset if the server does not support certain features."
},
"health_check": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"description": "Whether to perform periodic health checks on the running server process."
},
"interval_seconds": {
"type": "integer",
"default": 60,
"minimum": 10,
"description": "Seconds between health check probes."
},
"restart_on_failure": {
"type": "boolean",
"default": true,
"description": "Whether to automatically restart the server if health checks fail."
},
"max_restarts": {
"type": "integer",
"default": 3,
"minimum": 0,
"description": "Maximum number of automatic restarts before marking the server as failed."
}
},
"additionalProperties": false,
"description": "Health check configuration for the running server process."
}
},
"required": ["name", "languages", "command"],
"additionalProperties": false
}
# ─── LSP Server Configuration ────────────────────────────────────────
# Registered via: agents lsp add --config <this-file>
# Referenced by actors via: lsp: [<namespace>/<name>]
name: <namespace>/<server-name> # Namespaced identifier (required)
description: "..." # Human-readable description (optional)
languages: # Supported languages (required, min 1)
- python
- pyi # e.g., Python stub files
command: pyright-langserver # Launch command (required)
args: # Additional arguments (optional)
- --stdio
env: # Environment variables (optional)
PYTHONPATH: /app/src
root_path: "{{ project.root }}" # Workspace root, Jinja2 supported (optional, default: {{ project.root }})
init_options: # LSP initialize request options (optional)
python.analysis.typeCheckingMode: standard
python.analysis.autoSearchPaths: true
python.analysis.diagnosticSeverityOverrides:
reportMissingImports: warning
reportUnusedVariable: information
capabilities: # Advertised capabilities (optional, default: all)
- diagnostics
- hover
- completions
- references
- definitions
- symbols
- formatting
- code_actions
- rename
health_check: # Health monitoring (optional)
enabled: true # Periodic health probes (default: true)
interval_seconds: 60 # Probe interval (default: 60, min: 10)
restart_on_failure: true # Auto-restart on failure (default: true)
max_restarts: 3 # Max auto-restarts before marking failed (default: 3)
name: local/pyright
description: "Pyright language server for Python type checking and intelligence"
languages:
- python
- pyi
command: pyright-langserver
args: ["--stdio"]
init_options:
python.analysis.typeCheckingMode: standard
python.analysis.autoSearchPaths: true
python.analysis.useLibraryCodeForTypes: true
name: local/ts-server
description: "TypeScript/JavaScript language server"
languages:
- typescript
- javascript
- tsx
- jsx
command: typescript-language-server
args: ["--stdio"]
init_options:
preferences:
includeInlayParameterNameHints: all
includeInlayVariableTypeHints: true
name: local/gopls
description: "Go language server (diagnostics and navigation only)"
languages:
- go
command: gopls
args: ["serve"]
capabilities:
- diagnostics
- hover
- references
- definitions
- symbols
health_check:
interval_seconds: 120
max_restarts: 5
name: local/rust-analyzer
description: "Rust Analyzer language server"
languages:
- rust
command: rust-analyzer
env:
CARGO_HOME: /home/user/.cargo
RUSTUP_HOME: /home/user/.rustup
init_options:
cargo:
allFeatures: true
checkOnSave:
command: clippy