What you can say
The parser tolerates many phrasings. The load-bearing fields are which token and how much; everything else has a sensible default.| input | how it parses |
|---|---|
create a position with 0.05 ETH passively | capital + risk profile, fully specified |
LP some USDC | token only - asks how much USDC? |
provide liquidity 1000 USDC ETH/USDC 5bps | pinned pair + fee tier |
open ETH/USDC position with 1.5 ETH stay long ETH | pinned pair + exposure preference |
create a position | both missing - asks which token and how much? |
passive,safe,cautious,defensive→ conservativebalanced,moderate→ balancedaggressive,active,yolo,degen,spicy→ aggressive
stay long ETH,keep my X,hold my X→ exposureBias=long-token (range shifted so capital token sits more in the position)- default → neutral (centered on current price, ~50/50 deposit)
What happens
- Goal extraction: parser fills
createGoal. Missing capital triggers one clarification turn. - CLI sends
flow_create_startto Scout (or runs the in-process orchestrator if AXL nodes aren’t visible). - Scout calls
discoverPools(chainId)- real on-chain probe of the v4 PoolManager via StateView. Returns initialized pools with non-zero liquidity, ranked by liquidity descending. Per-pool: vol, yield estimate, regime classification. - Strategist proposes 2-5
(poolIndex, widthMultiplier, centerOffset, exposureBias)candidates. The LLM picks proportions; deterministic helpers snap totickSpacingand compute deposit amounts viaallocateForCreate. - Critic runs deterministic stress (1×, 2×, 3× vol) per candidate and judges against the user’s risk profile. Vetoes weak candidates, asks for revisions, accepts winners.
- On accept: emits
plan_readywithkind: "create". CLI shows the prepared mint action and waits forapprove it. - On deadlock after
ZUNO_MAX_DEBATE_ROUNDS: Arbiter picks one candidate from the latest proposal with explicit reasoning. apply itbuilds the v4 mint viabuildMint, signs through Turnkey, submits. The new tokenId becomes visible after one confirmation ininspect my positions.
Example
Pool universe
Pool discovery is real and dynamic. Zuno enumerates every(token0, token1, feeTier) combination from its token registry,
computes the deterministic v4 pool id for each, and reads
StateView.getSlot0 + getLiquidity to confirm initialization.
Unknown tokens (anything not in the registry) are excluded. To extend:
add the token to packages/chain/src/tokens/constants.ts.
To force a re-probe:
~/.zuno/pools-{chainId}.json with a 30-min TTL.
Risk-profile floors
The Critic’s veto thresholds are keyed to your risk profile:| profile | min base buffer | max gas/yield | tiebreak axis |
|---|---|---|---|
| conservative | 36h | 1.2× | largest 2× vol buffer |
| balanced | 24h | 1.6× | best buffer × yield |
| aggressive | 14h | 2.4× | highest yield non-vetoed |
ZUNO_RISK_PROFILE=conservative|balanced|aggressive.
Without the mesh
If the four AXL agent peers aren’t visible, the CLI runs the same four handlers in-process viarunDebateCreate. If OPENAI_API_KEY is also
unset, set ZUNO_DETERMINISTIC=true to use the deterministic fallback
shapes. Pool discovery doesn’t need an LLM.