@mailmodo/a2a 0.3.3 → 0.3.5

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/dist/index.js CHANGED
@@ -1,30 +1,9 @@
1
1
  var __create = Object.create;
2
2
  var __defProp = Object.defineProperty;
3
- var __defProps = Object.defineProperties;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
5
  var __getProtoOf = Object.getPrototypeOf;
9
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
10
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
- var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
12
- var __typeError = (msg) => {
13
- throw TypeError(msg);
14
- };
15
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
16
- var __spreadValues = (a, b) => {
17
- for (var prop in b || (b = {}))
18
- if (__hasOwnProp.call(b, prop))
19
- __defNormalProp(a, prop, b[prop]);
20
- if (__getOwnPropSymbols)
21
- for (var prop of __getOwnPropSymbols(b)) {
22
- if (__propIsEnum.call(b, prop))
23
- __defNormalProp(a, prop, b[prop]);
24
- }
25
- return a;
26
- };
27
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
28
7
  var __export = (target, all) => {
29
8
  for (var name in all)
30
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -46,70 +25,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
46
25
  mod
47
26
  ));
48
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
49
- var __async = (__this, __arguments, generator) => {
50
- return new Promise((resolve, reject) => {
51
- var fulfilled = (value) => {
52
- try {
53
- step(generator.next(value));
54
- } catch (e) {
55
- reject(e);
56
- }
57
- };
58
- var rejected = (value) => {
59
- try {
60
- step(generator.throw(value));
61
- } catch (e) {
62
- reject(e);
63
- }
64
- };
65
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
66
- step((generator = generator.apply(__this, __arguments)).next());
67
- });
68
- };
69
- var __await = function(promise, isYieldStar) {
70
- this[0] = promise;
71
- this[1] = isYieldStar;
72
- };
73
- var __asyncGenerator = (__this, __arguments, generator) => {
74
- var resume = (k, v, yes, no) => {
75
- try {
76
- var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done;
77
- Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no));
78
- } catch (e) {
79
- no(e);
80
- }
81
- }, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {};
82
- return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it;
83
- };
84
- var __yieldStar = (value) => {
85
- var obj = value[__knownSymbol("asyncIterator")], isAwait = false, method, it = {};
86
- if (obj == null) {
87
- obj = value[__knownSymbol("iterator")]();
88
- method = (k) => it[k] = (x) => obj[k](x);
89
- } else {
90
- obj = obj.call(value);
91
- method = (k) => it[k] = (v) => {
92
- if (isAwait) {
93
- isAwait = false;
94
- if (k === "throw") throw v;
95
- return v;
96
- }
97
- isAwait = true;
98
- return {
99
- done: false,
100
- value: new __await(new Promise((resolve) => {
101
- var x = obj[k](v);
102
- if (!(x instanceof Object)) __typeError("Object expected");
103
- resolve(x);
104
- }), 1)
105
- };
106
- };
107
- }
108
- return it[__knownSymbol("iterator")] = () => it, method("next"), "throw" in obj ? method("throw") : it.throw = (x) => {
109
- throw x;
110
- }, "return" in obj && method("return"), it;
111
- };
112
- var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
113
28
 
114
29
  // src/index.ts
115
30
  var index_exports = {};
@@ -128,6 +43,7 @@ __export(index_exports, {
128
43
  ResultManager: () => ResultManager,
129
44
  createAuthenticatingFetchWithRetry: () => createAuthenticatingFetchWithRetry,
130
45
  getCurrentTimestamp: () => getCurrentTimestamp,
46
+ getRequestedExtensions: () => getRequestedExtensions,
131
47
  isArtifactUpdate: () => isArtifactUpdate,
132
48
  isObject: () => isObject,
133
49
  isTaskStatusUpdate: () => isTaskStatusUpdate
@@ -136,15 +52,23 @@ module.exports = __toCommonJS(index_exports);
136
52
 
137
53
  // src/constants.ts
138
54
  var AGENT_CARD_PATH = ".well-known/agent-card.json";
55
+ var HTTP_EXTENSION_HEADER = "X-A2A-Extensions";
139
56
 
140
57
  // src/server/agent_execution/request_context.ts
141
58
  var RequestContext = class {
142
- constructor(userMessage, taskId, contextId, task, referenceTasks) {
59
+ userMessage;
60
+ taskId;
61
+ contextId;
62
+ task;
63
+ referenceTasks;
64
+ context;
65
+ constructor(userMessage, taskId, contextId, task, referenceTasks, context) {
143
66
  this.userMessage = userMessage;
144
67
  this.taskId = taskId;
145
68
  this.contextId = contextId;
146
69
  this.task = task;
147
70
  this.referenceTasks = referenceTasks;
71
+ this.context = context;
148
72
  }
149
73
  };
150
74
 
@@ -164,9 +88,7 @@ var DefaultExecutionEventBus = class extends import_events.EventEmitter {
164
88
 
165
89
  // src/server/events/execution_event_bus_manager.ts
166
90
  var DefaultExecutionEventBusManager = class {
167
- constructor() {
168
- this.taskIdToBus = /* @__PURE__ */ new Map();
169
- }
91
+ taskIdToBus = /* @__PURE__ */ new Map();
170
92
  /**
171
93
  * Creates or retrieves an existing ExecutionEventBus based on the taskId.
172
94
  * @param taskId The ID of the task.
@@ -202,45 +124,46 @@ var DefaultExecutionEventBusManager = class {
202
124
 
203
125
  // src/server/events/execution_event_queue.ts
204
126
  var ExecutionEventQueue = class {
127
+ eventBus;
128
+ eventQueue = [];
129
+ resolvePromise;
130
+ stopped = false;
131
+ boundHandleEvent;
205
132
  constructor(eventBus) {
206
- this.eventQueue = [];
207
- this.stopped = false;
208
- this.handleEvent = (event) => {
209
- if (this.stopped) return;
210
- this.eventQueue.push(event);
211
- if (this.resolvePromise) {
212
- this.resolvePromise();
213
- this.resolvePromise = void 0;
214
- }
215
- };
216
- this.handleFinished = () => {
217
- this.stop();
218
- };
219
133
  this.eventBus = eventBus;
220
134
  this.eventBus.on("event", this.handleEvent);
221
135
  this.eventBus.on("finished", this.handleFinished);
222
136
  }
137
+ handleEvent = (event) => {
138
+ if (this.stopped) return;
139
+ this.eventQueue.push(event);
140
+ if (this.resolvePromise) {
141
+ this.resolvePromise();
142
+ this.resolvePromise = void 0;
143
+ }
144
+ };
145
+ handleFinished = () => {
146
+ this.stop();
147
+ };
223
148
  /**
224
149
  * Provides an async generator that yields events from the event bus.
225
150
  * Stops when a Message event is received or a TaskStatusUpdateEvent with final=true is received.
226
151
  */
227
- events() {
228
- return __asyncGenerator(this, null, function* () {
229
- while (!this.stopped || this.eventQueue.length > 0) {
230
- if (this.eventQueue.length > 0) {
231
- const event = this.eventQueue.shift();
232
- yield event;
233
- if (event.kind === "message" || event.kind === "status-update" && event.final) {
234
- this.handleFinished();
235
- break;
236
- }
237
- } else if (!this.stopped) {
238
- yield new __await(new Promise((resolve) => {
239
- this.resolvePromise = resolve;
240
- }));
152
+ async *events() {
153
+ while (!this.stopped || this.eventQueue.length > 0) {
154
+ if (this.eventQueue.length > 0) {
155
+ const event = this.eventQueue.shift();
156
+ yield event;
157
+ if (event.kind === "message" || event.kind === "status-update" && event.final) {
158
+ this.handleFinished();
159
+ break;
241
160
  }
161
+ } else if (!this.stopped) {
162
+ await new Promise((resolve) => {
163
+ this.resolvePromise = resolve;
164
+ });
242
165
  }
243
- });
166
+ }
244
167
  }
245
168
  /**
246
169
  * Stops the event queue from processing further events.
@@ -269,12 +192,23 @@ function isTaskStatusUpdate(update) {
269
192
  function isArtifactUpdate(update) {
270
193
  return isObject(update) && "parts" in update;
271
194
  }
195
+ function getRequestedExtensions(values) {
196
+ if (!values) {
197
+ return /* @__PURE__ */ new Set();
198
+ }
199
+ return new Set(
200
+ values.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0)
201
+ );
202
+ }
272
203
 
273
204
  // src/server/request_handler/default_request_handler.ts
274
205
  var import_uuid = require("uuid");
275
206
 
276
207
  // src/server/error.ts
277
208
  var A2AError = class _A2AError extends Error {
209
+ code;
210
+ data;
211
+ taskId;
278
212
  // Optional task ID context
279
213
  constructor(code, message, data, taskId) {
280
214
  super(message);
@@ -304,10 +238,7 @@ var A2AError = class _A2AError extends Error {
304
238
  return new _A2AError(-32600, message, data);
305
239
  }
306
240
  static methodNotFound(method) {
307
- return new _A2AError(
308
- -32601,
309
- `Method not found: ${method}`
310
- );
241
+ return new _A2AError(-32601, `Method not found: ${method}`);
311
242
  }
312
243
  static invalidParams(message, data) {
313
244
  return new _A2AError(-32602, message, data);
@@ -316,43 +247,29 @@ var A2AError = class _A2AError extends Error {
316
247
  return new _A2AError(-32603, message, data);
317
248
  }
318
249
  static taskNotFound(taskId) {
319
- return new _A2AError(
320
- -32001,
321
- `Task not found: ${taskId}`,
322
- void 0,
323
- taskId
324
- );
250
+ return new _A2AError(-32001, `Task not found: ${taskId}`, void 0, taskId);
325
251
  }
326
252
  static taskNotCancelable(taskId) {
327
- return new _A2AError(
328
- -32002,
329
- `Task not cancelable: ${taskId}`,
330
- void 0,
331
- taskId
332
- );
253
+ return new _A2AError(-32002, `Task not cancelable: ${taskId}`, void 0, taskId);
333
254
  }
334
255
  static pushNotificationNotSupported() {
335
- return new _A2AError(
336
- -32003,
337
- "Push Notification is not supported"
338
- );
256
+ return new _A2AError(-32003, "Push Notification is not supported");
339
257
  }
340
258
  static unsupportedOperation(operation) {
341
- return new _A2AError(
342
- -32004,
343
- `Unsupported operation: ${operation}`
344
- );
259
+ return new _A2AError(-32004, `Unsupported operation: ${operation}`);
345
260
  }
346
261
  static authenticatedExtendedCardNotConfigured() {
347
- return new _A2AError(
348
- -32007,
349
- `Extended card not configured.`
350
- );
262
+ return new _A2AError(-32007, `Extended card not configured.`);
351
263
  }
352
264
  };
353
265
 
354
266
  // src/server/result_manager.ts
355
267
  var ResultManager = class {
268
+ taskStore;
269
+ currentTask;
270
+ latestUserMessage;
271
+ // To add to history if a new task is created
272
+ finalMessageResult;
356
273
  // Stores the message if it's the final result
357
274
  constructor(taskStore) {
358
275
  this.taskStore = taskStore;
@@ -364,99 +281,117 @@ var ResultManager = class {
364
281
  * Processes an agent execution event and updates the task store.
365
282
  * @param event The agent execution event.
366
283
  */
367
- processEvent(event) {
368
- return __async(this, null, function* () {
369
- var _a, _b, _c;
370
- if (event.kind === "message") {
371
- this.finalMessageResult = event;
372
- } else if (event.kind === "task") {
373
- const taskEvent = event;
374
- this.currentTask = __spreadValues({}, taskEvent);
375
- if (this.latestUserMessage) {
376
- if (!((_a = this.currentTask.history) == null ? void 0 : _a.find((msg) => msg.messageId === this.latestUserMessage.messageId))) {
377
- this.currentTask.history = [this.latestUserMessage, ...this.currentTask.history || []];
284
+ async processEvent(event) {
285
+ if (event.kind === "message") {
286
+ this.finalMessageResult = event;
287
+ } else if (event.kind === "task") {
288
+ const taskEvent = event;
289
+ this.currentTask = { ...taskEvent };
290
+ if (this.latestUserMessage) {
291
+ if (!this.currentTask.history?.find(
292
+ (msg) => msg.messageId === this.latestUserMessage.messageId
293
+ )) {
294
+ this.currentTask.history = [this.latestUserMessage, ...this.currentTask.history || []];
295
+ }
296
+ }
297
+ await this.saveCurrentTask();
298
+ } else if (event.kind === "status-update") {
299
+ const updateEvent = event;
300
+ if (this.currentTask && this.currentTask.id === updateEvent.taskId) {
301
+ this.currentTask.status = updateEvent.status;
302
+ if (updateEvent.status.message) {
303
+ if (!this.currentTask.history?.find(
304
+ (msg) => msg.messageId === updateEvent.status.message.messageId
305
+ )) {
306
+ this.currentTask.history = [
307
+ ...this.currentTask.history || [],
308
+ updateEvent.status.message
309
+ ];
378
310
  }
379
311
  }
380
- yield this.saveCurrentTask();
381
- } else if (event.kind === "status-update") {
382
- const updateEvent = event;
383
- if (this.currentTask && this.currentTask.id === updateEvent.taskId) {
312
+ await this.saveCurrentTask();
313
+ } else if (!this.currentTask && updateEvent.taskId) {
314
+ const loaded = await this.taskStore.load(updateEvent.taskId);
315
+ if (loaded) {
316
+ this.currentTask = loaded;
384
317
  this.currentTask.status = updateEvent.status;
385
318
  if (updateEvent.status.message) {
386
- if (!((_b = this.currentTask.history) == null ? void 0 : _b.find((msg) => msg.messageId === updateEvent.status.message.messageId))) {
387
- this.currentTask.history = [...this.currentTask.history || [], updateEvent.status.message];
319
+ if (!this.currentTask.history?.find(
320
+ (msg) => msg.messageId === updateEvent.status.message.messageId
321
+ )) {
322
+ this.currentTask.history = [
323
+ ...this.currentTask.history || [],
324
+ updateEvent.status.message
325
+ ];
388
326
  }
389
327
  }
390
- yield this.saveCurrentTask();
391
- } else if (!this.currentTask && updateEvent.taskId) {
392
- const loaded = yield this.taskStore.load(updateEvent.taskId);
393
- if (loaded) {
394
- this.currentTask = loaded;
395
- this.currentTask.status = updateEvent.status;
396
- if (updateEvent.status.message) {
397
- if (!((_c = this.currentTask.history) == null ? void 0 : _c.find((msg) => msg.messageId === updateEvent.status.message.messageId))) {
398
- this.currentTask.history = [...this.currentTask.history || [], updateEvent.status.message];
399
- }
400
- }
401
- yield this.saveCurrentTask();
328
+ await this.saveCurrentTask();
329
+ } else {
330
+ console.warn(
331
+ `ResultManager: Received status update for unknown task ${updateEvent.taskId}`
332
+ );
333
+ }
334
+ }
335
+ } else if (event.kind === "artifact-update") {
336
+ const artifactEvent = event;
337
+ if (this.currentTask && this.currentTask.id === artifactEvent.taskId) {
338
+ if (!this.currentTask.artifacts) {
339
+ this.currentTask.artifacts = [];
340
+ }
341
+ const existingArtifactIndex = this.currentTask.artifacts.findIndex(
342
+ (art) => art.artifactId === artifactEvent.artifact.artifactId
343
+ );
344
+ if (existingArtifactIndex !== -1) {
345
+ if (artifactEvent.append) {
346
+ const existingArtifact = this.currentTask.artifacts[existingArtifactIndex];
347
+ existingArtifact.parts.push(...artifactEvent.artifact.parts);
348
+ if (artifactEvent.artifact.description)
349
+ existingArtifact.description = artifactEvent.artifact.description;
350
+ if (artifactEvent.artifact.name) existingArtifact.name = artifactEvent.artifact.name;
351
+ if (artifactEvent.artifact.metadata)
352
+ existingArtifact.metadata = {
353
+ ...existingArtifact.metadata,
354
+ ...artifactEvent.artifact.metadata
355
+ };
402
356
  } else {
403
- console.warn(`ResultManager: Received status update for unknown task ${updateEvent.taskId}`);
357
+ this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
404
358
  }
359
+ } else {
360
+ this.currentTask.artifacts.push(artifactEvent.artifact);
405
361
  }
406
- } else if (event.kind === "artifact-update") {
407
- const artifactEvent = event;
408
- if (this.currentTask && this.currentTask.id === artifactEvent.taskId) {
409
- if (!this.currentTask.artifacts) {
410
- this.currentTask.artifacts = [];
411
- }
362
+ await this.saveCurrentTask();
363
+ } else if (!this.currentTask && artifactEvent.taskId) {
364
+ const loaded = await this.taskStore.load(artifactEvent.taskId);
365
+ if (loaded) {
366
+ this.currentTask = loaded;
367
+ if (!this.currentTask.artifacts) this.currentTask.artifacts = [];
412
368
  const existingArtifactIndex = this.currentTask.artifacts.findIndex(
413
369
  (art) => art.artifactId === artifactEvent.artifact.artifactId
414
370
  );
415
371
  if (existingArtifactIndex !== -1) {
416
372
  if (artifactEvent.append) {
417
- const existingArtifact = this.currentTask.artifacts[existingArtifactIndex];
418
- existingArtifact.parts.push(...artifactEvent.artifact.parts);
419
- if (artifactEvent.artifact.description) existingArtifact.description = artifactEvent.artifact.description;
420
- if (artifactEvent.artifact.name) existingArtifact.name = artifactEvent.artifact.name;
421
- if (artifactEvent.artifact.metadata) existingArtifact.metadata = __spreadValues(__spreadValues({}, existingArtifact.metadata), artifactEvent.artifact.metadata);
373
+ this.currentTask.artifacts[existingArtifactIndex].parts.push(
374
+ ...artifactEvent.artifact.parts
375
+ );
422
376
  } else {
423
377
  this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
424
378
  }
425
379
  } else {
426
380
  this.currentTask.artifacts.push(artifactEvent.artifact);
427
381
  }
428
- yield this.saveCurrentTask();
429
- } else if (!this.currentTask && artifactEvent.taskId) {
430
- const loaded = yield this.taskStore.load(artifactEvent.taskId);
431
- if (loaded) {
432
- this.currentTask = loaded;
433
- if (!this.currentTask.artifacts) this.currentTask.artifacts = [];
434
- const existingArtifactIndex = this.currentTask.artifacts.findIndex(
435
- (art) => art.artifactId === artifactEvent.artifact.artifactId
436
- );
437
- if (existingArtifactIndex !== -1) {
438
- if (artifactEvent.append) {
439
- this.currentTask.artifacts[existingArtifactIndex].parts.push(...artifactEvent.artifact.parts);
440
- } else {
441
- this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
442
- }
443
- } else {
444
- this.currentTask.artifacts.push(artifactEvent.artifact);
445
- }
446
- yield this.saveCurrentTask();
447
- } else {
448
- console.warn(`ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`);
449
- }
382
+ await this.saveCurrentTask();
383
+ } else {
384
+ console.warn(
385
+ `ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`
386
+ );
450
387
  }
451
388
  }
452
- });
389
+ }
453
390
  }
454
- saveCurrentTask() {
455
- return __async(this, null, function* () {
456
- if (this.currentTask) {
457
- yield this.taskStore.save(this.currentTask);
458
- }
459
- });
391
+ async saveCurrentTask() {
392
+ if (this.currentTask) {
393
+ await this.taskStore.save(this.currentTask);
394
+ }
460
395
  }
461
396
  /**
462
397
  * Gets the final result, which could be a Message or a Task.
@@ -479,440 +414,623 @@ var ResultManager = class {
479
414
  }
480
415
  };
481
416
 
417
+ // src/server/push_notification/push_notification_store.ts
418
+ var InMemoryPushNotificationStore = class {
419
+ store = /* @__PURE__ */ new Map();
420
+ async save(taskId, pushNotificationConfig) {
421
+ const configs = this.store.get(taskId) || [];
422
+ if (!pushNotificationConfig.id) {
423
+ pushNotificationConfig.id = taskId;
424
+ }
425
+ const existingIndex = configs.findIndex((config) => config.id === pushNotificationConfig.id);
426
+ if (existingIndex !== -1) {
427
+ configs.splice(existingIndex, 1);
428
+ }
429
+ configs.push(pushNotificationConfig);
430
+ this.store.set(taskId, configs);
431
+ }
432
+ async load(taskId) {
433
+ const configs = this.store.get(taskId);
434
+ return configs || [];
435
+ }
436
+ async delete(taskId, configId) {
437
+ if (configId === void 0) {
438
+ configId = taskId;
439
+ }
440
+ const configs = this.store.get(taskId);
441
+ if (!configs) {
442
+ return;
443
+ }
444
+ const configIndex = configs.findIndex((config) => config.id === configId);
445
+ if (configIndex !== -1) {
446
+ configs.splice(configIndex, 1);
447
+ }
448
+ if (configs.length === 0) {
449
+ this.store.delete(taskId);
450
+ } else {
451
+ this.store.set(taskId, configs);
452
+ }
453
+ }
454
+ };
455
+
456
+ // src/server/push_notification/default_push_notification_sender.ts
457
+ var DefaultPushNotificationSender = class {
458
+ pushNotificationStore;
459
+ notificationChain;
460
+ options;
461
+ constructor(pushNotificationStore, options = {}) {
462
+ this.pushNotificationStore = pushNotificationStore;
463
+ this.notificationChain = /* @__PURE__ */ new Map();
464
+ this.options = {
465
+ timeout: 5e3,
466
+ tokenHeaderName: "X-A2A-Notification-Token",
467
+ ...options
468
+ };
469
+ }
470
+ async send(task) {
471
+ const pushConfigs = await this.pushNotificationStore.load(task.id);
472
+ if (!pushConfigs || pushConfigs.length === 0) {
473
+ return;
474
+ }
475
+ const lastPromise = this.notificationChain.get(task.id) ?? Promise.resolve();
476
+ const newPromise = lastPromise.then(async () => {
477
+ const dispatches = pushConfigs.map(async (pushConfig) => {
478
+ try {
479
+ await this._dispatchNotification(task, pushConfig);
480
+ } catch (error) {
481
+ console.error(
482
+ `Error sending push notification for task_id=${task.id} to URL: ${pushConfig.url}. Error:`,
483
+ error
484
+ );
485
+ }
486
+ });
487
+ await Promise.all(dispatches);
488
+ });
489
+ this.notificationChain.set(task.id, newPromise);
490
+ newPromise.finally(() => {
491
+ if (this.notificationChain.get(task.id) === newPromise) {
492
+ this.notificationChain.delete(task.id);
493
+ }
494
+ });
495
+ }
496
+ async _dispatchNotification(task, pushConfig) {
497
+ const url = pushConfig.url;
498
+ const controller = new AbortController();
499
+ const timeoutId = setTimeout(() => controller.abort(), this.options.timeout);
500
+ try {
501
+ const headers = {
502
+ "Content-Type": "application/json"
503
+ };
504
+ if (pushConfig.token) {
505
+ headers[this.options.tokenHeaderName] = pushConfig.token;
506
+ }
507
+ const response = await fetch(url, {
508
+ method: "POST",
509
+ headers,
510
+ body: JSON.stringify(task),
511
+ signal: controller.signal
512
+ });
513
+ if (!response.ok) {
514
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
515
+ }
516
+ console.info(`Push notification sent for task_id=${task.id} to URL: ${url}`);
517
+ } finally {
518
+ clearTimeout(timeoutId);
519
+ }
520
+ }
521
+ };
522
+
523
+ // src/server/context.ts
524
+ var ServerCallContext = class {
525
+ _requestedExtensions;
526
+ _user;
527
+ _activatedExtensions;
528
+ constructor(requestedExtensions, user) {
529
+ this._requestedExtensions = requestedExtensions;
530
+ this._user = user;
531
+ }
532
+ get user() {
533
+ return this._user;
534
+ }
535
+ get activatedExtensions() {
536
+ return this._activatedExtensions;
537
+ }
538
+ get requestedExtensions() {
539
+ return this._requestedExtensions;
540
+ }
541
+ addActivatedExtension(uri) {
542
+ if (this._requestedExtensions?.has(uri)) {
543
+ if (!this._activatedExtensions) {
544
+ this._activatedExtensions = /* @__PURE__ */ new Set();
545
+ }
546
+ this._activatedExtensions.add(uri);
547
+ }
548
+ }
549
+ };
550
+
482
551
  // src/server/request_handler/default_request_handler.ts
483
552
  var terminalStates = ["completed", "failed", "canceled", "rejected"];
484
553
  var DefaultRequestHandler = class {
485
- constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), extendedAgentCard) {
486
- // Store for push notification configurations (could be part of TaskStore or separate)
487
- this.pushNotificationConfigs = /* @__PURE__ */ new Map();
554
+ agentCard;
555
+ taskStore;
556
+ agentExecutor;
557
+ eventBusManager;
558
+ pushNotificationStore;
559
+ pushNotificationSender;
560
+ extendedAgentCardProvider;
561
+ constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), pushNotificationStore, pushNotificationSender, extendedAgentCardProvider) {
488
562
  this.agentCard = agentCard;
489
563
  this.taskStore = taskStore;
490
564
  this.agentExecutor = agentExecutor;
491
565
  this.eventBusManager = eventBusManager;
492
- this.extendedAgentCard = extendedAgentCard;
566
+ this.extendedAgentCardProvider = extendedAgentCardProvider;
567
+ if (agentCard.capabilities.pushNotifications) {
568
+ this.pushNotificationStore = pushNotificationStore || new InMemoryPushNotificationStore();
569
+ this.pushNotificationSender = pushNotificationSender || new DefaultPushNotificationSender(this.pushNotificationStore);
570
+ }
493
571
  }
494
- getAgentCard() {
495
- return __async(this, null, function* () {
496
- return this.agentCard;
497
- });
572
+ async getAgentCard() {
573
+ return this.agentCard;
498
574
  }
499
- getAuthenticatedExtendedAgentCard() {
500
- return __async(this, null, function* () {
501
- if (!this.extendedAgentCard) {
502
- throw A2AError.authenticatedExtendedCardNotConfigured();
503
- }
504
- return this.extendedAgentCard;
505
- });
575
+ async getAuthenticatedExtendedAgentCard(context) {
576
+ if (!this.agentCard.supportsAuthenticatedExtendedCard) {
577
+ throw A2AError.unsupportedOperation("Agent does not support authenticated extended card.");
578
+ }
579
+ if (!this.extendedAgentCardProvider) {
580
+ throw A2AError.authenticatedExtendedCardNotConfigured();
581
+ }
582
+ if (typeof this.extendedAgentCardProvider === "function") {
583
+ return this.extendedAgentCardProvider(context);
584
+ }
585
+ if (context?.user?.isAuthenticated) {
586
+ return this.extendedAgentCardProvider;
587
+ }
588
+ return this.agentCard;
506
589
  }
507
- _createRequestContext(incomingMessage, taskId, isStream) {
508
- return __async(this, null, function* () {
509
- let task;
510
- let referenceTasks;
511
- if (incomingMessage.taskId) {
512
- task = yield this.taskStore.load(incomingMessage.taskId);
513
- if (!task) {
514
- throw A2AError.taskNotFound(incomingMessage.taskId);
515
- }
516
- if (terminalStates.includes(task.status.state)) {
517
- throw A2AError.invalidRequest(`Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`);
518
- }
590
+ async _createRequestContext(incomingMessage, context) {
591
+ let task;
592
+ let referenceTasks;
593
+ if (incomingMessage.taskId) {
594
+ task = await this.taskStore.load(incomingMessage.taskId);
595
+ if (!task) {
596
+ throw A2AError.taskNotFound(incomingMessage.taskId);
519
597
  }
520
- if (incomingMessage.referenceTaskIds && incomingMessage.referenceTaskIds.length > 0) {
521
- referenceTasks = [];
522
- for (const refId of incomingMessage.referenceTaskIds) {
523
- const refTask = yield this.taskStore.load(refId);
524
- if (refTask) {
525
- referenceTasks.push(refTask);
526
- } else {
527
- console.warn(`Reference task ${refId} not found.`);
528
- }
598
+ if (terminalStates.includes(task.status.state)) {
599
+ throw A2AError.invalidRequest(
600
+ `Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`
601
+ );
602
+ }
603
+ task.history = [...task.history || [], incomingMessage];
604
+ await this.taskStore.save(task);
605
+ }
606
+ const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
607
+ if (incomingMessage.referenceTaskIds && incomingMessage.referenceTaskIds.length > 0) {
608
+ referenceTasks = [];
609
+ for (const refId of incomingMessage.referenceTaskIds) {
610
+ const refTask = await this.taskStore.load(refId);
611
+ if (refTask) {
612
+ referenceTasks.push(refTask);
613
+ } else {
614
+ console.warn(`Reference task ${refId} not found.`);
529
615
  }
530
616
  }
531
- const contextId = incomingMessage.contextId || (task == null ? void 0 : task.contextId) || (0, import_uuid.v4)();
532
- const messageForContext = __spreadProps(__spreadValues({}, incomingMessage), {
533
- contextId
534
- });
535
- return new RequestContext(
536
- messageForContext,
537
- taskId,
538
- contextId,
539
- task,
540
- referenceTasks
617
+ }
618
+ const contextId = incomingMessage.contextId || task?.contextId || (0, import_uuid.v4)();
619
+ if (context?.requestedExtensions) {
620
+ const agentCard = await this.getAgentCard();
621
+ const exposedExtensions = new Set(
622
+ agentCard.capabilities.extensions?.map((ext) => ext.uri) || []
541
623
  );
542
- });
624
+ const validExtensions = new Set(
625
+ Array.from(context.requestedExtensions).filter(
626
+ (extension) => exposedExtensions.has(extension)
627
+ )
628
+ );
629
+ context = new ServerCallContext(validExtensions, context.user);
630
+ }
631
+ const messageForContext = {
632
+ ...incomingMessage,
633
+ contextId,
634
+ taskId
635
+ };
636
+ return new RequestContext(messageForContext, taskId, contextId, task, referenceTasks, context);
543
637
  }
544
- _processEvents(taskId, resultManager, eventQueue, options) {
545
- return __async(this, null, function* () {
546
- let firstResultSent = false;
547
- try {
638
+ async _processEvents(taskId, resultManager, eventQueue, options) {
639
+ let firstResultSent = false;
640
+ try {
641
+ for await (const event of eventQueue.events()) {
642
+ await resultManager.processEvent(event);
548
643
  try {
549
- for (var iter = __forAwait(eventQueue.events()), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
550
- const event = temp.value;
551
- yield resultManager.processEvent(event);
552
- if ((options == null ? void 0 : options.firstResultResolver) && !firstResultSent) {
553
- if (event.kind === "message" || event.kind === "task") {
554
- options.firstResultResolver(event);
555
- firstResultSent = true;
556
- }
557
- }
644
+ await this._sendPushNotificationIfNeeded(event);
645
+ } catch (error) {
646
+ console.error(`Error sending push notification: ${error}`);
647
+ }
648
+ if (options?.firstResultResolver && !firstResultSent) {
649
+ let firstResult;
650
+ if (event.kind === "message") {
651
+ firstResult = event;
652
+ } else {
653
+ firstResult = resultManager.getCurrentTask();
558
654
  }
559
- } catch (temp) {
560
- error = [temp];
561
- } finally {
562
- try {
563
- more && (temp = iter.return) && (yield temp.call(iter));
564
- } finally {
565
- if (error)
566
- throw error[0];
655
+ if (firstResult) {
656
+ options.firstResultResolver(firstResult);
657
+ firstResultSent = true;
567
658
  }
568
659
  }
569
- if ((options == null ? void 0 : options.firstResultRejector) && !firstResultSent) {
570
- options.firstResultRejector(A2AError.internalError("Execution finished before a message or task was produced."));
571
- }
572
- } catch (error2) {
573
- console.error(`Event processing loop failed for task ${taskId}:`, error2);
574
- if ((options == null ? void 0 : options.firstResultRejector) && !firstResultSent) {
575
- options.firstResultRejector(error2);
576
- }
577
- throw error2;
578
- } finally {
579
- this.eventBusManager.cleanupByTaskId(taskId);
580
- }
581
- });
582
- }
583
- sendMessage(params) {
584
- return __async(this, null, function* () {
585
- var _a;
586
- const incomingMessage = params.message;
587
- if (!incomingMessage.messageId) {
588
- throw A2AError.invalidParams("message.messageId is required.");
589
660
  }
590
- const isBlocking = ((_a = params.configuration) == null ? void 0 : _a.blocking) !== false;
591
- const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
592
- const resultManager = new ResultManager(this.taskStore);
593
- resultManager.setContext(incomingMessage);
594
- const requestContext = yield this._createRequestContext(incomingMessage, taskId, false);
595
- const finalMessageForAgent = requestContext.userMessage;
596
- const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
597
- const eventQueue = new ExecutionEventQueue(eventBus);
598
- this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
599
- var _a2, _b, _c, _d, _e;
600
- console.error(`Agent execution failed for message ${finalMessageForAgent.messageId}:`, err);
601
- const errorTask = {
602
- id: ((_a2 = requestContext.task) == null ? void 0 : _a2.id) || (0, import_uuid.v4)(),
603
- // Use existing task ID or generate new
604
- contextId: finalMessageForAgent.contextId,
605
- status: {
606
- state: "failed",
607
- message: {
608
- kind: "message",
609
- role: "agent",
610
- messageId: (0, import_uuid.v4)(),
611
- parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
612
- taskId: (_b = requestContext.task) == null ? void 0 : _b.id,
613
- contextId: finalMessageForAgent.contextId
614
- },
615
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
616
- },
617
- history: ((_c = requestContext.task) == null ? void 0 : _c.history) ? [...requestContext.task.history] : [],
618
- kind: "task"
619
- };
620
- if (finalMessageForAgent) {
621
- if (!((_d = errorTask.history) == null ? void 0 : _d.find((m) => m.messageId === finalMessageForAgent.messageId))) {
622
- (_e = errorTask.history) == null ? void 0 : _e.push(finalMessageForAgent);
623
- }
624
- }
625
- eventBus.publish(errorTask);
626
- eventBus.publish({
627
- // And publish a final status update
628
- kind: "status-update",
629
- taskId: errorTask.id,
630
- contextId: errorTask.contextId,
631
- status: errorTask.status,
632
- final: true
633
- });
634
- eventBus.finished();
635
- });
636
- if (isBlocking) {
637
- yield this._processEvents(taskId, resultManager, eventQueue);
638
- const finalResult = resultManager.getFinalResult();
639
- if (!finalResult) {
640
- throw A2AError.internalError("Agent execution finished without a result, and no task context found.");
641
- }
642
- return finalResult;
643
- } else {
644
- return new Promise((resolve, reject) => {
645
- this._processEvents(taskId, resultManager, eventQueue, {
646
- firstResultResolver: resolve,
647
- firstResultRejector: reject
648
- });
649
- });
661
+ if (options?.firstResultRejector && !firstResultSent) {
662
+ options.firstResultRejector(
663
+ A2AError.internalError("Execution finished before a message or task was produced.")
664
+ );
650
665
  }
651
- });
666
+ } catch (error) {
667
+ console.error(`Event processing loop failed for task ${taskId}:`, error);
668
+ this._handleProcessingError(
669
+ error,
670
+ resultManager,
671
+ firstResultSent,
672
+ taskId,
673
+ options?.firstResultRejector
674
+ );
675
+ } finally {
676
+ this.eventBusManager.cleanupByTaskId(taskId);
677
+ }
652
678
  }
653
- sendMessageStream(params) {
654
- return __asyncGenerator(this, null, function* () {
655
- const incomingMessage = params.message;
656
- if (!incomingMessage.messageId) {
657
- throw A2AError.invalidParams("message.messageId is required for streaming.");
658
- }
659
- const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
660
- const resultManager = new ResultManager(this.taskStore);
661
- resultManager.setContext(incomingMessage);
662
- const requestContext = yield new __await(this._createRequestContext(incomingMessage, taskId, true));
663
- const finalMessageForAgent = requestContext.userMessage;
664
- const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
665
- const eventQueue = new ExecutionEventQueue(eventBus);
666
- this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
667
- var _a, _b;
668
- console.error(`Agent execution failed for stream message ${finalMessageForAgent.messageId}:`, err);
669
- const errorTaskStatus = {
670
- kind: "status-update",
671
- taskId: ((_a = requestContext.task) == null ? void 0 : _a.id) || (0, import_uuid.v4)(),
672
- // Use existing or a placeholder
673
- contextId: finalMessageForAgent.contextId,
674
- status: {
675
- state: "failed",
676
- message: {
677
- kind: "message",
678
- role: "agent",
679
- messageId: (0, import_uuid.v4)(),
680
- parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
681
- taskId: (_b = requestContext.task) == null ? void 0 : _b.id,
682
- contextId: finalMessageForAgent.contextId
683
- },
684
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
679
+ async sendMessage(params, context) {
680
+ const incomingMessage = params.message;
681
+ if (!incomingMessage.messageId) {
682
+ throw A2AError.invalidParams("message.messageId is required.");
683
+ }
684
+ const isBlocking = params.configuration?.blocking !== false;
685
+ const resultManager = new ResultManager(this.taskStore);
686
+ resultManager.setContext(incomingMessage);
687
+ const requestContext = await this._createRequestContext(incomingMessage, context);
688
+ const taskId = requestContext.taskId;
689
+ const finalMessageForAgent = requestContext.userMessage;
690
+ if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
691
+ await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
692
+ }
693
+ const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
694
+ const eventQueue = new ExecutionEventQueue(eventBus);
695
+ this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
696
+ console.error(`Agent execution failed for message ${finalMessageForAgent.messageId}:`, err);
697
+ const errorTask = {
698
+ id: requestContext.task?.id || (0, import_uuid.v4)(),
699
+ // Use existing task ID or generate new
700
+ contextId: finalMessageForAgent.contextId,
701
+ status: {
702
+ state: "failed",
703
+ message: {
704
+ kind: "message",
705
+ role: "agent",
706
+ messageId: (0, import_uuid.v4)(),
707
+ parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
708
+ taskId: requestContext.task?.id,
709
+ contextId: finalMessageForAgent.contextId
685
710
  },
686
- final: true
687
- // This will terminate the stream for the client
688
- };
689
- eventBus.publish(errorTaskStatus);
690
- });
691
- try {
692
- try {
693
- for (var iter = __forAwait(eventQueue.events()), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
694
- const event = temp.value;
695
- yield new __await(resultManager.processEvent(event));
696
- yield event;
697
- }
698
- } catch (temp) {
699
- error = [temp];
700
- } finally {
701
- try {
702
- more && (temp = iter.return) && (yield new __await(temp.call(iter)));
703
- } finally {
704
- if (error)
705
- throw error[0];
706
- }
711
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
712
+ },
713
+ history: requestContext.task?.history ? [...requestContext.task.history] : [],
714
+ kind: "task"
715
+ };
716
+ if (finalMessageForAgent) {
717
+ if (!errorTask.history?.find((m) => m.messageId === finalMessageForAgent.messageId)) {
718
+ errorTask.history?.push(finalMessageForAgent);
707
719
  }
708
- } finally {
709
- this.eventBusManager.cleanupByTaskId(taskId);
710
720
  }
721
+ eventBus.publish(errorTask);
722
+ eventBus.publish({
723
+ // And publish a final status update
724
+ kind: "status-update",
725
+ taskId: errorTask.id,
726
+ contextId: errorTask.contextId,
727
+ status: errorTask.status,
728
+ final: true
729
+ });
730
+ eventBus.finished();
711
731
  });
712
- }
713
- getTask(params) {
714
- return __async(this, null, function* () {
715
- const task = yield this.taskStore.load(params.id);
716
- if (!task) {
717
- throw A2AError.taskNotFound(params.id);
718
- }
719
- if (params.historyLength !== void 0 && params.historyLength >= 0) {
720
- if (task.history) {
721
- task.history = task.history.slice(-params.historyLength);
722
- }
723
- } else {
724
- task.history = [];
732
+ if (isBlocking) {
733
+ await this._processEvents(taskId, resultManager, eventQueue);
734
+ const finalResult = resultManager.getFinalResult();
735
+ if (!finalResult) {
736
+ throw A2AError.internalError(
737
+ "Agent execution finished without a result, and no task context found."
738
+ );
725
739
  }
726
- return task;
727
- });
740
+ return finalResult;
741
+ } else {
742
+ return new Promise((resolve, reject) => {
743
+ this._processEvents(taskId, resultManager, eventQueue, {
744
+ firstResultResolver: resolve,
745
+ firstResultRejector: reject
746
+ });
747
+ });
748
+ }
728
749
  }
729
- cancelTask(params) {
730
- return __async(this, null, function* () {
731
- const task = yield this.taskStore.load(params.id);
732
- if (!task) {
733
- throw A2AError.taskNotFound(params.id);
734
- }
735
- const nonCancelableStates = ["completed", "failed", "canceled", "rejected"];
736
- if (nonCancelableStates.includes(task.status.state)) {
737
- throw A2AError.taskNotCancelable(params.id);
738
- }
739
- const eventBus = this.eventBusManager.getByTaskId(params.id);
740
- if (eventBus) {
741
- yield this.agentExecutor.cancelTask(params.id, eventBus);
742
- } else {
743
- task.status = {
744
- state: "canceled",
750
+ async *sendMessageStream(params, context) {
751
+ const incomingMessage = params.message;
752
+ if (!incomingMessage.messageId) {
753
+ throw A2AError.invalidParams("message.messageId is required for streaming.");
754
+ }
755
+ const resultManager = new ResultManager(this.taskStore);
756
+ resultManager.setContext(incomingMessage);
757
+ const requestContext = await this._createRequestContext(incomingMessage, context);
758
+ const taskId = requestContext.taskId;
759
+ const finalMessageForAgent = requestContext.userMessage;
760
+ const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
761
+ const eventQueue = new ExecutionEventQueue(eventBus);
762
+ if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
763
+ await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
764
+ }
765
+ this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
766
+ console.error(
767
+ `Agent execution failed for stream message ${finalMessageForAgent.messageId}:`,
768
+ err
769
+ );
770
+ const errorTaskStatus = {
771
+ kind: "status-update",
772
+ taskId: requestContext.task?.id || (0, import_uuid.v4)(),
773
+ // Use existing or a placeholder
774
+ contextId: finalMessageForAgent.contextId,
775
+ status: {
776
+ state: "failed",
745
777
  message: {
746
- // Optional: Add a system message indicating cancellation
747
778
  kind: "message",
748
779
  role: "agent",
749
780
  messageId: (0, import_uuid.v4)(),
750
- parts: [{ kind: "text", text: "Task cancellation requested by user." }],
751
- taskId: task.id,
752
- contextId: task.contextId
781
+ parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
782
+ taskId: requestContext.task?.id,
783
+ contextId: finalMessageForAgent.contextId
753
784
  },
754
785
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
755
- };
756
- task.history = [...task.history || [], task.status.message];
757
- yield this.taskStore.save(task);
758
- }
759
- const latestTask = yield this.taskStore.load(params.id);
760
- return latestTask;
786
+ },
787
+ final: true
788
+ // This will terminate the stream for the client
789
+ };
790
+ eventBus.publish(errorTaskStatus);
761
791
  });
762
- }
763
- setTaskPushNotificationConfig(params) {
764
- return __async(this, null, function* () {
765
- if (!this.agentCard.capabilities.pushNotifications) {
766
- throw A2AError.pushNotificationNotSupported();
767
- }
768
- const task = yield this.taskStore.load(params.taskId);
769
- if (!task) {
770
- throw A2AError.taskNotFound(params.taskId);
771
- }
772
- const { taskId, pushNotificationConfig } = params;
773
- if (!pushNotificationConfig.id) {
774
- pushNotificationConfig.id = taskId;
792
+ try {
793
+ for await (const event of eventQueue.events()) {
794
+ await resultManager.processEvent(event);
795
+ await this._sendPushNotificationIfNeeded(event);
796
+ yield event;
775
797
  }
776
- const configs = this.pushNotificationConfigs.get(taskId) || [];
777
- const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfig.id);
778
- updatedConfigs.push(pushNotificationConfig);
779
- this.pushNotificationConfigs.set(taskId, updatedConfigs);
780
- return params;
781
- });
798
+ } finally {
799
+ this.eventBusManager.cleanupByTaskId(taskId);
800
+ }
782
801
  }
783
- getTaskPushNotificationConfig(params) {
784
- return __async(this, null, function* () {
785
- if (!this.agentCard.capabilities.pushNotifications) {
786
- throw A2AError.pushNotificationNotSupported();
787
- }
788
- const task = yield this.taskStore.load(params.id);
789
- if (!task) {
790
- throw A2AError.taskNotFound(params.id);
791
- }
792
- const configs = this.pushNotificationConfigs.get(params.id) || [];
793
- if (configs.length === 0) {
794
- throw A2AError.internalError(`Push notification config not found for task ${params.id}.`);
795
- }
796
- let configId;
797
- if ("pushNotificationConfigId" in params && params.pushNotificationConfigId) {
798
- configId = params.pushNotificationConfigId;
799
- } else {
800
- configId = params.id;
801
- }
802
- const config = configs.find((c) => c.id === configId);
803
- if (!config) {
804
- throw A2AError.internalError(`Push notification config with id '${configId}' not found for task ${params.id}.`);
802
+ async getTask(params, _context) {
803
+ const task = await this.taskStore.load(params.id);
804
+ if (!task) {
805
+ throw A2AError.taskNotFound(params.id);
806
+ }
807
+ if (params.historyLength !== void 0 && params.historyLength >= 0) {
808
+ if (task.history) {
809
+ task.history = task.history.slice(-params.historyLength);
805
810
  }
806
- return { taskId: params.id, pushNotificationConfig: config };
807
- });
811
+ } else {
812
+ task.history = [];
813
+ }
814
+ return task;
808
815
  }
809
- listTaskPushNotificationConfigs(params) {
810
- return __async(this, null, function* () {
811
- if (!this.agentCard.capabilities.pushNotifications) {
812
- throw A2AError.pushNotificationNotSupported();
813
- }
814
- const task = yield this.taskStore.load(params.id);
815
- if (!task) {
816
- throw A2AError.taskNotFound(params.id);
817
- }
818
- const configs = this.pushNotificationConfigs.get(params.id) || [];
819
- return configs.map((config) => ({
820
- taskId: params.id,
821
- pushNotificationConfig: config
822
- }));
823
- });
816
+ async cancelTask(params, _context) {
817
+ const task = await this.taskStore.load(params.id);
818
+ if (!task) {
819
+ throw A2AError.taskNotFound(params.id);
820
+ }
821
+ const nonCancelableStates = ["completed", "failed", "canceled", "rejected"];
822
+ if (nonCancelableStates.includes(task.status.state)) {
823
+ throw A2AError.taskNotCancelable(params.id);
824
+ }
825
+ const eventBus = this.eventBusManager.getByTaskId(params.id);
826
+ if (eventBus) {
827
+ const eventQueue = new ExecutionEventQueue(eventBus);
828
+ await this.agentExecutor.cancelTask(params.id, eventBus);
829
+ await this._processEvents(params.id, new ResultManager(this.taskStore), eventQueue);
830
+ } else {
831
+ task.status = {
832
+ state: "canceled",
833
+ message: {
834
+ // Optional: Add a system message indicating cancellation
835
+ kind: "message",
836
+ role: "agent",
837
+ messageId: (0, import_uuid.v4)(),
838
+ parts: [{ kind: "text", text: "Task cancellation requested by user." }],
839
+ taskId: task.id,
840
+ contextId: task.contextId
841
+ },
842
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
843
+ };
844
+ task.history = [...task.history || [], task.status.message];
845
+ await this.taskStore.save(task);
846
+ }
847
+ const latestTask = await this.taskStore.load(params.id);
848
+ if (!latestTask) {
849
+ throw A2AError.internalError(`Task ${params.id} not found after cancellation.`);
850
+ }
851
+ if (latestTask.status.state != "canceled") {
852
+ throw A2AError.taskNotCancelable(params.id);
853
+ }
854
+ return latestTask;
824
855
  }
825
- deleteTaskPushNotificationConfig(params) {
826
- return __async(this, null, function* () {
827
- if (!this.agentCard.capabilities.pushNotifications) {
828
- throw A2AError.pushNotificationNotSupported();
829
- }
830
- const task = yield this.taskStore.load(params.id);
831
- if (!task) {
832
- throw A2AError.taskNotFound(params.id);
833
- }
834
- const { id: taskId, pushNotificationConfigId } = params;
835
- const configs = this.pushNotificationConfigs.get(taskId);
836
- if (!configs) {
837
- return;
838
- }
839
- const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfigId);
840
- if (updatedConfigs.length === 0) {
841
- this.pushNotificationConfigs.delete(taskId);
842
- } else if (updatedConfigs.length < configs.length) {
843
- this.pushNotificationConfigs.set(taskId, updatedConfigs);
844
- }
845
- });
856
+ async setTaskPushNotificationConfig(params, _context) {
857
+ if (!this.agentCard.capabilities.pushNotifications) {
858
+ throw A2AError.pushNotificationNotSupported();
859
+ }
860
+ const task = await this.taskStore.load(params.taskId);
861
+ if (!task) {
862
+ throw A2AError.taskNotFound(params.taskId);
863
+ }
864
+ const { taskId, pushNotificationConfig } = params;
865
+ if (!pushNotificationConfig.id) {
866
+ pushNotificationConfig.id = taskId;
867
+ }
868
+ await this.pushNotificationStore?.save(taskId, pushNotificationConfig);
869
+ return params;
846
870
  }
847
- resubscribe(params) {
848
- return __asyncGenerator(this, null, function* () {
849
- if (!this.agentCard.capabilities.streaming) {
850
- throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
851
- }
852
- const task = yield new __await(this.taskStore.load(params.id));
853
- if (!task) {
854
- throw A2AError.taskNotFound(params.id);
855
- }
856
- yield task;
857
- const finalStates = ["completed", "failed", "canceled", "rejected"];
858
- if (finalStates.includes(task.status.state)) {
859
- return;
860
- }
861
- const eventBus = this.eventBusManager.getByTaskId(params.id);
862
- if (!eventBus) {
863
- console.warn(`Resubscribe: No active event bus for task ${params.id}.`);
864
- return;
865
- }
866
- const eventQueue = new ExecutionEventQueue(eventBus);
867
- try {
868
- try {
869
- for (var iter = __forAwait(eventQueue.events()), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
870
- const event = temp.value;
871
- if (event.kind === "status-update" && event.taskId === params.id) {
872
- yield event;
873
- } else if (event.kind === "artifact-update" && event.taskId === params.id) {
874
- yield event;
875
- } else if (event.kind === "task" && event.id === params.id) {
876
- yield event;
877
- }
878
- }
879
- } catch (temp) {
880
- error = [temp];
881
- } finally {
882
- try {
883
- more && (temp = iter.return) && (yield new __await(temp.call(iter)));
884
- } finally {
885
- if (error)
886
- throw error[0];
887
- }
871
+ async getTaskPushNotificationConfig(params, _context) {
872
+ if (!this.agentCard.capabilities.pushNotifications) {
873
+ throw A2AError.pushNotificationNotSupported();
874
+ }
875
+ const task = await this.taskStore.load(params.id);
876
+ if (!task) {
877
+ throw A2AError.taskNotFound(params.id);
878
+ }
879
+ const configs = await this.pushNotificationStore?.load(params.id) || [];
880
+ if (configs.length === 0) {
881
+ throw A2AError.internalError(`Push notification config not found for task ${params.id}.`);
882
+ }
883
+ let configId;
884
+ if ("pushNotificationConfigId" in params && params.pushNotificationConfigId) {
885
+ configId = params.pushNotificationConfigId;
886
+ } else {
887
+ configId = params.id;
888
+ }
889
+ const config = configs.find((c) => c.id === configId);
890
+ if (!config) {
891
+ throw A2AError.internalError(
892
+ `Push notification config with id '${configId}' not found for task ${params.id}.`
893
+ );
894
+ }
895
+ return { taskId: params.id, pushNotificationConfig: config };
896
+ }
897
+ async listTaskPushNotificationConfigs(params, _context) {
898
+ if (!this.agentCard.capabilities.pushNotifications) {
899
+ throw A2AError.pushNotificationNotSupported();
900
+ }
901
+ const task = await this.taskStore.load(params.id);
902
+ if (!task) {
903
+ throw A2AError.taskNotFound(params.id);
904
+ }
905
+ const configs = await this.pushNotificationStore?.load(params.id) || [];
906
+ return configs.map((config) => ({
907
+ taskId: params.id,
908
+ pushNotificationConfig: config
909
+ }));
910
+ }
911
+ async deleteTaskPushNotificationConfig(params, _context) {
912
+ if (!this.agentCard.capabilities.pushNotifications) {
913
+ throw A2AError.pushNotificationNotSupported();
914
+ }
915
+ const task = await this.taskStore.load(params.id);
916
+ if (!task) {
917
+ throw A2AError.taskNotFound(params.id);
918
+ }
919
+ const { id: taskId, pushNotificationConfigId } = params;
920
+ await this.pushNotificationStore?.delete(taskId, pushNotificationConfigId);
921
+ }
922
+ async *resubscribe(params, _context) {
923
+ if (!this.agentCard.capabilities.streaming) {
924
+ throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
925
+ }
926
+ const task = await this.taskStore.load(params.id);
927
+ if (!task) {
928
+ throw A2AError.taskNotFound(params.id);
929
+ }
930
+ yield task;
931
+ const finalStates = ["completed", "failed", "canceled", "rejected"];
932
+ if (finalStates.includes(task.status.state)) {
933
+ return;
934
+ }
935
+ const eventBus = this.eventBusManager.getByTaskId(params.id);
936
+ if (!eventBus) {
937
+ console.warn(`Resubscribe: No active event bus for task ${params.id}.`);
938
+ return;
939
+ }
940
+ const eventQueue = new ExecutionEventQueue(eventBus);
941
+ try {
942
+ for await (const event of eventQueue.events()) {
943
+ if (event.kind === "status-update" && event.taskId === params.id) {
944
+ yield event;
945
+ } else if (event.kind === "artifact-update" && event.taskId === params.id) {
946
+ yield event;
947
+ } else if (event.kind === "task" && event.id === params.id) {
948
+ yield event;
888
949
  }
889
- } finally {
890
- eventQueue.stop();
891
950
  }
892
- });
951
+ } finally {
952
+ eventQueue.stop();
953
+ }
954
+ }
955
+ async _sendPushNotificationIfNeeded(event) {
956
+ if (!this.agentCard.capabilities.pushNotifications) {
957
+ return;
958
+ }
959
+ let taskId = "";
960
+ if (event.kind == "task") {
961
+ const task2 = event;
962
+ taskId = task2.id;
963
+ } else {
964
+ taskId = event.taskId;
965
+ }
966
+ if (!taskId) {
967
+ console.error(`Task ID not found for event ${event.kind}.`);
968
+ return;
969
+ }
970
+ const task = await this.taskStore.load(taskId);
971
+ if (!task) {
972
+ console.error(`Task ${taskId} not found.`);
973
+ return;
974
+ }
975
+ this.pushNotificationSender?.send(task);
976
+ }
977
+ async _handleProcessingError(error, resultManager, firstResultSent, taskId, firstResultRejector) {
978
+ if (firstResultRejector && !firstResultSent) {
979
+ firstResultRejector(error);
980
+ return;
981
+ }
982
+ if (!firstResultRejector) {
983
+ throw error;
984
+ }
985
+ const currentTask = resultManager.getCurrentTask();
986
+ const errorMessage = error instanceof Error && error.message || "Unknown error";
987
+ if (currentTask) {
988
+ const statusUpdateFailed = {
989
+ taskId: currentTask.id,
990
+ contextId: currentTask.contextId,
991
+ status: {
992
+ state: "failed",
993
+ message: {
994
+ kind: "message",
995
+ role: "agent",
996
+ messageId: (0, import_uuid.v4)(),
997
+ parts: [{ kind: "text", text: `Event processing loop failed: ${errorMessage}` }],
998
+ taskId: currentTask.id,
999
+ contextId: currentTask.contextId
1000
+ },
1001
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1002
+ },
1003
+ kind: "status-update",
1004
+ final: true
1005
+ };
1006
+ try {
1007
+ await resultManager.processEvent(statusUpdateFailed);
1008
+ } catch (error2) {
1009
+ console.error(
1010
+ `Event processing loop failed for task ${taskId}: ${error2 instanceof Error && error2.message || "Unknown error"}`
1011
+ );
1012
+ }
1013
+ } else {
1014
+ console.error(`Event processing loop failed for task ${taskId}: ${errorMessage}`);
1015
+ }
893
1016
  }
894
1017
  };
895
1018
 
896
1019
  // src/server/store.ts
897
1020
  var InMemoryTaskStore = class {
898
- constructor() {
899
- this.store = /* @__PURE__ */ new Map();
900
- }
901
- load(taskId) {
902
- return __async(this, null, function* () {
903
- const entry = this.store.get(taskId);
904
- return entry ? __spreadValues({}, entry) : void 0;
905
- });
1021
+ store = /* @__PURE__ */ new Map();
1022
+ async load(taskId) {
1023
+ const entry = this.store.get(taskId);
1024
+ return entry ? { ...entry } : void 0;
906
1025
  }
907
- save(task) {
908
- return __async(this, null, function* () {
909
- this.store.set(task.id, __spreadValues({}, task));
910
- });
1026
+ async save(task) {
1027
+ this.store.set(task.id, { ...task });
911
1028
  }
912
1029
  };
913
1030
 
914
1031
  // src/server/transports/jsonrpc_transport_handler.ts
915
1032
  var JsonRpcTransportHandler = class {
1033
+ requestHandler;
916
1034
  constructor(requestHandler) {
917
1035
  this.requestHandler = requestHandler;
918
1036
  }
@@ -921,156 +1039,556 @@ var JsonRpcTransportHandler = class {
921
1039
  * For streaming methods, it returns an AsyncGenerator of JSONRPCResult.
922
1040
  * For non-streaming methods, it returns a Promise of a single JSONRPCMessage (Result or ErrorResponse).
923
1041
  */
924
- handle(requestBody) {
925
- return __async(this, null, function* () {
926
- let rpcRequest;
927
- try {
928
- if (typeof requestBody === "string") {
929
- rpcRequest = JSON.parse(requestBody);
930
- } else if (typeof requestBody === "object" && requestBody !== null) {
931
- rpcRequest = requestBody;
932
- } else {
933
- throw A2AError.parseError("Invalid request body type.");
1042
+ async handle(requestBody, context) {
1043
+ let rpcRequest;
1044
+ try {
1045
+ if (typeof requestBody === "string") {
1046
+ rpcRequest = JSON.parse(requestBody);
1047
+ } else if (typeof requestBody === "object" && requestBody !== null) {
1048
+ rpcRequest = requestBody;
1049
+ } else {
1050
+ throw A2AError.parseError("Invalid request body type.");
1051
+ }
1052
+ if (!this.isRequestValid(rpcRequest)) {
1053
+ throw A2AError.invalidRequest("Invalid JSON-RPC Request.");
1054
+ }
1055
+ } catch (error) {
1056
+ const a2aError = error instanceof A2AError ? error : A2AError.parseError(
1057
+ error instanceof SyntaxError && error.message || "Failed to parse JSON request."
1058
+ );
1059
+ return {
1060
+ jsonrpc: "2.0",
1061
+ id: rpcRequest?.id !== void 0 ? rpcRequest.id : null,
1062
+ error: a2aError.toJSONRPCError()
1063
+ };
1064
+ }
1065
+ const { method, id: requestId = null } = rpcRequest;
1066
+ try {
1067
+ if (method !== "agent/getAuthenticatedExtendedCard" && !this.paramsAreValid(rpcRequest.params)) {
1068
+ throw A2AError.invalidParams(`Invalid method parameters.`);
1069
+ }
1070
+ if (method === "message/stream" || method === "tasks/resubscribe") {
1071
+ const params = rpcRequest.params;
1072
+ const agentCard = await this.requestHandler.getAgentCard();
1073
+ if (!agentCard.capabilities.streaming) {
1074
+ throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
934
1075
  }
935
- if (rpcRequest.jsonrpc !== "2.0" || !rpcRequest.method || typeof rpcRequest.method !== "string") {
936
- throw A2AError.invalidRequest(
937
- "Invalid JSON-RPC request structure."
938
- );
1076
+ const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params, context) : this.requestHandler.resubscribe(params, context);
1077
+ return (async function* jsonRpcEventStream() {
1078
+ try {
1079
+ for await (const event of agentEventStream) {
1080
+ yield {
1081
+ jsonrpc: "2.0",
1082
+ id: requestId,
1083
+ // Use the original request ID for all streamed responses
1084
+ result: event
1085
+ };
1086
+ }
1087
+ } catch (streamError) {
1088
+ console.error(
1089
+ `Error in agent event stream for ${method} (request ${requestId}):`,
1090
+ streamError
1091
+ );
1092
+ throw streamError;
1093
+ }
1094
+ })();
1095
+ } else {
1096
+ let result;
1097
+ switch (method) {
1098
+ case "message/send":
1099
+ result = await this.requestHandler.sendMessage(rpcRequest.params, context);
1100
+ break;
1101
+ case "tasks/get":
1102
+ result = await this.requestHandler.getTask(rpcRequest.params, context);
1103
+ break;
1104
+ case "tasks/cancel":
1105
+ result = await this.requestHandler.cancelTask(rpcRequest.params, context);
1106
+ break;
1107
+ case "tasks/pushNotificationConfig/set":
1108
+ result = await this.requestHandler.setTaskPushNotificationConfig(
1109
+ rpcRequest.params,
1110
+ context
1111
+ );
1112
+ break;
1113
+ case "tasks/pushNotificationConfig/get":
1114
+ result = await this.requestHandler.getTaskPushNotificationConfig(
1115
+ rpcRequest.params,
1116
+ context
1117
+ );
1118
+ break;
1119
+ case "tasks/pushNotificationConfig/delete":
1120
+ await this.requestHandler.deleteTaskPushNotificationConfig(rpcRequest.params, context);
1121
+ result = null;
1122
+ break;
1123
+ case "tasks/pushNotificationConfig/list":
1124
+ result = await this.requestHandler.listTaskPushNotificationConfigs(
1125
+ rpcRequest.params,
1126
+ context
1127
+ );
1128
+ break;
1129
+ case "agent/getAuthenticatedExtendedCard":
1130
+ result = await this.requestHandler.getAuthenticatedExtendedAgentCard(context);
1131
+ break;
1132
+ default:
1133
+ throw A2AError.methodNotFound(method);
939
1134
  }
940
- } catch (error) {
941
- const a2aError = error instanceof A2AError ? error : A2AError.parseError(error.message || "Failed to parse JSON request.");
942
1135
  return {
943
1136
  jsonrpc: "2.0",
944
- id: typeof (rpcRequest == null ? void 0 : rpcRequest.id) !== "undefined" ? rpcRequest.id : null,
945
- error: a2aError.toJSONRPCError()
1137
+ id: requestId,
1138
+ result
946
1139
  };
947
1140
  }
948
- const { method, id: requestId = null } = rpcRequest;
1141
+ } catch (error) {
1142
+ let a2aError;
1143
+ if (error instanceof A2AError) {
1144
+ a2aError = error;
1145
+ } else {
1146
+ a2aError = A2AError.internalError(
1147
+ error instanceof Error && error.message || "An unexpected error occurred."
1148
+ );
1149
+ }
1150
+ return {
1151
+ jsonrpc: "2.0",
1152
+ id: requestId,
1153
+ error: a2aError.toJSONRPCError()
1154
+ };
1155
+ }
1156
+ }
1157
+ // Validates the basic structure of a JSON-RPC request
1158
+ isRequestValid(rpcRequest) {
1159
+ if (rpcRequest.jsonrpc !== "2.0") {
1160
+ return false;
1161
+ }
1162
+ if ("id" in rpcRequest) {
1163
+ const id = rpcRequest.id;
1164
+ const isString = typeof id === "string";
1165
+ const isInteger = typeof id === "number" && Number.isInteger(id);
1166
+ const isNull = id === null;
1167
+ if (!isString && !isInteger && !isNull) {
1168
+ return false;
1169
+ }
1170
+ }
1171
+ if (!rpcRequest.method || typeof rpcRequest.method !== "string") {
1172
+ return false;
1173
+ }
1174
+ return true;
1175
+ }
1176
+ // Validates that params is an object with non-empty string keys
1177
+ paramsAreValid(params) {
1178
+ if (typeof params !== "object" || params === null || Array.isArray(params)) {
1179
+ return false;
1180
+ }
1181
+ for (const key of Object.keys(params)) {
1182
+ if (key === "") {
1183
+ return false;
1184
+ }
1185
+ }
1186
+ return true;
1187
+ }
1188
+ };
1189
+
1190
+ // src/errors.ts
1191
+ var TaskNotFoundError = class extends Error {
1192
+ constructor(message) {
1193
+ super(message ?? "Task not found");
1194
+ this.name = "TaskNotFoundError";
1195
+ }
1196
+ };
1197
+ var TaskNotCancelableError = class extends Error {
1198
+ constructor(message) {
1199
+ super(message ?? "Task cannot be canceled");
1200
+ this.name = "TaskNotCancelableError";
1201
+ }
1202
+ };
1203
+ var PushNotificationNotSupportedError = class extends Error {
1204
+ constructor(message) {
1205
+ super(message ?? "Push Notification is not supported");
1206
+ this.name = "PushNotificationNotSupportedError";
1207
+ }
1208
+ };
1209
+ var UnsupportedOperationError = class extends Error {
1210
+ constructor(message) {
1211
+ super(message ?? "This operation is not supported");
1212
+ this.name = "UnsupportedOperationError";
1213
+ }
1214
+ };
1215
+ var ContentTypeNotSupportedError = class extends Error {
1216
+ constructor(message) {
1217
+ super(message ?? "Incompatible content types");
1218
+ this.name = "ContentTypeNotSupportedError";
1219
+ }
1220
+ };
1221
+ var InvalidAgentResponseError = class extends Error {
1222
+ constructor(message) {
1223
+ super(message ?? "Invalid agent response type");
1224
+ this.name = "InvalidAgentResponseError";
1225
+ }
1226
+ };
1227
+ var AuthenticatedExtendedCardNotConfiguredError = class extends Error {
1228
+ constructor(message) {
1229
+ super(message ?? "Authenticated Extended Card not configured");
1230
+ this.name = "AuthenticatedExtendedCardNotConfiguredError";
1231
+ }
1232
+ };
1233
+
1234
+ // src/client/transports/json_rpc_transport.ts
1235
+ var JsonRpcTransport = class _JsonRpcTransport {
1236
+ customFetchImpl;
1237
+ endpoint;
1238
+ requestIdCounter = 1;
1239
+ constructor(options) {
1240
+ this.endpoint = options.endpoint;
1241
+ this.customFetchImpl = options.fetchImpl;
1242
+ }
1243
+ async sendMessage(params, options, idOverride) {
1244
+ const rpcResponse = await this._sendRpcRequest(
1245
+ "message/send",
1246
+ params,
1247
+ idOverride,
1248
+ options
1249
+ );
1250
+ return rpcResponse.result;
1251
+ }
1252
+ async *sendMessageStream(params, options) {
1253
+ yield* this._sendStreamingRequest("message/stream", params, options);
1254
+ }
1255
+ async setTaskPushNotificationConfig(params, options, idOverride) {
1256
+ const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/set", params, idOverride, options);
1257
+ return rpcResponse.result;
1258
+ }
1259
+ async getTaskPushNotificationConfig(params, options, idOverride) {
1260
+ const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/get", params, idOverride, options);
1261
+ return rpcResponse.result;
1262
+ }
1263
+ async listTaskPushNotificationConfig(params, options, idOverride) {
1264
+ const rpcResponse = await this._sendRpcRequest("tasks/pushNotificationConfig/list", params, idOverride, options);
1265
+ return rpcResponse.result;
1266
+ }
1267
+ async deleteTaskPushNotificationConfig(params, options, idOverride) {
1268
+ await this._sendRpcRequest("tasks/pushNotificationConfig/delete", params, idOverride, options);
1269
+ }
1270
+ async getTask(params, options, idOverride) {
1271
+ const rpcResponse = await this._sendRpcRequest(
1272
+ "tasks/get",
1273
+ params,
1274
+ idOverride,
1275
+ options
1276
+ );
1277
+ return rpcResponse.result;
1278
+ }
1279
+ async cancelTask(params, options, idOverride) {
1280
+ const rpcResponse = await this._sendRpcRequest(
1281
+ "tasks/cancel",
1282
+ params,
1283
+ idOverride,
1284
+ options
1285
+ );
1286
+ return rpcResponse.result;
1287
+ }
1288
+ async *resubscribeTask(params, options) {
1289
+ yield* this._sendStreamingRequest("tasks/resubscribe", params, options);
1290
+ }
1291
+ async callExtensionMethod(method, params, idOverride, options) {
1292
+ return await this._sendRpcRequest(
1293
+ method,
1294
+ params,
1295
+ idOverride,
1296
+ options
1297
+ );
1298
+ }
1299
+ _fetch(...args) {
1300
+ if (this.customFetchImpl) {
1301
+ return this.customFetchImpl(...args);
1302
+ }
1303
+ if (typeof fetch === "function") {
1304
+ return fetch(...args);
1305
+ }
1306
+ throw new Error(
1307
+ "A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2ATransportOptions. "
1308
+ );
1309
+ }
1310
+ async _sendRpcRequest(method, params, idOverride, options) {
1311
+ const requestId = idOverride ?? this.requestIdCounter++;
1312
+ const rpcRequest = {
1313
+ jsonrpc: "2.0",
1314
+ method,
1315
+ params,
1316
+ id: requestId
1317
+ };
1318
+ const httpResponse = await this._fetchRpc(rpcRequest, "application/json", options?.signal);
1319
+ if (!httpResponse.ok) {
1320
+ let errorBodyText = "(empty or non-JSON response)";
1321
+ let errorJson;
949
1322
  try {
950
- if (method === "agent/getAuthenticatedExtendedCard") {
951
- const result = yield this.requestHandler.getAuthenticatedExtendedAgentCard();
952
- return {
953
- jsonrpc: "2.0",
954
- id: requestId,
955
- result
956
- };
957
- }
958
- if (!rpcRequest.params) {
959
- throw A2AError.invalidParams(`'params' is required for '${method}'`);
960
- }
961
- if (method === "message/stream" || method === "tasks/resubscribe") {
962
- const params = rpcRequest.params;
963
- const agentCard = yield this.requestHandler.getAgentCard();
964
- if (!agentCard.capabilities.streaming) {
965
- throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
1323
+ errorBodyText = await httpResponse.text();
1324
+ errorJson = JSON.parse(errorBodyText);
1325
+ } catch (e) {
1326
+ throw new Error(
1327
+ `HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`,
1328
+ { cause: e }
1329
+ );
1330
+ }
1331
+ if (errorJson.jsonrpc && errorJson.error) {
1332
+ throw _JsonRpcTransport.mapToError(errorJson);
1333
+ } else {
1334
+ throw new Error(
1335
+ `HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`
1336
+ );
1337
+ }
1338
+ }
1339
+ const rpcResponse = await httpResponse.json();
1340
+ if (rpcResponse.id !== requestId) {
1341
+ console.error(
1342
+ `CRITICAL: RPC response ID mismatch for method ${method}. Expected ${requestId}, got ${rpcResponse.id}.`
1343
+ );
1344
+ }
1345
+ if ("error" in rpcResponse) {
1346
+ throw _JsonRpcTransport.mapToError(rpcResponse);
1347
+ }
1348
+ return rpcResponse;
1349
+ }
1350
+ async _fetchRpc(rpcRequest, acceptHeader = "application/json", signal) {
1351
+ const requestInit = {
1352
+ method: "POST",
1353
+ headers: {
1354
+ "Content-Type": "application/json",
1355
+ Accept: acceptHeader
1356
+ },
1357
+ body: JSON.stringify(rpcRequest),
1358
+ signal
1359
+ };
1360
+ return this._fetch(this.endpoint, requestInit);
1361
+ }
1362
+ async *_sendStreamingRequest(method, params, options) {
1363
+ const clientRequestId = this.requestIdCounter++;
1364
+ const rpcRequest = {
1365
+ jsonrpc: "2.0",
1366
+ method,
1367
+ params,
1368
+ id: clientRequestId
1369
+ };
1370
+ const response = await this._fetchRpc(rpcRequest, "text/event-stream", options?.signal);
1371
+ if (!response.ok) {
1372
+ let errorBody = "";
1373
+ let errorJson;
1374
+ try {
1375
+ errorBody = await response.text();
1376
+ errorJson = JSON.parse(errorBody);
1377
+ } catch (e) {
1378
+ throw new Error(
1379
+ `HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`,
1380
+ { cause: e }
1381
+ );
1382
+ }
1383
+ if (errorJson.error) {
1384
+ throw new Error(
1385
+ `HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`
1386
+ );
1387
+ }
1388
+ throw new Error(
1389
+ `HTTP error establishing stream for ${method}: ${response.status} ${response.statusText}`
1390
+ );
1391
+ }
1392
+ if (!response.headers.get("Content-Type")?.startsWith("text/event-stream")) {
1393
+ throw new Error(
1394
+ `Invalid response Content-Type for SSE stream for ${method}. Expected 'text/event-stream'.`
1395
+ );
1396
+ }
1397
+ yield* this._parseA2ASseStream(response, clientRequestId);
1398
+ }
1399
+ async *_parseA2ASseStream(response, originalRequestId) {
1400
+ if (!response.body) {
1401
+ throw new Error("SSE response body is undefined. Cannot read stream.");
1402
+ }
1403
+ const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
1404
+ let buffer = "";
1405
+ let eventDataBuffer = "";
1406
+ try {
1407
+ while (true) {
1408
+ const { done, value } = await reader.read();
1409
+ if (done) {
1410
+ if (eventDataBuffer.trim()) {
1411
+ const result = this._processSseEventData(
1412
+ eventDataBuffer,
1413
+ originalRequestId
1414
+ );
1415
+ yield result;
966
1416
  }
967
- const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params) : this.requestHandler.resubscribe(params);
968
- return function jsonRpcEventStream() {
969
- return __asyncGenerator(this, null, function* () {
970
- try {
971
- try {
972
- for (var iter = __forAwait(agentEventStream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
973
- const event = temp.value;
974
- yield {
975
- jsonrpc: "2.0",
976
- id: requestId,
977
- // Use the original request ID for all streamed responses
978
- result: event
979
- };
980
- }
981
- } catch (temp) {
982
- error = [temp];
983
- } finally {
984
- try {
985
- more && (temp = iter.return) && (yield new __await(temp.call(iter)));
986
- } finally {
987
- if (error)
988
- throw error[0];
989
- }
990
- }
991
- } catch (streamError) {
992
- console.error(`Error in agent event stream for ${method} (request ${requestId}):`, streamError);
993
- throw streamError;
994
- }
995
- });
996
- }();
997
- } else {
998
- let result;
999
- switch (method) {
1000
- case "message/send":
1001
- result = yield this.requestHandler.sendMessage(rpcRequest.params);
1002
- break;
1003
- case "tasks/get":
1004
- result = yield this.requestHandler.getTask(rpcRequest.params);
1005
- break;
1006
- case "tasks/cancel":
1007
- result = yield this.requestHandler.cancelTask(rpcRequest.params);
1008
- break;
1009
- case "tasks/pushNotificationConfig/set":
1010
- result = yield this.requestHandler.setTaskPushNotificationConfig(
1011
- rpcRequest.params
1012
- );
1013
- break;
1014
- case "tasks/pushNotificationConfig/get":
1015
- result = yield this.requestHandler.getTaskPushNotificationConfig(
1016
- rpcRequest.params
1017
- );
1018
- break;
1019
- case "tasks/pushNotificationConfig/delete":
1020
- yield this.requestHandler.deleteTaskPushNotificationConfig(
1021
- rpcRequest.params
1022
- );
1023
- result = null;
1024
- break;
1025
- case "tasks/pushNotificationConfig/list":
1026
- result = yield this.requestHandler.listTaskPushNotificationConfigs(
1027
- rpcRequest.params
1417
+ break;
1418
+ }
1419
+ buffer += value;
1420
+ let lineEndIndex;
1421
+ while ((lineEndIndex = buffer.indexOf("\n")) >= 0) {
1422
+ const line = buffer.substring(0, lineEndIndex).trim();
1423
+ buffer = buffer.substring(lineEndIndex + 1);
1424
+ if (line === "") {
1425
+ if (eventDataBuffer) {
1426
+ const result = this._processSseEventData(
1427
+ eventDataBuffer,
1428
+ originalRequestId
1028
1429
  );
1029
- break;
1030
- default:
1031
- throw A2AError.methodNotFound(method);
1430
+ yield result;
1431
+ eventDataBuffer = "";
1432
+ }
1433
+ } else if (line.startsWith("data:")) {
1434
+ eventDataBuffer += line.substring(5).trimStart() + "\n";
1032
1435
  }
1033
- return {
1034
- jsonrpc: "2.0",
1035
- id: requestId,
1036
- result
1037
- };
1038
1436
  }
1039
- } catch (error) {
1040
- const a2aError = error instanceof A2AError ? error : A2AError.internalError(error.message || "An unexpected error occurred.");
1041
- return {
1042
- jsonrpc: "2.0",
1043
- id: requestId,
1044
- error: a2aError.toJSONRPCError()
1045
- };
1046
1437
  }
1047
- });
1438
+ } catch (error) {
1439
+ console.error(
1440
+ "Error reading or parsing SSE stream:",
1441
+ error instanceof Error && error.message || "Error unknown"
1442
+ );
1443
+ throw error;
1444
+ } finally {
1445
+ reader.releaseLock();
1446
+ }
1447
+ }
1448
+ _processSseEventData(jsonData, originalRequestId) {
1449
+ if (!jsonData.trim()) {
1450
+ throw new Error("Attempted to process empty SSE event data.");
1451
+ }
1452
+ try {
1453
+ const sseJsonRpcResponse = JSON.parse(jsonData.replace(/\n$/, ""));
1454
+ const a2aStreamResponse = sseJsonRpcResponse;
1455
+ if (a2aStreamResponse.id !== originalRequestId) {
1456
+ console.warn(
1457
+ `SSE Event's JSON-RPC response ID mismatch. Client request ID: ${originalRequestId}, event response ID: ${a2aStreamResponse.id}.`
1458
+ );
1459
+ }
1460
+ if ("error" in a2aStreamResponse) {
1461
+ const err = a2aStreamResponse.error;
1462
+ throw new Error(
1463
+ `SSE event contained an error: ${err.message} (Code: ${err.code}) Data: ${JSON.stringify(err.data || {})}`
1464
+ );
1465
+ }
1466
+ if (!("result" in a2aStreamResponse) || typeof a2aStreamResponse.result === "undefined") {
1467
+ throw new Error(`SSE event JSON-RPC response is missing 'result' field. Data: ${jsonData}`);
1468
+ }
1469
+ return a2aStreamResponse.result;
1470
+ } catch (e) {
1471
+ if (e instanceof Error && (e.message.startsWith("SSE event contained an error") || e.message.startsWith("SSE event JSON-RPC response is missing 'result' field"))) {
1472
+ throw e;
1473
+ }
1474
+ console.error(
1475
+ "Failed to parse SSE event data string or unexpected JSON-RPC structure:",
1476
+ jsonData,
1477
+ e
1478
+ );
1479
+ throw new Error(
1480
+ `Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e instanceof Error && e.message || "Unknown error"}`
1481
+ );
1482
+ }
1483
+ }
1484
+ static mapToError(response) {
1485
+ switch (response.error.code) {
1486
+ case -32001:
1487
+ return new TaskNotFoundJSONRPCError(response);
1488
+ case -32002:
1489
+ return new TaskNotCancelableJSONRPCError(response);
1490
+ case -32003:
1491
+ return new PushNotificationNotSupportedJSONRPCError(response);
1492
+ case -32004:
1493
+ return new UnsupportedOperationJSONRPCError(response);
1494
+ case -32005:
1495
+ return new ContentTypeNotSupportedJSONRPCError(response);
1496
+ case -32006:
1497
+ return new InvalidAgentResponseJSONRPCError(response);
1498
+ case -32007:
1499
+ return new AuthenticatedExtendedCardNotConfiguredJSONRPCError(response);
1500
+ default:
1501
+ return new JSONRPCTransportError(response);
1502
+ }
1503
+ }
1504
+ };
1505
+ var JSONRPCTransportError = class extends Error {
1506
+ constructor(errorResponse) {
1507
+ super(
1508
+ `JSON-RPC error: ${errorResponse.error.message} (Code: ${errorResponse.error.code}) Data: ${JSON.stringify(errorResponse.error.data || {})}`
1509
+ );
1510
+ this.errorResponse = errorResponse;
1511
+ }
1512
+ };
1513
+ var TaskNotFoundJSONRPCError = class extends TaskNotFoundError {
1514
+ constructor(errorResponse) {
1515
+ super();
1516
+ this.errorResponse = errorResponse;
1517
+ }
1518
+ };
1519
+ var TaskNotCancelableJSONRPCError = class extends TaskNotCancelableError {
1520
+ constructor(errorResponse) {
1521
+ super();
1522
+ this.errorResponse = errorResponse;
1523
+ }
1524
+ };
1525
+ var PushNotificationNotSupportedJSONRPCError = class extends PushNotificationNotSupportedError {
1526
+ constructor(errorResponse) {
1527
+ super();
1528
+ this.errorResponse = errorResponse;
1529
+ }
1530
+ };
1531
+ var UnsupportedOperationJSONRPCError = class extends UnsupportedOperationError {
1532
+ constructor(errorResponse) {
1533
+ super();
1534
+ this.errorResponse = errorResponse;
1535
+ }
1536
+ };
1537
+ var ContentTypeNotSupportedJSONRPCError = class extends ContentTypeNotSupportedError {
1538
+ constructor(errorResponse) {
1539
+ super();
1540
+ this.errorResponse = errorResponse;
1541
+ }
1542
+ };
1543
+ var InvalidAgentResponseJSONRPCError = class extends InvalidAgentResponseError {
1544
+ constructor(errorResponse) {
1545
+ super();
1546
+ this.errorResponse = errorResponse;
1547
+ }
1548
+ };
1549
+ var AuthenticatedExtendedCardNotConfiguredJSONRPCError = class extends AuthenticatedExtendedCardNotConfiguredError {
1550
+ constructor(errorResponse) {
1551
+ super();
1552
+ this.errorResponse = errorResponse;
1048
1553
  }
1049
1554
  };
1050
1555
 
1051
1556
  // src/client/client.ts
1052
1557
  var A2AClient = class _A2AClient {
1558
+ static emptyOptions = void 0;
1559
+ agentCardPromise;
1560
+ customFetchImpl;
1561
+ serviceEndpointUrl;
1562
+ // To be populated from AgentCard after fetchin
1563
+ // 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.
1564
+ // New transport abstraction isn't going to expose individual transport specific fields, so to keep returning JSON-RPC IDs here for compatibility,
1565
+ // keep counter here and pass it to JsonRpcTransport via an optional idOverride parameter (which is not visible via transport-agnostic A2ATransport interface).
1566
+ transport;
1567
+ requestIdCounter = 1;
1053
1568
  /**
1054
1569
  * Constructs an A2AClient instance from an AgentCard.
1055
1570
  * @param agentCard The AgentCard object.
1056
1571
  * @param options Optional. The options for the A2AClient including the fetch/auth implementation.
1057
1572
  */
1058
1573
  constructor(agentCard, options) {
1059
- this.requestIdCounter = 1;
1060
- this.customFetchImpl = options == null ? void 0 : options.fetchImpl;
1574
+ this.customFetchImpl = options?.fetchImpl;
1061
1575
  if (typeof agentCard === "string") {
1062
- console.warn("Warning: Constructing A2AClient with a URL is deprecated. Please use A2AClient.fromCardUrl() instead.");
1063
- this.agentCardPromise = this._fetchAndCacheAgentCard(agentCard, options == null ? void 0 : options.agentCardPath);
1576
+ console.warn(
1577
+ "Warning: Constructing A2AClient with a URL is deprecated. Please use A2AClient.fromCardUrl() instead."
1578
+ );
1579
+ this.agentCardPromise = this._fetchAndCacheAgentCard(agentCard, options?.agentCardPath);
1064
1580
  } else {
1065
1581
  if (!agentCard.url) {
1066
- throw new Error("Provided Agent Card does not contain a valid 'url' for the service endpoint.");
1582
+ throw new Error(
1583
+ "Provided Agent Card does not contain a valid 'url' for the service endpoint."
1584
+ );
1067
1585
  }
1068
1586
  this.serviceEndpointUrl = agentCard.url;
1069
1587
  this.agentCardPromise = Promise.resolve(agentCard);
1070
1588
  }
1071
1589
  }
1072
1590
  /**
1073
- * Dynamically resolves the fetch implementation to use for requests.
1591
+ * Dynamically resolves the fetch implementation to use for requests.
1074
1592
  * Prefers a custom implementation if provided, otherwise falls back to the global fetch.
1075
1593
  * @returns The fetch implementation.
1076
1594
  * @param args Arguments to pass to the fetch implementation.
@@ -1093,97 +1611,36 @@ var A2AClient = class _A2AClient {
1093
1611
  * @param options Optional. The options for the A2AClient including the fetch/auth implementation.
1094
1612
  * @returns A Promise that resolves to a new A2AClient instance.
1095
1613
  */
1096
- static fromCardUrl(agentCardUrl, options) {
1097
- return __async(this, null, function* () {
1098
- const fetchImpl = options == null ? void 0 : options.fetchImpl;
1099
- const requestInit = {
1100
- headers: { "Accept": "application/json" }
1101
- };
1102
- let response;
1103
- if (fetchImpl) {
1104
- response = yield fetchImpl(agentCardUrl, requestInit);
1105
- } else if (typeof fetch === "function") {
1106
- response = yield fetch(agentCardUrl, requestInit);
1107
- } else {
1108
- throw new Error(
1109
- "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`."
1110
- );
1111
- }
1112
- if (!response.ok) {
1113
- throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
1114
- }
1115
- let agentCard;
1116
- try {
1117
- agentCard = yield response.json();
1118
- } catch (error) {
1119
- console.error("Failed to parse Agent Card JSON:", error);
1120
- throw new Error(`Failed to parse Agent Card JSON from ${agentCardUrl}. Original error: ${error.message}`);
1121
- }
1122
- return new _A2AClient(agentCard, options);
1123
- });
1124
- }
1125
- /**
1126
- * Helper method to make a generic JSON-RPC POST request.
1127
- * @param method The RPC method name.
1128
- * @param params The parameters for the RPC method.
1129
- * @returns A Promise that resolves to the RPC response.
1130
- */
1131
- _postRpcRequest(method, params) {
1132
- return __async(this, null, function* () {
1133
- const endpoint = yield this._getServiceEndpoint();
1134
- const requestId = this.requestIdCounter++;
1135
- const rpcRequest = {
1136
- jsonrpc: "2.0",
1137
- method,
1138
- params,
1139
- // Cast because TParams structure varies per method
1140
- id: requestId
1141
- };
1142
- const httpResponse = yield this._fetchRpc(endpoint, rpcRequest);
1143
- if (!httpResponse.ok) {
1144
- let errorBodyText = "(empty or non-JSON response)";
1145
- try {
1146
- errorBodyText = yield httpResponse.text();
1147
- const errorJson = JSON.parse(errorBodyText);
1148
- if (errorJson.jsonrpc && errorJson.error) {
1149
- return errorJson;
1150
- } else if (!errorJson.jsonrpc && errorJson.error) {
1151
- throw new Error(`RPC error for ${method}: ${errorJson.error.message} (Code: ${errorJson.error.code}, HTTP Status: ${httpResponse.status}) Data: ${JSON.stringify(errorJson.error.data || {})}`);
1152
- } else if (!errorJson.jsonrpc) {
1153
- throw new Error(`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`);
1154
- }
1155
- } catch (e) {
1156
- if (e.message.startsWith("RPC error for") || e.message.startsWith("HTTP error for")) throw e;
1157
- throw new Error(`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`);
1158
- }
1159
- }
1160
- const rpcResponse = yield httpResponse.json();
1161
- if (rpcResponse.id !== requestId) {
1162
- console.error(`CRITICAL: RPC response ID mismatch for method ${method}. Expected ${requestId}, got ${rpcResponse.id}. This may lead to incorrect response handling.`);
1163
- }
1164
- return rpcResponse;
1165
- });
1166
- }
1167
- /**
1168
- * Internal helper method to fetch the RPC service endpoint.
1169
- * @param url The URL to fetch.
1170
- * @param rpcRequest The JSON-RPC request to send.
1171
- * @param acceptHeader The Accept header to use. Defaults to "application/json".
1172
- * @returns A Promise that resolves to the fetch HTTP response.
1173
- */
1174
- _fetchRpc(url, rpcRequest, acceptHeader = "application/json") {
1175
- return __async(this, null, function* () {
1176
- const requestInit = {
1177
- method: "POST",
1178
- headers: {
1179
- "Content-Type": "application/json",
1180
- "Accept": acceptHeader
1181
- // Expect JSON response for non-streaming requests
1182
- },
1183
- body: JSON.stringify(rpcRequest)
1184
- };
1185
- return this._fetch(url, requestInit);
1186
- });
1614
+ static async fromCardUrl(agentCardUrl, options) {
1615
+ const fetchImpl = options?.fetchImpl;
1616
+ const requestInit = {
1617
+ headers: { Accept: "application/json" }
1618
+ };
1619
+ let response;
1620
+ if (fetchImpl) {
1621
+ response = await fetchImpl(agentCardUrl, requestInit);
1622
+ } else if (typeof fetch === "function") {
1623
+ response = await fetch(agentCardUrl, requestInit);
1624
+ } else {
1625
+ throw new Error(
1626
+ "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`."
1627
+ );
1628
+ }
1629
+ if (!response.ok) {
1630
+ throw new Error(
1631
+ `Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
1632
+ );
1633
+ }
1634
+ let agentCard;
1635
+ try {
1636
+ agentCard = await response.json();
1637
+ } catch (error) {
1638
+ console.error("Failed to parse Agent Card JSON:", error);
1639
+ throw new Error(
1640
+ `Failed to parse Agent Card JSON from ${agentCardUrl}. Original error: ${error.message}`
1641
+ );
1642
+ }
1643
+ return new _A2AClient(agentCard, options);
1187
1644
  }
1188
1645
  /**
1189
1646
  * Sends a message to the agent.
@@ -1193,10 +1650,11 @@ var A2AClient = class _A2AClient {
1193
1650
  * @param params The parameters for sending the message, including the message content and configuration.
1194
1651
  * @returns A Promise resolving to SendMessageResponse, which can be a Message, Task, or an error.
1195
1652
  */
1196
- sendMessage(params) {
1197
- return __async(this, null, function* () {
1198
- return this._postRpcRequest("message/send", params);
1199
- });
1653
+ async sendMessage(params) {
1654
+ return await this.invokeJsonRpc(
1655
+ (t, p, id) => t.sendMessage(p, _A2AClient.emptyOptions, id),
1656
+ params
1657
+ );
1200
1658
  }
1201
1659
  /**
1202
1660
  * Sends a message to the agent and streams back responses using Server-Sent Events (SSE).
@@ -1207,42 +1665,15 @@ var A2AClient = class _A2AClient {
1207
1665
  * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
1208
1666
  * The generator throws an error if streaming is not supported or if an HTTP/SSE error occurs.
1209
1667
  */
1210
- sendMessageStream(params) {
1211
- return __asyncGenerator(this, null, function* () {
1212
- var _a, _b;
1213
- const agentCard = yield new __await(this.agentCardPromise);
1214
- if (!((_a = agentCard.capabilities) == null ? void 0 : _a.streaming)) {
1215
- throw new Error("Agent does not support streaming (AgentCard.capabilities.streaming is not true).");
1216
- }
1217
- const endpoint = yield new __await(this._getServiceEndpoint());
1218
- const clientRequestId = this.requestIdCounter++;
1219
- const rpcRequest = {
1220
- // This is the initial JSON-RPC request to establish the stream
1221
- jsonrpc: "2.0",
1222
- method: "message/stream",
1223
- params,
1224
- id: clientRequestId
1225
- };
1226
- const response = yield new __await(this._fetchRpc(endpoint, rpcRequest, "text/event-stream"));
1227
- if (!response.ok) {
1228
- let errorBody = "";
1229
- try {
1230
- errorBody = yield new __await(response.text());
1231
- const errorJson = JSON.parse(errorBody);
1232
- if (errorJson.error) {
1233
- throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`);
1234
- }
1235
- } catch (e) {
1236
- if (e.message.startsWith("HTTP error establishing stream")) throw e;
1237
- throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`);
1238
- }
1239
- throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}`);
1240
- }
1241
- if (!((_b = response.headers.get("Content-Type")) == null ? void 0 : _b.startsWith("text/event-stream"))) {
1242
- throw new Error("Invalid response Content-Type for SSE stream. Expected 'text/event-stream'.");
1243
- }
1244
- yield* __yieldStar(this._parseA2ASseStream(response, clientRequestId));
1245
- });
1668
+ async *sendMessageStream(params) {
1669
+ const agentCard = await this.agentCardPromise;
1670
+ if (!agentCard.capabilities?.streaming) {
1671
+ throw new Error(
1672
+ "Agent does not support streaming (AgentCard.capabilities.streaming is not true)."
1673
+ );
1674
+ }
1675
+ const transport = await this._getOrCreateTransport();
1676
+ yield* transport.sendMessageStream(params);
1246
1677
  }
1247
1678
  /**
1248
1679
  * Sets or updates the push notification configuration for a given task.
@@ -1250,192 +1681,102 @@ var A2AClient = class _A2AClient {
1250
1681
  * @param params Parameters containing the taskId and the TaskPushNotificationConfig.
1251
1682
  * @returns A Promise resolving to SetTaskPushNotificationConfigResponse.
1252
1683
  */
1253
- setTaskPushNotificationConfig(params) {
1254
- return __async(this, null, function* () {
1255
- var _a;
1256
- const agentCard = yield this.agentCardPromise;
1257
- if (!((_a = agentCard.capabilities) == null ? void 0 : _a.pushNotifications)) {
1258
- throw new Error("Agent does not support push notifications (AgentCard.capabilities.pushNotifications is not true).");
1259
- }
1260
- return this._postRpcRequest(
1261
- "tasks/pushNotificationConfig/set",
1262
- params
1684
+ async setTaskPushNotificationConfig(params) {
1685
+ const agentCard = await this.agentCardPromise;
1686
+ if (!agentCard.capabilities?.pushNotifications) {
1687
+ throw new Error(
1688
+ "Agent does not support push notifications (AgentCard.capabilities.pushNotifications is not true)."
1263
1689
  );
1264
- });
1690
+ }
1691
+ return await this.invokeJsonRpc((t, p, id) => t.setTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
1265
1692
  }
1266
1693
  /**
1267
1694
  * Gets the push notification configuration for a given task.
1268
1695
  * @param params Parameters containing the taskId.
1269
1696
  * @returns A Promise resolving to GetTaskPushNotificationConfigResponse.
1270
1697
  */
1271
- getTaskPushNotificationConfig(params) {
1272
- return __async(this, null, function* () {
1273
- return this._postRpcRequest(
1274
- "tasks/pushNotificationConfig/get",
1275
- params
1276
- );
1277
- });
1698
+ async getTaskPushNotificationConfig(params) {
1699
+ return await this.invokeJsonRpc(
1700
+ (t, p, id) => t.getTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id),
1701
+ params
1702
+ );
1703
+ }
1704
+ /**
1705
+ * Lists the push notification configurations for a given task.
1706
+ * @param params Parameters containing the taskId.
1707
+ * @returns A Promise resolving to ListTaskPushNotificationConfigResponse.
1708
+ */
1709
+ async listTaskPushNotificationConfig(params) {
1710
+ return await this.invokeJsonRpc((t, p, id) => t.listTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
1711
+ }
1712
+ /**
1713
+ * Deletes the push notification configuration for a given task.
1714
+ * @param params Parameters containing the taskId and push notification configuration ID.
1715
+ * @returns A Promise resolving to DeleteTaskPushNotificationConfigResponse.
1716
+ */
1717
+ async deleteTaskPushNotificationConfig(params) {
1718
+ return await this.invokeJsonRpc((t, p, id) => t.deleteTaskPushNotificationConfig(p, _A2AClient.emptyOptions, id), params);
1278
1719
  }
1279
1720
  /**
1280
1721
  * Retrieves a task by its ID.
1281
1722
  * @param params Parameters containing the taskId and optional historyLength.
1282
1723
  * @returns A Promise resolving to GetTaskResponse, which contains the Task object or an error.
1283
1724
  */
1284
- getTask(params) {
1285
- return __async(this, null, function* () {
1286
- return this._postRpcRequest("tasks/get", params);
1287
- });
1725
+ async getTask(params) {
1726
+ return await this.invokeJsonRpc(
1727
+ (t, p, id) => t.getTask(p, _A2AClient.emptyOptions, id),
1728
+ params
1729
+ );
1288
1730
  }
1289
1731
  /**
1290
1732
  * Cancels a task by its ID.
1291
1733
  * @param params Parameters containing the taskId.
1292
1734
  * @returns A Promise resolving to CancelTaskResponse, which contains the updated Task object or an error.
1293
1735
  */
1294
- cancelTask(params) {
1295
- return __async(this, null, function* () {
1296
- return this._postRpcRequest("tasks/cancel", params);
1297
- });
1736
+ async cancelTask(params) {
1737
+ return await this.invokeJsonRpc(
1738
+ (t, p, id) => t.cancelTask(p, _A2AClient.emptyOptions, id),
1739
+ params
1740
+ );
1298
1741
  }
1299
1742
  /**
1300
- * Resubscribes to a task's event stream using Server-Sent Events (SSE).
1301
- * This is used if a previous SSE connection for an active task was broken.
1302
- * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
1303
- * @param params Parameters containing the taskId.
1304
- * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
1743
+ * @template TExtensionParams The type of parameters for the custom extension method.
1744
+ * @template TExtensionResponse The type of response expected from the custom extension method.
1745
+ * This should extend JSONRPCResponse. This ensures the extension response is still a valid A2A response.
1746
+ * @param method Custom JSON-RPC method defined in the AgentCard's extensions.
1747
+ * @param params Extension paramters defined in the AgentCard's extensions.
1748
+ * @returns A Promise that resolves to the RPC response.
1305
1749
  */
1306
- resubscribeTask(params) {
1307
- return __asyncGenerator(this, null, function* () {
1308
- var _a, _b;
1309
- const agentCard = yield new __await(this.agentCardPromise);
1310
- if (!((_a = agentCard.capabilities) == null ? void 0 : _a.streaming)) {
1311
- throw new Error("Agent does not support streaming (required for tasks/resubscribe).");
1312
- }
1313
- const endpoint = yield new __await(this._getServiceEndpoint());
1314
- const clientRequestId = this.requestIdCounter++;
1315
- const rpcRequest = {
1316
- // Initial JSON-RPC request to establish the stream
1317
- jsonrpc: "2.0",
1318
- method: "tasks/resubscribe",
1750
+ async callExtensionMethod(method, params) {
1751
+ const transport = await this._getOrCreateTransport();
1752
+ try {
1753
+ return await transport.callExtensionMethod(
1754
+ method,
1319
1755
  params,
1320
- id: clientRequestId
1321
- };
1322
- const response = yield new __await(this._fetch(endpoint, {
1323
- method: "POST",
1324
- headers: {
1325
- "Content-Type": "application/json",
1326
- "Accept": "text/event-stream"
1327
- },
1328
- body: JSON.stringify(rpcRequest)
1329
- }));
1330
- if (!response.ok) {
1331
- let errorBody = "";
1332
- try {
1333
- errorBody = yield new __await(response.text());
1334
- const errorJson = JSON.parse(errorBody);
1335
- if (errorJson.error) {
1336
- throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`);
1337
- }
1338
- } catch (e) {
1339
- if (e.message.startsWith("HTTP error establishing stream")) throw e;
1340
- throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`);
1341
- }
1342
- throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}`);
1343
- }
1344
- if (!((_b = response.headers.get("Content-Type")) == null ? void 0 : _b.startsWith("text/event-stream"))) {
1345
- throw new Error("Invalid response Content-Type for SSE stream on resubscribe. Expected 'text/event-stream'.");
1346
- }
1347
- yield* __yieldStar(this._parseA2ASseStream(response, clientRequestId));
1348
- });
1349
- }
1350
- /**
1351
- * Parses an HTTP response body as an A2A Server-Sent Event stream.
1352
- * Each 'data' field of an SSE event is expected to be a JSON-RPC 2.0 Response object,
1353
- * specifically a SendStreamingMessageResponse (or similar structure for resubscribe).
1354
- * @param response The HTTP Response object whose body is the SSE stream.
1355
- * @param originalRequestId The ID of the client's JSON-RPC request that initiated this stream.
1356
- * Used to validate the `id` in the streamed JSON-RPC responses.
1357
- * @returns An AsyncGenerator yielding the `result` field of each valid JSON-RPC success response from the stream.
1358
- */
1359
- _parseA2ASseStream(response, originalRequestId) {
1360
- return __asyncGenerator(this, null, function* () {
1361
- if (!response.body) {
1362
- throw new Error("SSE response body is undefined. Cannot read stream.");
1363
- }
1364
- const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
1365
- let buffer = "";
1366
- let eventDataBuffer = "";
1367
- try {
1368
- while (true) {
1369
- const { done, value } = yield new __await(reader.read());
1370
- if (done) {
1371
- if (eventDataBuffer.trim()) {
1372
- const result = this._processSseEventData(eventDataBuffer, originalRequestId);
1373
- yield result;
1374
- }
1375
- break;
1376
- }
1377
- buffer += value;
1378
- let lineEndIndex;
1379
- while ((lineEndIndex = buffer.indexOf("\n")) >= 0) {
1380
- const line = buffer.substring(0, lineEndIndex).trim();
1381
- buffer = buffer.substring(lineEndIndex + 1);
1382
- if (line === "") {
1383
- if (eventDataBuffer) {
1384
- const result = this._processSseEventData(eventDataBuffer, originalRequestId);
1385
- yield result;
1386
- eventDataBuffer = "";
1387
- }
1388
- } else if (line.startsWith("data:")) {
1389
- eventDataBuffer += line.substring(5).trimStart() + "\n";
1390
- } else if (line.startsWith(":")) {
1391
- } else if (line.includes(":")) {
1392
- }
1393
- }
1394
- }
1395
- } catch (error) {
1396
- console.error("Error reading or parsing SSE stream:", error.message);
1397
- throw error;
1398
- } finally {
1399
- reader.releaseLock();
1756
+ this.requestIdCounter++
1757
+ );
1758
+ } catch (e) {
1759
+ const errorResponse = extractJSONRPCError(e);
1760
+ if (errorResponse) {
1761
+ return errorResponse;
1400
1762
  }
1401
- });
1763
+ throw e;
1764
+ }
1402
1765
  }
1403
1766
  /**
1404
- * Processes a single SSE event's data string, expecting it to be a JSON-RPC response.
1405
- * @param jsonData The string content from one or more 'data:' lines of an SSE event.
1406
- * @param originalRequestId The ID of the client's request that initiated the stream.
1407
- * @returns The `result` field of the parsed JSON-RPC success response.
1408
- * @throws Error if data is not valid JSON, not a valid JSON-RPC response, an error response, or ID mismatch.
1767
+ * Resubscribes to a task's event stream using Server-Sent Events (SSE).
1768
+ * This is used if a previous SSE connection for an active task was broken.
1769
+ * Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
1770
+ * @param params Parameters containing the taskId.
1771
+ * @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
1409
1772
  */
1410
- _processSseEventData(jsonData, originalRequestId) {
1411
- if (!jsonData.trim()) {
1412
- throw new Error("Attempted to process empty SSE event data.");
1773
+ async *resubscribeTask(params) {
1774
+ const agentCard = await this.agentCardPromise;
1775
+ if (!agentCard.capabilities?.streaming) {
1776
+ throw new Error("Agent does not support streaming (required for tasks/resubscribe).");
1413
1777
  }
1414
- try {
1415
- const sseJsonRpcResponse = JSON.parse(jsonData.replace(/\n$/, ""));
1416
- const a2aStreamResponse = sseJsonRpcResponse;
1417
- if (a2aStreamResponse.id !== originalRequestId) {
1418
- console.warn(`SSE Event's JSON-RPC response ID mismatch. Client request ID: ${originalRequestId}, event response ID: ${a2aStreamResponse.id}.`);
1419
- }
1420
- if (this.isErrorResponse(a2aStreamResponse)) {
1421
- const err = a2aStreamResponse.error;
1422
- throw new Error(`SSE event contained an error: ${err.message} (Code: ${err.code}) Data: ${JSON.stringify(err.data || {})}`);
1423
- }
1424
- if (!("result" in a2aStreamResponse) || typeof a2aStreamResponse.result === "undefined") {
1425
- throw new Error(`SSE event JSON-RPC response is missing 'result' field. Data: ${jsonData}`);
1426
- }
1427
- const successResponse = a2aStreamResponse;
1428
- return successResponse.result;
1429
- } catch (e) {
1430
- if (e.message.startsWith("SSE event contained an error") || e.message.startsWith("SSE event JSON-RPC response is missing 'result' field")) {
1431
- throw e;
1432
- }
1433
- console.error("Failed to parse SSE event data string or unexpected JSON-RPC structure:", jsonData, e);
1434
- throw new Error(`Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e.message}`);
1435
- }
1436
- }
1437
- isErrorResponse(response) {
1438
- return "error" in response;
1778
+ const transport = await this._getOrCreateTransport();
1779
+ yield* transport.resubscribeTask(params);
1439
1780
  }
1440
1781
  ////////////////////////////////////////////////////////////////////////////////
1441
1782
  // Functions used to support old A2AClient Constructor to be deprecated soon
@@ -1446,7 +1787,16 @@ var A2AClient = class _A2AClient {
1446
1787
  // * getAgentCard changed to this.agentCard
1447
1788
  // * delete resolveAgentCardUrl(), _fetchAndCacheAgentCard(),
1448
1789
  // agentCardPath from A2AClientOptions
1790
+ // * delete _getOrCreateTransport
1449
1791
  ////////////////////////////////////////////////////////////////////////////////
1792
+ async _getOrCreateTransport() {
1793
+ if (this.transport) {
1794
+ return this.transport;
1795
+ }
1796
+ const endpoint = await this._getServiceEndpoint();
1797
+ this.transport = new JsonRpcTransport({ fetchImpl: this.customFetchImpl, endpoint });
1798
+ return this.transport;
1799
+ }
1450
1800
  /**
1451
1801
  * Fetches the Agent Card from the agent's well-known URI and caches its service endpoint URL.
1452
1802
  * This method is called by the constructor.
@@ -1454,51 +1804,53 @@ var A2AClient = class _A2AClient {
1454
1804
  * @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
1455
1805
  * @returns A Promise that resolves to the AgentCard.
1456
1806
  */
1457
- _fetchAndCacheAgentCard(agentBaseUrl, agentCardPath) {
1458
- return __async(this, null, function* () {
1459
- try {
1460
- const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
1461
- const response = yield this._fetch(agentCardUrl, {
1462
- headers: { "Accept": "application/json" }
1463
- });
1464
- if (!response.ok) {
1465
- throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
1466
- }
1467
- const agentCard = yield response.json();
1468
- if (!agentCard.url) {
1469
- throw new Error("Fetched Agent Card does not contain a valid 'url' for the service endpoint.");
1470
- }
1471
- this.serviceEndpointUrl = agentCard.url;
1472
- return agentCard;
1473
- } catch (error) {
1474
- console.error("Error fetching or parsing Agent Card:", error);
1475
- throw error;
1807
+ async _fetchAndCacheAgentCard(agentBaseUrl, agentCardPath) {
1808
+ try {
1809
+ const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
1810
+ const response = await this._fetch(agentCardUrl, {
1811
+ headers: { Accept: "application/json" }
1812
+ });
1813
+ if (!response.ok) {
1814
+ throw new Error(
1815
+ `Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
1816
+ );
1476
1817
  }
1477
- });
1818
+ const agentCard = await response.json();
1819
+ if (!agentCard.url) {
1820
+ throw new Error(
1821
+ "Fetched Agent Card does not contain a valid 'url' for the service endpoint."
1822
+ );
1823
+ }
1824
+ this.serviceEndpointUrl = agentCard.url;
1825
+ return agentCard;
1826
+ } catch (error) {
1827
+ console.error("Error fetching or parsing Agent Card:", error);
1828
+ throw error;
1829
+ }
1478
1830
  }
1479
1831
  /**
1480
- * Retrieves the Agent Card.
1481
- * If an `agentBaseUrl` is provided, it fetches the card from that specific URL.
1482
- * Otherwise, it returns the card fetched and cached during client construction.
1483
- * @param agentBaseUrl Optional. The base URL of the agent to fetch the card from.
1484
- * @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
1485
- * If provided, this will fetch a new card, not use the cached one from the constructor's URL.
1486
- * @returns A Promise that resolves to the AgentCard.
1487
- */
1488
- getAgentCard(agentBaseUrl, agentCardPath) {
1489
- return __async(this, null, function* () {
1490
- if (agentBaseUrl) {
1491
- const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
1492
- const response = yield this._fetch(agentCardUrl, {
1493
- headers: { "Accept": "application/json" }
1494
- });
1495
- if (!response.ok) {
1496
- throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
1497
- }
1498
- return yield response.json();
1832
+ * Retrieves the Agent Card.
1833
+ * If an `agentBaseUrl` is provided, it fetches the card from that specific URL.
1834
+ * Otherwise, it returns the card fetched and cached during client construction.
1835
+ * @param agentBaseUrl Optional. The base URL of the agent to fetch the card from.
1836
+ * @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
1837
+ * If provided, this will fetch a new card, not use the cached one from the constructor's URL.
1838
+ * @returns A Promise that resolves to the AgentCard.
1839
+ */
1840
+ async getAgentCard(agentBaseUrl, agentCardPath) {
1841
+ if (agentBaseUrl) {
1842
+ const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
1843
+ const response = await this._fetch(agentCardUrl, {
1844
+ headers: { Accept: "application/json" }
1845
+ });
1846
+ if (!response.ok) {
1847
+ throw new Error(
1848
+ `Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`
1849
+ );
1499
1850
  }
1500
- return this.agentCardPromise;
1501
- });
1851
+ return await response.json();
1852
+ }
1853
+ return this.agentCardPromise;
1502
1854
  }
1503
1855
  /**
1504
1856
  * Determines the agent card URL based on the agent URL.
@@ -1512,41 +1864,73 @@ var A2AClient = class _A2AClient {
1512
1864
  * Gets the RPC service endpoint URL. Ensures the agent card has been fetched first.
1513
1865
  * @returns A Promise that resolves to the service endpoint URL string.
1514
1866
  */
1515
- _getServiceEndpoint() {
1516
- return __async(this, null, function* () {
1517
- if (this.serviceEndpointUrl) {
1518
- return this.serviceEndpointUrl;
1519
- }
1520
- yield this.agentCardPromise;
1521
- if (!this.serviceEndpointUrl) {
1522
- throw new Error("Agent Card URL for RPC endpoint is not available. Fetching might have failed.");
1523
- }
1867
+ async _getServiceEndpoint() {
1868
+ if (this.serviceEndpointUrl) {
1524
1869
  return this.serviceEndpointUrl;
1525
- });
1870
+ }
1871
+ await this.agentCardPromise;
1872
+ if (!this.serviceEndpointUrl) {
1873
+ throw new Error(
1874
+ "Agent Card URL for RPC endpoint is not available. Fetching might have failed."
1875
+ );
1876
+ }
1877
+ return this.serviceEndpointUrl;
1878
+ }
1879
+ async invokeJsonRpc(caller, params) {
1880
+ const transport = await this._getOrCreateTransport();
1881
+ const requestId = this.requestIdCounter++;
1882
+ try {
1883
+ const result = await caller(transport, params, requestId);
1884
+ return {
1885
+ id: requestId,
1886
+ jsonrpc: "2.0",
1887
+ result: result ?? null
1888
+ // JSON-RPC requires result property on success, it will be null for "void" methods.
1889
+ };
1890
+ } catch (e) {
1891
+ const errorResponse = extractJSONRPCError(e);
1892
+ if (errorResponse) {
1893
+ return errorResponse;
1894
+ }
1895
+ throw e;
1896
+ }
1526
1897
  }
1527
1898
  };
1899
+ function extractJSONRPCError(error) {
1900
+ 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) {
1901
+ return error.errorResponse;
1902
+ } else {
1903
+ return void 0;
1904
+ }
1905
+ }
1528
1906
 
1529
1907
  // src/client/auth-handler.ts
1530
1908
  function createAuthenticatingFetchWithRetry(fetchImpl, authHandler) {
1531
- function authFetch(url, init) {
1532
- return __async(this, null, function* () {
1533
- const authHeaders = (yield authHandler.headers()) || {};
1534
- const mergedInit = __spreadProps(__spreadValues({}, init || {}), {
1535
- headers: __spreadValues(__spreadValues({}, authHeaders), (init == null ? void 0 : init.headers) || {})
1536
- });
1537
- let response = yield fetchImpl(url, mergedInit);
1538
- const updatedHeaders = yield authHandler.shouldRetryWithHeaders(mergedInit, response);
1539
- if (updatedHeaders) {
1540
- const retryInit = __spreadProps(__spreadValues({}, init || {}), {
1541
- headers: __spreadValues(__spreadValues({}, updatedHeaders), (init == null ? void 0 : init.headers) || {})
1542
- });
1543
- response = yield fetchImpl(url, retryInit);
1544
- if (response.ok && authHandler.onSuccessfulRetry) {
1545
- yield authHandler.onSuccessfulRetry(updatedHeaders);
1909
+ async function authFetch(url, init) {
1910
+ const authHeaders = await authHandler.headers() || {};
1911
+ const mergedInit = {
1912
+ ...init || {},
1913
+ headers: {
1914
+ ...authHeaders,
1915
+ ...init?.headers || {}
1916
+ }
1917
+ };
1918
+ let response = await fetchImpl(url, mergedInit);
1919
+ const updatedHeaders = await authHandler.shouldRetryWithHeaders(mergedInit, response);
1920
+ if (updatedHeaders) {
1921
+ const retryInit = {
1922
+ ...init || {},
1923
+ headers: {
1924
+ ...updatedHeaders,
1925
+ ...init?.headers || {}
1546
1926
  }
1927
+ };
1928
+ response = await fetchImpl(url, retryInit);
1929
+ if (response.ok && authHandler.onSuccessfulRetry) {
1930
+ await authHandler.onSuccessfulRetry(updatedHeaders);
1547
1931
  }
1548
- return response;
1549
- });
1932
+ }
1933
+ return response;
1550
1934
  }
1551
1935
  Object.setPrototypeOf(authFetch, Object.getPrototypeOf(fetchImpl));
1552
1936
  Object.defineProperties(authFetch, Object.getOwnPropertyDescriptors(fetchImpl));
@@ -1554,106 +1938,168 @@ function createAuthenticatingFetchWithRetry(fetchImpl, authHandler) {
1554
1938
  }
1555
1939
 
1556
1940
  // src/server/express/a2a_express_app.ts
1941
+ var import_express3 = __toESM(require("express"));
1942
+
1943
+ // src/server/express/json_rpc_handler.ts
1557
1944
  var import_express = __toESM(require("express"));
1558
- var A2AExpressApp = class {
1559
- constructor(requestHandler) {
1560
- this.requestHandler = requestHandler;
1561
- this.jsonRpcTransportHandler = new JsonRpcTransportHandler(requestHandler);
1945
+
1946
+ // src/server/authentication/user.ts
1947
+ var UnauthenticatedUser = class {
1948
+ get isAuthenticated() {
1949
+ return false;
1562
1950
  }
1563
- /**
1564
- * Adds A2A routes to an existing Express app.
1565
- * @param app Optional existing Express app.
1566
- * @param baseUrl The base URL for A2A endpoints (e.g., "/a2a/api").
1567
- * @param middlewares Optional array of Express middlewares to apply to the A2A routes.
1568
- * @param agentCardPath Optional custom path for the agent card endpoint (defaults to /.well-known/agent-card.json).
1569
- * @returns The Express app with A2A routes.
1570
- */
1571
- setupRoutes(app, baseUrl = "", middlewares, agentCardPath = AGENT_CARD_PATH) {
1572
- const router = import_express.default.Router();
1573
- router.use(import_express.default.json(), ...middlewares != null ? middlewares : []);
1574
- router.get(`/${agentCardPath}`, (req, res) => __async(this, null, function* () {
1575
- try {
1576
- const agentCard = yield this.requestHandler.getAgentCard();
1577
- res.json(agentCard);
1578
- } catch (error) {
1579
- console.error("Error fetching agent card:", error);
1580
- res.status(500).json({ error: "Failed to retrieve agent card" });
1581
- }
1582
- }));
1583
- router.post("/", (req, res) => __async(this, null, function* () {
1584
- var _a, _b, _c;
1585
- try {
1586
- const rpcResponseOrStream = yield this.jsonRpcTransportHandler.handle(req.body);
1587
- if (typeof (rpcResponseOrStream == null ? void 0 : rpcResponseOrStream[Symbol.asyncIterator]) === "function") {
1588
- const stream = rpcResponseOrStream;
1589
- res.setHeader("Content-Type", "text/event-stream");
1590
- res.setHeader("Cache-Control", "no-cache");
1591
- res.setHeader("Connection", "keep-alive");
1592
- res.flushHeaders();
1593
- try {
1594
- try {
1595
- for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
1596
- const event = temp.value;
1597
- res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
1951
+ get userName() {
1952
+ return "";
1953
+ }
1954
+ };
1955
+
1956
+ // src/server/express/json_rpc_handler.ts
1957
+ function jsonRpcHandler(options) {
1958
+ const jsonRpcTransportHandler = new JsonRpcTransportHandler(options.requestHandler);
1959
+ const router = import_express.default.Router();
1960
+ router.use(import_express.default.json(), jsonErrorHandler);
1961
+ router.post("/", async (req, res) => {
1962
+ try {
1963
+ const user = await options.userBuilder(req);
1964
+ const context = new ServerCallContext(
1965
+ getRequestedExtensions(req.header(HTTP_EXTENSION_HEADER)),
1966
+ user ?? new UnauthenticatedUser()
1967
+ );
1968
+ const rpcResponseOrStream = await jsonRpcTransportHandler.handle(req.body, context);
1969
+ if (context.activatedExtensions) {
1970
+ res.setHeader(HTTP_EXTENSION_HEADER, Array.from(context.activatedExtensions));
1971
+ }
1972
+ if (typeof rpcResponseOrStream?.[Symbol.asyncIterator] === "function") {
1973
+ const stream = rpcResponseOrStream;
1974
+ res.setHeader("Content-Type", "text/event-stream");
1975
+ res.setHeader("Cache-Control", "no-cache");
1976
+ res.setHeader("Connection", "keep-alive");
1977
+ res.flushHeaders();
1978
+ try {
1979
+ for await (const event of stream) {
1980
+ res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
1598
1981
  `);
1599
- res.write(`data: ${JSON.stringify(event)}
1982
+ res.write(`data: ${JSON.stringify(event)}
1600
1983
 
1601
1984
  `);
1602
- }
1603
- } catch (temp) {
1604
- error = [temp];
1605
- } finally {
1606
- try {
1607
- more && (temp = iter.return) && (yield temp.call(iter));
1608
- } finally {
1609
- if (error)
1610
- throw error[0];
1611
- }
1612
- }
1613
- } catch (streamError) {
1614
- console.error(`Error during SSE streaming (request ${(_a = req.body) == null ? void 0 : _a.id}):`, streamError);
1615
- const a2aError = streamError instanceof A2AError ? streamError : A2AError.internalError(streamError.message || "Streaming error.");
1616
- const errorResponse = {
1617
- jsonrpc: "2.0",
1618
- id: ((_b = req.body) == null ? void 0 : _b.id) || null,
1619
- // Use original request ID if available
1620
- error: a2aError.toJSONRPCError()
1621
- };
1622
- if (!res.headersSent) {
1623
- res.status(500).json(errorResponse);
1624
- } else {
1625
- res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
1985
+ }
1986
+ } catch (streamError) {
1987
+ console.error(`Error during SSE streaming (request ${req.body?.id}):`, streamError);
1988
+ let a2aError;
1989
+ if (streamError instanceof A2AError) {
1990
+ a2aError = streamError;
1991
+ } else {
1992
+ a2aError = A2AError.internalError(
1993
+ streamError instanceof Error && streamError.message || "Streaming error."
1994
+ );
1995
+ }
1996
+ const errorResponse = {
1997
+ jsonrpc: "2.0",
1998
+ id: req.body?.id || null,
1999
+ // Use original request ID if available
2000
+ error: a2aError.toJSONRPCError()
2001
+ };
2002
+ if (!res.headersSent) {
2003
+ res.status(500).json(errorResponse);
2004
+ } else {
2005
+ res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
1626
2006
  `);
1627
- res.write(`event: error
2007
+ res.write(`event: error
1628
2008
  `);
1629
- res.write(`data: ${JSON.stringify(errorResponse)}
2009
+ res.write(`data: ${JSON.stringify(errorResponse)}
1630
2010
 
1631
2011
  `);
1632
- }
1633
- } finally {
1634
- if (!res.writableEnded) {
1635
- res.end();
1636
- }
1637
2012
  }
1638
- } else {
1639
- const rpcResponse = rpcResponseOrStream;
1640
- res.status(200).json(rpcResponse);
1641
- }
1642
- } catch (error2) {
1643
- console.error("Unhandled error in A2AExpressApp POST handler:", error2);
1644
- const a2aError = error2 instanceof A2AError ? error2 : A2AError.internalError("General processing error.");
1645
- const errorResponse = {
1646
- jsonrpc: "2.0",
1647
- id: ((_c = req.body) == null ? void 0 : _c.id) || null,
1648
- error: a2aError.toJSONRPCError()
1649
- };
1650
- if (!res.headersSent) {
1651
- res.status(500).json(errorResponse);
1652
- } else if (!res.writableEnded) {
1653
- res.end();
2013
+ } finally {
2014
+ if (!res.writableEnded) {
2015
+ res.end();
2016
+ }
1654
2017
  }
2018
+ } else {
2019
+ const rpcResponse = rpcResponseOrStream;
2020
+ res.status(200).json(rpcResponse);
1655
2021
  }
1656
- }));
2022
+ } catch (error) {
2023
+ console.error("Unhandled error in JSON-RPC POST handler:", error);
2024
+ const a2aError = error instanceof A2AError ? error : A2AError.internalError("General processing error.");
2025
+ const errorResponse = {
2026
+ jsonrpc: "2.0",
2027
+ id: req.body?.id || null,
2028
+ error: a2aError.toJSONRPCError()
2029
+ };
2030
+ if (!res.headersSent) {
2031
+ res.status(500).json(errorResponse);
2032
+ } else if (!res.writableEnded) {
2033
+ res.end();
2034
+ }
2035
+ }
2036
+ });
2037
+ return router;
2038
+ }
2039
+ var jsonErrorHandler = (err, _req, res, next) => {
2040
+ if (err instanceof SyntaxError && "body" in err) {
2041
+ const a2aError = A2AError.parseError("Invalid JSON payload.");
2042
+ const errorResponse = {
2043
+ jsonrpc: "2.0",
2044
+ id: null,
2045
+ error: a2aError.toJSONRPCError()
2046
+ };
2047
+ return res.status(400).json(errorResponse);
2048
+ }
2049
+ next(err);
2050
+ };
2051
+
2052
+ // src/server/express/agent_card_handler.ts
2053
+ var import_express2 = __toESM(require("express"));
2054
+ function agentCardHandler(options) {
2055
+ const router = import_express2.default.Router();
2056
+ const provider = typeof options.agentCardProvider === "function" ? options.agentCardProvider : options.agentCardProvider.getAgentCard.bind(options.agentCardProvider);
2057
+ router.get("/", async (_req, res) => {
2058
+ try {
2059
+ const agentCard = await provider();
2060
+ res.json(agentCard);
2061
+ } catch (error) {
2062
+ console.error("Error fetching agent card:", error);
2063
+ res.status(500).json({ error: "Failed to retrieve agent card" });
2064
+ }
2065
+ });
2066
+ return router;
2067
+ }
2068
+
2069
+ // src/server/express/common.ts
2070
+ var UserBuilder = {
2071
+ NoAuthentication: () => Promise.resolve(new UnauthenticatedUser())
2072
+ };
2073
+
2074
+ // src/server/express/a2a_express_app.ts
2075
+ var A2AExpressApp = class {
2076
+ requestHandler;
2077
+ userBuilder;
2078
+ constructor(requestHandler, userBuilder = UserBuilder.NoAuthentication) {
2079
+ this.requestHandler = requestHandler;
2080
+ this.userBuilder = userBuilder;
2081
+ }
2082
+ /**
2083
+ * Adds A2A routes to an existing Express app.
2084
+ * @param app Optional existing Express app.
2085
+ * @param baseUrl The base URL for A2A endpoints (e.g., "/a2a/api").
2086
+ * @param middlewares Optional array of Express middlewares to apply to the A2A routes.
2087
+ * @param agentCardPath Optional custom path for the agent card endpoint (defaults to .well-known/agent-card.json).
2088
+ * @returns The Express app with A2A routes.
2089
+ */
2090
+ setupRoutes(app, baseUrl = "", middlewares, agentCardPath = AGENT_CARD_PATH) {
2091
+ const router = import_express3.default.Router();
2092
+ router.use(import_express3.default.json(), jsonErrorHandler);
2093
+ if (middlewares && middlewares.length > 0) {
2094
+ router.use(middlewares);
2095
+ }
2096
+ router.use(
2097
+ jsonRpcHandler({
2098
+ requestHandler: this.requestHandler,
2099
+ userBuilder: this.userBuilder
2100
+ })
2101
+ );
2102
+ router.use(`/${agentCardPath}`, agentCardHandler({ agentCardProvider: this.requestHandler }));
1657
2103
  app.use(baseUrl, router);
1658
2104
  return app;
1659
2105
  }
@@ -1674,6 +2120,7 @@ var A2AExpressApp = class {
1674
2120
  ResultManager,
1675
2121
  createAuthenticatingFetchWithRetry,
1676
2122
  getCurrentTimestamp,
2123
+ getRequestedExtensions,
1677
2124
  isArtifactUpdate,
1678
2125
  isObject,
1679
2126
  isTaskStatusUpdate