Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Advisory Decisions

Advisory decisions let you embed typed AI judgment into a spell while keeping execution deterministic, auditable, and safe. Every advisory has a schema, a timeout, and a fallback — so the spell always has a path forward even if the model is unavailable.

How It Works

advise → model call → schema validation → bind result
                    ↓ (on failure)
                 fallback value

The advisory output is validated against a declared schema. If validation fails (or the model times out), the fallback value is used instead.

Define an Advisor

Add an advisors section to your spell:

spell SmartRebalance {
  advisors: {
    risk: {
      model: "anthropic:claude-haiku-4-5-20251001"
      system_prompt: "Return JSON only. No prose."
      timeout: 20
      fallback: false
    }
  }

  venues: {
    aave: @aave_v3
    morpho: @morpho_blue
  }

  params: { amount: 50000 }

  on manual: {
    decision = advise risk: "Given current rates, should we rebalance USDC from Aave to Morpho?" {
      context: {
        balance: balance(USDC)
        amount: params.amount
      }
      within: "execution"
      output: {
        type: object
        fields: {
          allow: boolean
          reason: string
        }
      }
      on_violation: reject
      timeout: 20
      fallback: { allow: false, reason: "timeout" }
    }

    if decision.allow {
      aave.withdraw(USDC, params.amount)
      morpho.lend(USDC, params.amount)
    } else {
      emit skipped(reason=decision.reason)
    }
  }
}

Advisory Block Fields

FieldRequiredDescription
outputYesDeclares the expected output type and schema
timeoutYesSeconds before fallback is used
fallbackYesValue used when model is unavailable or times out
contextRecommendedNamed runtime expressions passed to the model
withinRecommendedPolicy scope label for audit
on_violationRecommendedreject or clamp on schema mismatch (default: reject)
clamp_constraintsConditionalRequired when on_violation: clamp

Output Schema Types

# Boolean
output: boolean

# Number with bounds
output: { type: number, min: 0, max: 100 }

# Enum
output: { type: enum, values: ["buy", "sell", "hold"] }

# Object
output: {
  type: object
  fields: {
    allow: boolean
    max_slippage_bps: { type: number, min: 1, max: 500 }
    reason: string
  }
}

Safe Execution Path

Validate in strict mode

Strict mode turns advisory warnings (missing context, within, on_violation) into failures:

Terminal
grimoire validate spells/smart-rebalance.spell --strict

Simulate to record advisory outputs

Terminal
grimoire simulate spells/smart-rebalance.spell --chain 1

The model runs during simulation. Outputs are recorded in the run ledger.

Dry-run with recorded decisions

Terminal
grimoire cast spells/smart-rebalance.spell \
  --dry-run \
  --chain 1 \
  --key-env PRIVATE_KEY \
  --rpc-url <rpc>

Live cast with advisory replay

Replay the exact advisory outputs from the simulation run — no model call needed:

Terminal
grimoire cast spells/smart-rebalance.spell \
  --chain 1 \
  --key-env PRIVATE_KEY \
  --rpc-url <rpc> \
  --advisory-replay <runId>

Inspecting Advisory Events

Terminal
grimoire log spells/smart-rebalance.spell <runId>

Look for these events in the ledger:

EventMeaning
advisory_startedAdvisory step began
advisory_model_usedModel call succeeded
advisory_completedOutput validated and bound
advisory_failedModel/schema failure, fallback used

Troubleshooting

Advisory output violated schema — align the model's output (or fallback) with the declared output schema.

--advisory-replay requires state persistence — remove --no-state from the replay command.

Advisory step enables clamp but has no clamp_constraints — add clamp_constraints: [max_slippage] when using on_violation: clamp.