@mastra/server 1.32.1 → 1.33.0-alpha.0
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/CHANGELOG.md +25 -0
- package/dist/{chunk-ALUAG74N.js → chunk-3KIFZFY7.js} +575 -23
- package/dist/chunk-3KIFZFY7.js.map +1 -0
- package/dist/{chunk-3TFM333T.cjs → chunk-CJ2LC5EE.cjs} +578 -22
- package/dist/chunk-CJ2LC5EE.cjs.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/server/a2a/push-notification-sender.d.ts +25 -0
- package/dist/server/a2a/push-notification-sender.d.ts.map +1 -0
- package/dist/server/a2a/push-notification-store.d.ts +22 -0
- package/dist/server/a2a/push-notification-store.d.ts.map +1 -0
- package/dist/server/handlers/a2a.cjs +26 -10
- package/dist/server/handlers/a2a.d.ts +44 -6
- package/dist/server/handlers/a2a.d.ts.map +1 -1
- package/dist/server/handlers/a2a.js +1 -1
- package/dist/server/handlers.cjs +2 -2
- package/dist/server/handlers.js +1 -1
- package/dist/server/server-adapter/index.cjs +2 -2
- package/dist/server/server-adapter/index.js +1 -1
- package/package.json +6 -5
- package/dist/chunk-3TFM333T.cjs.map +0 -1
- package/dist/chunk-ALUAG74N.js.map +0 -1
|
@@ -9,6 +9,10 @@ var chunkO7I5CWRX_cjs = require('./chunk-O7I5CWRX.cjs');
|
|
|
9
9
|
var util = require('util');
|
|
10
10
|
var a2a = require('@mastra/core/a2a');
|
|
11
11
|
var v4 = require('zod/v4');
|
|
12
|
+
var promises = require('dns/promises');
|
|
13
|
+
var http = require('http');
|
|
14
|
+
var https = require('https');
|
|
15
|
+
var net = require('net');
|
|
12
16
|
|
|
13
17
|
// src/server/handlers/a2a.ts
|
|
14
18
|
var a2a_exports = {};
|
|
@@ -17,8 +21,12 @@ chunkO7I5CWRX_cjs.__export(a2a_exports, {
|
|
|
17
21
|
GET_AGENT_CARD_ROUTE: () => GET_AGENT_CARD_ROUTE,
|
|
18
22
|
getAgentCardByIdHandler: () => getAgentCardByIdHandler,
|
|
19
23
|
getAgentExecutionHandler: () => getAgentExecutionHandler,
|
|
24
|
+
handleDeleteTaskPushNotificationConfig: () => handleDeleteTaskPushNotificationConfig,
|
|
25
|
+
handleGetTaskPushNotificationConfig: () => handleGetTaskPushNotificationConfig,
|
|
26
|
+
handleListTaskPushNotificationConfig: () => handleListTaskPushNotificationConfig,
|
|
20
27
|
handleMessageSend: () => handleMessageSend,
|
|
21
28
|
handleMessageStream: () => handleMessageStream,
|
|
29
|
+
handleSetTaskPushNotificationConfig: () => handleSetTaskPushNotificationConfig,
|
|
22
30
|
handleTaskCancel: () => handleTaskCancel,
|
|
23
31
|
handleTaskGet: () => handleTaskGet,
|
|
24
32
|
handleTaskResubscribe: () => handleTaskResubscribe
|
|
@@ -79,6 +87,231 @@ function convertToCoreMessagePart(part) {
|
|
|
79
87
|
throw new Error("Data parts are not supported in core messages");
|
|
80
88
|
}
|
|
81
89
|
}
|
|
90
|
+
var DEFAULT_PUSH_NOTIFICATION_TOKEN_HEADER = "X-A2A-Notification-Token";
|
|
91
|
+
function isDisallowedHostname(hostname) {
|
|
92
|
+
const normalized = hostname.toLowerCase();
|
|
93
|
+
return normalized === "localhost" || normalized.endsWith(".localhost") || normalized.endsWith(".local") || normalized.endsWith(".internal") || !normalized.includes(".");
|
|
94
|
+
}
|
|
95
|
+
function isDisallowedIpv4(address) {
|
|
96
|
+
const [first = -1, second = -1] = address.split(".").map(Number);
|
|
97
|
+
return first === 10 || first === 127 || first === 169 && second === 254 || first === 172 && second >= 16 && second <= 31 || first === 192 && second === 168;
|
|
98
|
+
}
|
|
99
|
+
function isDisallowedIpv6(address) {
|
|
100
|
+
const normalized = address.toLowerCase();
|
|
101
|
+
return normalized === "::1" || normalized.startsWith("fe8") || normalized.startsWith("fe9") || normalized.startsWith("fea") || normalized.startsWith("feb") || normalized.startsWith("fc") || normalized.startsWith("fd");
|
|
102
|
+
}
|
|
103
|
+
function isDisallowedIpAddress(address) {
|
|
104
|
+
const version = net.isIP(address);
|
|
105
|
+
if (version === 4) {
|
|
106
|
+
return isDisallowedIpv4(address);
|
|
107
|
+
}
|
|
108
|
+
if (version === 6) {
|
|
109
|
+
return isDisallowedIpv6(address);
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
var DefaultPushNotificationSender = class {
|
|
114
|
+
constructor(pushNotificationStore, options = {}) {
|
|
115
|
+
this.pushNotificationStore = pushNotificationStore;
|
|
116
|
+
this.options = options;
|
|
117
|
+
}
|
|
118
|
+
pushNotificationStore;
|
|
119
|
+
options;
|
|
120
|
+
getStore() {
|
|
121
|
+
return this.pushNotificationStore;
|
|
122
|
+
}
|
|
123
|
+
async resolveValidatedDestination(rawUrl) {
|
|
124
|
+
const url = new URL(rawUrl);
|
|
125
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
126
|
+
throw new Error(`Push notification URL must use http or https: ${url.protocol}`);
|
|
127
|
+
}
|
|
128
|
+
const hostname = url.hostname.toLowerCase();
|
|
129
|
+
if (this.options.allowedHosts && !this.options.allowedHosts.includes(hostname)) {
|
|
130
|
+
throw new Error(`Push notification host is not allowed: ${hostname}`);
|
|
131
|
+
}
|
|
132
|
+
if (isDisallowedHostname(hostname)) {
|
|
133
|
+
throw new Error(`Push notification URL must not target local or internal hosts: ${hostname}`);
|
|
134
|
+
}
|
|
135
|
+
if (isDisallowedIpAddress(hostname)) {
|
|
136
|
+
throw new Error(`Push notification URL must not target local or private IPs: ${hostname}`);
|
|
137
|
+
}
|
|
138
|
+
const resolvedAddresses = net.isIP(hostname) === 0 ? await (this.options.lookup ?? promises.lookup)(hostname, { all: true, verbatim: true }) : [{ address: hostname, family: net.isIP(hostname) }];
|
|
139
|
+
if (resolvedAddresses.some((result) => isDisallowedIpAddress(result.address))) {
|
|
140
|
+
throw new Error(`Push notification URL resolved to a local or private IP: ${hostname}`);
|
|
141
|
+
}
|
|
142
|
+
const requestUrl = new URL(url.toString());
|
|
143
|
+
requestUrl.hostname = resolvedAddresses[0].address;
|
|
144
|
+
return {
|
|
145
|
+
originalUrl: url,
|
|
146
|
+
requestUrl,
|
|
147
|
+
hostHeader: url.host,
|
|
148
|
+
servername: net.isIP(hostname) === 0 ? hostname : void 0
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
async postTaskSnapshot({
|
|
152
|
+
requestUrl,
|
|
153
|
+
hostHeader,
|
|
154
|
+
servername,
|
|
155
|
+
headers,
|
|
156
|
+
body,
|
|
157
|
+
timeout
|
|
158
|
+
}) {
|
|
159
|
+
headers.set("host", hostHeader);
|
|
160
|
+
const signal = typeof AbortSignal.timeout === "function" ? AbortSignal.timeout(timeout) : void 0;
|
|
161
|
+
if (this.options.fetch) {
|
|
162
|
+
return this.options.fetch(requestUrl.toString(), {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers,
|
|
165
|
+
body,
|
|
166
|
+
signal
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
const transport = requestUrl.protocol === "https:" ? https.request : http.request;
|
|
170
|
+
return await new Promise((resolve, reject) => {
|
|
171
|
+
const request = transport(
|
|
172
|
+
{
|
|
173
|
+
protocol: requestUrl.protocol,
|
|
174
|
+
hostname: requestUrl.hostname,
|
|
175
|
+
port: requestUrl.port || void 0,
|
|
176
|
+
path: `${requestUrl.pathname}${requestUrl.search}`,
|
|
177
|
+
method: "POST",
|
|
178
|
+
headers: Object.fromEntries(headers.entries()),
|
|
179
|
+
servername
|
|
180
|
+
},
|
|
181
|
+
(response) => {
|
|
182
|
+
response.resume();
|
|
183
|
+
response.on("end", () => {
|
|
184
|
+
resolve({
|
|
185
|
+
ok: !!response.statusCode && response.statusCode >= 200 && response.statusCode < 300,
|
|
186
|
+
status: response.statusCode ?? 0,
|
|
187
|
+
statusText: response.statusMessage ?? ""
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
request.on("error", reject);
|
|
193
|
+
if (signal) {
|
|
194
|
+
signal.addEventListener(
|
|
195
|
+
"abort",
|
|
196
|
+
() => {
|
|
197
|
+
request.destroy(signal.reason instanceof Error ? signal.reason : new Error("Push notification timed out"));
|
|
198
|
+
},
|
|
199
|
+
{ once: true }
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
request.end(body);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
async sendNotifications({
|
|
206
|
+
agentId,
|
|
207
|
+
task,
|
|
208
|
+
logger
|
|
209
|
+
}) {
|
|
210
|
+
const configs = this.pushNotificationStore.list({
|
|
211
|
+
agentId,
|
|
212
|
+
params: { id: task.id }
|
|
213
|
+
});
|
|
214
|
+
if (configs.length === 0) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
await Promise.allSettled(
|
|
218
|
+
configs.map(async (config) => {
|
|
219
|
+
const headers = new Headers({
|
|
220
|
+
"content-type": "application/json"
|
|
221
|
+
});
|
|
222
|
+
if (config.pushNotificationConfig.token) {
|
|
223
|
+
headers.set(
|
|
224
|
+
this.options.tokenHeaderName ?? DEFAULT_PUSH_NOTIFICATION_TOKEN_HEADER,
|
|
225
|
+
config.pushNotificationConfig.token
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
const auth = config.pushNotificationConfig.authentication;
|
|
229
|
+
if (auth?.credentials) {
|
|
230
|
+
if (auth.schemes.includes("Bearer")) {
|
|
231
|
+
headers.set("authorization", `Bearer ${auth.credentials}`);
|
|
232
|
+
} else if (auth.schemes.includes("Basic")) {
|
|
233
|
+
headers.set("authorization", `Basic ${auth.credentials}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const { requestUrl, hostHeader, servername } = await this.resolveValidatedDestination(
|
|
237
|
+
config.pushNotificationConfig.url
|
|
238
|
+
);
|
|
239
|
+
const response = await this.postTaskSnapshot({
|
|
240
|
+
requestUrl,
|
|
241
|
+
hostHeader,
|
|
242
|
+
servername,
|
|
243
|
+
headers,
|
|
244
|
+
body: JSON.stringify(task),
|
|
245
|
+
timeout: this.options.timeout ?? 5e3
|
|
246
|
+
});
|
|
247
|
+
if (!response.ok) {
|
|
248
|
+
throw new Error(
|
|
249
|
+
`Push notification failed with status ${response.status} ${response.statusText ?? ""}`.trim()
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
).then((results) => {
|
|
254
|
+
for (const result of results) {
|
|
255
|
+
if (result.status === "rejected") {
|
|
256
|
+
logger?.error("Failed to deliver A2A push notification", result.reason);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// src/server/a2a/push-notification-store.ts
|
|
264
|
+
function normalizeConfigId(taskId, configId) {
|
|
265
|
+
return configId || taskId;
|
|
266
|
+
}
|
|
267
|
+
var InMemoryPushNotificationStore = class {
|
|
268
|
+
store = /* @__PURE__ */ new Map();
|
|
269
|
+
getKey(agentId, taskId) {
|
|
270
|
+
return JSON.stringify([agentId, taskId]);
|
|
271
|
+
}
|
|
272
|
+
set({ agentId, config }) {
|
|
273
|
+
const key = this.getKey(agentId, config.taskId);
|
|
274
|
+
const configs = this.store.get(key) ?? /* @__PURE__ */ new Map();
|
|
275
|
+
const normalizedConfig = {
|
|
276
|
+
taskId: config.taskId,
|
|
277
|
+
pushNotificationConfig: {
|
|
278
|
+
...config.pushNotificationConfig,
|
|
279
|
+
id: normalizeConfigId(config.taskId, config.pushNotificationConfig.id)
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
configs.set(normalizedConfig.pushNotificationConfig.id, structuredClone(normalizedConfig));
|
|
283
|
+
this.store.set(key, configs);
|
|
284
|
+
return structuredClone(normalizedConfig);
|
|
285
|
+
}
|
|
286
|
+
get({
|
|
287
|
+
agentId,
|
|
288
|
+
params
|
|
289
|
+
}) {
|
|
290
|
+
const key = this.getKey(agentId, params.id);
|
|
291
|
+
const configId = normalizeConfigId(params.id, params.pushNotificationConfigId);
|
|
292
|
+
const config = this.store.get(key)?.get(configId);
|
|
293
|
+
return config ? structuredClone(config) : null;
|
|
294
|
+
}
|
|
295
|
+
list({
|
|
296
|
+
agentId,
|
|
297
|
+
params
|
|
298
|
+
}) {
|
|
299
|
+
const key = this.getKey(agentId, params.id);
|
|
300
|
+
return Array.from(this.store.get(key)?.values() ?? []).map((config) => structuredClone(config));
|
|
301
|
+
}
|
|
302
|
+
delete({ agentId, params }) {
|
|
303
|
+
const key = this.getKey(agentId, params.id);
|
|
304
|
+
const configs = this.store.get(key);
|
|
305
|
+
if (!configs) {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
const deleted = configs.delete(params.pushNotificationConfigId);
|
|
309
|
+
if (configs.size === 0) {
|
|
310
|
+
this.store.delete(key);
|
|
311
|
+
}
|
|
312
|
+
return deleted;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
82
315
|
|
|
83
316
|
// src/server/a2a/tasks.ts
|
|
84
317
|
function isTaskStatusUpdate(update) {
|
|
@@ -206,9 +439,27 @@ var messageSendParamsSchema = v4.z.object({
|
|
|
206
439
|
referenceTaskIds: v4.z.array(v4.z.string()).optional(),
|
|
207
440
|
extensions: v4.z.array(v4.z.string()).optional(),
|
|
208
441
|
metadata: v4.z.record(v4.z.string(), v4.z.any()).optional()
|
|
209
|
-
})
|
|
442
|
+
}),
|
|
443
|
+
configuration: v4.z.object({
|
|
444
|
+
acceptedOutputModes: v4.z.array(v4.z.string()).optional(),
|
|
445
|
+
blocking: v4.z.boolean().optional(),
|
|
446
|
+
historyLength: v4.z.number().optional(),
|
|
447
|
+
pushNotificationConfig: v4.z.object({
|
|
448
|
+
url: v4.z.string(),
|
|
449
|
+
id: v4.z.string().optional(),
|
|
450
|
+
token: v4.z.string().optional(),
|
|
451
|
+
authentication: v4.z.object({
|
|
452
|
+
schemes: v4.z.array(v4.z.string()),
|
|
453
|
+
credentials: v4.z.string().optional()
|
|
454
|
+
}).optional()
|
|
455
|
+
}).optional()
|
|
456
|
+
}).optional()
|
|
210
457
|
});
|
|
211
|
-
|
|
458
|
+
var defaultPushNotificationStore = new InMemoryPushNotificationStore();
|
|
459
|
+
var defaultPushNotificationSender = new DefaultPushNotificationSender(defaultPushNotificationStore);
|
|
460
|
+
function createAgentCardDefaults({
|
|
461
|
+
pushNotifications = false
|
|
462
|
+
} = {}) {
|
|
212
463
|
return {
|
|
213
464
|
protocolVersion: "0.3.0",
|
|
214
465
|
additionalInterfaces: [],
|
|
@@ -217,7 +468,7 @@ function createAgentCardDefaults() {
|
|
|
217
468
|
securitySchemes: {},
|
|
218
469
|
capabilities: {
|
|
219
470
|
streaming: true,
|
|
220
|
-
pushNotifications
|
|
471
|
+
pushNotifications,
|
|
221
472
|
stateTransitionHistory: false,
|
|
222
473
|
extensions: []
|
|
223
474
|
},
|
|
@@ -234,6 +485,7 @@ async function getAgentCardByIdHandler({
|
|
|
234
485
|
url: "https://mastra.ai"
|
|
235
486
|
},
|
|
236
487
|
version = "1.0",
|
|
488
|
+
pushNotifications = false,
|
|
237
489
|
requestContext
|
|
238
490
|
}) {
|
|
239
491
|
const agent = await chunkWZKXMP2U_cjs.getAgentFromSystem({ mastra, agentId });
|
|
@@ -244,7 +496,7 @@ async function getAgentCardByIdHandler({
|
|
|
244
496
|
url: executionUrl,
|
|
245
497
|
provider,
|
|
246
498
|
version,
|
|
247
|
-
...createAgentCardDefaults(),
|
|
499
|
+
...createAgentCardDefaults({ pushNotifications }),
|
|
248
500
|
// Convert agent tools to skills format for A2A protocol
|
|
249
501
|
skills: Object.entries(tools).map(([toolId, tool]) => ({
|
|
250
502
|
id: toolId,
|
|
@@ -340,6 +592,63 @@ function createDataArtifactUpdate({
|
|
|
340
592
|
}
|
|
341
593
|
};
|
|
342
594
|
}
|
|
595
|
+
function resolvePushNotificationPair({
|
|
596
|
+
pushNotificationStore,
|
|
597
|
+
pushNotificationSender
|
|
598
|
+
}) {
|
|
599
|
+
if (pushNotificationSender) {
|
|
600
|
+
return {
|
|
601
|
+
pushNotificationStore: pushNotificationSender.getStore(),
|
|
602
|
+
pushNotificationSender
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
if (pushNotificationStore) {
|
|
606
|
+
return {
|
|
607
|
+
pushNotificationStore,
|
|
608
|
+
pushNotificationSender: new DefaultPushNotificationSender(pushNotificationStore)
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
return {
|
|
612
|
+
pushNotificationStore: defaultPushNotificationStore,
|
|
613
|
+
pushNotificationSender: defaultPushNotificationSender
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
function createTaskPushNotificationConfig(taskId, pushNotificationConfig) {
|
|
617
|
+
return {
|
|
618
|
+
taskId,
|
|
619
|
+
pushNotificationConfig: {
|
|
620
|
+
...pushNotificationConfig,
|
|
621
|
+
id: pushNotificationConfig.id ?? taskId
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
function shouldSendPushNotification(previousTask, nextTask) {
|
|
626
|
+
const pushTriggerStates = ["completed", "failed", "canceled", "input-required"];
|
|
627
|
+
if (!pushTriggerStates.includes(nextTask.status.state)) {
|
|
628
|
+
return false;
|
|
629
|
+
}
|
|
630
|
+
return previousTask?.status.state !== nextTask.status.state;
|
|
631
|
+
}
|
|
632
|
+
async function saveTaskAndMaybeSendPushNotification({
|
|
633
|
+
taskStore,
|
|
634
|
+
pushNotificationSender,
|
|
635
|
+
previousTask,
|
|
636
|
+
nextTask,
|
|
637
|
+
agentId,
|
|
638
|
+
logger
|
|
639
|
+
}) {
|
|
640
|
+
await taskStore.save({ agentId, data: nextTask });
|
|
641
|
+
if (!shouldSendPushNotification(previousTask, nextTask)) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
void pushNotificationSender.sendNotifications({
|
|
645
|
+
agentId,
|
|
646
|
+
task: nextTask,
|
|
647
|
+
logger
|
|
648
|
+
}).catch((error) => {
|
|
649
|
+
logger?.error("Failed to schedule A2A push notification", error);
|
|
650
|
+
});
|
|
651
|
+
}
|
|
343
652
|
function extractFullStreamTextDelta(value) {
|
|
344
653
|
if (typeof value !== "object" || value === null || !("type" in value)) {
|
|
345
654
|
return null;
|
|
@@ -444,6 +753,8 @@ async function handleMessageSend({
|
|
|
444
753
|
requestId,
|
|
445
754
|
params,
|
|
446
755
|
taskStore,
|
|
756
|
+
pushNotificationStore,
|
|
757
|
+
pushNotificationSender,
|
|
447
758
|
agent,
|
|
448
759
|
agentId,
|
|
449
760
|
logger,
|
|
@@ -453,6 +764,13 @@ async function handleMessageSend({
|
|
|
453
764
|
const { message, metadata } = params;
|
|
454
765
|
const { contextId } = message;
|
|
455
766
|
const taskId = message.taskId || crypto.randomUUID();
|
|
767
|
+
const {
|
|
768
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
769
|
+
pushNotificationSender: resolvedPushNotificationSender
|
|
770
|
+
} = resolvePushNotificationPair({
|
|
771
|
+
pushNotificationStore,
|
|
772
|
+
pushNotificationSender
|
|
773
|
+
});
|
|
456
774
|
let currentData = await loadOrCreateTask({
|
|
457
775
|
taskId,
|
|
458
776
|
taskStore,
|
|
@@ -461,7 +779,13 @@ async function handleMessageSend({
|
|
|
461
779
|
contextId,
|
|
462
780
|
metadata
|
|
463
781
|
});
|
|
464
|
-
|
|
782
|
+
if (params.configuration?.pushNotificationConfig) {
|
|
783
|
+
resolvedPushNotificationStore.set({
|
|
784
|
+
agentId,
|
|
785
|
+
config: createTaskPushNotificationConfig(taskId, params.configuration.pushNotificationConfig)
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
const context = createTaskContext({
|
|
465
789
|
task: currentData,
|
|
466
790
|
userMessage: message,
|
|
467
791
|
history: currentData.history || [],
|
|
@@ -496,7 +820,15 @@ async function handleMessageSend({
|
|
|
496
820
|
finishReason: result.finishReason
|
|
497
821
|
}
|
|
498
822
|
};
|
|
499
|
-
await
|
|
823
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
824
|
+
taskStore,
|
|
825
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
826
|
+
previousTask: context.task,
|
|
827
|
+
nextTask: currentData,
|
|
828
|
+
agentId,
|
|
829
|
+
logger
|
|
830
|
+
});
|
|
831
|
+
context.task = currentData;
|
|
500
832
|
} catch (handlerError) {
|
|
501
833
|
const failureStatusUpdate = {
|
|
502
834
|
state: "failed",
|
|
@@ -514,7 +846,14 @@ async function handleMessageSend({
|
|
|
514
846
|
};
|
|
515
847
|
currentData = applyUpdateToTask(currentData, failureStatusUpdate);
|
|
516
848
|
try {
|
|
517
|
-
await
|
|
849
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
850
|
+
taskStore,
|
|
851
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
852
|
+
previousTask: context.task,
|
|
853
|
+
nextTask: currentData,
|
|
854
|
+
agentId,
|
|
855
|
+
logger
|
|
856
|
+
});
|
|
518
857
|
} catch (saveError) {
|
|
519
858
|
logger?.error(`Failed to save task ${currentData.id} after handler error:`, saveError?.message);
|
|
520
859
|
}
|
|
@@ -534,10 +873,115 @@ async function handleTaskGet({
|
|
|
534
873
|
}
|
|
535
874
|
return createSuccessResponse(requestId, task);
|
|
536
875
|
}
|
|
876
|
+
async function loadTaskOrThrow({
|
|
877
|
+
taskStore,
|
|
878
|
+
agentId,
|
|
879
|
+
taskId
|
|
880
|
+
}) {
|
|
881
|
+
const task = await taskStore.load({ agentId, taskId });
|
|
882
|
+
if (!task) {
|
|
883
|
+
throw a2a.MastraA2AError.taskNotFound(taskId);
|
|
884
|
+
}
|
|
885
|
+
return task;
|
|
886
|
+
}
|
|
887
|
+
async function handleSetTaskPushNotificationConfig({
|
|
888
|
+
requestId,
|
|
889
|
+
taskStore,
|
|
890
|
+
pushNotificationStore,
|
|
891
|
+
agentId,
|
|
892
|
+
params
|
|
893
|
+
}) {
|
|
894
|
+
await loadTaskOrThrow({
|
|
895
|
+
taskStore,
|
|
896
|
+
agentId,
|
|
897
|
+
taskId: params.taskId
|
|
898
|
+
});
|
|
899
|
+
const { pushNotificationStore: resolvedPushNotificationStore } = resolvePushNotificationPair({
|
|
900
|
+
pushNotificationStore
|
|
901
|
+
});
|
|
902
|
+
const config = resolvedPushNotificationStore.set({
|
|
903
|
+
agentId,
|
|
904
|
+
config: createTaskPushNotificationConfig(params.taskId, params.pushNotificationConfig)
|
|
905
|
+
});
|
|
906
|
+
return createSuccessResponse(requestId, config);
|
|
907
|
+
}
|
|
908
|
+
async function handleGetTaskPushNotificationConfig({
|
|
909
|
+
requestId,
|
|
910
|
+
taskStore,
|
|
911
|
+
pushNotificationStore,
|
|
912
|
+
agentId,
|
|
913
|
+
params
|
|
914
|
+
}) {
|
|
915
|
+
await loadTaskOrThrow({
|
|
916
|
+
taskStore,
|
|
917
|
+
agentId,
|
|
918
|
+
taskId: params.id
|
|
919
|
+
});
|
|
920
|
+
const { pushNotificationStore: resolvedPushNotificationStore } = resolvePushNotificationPair({
|
|
921
|
+
pushNotificationStore
|
|
922
|
+
});
|
|
923
|
+
const config = resolvedPushNotificationStore.get({
|
|
924
|
+
agentId,
|
|
925
|
+
params
|
|
926
|
+
});
|
|
927
|
+
if (!config) {
|
|
928
|
+
throw a2a.MastraA2AError.invalidParams(
|
|
929
|
+
`Push notification config not found: ${params.pushNotificationConfigId ?? params.id}`
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
return createSuccessResponse(requestId, config);
|
|
933
|
+
}
|
|
934
|
+
async function handleListTaskPushNotificationConfig({
|
|
935
|
+
requestId,
|
|
936
|
+
taskStore,
|
|
937
|
+
pushNotificationStore,
|
|
938
|
+
agentId,
|
|
939
|
+
params
|
|
940
|
+
}) {
|
|
941
|
+
await loadTaskOrThrow({
|
|
942
|
+
taskStore,
|
|
943
|
+
agentId,
|
|
944
|
+
taskId: params.id
|
|
945
|
+
});
|
|
946
|
+
const { pushNotificationStore: resolvedPushNotificationStore } = resolvePushNotificationPair({
|
|
947
|
+
pushNotificationStore
|
|
948
|
+
});
|
|
949
|
+
const configs = resolvedPushNotificationStore.list({
|
|
950
|
+
agentId,
|
|
951
|
+
params
|
|
952
|
+
});
|
|
953
|
+
return createSuccessResponse(requestId, configs);
|
|
954
|
+
}
|
|
955
|
+
async function handleDeleteTaskPushNotificationConfig({
|
|
956
|
+
requestId,
|
|
957
|
+
taskStore,
|
|
958
|
+
pushNotificationStore,
|
|
959
|
+
agentId,
|
|
960
|
+
params
|
|
961
|
+
}) {
|
|
962
|
+
await loadTaskOrThrow({
|
|
963
|
+
taskStore,
|
|
964
|
+
agentId,
|
|
965
|
+
taskId: params.id
|
|
966
|
+
});
|
|
967
|
+
const { pushNotificationStore: resolvedPushNotificationStore } = resolvePushNotificationPair({
|
|
968
|
+
pushNotificationStore
|
|
969
|
+
});
|
|
970
|
+
const deleted = resolvedPushNotificationStore.delete({
|
|
971
|
+
agentId,
|
|
972
|
+
params
|
|
973
|
+
});
|
|
974
|
+
if (!deleted) {
|
|
975
|
+
throw a2a.MastraA2AError.invalidParams(`Push notification config not found: ${params.pushNotificationConfigId}`);
|
|
976
|
+
}
|
|
977
|
+
return createSuccessResponse(requestId, null);
|
|
978
|
+
}
|
|
537
979
|
async function* handleMessageStream({
|
|
538
980
|
requestId,
|
|
539
981
|
params,
|
|
540
982
|
taskStore,
|
|
983
|
+
pushNotificationStore,
|
|
984
|
+
pushNotificationSender,
|
|
541
985
|
agent,
|
|
542
986
|
agentId,
|
|
543
987
|
logger,
|
|
@@ -547,6 +991,13 @@ async function* handleMessageStream({
|
|
|
547
991
|
const { message, metadata } = params;
|
|
548
992
|
const { contextId } = message;
|
|
549
993
|
const taskId = message.taskId || crypto.randomUUID();
|
|
994
|
+
const {
|
|
995
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
996
|
+
pushNotificationSender: resolvedPushNotificationSender
|
|
997
|
+
} = resolvePushNotificationPair({
|
|
998
|
+
pushNotificationStore,
|
|
999
|
+
pushNotificationSender
|
|
1000
|
+
});
|
|
550
1001
|
let currentData = await loadOrCreateTask({
|
|
551
1002
|
taskId,
|
|
552
1003
|
taskStore,
|
|
@@ -555,6 +1006,12 @@ async function* handleMessageStream({
|
|
|
555
1006
|
contextId,
|
|
556
1007
|
metadata
|
|
557
1008
|
});
|
|
1009
|
+
if (params.configuration?.pushNotificationConfig) {
|
|
1010
|
+
resolvedPushNotificationStore.set({
|
|
1011
|
+
agentId,
|
|
1012
|
+
config: createTaskPushNotificationConfig(taskId, params.configuration.pushNotificationConfig)
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
558
1015
|
currentData = applyUpdateToTask(currentData, {
|
|
559
1016
|
state: "working",
|
|
560
1017
|
message: {
|
|
@@ -564,7 +1021,13 @@ async function* handleMessageStream({
|
|
|
564
1021
|
parts: [{ kind: "text", text: "Generating response..." }]
|
|
565
1022
|
}
|
|
566
1023
|
});
|
|
567
|
-
await
|
|
1024
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
1025
|
+
taskStore,
|
|
1026
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
1027
|
+
nextTask: currentData,
|
|
1028
|
+
agentId,
|
|
1029
|
+
logger
|
|
1030
|
+
});
|
|
568
1031
|
yield createSuccessResponse(requestId, currentData);
|
|
569
1032
|
try {
|
|
570
1033
|
const resourceId = metadata?.resourceId ?? message.metadata?.resourceId ?? agentId;
|
|
@@ -591,7 +1054,13 @@ async function* handleMessageStream({
|
|
|
591
1054
|
lastChunk: false
|
|
592
1055
|
});
|
|
593
1056
|
currentData = applyUpdateToTask(currentData, textUpdate);
|
|
594
|
-
await
|
|
1057
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
1058
|
+
taskStore,
|
|
1059
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
1060
|
+
nextTask: currentData,
|
|
1061
|
+
agentId,
|
|
1062
|
+
logger
|
|
1063
|
+
});
|
|
595
1064
|
yield createSuccessResponse(requestId, textUpdate);
|
|
596
1065
|
sawTextArtifact = true;
|
|
597
1066
|
pendingTextChunk = textDelta;
|
|
@@ -618,7 +1087,13 @@ async function* handleMessageStream({
|
|
|
618
1087
|
lastChunk: !structuredData
|
|
619
1088
|
});
|
|
620
1089
|
currentData = applyUpdateToTask(currentData, textUpdate);
|
|
621
|
-
await
|
|
1090
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
1091
|
+
taskStore,
|
|
1092
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
1093
|
+
nextTask: currentData,
|
|
1094
|
+
agentId,
|
|
1095
|
+
logger
|
|
1096
|
+
});
|
|
622
1097
|
yield createSuccessResponse(requestId, textUpdate);
|
|
623
1098
|
sawTextArtifact = true;
|
|
624
1099
|
pendingTextChunk = void 0;
|
|
@@ -631,15 +1106,22 @@ async function* handleMessageStream({
|
|
|
631
1106
|
lastChunk: true
|
|
632
1107
|
});
|
|
633
1108
|
currentData = applyUpdateToTask(currentData, dataUpdate);
|
|
634
|
-
await
|
|
1109
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
1110
|
+
taskStore,
|
|
1111
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
1112
|
+
nextTask: currentData,
|
|
1113
|
+
agentId,
|
|
1114
|
+
logger
|
|
1115
|
+
});
|
|
635
1116
|
yield createSuccessResponse(requestId, dataUpdate);
|
|
636
1117
|
}
|
|
637
|
-
|
|
1118
|
+
const previousTask = currentData;
|
|
1119
|
+
const completedTask = applyUpdateToTask(currentData, {
|
|
638
1120
|
state: "completed",
|
|
639
1121
|
message: void 0
|
|
640
1122
|
});
|
|
641
|
-
|
|
642
|
-
...
|
|
1123
|
+
completedTask.metadata = {
|
|
1124
|
+
...completedTask.metadata,
|
|
643
1125
|
execution: {
|
|
644
1126
|
toolCalls: await result.toolCalls,
|
|
645
1127
|
toolResults: await result.toolResults,
|
|
@@ -647,8 +1129,17 @@ async function* handleMessageStream({
|
|
|
647
1129
|
finishReason: await result.finishReason
|
|
648
1130
|
}
|
|
649
1131
|
};
|
|
650
|
-
|
|
1132
|
+
currentData = completedTask;
|
|
1133
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
1134
|
+
taskStore,
|
|
1135
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
1136
|
+
previousTask,
|
|
1137
|
+
nextTask: currentData,
|
|
1138
|
+
agentId,
|
|
1139
|
+
logger
|
|
1140
|
+
});
|
|
651
1141
|
} catch (handlerError) {
|
|
1142
|
+
const previousTask = currentData;
|
|
652
1143
|
currentData = applyUpdateToTask(currentData, {
|
|
653
1144
|
state: "failed",
|
|
654
1145
|
message: {
|
|
@@ -664,7 +1155,14 @@ async function* handleMessageStream({
|
|
|
664
1155
|
}
|
|
665
1156
|
});
|
|
666
1157
|
try {
|
|
667
|
-
await
|
|
1158
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
1159
|
+
taskStore,
|
|
1160
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
1161
|
+
previousTask,
|
|
1162
|
+
nextTask: currentData,
|
|
1163
|
+
agentId,
|
|
1164
|
+
logger
|
|
1165
|
+
});
|
|
668
1166
|
} catch (saveError) {
|
|
669
1167
|
logger?.error(`Failed to save task ${currentData.id} after handler error:`, saveError?.message);
|
|
670
1168
|
}
|
|
@@ -771,6 +1269,7 @@ function createA2ASSEResponse(payload) {
|
|
|
771
1269
|
async function handleTaskCancel({
|
|
772
1270
|
requestId,
|
|
773
1271
|
taskStore,
|
|
1272
|
+
pushNotificationSender,
|
|
774
1273
|
agentId,
|
|
775
1274
|
taskId,
|
|
776
1275
|
logger
|
|
@@ -797,8 +1296,16 @@ async function handleTaskCancel({
|
|
|
797
1296
|
messageId: crypto.randomUUID()
|
|
798
1297
|
}
|
|
799
1298
|
};
|
|
1299
|
+
const previousTask = data;
|
|
800
1300
|
data = applyUpdateToTask(data, cancelUpdate);
|
|
801
|
-
await
|
|
1301
|
+
await saveTaskAndMaybeSendPushNotification({
|
|
1302
|
+
taskStore,
|
|
1303
|
+
pushNotificationSender: resolvePushNotificationPair({ pushNotificationSender }).pushNotificationSender,
|
|
1304
|
+
previousTask,
|
|
1305
|
+
nextTask: data,
|
|
1306
|
+
agentId,
|
|
1307
|
+
logger
|
|
1308
|
+
});
|
|
802
1309
|
taskStore.activeCancellations.delete(taskId);
|
|
803
1310
|
return createSuccessResponse(requestId, data);
|
|
804
1311
|
}
|
|
@@ -810,10 +1317,19 @@ async function getAgentExecutionHandler({
|
|
|
810
1317
|
method,
|
|
811
1318
|
params,
|
|
812
1319
|
taskStore,
|
|
1320
|
+
pushNotificationStore,
|
|
1321
|
+
pushNotificationSender,
|
|
813
1322
|
logger,
|
|
814
1323
|
abortSignal
|
|
815
1324
|
}) {
|
|
816
1325
|
const agent = await chunkWZKXMP2U_cjs.getAgentFromSystem({ mastra, agentId });
|
|
1326
|
+
const {
|
|
1327
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
1328
|
+
pushNotificationSender: resolvedPushNotificationSender
|
|
1329
|
+
} = resolvePushNotificationPair({
|
|
1330
|
+
pushNotificationStore,
|
|
1331
|
+
pushNotificationSender
|
|
1332
|
+
});
|
|
817
1333
|
let taskId;
|
|
818
1334
|
try {
|
|
819
1335
|
taskId = getTaskIdFromParams(params);
|
|
@@ -823,8 +1339,11 @@ async function getAgentExecutionHandler({
|
|
|
823
1339
|
requestId,
|
|
824
1340
|
params,
|
|
825
1341
|
taskStore,
|
|
1342
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
1343
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
826
1344
|
agent,
|
|
827
1345
|
agentId,
|
|
1346
|
+
logger,
|
|
828
1347
|
requestContext
|
|
829
1348
|
});
|
|
830
1349
|
return result;
|
|
@@ -834,8 +1353,11 @@ async function getAgentExecutionHandler({
|
|
|
834
1353
|
requestId,
|
|
835
1354
|
taskStore,
|
|
836
1355
|
params,
|
|
1356
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
1357
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
837
1358
|
agent,
|
|
838
1359
|
agentId,
|
|
1360
|
+
logger,
|
|
839
1361
|
requestContext
|
|
840
1362
|
});
|
|
841
1363
|
return result;
|
|
@@ -853,8 +1375,10 @@ async function getAgentExecutionHandler({
|
|
|
853
1375
|
const result = await handleTaskCancel({
|
|
854
1376
|
requestId,
|
|
855
1377
|
taskStore,
|
|
1378
|
+
pushNotificationSender: resolvedPushNotificationSender,
|
|
856
1379
|
agentId,
|
|
857
|
-
taskId: taskId || "No task ID provided"
|
|
1380
|
+
taskId: taskId || "No task ID provided",
|
|
1381
|
+
logger
|
|
858
1382
|
});
|
|
859
1383
|
return result;
|
|
860
1384
|
}
|
|
@@ -867,10 +1391,37 @@ async function getAgentExecutionHandler({
|
|
|
867
1391
|
abortSignal
|
|
868
1392
|
});
|
|
869
1393
|
case "tasks/pushNotificationConfig/set":
|
|
1394
|
+
return await handleSetTaskPushNotificationConfig({
|
|
1395
|
+
requestId,
|
|
1396
|
+
taskStore,
|
|
1397
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
1398
|
+
agentId,
|
|
1399
|
+
params
|
|
1400
|
+
});
|
|
870
1401
|
case "tasks/pushNotificationConfig/get":
|
|
1402
|
+
return await handleGetTaskPushNotificationConfig({
|
|
1403
|
+
requestId,
|
|
1404
|
+
taskStore,
|
|
1405
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
1406
|
+
agentId,
|
|
1407
|
+
params
|
|
1408
|
+
});
|
|
871
1409
|
case "tasks/pushNotificationConfig/list":
|
|
1410
|
+
return await handleListTaskPushNotificationConfig({
|
|
1411
|
+
requestId,
|
|
1412
|
+
taskStore,
|
|
1413
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
1414
|
+
agentId,
|
|
1415
|
+
params
|
|
1416
|
+
});
|
|
872
1417
|
case "tasks/pushNotificationConfig/delete":
|
|
873
|
-
|
|
1418
|
+
return await handleDeleteTaskPushNotificationConfig({
|
|
1419
|
+
requestId,
|
|
1420
|
+
taskStore,
|
|
1421
|
+
pushNotificationStore: resolvedPushNotificationStore,
|
|
1422
|
+
agentId,
|
|
1423
|
+
params
|
|
1424
|
+
});
|
|
874
1425
|
case "agent/getAuthenticatedExtendedCard":
|
|
875
1426
|
throw a2a.MastraA2AError.extendedAgentCardNotConfigured();
|
|
876
1427
|
default:
|
|
@@ -903,7 +1454,8 @@ var GET_AGENT_CARD_ROUTE = chunk7LAFXMXB_cjs.createRoute({
|
|
|
903
1454
|
mastra: ctx.mastra,
|
|
904
1455
|
requestContext: ctx.requestContext,
|
|
905
1456
|
agentId: ctx.agentId,
|
|
906
|
-
executionUrl
|
|
1457
|
+
executionUrl,
|
|
1458
|
+
pushNotifications: true
|
|
907
1459
|
});
|
|
908
1460
|
}
|
|
909
1461
|
});
|
|
@@ -943,10 +1495,14 @@ exports.GET_AGENT_CARD_ROUTE = GET_AGENT_CARD_ROUTE;
|
|
|
943
1495
|
exports.a2a_exports = a2a_exports;
|
|
944
1496
|
exports.getAgentCardByIdHandler = getAgentCardByIdHandler;
|
|
945
1497
|
exports.getAgentExecutionHandler = getAgentExecutionHandler;
|
|
1498
|
+
exports.handleDeleteTaskPushNotificationConfig = handleDeleteTaskPushNotificationConfig;
|
|
1499
|
+
exports.handleGetTaskPushNotificationConfig = handleGetTaskPushNotificationConfig;
|
|
1500
|
+
exports.handleListTaskPushNotificationConfig = handleListTaskPushNotificationConfig;
|
|
946
1501
|
exports.handleMessageSend = handleMessageSend;
|
|
947
1502
|
exports.handleMessageStream = handleMessageStream;
|
|
1503
|
+
exports.handleSetTaskPushNotificationConfig = handleSetTaskPushNotificationConfig;
|
|
948
1504
|
exports.handleTaskCancel = handleTaskCancel;
|
|
949
1505
|
exports.handleTaskGet = handleTaskGet;
|
|
950
1506
|
exports.handleTaskResubscribe = handleTaskResubscribe;
|
|
951
|
-
//# sourceMappingURL=chunk-
|
|
952
|
-
//# sourceMappingURL=chunk-
|
|
1507
|
+
//# sourceMappingURL=chunk-CJ2LC5EE.cjs.map
|
|
1508
|
+
//# sourceMappingURL=chunk-CJ2LC5EE.cjs.map
|