Skip to content

feat(a2a): enable native gRPC support and protocol routing#21403

Merged
alisa-alisa merged 8 commits intomainfrom
grpc-v0-branch3
Mar 12, 2026
Merged

feat(a2a): enable native gRPC support and protocol routing#21403
alisa-alisa merged 8 commits intomainfrom
grpc-v0-branch3

Conversation

@alisa-alisa
Copy link
Copy Markdown
Contributor

@alisa-alisa alisa-alisa commented Mar 6, 2026

Summary

This PR significantly simplifies and optimizes the A2A (Agent-to-Agent) client
implementation, focusing on gRPC transport reliability, streamlined card
normalization, and robust URL resolution. It removes complex SSRF/DNS-rebinding
protection logic that was causing connection issues and moves towards a leaner,
more maintainable architecture.

Details

1. Simplified gRPC Transport & A2A Client Manager

  • Simplified gRPC Instantiation: Replaced complex IP pinning and DNS
    rebinding logic with a direct GrpcTransportFactory instantiation using
    standard gRPC credentials.
  • Robust Card Resolution: Updated loadAgent to use
    resolver.resolve(agentCardUrl, ''). This prevents the A2A SDK from
    automatically appending .well-known/agent-card.json to URLs that are already
    fully qualified, fixing 404 errors when using direct card URLs.
  • Fixed Redundant Fetches: Optimized loadAgent to use
    factory.createFromAgentCard(agentCard) instead of re-fetching the card from
    the URL, improving performance and reliability.
  • Improved Error Handling: Added clearer error prefixing in
    sendMessageStream, getTask, and cancelTask to aid in debugging remote
    agent interactions.

2. Streamlined Agent Card Normalization (a2aUtils.ts)

  • Removed Zod Dependency: Refactored normalizeAgentCard to use manual
    field mapping and type guards instead of Zod schemas, reducing complexity and
    bundle size.
  • Protocol Compatibility: Added explicit mapping for supportedInterfaces
    to additionalInterfaces and protocolBinding to transport to support
    different A2A protocol versions.
  • Immutability: Implemented shallow copying in the normalization process to
    prevent unintended mutation of the SDK's cached objects.

3. Cleanup & Refactoring

  • Removed Dead Code: Deleted unused utility functions including
    pinUrlToIp, getGrpcChannelOptions, getGrpcCredentials, and
    extractNormalizedInterfaces.
  • Dependency Cleanup: Removed unused imports (e.g., node:dns, zod,
    safeLookup) and updated related unit tests.

Related Issues

Related to #18642.

How to Validate

  1. Unit Tests: Run core tests to ensure all A2A logic remains correct.
    npm test -w @google/gemini-cli-core -- src/agents/a2a-client-manager.test.ts src/agents/a2aUtils.test.ts
  2. Manual Verification: Start a remote gRPC agent and verify communication:
    • Configure a remote agent with a full agent_card_url (e.g.,
      http://127.0.0.1:9001/.well-known/agent-card.json).
    • Run a task involving that agent (e.g.,
      Hello, call the grpc-test-agent tool and say hi).
    • Confirm successful response from the remote agent.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@gemini-cli
Copy link
Copy Markdown
Contributor

gemini-cli Bot commented Mar 6, 2026

Hi @alisa-alisa, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.

We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines.

Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.

Thank you for your understanding and for being a part of our community!

@alisa-alisa
Copy link
Copy Markdown
Contributor Author

This PR is a part of another big split PR: #21348

@alisa-alisa alisa-alisa marked this pull request as ready for review March 6, 2026 14:35
@alisa-alisa alisa-alisa requested a review from a team as a code owner March 6, 2026 14:35
@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 significantly upgrades the agent-to-agent (A2A) communication layer by introducing native gRPC support and intelligent protocol routing. It prioritizes high-performance gRPC for AI agent interactions while maintaining robust security through comprehensive SSRF validation. These changes ensure efficient and secure communication, laying the groundwork for more advanced agent capabilities.

Highlights

  • Native gRPC Support: Integrated GrpcTransportFactory to enable native gRPC communication for remote agents, configuring secure/insecure credentials based on the target URL.
  • Protocol Routing: Implemented logic within A2AClientManager to automatically select gRPC as the preferred transport when available, with graceful fallback to REST or JSON-RPC.
  • Enhanced SSRF Protection: Introduced deep Server-Side Request Forgery (SSRF) validation, including pinning URLs to IPs to prevent DNS rebinding, checking for private IP ranges during initial agent loading, and recursively validating all transport URLs discovered within an agent card.
  • Improved Timeout Handling: Configured a dedicated Undici dispatcher for A2A communication with an extended 30-minute timeout to support long-running tasks without impacting global fetch settings.
  • SDK Upgrade: Updated @a2a-js/sdk to 0.3.10 to leverage the new multi-transport client factory and improved error handling.
Changelog
  • packages/core/src/agents/a2a-client-manager.test.ts
    • Updated imports to include gRPC client components and DNS utilities.
    • Refactored mocking strategy for @a2a-js/sdk/client and introduced node:dns/promises mocks.
    • Modified beforeEach setup to clear cache and mock DNS lookups for testing SSRF protection.
    • Added new test cases for ClientFactory configuration, resolveAgentCard failures, and factory.createFromAgentCard failures.
    • Introduced comprehensive tests for protocol routing and URL logic, including SSRF protection against private IPs, DNS rebinding, and malicious transport URLs within agent cards.
    • Simplified sendMessageStream, getTask, and cancelTask tests to use a unified mock client interface and updated error message expectations.
  • packages/core/src/agents/a2a-client-manager.ts
    • Added imports for GrpcTransportFactory and new A2A utility functions for gRPC options, URL pinning, and SSRF validation.
    • Modified a2aDispatcher to include safeLookup for connection-level SSRF protection.
    • Refactored a2aFetch to use a NodeFetchInit interface for dispatcher property.
    • Removed the resetInstanceForTesting static method.
    • Updated the loadAgent method to incorporate gRPC transport configuration, URL pinning, and initial SSRF validation via new private helper methods.
    • Replaced client.createFromUrl with client.createFromAgentCard for client instantiation.
    • Simplified error handling for sendMessageStream, getTask, and cancelTask methods.
    • Introduced new private methods: getFetchImpl for authentication handling, resolveAgentCard for initial card resolution and SSRF checks, and validateAgentCardUrls for deep SSRF validation of all URLs within an agent card.
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
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 significant enhancements by adding native gRPC support, protocol routing, and robust, multi-layered SSRF protection. The changes are well-structured, and the inclusion of comprehensive tests for the new security measures is excellent. I have one suggestion regarding the maintainability of the gRPC transport configuration to make it more resilient to future SDK changes.

Comment thread packages/core/src/agents/a2a-client-manager.ts Outdated
@gemini-cli gemini-cli Bot added the priority/p1 Important and should be addressed in the near term. label Mar 6, 2026
@anowardear062-svg
Copy link
Copy Markdown

Thanks

@alisa-alisa alisa-alisa force-pushed the grpc-v0-branch3 branch 2 times, most recently from c61ed08 to 15156e3 Compare March 9, 2026 21:19
Base automatically changed from grpc-v0-branch2 to main March 10, 2026 19:39
Comment thread packages/core/src/agents/a2aUtils.ts
Comment thread packages/core/src/agents/a2aUtils.ts Outdated
Comment thread packages/core/src/agents/a2aUtils.ts Outdated
Comment thread packages/core/src/agents/a2aUtils.ts Outdated
Comment thread packages/core/src/agents/a2a-client-manager.ts
Comment thread packages/core/src/agents/a2a-client-manager.ts Outdated
Comment thread packages/core/src/agents/a2a-client-manager.ts Outdated
Comment thread packages/core/src/agents/a2aUtils.ts Outdated
Comment thread packages/core/src/agents/a2a-client-manager.ts Outdated
Comment thread packages/core/src/agents/a2a-client-manager.ts Outdated
@alisa-alisa alisa-alisa force-pushed the grpc-v0-branch3 branch 2 times, most recently from 11f1e5a to ec8bf97 Compare March 11, 2026 15:53
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 11, 2026

Size Change: +121 kB (+0.46%)

Total Size: 26.1 MB

Filename Size Change
./bundle/chunk-QRRBF6VR.js 0 B -3.62 MB (removed) 🏆
./bundle/chunk-YFRXPORX.js 0 B -13.3 MB (removed) 🏆
./bundle/core-3JO26QAA.js 0 B -40.3 kB (removed) 🏆
./bundle/devtoolsService-N4KERIOX.js 0 B -27.7 kB (removed) 🏆
./bundle/interactiveCli-MKJKGJZJ.js 0 B -1.59 MB (removed) 🏆
./bundle/oauth2-provider-SWDO55LC.js 0 B -9.19 kB (removed) 🏆
./bundle/chunk-3Q6MCA74.js 13.4 MB +13.4 MB (new file) 🆕
./bundle/chunk-DFT3LMTI.js 3.62 MB +3.62 MB (new file) 🆕
./bundle/core-QCDH5RXP.js 40.1 kB +40.1 kB (new file) 🆕
./bundle/devtoolsService-YABOOZK2.js 27.7 kB +27.7 kB (new file) 🆕
./bundle/interactiveCli-W536GQ3B.js 1.59 MB +1.59 MB (new file) 🆕
./bundle/oauth2-provider-EDPGO3K6.js 9.19 kB +9.19 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-37ZTTFQF.js 966 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-FXR7IA3Q.js 1.95 MB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/gemini.js 689 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/keychain-token-storage-A3WKTJK3.js 0 B -518 B (removed) 🏆
./bundle/memoryDiscovery-URXPIMBI.js 922 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 221 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 227 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 11.5 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/undici-4X2YZID5.js 360 B 0 B
./bundle/keychain-token-storage-HL7KNNIG.js 518 B +518 B (new file) 🆕

compressed-size-action

adamfweidman and others added 2 commits March 12, 2026 10:50
…rect gRPC URL

- Pass empty string to resolver.resolve() to prevent SDK from appending
  /.well-known/agent-card.json to direct card URLs
- Simplify normalizeAgentCard to only handle proto field name aliases
  (supportedInterfaces → additionalInterfaces, protocolBinding → transport)
- Use gRPC-specific URL from additionalInterfaces for credentials
- Remove dead helper functions and unnecessary behaviors
- Add shallow copy to prevent SDK object mutation
@gemini-cli gemini-cli Bot added area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Mar 12, 2026
@alisa-alisa alisa-alisa enabled auto-merge March 12, 2026 20:00
@alisa-alisa alisa-alisa added this pull request to the merge queue Mar 12, 2026
Merged via the queue into main with commit 4d393f9 Mar 12, 2026
27 checks passed
@alisa-alisa alisa-alisa deleted the grpc-v0-branch3 branch March 12, 2026 21:49
ruomengz pushed a commit that referenced this pull request Mar 13, 2026
Co-authored-by: Adam Weidman <adamfweidman@google.com>
SUNDRAM07 pushed a commit to SUNDRAM07/gemini-cli that referenced this pull request Mar 30, 2026
warrenzhu25 pushed a commit to warrenzhu25/gemini-cli that referenced this pull request Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants