Skip to content

feat(a2a): implement standardized normalization and streaming reassembly#21402

Merged
mattKorwel merged 3 commits intomainfrom
grpc-v0-branch2
Mar 10, 2026
Merged

feat(a2a): implement standardized normalization and streaming reassembly#21402
mattKorwel merged 3 commits intomainfrom
grpc-v0-branch2

Conversation

@alisa-alisa
Copy link
Contributor

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

Summary

This PR introduces the core infrastructure for A2A communication, focusing on standardized agent card normalization, robust URL parsing, and streaming response reassembly. It builds on the security foundation from PR #1 and includes critical fixes for DNS resolution resilience.

Details

  • Robust Card Normalization: Adds comprehensive logic to a2aUtils.ts that handles varied agent card formats. It ensures transport and url fields are consistently populated and correctly synchronized between supportedInterfaces and additionalInterfaces.
  • Optimized URL Resolution: Implements a splitAgentCardUrl utility to correctly handle both base URLs and full URLs containing the standard .well-known path, preventing "path doubling" bugs during agent resolution.
  • Streaming Result Reassembler: Introduces the A2AResultReassembler class to reassemble incremental A2A streaming updates (status, messages, and artifacts) into a coherent, human-readable result.
  • DNS Resolution Resilience: Updated pinUrlToIp to explicitly handle cases where DNS resolution returns no addresses. The logic now correctly distinguishes between a hostname resolving only to private IPs (SSRF block) and a complete resolution failure, preventing potential TypeErrors and process crashes.
  • Transport Security Helpers: Includes pinUrlToIp to prevent DNS rebinding by pinning hostnames to their resolved IP addresses during the connection phase.

Why this is needed

Remote agents provide information in varied formats depending on the protocol version and implementation (REST vs gRPC). This PR centralizes the "parsing brain" of the A2A system, ensuring that subsequent execution logic (like the Client Manager) can rely on a consistent and safe data structure.

Related Issues

Related to issue #18642.

@gemini-cli
Copy link
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
Contributor Author

This is part of split PR : #21348

@alisa-alisa alisa-alisa marked this pull request as ready for review March 6, 2026 14:33
@alisa-alisa alisa-alisa requested a review from a team as a code owner March 6, 2026 14:33
@gemini-code-assist
Copy link
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 establishes foundational infrastructure for Agent-to-Agent (A2A) communication by introducing robust mechanisms for handling agent card data, securing network connections, and efficiently processing streaming responses. The changes ensure that agent information is consistently structured, URLs are safely resolved, and incremental updates are coherently reassembled, laying the groundwork for reliable agent interactions.

Highlights

  • Agent Card Normalization: Implemented a new normalizeAgentCard utility to standardize agent card formats, ensuring consistent population of transport and url fields and synchronizing supportedInterfaces with additionalInterfaces.
  • Robust URL Handling and Security: Introduced pinUrlToIp to prevent DNS rebinding by resolving and pinning hostnames to IP addresses, including checks for private IP ranges. Also added splitAgentCardUrl to correctly parse agent card URLs and avoid path doubling issues.
  • Streaming Result Reassembly Enhancements: Refactored the A2AResultReassembler to use new type guards for processing streaming updates (status, messages, artifacts), improving type safety and clarity in reassembling incremental A2A responses.
  • gRPC Credential and Channel Options: Added getGrpcCredentials to provide appropriate SSL or insecure credentials based on the URL scheme, and getGrpcChannelOptions to ensure correct SSL/authority matching when connecting to pinned IP addresses.
Changelog
  • packages/core/src/agents/a2aUtils.test.ts
    • Imported new utility functions and vi for mocking.
    • Added beforeEach hook to clear mocks.
    • Included new test suites for getGrpcCredentials, pinUrlToIp, normalizeAgentCard, and splitAgentCardUrl covering various scenarios.
    • Updated existing A2AResultReassembler tests to include contextId and id in update chunks and added a test for file parts without name or URI.
  • packages/core/src/agents/a2aUtils.ts
    • Imported grpc, lookup from node:dns/promises, and additional types from @a2a-js/sdk.
    • Imported isAddressPrivate for network security checks.
    • Refactored A2AResultReassembler.update to use new type guards for handling different SendMessageResult kinds.
    • Added normalizeAgentCard function to standardize agent card properties and interfaces.
    • Introduced getGrpcCredentials and getGrpcChannelOptions for gRPC connection management.
    • Implemented pinUrlToIp for DNS resolution, IP pinning, and SSRF prevention.
    • Added splitAgentCardUrl for robust URL parsing related to agent card paths.
    • Reorganized and added new type guards (isStatusUpdateEvent, isArtifactUpdateEvent, isMessage, isTask, isObject) for improved type safety.
Activity
  • The pull request introduces core infrastructure for A2A communication, building on previous security foundations.
  • It details robust card normalization, optimized URL resolution, streaming result reassembly, and transport security helpers.
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 introduces significant and well-structured functionality for A2A communication. The addition of agent card normalization, robust URL parsing, and especially the security-focused pinUrlToIp function to prevent DNS rebinding are excellent improvements. The code is well-organized and the refactoring of A2AResultReassembler improves type safety. I've found one critical issue in the new pinUrlToIp function that could lead to an unhandled exception, for which I've left a specific comment.

@gemini-cli gemini-cli bot added the priority/p1 Important and should be addressed in the near term. label Mar 6, 2026
Base automatically changed from grpc-v0-branch1 to main March 9, 2026 20:03
@alisa-alisa alisa-alisa requested a review from a team as a code owner March 9, 2026 20:03
@github-actions
Copy link

github-actions bot commented Mar 9, 2026

Size Change: +1.59 kB (+0.01%)

Total Size: 26.2 MB

Filename Size Change
./bundle/gemini.js 25.7 MB +1.59 kB (+0.01%)
ℹ️ View Unchanged
Filename Size
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 221 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 227 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 11.5 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB
./bundle/sandbox-macos-strict-open.sb 4.82 kB
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB

compressed-size-action

Copy link
Collaborator

@mattKorwel mattKorwel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR looks functionally sound (all builds, automated tests, and manual executions pass), but there are a few codebase rule violations that need to be addressed before it can be merged:

1. packages/core/src/agents/a2aUtils.ts (A2AResultReassembler.update)

Issue: The PR replaces an existing switch (chunk.kind) statement with a complex if/else if chain that uses newly introduced custom type guards.
Rule Violation: Avoid complex if statements where switch statements could be used.

2. packages/core/src/agents/a2aUtils.test.ts (Test Cleanup)

Issue: The test file uses beforeEach(() => { vi.clearAllMocks(); }); and mocks node:dns/promises at the top level.
Rule Violation: Always call vi.restoreAllMocks() in afterEach to prevent test pollution.

3. packages/core/src/agents/a2aUtils.test.ts (Typing in Tests)

Issue: The PR introduces multiple instances of // eslint-disable-next-line @typescript-eslint/no-explicit-any followed by ] as any); when mocking DNS lookup results.
Rule Violation: Avoid using any in tests; prefer proper types or unknown with narrowing.

4. packages/core/src/agents/a2aUtils.ts (Strict Typing)

Issue: The code accepts unknown and uses heavy double-casting (e.g., as unknown as AgentCard, as unknown as Record<...>, as unknown as AgentInterface) to bypass the TypeScript compiler, alongside eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion.
Rule Violation: Strictly forbid any and unknown in both CLI and Core packages. unknown is only allowed if it is immediately narrowed using type guards or Zod validation. Using a Zod schema to parse the incoming card is strongly recommended.

Please address these issues to ensure we maintain our codebase standards. Thank you!

Copy link
Collaborator

@mattKorwel mattKorwel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks!

@mattKorwel mattKorwel added this pull request to the merge queue Mar 10, 2026
Merged via the queue into main with commit be67470 Mar 10, 2026
27 checks passed
@mattKorwel mattKorwel deleted the grpc-v0-branch2 branch March 10, 2026 19:39
JaisalJain pushed a commit to JaisalJain/gemini-cli that referenced this pull request Mar 11, 2026
kunal-10-cloud pushed a commit to kunal-10-cloud/gemini-cli that referenced this pull request Mar 12, 2026
liamhelmer pushed a commit to badal-io/gemini-cli that referenced this pull request Mar 12, 2026
yashodipmore pushed a commit to yashodipmore/geemi-cli that referenced this pull request Mar 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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