@mailmodo/a2a 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -93
- package/dist/{a2a_request_handler-DQfg1Q-R.d.ts → a2a_request_handler-1Isk3l-0.d.mts} +16 -4
- package/dist/{a2a_request_handler-DPkhsCMt.d.mts → a2a_request_handler-BuP9LgXH.d.ts} +16 -4
- package/dist/chunk-7JFJW6P6.mjs +38 -0
- package/dist/{chunk-LVD4GF26.mjs → chunk-AZGEDUZX.mjs} +6 -7
- package/dist/chunk-BNBEZNW7.mjs +122 -0
- package/dist/client/index.d.mts +401 -47
- package/dist/client/index.d.ts +401 -47
- package/dist/client/index.js +525 -78
- package/dist/client/index.mjs +1110 -29
- package/dist/{types-Due_Cv6t.d.mts → extensions-DvruCIzw.d.mts} +40 -1
- package/dist/{types-Due_Cv6t.d.ts → extensions-DvruCIzw.d.ts} +40 -1
- package/dist/index.d.mts +5 -33
- package/dist/index.d.ts +5 -33
- package/dist/index.js +27 -2083
- package/dist/index.mjs +6 -42
- package/dist/server/express/index.d.mts +76 -4
- package/dist/server/express/index.d.ts +76 -4
- package/dist/server/express/index.js +563 -37
- package/dist/server/express/index.mjs +642 -6
- package/dist/server/index.d.mts +296 -6
- package/dist/server/index.d.ts +296 -6
- package/dist/server/index.js +265 -52
- package/dist/server/index.mjs +1050 -12
- package/package.json +39 -17
- package/dist/auth-handler-DVLcl8yj.d.mts +0 -209
- package/dist/auth-handler-Gzpf3xHC.d.ts +0 -209
- package/dist/chunk-HZFUOBJQ.mjs +0 -198
- package/dist/chunk-LIEYEFQG.mjs +0 -879
- package/dist/chunk-UBRSFN2J.mjs +0 -776
- package/dist/error-DExKs0Q3.d.mts +0 -233
- package/dist/error-j1vYKII2.d.ts +0 -233
package/dist/client/index.mjs
CHANGED
|
@@ -1,13 +1,700 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
A2A_ERROR_CODE,
|
|
3
|
+
AuthenticatedExtendedCardNotConfiguredError,
|
|
4
|
+
ContentTypeNotSupportedError,
|
|
5
|
+
InvalidAgentResponseError,
|
|
5
6
|
PushNotificationNotSupportedError,
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
TaskNotCancelableError,
|
|
8
|
+
TaskNotFoundError,
|
|
9
|
+
UnsupportedOperationError,
|
|
10
|
+
parseSseStream
|
|
11
|
+
} from "../chunk-BNBEZNW7.mjs";
|
|
8
12
|
import {
|
|
9
|
-
AGENT_CARD_PATH
|
|
13
|
+
AGENT_CARD_PATH,
|
|
14
|
+
HTTP_EXTENSION_HEADER
|
|
10
15
|
} from "../chunk-PHP7LM4Y.mjs";
|
|
16
|
+
import {
|
|
17
|
+
Extensions
|
|
18
|
+
} from "../chunk-7JFJW6P6.mjs";
|
|
19
|
+
|
|
20
|
+
// src/client/transports/json_rpc_transport.ts
|
|
21
|
+
var JsonRpcTransport = class _JsonRpcTransport {
|
|
22
|
+
customFetchImpl;
|
|
23
|
+
endpoint;
|
|
24
|
+
requestIdCounter = 1;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.endpoint = options.endpoint;
|
|
27
|
+
this.customFetchImpl = options.fetchImpl;
|
|
28
|
+
}
|
|
29
|
+
async getExtendedAgentCard(options, idOverride) {
|
|
30
|
+
const rpcResponse = await this._sendRpcRequest("agent/getAuthenticatedExtendedCard", void 0, idOverride, options);
|
|
31
|
+
return rpcResponse.result;
|
|
32
|
+
}
|
|
33
|
+
async sendMessage(params, options, idOverride) {
|
|
34
|
+
const rpcResponse = await this._sendRpcRequest(
|
|
35
|
+
"message/send",
|
|
36
|
+
params,
|
|
37
|
+
idOverride,
|
|
38
|
+
options
|
|
39
|
+
);
|
|
40
|
+
return rpcResponse.result;
|
|
41
|
+
}
|
|
42
|
+
async *sendMessageStream(params, options) {
|
|
43
|
+
yield* this._sendStreamingRequest("message/stream", params, options);
|
|
44
|
+
}
|
|
45
|
+
async setTaskPushNotificationConfig(params, options, idOverride) {
|
|
46
|
+
const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/set", params, idOverride, options);
|
|
47
|
+
return rpcResponse.result;
|
|
48
|
+
}
|
|
49
|
+
async getTaskPushNotificationConfig(params, options, idOverride) {
|
|
50
|
+
const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/get", params, idOverride, options);
|
|
51
|
+
return rpcResponse.result;
|
|
52
|
+
}
|
|
53
|
+
async listTaskPushNotificationConfig(params, options, idOverride) {
|
|
54
|
+
const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/list", params, idOverride, options);
|
|
55
|
+
return rpcResponse.result;
|
|
56
|
+
}
|
|
57
|
+
async deleteTaskPushNotificationConfig(params, options, idOverride) {
|
|
58
|
+
await this._sendRpcRequest("tasks/pushNotificationConfig/delete", params, idOverride, options);
|
|
59
|
+
}
|
|
60
|
+
async getTask(params, options, idOverride) {
|
|
61
|
+
const rpcResponse = await this._sendRpcRequest(
|
|
62
|
+
"tasks/get",
|
|
63
|
+
params,
|
|
64
|
+
idOverride,
|
|
65
|
+
options
|
|
66
|
+
);
|
|
67
|
+
return rpcResponse.result;
|
|
68
|
+
}
|
|
69
|
+
async cancelTask(params, options, idOverride) {
|
|
70
|
+
const rpcResponse = await this._sendRpcRequest(
|
|
71
|
+
"tasks/cancel",
|
|
72
|
+
params,
|
|
73
|
+
idOverride,
|
|
74
|
+
options
|
|
75
|
+
);
|
|
76
|
+
return rpcResponse.result;
|
|
77
|
+
}
|
|
78
|
+
async *resubscribeTask(params, options) {
|
|
79
|
+
yield* this._sendStreamingRequest("tasks/resubscribe", params, options);
|
|
80
|
+
}
|
|
81
|
+
async callExtensionMethod(method, params, idOverride, options) {
|
|
82
|
+
return await this._sendRpcRequest(
|
|
83
|
+
method,
|
|
84
|
+
params,
|
|
85
|
+
idOverride,
|
|
86
|
+
options
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
_fetch(...args) {
|
|
90
|
+
if (this.customFetchImpl) {
|
|
91
|
+
return this.customFetchImpl(...args);
|
|
92
|
+
}
|
|
93
|
+
if (typeof fetch === "function") {
|
|
94
|
+
return fetch(...args);
|
|
95
|
+
}
|
|
96
|
+
throw new Error(
|
|
97
|
+
"A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2ATransportOptions. "
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
async _sendRpcRequest(method, params, idOverride, options) {
|
|
101
|
+
const requestId = idOverride ?? this.requestIdCounter++;
|
|
102
|
+
const rpcRequest = {
|
|
103
|
+
jsonrpc: "2.0",
|
|
104
|
+
method,
|
|
105
|
+
params,
|
|
106
|
+
id: requestId
|
|
107
|
+
};
|
|
108
|
+
const httpResponse = await this._fetchRpc(rpcRequest, "application/json", options);
|
|
109
|
+
if (!httpResponse.ok) {
|
|
110
|
+
let errorBodyText = "(empty or non-JSON response)";
|
|
111
|
+
let errorJson;
|
|
112
|
+
try {
|
|
113
|
+
errorBodyText = await httpResponse.text();
|
|
114
|
+
errorJson = JSON.parse(errorBodyText);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`,
|
|
118
|
+
{ cause: e }
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
if (errorJson.jsonrpc && errorJson.error) {
|
|
122
|
+
throw _JsonRpcTransport.mapToError(errorJson);
|
|
123
|
+
} else {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const rpcResponse = await httpResponse.json();
|
|
130
|
+
if (rpcResponse.id !== requestId) {
|
|
131
|
+
console.error(
|
|
132
|
+
`CRITICAL: RPC response ID mismatch for method ${method}. Expected ${requestId}, got ${rpcResponse.id}.`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
if ("error" in rpcResponse) {
|
|
136
|
+
throw _JsonRpcTransport.mapToError(rpcResponse);
|
|
137
|
+
}
|
|
138
|
+
return rpcResponse;
|
|
139
|
+
}
|
|
140
|
+
async _fetchRpc(rpcRequest, acceptHeader = "application/json", options) {
|
|
141
|
+
const requestInit = {
|
|
142
|
+
method: "POST",
|
|
143
|
+
headers: {
|
|
144
|
+
...options?.serviceParameters,
|
|
145
|
+
"Content-Type": "application/json",
|
|
146
|
+
Accept: acceptHeader
|
|
147
|
+
},
|
|
148
|
+
body: JSON.stringify(rpcRequest),
|
|
149
|
+
signal: options?.signal
|
|
150
|
+
};
|
|
151
|
+
return this._fetch(this.endpoint, requestInit);
|
|
152
|
+
}
|
|
153
|
+
async *_sendStreamingRequest(method, params, options) {
|
|
154
|
+
const clientRequestId = this.requestIdCounter++;
|
|
155
|
+
const rpcRequest = {
|
|
156
|
+
jsonrpc: "2.0",
|
|
157
|
+
method,
|
|
158
|
+
params,
|
|
159
|
+
id: clientRequestId
|
|
160
|
+
};
|
|
161
|
+
const response = await this._fetchRpc(rpcRequest, "text/event-stream", options);
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
let errorBody = "";
|
|
164
|
+
let errorJson;
|
|
165
|
+
try {
|
|
166
|
+
errorBody = await response.text();
|
|
167
|
+
errorJson = JSON.parse(errorBody);
|
|
168
|
+
} catch (e) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`,
|
|
171
|
+
{ cause: e }
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
if (errorJson.error) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
throw new Error(
|
|
180
|
+
`HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
if (!response.headers.get("Content-Type")?.startsWith("text/event-stream")) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
`Invalid response Content-Type for SSE stream for ${method}. Expected 'text/event-stream'.`
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
for await (const event of parseSseStream(response)) {
|
|
189
|
+
yield this._processSseEventData(event.data, clientRequestId);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
_processSseEventData(jsonData, originalRequestId) {
|
|
193
|
+
if (!jsonData.trim()) {
|
|
194
|
+
throw new Error("Attempted to process empty SSE event data.");
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
const sseJsonRpcResponse = JSON.parse(jsonData);
|
|
198
|
+
const a2aStreamResponse = sseJsonRpcResponse;
|
|
199
|
+
if (a2aStreamResponse.id !== originalRequestId) {
|
|
200
|
+
console.warn(
|
|
201
|
+
`SSE Event's JSON-RPC response ID mismatch. Client request ID: ${originalRequestId}, event response ID: ${a2aStreamResponse.id}.`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
if ("error" in a2aStreamResponse) {
|
|
205
|
+
const err = a2aStreamResponse.error;
|
|
206
|
+
throw new Error(
|
|
207
|
+
`SSE event contained an error: ${err.message} (Code: ${err.code}) Data: ${JSON.stringify(err.data || {})}`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
if (!("result" in a2aStreamResponse) || typeof a2aStreamResponse.result === "undefined") {
|
|
211
|
+
throw new Error(`SSE event JSON-RPC response is missing 'result' field. Data: ${jsonData}`);
|
|
212
|
+
}
|
|
213
|
+
return a2aStreamResponse.result;
|
|
214
|
+
} catch (e) {
|
|
215
|
+
if (e instanceof Error && (e.message.startsWith("SSE event contained an error") || e.message.startsWith("SSE event JSON-RPC response is missing 'result' field"))) {
|
|
216
|
+
throw e;
|
|
217
|
+
}
|
|
218
|
+
console.error(
|
|
219
|
+
"Failed to parse SSE event data string or unexpected JSON-RPC structure:",
|
|
220
|
+
jsonData,
|
|
221
|
+
e
|
|
222
|
+
);
|
|
223
|
+
throw new Error(
|
|
224
|
+
`Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e instanceof Error && e.message || "Unknown error"}`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
static mapToError(response) {
|
|
229
|
+
switch (response.error.code) {
|
|
230
|
+
case -32001:
|
|
231
|
+
return new TaskNotFoundJSONRPCError(response);
|
|
232
|
+
case -32002:
|
|
233
|
+
return new TaskNotCancelableJSONRPCError(response);
|
|
234
|
+
case -32003:
|
|
235
|
+
return new PushNotificationNotSupportedJSONRPCError(response);
|
|
236
|
+
case -32004:
|
|
237
|
+
return new UnsupportedOperationJSONRPCError(response);
|
|
238
|
+
case -32005:
|
|
239
|
+
return new ContentTypeNotSupportedJSONRPCError(response);
|
|
240
|
+
case -32006:
|
|
241
|
+
return new InvalidAgentResponseJSONRPCError(response);
|
|
242
|
+
case -32007:
|
|
243
|
+
return new AuthenticatedExtendedCardNotConfiguredJSONRPCError(response);
|
|
244
|
+
default:
|
|
245
|
+
return new JSONRPCTransportError(response);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
var JsonRpcTransportFactory = class _JsonRpcTransportFactory {
|
|
250
|
+
constructor(options) {
|
|
251
|
+
this.options = options;
|
|
252
|
+
}
|
|
253
|
+
static name = "JSONRPC";
|
|
254
|
+
get protocolName() {
|
|
255
|
+
return _JsonRpcTransportFactory.name;
|
|
256
|
+
}
|
|
257
|
+
async create(url, _agentCard) {
|
|
258
|
+
return new JsonRpcTransport({
|
|
259
|
+
endpoint: url,
|
|
260
|
+
fetchImpl: this.options?.fetchImpl
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
var JSONRPCTransportError = class extends Error {
|
|
265
|
+
constructor(errorResponse) {
|
|
266
|
+
super(
|
|
267
|
+
`JSON-RPC error: ${errorResponse.error.message} (Code: ${errorResponse.error.code}) Data: ${JSON.stringify(errorResponse.error.data || {})}`
|
|
268
|
+
);
|
|
269
|
+
this.errorResponse = errorResponse;
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
var TaskNotFoundJSONRPCError = class extends TaskNotFoundError {
|
|
273
|
+
constructor(errorResponse) {
|
|
274
|
+
super();
|
|
275
|
+
this.errorResponse = errorResponse;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var TaskNotCancelableJSONRPCError = class extends TaskNotCancelableError {
|
|
279
|
+
constructor(errorResponse) {
|
|
280
|
+
super();
|
|
281
|
+
this.errorResponse = errorResponse;
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
var PushNotificationNotSupportedJSONRPCError = class extends PushNotificationNotSupportedError {
|
|
285
|
+
constructor(errorResponse) {
|
|
286
|
+
super();
|
|
287
|
+
this.errorResponse = errorResponse;
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
var UnsupportedOperationJSONRPCError = class extends UnsupportedOperationError {
|
|
291
|
+
constructor(errorResponse) {
|
|
292
|
+
super();
|
|
293
|
+
this.errorResponse = errorResponse;
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
var ContentTypeNotSupportedJSONRPCError = class extends ContentTypeNotSupportedError {
|
|
297
|
+
constructor(errorResponse) {
|
|
298
|
+
super();
|
|
299
|
+
this.errorResponse = errorResponse;
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
var InvalidAgentResponseJSONRPCError = class extends InvalidAgentResponseError {
|
|
303
|
+
constructor(errorResponse) {
|
|
304
|
+
super();
|
|
305
|
+
this.errorResponse = errorResponse;
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
var AuthenticatedExtendedCardNotConfiguredJSONRPCError = class extends AuthenticatedExtendedCardNotConfiguredError {
|
|
309
|
+
constructor(errorResponse) {
|
|
310
|
+
super();
|
|
311
|
+
this.errorResponse = errorResponse;
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// src/client/client.ts
|
|
316
|
+
var A2AClient = class _A2AClient {
|
|
317
|
+
static emptyOptions = void 0;
|
|
318
|
+
agentCardPromise;
|
|
319
|
+
customFetchImpl;
|
|
320
|
+
serviceEndpointUrl;
|
|
321
|
+
// To be populated from AgentCard after fetchin
|
|
322
|
+
// A2AClient is built around JSON-RPC types, so it will only support JSON-RPC transport, new client with transport agnostic interface is going to be created for multi-transport.
|
|
323
|
+
// New transport abstraction isn't going to expose individual transport specific fields, so to keep returning JSON-RPC IDs here for compatibility,
|
|
324
|
+
// keep counter here and pass it to JsonRpcTransport via an optional idOverride parameter (which is not visible via transport-agnostic A2ATransport interface).
|
|
325
|
+
transport;
|
|
326
|
+
requestIdCounter = 1;
|
|
327
|
+
/**
|
|
328
|
+
* Constructs an A2AClient instance from an AgentCard.
|
|
329
|
+
* @param agentCard The AgentCard object.
|
|
330
|
+
* @param options Optional. The options for the A2AClient including the fetch/auth implementation.
|
|
331
|
+
*/
|
|
332
|
+
constructor(agentCard, options) {
|
|
333
|
+
this.customFetchImpl = options?.fetchImpl;
|
|
334
|
+
if (typeof agentCard === "string") {
|
|
335
|
+
console.warn(
|
|
336
|
+
"Warning: Constructing A2AClient with a URL is deprecated. Please use A2AClient.fromCardUrl() instead."
|
|
337
|
+
);
|
|
338
|
+
this.agentCardPromise = this._fetchAndCacheAgentCard(agentCard, options?.agentCardPath);
|
|
339
|
+
} else {
|
|
340
|
+
if (!agentCard.url) {
|
|
341
|
+
throw new Error(
|
|
342
|
+
"Provided Agent Card does not contain a valid 'url' for the service endpoint."
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
this.serviceEndpointUrl = agentCard.url;
|
|
346
|
+
this.agentCardPromise = Promise.resolve(agentCard);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Dynamically resolves the fetch implementation to use for requests.
|
|
351
|
+
* Prefers a custom implementation if provided, otherwise falls back to the global fetch.
|
|
352
|
+
* @returns The fetch implementation.
|
|
353
|
+
* @param args Arguments to pass to the fetch implementation.
|
|
354
|
+
* @throws If no fetch implementation is available.
|
|
355
|
+
*/
|
|
356
|
+
_fetch(...args) {
|
|
357
|
+
if (this.customFetchImpl) {
|
|
358
|
+
return this.customFetchImpl(...args);
|
|
359
|
+
}
|
|
360
|
+
if (typeof fetch === "function") {
|
|
361
|
+
return fetch(...args);
|
|
362
|
+
}
|
|
363
|
+
throw new Error(
|
|
364
|
+
"A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2AClientOptions. For earlier Node.js versions (pre-v18), you can use a library like `node-fetch`."
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Creates an A2AClient instance by fetching the AgentCard from a URL then constructing the A2AClient.
|
|
369
|
+
* @param agentCardUrl The URL of the agent card.
|
|
370
|
+
* @param options Optional. The options for the A2AClient including the fetch/auth implementation.
|
|
371
|
+
* @returns A Promise that resolves to a new A2AClient instance.
|
|
372
|
+
*/
|
|
373
|
+
static async fromCardUrl(agentCardUrl, options) {
|
|
374
|
+
const fetchImpl = options?.fetchImpl;
|
|
375
|
+
const requestInit = {
|
|
376
|
+
headers: { Accept: "application/json" }
|
|
377
|
+
};
|
|
378
|
+
let response;
|
|
379
|
+
if (fetchImpl) {
|
|
380
|
+
response = await fetchImpl(agentCardUrl, requestInit);
|
|
381
|
+
} else if (typeof fetch === "function") {
|
|
382
|
+
response = await fetch(agentCardUrl, requestInit);
|
|
383
|
+
} else {
|
|
384
|
+
throw new Error(
|
|
385
|
+
"A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2AClientOptions. For earlier Node.js versions (pre-v18), you can use a library like `node-fetch`."
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
if (!response.ok) {
|
|
389
|
+
throw new Error(
|
|
390
|
+
`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
let agentCard;
|
|
394
|
+
try {
|
|
395
|
+
agentCard = await response.json();
|
|
396
|
+
} catch (error) {
|
|
397
|
+
console.error("Failed to parse Agent Card JSON:", error);
|
|
398
|
+
throw new Error(
|
|
399
|
+
`Failed to parse Agent Card JSON from ${agentCardUrl}. Original error: ${error.message}`
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
return new _A2AClient(agentCard, options);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Sends a message to the agent.
|
|
406
|
+
* The behavior (blocking/non-blocking) and push notification configuration
|
|
407
|
+
* are specified within the `params.configuration` object.
|
|
408
|
+
* Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
|
|
409
|
+
* @param params The parameters for sending the message, including the message content and configuration.
|
|
410
|
+
* @returns A Promise resolving to SendMessageResponse, which can be a Message, Task, or an error.
|
|
411
|
+
*/
|
|
412
|
+
async sendMessage(params) {
|
|
413
|
+
return await this.invokeJsonRpc(
|
|
414
|
+
(t, p, id) => t.sendMessage(p, _A2AClient.emptyOptions, id),
|
|
415
|
+
params
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Sends a message to the agent and streams back responses using Server-Sent Events (SSE).
|
|
420
|
+
* Push notification configuration can be specified in `params.configuration`.
|
|
421
|
+
* Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
|
|
422
|
+
* Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
|
|
423
|
+
* @param params The parameters for sending the message.
|
|
424
|
+
* @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
|
|
425
|
+
* The generator throws an error if streaming is not supported or if an HTTP/SSE error occurs.
|
|
426
|
+
*/
|
|
427
|
+
async *sendMessageStream(params) {
|
|
428
|
+
const agentCard = await this.agentCardPromise;
|
|
429
|
+
if (!agentCard.capabilities?.streaming) {
|
|
430
|
+
throw new Error(
|
|
431
|
+
"Agent does not support streaming (AgentCard.capabilities.streaming is not true)."
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
const transport = await this._getOrCreateTransport();
|
|
435
|
+
yield* transport.sendMessageStream(params);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Sets or updates the push notification configuration for a given task.
|
|
439
|
+
* Requires the agent to support push notifications (`capabilities.pushNotifications: true` in AgentCard).
|
|
440
|
+
* @param params Parameters containing the taskId and the TaskPushNotificationConfig.
|
|
441
|
+
* @returns A Promise resolving to SetTaskPushNotificationConfigResponse.
|
|
442
|
+
*/
|
|
443
|
+
async setTaskPushNotificationConfig(params) {
|
|
444
|
+
const agentCard = await this.agentCardPromise;
|
|
445
|
+
if (!agentCard.capabilities?.pushNotifications) {
|
|
446
|
+
throw new Error(
|
|
447
|
+
"Agent does not support push notifications (AgentCard.capabilities.pushNotifications is not true)."
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
return await this.invokeJsonRpc((t, p, id) => t.setTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Gets the push notification configuration for a given task.
|
|
454
|
+
* @param params Parameters containing the taskId.
|
|
455
|
+
* @returns A Promise resolving to GetTaskPushNotificationConfigResponse.
|
|
456
|
+
*/
|
|
457
|
+
async getTaskPushNotificationConfig(params) {
|
|
458
|
+
return await this.invokeJsonRpc(
|
|
459
|
+
(t, p, id) => t.getTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id),
|
|
460
|
+
params
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Lists the push notification configurations for a given task.
|
|
465
|
+
* @param params Parameters containing the taskId.
|
|
466
|
+
* @returns A Promise resolving to ListTaskPushNotificationConfigResponse.
|
|
467
|
+
*/
|
|
468
|
+
async listTaskPushNotificationConfig(params) {
|
|
469
|
+
return await this.invokeJsonRpc((t, p, id) => t.listTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Deletes the push notification configuration for a given task.
|
|
473
|
+
* @param params Parameters containing the taskId and push notification configuration ID.
|
|
474
|
+
* @returns A Promise resolving to DeleteTaskPushNotificationConfigResponse.
|
|
475
|
+
*/
|
|
476
|
+
async deleteTaskPushNotificationConfig(params) {
|
|
477
|
+
return await this.invokeJsonRpc((t, p, id) => t.deleteTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Retrieves a task by its ID.
|
|
481
|
+
* @param params Parameters containing the taskId and optional historyLength.
|
|
482
|
+
* @returns A Promise resolving to GetTaskResponse, which contains the Task object or an error.
|
|
483
|
+
*/
|
|
484
|
+
async getTask(params) {
|
|
485
|
+
return await this.invokeJsonRpc(
|
|
486
|
+
(t, p, id) => t.getTask(p, _A2AClient.emptyOptions, id),
|
|
487
|
+
params
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Cancels a task by its ID.
|
|
492
|
+
* @param params Parameters containing the taskId.
|
|
493
|
+
* @returns A Promise resolving to CancelTaskResponse, which contains the updated Task object or an error.
|
|
494
|
+
*/
|
|
495
|
+
async cancelTask(params) {
|
|
496
|
+
return await this.invokeJsonRpc(
|
|
497
|
+
(t, p, id) => t.cancelTask(p, _A2AClient.emptyOptions, id),
|
|
498
|
+
params
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* @template TExtensionParams The type of parameters for the custom extension method.
|
|
503
|
+
* @template TExtensionResponse The type of response expected from the custom extension method.
|
|
504
|
+
* This should extend JSONRPCResponse. This ensures the extension response is still a valid A2A response.
|
|
505
|
+
* @param method Custom JSON-RPC method defined in the AgentCard's extensions.
|
|
506
|
+
* @param params Extension paramters defined in the AgentCard's extensions.
|
|
507
|
+
* @returns A Promise that resolves to the RPC response.
|
|
508
|
+
*/
|
|
509
|
+
async callExtensionMethod(method, params) {
|
|
510
|
+
const transport = await this._getOrCreateTransport();
|
|
511
|
+
try {
|
|
512
|
+
return await transport.callExtensionMethod(
|
|
513
|
+
method,
|
|
514
|
+
params,
|
|
515
|
+
this.requestIdCounter++
|
|
516
|
+
);
|
|
517
|
+
} catch (e) {
|
|
518
|
+
const errorResponse = extractJSONRPCError(e);
|
|
519
|
+
if (errorResponse) {
|
|
520
|
+
return errorResponse;
|
|
521
|
+
}
|
|
522
|
+
throw e;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Resubscribes to a task's event stream using Server-Sent Events (SSE).
|
|
527
|
+
* This is used if a previous SSE connection for an active task was broken.
|
|
528
|
+
* Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
|
|
529
|
+
* @param params Parameters containing the taskId.
|
|
530
|
+
* @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
|
|
531
|
+
*/
|
|
532
|
+
async *resubscribeTask(params) {
|
|
533
|
+
const agentCard = await this.agentCardPromise;
|
|
534
|
+
if (!agentCard.capabilities?.streaming) {
|
|
535
|
+
throw new Error("Agent does not support streaming (required for tasks/resubscribe).");
|
|
536
|
+
}
|
|
537
|
+
const transport = await this._getOrCreateTransport();
|
|
538
|
+
yield* transport.resubscribeTask(params);
|
|
539
|
+
}
|
|
540
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
541
|
+
// Functions used to support old A2AClient Constructor to be deprecated soon
|
|
542
|
+
// TODOs:
|
|
543
|
+
// * remove `agentCardPromise`, and just use agentCard initialized
|
|
544
|
+
// * _getServiceEndpoint can be made synchronous or deleted and accessed via
|
|
545
|
+
// agentCard.url
|
|
546
|
+
// * getAgentCard changed to this.agentCard
|
|
547
|
+
// * delete resolveAgentCardUrl(), _fetchAndCacheAgentCard(),
|
|
548
|
+
// agentCardPath from A2AClientOptions
|
|
549
|
+
// * delete _getOrCreateTransport
|
|
550
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
551
|
+
async _getOrCreateTransport() {
|
|
552
|
+
if (this.transport) {
|
|
553
|
+
return this.transport;
|
|
554
|
+
}
|
|
555
|
+
const endpoint = await this._getServiceEndpoint();
|
|
556
|
+
this.transport = new JsonRpcTransport({ fetchImpl: this.customFetchImpl, endpoint });
|
|
557
|
+
return this.transport;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Fetches the Agent Card from the agent's well-known URI and caches its service endpoint URL.
|
|
561
|
+
* This method is called by the constructor.
|
|
562
|
+
* @param agentBaseUrl The base URL of the A2A agent (e.g., https://agent.example.com)
|
|
563
|
+
* @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
|
|
564
|
+
* @returns A Promise that resolves to the AgentCard.
|
|
565
|
+
*/
|
|
566
|
+
async _fetchAndCacheAgentCard(agentBaseUrl, agentCardPath) {
|
|
567
|
+
try {
|
|
568
|
+
const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
|
|
569
|
+
const response = await this._fetch(agentCardUrl, {
|
|
570
|
+
headers: { Accept: "application/json" }
|
|
571
|
+
});
|
|
572
|
+
if (!response.ok) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
const agentCard = await response.json();
|
|
578
|
+
if (!agentCard.url) {
|
|
579
|
+
throw new Error(
|
|
580
|
+
"Fetched Agent Card does not contain a valid 'url' for the service endpoint."
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
this.serviceEndpointUrl = agentCard.url;
|
|
584
|
+
return agentCard;
|
|
585
|
+
} catch (error) {
|
|
586
|
+
console.error("Error fetching or parsing Agent Card:", error);
|
|
587
|
+
throw error;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Retrieves the Agent Card.
|
|
592
|
+
* If an `agentBaseUrl` is provided, it fetches the card from that specific URL.
|
|
593
|
+
* Otherwise, it returns the card fetched and cached during client construction.
|
|
594
|
+
* @param agentBaseUrl Optional. The base URL of the agent to fetch the card from.
|
|
595
|
+
* @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
|
|
596
|
+
* If provided, this will fetch a new card, not use the cached one from the constructor's URL.
|
|
597
|
+
* @returns A Promise that resolves to the AgentCard.
|
|
598
|
+
*/
|
|
599
|
+
async getAgentCard(agentBaseUrl, agentCardPath) {
|
|
600
|
+
if (agentBaseUrl) {
|
|
601
|
+
const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
|
|
602
|
+
const response = await this._fetch(agentCardUrl, {
|
|
603
|
+
headers: { Accept: "application/json" }
|
|
604
|
+
});
|
|
605
|
+
if (!response.ok) {
|
|
606
|
+
throw new Error(
|
|
607
|
+
`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
return await response.json();
|
|
611
|
+
}
|
|
612
|
+
return this.agentCardPromise;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Determines the agent card URL based on the agent URL.
|
|
616
|
+
* @param agentBaseUrl The agent URL.
|
|
617
|
+
* @param agentCardPath Optional relative path to the agent card, defaults to .well-known/agent-card.json
|
|
618
|
+
*/
|
|
619
|
+
resolveAgentCardUrl(agentBaseUrl, agentCardPath = AGENT_CARD_PATH) {
|
|
620
|
+
return `${agentBaseUrl.replace(/\/$/, "")}/${agentCardPath.replace(/^\//, "")}`;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Gets the RPC service endpoint URL. Ensures the agent card has been fetched first.
|
|
624
|
+
* @returns A Promise that resolves to the service endpoint URL string.
|
|
625
|
+
*/
|
|
626
|
+
async _getServiceEndpoint() {
|
|
627
|
+
if (this.serviceEndpointUrl) {
|
|
628
|
+
return this.serviceEndpointUrl;
|
|
629
|
+
}
|
|
630
|
+
await this.agentCardPromise;
|
|
631
|
+
if (!this.serviceEndpointUrl) {
|
|
632
|
+
throw new Error(
|
|
633
|
+
"Agent Card URL for RPC endpoint is not available. Fetching might have failed."
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
return this.serviceEndpointUrl;
|
|
637
|
+
}
|
|
638
|
+
async invokeJsonRpc(caller, params) {
|
|
639
|
+
const transport = await this._getOrCreateTransport();
|
|
640
|
+
const requestId = this.requestIdCounter++;
|
|
641
|
+
try {
|
|
642
|
+
const result = await caller(transport, params, requestId);
|
|
643
|
+
return {
|
|
644
|
+
id: requestId,
|
|
645
|
+
jsonrpc: "2.0",
|
|
646
|
+
result: result ?? null
|
|
647
|
+
// JSON-RPC requires result property on success, it will be null for "void" methods.
|
|
648
|
+
};
|
|
649
|
+
} catch (e) {
|
|
650
|
+
const errorResponse = extractJSONRPCError(e);
|
|
651
|
+
if (errorResponse) {
|
|
652
|
+
return errorResponse;
|
|
653
|
+
}
|
|
654
|
+
throw e;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
function extractJSONRPCError(error) {
|
|
659
|
+
if (error instanceof Object && "errorResponse" in error && error.errorResponse instanceof Object && "jsonrpc" in error.errorResponse && error.errorResponse.jsonrpc === "2.0" && "error" in error.errorResponse && error.errorResponse.error !== null) {
|
|
660
|
+
return error.errorResponse;
|
|
661
|
+
} else {
|
|
662
|
+
return void 0;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// src/client/auth-handler.ts
|
|
667
|
+
function createAuthenticatingFetchWithRetry(fetchImpl, authHandler) {
|
|
668
|
+
async function authFetch(url, init) {
|
|
669
|
+
const authHeaders = await authHandler.headers() || {};
|
|
670
|
+
const mergedInit = {
|
|
671
|
+
...init || {},
|
|
672
|
+
headers: {
|
|
673
|
+
...authHeaders,
|
|
674
|
+
...init?.headers || {}
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
let response = await fetchImpl(url, mergedInit);
|
|
678
|
+
const updatedHeaders = await authHandler.shouldRetryWithHeaders(mergedInit, response);
|
|
679
|
+
if (updatedHeaders) {
|
|
680
|
+
const retryInit = {
|
|
681
|
+
...init || {},
|
|
682
|
+
headers: {
|
|
683
|
+
...updatedHeaders,
|
|
684
|
+
...init?.headers || {}
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
response = await fetchImpl(url, retryInit);
|
|
688
|
+
if (response.ok && authHandler.onSuccessfulRetry) {
|
|
689
|
+
await authHandler.onSuccessfulRetry(updatedHeaders);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
return response;
|
|
693
|
+
}
|
|
694
|
+
Object.setPrototypeOf(authFetch, Object.getPrototypeOf(fetchImpl));
|
|
695
|
+
Object.defineProperties(authFetch, Object.getOwnPropertyDescriptors(fetchImpl));
|
|
696
|
+
return authFetch;
|
|
697
|
+
}
|
|
11
698
|
|
|
12
699
|
// src/client/card-resolver.ts
|
|
13
700
|
var DefaultAgentCardResolver = class {
|
|
@@ -37,7 +724,7 @@ var DefaultAgentCardResolver = class {
|
|
|
37
724
|
}
|
|
38
725
|
};
|
|
39
726
|
var AgentCardResolver = {
|
|
40
|
-
|
|
727
|
+
default: new DefaultAgentCardResolver()
|
|
41
728
|
};
|
|
42
729
|
|
|
43
730
|
// src/client/multitransport-client.ts
|
|
@@ -47,6 +734,20 @@ var Client = class {
|
|
|
47
734
|
this.agentCard = agentCard;
|
|
48
735
|
this.config = config;
|
|
49
736
|
}
|
|
737
|
+
/**
|
|
738
|
+
* If the current agent card supports the extended feature, it will try to fetch the extended agent card from the server,
|
|
739
|
+
* Otherwise it will return the current agent card value.
|
|
740
|
+
*/
|
|
741
|
+
async getAgentCard(options) {
|
|
742
|
+
if (this.agentCard.supportsAuthenticatedExtendedCard) {
|
|
743
|
+
this.agentCard = await this.executeWithInterceptors(
|
|
744
|
+
{ method: "getAgentCard" },
|
|
745
|
+
options,
|
|
746
|
+
(_, options2) => this.transport.getExtendedAgentCard(options2)
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
return this.agentCard;
|
|
750
|
+
}
|
|
50
751
|
/**
|
|
51
752
|
* Sends a message to an agent to initiate a new interaction or to continue an existing one.
|
|
52
753
|
* Uses blocking mode by default.
|
|
@@ -71,6 +772,7 @@ var Client = class {
|
|
|
71
772
|
params = this.applyClientConfig({ params, blocking: true });
|
|
72
773
|
const beforeArgs = {
|
|
73
774
|
input: { method, value: params },
|
|
775
|
+
agentCard: this.agentCard,
|
|
74
776
|
options
|
|
75
777
|
};
|
|
76
778
|
const beforeResult = await this.interceptBefore(beforeArgs);
|
|
@@ -78,6 +780,7 @@ var Client = class {
|
|
|
78
780
|
const earlyReturn = beforeResult.earlyReturn.value;
|
|
79
781
|
const afterArgs = {
|
|
80
782
|
result: { method, value: earlyReturn },
|
|
783
|
+
agentCard: this.agentCard,
|
|
81
784
|
options: beforeArgs.options
|
|
82
785
|
};
|
|
83
786
|
await this.interceptAfter(afterArgs, beforeResult.executed);
|
|
@@ -88,6 +791,7 @@ var Client = class {
|
|
|
88
791
|
const result = await this.transport.sendMessage(beforeArgs.input.value, beforeArgs.options);
|
|
89
792
|
const afterArgs = {
|
|
90
793
|
result: { method, value: result },
|
|
794
|
+
agentCard: this.agentCard,
|
|
91
795
|
options: beforeArgs.options
|
|
92
796
|
};
|
|
93
797
|
await this.interceptAfter(afterArgs);
|
|
@@ -100,6 +804,7 @@ var Client = class {
|
|
|
100
804
|
)) {
|
|
101
805
|
const afterArgs = {
|
|
102
806
|
result: { method, value: event },
|
|
807
|
+
agentCard: this.agentCard,
|
|
103
808
|
options: beforeArgs.options
|
|
104
809
|
};
|
|
105
810
|
await this.interceptAfter(afterArgs);
|
|
@@ -187,12 +892,17 @@ var Client = class {
|
|
|
187
892
|
*/
|
|
188
893
|
async *resubscribeTask(params, options) {
|
|
189
894
|
const method = "resubscribeTask";
|
|
190
|
-
const beforeArgs = {
|
|
895
|
+
const beforeArgs = {
|
|
896
|
+
input: { method, value: params },
|
|
897
|
+
agentCard: this.agentCard,
|
|
898
|
+
options
|
|
899
|
+
};
|
|
191
900
|
const beforeResult = await this.interceptBefore(beforeArgs);
|
|
192
901
|
if (beforeResult) {
|
|
193
902
|
const earlyReturn = beforeResult.earlyReturn.value;
|
|
194
903
|
const afterArgs = {
|
|
195
904
|
result: { method, value: earlyReturn },
|
|
905
|
+
agentCard: this.agentCard,
|
|
196
906
|
options: beforeArgs.options
|
|
197
907
|
};
|
|
198
908
|
await this.interceptAfter(afterArgs, beforeResult.executed);
|
|
@@ -205,6 +915,7 @@ var Client = class {
|
|
|
205
915
|
)) {
|
|
206
916
|
const afterArgs = {
|
|
207
917
|
result: { method, value: event },
|
|
918
|
+
agentCard: this.agentCard,
|
|
208
919
|
options: beforeArgs.options
|
|
209
920
|
};
|
|
210
921
|
await this.interceptAfter(afterArgs);
|
|
@@ -231,6 +942,7 @@ var Client = class {
|
|
|
231
942
|
async executeWithInterceptors(input, options, transportCall) {
|
|
232
943
|
const beforeArgs = {
|
|
233
944
|
input,
|
|
945
|
+
agentCard: this.agentCard,
|
|
234
946
|
options
|
|
235
947
|
};
|
|
236
948
|
const beforeResult = await this.interceptBefore(beforeArgs);
|
|
@@ -240,6 +952,7 @@ var Client = class {
|
|
|
240
952
|
method: input.method,
|
|
241
953
|
value: beforeResult.earlyReturn.value
|
|
242
954
|
},
|
|
955
|
+
agentCard: this.agentCard,
|
|
243
956
|
options: beforeArgs.options
|
|
244
957
|
};
|
|
245
958
|
await this.interceptAfter(afterArgs2, beforeResult.executed);
|
|
@@ -248,6 +961,7 @@ var Client = class {
|
|
|
248
961
|
const result = await transportCall(beforeArgs.input.value, beforeArgs.options);
|
|
249
962
|
const afterArgs = {
|
|
250
963
|
result: { method: input.method, value: result },
|
|
964
|
+
agentCard: this.agentCard,
|
|
251
965
|
options: beforeArgs.options
|
|
252
966
|
};
|
|
253
967
|
await this.interceptAfter(afterArgs);
|
|
@@ -270,10 +984,8 @@ var Client = class {
|
|
|
270
984
|
}
|
|
271
985
|
}
|
|
272
986
|
async interceptAfter(args, interceptors) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
for (const interceptor of interceptors ?? this.config.interceptors) {
|
|
987
|
+
const reversedInterceptors = [...interceptors ?? this.config?.interceptors ?? []].reverse();
|
|
988
|
+
for (const interceptor of reversedInterceptors) {
|
|
277
989
|
await interceptor.after(args);
|
|
278
990
|
if (args.earlyReturn) {
|
|
279
991
|
return;
|
|
@@ -282,35 +994,283 @@ var Client = class {
|
|
|
282
994
|
}
|
|
283
995
|
};
|
|
284
996
|
|
|
997
|
+
// src/client/transports/rest_transport.ts
|
|
998
|
+
var RestTransport = class _RestTransport {
|
|
999
|
+
customFetchImpl;
|
|
1000
|
+
endpoint;
|
|
1001
|
+
constructor(options) {
|
|
1002
|
+
this.endpoint = options.endpoint.replace(/\/+$/, "");
|
|
1003
|
+
this.customFetchImpl = options.fetchImpl;
|
|
1004
|
+
}
|
|
1005
|
+
async getExtendedAgentCard(options) {
|
|
1006
|
+
return this._sendRequest("GET", "/v1/card", void 0, options);
|
|
1007
|
+
}
|
|
1008
|
+
async sendMessage(params, options) {
|
|
1009
|
+
return this._sendRequest("POST", "/v1/message:send", params, options);
|
|
1010
|
+
}
|
|
1011
|
+
async *sendMessageStream(params, options) {
|
|
1012
|
+
yield* this._sendStreamingRequest("/v1/message:stream", params, options);
|
|
1013
|
+
}
|
|
1014
|
+
async setTaskPushNotificationConfig(params, options) {
|
|
1015
|
+
return this._sendRequest(
|
|
1016
|
+
"POST",
|
|
1017
|
+
`/v1/tasks/${encodeURIComponent(params.taskId)}/pushNotificationConfigs`,
|
|
1018
|
+
{
|
|
1019
|
+
pushNotificationConfig: params.pushNotificationConfig
|
|
1020
|
+
},
|
|
1021
|
+
options
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
async getTaskPushNotificationConfig(params, options) {
|
|
1025
|
+
const { pushNotificationConfigId } = params;
|
|
1026
|
+
if (!pushNotificationConfigId) {
|
|
1027
|
+
throw new Error(
|
|
1028
|
+
"pushNotificationConfigId is required for getTaskPushNotificationConfig with REST transport."
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
return this._sendRequest(
|
|
1032
|
+
"GET",
|
|
1033
|
+
`/v1/tasks/${encodeURIComponent(params.id)}/pushNotificationConfigs/${encodeURIComponent(pushNotificationConfigId)}`,
|
|
1034
|
+
void 0,
|
|
1035
|
+
options
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
async listTaskPushNotificationConfig(params, options) {
|
|
1039
|
+
return this._sendRequest(
|
|
1040
|
+
"GET",
|
|
1041
|
+
`/v1/tasks/${encodeURIComponent(params.id)}/pushNotificationConfigs`,
|
|
1042
|
+
void 0,
|
|
1043
|
+
options
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
async deleteTaskPushNotificationConfig(params, options) {
|
|
1047
|
+
await this._sendRequest(
|
|
1048
|
+
"DELETE",
|
|
1049
|
+
`/v1/tasks/${encodeURIComponent(params.id)}/pushNotificationConfigs/${encodeURIComponent(params.pushNotificationConfigId)}`,
|
|
1050
|
+
void 0,
|
|
1051
|
+
options
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
async getTask(params, options) {
|
|
1055
|
+
const queryParams = new URLSearchParams();
|
|
1056
|
+
if (params.historyLength !== void 0) {
|
|
1057
|
+
queryParams.set("historyLength", String(params.historyLength));
|
|
1058
|
+
}
|
|
1059
|
+
const queryString = queryParams.toString();
|
|
1060
|
+
const path = `/v1/tasks/${encodeURIComponent(params.id)}${queryString ? `?${queryString}` : ""}`;
|
|
1061
|
+
return this._sendRequest("GET", path, void 0, options);
|
|
1062
|
+
}
|
|
1063
|
+
async cancelTask(params, options) {
|
|
1064
|
+
return this._sendRequest(
|
|
1065
|
+
"POST",
|
|
1066
|
+
`/v1/tasks/${encodeURIComponent(params.id)}:cancel`,
|
|
1067
|
+
void 0,
|
|
1068
|
+
options
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
async *resubscribeTask(params, options) {
|
|
1072
|
+
yield* this._sendStreamingRequest(
|
|
1073
|
+
`/v1/tasks/${encodeURIComponent(params.id)}:subscribe`,
|
|
1074
|
+
void 0,
|
|
1075
|
+
options
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
_fetch(...args) {
|
|
1079
|
+
if (this.customFetchImpl) {
|
|
1080
|
+
return this.customFetchImpl(...args);
|
|
1081
|
+
}
|
|
1082
|
+
if (typeof fetch === "function") {
|
|
1083
|
+
return fetch(...args);
|
|
1084
|
+
}
|
|
1085
|
+
throw new Error(
|
|
1086
|
+
"A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the RestTransportOptions."
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
_buildHeaders(options, acceptHeader = "application/json") {
|
|
1090
|
+
return {
|
|
1091
|
+
...options?.serviceParameters,
|
|
1092
|
+
"Content-Type": "application/json",
|
|
1093
|
+
Accept: acceptHeader
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
async _sendRequest(method, path, body, options) {
|
|
1097
|
+
const url = `${this.endpoint}${path}`;
|
|
1098
|
+
const requestInit = {
|
|
1099
|
+
method,
|
|
1100
|
+
headers: this._buildHeaders(options),
|
|
1101
|
+
signal: options?.signal
|
|
1102
|
+
};
|
|
1103
|
+
if (body !== void 0 && method !== "GET") {
|
|
1104
|
+
requestInit.body = JSON.stringify(body);
|
|
1105
|
+
}
|
|
1106
|
+
const response = await this._fetch(url, requestInit);
|
|
1107
|
+
if (!response.ok) {
|
|
1108
|
+
await this._handleErrorResponse(response, path);
|
|
1109
|
+
}
|
|
1110
|
+
if (response.status === 204) {
|
|
1111
|
+
return void 0;
|
|
1112
|
+
}
|
|
1113
|
+
const result = await response.json();
|
|
1114
|
+
return result;
|
|
1115
|
+
}
|
|
1116
|
+
async _handleErrorResponse(response, path) {
|
|
1117
|
+
let errorBodyText = "(empty or non-JSON response)";
|
|
1118
|
+
let errorBody;
|
|
1119
|
+
try {
|
|
1120
|
+
errorBodyText = await response.text();
|
|
1121
|
+
if (errorBodyText) {
|
|
1122
|
+
errorBody = JSON.parse(errorBodyText);
|
|
1123
|
+
}
|
|
1124
|
+
} catch (e) {
|
|
1125
|
+
throw new Error(
|
|
1126
|
+
`HTTP error for ${path}! Status: ${response.status} ${response.statusText}. Response: ${errorBodyText}`,
|
|
1127
|
+
{ cause: e }
|
|
1128
|
+
);
|
|
1129
|
+
}
|
|
1130
|
+
if (errorBody && typeof errorBody.code === "number") {
|
|
1131
|
+
throw _RestTransport.mapToError(errorBody);
|
|
1132
|
+
}
|
|
1133
|
+
throw new Error(
|
|
1134
|
+
`HTTP error for ${path}! Status: ${response.status} ${response.statusText}. Response: ${errorBodyText}`
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
async *_sendStreamingRequest(path, body, options) {
|
|
1138
|
+
const url = `${this.endpoint}${path}`;
|
|
1139
|
+
const requestInit = {
|
|
1140
|
+
method: "POST",
|
|
1141
|
+
headers: this._buildHeaders(options, "text/event-stream"),
|
|
1142
|
+
signal: options?.signal
|
|
1143
|
+
};
|
|
1144
|
+
if (body !== void 0) {
|
|
1145
|
+
requestInit.body = JSON.stringify(body);
|
|
1146
|
+
}
|
|
1147
|
+
const response = await this._fetch(url, requestInit);
|
|
1148
|
+
if (!response.ok) {
|
|
1149
|
+
await this._handleErrorResponse(response, path);
|
|
1150
|
+
}
|
|
1151
|
+
const contentType = response.headers.get("Content-Type");
|
|
1152
|
+
if (!contentType?.startsWith("text/event-stream")) {
|
|
1153
|
+
throw new Error(
|
|
1154
|
+
`Invalid response Content-Type for SSE stream. Expected 'text/event-stream', got '${contentType}'.`
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1157
|
+
for await (const event of parseSseStream(response)) {
|
|
1158
|
+
if (event.type === "error") {
|
|
1159
|
+
const errorData = JSON.parse(event.data);
|
|
1160
|
+
throw _RestTransport.mapToError(errorData);
|
|
1161
|
+
}
|
|
1162
|
+
yield this._processSseEventData(event.data);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
_processSseEventData(jsonData) {
|
|
1166
|
+
if (!jsonData.trim()) {
|
|
1167
|
+
throw new Error("Attempted to process empty SSE event data.");
|
|
1168
|
+
}
|
|
1169
|
+
try {
|
|
1170
|
+
const data = JSON.parse(jsonData);
|
|
1171
|
+
return data;
|
|
1172
|
+
} catch (e) {
|
|
1173
|
+
console.error("Failed to parse SSE event data:", jsonData, e);
|
|
1174
|
+
throw new Error(
|
|
1175
|
+
`Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e instanceof Error && e.message || "Unknown error"}`
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
static mapToError(error) {
|
|
1180
|
+
switch (error.code) {
|
|
1181
|
+
case A2A_ERROR_CODE.TASK_NOT_FOUND:
|
|
1182
|
+
return new TaskNotFoundError(error.message);
|
|
1183
|
+
case A2A_ERROR_CODE.TASK_NOT_CANCELABLE:
|
|
1184
|
+
return new TaskNotCancelableError(error.message);
|
|
1185
|
+
case A2A_ERROR_CODE.PUSH_NOTIFICATION_NOT_SUPPORTED:
|
|
1186
|
+
return new PushNotificationNotSupportedError(error.message);
|
|
1187
|
+
case A2A_ERROR_CODE.UNSUPPORTED_OPERATION:
|
|
1188
|
+
return new UnsupportedOperationError(error.message);
|
|
1189
|
+
case A2A_ERROR_CODE.CONTENT_TYPE_NOT_SUPPORTED:
|
|
1190
|
+
return new ContentTypeNotSupportedError(error.message);
|
|
1191
|
+
case A2A_ERROR_CODE.INVALID_AGENT_RESPONSE:
|
|
1192
|
+
return new InvalidAgentResponseError(error.message);
|
|
1193
|
+
case A2A_ERROR_CODE.AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED:
|
|
1194
|
+
return new AuthenticatedExtendedCardNotConfiguredError(error.message);
|
|
1195
|
+
default:
|
|
1196
|
+
return new Error(
|
|
1197
|
+
`REST error: ${error.message} (Code: ${error.code})${error.data ? ` Data: ${JSON.stringify(error.data)}` : ""}`
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
var RestTransportFactory = class _RestTransportFactory {
|
|
1203
|
+
constructor(options) {
|
|
1204
|
+
this.options = options;
|
|
1205
|
+
}
|
|
1206
|
+
static name = "HTTP+JSON";
|
|
1207
|
+
get protocolName() {
|
|
1208
|
+
return _RestTransportFactory.name;
|
|
1209
|
+
}
|
|
1210
|
+
async create(url, _agentCard) {
|
|
1211
|
+
return new RestTransport({
|
|
1212
|
+
endpoint: url,
|
|
1213
|
+
fetchImpl: this.options?.fetchImpl
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
};
|
|
1217
|
+
|
|
285
1218
|
// src/client/factory.ts
|
|
286
1219
|
var ClientFactoryOptions = {
|
|
287
|
-
|
|
288
|
-
|
|
1220
|
+
/**
|
|
1221
|
+
* SDK default options for {@link ClientFactory}.
|
|
1222
|
+
*/
|
|
1223
|
+
default: {
|
|
1224
|
+
transports: [new JsonRpcTransportFactory(), new RestTransportFactory()]
|
|
1225
|
+
},
|
|
1226
|
+
/**
|
|
1227
|
+
* Creates new options by merging an original and an override object.
|
|
1228
|
+
* Transports are merged based on `TransportFactory.protocolName`,
|
|
1229
|
+
* interceptors are concatenated, other fields are overriden.
|
|
1230
|
+
*
|
|
1231
|
+
* @example
|
|
1232
|
+
* ```ts
|
|
1233
|
+
* const options = ClientFactoryOptions.createFrom(ClientFactoryOptions.default, {
|
|
1234
|
+
* transports: [new MyCustomTransportFactory()], // adds a custom transport
|
|
1235
|
+
* clientConfig: { interceptors: [new MyInterceptor()] }, // adds a custom interceptor
|
|
1236
|
+
* });
|
|
1237
|
+
* ```
|
|
1238
|
+
*/
|
|
1239
|
+
createFrom(original, overrides) {
|
|
1240
|
+
return {
|
|
1241
|
+
...original,
|
|
1242
|
+
...overrides,
|
|
1243
|
+
transports: mergeTransports(original.transports, overrides.transports),
|
|
1244
|
+
clientConfig: {
|
|
1245
|
+
...original.clientConfig ?? {},
|
|
1246
|
+
...overrides.clientConfig ?? {},
|
|
1247
|
+
interceptors: mergeArrays(
|
|
1248
|
+
original.clientConfig?.interceptors,
|
|
1249
|
+
overrides.clientConfig?.interceptors
|
|
1250
|
+
),
|
|
1251
|
+
acceptedOutputModes: overrides.clientConfig?.acceptedOutputModes ?? original.clientConfig?.acceptedOutputModes
|
|
1252
|
+
},
|
|
1253
|
+
preferredTransports: overrides.preferredTransports ?? original.preferredTransports
|
|
1254
|
+
};
|
|
289
1255
|
}
|
|
290
1256
|
};
|
|
291
1257
|
var ClientFactory = class {
|
|
292
|
-
constructor(options = ClientFactoryOptions.
|
|
1258
|
+
constructor(options = ClientFactoryOptions.default) {
|
|
293
1259
|
this.options = options;
|
|
294
1260
|
if (!options.transports || options.transports.length === 0) {
|
|
295
1261
|
throw new Error("No transports provided");
|
|
296
1262
|
}
|
|
297
|
-
|
|
298
|
-
if (this.transportsByName.has(transport.protocolName)) {
|
|
299
|
-
throw new Error(`Duplicate transport name: ${transport.protocolName}`);
|
|
300
|
-
}
|
|
301
|
-
this.transportsByName.set(transport.protocolName, transport);
|
|
302
|
-
}
|
|
1263
|
+
this.transportsByName = transportsByName(options.transports);
|
|
303
1264
|
for (const transport of options.preferredTransports ?? []) {
|
|
304
|
-
|
|
305
|
-
if (!factory) {
|
|
1265
|
+
if (!this.transportsByName.has(transport)) {
|
|
306
1266
|
throw new Error(
|
|
307
1267
|
`Unknown preferred transport: ${transport}, available transports: ${[...this.transportsByName.keys()].join()}`
|
|
308
1268
|
);
|
|
309
1269
|
}
|
|
310
1270
|
}
|
|
311
|
-
this.agentCardResolver = options.cardResolver ?? AgentCardResolver.
|
|
1271
|
+
this.agentCardResolver = options.cardResolver ?? AgentCardResolver.default;
|
|
312
1272
|
}
|
|
313
|
-
transportsByName
|
|
1273
|
+
transportsByName;
|
|
314
1274
|
agentCardResolver;
|
|
315
1275
|
/**
|
|
316
1276
|
* Creates a new client from the provided agent card.
|
|
@@ -318,7 +1278,7 @@ var ClientFactory = class {
|
|
|
318
1278
|
async createFromAgentCard(agentCard) {
|
|
319
1279
|
const agentCardPreferred = agentCard.preferredTransport ?? JsonRpcTransportFactory.name;
|
|
320
1280
|
const additionalInterfaces = agentCard.additionalInterfaces ?? [];
|
|
321
|
-
const urlsPerAgentTransports = new
|
|
1281
|
+
const urlsPerAgentTransports = new CaseInsensitiveMap([
|
|
322
1282
|
[agentCardPreferred, agentCard.url],
|
|
323
1283
|
...additionalInterfaces.map((i) => [i.transport, i.url])
|
|
324
1284
|
]);
|
|
@@ -348,20 +1308,141 @@ var ClientFactory = class {
|
|
|
348
1308
|
/**
|
|
349
1309
|
* Downloads agent card using AgentCardResolver from options
|
|
350
1310
|
* and creates a new client from the downloaded card.
|
|
1311
|
+
*
|
|
1312
|
+
* @example
|
|
1313
|
+
* ```ts
|
|
1314
|
+
* const factory = new ClientFactory(); // use default options and default {@link AgentCardResolver}.
|
|
1315
|
+
* const client1 = await factory.createFromUrl('https://example.com'); // /.well-known/agent-card.json is used by default
|
|
1316
|
+
* const client2 = await factory.createFromUrl('https://example.com', '/my-agent-card.json'); // specify custom path
|
|
1317
|
+
* const client3 = await factory.createFromUrl('https://example.com/my-agent-card.json', ''); // specify full URL and set path to empty
|
|
1318
|
+
* ```
|
|
351
1319
|
*/
|
|
352
|
-
async
|
|
1320
|
+
async createFromUrl(baseUrl, path) {
|
|
353
1321
|
const agentCard = await this.agentCardResolver.resolve(baseUrl, path);
|
|
354
|
-
return
|
|
1322
|
+
return this.createFromAgentCard(agentCard);
|
|
1323
|
+
}
|
|
1324
|
+
};
|
|
1325
|
+
function mergeTransports(original, overrides) {
|
|
1326
|
+
if (!overrides) {
|
|
1327
|
+
return original;
|
|
1328
|
+
}
|
|
1329
|
+
const result = transportsByName(original);
|
|
1330
|
+
const overridesByName = transportsByName(overrides);
|
|
1331
|
+
for (const [name, factory] of overridesByName) {
|
|
1332
|
+
result.set(name, factory);
|
|
1333
|
+
}
|
|
1334
|
+
return Array.from(result.values());
|
|
1335
|
+
}
|
|
1336
|
+
function transportsByName(transports) {
|
|
1337
|
+
const result = new CaseInsensitiveMap();
|
|
1338
|
+
if (!transports) {
|
|
1339
|
+
return result;
|
|
1340
|
+
}
|
|
1341
|
+
for (const t of transports) {
|
|
1342
|
+
if (result.has(t.protocolName)) {
|
|
1343
|
+
throw new Error(`Duplicate protocol name: ${t.protocolName}`);
|
|
1344
|
+
}
|
|
1345
|
+
result.set(t.protocolName, t);
|
|
1346
|
+
}
|
|
1347
|
+
return result;
|
|
1348
|
+
}
|
|
1349
|
+
function mergeArrays(a1, a2) {
|
|
1350
|
+
if (!a1 && !a2) {
|
|
1351
|
+
return void 0;
|
|
1352
|
+
}
|
|
1353
|
+
return [...a1 ?? [], ...a2 ?? []];
|
|
1354
|
+
}
|
|
1355
|
+
var CaseInsensitiveMap = class extends Map {
|
|
1356
|
+
normalizeKey(key) {
|
|
1357
|
+
return key.toUpperCase();
|
|
1358
|
+
}
|
|
1359
|
+
set(key, value) {
|
|
1360
|
+
return super.set(this.normalizeKey(key), value);
|
|
1361
|
+
}
|
|
1362
|
+
get(key) {
|
|
1363
|
+
return super.get(this.normalizeKey(key));
|
|
1364
|
+
}
|
|
1365
|
+
has(key) {
|
|
1366
|
+
return super.has(this.normalizeKey(key));
|
|
1367
|
+
}
|
|
1368
|
+
delete(key) {
|
|
1369
|
+
return super.delete(this.normalizeKey(key));
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
|
|
1373
|
+
// src/client/service-parameters.ts
|
|
1374
|
+
var ServiceParameters = {
|
|
1375
|
+
create(...updates) {
|
|
1376
|
+
return ServiceParameters.createFrom(void 0, ...updates);
|
|
1377
|
+
},
|
|
1378
|
+
createFrom: (serviceParameters, ...updates) => {
|
|
1379
|
+
const result = serviceParameters ? { ...serviceParameters } : {};
|
|
1380
|
+
for (const update of updates) {
|
|
1381
|
+
update(result);
|
|
1382
|
+
}
|
|
1383
|
+
return result;
|
|
1384
|
+
}
|
|
1385
|
+
};
|
|
1386
|
+
function withA2AExtensions(...extensions) {
|
|
1387
|
+
return (parameters) => {
|
|
1388
|
+
parameters[HTTP_EXTENSION_HEADER] = Extensions.toServiceParameter(extensions);
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// src/client/context.ts
|
|
1393
|
+
var ClientCallContext = {
|
|
1394
|
+
/**
|
|
1395
|
+
* Create a new {@link ClientCallContext} with optional updates applied.
|
|
1396
|
+
*/
|
|
1397
|
+
create: (...updates) => {
|
|
1398
|
+
return ClientCallContext.createFrom(void 0, ...updates);
|
|
1399
|
+
},
|
|
1400
|
+
/**
|
|
1401
|
+
* Create a new {@link ClientCallContext} based on an existing one with updates applied.
|
|
1402
|
+
*/
|
|
1403
|
+
createFrom: (context, ...updates) => {
|
|
1404
|
+
const result = context ? { ...context } : {};
|
|
1405
|
+
for (const update of updates) {
|
|
1406
|
+
update(result);
|
|
1407
|
+
}
|
|
1408
|
+
return result;
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
var ClientCallContextKey = class {
|
|
1412
|
+
symbol;
|
|
1413
|
+
constructor(description) {
|
|
1414
|
+
this.symbol = Symbol(description);
|
|
1415
|
+
}
|
|
1416
|
+
set(value) {
|
|
1417
|
+
return (context) => {
|
|
1418
|
+
context[this.symbol] = value;
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
get(context) {
|
|
1422
|
+
return context[this.symbol];
|
|
355
1423
|
}
|
|
356
1424
|
};
|
|
357
1425
|
export {
|
|
358
1426
|
A2AClient,
|
|
359
1427
|
AgentCardResolver,
|
|
1428
|
+
AuthenticatedExtendedCardNotConfiguredError,
|
|
360
1429
|
Client,
|
|
1430
|
+
ClientCallContext,
|
|
1431
|
+
ClientCallContextKey,
|
|
361
1432
|
ClientFactory,
|
|
362
1433
|
ClientFactoryOptions,
|
|
1434
|
+
ContentTypeNotSupportedError,
|
|
363
1435
|
DefaultAgentCardResolver,
|
|
1436
|
+
InvalidAgentResponseError,
|
|
364
1437
|
JsonRpcTransport,
|
|
365
1438
|
JsonRpcTransportFactory,
|
|
366
|
-
|
|
1439
|
+
PushNotificationNotSupportedError,
|
|
1440
|
+
RestTransport,
|
|
1441
|
+
RestTransportFactory,
|
|
1442
|
+
ServiceParameters,
|
|
1443
|
+
TaskNotCancelableError,
|
|
1444
|
+
TaskNotFoundError,
|
|
1445
|
+
UnsupportedOperationError,
|
|
1446
|
+
createAuthenticatingFetchWithRetry,
|
|
1447
|
+
withA2AExtensions
|
|
367
1448
|
};
|