<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Building Workflows on Dwarf</title><link>https://docs.dwarf.run/building-workflows/</link><description>Recent content in Building Workflows on Dwarf</description><generator>Hugo</generator><language>en-US</language><atom:link href="https://docs.dwarf.run/building-workflows/index.xml" rel="self" type="application/rss+xml"/><item><title>Building Graphs</title><link>https://docs.dwarf.run/building-workflows/graphs/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/graphs/</guid><description>&lt;h1 id="building-graphs"&gt;Building Graphs&lt;a class="anchor" href="#building-graphs" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; defining workflows. This is the graph-authoring API: the tasks, transitions, conditions
and &lt;a href="https://docs.dwarf.run/concepts/#reducer"&gt;reducers&lt;/a&gt; that decide what runs when. Writing the task bodies themselves is &lt;a href="https://docs.dwarf.run/building-workflows/tasks/"&gt;Writing Tasks&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;A &lt;code&gt;workflow.Graph&lt;/code&gt; is the definition of a workflow. You build one in code and hand it to the engine via
your host&amp;rsquo;s &lt;code&gt;LoadGraph&lt;/code&gt;. This guide covers the full graph-authoring API.&lt;/p&gt;
&lt;h2 id="tasks"&gt;Tasks&lt;a class="anchor" href="#tasks" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A graph is a set of tasks connected by transitions. Bind a task with &lt;code&gt;SetURL&lt;/code&gt;, giving a &lt;strong&gt;task name&lt;/strong&gt;
(its identity in the graph) and a &lt;strong&gt;URL&lt;/strong&gt; (the address your host&amp;rsquo;s &lt;code&gt;ExecuteTask&lt;/code&gt; resolves to reach it):&lt;/p&gt;</description></item><item><title>Writing Tasks</title><link>https://docs.dwarf.run/building-workflows/tasks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/tasks/</guid><description>&lt;h1 id="writing-tasks"&gt;Writing Tasks&lt;a class="anchor" href="#writing-tasks" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; writing the code that runs inside a workflow. It covers the &lt;code&gt;workflow.Flow&lt;/code&gt; carrier a
task receives: reading and writing state, the control signals, and handling failure. The graph that decides
&lt;em&gt;which&lt;/em&gt; task runs is &lt;a href="https://docs.dwarf.run/building-workflows/graphs/"&gt;Building Graphs&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;A task is a function your host&amp;rsquo;s &lt;code&gt;ExecuteTask&lt;/code&gt; runs. It receives a &lt;code&gt;*workflow.Flow&lt;/code&gt; — the carrier holding the
step&amp;rsquo;s state and control signals — does its work, writes outputs back onto the flow, and returns. This
guide covers the Flow API a task uses.&lt;/p&gt;</description></item><item><title>Building a Host</title><link>https://docs.dwarf.run/building-workflows/building-a-host/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/building-a-host/</guid><description>&lt;h1 id="building-a-host"&gt;Building a Host&lt;a class="anchor" href="#building-a-host" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; putting Dwarf behind a real application. It turns
&lt;a href="https://docs.dwarf.run/operating/data-handling/#access-control-is-the-hosts-job"&gt;Access Control Is the Host&amp;rsquo;s Job&lt;/a&gt; into code.
Read &lt;a href="https://docs.dwarf.run/getting-started/"&gt;Getting Started&lt;/a&gt; first for the two-method &lt;code&gt;Host&lt;/code&gt; interface.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;The engine has no notion of a caller: no authentication, no authorization, no tenants. Every access decision
belongs to the layer you build around it. This page builds that layer for a multi-tenant service, as one
type, &lt;code&gt;App&lt;/code&gt;, that is three things at once:&lt;/p&gt;</description></item><item><title>Tasks in Other Languages</title><link>https://docs.dwarf.run/building-workflows/other-languages/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/other-languages/</guid><description>&lt;h1 id="tasks-in-other-languages"&gt;Tasks in Other Languages&lt;a class="anchor" href="#tasks-in-other-languages" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; whose tasks are, or need to be, written in a language other than Go. Read
&lt;a href="https://docs.dwarf.run/building-workflows/tasks/"&gt;Writing Tasks&lt;/a&gt; first: everything there about state, outputs and errors
still applies, only the transport changes.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;The Dwarf engine is written in Go, and so is the &lt;a href="https://docs.dwarf.run/how-dwarf-works/#the-pieces"&gt;host&lt;/a&gt; that embeds it.
Your tasks don&amp;rsquo;t have to be. The host decides how each task is reached, so it can just as well call a
service written in Python, TypeScript, Java or anything else, over HTTP or any other transport. Graphs are
JSON too (&lt;code&gt;workflow.Graph&lt;/code&gt; marshals to and from JSON), so &lt;code&gt;LoadGraph&lt;/code&gt; can fetch them from a service in any
language as well.&lt;/p&gt;</description></item><item><title>Fan-Out &amp; Subgraphs</title><link>https://docs.dwarf.run/building-workflows/fan-out-and-subgraphs/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/fan-out-and-subgraphs/</guid><description>&lt;h1 id="fan-out--subgraphs"&gt;Fan-Out &amp;amp; Subgraphs&lt;a class="anchor" href="#fan-out--subgraphs" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; building workflows that branch. Both features here are graph-authoring plus task-side
API, so read &lt;a href="https://docs.dwarf.run/building-workflows/graphs/"&gt;Building Graphs&lt;/a&gt; and &lt;a href="https://docs.dwarf.run/building-workflows/tasks/"&gt;Writing Tasks&lt;/a&gt; first.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Two features let a workflow do more than a straight line: &lt;strong&gt;fan-out/fan-in&lt;/strong&gt; runs work in parallel and
merges the results, and &lt;strong&gt;subgraphs&lt;/strong&gt; call another workflow as a child.&lt;/p&gt;
&lt;h2 id="fan-out"&gt;Fan-Out&lt;a class="anchor" href="#fan-out" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A fan-out runs several branches concurrently from one task. There are two kinds.&lt;/p&gt;</description></item><item><title>Driving Flows</title><link>https://docs.dwarf.run/building-workflows/flows/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/flows/</guid><description>&lt;h1 id="driving-flows"&gt;Driving Flows&lt;a class="anchor" href="#driving-flows" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; integrating Dwarf into an application. This is the reference for the calls your code
makes against a running engine — starting flows, reading them back, resuming and terminating them, and
managing retention. It assumes you have an engine configured; standing one up in production is
&lt;a href="https://docs.dwarf.run/operating/"&gt;Operating Dwarf&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Every interaction with a flow is a method on &lt;code&gt;*engine.Engine&lt;/code&gt;. They fall into a few groups: creating &amp;amp;
running, inspecting, pausing &amp;amp; resuming, terminating &amp;amp; recovering, continuing, and retention. Flows are
addressed by their &lt;strong&gt;flow key&lt;/strong&gt; (&lt;code&gt;{shard}-{hour}-{flowID}-{token}&lt;/code&gt;), returned at creation; steps by their &lt;strong&gt;step
key&lt;/strong&gt; (&lt;code&gt;{shard}-{hour}-{flowID}-{stepID}-{token}&lt;/code&gt;), which names its flow too.&lt;/p&gt;</description></item><item><title>Detecting Completion</title><link>https://docs.dwarf.run/building-workflows/detecting-completion/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/detecting-completion/</guid><description>&lt;h1 id="detecting-flow-completion"&gt;Detecting Flow Completion&lt;a class="anchor" href="#detecting-flow-completion" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; whose application needs to know when a flow finished — to answer an HTTP request, send a
notification, or trigger downstream work. It explains the three ways to learn a flow&amp;rsquo;s outcome and when to
use each.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;There are three ways to learn a flow&amp;rsquo;s outcome, and they suit different situations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Await&lt;/code&gt;&lt;/strong&gt; — block a live caller until the flow stops, then read the outcome.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Poll&lt;/code&gt;&lt;/strong&gt; — &lt;code&gt;Await&lt;/code&gt; with a bounded wait: on a ctx timeout it returns the flow&amp;rsquo;s &lt;em&gt;current&lt;/em&gt; outcome instead
of an error, so a caller whose own deadline is shorter than the flow can answer now and ask again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Orchestration&lt;/strong&gt; — model the follow-up work as tasks inside a workflow that calls the real work as a
&lt;a href="https://docs.dwarf.run/building-workflows/fan-out-and-subgraphs/#subgraphs"&gt;subgraph&lt;/a&gt;, so the reaction to success or failure is itself durable.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pick &lt;code&gt;Await&lt;/code&gt; when a caller is standing by and can wait for the result. Pick &lt;code&gt;Poll&lt;/code&gt; when the caller is bounded
by its own deadline — an HTTP handler backing a status endpoint — but the flow is not. Pick orchestration when
the reaction must happen reliably regardless of who is (or isn&amp;rsquo;t) waiting — a push notification, a downstream
call, a compensation.&lt;/p&gt;</description></item><item><title>Scheduling</title><link>https://docs.dwarf.run/building-workflows/scheduling/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/scheduling/</guid><description>&lt;h1 id="scheduling"&gt;Scheduling&lt;a class="anchor" href="#scheduling" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers and operators.&lt;/strong&gt; Developers set priority, fairness and time budgets per flow; operators
need the same model to read a backlog. The behaviour described here is what the
&lt;a href="https://docs.dwarf.run/operating/runbook/"&gt;Runbook&lt;/a&gt; assumes you know.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Dwarf decides &lt;em&gt;which&lt;/em&gt; pending step runs next, and how long each task may run. Most of this is automatic;
this guide explains the knobs you control. How a step survives a crashed worker is covered in
&lt;a href="https://docs.dwarf.run/how-dwarf-works/#crash-recovery"&gt;How Dwarf Works&lt;/a&gt;, and how a task retries a transient failure in
&lt;a href="https://docs.dwarf.run/building-workflows/tasks/#handling-transient-failures"&gt;Writing Tasks&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Testing</title><link>https://docs.dwarf.run/building-workflows/testing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/testing/</guid><description>&lt;h1 id="testing"&gt;Testing&lt;a class="anchor" href="#testing" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; writing tests for their own workflows. It covers the in-process harness Dwarf ships so
your test suite can run real flows with no database and no transport.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Dwarf ships an in-process test harness so you can exercise real workflows — scheduling, fan-out, subgraphs,
interrupts, retries — with no database to set up and no transport to stand up.&lt;/p&gt;
&lt;h2 id="the-two-pieces"&gt;The Two Pieces&lt;a class="anchor" href="#the-two-pieces" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;engine.NewEngineUnderTest(name)&lt;/code&gt;&lt;/strong&gt; constructs an engine wired for testing: an isolated SQLite in-memory
database (per name, and per shard for multi-shard tests), auto-dropped, with migrations run at &lt;code&gt;Startup&lt;/code&gt; —
no DSN. It takes a plain name rather than a &lt;code&gt;testing.TB&lt;/code&gt;, so a harness with no &lt;code&gt;*testing.T&lt;/code&gt; to hand over
reaches it the same way a Go test does; pass &lt;code&gt;t.Name()&lt;/code&gt; from a test. You call &lt;code&gt;Startup(ctx)&lt;/code&gt; yourself, so
any &lt;code&gt;Set*&lt;/code&gt; configuration goes in between, and you own teardown: &lt;code&gt;defer eng.Shutdown(ctx)&lt;/code&gt;. The name is the
isolation key — give several engines the same name to share one database, or distinct names to isolate
them. It logs to stderr at Error for CI clues (&lt;code&gt;DWARF_TEST_LOG_LEVEL&lt;/code&gt; overrides — &lt;code&gt;info&lt;/code&gt;/&lt;code&gt;debug&lt;/code&gt; for the
flow-status play-by-play, &lt;code&gt;silent&lt;/code&gt;/&lt;code&gt;off&lt;/code&gt; to quiet it); a benchmark or fuzz target silences it outright with
&lt;code&gt;SetLogger(slog.New(slog.DiscardHandler))&lt;/code&gt;, since per-iteration logging would swamp the measurement.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;hosts.Mux&lt;/code&gt;&lt;/strong&gt; is an in-memory implementation of the &lt;a href="https://docs.dwarf.run/how-dwarf-works/#the-pieces"&gt;&lt;code&gt;Host&lt;/code&gt;&lt;/a&gt; interface. Register graphs and task
functions on it, then register it with &lt;code&gt;SetHost(mux)&lt;/code&gt;; it implements &lt;code&gt;LoadGraph&lt;/code&gt; and &lt;code&gt;ExecuteTask&lt;/code&gt;
from those registrations.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TestCheckout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mux&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewMux&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Checkout&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Reserve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;inventory.reserve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Charge&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;billing.charge&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Reserve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Charge&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Charge&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;End&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;checkout&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;inventory.reserve&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Flow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;reserved&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HandleTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;billing.charge&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Flow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;receipt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;r-123&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;eng&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;dwarf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewEngineUnderTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;eng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Shutdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;eng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mux&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;eng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;eng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;checkout&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;sku&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ABC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StatusCompleted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;status %s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;receipt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;r-123&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;receipt %q&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Mux.HandleGraph(workflowURL, graph)&lt;/code&gt; registers a graph under the URL you pass to &lt;code&gt;Create&lt;/code&gt; or &lt;code&gt;Run&lt;/code&gt;;
&lt;code&gt;HandleTask(taskURL, handler)&lt;/code&gt; registers a task under the URL bound with &lt;code&gt;SetURL&lt;/code&gt;. The handler signature is the same &lt;code&gt;func(ctx, *workflow.Flow) error&lt;/code&gt;
you write in production.&lt;/p&gt;</description></item><item><title>Patterns</title><link>https://docs.dwarf.run/building-workflows/patterns/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dwarf.run/building-workflows/patterns/</guid><description>&lt;h1 id="patterns"&gt;Patterns&lt;a class="anchor" href="#patterns" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;blockquote class='book-hint '&gt;
&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt; looking for how to express a common need. Each recipe is short and links to the guide
that covers its building blocks.&lt;/p&gt;
&lt;/blockquote&gt;&lt;h2 id="an-llm-agent-loop"&gt;An LLM Agent Loop&lt;a class="anchor" href="#an-llm-agent-loop" aria-label="Anchor" aria-hidden="true"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An agent thinks, calls tools, and repeats until it has an answer. That is a loop in the graph: &lt;code&gt;Think&lt;/code&gt;
decides, and a &lt;code&gt;switch&lt;/code&gt; either runs the tools or ends the flow.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Think&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://agent/think&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;UseTools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://agent/use-tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransitionSwitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Think&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;UseTools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hasToolCalls&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransitionSwitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Think&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;End&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;!hasToolCalls&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddTransition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;UseTools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Think&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre class="mermaid"&gt;graph LR
 classDef task fill:#32a7c1,color:#f4f2ef,stroke:#32a7c1
 classDef term fill:#e5f4f3,color:#434343,stroke:#32a7c1
 linkStyle default stroke:#32a7c1

 t0[&amp;#34;Think&amp;#34;]:::task
 t0_switch{&amp;#34;switch&amp;#34;}:::term
 t1[&amp;#34;UseTools&amp;#34;]:::task
 t1 --&amp;gt; t0
 t0 --&amp;gt; t0_switch
 t0_switch --&amp;gt;|&amp;#34;hasToolCalls&amp;#34;| t1
 _start(( )):::term --&amp;gt; t0
 t0_switch --&amp;gt;|&amp;#34;!hasToolCalls&amp;#34;| _end(( )):::term&lt;/pre&gt;
&lt;p&gt;Every turn of the loop is a durable step, so a crash resumes the agent where it was. For a conversation,
end the flow when the agent has answered, and start the next turn with
&lt;a href="https://docs.dwarf.run/building-workflows/flows/#continue-a-flow"&gt;&lt;code&gt;Continue&lt;/code&gt;&lt;/a&gt;: it carries the previous turn&amp;rsquo;s final state
(the conversation so far) into a new flow. Your application keeps the conversation as a chain of flow keys,
and continues the key the last &lt;code&gt;Continue&lt;/code&gt; returned. To run several tool calls in parallel, have
&lt;code&gt;Think&lt;/code&gt; emit them as an array and fan out with
&lt;a href="https://docs.dwarf.run/building-workflows/fan-out-and-subgraphs/#dynamic-fan-out-foreach"&gt;&lt;code&gt;forEach&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>