@a2a-js/sdk 0.3.4 → 0.3.6
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 +258 -188
- package/dist/a2a_request_handler-B3LxMq3P.d.cts +49 -0
- package/dist/a2a_request_handler-BuP9LgXH.d.ts +49 -0
- package/dist/chunk-3QDLXHKS.js +8 -0
- package/dist/{chunk-JA52GYRU.js → chunk-LTPINR5K.js} +115 -61
- package/dist/chunk-ZX6KNMCP.js +38 -0
- package/dist/client/index.cjs +1057 -256
- package/dist/client/index.d.cts +419 -48
- package/dist/client/index.d.ts +419 -48
- package/dist/client/index.js +1015 -257
- package/dist/{types-DNKcmF0f.d.cts → extensions-DvruCIzw.d.cts} +28 -1
- package/dist/{types-DNKcmF0f.d.ts → extensions-DvruCIzw.d.ts} +28 -1
- package/dist/index.cjs +42 -2
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +9 -3
- package/dist/server/express/index.cjs +790 -141
- package/dist/server/express/index.d.cts +84 -7
- package/dist/server/express/index.d.ts +84 -7
- package/dist/server/express/index.js +651 -82
- package/dist/server/index.cjs +368 -145
- package/dist/server/index.d.cts +36 -26
- package/dist/server/index.d.ts +36 -26
- package/dist/server/index.js +227 -86
- package/package.json +17 -9
- package/dist/a2a_request_handler-B5t-IxgA.d.ts +0 -17
- package/dist/a2a_request_handler-DUvKWfix.d.cts +0 -17
- package/dist/chunk-67JNQ6TZ.js +0 -6
package/dist/server/index.js
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
A2AError,
|
|
3
|
-
JsonRpcTransportHandler
|
|
4
|
-
|
|
3
|
+
JsonRpcTransportHandler,
|
|
4
|
+
ServerCallContext,
|
|
5
|
+
UnauthenticatedUser
|
|
6
|
+
} from "../chunk-LTPINR5K.js";
|
|
7
|
+
import "../chunk-ZX6KNMCP.js";
|
|
5
8
|
|
|
6
9
|
// src/server/agent_execution/request_context.ts
|
|
7
10
|
var RequestContext = class {
|
|
8
11
|
userMessage;
|
|
9
|
-
task;
|
|
10
|
-
referenceTasks;
|
|
11
12
|
taskId;
|
|
12
13
|
contextId;
|
|
13
|
-
|
|
14
|
+
task;
|
|
15
|
+
referenceTasks;
|
|
16
|
+
context;
|
|
17
|
+
constructor(userMessage, taskId, contextId, task, referenceTasks, context) {
|
|
14
18
|
this.userMessage = userMessage;
|
|
15
19
|
this.taskId = taskId;
|
|
16
20
|
this.contextId = contextId;
|
|
17
21
|
this.task = task;
|
|
18
22
|
this.referenceTasks = referenceTasks;
|
|
23
|
+
this.context = context;
|
|
19
24
|
}
|
|
20
25
|
};
|
|
21
26
|
|
|
@@ -39,7 +44,7 @@ var DefaultExecutionEventBusManager = class {
|
|
|
39
44
|
/**
|
|
40
45
|
* Creates or retrieves an existing ExecutionEventBus based on the taskId.
|
|
41
46
|
* @param taskId The ID of the task.
|
|
42
|
-
* @returns An instance of
|
|
47
|
+
* @returns An instance of ExecutionEventBus.
|
|
43
48
|
*/
|
|
44
49
|
createOrGetByTaskId(taskId) {
|
|
45
50
|
if (!this.taskIdToBus.has(taskId)) {
|
|
@@ -50,7 +55,7 @@ var DefaultExecutionEventBusManager = class {
|
|
|
50
55
|
/**
|
|
51
56
|
* Retrieves an existing ExecutionEventBus based on the taskId.
|
|
52
57
|
* @param taskId The ID of the task.
|
|
53
|
-
* @returns An instance of
|
|
58
|
+
* @returns An instance of ExecutionEventBus or undefined if not found.
|
|
54
59
|
*/
|
|
55
60
|
getByTaskId(taskId) {
|
|
56
61
|
return this.taskIdToBus.get(taskId);
|
|
@@ -132,13 +137,15 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
132
137
|
// src/server/result_manager.ts
|
|
133
138
|
var ResultManager = class {
|
|
134
139
|
taskStore;
|
|
140
|
+
serverCallContext;
|
|
135
141
|
currentTask;
|
|
136
142
|
latestUserMessage;
|
|
137
143
|
// To add to history if a new task is created
|
|
138
144
|
finalMessageResult;
|
|
139
145
|
// Stores the message if it's the final result
|
|
140
|
-
constructor(taskStore) {
|
|
146
|
+
constructor(taskStore, serverCallContext) {
|
|
141
147
|
this.taskStore = taskStore;
|
|
148
|
+
this.serverCallContext = serverCallContext;
|
|
142
149
|
}
|
|
143
150
|
setContext(latestUserMessage) {
|
|
144
151
|
this.latestUserMessage = latestUserMessage;
|
|
@@ -154,7 +161,9 @@ var ResultManager = class {
|
|
|
154
161
|
const taskEvent = event;
|
|
155
162
|
this.currentTask = { ...taskEvent };
|
|
156
163
|
if (this.latestUserMessage) {
|
|
157
|
-
if (!this.currentTask.history?.find(
|
|
164
|
+
if (!this.currentTask.history?.find(
|
|
165
|
+
(msg) => msg.messageId === this.latestUserMessage.messageId
|
|
166
|
+
)) {
|
|
158
167
|
this.currentTask.history = [this.latestUserMessage, ...this.currentTask.history || []];
|
|
159
168
|
}
|
|
160
169
|
}
|
|
@@ -164,24 +173,36 @@ var ResultManager = class {
|
|
|
164
173
|
if (this.currentTask && this.currentTask.id === updateEvent.taskId) {
|
|
165
174
|
this.currentTask.status = updateEvent.status;
|
|
166
175
|
if (updateEvent.status.message) {
|
|
167
|
-
if (!this.currentTask.history?.find(
|
|
168
|
-
|
|
176
|
+
if (!this.currentTask.history?.find(
|
|
177
|
+
(msg) => msg.messageId === updateEvent.status.message.messageId
|
|
178
|
+
)) {
|
|
179
|
+
this.currentTask.history = [
|
|
180
|
+
...this.currentTask.history || [],
|
|
181
|
+
updateEvent.status.message
|
|
182
|
+
];
|
|
169
183
|
}
|
|
170
184
|
}
|
|
171
185
|
await this.saveCurrentTask();
|
|
172
186
|
} else if (!this.currentTask && updateEvent.taskId) {
|
|
173
|
-
const loaded = await this.taskStore.load(updateEvent.taskId);
|
|
187
|
+
const loaded = await this.taskStore.load(updateEvent.taskId, this.serverCallContext);
|
|
174
188
|
if (loaded) {
|
|
175
189
|
this.currentTask = loaded;
|
|
176
190
|
this.currentTask.status = updateEvent.status;
|
|
177
191
|
if (updateEvent.status.message) {
|
|
178
|
-
if (!this.currentTask.history?.find(
|
|
179
|
-
|
|
192
|
+
if (!this.currentTask.history?.find(
|
|
193
|
+
(msg) => msg.messageId === updateEvent.status.message.messageId
|
|
194
|
+
)) {
|
|
195
|
+
this.currentTask.history = [
|
|
196
|
+
...this.currentTask.history || [],
|
|
197
|
+
updateEvent.status.message
|
|
198
|
+
];
|
|
180
199
|
}
|
|
181
200
|
}
|
|
182
201
|
await this.saveCurrentTask();
|
|
183
202
|
} else {
|
|
184
|
-
console.warn(
|
|
203
|
+
console.warn(
|
|
204
|
+
`ResultManager: Received status update for unknown task ${updateEvent.taskId}`
|
|
205
|
+
);
|
|
185
206
|
}
|
|
186
207
|
}
|
|
187
208
|
} else if (event.kind === "artifact-update") {
|
|
@@ -197,9 +218,14 @@ var ResultManager = class {
|
|
|
197
218
|
if (artifactEvent.append) {
|
|
198
219
|
const existingArtifact = this.currentTask.artifacts[existingArtifactIndex];
|
|
199
220
|
existingArtifact.parts.push(...artifactEvent.artifact.parts);
|
|
200
|
-
if (artifactEvent.artifact.description)
|
|
221
|
+
if (artifactEvent.artifact.description)
|
|
222
|
+
existingArtifact.description = artifactEvent.artifact.description;
|
|
201
223
|
if (artifactEvent.artifact.name) existingArtifact.name = artifactEvent.artifact.name;
|
|
202
|
-
if (artifactEvent.artifact.metadata)
|
|
224
|
+
if (artifactEvent.artifact.metadata)
|
|
225
|
+
existingArtifact.metadata = {
|
|
226
|
+
...existingArtifact.metadata,
|
|
227
|
+
...artifactEvent.artifact.metadata
|
|
228
|
+
};
|
|
203
229
|
} else {
|
|
204
230
|
this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
|
|
205
231
|
}
|
|
@@ -208,7 +234,7 @@ var ResultManager = class {
|
|
|
208
234
|
}
|
|
209
235
|
await this.saveCurrentTask();
|
|
210
236
|
} else if (!this.currentTask && artifactEvent.taskId) {
|
|
211
|
-
const loaded = await this.taskStore.load(artifactEvent.taskId);
|
|
237
|
+
const loaded = await this.taskStore.load(artifactEvent.taskId, this.serverCallContext);
|
|
212
238
|
if (loaded) {
|
|
213
239
|
this.currentTask = loaded;
|
|
214
240
|
if (!this.currentTask.artifacts) this.currentTask.artifacts = [];
|
|
@@ -217,7 +243,9 @@ var ResultManager = class {
|
|
|
217
243
|
);
|
|
218
244
|
if (existingArtifactIndex !== -1) {
|
|
219
245
|
if (artifactEvent.append) {
|
|
220
|
-
this.currentTask.artifacts[existingArtifactIndex].parts.push(
|
|
246
|
+
this.currentTask.artifacts[existingArtifactIndex].parts.push(
|
|
247
|
+
...artifactEvent.artifact.parts
|
|
248
|
+
);
|
|
221
249
|
} else {
|
|
222
250
|
this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
|
|
223
251
|
}
|
|
@@ -226,14 +254,16 @@ var ResultManager = class {
|
|
|
226
254
|
}
|
|
227
255
|
await this.saveCurrentTask();
|
|
228
256
|
} else {
|
|
229
|
-
console.warn(
|
|
257
|
+
console.warn(
|
|
258
|
+
`ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`
|
|
259
|
+
);
|
|
230
260
|
}
|
|
231
261
|
}
|
|
232
262
|
}
|
|
233
263
|
}
|
|
234
264
|
async saveCurrentTask() {
|
|
235
265
|
if (this.currentTask) {
|
|
236
|
-
await this.taskStore.save(this.currentTask);
|
|
266
|
+
await this.taskStore.save(this.currentTask, this.serverCallContext);
|
|
237
267
|
}
|
|
238
268
|
}
|
|
239
269
|
/**
|
|
@@ -299,9 +329,11 @@ var InMemoryPushNotificationStore = class {
|
|
|
299
329
|
// src/server/push_notification/default_push_notification_sender.ts
|
|
300
330
|
var DefaultPushNotificationSender = class {
|
|
301
331
|
pushNotificationStore;
|
|
332
|
+
notificationChain;
|
|
302
333
|
options;
|
|
303
334
|
constructor(pushNotificationStore, options = {}) {
|
|
304
335
|
this.pushNotificationStore = pushNotificationStore;
|
|
336
|
+
this.notificationChain = /* @__PURE__ */ new Map();
|
|
305
337
|
this.options = {
|
|
306
338
|
timeout: 5e3,
|
|
307
339
|
tokenHeaderName: "X-A2A-Notification-Token",
|
|
@@ -313,10 +345,25 @@ var DefaultPushNotificationSender = class {
|
|
|
313
345
|
if (!pushConfigs || pushConfigs.length === 0) {
|
|
314
346
|
return;
|
|
315
347
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
348
|
+
const lastPromise = this.notificationChain.get(task.id) ?? Promise.resolve();
|
|
349
|
+
const newPromise = lastPromise.then(async () => {
|
|
350
|
+
const dispatches = pushConfigs.map(async (pushConfig) => {
|
|
351
|
+
try {
|
|
352
|
+
await this._dispatchNotification(task, pushConfig);
|
|
353
|
+
} catch (error) {
|
|
354
|
+
console.error(
|
|
355
|
+
`Error sending push notification for task_id=${task.id} to URL: ${pushConfig.url}. Error:`,
|
|
356
|
+
error
|
|
357
|
+
);
|
|
358
|
+
}
|
|
319
359
|
});
|
|
360
|
+
await Promise.all(dispatches);
|
|
361
|
+
});
|
|
362
|
+
this.notificationChain.set(task.id, newPromise);
|
|
363
|
+
newPromise.finally(() => {
|
|
364
|
+
if (this.notificationChain.get(task.id) === newPromise) {
|
|
365
|
+
this.notificationChain.delete(task.id);
|
|
366
|
+
}
|
|
320
367
|
});
|
|
321
368
|
}
|
|
322
369
|
async _dispatchNotification(task, pushConfig) {
|
|
@@ -340,8 +387,6 @@ var DefaultPushNotificationSender = class {
|
|
|
340
387
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
341
388
|
}
|
|
342
389
|
console.info(`Push notification sent for task_id=${task.id} to URL: ${url}`);
|
|
343
|
-
} catch (error) {
|
|
344
|
-
console.error(`Error sending push notification for task_id=${task.id} to URL: ${url}. Error:`, error);
|
|
345
390
|
} finally {
|
|
346
391
|
clearTimeout(timeoutId);
|
|
347
392
|
}
|
|
@@ -352,18 +397,18 @@ var DefaultPushNotificationSender = class {
|
|
|
352
397
|
var terminalStates = ["completed", "failed", "canceled", "rejected"];
|
|
353
398
|
var DefaultRequestHandler = class {
|
|
354
399
|
agentCard;
|
|
355
|
-
extendedAgentCard;
|
|
356
400
|
taskStore;
|
|
357
401
|
agentExecutor;
|
|
358
402
|
eventBusManager;
|
|
359
403
|
pushNotificationStore;
|
|
360
404
|
pushNotificationSender;
|
|
361
|
-
|
|
405
|
+
extendedAgentCardProvider;
|
|
406
|
+
constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), pushNotificationStore, pushNotificationSender, extendedAgentCardProvider) {
|
|
362
407
|
this.agentCard = agentCard;
|
|
363
408
|
this.taskStore = taskStore;
|
|
364
409
|
this.agentExecutor = agentExecutor;
|
|
365
410
|
this.eventBusManager = eventBusManager;
|
|
366
|
-
this.
|
|
411
|
+
this.extendedAgentCardProvider = extendedAgentCardProvider;
|
|
367
412
|
if (agentCard.capabilities.pushNotifications) {
|
|
368
413
|
this.pushNotificationStore = pushNotificationStore || new InMemoryPushNotificationStore();
|
|
369
414
|
this.pushNotificationSender = pushNotificationSender || new DefaultPushNotificationSender(this.pushNotificationStore);
|
|
@@ -372,28 +417,42 @@ var DefaultRequestHandler = class {
|
|
|
372
417
|
async getAgentCard() {
|
|
373
418
|
return this.agentCard;
|
|
374
419
|
}
|
|
375
|
-
async getAuthenticatedExtendedAgentCard() {
|
|
376
|
-
if (!this.
|
|
420
|
+
async getAuthenticatedExtendedAgentCard(context) {
|
|
421
|
+
if (!this.agentCard.supportsAuthenticatedExtendedCard) {
|
|
422
|
+
throw A2AError.unsupportedOperation("Agent does not support authenticated extended card.");
|
|
423
|
+
}
|
|
424
|
+
if (!this.extendedAgentCardProvider) {
|
|
377
425
|
throw A2AError.authenticatedExtendedCardNotConfigured();
|
|
378
426
|
}
|
|
379
|
-
|
|
427
|
+
if (typeof this.extendedAgentCardProvider === "function") {
|
|
428
|
+
return this.extendedAgentCardProvider(context);
|
|
429
|
+
}
|
|
430
|
+
if (context?.user?.isAuthenticated) {
|
|
431
|
+
return this.extendedAgentCardProvider;
|
|
432
|
+
}
|
|
433
|
+
return this.agentCard;
|
|
380
434
|
}
|
|
381
|
-
async _createRequestContext(incomingMessage,
|
|
435
|
+
async _createRequestContext(incomingMessage, context) {
|
|
382
436
|
let task;
|
|
383
437
|
let referenceTasks;
|
|
384
438
|
if (incomingMessage.taskId) {
|
|
385
|
-
task = await this.taskStore.load(incomingMessage.taskId);
|
|
439
|
+
task = await this.taskStore.load(incomingMessage.taskId, context);
|
|
386
440
|
if (!task) {
|
|
387
441
|
throw A2AError.taskNotFound(incomingMessage.taskId);
|
|
388
442
|
}
|
|
389
443
|
if (terminalStates.includes(task.status.state)) {
|
|
390
|
-
throw A2AError.invalidRequest(
|
|
444
|
+
throw A2AError.invalidRequest(
|
|
445
|
+
`Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`
|
|
446
|
+
);
|
|
391
447
|
}
|
|
448
|
+
task.history = [...task.history || [], incomingMessage];
|
|
449
|
+
await this.taskStore.save(task, context);
|
|
392
450
|
}
|
|
451
|
+
const taskId = incomingMessage.taskId || uuidv4();
|
|
393
452
|
if (incomingMessage.referenceTaskIds && incomingMessage.referenceTaskIds.length > 0) {
|
|
394
453
|
referenceTasks = [];
|
|
395
454
|
for (const refId of incomingMessage.referenceTaskIds) {
|
|
396
|
-
const refTask = await this.taskStore.load(refId);
|
|
455
|
+
const refTask = await this.taskStore.load(refId, context);
|
|
397
456
|
if (refTask) {
|
|
398
457
|
referenceTasks.push(refTask);
|
|
399
458
|
} else {
|
|
@@ -402,54 +461,74 @@ var DefaultRequestHandler = class {
|
|
|
402
461
|
}
|
|
403
462
|
}
|
|
404
463
|
const contextId = incomingMessage.contextId || task?.contextId || uuidv4();
|
|
464
|
+
if (context?.requestedExtensions) {
|
|
465
|
+
const agentCard = await this.getAgentCard();
|
|
466
|
+
const exposedExtensions = new Set(
|
|
467
|
+
agentCard.capabilities.extensions?.map((ext) => ext.uri) || []
|
|
468
|
+
);
|
|
469
|
+
const validExtensions = context.requestedExtensions.filter(
|
|
470
|
+
(extension) => exposedExtensions.has(extension)
|
|
471
|
+
);
|
|
472
|
+
context = new ServerCallContext(validExtensions, context.user);
|
|
473
|
+
}
|
|
405
474
|
const messageForContext = {
|
|
406
475
|
...incomingMessage,
|
|
407
|
-
contextId
|
|
408
|
-
};
|
|
409
|
-
return new RequestContext(
|
|
410
|
-
messageForContext,
|
|
411
|
-
taskId,
|
|
412
476
|
contextId,
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
);
|
|
477
|
+
taskId
|
|
478
|
+
};
|
|
479
|
+
return new RequestContext(messageForContext, taskId, contextId, task, referenceTasks, context);
|
|
416
480
|
}
|
|
417
|
-
async _processEvents(taskId, resultManager, eventQueue, options) {
|
|
481
|
+
async _processEvents(taskId, resultManager, eventQueue, context, options) {
|
|
418
482
|
let firstResultSent = false;
|
|
419
483
|
try {
|
|
420
484
|
for await (const event of eventQueue.events()) {
|
|
421
485
|
await resultManager.processEvent(event);
|
|
422
|
-
|
|
486
|
+
try {
|
|
487
|
+
await this._sendPushNotificationIfNeeded(event, context);
|
|
488
|
+
} catch (error) {
|
|
489
|
+
console.error(`Error sending push notification: ${error}`);
|
|
490
|
+
}
|
|
423
491
|
if (options?.firstResultResolver && !firstResultSent) {
|
|
424
|
-
|
|
425
|
-
|
|
492
|
+
let firstResult;
|
|
493
|
+
if (event.kind === "message") {
|
|
494
|
+
firstResult = event;
|
|
495
|
+
} else {
|
|
496
|
+
firstResult = resultManager.getCurrentTask();
|
|
497
|
+
}
|
|
498
|
+
if (firstResult) {
|
|
499
|
+
options.firstResultResolver(firstResult);
|
|
426
500
|
firstResultSent = true;
|
|
427
501
|
}
|
|
428
502
|
}
|
|
429
503
|
}
|
|
430
504
|
if (options?.firstResultRejector && !firstResultSent) {
|
|
431
|
-
options.firstResultRejector(
|
|
505
|
+
options.firstResultRejector(
|
|
506
|
+
A2AError.internalError("Execution finished before a message or task was produced.")
|
|
507
|
+
);
|
|
432
508
|
}
|
|
433
509
|
} catch (error) {
|
|
434
510
|
console.error(`Event processing loop failed for task ${taskId}:`, error);
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
511
|
+
this._handleProcessingError(
|
|
512
|
+
error,
|
|
513
|
+
resultManager,
|
|
514
|
+
firstResultSent,
|
|
515
|
+
taskId,
|
|
516
|
+
options?.firstResultRejector
|
|
517
|
+
);
|
|
439
518
|
} finally {
|
|
440
519
|
this.eventBusManager.cleanupByTaskId(taskId);
|
|
441
520
|
}
|
|
442
521
|
}
|
|
443
|
-
async sendMessage(params) {
|
|
522
|
+
async sendMessage(params, context) {
|
|
444
523
|
const incomingMessage = params.message;
|
|
445
524
|
if (!incomingMessage.messageId) {
|
|
446
525
|
throw A2AError.invalidParams("message.messageId is required.");
|
|
447
526
|
}
|
|
448
527
|
const isBlocking = params.configuration?.blocking !== false;
|
|
449
|
-
const
|
|
450
|
-
const resultManager = new ResultManager(this.taskStore);
|
|
528
|
+
const resultManager = new ResultManager(this.taskStore, context);
|
|
451
529
|
resultManager.setContext(incomingMessage);
|
|
452
|
-
const requestContext = await this._createRequestContext(incomingMessage,
|
|
530
|
+
const requestContext = await this._createRequestContext(incomingMessage, context);
|
|
531
|
+
const taskId = requestContext.taskId;
|
|
453
532
|
const finalMessageForAgent = requestContext.userMessage;
|
|
454
533
|
if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
|
|
455
534
|
await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
|
|
@@ -494,30 +573,32 @@ var DefaultRequestHandler = class {
|
|
|
494
573
|
eventBus.finished();
|
|
495
574
|
});
|
|
496
575
|
if (isBlocking) {
|
|
497
|
-
await this._processEvents(taskId, resultManager, eventQueue);
|
|
576
|
+
await this._processEvents(taskId, resultManager, eventQueue, context);
|
|
498
577
|
const finalResult = resultManager.getFinalResult();
|
|
499
578
|
if (!finalResult) {
|
|
500
|
-
throw A2AError.internalError(
|
|
579
|
+
throw A2AError.internalError(
|
|
580
|
+
"Agent execution finished without a result, and no task context found."
|
|
581
|
+
);
|
|
501
582
|
}
|
|
502
583
|
return finalResult;
|
|
503
584
|
} else {
|
|
504
585
|
return new Promise((resolve, reject) => {
|
|
505
|
-
this._processEvents(taskId, resultManager, eventQueue, {
|
|
586
|
+
this._processEvents(taskId, resultManager, eventQueue, context, {
|
|
506
587
|
firstResultResolver: resolve,
|
|
507
588
|
firstResultRejector: reject
|
|
508
589
|
});
|
|
509
590
|
});
|
|
510
591
|
}
|
|
511
592
|
}
|
|
512
|
-
async *sendMessageStream(params) {
|
|
593
|
+
async *sendMessageStream(params, context) {
|
|
513
594
|
const incomingMessage = params.message;
|
|
514
595
|
if (!incomingMessage.messageId) {
|
|
515
596
|
throw A2AError.invalidParams("message.messageId is required for streaming.");
|
|
516
597
|
}
|
|
517
|
-
const
|
|
518
|
-
const resultManager = new ResultManager(this.taskStore);
|
|
598
|
+
const resultManager = new ResultManager(this.taskStore, context);
|
|
519
599
|
resultManager.setContext(incomingMessage);
|
|
520
|
-
const requestContext = await this._createRequestContext(incomingMessage,
|
|
600
|
+
const requestContext = await this._createRequestContext(incomingMessage, context);
|
|
601
|
+
const taskId = requestContext.taskId;
|
|
521
602
|
const finalMessageForAgent = requestContext.userMessage;
|
|
522
603
|
const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
|
|
523
604
|
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
@@ -525,7 +606,10 @@ var DefaultRequestHandler = class {
|
|
|
525
606
|
await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
|
|
526
607
|
}
|
|
527
608
|
this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
|
|
528
|
-
console.error(
|
|
609
|
+
console.error(
|
|
610
|
+
`Agent execution failed for stream message ${finalMessageForAgent.messageId}:`,
|
|
611
|
+
err
|
|
612
|
+
);
|
|
529
613
|
const errorTaskStatus = {
|
|
530
614
|
kind: "status-update",
|
|
531
615
|
taskId: requestContext.task?.id || uuidv4(),
|
|
@@ -551,15 +635,15 @@ var DefaultRequestHandler = class {
|
|
|
551
635
|
try {
|
|
552
636
|
for await (const event of eventQueue.events()) {
|
|
553
637
|
await resultManager.processEvent(event);
|
|
554
|
-
await this._sendPushNotificationIfNeeded(event);
|
|
638
|
+
await this._sendPushNotificationIfNeeded(event, context);
|
|
555
639
|
yield event;
|
|
556
640
|
}
|
|
557
641
|
} finally {
|
|
558
642
|
this.eventBusManager.cleanupByTaskId(taskId);
|
|
559
643
|
}
|
|
560
644
|
}
|
|
561
|
-
async getTask(params) {
|
|
562
|
-
const task = await this.taskStore.load(params.id);
|
|
645
|
+
async getTask(params, context) {
|
|
646
|
+
const task = await this.taskStore.load(params.id, context);
|
|
563
647
|
if (!task) {
|
|
564
648
|
throw A2AError.taskNotFound(params.id);
|
|
565
649
|
}
|
|
@@ -572,8 +656,8 @@ var DefaultRequestHandler = class {
|
|
|
572
656
|
}
|
|
573
657
|
return task;
|
|
574
658
|
}
|
|
575
|
-
async cancelTask(params) {
|
|
576
|
-
const task = await this.taskStore.load(params.id);
|
|
659
|
+
async cancelTask(params, context) {
|
|
660
|
+
const task = await this.taskStore.load(params.id, context);
|
|
577
661
|
if (!task) {
|
|
578
662
|
throw A2AError.taskNotFound(params.id);
|
|
579
663
|
}
|
|
@@ -583,7 +667,14 @@ var DefaultRequestHandler = class {
|
|
|
583
667
|
}
|
|
584
668
|
const eventBus = this.eventBusManager.getByTaskId(params.id);
|
|
585
669
|
if (eventBus) {
|
|
670
|
+
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
586
671
|
await this.agentExecutor.cancelTask(params.id, eventBus);
|
|
672
|
+
await this._processEvents(
|
|
673
|
+
params.id,
|
|
674
|
+
new ResultManager(this.taskStore, context),
|
|
675
|
+
eventQueue,
|
|
676
|
+
context
|
|
677
|
+
);
|
|
587
678
|
} else {
|
|
588
679
|
task.status = {
|
|
589
680
|
state: "canceled",
|
|
@@ -599,16 +690,22 @@ var DefaultRequestHandler = class {
|
|
|
599
690
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
600
691
|
};
|
|
601
692
|
task.history = [...task.history || [], task.status.message];
|
|
602
|
-
await this.taskStore.save(task);
|
|
693
|
+
await this.taskStore.save(task, context);
|
|
694
|
+
}
|
|
695
|
+
const latestTask = await this.taskStore.load(params.id, context);
|
|
696
|
+
if (!latestTask) {
|
|
697
|
+
throw A2AError.internalError(`Task ${params.id} not found after cancellation.`);
|
|
698
|
+
}
|
|
699
|
+
if (latestTask.status.state != "canceled") {
|
|
700
|
+
throw A2AError.taskNotCancelable(params.id);
|
|
603
701
|
}
|
|
604
|
-
const latestTask = await this.taskStore.load(params.id);
|
|
605
702
|
return latestTask;
|
|
606
703
|
}
|
|
607
|
-
async setTaskPushNotificationConfig(params) {
|
|
704
|
+
async setTaskPushNotificationConfig(params, context) {
|
|
608
705
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
609
706
|
throw A2AError.pushNotificationNotSupported();
|
|
610
707
|
}
|
|
611
|
-
const task = await this.taskStore.load(params.taskId);
|
|
708
|
+
const task = await this.taskStore.load(params.taskId, context);
|
|
612
709
|
if (!task) {
|
|
613
710
|
throw A2AError.taskNotFound(params.taskId);
|
|
614
711
|
}
|
|
@@ -619,11 +716,11 @@ var DefaultRequestHandler = class {
|
|
|
619
716
|
await this.pushNotificationStore?.save(taskId, pushNotificationConfig);
|
|
620
717
|
return params;
|
|
621
718
|
}
|
|
622
|
-
async getTaskPushNotificationConfig(params) {
|
|
719
|
+
async getTaskPushNotificationConfig(params, context) {
|
|
623
720
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
624
721
|
throw A2AError.pushNotificationNotSupported();
|
|
625
722
|
}
|
|
626
|
-
const task = await this.taskStore.load(params.id);
|
|
723
|
+
const task = await this.taskStore.load(params.id, context);
|
|
627
724
|
if (!task) {
|
|
628
725
|
throw A2AError.taskNotFound(params.id);
|
|
629
726
|
}
|
|
@@ -639,15 +736,17 @@ var DefaultRequestHandler = class {
|
|
|
639
736
|
}
|
|
640
737
|
const config = configs.find((c) => c.id === configId);
|
|
641
738
|
if (!config) {
|
|
642
|
-
throw A2AError.internalError(
|
|
739
|
+
throw A2AError.internalError(
|
|
740
|
+
`Push notification config with id '${configId}' not found for task ${params.id}.`
|
|
741
|
+
);
|
|
643
742
|
}
|
|
644
743
|
return { taskId: params.id, pushNotificationConfig: config };
|
|
645
744
|
}
|
|
646
|
-
async listTaskPushNotificationConfigs(params) {
|
|
745
|
+
async listTaskPushNotificationConfigs(params, context) {
|
|
647
746
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
648
747
|
throw A2AError.pushNotificationNotSupported();
|
|
649
748
|
}
|
|
650
|
-
const task = await this.taskStore.load(params.id);
|
|
749
|
+
const task = await this.taskStore.load(params.id, context);
|
|
651
750
|
if (!task) {
|
|
652
751
|
throw A2AError.taskNotFound(params.id);
|
|
653
752
|
}
|
|
@@ -657,22 +756,22 @@ var DefaultRequestHandler = class {
|
|
|
657
756
|
pushNotificationConfig: config
|
|
658
757
|
}));
|
|
659
758
|
}
|
|
660
|
-
async deleteTaskPushNotificationConfig(params) {
|
|
759
|
+
async deleteTaskPushNotificationConfig(params, context) {
|
|
661
760
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
662
761
|
throw A2AError.pushNotificationNotSupported();
|
|
663
762
|
}
|
|
664
|
-
const task = await this.taskStore.load(params.id);
|
|
763
|
+
const task = await this.taskStore.load(params.id, context);
|
|
665
764
|
if (!task) {
|
|
666
765
|
throw A2AError.taskNotFound(params.id);
|
|
667
766
|
}
|
|
668
767
|
const { id: taskId, pushNotificationConfigId } = params;
|
|
669
768
|
await this.pushNotificationStore?.delete(taskId, pushNotificationConfigId);
|
|
670
769
|
}
|
|
671
|
-
async *resubscribe(params) {
|
|
770
|
+
async *resubscribe(params, context) {
|
|
672
771
|
if (!this.agentCard.capabilities.streaming) {
|
|
673
772
|
throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
|
|
674
773
|
}
|
|
675
|
-
const task = await this.taskStore.load(params.id);
|
|
774
|
+
const task = await this.taskStore.load(params.id, context);
|
|
676
775
|
if (!task) {
|
|
677
776
|
throw A2AError.taskNotFound(params.id);
|
|
678
777
|
}
|
|
@@ -701,7 +800,7 @@ var DefaultRequestHandler = class {
|
|
|
701
800
|
eventQueue.stop();
|
|
702
801
|
}
|
|
703
802
|
}
|
|
704
|
-
async _sendPushNotificationIfNeeded(event) {
|
|
803
|
+
async _sendPushNotificationIfNeeded(event, context) {
|
|
705
804
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
706
805
|
return;
|
|
707
806
|
}
|
|
@@ -716,13 +815,53 @@ var DefaultRequestHandler = class {
|
|
|
716
815
|
console.error(`Task ID not found for event ${event.kind}.`);
|
|
717
816
|
return;
|
|
718
817
|
}
|
|
719
|
-
const task = await this.taskStore.load(taskId);
|
|
818
|
+
const task = await this.taskStore.load(taskId, context);
|
|
720
819
|
if (!task) {
|
|
721
820
|
console.error(`Task ${taskId} not found.`);
|
|
722
821
|
return;
|
|
723
822
|
}
|
|
724
823
|
this.pushNotificationSender?.send(task);
|
|
725
824
|
}
|
|
825
|
+
async _handleProcessingError(error, resultManager, firstResultSent, taskId, firstResultRejector) {
|
|
826
|
+
if (firstResultRejector && !firstResultSent) {
|
|
827
|
+
firstResultRejector(error);
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
if (!firstResultRejector) {
|
|
831
|
+
throw error;
|
|
832
|
+
}
|
|
833
|
+
const currentTask = resultManager.getCurrentTask();
|
|
834
|
+
const errorMessage = error instanceof Error && error.message || "Unknown error";
|
|
835
|
+
if (currentTask) {
|
|
836
|
+
const statusUpdateFailed = {
|
|
837
|
+
taskId: currentTask.id,
|
|
838
|
+
contextId: currentTask.contextId,
|
|
839
|
+
status: {
|
|
840
|
+
state: "failed",
|
|
841
|
+
message: {
|
|
842
|
+
kind: "message",
|
|
843
|
+
role: "agent",
|
|
844
|
+
messageId: uuidv4(),
|
|
845
|
+
parts: [{ kind: "text", text: `Event processing loop failed: ${errorMessage}` }],
|
|
846
|
+
taskId: currentTask.id,
|
|
847
|
+
contextId: currentTask.contextId
|
|
848
|
+
},
|
|
849
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
850
|
+
},
|
|
851
|
+
kind: "status-update",
|
|
852
|
+
final: true
|
|
853
|
+
};
|
|
854
|
+
try {
|
|
855
|
+
await resultManager.processEvent(statusUpdateFailed);
|
|
856
|
+
} catch (error2) {
|
|
857
|
+
console.error(
|
|
858
|
+
`Event processing loop failed for task ${taskId}: ${error2 instanceof Error && error2.message || "Unknown error"}`
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
} else {
|
|
862
|
+
console.error(`Event processing loop failed for task ${taskId}: ${errorMessage}`);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
726
865
|
};
|
|
727
866
|
|
|
728
867
|
// src/server/store.ts
|
|
@@ -747,5 +886,7 @@ export {
|
|
|
747
886
|
InMemoryTaskStore,
|
|
748
887
|
JsonRpcTransportHandler,
|
|
749
888
|
RequestContext,
|
|
750
|
-
ResultManager
|
|
889
|
+
ResultManager,
|
|
890
|
+
ServerCallContext,
|
|
891
|
+
UnauthenticatedUser
|
|
751
892
|
};
|