Documentation Index
Fetch the complete documentation index at: https://docs.circuit.org/llms.txt
Use this file to discover all available pages before exploring further.
Directory Structure
<agent-name>/
├── main.py # Agent code (run/unwind functions)
├── DESCRIPTION.md # Agent description (shown in Circuit UI)
├── circuit.toml # Agent configuration
├── pyproject.toml # Dependencies
├── AGENTS.md # AI coding assistant context
└── CLAUDE.md # Claude compatibility pointer
<agent-name>/
├── index.ts # Agent code (run/unwind functions)
├── DESCRIPTION.md # Agent description (shown in Circuit UI)
├── circuit.toml # Agent configuration
├── package.json # Dependencies
├── tsconfig.json # TypeScript compiler settings
├── AGENTS.md # AI coding assistant context
└── CLAUDE.md # Claude compatibility pointer
Agent Code
from agent_sdk import Agent, AgentContext
from agent_sdk.agent_context import CurrentPosition
def run(agent: AgentContext) -> None:
agent.log("Hello from my agent!")
# Your agent logic here
def unwind(agent: AgentContext, positions: list[CurrentPosition]) -> None:
agent.log(f"Unwind requested for {len(positions)} positions")
# Optional unwind logic
agent = Agent(run_function=run, unwind_function=unwind)
run Function
- Signature:
def run(agent: AgentContext) -> None:
- Called periodically based on
runtimeIntervalMinutes
- Receives
AgentContext with session data and SDK methods
- Returns
void (no return value)
- Signature:
async function run(agent: AgentContext): Promise<void>
- Called periodically based on
runtimeIntervalMinutes
- Receives
AgentContext with session data and SDK methods
- Returns
void (no return value)
unwind Function
- Signature:
def unwind(agent: AgentContext, positions: list[CurrentPosition]) -> None:
- Called when you ask the agent to unwind positions
- Optional unwind logic for the provided positions
- Returns
void (no return value)
- Signature:
async function unwind(agent: AgentContext, positions: CurrentPosition[]): Promise<void>
- Called when the agent is unwound
- Optional unwind logic for the provided positions
- Returns
void (no return value)
DESCRIPTION.md
Every agent must include a DESCRIPTION.md file alongside circuit.toml. This Markdown file is displayed to users in the Circuit UI.
## Summary
A brief description of what your agent does and the value it provides to users.
## Strategy
Explain the core logic and decision-making process your agent follows. Include details on which protocols it interacts with, what conditions trigger actions, and how it manages positions.
## Risks
Outline the key risks users should understand before starting a session. Consider market risk, smart contract risk, liquidity risk, and any other factors that could result in loss of funds.
## Changelog
- **0.0.1** — Initial release.
circuit.toml
The circuit.toml file defines your agent’s metadata, asset requirements, execution settings, and deployment configuration. It must be in the root of your agent directory.
Full Example
name = "My Agent" # max 32 characters
tagline = "Short subtitle for cards" # max 32 characters
category = "experimental"
imageUrl = "https://cdn.circuit.org/agents/default"
walletType = "ethereum"
allowedExecutionModes = ["manual", "auto"]
runtimeIntervalMinutes = 15
schedule = "rolling"
filesToInclude = []
filesToExclude = []
[startingAsset]
network = "ethereum:1"
address = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
minimumAmount = "10000000000000000"
[settings.risk_level]
description = "How aggressively the agent trades"
type = "single_select"
default = "medium"
required = false
options = ["low", "medium", "high"]
Field Reference
| Field | Type | Required | Description |
|---|
name | string | Yes | Display name shown in the Circuit UI (32 characters or less). Cannot be changed after first publish — see Agent Identity below. |
tagline | string | Yes | Brief subtitle shown on agent cards (32 characters or less) |
category | string | No | Catalog category for the explore page. Allowed values: "spread", "prediction", "narrative", "quant", "yield", "experimental". Defaults to "experimental". |
imageUrl | string | No | Agent icon URL. Defaults to "https://cdn.circuit.org/agents/default". |
walletType | string | Yes | "ethereum" or "solana" |
allowedExecutionModes | string[] | Yes | Array of "auto" and/or "manual". First entry is the default for circuit dev run --hosted. |
runtimeIntervalMinutes | number | Yes | How often run() is called (in minutes). By default, the interval starts after the previous run completes. See schedule to align runs to clock boundaries instead. |
schedule | string | No | "rolling" (default) or "fixed". "rolling" runs again after the last run completes. "fixed" aligns runs to clock boundaries (for example :00, :15, :30, :45). Requires runtimeIntervalMinutes to divide evenly into 60. |
filesToInclude | string[] | No | Extra files/directories to upload (for monorepo setups). Relative paths from agent directory. |
filesToExclude | string[] | No | Files in agent directory to exclude from upload. |
deploymentRegionOverride | string | No | Override deployment region. Allowed values: "us-east-1" or "eu-central-1". Defaults to "us-east-1". |
settings | table | No | Configurable settings users can customize when starting a session. See [settings] below. |
Deployment Regions
| Allowed values | Default when omitted |
|---|
us-east-1, eu-central-1 | us-east-1 |
[startingAsset] Section
Defines the token a user must hold to start a session.
| Field | Type | Required | Description |
|---|
network | string | Yes | Network identifier (e.g., "ethereum:1", "solana", "hypercore:perp") |
address | string | Yes | Token contract address. For native tokens: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" (EVM) or "11111111111111111111111111111111" (Solana). For Hyperliquid perps: "USDC". |
minimumAmount | string | Yes | Minimum balance in raw units (wei, lamports, etc.). For hypercore:perp + USDC, use 8 decimal places (Circuit raw units; matches Hyperliquid USDC weiDecimals). |
Common Configurations
EVM agent with ETH on mainnet:
walletType = "ethereum"
[startingAsset]
network = "ethereum:1"
address = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
minimumAmount = "10000000000000000" # 0.01 ETH
EVM agent with USDC on Polygon:
walletType = "ethereum"
[startingAsset]
network = "ethereum:137"
address = "0x2791bca1f2de4661ed88a30c99a7a9449aa84174"
minimumAmount = "10000000" # 10 USDC (6 decimals)
Solana agent with SOL:
walletType = "solana"
[startingAsset]
network = "solana"
address = "11111111111111111111111111111111"
minimumAmount = "100000000" # 0.1 SOL (9 decimals)
Hyperliquid perps agent:
walletType = "ethereum"
[startingAsset]
network = "hypercore:perp"
address = "USDC"
minimumAmount = "100000000" # 1 USDC (8 decimals)
Agent Identity
Your agent’s identity on Circuit is derived from its name. Once you run circuit publish, the name is used to generate a permanent slug that links all future publishes, version history, sessions, and state to that agent. Changing the name after publishing will create a brand-new agent — the original agent and all its history will remain under the old name.
If you need to rename a published agent, create a new agent with the desired name and re-publish. The old agent can be left as-is or removed from the dashboard.
[settings] Section
Define configurable settings that users can customize when starting a session. Each setting is a TOML table under [settings.X] where X is the setting key. The display label is auto-derived from the key (snake_case to Title Case).
[settings.strategy]
description = "Which strategy the agent uses"
type = "single_select"
default = "conservative"
required = false
options = ["conservative", "aggressive"]
[settings.slippage_tolerance]
description = "Maximum slippage tolerance"
type = "percentage"
default = 0.5
required = false
[settings.buy_amount_usd]
description = "USD amount per buy order"
type = "number"
default = 50.0
required = false
[settings.max_orders_per_day]
description = "Maximum buy orders per day"
type = "integer"
default = 3
required = false
[settings.auto_compound]
description = "Automatically reinvest rewards"
type = "boolean"
default = true
required = false
[settings.treasury]
description = "Fee collection wallet"
type = "address"
default = "0x1234567890abcdef1234567890abcdef12345678"
required = false
[settings.api_key]
type = "text"
required = true
description = "Your API key for the external service"
Required settings have no default value. Users must provide a value before the agent runs. The agent will refuse to execute if any required settings are missing.
Setting fields:
| Field | Type | Required | Description |
|---|
description | string | No | Help text shown to users (max 200 characters) |
type | string | Yes | One of "text", "boolean", "single_select", "integer", "number", "percentage", "address" |
default | varies | Conditional | Default value — must match the type (see below). Required when required = false; not allowed when required = true. |
required | boolean | Yes | Whether users must provide a value. When true, no default is allowed; the agent will not run until a value is set. |
options | string[] | Conditional | Required for single_select; not allowed for other types |
Type rules:
| Type | Default value | Options |
|---|
text | String (max 1000 characters) | Not allowed |
boolean | true or false | Not allowed |
single_select | String matching one of the options | Required (max 20 options) |
integer | Whole number | Not allowed |
number | Any number (decimals allowed) | Not allowed |
percentage | Number between 0 and 100 (decimals allowed) | Not allowed |
address | Wallet address string (validated against walletType) | Not allowed |
Limits:
- Maximum 20 settings per agent
- Maximum 20 options per
single_select setting
- Options must be unique within a setting
- Setting keys must be unique across all settings
- Setting keys cannot be numeric (e.g.
0, 3.14) — use a descriptive name instead
- Default values for
single_select must match a valid option
Settings are displayed to users in the order they appear in the file.
Settings are snapshotted with each published version — changing settings requires a new publish.
At runtime, resolved setting values (defaults merged with session overrides) are available on AgentContext. See Settings SDK Reference for access patterns.
Notes
- The
version field follows semver. You must increment it before each circuit publish — publishing will fail if the version is not greater than the previously published version.
filesToInclude paths are relative to the agent directory. Use ../../utils to include shared code from a monorepo root. See Multi-Agent Monorepo.
.circuit is reserved for CLI-managed staging during local runs. Do not store agent source files under .circuit or point filesToInclude at that directory.
allowedExecutionModes order matters — the first entry is used as the execution mode for circuit dev run --hosted.
Next Steps