@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/README.md +272 -138
- package/dist/a2a_request_handler-DPkhsCMt.d.mts +37 -0
- package/dist/a2a_request_handler-DQfg1Q-R.d.ts +37 -0
- package/dist/auth-handler-DVLcl8yj.d.mts +209 -0
- package/dist/auth-handler-Gzpf3xHC.d.ts +209 -0
- package/dist/chunk-HZFUOBJQ.mjs +198 -0
- package/dist/chunk-LIEYEFQG.mjs +879 -0
- package/dist/chunk-LVD4GF26.mjs +262 -0
- package/dist/chunk-PHP7LM4Y.mjs +8 -0
- package/dist/chunk-UBRSFN2J.mjs +776 -0
- package/dist/client/index.d.mts +312 -0
- package/dist/client/index.d.ts +312 -0
- package/dist/client/index.js +1158 -0
- package/dist/client/index.mjs +367 -0
- package/dist/error-DExKs0Q3.d.mts +233 -0
- package/dist/error-j1vYKII2.d.ts +233 -0
- package/dist/index.d.mts +14 -2739
- package/dist/index.d.ts +14 -2739
- package/dist/index.js +1605 -1158
- package/dist/index.mjs +29 -1612
- package/dist/server/express/index.d.mts +25 -0
- package/dist/server/express/index.d.ts +25 -0
- package/dist/server/express/index.js +468 -0
- package/dist/server/express/index.mjs +10 -0
- package/dist/server/index.d.mts +26 -0
- package/dist/server/index.d.ts +26 -0
- package/dist/server/index.js +1173 -0
- package/dist/server/index.mjs +32 -0
- package/dist/types-Due_Cv6t.d.mts +2550 -0
- package/dist/types-Due_Cv6t.d.ts +2550 -0
- package/package.json +18 -11
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Request, Express, RequestHandler, ErrorRequestHandler } from 'express';
|
|
2
|
+
import { U as User, a as UnauthenticatedUser, A as A2ARequestHandler } from '../../a2a_request_handler-DPkhsCMt.mjs';
|
|
3
|
+
import '../../types-Due_Cv6t.mjs';
|
|
4
|
+
|
|
5
|
+
type UserBuilder = (req: Request) => Promise<User>;
|
|
6
|
+
declare const UserBuilder: {
|
|
7
|
+
NoAuthentication: () => Promise<UnauthenticatedUser>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
declare class A2AExpressApp {
|
|
11
|
+
private requestHandler;
|
|
12
|
+
private userBuilder;
|
|
13
|
+
constructor(requestHandler: A2ARequestHandler, userBuilder?: UserBuilder);
|
|
14
|
+
/**
|
|
15
|
+
* Adds A2A routes to an existing Express app.
|
|
16
|
+
* @param app Optional existing Express app.
|
|
17
|
+
* @param baseUrl The base URL for A2A endpoints (e.g., "/a2a/api").
|
|
18
|
+
* @param middlewares Optional array of Express middlewares to apply to the A2A routes.
|
|
19
|
+
* @param agentCardPath Optional custom path for the agent card endpoint (defaults to .well-known/agent-card.json).
|
|
20
|
+
* @returns The Express app with A2A routes.
|
|
21
|
+
*/
|
|
22
|
+
setupRoutes(app: Express, baseUrl?: string, middlewares?: Array<RequestHandler | ErrorRequestHandler>, agentCardPath?: string): Express;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { A2AExpressApp, UserBuilder };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Request, Express, RequestHandler, ErrorRequestHandler } from 'express';
|
|
2
|
+
import { U as User, a as UnauthenticatedUser, A as A2ARequestHandler } from '../../a2a_request_handler-DQfg1Q-R.js';
|
|
3
|
+
import '../../types-Due_Cv6t.js';
|
|
4
|
+
|
|
5
|
+
type UserBuilder = (req: Request) => Promise<User>;
|
|
6
|
+
declare const UserBuilder: {
|
|
7
|
+
NoAuthentication: () => Promise<UnauthenticatedUser>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
declare class A2AExpressApp {
|
|
11
|
+
private requestHandler;
|
|
12
|
+
private userBuilder;
|
|
13
|
+
constructor(requestHandler: A2ARequestHandler, userBuilder?: UserBuilder);
|
|
14
|
+
/**
|
|
15
|
+
* Adds A2A routes to an existing Express app.
|
|
16
|
+
* @param app Optional existing Express app.
|
|
17
|
+
* @param baseUrl The base URL for A2A endpoints (e.g., "/a2a/api").
|
|
18
|
+
* @param middlewares Optional array of Express middlewares to apply to the A2A routes.
|
|
19
|
+
* @param agentCardPath Optional custom path for the agent card endpoint (defaults to .well-known/agent-card.json).
|
|
20
|
+
* @returns The Express app with A2A routes.
|
|
21
|
+
*/
|
|
22
|
+
setupRoutes(app: Express, baseUrl?: string, middlewares?: Array<RequestHandler | ErrorRequestHandler>, agentCardPath?: string): Express;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { A2AExpressApp, UserBuilder };
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/server/express/index.ts
|
|
30
|
+
var express_exports = {};
|
|
31
|
+
__export(express_exports, {
|
|
32
|
+
A2AExpressApp: () => A2AExpressApp,
|
|
33
|
+
UserBuilder: () => UserBuilder
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(express_exports);
|
|
36
|
+
|
|
37
|
+
// src/server/express/a2a_express_app.ts
|
|
38
|
+
var import_express3 = __toESM(require("express"));
|
|
39
|
+
|
|
40
|
+
// src/constants.ts
|
|
41
|
+
var AGENT_CARD_PATH = ".well-known/agent-card.json";
|
|
42
|
+
var HTTP_EXTENSION_HEADER = "X-A2A-Extensions";
|
|
43
|
+
|
|
44
|
+
// src/server/express/json_rpc_handler.ts
|
|
45
|
+
var import_express = __toESM(require("express"));
|
|
46
|
+
|
|
47
|
+
// src/server/error.ts
|
|
48
|
+
var A2AError = class _A2AError extends Error {
|
|
49
|
+
code;
|
|
50
|
+
data;
|
|
51
|
+
taskId;
|
|
52
|
+
// Optional task ID context
|
|
53
|
+
constructor(code, message, data, taskId) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = "A2AError";
|
|
56
|
+
this.code = code;
|
|
57
|
+
this.data = data;
|
|
58
|
+
this.taskId = taskId;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Formats the error into a standard JSON-RPC error object structure.
|
|
62
|
+
*/
|
|
63
|
+
toJSONRPCError() {
|
|
64
|
+
const errorObject = {
|
|
65
|
+
code: this.code,
|
|
66
|
+
message: this.message
|
|
67
|
+
};
|
|
68
|
+
if (this.data !== void 0) {
|
|
69
|
+
errorObject.data = this.data;
|
|
70
|
+
}
|
|
71
|
+
return errorObject;
|
|
72
|
+
}
|
|
73
|
+
// Static factory methods for common errors
|
|
74
|
+
static parseError(message, data) {
|
|
75
|
+
return new _A2AError(-32700, message, data);
|
|
76
|
+
}
|
|
77
|
+
static invalidRequest(message, data) {
|
|
78
|
+
return new _A2AError(-32600, message, data);
|
|
79
|
+
}
|
|
80
|
+
static methodNotFound(method) {
|
|
81
|
+
return new _A2AError(-32601, `Method not found: ${method}`);
|
|
82
|
+
}
|
|
83
|
+
static invalidParams(message, data) {
|
|
84
|
+
return new _A2AError(-32602, message, data);
|
|
85
|
+
}
|
|
86
|
+
static internalError(message, data) {
|
|
87
|
+
return new _A2AError(-32603, message, data);
|
|
88
|
+
}
|
|
89
|
+
static taskNotFound(taskId) {
|
|
90
|
+
return new _A2AError(-32001, `Task not found: ${taskId}`, void 0, taskId);
|
|
91
|
+
}
|
|
92
|
+
static taskNotCancelable(taskId) {
|
|
93
|
+
return new _A2AError(-32002, `Task not cancelable: ${taskId}`, void 0, taskId);
|
|
94
|
+
}
|
|
95
|
+
static pushNotificationNotSupported() {
|
|
96
|
+
return new _A2AError(-32003, "Push Notification is not supported");
|
|
97
|
+
}
|
|
98
|
+
static unsupportedOperation(operation) {
|
|
99
|
+
return new _A2AError(-32004, `Unsupported operation: ${operation}`);
|
|
100
|
+
}
|
|
101
|
+
static authenticatedExtendedCardNotConfigured() {
|
|
102
|
+
return new _A2AError(-32007, `Extended card not configured.`);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// src/server/transports/jsonrpc_transport_handler.ts
|
|
107
|
+
var JsonRpcTransportHandler = class {
|
|
108
|
+
requestHandler;
|
|
109
|
+
constructor(requestHandler) {
|
|
110
|
+
this.requestHandler = requestHandler;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Handles an incoming JSON-RPC request.
|
|
114
|
+
* For streaming methods, it returns an AsyncGenerator of JSONRPCResult.
|
|
115
|
+
* For non-streaming methods, it returns a Promise of a single JSONRPCMessage (Result or ErrorResponse).
|
|
116
|
+
*/
|
|
117
|
+
async handle(requestBody, context) {
|
|
118
|
+
let rpcRequest;
|
|
119
|
+
try {
|
|
120
|
+
if (typeof requestBody === "string") {
|
|
121
|
+
rpcRequest = JSON.parse(requestBody);
|
|
122
|
+
} else if (typeof requestBody === "object" && requestBody !== null) {
|
|
123
|
+
rpcRequest = requestBody;
|
|
124
|
+
} else {
|
|
125
|
+
throw A2AError.parseError("Invalid request body type.");
|
|
126
|
+
}
|
|
127
|
+
if (!this.isRequestValid(rpcRequest)) {
|
|
128
|
+
throw A2AError.invalidRequest("Invalid JSON-RPC Request.");
|
|
129
|
+
}
|
|
130
|
+
} catch (error) {
|
|
131
|
+
const a2aError = error instanceof A2AError ? error : A2AError.parseError(
|
|
132
|
+
error instanceof SyntaxError && error.message || "Failed to parse JSON request."
|
|
133
|
+
);
|
|
134
|
+
return {
|
|
135
|
+
jsonrpc: "2.0",
|
|
136
|
+
id: rpcRequest?.id !== void 0 ? rpcRequest.id : null,
|
|
137
|
+
error: a2aError.toJSONRPCError()
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const { method, id: requestId = null } = rpcRequest;
|
|
141
|
+
try {
|
|
142
|
+
if (method !== "agent/getAuthenticatedExtendedCard" && !this.paramsAreValid(rpcRequest.params)) {
|
|
143
|
+
throw A2AError.invalidParams(`Invalid method parameters.`);
|
|
144
|
+
}
|
|
145
|
+
if (method === "message/stream" || method === "tasks/resubscribe") {
|
|
146
|
+
const params = rpcRequest.params;
|
|
147
|
+
const agentCard = await this.requestHandler.getAgentCard();
|
|
148
|
+
if (!agentCard.capabilities.streaming) {
|
|
149
|
+
throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
|
|
150
|
+
}
|
|
151
|
+
const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params, context) : this.requestHandler.resubscribe(params, context);
|
|
152
|
+
return (async function* jsonRpcEventStream() {
|
|
153
|
+
try {
|
|
154
|
+
for await (const event of agentEventStream) {
|
|
155
|
+
yield {
|
|
156
|
+
jsonrpc: "2.0",
|
|
157
|
+
id: requestId,
|
|
158
|
+
// Use the original request ID for all streamed responses
|
|
159
|
+
result: event
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
} catch (streamError) {
|
|
163
|
+
console.error(
|
|
164
|
+
`Error in agent event stream for ${method} (request ${requestId}):`,
|
|
165
|
+
streamError
|
|
166
|
+
);
|
|
167
|
+
throw streamError;
|
|
168
|
+
}
|
|
169
|
+
})();
|
|
170
|
+
} else {
|
|
171
|
+
let result;
|
|
172
|
+
switch (method) {
|
|
173
|
+
case "message/send":
|
|
174
|
+
result = await this.requestHandler.sendMessage(rpcRequest.params, context);
|
|
175
|
+
break;
|
|
176
|
+
case "tasks/get":
|
|
177
|
+
result = await this.requestHandler.getTask(rpcRequest.params, context);
|
|
178
|
+
break;
|
|
179
|
+
case "tasks/cancel":
|
|
180
|
+
result = await this.requestHandler.cancelTask(rpcRequest.params, context);
|
|
181
|
+
break;
|
|
182
|
+
case "tasks/pushNotificationConfig/set":
|
|
183
|
+
result = await this.requestHandler.setTaskPushNotificationConfig(
|
|
184
|
+
rpcRequest.params,
|
|
185
|
+
context
|
|
186
|
+
);
|
|
187
|
+
break;
|
|
188
|
+
case "tasks/pushNotificationConfig/get":
|
|
189
|
+
result = await this.requestHandler.getTaskPushNotificationConfig(
|
|
190
|
+
rpcRequest.params,
|
|
191
|
+
context
|
|
192
|
+
);
|
|
193
|
+
break;
|
|
194
|
+
case "tasks/pushNotificationConfig/delete":
|
|
195
|
+
await this.requestHandler.deleteTaskPushNotificationConfig(rpcRequest.params, context);
|
|
196
|
+
result = null;
|
|
197
|
+
break;
|
|
198
|
+
case "tasks/pushNotificationConfig/list":
|
|
199
|
+
result = await this.requestHandler.listTaskPushNotificationConfigs(
|
|
200
|
+
rpcRequest.params,
|
|
201
|
+
context
|
|
202
|
+
);
|
|
203
|
+
break;
|
|
204
|
+
case "agent/getAuthenticatedExtendedCard":
|
|
205
|
+
result = await this.requestHandler.getAuthenticatedExtendedAgentCard(context);
|
|
206
|
+
break;
|
|
207
|
+
default:
|
|
208
|
+
throw A2AError.methodNotFound(method);
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
jsonrpc: "2.0",
|
|
212
|
+
id: requestId,
|
|
213
|
+
result
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
} catch (error) {
|
|
217
|
+
let a2aError;
|
|
218
|
+
if (error instanceof A2AError) {
|
|
219
|
+
a2aError = error;
|
|
220
|
+
} else {
|
|
221
|
+
a2aError = A2AError.internalError(
|
|
222
|
+
error instanceof Error && error.message || "An unexpected error occurred."
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
jsonrpc: "2.0",
|
|
227
|
+
id: requestId,
|
|
228
|
+
error: a2aError.toJSONRPCError()
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Validates the basic structure of a JSON-RPC request
|
|
233
|
+
isRequestValid(rpcRequest) {
|
|
234
|
+
if (rpcRequest.jsonrpc !== "2.0") {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
if ("id" in rpcRequest) {
|
|
238
|
+
const id = rpcRequest.id;
|
|
239
|
+
const isString = typeof id === "string";
|
|
240
|
+
const isInteger = typeof id === "number" && Number.isInteger(id);
|
|
241
|
+
const isNull = id === null;
|
|
242
|
+
if (!isString && !isInteger && !isNull) {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (!rpcRequest.method || typeof rpcRequest.method !== "string") {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
// Validates that params is an object with non-empty string keys
|
|
252
|
+
paramsAreValid(params) {
|
|
253
|
+
if (typeof params !== "object" || params === null || Array.isArray(params)) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
for (const key of Object.keys(params)) {
|
|
257
|
+
if (key === "") {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// src/server/context.ts
|
|
266
|
+
var ServerCallContext = class {
|
|
267
|
+
_requestedExtensions;
|
|
268
|
+
_user;
|
|
269
|
+
_activatedExtensions;
|
|
270
|
+
constructor(requestedExtensions, user) {
|
|
271
|
+
this._requestedExtensions = requestedExtensions;
|
|
272
|
+
this._user = user;
|
|
273
|
+
}
|
|
274
|
+
get user() {
|
|
275
|
+
return this._user;
|
|
276
|
+
}
|
|
277
|
+
get activatedExtensions() {
|
|
278
|
+
return this._activatedExtensions;
|
|
279
|
+
}
|
|
280
|
+
get requestedExtensions() {
|
|
281
|
+
return this._requestedExtensions;
|
|
282
|
+
}
|
|
283
|
+
addActivatedExtension(uri) {
|
|
284
|
+
if (this._requestedExtensions?.has(uri)) {
|
|
285
|
+
if (!this._activatedExtensions) {
|
|
286
|
+
this._activatedExtensions = /* @__PURE__ */ new Set();
|
|
287
|
+
}
|
|
288
|
+
this._activatedExtensions.add(uri);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// src/server/utils.ts
|
|
294
|
+
function getRequestedExtensions(values) {
|
|
295
|
+
if (!values) {
|
|
296
|
+
return /* @__PURE__ */ new Set();
|
|
297
|
+
}
|
|
298
|
+
return new Set(
|
|
299
|
+
values.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0)
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// src/server/authentication/user.ts
|
|
304
|
+
var UnauthenticatedUser = class {
|
|
305
|
+
get isAuthenticated() {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
get userName() {
|
|
309
|
+
return "";
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
// src/server/express/json_rpc_handler.ts
|
|
314
|
+
function jsonRpcHandler(options) {
|
|
315
|
+
const jsonRpcTransportHandler = new JsonRpcTransportHandler(options.requestHandler);
|
|
316
|
+
const router = import_express.default.Router();
|
|
317
|
+
router.use(import_express.default.json(), jsonErrorHandler);
|
|
318
|
+
router.post("/", async (req, res) => {
|
|
319
|
+
try {
|
|
320
|
+
const user = await options.userBuilder(req);
|
|
321
|
+
const context = new ServerCallContext(
|
|
322
|
+
getRequestedExtensions(req.header(HTTP_EXTENSION_HEADER)),
|
|
323
|
+
user ?? new UnauthenticatedUser()
|
|
324
|
+
);
|
|
325
|
+
const rpcResponseOrStream = await jsonRpcTransportHandler.handle(req.body, context);
|
|
326
|
+
if (context.activatedExtensions) {
|
|
327
|
+
res.setHeader(HTTP_EXTENSION_HEADER, Array.from(context.activatedExtensions));
|
|
328
|
+
}
|
|
329
|
+
if (typeof rpcResponseOrStream?.[Symbol.asyncIterator] === "function") {
|
|
330
|
+
const stream = rpcResponseOrStream;
|
|
331
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
332
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
333
|
+
res.setHeader("Connection", "keep-alive");
|
|
334
|
+
res.flushHeaders();
|
|
335
|
+
try {
|
|
336
|
+
for await (const event of stream) {
|
|
337
|
+
res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
|
|
338
|
+
`);
|
|
339
|
+
res.write(`data: ${JSON.stringify(event)}
|
|
340
|
+
|
|
341
|
+
`);
|
|
342
|
+
}
|
|
343
|
+
} catch (streamError) {
|
|
344
|
+
console.error(`Error during SSE streaming (request ${req.body?.id}):`, streamError);
|
|
345
|
+
let a2aError;
|
|
346
|
+
if (streamError instanceof A2AError) {
|
|
347
|
+
a2aError = streamError;
|
|
348
|
+
} else {
|
|
349
|
+
a2aError = A2AError.internalError(
|
|
350
|
+
streamError instanceof Error && streamError.message || "Streaming error."
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
const errorResponse = {
|
|
354
|
+
jsonrpc: "2.0",
|
|
355
|
+
id: req.body?.id || null,
|
|
356
|
+
// Use original request ID if available
|
|
357
|
+
error: a2aError.toJSONRPCError()
|
|
358
|
+
};
|
|
359
|
+
if (!res.headersSent) {
|
|
360
|
+
res.status(500).json(errorResponse);
|
|
361
|
+
} else {
|
|
362
|
+
res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
|
|
363
|
+
`);
|
|
364
|
+
res.write(`event: error
|
|
365
|
+
`);
|
|
366
|
+
res.write(`data: ${JSON.stringify(errorResponse)}
|
|
367
|
+
|
|
368
|
+
`);
|
|
369
|
+
}
|
|
370
|
+
} finally {
|
|
371
|
+
if (!res.writableEnded) {
|
|
372
|
+
res.end();
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
} else {
|
|
376
|
+
const rpcResponse = rpcResponseOrStream;
|
|
377
|
+
res.status(200).json(rpcResponse);
|
|
378
|
+
}
|
|
379
|
+
} catch (error) {
|
|
380
|
+
console.error("Unhandled error in JSON-RPC POST handler:", error);
|
|
381
|
+
const a2aError = error instanceof A2AError ? error : A2AError.internalError("General processing error.");
|
|
382
|
+
const errorResponse = {
|
|
383
|
+
jsonrpc: "2.0",
|
|
384
|
+
id: req.body?.id || null,
|
|
385
|
+
error: a2aError.toJSONRPCError()
|
|
386
|
+
};
|
|
387
|
+
if (!res.headersSent) {
|
|
388
|
+
res.status(500).json(errorResponse);
|
|
389
|
+
} else if (!res.writableEnded) {
|
|
390
|
+
res.end();
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
return router;
|
|
395
|
+
}
|
|
396
|
+
var jsonErrorHandler = (err, _req, res, next) => {
|
|
397
|
+
if (err instanceof SyntaxError && "body" in err) {
|
|
398
|
+
const a2aError = A2AError.parseError("Invalid JSON payload.");
|
|
399
|
+
const errorResponse = {
|
|
400
|
+
jsonrpc: "2.0",
|
|
401
|
+
id: null,
|
|
402
|
+
error: a2aError.toJSONRPCError()
|
|
403
|
+
};
|
|
404
|
+
return res.status(400).json(errorResponse);
|
|
405
|
+
}
|
|
406
|
+
next(err);
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
// src/server/express/agent_card_handler.ts
|
|
410
|
+
var import_express2 = __toESM(require("express"));
|
|
411
|
+
function agentCardHandler(options) {
|
|
412
|
+
const router = import_express2.default.Router();
|
|
413
|
+
const provider = typeof options.agentCardProvider === "function" ? options.agentCardProvider : options.agentCardProvider.getAgentCard.bind(options.agentCardProvider);
|
|
414
|
+
router.get("/", async (_req, res) => {
|
|
415
|
+
try {
|
|
416
|
+
const agentCard = await provider();
|
|
417
|
+
res.json(agentCard);
|
|
418
|
+
} catch (error) {
|
|
419
|
+
console.error("Error fetching agent card:", error);
|
|
420
|
+
res.status(500).json({ error: "Failed to retrieve agent card" });
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
return router;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/server/express/common.ts
|
|
427
|
+
var UserBuilder = {
|
|
428
|
+
NoAuthentication: () => Promise.resolve(new UnauthenticatedUser())
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
// src/server/express/a2a_express_app.ts
|
|
432
|
+
var A2AExpressApp = class {
|
|
433
|
+
requestHandler;
|
|
434
|
+
userBuilder;
|
|
435
|
+
constructor(requestHandler, userBuilder = UserBuilder.NoAuthentication) {
|
|
436
|
+
this.requestHandler = requestHandler;
|
|
437
|
+
this.userBuilder = userBuilder;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Adds A2A routes to an existing Express app.
|
|
441
|
+
* @param app Optional existing Express app.
|
|
442
|
+
* @param baseUrl The base URL for A2A endpoints (e.g., "/a2a/api").
|
|
443
|
+
* @param middlewares Optional array of Express middlewares to apply to the A2A routes.
|
|
444
|
+
* @param agentCardPath Optional custom path for the agent card endpoint (defaults to .well-known/agent-card.json).
|
|
445
|
+
* @returns The Express app with A2A routes.
|
|
446
|
+
*/
|
|
447
|
+
setupRoutes(app, baseUrl = "", middlewares, agentCardPath = AGENT_CARD_PATH) {
|
|
448
|
+
const router = import_express3.default.Router();
|
|
449
|
+
router.use(import_express3.default.json(), jsonErrorHandler);
|
|
450
|
+
if (middlewares && middlewares.length > 0) {
|
|
451
|
+
router.use(middlewares);
|
|
452
|
+
}
|
|
453
|
+
router.use(
|
|
454
|
+
jsonRpcHandler({
|
|
455
|
+
requestHandler: this.requestHandler,
|
|
456
|
+
userBuilder: this.userBuilder
|
|
457
|
+
})
|
|
458
|
+
);
|
|
459
|
+
router.use(`/${agentCardPath}`, agentCardHandler({ agentCardProvider: this.requestHandler }));
|
|
460
|
+
app.use(baseUrl, router);
|
|
461
|
+
return app;
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
465
|
+
0 && (module.exports = {
|
|
466
|
+
A2AExpressApp,
|
|
467
|
+
UserBuilder
|
|
468
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { P as PushNotificationSender, a as PushNotificationStore } from '../error-DExKs0Q3.mjs';
|
|
2
|
+
export { i as A2AError, b as AgentExecutionEvent, A as AgentExecutor, D as DefaultExecutionEventBus, d as DefaultExecutionEventBusManager, f as DefaultRequestHandler, E as ExecutionEventBus, c as ExecutionEventBusManager, e as ExecutionEventQueue, g as ExtendedAgentCardProvider, j as InMemoryPushNotificationStore, I as InMemoryTaskStore, J as JsonRpcTransportHandler, R as RequestContext, h as ResultManager, T as TaskStore } from '../error-DExKs0Q3.mjs';
|
|
3
|
+
export { A as A2ARequestHandler, S as ServerCallContext, a as UnauthenticatedUser, U as User } from '../a2a_request_handler-DPkhsCMt.mjs';
|
|
4
|
+
import { T as Task } from '../types-Due_Cv6t.mjs';
|
|
5
|
+
import 'events';
|
|
6
|
+
|
|
7
|
+
interface DefaultPushNotificationSenderOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Timeout in milliseconds for the abort controller. Defaults to 5000ms.
|
|
10
|
+
*/
|
|
11
|
+
timeout?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Custom header name for the token. Defaults to 'X-A2A-Notification-Token'.
|
|
14
|
+
*/
|
|
15
|
+
tokenHeaderName?: string;
|
|
16
|
+
}
|
|
17
|
+
declare class DefaultPushNotificationSender implements PushNotificationSender {
|
|
18
|
+
private readonly pushNotificationStore;
|
|
19
|
+
private notificationChain;
|
|
20
|
+
private readonly options;
|
|
21
|
+
constructor(pushNotificationStore: PushNotificationStore, options?: DefaultPushNotificationSenderOptions);
|
|
22
|
+
send(task: Task): Promise<void>;
|
|
23
|
+
private _dispatchNotification;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { DefaultPushNotificationSender, type DefaultPushNotificationSenderOptions, PushNotificationSender, PushNotificationStore };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { P as PushNotificationSender, a as PushNotificationStore } from '../error-j1vYKII2.js';
|
|
2
|
+
export { i as A2AError, b as AgentExecutionEvent, A as AgentExecutor, D as DefaultExecutionEventBus, d as DefaultExecutionEventBusManager, f as DefaultRequestHandler, E as ExecutionEventBus, c as ExecutionEventBusManager, e as ExecutionEventQueue, g as ExtendedAgentCardProvider, j as InMemoryPushNotificationStore, I as InMemoryTaskStore, J as JsonRpcTransportHandler, R as RequestContext, h as ResultManager, T as TaskStore } from '../error-j1vYKII2.js';
|
|
3
|
+
export { A as A2ARequestHandler, S as ServerCallContext, a as UnauthenticatedUser, U as User } from '../a2a_request_handler-DQfg1Q-R.js';
|
|
4
|
+
import { T as Task } from '../types-Due_Cv6t.js';
|
|
5
|
+
import 'events';
|
|
6
|
+
|
|
7
|
+
interface DefaultPushNotificationSenderOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Timeout in milliseconds for the abort controller. Defaults to 5000ms.
|
|
10
|
+
*/
|
|
11
|
+
timeout?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Custom header name for the token. Defaults to 'X-A2A-Notification-Token'.
|
|
14
|
+
*/
|
|
15
|
+
tokenHeaderName?: string;
|
|
16
|
+
}
|
|
17
|
+
declare class DefaultPushNotificationSender implements PushNotificationSender {
|
|
18
|
+
private readonly pushNotificationStore;
|
|
19
|
+
private notificationChain;
|
|
20
|
+
private readonly options;
|
|
21
|
+
constructor(pushNotificationStore: PushNotificationStore, options?: DefaultPushNotificationSenderOptions);
|
|
22
|
+
send(task: Task): Promise<void>;
|
|
23
|
+
private _dispatchNotification;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { DefaultPushNotificationSender, type DefaultPushNotificationSenderOptions, PushNotificationSender, PushNotificationStore };
|