@a2a-js/sdk 0.2.5 → 0.3.1

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.
@@ -1,3 +1,8 @@
1
+ import {
2
+ A2AError,
3
+ JsonRpcTransportHandler
4
+ } from "../chunk-JA52GYRU.js";
5
+
1
6
  // src/server/agent_execution/request_context.ts
2
7
  var RequestContext = class {
3
8
  userMessage;
@@ -124,81 +129,6 @@ var ExecutionEventQueue = class {
124
129
  // src/server/request_handler/default_request_handler.ts
125
130
  import { v4 as uuidv4 } from "uuid";
126
131
 
127
- // src/server/error.ts
128
- var A2AError = class _A2AError extends Error {
129
- code;
130
- data;
131
- taskId;
132
- // Optional task ID context
133
- constructor(code, message, data, taskId) {
134
- super(message);
135
- this.name = "A2AError";
136
- this.code = code;
137
- this.data = data;
138
- this.taskId = taskId;
139
- }
140
- /**
141
- * Formats the error into a standard JSON-RPC error object structure.
142
- */
143
- toJSONRPCError() {
144
- const errorObject = {
145
- code: this.code,
146
- message: this.message
147
- };
148
- if (this.data !== void 0) {
149
- errorObject.data = this.data;
150
- }
151
- return errorObject;
152
- }
153
- // Static factory methods for common errors
154
- static parseError(message, data) {
155
- return new _A2AError(-32700, message, data);
156
- }
157
- static invalidRequest(message, data) {
158
- return new _A2AError(-32600, message, data);
159
- }
160
- static methodNotFound(method) {
161
- return new _A2AError(
162
- -32601,
163
- `Method not found: ${method}`
164
- );
165
- }
166
- static invalidParams(message, data) {
167
- return new _A2AError(-32602, message, data);
168
- }
169
- static internalError(message, data) {
170
- return new _A2AError(-32603, message, data);
171
- }
172
- static taskNotFound(taskId) {
173
- return new _A2AError(
174
- -32001,
175
- `Task not found: ${taskId}`,
176
- void 0,
177
- taskId
178
- );
179
- }
180
- static taskNotCancelable(taskId) {
181
- return new _A2AError(
182
- -32002,
183
- `Task not cancelable: ${taskId}`,
184
- void 0,
185
- taskId
186
- );
187
- }
188
- static pushNotificationNotSupported() {
189
- return new _A2AError(
190
- -32003,
191
- "Push Notification is not supported"
192
- );
193
- }
194
- static unsupportedOperation(operation) {
195
- return new _A2AError(
196
- -32004,
197
- `Unsupported operation: ${operation}`
198
- );
199
- }
200
- };
201
-
202
132
  // src/server/result_manager.ts
203
133
  var ResultManager = class {
204
134
  taskStore;
@@ -331,20 +261,28 @@ var ResultManager = class {
331
261
  var terminalStates = ["completed", "failed", "canceled", "rejected"];
332
262
  var DefaultRequestHandler = class {
333
263
  agentCard;
264
+ extendedAgentCard;
334
265
  taskStore;
335
266
  agentExecutor;
336
267
  eventBusManager;
337
268
  // Store for push notification configurations (could be part of TaskStore or separate)
338
269
  pushNotificationConfigs = /* @__PURE__ */ new Map();
339
- constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager()) {
270
+ constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), extendedAgentCard) {
340
271
  this.agentCard = agentCard;
341
272
  this.taskStore = taskStore;
342
273
  this.agentExecutor = agentExecutor;
343
274
  this.eventBusManager = eventBusManager;
275
+ this.extendedAgentCard = extendedAgentCard;
344
276
  }
345
277
  async getAgentCard() {
346
278
  return this.agentCard;
347
279
  }
280
+ async getAuthenticatedExtendedAgentCard() {
281
+ if (!this.extendedAgentCard) {
282
+ throw A2AError.authenticatedExtendedCardNotConfigured();
283
+ }
284
+ return this.extendedAgentCard;
285
+ }
348
286
  async _createRequestContext(incomingMessage, taskId, isStream) {
349
287
  let task;
350
288
  let referenceTasks;
@@ -567,27 +505,78 @@ var DefaultRequestHandler = class {
567
505
  if (!this.agentCard.capabilities.pushNotifications) {
568
506
  throw A2AError.pushNotificationNotSupported();
569
507
  }
570
- const taskAndHistory = await this.taskStore.load(params.taskId);
571
- if (!taskAndHistory) {
508
+ const task = await this.taskStore.load(params.taskId);
509
+ if (!task) {
572
510
  throw A2AError.taskNotFound(params.taskId);
573
511
  }
574
- this.pushNotificationConfigs.set(params.taskId, params.pushNotificationConfig);
512
+ const { taskId, pushNotificationConfig } = params;
513
+ if (!pushNotificationConfig.id) {
514
+ pushNotificationConfig.id = taskId;
515
+ }
516
+ const configs = this.pushNotificationConfigs.get(taskId) || [];
517
+ const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfig.id);
518
+ updatedConfigs.push(pushNotificationConfig);
519
+ this.pushNotificationConfigs.set(taskId, updatedConfigs);
575
520
  return params;
576
521
  }
577
522
  async getTaskPushNotificationConfig(params) {
578
523
  if (!this.agentCard.capabilities.pushNotifications) {
579
524
  throw A2AError.pushNotificationNotSupported();
580
525
  }
581
- const taskAndHistory = await this.taskStore.load(params.id);
582
- if (!taskAndHistory) {
526
+ const task = await this.taskStore.load(params.id);
527
+ if (!task) {
583
528
  throw A2AError.taskNotFound(params.id);
584
529
  }
585
- const config = this.pushNotificationConfigs.get(params.id);
586
- if (!config) {
530
+ const configs = this.pushNotificationConfigs.get(params.id) || [];
531
+ if (configs.length === 0) {
587
532
  throw A2AError.internalError(`Push notification config not found for task ${params.id}.`);
588
533
  }
534
+ let configId;
535
+ if ("pushNotificationConfigId" in params && params.pushNotificationConfigId) {
536
+ configId = params.pushNotificationConfigId;
537
+ } else {
538
+ configId = params.id;
539
+ }
540
+ const config = configs.find((c) => c.id === configId);
541
+ if (!config) {
542
+ throw A2AError.internalError(`Push notification config with id '${configId}' not found for task ${params.id}.`);
543
+ }
589
544
  return { taskId: params.id, pushNotificationConfig: config };
590
545
  }
546
+ async listTaskPushNotificationConfigs(params) {
547
+ if (!this.agentCard.capabilities.pushNotifications) {
548
+ throw A2AError.pushNotificationNotSupported();
549
+ }
550
+ const task = await this.taskStore.load(params.id);
551
+ if (!task) {
552
+ throw A2AError.taskNotFound(params.id);
553
+ }
554
+ const configs = this.pushNotificationConfigs.get(params.id) || [];
555
+ return configs.map((config) => ({
556
+ taskId: params.id,
557
+ pushNotificationConfig: config
558
+ }));
559
+ }
560
+ async deleteTaskPushNotificationConfig(params) {
561
+ if (!this.agentCard.capabilities.pushNotifications) {
562
+ throw A2AError.pushNotificationNotSupported();
563
+ }
564
+ const task = await this.taskStore.load(params.id);
565
+ if (!task) {
566
+ throw A2AError.taskNotFound(params.id);
567
+ }
568
+ const { id: taskId, pushNotificationConfigId } = params;
569
+ const configs = this.pushNotificationConfigs.get(taskId);
570
+ if (!configs) {
571
+ return;
572
+ }
573
+ const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfigId);
574
+ if (updatedConfigs.length === 0) {
575
+ this.pushNotificationConfigs.delete(taskId);
576
+ } else if (updatedConfigs.length < configs.length) {
577
+ this.pushNotificationConfigs.set(taskId, updatedConfigs);
578
+ }
579
+ }
591
580
  async *resubscribe(params) {
592
581
  if (!this.agentCard.capabilities.streaming) {
593
582
  throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
@@ -634,203 +623,8 @@ var InMemoryTaskStore = class {
634
623
  this.store.set(task.id, { ...task });
635
624
  }
636
625
  };
637
-
638
- // src/server/transports/jsonrpc_transport_handler.ts
639
- var JsonRpcTransportHandler = class {
640
- requestHandler;
641
- constructor(requestHandler) {
642
- this.requestHandler = requestHandler;
643
- }
644
- /**
645
- * Handles an incoming JSON-RPC request.
646
- * For streaming methods, it returns an AsyncGenerator of JSONRPCResult.
647
- * For non-streaming methods, it returns a Promise of a single JSONRPCMessage (Result or ErrorResponse).
648
- */
649
- async handle(requestBody) {
650
- let rpcRequest;
651
- try {
652
- if (typeof requestBody === "string") {
653
- rpcRequest = JSON.parse(requestBody);
654
- } else if (typeof requestBody === "object" && requestBody !== null) {
655
- rpcRequest = requestBody;
656
- } else {
657
- throw A2AError.parseError("Invalid request body type.");
658
- }
659
- if (rpcRequest.jsonrpc !== "2.0" || !rpcRequest.method || typeof rpcRequest.method !== "string") {
660
- throw A2AError.invalidRequest(
661
- "Invalid JSON-RPC request structure."
662
- );
663
- }
664
- } catch (error) {
665
- const a2aError = error instanceof A2AError ? error : A2AError.parseError(error.message || "Failed to parse JSON request.");
666
- return {
667
- jsonrpc: "2.0",
668
- id: typeof rpcRequest?.id !== "undefined" ? rpcRequest.id : null,
669
- error: a2aError.toJSONRPCError()
670
- };
671
- }
672
- const { method, params = {}, id: requestId = null } = rpcRequest;
673
- try {
674
- if (method === "message/stream" || method === "tasks/resubscribe") {
675
- const agentCard = await this.requestHandler.getAgentCard();
676
- if (!agentCard.capabilities.streaming) {
677
- throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
678
- }
679
- const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params) : this.requestHandler.resubscribe(params);
680
- return async function* jsonRpcEventStream() {
681
- try {
682
- for await (const event of agentEventStream) {
683
- yield {
684
- jsonrpc: "2.0",
685
- id: requestId,
686
- // Use the original request ID for all streamed responses
687
- result: event
688
- };
689
- }
690
- } catch (streamError) {
691
- console.error(`Error in agent event stream for ${method} (request ${requestId}):`, streamError);
692
- throw streamError;
693
- }
694
- }();
695
- } else {
696
- let result;
697
- switch (method) {
698
- case "message/send":
699
- result = await this.requestHandler.sendMessage(params);
700
- break;
701
- case "tasks/get":
702
- result = await this.requestHandler.getTask(params);
703
- break;
704
- case "tasks/cancel":
705
- result = await this.requestHandler.cancelTask(params);
706
- break;
707
- case "tasks/pushNotificationConfig/set":
708
- result = await this.requestHandler.setTaskPushNotificationConfig(
709
- params
710
- );
711
- break;
712
- case "tasks/pushNotificationConfig/get":
713
- result = await this.requestHandler.getTaskPushNotificationConfig(
714
- params
715
- );
716
- break;
717
- default:
718
- throw A2AError.methodNotFound(method);
719
- }
720
- return {
721
- jsonrpc: "2.0",
722
- id: requestId,
723
- result
724
- };
725
- }
726
- } catch (error) {
727
- const a2aError = error instanceof A2AError ? error : A2AError.internalError(error.message || "An unexpected error occurred.");
728
- return {
729
- jsonrpc: "2.0",
730
- id: requestId,
731
- error: a2aError.toJSONRPCError()
732
- };
733
- }
734
- }
735
- };
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
626
  export {
832
627
  A2AError,
833
- A2AExpressApp,
834
628
  DefaultExecutionEventBus,
835
629
  DefaultExecutionEventBusManager,
836
630
  DefaultRequestHandler,