Skip to content

Choosing a Surface

lionagi's CLI has several orchestration surfaces. They are layered, not competing: each one buys you something over the previous layer and costs something in latency and setup. This page is the decision guide; per-flag detail lives in the CLI Reference.

The decision table

Your task shape Reach for Why
One question, one answer li agent MODEL "prompt" Single turn, no planning overhead
Follow-up on earlier work li agent -r BRANCH_ID / -c Resumes the branch with full context
Same role used often li agent -a NAME Profile carries model, effort, system prompt, yolo
N independent subtasks, same shape li o fanout Decompose → parallel workers → optional synthesis
Subtasks depend on each other li o flow Planner builds a DAG; engine runs legs as dependencies clear
A pipeline you run repeatedly li play NAME Playbook = named, parametric, version-controlled flow
A well-known domain pipeline li engine run KIND Prebuilt research / review / coding / hypothesis / planning engines
Run it later, or on a cadence li schedule create Cron, interval, or repo-event triggers
Script must wait for a scheduled run to finish li monitor run ID Takes a schedule-run ID; blocks until terminal state, exit code reflects outcome
Watch progress live li monitor --watch Live table or per-run detail view
Agents messaging each other across runs li team Persistent shared inbox
Group many runs into one record li invoke One parent invocation row grouping N session rows

Sizing: don't pay for structure you don't need

Each layer adds a planning or coordination step that costs real wall-clock time before any work starts. The single most common misuse is reaching for a heavier surface than the task shape needs:

  • 1 legli agent. Never li o flow — you would pay a planner turn to produce a one-node DAG.
  • 2–3 independent legsli o fanout, or just two li agent calls in parallel from your own script. Fanout's decomposition phase only earns its cost when you want the orchestrator to choose the split.
  • 3+ legs with dependenciesli o flow. This is the break-even point: below it the planner turn dominates; above it dependency-aware parallelism wins.
  • The same flow, more than twice → promote it to a playbook and use li play. The point of a playbook is that the second invocation is one short command with typed args — not that the first one is faster.

The corollary: li play feeling slow is usually a shape problem, not an engine problem. A playbook wrapping a 2-leg task inherits the full plan-then-execute cycle. Check the DAG with --dry-run — if it plans one or two nodes, drop down a layer.

Composition patterns

The surfaces are designed to chain:

# Recurring pipeline: schedule an agent turn on a cron. Create prints
# the schedule ID; trigger and runs take that ID, not the name.
SCHED=$(li schedule create nightly-audit --cron "0 6 * * *" \
  --action-kind agent --agent auditor --model sonnet \
  --prompt "run the nightly audit" | awk '/^Created:/ {print $2}')

# Fire it now, then list its firings — each row carries a run ID and
# outcome. (Direct `li play` runs are watched with `li monitor --watch`.)
li schedule trigger "$SCHED"
li schedule runs "$SCHED"

# Copy a run ID from that listing, then block until it goes terminal
li monitor run "$RUN_ID" && echo "audit done"

# One dashboard row for a multi-run skill
INV=$(li invoke start --skill release-check --prompt "v0.28 gate")
li play backend  --invocation "$INV"
li play frontend --invocation "$INV"
li invoke end "$INV" --status completed

# Resume a worker that a fanout or flow left unfinished
li agent -r BRANCH_ID "pick up where you left off"

Two rules of thumb for choosing the chain:

  1. Automate the trigger before automating the pipeline. If you find yourself re-typing the same li play invocation daily, the next step is li schedule, not a bigger playbook.
  2. Poll the surface, not the filesystem. li monitor and li monitor run read the same state the engine writes; tailing run directories or sleeping in shell loops re-implements them badly.

What each layer persists

All surfaces share one state database, but what each writes differs:

  • li agent / li o fanout / li o flow / li play write a run directory under ~/.lionagi/runs/ (branch snapshots, stream buffers) plus session rows in the state database. A flow or fanout leg is a branch you can resume with li agent -r.
  • li engine run writes an engine-run row and its session rows to the state database only — no run directory.
  • li invoke writes one parent invocation row; the runs you attach to it keep their own persistence.
  • li schedule create writes schedule metadata; each firing records a schedule run, listed by li schedule runs ID.

Because the state database is shared, anything you start on one surface is observable from the others, and escalating a task to a heavier surface never orphans the work the lighter one already did.