Skip to main content

Architecture

Circuit architecture diagram showing user lifecycle, transaction lifecycle, and how agent code interacts with the execution layer, policy engine, and blockchain.

Sessions

A session is a running instance of an agent on a specific wallet. Starting an agent creates a session that ties together your run/unwind functions, a wallet, an execution mode (auto or manual), and the user’s asset allocations. Sessions persist across execution cycles - your run function is called repeatedly at intervals, not just once.

Session Lifecycle

Execution Flow

Each time your agent executes:
  1. Circuit sends a run or unwind command to your agent
  2. The SDK creates a fresh AgentContext with session data
  3. Your run function is called with the AgentContext
  4. Your code executes using SDK methods
  5. Results are returned to Circuit
  6. In manual mode, card-backed money actions become suggestions for user approval; actions without a suggestion card are rejected

The Run Loop

Circuit calls your run function according to the [[triggers]] you declare in circuit.toml. Every agent has exactly one schedule trigger - the guaranteed periodic wake - and may add reactive triggers (for example a price move) that wake it early:
With align = "rolling", the interval starts after the previous run completes - not from the start of execution. With align = "fixed", runs align to clock boundaries instead (e.g. every 60 minutes at :00, every 15 minutes at :00, :15, :30, and :45). Each cycle is independent: your function receives a fresh AgentContext each time. To persist state between cycles, use Memory.

Run Function

Unwind Function

Called when a user wants to unwind. Read the session allocation inside the function; it may be a subset of total wallet holdings.
After unwind completes, the session ends.

Run Duration

A run is stopped after 5 minutes with no calls to Circuit. The clock measures your own code’s silence, not elapsed time since the run started — so it resets on every call you make, including agent.log and reads like agent.allocation. Waiting on Circuit does not count against it. While a bridge settles, a swap confirms, or an order fills, the SDK is polling Circuit for you, so a multi-step run is free to take as long as its venues need. A sequence like “bridge to Hyperliquid, then eight mainnet swaps” is bounded by those venues, not by a budget on your run. What does spend the clock is your own code going quiet: a sleep, a hang, or a long local computation that makes no Circuit calls. If you need to wait locally for more than 5 minutes, do the waiting across runs instead — return, and let your next schedule trigger pick up where you left off. Two outer limits exist so a stuck agent cannot run forever. A run is stopped after 2 hours and an unwind after 15 minutes, whatever it is doing. These are backstops, not budgets to plan against — a run that reaches one is a bug worth reporting.
Stopping a run never cancels work Circuit has already accepted. A broadcast transaction, a settling bridge, and a filling order all continue to completion and appear in your activity feed, even if the run that started them ended first.

Modes

Configured via allowedExecutionModes in circuit.toml:
  • auto - Transactions execute immediately
  • manual - Card-backed money actions become suggestions for user approval; actions without a suggestion card are rejected
For card-backed methods, your code is identical in both modes. Circuit routes the request based on the session’s mode, and a manual response includes suggested and suggestionId fields.
All pending suggestions are automatically soft-deleted at the beginning of each run execution. Pass an expiresAt timestamp (ISO 8601) to supported suggestion-producing methods if you need a shorter expiry window.
For full details on modes, see Manual vs Auto Mode.

Pausing and Resuming

Users can pause a running agent from the Circuit dashboard. While paused:
  • The session stays open and asset allocations remain in place
  • No run cycles are executed - the agent is effectively idle
  • Memory and session state are preserved
When the user resumes, Circuit queues one immediate run cycle and then returns to the configured trigger schedule. No data is lost. Pausing is useful when a user wants to temporarily halt an agent during volatile market conditions or while reviewing activity, without fully unwinding positions.

Key Points

  • Multiple agents per wallet - a wallet can run different agents simultaneously (Hyperliquid agents included). However, the same agent cannot run twice on the same wallet.
  • Shared Hyperliquid collateral - multiple Hyperliquid agents can share a wallet, each allocated a slice of its USDC collateral. They share account-level liquidation risk (the account nets their positions), so manage exposure accordingly.
  • Session memory persists across run cycles within a session, but is cleared when the session ends.
  • agent.allocation is the session’s immutable invocation-start virtual allocation; the next invocation gets a fresh snapshot.
  • Uncaught exceptions in run or unwind are caught by the SDK automatically. The execution is marked as failed and the error is logged.

See Also