@a2a-js/sdk 0.2.5 → 0.3.0

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.
@@ -197,6 +197,12 @@ var A2AError = class _A2AError extends Error {
197
197
  `Unsupported operation: ${operation}`
198
198
  );
199
199
  }
200
+ static authenticatedExtendedCardNotConfigured() {
201
+ return new _A2AError(
202
+ -32007,
203
+ `Extended card not configured.`
204
+ );
205
+ }
200
206
  };
201
207
 
202
208
  // src/server/result_manager.ts
@@ -331,20 +337,28 @@ var ResultManager = class {
331
337
  var terminalStates = ["completed", "failed", "canceled", "rejected"];
332
338
  var DefaultRequestHandler = class {
333
339
  agentCard;
340
+ extendedAgentCard;
334
341
  taskStore;
335
342
  agentExecutor;
336
343
  eventBusManager;
337
344
  // Store for push notification configurations (could be part of TaskStore or separate)
338
345
  pushNotificationConfigs = /* @__PURE__ */ new Map();
339
- constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager()) {
346
+ constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), extendedAgentCard) {
340
347
  this.agentCard = agentCard;
341
348
  this.taskStore = taskStore;
342
349
  this.agentExecutor = agentExecutor;
343
350
  this.eventBusManager = eventBusManager;
351
+ this.extendedAgentCard = extendedAgentCard;
344
352
  }
345
353
  async getAgentCard() {
346
354
  return this.agentCard;
347
355
  }
356
+ async getAuthenticatedExtendedAgentCard() {
357
+ if (!this.extendedAgentCard) {
358
+ throw A2AError.authenticatedExtendedCardNotConfigured();
359
+ }
360
+ return this.extendedAgentCard;
361
+ }
348
362
  async _createRequestContext(incomingMessage, taskId, isStream) {
349
363
  let task;
350
364
  let referenceTasks;
@@ -567,27 +581,78 @@ var DefaultRequestHandler = class {
567
581
  if (!this.agentCard.capabilities.pushNotifications) {
568
582
  throw A2AError.pushNotificationNotSupported();
569
583
  }
570
- const taskAndHistory = await this.taskStore.load(params.taskId);
571
- if (!taskAndHistory) {
584
+ const task = await this.taskStore.load(params.taskId);
585
+ if (!task) {
572
586
  throw A2AError.taskNotFound(params.taskId);
573
587
  }
574
- this.pushNotificationConfigs.set(params.taskId, params.pushNotificationConfig);
588
+ const { taskId, pushNotificationConfig } = params;
589
+ if (!pushNotificationConfig.id) {
590
+ pushNotificationConfig.id = taskId;
591
+ }
592
+ const configs = this.pushNotificationConfigs.get(taskId) || [];
593
+ const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfig.id);
594
+ updatedConfigs.push(pushNotificationConfig);
595
+ this.pushNotificationConfigs.set(taskId, updatedConfigs);
575
596
  return params;
576
597
  }
577
598
  async getTaskPushNotificationConfig(params) {
578
599
  if (!this.agentCard.capabilities.pushNotifications) {
579
600
  throw A2AError.pushNotificationNotSupported();
580
601
  }
581
- const taskAndHistory = await this.taskStore.load(params.id);
582
- if (!taskAndHistory) {
602
+ const task = await this.taskStore.load(params.id);
603
+ if (!task) {
583
604
  throw A2AError.taskNotFound(params.id);
584
605
  }
585
- const config = this.pushNotificationConfigs.get(params.id);
586
- if (!config) {
606
+ const configs = this.pushNotificationConfigs.get(params.id) || [];
607
+ if (configs.length === 0) {
587
608
  throw A2AError.internalError(`Push notification config not found for task ${params.id}.`);
588
609
  }
610
+ let configId;
611
+ if ("pushNotificationConfigId" in params && params.pushNotificationConfigId) {
612
+ configId = params.pushNotificationConfigId;
613
+ } else {
614
+ configId = params.id;
615
+ }
616
+ const config = configs.find((c) => c.id === configId);
617
+ if (!config) {
618
+ throw A2AError.internalError(`Push notification config with id '${configId}' not found for task ${params.id}.`);
619
+ }
589
620
  return { taskId: params.id, pushNotificationConfig: config };
590
621
  }
622
+ async listTaskPushNotificationConfigs(params) {
623
+ if (!this.agentCard.capabilities.pushNotifications) {
624
+ throw A2AError.pushNotificationNotSupported();
625
+ }
626
+ const task = await this.taskStore.load(params.id);
627
+ if (!task) {
628
+ throw A2AError.taskNotFound(params.id);
629
+ }
630
+ const configs = this.pushNotificationConfigs.get(params.id) || [];
631
+ return configs.map((config) => ({
632
+ taskId: params.id,
633
+ pushNotificationConfig: config
634
+ }));
635
+ }
636
+ async deleteTaskPushNotificationConfig(params) {
637
+ if (!this.agentCard.capabilities.pushNotifications) {
638
+ throw A2AError.pushNotificationNotSupported();
639
+ }
640
+ const task = await this.taskStore.load(params.id);
641
+ if (!task) {
642
+ throw A2AError.taskNotFound(params.id);
643
+ }
644
+ const { id: taskId, pushNotificationConfigId } = params;
645
+ const configs = this.pushNotificationConfigs.get(taskId);
646
+ if (!configs) {
647
+ return;
648
+ }
649
+ const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfigId);
650
+ if (updatedConfigs.length === 0) {
651
+ this.pushNotificationConfigs.delete(taskId);
652
+ } else if (updatedConfigs.length < configs.length) {
653
+ this.pushNotificationConfigs.set(taskId, updatedConfigs);
654
+ }
655
+ }
591
656
  async *resubscribe(params) {
592
657
  if (!this.agentCard.capabilities.streaming) {
593
658
  throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
@@ -669,9 +734,21 @@ var JsonRpcTransportHandler = class {
669
734
  error: a2aError.toJSONRPCError()
670
735
  };
671
736
  }
672
- const { method, params = {}, id: requestId = null } = rpcRequest;
737
+ const { method, id: requestId = null } = rpcRequest;
673
738
  try {
739
+ if (method === "agent/getAuthenticatedExtendedCard") {
740
+ const result = await this.requestHandler.getAuthenticatedExtendedAgentCard();
741
+ return {
742
+ jsonrpc: "2.0",
743
+ id: requestId,
744
+ result
745
+ };
746
+ }
747
+ if (!rpcRequest.params) {
748
+ throw A2AError.invalidParams(`'params' is required for '${method}'`);
749
+ }
674
750
  if (method === "message/stream" || method === "tasks/resubscribe") {
751
+ const params = rpcRequest.params;
675
752
  const agentCard = await this.requestHandler.getAgentCard();
676
753
  if (!agentCard.capabilities.streaming) {
677
754
  throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
@@ -696,22 +773,33 @@ var JsonRpcTransportHandler = class {
696
773
  let result;
697
774
  switch (method) {
698
775
  case "message/send":
699
- result = await this.requestHandler.sendMessage(params);
776
+ result = await this.requestHandler.sendMessage(rpcRequest.params);
700
777
  break;
701
778
  case "tasks/get":
702
- result = await this.requestHandler.getTask(params);
779
+ result = await this.requestHandler.getTask(rpcRequest.params);
703
780
  break;
704
781
  case "tasks/cancel":
705
- result = await this.requestHandler.cancelTask(params);
782
+ result = await this.requestHandler.cancelTask(rpcRequest.params);
706
783
  break;
707
784
  case "tasks/pushNotificationConfig/set":
708
785
  result = await this.requestHandler.setTaskPushNotificationConfig(
709
- params
786
+ rpcRequest.params
710
787
  );
711
788
  break;
712
789
  case "tasks/pushNotificationConfig/get":
713
790
  result = await this.requestHandler.getTaskPushNotificationConfig(
714
- params
791
+ rpcRequest.params
792
+ );
793
+ break;
794
+ case "tasks/pushNotificationConfig/delete":
795
+ await this.requestHandler.deleteTaskPushNotificationConfig(
796
+ rpcRequest.params
797
+ );
798
+ result = null;
799
+ break;
800
+ case "tasks/pushNotificationConfig/list":
801
+ result = await this.requestHandler.listTaskPushNotificationConfigs(
802
+ rpcRequest.params
715
803
  );
716
804
  break;
717
805
  default:
@@ -733,104 +821,8 @@ var JsonRpcTransportHandler = class {
733
821
  }
734
822
  }
735
823
  };
736
-
737
- // src/server/a2a_express_app.ts
738
- import express from "express";
739
- var A2AExpressApp = class {
740
- requestHandler;
741
- // Kept for getAgentCard
742
- jsonRpcTransportHandler;
743
- constructor(requestHandler) {
744
- this.requestHandler = requestHandler;
745
- this.jsonRpcTransportHandler = new JsonRpcTransportHandler(requestHandler);
746
- }
747
- /**
748
- * Adds A2A routes to an existing Express app.
749
- * @param app Optional existing Express app.
750
- * @param baseUrl The base URL for A2A endpoints (e.g., "/a2a/api").
751
- * @param middlewares Optional array of Express middlewares to apply to the A2A routes.
752
- * @returns The Express app with A2A routes.
753
- */
754
- setupRoutes(app, baseUrl = "", middlewares) {
755
- const router = express.Router();
756
- router.use(express.json(), ...middlewares ?? []);
757
- router.get("/.well-known/agent.json", async (req, res) => {
758
- try {
759
- const agentCard = await this.requestHandler.getAgentCard();
760
- res.json(agentCard);
761
- } catch (error) {
762
- console.error("Error fetching agent card:", error);
763
- res.status(500).json({ error: "Failed to retrieve agent card" });
764
- }
765
- });
766
- router.post("/", async (req, res) => {
767
- try {
768
- const rpcResponseOrStream = await this.jsonRpcTransportHandler.handle(req.body);
769
- if (typeof rpcResponseOrStream?.[Symbol.asyncIterator] === "function") {
770
- const stream = rpcResponseOrStream;
771
- res.setHeader("Content-Type", "text/event-stream");
772
- res.setHeader("Cache-Control", "no-cache");
773
- res.setHeader("Connection", "keep-alive");
774
- res.flushHeaders();
775
- try {
776
- for await (const event of stream) {
777
- res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
778
- `);
779
- res.write(`data: ${JSON.stringify(event)}
780
-
781
- `);
782
- }
783
- } catch (streamError) {
784
- console.error(`Error during SSE streaming (request ${req.body?.id}):`, streamError);
785
- const a2aError = streamError instanceof A2AError ? streamError : A2AError.internalError(streamError.message || "Streaming error.");
786
- const errorResponse = {
787
- jsonrpc: "2.0",
788
- id: req.body?.id || null,
789
- // Use original request ID if available
790
- error: a2aError.toJSONRPCError()
791
- };
792
- if (!res.headersSent) {
793
- res.status(500).json(errorResponse);
794
- } else {
795
- res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
796
- `);
797
- res.write(`event: error
798
- `);
799
- res.write(`data: ${JSON.stringify(errorResponse)}
800
-
801
- `);
802
- }
803
- } finally {
804
- if (!res.writableEnded) {
805
- res.end();
806
- }
807
- }
808
- } else {
809
- const rpcResponse = rpcResponseOrStream;
810
- res.status(200).json(rpcResponse);
811
- }
812
- } catch (error) {
813
- console.error("Unhandled error in A2AExpressApp POST handler:", error);
814
- const a2aError = error instanceof A2AError ? error : A2AError.internalError("General processing error.");
815
- const errorResponse = {
816
- jsonrpc: "2.0",
817
- id: req.body?.id || null,
818
- error: a2aError.toJSONRPCError()
819
- };
820
- if (!res.headersSent) {
821
- res.status(500).json(errorResponse);
822
- } else if (!res.writableEnded) {
823
- res.end();
824
- }
825
- }
826
- });
827
- app.use(baseUrl, router);
828
- return app;
829
- }
830
- };
831
824
  export {
832
825
  A2AError,
833
- A2AExpressApp,
834
826
  DefaultExecutionEventBus,
835
827
  DefaultExecutionEventBusManager,
836
828
  DefaultRequestHandler,