@a2a-js/sdk 0.3.4 → 0.3.6

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.
@@ -29,23 +29,27 @@ __export(server_exports, {
29
29
  InMemoryTaskStore: () => InMemoryTaskStore,
30
30
  JsonRpcTransportHandler: () => JsonRpcTransportHandler,
31
31
  RequestContext: () => RequestContext,
32
- ResultManager: () => ResultManager
32
+ ResultManager: () => ResultManager,
33
+ ServerCallContext: () => ServerCallContext,
34
+ UnauthenticatedUser: () => UnauthenticatedUser
33
35
  });
34
36
  module.exports = __toCommonJS(server_exports);
35
37
 
36
38
  // src/server/agent_execution/request_context.ts
37
39
  var RequestContext = class {
38
40
  userMessage;
39
- task;
40
- referenceTasks;
41
41
  taskId;
42
42
  contextId;
43
- constructor(userMessage, taskId, contextId, task, referenceTasks) {
43
+ task;
44
+ referenceTasks;
45
+ context;
46
+ constructor(userMessage, taskId, contextId, task, referenceTasks, context) {
44
47
  this.userMessage = userMessage;
45
48
  this.taskId = taskId;
46
49
  this.contextId = contextId;
47
50
  this.task = task;
48
51
  this.referenceTasks = referenceTasks;
52
+ this.context = context;
49
53
  }
50
54
  };
51
55
 
@@ -69,7 +73,7 @@ var DefaultExecutionEventBusManager = class {
69
73
  /**
70
74
  * Creates or retrieves an existing ExecutionEventBus based on the taskId.
71
75
  * @param taskId The ID of the task.
72
- * @returns An instance of IExecutionEventBus.
76
+ * @returns An instance of ExecutionEventBus.
73
77
  */
74
78
  createOrGetByTaskId(taskId) {
75
79
  if (!this.taskIdToBus.has(taskId)) {
@@ -80,7 +84,7 @@ var DefaultExecutionEventBusManager = class {
80
84
  /**
81
85
  * Retrieves an existing ExecutionEventBus based on the taskId.
82
86
  * @param taskId The ID of the task.
83
- * @returns An instance of IExecutionEventBus or undefined if not found.
87
+ * @returns An instance of ExecutionEventBus or undefined if not found.
84
88
  */
85
89
  getByTaskId(taskId) {
86
90
  return this.taskIdToBus.get(taskId);
@@ -193,10 +197,7 @@ var A2AError = class _A2AError extends Error {
193
197
  return new _A2AError(-32600, message, data);
194
198
  }
195
199
  static methodNotFound(method) {
196
- return new _A2AError(
197
- -32601,
198
- `Method not found: ${method}`
199
- );
200
+ return new _A2AError(-32601, `Method not found: ${method}`);
200
201
  }
201
202
  static invalidParams(message, data) {
202
203
  return new _A2AError(-32602, message, data);
@@ -205,51 +206,34 @@ var A2AError = class _A2AError extends Error {
205
206
  return new _A2AError(-32603, message, data);
206
207
  }
207
208
  static taskNotFound(taskId) {
208
- return new _A2AError(
209
- -32001,
210
- `Task not found: ${taskId}`,
211
- void 0,
212
- taskId
213
- );
209
+ return new _A2AError(-32001, `Task not found: ${taskId}`, void 0, taskId);
214
210
  }
215
211
  static taskNotCancelable(taskId) {
216
- return new _A2AError(
217
- -32002,
218
- `Task not cancelable: ${taskId}`,
219
- void 0,
220
- taskId
221
- );
212
+ return new _A2AError(-32002, `Task not cancelable: ${taskId}`, void 0, taskId);
222
213
  }
223
214
  static pushNotificationNotSupported() {
224
- return new _A2AError(
225
- -32003,
226
- "Push Notification is not supported"
227
- );
215
+ return new _A2AError(-32003, "Push Notification is not supported");
228
216
  }
229
217
  static unsupportedOperation(operation) {
230
- return new _A2AError(
231
- -32004,
232
- `Unsupported operation: ${operation}`
233
- );
218
+ return new _A2AError(-32004, `Unsupported operation: ${operation}`);
234
219
  }
235
220
  static authenticatedExtendedCardNotConfigured() {
236
- return new _A2AError(
237
- -32007,
238
- `Extended card not configured.`
239
- );
221
+ return new _A2AError(-32007, `Extended card not configured.`);
240
222
  }
241
223
  };
242
224
 
243
225
  // src/server/result_manager.ts
244
226
  var ResultManager = class {
245
227
  taskStore;
228
+ serverCallContext;
246
229
  currentTask;
247
230
  latestUserMessage;
248
231
  // To add to history if a new task is created
249
232
  finalMessageResult;
250
233
  // Stores the message if it's the final result
251
- constructor(taskStore) {
234
+ constructor(taskStore, serverCallContext) {
252
235
  this.taskStore = taskStore;
236
+ this.serverCallContext = serverCallContext;
253
237
  }
254
238
  setContext(latestUserMessage) {
255
239
  this.latestUserMessage = latestUserMessage;
@@ -265,7 +249,9 @@ var ResultManager = class {
265
249
  const taskEvent = event;
266
250
  this.currentTask = { ...taskEvent };
267
251
  if (this.latestUserMessage) {
268
- if (!this.currentTask.history?.find((msg) => msg.messageId === this.latestUserMessage.messageId)) {
252
+ if (!this.currentTask.history?.find(
253
+ (msg) => msg.messageId === this.latestUserMessage.messageId
254
+ )) {
269
255
  this.currentTask.history = [this.latestUserMessage, ...this.currentTask.history || []];
270
256
  }
271
257
  }
@@ -275,24 +261,36 @@ var ResultManager = class {
275
261
  if (this.currentTask && this.currentTask.id === updateEvent.taskId) {
276
262
  this.currentTask.status = updateEvent.status;
277
263
  if (updateEvent.status.message) {
278
- if (!this.currentTask.history?.find((msg) => msg.messageId === updateEvent.status.message.messageId)) {
279
- this.currentTask.history = [...this.currentTask.history || [], updateEvent.status.message];
264
+ if (!this.currentTask.history?.find(
265
+ (msg) => msg.messageId === updateEvent.status.message.messageId
266
+ )) {
267
+ this.currentTask.history = [
268
+ ...this.currentTask.history || [],
269
+ updateEvent.status.message
270
+ ];
280
271
  }
281
272
  }
282
273
  await this.saveCurrentTask();
283
274
  } else if (!this.currentTask && updateEvent.taskId) {
284
- const loaded = await this.taskStore.load(updateEvent.taskId);
275
+ const loaded = await this.taskStore.load(updateEvent.taskId, this.serverCallContext);
285
276
  if (loaded) {
286
277
  this.currentTask = loaded;
287
278
  this.currentTask.status = updateEvent.status;
288
279
  if (updateEvent.status.message) {
289
- if (!this.currentTask.history?.find((msg) => msg.messageId === updateEvent.status.message.messageId)) {
290
- this.currentTask.history = [...this.currentTask.history || [], updateEvent.status.message];
280
+ if (!this.currentTask.history?.find(
281
+ (msg) => msg.messageId === updateEvent.status.message.messageId
282
+ )) {
283
+ this.currentTask.history = [
284
+ ...this.currentTask.history || [],
285
+ updateEvent.status.message
286
+ ];
291
287
  }
292
288
  }
293
289
  await this.saveCurrentTask();
294
290
  } else {
295
- console.warn(`ResultManager: Received status update for unknown task ${updateEvent.taskId}`);
291
+ console.warn(
292
+ `ResultManager: Received status update for unknown task ${updateEvent.taskId}`
293
+ );
296
294
  }
297
295
  }
298
296
  } else if (event.kind === "artifact-update") {
@@ -308,9 +306,14 @@ var ResultManager = class {
308
306
  if (artifactEvent.append) {
309
307
  const existingArtifact = this.currentTask.artifacts[existingArtifactIndex];
310
308
  existingArtifact.parts.push(...artifactEvent.artifact.parts);
311
- if (artifactEvent.artifact.description) existingArtifact.description = artifactEvent.artifact.description;
309
+ if (artifactEvent.artifact.description)
310
+ existingArtifact.description = artifactEvent.artifact.description;
312
311
  if (artifactEvent.artifact.name) existingArtifact.name = artifactEvent.artifact.name;
313
- if (artifactEvent.artifact.metadata) existingArtifact.metadata = { ...existingArtifact.metadata, ...artifactEvent.artifact.metadata };
312
+ if (artifactEvent.artifact.metadata)
313
+ existingArtifact.metadata = {
314
+ ...existingArtifact.metadata,
315
+ ...artifactEvent.artifact.metadata
316
+ };
314
317
  } else {
315
318
  this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
316
319
  }
@@ -319,7 +322,7 @@ var ResultManager = class {
319
322
  }
320
323
  await this.saveCurrentTask();
321
324
  } else if (!this.currentTask && artifactEvent.taskId) {
322
- const loaded = await this.taskStore.load(artifactEvent.taskId);
325
+ const loaded = await this.taskStore.load(artifactEvent.taskId, this.serverCallContext);
323
326
  if (loaded) {
324
327
  this.currentTask = loaded;
325
328
  if (!this.currentTask.artifacts) this.currentTask.artifacts = [];
@@ -328,7 +331,9 @@ var ResultManager = class {
328
331
  );
329
332
  if (existingArtifactIndex !== -1) {
330
333
  if (artifactEvent.append) {
331
- this.currentTask.artifacts[existingArtifactIndex].parts.push(...artifactEvent.artifact.parts);
334
+ this.currentTask.artifacts[existingArtifactIndex].parts.push(
335
+ ...artifactEvent.artifact.parts
336
+ );
332
337
  } else {
333
338
  this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
334
339
  }
@@ -337,14 +342,16 @@ var ResultManager = class {
337
342
  }
338
343
  await this.saveCurrentTask();
339
344
  } else {
340
- console.warn(`ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`);
345
+ console.warn(
346
+ `ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`
347
+ );
341
348
  }
342
349
  }
343
350
  }
344
351
  }
345
352
  async saveCurrentTask() {
346
353
  if (this.currentTask) {
347
- await this.taskStore.save(this.currentTask);
354
+ await this.taskStore.save(this.currentTask, this.serverCallContext);
348
355
  }
349
356
  }
350
357
  /**
@@ -410,9 +417,11 @@ var InMemoryPushNotificationStore = class {
410
417
  // src/server/push_notification/default_push_notification_sender.ts
411
418
  var DefaultPushNotificationSender = class {
412
419
  pushNotificationStore;
420
+ notificationChain;
413
421
  options;
414
422
  constructor(pushNotificationStore, options = {}) {
415
423
  this.pushNotificationStore = pushNotificationStore;
424
+ this.notificationChain = /* @__PURE__ */ new Map();
416
425
  this.options = {
417
426
  timeout: 5e3,
418
427
  tokenHeaderName: "X-A2A-Notification-Token",
@@ -424,10 +433,25 @@ var DefaultPushNotificationSender = class {
424
433
  if (!pushConfigs || pushConfigs.length === 0) {
425
434
  return;
426
435
  }
427
- pushConfigs.forEach((pushConfig) => {
428
- this._dispatchNotification(task, pushConfig).catch((error) => {
429
- console.error(`Error sending push notification for task_id=${task.id} to URL: ${pushConfig.url}. Error:`, error);
436
+ const lastPromise = this.notificationChain.get(task.id) ?? Promise.resolve();
437
+ const newPromise = lastPromise.then(async () => {
438
+ const dispatches = pushConfigs.map(async (pushConfig) => {
439
+ try {
440
+ await this._dispatchNotification(task, pushConfig);
441
+ } catch (error) {
442
+ console.error(
443
+ `Error sending push notification for task_id=${task.id} to URL: ${pushConfig.url}. Error:`,
444
+ error
445
+ );
446
+ }
430
447
  });
448
+ await Promise.all(dispatches);
449
+ });
450
+ this.notificationChain.set(task.id, newPromise);
451
+ newPromise.finally(() => {
452
+ if (this.notificationChain.get(task.id) === newPromise) {
453
+ this.notificationChain.delete(task.id);
454
+ }
431
455
  });
432
456
  }
433
457
  async _dispatchNotification(task, pushConfig) {
@@ -451,30 +475,86 @@ var DefaultPushNotificationSender = class {
451
475
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
452
476
  }
453
477
  console.info(`Push notification sent for task_id=${task.id} to URL: ${url}`);
454
- } catch (error) {
455
- console.error(`Error sending push notification for task_id=${task.id} to URL: ${url}. Error:`, error);
456
478
  } finally {
457
479
  clearTimeout(timeoutId);
458
480
  }
459
481
  }
460
482
  };
461
483
 
484
+ // src/extensions.ts
485
+ var Extensions = {
486
+ /**
487
+ * Creates new {@link Extensions} from `current` and `additional`.
488
+ * If `current` already contains `additional` it is returned unmodified.
489
+ */
490
+ createFrom: (current, additional) => {
491
+ if (current?.includes(additional)) {
492
+ return current;
493
+ }
494
+ return [...current ?? [], additional];
495
+ },
496
+ /**
497
+ * Creates {@link Extensions} from comma separated extensions identifiers as per
498
+ * https://a2a-protocol.org/latest/specification/#326-service-parameters.
499
+ * Parses the output of `toServiceParameter`.
500
+ */
501
+ parseServiceParameter: (value) => {
502
+ if (!value) {
503
+ return [];
504
+ }
505
+ const unique = new Set(
506
+ value.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0)
507
+ );
508
+ return Array.from(unique);
509
+ },
510
+ /**
511
+ * Converts {@link Extensions} to comma separated extensions identifiers as per
512
+ * https://a2a-protocol.org/latest/specification/#326-service-parameters.
513
+ */
514
+ toServiceParameter: (value) => {
515
+ return value.join(",");
516
+ }
517
+ };
518
+
519
+ // src/server/context.ts
520
+ var ServerCallContext = class {
521
+ _requestedExtensions;
522
+ _user;
523
+ _activatedExtensions;
524
+ constructor(requestedExtensions, user) {
525
+ this._requestedExtensions = requestedExtensions;
526
+ this._user = user;
527
+ }
528
+ get user() {
529
+ return this._user;
530
+ }
531
+ get activatedExtensions() {
532
+ return this._activatedExtensions;
533
+ }
534
+ get requestedExtensions() {
535
+ return this._requestedExtensions;
536
+ }
537
+ addActivatedExtension(uri) {
538
+ this._activatedExtensions = Extensions.createFrom(this._activatedExtensions, uri);
539
+ }
540
+ };
541
+
462
542
  // src/server/request_handler/default_request_handler.ts
463
543
  var terminalStates = ["completed", "failed", "canceled", "rejected"];
464
544
  var DefaultRequestHandler = class {
465
545
  agentCard;
466
- extendedAgentCard;
467
546
  taskStore;
468
547
  agentExecutor;
469
548
  eventBusManager;
470
549
  pushNotificationStore;
471
550
  pushNotificationSender;
472
- constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), pushNotificationStore, pushNotificationSender, extendedAgentCard) {
551
+ extendedAgentCardProvider;
552
+ constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), pushNotificationStore, pushNotificationSender, extendedAgentCardProvider) {
473
553
  this.agentCard = agentCard;
474
554
  this.taskStore = taskStore;
475
555
  this.agentExecutor = agentExecutor;
476
556
  this.eventBusManager = eventBusManager;
477
- this.extendedAgentCard = extendedAgentCard;
557
+ this.extendedAgentCardProvider = extendedAgentCardProvider;
478
558
  if (agentCard.capabilities.pushNotifications) {
479
559
  this.pushNotificationStore = pushNotificationStore || new InMemoryPushNotificationStore();
480
560
  this.pushNotificationSender = pushNotificationSender || new DefaultPushNotificationSender(this.pushNotificationStore);
@@ -483,28 +563,42 @@ var DefaultRequestHandler = class {
483
563
  async getAgentCard() {
484
564
  return this.agentCard;
485
565
  }
486
- async getAuthenticatedExtendedAgentCard() {
487
- if (!this.extendedAgentCard) {
566
+ async getAuthenticatedExtendedAgentCard(context) {
567
+ if (!this.agentCard.supportsAuthenticatedExtendedCard) {
568
+ throw A2AError.unsupportedOperation("Agent does not support authenticated extended card.");
569
+ }
570
+ if (!this.extendedAgentCardProvider) {
488
571
  throw A2AError.authenticatedExtendedCardNotConfigured();
489
572
  }
490
- return this.extendedAgentCard;
573
+ if (typeof this.extendedAgentCardProvider === "function") {
574
+ return this.extendedAgentCardProvider(context);
575
+ }
576
+ if (context?.user?.isAuthenticated) {
577
+ return this.extendedAgentCardProvider;
578
+ }
579
+ return this.agentCard;
491
580
  }
492
- async _createRequestContext(incomingMessage, taskId, isStream) {
581
+ async _createRequestContext(incomingMessage, context) {
493
582
  let task;
494
583
  let referenceTasks;
495
584
  if (incomingMessage.taskId) {
496
- task = await this.taskStore.load(incomingMessage.taskId);
585
+ task = await this.taskStore.load(incomingMessage.taskId, context);
497
586
  if (!task) {
498
587
  throw A2AError.taskNotFound(incomingMessage.taskId);
499
588
  }
500
589
  if (terminalStates.includes(task.status.state)) {
501
- throw A2AError.invalidRequest(`Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`);
590
+ throw A2AError.invalidRequest(
591
+ `Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`
592
+ );
502
593
  }
594
+ task.history = [...task.history || [], incomingMessage];
595
+ await this.taskStore.save(task, context);
503
596
  }
597
+ const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
504
598
  if (incomingMessage.referenceTaskIds && incomingMessage.referenceTaskIds.length > 0) {
505
599
  referenceTasks = [];
506
600
  for (const refId of incomingMessage.referenceTaskIds) {
507
- const refTask = await this.taskStore.load(refId);
601
+ const refTask = await this.taskStore.load(refId, context);
508
602
  if (refTask) {
509
603
  referenceTasks.push(refTask);
510
604
  } else {
@@ -513,54 +607,74 @@ var DefaultRequestHandler = class {
513
607
  }
514
608
  }
515
609
  const contextId = incomingMessage.contextId || task?.contextId || (0, import_uuid.v4)();
610
+ if (context?.requestedExtensions) {
611
+ const agentCard = await this.getAgentCard();
612
+ const exposedExtensions = new Set(
613
+ agentCard.capabilities.extensions?.map((ext) => ext.uri) || []
614
+ );
615
+ const validExtensions = context.requestedExtensions.filter(
616
+ (extension) => exposedExtensions.has(extension)
617
+ );
618
+ context = new ServerCallContext(validExtensions, context.user);
619
+ }
516
620
  const messageForContext = {
517
621
  ...incomingMessage,
518
- contextId
519
- };
520
- return new RequestContext(
521
- messageForContext,
522
- taskId,
523
622
  contextId,
524
- task,
525
- referenceTasks
526
- );
623
+ taskId
624
+ };
625
+ return new RequestContext(messageForContext, taskId, contextId, task, referenceTasks, context);
527
626
  }
528
- async _processEvents(taskId, resultManager, eventQueue, options) {
627
+ async _processEvents(taskId, resultManager, eventQueue, context, options) {
529
628
  let firstResultSent = false;
530
629
  try {
531
630
  for await (const event of eventQueue.events()) {
532
631
  await resultManager.processEvent(event);
533
- await this._sendPushNotificationIfNeeded(event);
632
+ try {
633
+ await this._sendPushNotificationIfNeeded(event, context);
634
+ } catch (error) {
635
+ console.error(`Error sending push notification: ${error}`);
636
+ }
534
637
  if (options?.firstResultResolver && !firstResultSent) {
535
- if (event.kind === "message" || event.kind === "task") {
536
- options.firstResultResolver(event);
638
+ let firstResult;
639
+ if (event.kind === "message") {
640
+ firstResult = event;
641
+ } else {
642
+ firstResult = resultManager.getCurrentTask();
643
+ }
644
+ if (firstResult) {
645
+ options.firstResultResolver(firstResult);
537
646
  firstResultSent = true;
538
647
  }
539
648
  }
540
649
  }
541
650
  if (options?.firstResultRejector && !firstResultSent) {
542
- options.firstResultRejector(A2AError.internalError("Execution finished before a message or task was produced."));
651
+ options.firstResultRejector(
652
+ A2AError.internalError("Execution finished before a message or task was produced.")
653
+ );
543
654
  }
544
655
  } catch (error) {
545
656
  console.error(`Event processing loop failed for task ${taskId}:`, error);
546
- if (options?.firstResultRejector && !firstResultSent) {
547
- options.firstResultRejector(error);
548
- }
549
- throw error;
657
+ this._handleProcessingError(
658
+ error,
659
+ resultManager,
660
+ firstResultSent,
661
+ taskId,
662
+ options?.firstResultRejector
663
+ );
550
664
  } finally {
551
665
  this.eventBusManager.cleanupByTaskId(taskId);
552
666
  }
553
667
  }
554
- async sendMessage(params) {
668
+ async sendMessage(params, context) {
555
669
  const incomingMessage = params.message;
556
670
  if (!incomingMessage.messageId) {
557
671
  throw A2AError.invalidParams("message.messageId is required.");
558
672
  }
559
673
  const isBlocking = params.configuration?.blocking !== false;
560
- const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
561
- const resultManager = new ResultManager(this.taskStore);
674
+ const resultManager = new ResultManager(this.taskStore, context);
562
675
  resultManager.setContext(incomingMessage);
563
- const requestContext = await this._createRequestContext(incomingMessage, taskId, false);
676
+ const requestContext = await this._createRequestContext(incomingMessage, context);
677
+ const taskId = requestContext.taskId;
564
678
  const finalMessageForAgent = requestContext.userMessage;
565
679
  if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
566
680
  await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
@@ -605,30 +719,32 @@ var DefaultRequestHandler = class {
605
719
  eventBus.finished();
606
720
  });
607
721
  if (isBlocking) {
608
- await this._processEvents(taskId, resultManager, eventQueue);
722
+ await this._processEvents(taskId, resultManager, eventQueue, context);
609
723
  const finalResult = resultManager.getFinalResult();
610
724
  if (!finalResult) {
611
- throw A2AError.internalError("Agent execution finished without a result, and no task context found.");
725
+ throw A2AError.internalError(
726
+ "Agent execution finished without a result, and no task context found."
727
+ );
612
728
  }
613
729
  return finalResult;
614
730
  } else {
615
731
  return new Promise((resolve, reject) => {
616
- this._processEvents(taskId, resultManager, eventQueue, {
732
+ this._processEvents(taskId, resultManager, eventQueue, context, {
617
733
  firstResultResolver: resolve,
618
734
  firstResultRejector: reject
619
735
  });
620
736
  });
621
737
  }
622
738
  }
623
- async *sendMessageStream(params) {
739
+ async *sendMessageStream(params, context) {
624
740
  const incomingMessage = params.message;
625
741
  if (!incomingMessage.messageId) {
626
742
  throw A2AError.invalidParams("message.messageId is required for streaming.");
627
743
  }
628
- const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
629
- const resultManager = new ResultManager(this.taskStore);
744
+ const resultManager = new ResultManager(this.taskStore, context);
630
745
  resultManager.setContext(incomingMessage);
631
- const requestContext = await this._createRequestContext(incomingMessage, taskId, true);
746
+ const requestContext = await this._createRequestContext(incomingMessage, context);
747
+ const taskId = requestContext.taskId;
632
748
  const finalMessageForAgent = requestContext.userMessage;
633
749
  const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
634
750
  const eventQueue = new ExecutionEventQueue(eventBus);
@@ -636,7 +752,10 @@ var DefaultRequestHandler = class {
636
752
  await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
637
753
  }
638
754
  this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
639
- console.error(`Agent execution failed for stream message ${finalMessageForAgent.messageId}:`, err);
755
+ console.error(
756
+ `Agent execution failed for stream message ${finalMessageForAgent.messageId}:`,
757
+ err
758
+ );
640
759
  const errorTaskStatus = {
641
760
  kind: "status-update",
642
761
  taskId: requestContext.task?.id || (0, import_uuid.v4)(),
@@ -662,15 +781,15 @@ var DefaultRequestHandler = class {
662
781
  try {
663
782
  for await (const event of eventQueue.events()) {
664
783
  await resultManager.processEvent(event);
665
- await this._sendPushNotificationIfNeeded(event);
784
+ await this._sendPushNotificationIfNeeded(event, context);
666
785
  yield event;
667
786
  }
668
787
  } finally {
669
788
  this.eventBusManager.cleanupByTaskId(taskId);
670
789
  }
671
790
  }
672
- async getTask(params) {
673
- const task = await this.taskStore.load(params.id);
791
+ async getTask(params, context) {
792
+ const task = await this.taskStore.load(params.id, context);
674
793
  if (!task) {
675
794
  throw A2AError.taskNotFound(params.id);
676
795
  }
@@ -683,8 +802,8 @@ var DefaultRequestHandler = class {
683
802
  }
684
803
  return task;
685
804
  }
686
- async cancelTask(params) {
687
- const task = await this.taskStore.load(params.id);
805
+ async cancelTask(params, context) {
806
+ const task = await this.taskStore.load(params.id, context);
688
807
  if (!task) {
689
808
  throw A2AError.taskNotFound(params.id);
690
809
  }
@@ -694,7 +813,14 @@ var DefaultRequestHandler = class {
694
813
  }
695
814
  const eventBus = this.eventBusManager.getByTaskId(params.id);
696
815
  if (eventBus) {
816
+ const eventQueue = new ExecutionEventQueue(eventBus);
697
817
  await this.agentExecutor.cancelTask(params.id, eventBus);
818
+ await this._processEvents(
819
+ params.id,
820
+ new ResultManager(this.taskStore, context),
821
+ eventQueue,
822
+ context
823
+ );
698
824
  } else {
699
825
  task.status = {
700
826
  state: "canceled",
@@ -710,16 +836,22 @@ var DefaultRequestHandler = class {
710
836
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
711
837
  };
712
838
  task.history = [...task.history || [], task.status.message];
713
- await this.taskStore.save(task);
839
+ await this.taskStore.save(task, context);
840
+ }
841
+ const latestTask = await this.taskStore.load(params.id, context);
842
+ if (!latestTask) {
843
+ throw A2AError.internalError(`Task ${params.id} not found after cancellation.`);
844
+ }
845
+ if (latestTask.status.state != "canceled") {
846
+ throw A2AError.taskNotCancelable(params.id);
714
847
  }
715
- const latestTask = await this.taskStore.load(params.id);
716
848
  return latestTask;
717
849
  }
718
- async setTaskPushNotificationConfig(params) {
850
+ async setTaskPushNotificationConfig(params, context) {
719
851
  if (!this.agentCard.capabilities.pushNotifications) {
720
852
  throw A2AError.pushNotificationNotSupported();
721
853
  }
722
- const task = await this.taskStore.load(params.taskId);
854
+ const task = await this.taskStore.load(params.taskId, context);
723
855
  if (!task) {
724
856
  throw A2AError.taskNotFound(params.taskId);
725
857
  }
@@ -730,11 +862,11 @@ var DefaultRequestHandler = class {
730
862
  await this.pushNotificationStore?.save(taskId, pushNotificationConfig);
731
863
  return params;
732
864
  }
733
- async getTaskPushNotificationConfig(params) {
865
+ async getTaskPushNotificationConfig(params, context) {
734
866
  if (!this.agentCard.capabilities.pushNotifications) {
735
867
  throw A2AError.pushNotificationNotSupported();
736
868
  }
737
- const task = await this.taskStore.load(params.id);
869
+ const task = await this.taskStore.load(params.id, context);
738
870
  if (!task) {
739
871
  throw A2AError.taskNotFound(params.id);
740
872
  }
@@ -750,15 +882,17 @@ var DefaultRequestHandler = class {
750
882
  }
751
883
  const config = configs.find((c) => c.id === configId);
752
884
  if (!config) {
753
- throw A2AError.internalError(`Push notification config with id '${configId}' not found for task ${params.id}.`);
885
+ throw A2AError.internalError(
886
+ `Push notification config with id '${configId}' not found for task ${params.id}.`
887
+ );
754
888
  }
755
889
  return { taskId: params.id, pushNotificationConfig: config };
756
890
  }
757
- async listTaskPushNotificationConfigs(params) {
891
+ async listTaskPushNotificationConfigs(params, context) {
758
892
  if (!this.agentCard.capabilities.pushNotifications) {
759
893
  throw A2AError.pushNotificationNotSupported();
760
894
  }
761
- const task = await this.taskStore.load(params.id);
895
+ const task = await this.taskStore.load(params.id, context);
762
896
  if (!task) {
763
897
  throw A2AError.taskNotFound(params.id);
764
898
  }
@@ -768,22 +902,22 @@ var DefaultRequestHandler = class {
768
902
  pushNotificationConfig: config
769
903
  }));
770
904
  }
771
- async deleteTaskPushNotificationConfig(params) {
905
+ async deleteTaskPushNotificationConfig(params, context) {
772
906
  if (!this.agentCard.capabilities.pushNotifications) {
773
907
  throw A2AError.pushNotificationNotSupported();
774
908
  }
775
- const task = await this.taskStore.load(params.id);
909
+ const task = await this.taskStore.load(params.id, context);
776
910
  if (!task) {
777
911
  throw A2AError.taskNotFound(params.id);
778
912
  }
779
913
  const { id: taskId, pushNotificationConfigId } = params;
780
914
  await this.pushNotificationStore?.delete(taskId, pushNotificationConfigId);
781
915
  }
782
- async *resubscribe(params) {
916
+ async *resubscribe(params, context) {
783
917
  if (!this.agentCard.capabilities.streaming) {
784
918
  throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
785
919
  }
786
- const task = await this.taskStore.load(params.id);
920
+ const task = await this.taskStore.load(params.id, context);
787
921
  if (!task) {
788
922
  throw A2AError.taskNotFound(params.id);
789
923
  }
@@ -812,7 +946,7 @@ var DefaultRequestHandler = class {
812
946
  eventQueue.stop();
813
947
  }
814
948
  }
815
- async _sendPushNotificationIfNeeded(event) {
949
+ async _sendPushNotificationIfNeeded(event, context) {
816
950
  if (!this.agentCard.capabilities.pushNotifications) {
817
951
  return;
818
952
  }
@@ -827,13 +961,53 @@ var DefaultRequestHandler = class {
827
961
  console.error(`Task ID not found for event ${event.kind}.`);
828
962
  return;
829
963
  }
830
- const task = await this.taskStore.load(taskId);
964
+ const task = await this.taskStore.load(taskId, context);
831
965
  if (!task) {
832
966
  console.error(`Task ${taskId} not found.`);
833
967
  return;
834
968
  }
835
969
  this.pushNotificationSender?.send(task);
836
970
  }
971
+ async _handleProcessingError(error, resultManager, firstResultSent, taskId, firstResultRejector) {
972
+ if (firstResultRejector && !firstResultSent) {
973
+ firstResultRejector(error);
974
+ return;
975
+ }
976
+ if (!firstResultRejector) {
977
+ throw error;
978
+ }
979
+ const currentTask = resultManager.getCurrentTask();
980
+ const errorMessage = error instanceof Error && error.message || "Unknown error";
981
+ if (currentTask) {
982
+ const statusUpdateFailed = {
983
+ taskId: currentTask.id,
984
+ contextId: currentTask.contextId,
985
+ status: {
986
+ state: "failed",
987
+ message: {
988
+ kind: "message",
989
+ role: "agent",
990
+ messageId: (0, import_uuid.v4)(),
991
+ parts: [{ kind: "text", text: `Event processing loop failed: ${errorMessage}` }],
992
+ taskId: currentTask.id,
993
+ contextId: currentTask.contextId
994
+ },
995
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
996
+ },
997
+ kind: "status-update",
998
+ final: true
999
+ };
1000
+ try {
1001
+ await resultManager.processEvent(statusUpdateFailed);
1002
+ } catch (error2) {
1003
+ console.error(
1004
+ `Event processing loop failed for task ${taskId}: ${error2 instanceof Error && error2.message || "Unknown error"}`
1005
+ );
1006
+ }
1007
+ } else {
1008
+ console.error(`Event processing loop failed for task ${taskId}: ${errorMessage}`);
1009
+ }
1010
+ }
837
1011
  };
838
1012
 
839
1013
  // src/server/store.ts
@@ -848,7 +1022,7 @@ var InMemoryTaskStore = class {
848
1022
  }
849
1023
  };
850
1024
 
851
- // src/server/transports/jsonrpc_transport_handler.ts
1025
+ // src/server/transports/jsonrpc/jsonrpc_transport_handler.ts
852
1026
  var JsonRpcTransportHandler = class {
853
1027
  requestHandler;
854
1028
  constructor(requestHandler) {
@@ -859,7 +1033,7 @@ var JsonRpcTransportHandler = class {
859
1033
  * For streaming methods, it returns an AsyncGenerator of JSONRPCResult.
860
1034
  * For non-streaming methods, it returns a Promise of a single JSONRPCMessage (Result or ErrorResponse).
861
1035
  */
862
- async handle(requestBody) {
1036
+ async handle(requestBody, context) {
863
1037
  let rpcRequest;
864
1038
  try {
865
1039
  if (typeof requestBody === "string") {
@@ -869,31 +1043,23 @@ var JsonRpcTransportHandler = class {
869
1043
  } else {
870
1044
  throw A2AError.parseError("Invalid request body type.");
871
1045
  }
872
- if (rpcRequest.jsonrpc !== "2.0" || !rpcRequest.method || typeof rpcRequest.method !== "string") {
873
- throw A2AError.invalidRequest(
874
- "Invalid JSON-RPC request structure."
875
- );
1046
+ if (!this.isRequestValid(rpcRequest)) {
1047
+ throw A2AError.invalidRequest("Invalid JSON-RPC Request.");
876
1048
  }
877
1049
  } catch (error) {
878
- const a2aError = error instanceof A2AError ? error : A2AError.parseError(error.message || "Failed to parse JSON request.");
1050
+ const a2aError = error instanceof A2AError ? error : A2AError.parseError(
1051
+ error instanceof SyntaxError && error.message || "Failed to parse JSON request."
1052
+ );
879
1053
  return {
880
1054
  jsonrpc: "2.0",
881
- id: typeof rpcRequest?.id !== "undefined" ? rpcRequest.id : null,
1055
+ id: rpcRequest?.id !== void 0 ? rpcRequest.id : null,
882
1056
  error: a2aError.toJSONRPCError()
883
1057
  };
884
1058
  }
885
1059
  const { method, id: requestId = null } = rpcRequest;
886
1060
  try {
887
- if (method === "agent/getAuthenticatedExtendedCard") {
888
- const result = await this.requestHandler.getAuthenticatedExtendedAgentCard();
889
- return {
890
- jsonrpc: "2.0",
891
- id: requestId,
892
- result
893
- };
894
- }
895
- if (!rpcRequest.params) {
896
- throw A2AError.invalidParams(`'params' is required for '${method}'`);
1061
+ if (method !== "agent/getAuthenticatedExtendedCard" && !this.paramsAreValid(rpcRequest.params)) {
1062
+ throw A2AError.invalidParams(`Invalid method parameters.`);
897
1063
  }
898
1064
  if (method === "message/stream" || method === "tasks/resubscribe") {
899
1065
  const params = rpcRequest.params;
@@ -901,8 +1067,8 @@ var JsonRpcTransportHandler = class {
901
1067
  if (!agentCard.capabilities.streaming) {
902
1068
  throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
903
1069
  }
904
- const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params) : this.requestHandler.resubscribe(params);
905
- return async function* jsonRpcEventStream() {
1070
+ const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params, context) : this.requestHandler.resubscribe(params, context);
1071
+ return (async function* jsonRpcEventStream() {
906
1072
  try {
907
1073
  for await (const event of agentEventStream) {
908
1074
  yield {
@@ -913,43 +1079,50 @@ var JsonRpcTransportHandler = class {
913
1079
  };
914
1080
  }
915
1081
  } catch (streamError) {
916
- console.error(`Error in agent event stream for ${method} (request ${requestId}):`, streamError);
1082
+ console.error(
1083
+ `Error in agent event stream for ${method} (request ${requestId}):`,
1084
+ streamError
1085
+ );
917
1086
  throw streamError;
918
1087
  }
919
- }();
1088
+ })();
920
1089
  } else {
921
1090
  let result;
922
1091
  switch (method) {
923
1092
  case "message/send":
924
- result = await this.requestHandler.sendMessage(rpcRequest.params);
1093
+ result = await this.requestHandler.sendMessage(rpcRequest.params, context);
925
1094
  break;
926
1095
  case "tasks/get":
927
- result = await this.requestHandler.getTask(rpcRequest.params);
1096
+ result = await this.requestHandler.getTask(rpcRequest.params, context);
928
1097
  break;
929
1098
  case "tasks/cancel":
930
- result = await this.requestHandler.cancelTask(rpcRequest.params);
1099
+ result = await this.requestHandler.cancelTask(rpcRequest.params, context);
931
1100
  break;
932
1101
  case "tasks/pushNotificationConfig/set":
933
1102
  result = await this.requestHandler.setTaskPushNotificationConfig(
934
- rpcRequest.params
1103
+ rpcRequest.params,
1104
+ context
935
1105
  );
936
1106
  break;
937
1107
  case "tasks/pushNotificationConfig/get":
938
1108
  result = await this.requestHandler.getTaskPushNotificationConfig(
939
- rpcRequest.params
1109
+ rpcRequest.params,
1110
+ context
940
1111
  );
941
1112
  break;
942
1113
  case "tasks/pushNotificationConfig/delete":
943
- await this.requestHandler.deleteTaskPushNotificationConfig(
944
- rpcRequest.params
945
- );
1114
+ await this.requestHandler.deleteTaskPushNotificationConfig(rpcRequest.params, context);
946
1115
  result = null;
947
1116
  break;
948
1117
  case "tasks/pushNotificationConfig/list":
949
1118
  result = await this.requestHandler.listTaskPushNotificationConfigs(
950
- rpcRequest.params
1119
+ rpcRequest.params,
1120
+ context
951
1121
  );
952
1122
  break;
1123
+ case "agent/getAuthenticatedExtendedCard":
1124
+ result = await this.requestHandler.getAuthenticatedExtendedAgentCard(context);
1125
+ break;
953
1126
  default:
954
1127
  throw A2AError.methodNotFound(method);
955
1128
  }
@@ -960,7 +1133,14 @@ var JsonRpcTransportHandler = class {
960
1133
  };
961
1134
  }
962
1135
  } catch (error) {
963
- const a2aError = error instanceof A2AError ? error : A2AError.internalError(error.message || "An unexpected error occurred.");
1136
+ let a2aError;
1137
+ if (error instanceof A2AError) {
1138
+ a2aError = error;
1139
+ } else {
1140
+ a2aError = A2AError.internalError(
1141
+ error instanceof Error && error.message || "An unexpected error occurred."
1142
+ );
1143
+ }
964
1144
  return {
965
1145
  jsonrpc: "2.0",
966
1146
  id: requestId,
@@ -968,6 +1148,47 @@ var JsonRpcTransportHandler = class {
968
1148
  };
969
1149
  }
970
1150
  }
1151
+ // Validates the basic structure of a JSON-RPC request
1152
+ isRequestValid(rpcRequest) {
1153
+ if (rpcRequest.jsonrpc !== "2.0") {
1154
+ return false;
1155
+ }
1156
+ if ("id" in rpcRequest) {
1157
+ const id = rpcRequest.id;
1158
+ const isString = typeof id === "string";
1159
+ const isInteger = typeof id === "number" && Number.isInteger(id);
1160
+ const isNull = id === null;
1161
+ if (!isString && !isInteger && !isNull) {
1162
+ return false;
1163
+ }
1164
+ }
1165
+ if (!rpcRequest.method || typeof rpcRequest.method !== "string") {
1166
+ return false;
1167
+ }
1168
+ return true;
1169
+ }
1170
+ // Validates that params is an object with non-empty string keys
1171
+ paramsAreValid(params) {
1172
+ if (typeof params !== "object" || params === null || Array.isArray(params)) {
1173
+ return false;
1174
+ }
1175
+ for (const key of Object.keys(params)) {
1176
+ if (key === "") {
1177
+ return false;
1178
+ }
1179
+ }
1180
+ return true;
1181
+ }
1182
+ };
1183
+
1184
+ // src/server/authentication/user.ts
1185
+ var UnauthenticatedUser = class {
1186
+ get isAuthenticated() {
1187
+ return false;
1188
+ }
1189
+ get userName() {
1190
+ return "";
1191
+ }
971
1192
  };
972
1193
  // Annotate the CommonJS export names for ESM import in node:
973
1194
  0 && (module.exports = {
@@ -981,5 +1202,7 @@ var JsonRpcTransportHandler = class {
981
1202
  InMemoryTaskStore,
982
1203
  JsonRpcTransportHandler,
983
1204
  RequestContext,
984
- ResultManager
1205
+ ResultManager,
1206
+ ServerCallContext,
1207
+ UnauthenticatedUser
985
1208
  });