465d7e1-dirty — 36 tools, exactly as
the model is offered them. The description column is the description the model
reads, verbatim: these are not documentation about the tools, they are the
prompt.
5 of them spend money and are marked ⚠. Those are withheld until
somebody presses Start, and gated again on the way through. See the tool server.
Tools that spend
arm_schedule ⚠
Put a schedule live NOW, rather than letting a chain arm it when the stage before it succeeds. From this moment it fires unattended and SPENDS REAL FUNDS every time. Prefer letting a chain arm it: that way nothing recurs until the setup it depends on actually worked.
decide_firing ⚠
Answer a scheduled run that could NOT START because the owner already had a task in flight. One task runs per owner at a time. run_now takes the slot as soon as it frees — not ‘try again now’, because the slot is busy. skip drops this firing only. Unanswered, it is dropped after a week.
place_order ⚠
Wait for a PRICE, then run a pipeline that is ALREADY SAVED. The trigger a schedule is to a clock. It holds no signature and compiles a fresh plan each time it fires, which is why one can rest for days without going stale — and why nothing is signed until the price is actually there. Use it for “buy X at Y”, “sell when it reaches Y”, and for unwinding a loan at a price: point it at a swap.router, loan.close or loan.shift plan. By default a short fill is ACCEPTED: it takes what the block will give, records it, and comes back for the rest. A STOP-LOSS is direction “at_or_below”; add trail_bps to make it trail the market up. A TAKE-PROFIT is the default “at_or_above”. Point either at the entry with protects and it sells only what that entry actually bought.
run_pipeline ⚠
MAKE A SAVED PIPELINE RUN. This SPENDS REAL FUNDS. It is the ONE tool for that, and it works out WHICH of three things you meant by reading the run — you do not choose: nothing has run it STARTS the revision as authored the run stopped it RESUMES from the steps that already settled, at the same revision, and does not replay them the run completed it REPEATS — copies the plan to the next revision and runs the whole thing again. It REFUSES once first and tells you the number to pass back, because that is a second position rather than a repair something is in flight it does nothing and says what is happening So “run it”, “run it again”, “resume it” and “continue it” are all THIS tool with the same arguments. Do NOT save a new revision to get a stopped run moving, and do NOT author the plan under a new task id: both re-execute what has already been paid for.
start_chain ⚠
Begin a saved chain. This SPENDS REAL FUNDS: it runs the first once-stage immediately. A stage that ends stuck stops the chain and arms nothing after it.
Tools that do not spend
cancel_order
Stop a resting order for good. What it already filled stays filled — this stops it firing again, it does not undo anything. Refused while a run is in flight, because cancelling the row cannot recall a transaction.
check_allowance
What the OPERATING ADDRESS may draw from the owner, and whether that covers an amount. A deposit.pull step needs TWO things and they fail differently: the tokens have to be held by the owner, and the account has to have PERMISSION to draw them. get_balances answers the first. This answers the second. Pass amount — in the asset’s own base units, so 500 USDC is “500000000” — to ask whether the allowance covers a draw of that size. Without it this only reports what is currently approved, and nothing is offered to fix. WHEN IT IS SHORT the console puts an Approve button in front of the person for exactly the gap. Tell them what it is for; you cannot press it. An approval moves no money — the tokens stay in their wallet and the account gains permission to draw them — and it is the owner’s signature, not this server’s. validate_pipeline already checks this for the pulls in a plan. Use this one when there is no plan yet, or when somebody asks about an allowance directly.
check_supported
FIRST, before anything else: check that the assets, chains and operations the person actually named are supported. Someone asks for DAI or for something on Solana and the answer is no — better known now than after a plan is built on it.
find_skill
ASK YOUR QUESTION HERE FIRST. Returns the ANSWER — the handful of sections that address it, from across every guide, each cited by file and line. Not a list of names to go and read: the text you need comes back in this one call. Ask in the words a person used — “only fill if the price is right”, “unwind a loan without selling first” — and it searches the prose AND the exact identifiers. Prefer this to read_skill, which returns whole documents and costs several times as much for the same answer. Call with no query to see the whole shape of what exists.
forget_run
GIVE UP a run that stopped part-way, so this owner can start something else. It spends nothing and it is not an undo. DO NOT CALL THIS ON YOUR OWN INITIATIVE. It is the one destructive verb you hold: it throws away a record of somebody’s money that cannot be put back, and no refusal you are reading is permission to use it. Call it ONLY when the person has said, in their own words and in this conversation, to give that run up — abandon it, drop it, forget it, get rid of it. said carries those words and the call is refused without them. If they have not said it, ASK; a refusal you cannot get past is a thing to report, not a thing to clear. NEVER AFTER stop_run, in the same breath. Stopping and giving up are two different decisions and the person has made only the first: a run that has just been stopped is one they may still want to carry on. Calling this because stop_run appeared to change nothing is the exact mistake it exists to prevent — stop is SUPPOSED to leave the slot held. THIS IS NOT STOP. stop_run ends a run and deliberately leaves it holding the owner’s slot — that is what makes stop-then-run-again a pause. A run that stopped part-way holding settled steps BLOCKS every other start for that owner, on purpose, so a second position is never opened against a wallet the first is still holding. This removes the run record, which is the thing doing the blocking. Use it when a stranded run is refusing a start and that run is genuinely finished with. If it should be carried on instead, say run it again and run_pipeline continues it — do not forget it first. NOTHING ON CHAIN IS UNDONE, and the settled steps stay settled: they are keyed on the task and revision, not on the record this removes, so running the task again still continues from them rather than replaying them.
get_account_state
Show the owner and the operating address — the account the agent operates and every plan spends from — and what each currently holds. Call this before deciding any amount.
get_balances
Read several asset balances for several holders at once. Pass “chain” to read somewhere other than base. Holders are roles: owner_account (the OPERATING ADDRESS, which is what every plan spends from), owner_wallet (the OWNER), or a plain 0x address. Pass the owner — the operating address is derived from it.
get_bridge_cost
What to SEND so that a wanted amount lands after a crossing, or what a given amount will deliver. Call it whenever a plan bridges. DO NOT WORK THIS OUT IN PROSE. A crossing keeps a fee, so sending exactly what the far side spends lands short and the run stops AFTER the money has already crossed — and the near miss is the common one: a gross-up rounded to the nearest cent is short by a fraction, which reads as correct and is not. Every “short 0.1 USDC” refusal is this arithmetic done by hand. Give must_arrive to size a crossing, which is the usual direction: it returns the exact integer for the bridge step’s Amount. Give sending to check an amount already written. Raw units both ways.
get_chain
Read a CHAIN: an ordered arrangement of pipelines, which runs once and which recurs, plus where a running one has got to. A strategy is rarely one plan — a setup that runs once and a loop that runs monthly are edited and approved on different rhythms. Call this before changing one.
get_fill_at_price
AT THIS PRICE, HOW MUCH FILLS RIGHT NOW. The question a limit order is made of, and the one the ladder cannot answer: get_tradeable_size tells you what a COST buys, this tells you what a PRICE buys. Call it before place_order whenever somebody names a price. An order for 40k is not wrong, but the person should know it before it rests for a week — and if nothing fills, that is a real answer rather than an error: the price asked for is better than the market. Measured across every pool, which is what a plan here executes. The price is a PAIR of raw amounts, never a decimal.
get_lending_rates
WHAT EVERY MARKET CHARGES RIGHT NOW: supply APY, borrow APY, how much of it is already borrowed, and the loan-to-value at which it liquidates. Aave v3’s reserves are enumerated FROM THE POOL, so it covers every asset Aave lists and not only the ones this system has a name for; Aave v4’s from its hub; Morpho’s are the curated markets. Call it before choosing a venue to borrow from, before quoting anybody a rate, and before assuming two venues cost the same — they routinely differ by more than a point on the same asset on the same chain. ASK ONCE, FOR EVERYTHING THE PLAN TOUCHES. chains and assets are lists: a plan lending XAUt on ethereum and cbBTC on base is ONE call, {“chains”:[“ethereum”,“base”],“assets”:[“XAUt”,“cbBTC”]}. Narrowing to one pair at a time is a round trip per pair and was measured costing three calls for one plan. Omitting both is also fine and returns every market on every chain.
get_lp_yield
BEFORE providing liquidity: what a range would have COLLECTED, from each pool’s real daily history, on every chain and fee tier at once. Answers the three questions a spot APY cannot — which network, which fee tier, and which range. An advertised APY is the last 24 hours across a pool’s whole book. This walks history a day at a time: the pool’s fees that day, times your liquidity over the pool’s, and ZERO on days the price left your band. A band that looked excellent was in range 19% of one window and idle for the rest, which no APY anywhere says. PASS EVERY RANGE YOU ARE WEIGHING IN ONE CALL. ranges is a list and each costs nothing extra, against a round trip per range otherwise. Omit it to get the widest band that held the price, which is the ceiling a narrower one is measured against. A range is “so many QUOTE per one BASE”. With one stablecoin that is dollars per coin and needs no thought; on WBTC/WETH or USDC/USDT set priced_in, because 25-40 and 0.025-0.04 are the same band from opposite ends. The direction used is always reported. IT ALSO ANSWERS WHAT YOU END UP WITH. Every answer carries a CASH IN HAND block: what the deposit is worth at the end, the impermanent loss, and the total against simply holding. Report that, not the fee figure alone — fees are half a ledger and people read them as the outcome. Still not modelled: compounding, rebalancing and gas. For “what if the price keeps going” pass exit_prices; for “what if I enter at X and leave at Y” pass entry_price and exit_price. A band traversed end to end sells every coin at the GEOMETRIC MEAN of its bounds, not at the price the asset finished at, and then stops earning — which is why a fast run to the top of a band is a bad outcome and not a good one. Fees are NET of Uniswap’s protocol fee, which the UNIfication vote switched on during 2026 — a quarter of the swap fee on the 0.01% and 0.05% tiers, a sixth on 0.3%. The subgraph’s own feesUSD is gross, so these figures are deliberately lower than a reader’s own arithmetic against it. REPORTING THE ANSWER, because this has been got wrong: the window DEFAULTS TO TWO YEARS, so name the window you actually got — the answer states its own length in days and years on the first line. The table gives two different rates: total is the return over the WHOLE window and per year is that annualised. Quoting total as an annual rate doubles it on a two-year window, which is exactly what happened to a 48.9% two-year figure reported as 48.9% a year. per year is an APR and NOT an APY: v3 keeps a position’s fees in a separate balance, so nothing compounds unless the owner collects and re-adds it by hand.
get_orders
What is resting, what filled, and in how many bites. A partially filled order is working, not failing — it took what the price would give and is waiting for the rest.
get_pipeline
Read back a pipeline that was saved, with its revision history AND whether a run of it has started, is in flight, or has STOPPED. Call this BEFORE changing a plan you did not just write, and before running one again: a revision cannot be edited in place, so a change means resending the whole document at the next revision, and reconstructing it from memory is how steps go missing.
get_positions
WHAT THIS OWNER ALREADY OWES AND HAS SUPPLIED, read from each venue rather than from any record this system keeps. Covers Aave v3, Aave v4 and Morpho, on every chain, for BOTH the operating address and the owner’s own wallet — they are separate borrowers and a debt on either is a real debt. Call this before any borrow, any repay, any loan shift, and before saying anything about what somebody holds. A position is the only thing that says whether a borrow can succeed: get_lending_rates says what it would cost, which is a different question.
get_prices
USD prices, from whichever source can answer for the asset. A tradeable asset (USDC, cbBTC, WETH) is quoted through the POOLS a swap would route through — the price you would actually get. A property token has no market and is quoted from 0xequity’s oracle, which is the price its OCLR router transacts at. This prices ONE UNIT; for a size that matters use get_swap_cost, which prices that size. PASS EVERY ASSET YOU CARE ABOUT IN ONE CALL. assets is a list and the cost of adding to it is one quote each, against a round trip per call otherwise — a plan touching four assets asked four times and spent four turns learning what one would have told it. Each asset is priced on EVERY chain that carries it, one row per chain, because the same token is not the same price in two places: WETH quoted 2492 on base within a second of each other. An asset absent from some chains is still priced on the ones that have it, and the others are named under it — so XAUt answers with its ethereum price rather than with the fact that Base does not carry it.
get_run_status
Report how a submitted pipeline is going, step by step.
get_schedule
Read a SCHEDULE — the recurring trigger attached to one pipeline — with its next dates and what became of past firings. A firing marked BLOCKED is waiting for a person and will be dropped if nobody answers.
get_swap_cost
What a specific trade will actually cost, all in — and what a BOUND would do to it before you write one into a plan. JUDGE A TRADE ON cost_vs_best_spot_pips, never on price_impact_pips: impact is measured against the route this quote chose and excludes the pool fee, so at size it can FALL while the trade gets more expensive. If cost_vs_best_spot_pips comes back null that means UNMEASURED, not free — read read_this, which says what to do instead. Call this before committing to an amount a person will care about. Send max_impact_bps or cost_bps to ask what that bound leaves: both shrink the offer, and offered_amount_in beside amount_in is the answer. Neither is slippage — slippage never changes the trade, only the floor it must clear.
get_tick_range
Turn a PRICE RANGE into the tick_lower and tick_upper a Uniswap V3 mint takes. Call it for every uni.* or flash.* step that carries ticks. DO NOT WORK TICKS OUT IN PROSE. Between a price and a tick sit a logarithm, a DECIMALS adjustment, the pool’s tick spacing and Uniswap’s own token ordering — which is by address, so it cannot be guessed from the symbols. Only the spacing reverts when it is wrong. Forget the decimals term on WETH/USDC and the tick is out by about 276,310: a valid int24 that mints happily, at prices nobody asked for, holding one token and earning nothing. It reports the prices the rounded ticks actually mean, which are never exactly the ones asked for. Say those back to the person.
get_tradeable_size
THE INVERTED QUESTION, and the one an order is actually made of: not “what does this size cost” but “what size costs at most N basis points”. Returns a size per cost level, in one call. Use it before choosing any large amount, and before offering to split an order into tranches — whether splitting helps depends on the pair and this is what decides it. Read saturated (the size is a floor, not a maximum) and pools_answered (levels measured over different pool counts are not on the same curve) before believing a number.
get_uni_positions
THE UNISWAP POSITIONS THIS OWNER ALREADY HOLDS — token id, pair, fee tier, price band and uncollected fees, read from the position manager on each chain. get_positions is LENDING and does not cover these. Call this before writing any plan that acts on a position the person already has: uni.decrease, uni.collect and every revert.* step take a position_id, and it is a token id that cannot be guessed or derived. Asking the person for it is the wrong move when this answers it. Reads the operating address AND the owner. A position pledged as collateral is NOT listed — the Revert vault holds the NFT while the loan is open, so the position manager reports it as the vault’s.