Skip to content

feat: add DNS-AID integration for agent discovery via DNS#4856

Open
IngmarVG-IB wants to merge 2 commits intogoogle:mainfrom
IngmarVG-IB:feat/dns-aid-integration
Open

feat: add DNS-AID integration for agent discovery via DNS#4856
IngmarVG-IB wants to merge 2 commits intogoogle:mainfrom
IngmarVG-IB:feat/dns-aid-integration

Conversation

@IngmarVG-IB
Copy link
Copy Markdown

@IngmarVG-IB IngmarVG-IB commented Mar 17, 2026

Summary

Adds google.adk.integrations.dns_aid — the decentralized counterpart to
integrations/agent_registry. Agents are discovered (and published) via
DNS-AID SVCB records (RFC 9460)
under _<name>._<protocol>._agents.<domain> rather than a centralized cloud
registry.

  • Opt-in: optional dependency, no behavior change for existing deployments
  • Lazy-imported: missing extra produces a helpful ImportError, not ModuleNotFoundError
  • Two bridges: RemoteA2aAgent (protocol=a2a) and McpToolset (protocol=mcp)
  • Three FunctionTools: discover, publish, unpublish for LlmAgent
pip install "google-adk[dns-aid]"

Motivation

Round 2 of #4856. Reframed as the decentralized counterpart to
agent_registry: same idea, different trust model. Restructure mirrors the
#5094 SecretManagerClient
move pattern.

Files changed

File Change
src/google/adk/integrations/dns_aid/__init__.py New — public surface
src/google/adk/integrations/dns_aid/dns_aid.py Newdiscover/publish/unpublish + get_dns_aid_tools
src/google/adk/integrations/dns_aid/a2a_bridge.py Newremote_a2a_agent_from_recordRemoteA2aAgent
src/google/adk/integrations/dns_aid/mcp_bridge.py Newmcp_toolset_from_recordMcpToolset
src/google/adk/integrations/dns_aid/README.md New — install, backend creds table, bridge examples, roadmap
tests/unittests/integrations/dns_aid/test_*.py New — 26 tests, mock-based
src/google/adk/tools/dns_aid_tool.py Re-export shim, DeprecationWarning
src/google/adk/tools/dns_aid_a2a_bridge.py Re-export shim, DeprecationWarning
pyproject.toml optional-dependencies.dns-aid = ["dns-aid>=0.18,<1", "google-adk[a2a]"]
AGENTS.md Drop stale assistant entry

Design decisions

  • Validation at the schema boundary: pydantic.Field constraints + Literal for protocol / backend_name so the FunctionTool schema constrains the LLM up front (RFC 1035 pattern for agent_name, ge=1/le=65535 for port, ge=60 for ttl).
  • Structured returns: discover_agents returns the DiscoveryResult dict directly. The previous json.dumps(default=str) wrapper forced the LLM to re-parse and silently stripped type info on datetimes/UUIDs.
  • Typed error translation: unpublish_agent distinguishes not_found / permission_denied / backend_unavailable / throttled / error so the LLM can decide whether to retry. The previous code returned not_found for every failure mode.
  • Closure parity: get_dns_aid_tools binds backend_name via inspect.signature + functools.wraps so adding a parameter upstream (e.g. policy_uri) doesn't silently desync the FunctionTool schema. A parity test guards the contract.
  • Sync bridges: both bridges are non-async — RemoteA2aAgent fetches the agent card lazily on first invocation, so no I/O happens at construction time.

Test plan

  • pytest tests/unittests/integrations/dns_aid/ — 26/26 pass
  • pre-commit run --all-files clean (pyink, isort, addlicense, pyproject-fmt, mdformat)
  • from google.adk.tools.dns_aid_tool import get_dns_aid_tools still works and emits DeprecationWarning
  • Branch rebased onto main

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 integrates DNS-AID (DNS-based Agent Identification and Discovery) into the Google ADK framework. It provides a decentralized discovery mechanism for AI agents, allowing ADK to find and interact with agents published via DNS SVCB records, specifically bridging DNS-AID discovered agents to ADK's existing A2A protocol support. This enhances ADK's ability to discover and connect with a broader range of agents.

Highlights

  • DNS-AID FunctionTools: Asynchronous discover_agents, publish_agent, and unpublish_agent functions were added and wrapped as FunctionTool objects for Google ADK.
  • Tool Factory: A get_dns_aid_tools() factory function was introduced, supporting DNS backend binding for publish/unpublish operations.
  • A2A Bridge: An A2A bridge was implemented to convert agents discovered via DNS-AID into ADK-compatible RemoteAgent references.

🧠 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
  • src/google/adk/tools/dns_aid_a2a_bridge.py
    • Added a new module to facilitate the conversion of DNS-AID AgentRecord objects, specifically those using the A2A protocol, into a dictionary format suitable for ADK's RemoteAgent construction.
  • src/google/adk/tools/dns_aid_tool.py
    • Introduced a new module containing discover_agents, publish_agent, and unpublish_agent asynchronous functions. These functions leverage the dns-aid library for agent management via DNS and are exposed as FunctionTool objects for use within Google ADK.
    • Added get_dns_aid_tools factory function to retrieve these tools, with support for binding a specific DNS backend for publishing and unpublishing operations.
Activity
  • No human activity has been recorded on 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.

@google-cla
Copy link
Copy Markdown

google-cla Bot commented Mar 17, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot adk-bot added the tools [Component] This issue is related to tools label Mar 17, 2026
@adk-bot
Copy link
Copy Markdown
Collaborator

adk-bot commented Mar 17, 2026

Hello @IngmarVG-IB, thank you for your contribution!

This PR is a new feature, could you please create a GitHub issue and associate it with this PR?

In addition, could you please provide the results of the unit tests as mentioned in your testing plan?

This information will help reviewers to review your PR more efficiently. Thanks!

Response from ADK Triaging Agent

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 DNS-AID tools for agent discovery, publishing, and unpublishing, along with a bridge to make discovered agents compatible with ADK's A2A protocol. The changes are well-structured. I've identified a critical issue in how function wrappers are created, which would prevent the tools from working correctly with the language model. I've also included some suggestions to improve type safety and maintainability.

Comment thread src/google/adk/tools/dns_aid_tool.py Outdated
Comment thread src/google/adk/tools/dns_aid_a2a_bridge.py Outdated
Comment thread src/google/adk/tools/dns_aid_a2a_bridge.py Outdated
Comment thread src/google/adk/tools/dns_aid_a2a_bridge.py Outdated
Comment thread src/google/adk/tools/dns_aid_tool.py Outdated
@IngmarVG-IB
Copy link
Copy Markdown
Author

Thanks for the review @gemini-code-assist and @adk-bot!

Fixes Applied (commit a7adb4c)

Critical: **kwargs in wrapper functions — Fixed. _publish and _unpublish now have explicit parameter signatures matching the original functions (minus backend_name). This ensures FunctionTool can introspect parameters correctly for LLM tool schemas.

Type hintsa2a_agent_from_record now uses AgentRecord instead of Any. get_dns_aid_tools returns list["FunctionTool"].

Imports — Moved dns_aid.core.models imports to top of dns_aid_a2a_bridge.py.

Magic string — Extracted A2A_AGENT_CARD_PATH = "/.well-known/agent-card.json" constant.

Will create a GitHub issue and provide unit test results as requested.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Thanks for the update, @IngmarVG-IB!

It's great to see these improvements addressing key aspects of code quality and maintainability:

  • Explicit Parameter Signatures for Wrapper Functions: This is a critical improvement for the FunctionTool to correctly introspect parameters and generate accurate LLM tool schemas. It significantly enhances the reliability and usability of the DNS-AID tools within the ADK framework.
  • Improved Type Hints: Using more specific type hints like AgentRecord and list["FunctionTool"] greatly improves code readability, makes the code easier to understand, and allows for better static analysis, which is beneficial for long-term maintainability.
  • Consolidated Imports: Moving imports to the top of the file aligns with Python best practices (PEP 8) and contributes to better code organization and readability.
  • Extracted Magic String: Replacing the magic string with a named constant (A2A_AGENT_CARD_PATH) is an excellent practice that enhances readability and makes future modifications safer and easier.

I also note your plan to create a GitHub issue and provide unit test results, which will be very helpful for the review process. Keep up the great work!

@rohityan
Copy link
Copy Markdown
Collaborator

Hi @IngmarVG-IB , Thank you for your contribution! It appears you haven't yet signed the Contributor License Agreement (CLA). Please visit https://cla.developers.google.com/ to complete the signing process. Once the CLA is signed, we'll be able to proceed with the review of your PR. Thank you!

@rohityan rohityan added the request clarification [Status] The maintainer need clarification or more information from the author label Mar 20, 2026
@IngmarVG-IB IngmarVG-IB force-pushed the feat/dns-aid-integration branch from a7adb4c to 460b613 Compare March 21, 2026 03:01
@IngmarVG-IB
Copy link
Copy Markdown
Author

Signed the CLA, anything else required at this point @rohityan ?

Adds google.adk.integrations.dns_aid as the decentralized counterpart to
integrations/agent_registry: instead of pulling agents from a centralized
cloud registry, agents are discovered (and published) via DNS SVCB records
under _<name>._<protocol>._agents.<domain>.

Public surface:

  from google.adk.integrations.dns_aid import (
      discover_agents,           # async; query DNS SVCB
      publish_agent,             # async; create SVCB+TXT records
      unpublish_agent,           # async; remove records
      get_dns_aid_tools,         # FunctionTool wrappers for an LlmAgent
      remote_a2a_agent_from_record,   # bridge to RemoteA2aAgent
      mcp_toolset_from_record,        # bridge to McpToolset
  )

Install:

  pip install "google-adk[dns-aid]"

The extra pulls dns-aid>=0.18,<1 and google-adk[a2a] (for the A2A bridge).

Implementation notes:

- Lives in integrations/, not tools/, per integrations/README.md and
  matching the PR google#5094 SecretManagerClient move pattern. Old import paths
  (google.adk.tools.dns_aid_tool, .dns_aid_a2a_bridge) remain as
  re-export shims that emit DeprecationWarning, scheduled for removal in
  a future release.
- dns_aid imports are lazy-wrapped per integrations/README.md rule 4 so
  a missing extra produces "pip install google-adk[dns-aid]" rather than
  a raw ModuleNotFoundError.
- LLM-callable args use pydantic Field constraints (RFC 1035 pattern for
  agent_name, ge=1/le=65535 for port, ge=60 for ttl) and Literal types
  for protocol and backend_name so the FunctionTool schema constrains
  the model up front instead of relying on runtime ValueErrors.
- discover_agents returns the structured DiscoveryResult dict directly;
  the previous json.dumps() wrapper forced the LLM to parse JSON and
  silently stripped type info on datetimes/UUIDs.
- unpublish_agent translates dns_aid exceptions into a typed status
  payload (not_found / permission_denied / backend_unavailable /
  throttled / error) so the LLM can decide whether to retry rather than
  being told "not found" for every failure mode.
- get_dns_aid_tools binds backend_name via inspect.signature +
  functools.wraps so adding a parameter upstream (e.g. policy_uri in
  Phase 6) doesn't silently desync the FunctionTool schema. A parity
  test in tests/unittests/integrations/dns_aid/test_dns_aid.py guards
  this contract.
- a2a_bridge.remote_a2a_agent_from_record returns a real RemoteA2aAgent
  (not the prior dict[str, Any]); RemoteA2aAgent fetches the card
  lazily on first invocation, so the bridge is sync.
- mcp_bridge.mcp_toolset_from_record is the symmetric piece for
  protocol=mcp, mirroring how integrations/agent_registry uses
  StreamableHTTPConnectionParams.
- Logger uses the project's required form
  logging.getLogger("google_adk." + __name__) so the
  check-file-contents CI gate doesn't reject it.

Tests: 26 new tests under tests/unittests/integrations/dns_aid/ cover
each rule path (validation, error translation, signature parity, bridge
type assertions). All pass with -p asyncio (asyncio_mode=auto).

README.md: full setup, per-backend credential table (route53,
cloudflare, cloud-dns, ns1, infoblox/nios, ddns, mock), bridge
examples, and a Future section flagging where trust verification, cap
docs, and policy enforcement will plug in (kept out of v1 to keep this
PR focused).
@IngmarVG-IB IngmarVG-IB force-pushed the feat/dns-aid-integration branch from 05e1ec5 to c03e35c Compare April 28, 2026 20:51
@IngmarVG-IB IngmarVG-IB changed the title feat: Add DNS-AID tools for agent discovery via DNS feat: add DNS-AID integration for agent discovery via DNS Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

request clarification [Status] The maintainer need clarification or more information from the author tools [Component] This issue is related to tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants