Skip to content

feat(py/genkit): complete DAP integration with registry#4459

Merged
yesudeep merged 18 commits intomainfrom
yesudeep/feat/agonizing-knot
Feb 6, 2026
Merged

feat(py/genkit): complete DAP integration with registry#4459
yesudeep merged 18 commits intomainfrom
yesudeep/feat/agonizing-knot

Conversation

@yesudeep
Copy link
Contributor

@yesudeep yesudeep commented Feb 5, 2026

Summary

Complete Dynamic Action Provider (DAP) integration for the Python SDK, achieving 100% parity with the JavaScript implementation.

Changes

Registry Enhancements

  • parse_registry_key() - Parses DAP-style keys like /dynamic-action-provider/mcp-host:tool/mytool
  • resolve_action_names() - Expands wildcard keys via DAPs (e.g., tool/*)
  • list_resolvable_actions() - Lists all actions including DAP-provided ones for DevUI
  • is_action_type() - Helper function to validate action type strings
  • DynamicActionProviderProtocol - Protocol for DAP interface (fixes circular import properly)

DevUI Integration

  • Updated reflection.py to use list_resolvable_actions() so DevUI displays DAP actions
  • Uses fully-qualified keys for de-duplication to prevent name collisions between DAPs

Code Quality

  • Replaced TYPE_CHECKING with Protocol-based type hints (proper circular import fix)
  • All imports at top of files per GEMINI.md guidelines
  • Fixed metadata construction to prevent name/description from being overwritten
  • Fixed stock symbol extraction heuristic in dap-demo sample
  • 25 tests passing in dap_test.py (100% parity with JS tests)

Documentation

  • Updated roadmap to reflect completed DAP features
  • Added comprehensive dap-demo sample with ELI5 documentation

Feature Parity

Feature JS Location Python Location Status
parse_registry_key() registry.ts:96-141 registry.py:112-182
resolve_action_names() registry.ts:196-212 registry.py:547-588
list_resolvable_actions() registry.ts:383-403 registry.py:679-749
is_action_type() registry.ts:77-81 action/types.py
DevUI integration reflection API reflection.py:226

Testing

cd py && uv run pytest packages/genkit/tests/genkit/blocks/dap_test.py -v
# 25 tests passing

Review Comments Addressed

  • Moved all inline imports to top of files
  • Fixed DAP action de-duplication to use fully-qualified keys
  • Fixed metadata construction order (metadata first, then name/description)
  • Fixed stock symbol extraction in dap-demo (reversed word order)
  • Replaced TYPE_CHECKING with Protocol for proper circular import fix
  • Added missing JS test parity tests (skip_trace, transformed_metadata)

@github-actions github-actions bot added docs Improvements or additions to documentation feature New feature or request python Python config labels Feb 5, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @yesudeep, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new Python sample for Dynamic Action Providers (DAPs), a feature that allows tools to be provided dynamically at runtime rather than being registered at startup. The sample serves as a practical reference for users to understand and implement DAPs, demonstrating key concepts such as dynamic tool creation, caching with Time-To-Live (TTL), and cache invalidation. It also updates the project roadmap to reflect the current parity status of the Python DAP implementation.

Highlights

  • New DAP Demo Sample: A new comprehensive Python sample (dap-demo) has been added to showcase the functionality of Dynamic Action Providers (DAPs).
  • Dynamic Tool Provisioning: The sample demonstrates how to dynamically create and provide tools at runtime, using multiple DAPs with different caching strategies (e.g., short TTL for weather tools, longer for finance tools).
  • Cache Management: Key DAP features like cache configuration (TTL) and manual cache invalidation are illustrated through dedicated flows.
  • DevUI Integration and Flows: Five distinct flows (weather_assistant, finance_assistant, multi_assistant, refresh_tools_demo, list_dap_tools) are provided for easy testing and visualization within the Genkit DevUI.
  • Roadmap Update: The roadmap.md document has been updated to reflect the completion of the Python DAP core implementation and includes a detailed feature comparison with the JavaScript canonical implementation.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • py/engdoc/parity-analysis/roadmap.md
    • Updated the 'Current Status' date to 2026-02-05.
    • Marked 'M7: DAP Core' and 'P0: DAP Core Implementation' as complete.
    • Added a new detailed section 'M11: Dynamic Action Provider (DAP) Analysis' which includes a feature comparison table between JS and Python DAP implementations, highlighting core functionality, DAP methods, cache configuration, registry integration, and test coverage.
    • Outlined remaining DAP gaps related to DevUI integration and registry key parsing.
  • py/pyproject.toml
    • Added 'dap-demo' as a workspace source.
  • py/samples/dap-demo/README.md
    • Added a comprehensive README for the DAP demo, explaining DAPs, key concepts (Dynamic Tool, Cache, TTL, Invalidation), architecture, demonstrated features, prerequisites, running instructions (manual and via sample runner), and testing in DevUI with details for each flow.
    • Provided Python code examples for DAP configuration.
  • py/samples/dap-demo/pyproject.toml
    • Added project metadata and dependencies for the 'dap-demo' sample, including 'genkit', 'genkit-plugin-google-genai', 'pydantic', and 'rich'.
  • py/samples/dap-demo/run.sh
    • Added a shell script to set up and run the 'dap-demo' sample, including environment variable checks, dependency installation, and starting the Genkit DevUI with hot reloading.
  • py/samples/dap-demo/src/main.py
    • Added the main Python application for the DAP demo.
    • Defines 'WeatherInput', 'FinanceInput', 'MultiInput', 'RefreshInput', 'ListToolsInput', and 'CurrencyConversion' Pydantic models for flow inputs.
    • Includes simulated 'fetch_weather_data' and 'fetch_stock_price' functions.
    • Implements 'weather_tools_provider' and 'finance_tools_provider' functions to dynamically provide tools with different 'DapCacheConfig' (5s TTL for weather, 60s for finance).
    • Defines five Genkit flows: 'weather_assistant', 'finance_assistant', 'multi_assistant', 'refresh_tools_demo', and 'list_dap_tools', demonstrating various DAP functionalities.
Activity
  • No human activity (comments, reviews, approvals) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
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 adds a comprehensive and well-documented sample for Dynamic Action Providers (DAPs) in Python, which is a great addition. The sample effectively demonstrates core DAP concepts like dynamic tool creation, caching with TTL, and cache invalidation. My review includes suggestions to make the sample even more robust by demonstrating how a model can use tools from DAPs, improving efficiency with concurrent fetching, and adhering to standard Python packaging conventions.

@yesudeep yesudeep requested a review from huangjeff5 as a code owner February 5, 2026 21:48
@yesudeep yesudeep force-pushed the yesudeep/feat/agonizing-knot branch 3 times, most recently from 1335313 to f251fe8 Compare February 5, 2026 22:43
@yesudeep yesudeep force-pushed the yesudeep/feat/agonizing-knot branch from f251fe8 to f91e4ed Compare February 5, 2026 22:50
@yesudeep yesudeep force-pushed the yesudeep/feat/agonizing-knot branch 3 times, most recently from 088fb0b to 0bd2149 Compare February 5, 2026 23:29
@yesudeep yesudeep changed the title feat(py/samples): add dap-demo sample for Dynamic Action Providers feat(py/genkit): complete DAP integration with registry Feb 5, 2026
@yesudeep
Copy link
Contributor Author

yesudeep commented Feb 5, 2026

/gemini review

Copy link
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 is a significant feature implementation, bringing the Python SDK's Dynamic Action Provider (DAP) functionality to full parity with the JavaScript implementation. The changes are extensive, touching the core registry, the DAP block, and adding comprehensive tests and a new sample. The code quality is high, with clear logic and good documentation. The new DAP sample is particularly well-done, providing clear explanations and examples. I have one minor comment regarding an import placement in the new sample that violates the project's coding standards.

@yesudeep
Copy link
Contributor Author

yesudeep commented Feb 5, 2026

/gemini review

Copy link
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 is a significant and well-executed effort to bring the Python SDK's Dynamic Action Provider (DAP) implementation to full parity with the JavaScript version. The changes are extensive, touching core registry logic, the DAP implementation itself, and adding comprehensive tests and documentation. The new dap-demo sample is an excellent addition that clearly demonstrates the new functionality. I've identified one potential bug in the registry's de-duplication logic for DAP-provided actions that could lead to missing actions in the DevUI, and I've suggested a fix along with a necessary update to a new test case. Overall, this is a high-quality contribution that greatly enhances the Python SDK.

@yesudeep
Copy link
Contributor Author

yesudeep commented Feb 5, 2026

/gemini review

Copy link
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 successfully completes the Dynamic Action Provider (DAP) integration for the Python SDK, bringing it to full feature parity with the JavaScript implementation. The changes are comprehensive, including significant enhancements to registry.py for DAP key parsing and action resolution, and a major refactoring of dap.py to align with the JS version's caching and action signature patterns. The addition of the dap-demo sample is excellent, providing a clear and well-documented example of the new capabilities. The test suite has also been appropriately expanded. Overall, this is a solid contribution. I have one minor suggestion to improve the logic in the new sample.

@yesudeep
Copy link
Contributor Author

yesudeep commented Feb 5, 2026

/gemini review

Copy link
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 is a significant feature contribution that completes the Dynamic Action Provider (DAP) integration for the Python SDK, bringing it to parity with the JavaScript implementation. The changes are extensive and well-executed, including enhancements to the registry for DAP key parsing and resolution, updates to the core DAP logic for caching and action definition, and comprehensive documentation updates. A new dap-demo sample provides an excellent demonstration of the new functionality, and the test suite has been expanded to ensure correctness. My review identified a minor issue in how action metadata is constructed, where action.metadata could unintentionally overwrite the action's name and description. I've provided suggestions to correct this behavior in the three places this pattern occurs.

@yesudeep yesudeep enabled auto-merge (squash) February 6, 2026 00:42
This sample demonstrates Dynamic Action Provider (DAP) usage including:
- Multiple DAPs with different caching strategies (weather and finance)
- Dynamic tool creation via ai.dynamic_tool()
- Cache invalidation
- Tool listing from DAP cache

The Python DAP implementation was already complete and at parity with
the JS canonical implementation. This sample provides a reference for
users learning to use DAPs.

Flows available in DevUI:
- weather_assistant: Get weather using dynamic tools
- finance_assistant: Answer finance queries
- multi_assistant: Combine tools from multiple DAPs
- refresh_tools_demo: Cache invalidation demo
- list_dap_tools: List available tools

Includes ELI5 documentation, data flow diagrams, and testing
instructions per GEMINI.md guidelines.
Updates the Python DAP implementation to match the latest JavaScript
changes from PR #4050:

- DAP action takes no input and returns list[ActionMetadata]
- Cache is created before action with set_dap/set_value pattern
- transform_dap_value returns flat list instead of grouped dict
- Metadata now includes name/description fields explicitly

Also updates tests to verify the new API behavior.
- Add ELI5 section with relatable analogies (toy box/catalog)
- Add version parity notes referencing JS PR #4050
- Update roadmap with JS PR #4050 alignment details
- Add sample reference to module docstring
- Restructure package: move main.py to src/dap_demo/__init__.py
- Update pyproject.toml packages to use proper package directory
- Update run.sh to use module execution (-m dap_demo)
- Use asyncio.gather for concurrent DAP cache fetches
- Improve flows to demonstrate direct tool invocation
- Add heuristic-based query routing in finance and multi assistants

Note: Dynamic tools from DAPs are not in the global registry, so they
must be invoked directly rather than passed to ai.generate() by name.
Fixes potential name collision bug where two different DAPs providing
actions with the same short name would cause one to be omitted.
Adds test_runs_action_with_transformed_metadata and test_skips_trace_when_requested
to match JS test parity. Now at 100% test coverage parity with JS.
Reverse word order to correctly extract 'AAPL' instead of 'THE' from
queries like 'What's the current price of AAPL stock?'
Properly fixes circular import by defining DynamicActionProviderProtocol
that describes the interface needed by Registry. This is cleaner than
TYPE_CHECKING as it provides runtime type safety through duck typing.
…tion

Apply metadata dict first, then set name and description to ensure
they cannot be accidentally overwritten by metadata fields.
- Add action.kind to metadata in all three places for DevUI consistency
- Use split(':', 1) to handle colons in action names
- Use ActionKind.DYNAMIC_ACTION_PROVIDER enum instead of string literal
DRY refactor - _create_action_metadata() helper now used in all three
places that build action metadata dicts.
Preserves inputSchema, outputSchema, and other metadata fields
from DAP-provided actions instead of only name, kind, description.
- registry.py: Include inputSchema/outputSchema in static action metadata
  for DevUI compatibility using model_validate
- dap-demo: Use isalnum() for stock ticker extraction to support
  tickers with numbers like '7CD'
- dap.py: Include inputSchema and outputSchema in _create_action_metadata
  so dynamic actions display schemas in DevUI
- registry.py: Clarify DAP key format in resolve_action_names docstring
  with full path prefix example
Use regex to clean punctuation from words before checking for
stock tickers. Handles cases like 'GOOG?' correctly and adds
minimum length check to avoid matching common words like 'OF'.
@yesudeep yesudeep force-pushed the yesudeep/feat/agonizing-knot branch from f0ed167 to 3e9711c Compare February 6, 2026 00:47
@yesudeep yesudeep merged commit c541f48 into main Feb 6, 2026
17 checks passed
@yesudeep yesudeep deleted the yesudeep/feat/agonizing-knot branch February 6, 2026 16:30
yesudeep added a commit to yesudeep/genkit that referenced this pull request Feb 6, 2026
@yesudeep yesudeep mentioned this pull request Feb 6, 2026
yesudeep added a commit that referenced this pull request Feb 13, 2026
Cross-checked all markdown files in py/ against the codebase and open PRs.
Fixed outdated content across 9 files.

engdoc/index.md:
- Fix Python version: 3.12+ → 3.10+
- Update feature parity table (6 of 7 features now ✅, Agents still ❌)
- Replace 8-plugin table with full 23-plugin parity table
- Rewrite all 6 Python code examples (generation, structured output,
  tool calling, chat, agents, data retrieval) with correct imports,
  Genkit() class API, and @ai.tool() decorator pattern

engdoc/extending/api.md:
- Replace stale Sync/Async design section (GenkitExperimental/SyncGenkit/
  AsyncGenkit never implemented) with actual async-first architecture
  documenting GenkitRegistry → GenkitBase → Genkit hierarchy

engdoc/extending/index.md:
- Update d2 diagram plugin list from 7 to 22 plugins

engdoc/extending/servers.md:
- Fill Python TODO links with actual file paths (flows.py, reflection.py)

engdoc/user_guide/python/publishing_pypi.md:
- Add ReleaseKit as primary publishing mechanism
- Demote manual workflow to "Legacy" section

GEMINI.md:
- Remove 7 dangling references to deleted files (engdoc/planning/,
  blog-genkit-python-*.md, release-publishing-guide.md)
- Update blog article guidelines from mandatory to optional
- Remove stale validation script checking deleted paths

.github/PR_RELEASE.md:
- Remove dangling reference to deleted blog-genkit-python-0.5.0.md

PARITY_AUDIT.md:
- G7: ✅ Done → ⬜ Reverted (#4459 reverted by #4469, needs re-land)
- §8c.3/§8c.4: Update stale text — X-Genkit-Span-Id IS now sent (#4511)
- §1d: genkitx-cohere ❌ → ✅ (in-tree cohere plugin exists)
- §6c: Community coverage 3/6 → 4/6
- G17: 🔄 draft → ⬜ (#4521 closed, needs new PR)
- G3/G12-G16/G4: Note #4510 is closed, needs new PR after G38
- G2→G1: Mark as superseded (#4516 titled [SUPERSEDED])
yesudeep added a commit that referenced this pull request Feb 13, 2026
Cross-checked all markdown files in py/ against the codebase and open PRs.
Fixed outdated content across 9 files.

engdoc/index.md:
- Fix Python version: 3.12+ → 3.10+
- Update feature parity table (6 of 7 features now ✅, Agents still ❌)
- Replace 8-plugin table with full 23-plugin parity table
- Rewrite all 6 Python code examples (generation, structured output,
  tool calling, chat, agents, data retrieval) with correct imports,
  Genkit() class API, and @ai.tool() decorator pattern

engdoc/extending/api.md:
- Replace stale Sync/Async design section (GenkitExperimental/SyncGenkit/
  AsyncGenkit never implemented) with actual async-first architecture
  documenting GenkitRegistry → GenkitBase → Genkit hierarchy

engdoc/extending/index.md:
- Update d2 diagram plugin list from 7 to 22 plugins

engdoc/extending/servers.md:
- Fill Python TODO links with actual file paths (flows.py, reflection.py)

engdoc/user_guide/python/publishing_pypi.md:
- Add ReleaseKit as primary publishing mechanism
- Demote manual workflow to "Legacy" section

GEMINI.md:
- Remove 7 dangling references to deleted files (engdoc/planning/,
  blog-genkit-python-*.md, release-publishing-guide.md)
- Update blog article guidelines from mandatory to optional
- Remove stale validation script checking deleted paths

.github/PR_RELEASE.md:
- Remove dangling reference to deleted blog-genkit-python-0.5.0.md

PARITY_AUDIT.md:
- G7: ✅ Done → ⬜ Reverted (#4459 reverted by #4469, needs re-land)
- §8c.3/§8c.4: Update stale text — X-Genkit-Span-Id IS now sent (#4511)
- §1d: genkitx-cohere ❌ → ✅ (in-tree cohere plugin exists)
- §6c: Community coverage 3/6 → 4/6
- G17: 🔄 draft → ⬜ (#4521 closed, needs new PR)
- G3/G12-G16/G4: Note #4510 is closed, needs new PR after G38
- G2→G1: Mark as superseded (#4516 titled [SUPERSEDED])
yesudeep added a commit that referenced this pull request Feb 13, 2026
Cross-checked all markdown files in py/ against the codebase and open PRs.
Fixed outdated content across 9 files.

engdoc/index.md:
- Fix Python version: 3.12+ → 3.10+
- Update feature parity table (6 of 7 features now ✅, Agents still ❌)
- Replace 8-plugin table with full 23-plugin parity table
- Rewrite all 6 Python code examples (generation, structured output,
  tool calling, chat, agents, data retrieval) with correct imports,
  Genkit() class API, and @ai.tool() decorator pattern

engdoc/extending/api.md:
- Replace stale Sync/Async design section (GenkitExperimental/SyncGenkit/
  AsyncGenkit never implemented) with actual async-first architecture
  documenting GenkitRegistry → GenkitBase → Genkit hierarchy

engdoc/extending/index.md:
- Update d2 diagram plugin list from 7 to 22 plugins

engdoc/extending/servers.md:
- Fill Python TODO links with actual file paths (flows.py, reflection.py)

engdoc/user_guide/python/publishing_pypi.md:
- Add ReleaseKit as primary publishing mechanism
- Demote manual workflow to "Legacy" section

GEMINI.md:
- Remove 7 dangling references to deleted files (engdoc/planning/,
  blog-genkit-python-*.md, release-publishing-guide.md)
- Update blog article guidelines from mandatory to optional
- Remove stale validation script checking deleted paths

.github/PR_RELEASE.md:
- Remove dangling reference to deleted blog-genkit-python-0.5.0.md

PARITY_AUDIT.md:
- G7: ✅ Done → ⬜ Reverted (#4459 reverted by #4469, needs re-land)
- §8c.3/§8c.4: Update stale text — X-Genkit-Span-Id IS now sent (#4511)
- §1d: genkitx-cohere ❌ → ✅ (in-tree cohere plugin exists)
- §6c: Community coverage 3/6 → 4/6
- G17: 🔄 draft → ⬜ (#4521 closed, needs new PR)
- G3/G12-G16/G4: Note #4510 is closed, needs new PR after G38
- G2→G1: Mark as superseded (#4516 titled [SUPERSEDED])
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 feature New feature or request python Python

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants