{"slug": "announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps", "title": "Announcing Genkit Middleware: Intercept, extend, and harden your agentic apps", "summary": "Genkit, an open-source framework for building AI-powered applications, has introduced a middleware system that allows developers to intercept and customize generation calls and tool execution loops. The middleware, available for TypeScript, Go, and Dart, includes pre-built solutions for retries, model fallbacks, tool approval, skills injection, and filesystem access, with Python support coming soon. This system enables developers to add reliability, safety, and custom behaviors to their agentic applications without modifying core prompts or logic.", "body_md": "Genkit is an open-source framework for building full-stack, AI-powered and agentic applications for any platform 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.\nGenkit solves this with middleware: composable hooks that intercept generation calls, including the tool execution loop, and inject custom behaviors. The middleware system is available today in TypeScript, Go, and Dart, with Python support coming soon.\nEvery generate()\ncall in Genkit runs a tool loop: 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:\nGenkit offers several pre-built middleware solutions for common use-cases. Here's what's available today:\nAutomatically retries failed model API calls on transient errors (RESOURCE_EXHAUSTED, UNAVAILABLE\n, etc.) using exponential backoff with jitter. Only the model call is retried; the surrounding tool loop is not replayed.\nresp, err := genkit.Generate(ctx, g,\nai.WithModelName(\"googleai/gemini-flash-latest\"),\nai.WithPrompt(\"Summarize the quarterly earnings report.\"),\nai.WithUse(&middleware.Retry{\nMaxRetries: 3,\nInitialDelayMs: 1000,\nBackoffFactor: 2,\n}),\n)\nSwitches to an alternative model when the primary model fails on a specified set of error codes. Useful for falling back to a completely different provider when your primary model exceeds its quota.\nresp, err := genkit.Generate(ctx, g,\nai.WithModelName(\"googleai/gemini-flash-latest\"),\nai.WithPrompt(\"Analyze this complex document...\"),\nai.WithUse(&middleware.Fallback{\nModels: []ai.ModelRef{\nanthropic.ModelRef(\"claude-sonnet-4-6\", nil), // fall back to Claude\n},\nStatuses: []core.StatusName{core.RESOURCE_EXHAUSTED},\n}),\n)\nRestricts 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.\nresp, _ := genkit.Generate(ctx, g,\nai.WithPrompt(\"Delete the temp files\"),\nai.WithTools(deleteFilesTool),\nai.WithUse(&middleware.ToolApproval{\nAllowedTools: []string{}, // empty = every tool call interrupts\n}),\n)\nif len(resp.Interrupts()) > 0 {\ninterrupt := resp.Interrupts()[0]\n// Prompt the user for approval, then resume with the approval flag.\napproved, _ := deleteFilesTool.RestartWith(interrupt,\nai.WithResumedMetadata[DeleteInput](map[string]any{\"toolApproved\": true}),\n)\nresp, err := genkit.Generate(ctx, g,\nai.WithMessages(resp.History()...),\nai.WithTools(deleteFilesTool),\nai.WithToolRestarts(approved),\nai.WithUse(&middleware.ToolApproval{}),\n)\nfmt.Println(resp.Text())\n}\nScans a directory for SKILL.md\nfiles and injects their content into the system prompt. Also exposes a use_skill\ntool so the model can load specific skills on demand.\nresp, err := genkit.Generate(ctx, g,\nai.WithPrompt(\"How do I deploy this service?\"),\nai.WithUse(&middleware.Skills{SkillPaths: []string{\"./skills\"}}),\n)\nGives the model scoped access to the local filesystem through injected tools (list_files\n, read_file\n, plus write_file\nand edit_file\nwhen writes are enabled). Path safety is enforced so the model can never escape the root directory.\nresp, err := genkit.Generate(ctx, g,\nai.WithPrompt(\"Create a hello world program in the workspace\"),\nai.WithUse(&middleware.Filesystem{\nRootDir: \"./workspace\",\nAllowWriteAccess: true,\n}),\n)\nThe 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.\nCustom middleware follows a simple contract across all languages: provide a name and a factory function that returns the hooks you want. The factory is called once per generate()\ninvocation, and you implement only the hooks you need.\nHere's a complete, custom content filter in ~20 lines of code:\n// ContentFilter rejects model responses containing any forbidden term.\ntype ContentFilter struct {\nForbiddenTerms []string `json:\"forbiddenTerms\"`\n}\nfunc (ContentFilter) Name() string { return \"app/contentFilter\" }\nfunc (f ContentFilter) New(ctx context.Context) (*ai.Hooks, error) {\nreturn &ai.Hooks{\nWrapModel: func(ctx context.Context, p *ai.ModelParams, next ai.ModelNext) (*ai.ModelResponse, error) {\nresp, err := next(ctx, p)\nif err != nil {\nreturn nil, err\n}\ntext := strings.ToLower(resp.Text())\nfor _, term := range f.ForbiddenTerms {\nif strings.Contains(text, strings.ToLower(term)) {\nreturn nil, fmt.Errorf(\"content filter: response contains %q\", term)\n}\n}\nreturn resp, nil\n},\n}, nil\n}\nYou can even compose and stack different middleware solutions. Middleware stacks left-to-right, with the first listed being the outermost wrapper and so on:\nresp, err := genkit.Generate(ctx, g,\nai.WithModelName(\"googleai/gemini-flash-latest\"),\nai.WithPrompt(\"What CRM should our customer use?\"),\nai.WithUse(\n&middleware.Retry{MaxRetries: 3}, // outer: retries the inner stack\n&ContentFilter{ // inner: validates model output\nForbiddenTerms: []string{\"CompetitorCRM\", \"RivalCo\", \"internal price\"},\n},\n),\n)\nHere Retry\nwraps ContentFilter\n, which wraps the model call. Order matters, and Genkit makes it explicit.\nIf 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!\nYou can use the Genkit Developer UI 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.\nWe’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 middleware documentation to dive deeper, or get started with Genkit if you're new to the framework.\nHave an idea for a new pre-built middleware? File an issue. We'd love to hear what would improve your development experience!\nHappy coding! 🚀", "url": "https://wpnews.pro/news/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps", "canonical_source": "https://developers.googleblog.com/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps/", "published_at": "2026-05-20 03:10:21.387525+00:00", "updated_at": "2026-05-20 03:10:24.433672+00:00", "lang": "en", "topics": ["artificial-intelligence", "developer-tools", "open-source", "large-language-models", "enterprise-software"], "entities": ["Genkit", "TypeScript", "Go", "Dart", "Python", "Google"], "alternates": {"html": "https://wpnews.pro/news/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps", "markdown": "https://wpnews.pro/news/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps.md", "text": "https://wpnews.pro/news/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps.txt", "jsonld": "https://wpnews.pro/news/announcing-genkit-middleware-intercept-extend-and-harden-your-agentic-apps.jsonld"}}