Core Concepts

Execution Model

How an agent call lands, gets proved, and resumes — across blocks.

In one paragraph

Inference on Theseus is never synchronous. A user can’t submit a model call and read the result in the same block — the inference runs off-chain on a prover, the proof has to come back, and the chain has to verify it before any state changes. That’s three stages, three different transactions, spanning multiple blocks. The pattern is borrowed from Substrate’s XCM async model and adapted for AI workloads.
  • Stage 1 (queue): call_agent interprets the agent’s ABG until it hits a model or tool call, then suspends.
  • Stage 2 (prove): an off-chain prover picks up the job and submits a verified result via submit_inference_result.
  • Stage 3 (resume): an inherent-driven on_initialize hook scans verified results and resumes the agent’s ABG with the original caller’s origin.
  • Capability surface: pallet_ship validates every emitted intent against the ABG’s declared capability set. Calls outside that set are rejected.

The three stages

Each stage is a distinct extrinsic with a distinct caller. The chain only verifies what each stage’s extrinsic carries — never raw prover output, never tool results from anyone but the registered enclave.

Stage 1 — Queue (call_agent)

A signed transaction lands in a block. pallet_agents creates an entry in PendingAgentJobs, records the original user origin, and begins interpreting the agent’s ABG. The interpreter advances through synchronous nodes (conditions, sequence, parallel) until it hits a ModelCall or ToolCall.

At that point AIVM queues an inference job and emits InferenceQueued. The agent suspends. The block closes; the user’s transaction is done.

Stage 2 — Prove (submit_inference_result)

An off-chain prover, subscribing to InferenceQueued, picks up the job. It runs the inference, generates a TensorCommitment proof (full prover) or signs the output (lite prover), and submits the result. AIVM verifies the proof via the native KZG host function and marks the job InferenceVerified.

No agent state transitions occur in this stage. The prover’s role is bounded: supply the inference result and the verification material. Nothing else.

Stage 3 — Resume (inherent, block-author-driven)

On every block, an on_initialize hook scans InferenceVerified entries (bounded by a per-block weight budget). For each, the agent loop resumes with the verified result, executing under the original user origin recorded in Stage 1.

The agent continues interpreting the ABG until it either hits another async boundary (back to Stage 1/2) or reaches a terminal node that emits SHIP intents. Intents execute under the same original origin.

Why three stages, not one

The split exists because each stage has a different trust relationship with the chain.

  • The user can submit call_agent but cannot run inference. They’re only authorized to start the work.
  • The prover can run inference and submit proofs but cannot mutate agent state. They’re only authorized to supply verified results.
  • The runtime (via the inherent hook) is the only thing that mutates agent state, and only after KZG verification has passed. State changes are always driven by deterministic on-chain logic, never by prover-controlled extrinsics.

Result: prover compromise can’t change agent state

Even a malicious prover can only submit results for jobs already in the queue, and only results that pass on-chain verification. They can’t synthesize new agent runs, can’t bypass ABG transitions, and can’t emit intents.

What kicks off Stage 1

Agents don’t run on every block — they sit dormant until something wakes them. There are three trigger categories:

Events

On-chain events the agent subscribes to: token transfers, calls from other agents, contract state changes.

Time

Scheduled wake-ups at a specific block height or interval. Cron-shaped.

External users

Anyone calls call_agent with an entrypoint and input.

The original-origin invariant

When call_agent lands in Stage 1, the chain records the caller’s origin. Every later step in that agent’s execution — Stage 2’s prover submission, Stage 3’s ABG resume, the eventual SHIP intents emitted at terminal nodes — runs under that same origin.

That preserves two things:

  • Fee accounting. The agent pays for inference and tools out of its own seus balance (reverse-gas), but user-side fees on the originating call_agent are billed to the original caller.
  • Authorization. SHIP intents that touch other accounts (transfers, contract calls) execute as the original caller, not as the agent. The agent can act on the caller’s behalf only to the extent the caller pre- authorized via the entrypoint.

Capability surface enforcement

An agent’s ABG declares the set of models, tools, sub-agents, and intent types it’s allowed to reference. This capability surface is part of the ABG itself, stored on-chain at registration time.

At every async boundary, AIVM and pallet_tools check that the requested model or tool is in the surface. At every terminal node, pallet_ship validates that emitted intents are inside it. Anything outside the surface is rejected at the runtime layer — the agent cannot exceed its declared capabilities even if the underlying model output suggests doing so.

Per-run limits

Each agent run is bounded so a misbehaving model can’t consume unbounded block weight or storage. The headline numbers:

LimitValue
Max ABG nodes256 per agent
Max steps per run64
Sync steps per tick16
Max messages per run10
Max sub-agent call depth2
Inference retries per node2
Tool retries per node2
Job expiry600 blocks (~1 hour)

Full reference at Network Parameters.

Documentation