@a2a-js/sdk 0.3.2 → 0.3.4
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 +506 -314
- package/dist/client/index.cjs +171 -71
- package/dist/client/index.d.cts +67 -34
- package/dist/client/index.d.ts +67 -34
- package/dist/client/index.js +171 -71
- package/dist/server/index.cjs +136 -19
- package/dist/server/index.d.cts +40 -4
- package/dist/server/index.d.ts +40 -4
- package/dist/server/index.js +134 -19
- package/package.json +4 -4
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { B as Message, aw as Task, aO as TaskStatusUpdateEvent, aQ as TaskArtifactUpdateEvent, ac as AgentCard, w as MessageSendParams, V as TaskQueryParams, X as TaskIdParams, Z as TaskPushNotificationConfig, a1 as GetTaskPushNotificationConfigParams, a5 as ListTaskPushNotificationConfigParams, a7 as DeleteTaskPushNotificationConfigParams, i as JSONRPCResponse, au as JSONRPCError } from '../types-DNKcmF0f.js';
|
|
2
|
+
import { B as Message, aw as Task, aO as TaskStatusUpdateEvent, aQ as TaskArtifactUpdateEvent, y as PushNotificationConfig, ac as AgentCard, w as MessageSendParams, V as TaskQueryParams, X as TaskIdParams, Z as TaskPushNotificationConfig, a1 as GetTaskPushNotificationConfigParams, a5 as ListTaskPushNotificationConfigParams, a7 as DeleteTaskPushNotificationConfigParams, i as JSONRPCResponse, au as JSONRPCError } from '../types-DNKcmF0f.js';
|
|
3
3
|
import { A as A2ARequestHandler } from '../a2a_request_handler-B5t-IxgA.js';
|
|
4
4
|
|
|
5
5
|
type AgentExecutionEvent = Message | Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent;
|
|
@@ -119,14 +119,31 @@ declare class InMemoryTaskStore implements TaskStore {
|
|
|
119
119
|
save(task: Task): Promise<void>;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
interface PushNotificationStore {
|
|
123
|
+
save(taskId: string, pushNotificationConfig: PushNotificationConfig): Promise<void>;
|
|
124
|
+
load(taskId: string): Promise<PushNotificationConfig[]>;
|
|
125
|
+
delete(taskId: string, configId?: string): Promise<void>;
|
|
126
|
+
}
|
|
127
|
+
declare class InMemoryPushNotificationStore implements PushNotificationStore {
|
|
128
|
+
private store;
|
|
129
|
+
save(taskId: string, pushNotificationConfig: PushNotificationConfig): Promise<void>;
|
|
130
|
+
load(taskId: string): Promise<PushNotificationConfig[]>;
|
|
131
|
+
delete(taskId: string, configId?: string): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
interface PushNotificationSender {
|
|
135
|
+
send(task: Task): Promise<void>;
|
|
136
|
+
}
|
|
137
|
+
|
|
122
138
|
declare class DefaultRequestHandler implements A2ARequestHandler {
|
|
123
139
|
private readonly agentCard;
|
|
124
140
|
private readonly extendedAgentCard?;
|
|
125
141
|
private readonly taskStore;
|
|
126
142
|
private readonly agentExecutor;
|
|
127
143
|
private readonly eventBusManager;
|
|
128
|
-
private readonly
|
|
129
|
-
|
|
144
|
+
private readonly pushNotificationStore?;
|
|
145
|
+
private readonly pushNotificationSender?;
|
|
146
|
+
constructor(agentCard: AgentCard, taskStore: TaskStore, agentExecutor: AgentExecutor, eventBusManager?: ExecutionEventBusManager, pushNotificationStore?: PushNotificationStore, pushNotificationSender?: PushNotificationSender, extendedAgentCard?: AgentCard);
|
|
130
147
|
getAgentCard(): Promise<AgentCard>;
|
|
131
148
|
getAuthenticatedExtendedAgentCard(): Promise<AgentCard>;
|
|
132
149
|
private _createRequestContext;
|
|
@@ -140,6 +157,7 @@ declare class DefaultRequestHandler implements A2ARequestHandler {
|
|
|
140
157
|
listTaskPushNotificationConfigs(params: ListTaskPushNotificationConfigParams): Promise<TaskPushNotificationConfig[]>;
|
|
141
158
|
deleteTaskPushNotificationConfig(params: DeleteTaskPushNotificationConfigParams): Promise<void>;
|
|
142
159
|
resubscribe(params: TaskIdParams): AsyncGenerator<Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent, void, undefined>;
|
|
160
|
+
private _sendPushNotificationIfNeeded;
|
|
143
161
|
}
|
|
144
162
|
|
|
145
163
|
declare class ResultManager {
|
|
@@ -207,4 +225,22 @@ declare class A2AError extends Error {
|
|
|
207
225
|
static authenticatedExtendedCardNotConfigured(): A2AError;
|
|
208
226
|
}
|
|
209
227
|
|
|
210
|
-
|
|
228
|
+
interface DefaultPushNotificationSenderOptions {
|
|
229
|
+
/**
|
|
230
|
+
* Timeout in milliseconds for the abort controller. Defaults to 5000ms.
|
|
231
|
+
*/
|
|
232
|
+
timeout?: number;
|
|
233
|
+
/**
|
|
234
|
+
* Custom header name for the token. Defaults to 'X-A2A-Notification-Token'.
|
|
235
|
+
*/
|
|
236
|
+
tokenHeaderName?: string;
|
|
237
|
+
}
|
|
238
|
+
declare class DefaultPushNotificationSender implements PushNotificationSender {
|
|
239
|
+
private readonly pushNotificationStore;
|
|
240
|
+
private readonly options;
|
|
241
|
+
constructor(pushNotificationStore: PushNotificationStore, options?: DefaultPushNotificationSenderOptions);
|
|
242
|
+
send(task: Task): Promise<void>;
|
|
243
|
+
private _dispatchNotification;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export { A2AError, A2ARequestHandler, type AgentExecutionEvent, type AgentExecutor, DefaultExecutionEventBus, DefaultExecutionEventBusManager, DefaultPushNotificationSender, type DefaultPushNotificationSenderOptions, DefaultRequestHandler, type ExecutionEventBus, type ExecutionEventBusManager, ExecutionEventQueue, InMemoryPushNotificationStore, InMemoryTaskStore, JsonRpcTransportHandler, type PushNotificationSender, type PushNotificationStore, RequestContext, ResultManager, type TaskStore };
|
package/dist/server/index.js
CHANGED
|
@@ -257,6 +257,97 @@ var ResultManager = class {
|
|
|
257
257
|
}
|
|
258
258
|
};
|
|
259
259
|
|
|
260
|
+
// src/server/push_notification/push_notification_store.ts
|
|
261
|
+
var InMemoryPushNotificationStore = class {
|
|
262
|
+
store = /* @__PURE__ */ new Map();
|
|
263
|
+
async save(taskId, pushNotificationConfig) {
|
|
264
|
+
const configs = this.store.get(taskId) || [];
|
|
265
|
+
if (!pushNotificationConfig.id) {
|
|
266
|
+
pushNotificationConfig.id = taskId;
|
|
267
|
+
}
|
|
268
|
+
const existingIndex = configs.findIndex((config) => config.id === pushNotificationConfig.id);
|
|
269
|
+
if (existingIndex !== -1) {
|
|
270
|
+
configs.splice(existingIndex, 1);
|
|
271
|
+
}
|
|
272
|
+
configs.push(pushNotificationConfig);
|
|
273
|
+
this.store.set(taskId, configs);
|
|
274
|
+
}
|
|
275
|
+
async load(taskId) {
|
|
276
|
+
const configs = this.store.get(taskId);
|
|
277
|
+
return configs || [];
|
|
278
|
+
}
|
|
279
|
+
async delete(taskId, configId) {
|
|
280
|
+
if (configId === void 0) {
|
|
281
|
+
configId = taskId;
|
|
282
|
+
}
|
|
283
|
+
const configs = this.store.get(taskId);
|
|
284
|
+
if (!configs) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const configIndex = configs.findIndex((config) => config.id === configId);
|
|
288
|
+
if (configIndex !== -1) {
|
|
289
|
+
configs.splice(configIndex, 1);
|
|
290
|
+
}
|
|
291
|
+
if (configs.length === 0) {
|
|
292
|
+
this.store.delete(taskId);
|
|
293
|
+
} else {
|
|
294
|
+
this.store.set(taskId, configs);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// src/server/push_notification/default_push_notification_sender.ts
|
|
300
|
+
var DefaultPushNotificationSender = class {
|
|
301
|
+
pushNotificationStore;
|
|
302
|
+
options;
|
|
303
|
+
constructor(pushNotificationStore, options = {}) {
|
|
304
|
+
this.pushNotificationStore = pushNotificationStore;
|
|
305
|
+
this.options = {
|
|
306
|
+
timeout: 5e3,
|
|
307
|
+
tokenHeaderName: "X-A2A-Notification-Token",
|
|
308
|
+
...options
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
async send(task) {
|
|
312
|
+
const pushConfigs = await this.pushNotificationStore.load(task.id);
|
|
313
|
+
if (!pushConfigs || pushConfigs.length === 0) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
pushConfigs.forEach((pushConfig) => {
|
|
317
|
+
this._dispatchNotification(task, pushConfig).catch((error) => {
|
|
318
|
+
console.error(`Error sending push notification for task_id=${task.id} to URL: ${pushConfig.url}. Error:`, error);
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
async _dispatchNotification(task, pushConfig) {
|
|
323
|
+
const url = pushConfig.url;
|
|
324
|
+
const controller = new AbortController();
|
|
325
|
+
const timeoutId = setTimeout(() => controller.abort(), this.options.timeout);
|
|
326
|
+
try {
|
|
327
|
+
const headers = {
|
|
328
|
+
"Content-Type": "application/json"
|
|
329
|
+
};
|
|
330
|
+
if (pushConfig.token) {
|
|
331
|
+
headers[this.options.tokenHeaderName] = pushConfig.token;
|
|
332
|
+
}
|
|
333
|
+
const response = await fetch(url, {
|
|
334
|
+
method: "POST",
|
|
335
|
+
headers,
|
|
336
|
+
body: JSON.stringify(task),
|
|
337
|
+
signal: controller.signal
|
|
338
|
+
});
|
|
339
|
+
if (!response.ok) {
|
|
340
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
341
|
+
}
|
|
342
|
+
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
|
+
} finally {
|
|
346
|
+
clearTimeout(timeoutId);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
260
351
|
// src/server/request_handler/default_request_handler.ts
|
|
261
352
|
var terminalStates = ["completed", "failed", "canceled", "rejected"];
|
|
262
353
|
var DefaultRequestHandler = class {
|
|
@@ -265,14 +356,18 @@ var DefaultRequestHandler = class {
|
|
|
265
356
|
taskStore;
|
|
266
357
|
agentExecutor;
|
|
267
358
|
eventBusManager;
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), extendedAgentCard) {
|
|
359
|
+
pushNotificationStore;
|
|
360
|
+
pushNotificationSender;
|
|
361
|
+
constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), pushNotificationStore, pushNotificationSender, extendedAgentCard) {
|
|
271
362
|
this.agentCard = agentCard;
|
|
272
363
|
this.taskStore = taskStore;
|
|
273
364
|
this.agentExecutor = agentExecutor;
|
|
274
365
|
this.eventBusManager = eventBusManager;
|
|
275
366
|
this.extendedAgentCard = extendedAgentCard;
|
|
367
|
+
if (agentCard.capabilities.pushNotifications) {
|
|
368
|
+
this.pushNotificationStore = pushNotificationStore || new InMemoryPushNotificationStore();
|
|
369
|
+
this.pushNotificationSender = pushNotificationSender || new DefaultPushNotificationSender(this.pushNotificationStore);
|
|
370
|
+
}
|
|
276
371
|
}
|
|
277
372
|
async getAgentCard() {
|
|
278
373
|
return this.agentCard;
|
|
@@ -324,6 +419,7 @@ var DefaultRequestHandler = class {
|
|
|
324
419
|
try {
|
|
325
420
|
for await (const event of eventQueue.events()) {
|
|
326
421
|
await resultManager.processEvent(event);
|
|
422
|
+
await this._sendPushNotificationIfNeeded(event);
|
|
327
423
|
if (options?.firstResultResolver && !firstResultSent) {
|
|
328
424
|
if (event.kind === "message" || event.kind === "task") {
|
|
329
425
|
options.firstResultResolver(event);
|
|
@@ -355,6 +451,9 @@ var DefaultRequestHandler = class {
|
|
|
355
451
|
resultManager.setContext(incomingMessage);
|
|
356
452
|
const requestContext = await this._createRequestContext(incomingMessage, taskId, false);
|
|
357
453
|
const finalMessageForAgent = requestContext.userMessage;
|
|
454
|
+
if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
|
|
455
|
+
await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
|
|
456
|
+
}
|
|
358
457
|
const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
|
|
359
458
|
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
360
459
|
this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
|
|
@@ -422,6 +521,9 @@ var DefaultRequestHandler = class {
|
|
|
422
521
|
const finalMessageForAgent = requestContext.userMessage;
|
|
423
522
|
const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
|
|
424
523
|
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
524
|
+
if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
|
|
525
|
+
await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
|
|
526
|
+
}
|
|
425
527
|
this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
|
|
426
528
|
console.error(`Agent execution failed for stream message ${finalMessageForAgent.messageId}:`, err);
|
|
427
529
|
const errorTaskStatus = {
|
|
@@ -449,6 +551,7 @@ var DefaultRequestHandler = class {
|
|
|
449
551
|
try {
|
|
450
552
|
for await (const event of eventQueue.events()) {
|
|
451
553
|
await resultManager.processEvent(event);
|
|
554
|
+
await this._sendPushNotificationIfNeeded(event);
|
|
452
555
|
yield event;
|
|
453
556
|
}
|
|
454
557
|
} finally {
|
|
@@ -513,10 +616,7 @@ var DefaultRequestHandler = class {
|
|
|
513
616
|
if (!pushNotificationConfig.id) {
|
|
514
617
|
pushNotificationConfig.id = taskId;
|
|
515
618
|
}
|
|
516
|
-
|
|
517
|
-
const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfig.id);
|
|
518
|
-
updatedConfigs.push(pushNotificationConfig);
|
|
519
|
-
this.pushNotificationConfigs.set(taskId, updatedConfigs);
|
|
619
|
+
await this.pushNotificationStore?.save(taskId, pushNotificationConfig);
|
|
520
620
|
return params;
|
|
521
621
|
}
|
|
522
622
|
async getTaskPushNotificationConfig(params) {
|
|
@@ -527,7 +627,7 @@ var DefaultRequestHandler = class {
|
|
|
527
627
|
if (!task) {
|
|
528
628
|
throw A2AError.taskNotFound(params.id);
|
|
529
629
|
}
|
|
530
|
-
const configs = this.
|
|
630
|
+
const configs = await this.pushNotificationStore?.load(params.id) || [];
|
|
531
631
|
if (configs.length === 0) {
|
|
532
632
|
throw A2AError.internalError(`Push notification config not found for task ${params.id}.`);
|
|
533
633
|
}
|
|
@@ -551,7 +651,7 @@ var DefaultRequestHandler = class {
|
|
|
551
651
|
if (!task) {
|
|
552
652
|
throw A2AError.taskNotFound(params.id);
|
|
553
653
|
}
|
|
554
|
-
const configs = this.
|
|
654
|
+
const configs = await this.pushNotificationStore?.load(params.id) || [];
|
|
555
655
|
return configs.map((config) => ({
|
|
556
656
|
taskId: params.id,
|
|
557
657
|
pushNotificationConfig: config
|
|
@@ -566,16 +666,7 @@ var DefaultRequestHandler = class {
|
|
|
566
666
|
throw A2AError.taskNotFound(params.id);
|
|
567
667
|
}
|
|
568
668
|
const { id: taskId, pushNotificationConfigId } = params;
|
|
569
|
-
|
|
570
|
-
if (!configs) {
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
const updatedConfigs = configs.filter((c) => c.id !== pushNotificationConfigId);
|
|
574
|
-
if (updatedConfigs.length === 0) {
|
|
575
|
-
this.pushNotificationConfigs.delete(taskId);
|
|
576
|
-
} else if (updatedConfigs.length < configs.length) {
|
|
577
|
-
this.pushNotificationConfigs.set(taskId, updatedConfigs);
|
|
578
|
-
}
|
|
669
|
+
await this.pushNotificationStore?.delete(taskId, pushNotificationConfigId);
|
|
579
670
|
}
|
|
580
671
|
async *resubscribe(params) {
|
|
581
672
|
if (!this.agentCard.capabilities.streaming) {
|
|
@@ -610,6 +701,28 @@ var DefaultRequestHandler = class {
|
|
|
610
701
|
eventQueue.stop();
|
|
611
702
|
}
|
|
612
703
|
}
|
|
704
|
+
async _sendPushNotificationIfNeeded(event) {
|
|
705
|
+
if (!this.agentCard.capabilities.pushNotifications) {
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
let taskId = "";
|
|
709
|
+
if (event.kind == "task") {
|
|
710
|
+
const task2 = event;
|
|
711
|
+
taskId = task2.id;
|
|
712
|
+
} else {
|
|
713
|
+
taskId = event.taskId;
|
|
714
|
+
}
|
|
715
|
+
if (!taskId) {
|
|
716
|
+
console.error(`Task ID not found for event ${event.kind}.`);
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
const task = await this.taskStore.load(taskId);
|
|
720
|
+
if (!task) {
|
|
721
|
+
console.error(`Task ${taskId} not found.`);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
this.pushNotificationSender?.send(task);
|
|
725
|
+
}
|
|
613
726
|
};
|
|
614
727
|
|
|
615
728
|
// src/server/store.ts
|
|
@@ -627,8 +740,10 @@ export {
|
|
|
627
740
|
A2AError,
|
|
628
741
|
DefaultExecutionEventBus,
|
|
629
742
|
DefaultExecutionEventBusManager,
|
|
743
|
+
DefaultPushNotificationSender,
|
|
630
744
|
DefaultRequestHandler,
|
|
631
745
|
ExecutionEventQueue,
|
|
746
|
+
InMemoryPushNotificationStore,
|
|
632
747
|
InMemoryTaskStore,
|
|
633
748
|
JsonRpcTransportHandler,
|
|
634
749
|
RequestContext,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a2a-js/sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Server & Client SDK for Agent2Agent protocol",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
"@genkit-ai/googleai": "^1.8.0",
|
|
44
44
|
"@genkit-ai/vertexai": "^1.8.0",
|
|
45
45
|
"@types/chai": "^5.2.2",
|
|
46
|
-
"@types/express": "^
|
|
46
|
+
"@types/express": "^5.0.3",
|
|
47
47
|
"@types/mocha": "^10.0.10",
|
|
48
48
|
"@types/node": "^22.13.14",
|
|
49
49
|
"@types/sinon": "^17.0.4",
|
|
50
50
|
"c8": "^10.1.3",
|
|
51
51
|
"chai": "^5.2.0",
|
|
52
|
-
"express": "^
|
|
52
|
+
"express": "^5.1.0",
|
|
53
53
|
"genkit": "^1.8.0",
|
|
54
54
|
"gts": "^6.0.2",
|
|
55
55
|
"json-schema-to-typescript": "^15.0.4",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"uuid": "^11.1.0"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
|
-
"express": "^4.21.2"
|
|
76
|
+
"express": "^4.21.2 || ^5.1.0"
|
|
77
77
|
},
|
|
78
78
|
"peerDependenciesMeta": {
|
|
79
79
|
"express": {
|