@a2a-js/sdk 0.3.5 → 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 +225 -187
- 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-SY3G7ITG.js → chunk-LTPINR5K.js} +81 -56
- package/dist/chunk-SJNAG4AL.js +122 -0
- package/dist/chunk-ZX6KNMCP.js +38 -0
- package/dist/client/index.cjs +1304 -265
- package/dist/client/index.d.cts +477 -48
- package/dist/client/index.d.ts +477 -48
- package/dist/client/index.js +1165 -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 +757 -146
- package/dist/server/express/index.d.cts +83 -6
- package/dist/server/express/index.d.ts +83 -6
- package/dist/server/express/index.js +620 -92
- package/dist/server/index.cjs +486 -142
- package/dist/server/index.d.cts +100 -33
- package/dist/server/index.d.ts +100 -33
- package/dist/server/index.js +379 -88
- package/package.json +21 -22
- 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.cjs
CHANGED
|
@@ -29,37 +29,219 @@ __export(server_exports, {
|
|
|
29
29
|
InMemoryTaskStore: () => InMemoryTaskStore,
|
|
30
30
|
JsonRpcTransportHandler: () => JsonRpcTransportHandler,
|
|
31
31
|
RequestContext: () => RequestContext,
|
|
32
|
-
ResultManager: () => ResultManager
|
|
32
|
+
ResultManager: () => ResultManager,
|
|
33
|
+
ServerCallContext: () => ServerCallContext,
|
|
34
|
+
UnauthenticatedUser: () => UnauthenticatedUser
|
|
33
35
|
});
|
|
34
36
|
module.exports = __toCommonJS(server_exports);
|
|
35
37
|
|
|
36
38
|
// src/server/agent_execution/request_context.ts
|
|
37
39
|
var RequestContext = class {
|
|
38
40
|
userMessage;
|
|
39
|
-
task;
|
|
40
|
-
referenceTasks;
|
|
41
41
|
taskId;
|
|
42
42
|
contextId;
|
|
43
|
-
|
|
43
|
+
task;
|
|
44
|
+
referenceTasks;
|
|
45
|
+
context;
|
|
46
|
+
constructor(userMessage, taskId, contextId, task, referenceTasks, context) {
|
|
44
47
|
this.userMessage = userMessage;
|
|
45
48
|
this.taskId = taskId;
|
|
46
49
|
this.contextId = contextId;
|
|
47
50
|
this.task = task;
|
|
48
51
|
this.referenceTasks = referenceTasks;
|
|
52
|
+
this.context = context;
|
|
49
53
|
}
|
|
50
54
|
};
|
|
51
55
|
|
|
52
56
|
// src/server/events/execution_event_bus.ts
|
|
53
|
-
var
|
|
54
|
-
|
|
55
|
-
constructor() {
|
|
56
|
-
super();
|
|
57
|
+
var CustomEventImpl = typeof CustomEvent !== "undefined" ? CustomEvent : class CustomEventPolyfill extends Event {
|
|
58
|
+
detail;
|
|
59
|
+
constructor(type, eventInitDict) {
|
|
60
|
+
super(type, eventInitDict);
|
|
61
|
+
this.detail = eventInitDict?.detail ?? null;
|
|
57
62
|
}
|
|
63
|
+
};
|
|
64
|
+
function isAgentExecutionCustomEvent(e) {
|
|
65
|
+
return e instanceof CustomEventImpl;
|
|
66
|
+
}
|
|
67
|
+
var DefaultExecutionEventBus = class extends EventTarget {
|
|
68
|
+
// Separate storage for each event type - both use the interface's Listener type
|
|
69
|
+
// but are invoked differently (with event payload vs. no arguments)
|
|
70
|
+
eventListeners = /* @__PURE__ */ new Map();
|
|
71
|
+
finishedListeners = /* @__PURE__ */ new Map();
|
|
58
72
|
publish(event) {
|
|
59
|
-
this.
|
|
73
|
+
this.dispatchEvent(new CustomEventImpl("event", { detail: event }));
|
|
60
74
|
}
|
|
61
75
|
finished() {
|
|
62
|
-
this.
|
|
76
|
+
this.dispatchEvent(new Event("finished"));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* EventEmitter-compatible 'on' method.
|
|
80
|
+
* Wraps the listener to extract event detail from CustomEvent.
|
|
81
|
+
* Supports multiple registrations of the same listener (like EventEmitter).
|
|
82
|
+
* @param eventName The event name to listen for.
|
|
83
|
+
* @param listener The callback function to invoke when the event is emitted.
|
|
84
|
+
* @returns This instance for method chaining.
|
|
85
|
+
*/
|
|
86
|
+
on(eventName, listener) {
|
|
87
|
+
if (eventName === "event") {
|
|
88
|
+
this.addEventListenerInternal(listener);
|
|
89
|
+
} else {
|
|
90
|
+
this.addFinishedListenerInternal(listener);
|
|
91
|
+
}
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* EventEmitter-compatible 'off' method.
|
|
96
|
+
* Uses the stored wrapped listener for proper removal.
|
|
97
|
+
* Removes at most one instance of a listener per call (like EventEmitter).
|
|
98
|
+
* @param eventName The event name to stop listening for.
|
|
99
|
+
* @param listener The callback function to remove.
|
|
100
|
+
* @returns This instance for method chaining.
|
|
101
|
+
*/
|
|
102
|
+
off(eventName, listener) {
|
|
103
|
+
if (eventName === "event") {
|
|
104
|
+
this.removeEventListenerInternal(listener);
|
|
105
|
+
} else {
|
|
106
|
+
this.removeFinishedListenerInternal(listener);
|
|
107
|
+
}
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* EventEmitter-compatible 'once' method.
|
|
112
|
+
* Listener is automatically removed after first invocation.
|
|
113
|
+
* Supports multiple registrations of the same listener (like EventEmitter).
|
|
114
|
+
* @param eventName The event name to listen for once.
|
|
115
|
+
* @param listener The callback function to invoke when the event is emitted.
|
|
116
|
+
* @returns This instance for method chaining.
|
|
117
|
+
*/
|
|
118
|
+
once(eventName, listener) {
|
|
119
|
+
if (eventName === "event") {
|
|
120
|
+
this.addEventListenerOnceInternal(listener);
|
|
121
|
+
} else {
|
|
122
|
+
this.addFinishedListenerOnceInternal(listener);
|
|
123
|
+
}
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* EventEmitter-compatible 'removeAllListeners' method.
|
|
128
|
+
* Removes all listeners for a specific event or all events.
|
|
129
|
+
* @param eventName Optional event name to remove listeners for. If omitted, removes all.
|
|
130
|
+
* @returns This instance for method chaining.
|
|
131
|
+
*/
|
|
132
|
+
removeAllListeners(eventName) {
|
|
133
|
+
if (eventName === void 0 || eventName === "event") {
|
|
134
|
+
for (const wrappedListeners of this.eventListeners.values()) {
|
|
135
|
+
for (const wrapped of wrappedListeners) {
|
|
136
|
+
this.removeEventListener("event", wrapped);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
this.eventListeners.clear();
|
|
140
|
+
}
|
|
141
|
+
if (eventName === void 0 || eventName === "finished") {
|
|
142
|
+
for (const wrappedListeners of this.finishedListeners.values()) {
|
|
143
|
+
for (const wrapped of wrappedListeners) {
|
|
144
|
+
this.removeEventListener("finished", wrapped);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
this.finishedListeners.clear();
|
|
148
|
+
}
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
// ========================
|
|
152
|
+
// Helper methods for listener tracking
|
|
153
|
+
// ========================
|
|
154
|
+
/**
|
|
155
|
+
* Adds a wrapped listener to the tracking map.
|
|
156
|
+
*/
|
|
157
|
+
trackListener(listenerMap, listener, wrapped) {
|
|
158
|
+
const existing = listenerMap.get(listener);
|
|
159
|
+
if (existing) {
|
|
160
|
+
existing.push(wrapped);
|
|
161
|
+
} else {
|
|
162
|
+
listenerMap.set(listener, [wrapped]);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Removes a wrapped listener from the tracking map (for once cleanup).
|
|
167
|
+
*/
|
|
168
|
+
untrackWrappedListener(listenerMap, listener, wrapped) {
|
|
169
|
+
const wrappedList = listenerMap.get(listener);
|
|
170
|
+
if (wrappedList && wrappedList.length > 0) {
|
|
171
|
+
const index = wrappedList.indexOf(wrapped);
|
|
172
|
+
if (index !== -1) {
|
|
173
|
+
wrappedList.splice(index, 1);
|
|
174
|
+
if (wrappedList.length === 0) {
|
|
175
|
+
listenerMap.delete(listener);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// ========================
|
|
181
|
+
// Internal methods for 'event' listeners
|
|
182
|
+
// ========================
|
|
183
|
+
addEventListenerInternal(listener) {
|
|
184
|
+
const wrapped = (e) => {
|
|
185
|
+
if (!isAgentExecutionCustomEvent(e)) {
|
|
186
|
+
throw new Error('Internal error: expected CustomEvent for "event" type');
|
|
187
|
+
}
|
|
188
|
+
listener.call(this, e.detail);
|
|
189
|
+
};
|
|
190
|
+
this.trackListener(this.eventListeners, listener, wrapped);
|
|
191
|
+
this.addEventListener("event", wrapped);
|
|
192
|
+
}
|
|
193
|
+
removeEventListenerInternal(listener) {
|
|
194
|
+
const wrappedList = this.eventListeners.get(listener);
|
|
195
|
+
if (wrappedList && wrappedList.length > 0) {
|
|
196
|
+
const wrapped = wrappedList.pop();
|
|
197
|
+
if (wrappedList.length === 0) {
|
|
198
|
+
this.eventListeners.delete(listener);
|
|
199
|
+
}
|
|
200
|
+
this.removeEventListener("event", wrapped);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
addEventListenerOnceInternal(listener) {
|
|
204
|
+
const wrapped = (e) => {
|
|
205
|
+
if (!isAgentExecutionCustomEvent(e)) {
|
|
206
|
+
throw new Error('Internal error: expected CustomEvent for "event" type');
|
|
207
|
+
}
|
|
208
|
+
this.untrackWrappedListener(this.eventListeners, listener, wrapped);
|
|
209
|
+
listener.call(this, e.detail);
|
|
210
|
+
};
|
|
211
|
+
this.trackListener(this.eventListeners, listener, wrapped);
|
|
212
|
+
this.addEventListener("event", wrapped, { once: true });
|
|
213
|
+
}
|
|
214
|
+
// ========================
|
|
215
|
+
// Internal methods for 'finished' listeners
|
|
216
|
+
// ========================
|
|
217
|
+
// The interface declares listeners as (event: AgentExecutionEvent) => void,
|
|
218
|
+
// but for 'finished' events they are invoked with no arguments (EventEmitter behavior).
|
|
219
|
+
// We use Function.prototype.call to invoke with `this` as the event bus (matching
|
|
220
|
+
// EventEmitter semantics) and no arguments, which is type-safe.
|
|
221
|
+
addFinishedListenerInternal(listener) {
|
|
222
|
+
const wrapped = () => {
|
|
223
|
+
listener.call(this);
|
|
224
|
+
};
|
|
225
|
+
this.trackListener(this.finishedListeners, listener, wrapped);
|
|
226
|
+
this.addEventListener("finished", wrapped);
|
|
227
|
+
}
|
|
228
|
+
removeFinishedListenerInternal(listener) {
|
|
229
|
+
const wrappedList = this.finishedListeners.get(listener);
|
|
230
|
+
if (wrappedList && wrappedList.length > 0) {
|
|
231
|
+
const wrapped = wrappedList.pop();
|
|
232
|
+
if (wrappedList.length === 0) {
|
|
233
|
+
this.finishedListeners.delete(listener);
|
|
234
|
+
}
|
|
235
|
+
this.removeEventListener("finished", wrapped);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
addFinishedListenerOnceInternal(listener) {
|
|
239
|
+
const wrapped = () => {
|
|
240
|
+
this.untrackWrappedListener(this.finishedListeners, listener, wrapped);
|
|
241
|
+
listener.call(this);
|
|
242
|
+
};
|
|
243
|
+
this.trackListener(this.finishedListeners, listener, wrapped);
|
|
244
|
+
this.addEventListener("finished", wrapped, { once: true });
|
|
63
245
|
}
|
|
64
246
|
};
|
|
65
247
|
|
|
@@ -69,7 +251,7 @@ var DefaultExecutionEventBusManager = class {
|
|
|
69
251
|
/**
|
|
70
252
|
* Creates or retrieves an existing ExecutionEventBus based on the taskId.
|
|
71
253
|
* @param taskId The ID of the task.
|
|
72
|
-
* @returns An instance of
|
|
254
|
+
* @returns An instance of ExecutionEventBus.
|
|
73
255
|
*/
|
|
74
256
|
createOrGetByTaskId(taskId) {
|
|
75
257
|
if (!this.taskIdToBus.has(taskId)) {
|
|
@@ -80,7 +262,7 @@ var DefaultExecutionEventBusManager = class {
|
|
|
80
262
|
/**
|
|
81
263
|
* Retrieves an existing ExecutionEventBus based on the taskId.
|
|
82
264
|
* @param taskId The ID of the task.
|
|
83
|
-
* @returns An instance of
|
|
265
|
+
* @returns An instance of ExecutionEventBus or undefined if not found.
|
|
84
266
|
*/
|
|
85
267
|
getByTaskId(taskId) {
|
|
86
268
|
return this.taskIdToBus.get(taskId);
|
|
@@ -193,10 +375,7 @@ var A2AError = class _A2AError extends Error {
|
|
|
193
375
|
return new _A2AError(-32600, message, data);
|
|
194
376
|
}
|
|
195
377
|
static methodNotFound(method) {
|
|
196
|
-
return new _A2AError(
|
|
197
|
-
-32601,
|
|
198
|
-
`Method not found: ${method}`
|
|
199
|
-
);
|
|
378
|
+
return new _A2AError(-32601, `Method not found: ${method}`);
|
|
200
379
|
}
|
|
201
380
|
static invalidParams(message, data) {
|
|
202
381
|
return new _A2AError(-32602, message, data);
|
|
@@ -205,51 +384,34 @@ var A2AError = class _A2AError extends Error {
|
|
|
205
384
|
return new _A2AError(-32603, message, data);
|
|
206
385
|
}
|
|
207
386
|
static taskNotFound(taskId) {
|
|
208
|
-
return new _A2AError(
|
|
209
|
-
-32001,
|
|
210
|
-
`Task not found: ${taskId}`,
|
|
211
|
-
void 0,
|
|
212
|
-
taskId
|
|
213
|
-
);
|
|
387
|
+
return new _A2AError(-32001, `Task not found: ${taskId}`, void 0, taskId);
|
|
214
388
|
}
|
|
215
389
|
static taskNotCancelable(taskId) {
|
|
216
|
-
return new _A2AError(
|
|
217
|
-
-32002,
|
|
218
|
-
`Task not cancelable: ${taskId}`,
|
|
219
|
-
void 0,
|
|
220
|
-
taskId
|
|
221
|
-
);
|
|
390
|
+
return new _A2AError(-32002, `Task not cancelable: ${taskId}`, void 0, taskId);
|
|
222
391
|
}
|
|
223
392
|
static pushNotificationNotSupported() {
|
|
224
|
-
return new _A2AError(
|
|
225
|
-
-32003,
|
|
226
|
-
"Push Notification is not supported"
|
|
227
|
-
);
|
|
393
|
+
return new _A2AError(-32003, "Push Notification is not supported");
|
|
228
394
|
}
|
|
229
395
|
static unsupportedOperation(operation) {
|
|
230
|
-
return new _A2AError(
|
|
231
|
-
-32004,
|
|
232
|
-
`Unsupported operation: ${operation}`
|
|
233
|
-
);
|
|
396
|
+
return new _A2AError(-32004, `Unsupported operation: ${operation}`);
|
|
234
397
|
}
|
|
235
398
|
static authenticatedExtendedCardNotConfigured() {
|
|
236
|
-
return new _A2AError(
|
|
237
|
-
-32007,
|
|
238
|
-
`Extended card not configured.`
|
|
239
|
-
);
|
|
399
|
+
return new _A2AError(-32007, `Extended card not configured.`);
|
|
240
400
|
}
|
|
241
401
|
};
|
|
242
402
|
|
|
243
403
|
// src/server/result_manager.ts
|
|
244
404
|
var ResultManager = class {
|
|
245
405
|
taskStore;
|
|
406
|
+
serverCallContext;
|
|
246
407
|
currentTask;
|
|
247
408
|
latestUserMessage;
|
|
248
409
|
// To add to history if a new task is created
|
|
249
410
|
finalMessageResult;
|
|
250
411
|
// Stores the message if it's the final result
|
|
251
|
-
constructor(taskStore) {
|
|
412
|
+
constructor(taskStore, serverCallContext) {
|
|
252
413
|
this.taskStore = taskStore;
|
|
414
|
+
this.serverCallContext = serverCallContext;
|
|
253
415
|
}
|
|
254
416
|
setContext(latestUserMessage) {
|
|
255
417
|
this.latestUserMessage = latestUserMessage;
|
|
@@ -265,7 +427,9 @@ var ResultManager = class {
|
|
|
265
427
|
const taskEvent = event;
|
|
266
428
|
this.currentTask = { ...taskEvent };
|
|
267
429
|
if (this.latestUserMessage) {
|
|
268
|
-
if (!this.currentTask.history?.find(
|
|
430
|
+
if (!this.currentTask.history?.find(
|
|
431
|
+
(msg) => msg.messageId === this.latestUserMessage.messageId
|
|
432
|
+
)) {
|
|
269
433
|
this.currentTask.history = [this.latestUserMessage, ...this.currentTask.history || []];
|
|
270
434
|
}
|
|
271
435
|
}
|
|
@@ -275,24 +439,36 @@ var ResultManager = class {
|
|
|
275
439
|
if (this.currentTask && this.currentTask.id === updateEvent.taskId) {
|
|
276
440
|
this.currentTask.status = updateEvent.status;
|
|
277
441
|
if (updateEvent.status.message) {
|
|
278
|
-
if (!this.currentTask.history?.find(
|
|
279
|
-
|
|
442
|
+
if (!this.currentTask.history?.find(
|
|
443
|
+
(msg) => msg.messageId === updateEvent.status.message.messageId
|
|
444
|
+
)) {
|
|
445
|
+
this.currentTask.history = [
|
|
446
|
+
...this.currentTask.history || [],
|
|
447
|
+
updateEvent.status.message
|
|
448
|
+
];
|
|
280
449
|
}
|
|
281
450
|
}
|
|
282
451
|
await this.saveCurrentTask();
|
|
283
452
|
} else if (!this.currentTask && updateEvent.taskId) {
|
|
284
|
-
const loaded = await this.taskStore.load(updateEvent.taskId);
|
|
453
|
+
const loaded = await this.taskStore.load(updateEvent.taskId, this.serverCallContext);
|
|
285
454
|
if (loaded) {
|
|
286
455
|
this.currentTask = loaded;
|
|
287
456
|
this.currentTask.status = updateEvent.status;
|
|
288
457
|
if (updateEvent.status.message) {
|
|
289
|
-
if (!this.currentTask.history?.find(
|
|
290
|
-
|
|
458
|
+
if (!this.currentTask.history?.find(
|
|
459
|
+
(msg) => msg.messageId === updateEvent.status.message.messageId
|
|
460
|
+
)) {
|
|
461
|
+
this.currentTask.history = [
|
|
462
|
+
...this.currentTask.history || [],
|
|
463
|
+
updateEvent.status.message
|
|
464
|
+
];
|
|
291
465
|
}
|
|
292
466
|
}
|
|
293
467
|
await this.saveCurrentTask();
|
|
294
468
|
} else {
|
|
295
|
-
console.warn(
|
|
469
|
+
console.warn(
|
|
470
|
+
`ResultManager: Received status update for unknown task ${updateEvent.taskId}`
|
|
471
|
+
);
|
|
296
472
|
}
|
|
297
473
|
}
|
|
298
474
|
} else if (event.kind === "artifact-update") {
|
|
@@ -308,9 +484,14 @@ var ResultManager = class {
|
|
|
308
484
|
if (artifactEvent.append) {
|
|
309
485
|
const existingArtifact = this.currentTask.artifacts[existingArtifactIndex];
|
|
310
486
|
existingArtifact.parts.push(...artifactEvent.artifact.parts);
|
|
311
|
-
if (artifactEvent.artifact.description)
|
|
487
|
+
if (artifactEvent.artifact.description)
|
|
488
|
+
existingArtifact.description = artifactEvent.artifact.description;
|
|
312
489
|
if (artifactEvent.artifact.name) existingArtifact.name = artifactEvent.artifact.name;
|
|
313
|
-
if (artifactEvent.artifact.metadata)
|
|
490
|
+
if (artifactEvent.artifact.metadata)
|
|
491
|
+
existingArtifact.metadata = {
|
|
492
|
+
...existingArtifact.metadata,
|
|
493
|
+
...artifactEvent.artifact.metadata
|
|
494
|
+
};
|
|
314
495
|
} else {
|
|
315
496
|
this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
|
|
316
497
|
}
|
|
@@ -319,7 +500,7 @@ var ResultManager = class {
|
|
|
319
500
|
}
|
|
320
501
|
await this.saveCurrentTask();
|
|
321
502
|
} else if (!this.currentTask && artifactEvent.taskId) {
|
|
322
|
-
const loaded = await this.taskStore.load(artifactEvent.taskId);
|
|
503
|
+
const loaded = await this.taskStore.load(artifactEvent.taskId, this.serverCallContext);
|
|
323
504
|
if (loaded) {
|
|
324
505
|
this.currentTask = loaded;
|
|
325
506
|
if (!this.currentTask.artifacts) this.currentTask.artifacts = [];
|
|
@@ -328,7 +509,9 @@ var ResultManager = class {
|
|
|
328
509
|
);
|
|
329
510
|
if (existingArtifactIndex !== -1) {
|
|
330
511
|
if (artifactEvent.append) {
|
|
331
|
-
this.currentTask.artifacts[existingArtifactIndex].parts.push(
|
|
512
|
+
this.currentTask.artifacts[existingArtifactIndex].parts.push(
|
|
513
|
+
...artifactEvent.artifact.parts
|
|
514
|
+
);
|
|
332
515
|
} else {
|
|
333
516
|
this.currentTask.artifacts[existingArtifactIndex] = artifactEvent.artifact;
|
|
334
517
|
}
|
|
@@ -337,14 +520,16 @@ var ResultManager = class {
|
|
|
337
520
|
}
|
|
338
521
|
await this.saveCurrentTask();
|
|
339
522
|
} else {
|
|
340
|
-
console.warn(
|
|
523
|
+
console.warn(
|
|
524
|
+
`ResultManager: Received artifact update for unknown task ${artifactEvent.taskId}`
|
|
525
|
+
);
|
|
341
526
|
}
|
|
342
527
|
}
|
|
343
528
|
}
|
|
344
529
|
}
|
|
345
530
|
async saveCurrentTask() {
|
|
346
531
|
if (this.currentTask) {
|
|
347
|
-
await this.taskStore.save(this.currentTask);
|
|
532
|
+
await this.taskStore.save(this.currentTask, this.serverCallContext);
|
|
348
533
|
}
|
|
349
534
|
}
|
|
350
535
|
/**
|
|
@@ -432,7 +617,10 @@ var DefaultPushNotificationSender = class {
|
|
|
432
617
|
try {
|
|
433
618
|
await this._dispatchNotification(task, pushConfig);
|
|
434
619
|
} catch (error) {
|
|
435
|
-
console.error(
|
|
620
|
+
console.error(
|
|
621
|
+
`Error sending push notification for task_id=${task.id} to URL: ${pushConfig.url}. Error:`,
|
|
622
|
+
error
|
|
623
|
+
);
|
|
436
624
|
}
|
|
437
625
|
});
|
|
438
626
|
await Promise.all(dispatches);
|
|
@@ -471,22 +659,80 @@ var DefaultPushNotificationSender = class {
|
|
|
471
659
|
}
|
|
472
660
|
};
|
|
473
661
|
|
|
662
|
+
// src/extensions.ts
|
|
663
|
+
var Extensions = {
|
|
664
|
+
/**
|
|
665
|
+
* Creates new {@link Extensions} from `current` and `additional`.
|
|
666
|
+
* If `current` already contains `additional` it is returned unmodified.
|
|
667
|
+
*/
|
|
668
|
+
createFrom: (current, additional) => {
|
|
669
|
+
if (current?.includes(additional)) {
|
|
670
|
+
return current;
|
|
671
|
+
}
|
|
672
|
+
return [...current ?? [], additional];
|
|
673
|
+
},
|
|
674
|
+
/**
|
|
675
|
+
* Creates {@link Extensions} from comma separated extensions identifiers as per
|
|
676
|
+
* https://a2a-protocol.org/latest/specification/#326-service-parameters.
|
|
677
|
+
* Parses the output of `toServiceParameter`.
|
|
678
|
+
*/
|
|
679
|
+
parseServiceParameter: (value) => {
|
|
680
|
+
if (!value) {
|
|
681
|
+
return [];
|
|
682
|
+
}
|
|
683
|
+
const unique = new Set(
|
|
684
|
+
value.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0)
|
|
685
|
+
);
|
|
686
|
+
return Array.from(unique);
|
|
687
|
+
},
|
|
688
|
+
/**
|
|
689
|
+
* Converts {@link Extensions} to comma separated extensions identifiers as per
|
|
690
|
+
* https://a2a-protocol.org/latest/specification/#326-service-parameters.
|
|
691
|
+
*/
|
|
692
|
+
toServiceParameter: (value) => {
|
|
693
|
+
return value.join(",");
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
// src/server/context.ts
|
|
698
|
+
var ServerCallContext = class {
|
|
699
|
+
_requestedExtensions;
|
|
700
|
+
_user;
|
|
701
|
+
_activatedExtensions;
|
|
702
|
+
constructor(requestedExtensions, user) {
|
|
703
|
+
this._requestedExtensions = requestedExtensions;
|
|
704
|
+
this._user = user;
|
|
705
|
+
}
|
|
706
|
+
get user() {
|
|
707
|
+
return this._user;
|
|
708
|
+
}
|
|
709
|
+
get activatedExtensions() {
|
|
710
|
+
return this._activatedExtensions;
|
|
711
|
+
}
|
|
712
|
+
get requestedExtensions() {
|
|
713
|
+
return this._requestedExtensions;
|
|
714
|
+
}
|
|
715
|
+
addActivatedExtension(uri) {
|
|
716
|
+
this._activatedExtensions = Extensions.createFrom(this._activatedExtensions, uri);
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
|
|
474
720
|
// src/server/request_handler/default_request_handler.ts
|
|
475
721
|
var terminalStates = ["completed", "failed", "canceled", "rejected"];
|
|
476
722
|
var DefaultRequestHandler = class {
|
|
477
723
|
agentCard;
|
|
478
|
-
extendedAgentCard;
|
|
479
724
|
taskStore;
|
|
480
725
|
agentExecutor;
|
|
481
726
|
eventBusManager;
|
|
482
727
|
pushNotificationStore;
|
|
483
728
|
pushNotificationSender;
|
|
484
|
-
|
|
729
|
+
extendedAgentCardProvider;
|
|
730
|
+
constructor(agentCard, taskStore, agentExecutor, eventBusManager = new DefaultExecutionEventBusManager(), pushNotificationStore, pushNotificationSender, extendedAgentCardProvider) {
|
|
485
731
|
this.agentCard = agentCard;
|
|
486
732
|
this.taskStore = taskStore;
|
|
487
733
|
this.agentExecutor = agentExecutor;
|
|
488
734
|
this.eventBusManager = eventBusManager;
|
|
489
|
-
this.
|
|
735
|
+
this.extendedAgentCardProvider = extendedAgentCardProvider;
|
|
490
736
|
if (agentCard.capabilities.pushNotifications) {
|
|
491
737
|
this.pushNotificationStore = pushNotificationStore || new InMemoryPushNotificationStore();
|
|
492
738
|
this.pushNotificationSender = pushNotificationSender || new DefaultPushNotificationSender(this.pushNotificationStore);
|
|
@@ -495,30 +741,42 @@ var DefaultRequestHandler = class {
|
|
|
495
741
|
async getAgentCard() {
|
|
496
742
|
return this.agentCard;
|
|
497
743
|
}
|
|
498
|
-
async getAuthenticatedExtendedAgentCard() {
|
|
499
|
-
if (!this.
|
|
744
|
+
async getAuthenticatedExtendedAgentCard(context) {
|
|
745
|
+
if (!this.agentCard.supportsAuthenticatedExtendedCard) {
|
|
746
|
+
throw A2AError.unsupportedOperation("Agent does not support authenticated extended card.");
|
|
747
|
+
}
|
|
748
|
+
if (!this.extendedAgentCardProvider) {
|
|
500
749
|
throw A2AError.authenticatedExtendedCardNotConfigured();
|
|
501
750
|
}
|
|
502
|
-
|
|
751
|
+
if (typeof this.extendedAgentCardProvider === "function") {
|
|
752
|
+
return this.extendedAgentCardProvider(context);
|
|
753
|
+
}
|
|
754
|
+
if (context?.user?.isAuthenticated) {
|
|
755
|
+
return this.extendedAgentCardProvider;
|
|
756
|
+
}
|
|
757
|
+
return this.agentCard;
|
|
503
758
|
}
|
|
504
|
-
async _createRequestContext(incomingMessage,
|
|
759
|
+
async _createRequestContext(incomingMessage, context) {
|
|
505
760
|
let task;
|
|
506
761
|
let referenceTasks;
|
|
507
762
|
if (incomingMessage.taskId) {
|
|
508
|
-
task = await this.taskStore.load(incomingMessage.taskId);
|
|
763
|
+
task = await this.taskStore.load(incomingMessage.taskId, context);
|
|
509
764
|
if (!task) {
|
|
510
765
|
throw A2AError.taskNotFound(incomingMessage.taskId);
|
|
511
766
|
}
|
|
512
767
|
if (terminalStates.includes(task.status.state)) {
|
|
513
|
-
throw A2AError.invalidRequest(
|
|
768
|
+
throw A2AError.invalidRequest(
|
|
769
|
+
`Task ${task.id} is in a terminal state (${task.status.state}) and cannot be modified.`
|
|
770
|
+
);
|
|
514
771
|
}
|
|
515
772
|
task.history = [...task.history || [], incomingMessage];
|
|
516
|
-
await this.taskStore.save(task);
|
|
773
|
+
await this.taskStore.save(task, context);
|
|
517
774
|
}
|
|
775
|
+
const taskId = incomingMessage.taskId || (0, import_uuid.v4)();
|
|
518
776
|
if (incomingMessage.referenceTaskIds && incomingMessage.referenceTaskIds.length > 0) {
|
|
519
777
|
referenceTasks = [];
|
|
520
778
|
for (const refId of incomingMessage.referenceTaskIds) {
|
|
521
|
-
const refTask = await this.taskStore.load(refId);
|
|
779
|
+
const refTask = await this.taskStore.load(refId, context);
|
|
522
780
|
if (refTask) {
|
|
523
781
|
referenceTasks.push(refTask);
|
|
524
782
|
} else {
|
|
@@ -527,24 +785,33 @@ var DefaultRequestHandler = class {
|
|
|
527
785
|
}
|
|
528
786
|
}
|
|
529
787
|
const contextId = incomingMessage.contextId || task?.contextId || (0, import_uuid.v4)();
|
|
788
|
+
if (context?.requestedExtensions) {
|
|
789
|
+
const agentCard = await this.getAgentCard();
|
|
790
|
+
const exposedExtensions = new Set(
|
|
791
|
+
agentCard.capabilities.extensions?.map((ext) => ext.uri) || []
|
|
792
|
+
);
|
|
793
|
+
const validExtensions = context.requestedExtensions.filter(
|
|
794
|
+
(extension) => exposedExtensions.has(extension)
|
|
795
|
+
);
|
|
796
|
+
context = new ServerCallContext(validExtensions, context.user);
|
|
797
|
+
}
|
|
530
798
|
const messageForContext = {
|
|
531
799
|
...incomingMessage,
|
|
532
|
-
contextId
|
|
533
|
-
};
|
|
534
|
-
return new RequestContext(
|
|
535
|
-
messageForContext,
|
|
536
|
-
taskId,
|
|
537
800
|
contextId,
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
);
|
|
801
|
+
taskId
|
|
802
|
+
};
|
|
803
|
+
return new RequestContext(messageForContext, taskId, contextId, task, referenceTasks, context);
|
|
541
804
|
}
|
|
542
|
-
async _processEvents(taskId, resultManager, eventQueue, options) {
|
|
805
|
+
async _processEvents(taskId, resultManager, eventQueue, context, options) {
|
|
543
806
|
let firstResultSent = false;
|
|
544
807
|
try {
|
|
545
808
|
for await (const event of eventQueue.events()) {
|
|
546
809
|
await resultManager.processEvent(event);
|
|
547
|
-
|
|
810
|
+
try {
|
|
811
|
+
await this._sendPushNotificationIfNeeded(event, context);
|
|
812
|
+
} catch (error) {
|
|
813
|
+
console.error(`Error sending push notification: ${error}`);
|
|
814
|
+
}
|
|
548
815
|
if (options?.firstResultResolver && !firstResultSent) {
|
|
549
816
|
let firstResult;
|
|
550
817
|
if (event.kind === "message") {
|
|
@@ -559,28 +826,33 @@ var DefaultRequestHandler = class {
|
|
|
559
826
|
}
|
|
560
827
|
}
|
|
561
828
|
if (options?.firstResultRejector && !firstResultSent) {
|
|
562
|
-
options.firstResultRejector(
|
|
829
|
+
options.firstResultRejector(
|
|
830
|
+
A2AError.internalError("Execution finished before a message or task was produced.")
|
|
831
|
+
);
|
|
563
832
|
}
|
|
564
833
|
} catch (error) {
|
|
565
834
|
console.error(`Event processing loop failed for task ${taskId}:`, error);
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
835
|
+
this._handleProcessingError(
|
|
836
|
+
error,
|
|
837
|
+
resultManager,
|
|
838
|
+
firstResultSent,
|
|
839
|
+
taskId,
|
|
840
|
+
options?.firstResultRejector
|
|
841
|
+
);
|
|
570
842
|
} finally {
|
|
571
843
|
this.eventBusManager.cleanupByTaskId(taskId);
|
|
572
844
|
}
|
|
573
845
|
}
|
|
574
|
-
async sendMessage(params) {
|
|
846
|
+
async sendMessage(params, context) {
|
|
575
847
|
const incomingMessage = params.message;
|
|
576
848
|
if (!incomingMessage.messageId) {
|
|
577
849
|
throw A2AError.invalidParams("message.messageId is required.");
|
|
578
850
|
}
|
|
579
851
|
const isBlocking = params.configuration?.blocking !== false;
|
|
580
|
-
const
|
|
581
|
-
const resultManager = new ResultManager(this.taskStore);
|
|
852
|
+
const resultManager = new ResultManager(this.taskStore, context);
|
|
582
853
|
resultManager.setContext(incomingMessage);
|
|
583
|
-
const requestContext = await this._createRequestContext(incomingMessage,
|
|
854
|
+
const requestContext = await this._createRequestContext(incomingMessage, context);
|
|
855
|
+
const taskId = requestContext.taskId;
|
|
584
856
|
const finalMessageForAgent = requestContext.userMessage;
|
|
585
857
|
if (params.configuration?.pushNotificationConfig && this.agentCard.capabilities.pushNotifications) {
|
|
586
858
|
await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
|
|
@@ -625,30 +897,32 @@ var DefaultRequestHandler = class {
|
|
|
625
897
|
eventBus.finished();
|
|
626
898
|
});
|
|
627
899
|
if (isBlocking) {
|
|
628
|
-
await this._processEvents(taskId, resultManager, eventQueue);
|
|
900
|
+
await this._processEvents(taskId, resultManager, eventQueue, context);
|
|
629
901
|
const finalResult = resultManager.getFinalResult();
|
|
630
902
|
if (!finalResult) {
|
|
631
|
-
throw A2AError.internalError(
|
|
903
|
+
throw A2AError.internalError(
|
|
904
|
+
"Agent execution finished without a result, and no task context found."
|
|
905
|
+
);
|
|
632
906
|
}
|
|
633
907
|
return finalResult;
|
|
634
908
|
} else {
|
|
635
909
|
return new Promise((resolve, reject) => {
|
|
636
|
-
this._processEvents(taskId, resultManager, eventQueue, {
|
|
910
|
+
this._processEvents(taskId, resultManager, eventQueue, context, {
|
|
637
911
|
firstResultResolver: resolve,
|
|
638
912
|
firstResultRejector: reject
|
|
639
913
|
});
|
|
640
914
|
});
|
|
641
915
|
}
|
|
642
916
|
}
|
|
643
|
-
async *sendMessageStream(params) {
|
|
917
|
+
async *sendMessageStream(params, context) {
|
|
644
918
|
const incomingMessage = params.message;
|
|
645
919
|
if (!incomingMessage.messageId) {
|
|
646
920
|
throw A2AError.invalidParams("message.messageId is required for streaming.");
|
|
647
921
|
}
|
|
648
|
-
const
|
|
649
|
-
const resultManager = new ResultManager(this.taskStore);
|
|
922
|
+
const resultManager = new ResultManager(this.taskStore, context);
|
|
650
923
|
resultManager.setContext(incomingMessage);
|
|
651
|
-
const requestContext = await this._createRequestContext(incomingMessage,
|
|
924
|
+
const requestContext = await this._createRequestContext(incomingMessage, context);
|
|
925
|
+
const taskId = requestContext.taskId;
|
|
652
926
|
const finalMessageForAgent = requestContext.userMessage;
|
|
653
927
|
const eventBus = this.eventBusManager.createOrGetByTaskId(taskId);
|
|
654
928
|
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
@@ -656,7 +930,10 @@ var DefaultRequestHandler = class {
|
|
|
656
930
|
await this.pushNotificationStore?.save(taskId, params.configuration.pushNotificationConfig);
|
|
657
931
|
}
|
|
658
932
|
this.agentExecutor.execute(requestContext, eventBus).catch((err) => {
|
|
659
|
-
console.error(
|
|
933
|
+
console.error(
|
|
934
|
+
`Agent execution failed for stream message ${finalMessageForAgent.messageId}:`,
|
|
935
|
+
err
|
|
936
|
+
);
|
|
660
937
|
const errorTaskStatus = {
|
|
661
938
|
kind: "status-update",
|
|
662
939
|
taskId: requestContext.task?.id || (0, import_uuid.v4)(),
|
|
@@ -682,15 +959,15 @@ var DefaultRequestHandler = class {
|
|
|
682
959
|
try {
|
|
683
960
|
for await (const event of eventQueue.events()) {
|
|
684
961
|
await resultManager.processEvent(event);
|
|
685
|
-
await this._sendPushNotificationIfNeeded(event);
|
|
962
|
+
await this._sendPushNotificationIfNeeded(event, context);
|
|
686
963
|
yield event;
|
|
687
964
|
}
|
|
688
965
|
} finally {
|
|
689
966
|
this.eventBusManager.cleanupByTaskId(taskId);
|
|
690
967
|
}
|
|
691
968
|
}
|
|
692
|
-
async getTask(params) {
|
|
693
|
-
const task = await this.taskStore.load(params.id);
|
|
969
|
+
async getTask(params, context) {
|
|
970
|
+
const task = await this.taskStore.load(params.id, context);
|
|
694
971
|
if (!task) {
|
|
695
972
|
throw A2AError.taskNotFound(params.id);
|
|
696
973
|
}
|
|
@@ -703,8 +980,8 @@ var DefaultRequestHandler = class {
|
|
|
703
980
|
}
|
|
704
981
|
return task;
|
|
705
982
|
}
|
|
706
|
-
async cancelTask(params) {
|
|
707
|
-
const task = await this.taskStore.load(params.id);
|
|
983
|
+
async cancelTask(params, context) {
|
|
984
|
+
const task = await this.taskStore.load(params.id, context);
|
|
708
985
|
if (!task) {
|
|
709
986
|
throw A2AError.taskNotFound(params.id);
|
|
710
987
|
}
|
|
@@ -716,7 +993,12 @@ var DefaultRequestHandler = class {
|
|
|
716
993
|
if (eventBus) {
|
|
717
994
|
const eventQueue = new ExecutionEventQueue(eventBus);
|
|
718
995
|
await this.agentExecutor.cancelTask(params.id, eventBus);
|
|
719
|
-
await this._processEvents(
|
|
996
|
+
await this._processEvents(
|
|
997
|
+
params.id,
|
|
998
|
+
new ResultManager(this.taskStore, context),
|
|
999
|
+
eventQueue,
|
|
1000
|
+
context
|
|
1001
|
+
);
|
|
720
1002
|
} else {
|
|
721
1003
|
task.status = {
|
|
722
1004
|
state: "canceled",
|
|
@@ -732,9 +1014,9 @@ var DefaultRequestHandler = class {
|
|
|
732
1014
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
733
1015
|
};
|
|
734
1016
|
task.history = [...task.history || [], task.status.message];
|
|
735
|
-
await this.taskStore.save(task);
|
|
1017
|
+
await this.taskStore.save(task, context);
|
|
736
1018
|
}
|
|
737
|
-
const latestTask = await this.taskStore.load(params.id);
|
|
1019
|
+
const latestTask = await this.taskStore.load(params.id, context);
|
|
738
1020
|
if (!latestTask) {
|
|
739
1021
|
throw A2AError.internalError(`Task ${params.id} not found after cancellation.`);
|
|
740
1022
|
}
|
|
@@ -743,11 +1025,11 @@ var DefaultRequestHandler = class {
|
|
|
743
1025
|
}
|
|
744
1026
|
return latestTask;
|
|
745
1027
|
}
|
|
746
|
-
async setTaskPushNotificationConfig(params) {
|
|
1028
|
+
async setTaskPushNotificationConfig(params, context) {
|
|
747
1029
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
748
1030
|
throw A2AError.pushNotificationNotSupported();
|
|
749
1031
|
}
|
|
750
|
-
const task = await this.taskStore.load(params.taskId);
|
|
1032
|
+
const task = await this.taskStore.load(params.taskId, context);
|
|
751
1033
|
if (!task) {
|
|
752
1034
|
throw A2AError.taskNotFound(params.taskId);
|
|
753
1035
|
}
|
|
@@ -758,11 +1040,11 @@ var DefaultRequestHandler = class {
|
|
|
758
1040
|
await this.pushNotificationStore?.save(taskId, pushNotificationConfig);
|
|
759
1041
|
return params;
|
|
760
1042
|
}
|
|
761
|
-
async getTaskPushNotificationConfig(params) {
|
|
1043
|
+
async getTaskPushNotificationConfig(params, context) {
|
|
762
1044
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
763
1045
|
throw A2AError.pushNotificationNotSupported();
|
|
764
1046
|
}
|
|
765
|
-
const task = await this.taskStore.load(params.id);
|
|
1047
|
+
const task = await this.taskStore.load(params.id, context);
|
|
766
1048
|
if (!task) {
|
|
767
1049
|
throw A2AError.taskNotFound(params.id);
|
|
768
1050
|
}
|
|
@@ -778,15 +1060,17 @@ var DefaultRequestHandler = class {
|
|
|
778
1060
|
}
|
|
779
1061
|
const config = configs.find((c) => c.id === configId);
|
|
780
1062
|
if (!config) {
|
|
781
|
-
throw A2AError.internalError(
|
|
1063
|
+
throw A2AError.internalError(
|
|
1064
|
+
`Push notification config with id '${configId}' not found for task ${params.id}.`
|
|
1065
|
+
);
|
|
782
1066
|
}
|
|
783
1067
|
return { taskId: params.id, pushNotificationConfig: config };
|
|
784
1068
|
}
|
|
785
|
-
async listTaskPushNotificationConfigs(params) {
|
|
1069
|
+
async listTaskPushNotificationConfigs(params, context) {
|
|
786
1070
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
787
1071
|
throw A2AError.pushNotificationNotSupported();
|
|
788
1072
|
}
|
|
789
|
-
const task = await this.taskStore.load(params.id);
|
|
1073
|
+
const task = await this.taskStore.load(params.id, context);
|
|
790
1074
|
if (!task) {
|
|
791
1075
|
throw A2AError.taskNotFound(params.id);
|
|
792
1076
|
}
|
|
@@ -796,22 +1080,22 @@ var DefaultRequestHandler = class {
|
|
|
796
1080
|
pushNotificationConfig: config
|
|
797
1081
|
}));
|
|
798
1082
|
}
|
|
799
|
-
async deleteTaskPushNotificationConfig(params) {
|
|
1083
|
+
async deleteTaskPushNotificationConfig(params, context) {
|
|
800
1084
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
801
1085
|
throw A2AError.pushNotificationNotSupported();
|
|
802
1086
|
}
|
|
803
|
-
const task = await this.taskStore.load(params.id);
|
|
1087
|
+
const task = await this.taskStore.load(params.id, context);
|
|
804
1088
|
if (!task) {
|
|
805
1089
|
throw A2AError.taskNotFound(params.id);
|
|
806
1090
|
}
|
|
807
1091
|
const { id: taskId, pushNotificationConfigId } = params;
|
|
808
1092
|
await this.pushNotificationStore?.delete(taskId, pushNotificationConfigId);
|
|
809
1093
|
}
|
|
810
|
-
async *resubscribe(params) {
|
|
1094
|
+
async *resubscribe(params, context) {
|
|
811
1095
|
if (!this.agentCard.capabilities.streaming) {
|
|
812
1096
|
throw A2AError.unsupportedOperation("Streaming (and thus resubscription) is not supported.");
|
|
813
1097
|
}
|
|
814
|
-
const task = await this.taskStore.load(params.id);
|
|
1098
|
+
const task = await this.taskStore.load(params.id, context);
|
|
815
1099
|
if (!task) {
|
|
816
1100
|
throw A2AError.taskNotFound(params.id);
|
|
817
1101
|
}
|
|
@@ -840,7 +1124,7 @@ var DefaultRequestHandler = class {
|
|
|
840
1124
|
eventQueue.stop();
|
|
841
1125
|
}
|
|
842
1126
|
}
|
|
843
|
-
async _sendPushNotificationIfNeeded(event) {
|
|
1127
|
+
async _sendPushNotificationIfNeeded(event, context) {
|
|
844
1128
|
if (!this.agentCard.capabilities.pushNotifications) {
|
|
845
1129
|
return;
|
|
846
1130
|
}
|
|
@@ -855,13 +1139,53 @@ var DefaultRequestHandler = class {
|
|
|
855
1139
|
console.error(`Task ID not found for event ${event.kind}.`);
|
|
856
1140
|
return;
|
|
857
1141
|
}
|
|
858
|
-
const task = await this.taskStore.load(taskId);
|
|
1142
|
+
const task = await this.taskStore.load(taskId, context);
|
|
859
1143
|
if (!task) {
|
|
860
1144
|
console.error(`Task ${taskId} not found.`);
|
|
861
1145
|
return;
|
|
862
1146
|
}
|
|
863
1147
|
this.pushNotificationSender?.send(task);
|
|
864
1148
|
}
|
|
1149
|
+
async _handleProcessingError(error, resultManager, firstResultSent, taskId, firstResultRejector) {
|
|
1150
|
+
if (firstResultRejector && !firstResultSent) {
|
|
1151
|
+
firstResultRejector(error);
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
if (!firstResultRejector) {
|
|
1155
|
+
throw error;
|
|
1156
|
+
}
|
|
1157
|
+
const currentTask = resultManager.getCurrentTask();
|
|
1158
|
+
const errorMessage = error instanceof Error && error.message || "Unknown error";
|
|
1159
|
+
if (currentTask) {
|
|
1160
|
+
const statusUpdateFailed = {
|
|
1161
|
+
taskId: currentTask.id,
|
|
1162
|
+
contextId: currentTask.contextId,
|
|
1163
|
+
status: {
|
|
1164
|
+
state: "failed",
|
|
1165
|
+
message: {
|
|
1166
|
+
kind: "message",
|
|
1167
|
+
role: "agent",
|
|
1168
|
+
messageId: (0, import_uuid.v4)(),
|
|
1169
|
+
parts: [{ kind: "text", text: `Event processing loop failed: ${errorMessage}` }],
|
|
1170
|
+
taskId: currentTask.id,
|
|
1171
|
+
contextId: currentTask.contextId
|
|
1172
|
+
},
|
|
1173
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1174
|
+
},
|
|
1175
|
+
kind: "status-update",
|
|
1176
|
+
final: true
|
|
1177
|
+
};
|
|
1178
|
+
try {
|
|
1179
|
+
await resultManager.processEvent(statusUpdateFailed);
|
|
1180
|
+
} catch (error2) {
|
|
1181
|
+
console.error(
|
|
1182
|
+
`Event processing loop failed for task ${taskId}: ${error2 instanceof Error && error2.message || "Unknown error"}`
|
|
1183
|
+
);
|
|
1184
|
+
}
|
|
1185
|
+
} else {
|
|
1186
|
+
console.error(`Event processing loop failed for task ${taskId}: ${errorMessage}`);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
865
1189
|
};
|
|
866
1190
|
|
|
867
1191
|
// src/server/store.ts
|
|
@@ -876,7 +1200,7 @@ var InMemoryTaskStore = class {
|
|
|
876
1200
|
}
|
|
877
1201
|
};
|
|
878
1202
|
|
|
879
|
-
// src/server/transports/jsonrpc_transport_handler.ts
|
|
1203
|
+
// src/server/transports/jsonrpc/jsonrpc_transport_handler.ts
|
|
880
1204
|
var JsonRpcTransportHandler = class {
|
|
881
1205
|
requestHandler;
|
|
882
1206
|
constructor(requestHandler) {
|
|
@@ -887,7 +1211,7 @@ var JsonRpcTransportHandler = class {
|
|
|
887
1211
|
* For streaming methods, it returns an AsyncGenerator of JSONRPCResult.
|
|
888
1212
|
* For non-streaming methods, it returns a Promise of a single JSONRPCMessage (Result or ErrorResponse).
|
|
889
1213
|
*/
|
|
890
|
-
async handle(requestBody) {
|
|
1214
|
+
async handle(requestBody, context) {
|
|
891
1215
|
let rpcRequest;
|
|
892
1216
|
try {
|
|
893
1217
|
if (typeof requestBody === "string") {
|
|
@@ -901,24 +1225,18 @@ var JsonRpcTransportHandler = class {
|
|
|
901
1225
|
throw A2AError.invalidRequest("Invalid JSON-RPC Request.");
|
|
902
1226
|
}
|
|
903
1227
|
} catch (error) {
|
|
904
|
-
const a2aError = error instanceof A2AError ? error : A2AError.parseError(
|
|
1228
|
+
const a2aError = error instanceof A2AError ? error : A2AError.parseError(
|
|
1229
|
+
error instanceof SyntaxError && error.message || "Failed to parse JSON request."
|
|
1230
|
+
);
|
|
905
1231
|
return {
|
|
906
1232
|
jsonrpc: "2.0",
|
|
907
|
-
id:
|
|
1233
|
+
id: rpcRequest?.id !== void 0 ? rpcRequest.id : null,
|
|
908
1234
|
error: a2aError.toJSONRPCError()
|
|
909
1235
|
};
|
|
910
1236
|
}
|
|
911
1237
|
const { method, id: requestId = null } = rpcRequest;
|
|
912
1238
|
try {
|
|
913
|
-
if (method
|
|
914
|
-
const result = await this.requestHandler.getAuthenticatedExtendedAgentCard();
|
|
915
|
-
return {
|
|
916
|
-
jsonrpc: "2.0",
|
|
917
|
-
id: requestId,
|
|
918
|
-
result
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
if (!this.paramsAreValid(rpcRequest.params)) {
|
|
1239
|
+
if (method !== "agent/getAuthenticatedExtendedCard" && !this.paramsAreValid(rpcRequest.params)) {
|
|
922
1240
|
throw A2AError.invalidParams(`Invalid method parameters.`);
|
|
923
1241
|
}
|
|
924
1242
|
if (method === "message/stream" || method === "tasks/resubscribe") {
|
|
@@ -927,8 +1245,8 @@ var JsonRpcTransportHandler = class {
|
|
|
927
1245
|
if (!agentCard.capabilities.streaming) {
|
|
928
1246
|
throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
|
|
929
1247
|
}
|
|
930
|
-
const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params) : this.requestHandler.resubscribe(params);
|
|
931
|
-
return async function* jsonRpcEventStream() {
|
|
1248
|
+
const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params, context) : this.requestHandler.resubscribe(params, context);
|
|
1249
|
+
return (async function* jsonRpcEventStream() {
|
|
932
1250
|
try {
|
|
933
1251
|
for await (const event of agentEventStream) {
|
|
934
1252
|
yield {
|
|
@@ -939,43 +1257,50 @@ var JsonRpcTransportHandler = class {
|
|
|
939
1257
|
};
|
|
940
1258
|
}
|
|
941
1259
|
} catch (streamError) {
|
|
942
|
-
console.error(
|
|
1260
|
+
console.error(
|
|
1261
|
+
`Error in agent event stream for ${method} (request ${requestId}):`,
|
|
1262
|
+
streamError
|
|
1263
|
+
);
|
|
943
1264
|
throw streamError;
|
|
944
1265
|
}
|
|
945
|
-
}();
|
|
1266
|
+
})();
|
|
946
1267
|
} else {
|
|
947
1268
|
let result;
|
|
948
1269
|
switch (method) {
|
|
949
1270
|
case "message/send":
|
|
950
|
-
result = await this.requestHandler.sendMessage(rpcRequest.params);
|
|
1271
|
+
result = await this.requestHandler.sendMessage(rpcRequest.params, context);
|
|
951
1272
|
break;
|
|
952
1273
|
case "tasks/get":
|
|
953
|
-
result = await this.requestHandler.getTask(rpcRequest.params);
|
|
1274
|
+
result = await this.requestHandler.getTask(rpcRequest.params, context);
|
|
954
1275
|
break;
|
|
955
1276
|
case "tasks/cancel":
|
|
956
|
-
result = await this.requestHandler.cancelTask(rpcRequest.params);
|
|
1277
|
+
result = await this.requestHandler.cancelTask(rpcRequest.params, context);
|
|
957
1278
|
break;
|
|
958
1279
|
case "tasks/pushNotificationConfig/set":
|
|
959
1280
|
result = await this.requestHandler.setTaskPushNotificationConfig(
|
|
960
|
-
rpcRequest.params
|
|
1281
|
+
rpcRequest.params,
|
|
1282
|
+
context
|
|
961
1283
|
);
|
|
962
1284
|
break;
|
|
963
1285
|
case "tasks/pushNotificationConfig/get":
|
|
964
1286
|
result = await this.requestHandler.getTaskPushNotificationConfig(
|
|
965
|
-
rpcRequest.params
|
|
1287
|
+
rpcRequest.params,
|
|
1288
|
+
context
|
|
966
1289
|
);
|
|
967
1290
|
break;
|
|
968
1291
|
case "tasks/pushNotificationConfig/delete":
|
|
969
|
-
await this.requestHandler.deleteTaskPushNotificationConfig(
|
|
970
|
-
rpcRequest.params
|
|
971
|
-
);
|
|
1292
|
+
await this.requestHandler.deleteTaskPushNotificationConfig(rpcRequest.params, context);
|
|
972
1293
|
result = null;
|
|
973
1294
|
break;
|
|
974
1295
|
case "tasks/pushNotificationConfig/list":
|
|
975
1296
|
result = await this.requestHandler.listTaskPushNotificationConfigs(
|
|
976
|
-
rpcRequest.params
|
|
1297
|
+
rpcRequest.params,
|
|
1298
|
+
context
|
|
977
1299
|
);
|
|
978
1300
|
break;
|
|
1301
|
+
case "agent/getAuthenticatedExtendedCard":
|
|
1302
|
+
result = await this.requestHandler.getAuthenticatedExtendedAgentCard(context);
|
|
1303
|
+
break;
|
|
979
1304
|
default:
|
|
980
1305
|
throw A2AError.methodNotFound(method);
|
|
981
1306
|
}
|
|
@@ -986,7 +1311,14 @@ var JsonRpcTransportHandler = class {
|
|
|
986
1311
|
};
|
|
987
1312
|
}
|
|
988
1313
|
} catch (error) {
|
|
989
|
-
|
|
1314
|
+
let a2aError;
|
|
1315
|
+
if (error instanceof A2AError) {
|
|
1316
|
+
a2aError = error;
|
|
1317
|
+
} else {
|
|
1318
|
+
a2aError = A2AError.internalError(
|
|
1319
|
+
error instanceof Error && error.message || "An unexpected error occurred."
|
|
1320
|
+
);
|
|
1321
|
+
}
|
|
990
1322
|
return {
|
|
991
1323
|
jsonrpc: "2.0",
|
|
992
1324
|
id: requestId,
|
|
@@ -1026,6 +1358,16 @@ var JsonRpcTransportHandler = class {
|
|
|
1026
1358
|
return true;
|
|
1027
1359
|
}
|
|
1028
1360
|
};
|
|
1361
|
+
|
|
1362
|
+
// src/server/authentication/user.ts
|
|
1363
|
+
var UnauthenticatedUser = class {
|
|
1364
|
+
get isAuthenticated() {
|
|
1365
|
+
return false;
|
|
1366
|
+
}
|
|
1367
|
+
get userName() {
|
|
1368
|
+
return "";
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1029
1371
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1030
1372
|
0 && (module.exports = {
|
|
1031
1373
|
A2AError,
|
|
@@ -1038,5 +1380,7 @@ var JsonRpcTransportHandler = class {
|
|
|
1038
1380
|
InMemoryTaskStore,
|
|
1039
1381
|
JsonRpcTransportHandler,
|
|
1040
1382
|
RequestContext,
|
|
1041
|
-
ResultManager
|
|
1383
|
+
ResultManager,
|
|
1384
|
+
ServerCallContext,
|
|
1385
|
+
UnauthenticatedUser
|
|
1042
1386
|
});
|