-
Notifications
You must be signed in to change notification settings - Fork 71
feat: add type-safe response handling #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- 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.
There was a problem hiding this 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>
andA2ASuccessResponse
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, throwingA2AClientError
for errors, aligning with modern exception-based handling. - Advanced Type Guards for Union Types: Added generic type guards like
isTask<T>()
andisMessage<T>()
usingExtract<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, andExtractByKind<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
-
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. ↩
There was a problem hiding this 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.
/** | ||
* 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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** | ||
* 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'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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') | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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'
.
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' | |
); | |
} |
@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. |
@swapydapy could you please take a look? |
I’m looking for your feedback |
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.
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
CONTRIBUTING
Guide.fix:
which represents bug fixes, and correlates to a SemVer patch.feat:
represents a new feature, and correlates to a SemVer minor.feat!:
, orfix!:
,refactor!:
, etc., which represent a breaking change (indicated by the!
) and will result in a SemVer major.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