Skip to main content

Run an autonomous agent

Fork V6 introduces agentic mining: a miner runs a multi-step loop with tool calls (web search, chain queries, math), emitting one AGENT_STEP tx per iteration. You pay only for tokens actually generated — billing is per-token with escrow + refund.

Lifecycle

USER MAINNET MINER
[AGENT_REQUEST] │ │
├─ escrow maxFee (default 1 OMBRA) ───────────►│
├── P2P broadcast ──────────────►│
│ [agent listener]
│ ├─ AGENT_CLAIM
│ ├─ loop:
│ │ LLM call w/ tools
│ │ AGENT_STEP × N
│ └─ AGENT_FINISH
│◄───────────────────────────── │
│ settle: minerReward, refund │

Billing constants

ConstantValueMeaning
AGENT_REWARD_PER_TOKEN1 micro0.000001 OMBRA per output token
AGENT_NETWORK_FEE_PER_STEP100 micro0.0001 OMBRA per AGENT_STEP tx
CHAT_TURN_FEE100 microPublic chat message fee

maxFee is escrowed at request time. At finish:

  • minerReward = totalTokensOut × AGENT_REWARD_PER_TOKEN
  • networkFee ≈ steps × AGENT_NETWORK_FEE_PER_STEP
  • userRefund = maxFee − minerReward − networkFee (returned to submitter)

Available tools

A miner advertises which tools it implements. The user picks a subset (whitelist). Common tools:

  • Chain readchain_get_balance, chain_get_height, chain_get_block, chain_get_tx, chain_list_nfts, chain_recent_blocks, chain_list_validators
  • Utilitiesnow, date_parse, date_diff, math_eval, regex_match
  • Webweb_search, fetch_url

The full list is enumerated by GET /api/agent/v6/tools on the miner's local IPC (not exposed publicly).

Example: agent run

import {
OmbraClient, Wallet,
buildAgentRequestTx,
computeAgentRunId, computeConversationId,
MICRO_OMBRA,
} from "@ombrachain/sdk";

const client = new OmbraClient({ endpoint: "https://api.ombra-net.com" });
const wallet = Wallet.fromMnemonic("...");

const acct = await client.chain.getAccount(wallet.address);
const runId = computeAgentRunId(wallet.address, acct.nonce, "What's my balance?");
const convId = computeConversationId(wallet.address);

const tx = buildAgentRequestTx(wallet.address, {
agentRunId: runId,
conversationId: convId,
prompt: "What's my balance and how many NFTs do I own?",
toolsWhitelist: ["chain_get_balance", "chain_list_nfts"],
maxFee: BigInt(MICRO_OMBRA), // 1 OMBRA escrow
maxSteps: 100,
}, acct.nonce, wallet.privateKey);

await client.chain.submitTx(tx);

// Poll status + steps
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 2000));
const res = await fetch(`https://api.ombra-net.com/api/agent/v6/run/${runId}`);
if (!res.ok) continue;
const run = await res.json();
if (run.status === "completed") {
console.log("answer:", run.finalAnswerInline);
console.log("tokens:", run.totalTokensOut, "reward:", run.minerReward, "refund:", run.userRefund);
break;
}
}

Browser flow via window.ombra

If you're building a dApp, use the Ombra Wallet extension instead of holding private keys:

const result = await window.ombra.request({
method: "ombra_submitAgentRequest",
params: {
prompt: "What's my balance?",
toolsWhitelist: ["chain_get_balance"],
maxFee: "1000000",
maxSteps: 50,
},
});
console.log("agentRunId:", result.agentRunId);

The extension opens an approval popup with prompt + escrow details, then signs with the user's wallet.

See Recipes › Submit agent run for full SSE streaming + step rendering.