Skip to content

Conversation

kiwamizamurai
Copy link

@kiwamizamurai kiwamizamurai commented Sep 4, 2025

Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Follow the CONTRIBUTING Guide.
  • Make your Pull Request title in the https://www.conventionalcommits.org/ specification.
    • Important Prefixes for release-please:
      • fix: which represents bug fixes, and correlates to a SemVer patch.
      • feat: represents a new feature, and correlates to a SemVer minor.
      • feat!:, or fix!:, refactor!:, etc., which represent a breaking change (indicated by the !) and will result in a SemVer major.
  • Ensure the tests and linter pass
  • Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> 🦕

Summary

This PR enhances the A2A-JS SDK with modern TypeScript features for improved type safety and developer experience

Benefits

  • Type Safety: Leverages TypeScript's conditional types and template literals for compile-time safety
  • Developer Experience: Eliminates boilerplate error checking and type assertions

- Introduced type guards for distinguishing between 'task' and 'message' types.
- Added utility types for extracting specific result types based on their 'kind'.
- Implemented a type-safe result processor that infers correct handler types based on result kind.
- Enhanced compile-time validation for result IDs using template literal types.
- Introduced type utilities for filtering and extracting successful JSON-RPC responses.
- Implemented a custom error class for handling A2A client RPC errors.
- Added type-safe functions for parsing and handling JSON-RPC responses, including support for streaming responses.
- Enhanced type guards to distinguish between success and error responses, ensuring type safety across client methods.
- Added exports for response utilities and type guards to enhance client functionality.
- Improved modularity by including new utility files for better code organization.
- Updated A2AClient methods to return specific success response types, improving type safety and clarity.
- Introduced `parseSuccessResponse` utility for consistent error handling across methods.
- Adjusted method signatures for `sendMessage`, `setTaskPushNotificationConfig`, `getTaskPushNotificationConfig`, `listTaskPushNotificationConfig`, `deleteTaskPushNotificationConfig`, `getTask`, and `cancelTask` to reflect new response types.
- Enhanced error handling to throw `A2AClientError` for error responses, ensuring robust client behavior.
…Client

- Updated client authentication tests to throw A2AClientError for error responses, improving error handling consistency.
- Added new response utility tests to validate type safety and error handling for JSON-RPC responses.
- Implemented type guards and utility functions for parsing success and error responses, enhancing developer experience and type safety.
- Introduced a new property `protocolVersion` set to '1.0' in the movie agent card configuration, enhancing the agent's metadata for better versioning and compatibility.
…cessing

- Refactored message sending logic to utilize try-catch for error handling, ensuring robust responses from the A2AClient.
- Introduced type guards for automatic type inference in response handling, enhancing clarity and reducing manual error checks.
- Updated the client example to demonstrate improved response processing for both tasks and messages, leveraging new utility functions for better type safety.
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.

Summary of Changes

Hello @kiwamizamurai, 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 enhances the A2A-JS SDK by integrating advanced TypeScript features to improve type safety and developer experience. The core change shifts the client's response handling from returning union types (success | error) to throwing exceptions for errors, providing a more modern and predictable API. This change simplifies client-side code by removing boilerplate error checks and leveraging compile-time type inference for various response patterns.

Highlights

  • Type-Level Error Response Filtering: Introduced FilterSuccessResponse<T> and A2ASuccessResponse to exclude error responses at compile time, eliminating the need for manual 'error' in response checks.
  • Unified Error Handling: Implemented A2AClientError custom class for structured RPC error information. All client methods now return success types only, throwing A2AClientError for errors, aligning with modern exception-based handling.
  • Advanced Type Guards for Union Types: Added generic type guards like isTask<T>() and isMessage<T>() using Extract<T, { kind: 'task' }> for automatic TypeScript type inference, reducing manual property checking.
  • Pattern-Based Result Processing: Introduced withResultType() for conditional type-based pattern matching on union results, and ExtractByKind<TUnion, TKind> for precise type extraction.
  • Enhanced Streaming Type Safety: Updated SSE stream processing to utilize the new type-safe response parsing, ensuring consistent error handling across all response types, with streaming errors now throwing A2AClientError.
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 in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

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 issue 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.

@kiwamizamurai kiwamizamurai changed the title feat: add advanced type-safe response handling feat: add type-safe response handling Sep 4, 2025
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 a significant and well-executed enhancement to the A2A-JS SDK by adding advanced type-safe response handling. The shift to throwing exceptions for error responses, coupled with the new type utilities and guards like A2AClientError, parseSuccessResponse, and withResultType, greatly improves the developer experience and code clarity. The changes are consistently applied across the client, including streaming methods, and are well-documented in the README. I've included a few suggestions to remove some unused code from the newly added utility files to further improve maintainability.

Comment on lines +69 to +77
/**
* Handles JSON-RPC response by either returning the success response or throwing an error.
* This provides a uniform way to handle responses across all client methods.
*/
export function handleRpcResponse<T extends JSONRPCResponse>(
response: T
): FilterSuccessResponse<T> {
return parseSuccessResponse(response);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The function handleRpcResponse is an exact wrapper around parseSuccessResponse and is currently unused. To simplify the API and prevent confusion, it's recommended to remove it.

Comment on lines +13 to +21
/**
* Template literal types for A2A result pattern matching.
* Provides compile-time pattern validation for result IDs.
*/
export type A2AResultPattern<T extends string> =
T extends `task-${infer _Rest}` ? 'task'
: T extends `msg-${infer _Rest}` ? 'message'
: T extends `user-msg-${infer _Rest}` ? 'user-message'
: 'unknown';
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The A2AResultPattern type is not used anywhere in the project. To keep the codebase clean and avoid dead code, it's best to remove it.

Comment on lines +36 to +43
export function isMessage<T>(result: T): result is Extract<T, { kind: 'message' | 'user-message' }> {
return (
typeof result === 'object' &&
result !== null &&
'kind' in result &&
(result.kind === 'message' || result.kind === 'user-message')
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The kind 'user-message' is checked here, but it's not defined in src/types.ts and appears to be unused throughout the project. This also affects ExtractMessage on line 11 and the message handler in withResultType on line 53. To remove dead code and improve clarity, please remove all logic related to 'user-message'.

Suggested change
export function isMessage<T>(result: T): result is Extract<T, { kind: 'message' | 'user-message' }> {
return (
typeof result === 'object' &&
result !== null &&
'kind' in result &&
(result.kind === 'message' || result.kind === 'user-message')
);
}
export function isMessage<T>(result: T): result is Extract<T, { kind: 'message' }> {
return (
typeof result === 'object' &&
result !== null &&
'kind' in result &&
result.kind === 'message'
);
}

@kiwamizamurai
Copy link
Author

@swapydapy thank you for your product

I’ve been exploring A2A and using this OSS, and I created a PR with some improvements based on usability from my perspective. I’d appreciate it if you could take a look.

I’m also just getting started with TypeScript, so I’d be grateful for any comments if my implementation looks off.

@kiwamizamurai
Copy link
Author

@swapydapy could you please take a look?

@kiwamizamurai
Copy link
Author

I’m looking for your feedback
Thank you in advance

@kiwamizamurai
Copy link
Author

did i make some mistake? 🤔

…error throwing

- Updated the callExtensionMethod to return a parsed success response, improving type safety.
- Introduced A2AClientError throwing for error responses, ensuring consistent error handling.
- Removed unnecessary type checks in tests, simplifying the error handling logic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant