feat: add DNS-AID integration for agent discovery via DNS#4856
feat: add DNS-AID integration for agent discovery via DNS#4856IngmarVG-IB wants to merge 2 commits intogoogle:mainfrom
Conversation
Summary of ChangesHello, 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
🧠 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
Activity
Using Gemini Code AssistThe 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
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 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
|
|
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. |
|
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 |
There was a problem hiding this comment.
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.
|
Thanks for the review @gemini-code-assist and @adk-bot! Fixes Applied (commit a7adb4c)Critical: Type hints — Imports — Moved Magic string — Extracted Will create a GitHub issue and provide unit test results as requested. |
|
Thanks for the update, @IngmarVG-IB! It's great to see these improvements addressing key aspects of code quality and maintainability:
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! |
|
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! |
a7adb4c to
460b613
Compare
|
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).
05e1ec5 to
c03e35c
Compare
Summary
Adds
google.adk.integrations.dns_aid— the decentralized counterpart tointegrations/agent_registry. Agents are discovered (and published) viaDNS-AID SVCB records (RFC 9460)
under
_<name>._<protocol>._agents.<domain>rather than a centralized cloudregistry.
ImportError, notModuleNotFoundErrorRemoteA2aAgent(protocol=a2a) andMcpToolset(protocol=mcp)discover,publish,unpublishforLlmAgentpip 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
SecretManagerClientmove pattern.
Files changed
src/google/adk/integrations/dns_aid/__init__.pysrc/google/adk/integrations/dns_aid/dns_aid.pydiscover/publish/unpublish+get_dns_aid_toolssrc/google/adk/integrations/dns_aid/a2a_bridge.pyremote_a2a_agent_from_record→RemoteA2aAgentsrc/google/adk/integrations/dns_aid/mcp_bridge.pymcp_toolset_from_record→McpToolsetsrc/google/adk/integrations/dns_aid/README.mdtests/unittests/integrations/dns_aid/test_*.pysrc/google/adk/tools/dns_aid_tool.pyDeprecationWarningsrc/google/adk/tools/dns_aid_a2a_bridge.pyDeprecationWarningpyproject.tomloptional-dependencies.dns-aid = ["dns-aid>=0.18,<1", "google-adk[a2a]"]AGENTS.mdDesign decisions
pydantic.Fieldconstraints +Literalforprotocol/backend_nameso the FunctionTool schema constrains the LLM up front (RFC 1035 pattern foragent_name,ge=1/le=65535for port,ge=60for ttl).discover_agentsreturns theDiscoveryResultdict directly. The previousjson.dumps(default=str)wrapper forced the LLM to re-parse and silently stripped type info on datetimes/UUIDs.unpublish_agentdistinguishesnot_found/permission_denied/backend_unavailable/throttled/errorso the LLM can decide whether to retry. The previous code returnednot_foundfor every failure mode.get_dns_aid_toolsbindsbackend_nameviainspect.signature+functools.wrapsso adding a parameter upstream (e.g.policy_uri) doesn't silently desync the FunctionTool schema. A parity test guards the contract.RemoteA2aAgentfetches 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 passpre-commit run --all-filesclean (pyink, isort, addlicense, pyproject-fmt, mdformat)from google.adk.tools.dns_aid_tool import get_dns_aid_toolsstill works and emitsDeprecationWarningmain