Skip to content

feat(py): Implement generate middleware#5074

Draft
huangjeff5 wants to merge 6 commits intomainfrom
jh-mw-pr1
Draft

feat(py): Implement generate middleware#5074
huangjeff5 wants to merge 6 commits intomainfrom
jh-mw-pr1

Conversation

@huangjeff5
Copy link
Copy Markdown
Contributor

  • Introduces BaseMiddleware / GenerateMiddleware / generate_middleware, middleware_plugin, and Plugin.generate_middleware() so apps register middleware definitions on the app.
  • generate(..., use=[...]) accepts only MiddlewareRef (or dicts coerced to MiddlewareRef); resolves names via the registry.
  • Wires middleware into generate and parallel tool execution (wrap_tool chain preserved with asyncio.gather).
  • Genkit.generate_middleware() builds definitions without registering; registration is via plugins.
  • GenerateActionOptions.use typed as list[MiddlewareRef] | None with dict coercion in validation.
  • Removes legacy _ai/_middleware.py.
  • Built-in stock middleware (retry, fallback, …) are stubbed / deferred to a follow-up PR; register_builtin_generate_middleware is a no-op for names until then.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive middleware system for the Genkit Python package, allowing developers to intercept and modify generation, model calls, and tool executions. Key changes include new BaseMiddleware and GenerateMiddleware abstractions, a MiddlewareRef type for referencing middleware, and updated registration mechanisms via Genkit and a new middleware_plugin helper. The augment_with_context middleware has been refactored to align with the new system, and the reflection API is updated to expose middleware definitions. The feedback suggests improving the handling of the genkit argument in middleware resolution, enhancing middleware name validation, and ensuring robustness against concurrent plugin modifications during initialization.

from ._utils import _CONTEXT_PREFACE, _context_item_template, _last_user_message


def augment_with_context(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we stil use ths helper?


"""Abstract middleware runtime hook signatures.

``MiddlewareRuntime`` lives here with types from ``genkit._core._model`` and
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this comment

async def initialize_all_plugins(self) -> None:
"""Initialize every registered plugin once (lazy init is idempotent).

Used by the reflection server so values such as default models are
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shorten this comment.



def builtin_generate_middleware_definitions() -> list[GenerateMiddleware]:
"""Stock middleware definitions; empty until built-in middleware PR lands."""
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

augment_with_context should show up here

_FORBIDDEN_IN_MIDDLEWARE_KEY_SEGMENT = re.compile(r'[\x00-\x1f/\\:]|\s')


class _MiddlewareRegistryView(Protocol):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call it RegistryLike maybe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant