@cogitator-ai/a2a 0.2.1 → 0.3.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.
Files changed (57) hide show
  1. package/README.md +216 -7
  2. package/dist/adapters/express.d.ts.map +1 -1
  3. package/dist/adapters/express.js +24 -6
  4. package/dist/adapters/express.js.map +1 -1
  5. package/dist/adapters/fastify.d.ts.map +1 -1
  6. package/dist/adapters/fastify.js +25 -6
  7. package/dist/adapters/fastify.js.map +1 -1
  8. package/dist/adapters/hono.d.ts.map +1 -1
  9. package/dist/adapters/hono.js +22 -4
  10. package/dist/adapters/hono.js.map +1 -1
  11. package/dist/adapters/koa.d.ts.map +1 -1
  12. package/dist/adapters/koa.js +28 -6
  13. package/dist/adapters/koa.js.map +1 -1
  14. package/dist/adapters/next.d.ts +1 -6
  15. package/dist/adapters/next.d.ts.map +1 -1
  16. package/dist/adapters/next.js +22 -4
  17. package/dist/adapters/next.js.map +1 -1
  18. package/dist/agent-card.d.ts +10 -0
  19. package/dist/agent-card.d.ts.map +1 -1
  20. package/dist/agent-card.js +26 -0
  21. package/dist/agent-card.js.map +1 -1
  22. package/dist/client.d.ts +9 -1
  23. package/dist/client.d.ts.map +1 -1
  24. package/dist/client.js +67 -17
  25. package/dist/client.js.map +1 -1
  26. package/dist/errors.d.ts +2 -0
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +14 -0
  29. package/dist/errors.js.map +1 -1
  30. package/dist/index.d.ts +8 -5
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +4 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/push-notifications.d.ts +17 -0
  35. package/dist/push-notifications.d.ts.map +1 -0
  36. package/dist/push-notifications.js +97 -0
  37. package/dist/push-notifications.js.map +1 -0
  38. package/dist/redis-task-store.d.ts +28 -0
  39. package/dist/redis-task-store.d.ts.map +1 -0
  40. package/dist/redis-task-store.js +95 -0
  41. package/dist/redis-task-store.js.map +1 -0
  42. package/dist/server.d.ts +11 -0
  43. package/dist/server.d.ts.map +1 -1
  44. package/dist/server.js +139 -16
  45. package/dist/server.js.map +1 -1
  46. package/dist/task-manager.d.ts +3 -2
  47. package/dist/task-manager.d.ts.map +1 -1
  48. package/dist/task-manager.js +29 -2
  49. package/dist/task-manager.js.map +1 -1
  50. package/dist/task-store.d.ts.map +1 -1
  51. package/dist/task-store.js +6 -1
  52. package/dist/task-store.js.map +1 -1
  53. package/dist/types.d.ts +41 -2
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/types.js +1 -6
  56. package/dist/types.js.map +1 -1
  57. package/package.json +1 -1
package/README.md CHANGED
@@ -15,7 +15,12 @@ pnpm add @cogitator-ai/a2a
15
15
  - **asTool() Bridge** - Wrap remote A2A agents as local Cogitator tools
16
16
  - **Agent Card** - Auto-generate A2A Agent Cards from agent metadata
17
17
  - **Task Management** - Full task lifecycle (working, completed, failed, canceled)
18
- - **SSE Streaming** - Real-time streaming on both server and client
18
+ - **Multi-Turn Conversations** - Stateful conversations with contextId and continueTask
19
+ - **SSE Streaming** - Real-time streaming with token-level events
20
+ - **Push Notifications** - Webhook-based task event notifications
21
+ - **Agent Card Signing** - HMAC-SHA256 signing and verification
22
+ - **Extended Agent Card** - Authenticated endpoint with extra details
23
+ - **RedisTaskStore** - Production-grade task persistence
19
24
  - **Framework Adapters** - Express, Hono, Fastify, Koa, Next.js
20
25
  - **Zero Dependencies** - Own implementation from spec, no external A2A deps
21
26
 
@@ -97,6 +102,204 @@ const result = await cogitator.run(orchestrator, {
97
102
  });
98
103
  ```
99
104
 
105
+ ## Multi-Turn Conversations
106
+
107
+ Continue tasks within the same conversation context using `contextId` and `continueTask`:
108
+
109
+ ```typescript
110
+ const client = new A2AClient('https://remote-agent.example.com');
111
+
112
+ // Start a conversation
113
+ const task = await client.sendMessage({
114
+ role: 'user',
115
+ parts: [{ type: 'text', text: 'Research quantum computing' }],
116
+ });
117
+
118
+ // Continue the same task with follow-up
119
+ const updated = await client.continueTask(task.id, 'Now compare it with classical computing');
120
+
121
+ // Both tasks share the same contextId
122
+ console.log(task.contextId === updated.contextId); // true
123
+ ```
124
+
125
+ On the server side, multi-turn is handled automatically. When a message includes a `taskId`, the server calls `continueTask` which appends to the existing task history and re-runs the agent with full context.
126
+
127
+ ## Listing Tasks
128
+
129
+ Query tasks with filtering and pagination via `tasks/list`:
130
+
131
+ ```typescript
132
+ const client = new A2AClient('https://remote-agent.example.com');
133
+
134
+ // List all tasks
135
+ const tasks = await client.listTasks();
136
+
137
+ // Filter by context (conversation)
138
+ const conversationTasks = await client.listTasks({
139
+ contextId: 'ctx_abc123',
140
+ });
141
+
142
+ // Filter by state with pagination
143
+ const completedTasks = await client.listTasks({
144
+ state: 'completed',
145
+ limit: 10,
146
+ offset: 0,
147
+ });
148
+ ```
149
+
150
+ ## Token Streaming
151
+
152
+ SSE streaming includes token-level events alongside status and artifact updates:
153
+
154
+ ```typescript
155
+ for await (const event of client.sendMessageStream({
156
+ role: 'user',
157
+ parts: [{ type: 'text', text: 'Write a poem' }],
158
+ })) {
159
+ switch (event.type) {
160
+ case 'token':
161
+ process.stdout.write(event.token);
162
+ break;
163
+ case 'status-update':
164
+ console.log(`\nStatus: ${event.status.state}`);
165
+ break;
166
+ case 'artifact-update':
167
+ console.log(`\nArtifact: ${event.artifact.id}`);
168
+ break;
169
+ }
170
+ }
171
+ ```
172
+
173
+ The server emits `TokenStreamEvent` for each token generated by the LLM via the `onToken` callback, giving clients real-time character-by-character output.
174
+
175
+ ## RedisTaskStore
176
+
177
+ For production deployments, use `RedisTaskStore` instead of the default in-memory store:
178
+
179
+ ```typescript
180
+ import { A2AServer, RedisTaskStore } from '@cogitator-ai/a2a';
181
+ import Redis from 'ioredis';
182
+
183
+ const redis = new Redis('redis://localhost:6379');
184
+
185
+ const a2aServer = new A2AServer({
186
+ agents: { researcher },
187
+ cogitator,
188
+ taskStore: new RedisTaskStore({
189
+ client: redis,
190
+ keyPrefix: 'a2a:task:',
191
+ ttl: 86400, // 24h expiry
192
+ }),
193
+ });
194
+ ```
195
+
196
+ `RedisTaskStore` implements the full `TaskStore` interface including `list()` with filtering by `contextId`, `state`, pagination, and timestamp-based sorting.
197
+
198
+ ## Push Notifications
199
+
200
+ Register webhooks to receive task event notifications:
201
+
202
+ ```typescript
203
+ const client = new A2AClient('https://remote-agent.example.com');
204
+
205
+ // Start a task
206
+ const task = await client.sendMessage({
207
+ role: 'user',
208
+ parts: [{ type: 'text', text: 'Long running analysis' }],
209
+ });
210
+
211
+ // Register a webhook for this task
212
+ const config = await client.createPushNotification(task.id, {
213
+ webhookUrl: 'https://my-app.com/webhooks/a2a',
214
+ authenticationInfo: {
215
+ scheme: 'bearer',
216
+ credentials: { token: 'my-webhook-secret' },
217
+ },
218
+ });
219
+
220
+ // List registered webhooks
221
+ const configs = await client.listPushNotifications(task.id);
222
+
223
+ // Remove a webhook
224
+ await client.deletePushNotification(task.id, config.id!);
225
+ ```
226
+
227
+ Server-side setup requires a `PushNotificationStore`:
228
+
229
+ ```typescript
230
+ import { A2AServer, InMemoryPushNotificationStore } from '@cogitator-ai/a2a';
231
+
232
+ const a2aServer = new A2AServer({
233
+ agents: { researcher },
234
+ cogitator,
235
+ pushNotificationStore: new InMemoryPushNotificationStore(),
236
+ });
237
+ ```
238
+
239
+ When configured, the server automatically sends POST requests with `A2AStreamEvent` payloads to registered webhook URLs on task status and artifact updates. The Agent Card will advertise `pushNotifications: true`.
240
+
241
+ ## Agent Card Signing
242
+
243
+ Sign Agent Cards with HMAC-SHA256 for integrity verification:
244
+
245
+ ```typescript
246
+ import { signAgentCard, verifyAgentCardSignature } from '@cogitator-ai/a2a';
247
+
248
+ // Server-side: sign cards automatically
249
+ const a2aServer = new A2AServer({
250
+ agents: { researcher },
251
+ cogitator,
252
+ cardSigning: {
253
+ algorithm: 'hmac-sha256',
254
+ secret: process.env.CARD_SIGNING_SECRET!,
255
+ },
256
+ });
257
+
258
+ // Client-side: verify a card's signature
259
+ const client = new A2AClient('https://remote-agent.example.com');
260
+ const isValid = await client.verifyAgentCard(process.env.CARD_SIGNING_SECRET!);
261
+
262
+ // Or manually
263
+ const card = await client.agentCard();
264
+ const valid = verifyAgentCardSignature(card, 'shared-secret');
265
+ ```
266
+
267
+ ## Extended Agent Card
268
+
269
+ Provide an authenticated endpoint with additional agent details (rate limits, pricing, extended skills):
270
+
271
+ ```typescript
272
+ // Server-side: configure extended card generator
273
+ const a2aServer = new A2AServer({
274
+ agents: { researcher },
275
+ cogitator,
276
+ extendedCardGenerator: (agentName) => ({
277
+ ...a2aServer.getAgentCard(agentName),
278
+ extendedSkills: [
279
+ {
280
+ id: 'deep_research',
281
+ name: 'deep_research',
282
+ description: 'Multi-source deep research',
283
+ inputModes: ['text/plain'],
284
+ outputModes: ['text/plain', 'application/json'],
285
+ },
286
+ ],
287
+ rateLimit: { requestsPerMinute: 60 },
288
+ pricing: { model: 'per-request', details: '$0.01 per task' },
289
+ metadata: { version: '2.1.0', region: 'us-east-1' },
290
+ }),
291
+ });
292
+
293
+ // Client-side: fetch the extended card (requires auth)
294
+ const client = new A2AClient('https://remote-agent.example.com', {
295
+ headers: { Authorization: 'Bearer my-token' },
296
+ });
297
+ const extendedCard = await client.extendedAgentCard();
298
+ console.log(extendedCard.rateLimit, extendedCard.pricing);
299
+ ```
300
+
301
+ The `agent/extendedCard` method is only available when `extendedCardGenerator` is configured on the server. The Agent Card advertises this via `capabilities.extendedAgentCard: true`.
302
+
100
303
  ## Framework Adapters
101
304
 
102
305
  ```typescript
@@ -123,12 +326,18 @@ export const { GET, POST } = a2aNext(server);
123
326
 
124
327
  ## A2A Protocol
125
328
 
126
- | Method | Description |
127
- | ---------------- | ---------------------------------- |
128
- | `message/send` | Send a message, get completed task |
129
- | `message/stream` | Send with SSE streaming |
130
- | `tasks/get` | Retrieve task by ID |
131
- | `tasks/cancel` | Cancel a running task |
329
+ | Method | Description |
330
+ | ------------------------------- | ----------------------------------------- |
331
+ | `message/send` | Send a message, get completed task |
332
+ | `message/stream` | Send with SSE streaming (incl. tokens) |
333
+ | `tasks/get` | Retrieve task by ID |
334
+ | `tasks/cancel` | Cancel a running task |
335
+ | `tasks/list` | List tasks with filtering and pagination |
336
+ | `tasks/pushNotification/create` | Register a webhook for task events |
337
+ | `tasks/pushNotification/get` | Get a push notification config |
338
+ | `tasks/pushNotification/list` | List push notification configs for a task |
339
+ | `tasks/pushNotification/delete` | Remove a push notification config |
340
+ | `agent/extendedCard` | Fetch extended Agent Card (authenticated) |
132
341
 
133
342
  ## Part of Cogitator
134
343
 
@@ -1 +1 @@
1
- {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqC,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAqCpD"}
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqC,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAkDpD"}
@@ -1,4 +1,6 @@
1
1
  import { Router, json } from 'express';
2
+ import { createErrorResponse } from '../json-rpc.js';
3
+ import * as errors from '../errors.js';
2
4
  export function a2aExpress(server) {
3
5
  const router = Router();
4
6
  router.get('/.well-known/agent.json', (_req, res) => {
@@ -6,8 +8,13 @@ export function a2aExpress(server) {
6
8
  res.json(cards.length === 1 ? cards[0] : cards);
7
9
  });
8
10
  router.post('/a2a', json(), async (req, res) => {
11
+ const contentType = req.headers['content-type'];
12
+ if (contentType && !contentType.includes('application/json')) {
13
+ res.json(createErrorResponse(null, errors.contentTypeNotSupported(contentType)));
14
+ return;
15
+ }
9
16
  const body = req.body;
10
- const isStreaming = req.headers.accept === 'text/event-stream' || body?.method === 'message/stream';
17
+ const isStreaming = req.headers.accept?.includes('text/event-stream') || body?.method === 'message/stream';
11
18
  if (isStreaming) {
12
19
  res.writeHead(200, {
13
20
  'Content-Type': 'text/event-stream',
@@ -16,18 +23,29 @@ export function a2aExpress(server) {
16
23
  });
17
24
  try {
18
25
  for await (const event of server.handleJsonRpcStream(body)) {
26
+ if (res.writableEnded)
27
+ break;
19
28
  res.write(`data: ${JSON.stringify(event)}\n\n`);
20
29
  }
21
- res.write('data: [DONE]\n\n');
30
+ if (!res.writableEnded)
31
+ res.write('data: [DONE]\n\n');
22
32
  }
23
33
  catch (error) {
24
- res.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
34
+ if (!res.writableEnded) {
35
+ res.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
36
+ }
25
37
  }
26
- res.end();
38
+ if (!res.writableEnded)
39
+ res.end();
27
40
  return;
28
41
  }
29
- const response = await server.handleJsonRpc(body);
30
- res.json(response);
42
+ try {
43
+ const response = await server.handleJsonRpc(body);
44
+ res.json(response);
45
+ }
46
+ catch (error) {
47
+ res.json(createErrorResponse(null, errors.internalError(String(error))));
48
+ }
31
49
  });
32
50
  return router;
33
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAA+B,MAAM,SAAS,CAAC;AAGpE,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QACrE,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAChE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,MAAM,WAAW,GACf,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,mBAAmB,IAAI,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;QAElF,IAAI,WAAW,EAAE,CAAC;YAChB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,UAAU;gBAC3B,UAAU,EAAE,YAAY;aACzB,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3D,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAClD,CAAC;gBACD,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAChC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YACrE,CAAC;YACD,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAClD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/adapters/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAA+B,MAAM,SAAS,CAAC;AAEpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;QACrE,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAChE,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAChD,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACjF,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,MAAM,WAAW,GACf,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC,IAAI,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;QAEzF,IAAI,WAAW,EAAE,CAAC;YAChB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,mBAAmB;gBACnC,eAAe,EAAE,UAAU;gBAC3B,UAAU,EAAE,YAAY;aACzB,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3D,IAAI,GAAG,CAAC,aAAa;wBAAE,MAAM;oBAC7B,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAClD,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,aAAa;oBAAE,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACxD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;oBACvB,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBACrE,CAAC;YACH,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,aAAa;gBAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../src/adapters/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,kBAAkB,CAmChE"}
1
+ {"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../src/adapters/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,kBAAkB,CAiDhE"}
@@ -1,3 +1,5 @@
1
+ import { createErrorResponse } from '../json-rpc.js';
2
+ import * as errors from '../errors.js';
1
3
  export function a2aFastify(server) {
2
4
  return async (fastify) => {
3
5
  fastify.get('/.well-known/agent.json', async (_request, reply) => {
@@ -5,9 +7,15 @@ export function a2aFastify(server) {
5
7
  return reply.send(cards.length === 1 ? cards[0] : cards);
6
8
  });
7
9
  fastify.post('/a2a', async (request, reply) => {
10
+ const contentType = request.headers['content-type'];
11
+ if (contentType && !contentType.includes('application/json')) {
12
+ return reply.send(createErrorResponse(null, errors.contentTypeNotSupported(contentType)));
13
+ }
8
14
  const body = request.body;
9
- const isStreaming = request.headers.accept === 'text/event-stream' || body?.method === 'message/stream';
15
+ const isStreaming = request.headers.accept?.includes('text/event-stream') ||
16
+ body?.method === 'message/stream';
10
17
  if (isStreaming) {
18
+ void reply.hijack();
11
19
  reply.raw.writeHead(200, {
12
20
  'Content-Type': 'text/event-stream',
13
21
  'Cache-Control': 'no-cache',
@@ -15,18 +23,29 @@ export function a2aFastify(server) {
15
23
  });
16
24
  try {
17
25
  for await (const event of server.handleJsonRpcStream(body)) {
26
+ if (reply.raw.writableEnded)
27
+ break;
18
28
  reply.raw.write(`data: ${JSON.stringify(event)}\n\n`);
19
29
  }
20
- reply.raw.write('data: [DONE]\n\n');
30
+ if (!reply.raw.writableEnded)
31
+ reply.raw.write('data: [DONE]\n\n');
21
32
  }
22
33
  catch (error) {
23
- reply.raw.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
34
+ if (!reply.raw.writableEnded) {
35
+ reply.raw.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
36
+ }
24
37
  }
25
- reply.raw.end();
38
+ if (!reply.raw.writableEnded)
39
+ reply.raw.end();
26
40
  return;
27
41
  }
28
- const response = await server.handleJsonRpc(body);
29
- return reply.send(response);
42
+ try {
43
+ const response = await server.handleJsonRpc(body);
44
+ return reply.send(response);
45
+ }
46
+ catch (error) {
47
+ return reply.send(createErrorResponse(null, errors.internalError(String(error))));
48
+ }
30
49
  });
31
50
  };
32
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../src/adapters/fastify.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,OAAO,KAAK,EAAE,OAAwB,EAAE,EAAE;QACxC,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;YACrC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,IAA2C,CAAC;YACjE,MAAM,WAAW,GACf,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,mBAAmB,IAAI,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;YAEtF,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;oBACvB,cAAc,EAAE,mBAAmB;oBACnC,eAAe,EAAE,UAAU;oBAC3B,UAAU,EAAE,YAAY;iBACzB,CAAC,CAAC;gBAEH,IAAI,CAAC;oBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC3D,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBACxD,CAAC;oBACD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBACtC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC3E,CAAC;gBACD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAClD,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../src/adapters/fastify.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../src/adapters/hono.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+B/C"}
1
+ {"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../src/adapters/hono.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+C/C"}
@@ -1,5 +1,7 @@
1
1
  import { Hono } from 'hono';
2
2
  import { streamSSE } from 'hono/streaming';
3
+ import { createErrorResponse } from '../json-rpc.js';
4
+ import * as errors from '../errors.js';
3
5
  export function a2aHono(server) {
4
6
  const app = new Hono();
5
7
  app.get('/.well-known/agent.json', (c) => {
@@ -7,8 +9,19 @@ export function a2aHono(server) {
7
9
  return c.json(cards.length === 1 ? cards[0] : cards);
8
10
  });
9
11
  app.post('/a2a', async (c) => {
10
- const body = await c.req.json();
11
- const isStreaming = c.req.header('accept') === 'text/event-stream' || body?.method === 'message/stream';
12
+ const contentType = c.req.header('content-type');
13
+ if (contentType && !contentType.includes('application/json')) {
14
+ return c.json(createErrorResponse(null, errors.contentTypeNotSupported(contentType)));
15
+ }
16
+ let body;
17
+ try {
18
+ body = await c.req.json();
19
+ }
20
+ catch {
21
+ return c.json(createErrorResponse(null, errors.parseError('Invalid JSON body')));
22
+ }
23
+ const isStreaming = c.req.header('accept')?.includes('text/event-stream') ||
24
+ body?.method === 'message/stream';
12
25
  if (isStreaming) {
13
26
  return streamSSE(c, async (stream) => {
14
27
  try {
@@ -22,8 +35,13 @@ export function a2aHono(server) {
22
35
  }
23
36
  });
24
37
  }
25
- const response = await server.handleJsonRpc(body);
26
- return c.json(response);
38
+ try {
39
+ const response = await server.handleJsonRpc(body);
40
+ return c.json(response);
41
+ }
42
+ catch (error) {
43
+ return c.json(createErrorResponse(null, errors.internalError(String(error))));
44
+ }
27
45
  });
28
46
  return app;
29
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hono.js","sourceRoot":"","sources":["../../src/adapters/hono.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,MAAM,UAAU,OAAO,CAAC,MAAiB;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,GAAG,CAAC,GAAG,CAAC,yBAAyB,EAAE,CAAC,CAAC,EAAE,EAAE;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QACrC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,WAAW,GACf,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,mBAAmB,IAAI,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;QAEtF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACnC,IAAI,CAAC;oBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC3D,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBACzD,CAAC;oBACD,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC5C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAClD,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"hono.js","sourceRoot":"","sources":["../../src/adapters/hono.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"koa.d.ts","sourceRoot":"","sources":["../../src/adapters/koa.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,KAAK,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAyCpD"}
1
+ {"version":3,"file":"koa.d.ts","sourceRoot":"","sources":["../../src/adapters/koa.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,KAAK,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CA6DpD"}
@@ -1,3 +1,5 @@
1
+ import { createErrorResponse } from '../json-rpc.js';
2
+ import * as errors from '../errors.js';
1
3
  export function a2aKoa(server) {
2
4
  return async (ctx, next) => {
3
5
  if (ctx.path === '/.well-known/agent.json' && ctx.method === 'GET') {
@@ -6,8 +8,17 @@ export function a2aKoa(server) {
6
8
  return;
7
9
  }
8
10
  if (ctx.path === '/a2a' && ctx.method === 'POST') {
11
+ const contentType = ctx.headers['content-type'];
12
+ if (contentType && !contentType.includes('application/json')) {
13
+ ctx.body = createErrorResponse(null, errors.contentTypeNotSupported(contentType));
14
+ return;
15
+ }
9
16
  const body = ctx.request.body;
10
- const isStreaming = ctx.headers.accept === 'text/event-stream' || body?.method === 'message/stream';
17
+ if (!body) {
18
+ ctx.body = createErrorResponse(null, errors.parseError('Request body not parsed. Ensure body-parsing middleware is applied.'));
19
+ return;
20
+ }
21
+ const isStreaming = ctx.headers.accept?.includes('text/event-stream') || body.method === 'message/stream';
11
22
  if (isStreaming) {
12
23
  ctx.respond = false;
13
24
  const res = ctx.res;
@@ -18,18 +29,29 @@ export function a2aKoa(server) {
18
29
  });
19
30
  try {
20
31
  for await (const event of server.handleJsonRpcStream(body)) {
32
+ if (res.writableEnded)
33
+ break;
21
34
  res.write(`data: ${JSON.stringify(event)}\n\n`);
22
35
  }
23
- res.write('data: [DONE]\n\n');
36
+ if (!res.writableEnded)
37
+ res.write('data: [DONE]\n\n');
24
38
  }
25
39
  catch (error) {
26
- res.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
40
+ if (!res.writableEnded) {
41
+ res.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
42
+ }
27
43
  }
28
- res.end();
44
+ if (!res.writableEnded)
45
+ res.end();
29
46
  return;
30
47
  }
31
- const response = await server.handleJsonRpc(body);
32
- ctx.body = response;
48
+ try {
49
+ const response = await server.handleJsonRpc(body);
50
+ ctx.body = response;
51
+ }
52
+ catch (error) {
53
+ ctx.body = createErrorResponse(null, errors.internalError(String(error)));
54
+ }
33
55
  return;
34
56
  }
35
57
  await next();
@@ -1 +1 @@
1
- {"version":3,"file":"koa.js","sourceRoot":"","sources":["../../src/adapters/koa.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,MAAM,CAAC,MAAiB;IACtC,OAAO,KAAK,EAAE,GAAY,EAAE,IAAyB,EAAE,EAAE;QACvD,IAAI,GAAG,CAAC,IAAI,KAAK,yBAAyB,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YACnE,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;YACrC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACjD,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACjD,MAAM,IAAI,GAAI,GAAG,CAAC,OAAwD,CAAC,IAAI,CAAC;YAChF,MAAM,WAAW,GACf,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,mBAAmB,IAAI,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;YAElF,IAAI,WAAW,EAAE,CAAC;gBAChB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;gBACpB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;gBACpB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;oBACjB,cAAc,EAAE,mBAAmB;oBACnC,eAAe,EAAE,UAAU;oBAC3B,UAAU,EAAE,YAAY;iBACzB,CAAC,CAAC;gBAEH,IAAI,CAAC;oBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC3D,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBAClD,CAAC;oBACD,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBAChC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBACrE,CAAC;gBACD,GAAG,CAAC,GAAG,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAClD,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC;YACpB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"koa.js","sourceRoot":"","sources":["../../src/adapters/koa.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,6 @@
1
1
  import type { A2AServer } from '../server.js';
2
- interface NextRequest {
3
- json(): Promise<unknown>;
4
- headers: Headers;
5
- }
6
2
  export declare function a2aNext(server: A2AServer): {
7
3
  GET(): Promise<Response>;
8
- POST(request: NextRequest): Promise<Response>;
4
+ POST(request: Request): Promise<Response>;
9
5
  };
10
- export {};
11
6
  //# sourceMappingURL=next.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,UAAU,WAAW;IACnB,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS;WAExB,OAAO,CAAC,QAAQ,CAAC;kBAKV,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;EAoCtD"}
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS;WAExB,OAAO,CAAC,QAAQ,CAAC;kBAKV,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;EAwDlD"}
@@ -1,3 +1,5 @@
1
+ import { createErrorResponse } from '../json-rpc.js';
2
+ import * as errors from '../errors.js';
1
3
  export function a2aNext(server) {
2
4
  return {
3
5
  async GET() {
@@ -5,8 +7,19 @@ export function a2aNext(server) {
5
7
  return Response.json(cards.length === 1 ? cards[0] : cards);
6
8
  },
7
9
  async POST(request) {
8
- const body = (await request.json());
9
- const isStreaming = request.headers.get('accept') === 'text/event-stream' || body?.method === 'message/stream';
10
+ const contentType = request.headers.get('content-type');
11
+ if (contentType && !contentType.includes('application/json')) {
12
+ return Response.json(createErrorResponse(null, errors.contentTypeNotSupported(contentType)));
13
+ }
14
+ let body;
15
+ try {
16
+ body = await request.json();
17
+ }
18
+ catch {
19
+ return Response.json(createErrorResponse(null, errors.parseError('Invalid JSON body')));
20
+ }
21
+ const isStreaming = request.headers.get('accept')?.includes('text/event-stream') ||
22
+ body?.method === 'message/stream';
10
23
  if (isStreaming) {
11
24
  const encoder = new TextEncoder();
12
25
  const stream = new ReadableStream({
@@ -31,8 +44,13 @@ export function a2aNext(server) {
31
44
  },
32
45
  });
33
46
  }
34
- const response = await server.handleJsonRpc(body);
35
- return Response.json(response);
47
+ try {
48
+ const response = await server.handleJsonRpc(body);
49
+ return Response.json(response);
50
+ }
51
+ catch (error) {
52
+ return Response.json(createErrorResponse(null, errors.internalError(String(error))));
53
+ }
36
54
  },
37
55
  };
38
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,OAAO,CAAC,MAAiB;IACvC,OAAO;QACL,KAAK,CAAC,GAAG;YACP,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;YACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAoB;YAC7B,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAwC,CAAC;YAC3E,MAAM,WAAW,GACf,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,mBAAmB,IAAI,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;YAE7F,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;gBAClC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;oBAChC,KAAK,CAAC,KAAK,CAAC,UAAU;wBACpB,IAAI,CAAC;4BACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;gCAC3D,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;4BAC3E,CAAC;4BACD,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;wBACzD,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,UAAU,CAAC,OAAO,CAChB,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CACxE,CAAC;wBACJ,CAAC;wBACD,UAAU,CAAC,KAAK,EAAE,CAAC;oBACrB,CAAC;iBACF,CAAC,CAAC;gBAEH,OAAO,IAAI,QAAQ,CAAC,MAAM,EAAE;oBAC1B,OAAO,EAAE;wBACP,cAAc,EAAE,mBAAmB;wBACnC,eAAe,EAAE,UAAU;wBAC3B,UAAU,EAAE,YAAY;qBACzB;iBACF,CAAC,CAAC;YACL,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"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"}
@@ -6,4 +6,14 @@ export interface AgentCardOptions {
6
6
  provider?: AgentProvider;
7
7
  }
8
8
  export declare function generateAgentCard(agent: IAgent, options: AgentCardOptions): AgentCard;
9
+ export interface AgentCardSigningOptions {
10
+ algorithm?: 'hmac-sha256';
11
+ secret: string;
12
+ }
13
+ export declare function signAgentCard(card: AgentCard, options: AgentCardSigningOptions): AgentCard & {
14
+ signature: string;
15
+ };
16
+ export declare function verifyAgentCardSignature(card: AgentCard & {
17
+ signature?: string;
18
+ }, secret: string): boolean;
9
19
  //# sourceMappingURL=agent-card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-card.d.ts","sourceRoot":"","sources":["../src/agent-card.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,IAAI,MAAM,EAAQ,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAc,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAExF,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAYD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAuBrF"}
1
+ {"version":3,"file":"agent-card.d.ts","sourceRoot":"","sources":["../src/agent-card.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,IAAI,MAAM,EAAQ,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAc,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAExF,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAYD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAuBrF;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,uBAAuB,GAC/B,SAAS,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAKnC;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,SAAS,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EACxC,MAAM,EAAE,MAAM,GACb,OAAO,CAcT"}