<?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>Announcing Genkit Dart 1.0: Build production-ready agentic apps with Dart and Flutter</title><link>https://genkit.dev/blog/genkit-dart-1-0/</link><guid isPermaLink="true">https://genkit.dev/blog/genkit-dart-1-0/</guid><description>Announcing the stable 1.0 release of Genkit Dart, Google&apos;s open-source framework for building AI-powered features and agentic apps with Dart and Flutter.

</description><pubDate>Thu, 08 Oct 2026 12:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This announcement was cross-posted from the &lt;a href=&quot;https://flutter.dev/blog/announcing-genkit-dart-1-0&quot;&gt;official Flutter blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Dart and Flutter let you build high-quality apps for mobile, web, and desktop from a single codebase. With &lt;a href=&quot;https://genkit.dev/docs/dart/get-started/&quot;&gt;Genkit Dart&lt;/a&gt;, you can bring that same productivity to full-stack, agentic apps.&lt;/p&gt;
&lt;p&gt;Today, we’re announcing &lt;strong&gt;Genkit Dart 1.0&lt;/strong&gt;, the first stable, production-ready release of Google’s open-source framework for building AI-powered features and agents in Dart. Since our &lt;a href=&quot;https://dart.dev/blog/announcing-genkit-dart-build-full-stack-ai-apps-with-dart-and-flutter&quot;&gt;preview launch&lt;/a&gt; earlier this year, feedback from the Dart and Flutter community has helped us refine the APIs and expand the toolkit for production workloads.&lt;/p&gt;
&lt;p&gt;To get started, add &lt;code dir=&quot;auto&quot;&gt;genkit&lt;/code&gt; 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;dart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pub&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&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You can also install the agent skill to give AI coding assistants like Antigravity, Claude Code, and Codex up-to-date knowledge of Genkit Dart APIs and best practices:&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;why-genkit-dart&quot;&gt;Why Genkit Dart&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit provides a unified API across model providers, end-to-end type safety between your server and client, and local tooling to test and debug your AI workflows.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;use-any-model-with-one-api&quot;&gt;Use any model with one API&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Genkit supports Google Gemini, Anthropic Claude, OpenAI, and OpenAI-compatible models through a single interface. You register model providers as plugins and can switch between models without rewriting your application logic:&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; 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;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;final&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;Suggest a weekend getaway from San Francisco.&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;final&lt;/span&gt;&lt;span&gt; fromGemini &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; prompt,&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; fromClaude &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-sonnet-5-5&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; prompt,&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;end-to-end-type-safety-with-flows&quot;&gt;End-to-end type safety with flows&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Genkit lets you wrap your AI logic into &lt;strong&gt;flows&lt;/strong&gt;: strongly typed, observable functions that are easy to test and deploy as HTTP endpoints. Using the &lt;a href=&quot;https://pub.dev/packages/schemantic&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;schemantic&lt;/code&gt;&lt;/a&gt; package, you can define your data schemas once in Dart, generate structured output from the model, and share those exact types between your backend and 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;// shared/lib/models.dart (used by both server and app)&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;span&gt;// ...plus an Itinerary schema for the result.&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;// server/bin/server.dart&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; planTrip &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;Itinerary&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;/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-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;Plan 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 trip to &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;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;outputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Itinerary&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;);&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.output&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;span&gt;await&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;GenkitRouter&lt;/span&gt;&lt;span&gt;()..&lt;/span&gt;&lt;span&gt;addAction&lt;/span&gt;&lt;span&gt;(planTrip)).&lt;/span&gt;&lt;span&gt;serve&lt;/span&gt;&lt;span&gt;(port&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;8080&lt;/span&gt;&lt;span&gt;); &lt;/span&gt;&lt;span&gt;// POST /planTrip&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;// app/lib/main.dart&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; planTrip &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://api.example.com/planTrip&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;// Your Genkit endpoint&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;Itinerary&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;/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;planTrip&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;Kyoto&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;run-anywhere-dart-runs&quot;&gt;Run anywhere Dart runs&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Because your AI logic is written in standard Dart, you get fast iteration with hot reload and the flexibility to run your code wherever it fits your architecture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Directly in Flutter:&lt;/strong&gt; Call models straight from your app for rapid prototyping or bring-your-own-key experiences (never embed private API keys in a published client app).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On a Dart server:&lt;/strong&gt; Run complex flows and keep sensitive prompts on the backend, then call them from Flutter using &lt;code dir=&quot;auto&quot;&gt;defineRemoteAction&lt;/code&gt; as shown above.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;In Flutter with remote models:&lt;/strong&gt; Keep your AI logic in the Flutter app while routing model requests through a lightweight Genkit backend that protects your API keys and enforces authorization:&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;server/bin/server.dart&lt;/span&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; genkit &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;GenkitRouter&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;addAction&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;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;path&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;/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;// Runs before the model; throw a GenkitException to reject the 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;&lt;/span&gt;&lt;span&gt;contextProvider&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;/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;&apos;user&apos;&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;verifyUser&lt;/span&gt;&lt;span&gt;(request.headers[&lt;/span&gt;&lt;span&gt;&apos;authorization&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;await&lt;/span&gt;&lt;span&gt; genkit.&lt;/span&gt;&lt;span&gt;serve&lt;/span&gt;&lt;span&gt;(port&lt;/span&gt;&lt;span&gt;:&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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// app/lib/main.dart&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; gemini &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;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;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;https://api.example.com/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;headers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; (context) &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;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;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getIdToken&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;(&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; 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;&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;Suggest a packing list for Kyoto in April.&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;h3 id=&quot;test-and-debug-with-the-developer-ui&quot;&gt;Test and debug with the Developer UI&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Genkit includes a local Developer UI for testing flows, experimenting with prompts, and inspecting execution traces step by step. Launch it alongside your Dart process using 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;img src=&quot;https://genkit.dev/_astro/devui-trace.Bi-BxTMR_ZyuvfF.webp&quot; alt=&quot;Inspecting an agent&amp;#x27;s model and tool calls in the Genkit Developer UI&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2020&quot; height=&quot;1400&quot;&gt;
&lt;div&gt;&lt;h2 id=&quot;built-for-agentic-workflows&quot;&gt;Built for agentic workflows&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Since the preview launch, we’ve expanded Genkit Dart with capabilities designed for multi-step agentic workflows, including human-in-the-loop interrupts, generation middleware, prompt management, and production telemetry.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;give-models-tools-with-human-in-the-loop-interrupts&quot;&gt;Give models tools with human-in-the-loop interrupts&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Tools let models call your Dart functions to fetch data or trigger actions, like searching for flights or booking a hotel. When an action requires user confirmation, a tool can pause the generation loop by returning &lt;code dir=&quot;auto&quot;&gt;.interrupt(...)&lt;/code&gt; instead of &lt;code dir=&quot;auto&quot;&gt;.response(...)&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;final&lt;/span&gt;&lt;span&gt; bookHotel &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;bookHotel&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;Books a hotel room for the user.&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;HotelBooking&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; (input, ctx) &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;// Ask the user to confirm before charging their card.&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; (ctx.resumed &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&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;interrupt&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;span&gt;&apos;hotel&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; input.hotelName, &lt;/span&gt;&lt;span&gt;&apos;total&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; input.totalPrice});&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;final&lt;/span&gt;&lt;span&gt; confirmation &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; hotels.&lt;/span&gt;&lt;span&gt;book&lt;/span&gt;&lt;span&gt;(input);&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;response&lt;/span&gt;&lt;span&gt;(confirmation.id);&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;Putting the approval check inside the tool guarantees that the model can’t bypass it. When &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; returns with &lt;code dir=&quot;auto&quot;&gt;FinishReason.interrupted&lt;/code&gt;, your Flutter app can prompt the user for confirmation and resume execution from where it paused.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;extend-generation-with-middleware&quot;&gt;Extend generation with middleware&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Middleware hooks directly into the &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; loop to intercept model calls, inject tools, or modify requests and responses. Using &lt;code dir=&quot;auto&quot;&gt;genkit&lt;/code&gt; and &lt;a href=&quot;https://pub.dev/packages/genkit_middleware&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;genkit_middleware&lt;/code&gt;&lt;/a&gt;, you can attach prepackaged middleware like automatic retries, dynamic &lt;code dir=&quot;auto&quot;&gt;SKILL.md&lt;/code&gt; loading, and tool approval rules to any &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; call:&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; 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;span&gt;SkillsPlugin&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;ToolApprovalPlugin&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;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;Move my Kyoto hotel check-in to Friday.&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; [findBookings, updateBooking],&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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&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;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;span&gt;&apos;findBookings&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;use_skill&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;p&gt;You can also author custom middleware with &lt;code dir=&quot;auto&quot;&gt;defineGenerateMiddleware&lt;/code&gt; for cross-cutting logic like logging, caching, or model fallbacks.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;manage-prompts-with-dotprompt&quot;&gt;Manage prompts with Dotprompt&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://genkit.dev/docs/dart/dotprompt/&quot;&gt;Dotprompt&lt;/a&gt; lets you manage prompt templates, model configuration, and input/output schemas together in &lt;code dir=&quot;auto&quot;&gt;.prompt&lt;/code&gt; files. Genkit automatically loads prompts from your &lt;code dir=&quot;auto&quot;&gt;prompts/&lt;/code&gt; directory so you can invoke them as callable functions in 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;---&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;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;destination&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;string&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;Write a friendly, two-sentence introduction to &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; for a first-time visitor.&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;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; introPrompt &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;destinationIntro&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;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;introPrompt&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;span&gt;&apos;destination&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Kyoto&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;h3 id=&quot;monitor-your-app-in-production&quot;&gt;Monitor your app in production&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;When you’re ready to deploy, the &lt;a href=&quot;https://pub.dev/packages/genkit_otel&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;genkit_otel&lt;/code&gt;&lt;/a&gt; package exports traces, token usage, and latency metrics using the OpenTelemetry GenAI semantic conventions, integrating directly with your existing observability backend:&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:dartastic_opentelemetry/dartastic_opentelemetry.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/telemetry.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_otel/genkit_otel.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;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OTel&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;initialize&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;configureInstrumentation&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;GenAiInstrumentation&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;whats-next-stateful-agents-and-generative-ui&quot;&gt;What’s next: stateful agents and generative UI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Alongside the stable 1.0 core, we’re developing higher-level agentic APIs under the &lt;code dir=&quot;auto&quot;&gt;package:genkit/experimental.dart&lt;/code&gt; import so you can try them early and help shape their design.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stateful agents&lt;/strong&gt; combine a model, tools, system instructions, and state into a single &lt;code dir=&quot;auto&quot;&gt;defineAgent&lt;/code&gt; call. Conversations persist across turns and app restarts using session stores, and you can use &lt;code dir=&quot;auto&quot;&gt;remoteAgent&lt;/code&gt; to delegate tasks to subagents or expose agents over HTTP to connect with 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/experimental.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;final&lt;/span&gt;&lt;span&gt; travelAgent &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;defineAgent&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;travelAgent&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; 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;system&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;You help users plan and book trips.&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; [searchFlights, bookHotel],&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;store&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FirestoreSessionStore&lt;/span&gt;&lt;span&gt;(collection&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;sessions&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; chat &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; travelAgent.&lt;/span&gt;&lt;span&gt;chat&lt;/span&gt;&lt;span&gt;(sessionId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;user-123&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;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; chat.&lt;/span&gt;&lt;span&gt;send&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;&apos;Find me a weekend in Lisbon.&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;p&gt;&lt;strong&gt;Generative UI with A2UI&lt;/strong&gt; lets agents stream interactive UI surfaces instead of plain text. With &lt;a href=&quot;https://pub.dev/packages/genkit_a2ui&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;genkit_a2ui&lt;/code&gt;&lt;/a&gt;, an agent can emit components like date pickers, forms, and confirmation cards that your Flutter app renders incrementally as native widgets. Check out the &lt;a href=&quot;https://genkit.dev/docs/dart/agents/a2ui/&quot;&gt;A2UI guide&lt;/a&gt; to learn more.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit Dart 1.0 is available on &lt;a href=&quot;https://pub.dev/packages/genkit&quot;&gt;pub.dev&lt;/a&gt; today. Thank you to everyone in the Dart and Flutter community who built with the preview, reported issues, and contributed pull requests to help bring Genkit Dart to 1.0.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Get started:&lt;/strong&gt; Follow 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;Explore samples:&lt;/strong&gt; Browse the &lt;a href=&quot;https://github.com/genkit-ai/genkit-dart/tree/main/testapps&quot;&gt;sample apps on GitHub&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Join the community:&lt;/strong&gt; Chat with the team on &lt;a href=&quot;https://discord.gg/qXt5zzQKpc&quot;&gt;Discord&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stay updated:&lt;/strong&gt; Follow Genkit 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;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can’t wait to see what you build with Genkit Dart 1.0!&lt;/p&gt;</content:encoded><category>dart</category><category>flutter</category><category>announcements</category><category>releases</category></item><item><title>Genkit Python 0.12: Generative UI with A2UI, typed Pydantic streaming, and Deep Research and Lyria models</title><link>https://genkit.dev/blog/genkit-python-0-12/</link><guid isPermaLink="true">https://genkit.dev/blog/genkit-python-0-12/</guid><description>Genkit Python 0.12 brings generative UI with A2UI, typed Pydantic streaming, Deep Research and Lyria 3 models, and simpler mid-turn error recovery.

</description><pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://genkit.dev/docs/python/overview/&quot;&gt;Genkit Python&lt;/a&gt; 0.12 makes it easier to build interactive, multimodal AI applications in Python. With the new &lt;code dir=&quot;auto&quot;&gt;genkit-a2ui&lt;/code&gt; package, your agents can render interactive UI components instead of plain text, and &lt;code dir=&quot;auto&quot;&gt;generate_stream&lt;/code&gt; now yields typed Pydantic model instances as tokens arrive. This release also adds support for Google’s Deep Research and Lyria 3 audio generation models, along with simpler error recovery during multi-step turns.&lt;/p&gt;
&lt;p&gt;To start using this new version, run the following command in your terminal:&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;uv&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&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;genkit-google-genai&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;build-interactive-uis-with-a2ui&quot;&gt;Build interactive UIs with A2UI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Plain text is often not the best interface for tasks like booking a table, filtering search results, or filling out a form. The new &lt;code dir=&quot;auto&quot;&gt;genkit-a2ui&lt;/code&gt; package brings &lt;a href=&quot;https://a2ui.org/&quot;&gt;A2UI&lt;/a&gt; generative UI support to Genkit Python, letting your models respond with rich, interactive UI components.&lt;/p&gt;
&lt;p&gt;Install the package alongside core Genkit:&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;uv&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-a2ui&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Add &lt;code dir=&quot;auto&quot;&gt;Surfaces()&lt;/code&gt; to &lt;code dir=&quot;auto&quot;&gt;use&lt;/code&gt; on &lt;code dir=&quot;auto&quot;&gt;ai.generate&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;ai.define_agent&lt;/code&gt; to enable generative UI. Across multi-turn conversations, &lt;code dir=&quot;auto&quot;&gt;Surfaces()&lt;/code&gt; automatically tracks what is currently on screen and feeds user interactions, such as button clicks or form submissions, back into the conversation so the model can update the UI in place:&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;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_a2ui &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Surfaces, envelopes_from_parts&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GoogleAI&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;ai &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;[GoogleAI()])&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;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.generate(&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;GoogleAI.gemini_model(&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;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Show me the current weather and forecast for Tokyo.&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;use&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;[Surfaces()],&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;print&lt;/span&gt;&lt;span&gt;(envelopes_from_parts(response.message.content))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Out of the box, &lt;code dir=&quot;auto&quot;&gt;Surfaces()&lt;/code&gt; validates generated UI against a built-in catalog of common layout and input components, or you can register your own custom design system components with &lt;code dir=&quot;auto&quot;&gt;load_catalog&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Because A2UI uses a language-agnostic format, you can pair a Genkit Python backend with web frontends in JavaScript or TypeScript and multi-platform apps built with Dart and Flutter. Genkit’s client helpers (&lt;code dir=&quot;auto&quot;&gt;@genkit-ai/a2ui/client&lt;/code&gt; for JavaScript and &lt;code dir=&quot;auto&quot;&gt;package:genkit_a2ui/client.dart&lt;/code&gt; for Dart and Flutter) handle extracting streamed UI updates for your renderer and sending user actions back to your Python agent:&lt;/p&gt;
&lt;video src=&quot;/_astro/a2ui-demo.ClEAg0EX.mp4&quot; controls loop muted playsinline&gt;&lt;/video&gt;
&lt;p&gt;&lt;em&gt;A Flutter client rendering an interactive Cymbal Bistro reservation form streamed from a Genkit Python agent with A2UI, then submitting the selected time slot and seating preference to confirm the booking.&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;stream-typed-pydantic-models&quot;&gt;Stream typed Pydantic models&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When you stream structured outputs with &lt;code dir=&quot;auto&quot;&gt;output_schema&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;generate_stream&lt;/code&gt; now populates &lt;code dir=&quot;auto&quot;&gt;chunk.output&lt;/code&gt; with a partial Pydantic model instance instead of a raw dictionary. You get editor autocomplete and type-safe attribute access while rendering live UI updates as tokens arrive:&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;from&lt;/span&gt;&lt;span&gt; pydantic &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; BaseModel&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GoogleAI&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;ai &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Genkit(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;plugins&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;[GoogleAI()],&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;GoogleAI.gemini_model(&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;/div&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;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Country&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BaseModel&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;str&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;capital: &lt;/span&gt;&lt;span&gt;str&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;population: &lt;/span&gt;&lt;span&gt;int&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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sr &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.generate_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;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Give quick facts about Japan.&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;output_schema&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;Country,&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;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; chunk &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; sr:&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; chunk.output &lt;/span&gt;&lt;span&gt;and&lt;/span&gt;&lt;span&gt; chunk.output.name:&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;(chunk.output.name)&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_country &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; sr.response).output&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;(final_country)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;As fields stream in, unset fields default to &lt;code dir=&quot;auto&quot;&gt;None&lt;/code&gt; and partial strings grow with each chunk. Once streaming completes, &lt;code dir=&quot;auto&quot;&gt;(await sr.response).output&lt;/code&gt; returns the fully validated &lt;code dir=&quot;auto&quot;&gt;Country&lt;/code&gt; instance.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;run-deep-research-jobs-and-generate-audio-with-lyria-3&quot;&gt;Run Deep Research jobs and generate audio with Lyria 3&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code dir=&quot;auto&quot;&gt;genkit-google-genai&lt;/code&gt; plugin adds support for Google’s Deep Research agent and Lyria 3 audio generation models.&lt;/p&gt;
&lt;p&gt;Deep Research plans and executes multi-step research tasks over several minutes. You can launch a research request in the background with &lt;code dir=&quot;auto&quot;&gt;generate_operation&lt;/code&gt; and poll for the completed report using &lt;code dir=&quot;auto&quot;&gt;check_operation&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; asyncio&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GoogleAI&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;ai &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;[GoogleAI()])&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;operation &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.generate_operation(&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;GoogleAI.deep_research_model(&lt;/span&gt;&lt;span&gt;&apos;deep-research-preview-04-2026&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;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Summarize recent advances in quantum error correction for a technical audience.&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;while&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; operation.done:&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; asyncio.sleep(&lt;/span&gt;&lt;span&gt;10&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;operation &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.check_operation(operation)&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;print&lt;/span&gt;&lt;span&gt;(operation.output)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;To generate music and instrumental audio clips from text prompts, pass &lt;code dir=&quot;auto&quot;&gt;GoogleAI.lyria_model&lt;/code&gt; to &lt;code dir=&quot;auto&quot;&gt;ai.generate&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;clip &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.generate(&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;GoogleAI.lyria_model(&lt;/span&gt;&lt;span&gt;&apos;lyria-3-clip-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;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;A short piano loop, rainy window.&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;for&lt;/span&gt;&lt;span&gt; part &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; clip.message.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;if&lt;/span&gt;&lt;span&gt; part.media:&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;(part.media.url)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You can also experiment with &lt;code dir=&quot;auto&quot;&gt;lyria-3-clip-preview&lt;/code&gt; directly in the Genkit Developer UI and listen to generated audio clips right in the browser:&lt;/p&gt;
&lt;video src=&quot;/_astro/lyria-model-runner.B2kKHdWs.mp4&quot; controls loop playsinline&gt;&lt;/video&gt;
&lt;p&gt;&lt;em&gt;Generating and playing back an instrumental piano loop from a text prompt with &lt;code dir=&quot;auto&quot;&gt;lyria-3-clip-preview&lt;/code&gt; in the Genkit Developer UI.&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;recover-cleanly-from-mid-turn-errors&quot;&gt;Recover cleanly from mid-turn errors&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Previously, if a model failed to match your &lt;code dir=&quot;auto&quot;&gt;output_schema&lt;/code&gt; or a tool call failed mid-turn, &lt;code dir=&quot;auto&quot;&gt;ai.generate&lt;/code&gt; raised an exception and discarded the conversation history and raw model output you needed to recover.&lt;/p&gt;
&lt;p&gt;Now, &lt;code dir=&quot;auto&quot;&gt;ai.generate&lt;/code&gt; only raises &lt;code dir=&quot;auto&quot;&gt;GenkitError&lt;/code&gt; for setup mistakes before a turn starts, such as an invalid model name. Once a turn is underway, &lt;code dir=&quot;auto&quot;&gt;ai.generate&lt;/code&gt; always returns a &lt;code dir=&quot;auto&quot;&gt;ModelResponse&lt;/code&gt; so you can inspect &lt;code dir=&quot;auto&quot;&gt;response.error&lt;/code&gt; alongside the preserved &lt;code dir=&quot;auto&quot;&gt;response.messages&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;response.text&lt;/code&gt; to debug or retry without losing progress:&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;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit, GenkitError&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GoogleAI&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;ai &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;[GoogleAI()], &lt;/span&gt;&lt;span&gt;model&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;GoogleAI.gemini_model(&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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;try&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;history &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;None&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; attempt &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;range&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;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.generate(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Look up order #412 and process a refund.&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; attempt &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;None&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;messages&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;history,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;tools&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;[lookup_order, process_refund],&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; &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; response.error:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;break&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;(&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&apos;Turn failed (&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;response.error.reason&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;). Resuming...&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;# =&gt; Turn failed (TOOL_FAILED). Resuming...&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;history &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;/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;span&gt;# =&gt; Looked up order #412 and issued an $85 refund.&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;except&lt;/span&gt;&lt;span&gt; GenkitError &lt;/span&gt;&lt;span&gt;as&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;print&lt;/span&gt;&lt;span&gt;(err.reason)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# =&gt; MODEL_NOT_FOUND&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Inside tools, you can also raise &lt;code dir=&quot;auto&quot;&gt;PublicError&lt;/code&gt; to pass safe, user-facing error messages back on &lt;code dir=&quot;auto&quot;&gt;response.error&lt;/code&gt; while unexpected exceptions stay masked.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Simpler Part API.&lt;/strong&gt; You can now create message parts directly with &lt;code dir=&quot;auto&quot;&gt;Part(text=&apos;hello&apos;)&lt;/code&gt; and read &lt;code dir=&quot;auto&quot;&gt;part.text&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;part.media&lt;/code&gt; without unwrapping &lt;code dir=&quot;auto&quot;&gt;part.root&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multipart tool responses.&lt;/strong&gt; Tools can now return media attachments alongside structured JSON in a single tool response.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenAI plugin updates.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;genkit_openai&lt;/code&gt; adds support for &lt;code dir=&quot;auto&quot;&gt;gpt-6-astra&lt;/code&gt; and improves streaming for reasoning tokens, tool calls, and refusal metadata.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Per-request API keys.&lt;/strong&gt; Multi-tenant apps can now pass per-request Gemini credentials through &lt;code dir=&quot;auto&quot;&gt;context={&apos;secrets&apos;: {&apos;api_key&apos;: tenant_key}}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;We can’t wait to see what you build with Genkit Python 0.12. Explore the &lt;a href=&quot;https://genkit.dev/docs/python/overview/&quot;&gt;Genkit Python documentation&lt;/a&gt;, check out the &lt;a href=&quot;https://github.com/genkit-ai/genkit/tree/main/py/samples&quot;&gt;Python sample applications&lt;/a&gt;, or read the &lt;a href=&quot;https://github.com/genkit-ai/genkit/releases/tag/py%2Fv0.12.0&quot;&gt;complete v0.12.0 release notes on GitHub&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>python</category><category>announcements</category><category>releases</category></item><item><title>Genkit Dart 0.17: Resumable generate and agent loops, async subagents, and pluggable telemetry</title><link>https://genkit.dev/blog/genkit-dart-0-17/</link><guid isPermaLink="true">https://genkit.dev/blog/genkit-dart-0-17/</guid><description>Genkit Dart 0.17 brings resumable generate calls and agent snapshots, background subagents, and pluggable telemetry with genkit_otel.

</description><pubDate>Mon, 21 Sep 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As we move toward a stable 1.0 release, &lt;a href=&quot;https://genkit.dev/docs/dart/overview/&quot;&gt;Genkit Dart&lt;/a&gt; 0.17 brings resumable generation and agent snapshots, background subagents, and pluggable OpenTelemetry instrumentation. Failed or aborted &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; calls and agent turns now preserve completed tool rounds so you can resume where execution stopped, and orchestrator agents can delegate long-running tasks to background subagents without blocking the main conversation. This release also keeps core free of OpenTelemetry dependencies via the new &lt;code dir=&quot;auto&quot;&gt;genkit_otel&lt;/code&gt; package and upgrades the &lt;code dir=&quot;auto&quot;&gt;genkit_openai&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;genkit_mcp&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;genkit_anthropic&lt;/code&gt;, and &lt;code dir=&quot;auto&quot;&gt;genkit_google_genai&lt;/code&gt; plugins.&lt;/p&gt;
&lt;p&gt;To start using this new version, run the following command in your terminal:&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;dart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pub&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&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;resume-incomplete-generate-calls&quot;&gt;Resume incomplete generate calls&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When a multi-turn tool loop ends early due to errors, turn limits, or cancellation, &lt;code dir=&quot;auto&quot;&gt;ai.generate&lt;/code&gt; now returns the intermediate state instead of throwing an exception. This lets you inspect progress and resume from where you left off, without repeating completed tool calls:&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;var&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;Search flights to Kyoto, then reserve a hotel.&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; [searchFlights, bookHotel],&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;.failed &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;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;.aborted) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Completed tool rounds are preserved in 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;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;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;tools&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [searchFlights, bookHotel],&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;The &lt;code dir=&quot;auto&quot;&gt;messages&lt;/code&gt; history preserves completed tool rounds and omits pending requests, so you can pass &lt;code dir=&quot;auto&quot;&gt;messages&lt;/code&gt; directly back into &lt;code dir=&quot;auto&quot;&gt;ai.generate&lt;/code&gt; to resume execution without duplicate calls.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;resume-failed-or-aborted-agent-snapshots&quot;&gt;Resume failed or aborted agent snapshots&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Stateful agents bring this same crash recovery to persistent chat sessions. When an agent turn fails or is cancelled mid-flight, Genkit automatically checkpoints the user prompt and any completed tool calls into a session snapshot before throwing &lt;code dir=&quot;auto&quot;&gt;AgentError&lt;/code&gt;. Pass &lt;code dir=&quot;auto&quot;&gt;e.snapshotId&lt;/code&gt; back to &lt;code dir=&quot;auto&quot;&gt;agent.chat&lt;/code&gt; to resume the turn from that checkpoint instead of asking the user to start over:&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; chat &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; travelAgent.&lt;/span&gt;&lt;span&gt;chat&lt;/span&gt;&lt;span&gt;(sessionId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; sessionId);&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;try&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; chat.&lt;/span&gt;&lt;span&gt;send&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;&apos;Book the full itinerary.&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;on&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AgentError&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt; (e) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Resume from the saved checkpoint containing completed tool calls:&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; (e.status &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;UNAVAILABLE&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; e.snapshotId &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&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; rerun &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; travelAgent.&lt;/span&gt;&lt;span&gt;chat&lt;/span&gt;&lt;span&gt;(snapshotId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; e.snapshotId);&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; rerun.&lt;/span&gt;&lt;span&gt;send&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;delegate-work-to-background-subagents&quot;&gt;Delegate work to background subagents&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Regular subagents run inside a single tool call and block the main agent until every delegated task finishes, freezing the conversation during slow jobs like deep research reports or codebase audits. Setting &lt;code dir=&quot;auto&quot;&gt;async: true&lt;/code&gt; on the &lt;code dir=&quot;auto&quot;&gt;agents&lt;/code&gt; middleware lets your orchestrator launch subagents in the background and return a &lt;code dir=&quot;auto&quot;&gt;taskId&lt;/code&gt; immediately, so the main agent can reply to the user right away and keep the conversation moving while heavy work runs across turns.&lt;/p&gt;
&lt;p&gt;Because background subagents run in their own tracked sessions outside the turn loop, the orchestrator can check in on progress, wait with a timeout to share partial results as faster tasks finish, cancel in-flight work the user no longer needs, or send follow-up instructions into a subagent’s existing session without starting over:&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_middleware/agents.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;final&lt;/span&gt;&lt;span&gt; researcher &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;defineAgent&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;researcher&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;Researches a single topic and returns a concise summary.&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;system&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Return a tight 3-4 sentence summary of the 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;/span&gt;&lt;/span&gt;&lt;span&gt;store&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;InMemorySessionStore&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; orchestrator &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;defineAgent&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;asyncOrchestrator&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;system&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Coordinate multi-topic research requests in the background.&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;agents&lt;/span&gt;&lt;span&gt;(agents&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&apos;researcher&apos;&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;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;store&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;InMemorySessionStore&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;Here is &lt;code dir=&quot;auto&quot;&gt;asyncOrchestrator&lt;/code&gt; running in the Genkit Developer UI, returning &lt;code dir=&quot;auto&quot;&gt;&quot;status&quot;: &quot;pending&quot;&lt;/code&gt; and a &lt;code dir=&quot;auto&quot;&gt;taskId&lt;/code&gt; for each delegated task so the main turn can reply immediately while the &lt;code dir=&quot;auto&quot;&gt;researcher&lt;/code&gt; subagents continue running in the background:&lt;/p&gt;
&lt;img src=&quot;https://genkit.dev/_astro/async-subagents-runner.BjM8PL3b_1stIYN.webp&quot; alt=&quot;Background subagents running in the Genkit Developer UI&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2912&quot; height=&quot;1638&quot;&gt;
&lt;div&gt;&lt;h2 id=&quot;pluggable-telemetry-and-opentelemetry-genai-support&quot;&gt;Pluggable telemetry and OpenTelemetry GenAI support&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Core Genkit no longer pulls in OpenTelemetry dependencies by default, keeping your app’s footprint small while local tracing still works automatically with the Genkit Developer UI. When you deploy to production, install the new &lt;a href=&quot;https://pub.dev/packages/genkit_otel&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;genkit_otel&lt;/code&gt;&lt;/a&gt; package and register &lt;code dir=&quot;auto&quot;&gt;GenAiInstrumentation&lt;/code&gt; with &lt;code dir=&quot;auto&quot;&gt;configureInstrumentation&lt;/code&gt; to export traces, token usage, and operation latency following the OpenTelemetry GenAI semantic conventions:&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:dartastic_opentelemetry/dartastic_opentelemetry.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/telemetry.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_otel/genkit_otel.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;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;OTel&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;initialize&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;configureInstrumentation&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;GenAiInstrumentation&lt;/span&gt;&lt;span&gt;(contentCapturingMode&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ContentCapturingMode&lt;/span&gt;&lt;span&gt;.spanOnly),&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; 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;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Updated OpenAI model catalog.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;genkit_openai&lt;/code&gt; now ships with an updated catalog of chat and embedding models with preconfigured capability presets and typed shortcuts on &lt;code dir=&quot;auto&quot;&gt;OpenAIModels&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;OpenAIEmbedders&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Streamable HTTP and latest MCP spec.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;genkit_mcp&lt;/code&gt; is now powered by the official &lt;code dir=&quot;auto&quot;&gt;mcp_dart&lt;/code&gt; SDK, adding support for the latest Model Context Protocol specification and Streamable HTTP servers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-turn extended thinking for Anthropic.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;genkit_anthropic&lt;/code&gt; now preserves Claude’s reasoning blocks across multi-step tool loops so extended thinking stays intact throughout complex workflows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gemma discovery and deterministic seeds.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;genkit_google_genai&lt;/code&gt; adds built-in model discovery for Gemma alongside &lt;code dir=&quot;auto&quot;&gt;seed&lt;/code&gt; support for reproducible outputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;We can’t wait to see what you build with Genkit Dart 0.17. Check out the &lt;a href=&quot;https://genkit.dev/docs/dart/get-started/&quot;&gt;Genkit Dart documentation&lt;/a&gt;, explore the &lt;a href=&quot;https://github.com/genkit-ai/genkit-dart/tree/main/testapps&quot;&gt;sample applications&lt;/a&gt;, or read the release notes for &lt;a href=&quot;https://github.com/genkit-ai/genkit-dart/releases/tag/genkit-v0.17.0&quot;&gt;genkit v0.17.0&lt;/a&gt; and &lt;a href=&quot;https://github.com/genkit-ai/genkit-dart/releases/tag/genkit_otel-v0.1.0&quot;&gt;genkit_otel v0.1.0&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>dart</category><category>announcements</category><category>releases</category></item><item><title>Genkit CLI &amp; Dev UI 1.43: Improved human-in-the-loop testing and log viewing</title><link>https://genkit.dev/blog/genkit-cli-1-43/</link><guid isPermaLink="true">https://genkit.dev/blog/genkit-cli-1-43/</guid><description>Genkit CLI and Developer UI 1.43 makes it easier to test human-in-the-loop agents and inspect execution logs in both the browser and the terminal.

</description><pubDate>Fri, 18 Sep 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://genkit.dev/docs/devtools/&quot;&gt;Genkit CLI and Developer UI&lt;/a&gt; 1.43 makes it easier to test human-in-the-loop agents and inspect execution logs in both the browser and the terminal. You can now step through multiple tool interrupts in the Agent Runner, view execution logs alongside trace spans in a dedicated bottom drawer, and query logs from your terminal or coding agent with &lt;code dir=&quot;auto&quot;&gt;genkit log:list&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To install or upgrade to the latest version, run the following command in your terminal:&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;div&gt;&lt;h2 id=&quot;step-through-human-in-the-loop-interrupts-in-the-agent-runner&quot;&gt;Step through human-in-the-loop interrupts in the Agent Runner&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When an agent pauses execution for human review or external signoff, it often queues multiple pending tool calls within the same turn, such as reserving both a flight and a hotel before generating a final itinerary. Built on an interactive stepper, the Agent Runner now groups interrupted tool calls into a single &lt;strong&gt;Action Required&lt;/strong&gt; card so you can inspect and resolve each request in order.&lt;/p&gt;
&lt;video src=&quot;/_astro/agent-runner-tools.CNT6qSyk.mp4&quot; controls loop muted playsinline&gt;&lt;/video&gt;
&lt;p&gt;You can step forward and backward through pending tool requests using the &lt;strong&gt;Next&lt;/strong&gt; and &lt;strong&gt;Previous&lt;/strong&gt; controls, inspect the proposed input arguments, and choose how to resolve each call:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Respond with Output&lt;/strong&gt; injects a JSON return value directly into the session history, bypassing the tool handler code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Restart with Context&lt;/strong&gt; re-executes the tool handler while passing additional verification metadata in the &lt;code dir=&quot;auto&quot;&gt;resumed&lt;/code&gt; context object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you reach the final tool request in the stepper, clicking &lt;strong&gt;Resume&lt;/strong&gt; (or &lt;strong&gt;Submit responses&lt;/strong&gt; in manual tool response mode) submits all tool resolutions together so the agent can complete its turn.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;top-level-trace-logs-drawer-in-the-developer-ui&quot;&gt;Top-level Trace Logs drawer in the Developer UI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Previously, trace logs lived inside a section within the right-hand Span Details panel, requiring you to scroll past lengthy span inputs and outputs to inspect log messages. In 1.43, the &lt;strong&gt;Logs&lt;/strong&gt; panel has been promoted to an always-visible, resizable, collapsible bottom drawer spanning the full width of the Trace Viewer.&lt;/p&gt;
&lt;img src=&quot;https://genkit.dev/_astro/devui-trace-logs-expanded.D9dgY0jM_tKdBN.webp&quot; alt=&quot;Top-level Logs panel in the Genkit Developer UI trace viewer with inline attribute previews and correlated span metadata&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;2880&quot; height=&quot;1800&quot;&gt;
&lt;p&gt;This layout lets you inspect the span execution tree, span details, and correlated runtime logs simultaneously. Each row displays a severity badge, timestamp, and an inline preview of structured key-value attributes. Clicking any entry expands its full structured JSON payload together with its correlated &lt;code dir=&quot;auto&quot;&gt;traceId&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;spanId&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;query-execution-logs-with-genkit-loglist&quot;&gt;Query execution logs with &lt;code dir=&quot;auto&quot;&gt;genkit log:list&lt;/code&gt;&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The new &lt;code dir=&quot;auto&quot;&gt;genkit log:list&lt;/code&gt; CLI command queries execution logs directly from the local telemetry server. This makes logs easy to inspect from your terminal and directly accessible to AI coding agents (such as Antigravity, Claude Code, or Cursor) for agent-driven debugging without copying payloads out of the browser.&lt;/p&gt;
&lt;p&gt;You can filter logs by trace ID, span ID, or minimum severity (for example, &lt;code dir=&quot;auto&quot;&gt;--severity info&lt;/code&gt; returns &lt;code dir=&quot;auto&quot;&gt;INFO&lt;/code&gt; and above):&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;log:list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--trace-id&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;7b8e9a01c2d3e4f5a6b7c8d9e0f1a2b3&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--severity&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;By default, &lt;code dir=&quot;auto&quot;&gt;genkit log:list&lt;/code&gt; prints newest entries first in a readable summary format:&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;Found 3 logs:&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;ID:       9f4a21c0-88b1-4e2a-9c14-0a1b2c3d4e5f&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Span ID:  1000000000000006&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Severity: WARN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Time:     9/17/2026, 7:01:41 PM&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Message:  Turn interrupted awaiting human approval&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Attrs:    pendingTools=2, cluster=us-central1&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;ID:       7956edb0-15ac-4a78-a419-fcf698326392&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Span ID:  1000000000000004&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Severity: INFO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Time:     9/17/2026, 7:01:41 PM&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Message:  Canary verification passed&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Attrs:    status=HEALTHY, p99LatencyMs=42&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;ID:       cce5e07e-c686-4069-95da-efb18265f796&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Span ID:  1000000000000002&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Severity: INFO&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Time:     9/17/2026, 7:01:40 PM&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Message:  Saved session checkpoint snap-20260917-01&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Attrs:    sessionId=sess-prod-rollout-9941&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;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python OTLP debug log streaming.&lt;/strong&gt; Running Python workflows under &lt;code dir=&quot;auto&quot;&gt;genkit start&lt;/code&gt; now streams &lt;code dir=&quot;auto&quot;&gt;debug&lt;/code&gt; and higher lifecycle logs from &lt;code dir=&quot;auto&quot;&gt;ai.generate()&lt;/code&gt; to the Developer UI over OTLP while keeping your terminal output at the configured &lt;code dir=&quot;auto&quot;&gt;GENKIT_LOG&lt;/code&gt; level.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Composite badges for agent companion spans.&lt;/strong&gt; Trace views now display composite two-icon badges (&lt;code dir=&quot;auto&quot;&gt;robot&lt;/code&gt; + secondary icon) for background agent actions including &lt;code dir=&quot;auto&quot;&gt;agent-snapshot&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;agent-wait&lt;/code&gt;, and &lt;code dir=&quot;auto&quot;&gt;agent-abort&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bundled multipart artifact downloads.&lt;/strong&gt; When an agent session artifact contains multiple files, downloading it from the &lt;strong&gt;Artifacts&lt;/strong&gt; panel now bundles all parts into a single &lt;code dir=&quot;auto&quot;&gt;.zip&lt;/code&gt; archive instead of downloading files individually.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java and Kotlin runtime detection.&lt;/strong&gt; The CLI and telemetry server automatically detect &lt;code dir=&quot;auto&quot;&gt;java&lt;/code&gt; projects when &lt;code dir=&quot;auto&quot;&gt;pom.xml&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;build.gradle&lt;/code&gt;, or &lt;code dir=&quot;auto&quot;&gt;build.gradle.kts&lt;/code&gt; files are present in the project root.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accessibility and theme refinements.&lt;/strong&gt; Improved keyboard and screen-reader accessibility across trace and navigation views, and synchronized JSON editor colors across light and dark themes.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Upgrade to Genkit CLI and Developer UI 1.43 today to try human-in-the-loop agent stepping, the Trace Logs drawer, and &lt;code dir=&quot;auto&quot;&gt;genkit log:list&lt;/code&gt;. Explore the &lt;a href=&quot;https://genkit.dev/docs/devtools/&quot;&gt;Genkit Developer Tools documentation&lt;/a&gt; for guides, or read the &lt;a href=&quot;https://github.com/genkit-ai/genkit/releases/tag/genkit-cli%401.43.0&quot;&gt;full 1.43.0 release notes on GitHub&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>announcements</category><category>releases</category></item><item><title>Genkit Go 1.13: Resumable generate and agent loops, async subagents, and A2UI</title><link>https://genkit.dev/blog/genkit-go-1-13/</link><guid isPermaLink="true">https://genkit.dev/blog/genkit-go-1-13/</guid><description>Genkit Go 1.13 brings resumable agent control flow, background subagents, and streaming interactive UI with the new A2UI plugin.

</description><pubDate>Thu, 03 Sep 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://genkit.dev/docs/go/overview/&quot;&gt;Genkit Go&lt;/a&gt; 1.13 brings resumable agent control flow, background subagents, and streaming interactive UI. Generate calls and agent turns now keep their progress when they fail or get cancelled, so you can resume them at any time. Subagents can run in the background while the orchestrator keeps working, and with the new &lt;a href=&quot;https://a2ui.org/&quot;&gt;A2UI&lt;/a&gt; (Agent-to-User Interface) plugin, an agent can stream interactive surfaces straight to the frontend.&lt;/p&gt;
&lt;p&gt;To start using this new version, run the following command in your terminal:&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@latest&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;keep-progress-across-interrupted-generate-calls&quot;&gt;Keep progress across interrupted generate calls&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When you’re in the middle of a multi-step tool loop, you don’t want an error on step five to cause you to lose all of your progress.&lt;/p&gt;
&lt;p&gt;Now &lt;code dir=&quot;auto&quot;&gt;Generate&lt;/code&gt; returns what it finished alongside the error. Send it right back to retry the failed step without redoing the tool calls that already worked:&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;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;Plan the trip.&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;(searchFlights, bookHotel),&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;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;span&gt;&amp;#x26;&amp;#x26;&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;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;// resp.FinishReason: Failed (error encountered) or Aborted (cancelled).&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// resp.Error: the cause, classified.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// resp.History(): the tool rounds that finished, ready to send again.&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; 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;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;(searchFlights, bookHotel),&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;&lt;code dir=&quot;auto&quot;&gt;History()&lt;/code&gt; stops at a clean turn boundary: the completed rounds, nothing half-done, so any provider accepts it. Streaming works the same way: &lt;code dir=&quot;auto&quot;&gt;GenerateStream&lt;/code&gt; yields the partial response next to its error.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;resume-any-agent-turn-whether-it-succeeded-failed-or-was-aborted&quot;&gt;Resume any agent turn, whether it succeeded, failed, or was aborted&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit agents bring the same resumability to stateful sessions. A turn that fails saves the tool rounds it completed as a &lt;code dir=&quot;auto&quot;&gt;failed&lt;/code&gt; snapshot. Send an empty input to run the turn again on what was saved:&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;out, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; agent.&lt;/span&gt;&lt;span&gt;RunText&lt;/span&gt;&lt;span&gt;(ctx, &lt;/span&gt;&lt;span&gt;&quot;Book the full itinerary.&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;if&lt;/span&gt;&lt;span&gt; out.FinishReason &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; aix.AgentFinishReasonFailed {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// out.Error has the status. Transient? Run the turn again:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// no new message, no repeated tool calls.&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;out, err &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; agent.&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;aix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;AgentInput&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;aix.&lt;/span&gt;&lt;span&gt;WithSessionID&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;any&lt;/span&gt;&lt;span&gt;](out.SessionID))&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;If you cancel the context, hit a deadline, or exhaust your turn limit, the agent saves an &lt;code dir=&quot;auto&quot;&gt;aborted&lt;/code&gt; snapshot with completed turns intact. &lt;code dir=&quot;auto&quot;&gt;Run&lt;/code&gt; returns this output alongside the error so you know exactly where execution stopped:&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;out, err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; chatAgent.&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;aix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;AgentInput&lt;/span&gt;&lt;span&gt;{Message: msg}) &lt;/span&gt;&lt;span&gt;// ctx cancelled&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; out.FinishReason &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; aix.AgentFinishReasonAborted {&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;out, err &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; chatAgent.&lt;/span&gt;&lt;span&gt;Run&lt;/span&gt;&lt;span&gt;(context.&lt;/span&gt;&lt;span&gt;Background&lt;/span&gt;&lt;span&gt;(), &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;aix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;AgentInput&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;aix.&lt;/span&gt;&lt;span&gt;WithSnapshotID&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;any&lt;/span&gt;&lt;span&gt;](out.SnapshotID))&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;Whether a failure is worth retrying is your call. The runtime saves the snapshot and the classified error and gets out of the way. Detached runs get a proper &lt;code dir=&quot;auto&quot;&gt;aborting&lt;/code&gt; status while they wind down, so a stop never leaves a row stuck in &lt;code dir=&quot;auto&quot;&gt;pending&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;subagents-run-in-the-background&quot;&gt;Subagents run in the background&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Setting &lt;code dir=&quot;auto&quot;&gt;Async: true&lt;/code&gt; on the &lt;code dir=&quot;auto&quot;&gt;Agents&lt;/code&gt; middleware enables background subagents. Each delegation tool gains a &lt;code dir=&quot;auto&quot;&gt;background&lt;/code&gt; flag that returns a task ID immediately, while three shared tools let the orchestrator check, wait for, or abort launched tasks:&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;researcher &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkitx.&lt;/span&gt;&lt;span&gt;DefineAgent&lt;/span&gt;&lt;span&gt;(g, &lt;/span&gt;&lt;span&gt;&quot;researcher&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;aix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;InlinePrompt&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;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;WithSystem&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;You are a thorough research assistant.&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;aix.&lt;/span&gt;&lt;span&gt;WithDescription&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;Researches a topic and summarizes findings.&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;// Background work is tracked by a snapshot, so the subagent needs a store.&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;aix.&lt;/span&gt;&lt;span&gt;WithSessionStore&lt;/span&gt;&lt;span&gt;(localstore.&lt;/span&gt;&lt;span&gt;NewInMemorySessionStore&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;any&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;orchestrator &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkitx.&lt;/span&gt;&lt;span&gt;DefineAgent&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;any&lt;/span&gt;&lt;span&gt;](g, &lt;/span&gt;&lt;span&gt;&quot;orchestrator&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;aix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;InlinePrompt&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;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;WithSystem&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Delegate research and keep the user updated.&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;middlewarex&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Agents&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;Agents: []&lt;/span&gt;&lt;span&gt;aix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;AgentRef&lt;/span&gt;&lt;span&gt;{researcher.&lt;/span&gt;&lt;span&gt;Ref&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;Async:  &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;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&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;delegate_to_researcher    {task, background: true}    -&gt; taskId, right away&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;check_background_tasks    {taskIds}                   -&gt; where each one stands&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;wait_for_background_tasks {taskIds, timeoutSeconds?}  -&gt; results as they settle&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;abort_background_tasks    {taskIds}                   -&gt; stop, keep the progress&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;continue_task             {taskId, instructions?}     -&gt; pick up where it left off&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;There is no separate task registry to maintain. The task ID lives directly in the tool result within the conversation history, allowing an orchestrator to resume tracking even after a restart. &lt;code dir=&quot;auto&quot;&gt;wait_for_background_tasks&lt;/code&gt; also accepts a timeout, turning a slow subagent into an interim status update rather than a blocked turn.&lt;/p&gt;
&lt;p&gt;Every background delegation returns a &lt;code dir=&quot;auto&quot;&gt;taskId&lt;/code&gt; that you can pass to &lt;code dir=&quot;auto&quot;&gt;continue_task&lt;/code&gt;. An interrupted subagent picks up from its last saved progress, while a completed one accepts follow-up instructions in its existing session.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;background-runs-are-tasks-any-process-can-pick-up&quot;&gt;Background runs are tasks any process can pick up&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;RunDetached&lt;/code&gt; starts an agent in the background and hands you a task. The task is just a snapshot ID, so store it anywhere and rehydrate it later:&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;task, _ &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; agent.&lt;/span&gt;&lt;span&gt;RunDetached&lt;/span&gt;&lt;span&gt;(ctx, &lt;/span&gt;&lt;span&gt;&amp;#x26;&lt;/span&gt;&lt;span&gt;aix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;AgentInput&lt;/span&gt;&lt;span&gt;{Message: msg})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;id &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; task.&lt;/span&gt;&lt;span&gt;SnapshotID&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;// save it&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;// Any process, any time later:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;snap, _ &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; agent.&lt;/span&gt;&lt;span&gt;Task&lt;/span&gt;&lt;span&gt;(id).&lt;/span&gt;&lt;span&gt;Wait&lt;/span&gt;&lt;span&gt;(ctx) &lt;/span&gt;&lt;span&gt;// or Poll for one read, Abort to stop&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 remote clients, &lt;code dir=&quot;auto&quot;&gt;POST /agents/{name}/waitForSnapshot&lt;/code&gt; provides the same blocking behavior over HTTP, resolving when the background task finishes instead of using a client-side polling loop. You can also use &lt;code dir=&quot;auto&quot;&gt;AgentHandle&lt;/code&gt; to invoke agents by name without declaring static type parameters:&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;h &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; genkitx.&lt;/span&gt;&lt;span&gt;LookupAgent&lt;/span&gt;&lt;span&gt;(g, &lt;/span&gt;&lt;span&gt;&quot;researcher&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;out, _ &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; h.&lt;/span&gt;&lt;span&gt;RunText&lt;/span&gt;&lt;span&gt;(ctx, &lt;/span&gt;&lt;span&gt;&quot;Summarize the latest Go release.&quot;&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;stream-interactive-ui-with-a2ui&quot;&gt;Stream interactive UI with A2UI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The new preview &lt;code dir=&quot;auto&quot;&gt;a2ui&lt;/code&gt; plugin brings A2UI support to Genkit Go. Your agent streams interactive surfaces, and the client renders them as they arrive. Giving your agent A2UI capabilities is as simple as adding a single middleware:&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; a2uix &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;github.com/firebase/genkit/go/plugins/a2ui/exp&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;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;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;WithSystem&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Render UI when it is clearer than prose.&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;show me the weather in Tokyo&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;a2uix&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Surfaces&lt;/span&gt;&lt;span&gt;{}), &lt;/span&gt;&lt;span&gt;// bundled basic catalog&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;// Envelopes ride as data parts. Hand them to any A2UI renderer.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;envelopes &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; a2uix.&lt;/span&gt;&lt;span&gt;EnvelopesFromParts&lt;/span&gt;&lt;span&gt;(resp.Message.Content)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The envelopes are byte-compatible with the JS and Dart plugins and the @a2ui/* renderers, so our &lt;a href=&quot;https://github.com/genkit-ai/genkit/tree/main/js/testapps/a2ui/web&quot;&gt;A2UI web demo&lt;/a&gt; works unchanged against a &lt;a href=&quot;https://github.com/genkit-ai/genkit/tree/main/go/samples/basic-middleware/a2ui&quot;&gt;Go backend sample&lt;/a&gt;. Bring your own components with &lt;code dir=&quot;auto&quot;&gt;LoadCatalog&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Provider blockage error handling.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;GenerateData&lt;/code&gt; and other typed helpers return &lt;code dir=&quot;auto&quot;&gt;ai.ErrGenerationBlocked&lt;/code&gt; when a provider blocks a response, making policy refusals distinct from validation failures.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context cache composition.&lt;/strong&gt; Gemini explicit context caching no longer sends the cached prefix inline or creates a new cache on every request. &lt;code dir=&quot;auto&quot;&gt;WithCacheTTL&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;WithCacheName&lt;/code&gt; now compose.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Developer UI enhancements.&lt;/strong&gt; The background-task panel works with Go background models, middleware config fields include descriptions, and each JSON-dispatched middleware call receives its own config.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trace fidelity.&lt;/strong&gt; Tool-loop turns record the messages they sent, reasoning parts render as one thought, and &lt;code dir=&quot;auto&quot;&gt;googlegenai&lt;/code&gt; uses a plain HTTP client by default.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New agent samples.&lt;/strong&gt; The &lt;code dir=&quot;auto&quot;&gt;basic-agents&lt;/code&gt; sample adds an incident commander built on background delegation, and &lt;a href=&quot;https://github.com/genkit-ai/genkit/tree/main/go/samples/basic-middleware/a2ui&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;basic-middleware/a2ui&lt;/code&gt;&lt;/a&gt; serves the A2UI web demo.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;We can’t wait to see what you build with Genkit Go 1.13. Check out the &lt;a href=&quot;https://genkit.dev/docs/go/get-started/&quot;&gt;Genkit Go docs&lt;/a&gt;, run the &lt;a href=&quot;https://github.com/genkit-ai/genkit/blob/main/go/samples/basic-agents/commander.go&quot;&gt;updated samples&lt;/a&gt;, or read the &lt;a href=&quot;https://github.com/genkit-ai/genkit/releases/tag/go%2Fv1.13.0&quot;&gt;full release notes&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>go</category><category>announcements</category><category>releases</category></item><item><title>Genkit Python 0.11: Video generation, typed model options, and unified error handling</title><link>https://genkit.dev/blog/genkit-python-0-11/</link><guid isPermaLink="true">https://genkit.dev/blog/genkit-python-0-11/</guid><description>Genkit Python 0.11 brings video generation, improved DX for model configuration, unified error handling across providers, and structured debug logs in the Developer UI.

</description><pubDate>Wed, 02 Sep 2026 12:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://genkit.dev/docs/python/overview/&quot;&gt;Genkit Python&lt;/a&gt; 0.11 brings video generation, improved DX for model configuration, unified error handling across providers, and structured debug logs in the Developer UI. Video models now run as background operations you can poll or cancel, family constructors provide autocomplete for model options directly in your editor, and provider HTTP errors normalize into a single &lt;code dir=&quot;auto&quot;&gt;GenkitError&lt;/code&gt; with classified statuses. Calls to &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; also preserve intermediate message history when a tool loop ends early, allowing you to resume execution without repeating completed tool calls.&lt;/p&gt;
&lt;p&gt;To install or update to the new version, run the following command in your terminal:&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;uv&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&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;genkit-google-genai&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;generate-video-content&quot;&gt;Generate video content&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit Python now supports video generation with models like Veo. Because rendering high-resolution video takes time, generation runs as an asynchronous background operation using &lt;code dir=&quot;auto&quot;&gt;generate_operation&lt;/code&gt;, returning an &lt;code dir=&quot;auto&quot;&gt;Operation&lt;/code&gt; you can poll until the video is ready:&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; asyncio&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GoogleAI&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;ai &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;[GoogleAI()])&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;operation &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.generate_operation(&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;GoogleAI.veo_model(&lt;/span&gt;&lt;span&gt;&apos;veo-3.1-fast-generate-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;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;A paper airplane gliding through a bright classroom&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;while&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; operation.done:&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; asyncio.sleep(&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;operation &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.check_operation(operation)&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;print&lt;/span&gt;&lt;span&gt;(operation.output.media[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;].url)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;You can also test video models interactively in the Developer UI. Submitting a prompt from the model runner tracks the background generation and plays the finished video directly in the browser:&lt;/p&gt;
&lt;video src=&quot;/_astro/veo-model-runner.DITS-jDG.mp4&quot; controls loop muted playsinline&gt;&lt;/video&gt;
&lt;div&gt;&lt;h2 id=&quot;configure-models-with-strongly-typed-options&quot;&gt;Configure models with strongly typed options&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit Python now provides strongly typed model references. Family constructors like &lt;code dir=&quot;auto&quot;&gt;GoogleAI.gemini_model&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;Anthropic.claude_model&lt;/code&gt;, and &lt;code dir=&quot;auto&quot;&gt;OpenAI.gpt_model&lt;/code&gt; bind each model directly to its supported configuration 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;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_anthropic &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Anthropic, AnthropicConfig&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GeminiConfigSchema, GoogleAI&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_openai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; OpenAI, OpenAIConfig&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;ai &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;[GoogleAI(), Anthropic(), OpenAI()])&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;# Pass typed model references and provider configs directly inline&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;res1 &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.generate(&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;GoogleAI.gemini_model(&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;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;config&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;GeminiConfigSchema(&lt;/span&gt;&lt;span&gt;temperature&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;0.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;span&gt;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Say hi in one word.&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;res2 &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.generate(&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;Anthropic.claude_model(&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;claude-sonnet-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;config&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;AnthropicConfig(&lt;/span&gt;&lt;span&gt;max_output_tokens&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;1024&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;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Say hi in one word.&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;res3 &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.generate(&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;OpenAI.gpt_model(&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;gpt-5.2&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;config&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;OpenAIConfig(&lt;/span&gt;&lt;span&gt;temperature&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;0.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;span&gt;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Say hi in one word.&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;p&gt;Typed references provide autocomplete, inline parameter hints, and type safety in your editor, helping you discover supported options and catch provider mismatches before running your code.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;unified-error-handling-across-model-providers&quot;&gt;Unified error handling across model providers&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit Python now normalizes provider exceptions into a unified &lt;code dir=&quot;auto&quot;&gt;GenkitError&lt;/code&gt;. A single error handling block gives you consistent status codes across Gemini, Anthropic, and OpenAI:&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;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit, GenkitError&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GoogleAI&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_middleware &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Retry&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;ai &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;[GoogleAI()])&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;try&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;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.generate(&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;GoogleAI.gemini_model(&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;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Draft a travel itinerary for a weekend in Kyoto.&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;use&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;[Retry()],&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;(response.text)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;except&lt;/span&gt;&lt;span&gt; GenkitError &lt;/span&gt;&lt;span&gt;as&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;# Unified exception type across Gemini, Claude, and GPT&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;(err.status, err.original_message)&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.status &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;RESOURCE_EXHAUSTED&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;and&lt;/span&gt;&lt;span&gt; err.response_metadata:&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;(&lt;/span&gt;&lt;span&gt;&apos;Retry after&apos;&lt;/span&gt;&lt;span&gt;, err.response_metadata.get(&lt;/span&gt;&lt;span&gt;&apos;retry_after_ms&apos;&lt;/span&gt;&lt;span&gt;), &lt;/span&gt;&lt;span&gt;&apos;ms&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;p&gt;Standardized status codes make it straightforward to inspect rate limits, configure retries, and build consistent error recovery across every provider.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;debug-logs-in-the-developer-ui&quot;&gt;Debug logs in the Developer UI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When iterating on your AI application locally, calls to &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; now stream structured debug logs directly into the Developer UI trace viewer.&lt;/p&gt;
&lt;p&gt;Execution spans capture lifecycle milestones like model calls, tool executions, and middleware behavior in the Logs panel. This gives you a detailed diagnostic trail right beside your trace spans while keeping your terminal output clean.&lt;/p&gt;
&lt;img src=&quot;https://genkit.dev/_astro/devui-traces.DaVo8p01_m0Sw8.webp&quot; alt=&quot;Debug logs in the Developer UI trace viewer&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;3200&quot; height=&quot;1800&quot;&gt;
&lt;div&gt;&lt;h2 id=&quot;resume-incomplete-generate-calls&quot;&gt;Resume incomplete generate calls&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When a multi-turn tool loop ends early due to errors or turn limits, &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; now returns the intermediate state instead of raising an exception. This lets you inspect progress and resume from where you left off, without repeating completed tool calls:&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;from&lt;/span&gt;&lt;span&gt; pydantic &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; BaseModel&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; Genkit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; genkit_google_genai &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; GoogleAI&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;ai &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Genkit(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;plugins&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;[GoogleAI()],&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;GoogleAI.gemini_model(&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;/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;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TripQuery&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BaseModel&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;destination: &lt;/span&gt;&lt;span&gt;str&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;@ai.tool&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;search_flights&lt;/span&gt;&lt;span&gt;(query: TripQuery) -&gt; list[&lt;/span&gt;&lt;span&gt;str&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;&quot;&quot;Find available flights to a destination.&quot;&quot;&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;return&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&apos;Flight 101 to &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;query.destination&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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;@ai.tool&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;book_hotel&lt;/span&gt;&lt;span&gt;(query: TripQuery) -&gt; &lt;/span&gt;&lt;span&gt;str&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;&quot;&quot;Reserve hotel accommodations in a destination.&quot;&quot;&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;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;&apos;Hotel in &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;query.destination&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt; reserved&apos;&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;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.generate(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;prompt&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&apos;Search flights to Kyoto, then reserve a hotel.&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;tools&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;[search_flights, book_hotel],&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.finish_reason &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;&apos;failed&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;aborted&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;# Completed tool rounds are preserved in 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;# Resume the turn without repeating earlier tool calls:&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;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.generate(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&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;tools&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;[search_flights, book_hotel],&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;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;The &lt;code dir=&quot;auto&quot;&gt;messages&lt;/code&gt; history preserves completed tool rounds and omits pending requests, so you can pass &lt;code dir=&quot;auto&quot;&gt;messages&lt;/code&gt; directly back into &lt;code dir=&quot;auto&quot;&gt;generate&lt;/code&gt; to resume execution without duplicate calls.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;also-in-this-release&quot;&gt;Also in this release&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenAI streaming token usage.&lt;/strong&gt; Streaming completions from OpenAI now request and populate token consumption metrics through &lt;code dir=&quot;auto&quot;&gt;include_usage&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Whisper translation routing.&lt;/strong&gt; Whisper audio models now accept &lt;code dir=&quot;auto&quot;&gt;config={&apos;translate&apos;: True}&lt;/code&gt;, routing requests to the translations endpoint.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Upgrade to Genkit Python 0.11 today to take advantage of video generation, improved model configuration, and resumable generation. Explore the &lt;a href=&quot;https://genkit.dev/docs/python/overview/&quot;&gt;Genkit Python documentation&lt;/a&gt;, experiment with the &lt;a href=&quot;https://github.com/genkit-ai/genkit/tree/main/py/samples&quot;&gt;Python samples&lt;/a&gt;, or review the &lt;a href=&quot;https://github.com/genkit-ai/genkit/pull/6281&quot;&gt;complete v0.11.0 release notes&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>python</category><category>announcements</category><category>releases</category></item><item><title>Genkit Agents come to Dart: full-stack conversational AI for Flutter</title><link>https://genkit.dev/blog/announcing-genkit-agents-dart/</link><guid isPermaLink="true">https://genkit.dev/blog/announcing-genkit-agents-dart/</guid><description>The Agents API is now in Dart. Define an agent on the server and drive it from your Flutter app with the same chat() interface via remoteAgent, and reach agents written in Dart, JS, Go, or Python over one shared protocol.

</description><pubDate>Wed, 15 Jul 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 Dart, TypeScript, Go, and Python. Some of the most compelling AI features are conversational: a support assistant that remembers the ticket, a copilot that works across several turns. Each needs more than a single &lt;code dir=&quot;auto&quot;&gt;generate()&lt;/code&gt; call. Building one means wiring up message history, the tool loop, streaming, persistence, and a client protocol by hand, plumbing that repeats on every project and has little to do with what makes your app distinct.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Agents API&lt;/strong&gt; is now available in Genkit Dart. It packages all of that behind one interface. You define an agent on the server, then drive it with the same &lt;code dir=&quot;auto&quot;&gt;chat()&lt;/code&gt; API whether it runs in process or behind an HTTP endpoint. And because that endpoint speaks one shared wire protocol, a Flutter app can talk to agents written in Dart, JS, Go, or Python without changing a line of client code.&lt;/p&gt;
&lt;p&gt;For Flutter developers this closes the loop: the same language, the same types, and the same &lt;code dir=&quot;auto&quot;&gt;chat()&lt;/code&gt; surface run on both the server and the client.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;define-an-agent&quot;&gt;Define an agent&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;An agent needs a name and a system prompt to start. From there you add tools, state, and a session store as the feature grows. Here is a weather agent with a single tool and a file-backed session store so conversations survive restarts:&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/experimental.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/experimental_io.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;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;&lt;span&gt;  &lt;/span&gt;&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;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;/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; getWeather &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;getWeather&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;Get the current weather for a given location.&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;GetWeatherInput&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;GetWeatherOutput&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; (input, _) &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;GetWeatherOutput&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;weather&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Sunny in &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;location&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;/span&gt;&lt;/span&gt;&lt;span&gt;temperature&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;71F&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;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; weatherAgent &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; ai.&lt;/span&gt;&lt;span&gt;defineAgent&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;weatherAgent&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;system&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;You are an assistant helping with weather information. Use the &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;getWeather tool.&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; [getWeather],&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;store&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FileSessionStore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;.sessions&apos;&lt;/span&gt;&lt;span&gt;), &lt;/span&gt;&lt;span&gt;// server-managed state&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;The same agent object handles a one-shot reply, a streamed turn, a paused tool call, and a multi-turn conversation. You call it in process just like you would over HTTP:&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; chat &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; weatherAgent.&lt;/span&gt;&lt;span&gt;chat&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; turn &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; chat.&lt;/span&gt;&lt;span&gt;sendStream&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;&apos;What is the weather in London?&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;await&lt;/span&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; chunk &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; turn.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;&lt;/span&gt;&lt;span&gt;stdout.&lt;/span&gt;&lt;span&gt;write&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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; res &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; turn.response;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code dir=&quot;auto&quot;&gt;chat&lt;/code&gt; carries its &lt;code dir=&quot;auto&quot;&gt;snapshotId&lt;/code&gt;/state forward across turns automatically, so multi-turn is just calling &lt;code dir=&quot;auto&quot;&gt;send&lt;/code&gt; again. Adding a &lt;code dir=&quot;auto&quot;&gt;store&lt;/code&gt; makes the agent &lt;strong&gt;server-managed&lt;/strong&gt;: the server persists messages, custom state, and artifacts as snapshots, and clients continue by sending back a session ID. Leave the store off and the agent is &lt;strong&gt;client-managed&lt;/strong&gt;, so the client owns the state blob and passes it back each turn.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;serve-it-over-http&quot;&gt;Serve it over HTTP&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Every agent is already a servable action, so putting one behind an HTTP endpoint takes only a few lines with &lt;a href=&quot;https://pub.dev/packages/genkit_shelf&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;genkit_shelf&lt;/code&gt;&lt;/a&gt;. You mount the agent’s turn action alongside its snapshot and abort companions:&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;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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;router.&lt;/span&gt;&lt;span&gt;post&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;/api/weatherAgent&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;shelfHandler&lt;/span&gt;&lt;span&gt;(weatherAgent.action));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;router.&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/weatherAgent/getSnapshot&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;(weatherAgent.getSnapshotDataAction),&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;router.&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/weatherAgent/abort&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;(weatherAgent.abortAgentAction),&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;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;InternetAddress&lt;/span&gt;&lt;span&gt;.anyIPv4, &lt;/span&gt;&lt;span&gt;8080&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;Each agent gets a turn endpoint that handles normal and streaming turns, plus a &lt;code dir=&quot;auto&quot;&gt;getSnapshot&lt;/code&gt; companion when it has a session store and an &lt;code dir=&quot;auto&quot;&gt;abort&lt;/code&gt; companion for detached background work. That same wire protocol is what the client below speaks.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;the-flutter-payoff-remoteagent-on-the-client&quot;&gt;The Flutter payoff: &lt;code dir=&quot;auto&quot;&gt;remoteAgent&lt;/code&gt; on the client&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The piece that ties your server and your Flutter app together is the remote client. &lt;code dir=&quot;auto&quot;&gt;remoteAgent()&lt;/code&gt; from &lt;code dir=&quot;auto&quot;&gt;package:genkit/experimental_client.dart&lt;/code&gt; returns a handle with the &lt;strong&gt;same &lt;code dir=&quot;auto&quot;&gt;chat()&lt;/code&gt; interface&lt;/strong&gt; as a local agent, so the code that drives an agent in your backend tests is the code that drives it from your app. There is no separate request and response protocol to design, and no streaming format to invent.&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/experimental_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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; weather &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remoteAgent&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;http://localhost:8080/api/weatherAgent&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;getSnapshotUrl&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;http://localhost:8080/api/weatherAgent/getSnapshot&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;abortUrl&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;http://localhost:8080/api/weatherAgent/abort&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; chat &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; weather.&lt;/span&gt;&lt;span&gt;chat&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; turn &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; chat.&lt;/span&gt;&lt;span&gt;sendStream&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;&apos;Weather in Tokyo?&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;await&lt;/span&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; chunk &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; turn.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;&lt;/span&gt;&lt;span&gt;stdout.&lt;/span&gt;&lt;span&gt;write&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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; res &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; turn.response;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Streaming is built into the same interface: &lt;code dir=&quot;auto&quot;&gt;sendStream()&lt;/code&gt; gives you a chunk stream and a final response, and each chunk can carry text, custom state, or an artifact as it is produced. Here is a compact Flutter widget that streams a turn straight into the UI:&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;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;WeatherChat&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;StatefulWidget&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;WeatherChat&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;span&gt;super&lt;/span&gt;&lt;span&gt;.key});&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;State&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;WeatherChat&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;createState&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;_WeatherChatState&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;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;_WeatherChatState&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;State&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;WeatherChat&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;final&lt;/span&gt;&lt;span&gt; _agent &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remoteAgent&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-backend.example.com/api/weatherAgent&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;late&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;final&lt;/span&gt;&lt;span&gt; _chat &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; _agent.&lt;/span&gt;&lt;span&gt;chat&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; _text &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;/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;&amp;#x3C;&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt;&gt; &lt;/span&gt;&lt;span&gt;_ask&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;String&lt;/span&gt;&lt;span&gt; prompt) &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;setState&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&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;&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;final&lt;/span&gt;&lt;span&gt; turn &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; _chat.&lt;/span&gt;&lt;span&gt;sendStream&lt;/span&gt;&lt;span&gt;(text&lt;/span&gt;&lt;span&gt;:&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;await&lt;/span&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; chunk &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; turn.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;if&lt;/span&gt;&lt;span&gt; (chunk.text.isNotEmpty) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;setState&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; _text &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; chunk.accumulatedText);&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;&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;Widget&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;build&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BuildContext&lt;/span&gt;&lt;span&gt; context) {&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;Column&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;children&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;Expanded&lt;/span&gt;&lt;span&gt;(child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SingleChildScrollView&lt;/span&gt;&lt;span&gt;(child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Text&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;TextField&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;onSubmitted&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; _ask,&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;decoration&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;InputDecoration&lt;/span&gt;&lt;span&gt;(hintText&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;Ask about the weather&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;&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;p&gt;The client resolves dynamic auth headers per request, applies streamed state patches, and continues the next turn with a session ID, a snapshot ID, or client-managed state, whichever your agent uses. Because &lt;code dir=&quot;auto&quot;&gt;remoteAgent&lt;/code&gt; lives in the browser-safe &lt;code dir=&quot;auto&quot;&gt;package:genkit/experimental_client.dart&lt;/code&gt;, the same code runs on Flutter mobile, desktop, and web.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;one-protocol-any-backend-any-client&quot;&gt;One protocol, any backend, any client&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Here is the part that matters for real teams: the agent wire protocol is shared across every Genkit language. A &lt;code dir=&quot;auto&quot;&gt;remoteAgent&lt;/code&gt; in your Flutter app does not know or care what language its server is written in. It talks to agents written in &lt;strong&gt;Dart, JS, Go, or Python&lt;/strong&gt; over the exact same HTTP interface.&lt;/p&gt;
&lt;p&gt;That means your Flutter frontend can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connect to a &lt;strong&gt;Dart&lt;/strong&gt; backend so your whole stack is one language.&lt;/li&gt;
&lt;li&gt;Reach an existing &lt;strong&gt;JS&lt;/strong&gt;, &lt;strong&gt;Go&lt;/strong&gt;, or &lt;strong&gt;Python&lt;/strong&gt; agent your team already runs, with no bespoke client.&lt;/li&gt;
&lt;li&gt;Switch or mix backends later without rewriting the app. The client code is identical.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The frontend code above stays the same in every case. Only the URL changes.&lt;/p&gt;
&lt;p&gt;And it runs both ways: because the protocol is symmetric, an agent you write in Dart is reachable by a &lt;code dir=&quot;auto&quot;&gt;remoteAgent&lt;/code&gt; in &lt;strong&gt;JS, Go, or Python&lt;/strong&gt; just as easily. A Dart backend can power a web, mobile, or server client written in another language, so Dart is a first-class choice for the server side even when your frontend is not Dart.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;beyond-chat&quot;&gt;Beyond chat&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The Agents API in Dart carries the full feature set, not just streaming chat:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Custom state.&lt;/strong&gt; Tools mutate typed session state through &lt;code dir=&quot;auto&quot;&gt;ai.currentSession()&lt;/code&gt;, and Genkit streams the changes to the client as &lt;code dir=&quot;auto&quot;&gt;customPatch&lt;/code&gt; chunks so your UI stays live mid-turn. Great for a task list, workflow status, or any structured value that drives the next turn.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Human in the loop.&lt;/strong&gt; A tool can interrupt to pause a turn before a payment, a deployment, or any action you do not want to run automatically. The client approves, rejects, or supplies the missing value, then resumes the same chat.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom agents.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;defineCustomAgent&lt;/code&gt; gives you full control of the turn loop for multi-step orchestration, multiple models, and manual message and state handling, all while streaming status to the client.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Work that outlives the request.&lt;/strong&gt; With server-managed state, a client can detach a long turn, close the app, and reconnect later by snapshot ID while the agent keeps working on the server.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;get-started&quot;&gt;Get started&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Genkit Agents bring the repeated plumbing of conversational, full-stack AI to Dart and Flutter as something you configure rather than rebuild. Define an agent on the server, give it a store when you want persistence, and drive it from your Flutter app with the same &lt;code dir=&quot;auto&quot;&gt;chat()&lt;/code&gt; interface through &lt;code dir=&quot;auto&quot;&gt;remoteAgent()&lt;/code&gt;.&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/agents/overview&quot;&gt;Agents 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 coding! 🚀&lt;/p&gt;</content:encoded><category>dart</category></item><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 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></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 built with Gemini 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></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, Dart, and Python (&lt;code dir=&quot;auto&quot;&gt;genkit-middleware&lt;/code&gt; — see the &lt;a href=&quot;https://genkit.dev/docs/middleware&quot;&gt;middleware docs&lt;/a&gt;).&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 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></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_2eY72f.webp&quot; alt=&quot;The Genkit Developer UI running the Trip Planner flow&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;3456&quot; height=&quot;2168&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>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 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>