Run the shipped example
Four runnable assemblies ship in the repository. Running one end to end takes two commands, and it leaves a record you can read afterwards.
A run calls a model provider and costs money. Set up a credential first: Providers, models, and credentials.
Name the assembly and the flow
Section titled “Name the assembly and the flow”An assembly holds one or more flows. A flow is one procedure from start to finish. A run names both.
The four assemblies in examples/ use these names.
| Assembly | Flow | What it does |
|---|---|---|
hello |
greet |
Turns a joining note into a three-sentence welcome for a new teammate. |
triage |
triage |
Sorts an inbound customer request into an urgent or a routine queue and writes the routing memo. |
brief |
brief |
Turns a week of short team notes into one digest with a title and a tag list. |
outline |
plan |
Plans a report from a rough topic, section by section. |
Only triage repeats its own name. Typing the assembly name twice for the other three names a flow that does not exist, and bot refuses the folder.
A target that begins with /, ./, or ../ is a path on disk. Anything else is a name the home already holds.
Check before you run
Section titled “Check before you run”Run this from examples/.
$ bot assembly check ./triage/triageflows/triage/FLOW.md flow-definition type=FLOW flow=flows/triage max_subflow_calls=1001-classify STAGE flow=flows/triage input=request.txt output=classify.json options=intelligence=default,provider=google,model=gemini-3.5-flash-lite,reasoning=low,timeout=300,retries=1,local-context=ignore02-route CHOOSE flow=flows/triage input=- output=- options=intelligence=default,provider=google,model=gemini-3.5-flash-lite,reasoning=low,timeout=120,retries=1,local-context=ignore02-route/routine/01-routine STAGE flow=flows/triage input=classify.json output=routine.txt options=intelligence=default,provider=google,model=gemini-3.5-flash-lite,reasoning=low,timeout=120,retries=2,local-context=ignore02-route/urgent/01-urgent STAGE flow=flows/triage input=classify.json output=urgent.txt options=intelligence=default,provider=google,model=gemini-3.5-flash-lite,reasoning=low,timeout=120,retries=2,local-context=ignore03-verify STAGE flow=flows/triage input=routine.txt output=verify.txt options=intelligence=default,provider=google,model=gemini-3.5-flash-lite,reasoning=low,timeout=3600,retries=1,local-context=ignore possible_inputs=routine.txt,urgent.txt$ echo $?0The first line is the flow definition. Each line after it is one node the run could reach, in the order you wrote them. CHOOSE marks a branch point, and both of its branches are listed because either could run.
The provider, model, and reasoning values are whatever your own config.yaml names under default, so yours will differ. This paste was taken against a home whose default is google / gemini-3.5-flash-lite / low. Everything else is the assembly.
03-verify follows the choice, so it carries two input fields. input holds the files that arrive together, which is one branch’s output. possible_inputs holds the union of what could arrive. A node that only ever receives one set of files prints input alone.
The command returns 20 rows at a time. A larger assembly does not fall off the end silently. Bot then writes More assembly stages remain. Continue with --after <cursor>. to standard error, so it can arrive before the rows on your screen and stays out of a redirected file. Passing that cursor to --after returns the next page. --limit N changes the page size, up to 200.
Run it
Section titled “Run it”There are three ways to hand over the request.
bot run start ./triage/triage "our checkout has been down since Friday"bot run start ./triage/triage @data/request-urgent.txtcat data/request-routine.txt | bot run start ./triage/triagedata/request-urgent.txt and data/request-routine.txt ship beside the examples. The first names a deadline and takes the urgent branch. The second is a billing question and takes the routine one.
The routing memo lands on standard output. Piping it into another program works unchanged.
--in DIR sets the directory where the run starts work. It defaults to your current directory. Use a worktree or another intended directory when you do not want the current directory used.
What the exit code means
Section titled “What the exit code means”| Exit | What happened | What to do |
|---|---|---|
0 |
The flow finished and the answer passed its checks. | Use the answer. bot run output RUN --raw gives it back any time after. |
1 |
It ran and the work did not pass. | Read the record. bot run list prints the cause in one word beside the code. |
2 |
The run was impossible. | Read standard error. If a record exists, it says where. |
128+n |
Something outside killed it. A run stopped by a signal exits 128 plus the signal’s number. |
Read the record like any other ending. |
When it refuses or fails covers each of these in turn.
Find the record
Section titled “Find the record”Every run leaves a self-contained directory holding the request, a copy of the assembly it ran, what each stage was told, what each stage produced, and what judged it.
bot run listbot run events RUNbot run output RUN --rawbot run list prints one row per run. RUN is any unique prefix of a run’s name.
Reading a record says which reading answers which question.
Next: write your own.