<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Genkit | Blog</title><description/><link>https://genkit.dev/</link><language>en</language><item><title>Dotprompt comes to Genkit Dart: Richer prompt templating and management</title><link>https://genkit.dev/blog/dotprompt-comes-to-genkit-dart/</link><guid isPermaLink="true">https://genkit.dev/blog/dotprompt-comes-to-genkit-dart/</guid><description>Genkit Dart 0.14.0 adds Dotprompt support, letting you manage prompts, models, and parameters as version-controlled config in .prompt files, decoupled from your app code and tunable in the Developer UI.

</description><pubDate>Fri, 19 Jun 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Prompt engineering is an iterative process. The model, its parameters, and the prompt text all shape the output together, and getting them right takes many rounds of tuning. As a prompt grows in complexity, it helps to treat that whole bundle as an artifact you can edit, version, and test on its own. That is where Dotrpompt can help!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Genkit Dart 0.14.0&lt;/strong&gt; brings &lt;a href=&quot;https://github.com/google/dotprompt&quot;&gt;Dotprompt&lt;/a&gt; to Dart and Flutter developers. Simple prompts are often fine inline, and Genkit still supports that. When a prompt does more work, Dotprompt lets you move it into a &lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; file that lives alongside your app. You define the prompt there, iterate on it in the Developer UI, and run it from Dart by name.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;a-prompt-in-a-file&quot;&gt;A prompt in a file&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; file is YAML front matter, holding the model and its config, followed by a &lt;a href=&quot;https://handlebarsjs.com/guide/&quot;&gt;Handlebars&lt;/a&gt; template. Drop this into your &lt;code dir=&quot;auto&quot;&gt;prompts/&lt;/code&gt; directory as &lt;code dir=&quot;auto&quot;&gt;greeting.prompt&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;---&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;googleai/gemini-flash-latest&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;temperature&lt;/span&gt;&lt;span&gt;: 0.7&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;schema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;string, the person to greet&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;style&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;string, the greeting style (e.g. cheerful, casual, pirate)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;---&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{{&lt;/span&gt;&lt;span&gt;role&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;system&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;}}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;You are a friendly greeter. Greet the user warmly.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{{&lt;/span&gt;&lt;span&gt;role&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;user&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;}}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Say hello to &lt;/span&gt;&lt;span&gt;{{&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;}}&lt;/span&gt;&lt;span&gt; in a &lt;/span&gt;&lt;span&gt;{{&lt;/span&gt;&lt;span&gt;style&lt;/span&gt;&lt;span&gt;}}&lt;/span&gt;&lt;span&gt; way.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Then load and run it from your app. By default Genkit looks for prompts in &lt;code dir=&quot;auto&quot;&gt;./prompts&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit/genkit.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit_google_genai/genkit_google_genai.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; ai &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Genkit&lt;/span&gt;&lt;span&gt;(plugins&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;googleAI&lt;/span&gt;&lt;span&gt;()]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; greeting &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;greeting&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;greeting&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;span&gt;&apos;name&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Ada&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;style&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;cheerful&apos;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(response.text);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;For a prompt like this, none of the prose lives in your code. The model and temperature sit right next to the text they shape, and your application asks for the prompt by name and stays out of the tuning loop.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;when-to-give-a-prompt-its-own-file&quot;&gt;When to give a prompt its own file&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Not every prompt needs one. A single-line system prompt can stay in your Dart. Reach for a &lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; file once a prompt does enough work to earn the benefits below, which usually means complex or highly dynamic templating, or text that a separate subject-matter expert needs to review and edit.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Independent versioning:&lt;/strong&gt; Prompt changes land as prompt diffs you can review and revert on their own, without untangling them from application logic. The history shows exactly how the wording, model, and config evolved.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Real templating:&lt;/strong&gt; Handlebars helpers, partials, and conditionals express complex, dynamic prompts cleanly, so you can drop the brittle string concatenation in Dart.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accessible for non-developers:&lt;/strong&gt; A subject-matter expert who doesn’t work on the code can read the plain YAML and template and adjust the prompt with more confidence.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An executable, testable unit:&lt;/strong&gt; The model, config, input and output schemas, and template all travel together as one runnable artifact. You render it, run it, and assert on its output directly, rather than reassembling the pieces at every call site.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fast iteration:&lt;/strong&gt; Load prompts in the Developer UI, where you run it against custom input, compare against variants, and view detailed execution traces for rapid iteration.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;what-shipped&quot;&gt;What shipped&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;This release brings the full Dotprompt feature set to Dart:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; files&lt;/strong&gt; with YAML front matter, Handlebars templates, and the &lt;code dir=&quot;auto&quot;&gt;{{role}}&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;{{media}}&lt;/code&gt; helpers for multi-message and multimodal prompts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured I/O&lt;/strong&gt; via input and output schemas, including Picoschema and schemas defined in code with &lt;a href=&quot;https://pub.dev/packages/schemantic&quot;&gt;schemantic&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Streaming&lt;/strong&gt; with &lt;code dir=&quot;auto&quot;&gt;prompt.stream()&lt;/code&gt;, plus &lt;code dir=&quot;auto&quot;&gt;render()&lt;/code&gt; to inspect the final messages without calling the model.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variants&lt;/strong&gt; for side-by-side experimentation. Add a &lt;code dir=&quot;auto&quot;&gt;greeting.formal.prompt&lt;/code&gt; file and load it with &lt;code dir=&quot;auto&quot;&gt;await ai.prompt(&apos;greeting&apos;, variant: &apos;formal&apos;)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Partials&lt;/strong&gt; for reusable snippets. A file like &lt;code dir=&quot;auto&quot;&gt;_signature.prompt&lt;/code&gt; can be included in any prompt with &lt;code dir=&quot;auto&quot;&gt;{{&gt; signature}}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;prompt-templates-in-code&quot;&gt;Prompt templates in code&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Prefer to keep prompts in code but still want the templating benefits? Define a strongly-typed input schema with &lt;a href=&quot;https://pub.dev/packages/schemantic&quot;&gt;schemantic&lt;/a&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;@Schema&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;abstract&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$JokeInput&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;@Field&lt;/span&gt;&lt;span&gt;(description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;The joke topic (e.g. programming, cats, cooking)&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; topic;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;@Field&lt;/span&gt;&lt;span&gt;(description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;The joke style (e.g. punny, dry, dad)&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; style;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Then &lt;code dir=&quot;auto&quot;&gt;definePrompt()&lt;/code&gt; takes the same metadata as a &lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; file with a Handlebars template and the generated schema:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; jokePrompt &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;definePrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;joke&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;modelRef&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;googleai/gemini-flash-latest&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;&apos;temperature&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0.9&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;JokeInput&lt;/span&gt;&lt;span&gt;.$schema,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;system&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;You are a witty comedian. Keep jokes family-friendly.&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Tell me a {{style}} joke about {{topic}}.&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;jokePrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;JokeInput&lt;/span&gt;&lt;span&gt;(topic&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;cats&apos;&lt;/span&gt;&lt;span&gt;, style&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;punny&apos;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(response.text);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;And when you need to build messages programmatically, &lt;code dir=&quot;auto&quot;&gt;defineCustomPrompt()&lt;/code&gt; lets you return a &lt;code dir=&quot;auto&quot;&gt;GenerateActionOptions&lt;/code&gt; describing the request yourself.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;iterate-in-the-developer-ui&quot;&gt;Iterate in the Developer UI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Every &lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; file loads straight into the &lt;a href=&quot;https://genkit.dev/docs/dart/devtools&quot;&gt;Genkit Developer UI&lt;/a&gt;. There you can edit parameters, run them against live input, and compare variants side by side in traces.&lt;/p&gt;
&lt;p&gt;Start the UI alongside your app:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;genkit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;start&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;video src=&quot;/_astro/genkit-dart-dotpromt-devui.CGAQAuK3.mov&quot; controls autoplay loop muted=&quot;true&quot; playsinline&gt;&lt;/video&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Update to Genkit Dart 0.14.0 and start moving your prompts into &lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; files today.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Read the docs:&lt;/strong&gt; Dive into the &lt;a href=&quot;https://genkit.dev/docs/dart/dotprompt&quot;&gt;Dotprompt documentation&lt;/a&gt; to see everything you can do.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New to Genkit Dart?&lt;/strong&gt; Start with the &lt;a href=&quot;https://genkit.dev/docs/dart/get-started&quot;&gt;quickstart guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Join the community:&lt;/strong&gt; Ask questions and chat with the team on our &lt;a href=&quot;https://discord.gg/qXt5zzQKpc&quot;&gt;Discord server&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stay updated:&lt;/strong&gt; Follow us on &lt;a href=&quot;https://x.com/genkitframework&quot;&gt;X&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/company/genkit&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Give feedback:&lt;/strong&gt; Open an issue on the &lt;a href=&quot;https://github.com/genkit-ai/genkit-dart&quot;&gt;GitHub repository&lt;/a&gt; to report bugs or request features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can’t wait to see what you build. Happy prompting! 🚀&lt;/p&gt;</content:encoded><category>dart</category><category>flutter</category><category>dotprompt</category></item><item><title>Is it thinking or is it broken? Building transparent AI chat UIs with Genkit</title><link>https://genkit.dev/blog/streaming-thoughts/</link><guid isPermaLink="true">https://genkit.dev/blog/streaming-thoughts/</guid><description>Learn how to extract and stream model thought processes using Genkit and server-sent events, and render them in a custom React component to create a highly responsive user experience.

</description><pubDate>Wed, 17 Jun 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the worst user experiences imaginable is that your users are convinced &lt;span&gt;your app is
broken while your app is working correctly&lt;/span&gt;. This is even more apparent with AI powered apps
since processing takes some time to occur with AI models. Your user sends a chat message and
then they are stuck waiting on a response with no insight into whether or not the app is
doing anything. In this post, we are going to break down how to &lt;span&gt;give your users insights
into your agents’ thought process&lt;/span&gt; to make sure your users aren’t left hanging.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;streaming-thoughts&quot;&gt;Streaming thoughts&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit has the capability through server sent events to emit a stream of data to clients connecting to your agent. Some of
the things that can be streamed include the regular text responses but most models now include things
like &lt;a href=&quot;https://ai.google.dev/gemini-api/docs/thinking&quot;&gt;thinking&lt;/a&gt; to improve their reasoning and responses to users.
The following is an example of the experience you can create with Genkit
that visualizes your thinking process for your model.&lt;/p&gt;
&lt;div&gt; &lt;div&gt; &lt;div&gt; &lt;div&gt; &lt;span&gt;&lt;/span&gt; &lt;span&gt;&lt;/span&gt; &lt;span&gt;&lt;/span&gt; &lt;/div&gt; &lt;div&gt;Agent Streaming Session Demo&lt;/div&gt; &lt;div&gt; &lt;button id=&quot;reset-demo-btn&quot; title=&quot;Reset Conversation&quot;&gt; &lt;span&gt;↺&lt;/span&gt; Reset
&lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div id=&quot;chat-messages-container&quot;&gt; &lt;!-- Welcome message --&gt; &lt;div&gt; &lt;div&gt; &lt;p&gt;Hello! I am your simulated Genkit AI instance powered by Gemini 3.5 Flash. Ask me a question or try a suggestion below, and I&apos;ll stream my step-by-step thinking process alongside my final response!&lt;/p&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div&gt; &lt;div id=&quot;preset-prompts&quot;&gt; &lt;span&gt;Suggestions:&lt;/span&gt; &lt;button&gt;Why is Genkit so cool?&lt;/button&gt; &lt;button&gt;How does middleware harden AI agents?&lt;/button&gt; &lt;button&gt;Plan a 3-day tech trip to Tokyo&lt;/button&gt; &lt;/div&gt; &lt;form id=&quot;chat-demo-form&quot;&gt; &lt;input type=&quot;text&quot; id=&quot;chat-demo-input&quot; placeholder=&quot;Type a message to your agent...&quot; autocomplete=&quot;off&quot;&gt; &lt;button type=&quot;submit&quot; id=&quot;chat-demo-submit&quot; title=&quot;Send request&quot;&gt; &lt;svg width=&quot;20&quot; height=&quot;20&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt; &lt;line x1=&quot;22&quot; y1=&quot;2&quot; x2=&quot;11&quot; y2=&quot;13&quot;&gt;&lt;/line&gt; &lt;polygon points=&quot;22 2 15 22 11 13 2 9 22 2&quot;&gt;&lt;/polygon&gt; &lt;/svg&gt; &lt;/button&gt; &lt;/form&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  
&lt;p&gt;This not only gives you insight into what the agent is doing but also improves the output of the response.
By using thinking, we can &lt;span&gt;improve our agents’ responses and also provide a better user experience&lt;/span&gt;.
Below is a Genkit code snippet on how to extract a thought from an agent and then by using a server sent events
stream that thought process down to the user.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// 1. Generate a stream with thinking config enabled&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generateStream&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model: googleAI.&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-flash-latest&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt: &lt;/span&gt;&lt;span&gt;&apos;Why is Genkit so cool?&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;config: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;thinkingConfig: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;includeThoughts: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;thinkingLevel: &lt;/span&gt;&lt;span&gt;&apos;MEDIUM&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// 2. Consume the stream and separate reasoning from the final response&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;chunk&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt; stream) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Extract reasoning (thinking process)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;thoughtText&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; chunk.reasoning &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (thoughtText) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;sendChunk&lt;/span&gt;&lt;span&gt;({ type: &lt;/span&gt;&lt;span&gt;&apos;thought&apos;&lt;/span&gt;&lt;span&gt;, content: thoughtText });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Extract standard text response&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; chunk.text;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (text) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;sendChunk&lt;/span&gt;&lt;span&gt;({ type: &lt;/span&gt;&lt;span&gt;&apos;text&apos;&lt;/span&gt;&lt;span&gt;, content: text });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;After looking at this sample, you may be wondering what &lt;code dir=&quot;auto&quot;&gt;sendChunk&lt;/code&gt; is returning. This is the
Output Schema that we defined for our Genkit flow. In this example, it looks something like this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StreamChunkSchema&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; z.&lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;messageId: z.&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;type: z.&lt;/span&gt;&lt;span&gt;enum&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span&gt;&apos;thought&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;text&apos;&lt;/span&gt;&lt;span&gt;]),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;content: z.&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;currentStep: z.&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;optional&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;rendering-the-thoughts-in-the-chat-window&quot;&gt;Rendering the thoughts in the chat window&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;By having the thoughts being streamed from the server, we can now put together responses that our
client would receive to give some clarity to our users. We designed a React component that is a
thought box that uses CSS to show an animation as new thoughts are streamed down. We also provided
an option to then receive those thoughts and store all of them in a smaller text box that is
collapsible so users can inspect the full thought contents as they are received giving the user a
choice &lt;span&gt;to see what exactly the model is doing or to continue to recieve high level updates&lt;/span&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; React, { useState } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;react&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ThoughtBoxProps&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;    &lt;/span&gt;&lt;span&gt;// The full accumulated thought content&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;stepName&lt;/span&gt;&lt;span&gt;?:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;;  &lt;/span&gt;&lt;span&gt;// The current step description (e.g. &quot;Analyzing input&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ThoughtBox&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;React&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;FC&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ThoughtBoxProps&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ({ &lt;/span&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;stepName&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;isOpen&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;setIsOpen&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;useState&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;activeStep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; stepName &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Thinking&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;message thought-message&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;thought-box&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;/* Animated header showing the current step */&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;thought-header&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;`indicator-${&lt;/span&gt;&lt;span&gt;activeStep&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;thought-indicator indicator-animate&quot;&lt;/span&gt;&lt;span&gt; /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;`label-${&lt;/span&gt;&lt;span&gt;activeStep&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;thought-step-label step-animate&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Thinking: {activeStep}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;/* Collapsible details wrapper for the full thought content */&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;details&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;thought-details&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;onToggle&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;{(&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;setIsOpen&lt;/span&gt;&lt;span&gt;(e.currentTarget.open)}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;summary&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;thought-summary&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;summary-text&quot;&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;              &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{isOpen &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Hide Full Reasoning&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Show Full Reasoning&apos;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;span&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;summary&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;className&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;thought-body&quot;&lt;/span&gt;&lt;span&gt;&gt;{content}&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;details&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;#x3C;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;With this component, we can easily add it to other apps that are not strictly
chat based apps but other apps that might want to have a thought component
rendered while the models are thinking.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;putting-it-all-together&quot;&gt;Putting it all together&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Using a small React component with our Genkit flow allows us to
&lt;span&gt;keep the user informed of what is going on while our models are thinking&lt;/span&gt;.
This makes it appear that the model is working and processing information keeping the user informed
and limiting their impression that the app has stalled or is broken.&lt;/p&gt;
&lt;p&gt;If you want to try out the React component and Genkit streaming server-sent
events yourself, you can check out the &lt;a href=&quot;https://github.com/genkit-ai/samples/tree/main/agent-streaming&quot;&gt;streaming thoughts sample&lt;/a&gt;
in our samples repository.&lt;/p&gt;</content:encoded><category>typescript</category><category>agents</category><category>ux</category></item><item><title>Announcing Genkit Middleware: Intercept, extend, and harden your agentic apps</title><link>https://genkit.dev/blog/announcing-genkit-middleware/</link><guid isPermaLink="true">https://genkit.dev/blog/announcing-genkit-middleware/</guid><description>Middleware lets you inject generation calls with reusable, composable behavior like retries, model fallback, and tool approval, with an extensible API.

</description><pubDate>Thu, 14 May 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://genkit.dev&quot;&gt;Genkit&lt;/a&gt; is an open-source framework for &lt;strong&gt;building full-stack, AI-powered and agentic applications for any platform&lt;/strong&gt; with support for TypeScript, Go, Dart, and Python. Building a production-ready agentic applications and AI features requires more than powerful models and careful prompting. You might need retries and fallbacks for maximum reliability, human approval before destructive tool calls, and observability across every layer.&lt;/p&gt;
&lt;p&gt;Genkit solves this with &lt;strong&gt;middleware&lt;/strong&gt;: composable hooks that intercept generation calls, including the tool execution loop, and inject custom behaviors. The middleware system is available today in TypeScript, Go, and Dart, with Python support coming soon.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;how-genkit-middleware-works&quot;&gt;How Genkit middleware works&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Every &lt;code dir=&quot;auto&quot;&gt;generate()&lt;/code&gt; call in Genkit runs a &lt;strong&gt;tool loop&lt;/strong&gt;: the model produces output, any requested tools execute, the results feed back into a new model call, and the cycle repeats until the model is done. Middleware hooks attach at three layers of this loop:&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align=&quot;left&quot;&gt;Hook&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;When it runs&lt;/th&gt;&lt;th align=&quot;left&quot;&gt;Typical use&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Generate&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Once per tool-loop iteration&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Context injection, message rewriting, conversation-level logic&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Once per model API call&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Retry, fallback, caching, latency logging&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;Tool&lt;/strong&gt;&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Once per tool execution&lt;/td&gt;&lt;td align=&quot;left&quot;&gt;Human-in-the-loop, sandboxing, per-tool logging&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;&lt;h2 id=&quot;pre-built-middleware&quot;&gt;Pre-built middleware&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit offers several pre-built middleware solutions for common use-cases. Here’s what’s available today:&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-retry&quot;&gt;1. Retry&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Automatically retries failed model API calls on transient errors (&lt;code dir=&quot;auto&quot;&gt;RESOURCE_EXHAUSTED&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;UNAVAILABLE&lt;/code&gt;, etc.) using exponential backoff with jitter. Only the model call is retried; the surrounding tool loop is not replayed.&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;lang&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-40&quot; id=&quot;tab-40&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  TypeScript &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-41&quot; id=&quot;tab-41&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Go &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-42&quot; id=&quot;tab-42&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Dart &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-40&quot; aria-labelledby=&quot;tab-40&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model: googleAI.&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-flash-latest&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt: &lt;/span&gt;&lt;span&gt;&apos;Summarize the quarterly earnings report.&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;retry&lt;/span&gt;&lt;span&gt;({ maxRetries: &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, initialDelayMs: &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;, backoffFactor: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-41&quot; aria-labelledby=&quot;tab-41&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithModelName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;googleai/gemini-flash-latest&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Summarize the quarterly earnings report.&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithUse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;middleware&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Retry&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;MaxRetries:     &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;InitialDelayMs: &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;BackoffFactor:  &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-42&quot; aria-labelledby=&quot;tab-42&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; googleAI.&lt;/span&gt;&lt;span&gt;gemini&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-flash-latest&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Summarize the quarterly earnings report.&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;retry&lt;/span&gt;&lt;span&gt;(maxRetries&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, initialDelayMs&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;, backoffFactor&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;div&gt;&lt;h3 id=&quot;2-fallback&quot;&gt;2. Fallback&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Switches to an alternative model when the primary model fails on a specified set of error codes. Useful for falling back to a smaller, faster model, or a different provider entirely, when your primary model exceeds its quota.&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;lang&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-43&quot; id=&quot;tab-43&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  TypeScript &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-44&quot; id=&quot;tab-44&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Go &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-43&quot; aria-labelledby=&quot;tab-43&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model: googleAI.&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-pro-latest&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt: &lt;/span&gt;&lt;span&gt;&apos;Analyze this complex document...&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;fallback&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;models: [googleAI.&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-flash-latest&apos;&lt;/span&gt;&lt;span&gt;)],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;statuses: [&lt;/span&gt;&lt;span&gt;&apos;RESOURCE_EXHAUSTED&apos;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-44&quot; aria-labelledby=&quot;tab-44&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithModelName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;googleai/gemini-pro-latest&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Analyze this complex document...&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithUse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;middleware&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Fallback&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Models: []&lt;/span&gt;&lt;span&gt;ai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ModelRef&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;googlegenai.&lt;/span&gt;&lt;span&gt;ModelRef&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;googleai/gemini-flash-latest&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Statuses: []&lt;/span&gt;&lt;span&gt;core&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;StatusName&lt;/span&gt;&lt;span&gt;{core.RESOURCE_EXHAUSTED},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;blockquote&gt;
&lt;p&gt;Fallback isn’t available in the Dart SDK yet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;h3 id=&quot;3-tool-approval&quot;&gt;3. Tool approval&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Restricts tool execution to an allow-list. Any tool not on the list triggers an interrupt, enabling human-in-the-loop confirmation before the action proceeds.&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;lang&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-45&quot; id=&quot;tab-45&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  TypeScript &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-46&quot; id=&quot;tab-46&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Go &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-47&quot; id=&quot;tab-47&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Dart &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-45&quot; aria-labelledby=&quot;tab-45&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// 1. Initial attempt — an empty allow-list interrupts every tool call.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt: &lt;/span&gt;&lt;span&gt;&apos;Delete the temp files&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tools: [deleteFilesTool],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use: [&lt;/span&gt;&lt;span&gt;toolApproval&lt;/span&gt;&lt;span&gt;({ approved: [] })],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (response.finishReason &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;interrupted&apos;&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interrupt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; response.interrupts[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 2. Prompt the user for approval, then recreate the tool request.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;approvedPart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restartTool&lt;/span&gt;&lt;span&gt;(interrupt, { toolApproved: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 3. Resume execution with the approval.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resumed&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;messages: response.messages,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;resume: { restart: [approvedPart] },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use: [&lt;/span&gt;&lt;span&gt;toolApproval&lt;/span&gt;&lt;span&gt;({ approved: [] })],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-46&quot; aria-labelledby=&quot;tab-46&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, _ &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Delete the temp files&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithTools&lt;/span&gt;&lt;span&gt;(deleteFilesTool),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithUse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;middleware&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ToolApproval&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AllowedTools: []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;{}, &lt;/span&gt;&lt;span&gt;// empty = every tool call interrupts&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;(resp.&lt;/span&gt;&lt;span&gt;Interrupts&lt;/span&gt;&lt;span&gt;()) &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;interrupt &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; resp.&lt;/span&gt;&lt;span&gt;Interrupts&lt;/span&gt;&lt;span&gt;()[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Prompt the user for approval, then resume with the approval flag.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;approved, _ &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; deleteFilesTool.&lt;/span&gt;&lt;span&gt;RestartWith&lt;/span&gt;&lt;span&gt;(interrupt,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithResumedMetadata&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;DeleteInput&lt;/span&gt;&lt;span&gt;](&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;any&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;toolApproved&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithMessages&lt;/span&gt;&lt;span&gt;(resp.&lt;/span&gt;&lt;span&gt;History&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithTools&lt;/span&gt;&lt;span&gt;(deleteFilesTool),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithToolRestarts&lt;/span&gt;&lt;span&gt;(approved),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithUse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;middleware&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ToolApproval&lt;/span&gt;&lt;span&gt;{}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fmt.&lt;/span&gt;&lt;span&gt;Println&lt;/span&gt;&lt;span&gt;(resp.&lt;/span&gt;&lt;span&gt;Text&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-47&quot; aria-labelledby=&quot;tab-47&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// 1. Initial attempt — an empty allow-list interrupts every tool call.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Delete the temp files&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tools&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [deleteFilesTool],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;toolApproval&lt;/span&gt;&lt;span&gt;(approved&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [])],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (response.finishReason &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FinishReason&lt;/span&gt;&lt;span&gt;.interrupted) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; part &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; response.interrupts.first;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 2. Ask the user for approval, then resume execution.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; resumed &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;messages&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; response.messages,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;resume&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;InterruptResponse&lt;/span&gt;&lt;span&gt;(part, &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;)],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;toolApproval&lt;/span&gt;&lt;span&gt;(approved&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [])],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;div&gt;&lt;h3 id=&quot;4-skills&quot;&gt;4. Skills&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Scans a directory for &lt;code dir=&quot;auto&quot;&gt;SKILL.md&lt;/code&gt; files and injects their content into the system prompt. Also exposes a &lt;code dir=&quot;auto&quot;&gt;use_skill&lt;/code&gt; tool so the model can load specific skills on demand.&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;lang&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-48&quot; id=&quot;tab-48&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  TypeScript &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-49&quot; id=&quot;tab-49&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Go &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-50&quot; id=&quot;tab-50&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Dart &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-48&quot; aria-labelledby=&quot;tab-48&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt: &lt;/span&gt;&lt;span&gt;&apos;How do I deploy this service?&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use: [&lt;/span&gt;&lt;span&gt;skills&lt;/span&gt;&lt;span&gt;({ skillPaths: [&lt;/span&gt;&lt;span&gt;&apos;./skills&apos;&lt;/span&gt;&lt;span&gt;] })],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-49&quot; aria-labelledby=&quot;tab-49&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;How do I deploy this service?&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithUse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;middleware&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Skills&lt;/span&gt;&lt;span&gt;{SkillPaths: []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;./skills&quot;&lt;/span&gt;&lt;span&gt;}}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-50&quot; aria-labelledby=&quot;tab-50&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;How do I deploy this service?&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;skills&lt;/span&gt;&lt;span&gt;(skillPaths&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&apos;./skills&apos;&lt;/span&gt;&lt;span&gt;])],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;div&gt;&lt;h3 id=&quot;5-filesystem&quot;&gt;5. Filesystem&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Gives the model scoped access to the local filesystem through injected tools (&lt;code dir=&quot;auto&quot;&gt;list_files&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;read_file&lt;/code&gt;, plus &lt;code dir=&quot;auto&quot;&gt;write_file&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;edit_file&lt;/code&gt; when writes are enabled). Path safety is enforced so the model can never escape the root directory.&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;lang&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-51&quot; id=&quot;tab-51&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  TypeScript &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-52&quot; id=&quot;tab-52&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Go &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-53&quot; id=&quot;tab-53&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Dart &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-51&quot; aria-labelledby=&quot;tab-51&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt: &lt;/span&gt;&lt;span&gt;&apos;Create a hello world program in the workspace&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use: [&lt;/span&gt;&lt;span&gt;filesystem&lt;/span&gt;&lt;span&gt;({ rootDirectory: &lt;/span&gt;&lt;span&gt;&apos;./workspace&apos;&lt;/span&gt;&lt;span&gt;, allowWriteAccess: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; })],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-52&quot; aria-labelledby=&quot;tab-52&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Create a hello world program in the workspace&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithUse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;middleware&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Filesystem&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;RootDir:          &lt;/span&gt;&lt;span&gt;&quot;./workspace&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;AllowWriteAccess: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-53&quot; aria-labelledby=&quot;tab-53&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Create a hello world program in the workspace&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;filesystem&lt;/span&gt;&lt;span&gt;(rootDirectory&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;./workspace&apos;&lt;/span&gt;&lt;span&gt;)],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;div&gt;&lt;h2 id=&quot;building-custom-middleware&quot;&gt;Building custom middleware&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The pre-built middleware covers common scenarios, but the real power of the system is in writing your own. Imagine you’re building an agentic customer-support app and need to ensure the model never mentions competitor products or internal pricing data. Rather than encoding these rules in every prompt, you can enforce them deterministically with middleware.&lt;/p&gt;
&lt;p&gt;Custom middleware follows a simple contract across all languages: provide a name and a factory that returns the hooks you want. The factory runs once per &lt;code dir=&quot;auto&quot;&gt;generate()&lt;/code&gt; invocation, and you implement only the hooks you need.&lt;/p&gt;
&lt;p&gt;Here’s a complete, custom content filter that rejects any response containing a forbidden term:&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;lang&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-54&quot; id=&quot;tab-54&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  TypeScript &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-55&quot; id=&quot;tab-55&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Go &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-56&quot; id=&quot;tab-56&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Dart &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-54&quot; aria-labelledby=&quot;tab-54&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { generateMiddleware, z } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;genkit&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;contentFilter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;generateMiddleware&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name: &lt;/span&gt;&lt;span&gt;&apos;contentFilter&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;description: &lt;/span&gt;&lt;span&gt;&apos;Rejects model responses containing forbidden terms&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;configSchema: z.&lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt;({ forbiddenTerms: z.&lt;/span&gt;&lt;span&gt;array&lt;/span&gt;&lt;span&gt;(z.&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;()) }),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt; }) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; ({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;req&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;next&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;next&lt;/span&gt;&lt;span&gt;(req, ctx);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; resp.text.&lt;/span&gt;&lt;span&gt;toLowerCase&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;term&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt; config?.forbiddenTerms &lt;/span&gt;&lt;span&gt;??&lt;/span&gt;&lt;span&gt; []) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (text.&lt;/span&gt;&lt;span&gt;includes&lt;/span&gt;&lt;span&gt;(term.&lt;/span&gt;&lt;span&gt;toLowerCase&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`content filter: response contains &quot;${&lt;/span&gt;&lt;span&gt;term&lt;/span&gt;&lt;span&gt;}&quot;`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; resp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-55&quot; aria-labelledby=&quot;tab-55&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// ContentFilter rejects model responses containing any forbidden term.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ContentFilter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ForbiddenTerms []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`json:&quot;forbiddenTerms&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;ContentFilter&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;app/contentFilter&quot;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;f &lt;/span&gt;&lt;span&gt;ContentFilter&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;New&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Context&lt;/span&gt;&lt;span&gt;) (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;ai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Hooks&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;ai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Hooks&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;WrapModel: &lt;/span&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Context&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;ai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ModelParams&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;next&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ModelNext&lt;/span&gt;&lt;span&gt;) (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;ai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ModelResponse&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;next&lt;/span&gt;&lt;span&gt;(ctx, p)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;span&gt;, err&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;text &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; strings.&lt;/span&gt;&lt;span&gt;ToLower&lt;/span&gt;&lt;span&gt;(resp.&lt;/span&gt;&lt;span&gt;Text&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; _, term &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt; f.ForbiddenTerms {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; strings.&lt;/span&gt;&lt;span&gt;Contains&lt;/span&gt;&lt;span&gt;(text, strings.&lt;/span&gt;&lt;span&gt;ToLower&lt;/span&gt;&lt;span&gt;(term)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;span&gt;, fmt.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;content filter: response contains &lt;/span&gt;&lt;span&gt;%q&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, term)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; resp, &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}, &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-56&quot; aria-labelledby=&quot;tab-56&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Reject model responses containing any forbidden term.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ContentFilter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;GenerateMiddleware&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt;&gt; forbiddenTerms;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;ContentFilter&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.forbiddenTerms &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; []});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;@override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Future&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ModelRequest&lt;/span&gt;&lt;span&gt; request, &lt;/span&gt;&lt;span&gt;dynamic&lt;/span&gt;&lt;span&gt; ctx, &lt;/span&gt;&lt;span&gt;dynamic&lt;/span&gt;&lt;span&gt; next) &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;next&lt;/span&gt;&lt;span&gt;(request, ctx);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; text &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; response.text.&lt;/span&gt;&lt;span&gt;toLowerCase&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; term &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; forbiddenTerms) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (text.&lt;/span&gt;&lt;span&gt;contains&lt;/span&gt;&lt;span&gt;(term.&lt;/span&gt;&lt;span&gt;toLowerCase&lt;/span&gt;&lt;span&gt;())) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Exception&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;content filter: response contains &quot;&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;term&lt;/span&gt;&lt;span&gt;&quot;&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; response;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Register it with &lt;code dir=&quot;auto&quot;&gt;defineMiddleware&lt;/code&gt; to expose a &lt;code dir=&quot;auto&quot;&gt;contentFilter()&lt;/code&gt; helper you can drop into a &lt;code dir=&quot;auto&quot;&gt;use&lt;/code&gt; array. See the &lt;a href=&quot;https://genkit.dev/docs/middleware/&quot;&gt;middleware docs&lt;/a&gt; for the full registered pattern.&lt;/p&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;p&gt;You can even compose and stack different middleware solutions. Middleware stacks left-to-right, with the first listed being the outermost wrapper:&lt;/p&gt;
&lt;starlight-tabs data-sync-key=&quot;lang&quot;&gt; &lt;div&gt; &lt;ul role=&quot;tablist&quot;&gt; &lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-57&quot; id=&quot;tab-57&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;  TypeScript &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-58&quot; id=&quot;tab-58&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Go &lt;/a&gt; &lt;/li&gt;&lt;li role=&quot;presentation&quot;&gt; &lt;a role=&quot;tab&quot; href=&quot;#tab-panel-59&quot; id=&quot;tab-59&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;  Dart &lt;/a&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div id=&quot;tab-panel-57&quot; aria-labelledby=&quot;tab-57&quot; role=&quot;tabpanel&quot;&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model: googleAI.&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-flash-latest&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt: &lt;/span&gt;&lt;span&gt;&apos;What CRM should our customer use?&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;retry&lt;/span&gt;&lt;span&gt;({ maxRetries: &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; }), &lt;/span&gt;&lt;span&gt;// outer: retries the inner stack&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;contentFilter&lt;/span&gt;&lt;span&gt;({           &lt;/span&gt;&lt;span&gt;// inner: validates model output&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;forbiddenTerms: [&lt;/span&gt;&lt;span&gt;&apos;CompetitorCRM&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;RivalCo&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;internal price&apos;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-58&quot; aria-labelledby=&quot;tab-58&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithModelName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;googleai/gemini-flash-latest&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;What CRM should our customer use?&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithUse&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;middleware&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Retry&lt;/span&gt;&lt;span&gt;{MaxRetries: &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;},           &lt;/span&gt;&lt;span&gt;// outer: retries the inner stack&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;ContentFilter&lt;/span&gt;&lt;span&gt;{                              &lt;/span&gt;&lt;span&gt;// inner: validates model output&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ForbiddenTerms: []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;CompetitorCRM&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;RivalCo&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;internal price&quot;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt;&lt;div id=&quot;tab-panel-59&quot; aria-labelledby=&quot;tab-59&quot; role=&quot;tabpanel&quot; hidden&gt; &lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; googleAI.&lt;/span&gt;&lt;span&gt;gemini&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-flash-latest&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;What CRM should our customer use?&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;use&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;retry&lt;/span&gt;&lt;span&gt;(maxRetries&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;),                 &lt;/span&gt;&lt;span&gt;// outer: retries the inner stack&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;contentFilter&lt;/span&gt;&lt;span&gt;(forbiddenTerms&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; [ &lt;/span&gt;&lt;span&gt;// inner: validates model output&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;&apos;CompetitorCRM&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;RivalCo&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;internal price&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt; &lt;/div&gt; &lt;starlight-tabs-restore&gt;&lt;/starlight-tabs-restore&gt; &lt;/starlight-tabs&gt;  
&lt;p&gt;Here &lt;code dir=&quot;auto&quot;&gt;Retry&lt;/code&gt; wraps &lt;code dir=&quot;auto&quot;&gt;ContentFilter&lt;/code&gt;, which wraps the model call. Order matters, and Genkit makes it explicit.&lt;/p&gt;
&lt;p&gt;If you think you’ve built a middleware that will be valuable to other developers, you can publish it as a package for others to benefit from!&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-developer-ui-experience&quot;&gt;The Developer UI experience&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;You can use the Genkit &lt;a href=&quot;https://genkit.dev/docs/devtools/&quot;&gt;Developer UI&lt;/a&gt; to inspect, test, and debug your application, including middleware execution. When you register middleware, it becomes visible in the Dev UI: you can inspect its configuration, trace execution through each hook layer, and test different combinations.&lt;/p&gt;
&lt;video src=&quot;/_astro/middleware.yFII6BhA.mp4&quot; controls autoplay loop muted=&quot;true&quot; playsinline&gt;&lt;/video&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;We’re excited for the capabilities that Genkit middleware unlocks for your apps, and we’re looking forward to seeing what custom middleware you’ll build to solve for your use-cases. Check out the &lt;a href=&quot;https://genkit.dev/docs/middleware/&quot;&gt;middleware documentation&lt;/a&gt; to dive deeper, or &lt;a href=&quot;https://genkit.dev/docs/get-started/&quot;&gt;get started with Genkit&lt;/a&gt; if you’re new to the framework.&lt;/p&gt;
&lt;p&gt;Have an idea for a new pre-built middleware? &lt;a href=&quot;https://github.com/genkit-ai/genkit/issues&quot;&gt;File an issue&lt;/a&gt;. We’d love to hear what would improve your development experience!&lt;/p&gt;
&lt;p&gt;Happy coding! 🚀&lt;/p&gt;</content:encoded><category>typescript</category><category>go</category><category>dart</category><category>middleware</category></item><item><title>Announcing Genkit Dart: Build full-stack AI apps with Dart and Flutter</title><link>https://genkit.dev/blog/announcing-genkit-dart/</link><guid isPermaLink="true">https://genkit.dev/blog/announcing-genkit-dart/</guid><description>Announcing the preview launch of Genkit Dart. Build full-stack, AI-powered apps for any platform with Dart and Flutter, with model flexibility, type-safety, and a local Developer UI.

</description><pubDate>Tue, 10 Mar 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The Dart and Flutter communities have always pushed the boundaries of what’s possible across screens. You’ve shown that building high-quality, multi-platform applications doesn’t require compromising on developer experience. Now we’re bringing the same “write once, run anywhere” philosophy to AI-powered features and applications.&lt;/p&gt;
&lt;p&gt;We are thrilled to announce the preview launch of &lt;strong&gt;Genkit Dart&lt;/strong&gt;, an open-source AI framework for Dart and Flutter developers. Already available for TypeScript, Go, and Python, Genkit now empowers you to build &lt;strong&gt;high-quality, full-stack, AI-powered applications for any platform&lt;/strong&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;why-choose-genkit-dart&quot;&gt;Why choose Genkit Dart?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit Dart provides you with the following capabilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Model-agnostic API:&lt;/strong&gt; Supports Google, Anthropic, OpenAI, and OpenAI API-compatible models out-of-the-box. You’re never locked into a single provider.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type safety:&lt;/strong&gt; Uses Dart’s strong type system with the &lt;code dir=&quot;auto&quot;&gt;schemantic&lt;/code&gt; package to generate strongly typed data and create type-safe AI flows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Run code anywhere:&lt;/strong&gt; Write your AI logic once and run it as a backend service or directly inside your Flutter app.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Developer UI:&lt;/strong&gt; Includes a localhost web UI where you can test prompts, view traces, and debug your flows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Complete AI toolkit:&lt;/strong&gt; Provides everything you need to build high-quality AI features, including structured output, tools, multi-step flows, observability, and more.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;model-agnostic-api&quot;&gt;Model-agnostic API&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit is designed to support any LLM provider, with out-of-the-box support for Google, Anthropic, OpenAI, and OpenAI API-compatible models in this release. This lets you switch between providers with minimal code changes.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit/genkit.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit_google_genai/genkit_google_genai.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit_anthropic/genkit_anthropic.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Initialize Genkit with plugins&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; ai &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Genkit&lt;/span&gt;&lt;span&gt;(plugins&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;googleAI&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;anthropic&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Call Google Gemini&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; geminiResponse &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; googleAI.&lt;/span&gt;&lt;span&gt;gemini&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-3.1-pro-preview&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Hello from Gemini&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Call Anthropic Claude&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; claudeResponse &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; anthropic.&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;claude-opus-4.6&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Hello from Claude&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;type-safe-ai-flows&quot;&gt;Type-safe AI flows&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit lets you wrap your AI logic into testable, observable, deployable functions called &lt;strong&gt;flows&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Here is an example of a Travel Planner flow using strongly-typed input and output schemas, with tool calling:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit/genkit.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit_google_genai/genkit_google_genai.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:schemantic/schemantic.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;part&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;travel_flow.g.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Define flow input schema with schemantic&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;@Schema&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;abstract&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$TripRequest&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; destination;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; days;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Define tool input schema&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;@Schema&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;abstract&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$WeatherRequest&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;@Field&lt;/span&gt;&lt;span&gt;(description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;The city name&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; city;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Initialize Genkit and register the Google AI plugin&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; ai &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Genkit&lt;/span&gt;&lt;span&gt;(plugins&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;googleAI&lt;/span&gt;&lt;span&gt;()]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Define a tool the model can invoke to fetch live data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;defineTool&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;fetchWeather&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Retrieves the current weather forecast for a given city&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WeatherRequest&lt;/span&gt;&lt;span&gt;.$schema,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (request, _) &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; request.city.&lt;/span&gt;&lt;span&gt;toLowerCase&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;seattle&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Rainy&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Sunny&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Construct a strongly-typed, observable flow&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; tripPlannerFlow &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;defineFlow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;planTrip&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TripRequest&lt;/span&gt;&lt;span&gt;.$schema,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;outputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (request, _) &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// Generate content using the model and tool&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; googleAI.&lt;/span&gt;&lt;span&gt;gemini&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-3.1-pro-preview&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Build a &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;days&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;-day travel itinerary for &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;destination&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;. &apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;&apos;Make sure to check the weather forecast first to suggest appropriate activities.&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;toolNames&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&apos;fetchWeather&apos;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; response.text;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Run the flow&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; itinerary &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tripPlannerFlow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;TripRequest&lt;/span&gt;&lt;span&gt;(destination&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Seattle&apos;&lt;/span&gt;&lt;span&gt;, days&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;print&lt;/span&gt;&lt;span&gt;(itinerary);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;When you’re ready, you can easily expose your flow as an API using the &lt;code dir=&quot;auto&quot;&gt;genkit_shelf&lt;/code&gt; package and deploy it to any platform that supports Dart.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit_shelf/genkit_shelf.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:shelf_router/shelf_router.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:shelf/shelf_io.dart&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; io;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// ... initialize Genkit and define tripPlannerFlow ...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; router &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Router&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;..&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;&apos;/api/planTrip&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;shelfHandler&lt;/span&gt;&lt;span&gt;(tripPlannerFlow),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; io.&lt;/span&gt;&lt;span&gt;serve&lt;/span&gt;&lt;span&gt;(router.call, &lt;/span&gt;&lt;span&gt;&apos;localhost&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;8080&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;run-anywhere-dart-runs&quot;&gt;Run anywhere Dart runs&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Most complex AI logic runs on a server. However, because Dart works on both the frontend and backend, Genkit lets you easily move your AI code between your server and your Flutter app.&lt;/p&gt;
&lt;p&gt;Here are a few ways you can build with Genkit Dart:&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-entirely-in-flutter-for-prototyping&quot;&gt;1. Entirely in Flutter for prototyping&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;You can write all of your Genkit logic, including model calls, directly in your Flutter app. This is great for prototypes or apps where users provide their own API keys and prompts aren’t private.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; You should never publish an app with your API key embedded in the source code as it can be extracted and used by others.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;2-call-backend-flows-from-flutter&quot;&gt;2. Call backend flows from Flutter&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;When your prompts are sensitive or your AI logic is complex, you can move the entire flow to your backend. Your Flutter app can then call this flow by defining it as a “remote action”. Since the backend and frontend are both in Dart, they can share the same schemas for end-to-end type safety.&lt;/p&gt;
&lt;p&gt;Here is an example showing how to call the Trip Planner backend flow we defined earlier from your Flutter app:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit/client.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:my_shared_models/models.dart&apos;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;// Shared schema&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; tripPlannerFlow &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;defineRemoteAction&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;https://your-server.com/api/planTrip&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;inputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TripRequest&lt;/span&gt;&lt;span&gt;.$schema,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;outputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; itinerary &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tripPlannerFlow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TripRequest&lt;/span&gt;&lt;span&gt;(destination&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Tokyo&apos;&lt;/span&gt;&lt;span&gt;, days&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-in-flutter-with-remote-models&quot;&gt;3. In Flutter with remote models&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;To secure your API keys while keeping the core AI logic in your Flutter app, you can create a small Genkit backend that proxies requests to the model provider with custom authorization logic. The models exposed through this backend are &lt;strong&gt;remote models&lt;/strong&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit_google_genai/genkit_google_genai.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit_shelf/genkit_shelf.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:shelf_router/shelf_router.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:shelf/shelf_io.dart&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; io;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Backend securely proxies requests to the model&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; geminiApi &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;googleAI&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; targetModel &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; geminiApi.&lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;gemini-3.1-flash-lite-preview&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; router &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Router&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;..&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;&apos;/api/gemini-model&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;shelfHandler&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;targetModel,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// Insert custom authorization logic here&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;contextProvider&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (req) &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;&apos;customAuth&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; io.&lt;/span&gt;&lt;span&gt;serve&lt;/span&gt;&lt;span&gt;(router.call, &lt;/span&gt;&lt;span&gt;&apos;localhost&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;8080&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;In your Flutter app, use the remote model instead of a direct model plugin, passing any headers your server needs. This saves you from exposing your API keys and gives you more control over request authorization.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;package:genkit/genkit.dart&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Flutter app communicates with the proxy server&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; ai &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Genkit&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; secureModel &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;defineRemoteModel&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;secureModel&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;https://api.yourdomain.com/api/gemini-model&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;headers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (context) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt;&apos;Authorization&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Bearer &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;fetchSessionToken&lt;/span&gt;&lt;span&gt;()}&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; response &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;generate&lt;/span&gt;&lt;span&gt;(model&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; secureModel, prompt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Write me a poem.&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;powerful-tools-for-ai-development&quot;&gt;Powerful tools for AI development&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Building high-quality AI applications requires thorough testing and continuous iteration to achieve reliable results. To help with this, Genkit provides a powerful local Developer UI.&lt;/p&gt;
&lt;p&gt;You can start the Developer UI alongside your code by running your app with the Genkit CLI:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;genkit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;start&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bin/server.dart&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Here is a look at testing a more advanced version of our Trip Planner flow in the Developer UI:&lt;/p&gt;
&lt;img src=&quot;https://genkit.dev/_astro/genkit-dart-devui.BEcBveTD_Z14QEMW.webp&quot; alt=&quot;The Genkit Developer UI running the Trip Planner flow&quot; width=&quot;3456&quot; height=&quot;2168&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;
&lt;div&gt;&lt;h2 id=&quot;ai-coding-assistance&quot;&gt;AI coding assistance&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;For the best experience using Genkit Dart with AI coding tools like Antigravity, Gemini CLI, or Claude Code, install the &lt;strong&gt;Genkit Dart agent skill&lt;/strong&gt;. This gives your AI assistant the knowledge to accurately write and debug your AI features.&lt;/p&gt;
&lt;p&gt;Add the skill to your project:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;npx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;skills&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;genkit-ai/skills&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;learn-more&quot;&gt;Learn more&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;This release is an &lt;strong&gt;early preview&lt;/strong&gt;. We want to work with Dart and Flutter developers to improve the framework. You can find the core packages and provider plugins on pub.dev today.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Get started:&lt;/strong&gt; Read our &lt;a href=&quot;https://genkit.dev/docs/dart/get-started/&quot;&gt;quickstart guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Join the community:&lt;/strong&gt; Join our &lt;a href=&quot;https://discord.gg/qXt5zzQKpc&quot;&gt;Discord server&lt;/a&gt; to ask questions and chat with the team.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stay updated:&lt;/strong&gt; Follow us on &lt;a href=&quot;https://x.com/genkitframework&quot;&gt;X&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/company/genkit&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Give feedback:&lt;/strong&gt; Open an issue on our &lt;a href=&quot;https://github.com/genkit-ai/genkit-dart&quot;&gt;GitHub repository&lt;/a&gt; to report bugs or request features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can’t wait to see what you build with Genkit Dart!&lt;/p&gt;</content:encoded><category>dart</category><category>flutter</category><category>announcements</category></item><item><title>Announcing Genkit Go 1.0 and enhanced AI-assisted development</title><link>https://genkit.dev/blog/announcing-genkit-go-1-0/</link><guid isPermaLink="true">https://genkit.dev/blog/announcing-genkit-go-1-0/</guid><description>Genkit Go 1.0 is the first stable, production-ready release of Google&apos;s open-source AI framework for Go, alongside the new genkit init:ai-tools command for AI-assisted development.

</description><pubDate>Wed, 10 Sep 2025 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We’re excited to announce the release of &lt;strong&gt;Genkit Go 1.0&lt;/strong&gt;, the first stable, production-ready release of Google’s open-source AI development framework for the Go ecosystem. Along with this release, we’re also introducing the &lt;code dir=&quot;auto&quot;&gt;genkit init:ai-tools&lt;/code&gt; command to supercharge your AI-assisted development workflow.&lt;/p&gt;
&lt;p&gt;Genkit is an open-source framework for building full-stack AI-powered applications. It provides a unified interface for multiple model providers and streamlined APIs for multimodal content, structured outputs, tool calling, retrieval-augmented generation (RAG), and agentic workflows. With Genkit Go, you can now build and deploy production-ready AI applications with the speed, safety, and reliability of Go.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;tldr&quot;&gt;TL;DR&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Genkit Go&lt;/strong&gt; is now stable and ready for production use!&lt;/p&gt;
&lt;p&gt;Key features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Type-safe AI flows&lt;/strong&gt; with Go structs and JSON schema validation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unified model interface&lt;/strong&gt; supporting Google AI, Vertex AI, OpenAI, Ollama, and more&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool calling, RAG, and multimodal support&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rich local development tools&lt;/strong&gt; with a standalone CLI binary and Developer UI&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI coding assistant integration&lt;/strong&gt; via the &lt;code dir=&quot;auto&quot;&gt;genkit init:ai-tools&lt;/code&gt; command for tools like the Gemini CLI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ready to start coding? Check out our &lt;a href=&quot;https://genkit.dev/docs/go/get-started/&quot;&gt;get started guide&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;whats-new-in-genkit-go-10&quot;&gt;What’s new in Genkit Go 1.0&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;production-ready&quot;&gt;Production-ready&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Genkit Go 1.0 represents our commitment to providing a stable, reliable foundation for building AI-powered applications in Go. With this release, you can deploy AI-powered applications to production with Genkit, knowing that the API is stable and well-tested.&lt;/p&gt;
&lt;p&gt;Like Go itself, it is intended that programs written with Genkit 1.* will continue to compile and run correctly, unchanged, even as future “point” releases of Genkit arise (Genkit 1.1, Genkit 1.2, etc.).&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;type-safe-ai-flows&quot;&gt;Type-safe AI flows&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;One of Genkit’s most powerful features is &lt;strong&gt;flows&lt;/strong&gt;: functions for AI use-cases that provide observability, easy testing, and simplified deployment. Here’s how you can define a flow in Go for generating structured recipes:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;package&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;encoding/json&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;fmt&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github.com/firebase/genkit/go/ai&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github.com/firebase/genkit/go/genkit&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github.com/firebase/genkit/go/plugins/googlegenai&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Define your data structures&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RecipeInput&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Ingredient          &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`json:&quot;ingredient&quot; jsonschema:&quot;description=Main ingredient or cuisine type&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;DietaryRestrictions &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`json:&quot;dietaryRestrictions,omitempty&quot; jsonschema:&quot;description=Any dietary restrictions&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Recipe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Title        &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;`json:&quot;title&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Description  &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;`json:&quot;description&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;PrepTime     &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;`json:&quot;prepTime&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;CookTime     &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;`json:&quot;cookTime&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Servings     &lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;`json:&quot;servings&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Ingredients  []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`json:&quot;ingredients&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Instructions []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`json:&quot;instructions&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Tips         []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`json:&quot;tips,omitempty&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ctx &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; context.&lt;/span&gt;&lt;span&gt;Background&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Initialize Genkit with plugins&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;g &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Init&lt;/span&gt;&lt;span&gt;(ctx,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;genkit.&lt;/span&gt;&lt;span&gt;WithPlugins&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;googlegenai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;GoogleAI&lt;/span&gt;&lt;span&gt;{}),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;genkit.&lt;/span&gt;&lt;span&gt;WithDefaultModel&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;googleai/gemini-flash-latest&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Define a type-safe flow&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;recipeFlow &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;DefineFlow&lt;/span&gt;&lt;span&gt;(g, &lt;/span&gt;&lt;span&gt;&quot;recipeGeneratorFlow&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Context&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;RecipeInput&lt;/span&gt;&lt;span&gt;) (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;Recipe&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;dietaryRestrictions &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; input.DietaryRestrictions&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; dietaryRestrictions &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;dietaryRestrictions &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;none&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prompt &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; fmt.&lt;/span&gt;&lt;span&gt;Sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`Create a recipe with the following requirements:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Main ingredient: &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Dietary restrictions: &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;, input.Ingredient, dietaryRestrictions)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// Generate structured data with type safety&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;recipe, _, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;GenerateData&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Recipe&lt;/span&gt;&lt;span&gt;](ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(prompt),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;                &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;span&gt;, fmt.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;failed to generate recipe: &lt;/span&gt;&lt;span&gt;%w&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, err)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; recipe, &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Run the flow&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;recipe, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; recipeFlow.&lt;/span&gt;&lt;span&gt;Run&lt;/span&gt;&lt;span&gt;(ctx, &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;RecipeInput&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Ingredient:          &lt;/span&gt;&lt;span&gt;&quot;avocado&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;DietaryRestrictions: &lt;/span&gt;&lt;span&gt;&quot;vegetarian&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;log.&lt;/span&gt;&lt;span&gt;Fatalf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;could not generate recipe: &lt;/span&gt;&lt;span&gt;%v&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, err)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Print the structured recipe&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;recipeJSON, _ &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; json.&lt;/span&gt;&lt;span&gt;MarshalIndent&lt;/span&gt;&lt;span&gt;(recipe, &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;  &quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fmt.&lt;/span&gt;&lt;span&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Sample recipe generated:&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fmt.&lt;/span&gt;&lt;span&gt;Println&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;(recipeJSON))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&amp;#x3C;-&lt;/span&gt;&lt;span&gt;ctx.&lt;/span&gt;&lt;span&gt;Done&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;// Used for local testing only&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;unified-model-interface&quot;&gt;Unified model interface&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Genkit Go provides a single, consistent interface for working with multiple AI model providers including Google AI, Vertex AI, OpenAI, Anthropic, and Ollama. Learn more about &lt;a href=&quot;https://genkit.dev/docs/go/models/&quot;&gt;generating content with AI models&lt;/a&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Use Google AI models&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithModelName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;googleai/gemini-flash-latest&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;What is the weather like today?&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Use OpenAI models&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithModelName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;openai/gpt-4o&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;How are you today?&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Switch to Ollama for local models&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithModelName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;ollama/llama3&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;What is the meaning of life?&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;tool-calling&quot;&gt;Tool calling&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Genkit Go makes it easy to give your AI models access to external functions and APIs. See the &lt;a href=&quot;https://genkit.dev/docs/go/tool-calling/&quot;&gt;complete tool calling guide&lt;/a&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Define a tool&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WeatherInput&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Location &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;`json:&quot;location&quot; jsonschema_description:&quot;Location to get weather for&quot;`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;getWeatherTool &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;DefineTool&lt;/span&gt;&lt;span&gt;(g, &lt;/span&gt;&lt;span&gt;&quot;getWeather&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&quot;Gets the current weather in a given location&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;ai&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ToolContext&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WeatherInput&lt;/span&gt;&lt;span&gt;) (&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// Your weather API logic here&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; fmt.&lt;/span&gt;&lt;span&gt;Sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;The current weather in &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; is 72°F and sunny.&quot;&lt;/span&gt;&lt;span&gt;, input.Location), &lt;/span&gt;&lt;span&gt;nil&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Use the tool in generation&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;resp, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;Generate&lt;/span&gt;&lt;span&gt;(ctx, g,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithPrompt&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;What&apos;s the weather in San Francisco?&quot;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ai.&lt;/span&gt;&lt;span&gt;WithTools&lt;/span&gt;&lt;span&gt;(getWeatherTool),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;easy-deployment&quot;&gt;Easy deployment&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Deploy your flows as HTTP endpoints with minimal setup. See the &lt;a href=&quot;https://genkit.dev/docs/go/deployment/cloud-run/&quot;&gt;deployment guides&lt;/a&gt; for more options:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Create HTTP handlers for your flows&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;mux &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; http.&lt;/span&gt;&lt;span&gt;NewServeMux&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;mux.&lt;/span&gt;&lt;span&gt;HandleFunc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;POST /recipeGeneratorFlow&quot;&lt;/span&gt;&lt;span&gt;, genkit.&lt;/span&gt;&lt;span&gt;Handler&lt;/span&gt;&lt;span&gt;(recipeFlow))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Start the server&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;log.&lt;/span&gt;&lt;span&gt;Fatal&lt;/span&gt;&lt;span&gt;(server.&lt;/span&gt;&lt;span&gt;Start&lt;/span&gt;&lt;span&gt;(ctx, &lt;/span&gt;&lt;span&gt;&quot;127.0.0.1:3400&quot;&lt;/span&gt;&lt;span&gt;, mux))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;rich-developer-tooling&quot;&gt;Rich developer tooling&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit Go comes with a comprehensive set of development tools designed to make building AI applications fast and intuitive. The entire local toolchain is available through a single CLI that works seamlessly with your Go development workflow.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;standalone-cli-installation&quot;&gt;Standalone CLI installation&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Get started quickly with our standalone CLI binary, with no other runtime installations required:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For macOS and Linux:&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-sL&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cli.genkit.dev&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bash&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;For Windows:&lt;/strong&gt; Download directly from &lt;a href=&quot;https://cli.genkit.dev&quot;&gt;cli.genkit.dev&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The CLI works with Genkit applications in any supported language (JavaScript, Go, Python) and provides you with several convenient commands to rapidly test and iterate such as running and evaluating your flows.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;interactive-developer-ui&quot;&gt;Interactive Developer UI&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The Developer UI provides a visual interface for testing and debugging your AI applications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Test flows interactively&lt;/strong&gt;: Run flows with different inputs and see cleanly rendered results&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Debug with detailed tracing&lt;/strong&gt;: Visualize exactly what your AI flows are doing step-by-step&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor performance&lt;/strong&gt;: Track latency, token usage, and costs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Experiment with prompts&lt;/strong&gt;: Test different prompts and model configurations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Launch the Developer UI alongside your Go application through the CLI:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;genkit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;start&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;go&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Here’s what the experience looks like when running and inspecting the &lt;code dir=&quot;auto&quot;&gt;recipeGenerator&lt;/code&gt; flow from earlier:&lt;/p&gt;
&lt;video src=&quot;/_astro/devui-flow-runner-clipped.M3nxPQfi.mp4&quot; controls autoplay loop muted=&quot;true&quot; playsinline&gt;&lt;/video&gt;
&lt;div&gt;&lt;h2 id=&quot;introducing-genkit-initai-tools&quot;&gt;Introducing &lt;code dir=&quot;auto&quot;&gt;genkit init:ai-tools&lt;/code&gt;&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;We’re also excited to introduce the &lt;code dir=&quot;auto&quot;&gt;genkit init:ai-tools&lt;/code&gt; command that revolutionizes how you work with AI assistants during development. This feature, now available for both JavaScript and &lt;strong&gt;Go developers&lt;/strong&gt;, automatically configures popular AI coding assistants to work seamlessly with the Genkit framework and tooling. Learn more about &lt;a href=&quot;https://genkit.dev/docs/go/mcp-server/&quot;&gt;AI-assisted development in Genkit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To use it, install the Genkit CLI and run:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;genkit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;init:ai-tools&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Running the command does the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Detects existing AI assistant configurations&lt;/strong&gt; and preserves your current settings&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Installs the Genkit MCP server&lt;/strong&gt; with powerful development tools:
&lt;ul&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;lookup_genkit_docs&lt;/code&gt;: Search Genkit documentation from genkit.dev&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;list_flows&lt;/code&gt;: List all flows in your current Genkit app&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;run_flow&lt;/code&gt;: Execute flows with test inputs&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;get_trace&lt;/code&gt;: Fetch execution traces for debugging and analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Creates a GENKIT.md file&lt;/strong&gt; with comprehensive language-specific instructions for AI assistants&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;h3 id=&quot;supported-ai-tools&quot;&gt;Supported AI tools&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The command has built-in support for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gemini CLI&lt;/strong&gt; - Google’s CLI-based AI coding assistant&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Firebase Studio&lt;/strong&gt; - Firebase’s agentic, cloud-based development environment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; - Anthropic’s coding assistant&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cursor&lt;/strong&gt; - AI-powered code editor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For other tools, select the “generic” option to get a &lt;code dir=&quot;auto&quot;&gt;GENKIT.md&lt;/code&gt; file you can integrate manually.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;enhanced-development-experience&quot;&gt;Enhanced development experience&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;With AI assistant integration, you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ask questions about Genkit Go APIs&lt;/strong&gt; and get accurate, up-to-date answers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generate Go-specific Genkit code&lt;/strong&gt; that follows best practices&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Debug flows&lt;/strong&gt; by having your AI assistant analyze traces&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test your applications&lt;/strong&gt; with AI-generated inputs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Get help with Go-specific patterns&lt;/strong&gt; and idiomatic code&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;quick-start&quot;&gt;Quick start&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;1. Create a new project:&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-genkit-app&lt;/span&gt;&lt;span&gt; &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-genkit-app&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;go&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;example/my-genkit-app&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2. Install Genkit and CLI:&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;go&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;github.com/firebase/genkit/go&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-sL&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cli.genkit.dev&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bash&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;3. Set up AI assistant integration:&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;genkit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;init:ai-tools&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;4. Create your first flow&lt;/strong&gt; using the examples above&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Start the Developer UI:&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;genkit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;start&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;go&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;For a more detailed walkthrough, see the &lt;a href=&quot;https://genkit.dev/docs/go/get-started/&quot;&gt;get started guide&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;learn-more&quot;&gt;Learn more&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href=&quot;https://genkit.dev&quot;&gt;genkit.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Get started guide&lt;/strong&gt;: &lt;a href=&quot;https://genkit.dev/docs/go/get-started/&quot;&gt;Go quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go API reference&lt;/strong&gt;: &lt;a href=&quot;https://pkg.go.dev/github.com/firebase/genkit/go&quot;&gt;pkg.go.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;a href=&quot;https://github.com/firebase/genkit/tree/main/go/samples&quot;&gt;GitHub samples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Community&lt;/strong&gt;: &lt;a href=&quot;https://discord.gg/qXt5zzQKpc&quot;&gt;Genkit Discord&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Genkit Go 1.0 combines Go’s performance and reliability with Genkit’s production-ready AI framework and tooling. We can’t wait to see what you build!&lt;/p&gt;
&lt;p&gt;Happy coding! 🚀&lt;/p&gt;</content:encoded><category>go</category><category>announcements</category></item></channel></rss>