Skip to content

chore(py): refactor folder organization for core plugins#5341

Open
huangjeff5 wants to merge 3 commits into
jh-dx-fix1from
jh-dx-fix2
Open

chore(py): refactor folder organization for core plugins#5341
huangjeff5 wants to merge 3 commits into
jh-dx-fix1from
jh-dx-fix2

Conversation

@huangjeff5
Copy link
Copy Markdown
Contributor

Context

Fixes two issues in the python repo:

1. Plugin imports never resolved in the IDE.

You get red squiggly lines in the IDE when you dofrom genkit.plugins.google_genai import GoogleAI in across samples and tests. Runtime worked fine, but no static analyzer could resolve the import if you cloned the repo and tried to run a sample locally.

The reason: each plugin lived in its own top-level directory (py/plugins/<dash-name>/src/genkit/plugins/<underscore_name>/) while the rest of the genkit package lived in py/packages/genkit/src/genkit/. So from Python's perspective there were 10 different physical directories that all claimed to contribute modules to a single logical package, genkit.plugins.*. Static analyzers (pyright, pyrefly, ty) walk one source root at a time and don't merge them so even though runtime worked, IDEs with these type checkers would complain.

2. The python repo had additional layers of nesting that don't need to exist, adding complexity.

py/packages/genkit/ was a one-package directory that wrapped a single wheel. Once we'd already decided to pull plugin source into the core tree, there wasn't a good reason left for the packages/ wrapper to exist, and it added two extra path segments between the repo root and src/genkit/.

This should be a refactor to simplify Genkit maintenance. There should be no visible impact to app developers.

Changes

Move plugin sources into the core genkit tree, and drop the packages/genkit/ wrapper at the same time.

Before:
  py/packages/genkit/src/genkit/                     # core
  py/packages/genkit/tests/
  py/packages/genkit/pyproject.toml
  py/plugins/anthropic/src/genkit/plugins/anthropic/         # each plugin in its own
  py/plugins/google-genai/src/genkit/plugins/google_genai/   # top-level directory
  py/plugins/ollama/src/genkit/plugins/ollama/
  ...
  py/pyproject.toml   # workspace config only

After:
  py/src/genkit/                                     # core
  py/src/genkit/plugins/anthropic/                   # plugins live alongside core
  py/src/genkit/plugins/google_genai/                # in one physical tree
  py/src/genkit/plugins/ollama/
  ...
  py/tests/
  py/pyproject.toml   # workspace config AND genkit wheel manifest

Plugins still ship as separate wheels on PyPI (pip install genkit-plugin-google-genai still installs only that plugin) — they just live in one tree on disk for the purposes of static analysis and contributor sanity. Each plugin keeps its own pyproject.toml next to its source, which is what builds its wheel. The workspace, pyright, pyrefly, and ty configs all collapse from a list of nine source roots to one. The root py/pyproject.toml now serves both as the workspace config and as the wheel manifest for the core genkit package (absorbing the old py/packages/genkit/pyproject.toml).

Fix the type errors that this exposes.

A side effect of getting plugin imports to resolve is that, for the first time, pyright actually walks the plugin tree as part of repo-wide type-checking. It found roughly twenty latent type errors that had been there for months — most of them small (Pydantic field-alias positional vs. keyword arg, SDK union types that needed narrowing, an invariant collection signature where a covariant one was wanted). Each one is a real static-correctness fix; none of them change runtime behavior. Going forward, anyone editing plugin code gets type feedback in the IDE from the first character they type.

A few smaller workspace cleanups that come along with the move:

  • A new plugins dependency group plus default-groups = [..., "plugins"] makes uv sync install every workspace plugin so monorepo contributors don't have to remember to install them by hand.
  • websockets>=15.0 is pinned as a direct dependency of genkit — it was previously transitive via genkit-plugin-google-genai, which would have broken anyone installing genkit standalone (a latent bug that the layout cleanup happened to surface).

Expected Outcomes

  • IDEs with standard type checkers should correctly resolve the plugin imports in samples by default (after running uv sync).
  • Plugin code is actually type-checked.
  • Generally simpler layout with reduced nesting.

@github-actions github-actions Bot added docs Improvements or additions to documentation python Python config fix labels May 18, 2026
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 restructures the Python SDK by moving the core framework to the workspace root and consolidating plugins under src/genkit/plugins. Build targets, linting paths, and utility scripts were updated to accommodate this new layout. Key code changes include refactoring the Anthropic plugin's streaming logic and adding type narrowing in the OpenAI compatibility layer. Feedback suggests replacing type-narrowing assertions with more robust error handling for production stability and warns of potential runtime validation failures when passing internal Pydantic fields as keyword arguments.

Comment thread py/src/genkit/plugins/compat_oai/models/audio.py
Comment thread py/src/genkit/plugins/ollama/models.py
@huangjeff5 huangjeff5 marked this pull request as ready for review May 21, 2026 20:07
@huangjeff5 huangjeff5 requested a review from a team as a code owner May 21, 2026 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config docs Improvements or additions to documentation fix python Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant