@mailmodo/a2a 0.3.3 → 0.3.7
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 +385 -173
- package/dist/a2a_request_handler-1Isk3l-0.d.mts +49 -0
- package/dist/a2a_request_handler-BuP9LgXH.d.ts +49 -0
- package/dist/chunk-7JFJW6P6.mjs +38 -0
- package/dist/chunk-AZGEDUZX.mjs +261 -0
- package/dist/chunk-BNBEZNW7.mjs +122 -0
- package/dist/chunk-PHP7LM4Y.mjs +8 -0
- package/dist/client/index.d.mts +666 -0
- package/dist/client/index.d.ts +666 -0
- package/dist/client/index.js +1605 -0
- package/dist/client/index.mjs +1448 -0
- package/dist/extensions-DvruCIzw.d.mts +2589 -0
- package/dist/extensions-DvruCIzw.d.ts +2589 -0
- package/dist/index.d.mts +5 -2758
- package/dist/index.d.ts +5 -2758
- package/dist/index.js +28 -1637
- package/dist/index.mjs +9 -1628
- package/dist/server/express/index.d.mts +97 -0
- package/dist/server/express/index.d.ts +97 -0
- package/dist/server/express/index.js +994 -0
- package/dist/server/express/index.mjs +646 -0
- package/dist/server/index.d.mts +316 -0
- package/dist/server/index.d.ts +316 -0
- package/dist/server/index.js +1386 -0
- package/dist/server/index.mjs +1070 -0
- package/package.json +51 -22
package/dist/index.js
CHANGED
|
@@ -1,30 +1,7 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defProps = Object.defineProperties;
|
|
4
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
9
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
-
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
12
|
-
var __typeError = (msg) => {
|
|
13
|
-
throw TypeError(msg);
|
|
14
|
-
};
|
|
15
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
16
|
-
var __spreadValues = (a, b) => {
|
|
17
|
-
for (var prop in b || (b = {}))
|
|
18
|
-
if (__hasOwnProp.call(b, prop))
|
|
19
|
-
__defNormalProp(a, prop, b[prop]);
|
|
20
|
-
if (__getOwnPropSymbols)
|
|
21
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
22
|
-
if (__propIsEnum.call(b, prop))
|
|
23
|
-
__defNormalProp(a, prop, b[prop]);
|
|
24
|
-
}
|
|
25
|
-
return a;
|
|
26
|
-
};
|
|
27
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
28
5
|
var __export = (target, all) => {
|
|
29
6
|
for (var name in all)
|
|
30
7
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -37,1644 +14,58 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
37
14
|
}
|
|
38
15
|
return to;
|
|
39
16
|
};
|
|
40
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
41
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
42
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
43
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
44
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
45
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
46
|
-
mod
|
|
47
|
-
));
|
|
48
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
49
|
-
var __async = (__this, __arguments, generator) => {
|
|
50
|
-
return new Promise((resolve, reject) => {
|
|
51
|
-
var fulfilled = (value) => {
|
|
52
|
-
try {
|
|
53
|
-
step(generator.next(value));
|
|
54
|
-
} catch (e) {
|
|
55
|
-
reject(e);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
var rejected = (value) => {
|
|
59
|
-
try {
|
|
60
|
-
step(generator.throw(value));
|
|
61
|
-
} catch (e) {
|
|
62
|
-
reject(e);
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
66
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
67
|
-
});
|
|
68
|
-
};
|
|
69
|
-
var __await = function(promise, isYieldStar) {
|
|
70
|
-
this[0] = promise;
|
|
71
|
-
this[1] = isYieldStar;
|
|
72
|
-
};
|
|
73
|
-
var __asyncGenerator = (__this, __arguments, generator) => {
|
|
74
|
-
var resume = (k, v, yes, no) => {
|
|
75
|
-
try {
|
|
76
|
-
var x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done;
|
|
77
|
-
Promise.resolve(isAwait ? v[0] : v).then((y) => isAwait ? resume(k === "return" ? k : "next", v[1] ? { done: y.done, value: y.value } : y, yes, no) : yes({ value: y, done })).catch((e) => resume("throw", e, yes, no));
|
|
78
|
-
} catch (e) {
|
|
79
|
-
no(e);
|
|
80
|
-
}
|
|
81
|
-
}, method = (k) => it[k] = (x) => new Promise((yes, no) => resume(k, x, yes, no)), it = {};
|
|
82
|
-
return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it;
|
|
83
|
-
};
|
|
84
|
-
var __yieldStar = (value) => {
|
|
85
|
-
var obj = value[__knownSymbol("asyncIterator")], isAwait = false, method, it = {};
|
|
86
|
-
if (obj == null) {
|
|
87
|
-
obj = value[__knownSymbol("iterator")]();
|
|
88
|
-
method = (k) => it[k] = (x) => obj[k](x);
|
|
89
|
-
} else {
|
|
90
|
-
obj = obj.call(value);
|
|
91
|
-
method = (k) => it[k] = (v) => {
|
|
92
|
-
if (isAwait) {
|
|
93
|
-
isAwait = false;
|
|
94
|
-
if (k === "throw") throw v;
|
|
95
|
-
return v;
|
|
96
|
-
}
|
|
97
|
-
isAwait = true;
|
|
98
|
-
return {
|
|
99
|
-
done: false,
|
|
100
|
-
value: new __await(new Promise((resolve) => {
|
|
101
|
-
var x = obj[k](v);
|
|
102
|
-
if (!(x instanceof Object)) __typeError("Object expected");
|
|
103
|
-
resolve(x);
|
|
104
|
-
}), 1)
|
|
105
|
-
};
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
return it[__knownSymbol("iterator")] = () => it, method("next"), "throw" in obj ? method("throw") : it.throw = (x) => {
|
|
109
|
-
throw x;
|
|
110
|
-
}, "return" in obj && method("return"), it;
|
|
111
|
-
};
|
|
112
|
-
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
113
18
|
|
|
114
19
|
// src/index.ts
|
|
115
20
|
var index_exports = {};
|
|
116
21
|
__export(index_exports, {
|
|
117
|
-
A2AClient: () => A2AClient,
|
|
118
|
-
A2AError: () => A2AError,
|
|
119
|
-
A2AExpressApp: () => A2AExpressApp,
|
|
120
22
|
AGENT_CARD_PATH: () => AGENT_CARD_PATH,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
DefaultRequestHandler: () => DefaultRequestHandler,
|
|
124
|
-
ExecutionEventQueue: () => ExecutionEventQueue,
|
|
125
|
-
InMemoryTaskStore: () => InMemoryTaskStore,
|
|
126
|
-
JsonRpcTransportHandler: () => JsonRpcTransportHandler,
|
|
127
|
-
RequestContext: () => RequestContext,
|
|
128
|
-
ResultManager: () => ResultManager,
|
|
129
|
-
createAuthenticatingFetchWithRetry: () => createAuthenticatingFetchWithRetry,
|
|
130
|
-
getCurrentTimestamp: () => getCurrentTimestamp,
|
|
131
|
-
isArtifactUpdate: () => isArtifactUpdate,
|
|
132
|
-
isObject: () => isObject,
|
|
133
|
-
isTaskStatusUpdate: () => isTaskStatusUpdate
|
|
23
|
+
Extensions: () => Extensions,
|
|
24
|
+
HTTP_EXTENSION_HEADER: () => HTTP_EXTENSION_HEADER
|
|
134
25
|
});
|
|
135
26
|
module.exports = __toCommonJS(index_exports);
|
|
136
27
|
|
|
137
28
|
// src/constants.ts
|
|
138
29
|
var AGENT_CARD_PATH = ".well-known/agent-card.json";
|
|
30
|
+
var HTTP_EXTENSION_HEADER = "X-A2A-Extensions";
|
|
139
31
|
|
|
140
|
-
// src/
|
|
141
|
-
var
|
|
142
|
-
constructor(userMessage, taskId, contextId, task, referenceTasks) {
|
|
143
|
-
this.userMessage = userMessage;
|
|
144
|
-
this.taskId = taskId;
|
|
145
|
-
this.contextId = contextId;
|
|
146
|
-
this.task = task;
|
|
147
|
-
this.referenceTasks = referenceTasks;
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// src/server/events/execution_event_bus.ts
|
|
152
|
-
var import_events = require("events");
|
|
153
|
-
var DefaultExecutionEventBus = class extends import_events.EventEmitter {
|
|
154
|
-
constructor() {
|
|
155
|
-
super();
|
|
156
|
-
}
|
|
157
|
-
publish(event) {
|
|
158
|
-
this.emit("event", event);
|
|
159
|
-
}
|
|
160
|
-
finished() {
|
|
161
|
-
this.emit("finished");
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// src/server/events/execution_event_bus_manager.ts
|
|
166
|
-
var DefaultExecutionEventBusManager = class {
|
|
167
|
-
constructor() {
|
|
168
|
-
this.taskIdToBus = /* @__PURE__ */ new Map();
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Creates or retrieves an existing ExecutionEventBus based on the taskId.
|
|
172
|
-
* @param taskId The ID of the task.
|
|
173
|
-
* @returns An instance of IExecutionEventBus.
|
|
174
|
-
*/
|
|
175
|
-
createOrGetByTaskId(taskId) {
|
|
176
|
-
if (!this.taskIdToBus.has(taskId)) {
|
|
177
|
-
this.taskIdToBus.set(taskId, new DefaultExecutionEventBus());
|
|
178
|
-
}
|
|
179
|
-
return this.taskIdToBus.get(taskId);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Retrieves an existing ExecutionEventBus based on the taskId.
|
|
183
|
-
* @param taskId The ID of the task.
|
|
184
|
-
* @returns An instance of IExecutionEventBus or undefined if not found.
|
|
185
|
-
*/
|
|
186
|
-
getByTaskId(taskId) {
|
|
187
|
-
return this.taskIdToBus.get(taskId);
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Removes the event bus for a given taskId.
|
|
191
|
-
* This should be called when an execution flow is complete to free resources.
|
|
192
|
-
* @param taskId The ID of the task.
|
|
193
|
-
*/
|
|
194
|
-
cleanupByTaskId(taskId) {
|
|
195
|
-
const bus = this.taskIdToBus.get(taskId);
|
|
196
|
-
if (bus) {
|
|
197
|
-
bus.removeAllListeners();
|
|
198
|
-
}
|
|
199
|
-
this.taskIdToBus.delete(taskId);
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
// src/server/events/execution_event_queue.ts
|
|
204
|
-
var ExecutionEventQueue = class {
|
|
205
|
-
constructor(eventBus) {
|
|
206
|
-
this.eventQueue = [];
|
|
207
|
-
this.stopped = false;
|
|
208
|
-
this.handleEvent = (event) => {
|
|
209
|
-
if (this.stopped) return;
|
|
210
|
-
this.eventQueue.push(event);
|
|
211
|
-
if (this.resolvePromise) {
|
|
212
|
-
this.resolvePromise();
|
|
213
|
-
this.resolvePromise = void 0;
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
this.handleFinished = () => {
|
|
217
|
-
this.stop();
|
|
218
|
-
};
|
|
219
|
-
this.eventBus = eventBus;
|
|
220
|
-
this.eventBus.on("event", this.handleEvent);
|
|
221
|
-
this.eventBus.on("finished", this.handleFinished);
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Provides an async generator that yields events from the event bus.
|
|
225
|
-
* Stops when a Message event is received or a TaskStatusUpdateEvent with final=true is received.
|
|
226
|
-
*/
|
|
227
|
-
events() {
|
|
228
|
-
return __asyncGenerator(this, null, function* () {
|
|
229
|
-
while (!this.stopped || this.eventQueue.length > 0) {
|
|
230
|
-
if (this.eventQueue.length > 0) {
|
|
231
|
-
const event = this.eventQueue.shift();
|
|
232
|
-
yield event;
|
|
233
|
-
if (event.kind === "message" || event.kind === "status-update" && event.final) {
|
|
234
|
-
this.handleFinished();
|
|
235
|
-
break;
|
|
236
|
-
}
|
|
237
|
-
} else if (!this.stopped) {
|
|
238
|
-
yield new __await(new Promise((resolve) => {
|
|
239
|
-
this.resolvePromise = resolve;
|
|
240
|
-
}));
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Stops the event queue from processing further events.
|
|
247
|
-
*/
|
|
248
|
-
stop() {
|
|
249
|
-
this.stopped = true;
|
|
250
|
-
if (this.resolvePromise) {
|
|
251
|
-
this.resolvePromise();
|
|
252
|
-
this.resolvePromise = void 0;
|
|
253
|
-
}
|
|
254
|
-
this.eventBus.off("event", this.handleEvent);
|
|
255
|
-
this.eventBus.off("finished", this.handleFinished);
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
// src/server/utils.ts
|
|
260
|
-
function getCurrentTimestamp() {
|
|
261
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
262
|
-
}
|
|
263
|
-
function isObject(value) {
|
|
264
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
265
|
-
}
|
|
266
|
-
function isTaskStatusUpdate(update) {
|
|
267
|
-
return isObject(update) && "state" in update && !("parts" in update);
|
|
268
|
-
}
|
|
269
|
-
function isArtifactUpdate(update) {
|
|
270
|
-
return isObject(update) && "parts" in update;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// src/server/request_handler/default_request_handler.ts
|
|
274
|
-
var import_uuid = require("uuid");
|
|
275
|
-
|
|
276
|
-
// src/server/error.ts
|
|
277
|
-
var A2AError = class _A2AError extends Error {
|
|
278
|
-
// Optional task ID context
|
|
279
|
-
constructor(code, message, data, taskId) {
|
|
280
|
-
super(message);
|
|
281
|
-
this.name = "A2AError";
|
|
282
|
-
this.code = code;
|
|
283
|
-
this.data = data;
|
|
284
|
-
this.taskId = taskId;
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Formats the error into a standard JSON-RPC error object structure.
|
|
288
|
-
*/
|
|
289
|
-
toJSONRPCError() {
|
|
290
|
-
const errorObject = {
|
|
291
|
-
code: this.code,
|
|
292
|
-
message: this.message
|
|
293
|
-
};
|
|
294
|
-
if (this.data !== void 0) {
|
|
295
|
-
errorObject.data = this.data;
|
|
296
|
-
}
|
|
297
|
-
return errorObject;
|
|
298
|
-
}
|
|
299
|
-
// Static factory methods for common errors
|
|
300
|
-
static parseError(message, data) {
|
|
301
|
-
return new _A2AError(-32700, message, data);
|
|
302
|
-
}
|
|
303
|
-
static invalidRequest(message, data) {
|
|
304
|
-
return new _A2AError(-32600, message, data);
|
|
305
|
-
}
|
|
306
|
-
static methodNotFound(method) {
|
|
307
|
-
return new _A2AError(
|
|
308
|
-
-32601,
|
|
309
|
-
`Method not found: ${method}`
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
static invalidParams(message, data) {
|
|
313
|
-
return new _A2AError(-32602, message, data);
|
|
314
|
-
}
|
|
315
|
-
static internalError(message, data) {
|
|
316
|
-
return new _A2AError(-32603, message, data);
|
|
317
|
-
}
|
|
318
|
-
static taskNotFound(taskId) {
|
|
319
|
-
return new _A2AError(
|
|
320
|
-
-32001,
|
|
321
|
-
`Task not found: ${taskId}`,
|
|
322
|
-
void 0,
|
|
323
|
-
taskId
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
static taskNotCancelable(taskId) {
|
|
327
|
-
return new _A2AError(
|
|
328
|
-
-32002,
|
|
329
|
-
`Task not cancelable: ${taskId}`,
|
|
330
|
-
void 0,
|
|
331
|
-
taskId
|
|
332
|
-
);
|
|
333
|
-
}
|
|
334
|
-
static pushNotificationNotSupported() {
|
|
335
|
-
return new _A2AError(
|
|
336
|
-
-32003,
|
|
337
|
-
"Push Notification is not supported"
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
static unsupportedOperation(operation) {
|
|
341
|
-
return new _A2AError(
|
|
342
|
-
-32004,
|
|
343
|
-
`Unsupported operation: ${operation}`
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
static authenticatedExtendedCardNotConfigured() {
|
|
347
|
-
return new _A2AError(
|
|
348
|
-
-32007,
|
|
349
|
-
`Extended card not configured.`
|
|
350
|
-
);
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
// src/server/result_manager.ts
|
|
355
|
-
var ResultManager = class {
|
|
356
|
-
// Stores the message if it's the final result
|
|
357
|
-
constructor(taskStore) {
|
|
358
|
-
this.taskStore = taskStore;
|
|
359
|
-
}
|
|
360
|
-
setContext(latestUserMessage) {
|
|
361
|
-
this.latestUserMessage = latestUserMessage;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Processes an agent execution event and updates the task store.
|
|
365
|
-
* @param event The agent execution event.
|
|
366
|
-
*/
|
|
367
|
-
processEvent(event) {
|
|
368
|
-
return __async(this, null, function* () {
|
|
369
|
-
var _a, _b, _c;
|
|
370
|
-
if (event.kind === "message") {
|
|
371
|
-
this.finalMessageResult = event;
|
|
372
|
-
} else if (event.kind === "task") {
|
|
373
|
-
const taskEvent = event;
|
|
374
|
-
this.currentTask = __spreadValues({}, taskEvent);
|
|
375
|
-
if (this.latestUserMessage) {
|
|
376
|
-
if (!((_a = this.currentTask.history) == null ? void 0 : _a.find((msg) => msg.messageId === this.latestUserMessage.messageId))) {
|
|
377
|
-
this.currentTask.history = [this.latestUserMessage, ...this.currentTask.history || []];
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
yield this.saveCurrentTask();
|
|
381
|
-
} else if (event.kind === "status-update") {
|
|
382
|
-
const updateEvent = event;
|
|
383
|
-
if (this.currentTask && this.currentTask.id === updateEvent.taskId) {
|
|
384
|
-
this.currentTask.status = updateEvent.status;
|
|
385
|
-
if (updateEvent.status.message) {
|
|
386
|
-
if (!((_b = this.currentTask.history) == null ? void 0 : _b.find((msg) => msg.messageId === updateEvent.status.message.messageId))) {
|
|
387
|
-
this.currentTask.history = [...this.currentTask.history || [], updateEvent.status.message];
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
yield this.saveCurrentTask();
|
|
391
|
-
} else if (!this.currentTask && updateEvent.taskId) {
|
|
392
|
-
const loaded = yield this.taskStore.load(updateEvent.taskId);
|
|
393
|
-
if (loaded) {
|
|
394
|
-
this.currentTask = loaded;
|
|
395
|
-
this.currentTask.status = updateEvent.status;
|
|
396
|
-
if (updateEvent.status.message) {
|
|
397
|
-
if (!((_c = this.currentTask.history) == null ? void 0 : _c.find((msg) => msg.messageId === updateEvent.status.message.messageId))) {
|
|
398
|
-
this.currentTask.history = [...this.currentTask.history || [], updateEvent.status.message];
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
yield this.saveCurrentTask();
|
|
402
|
-
} else {
|
|
403
|
-
console.warn(`ResultManager: Received status update for unknown task ${updateEvent.taskId}`);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
} else if (event.kind === "artifact-update") {
|
|
407
|
-
const artifactEvent = event;
|
|
408
|
-
if (this.currentTask && this.currentTask.id === artifactEvent.taskId) {
|
|
409
|
-
if (!this.currentTask.artifacts) {
|
|
410
|
-
this.currentTask.artifacts = [];
|
|
411
|
-
}
|
|
412
|
-
const existingArtifactIndex = this.currentTask.artifacts.findIndex(
|
|
413
|
-
(art) => art.artifactId === artifactEvent.artifact.artifactId
|
|
414
|
-
);
|
|
415
|
-
if (existingArtifactIndex !== -1) {
|
|
416
|
-
if (artifactEvent.append) {
|
|
417
|
-
const existingArtifact = this.currentTask.artifacts[existingArtifactIndex];
|
|
418
|
-
existingArtifact.parts.push(...artifactEvent.artifact.parts);
|
|
419
|
-
if (artifactEvent.artifact.description) existingArtifact.description = artifactEvent.artifact.description;
|
|
420
|
-
if (artifactEvent.artifact.name) existingArtifact.name = artifactEvent.artifact.name;
|
|
421
|
-
if (artifactEvent.artifact.metadata) existingArtifact.metadata = __spreadValues(__spreadValues({}, existingArtifact.metadata), artifactEvent.artifact.metadata);
|
|
422
|
-
} else {
|
|
423
|
-
this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
|
|
424
|
-
}
|
|
425
|
-
} else {
|
|
426
|
-
this.currentTask.artifacts.push(artifactEvent.artifact);
|
|
427
|
-
}
|
|
428
|
-
yield this.saveCurrentTask();
|
|
429
|
-
} else if (!this.currentTask && artifactEvent.taskId) {
|
|
430
|
-
const loaded = yield this.taskStore.load(artifactEvent.taskId);
|
|
431
|
-
if (loaded) {
|
|
432
|
-
this.currentTask = loaded;
|
|
433
|
-
if (!this.currentTask.artifacts) this.currentTask.artifacts = [];
|
|
434
|
-
const existingArtifactIndex = this.currentTask.artifacts.findIndex(
|
|
435
|
-
(art) => art.artifactId === artifactEvent.artifact.artifactId
|
|
436
|
-
);
|
|
437
|
-
if (existingArtifactIndex !== -1) {
|
|
438
|
-
if (artifactEvent.append) {
|
|
439
|
-
this.currentTask.artifacts[existingArtifactIndex].parts.push(...artifactEvent.artifact.parts);
|
|
440
|
-
} else {
|
|
441
|
-
this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
|
|
442
|
-
}
|
|
443
|
-
} else {
|
|
444
|
-
this.currentTask.artifacts.push(artifactEvent.artifact);
|
|
445
|
-
}
|
|
446
|
-
yield this.saveCurrentTask();
|
|
447
|
-
} else {
|
|
448
|
-
console.warn(`ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
saveCurrentTask() {
|
|
455
|
-
return __async(this, null, function* () {
|
|
456
|
-
if (this.currentTask) {
|
|
457
|
-
yield this.taskStore.save(this.currentTask);
|
|
458
|
-
}
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
* Gets the final result, which could be a Message or a Task.
|
|
463
|
-
* This should be called after the event stream has been fully processed.
|
|
464
|
-
* @returns The final Message or the current Task.
|
|
465
|
-
*/
|
|
466
|
-
getFinalResult() {
|
|
467
|
-
if (this.finalMessageResult) {
|
|
468
|
-
return this.finalMessageResult;
|
|
469
|
-
}
|
|
470
|
-
return this.currentTask;
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* Gets the task currently being managed by this ResultManager instance.
|
|
474
|
-
* This task could be one that was started with or one created during agent execution.
|
|
475
|
-
* @returns The current Task or undefined if no task is active.
|
|
476
|
-
*/
|
|
477
|
-
getCurrentTask() {
|
|
478
|
-
return this.currentTask;
|
|
479
|
-
}
|
|
480
|
-
};
|
|
481
|
-
|
|
482
|
-
// src/server/request_handler/default_request_handler.ts
|
|
483
|
-
var terminalStates = ["completed", "failed", "canceled", "rejected"];
|
|
484
|
-
var DefaultRequestHandler = class {
|
|
485
|
-
constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), extendedAgentCard) {
|
|
486
|
-
// Store for push notification configurations (could be part of TaskStore or separate)
|
|
487
|
-
this.pushNotificationConfigs = /* @__PURE__ */ new Map();
|
|
488
|
-
this.agentCard = agentCard;
|
|
489
|
-
this.taskStore = taskStore;
|
|
490
|
-
this.agentExecutor = agentExecutor;
|
|
491
|
-
this.eventBusManager = eventBusManager;
|
|
492
|
-
this.extendedAgentCard = extendedAgentCard;
|
|
493
|
-
}
|
|
494
|
-
getAgentCard() {
|
|
495
|
-
return __async(this, null, function* () {
|
|
496
|
-
return this.agentCard;
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
getAuthenticatedExtendedAgentCard() {
|
|
500
|
-
return __async(this, null, function* () {
|
|
501
|
-
if (!this.extendedAgentCard) {
|
|
502
|
-
throw A2AError.authenticatedExtendedCardNotConfigured();
|
|
503
|
-
}
|
|
504
|
-
return this.extendedAgentCard;
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
_createRequestContext(incomingMessage, taskId, isStream) {
|
|
508
|
-
return __async(this, null, function* () {
|
|
509
|
-
let task;
|
|
510
|
-
let referenceTasks;
|
|
511
|
-
if (incomingMessage.taskId) {
|
|
512
|
-
task = yield this.taskStore.load(incomingMessage.taskId);
|
|
513
|
-
if (!task) {
|
|
514
|
-
throw A2AError.taskNotFound(incomingMessage.taskId);
|
|
515
|
-
}
|
|
516
|
-
if (terminalStates.includes(task.status.state)) {
|
|
517
|
-
throw A2AError.invalidRequest(`Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
if (incomingMessage.referenceTaskIds && incomingMessage.referenceTaskIds.length > 0) {
|
|
521
|
-
referenceTasks = [];
|
|
522
|
-
for (const refId of incomingMessage.referenceTaskIds) {
|
|
523
|
-
const refTask = yield this.taskStore.load(refId);
|
|
524
|
-
if (refTask) {
|
|
525
|
-
referenceTasks.push(refTask);
|
|
526
|
-
} else {
|
|
527
|
-
console.warn(`Reference task ${refId} not found.`);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
const contextId = incomingMessage.contextId || (task == null ? void 0 : task.contextId) || (0, import_uuid.v4)();
|
|
532
|
-
const messageForContext = __spreadProps(__spreadValues({}, incomingMessage), {
|
|
533
|
-
contextId
|
|
534
|
-
});
|
|
535
|
-
return new RequestContext(
|
|
536
|
-
messageForContext,
|
|
537
|
-
taskId,
|
|
538
|
-
contextId,
|
|
539
|
-
task,
|
|
540
|
-
referenceTasks
|
|
541
|
-
);
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
_processEvents(taskId, resultManager, eventQueue, options) {
|
|
545
|
-
return __async(this, null, function* () {
|
|
546
|
-
let firstResultSent = false;
|
|
547
|
-
try {
|
|
548
|
-
try {
|
|
549
|
-
for (var iter = __forAwait(eventQueue.events()), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
|
|
550
|
-
const event = temp.value;
|
|
551
|
-
yield resultManager.processEvent(event);
|
|
552
|
-
if ((options == null ? void 0 : options.firstResultResolver) && !firstResultSent) {
|
|
553
|
-
if (event.kind === "message" || event.kind === "task") {
|
|
554
|
-
options.firstResultResolver(event);
|
|
555
|
-
firstResultSent = true;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
} catch (temp) {
|
|
560
|
-
error = [temp];
|
|
561
|
-
} finally {
|
|
562
|
-
try {
|
|
563
|
-
more && (temp = iter.return) && (yield temp.call(iter));
|
|
564
|
-
} finally {
|
|
565
|
-
if (error)
|
|
566
|
-
throw error[0];
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
if ((options == null ? void 0 : options.firstResultRejector) && !firstResultSent) {
|
|
570
|
-
options.firstResultRejector(A2AError.internalError("Execution finished before a message or task was produced."));
|
|
571
|
-
}
|
|
572
|
-
} catch (error2) {
|
|
573
|
-
console.error(`Event processing loop failed for task ${taskId}:`, error2);
|
|
574
|
-
if ((options == null ? void 0 : options.firstResultRejector) && !firstResultSent) {
|
|
575
|
-
options.firstResultRejector(error2);
|
|
576
|
-
}
|
|
577
|
-
throw error2;
|
|
578
|
-
} finally {
|
|
579
|
-
this.eventBusManager.cleanupByTaskId(taskId);
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
sendMessage(params) {
|
|
584
|
-
return __async(this, null, function* () {
|
|
585
|
-
var _a;
|
|
586
|
-
const incomingMessage = params.message;
|
|
587
|
-
if (!incomingMessage.messageId) {
|
|
588
|
-
throw A2AError.invalidParams("message.messageId is required.");
|
|
589
|
-
}
|
|
590
|
-
const isBlocking = ((_a = params.configuration) == null ? void 0 : _a.blocking) !== false;
|
|
591
|
-
const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
|
|
592
|
-
const resultManager = new ResultManager(this.taskStore);
|
|
593
|
-
resultManager.setContext(incomingMessage);
|
|
594
|
-
const requestContext = yield this._createRequestContext(incomingMessage, taskId, false);
|
|
595
|
-
const finalMessageForAgent = requestContext.userMessage;
|
|
596
|
-
const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
|
|
597
|
-
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
598
|
-
this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
|
|
599
|
-
var _a2, _b, _c, _d, _e;
|
|
600
|
-
console.error(`Agent execution failed for message ${finalMessageForAgent.messageId}:`, err);
|
|
601
|
-
const errorTask = {
|
|
602
|
-
id: ((_a2 = requestContext.task) == null ? void 0 : _a2.id) || (0, import_uuid.v4)(),
|
|
603
|
-
// Use existing task ID or generate new
|
|
604
|
-
contextId: finalMessageForAgent.contextId,
|
|
605
|
-
status: {
|
|
606
|
-
state: "failed",
|
|
607
|
-
message: {
|
|
608
|
-
kind: "message",
|
|
609
|
-
role: "agent",
|
|
610
|
-
messageId: (0, import_uuid.v4)(),
|
|
611
|
-
parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
|
|
612
|
-
taskId: (_b = requestContext.task) == null ? void 0 : _b.id,
|
|
613
|
-
contextId: finalMessageForAgent.contextId
|
|
614
|
-
},
|
|
615
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
616
|
-
},
|
|
617
|
-
history: ((_c = requestContext.task) == null ? void 0 : _c.history) ? [...requestContext.task.history] : [],
|
|
618
|
-
kind: "task"
|
|
619
|
-
};
|
|
620
|
-
if (finalMessageForAgent) {
|
|
621
|
-
if (!((_d = errorTask.history) == null ? void 0 : _d.find((m) => m.messageId === finalMessageForAgent.messageId))) {
|
|
622
|
-
(_e = errorTask.history) == null ? void 0 : _e.push(finalMessageForAgent);
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
eventBus.publish(errorTask);
|
|
626
|
-
eventBus.publish({
|
|
627
|
-
// And publish a final status update
|
|
628
|
-
kind: "status-update",
|
|
629
|
-
taskId: errorTask.id,
|
|
630
|
-
contextId: errorTask.contextId,
|
|
631
|
-
status: errorTask.status,
|
|
632
|
-
final: true
|
|
633
|
-
});
|
|
634
|
-
eventBus.finished();
|
|
635
|
-
});
|
|
636
|
-
if (isBlocking) {
|
|
637
|
-
yield this._processEvents(taskId, resultManager, eventQueue);
|
|
638
|
-
const finalResult = resultManager.getFinalResult();
|
|
639
|
-
if (!finalResult) {
|
|
640
|
-
throw A2AError.internalError("Agent execution finished without a result, and no task context found.");
|
|
641
|
-
}
|
|
642
|
-
return finalResult;
|
|
643
|
-
} else {
|
|
644
|
-
return new Promise((resolve, reject) => {
|
|
645
|
-
this._processEvents(taskId, resultManager, eventQueue, {
|
|
646
|
-
firstResultResolver: resolve,
|
|
647
|
-
firstResultRejector: reject
|
|
648
|
-
});
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
sendMessageStream(params) {
|
|
654
|
-
return __asyncGenerator(this, null, function* () {
|
|
655
|
-
const incomingMessage = params.message;
|
|
656
|
-
if (!incomingMessage.messageId) {
|
|
657
|
-
throw A2AError.invalidParams("message.messageId is required for streaming.");
|
|
658
|
-
}
|
|
659
|
-
const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
|
|
660
|
-
const resultManager = new ResultManager(this.taskStore);
|
|
661
|
-
resultManager.setContext(incomingMessage);
|
|
662
|
-
const requestContext = yield new __await(this._createRequestContext(incomingMessage, taskId, true));
|
|
663
|
-
const finalMessageForAgent = requestContext.userMessage;
|
|
664
|
-
const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
|
|
665
|
-
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
666
|
-
this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
|
|
667
|
-
var _a, _b;
|
|
668
|
-
console.error(`Agent execution failed for stream message ${finalMessageForAgent.messageId}:`, err);
|
|
669
|
-
const errorTaskStatus = {
|
|
670
|
-
kind: "status-update",
|
|
671
|
-
taskId: ((_a = requestContext.task) == null ? void 0 : _a.id) || (0, import_uuid.v4)(),
|
|
672
|
-
// Use existing or a placeholder
|
|
673
|
-
contextId: finalMessageForAgent.contextId,
|
|
674
|
-
status: {
|
|
675
|
-
state: "failed",
|
|
676
|
-
message: {
|
|
677
|
-
kind: "message",
|
|
678
|
-
role: "agent",
|
|
679
|
-
messageId: (0, import_uuid.v4)(),
|
|
680
|
-
parts: [{ kind: "text", text: `Agent execution error: ${err.message}` }],
|
|
681
|
-
taskId: (_b = requestContext.task) == null ? void 0 : _b.id,
|
|
682
|
-
contextId: finalMessageForAgent.contextId
|
|
683
|
-
},
|
|
684
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
685
|
-
},
|
|
686
|
-
final: true
|
|
687
|
-
// This will terminate the stream for the client
|
|
688
|
-
};
|
|
689
|
-
eventBus.publish(errorTaskStatus);
|
|
690
|
-
});
|
|
691
|
-
try {
|
|
692
|
-
try {
|
|
693
|
-
for (var iter = __forAwait(eventQueue.events()), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
694
|
-
const event = temp.value;
|
|
695
|
-
yield new __await(resultManager.processEvent(event));
|
|
696
|
-
yield event;
|
|
697
|
-
}
|
|
698
|
-
} catch (temp) {
|
|
699
|
-
error = [temp];
|
|
700
|
-
} finally {
|
|
701
|
-
try {
|
|
702
|
-
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
703
|
-
} finally {
|
|
704
|
-
if (error)
|
|
705
|
-
throw error[0];
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
} finally {
|
|
709
|
-
this.eventBusManager.cleanupByTaskId(taskId);
|
|
710
|
-
}
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
getTask(params) {
|
|
714
|
-
return __async(this, null, function* () {
|
|
715
|
-
const task = yield this.taskStore.load(params.id);
|
|
716
|
-
if (!task) {
|
|
717
|
-
throw A2AError.taskNotFound(params.id);
|
|
718
|
-
}
|
|
719
|
-
if (params.historyLength !== void 0 && params.historyLength >= 0) {
|
|
720
|
-
if (task.history) {
|
|
721
|
-
task.history = task.history.slice(-params.historyLength);
|
|
722
|
-
}
|
|
723
|
-
} else {
|
|
724
|
-
task.history = [];
|
|
725
|
-
}
|
|
726
|
-
return task;
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
|
-
cancelTask(params) {
|
|
730
|
-
return __async(this, null, function* () {
|
|
731
|
-
const task = yield this.taskStore.load(params.id);
|
|
732
|
-
if (!task) {
|
|
733
|
-
throw A2AError.taskNotFound(params.id);
|
|
734
|
-
}
|
|
735
|
-
const nonCancelableStates = ["completed", "failed", "canceled", "rejected"];
|
|
736
|
-
if (nonCancelableStates.includes(task.status.state)) {
|
|
737
|
-
throw A2AError.taskNotCancelable(params.id);
|
|
738
|
-
}
|
|
739
|
-
const eventBus = this.eventBusManager.getByTaskId(params.id);
|
|
740
|
-
if (eventBus) {
|
|
741
|
-
yield this.agentExecutor.cancelTask(params.id, eventBus);
|
|
742
|
-
} else {
|
|
743
|
-
task.status = {
|
|
744
|
-
state: "canceled",
|
|
745
|
-
message: {
|
|
746
|
-
// Optional: Add a system message indicating cancellation
|
|
747
|
-
kind: "message",
|
|
748
|
-
role: "agent",
|
|
749
|
-
messageId: (0, import_uuid.v4)(),
|
|
750
|
-
parts: [{ kind: "text", text: "Task cancellation requested by user." }],
|
|
751
|
-
taskId: task.id,
|
|
752
|
-
contextId: task.contextId
|
|
753
|
-
},
|
|
754
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
755
|
-
};
|
|
756
|
-
task.history = [...task.history || [], task.status.message];
|
|
757
|
-
yield this.taskStore.save(task);
|
|
758
|
-
}
|
|
759
|
-
const latestTask = yield this.taskStore.load(params.id);
|
|
760
|
-
return latestTask;
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
setTaskPushNotificationConfig(params) {
|
|
764
|
-
return __async(this, null, function* () {
|
|
765
|
-
if (!this.agentCard.capabilities.pushNotifications) {
|
|
766
|
-
throw A2AError.pushNotificationNotSupported();
|
|
767
|
-
}
|
|
768
|
-
const task = yield this.taskStore.load(params.taskId);
|
|
769
|
-
if (!task) {
|
|
770
|
-
throw A2AError.taskNotFound(params.taskId);
|
|
771
|
-
}
|
|
772
|
-
const { taskId, pushNotificationConfig } = params;
|
|
773
|
-
if (!pushNotificationConfig.id) {
|
|
774
|
-
pushNotificationConfig.id = taskId;
|
|
775
|
-
}
|
|
776
|
-
const configs = this.pushNotificationConfigs.get(taskId) || [];
|
|
777
|
-
const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfig.id);
|
|
778
|
-
updatedConfigs.push(pushNotificationConfig);
|
|
779
|
-
this.pushNotificationConfigs.set(taskId, updatedConfigs);
|
|
780
|
-
return params;
|
|
781
|
-
});
|
|
782
|
-
}
|
|
783
|
-
getTaskPushNotificationConfig(params) {
|
|
784
|
-
return __async(this, null, function* () {
|
|
785
|
-
if (!this.agentCard.capabilities.pushNotifications) {
|
|
786
|
-
throw A2AError.pushNotificationNotSupported();
|
|
787
|
-
}
|
|
788
|
-
const task = yield this.taskStore.load(params.id);
|
|
789
|
-
if (!task) {
|
|
790
|
-
throw A2AError.taskNotFound(params.id);
|
|
791
|
-
}
|
|
792
|
-
const configs = this.pushNotificationConfigs.get(params.id) || [];
|
|
793
|
-
if (configs.length === 0) {
|
|
794
|
-
throw A2AError.internalError(`Push notification config not found for task ${params.id}.`);
|
|
795
|
-
}
|
|
796
|
-
let configId;
|
|
797
|
-
if ("pushNotificationConfigId" in params && params.pushNotificationConfigId) {
|
|
798
|
-
configId = params.pushNotificationConfigId;
|
|
799
|
-
} else {
|
|
800
|
-
configId = params.id;
|
|
801
|
-
}
|
|
802
|
-
const config = configs.find((c) => c.id === configId);
|
|
803
|
-
if (!config) {
|
|
804
|
-
throw A2AError.internalError(`Push notification config with id '${configId}' not found for task ${params.id}.`);
|
|
805
|
-
}
|
|
806
|
-
return { taskId: params.id, pushNotificationConfig: config };
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
listTaskPushNotificationConfigs(params) {
|
|
810
|
-
return __async(this, null, function* () {
|
|
811
|
-
if (!this.agentCard.capabilities.pushNotifications) {
|
|
812
|
-
throw A2AError.pushNotificationNotSupported();
|
|
813
|
-
}
|
|
814
|
-
const task = yield this.taskStore.load(params.id);
|
|
815
|
-
if (!task) {
|
|
816
|
-
throw A2AError.taskNotFound(params.id);
|
|
817
|
-
}
|
|
818
|
-
const configs = this.pushNotificationConfigs.get(params.id) || [];
|
|
819
|
-
return configs.map((config) => ({
|
|
820
|
-
taskId: params.id,
|
|
821
|
-
pushNotificationConfig: config
|
|
822
|
-
}));
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
deleteTaskPushNotificationConfig(params) {
|
|
826
|
-
return __async(this, null, function* () {
|
|
827
|
-
if (!this.agentCard.capabilities.pushNotifications) {
|
|
828
|
-
throw A2AError.pushNotificationNotSupported();
|
|
829
|
-
}
|
|
830
|
-
const task = yield this.taskStore.load(params.id);
|
|
831
|
-
if (!task) {
|
|
832
|
-
throw A2AError.taskNotFound(params.id);
|
|
833
|
-
}
|
|
834
|
-
const { id: taskId, pushNotificationConfigId } = params;
|
|
835
|
-
const configs = this.pushNotificationConfigs.get(taskId);
|
|
836
|
-
if (!configs) {
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfigId);
|
|
840
|
-
if (updatedConfigs.length === 0) {
|
|
841
|
-
this.pushNotificationConfigs.delete(taskId);
|
|
842
|
-
} else if (updatedConfigs.length < configs.length) {
|
|
843
|
-
this.pushNotificationConfigs.set(taskId, updatedConfigs);
|
|
844
|
-
}
|
|
845
|
-
});
|
|
846
|
-
}
|
|
847
|
-
resubscribe(params) {
|
|
848
|
-
return __asyncGenerator(this, null, function* () {
|
|
849
|
-
if (!this.agentCard.capabilities.streaming) {
|
|
850
|
-
throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
|
|
851
|
-
}
|
|
852
|
-
const task = yield new __await(this.taskStore.load(params.id));
|
|
853
|
-
if (!task) {
|
|
854
|
-
throw A2AError.taskNotFound(params.id);
|
|
855
|
-
}
|
|
856
|
-
yield task;
|
|
857
|
-
const finalStates = ["completed", "failed", "canceled", "rejected"];
|
|
858
|
-
if (finalStates.includes(task.status.state)) {
|
|
859
|
-
return;
|
|
860
|
-
}
|
|
861
|
-
const eventBus = this.eventBusManager.getByTaskId(params.id);
|
|
862
|
-
if (!eventBus) {
|
|
863
|
-
console.warn(`Resubscribe: No active event bus for task ${params.id}.`);
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
867
|
-
try {
|
|
868
|
-
try {
|
|
869
|
-
for (var iter = __forAwait(eventQueue.events()), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
870
|
-
const event = temp.value;
|
|
871
|
-
if (event.kind === "status-update" && event.taskId === params.id) {
|
|
872
|
-
yield event;
|
|
873
|
-
} else if (event.kind === "artifact-update" && event.taskId === params.id) {
|
|
874
|
-
yield event;
|
|
875
|
-
} else if (event.kind === "task" && event.id === params.id) {
|
|
876
|
-
yield event;
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
} catch (temp) {
|
|
880
|
-
error = [temp];
|
|
881
|
-
} finally {
|
|
882
|
-
try {
|
|
883
|
-
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
884
|
-
} finally {
|
|
885
|
-
if (error)
|
|
886
|
-
throw error[0];
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
} finally {
|
|
890
|
-
eventQueue.stop();
|
|
891
|
-
}
|
|
892
|
-
});
|
|
893
|
-
}
|
|
894
|
-
};
|
|
895
|
-
|
|
896
|
-
// src/server/store.ts
|
|
897
|
-
var InMemoryTaskStore = class {
|
|
898
|
-
constructor() {
|
|
899
|
-
this.store = /* @__PURE__ */ new Map();
|
|
900
|
-
}
|
|
901
|
-
load(taskId) {
|
|
902
|
-
return __async(this, null, function* () {
|
|
903
|
-
const entry = this.store.get(taskId);
|
|
904
|
-
return entry ? __spreadValues({}, entry) : void 0;
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
save(task) {
|
|
908
|
-
return __async(this, null, function* () {
|
|
909
|
-
this.store.set(task.id, __spreadValues({}, task));
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
};
|
|
913
|
-
|
|
914
|
-
// src/server/transports/jsonrpc_transport_handler.ts
|
|
915
|
-
var JsonRpcTransportHandler = class {
|
|
916
|
-
constructor(requestHandler) {
|
|
917
|
-
this.requestHandler = requestHandler;
|
|
918
|
-
}
|
|
919
|
-
/**
|
|
920
|
-
* Handles an incoming JSON-RPC request.
|
|
921
|
-
* For streaming methods, it returns an AsyncGenerator of JSONRPCResult.
|
|
922
|
-
* For non-streaming methods, it returns a Promise of a single JSONRPCMessage (Result or ErrorResponse).
|
|
923
|
-
*/
|
|
924
|
-
handle(requestBody) {
|
|
925
|
-
return __async(this, null, function* () {
|
|
926
|
-
let rpcRequest;
|
|
927
|
-
try {
|
|
928
|
-
if (typeof requestBody === "string") {
|
|
929
|
-
rpcRequest = JSON.parse(requestBody);
|
|
930
|
-
} else if (typeof requestBody === "object" && requestBody !== null) {
|
|
931
|
-
rpcRequest = requestBody;
|
|
932
|
-
} else {
|
|
933
|
-
throw A2AError.parseError("Invalid request body type.");
|
|
934
|
-
}
|
|
935
|
-
if (rpcRequest.jsonrpc !== "2.0" || !rpcRequest.method || typeof rpcRequest.method !== "string") {
|
|
936
|
-
throw A2AError.invalidRequest(
|
|
937
|
-
"Invalid JSON-RPC request structure."
|
|
938
|
-
);
|
|
939
|
-
}
|
|
940
|
-
} catch (error) {
|
|
941
|
-
const a2aError = error instanceof A2AError ? error : A2AError.parseError(error.message || "Failed to parse JSON request.");
|
|
942
|
-
return {
|
|
943
|
-
jsonrpc: "2.0",
|
|
944
|
-
id: typeof (rpcRequest == null ? void 0 : rpcRequest.id) !== "undefined" ? rpcRequest.id : null,
|
|
945
|
-
error: a2aError.toJSONRPCError()
|
|
946
|
-
};
|
|
947
|
-
}
|
|
948
|
-
const { method, id: requestId = null } = rpcRequest;
|
|
949
|
-
try {
|
|
950
|
-
if (method === "agent/getAuthenticatedExtendedCard") {
|
|
951
|
-
const result = yield this.requestHandler.getAuthenticatedExtendedAgentCard();
|
|
952
|
-
return {
|
|
953
|
-
jsonrpc: "2.0",
|
|
954
|
-
id: requestId,
|
|
955
|
-
result
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
if (!rpcRequest.params) {
|
|
959
|
-
throw A2AError.invalidParams(`'params' is required for '${method}'`);
|
|
960
|
-
}
|
|
961
|
-
if (method === "message/stream" || method === "tasks/resubscribe") {
|
|
962
|
-
const params = rpcRequest.params;
|
|
963
|
-
const agentCard = yield this.requestHandler.getAgentCard();
|
|
964
|
-
if (!agentCard.capabilities.streaming) {
|
|
965
|
-
throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
|
|
966
|
-
}
|
|
967
|
-
const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params) : this.requestHandler.resubscribe(params);
|
|
968
|
-
return function jsonRpcEventStream() {
|
|
969
|
-
return __asyncGenerator(this, null, function* () {
|
|
970
|
-
try {
|
|
971
|
-
try {
|
|
972
|
-
for (var iter = __forAwait(agentEventStream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
973
|
-
const event = temp.value;
|
|
974
|
-
yield {
|
|
975
|
-
jsonrpc: "2.0",
|
|
976
|
-
id: requestId,
|
|
977
|
-
// Use the original request ID for all streamed responses
|
|
978
|
-
result: event
|
|
979
|
-
};
|
|
980
|
-
}
|
|
981
|
-
} catch (temp) {
|
|
982
|
-
error = [temp];
|
|
983
|
-
} finally {
|
|
984
|
-
try {
|
|
985
|
-
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
986
|
-
} finally {
|
|
987
|
-
if (error)
|
|
988
|
-
throw error[0];
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
} catch (streamError) {
|
|
992
|
-
console.error(`Error in agent event stream for ${method} (request ${requestId}):`, streamError);
|
|
993
|
-
throw streamError;
|
|
994
|
-
}
|
|
995
|
-
});
|
|
996
|
-
}();
|
|
997
|
-
} else {
|
|
998
|
-
let result;
|
|
999
|
-
switch (method) {
|
|
1000
|
-
case "message/send":
|
|
1001
|
-
result = yield this.requestHandler.sendMessage(rpcRequest.params);
|
|
1002
|
-
break;
|
|
1003
|
-
case "tasks/get":
|
|
1004
|
-
result = yield this.requestHandler.getTask(rpcRequest.params);
|
|
1005
|
-
break;
|
|
1006
|
-
case "tasks/cancel":
|
|
1007
|
-
result = yield this.requestHandler.cancelTask(rpcRequest.params);
|
|
1008
|
-
break;
|
|
1009
|
-
case "tasks/pushNotificationConfig/set":
|
|
1010
|
-
result = yield this.requestHandler.setTaskPushNotificationConfig(
|
|
1011
|
-
rpcRequest.params
|
|
1012
|
-
);
|
|
1013
|
-
break;
|
|
1014
|
-
case "tasks/pushNotificationConfig/get":
|
|
1015
|
-
result = yield this.requestHandler.getTaskPushNotificationConfig(
|
|
1016
|
-
rpcRequest.params
|
|
1017
|
-
);
|
|
1018
|
-
break;
|
|
1019
|
-
case "tasks/pushNotificationConfig/delete":
|
|
1020
|
-
yield this.requestHandler.deleteTaskPushNotificationConfig(
|
|
1021
|
-
rpcRequest.params
|
|
1022
|
-
);
|
|
1023
|
-
result = null;
|
|
1024
|
-
break;
|
|
1025
|
-
case "tasks/pushNotificationConfig/list":
|
|
1026
|
-
result = yield this.requestHandler.listTaskPushNotificationConfigs(
|
|
1027
|
-
rpcRequest.params
|
|
1028
|
-
);
|
|
1029
|
-
break;
|
|
1030
|
-
default:
|
|
1031
|
-
throw A2AError.methodNotFound(method);
|
|
1032
|
-
}
|
|
1033
|
-
return {
|
|
1034
|
-
jsonrpc: "2.0",
|
|
1035
|
-
id: requestId,
|
|
1036
|
-
result
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
} catch (error) {
|
|
1040
|
-
const a2aError = error instanceof A2AError ? error : A2AError.internalError(error.message || "An unexpected error occurred.");
|
|
1041
|
-
return {
|
|
1042
|
-
jsonrpc: "2.0",
|
|
1043
|
-
id: requestId,
|
|
1044
|
-
error: a2aError.toJSONRPCError()
|
|
1045
|
-
};
|
|
1046
|
-
}
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
};
|
|
1050
|
-
|
|
1051
|
-
// src/client/client.ts
|
|
1052
|
-
var A2AClient = class _A2AClient {
|
|
32
|
+
// src/extensions.ts
|
|
33
|
+
var Extensions = {
|
|
1053
34
|
/**
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
1056
|
-
* @param options Optional. The options for the A2AClient including the fetch/auth implementation.
|
|
35
|
+
* Creates new {@link Extensions} from `current` and `additional`.
|
|
36
|
+
* If `current` already contains `additional` it is returned unmodified.
|
|
1057
37
|
*/
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
if (typeof agentCard === "string") {
|
|
1062
|
-
console.warn("Warning: Constructing A2AClient with a URL is deprecated. Please use A2AClient.fromCardUrl() instead.");
|
|
1063
|
-
this.agentCardPromise = this._fetchAndCacheAgentCard(agentCard, options == null ? void 0 : options.agentCardPath);
|
|
1064
|
-
} else {
|
|
1065
|
-
if (!agentCard.url) {
|
|
1066
|
-
throw new Error("Provided Agent Card does not contain a valid 'url' for the service endpoint.");
|
|
1067
|
-
}
|
|
1068
|
-
this.serviceEndpointUrl = agentCard.url;
|
|
1069
|
-
this.agentCardPromise = Promise.resolve(agentCard);
|
|
38
|
+
createFrom: (current, additional) => {
|
|
39
|
+
if (current?.includes(additional)) {
|
|
40
|
+
return current;
|
|
1070
41
|
}
|
|
1071
|
-
|
|
42
|
+
return [...current ?? [], additional];
|
|
43
|
+
},
|
|
1072
44
|
/**
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
1076
|
-
* @param args Arguments to pass to the fetch implementation.
|
|
1077
|
-
* @throws If no fetch implementation is available.
|
|
45
|
+
* Creates {@link Extensions} from comma separated extensions identifiers as per
|
|
46
|
+
* https://a2a-protocol.org/latest/specification/#326-service-parameters.
|
|
47
|
+
* Parses the output of `toServiceParameter`.
|
|
1078
48
|
*/
|
|
1079
|
-
|
|
1080
|
-
if (
|
|
1081
|
-
return
|
|
1082
|
-
}
|
|
1083
|
-
if (typeof fetch === "function") {
|
|
1084
|
-
return fetch(...args);
|
|
49
|
+
parseServiceParameter: (value) => {
|
|
50
|
+
if (!value) {
|
|
51
|
+
return [];
|
|
1085
52
|
}
|
|
1086
|
-
|
|
1087
|
-
"
|
|
53
|
+
const unique = new Set(
|
|
54
|
+
value.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0)
|
|
1088
55
|
);
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
* Creates an A2AClient instance by fetching the AgentCard from a URL then constructing the A2AClient.
|
|
1092
|
-
* @param agentCardUrl The URL of the agent card.
|
|
1093
|
-
* @param options Optional. The options for the A2AClient including the fetch/auth implementation.
|
|
1094
|
-
* @returns A Promise that resolves to a new A2AClient instance.
|
|
1095
|
-
*/
|
|
1096
|
-
static fromCardUrl(agentCardUrl, options) {
|
|
1097
|
-
return __async(this, null, function* () {
|
|
1098
|
-
const fetchImpl = options == null ? void 0 : options.fetchImpl;
|
|
1099
|
-
const requestInit = {
|
|
1100
|
-
headers: { "Accept": "application/json" }
|
|
1101
|
-
};
|
|
1102
|
-
let response;
|
|
1103
|
-
if (fetchImpl) {
|
|
1104
|
-
response = yield fetchImpl(agentCardUrl, requestInit);
|
|
1105
|
-
} else if (typeof fetch === "function") {
|
|
1106
|
-
response = yield fetch(agentCardUrl, requestInit);
|
|
1107
|
-
} else {
|
|
1108
|
-
throw new Error(
|
|
1109
|
-
"A `fetch` implementation was not provided and is not available in the global scope. Please provide a `fetchImpl` in the A2AClientOptions. For earlier Node.js versions (pre-v18), you can use a library like `node-fetch`."
|
|
1110
|
-
);
|
|
1111
|
-
}
|
|
1112
|
-
if (!response.ok) {
|
|
1113
|
-
throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
|
|
1114
|
-
}
|
|
1115
|
-
let agentCard;
|
|
1116
|
-
try {
|
|
1117
|
-
agentCard = yield response.json();
|
|
1118
|
-
} catch (error) {
|
|
1119
|
-
console.error("Failed to parse Agent Card JSON:", error);
|
|
1120
|
-
throw new Error(`Failed to parse Agent Card JSON from ${agentCardUrl}. Original error: ${error.message}`);
|
|
1121
|
-
}
|
|
1122
|
-
return new _A2AClient(agentCard, options);
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
/**
|
|
1126
|
-
* Helper method to make a generic JSON-RPC POST request.
|
|
1127
|
-
* @param method The RPC method name.
|
|
1128
|
-
* @param params The parameters for the RPC method.
|
|
1129
|
-
* @returns A Promise that resolves to the RPC response.
|
|
1130
|
-
*/
|
|
1131
|
-
_postRpcRequest(method, params) {
|
|
1132
|
-
return __async(this, null, function* () {
|
|
1133
|
-
const endpoint = yield this._getServiceEndpoint();
|
|
1134
|
-
const requestId = this.requestIdCounter++;
|
|
1135
|
-
const rpcRequest = {
|
|
1136
|
-
jsonrpc: "2.0",
|
|
1137
|
-
method,
|
|
1138
|
-
params,
|
|
1139
|
-
// Cast because TParams structure varies per method
|
|
1140
|
-
id: requestId
|
|
1141
|
-
};
|
|
1142
|
-
const httpResponse = yield this._fetchRpc(endpoint, rpcRequest);
|
|
1143
|
-
if (!httpResponse.ok) {
|
|
1144
|
-
let errorBodyText = "(empty or non-JSON response)";
|
|
1145
|
-
try {
|
|
1146
|
-
errorBodyText = yield httpResponse.text();
|
|
1147
|
-
const errorJson = JSON.parse(errorBodyText);
|
|
1148
|
-
if (errorJson.jsonrpc && errorJson.error) {
|
|
1149
|
-
return errorJson;
|
|
1150
|
-
} else if (!errorJson.jsonrpc && errorJson.error) {
|
|
1151
|
-
throw new Error(`RPC error for ${method}: ${errorJson.error.message} (Code: ${errorJson.error.code}, HTTP Status: ${httpResponse.status}) Data: ${JSON.stringify(errorJson.error.data || {})}`);
|
|
1152
|
-
} else if (!errorJson.jsonrpc) {
|
|
1153
|
-
throw new Error(`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`);
|
|
1154
|
-
}
|
|
1155
|
-
} catch (e) {
|
|
1156
|
-
if (e.message.startsWith("RPC error for") || e.message.startsWith("HTTP error for")) throw e;
|
|
1157
|
-
throw new Error(`HTTP error for ${method}! Status: ${httpResponse.status} ${httpResponse.statusText}. Response: ${errorBodyText}`);
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
const rpcResponse = yield httpResponse.json();
|
|
1161
|
-
if (rpcResponse.id !== requestId) {
|
|
1162
|
-
console.error(`CRITICAL: RPC response ID mismatch for method ${method}. Expected ${requestId}, got ${rpcResponse.id}. This may lead to incorrect response handling.`);
|
|
1163
|
-
}
|
|
1164
|
-
return rpcResponse;
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1167
|
-
/**
|
|
1168
|
-
* Internal helper method to fetch the RPC service endpoint.
|
|
1169
|
-
* @param url The URL to fetch.
|
|
1170
|
-
* @param rpcRequest The JSON-RPC request to send.
|
|
1171
|
-
* @param acceptHeader The Accept header to use. Defaults to "application/json".
|
|
1172
|
-
* @returns A Promise that resolves to the fetch HTTP response.
|
|
1173
|
-
*/
|
|
1174
|
-
_fetchRpc(url, rpcRequest, acceptHeader = "application/json") {
|
|
1175
|
-
return __async(this, null, function* () {
|
|
1176
|
-
const requestInit = {
|
|
1177
|
-
method: "POST",
|
|
1178
|
-
headers: {
|
|
1179
|
-
"Content-Type": "application/json",
|
|
1180
|
-
"Accept": acceptHeader
|
|
1181
|
-
// Expect JSON response for non-streaming requests
|
|
1182
|
-
},
|
|
1183
|
-
body: JSON.stringify(rpcRequest)
|
|
1184
|
-
};
|
|
1185
|
-
return this._fetch(url, requestInit);
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
/**
|
|
1189
|
-
* Sends a message to the agent.
|
|
1190
|
-
* The behavior (blocking/non-blocking) and push notification configuration
|
|
1191
|
-
* are specified within the `params.configuration` object.
|
|
1192
|
-
* Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
|
|
1193
|
-
* @param params The parameters for sending the message, including the message content and configuration.
|
|
1194
|
-
* @returns A Promise resolving to SendMessageResponse, which can be a Message, Task, or an error.
|
|
1195
|
-
*/
|
|
1196
|
-
sendMessage(params) {
|
|
1197
|
-
return __async(this, null, function* () {
|
|
1198
|
-
return this._postRpcRequest("message/send", params);
|
|
1199
|
-
});
|
|
1200
|
-
}
|
|
1201
|
-
/**
|
|
1202
|
-
* Sends a message to the agent and streams back responses using Server-Sent Events (SSE).
|
|
1203
|
-
* Push notification configuration can be specified in `params.configuration`.
|
|
1204
|
-
* Optionally, `params.message.contextId` or `params.message.taskId` can be provided.
|
|
1205
|
-
* Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
|
|
1206
|
-
* @param params The parameters for sending the message.
|
|
1207
|
-
* @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
|
|
1208
|
-
* The generator throws an error if streaming is not supported or if an HTTP/SSE error occurs.
|
|
1209
|
-
*/
|
|
1210
|
-
sendMessageStream(params) {
|
|
1211
|
-
return __asyncGenerator(this, null, function* () {
|
|
1212
|
-
var _a, _b;
|
|
1213
|
-
const agentCard = yield new __await(this.agentCardPromise);
|
|
1214
|
-
if (!((_a = agentCard.capabilities) == null ? void 0 : _a.streaming)) {
|
|
1215
|
-
throw new Error("Agent does not support streaming (AgentCard.capabilities.streaming is not true).");
|
|
1216
|
-
}
|
|
1217
|
-
const endpoint = yield new __await(this._getServiceEndpoint());
|
|
1218
|
-
const clientRequestId = this.requestIdCounter++;
|
|
1219
|
-
const rpcRequest = {
|
|
1220
|
-
// This is the initial JSON-RPC request to establish the stream
|
|
1221
|
-
jsonrpc: "2.0",
|
|
1222
|
-
method: "message/stream",
|
|
1223
|
-
params,
|
|
1224
|
-
id: clientRequestId
|
|
1225
|
-
};
|
|
1226
|
-
const response = yield new __await(this._fetchRpc(endpoint, rpcRequest, "text/event-stream"));
|
|
1227
|
-
if (!response.ok) {
|
|
1228
|
-
let errorBody = "";
|
|
1229
|
-
try {
|
|
1230
|
-
errorBody = yield new __await(response.text());
|
|
1231
|
-
const errorJson = JSON.parse(errorBody);
|
|
1232
|
-
if (errorJson.error) {
|
|
1233
|
-
throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`);
|
|
1234
|
-
}
|
|
1235
|
-
} catch (e) {
|
|
1236
|
-
if (e.message.startsWith("HTTP error establishing stream")) throw e;
|
|
1237
|
-
throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`);
|
|
1238
|
-
}
|
|
1239
|
-
throw new Error(`HTTP error establishing stream for message/stream: ${response.status} ${response.statusText}`);
|
|
1240
|
-
}
|
|
1241
|
-
if (!((_b = response.headers.get("Content-Type")) == null ? void 0 : _b.startsWith("text/event-stream"))) {
|
|
1242
|
-
throw new Error("Invalid response Content-Type for SSE stream. Expected 'text/event-stream'.");
|
|
1243
|
-
}
|
|
1244
|
-
yield* __yieldStar(this._parseA2ASseStream(response, clientRequestId));
|
|
1245
|
-
});
|
|
1246
|
-
}
|
|
56
|
+
return Array.from(unique);
|
|
57
|
+
},
|
|
1247
58
|
/**
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1250
|
-
* @param params Parameters containing the taskId and the TaskPushNotificationConfig.
|
|
1251
|
-
* @returns A Promise resolving to SetTaskPushNotificationConfigResponse.
|
|
59
|
+
* Converts {@link Extensions} to comma separated extensions identifiers as per
|
|
60
|
+
* https://a2a-protocol.org/latest/specification/#326-service-parameters.
|
|
1252
61
|
*/
|
|
1253
|
-
|
|
1254
|
-
return
|
|
1255
|
-
var _a;
|
|
1256
|
-
const agentCard = yield this.agentCardPromise;
|
|
1257
|
-
if (!((_a = agentCard.capabilities) == null ? void 0 : _a.pushNotifications)) {
|
|
1258
|
-
throw new Error("Agent does not support push notifications (AgentCard.capabilities.pushNotifications is not true).");
|
|
1259
|
-
}
|
|
1260
|
-
return this._postRpcRequest(
|
|
1261
|
-
"tasks/pushNotificationConfig/set",
|
|
1262
|
-
params
|
|
1263
|
-
);
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
|
-
/**
|
|
1267
|
-
* Gets the push notification configuration for a given task.
|
|
1268
|
-
* @param params Parameters containing the taskId.
|
|
1269
|
-
* @returns A Promise resolving to GetTaskPushNotificationConfigResponse.
|
|
1270
|
-
*/
|
|
1271
|
-
getTaskPushNotificationConfig(params) {
|
|
1272
|
-
return __async(this, null, function* () {
|
|
1273
|
-
return this._postRpcRequest(
|
|
1274
|
-
"tasks/pushNotificationConfig/get",
|
|
1275
|
-
params
|
|
1276
|
-
);
|
|
1277
|
-
});
|
|
1278
|
-
}
|
|
1279
|
-
/**
|
|
1280
|
-
* Retrieves a task by its ID.
|
|
1281
|
-
* @param params Parameters containing the taskId and optional historyLength.
|
|
1282
|
-
* @returns A Promise resolving to GetTaskResponse, which contains the Task object or an error.
|
|
1283
|
-
*/
|
|
1284
|
-
getTask(params) {
|
|
1285
|
-
return __async(this, null, function* () {
|
|
1286
|
-
return this._postRpcRequest("tasks/get", params);
|
|
1287
|
-
});
|
|
1288
|
-
}
|
|
1289
|
-
/**
|
|
1290
|
-
* Cancels a task by its ID.
|
|
1291
|
-
* @param params Parameters containing the taskId.
|
|
1292
|
-
* @returns A Promise resolving to CancelTaskResponse, which contains the updated Task object or an error.
|
|
1293
|
-
*/
|
|
1294
|
-
cancelTask(params) {
|
|
1295
|
-
return __async(this, null, function* () {
|
|
1296
|
-
return this._postRpcRequest("tasks/cancel", params);
|
|
1297
|
-
});
|
|
1298
|
-
}
|
|
1299
|
-
/**
|
|
1300
|
-
* Resubscribes to a task's event stream using Server-Sent Events (SSE).
|
|
1301
|
-
* This is used if a previous SSE connection for an active task was broken.
|
|
1302
|
-
* Requires the agent to support streaming (`capabilities.streaming: true` in AgentCard).
|
|
1303
|
-
* @param params Parameters containing the taskId.
|
|
1304
|
-
* @returns An AsyncGenerator yielding A2AStreamEventData (Message, Task, TaskStatusUpdateEvent, or TaskArtifactUpdateEvent).
|
|
1305
|
-
*/
|
|
1306
|
-
resubscribeTask(params) {
|
|
1307
|
-
return __asyncGenerator(this, null, function* () {
|
|
1308
|
-
var _a, _b;
|
|
1309
|
-
const agentCard = yield new __await(this.agentCardPromise);
|
|
1310
|
-
if (!((_a = agentCard.capabilities) == null ? void 0 : _a.streaming)) {
|
|
1311
|
-
throw new Error("Agent does not support streaming (required for tasks/resubscribe).");
|
|
1312
|
-
}
|
|
1313
|
-
const endpoint = yield new __await(this._getServiceEndpoint());
|
|
1314
|
-
const clientRequestId = this.requestIdCounter++;
|
|
1315
|
-
const rpcRequest = {
|
|
1316
|
-
// Initial JSON-RPC request to establish the stream
|
|
1317
|
-
jsonrpc: "2.0",
|
|
1318
|
-
method: "tasks/resubscribe",
|
|
1319
|
-
params,
|
|
1320
|
-
id: clientRequestId
|
|
1321
|
-
};
|
|
1322
|
-
const response = yield new __await(this._fetch(endpoint, {
|
|
1323
|
-
method: "POST",
|
|
1324
|
-
headers: {
|
|
1325
|
-
"Content-Type": "application/json",
|
|
1326
|
-
"Accept": "text/event-stream"
|
|
1327
|
-
},
|
|
1328
|
-
body: JSON.stringify(rpcRequest)
|
|
1329
|
-
}));
|
|
1330
|
-
if (!response.ok) {
|
|
1331
|
-
let errorBody = "";
|
|
1332
|
-
try {
|
|
1333
|
-
errorBody = yield new __await(response.text());
|
|
1334
|
-
const errorJson = JSON.parse(errorBody);
|
|
1335
|
-
if (errorJson.error) {
|
|
1336
|
-
throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}. RPC Error: ${errorJson.error.message} (Code: ${errorJson.error.code})`);
|
|
1337
|
-
}
|
|
1338
|
-
} catch (e) {
|
|
1339
|
-
if (e.message.startsWith("HTTP error establishing stream")) throw e;
|
|
1340
|
-
throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}. Response: ${errorBody || "(empty)"}`);
|
|
1341
|
-
}
|
|
1342
|
-
throw new Error(`HTTP error establishing stream for tasks/resubscribe: ${response.status} ${response.statusText}`);
|
|
1343
|
-
}
|
|
1344
|
-
if (!((_b = response.headers.get("Content-Type")) == null ? void 0 : _b.startsWith("text/event-stream"))) {
|
|
1345
|
-
throw new Error("Invalid response Content-Type for SSE stream on resubscribe. Expected 'text/event-stream'.");
|
|
1346
|
-
}
|
|
1347
|
-
yield* __yieldStar(this._parseA2ASseStream(response, clientRequestId));
|
|
1348
|
-
});
|
|
1349
|
-
}
|
|
1350
|
-
/**
|
|
1351
|
-
* Parses an HTTP response body as an A2A Server-Sent Event stream.
|
|
1352
|
-
* Each 'data' field of an SSE event is expected to be a JSON-RPC 2.0 Response object,
|
|
1353
|
-
* specifically a SendStreamingMessageResponse (or similar structure for resubscribe).
|
|
1354
|
-
* @param response The HTTP Response object whose body is the SSE stream.
|
|
1355
|
-
* @param originalRequestId The ID of the client's JSON-RPC request that initiated this stream.
|
|
1356
|
-
* Used to validate the `id` in the streamed JSON-RPC responses.
|
|
1357
|
-
* @returns An AsyncGenerator yielding the `result` field of each valid JSON-RPC success response from the stream.
|
|
1358
|
-
*/
|
|
1359
|
-
_parseA2ASseStream(response, originalRequestId) {
|
|
1360
|
-
return __asyncGenerator(this, null, function* () {
|
|
1361
|
-
if (!response.body) {
|
|
1362
|
-
throw new Error("SSE response body is undefined. Cannot read stream.");
|
|
1363
|
-
}
|
|
1364
|
-
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
1365
|
-
let buffer = "";
|
|
1366
|
-
let eventDataBuffer = "";
|
|
1367
|
-
try {
|
|
1368
|
-
while (true) {
|
|
1369
|
-
const { done, value } = yield new __await(reader.read());
|
|
1370
|
-
if (done) {
|
|
1371
|
-
if (eventDataBuffer.trim()) {
|
|
1372
|
-
const result = this._processSseEventData(eventDataBuffer, originalRequestId);
|
|
1373
|
-
yield result;
|
|
1374
|
-
}
|
|
1375
|
-
break;
|
|
1376
|
-
}
|
|
1377
|
-
buffer += value;
|
|
1378
|
-
let lineEndIndex;
|
|
1379
|
-
while ((lineEndIndex = buffer.indexOf("\n")) >= 0) {
|
|
1380
|
-
const line = buffer.substring(0, lineEndIndex).trim();
|
|
1381
|
-
buffer = buffer.substring(lineEndIndex + 1);
|
|
1382
|
-
if (line === "") {
|
|
1383
|
-
if (eventDataBuffer) {
|
|
1384
|
-
const result = this._processSseEventData(eventDataBuffer, originalRequestId);
|
|
1385
|
-
yield result;
|
|
1386
|
-
eventDataBuffer = "";
|
|
1387
|
-
}
|
|
1388
|
-
} else if (line.startsWith("data:")) {
|
|
1389
|
-
eventDataBuffer += line.substring(5).trimStart() + "\n";
|
|
1390
|
-
} else if (line.startsWith(":")) {
|
|
1391
|
-
} else if (line.includes(":")) {
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
} catch (error) {
|
|
1396
|
-
console.error("Error reading or parsing SSE stream:", error.message);
|
|
1397
|
-
throw error;
|
|
1398
|
-
} finally {
|
|
1399
|
-
reader.releaseLock();
|
|
1400
|
-
}
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1403
|
-
/**
|
|
1404
|
-
* Processes a single SSE event's data string, expecting it to be a JSON-RPC response.
|
|
1405
|
-
* @param jsonData The string content from one or more 'data:' lines of an SSE event.
|
|
1406
|
-
* @param originalRequestId The ID of the client's request that initiated the stream.
|
|
1407
|
-
* @returns The `result` field of the parsed JSON-RPC success response.
|
|
1408
|
-
* @throws Error if data is not valid JSON, not a valid JSON-RPC response, an error response, or ID mismatch.
|
|
1409
|
-
*/
|
|
1410
|
-
_processSseEventData(jsonData, originalRequestId) {
|
|
1411
|
-
if (!jsonData.trim()) {
|
|
1412
|
-
throw new Error("Attempted to process empty SSE event data.");
|
|
1413
|
-
}
|
|
1414
|
-
try {
|
|
1415
|
-
const sseJsonRpcResponse = JSON.parse(jsonData.replace(/\n$/, ""));
|
|
1416
|
-
const a2aStreamResponse = sseJsonRpcResponse;
|
|
1417
|
-
if (a2aStreamResponse.id !== originalRequestId) {
|
|
1418
|
-
console.warn(`SSE Event's JSON-RPC response ID mismatch. Client request ID: ${originalRequestId}, event response ID: ${a2aStreamResponse.id}.`);
|
|
1419
|
-
}
|
|
1420
|
-
if (this.isErrorResponse(a2aStreamResponse)) {
|
|
1421
|
-
const err = a2aStreamResponse.error;
|
|
1422
|
-
throw new Error(`SSE event contained an error: ${err.message} (Code: ${err.code}) Data: ${JSON.stringify(err.data || {})}`);
|
|
1423
|
-
}
|
|
1424
|
-
if (!("result" in a2aStreamResponse) || typeof a2aStreamResponse.result === "undefined") {
|
|
1425
|
-
throw new Error(`SSE event JSON-RPC response is missing 'result' field. Data: ${jsonData}`);
|
|
1426
|
-
}
|
|
1427
|
-
const successResponse = a2aStreamResponse;
|
|
1428
|
-
return successResponse.result;
|
|
1429
|
-
} catch (e) {
|
|
1430
|
-
if (e.message.startsWith("SSE event contained an error") || e.message.startsWith("SSE event JSON-RPC response is missing 'result' field")) {
|
|
1431
|
-
throw e;
|
|
1432
|
-
}
|
|
1433
|
-
console.error("Failed to parse SSE event data string or unexpected JSON-RPC structure:", jsonData, e);
|
|
1434
|
-
throw new Error(`Failed to parse SSE event data: "${jsonData.substring(0, 100)}...". Original error: ${e.message}`);
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
isErrorResponse(response) {
|
|
1438
|
-
return "error" in response;
|
|
1439
|
-
}
|
|
1440
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
1441
|
-
// Functions used to support old A2AClient Constructor to be deprecated soon
|
|
1442
|
-
// TODOs:
|
|
1443
|
-
// * remove `agentCardPromise`, and just use agentCard initialized
|
|
1444
|
-
// * _getServiceEndpoint can be made synchronous or deleted and accessed via
|
|
1445
|
-
// agentCard.url
|
|
1446
|
-
// * getAgentCard changed to this.agentCard
|
|
1447
|
-
// * delete resolveAgentCardUrl(), _fetchAndCacheAgentCard(),
|
|
1448
|
-
// agentCardPath from A2AClientOptions
|
|
1449
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
1450
|
-
/**
|
|
1451
|
-
* Fetches the Agent Card from the agent's well-known URI and caches its service endpoint URL.
|
|
1452
|
-
* This method is called by the constructor.
|
|
1453
|
-
* @param agentBaseUrl The base URL of the A2A agent (e.g., https://agent.example.com)
|
|
1454
|
-
* @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
|
|
1455
|
-
* @returns A Promise that resolves to the AgentCard.
|
|
1456
|
-
*/
|
|
1457
|
-
_fetchAndCacheAgentCard(agentBaseUrl, agentCardPath) {
|
|
1458
|
-
return __async(this, null, function* () {
|
|
1459
|
-
try {
|
|
1460
|
-
const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
|
|
1461
|
-
const response = yield this._fetch(agentCardUrl, {
|
|
1462
|
-
headers: { "Accept": "application/json" }
|
|
1463
|
-
});
|
|
1464
|
-
if (!response.ok) {
|
|
1465
|
-
throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
|
|
1466
|
-
}
|
|
1467
|
-
const agentCard = yield response.json();
|
|
1468
|
-
if (!agentCard.url) {
|
|
1469
|
-
throw new Error("Fetched Agent Card does not contain a valid 'url' for the service endpoint.");
|
|
1470
|
-
}
|
|
1471
|
-
this.serviceEndpointUrl = agentCard.url;
|
|
1472
|
-
return agentCard;
|
|
1473
|
-
} catch (error) {
|
|
1474
|
-
console.error("Error fetching or parsing Agent Card:", error);
|
|
1475
|
-
throw error;
|
|
1476
|
-
}
|
|
1477
|
-
});
|
|
1478
|
-
}
|
|
1479
|
-
/**
|
|
1480
|
-
* Retrieves the Agent Card.
|
|
1481
|
-
* If an `agentBaseUrl` is provided, it fetches the card from that specific URL.
|
|
1482
|
-
* Otherwise, it returns the card fetched and cached during client construction.
|
|
1483
|
-
* @param agentBaseUrl Optional. The base URL of the agent to fetch the card from.
|
|
1484
|
-
* @param agentCardPath path to the agent card, defaults to .well-known/agent-card.json
|
|
1485
|
-
* If provided, this will fetch a new card, not use the cached one from the constructor's URL.
|
|
1486
|
-
* @returns A Promise that resolves to the AgentCard.
|
|
1487
|
-
*/
|
|
1488
|
-
getAgentCard(agentBaseUrl, agentCardPath) {
|
|
1489
|
-
return __async(this, null, function* () {
|
|
1490
|
-
if (agentBaseUrl) {
|
|
1491
|
-
const agentCardUrl = this.resolveAgentCardUrl(agentBaseUrl, agentCardPath);
|
|
1492
|
-
const response = yield this._fetch(agentCardUrl, {
|
|
1493
|
-
headers: { "Accept": "application/json" }
|
|
1494
|
-
});
|
|
1495
|
-
if (!response.ok) {
|
|
1496
|
-
throw new Error(`Failed to fetch Agent Card from ${agentCardUrl}: ${response.status} ${response.statusText}`);
|
|
1497
|
-
}
|
|
1498
|
-
return yield response.json();
|
|
1499
|
-
}
|
|
1500
|
-
return this.agentCardPromise;
|
|
1501
|
-
});
|
|
1502
|
-
}
|
|
1503
|
-
/**
|
|
1504
|
-
* Determines the agent card URL based on the agent URL.
|
|
1505
|
-
* @param agentBaseUrl The agent URL.
|
|
1506
|
-
* @param agentCardPath Optional relative path to the agent card, defaults to .well-known/agent-card.json
|
|
1507
|
-
*/
|
|
1508
|
-
resolveAgentCardUrl(agentBaseUrl, agentCardPath = AGENT_CARD_PATH) {
|
|
1509
|
-
return `${agentBaseUrl.replace(/\/$/, "")}/${agentCardPath.replace(/^\//, "")}`;
|
|
1510
|
-
}
|
|
1511
|
-
/**
|
|
1512
|
-
* Gets the RPC service endpoint URL. Ensures the agent card has been fetched first.
|
|
1513
|
-
* @returns A Promise that resolves to the service endpoint URL string.
|
|
1514
|
-
*/
|
|
1515
|
-
_getServiceEndpoint() {
|
|
1516
|
-
return __async(this, null, function* () {
|
|
1517
|
-
if (this.serviceEndpointUrl) {
|
|
1518
|
-
return this.serviceEndpointUrl;
|
|
1519
|
-
}
|
|
1520
|
-
yield this.agentCardPromise;
|
|
1521
|
-
if (!this.serviceEndpointUrl) {
|
|
1522
|
-
throw new Error("Agent Card URL for RPC endpoint is not available. Fetching might have failed.");
|
|
1523
|
-
}
|
|
1524
|
-
return this.serviceEndpointUrl;
|
|
1525
|
-
});
|
|
1526
|
-
}
|
|
1527
|
-
};
|
|
1528
|
-
|
|
1529
|
-
// src/client/auth-handler.ts
|
|
1530
|
-
function createAuthenticatingFetchWithRetry(fetchImpl, authHandler) {
|
|
1531
|
-
function authFetch(url, init) {
|
|
1532
|
-
return __async(this, null, function* () {
|
|
1533
|
-
const authHeaders = (yield authHandler.headers()) || {};
|
|
1534
|
-
const mergedInit = __spreadProps(__spreadValues({}, init || {}), {
|
|
1535
|
-
headers: __spreadValues(__spreadValues({}, authHeaders), (init == null ? void 0 : init.headers) || {})
|
|
1536
|
-
});
|
|
1537
|
-
let response = yield fetchImpl(url, mergedInit);
|
|
1538
|
-
const updatedHeaders = yield authHandler.shouldRetryWithHeaders(mergedInit, response);
|
|
1539
|
-
if (updatedHeaders) {
|
|
1540
|
-
const retryInit = __spreadProps(__spreadValues({}, init || {}), {
|
|
1541
|
-
headers: __spreadValues(__spreadValues({}, updatedHeaders), (init == null ? void 0 : init.headers) || {})
|
|
1542
|
-
});
|
|
1543
|
-
response = yield fetchImpl(url, retryInit);
|
|
1544
|
-
if (response.ok && authHandler.onSuccessfulRetry) {
|
|
1545
|
-
yield authHandler.onSuccessfulRetry(updatedHeaders);
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
return response;
|
|
1549
|
-
});
|
|
1550
|
-
}
|
|
1551
|
-
Object.setPrototypeOf(authFetch, Object.getPrototypeOf(fetchImpl));
|
|
1552
|
-
Object.defineProperties(authFetch, Object.getOwnPropertyDescriptors(fetchImpl));
|
|
1553
|
-
return authFetch;
|
|
1554
|
-
}
|
|
1555
|
-
|
|
1556
|
-
// src/server/express/a2a_express_app.ts
|
|
1557
|
-
var import_express = __toESM(require("express"));
|
|
1558
|
-
var A2AExpressApp = class {
|
|
1559
|
-
constructor(requestHandler) {
|
|
1560
|
-
this.requestHandler = requestHandler;
|
|
1561
|
-
this.jsonRpcTransportHandler = new JsonRpcTransportHandler(requestHandler);
|
|
1562
|
-
}
|
|
1563
|
-
/**
|
|
1564
|
-
* Adds A2A routes to an existing Express app.
|
|
1565
|
-
* @param app Optional existing Express app.
|
|
1566
|
-
* @param baseUrl The base URL for A2A endpoints (e.g., "/a2a/api").
|
|
1567
|
-
* @param middlewares Optional array of Express middlewares to apply to the A2A routes.
|
|
1568
|
-
* @param agentCardPath Optional custom path for the agent card endpoint (defaults to /.well-known/agent-card.json).
|
|
1569
|
-
* @returns The Express app with A2A routes.
|
|
1570
|
-
*/
|
|
1571
|
-
setupRoutes(app, baseUrl = "", middlewares, agentCardPath = AGENT_CARD_PATH) {
|
|
1572
|
-
const router = import_express.default.Router();
|
|
1573
|
-
router.use(import_express.default.json(), ...middlewares != null ? middlewares : []);
|
|
1574
|
-
router.get(`/${agentCardPath}`, (req, res) => __async(this, null, function* () {
|
|
1575
|
-
try {
|
|
1576
|
-
const agentCard = yield this.requestHandler.getAgentCard();
|
|
1577
|
-
res.json(agentCard);
|
|
1578
|
-
} catch (error) {
|
|
1579
|
-
console.error("Error fetching agent card:", error);
|
|
1580
|
-
res.status(500).json({ error: "Failed to retrieve agent card" });
|
|
1581
|
-
}
|
|
1582
|
-
}));
|
|
1583
|
-
router.post("/", (req, res) => __async(this, null, function* () {
|
|
1584
|
-
var _a, _b, _c;
|
|
1585
|
-
try {
|
|
1586
|
-
const rpcResponseOrStream = yield this.jsonRpcTransportHandler.handle(req.body);
|
|
1587
|
-
if (typeof (rpcResponseOrStream == null ? void 0 : rpcResponseOrStream[Symbol.asyncIterator]) === "function") {
|
|
1588
|
-
const stream = rpcResponseOrStream;
|
|
1589
|
-
res.setHeader("Content-Type", "text/event-stream");
|
|
1590
|
-
res.setHeader("Cache-Control", "no-cache");
|
|
1591
|
-
res.setHeader("Connection", "keep-alive");
|
|
1592
|
-
res.flushHeaders();
|
|
1593
|
-
try {
|
|
1594
|
-
try {
|
|
1595
|
-
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {
|
|
1596
|
-
const event = temp.value;
|
|
1597
|
-
res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
|
|
1598
|
-
`);
|
|
1599
|
-
res.write(`data: ${JSON.stringify(event)}
|
|
1600
|
-
|
|
1601
|
-
`);
|
|
1602
|
-
}
|
|
1603
|
-
} catch (temp) {
|
|
1604
|
-
error = [temp];
|
|
1605
|
-
} finally {
|
|
1606
|
-
try {
|
|
1607
|
-
more && (temp = iter.return) && (yield temp.call(iter));
|
|
1608
|
-
} finally {
|
|
1609
|
-
if (error)
|
|
1610
|
-
throw error[0];
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
} catch (streamError) {
|
|
1614
|
-
console.error(`Error during SSE streaming (request ${(_a = req.body) == null ? void 0 : _a.id}):`, streamError);
|
|
1615
|
-
const a2aError = streamError instanceof A2AError ? streamError : A2AError.internalError(streamError.message || "Streaming error.");
|
|
1616
|
-
const errorResponse = {
|
|
1617
|
-
jsonrpc: "2.0",
|
|
1618
|
-
id: ((_b = req.body) == null ? void 0 : _b.id) || null,
|
|
1619
|
-
// Use original request ID if available
|
|
1620
|
-
error: a2aError.toJSONRPCError()
|
|
1621
|
-
};
|
|
1622
|
-
if (!res.headersSent) {
|
|
1623
|
-
res.status(500).json(errorResponse);
|
|
1624
|
-
} else {
|
|
1625
|
-
res.write(`id: ${(/* @__PURE__ */ new Date()).getTime()}
|
|
1626
|
-
`);
|
|
1627
|
-
res.write(`event: error
|
|
1628
|
-
`);
|
|
1629
|
-
res.write(`data: ${JSON.stringify(errorResponse)}
|
|
1630
|
-
|
|
1631
|
-
`);
|
|
1632
|
-
}
|
|
1633
|
-
} finally {
|
|
1634
|
-
if (!res.writableEnded) {
|
|
1635
|
-
res.end();
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
} else {
|
|
1639
|
-
const rpcResponse = rpcResponseOrStream;
|
|
1640
|
-
res.status(200).json(rpcResponse);
|
|
1641
|
-
}
|
|
1642
|
-
} catch (error2) {
|
|
1643
|
-
console.error("Unhandled error in A2AExpressApp POST handler:", error2);
|
|
1644
|
-
const a2aError = error2 instanceof A2AError ? error2 : A2AError.internalError("General processing error.");
|
|
1645
|
-
const errorResponse = {
|
|
1646
|
-
jsonrpc: "2.0",
|
|
1647
|
-
id: ((_c = req.body) == null ? void 0 : _c.id) || null,
|
|
1648
|
-
error: a2aError.toJSONRPCError()
|
|
1649
|
-
};
|
|
1650
|
-
if (!res.headersSent) {
|
|
1651
|
-
res.status(500).json(errorResponse);
|
|
1652
|
-
} else if (!res.writableEnded) {
|
|
1653
|
-
res.end();
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
}));
|
|
1657
|
-
app.use(baseUrl, router);
|
|
1658
|
-
return app;
|
|
62
|
+
toServiceParameter: (value) => {
|
|
63
|
+
return value.join(",");
|
|
1659
64
|
}
|
|
1660
65
|
};
|
|
1661
66
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1662
67
|
0 && (module.exports = {
|
|
1663
|
-
A2AClient,
|
|
1664
|
-
A2AError,
|
|
1665
|
-
A2AExpressApp,
|
|
1666
68
|
AGENT_CARD_PATH,
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
DefaultRequestHandler,
|
|
1670
|
-
ExecutionEventQueue,
|
|
1671
|
-
InMemoryTaskStore,
|
|
1672
|
-
JsonRpcTransportHandler,
|
|
1673
|
-
RequestContext,
|
|
1674
|
-
ResultManager,
|
|
1675
|
-
createAuthenticatingFetchWithRetry,
|
|
1676
|
-
getCurrentTimestamp,
|
|
1677
|
-
isArtifactUpdate,
|
|
1678
|
-
isObject,
|
|
1679
|
-
isTaskStatusUpdate
|
|
69
|
+
Extensions,
|
|
70
|
+
HTTP_EXTENSION_HEADER
|
|
1680
71
|
});
|