@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.
- package/README.md +15 -1
- package/dist/a2a_request_handler-B5t-IxgA.d.ts +17 -0
- package/dist/a2a_request_handler-DUvKWfix.d.cts +17 -0
- package/dist/chunk-JA52GYRU.js +207 -0
- package/dist/client/index.d.cts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/server/express/index.cjs +338 -0
- package/dist/server/express/index.d.cts +19 -0
- package/dist/server/express/index.d.ts +19 -0
- package/dist/server/express/index.js +102 -0
- package/dist/server/index.cjs +102 -121
- package/dist/server/index.d.cts +11 -32
- package/dist/server/index.d.ts +11 -32
- package/dist/server/index.js +72 -278
- package/dist/types-DNKcmF0f.d.cts +2562 -0
- package/dist/types-DNKcmF0f.d.ts +2562 -0
- package/package.json +20 -7
- package/dist/types-CcBgkR2G.d.cts +0 -2048
- package/dist/types-CcBgkR2G.d.ts +0 -2048
package/dist/server/index.js
CHANGED
|
@@ -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
|
|
571
|
-
if (!
|
|
508
|
+
const task = await this.taskStore.load(params.taskId);
|
|
509
|
+
if (!task) {
|
|
572
510
|
throw A2AError.taskNotFound(params.taskId);
|
|
573
511
|
}
|
|
574
|
-
|
|
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
|
|
582
|
-
if (!
|
|
526
|
+
const task = await this.taskStore.load(params.id);
|
|
527
|
+
if (!task) {
|
|
583
528
|
throw A2AError.taskNotFound(params.id);
|
|
584
529
|
}
|
|
585
|
-
const
|
|
586
|
-
if (
|
|
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,
|