feat: Provide a more friendly builder-based way to configure transpor…#238
Conversation
There was a problem hiding this comment.
Summary of Changes
Hello @brasseld, 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 introduces a significant enhancement to the client configuration process by implementing a new builder-based API. The primary goal is to provide a more user-friendly and fluent way to set up and customize client transports, moving away from the previous ClientFactory approach. This change simplifies client instantiation, improves modularity by centralizing transport configuration, and refactors core configuration classes for better maintainability. The update also includes necessary adjustments to module dependencies and documentation to reflect these architectural improvements.
Highlights
- New Client Builder API: Introduced a new
ClientBuilderclass that provides a more intuitive and fluent API for constructingClientinstances, simplifying the process of setting up client configurations and transports. - Removal of ClientFactory: The previous
ClientFactoryclass has been removed, streamlining the client instantiation process and consolidating configuration logic within the new builder pattern. - Simplified Transport Configuration: Refactored how transport-specific settings are applied. Instead of passing a list of
ClientTransportConfigobjects toClientConfig, transports are now configured directly on theClientBuilderusing dedicated methods likewithJsonRpcTransportandwithTransport. - ClientConfig Refactoring: The
ClientConfigclass has been updated to no longer directly manageClientTransportConfiginstances, reducing its complexity and focusing its role on general client settings. - Module and Package Restructuring: Core utility classes related to client configuration and interceptors, such as
A2ACardResolver,ClientCallContext,ClientCallInterceptor, andPayloadAndHeaders, have been relocated to more appropriate modules and packages (http-clientandclient/transport/spi/interceptors) to improve modularity and organization. - Standardized Transport SPI: New abstract classes
ClientTransportConfigandClientTransportConfigBuilderhave been added to the Service Provider Interface (SPI) module, providing a standardized and extensible framework for defining and building transport-specific configurations. - Dependency Updates: Updated
pom.xmlfiles across various modules to reflect the new dependency structure, including the removal of the dedicatedclient-configmodule and adjustments for the new builder-based approach. - Documentation and Example Updates: The
README.mdand example client code have been updated to demonstrate the usage of the newClientBuilderAPI, providing clear guidance for developers adopting the new configuration approach.
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.
Code Review
This pull request introduces a significant and positive change by refactoring the client creation mechanism to a more intuitive and fluent builder-based API. The removal of ClientFactory in favor of ClientBuilder simplifies transport configuration and improves the overall developer experience. The changes are well-structured, including updates to documentation and tests to reflect the new API. I've identified a few areas for improvement, mainly concerning null-safety, deterministic behavior, and clarity in the documentation examples. Addressing these points will make the new API even more robust and user-friendly.
...nt/transport/spi/src/main/java/io/a2a/client/transport/spi/ClientTransportConfigBuilder.java
Show resolved
Hide resolved
db67c38 to
5e01ede
Compare
...nt/transport/spi/src/main/java/io/a2a/client/transport/spi/ClientTransportConfigBuilder.java
Outdated
Show resolved
Hide resolved
client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransportProvider.java
Outdated
Show resolved
Hide resolved
.../transport/jsonrpc/src/main/java/io/a2a/client/transport/jsonrpc/JSONRPCTransportConfig.java
Show resolved
Hide resolved
tests/server-common/src/test/java/io/a2a/server/apps/common/AbstractA2AServerTest.java
Outdated
Show resolved
Hide resolved
5e01ede to
623ba51
Compare
|
@fjuma thanks for your comments. Most (all !) the points you have raised should have been fixed now. |
client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransportConfig.java
Show resolved
Hide resolved
...nt/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransportConfigBuilder.java
Show resolved
Hide resolved
client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransportProvider.java
Outdated
Show resolved
Hide resolved
...nt/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransportConfigBuilder.java
Show resolved
Hide resolved
623ba51 to
7af5e84
Compare
|
I have pushed a new version to fix your previous comments, and also provided an implementation for this #238 (comment) |
7af5e84 to
ac72101
Compare
README.md
Outdated
| .builder(agentCard) | ||
| .clientConfig(clientConfig) | ||
| .withTransport(JSONRPCTransport.class, new JSONRPCTransportConfig()) | ||
| .addStreamConsumers(consumers) |
README.md
Outdated
| Client client = Client | ||
| .builder(agentCard) | ||
| .clientConfig(clientConfig) | ||
| .withTransport(GrpcTransport.class, new GrpcTransportConfigBuilder(channelFactory)) |
There was a problem hiding this comment.
new GrpcTransportConfig(channelFactory)
|
Thanks very much for all the updates, @brasseld! I've just added a couple final comments for the README. |
ac72101 to
d811eac
Compare
|
Last updates puhsed @fjuma |
|
I understand there is a 'global' ClientConfig to be shared across transports, but I'm wondering what would be the case if we want a different configuration per transport. It feels a bit strange to define a configuration for the client to then define one per transport. |
|
@ehsavoie @fjuma Just throwing this out there without much thought. But I think perhaps if what you say becomes an issue, then an option in the future could be:
Then when constructing the client for each transport, we merge in the overrides with the global ClientConfig for each transport |
|
@kabir @fjuma @ehsavoie I quickly looked at how it's done for the MCP SDK, and it's somehow similar approach: https://modelcontextprotocol.io/sdk/java/mcp-client#sse-httpclient |
|
@brasseld It was more a theorical question, and we can rethink about it if this question is raised in the future. |
client/base/src/main/java/io/a2a/client/config/ClientConfig.java
Outdated
Show resolved
Hide resolved
d811eac to
21939d0
Compare
|
Thanks @brasseld! |
a2aproject#238) …t configuration This PR is a proposal to make the transport configuration specific to a given transport implementation. This one will ease developer experience by providing a builder for configuring a Client in a more stricter way compare to what exists today. Also, this will help at getting rid of strong coupling with different transport implementations. Two benefits: Get rid of dependencies which may not be required (grpc dependencies if you only go for jsonrpc) Easier to provide new transport implementation (such as HTTP+JSON). # Description Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Follow the [`CONTRIBUTING` Guide](../CONTRIBUTING.md). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - Important Prefixes for [release-please](https://github.com/googleapis/release-please): - `fix:` which represents bug fixes, and correlates to a [SemVer](https://semver.org/) 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. - [x] Ensure the tests pass - [x] Appropriate READMEs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕
…t configuration
This PR is a proposal to make the transport configuration specific to a given transport implementation.
This one will ease developer experience by providing a builder for configuring a Client in a more stricter way compare to what exists today.
Also, this will help at getting rid of strong coupling with different transport implementations.
Two benefits:
Get rid of dependencies which may not be required (grpc dependencies if you only go for jsonrpc)
Easier to provide new transport implementation (such as HTTP+JSON).
Description
Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
CONTRIBUTINGGuide.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> 🦕