Skip to main content

Genkit Middleware Plugin

A collection of middleware implementations for Genkit Python.

Overview

This plugin provides six concrete middleware implementations for common use cases:

  • Retry: Retries model API calls on transient errors with exponential backoff
  • Fallback: Falls back to alternative models when the primary model fails
  • ToolApproval: Requires explicit approval before executing tool calls
  • Skills: Exposes a library of skills as system prompts and tools
  • Filesystem: Provides sandboxed filesystem operations
  • Artifacts: Session artifact listing plus read/write artifact tools

Quick start

Import the middleware classes you need and pass instances directly into use=[]:

from genkit import Genkit
from genkit_google_genai import GoogleAI
from genkit_middleware import Retry, Fallback, Middleware

ai = Genkit(plugins=[GoogleAI(), Middleware()])

response = await ai.generate(
    model=GoogleAI.gemini_model('gemini-flash-latest'),
    prompt='Hello!',
    use=[
        Retry(max_retries=5),
        Fallback(models=['googleai/gemini-2.5-pro']),
    ],
)

These middlewares appear in the Dev UI by default.

Installation

uv add genkit-middleware genkit-google-genai

Usage

Retry

Automatically retries model calls on transient failures with configurable exponential backoff:

from genkit_google_genai import GoogleAI
from genkit_middleware import Retry

retry = Retry(
    max_retries=3,
    statuses=['UNAVAILABLE', 'DEADLINE_EXCEEDED', 'RESOURCE_EXHAUSTED'],
    initial_delay_ms=1000,
    max_delay_ms=60000,
    backoff_factor=2.0,
    no_jitter=False,  # set True for deterministic backoff (tests)
)

response = await ai.generate(
    model=GoogleAI.gemini_model('gemini-flash-latest'),
    prompt='Hello!',
    use=[retry],
)

Fallback

Falls back to alternative models on retryable errors:

from genkit_google_genai import GoogleAI
from genkit_middleware import Fallback

fallback = Fallback(
    models=[
        'googleai/gemini-2.5-pro',
        'googleai/gemini-flash-latest',
    ],
    statuses=['UNAVAILABLE', 'DEADLINE_EXCEEDED'],
)

response = await ai.generate(
    model=GoogleAI.gemini_model('gemini-pro-latest'),
    prompt='Hello!',
    use=[fallback],
)

ToolApproval

Requires approval before executing tools (useful for sensitive operations):

from pydantic import BaseModel, Field

from genkit import restart_tool
from genkit_google_genai import GoogleAI
from genkit_middleware import ToolApproval


class DeleteInput(BaseModel):
    name: str = Field(description='Database name to delete')


@ai.tool()
async def delete_database(input: DeleteInput) -> str:
    return f'Deleted {input.name}'


approval = ToolApproval(
    allowed_tools=['get_weather', 'search'],  # These tools run without approval
)

first = await ai.generate(
    model=GoogleAI.gemini_model('gemini-flash-latest'),
    prompt='Delete the database',
    tools=['delete_database'],
    use=[approval],
)

When a non-allowed tool is called, execution is interrupted. Approve and re-run the tool by restarting it with resumed_metadata that includes tool_approved:

response = await ai.generate(
    model=GoogleAI.gemini_model('gemini-flash-latest'),
    prompt='Delete the database',
    messages=list(first.messages),
    tools=['delete_database'],
    use=[approval],
    resume_restart=restart_tool(
        interrupt=first.interrupts[0],
        resumed_metadata={'tool_approved': True},
    ),
)

Skills

Scans directories for SKILL.md files and exposes them as loadable instructions:

from genkit_google_genai import GoogleAI
from genkit_middleware import Skills

skills = Skills(
    skill_paths=['skills', 'prompts/skills'],
)

response = await ai.generate(
    model=GoogleAI.gemini_model('gemini-flash-latest'),
    prompt='Help me with Python',
    use=[skills],
)

Skills are discovered by scanning for directories containing SKILL.md files. Each SKILL.md can have optional YAML frontmatter:

---
name: python-expert
description: Expert Python programming assistance
---

You are an expert Python programmer...

Filesystem

Provides sandboxed file operations confined to a root directory:

from genkit_google_genai import GoogleAI
from genkit_middleware import Filesystem

fs = Filesystem(
    root_dir='./workspace',
    allow_write_access=True,
    tool_name_prefix='',
)

response = await ai.generate(
    model=GoogleAI.gemini_model('gemini-flash-latest'),
    prompt='List files in the current directory',
    use=[fs],
)

Provides four tools:

  • list_files: List files in a directory
  • read_file: Read file content
  • write_file: Write to a file (requires allow_write_access=True)
  • edit_file: Edit file with string replacements (requires allow_write_access=True)

Artifacts

Exposes read_artifact / write_artifact tools and lists session artifacts in the system prompt. Intended for agent sessions:

from genkit_middleware import Artifacts, Middleware

from genkit import Genkit
from genkit.agent import InMemorySessionStore
from genkit_google_genai import GoogleAI

ai = Genkit(plugins=[GoogleAI(), Middleware()])

agent = ai.define_agent(
    name='workspaceAgent',
    model=GoogleAI.gemini_model('gemini-flash-latest'),
    use=[Artifacts()],
    store=InMemorySessionStore(),
)

chat = agent.chat()
await chat.send('Write poem.txt with a short poem about Python agents.')
# chat.artifacts now includes poem.txt

Release files for genkit-middleware 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for genkit-middleware 0.11.0
File Size Uploaded
genkit_middleware-0.11.0.tar.gz 22.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for genkit-middleware 0.11.0
File Interpreter ABI Platform
genkit_middleware-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 46.2 kB

Release files / genkit_middleware-0.11.0.tar.gz

Download URL genkit_middleware-0.11.0.tar.gz
Size 22.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1e099fe5d4718130facf12e8eb3a1a09733f714e9d34884c1d0b216b27703c0b
BLAKE2b-256 checksum
How to use checksums
e499dc771ade79733fc52e2e255e5500ad896e03f4af1d37d30470845d767a91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / genkit_middleware-0.11.0-py3-none-any.whl

Download URL genkit_middleware-0.11.0-py3-none-any.whl
Size 23.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2a57404153d904c4525de20ca7a74d99f75ad8912d2c14e0dfb8381e5506e273
BLAKE2b-256 checksum
How to use checksums
ae4bc86515629333a0555f17db71358b977e2df21b5ceff31b00740c71943f41
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.12.0

2 release files

This release

0.11.0 This release

2 release files

0.10.0

2 release files

0.9.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page