@glinr/theauth 0.4.2

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.
@@ -0,0 +1,826 @@
1
+ import * as jose from 'jose';
2
+ import { z } from 'zod';
3
+
4
+ // src/a2a/agent-card.ts
5
+
6
+ // src/crypto/web-crypto.ts
7
+ function generateId() {
8
+ return globalThis.crypto.randomUUID();
9
+ }
10
+ new TextEncoder();
11
+ var A2A_PROTOCOL_VERSION = "0.3";
12
+ var A2A_JSONRPC_VERSION = "2.0";
13
+ var A2A_WELL_KNOWN_PATH = "/.well-known/agent.json";
14
+ var A2A_ERROR_CODES = {
15
+ PARSE_ERROR: -32700,
16
+ INVALID_REQUEST: -32600,
17
+ METHOD_NOT_FOUND: -32601,
18
+ INVALID_PARAMS: -32602,
19
+ INTERNAL_ERROR: -32603,
20
+ // A2A-specific codes (application-defined range)
21
+ TASK_NOT_FOUND: -32001,
22
+ AGENT_NOT_FOUND: -32002,
23
+ AUTHENTICATION_REQUIRED: -32003,
24
+ PERMISSION_DENIED: -32004,
25
+ RATE_LIMITED: -32005,
26
+ TASK_ALREADY_COMPLETED: -32006
27
+ };
28
+ var A2A_METHODS = {
29
+ SEND_MESSAGE: "message/send",
30
+ SEND_STREAMING_MESSAGE: "message/stream",
31
+ GET_TASK: "tasks/get",
32
+ CANCEL_TASK: "tasks/cancel"
33
+ };
34
+ var A2ATextPartSchema = z.object({
35
+ type: z.literal("text"),
36
+ text: z.string()
37
+ });
38
+ var A2AFilePartSchema = z.object({
39
+ type: z.literal("file"),
40
+ fileUri: z.string(),
41
+ mimeType: z.string(),
42
+ name: z.string().optional()
43
+ });
44
+ var A2ADataPartSchema = z.object({
45
+ type: z.literal("data"),
46
+ mimeType: z.string(),
47
+ data: z.string()
48
+ });
49
+ var A2APartSchema = z.discriminatedUnion("type", [
50
+ A2ATextPartSchema,
51
+ A2AFilePartSchema,
52
+ A2ADataPartSchema
53
+ ]);
54
+ var A2AMessageSchema = z.object({
55
+ id: z.string().min(1),
56
+ role: z.enum(["user", "agent"]),
57
+ parts: z.array(A2APartSchema).min(1),
58
+ createdAt: z.string(),
59
+ metadata: z.record(z.unknown()).optional(),
60
+ referenceTaskIds: z.array(z.string()).optional()
61
+ });
62
+ var A2ATaskStateSchema = z.enum([
63
+ "submitted",
64
+ "working",
65
+ "input-required",
66
+ "completed",
67
+ "failed",
68
+ "canceled",
69
+ "auth-required",
70
+ "rejected"
71
+ ]);
72
+ var A2ATaskStatusSchema = z.object({
73
+ code: A2ATaskStateSchema,
74
+ message: z.string().optional(),
75
+ progress: z.number().min(0).max(100).optional()
76
+ });
77
+ var A2AArtifactSchema = z.object({
78
+ id: z.string().min(1),
79
+ name: z.string().optional(),
80
+ mimeType: z.string().optional(),
81
+ parts: z.array(A2APartSchema).min(1),
82
+ metadata: z.record(z.unknown()).optional(),
83
+ createdAt: z.string()
84
+ });
85
+ var A2ATaskSchema = z.object({
86
+ id: z.string().min(1),
87
+ contextId: z.string().min(1),
88
+ status: A2ATaskStatusSchema,
89
+ createdAt: z.string(),
90
+ updatedAt: z.string(),
91
+ history: z.array(A2AMessageSchema).optional(),
92
+ artifacts: z.array(A2AArtifactSchema).optional(),
93
+ metadata: z.record(z.unknown()).optional()
94
+ });
95
+ var A2AAgentSkillSchema = z.object({
96
+ id: z.string().min(1),
97
+ name: z.string().min(1),
98
+ description: z.string(),
99
+ inputSchema: z.record(z.unknown()).optional(),
100
+ outputSchema: z.record(z.unknown()).optional(),
101
+ supportedMediaTypes: z.array(z.string()).optional(),
102
+ tags: z.array(z.string()).optional()
103
+ });
104
+ var A2AAgentProviderSchema = z.object({
105
+ name: z.string().min(1),
106
+ email: z.string().optional(),
107
+ url: z.string().optional()
108
+ });
109
+ var A2AAgentCapabilitiesSchema = z.object({
110
+ streaming: z.boolean().optional(),
111
+ pushNotifications: z.boolean().optional(),
112
+ extendedAgentCard: z.boolean().optional()
113
+ });
114
+ var A2ASecuritySchemeBaseSchema = z.object({
115
+ description: z.string().optional()
116
+ });
117
+ var A2AApiKeySecuritySchemeSchema = A2ASecuritySchemeBaseSchema.extend({
118
+ type: z.literal("apiKey"),
119
+ name: z.string().min(1),
120
+ in: z.enum(["query", "header", "cookie"])
121
+ });
122
+ var A2AHttpSecuritySchemeSchema = A2ASecuritySchemeBaseSchema.extend({
123
+ type: z.literal("http"),
124
+ scheme: z.string().min(1),
125
+ bearerFormat: z.string().optional()
126
+ });
127
+ var A2AOAuth2FlowSchema = z.object({
128
+ authorizationUrl: z.string().optional(),
129
+ tokenUrl: z.string().optional(),
130
+ refreshUrl: z.string().optional(),
131
+ scopes: z.record(z.string())
132
+ });
133
+ var A2AOAuth2SecuritySchemeSchema = A2ASecuritySchemeBaseSchema.extend({
134
+ type: z.literal("oauth2"),
135
+ flows: z.object({
136
+ implicit: A2AOAuth2FlowSchema.optional(),
137
+ password: A2AOAuth2FlowSchema.optional(),
138
+ clientCredentials: A2AOAuth2FlowSchema.optional(),
139
+ authorizationCode: A2AOAuth2FlowSchema.optional(),
140
+ deviceCode: A2AOAuth2FlowSchema.optional()
141
+ })
142
+ });
143
+ var A2AOidcSecuritySchemeSchema = A2ASecuritySchemeBaseSchema.extend({
144
+ type: z.literal("openIdConnect"),
145
+ openIdConnectUrl: z.string().min(1)
146
+ });
147
+ var A2AMutualTlsSecuritySchemeSchema = A2ASecuritySchemeBaseSchema.extend({
148
+ type: z.literal("mutualTls")
149
+ });
150
+ var A2ASecuritySchemeSchema = z.discriminatedUnion("type", [
151
+ A2AApiKeySecuritySchemeSchema,
152
+ A2AHttpSecuritySchemeSchema,
153
+ A2AOAuth2SecuritySchemeSchema,
154
+ A2AOidcSecuritySchemeSchema,
155
+ A2AMutualTlsSecuritySchemeSchema
156
+ ]);
157
+ var A2AAgentCardSignatureSchema = z.object({
158
+ algorithm: z.string().min(1),
159
+ signature: z.string().min(1),
160
+ keyId: z.string().min(1)
161
+ });
162
+ var A2AAgentCardSchema = z.object({
163
+ id: z.string().min(1),
164
+ name: z.string().min(1),
165
+ description: z.string(),
166
+ version: z.string().min(1),
167
+ protocolVersion: z.string().min(1),
168
+ url: z.string().url(),
169
+ provider: A2AAgentProviderSchema.optional(),
170
+ capabilities: A2AAgentCapabilitiesSchema.optional(),
171
+ skills: z.array(A2AAgentSkillSchema).min(1),
172
+ securitySchemes: z.record(A2ASecuritySchemeSchema).optional(),
173
+ security: z.array(z.record(z.array(z.string()))).optional(),
174
+ defaultInputModes: z.array(z.string()).optional(),
175
+ defaultOutputModes: z.array(z.string()).optional(),
176
+ documentationUrl: z.string().url().optional(),
177
+ signature: A2AAgentCardSignatureSchema.optional(),
178
+ metadata: z.record(z.unknown()).optional()
179
+ });
180
+ var A2ASendMessageConfigurationSchema = z.object({
181
+ acceptedOutputModes: z.array(z.string()).optional(),
182
+ historyLength: z.number().int().min(0).optional(),
183
+ returnImmediately: z.boolean().optional()
184
+ });
185
+ var A2ASendMessageParamsSchema = z.object({
186
+ message: A2AMessageSchema,
187
+ configuration: A2ASendMessageConfigurationSchema.optional(),
188
+ metadata: z.record(z.unknown()).optional()
189
+ });
190
+ var A2AGetTaskParamsSchema = z.object({
191
+ id: z.string().min(1),
192
+ historyLength: z.number().int().min(0).optional()
193
+ });
194
+ var A2ACancelTaskParamsSchema = z.object({
195
+ id: z.string().min(1),
196
+ metadata: z.record(z.unknown()).optional()
197
+ });
198
+ var A2AJsonRpcRequestSchema = z.object({
199
+ jsonrpc: z.literal("2.0"),
200
+ id: z.union([z.string(), z.number()]),
201
+ method: z.string().min(1),
202
+ params: z.unknown()
203
+ });
204
+
205
+ // src/a2a/agent-card.ts
206
+ function createAgentCard(input) {
207
+ const card = {
208
+ id: input.agent.id,
209
+ name: input.agent.name,
210
+ description: input.description,
211
+ version: input.version,
212
+ protocolVersion: A2A_PROTOCOL_VERSION,
213
+ url: input.url,
214
+ skills: input.skills
215
+ };
216
+ if (input.provider) card.provider = input.provider;
217
+ if (input.capabilities) card.capabilities = input.capabilities;
218
+ if (input.securitySchemes) card.securitySchemes = input.securitySchemes;
219
+ if (input.security) card.security = input.security;
220
+ if (input.defaultInputModes) card.defaultInputModes = input.defaultInputModes;
221
+ if (input.defaultOutputModes) card.defaultOutputModes = input.defaultOutputModes;
222
+ if (input.documentationUrl) card.documentationUrl = input.documentationUrl;
223
+ if (input.metadata) card.metadata = input.metadata;
224
+ return card;
225
+ }
226
+ function validateAgentCard(card) {
227
+ const parsed = A2AAgentCardSchema.safeParse(card);
228
+ if (!parsed.success) {
229
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`);
230
+ return {
231
+ success: false,
232
+ error: {
233
+ code: "A2A_INVALID_AGENT_CARD",
234
+ message: `Invalid Agent Card: ${issues.join("; ")}`,
235
+ details: { issues }
236
+ }
237
+ };
238
+ }
239
+ return { success: true, data: parsed.data };
240
+ }
241
+ async function signAgentCard(options) {
242
+ const { card, privateKey, algorithm = "ES256", keyId } = options;
243
+ try {
244
+ const { signature: _ignored, ...cardWithoutSignature } = card;
245
+ const payload = new TextEncoder().encode(JSON.stringify(cardWithoutSignature));
246
+ const key = "kty" in privateKey ? await jose.importJWK(privateKey, algorithm) : privateKey;
247
+ const kid = keyId ?? generateId();
248
+ const jws = await new jose.CompactSign(payload).setProtectedHeader({ alg: algorithm, kid }).sign(key);
249
+ const signedCard = {
250
+ ...card,
251
+ signature: {
252
+ algorithm,
253
+ signature: jws,
254
+ keyId: kid
255
+ }
256
+ };
257
+ return { success: true, data: signedCard };
258
+ } catch (err) {
259
+ return {
260
+ success: false,
261
+ error: {
262
+ code: "A2A_SIGN_FAILED",
263
+ message: err instanceof Error ? err.message : "Failed to sign agent card"
264
+ }
265
+ };
266
+ }
267
+ }
268
+ async function verifyAgentCard(options) {
269
+ const { card, publicKey } = options;
270
+ if (!card.signature) {
271
+ return {
272
+ success: false,
273
+ error: {
274
+ code: "A2A_NO_SIGNATURE",
275
+ message: "Agent Card has no signature to verify"
276
+ }
277
+ };
278
+ }
279
+ try {
280
+ const { signature, ...cardWithoutSignature } = card;
281
+ const algorithm = signature.algorithm;
282
+ const key = "kty" in publicKey ? await jose.importJWK(publicKey, algorithm) : publicKey;
283
+ const { payload } = await jose.compactVerify(signature.signature, key);
284
+ const decoded = new TextDecoder().decode(payload);
285
+ const signedContent = JSON.parse(decoded);
286
+ const currentContent = JSON.stringify(cardWithoutSignature);
287
+ const parsedCurrentContent = JSON.parse(currentContent);
288
+ const matches = JSON.stringify(signedContent) === JSON.stringify(parsedCurrentContent);
289
+ return {
290
+ success: true,
291
+ data: { valid: matches, card }
292
+ };
293
+ } catch (err) {
294
+ return {
295
+ success: false,
296
+ error: {
297
+ code: "A2A_VERIFY_FAILED",
298
+ message: err instanceof Error ? err.message : "Failed to verify agent card signature"
299
+ }
300
+ };
301
+ }
302
+ }
303
+
304
+ // src/a2a/client.ts
305
+ function createA2AClient(config) {
306
+ const fetchFn = config.fetch ?? globalThis.fetch;
307
+ const timeout = config.timeout ?? 3e4;
308
+ let cachedCard;
309
+ function getBaseUrl() {
310
+ if (typeof config.agent === "string") {
311
+ return config.agent.replace(/\/$/, "");
312
+ }
313
+ return config.agent.url.replace(/\/$/, "");
314
+ }
315
+ if (typeof config.agent !== "string") {
316
+ cachedCard = config.agent;
317
+ }
318
+ async function getAuthHeaders() {
319
+ if (!config.getAuthToken) return {};
320
+ const token = await config.getAuthToken();
321
+ return { Authorization: `Bearer ${token}` };
322
+ }
323
+ async function jsonRpcCall(method, params) {
324
+ const baseUrl = cachedCard?.url ?? getBaseUrl();
325
+ const authHeaders = await getAuthHeaders();
326
+ const controller = new AbortController();
327
+ const timer = setTimeout(() => controller.abort(), timeout);
328
+ try {
329
+ const response = await fetchFn(baseUrl, {
330
+ method: "POST",
331
+ headers: {
332
+ "Content-Type": "application/json",
333
+ ...authHeaders
334
+ },
335
+ body: JSON.stringify({
336
+ jsonrpc: A2A_JSONRPC_VERSION,
337
+ id: generateId(),
338
+ method,
339
+ params
340
+ }),
341
+ signal: controller.signal
342
+ });
343
+ if (!response.ok) {
344
+ return {
345
+ success: false,
346
+ error: {
347
+ code: "A2A_HTTP_ERROR",
348
+ message: `HTTP ${response.status}: ${response.statusText}`
349
+ }
350
+ };
351
+ }
352
+ const body = await response.json();
353
+ if (body.error) {
354
+ return {
355
+ success: false,
356
+ error: {
357
+ code: `A2A_RPC_${body.error.code}`,
358
+ message: body.error.message,
359
+ details: body.error.data ? { data: body.error.data } : void 0
360
+ }
361
+ };
362
+ }
363
+ return { success: true, data: body.result };
364
+ } catch (err) {
365
+ if (err instanceof DOMException && err.name === "AbortError") {
366
+ return {
367
+ success: false,
368
+ error: {
369
+ code: "A2A_TIMEOUT",
370
+ message: `Request timed out after ${timeout}ms`
371
+ }
372
+ };
373
+ }
374
+ return {
375
+ success: false,
376
+ error: {
377
+ code: "A2A_REQUEST_FAILED",
378
+ message: err instanceof Error ? err.message : "Request failed"
379
+ }
380
+ };
381
+ } finally {
382
+ clearTimeout(timer);
383
+ }
384
+ }
385
+ async function discover() {
386
+ if (cachedCard) {
387
+ return { success: true, data: cachedCard };
388
+ }
389
+ const baseUrl = getBaseUrl();
390
+ const url = `${baseUrl}${A2A_WELL_KNOWN_PATH}`;
391
+ const authHeaders = await getAuthHeaders();
392
+ const controller = new AbortController();
393
+ const timer = setTimeout(() => controller.abort(), timeout);
394
+ try {
395
+ const response = await fetchFn(url, {
396
+ method: "GET",
397
+ headers: authHeaders,
398
+ signal: controller.signal
399
+ });
400
+ if (!response.ok) {
401
+ return {
402
+ success: false,
403
+ error: {
404
+ code: "A2A_DISCOVERY_FAILED",
405
+ message: `Discovery failed: HTTP ${response.status}`
406
+ }
407
+ };
408
+ }
409
+ const body = await response.json();
410
+ const parsed = A2AAgentCardSchema.safeParse(body);
411
+ if (!parsed.success) {
412
+ return {
413
+ success: false,
414
+ error: {
415
+ code: "A2A_INVALID_AGENT_CARD",
416
+ message: `Invalid agent card: ${parsed.error.issues.map((i) => i.message).join("; ")}`
417
+ }
418
+ };
419
+ }
420
+ cachedCard = parsed.data;
421
+ return { success: true, data: cachedCard };
422
+ } catch (err) {
423
+ return {
424
+ success: false,
425
+ error: {
426
+ code: "A2A_DISCOVERY_FAILED",
427
+ message: err instanceof Error ? err.message : "Discovery request failed"
428
+ }
429
+ };
430
+ } finally {
431
+ clearTimeout(timer);
432
+ }
433
+ }
434
+ async function sendMessage(params) {
435
+ return jsonRpcCall(A2A_METHODS.SEND_MESSAGE, params);
436
+ }
437
+ async function getTask(params) {
438
+ return jsonRpcCall(A2A_METHODS.GET_TASK, params);
439
+ }
440
+ async function cancelTask(params) {
441
+ return jsonRpcCall(A2A_METHODS.CANCEL_TASK, params);
442
+ }
443
+ async function* sendStreamingMessage(params) {
444
+ const baseUrl = cachedCard?.url ?? getBaseUrl();
445
+ const authHeaders = await getAuthHeaders();
446
+ const response = await fetchFn(baseUrl, {
447
+ method: "POST",
448
+ headers: {
449
+ "Content-Type": "application/json",
450
+ Accept: "text/event-stream",
451
+ ...authHeaders
452
+ },
453
+ body: JSON.stringify({
454
+ jsonrpc: A2A_JSONRPC_VERSION,
455
+ id: generateId(),
456
+ method: A2A_METHODS.SEND_STREAMING_MESSAGE,
457
+ params
458
+ })
459
+ });
460
+ if (!response.ok || !response.body) {
461
+ throw new Error(`Streaming request failed: HTTP ${response.status}`);
462
+ }
463
+ const reader = response.body.getReader();
464
+ const decoder = new TextDecoder();
465
+ let buffer = "";
466
+ try {
467
+ while (true) {
468
+ const { done, value } = await reader.read();
469
+ if (done) break;
470
+ buffer += decoder.decode(value, { stream: true });
471
+ const lines = buffer.split("\n");
472
+ buffer = lines.pop() ?? "";
473
+ for (const line of lines) {
474
+ if (line.startsWith("data: ")) {
475
+ const data = line.slice(6).trim();
476
+ if (data === "[DONE]") return;
477
+ try {
478
+ yield JSON.parse(data);
479
+ } catch {
480
+ }
481
+ }
482
+ }
483
+ }
484
+ } finally {
485
+ reader.releaseLock();
486
+ }
487
+ }
488
+ return {
489
+ discover,
490
+ sendMessage,
491
+ getTask,
492
+ cancelTask,
493
+ sendStreamingMessage
494
+ };
495
+ }
496
+
497
+ // src/a2a/server.ts
498
+ function createInMemoryTaskStore() {
499
+ const tasks = /* @__PURE__ */ new Map();
500
+ return {
501
+ async get(taskId) {
502
+ return tasks.get(taskId);
503
+ },
504
+ async set(taskId, task) {
505
+ tasks.set(taskId, task);
506
+ },
507
+ async delete(taskId) {
508
+ return tasks.delete(taskId);
509
+ }
510
+ };
511
+ }
512
+ function jsonRpcError(id, error) {
513
+ const body = {
514
+ jsonrpc: A2A_JSONRPC_VERSION,
515
+ id: id ?? 0,
516
+ error
517
+ };
518
+ return new Response(JSON.stringify(body), {
519
+ status: 200,
520
+ // JSON-RPC always returns 200
521
+ headers: { "Content-Type": "application/json" }
522
+ });
523
+ }
524
+ function jsonRpcSuccess(id, result) {
525
+ const body = {
526
+ jsonrpc: A2A_JSONRPC_VERSION,
527
+ id,
528
+ result
529
+ };
530
+ return new Response(JSON.stringify(body), {
531
+ status: 200,
532
+ headers: { "Content-Type": "application/json" }
533
+ });
534
+ }
535
+ function createA2AServer(config) {
536
+ const taskStore = config.taskStore ?? createInMemoryTaskStore();
537
+ async function audit(event) {
538
+ if (config.onAudit) {
539
+ await config.onAudit({
540
+ ...event,
541
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
542
+ });
543
+ }
544
+ }
545
+ async function authenticate(request) {
546
+ if (!config.authenticate) {
547
+ return { agentId: null, error: null };
548
+ }
549
+ const agentId = await config.authenticate(request);
550
+ if (agentId === null) {
551
+ return {
552
+ agentId: null,
553
+ error: jsonRpcError(0, {
554
+ code: A2A_ERROR_CODES.AUTHENTICATION_REQUIRED,
555
+ message: "Authentication required"
556
+ })
557
+ };
558
+ }
559
+ return { agentId, error: null };
560
+ }
561
+ async function handleSendMessage(id, params, agentId) {
562
+ const parsed = A2ASendMessageParamsSchema.safeParse(params);
563
+ if (!parsed.success) {
564
+ await audit({
565
+ method: A2A_METHODS.SEND_MESSAGE,
566
+ agentId,
567
+ success: false,
568
+ error: "Invalid params"
569
+ });
570
+ return jsonRpcError(id, {
571
+ code: A2A_ERROR_CODES.INVALID_PARAMS,
572
+ message: `Invalid params: ${parsed.error.issues.map((i) => i.message).join("; ")}`
573
+ });
574
+ }
575
+ try {
576
+ const task = await config.handler.onMessage(parsed.data.message, parsed.data.configuration);
577
+ await taskStore.set(task.id, task);
578
+ await audit({
579
+ method: A2A_METHODS.SEND_MESSAGE,
580
+ agentId,
581
+ taskId: task.id,
582
+ success: true
583
+ });
584
+ return jsonRpcSuccess(id, task);
585
+ } catch (err) {
586
+ const message = err instanceof Error ? err.message : "Internal error";
587
+ await audit({
588
+ method: A2A_METHODS.SEND_MESSAGE,
589
+ agentId,
590
+ success: false,
591
+ error: message
592
+ });
593
+ return jsonRpcError(id, {
594
+ code: A2A_ERROR_CODES.INTERNAL_ERROR,
595
+ message
596
+ });
597
+ }
598
+ }
599
+ async function handleGetTask(id, params, agentId) {
600
+ const parsed = A2AGetTaskParamsSchema.safeParse(params);
601
+ if (!parsed.success) {
602
+ return jsonRpcError(id, {
603
+ code: A2A_ERROR_CODES.INVALID_PARAMS,
604
+ message: "Invalid params: id is required"
605
+ });
606
+ }
607
+ const task = await taskStore.get(parsed.data.id);
608
+ if (!task) {
609
+ await audit({
610
+ method: A2A_METHODS.GET_TASK,
611
+ agentId,
612
+ taskId: parsed.data.id,
613
+ success: false,
614
+ error: "Task not found"
615
+ });
616
+ return jsonRpcError(id, {
617
+ code: A2A_ERROR_CODES.TASK_NOT_FOUND,
618
+ message: `Task ${parsed.data.id} not found`
619
+ });
620
+ }
621
+ let result = task;
622
+ if (parsed.data.historyLength !== void 0 && task.history) {
623
+ const len = parsed.data.historyLength;
624
+ result = {
625
+ ...task,
626
+ history: len === 0 ? [] : task.history.slice(-len)
627
+ };
628
+ }
629
+ await audit({
630
+ method: A2A_METHODS.GET_TASK,
631
+ agentId,
632
+ taskId: task.id,
633
+ success: true
634
+ });
635
+ return jsonRpcSuccess(id, result);
636
+ }
637
+ async function handleCancelTask(id, params, agentId) {
638
+ const parsed = A2ACancelTaskParamsSchema.safeParse(params);
639
+ if (!parsed.success) {
640
+ return jsonRpcError(id, {
641
+ code: A2A_ERROR_CODES.INVALID_PARAMS,
642
+ message: "Invalid params: id is required"
643
+ });
644
+ }
645
+ const existing = await taskStore.get(parsed.data.id);
646
+ if (!existing) {
647
+ await audit({
648
+ method: A2A_METHODS.CANCEL_TASK,
649
+ agentId,
650
+ taskId: parsed.data.id,
651
+ success: false,
652
+ error: "Task not found"
653
+ });
654
+ return jsonRpcError(id, {
655
+ code: A2A_ERROR_CODES.TASK_NOT_FOUND,
656
+ message: `Task ${parsed.data.id} not found`
657
+ });
658
+ }
659
+ if (existing.status.code === "completed" || existing.status.code === "failed" || existing.status.code === "canceled") {
660
+ await audit({
661
+ method: A2A_METHODS.CANCEL_TASK,
662
+ agentId,
663
+ taskId: existing.id,
664
+ success: false,
665
+ error: "Task already in terminal state"
666
+ });
667
+ return jsonRpcError(id, {
668
+ code: A2A_ERROR_CODES.TASK_ALREADY_COMPLETED,
669
+ message: `Task ${parsed.data.id} is already ${existing.status.code}`
670
+ });
671
+ }
672
+ if (config.handler.onCancel) {
673
+ try {
674
+ const canceled2 = await config.handler.onCancel(parsed.data.id);
675
+ await taskStore.set(canceled2.id, canceled2);
676
+ await audit({
677
+ method: A2A_METHODS.CANCEL_TASK,
678
+ agentId,
679
+ taskId: canceled2.id,
680
+ success: true
681
+ });
682
+ return jsonRpcSuccess(id, canceled2);
683
+ } catch (err) {
684
+ const message = err instanceof Error ? err.message : "Cancel failed";
685
+ await audit({
686
+ method: A2A_METHODS.CANCEL_TASK,
687
+ agentId,
688
+ taskId: parsed.data.id,
689
+ success: false,
690
+ error: message
691
+ });
692
+ return jsonRpcError(id, {
693
+ code: A2A_ERROR_CODES.INTERNAL_ERROR,
694
+ message
695
+ });
696
+ }
697
+ }
698
+ const canceled = {
699
+ ...existing,
700
+ status: { code: "canceled", message: "Canceled by client" },
701
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
702
+ };
703
+ await taskStore.set(canceled.id, canceled);
704
+ await audit({
705
+ method: A2A_METHODS.CANCEL_TASK,
706
+ agentId,
707
+ taskId: canceled.id,
708
+ success: true
709
+ });
710
+ return jsonRpcSuccess(id, canceled);
711
+ }
712
+ function handleStreamingMessage(id, params, agentId) {
713
+ if (!config.handler.onMessageStream) {
714
+ return jsonRpcError(id, {
715
+ code: A2A_ERROR_CODES.METHOD_NOT_FOUND,
716
+ message: "Streaming not supported by this agent"
717
+ });
718
+ }
719
+ const parsed = A2ASendMessageParamsSchema.safeParse(params);
720
+ if (!parsed.success) {
721
+ return jsonRpcError(id, {
722
+ code: A2A_ERROR_CODES.INVALID_PARAMS,
723
+ message: "Invalid params"
724
+ });
725
+ }
726
+ const stream = config.handler.onMessageStream(parsed.data.message, parsed.data.configuration);
727
+ const encoder = new TextEncoder();
728
+ const readable = new ReadableStream({
729
+ async start(controller) {
730
+ try {
731
+ for await (const event of stream) {
732
+ const data = JSON.stringify(event);
733
+ controller.enqueue(encoder.encode(`data: ${data}
734
+
735
+ `));
736
+ }
737
+ controller.enqueue(encoder.encode("data: [DONE]\n\n"));
738
+ controller.close();
739
+ } catch (err) {
740
+ const errorData = JSON.stringify({
741
+ type: "error",
742
+ error: {
743
+ code: A2A_ERROR_CODES.INTERNAL_ERROR,
744
+ message: err instanceof Error ? err.message : "Stream error"
745
+ }
746
+ });
747
+ controller.enqueue(encoder.encode(`data: ${errorData}
748
+
749
+ `));
750
+ controller.close();
751
+ }
752
+ void audit({
753
+ method: A2A_METHODS.SEND_STREAMING_MESSAGE,
754
+ agentId,
755
+ success: true
756
+ });
757
+ }
758
+ });
759
+ return new Response(readable, {
760
+ status: 200,
761
+ headers: {
762
+ "Content-Type": "text/event-stream",
763
+ "Cache-Control": "no-cache",
764
+ Connection: "keep-alive"
765
+ }
766
+ });
767
+ }
768
+ async function handleRequest(request) {
769
+ const url = new URL(request.url);
770
+ if (request.method === "GET" && url.pathname.endsWith(A2A_WELL_KNOWN_PATH)) {
771
+ return new Response(JSON.stringify(config.agentCard), {
772
+ status: 200,
773
+ headers: { "Content-Type": "application/json" }
774
+ });
775
+ }
776
+ if (request.method !== "POST") {
777
+ return new Response("Method Not Allowed", { status: 405 });
778
+ }
779
+ const auth = await authenticate(request);
780
+ if (auth.error) return auth.error;
781
+ const agentId = auth.agentId;
782
+ let body;
783
+ try {
784
+ body = await request.json();
785
+ } catch {
786
+ return jsonRpcError(null, {
787
+ code: A2A_ERROR_CODES.PARSE_ERROR,
788
+ message: "Invalid JSON"
789
+ });
790
+ }
791
+ const envelope = A2AJsonRpcRequestSchema.safeParse(body);
792
+ if (!envelope.success) {
793
+ return jsonRpcError(null, {
794
+ code: A2A_ERROR_CODES.INVALID_REQUEST,
795
+ message: "Invalid JSON-RPC request"
796
+ });
797
+ }
798
+ const { id: reqId, method, params } = envelope.data;
799
+ switch (method) {
800
+ case A2A_METHODS.SEND_MESSAGE:
801
+ return handleSendMessage(reqId, params, agentId);
802
+ case A2A_METHODS.GET_TASK:
803
+ return handleGetTask(reqId, params, agentId);
804
+ case A2A_METHODS.CANCEL_TASK:
805
+ return handleCancelTask(reqId, params, agentId);
806
+ case A2A_METHODS.SEND_STREAMING_MESSAGE:
807
+ return handleStreamingMessage(reqId, params, agentId);
808
+ default:
809
+ await audit({
810
+ method,
811
+ agentId,
812
+ success: false,
813
+ error: "Method not found"
814
+ });
815
+ return jsonRpcError(reqId, {
816
+ code: A2A_ERROR_CODES.METHOD_NOT_FOUND,
817
+ message: `Unknown method: ${method}`
818
+ });
819
+ }
820
+ }
821
+ return { handleRequest, taskStore };
822
+ }
823
+
824
+ export { A2AAgentCapabilitiesSchema, A2AAgentCardSchema, A2AAgentCardSignatureSchema, A2AAgentProviderSchema, A2AAgentSkillSchema, A2AApiKeySecuritySchemeSchema, A2AArtifactSchema, A2ACancelTaskParamsSchema, A2ADataPartSchema, A2AFilePartSchema, A2AGetTaskParamsSchema, A2AHttpSecuritySchemeSchema, A2AJsonRpcRequestSchema, A2AMessageSchema, A2AMutualTlsSecuritySchemeSchema, A2AOAuth2FlowSchema, A2AOAuth2SecuritySchemeSchema, A2AOidcSecuritySchemeSchema, A2APartSchema, A2ASecuritySchemeSchema, A2ASendMessageConfigurationSchema, A2ASendMessageParamsSchema, A2ATaskSchema, A2ATaskStateSchema, A2ATaskStatusSchema, A2ATextPartSchema, A2A_ERROR_CODES, A2A_JSONRPC_VERSION, A2A_METHODS, A2A_PROTOCOL_VERSION, A2A_WELL_KNOWN_PATH, createA2AClient, createA2AServer, createAgentCard, signAgentCard, validateAgentCard, verifyAgentCard };
825
+ //# sourceMappingURL=index.js.map
826
+ //# sourceMappingURL=index.js.map