Skip to content

Commit 5beb29c

Browse files
committed
feat: Update the ClientTransport interface, introducing ClientCallContext, ClientConfig, and ClientCallInterceptor similar to the Python SDK. Introduce a ClientTransportProvider and update the JSONRPC and gRPC transport implementations. Introduce a new Client and ClientFactory implementations.
1 parent 8199a4c commit 5beb29c

File tree

51 files changed

+2684
-2006
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2684
-2006
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.a2a.client.config;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* A context passed with each client call, allowing for call-specific.
7+
* configuration and data passing. Such as authentication details or
8+
* request deadlines.
9+
*/
10+
public class ClientCallContext {
11+
12+
private final Map<String, Object> state;
13+
private final Map<String, String> headers;
14+
15+
public ClientCallContext(Map<String, Object> state, Map<String, String> headers) {
16+
this.state = state;
17+
this.headers = headers;
18+
}
19+
20+
public Map<String, Object> getState() {
21+
return state;
22+
}
23+
24+
public Map<String, String> getHeaders() {
25+
return headers;
26+
}
27+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.a2a.client.config;
2+
3+
import java.util.Map;
4+
5+
import io.a2a.spec.AgentCard;
6+
7+
/**
8+
* An abstract base class for client-side call interceptors.
9+
* Interceptors can inspect and modify requests before they are sent,
10+
* which is ideal for concerns like authentication, logging, or tracing.
11+
*/
12+
public abstract class ClientCallInterceptor {
13+
14+
/**
15+
* Intercept a client call before the request is sent.
16+
*
17+
* @param methodName the name of the protocol method (e.g., 'message/send')
18+
* @param payload the request payload
19+
* @param headers the headers to use
20+
* @param agentCard the agent card (may be {@code null})
21+
* @param clientCallContext the {@code ClientCallContext} for this call (may be {@code null})
22+
* @return the potentially modified payload and headers
23+
*/
24+
public abstract PayloadAndHeaders intercept(String methodName, Object payload, Map<String, String> headers,
25+
AgentCard agentCard, ClientCallContext clientCallContext);
26+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package io.a2a.client.config;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import io.a2a.client.http.A2AHttpClient;
7+
import io.a2a.spec.PushNotificationConfig;
8+
import io.grpc.Channel;
9+
10+
/**
11+
* Configuration for the A2A client factory.
12+
*/
13+
public class ClientConfig {
14+
15+
private final Boolean streaming;
16+
private final Boolean polling;
17+
private final A2AHttpClient httpClient;
18+
private final Channel channel;
19+
private final List<String> supportedTransports;
20+
private final Boolean useClientPreference;
21+
private final List<String> acceptedOutputModes;
22+
private final PushNotificationConfig pushNotificationConfig;
23+
private final Integer historyLength;
24+
private final Map<String, Object> metadata;
25+
26+
public ClientConfig(Boolean streaming, Boolean polling, A2AHttpClient httpClient, Channel channel,
27+
List<String> supportedTransports, Boolean useClientPreference,
28+
List<String> acceptedOutputModes, PushNotificationConfig pushNotificationConfig,
29+
Integer historyLength, Map<String, Object> metadata) {
30+
this.streaming = streaming == null ? true : streaming;
31+
this.polling = polling == null ? false : polling;
32+
this.httpClient = httpClient;
33+
this.channel = channel;
34+
this.supportedTransports = supportedTransports;
35+
this.useClientPreference = useClientPreference == null ? false : useClientPreference;
36+
this.acceptedOutputModes = acceptedOutputModes;
37+
this.pushNotificationConfig = pushNotificationConfig;
38+
this.historyLength = historyLength;
39+
this.metadata = metadata;
40+
}
41+
42+
public boolean isStreaming() {
43+
return streaming;
44+
}
45+
46+
public boolean isPolling() {
47+
return polling;
48+
}
49+
50+
public A2AHttpClient getHttpClient() {
51+
return httpClient;
52+
}
53+
54+
public Channel getChannel() {
55+
return channel;
56+
}
57+
58+
public List<String> getSupportedTransports() {
59+
return supportedTransports;
60+
}
61+
62+
public boolean isUseClientPreference() {
63+
return useClientPreference;
64+
}
65+
66+
public List<String> getAcceptedOutputModes() {
67+
return acceptedOutputModes;
68+
}
69+
70+
public PushNotificationConfig getPushNotificationConfig() {
71+
return pushNotificationConfig;
72+
}
73+
74+
public Integer getHistoryLength() {
75+
return historyLength;
76+
}
77+
78+
public Map<String, Object> getMetadata() {
79+
return metadata;
80+
}
81+
82+
public static class Builder {
83+
private Boolean streaming;
84+
private Boolean polling;
85+
private A2AHttpClient httpClient;
86+
private Channel channel;
87+
private List<String> supportedTransports;
88+
private Boolean useClientPreference;
89+
private List<String> acceptedOutputModes;
90+
private PushNotificationConfig pushNotificationConfig;
91+
private Integer historyLength;
92+
private Map<String, Object> metadata;
93+
94+
public Builder setStreaming(Boolean streaming) {
95+
this.streaming = streaming;
96+
return this;
97+
}
98+
99+
public Builder setPolling(Boolean polling) {
100+
this.polling = polling;
101+
return this;
102+
}
103+
104+
public Builder setHttpClient(A2AHttpClient httpClient) {
105+
this.httpClient = httpClient;
106+
return this;
107+
}
108+
109+
public Builder setChannel(Channel channel) {
110+
this.channel = channel;
111+
return this;
112+
}
113+
114+
public Builder setSupportedTransports(List<String> supportedTransports) {
115+
this.supportedTransports = supportedTransports;
116+
return this;
117+
}
118+
119+
public Builder setUseClientPreference(Boolean useClientPreference) {
120+
this.useClientPreference = useClientPreference;
121+
return this;
122+
}
123+
124+
public Builder setAcceptedOutputModes(List<String> acceptedOutputModes) {
125+
this.acceptedOutputModes = acceptedOutputModes;
126+
return this;
127+
}
128+
129+
public Builder setPushNotificationConfig(PushNotificationConfig pushNotificationConfig) {
130+
this.pushNotificationConfig = pushNotificationConfig;
131+
return this;
132+
}
133+
134+
public Builder setHistoryLength(Integer historyLength) {
135+
this.historyLength = historyLength;
136+
return this;
137+
}
138+
139+
public Builder setMetadata(Map<String, Object> metadata) {
140+
this.metadata = metadata;
141+
return this;
142+
}
143+
144+
public ClientConfig build() {
145+
return new ClientConfig(streaming, polling, httpClient, channel,
146+
supportedTransports, useClientPreference, acceptedOutputModes,
147+
pushNotificationConfig, historyLength, metadata);
148+
}
149+
}
150+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.a2a.client.config;
2+
3+
import java.util.Map;
4+
5+
public class PayloadAndHeaders {
6+
7+
private final Object payload;
8+
private final Map<String, String> headers;
9+
10+
public PayloadAndHeaders(Object payload, Map<String, String> headers) {
11+
this.payload = payload;
12+
this.headers = headers;
13+
}
14+
15+
public Object getPayload() {
16+
return payload;
17+
}
18+
19+
public Map<String, String> getHeaders() {
20+
return headers;
21+
}
22+
}

client-transport/grpc/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
<description>Java SDK for the Agent2Agent Protocol (A2A) - gRPC Client Transport</description>
1818

1919
<dependencies>
20+
<dependency>
21+
<groupId>${project.groupId}</groupId>
22+
<artifactId>a2a-java-sdk-client-config</artifactId>
23+
<version>${project.version}</version>
24+
</dependency>
2025
<dependency>
2126
<groupId>${project.groupId}</groupId>
2227
<artifactId>a2a-java-sdk-common</artifactId>

client-transport/grpc/src/main/java/io/a2a/client/transport/grpc/EventStreamObserver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ public void onNext(StreamResponse response) {
4747

4848
@Override
4949
public void onError(Throwable t) {
50-
errorHandler.accept(t);
50+
if (errorHandler != null) {
51+
errorHandler.accept(t);
52+
}
5153
}
5254

5355
@Override

0 commit comments

Comments
 (0)