Build agents by conversation

You describe the agent as you would brief an assistant: what it should do, which services it may use, how much it may spend. Claude turns that into a spec, creates it on the agent runner, runs it, and reads the run back with every paid call and its receipt. Then you schedule it, change it, publish it as a service, and build a second agent that hires it. The app's builder asks the same questions on eight screens (Build an agent network); in Claude you answer them in words.

Start from a ready-made agent

You: "What ready-made agents are there?"

Claude calls aioum_starters with {}

You see: 12 agent starters and 13 pipelines (… ready to use), the count of ready ones following what is live, then each one's id, name, group, tagline, mode, how many tools it resolves to on your network, a sampleInput (no budget: that is yours), and available, which is false, with the missing categories named, when the network has no live listing of a kind the starter needs. The ids are morning-brief, token-scanner, swap-router, best-rate-swap, bridge-quote, prediction-odds, wallet-watch, news-digest, community-poster, tune-machine, and two workflows that need no AI, price-check and fear-greed-log.

You: "Create the morning brief, but cap it at 2 dollars."

Claude calls aioum_agent_create with { "starter": "morning-brief", "spec": { "budget": { "capUsdc": 2, "perRunMaxUsdc": 0.25 } } }

You see: Created agent Morning crypto brief (agent_…) from starter morning-brief. The starter's name, instructions, mode, tools and steps are copied; anything in spec replaces them, and spec.budget with both caps is required: without it the tool answers Set the budget you are willing to spend: spec.budget.capUsdc (the lifetime cap) and spec.budget.perRunMaxUsdc (the most one run may spend), in USDC, both above zero and sends nothing.

Prompt first

You: "Make me a 1 minute cartoon clip similar to South Park. Twenty-five dollars."

Claude calls aioum_super with { "prompt": "Make me a 1 minute cartoon clip similar to South Park", "budgetUsdc": 25 }

You see: Created super agent 1 minute cartoon clip similar to South Park (agent_…): plans with a local model on the runner (qwen2.5:7b) (qwen2.5:7b on your node (7B tier) over Planner Ollama · llama3.2 (3B tier)); project "Make me a 1 minute cartoon clip similar to South Park" (proj_…) with 7 stages; started, follow it with aioum_project_get. The record carries the agent (fully loose on services, skills and data, payAcross on, the budget as both caps), the project with the stages its planner proposed (proposed names the planner and, for a listing, the plan run and its cost), and the planner with its kind (marketplace, key or local), label and why. start: false leaves it a draft to look at; planner picks one yourself ("marketplace:<serviceId>", "anthropic", "openai"). Without budgetUsdc the tool answers Set the budget you are willing to spend: budgetUsdc, in USDC, above zero.

Build one from words

You: "Build me an agent that reports Ethereum gas and the top three coins by market cap. Two sentences, numbers first. At most 25 cents a run, 5 dollars lifetime. It may use other services if it needs to, but never service 12."

Claude calls aioum_tools with { "q": "gas" } and { "q": "markets" } to find the service ids, then aioum_agent_create with:

{
  "spec": {
    "name": "Gas and price brief",
    "description": "ETH gas and the top coins, in one paragraph.",
    "instructions": "Report ETH gas and the top three coins with 24h change. Two sentences.",
    "mode": "assistant",
    "tools": [
      { "serviceId": "7", "tool": "gasPrice" },
      { "serviceId": "3", "tool": "markets" }
    ],
    "access": "prefer",
    "deny": ["12"],
    "budget": { "capUsdc": 5, "perRunMaxUsdc": 0.25 }
  }
}

You see: the new agent's card: its id (agent_…), name, mode, access, how many tools and steps it has, its budget, schedule and published state, runs: 0 and spentUsdc: 0. aioum_agent_get with { "id": "agent_…" } shows it in full, instructions and tool list included. Agents are created under the server's AIOUM_OWNER, and aioum_agents lists that owner's agents.

The spec's fields are the builder's eight screens. mode is assistant (an AI model reads the instructions and picks tools) or workflow (fixed steps, no AI). tools are serviceId and tool pairs from aioum_tools. access is how an assistant picks: only (the listed tools and nothing else), prefer (those first, then anything it finds on the marketplace) or open (no picks; it finds everything itself). deny lists service ids it must never use, in any mode. budget is the lifetime cap and the cap per run, in USDC, enforced by the runner outside the AI; both are required to create and never filled in. Optional: planner (auto, anthropic, openai, or marketplace with plannerService { "serviceId", "tool": "plan" }, a planner listing anyone runs, paid per turn), outputTemplate and a schedule. A tool on your private node is { "serviceId": "local", "tool": "ws.write" }, free. skills lists skill ids from aioum_skills (an index id, or svc:<serviceId> for one listed on a node) and skillsAccess says how it reaches them, only, prefer (default) or open; data is { "memory": [ids], "files": [paths] } from your node with dataAccess the same three ways. payAcross (default true) lets the wallet on your node swap what it holds into USDC at the best rate when the runner's wallet is short for a call; false fails the call instead. The runner adds learnedSkills, what the agent kept on its own, and boughtSkills, one-time skills it paid for (Skills).

A workflow spec names its steps instead of tools; step arguments use {{input}} for the run's text and {{steps.0.text}} (or a field of a JSON result, {{steps.0.result.bitcoin.usd}}) for earlier results:

{
  "spec": {
    "name": "Price check",
    "mode": "workflow",
    "steps": [
      { "title": "Fetch the price", "tool": { "serviceId": "3", "tool": "price" },
        "args": { "ids": "{{input}}", "vs": "usd" } }
    ],
    "outputTemplate": "{{input}}: {{steps.0.text}}",
    "budget": { "capUsdc": 2, "perRunMaxUsdc": 0.05 }
  }
}

An assistant needs a planner: a planner listing on the marketplace, or a key or local Ollama on the runner. aioum_planners lists the listings and says what the runner has of its own. A workflow runs without any.

Run it and read the receipts

You: "Run it."

Claude calls aioum_agent_run with { "id": "agent_…", "input": "" }

The tool waits for the run to finish, up to timeoutSeconds (default 300), and returns the whole run.

You see: Run run_… done in 14s: spent 0.004 USDC over 2 paid calls, then the run: its status (done, failed or stopped), trigger, input, output, planner, the steps in order, spendByService and receipts. Each step has its kind: thought (the planner's reasoning summary), status (its one sentence on what it is about to do), tool (the tool as Service:tool, its args, the result, costUsdc, ms, and a doing line for a person), skill (a skill loaded, with its price when listed), search (when the agent looked for a tool itself), info (each session settled, what was paid and what was refunded), rating, and final. To follow a run while it is going, aioum_run_watch with { "runId": "run_…" } returns each step as it lands, then the spend per service; aioum_spend with { "agentId": "agent_…", "period": "24h" } adds an agent's spend up per service and per day (Watch it work). The receipts are one per service the run paid: serviceName, sessionId, depositedUsdc, spentUsdc, settled, the settlement txHash, and the rating the agent gave the operator with its ratingTx. A run still going at the timeout comes back as it stands, with timedOut: true and a note to fetch it later with aioum_run_get.

Look back

You: "Show me the last five runs of that agent, and the full log of the one that failed."

Claude calls aioum_runs with { "agentId": "agent_…", "limit": 5 }, then aioum_run_get with { "runId": "run_…" }

You see: the runs newest first with their status, trigger (manual, schedule or service, the last meaning another agent hired it), spentUsdc, calls and error; then the one run in full, steps and receipts included. aioum_run_stop with { "runId": "run_…" } stops a run in progress; its open sessions settle and the unspent deposits refund.

Put it on a schedule

You: "Run it every hour with 'Give me the brief.'"

Claude calls aioum_agent_schedule with { "id": "agent_…", "everyMinutes": 60, "input": "Give me the brief.", "enabled": true }

You see: Agent Gas and price brief runs every 60 minutes., with the agent's id and its schedule. Runs it starts have trigger: "schedule". To pause it, Claude sends { "id": "agent_…", "enabled": false }; enabled is the one field the tool always needs.

Change it

You: "Raise the per-run cap to 50 cents."

Claude calls aioum_agent_update with { "id": "agent_…", "spec": { "budget": { "capUsdc": 5, "perRunMaxUsdc": 0.5 } } }

You see: the agent's card with the new budget. The fields in spec replace the agent's; send the whole budget object, both numbers, and the whole tools list when you change either.

Publish it

You: "Publish it as a service at 5 cents a call."

Claude calls aioum_agent_publish with { "id": "agent_…", "priceUsdc": 0.05 }

You see: Published agent Gas and price brief as service #41 at 0.05 USDC/call., with the agent's id and its published block: the listing's serviceId, its key (agent-gas-and-price-brief-…), priceUsdc, category (agent:gas-and-price-brief), the nodeUrl that serves it and at. The stack's catalogue node stakes for the listing (stakeZai of its own; unset, 10,000 when its wallet holds that much, else 100, live once backers bring the total to 10,000) and registers it on-chain with its own wallet; your key signs nothing. The listing has one tool, named after the agent in lowercase with dashes: gas-and-price-brief. On a real chain the node accepts these listings only when started with AIOUM_ADMIN_ALLOW_ADD=1, and the server needs AIOUM_NODE_TOKEN when the node's admin API has one.

A second agent that hires the first

You: "Now build an agent that asks the brief for its report every morning and emails it to me in three bullets."

Claude calls aioum_agent_create with a spec whose tools include the published listing:

{
  "spec": {
    "name": "Morning mail",
    "instructions": "Ask the brief service for its report, then rewrite it as three bullets.",
    "mode": "assistant",
    "tools": [{ "serviceId": "41", "tool": "gas-and-price-brief" }],
    "access": "only",
    "budget": { "capUsdc": 10, "perRunMaxUsdc": 0.5 },
    "schedule": { "everyMinutes": 1440, "input": "Today's report.", "enabled": true }
  }
}

You see: the second agent's card. When it runs, it pays the first agent's price per call with a receipt like any other service, and the first agent runs with trigger: "service", paying for its own tools from its own budget and keeping the difference; aioum_runs shows both runs. An agent cannot hire itself, and a published agent never finds its own listing in a search.

Take it off the market, or delete it

You: "Unpublish the brief and delete the mail agent."

Claude calls aioum_agent_unpublish with { "id": "agent_…" }, then aioum_agent_delete with { "id": "agent_…" }

You see: Unpublished agent Gas and price brief. with published: null, its listing gone from the marketplace, then Deleted agent agent_…. Deleting an agent that is still published is refused with "unpublish this agent before deleting it". aioum_agents, with an optional owner, lists what is left.

Next: Pick up a pipeline by conversation — which pipelines are ready, what the others need, one call to build the network and start the job.