Early Access. Commands and behavior can change between releases.
agent(prompt) starts one and resolves to its final text, so
running ten reviewers at once is await parallel([...]): ordinary code, with the agents doing the
thinking.
You don’t need a flag or a keyword. Architech uses a workflow on its own when the work has a
shape: the same operation over a list, or independent pieces that could run at once. Save that
shape in your repo and you can run it by name.
A workflow you can run
Save this as.architech/workflows/review-changed.js:
.architech/workflows/review-changed.js
Background runs
Ask Architech to run a workflow in the background when you have other work to do. It starts the workflow withrun_in_background: true, gets a job_id, and receives the result when it finishes.
It can read the status or full result again with Workflow({ job_id: "workflow-1" }) without
starting the agents again.
In an interactive session, Ctrl+Shift+B sends running foreground workflows to the background.
Their agents keep running; nothing restarts. Your terminal must send this key combination as its
own key.
The last 50 finished background results stay available in the current session. Restarting or
switching sessions drops the handles, not the agents already in the fleet list. Use the fleet list
to inspect or stop single agents; Jobs doesn’t list background workflow results.
When a workflow is the right tool
Reach for one
The same operation repeats over a list · independent readers can run at once · each item flows
through the same few stages · you want to run it again next week without retyping it.
Don't
The work is one question: ask it directly · each step depends on what the last one found · you’d
be writing the analysis into the script instead of letting the agents do it.
agent() call is a full model run with its own context, so
a workflow that fans out five ways costs about five times one agent, plus the merge. That’s worth it
when five agents read five different things, and a waste when you split a question with one
answer.
The script is control flow, not analysis. Keep it short; let the agents think.
Where workflows live
.architech/workflows/ are ordinary source files: commit them, review them in a pull
request, share them with your team. Use .js for new workflows. Architech also picks up existing
.ts files, but their bodies must still be plain JavaScript.
The meta block
A saved workflow declares a meta object so it can be listed and described without being run.
Architech reads
meta by pattern; it doesn’t run it. So two things matter:
- Write it at the top level as
export const meta = { … }, with the closing}at the start of its own line. - Give
nameanddescriptionplain string literals: not a variable, not a template with a substitution in it.
meta is left out of the list, not run, and /workflows says how many
it skipped. Architech never runs a file in .architech/workflows/ just to find out what it is.
Running one
args:
args
args arrives in the script as Architech passed it (an object or list sent as a JSON string is
decoded first). It’s what makes a script reusable, so read it at the top and give it a shape you
can rely on:
The script API
A script can use these six things and nothing else: norequire, no timers, no file system, no
network.
Return a value from the top level and it becomes the workflow’s result.
console is available for
debugging.
agent(prompt, opts)
Workflow agents are sub-agents like any other: they appear in the
fleet list alongside anything you started by hand.
Failure is a value, not an exception
- An
agent()whose run fails resolves to a string beginning[agent failed: …]. Your script keeps going, and can branch on it. - An
agent()that runs past its time limit resolves to[agent timed out: …]. The agent itself keeps running in the fleet list. A late result replaces the timeout marker only when the thunk or stage returns that marker unchanged and itsparallel()orpipeline()is still waiting. A directawait agent(), a transformed marker or an already-returned combinator is not retroactively updated just because the rest of the workflow is still running. - A thunk that throws inside
parallel()becomesnullin that slot; the others are unaffected. - A stage that throws inside
pipeline()drops that item tonull; the other items keep flowing. - A script that throws, or has a syntax error, fails the run, never the session, and every agent it had already dispatched is still reported.
[agent never started: …] when its queue-wait limit is
reached. So check for null, [agent failed:, [agent timed out: and [agent never started:
before feeding a result into the next prompt.
Two rules
Math.random() and Date.now() throw
Both are removed inside a workflow, and calling either fails the run with a message saying so.
A workflow should be re-runnable: the same script with the same args should describe the same
run. A script that rolls a die or reads the clock takes a different path each time, and its record
no longer matches what it would do again. If you need a seed or a timestamp, decide it outside
and pass it in through args:
new Date() is not blocked, but it has the same problem. Take the time from args too.Label every agent
The live view names each row byopts.label. Give every agent() call a label that says which
piece of work it is:
What a run looks like
A workflow shows as a live row that fills in as it runs. Phases open and close, each agent gets a line with its state and run time, and the last line sums up the run.
Past eight agents in a phase, extra rows are counted (
+ 4 more), never dropped. On a narrow
terminal the block folds into fewer, denser lines without losing information. The row stays in
your transcript after the run ends.
Limits
- One agent gets ten minutes by default, counted from when it starts, not while it waits in the
queue. After that its call stops waiting and resolves to a timed-out string; the agent is not
stopped, and the rest of the run continues. Change it per call with
timeoutMs. - The run itself is not time-limited. It ends when the script returns. Agents still running at that point are named in the result and keep running in the fleet list.
- No resumable workflow history is persisted. The result and its digest live in the transcript; background handles live only in this session. Running a workflow again runs it from the top.
- A workflow cannot reach the disk or the network itself. Only the agents can, through their own tools.
- If sub-agents aren’t available, the workflow refuses up front and says why, instead of
hanging on its first
agent()call.architech --primehas noWorkflowtool; workflows run in normal orchestrator and agent sessions.
Sub-agents
The fleet list and the viewer, where a workflow’s agents show up.