@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.
- package/README.md +216 -7
- package/dist/adapters/express.d.ts.map +1 -1
- package/dist/adapters/express.js +24 -6
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/fastify.d.ts.map +1 -1
- package/dist/adapters/fastify.js +25 -6
- package/dist/adapters/fastify.js.map +1 -1
- package/dist/adapters/hono.d.ts.map +1 -1
- package/dist/adapters/hono.js +22 -4
- package/dist/adapters/hono.js.map +1 -1
- package/dist/adapters/koa.d.ts.map +1 -1
- package/dist/adapters/koa.js +28 -6
- package/dist/adapters/koa.js.map +1 -1
- package/dist/adapters/next.d.ts +1 -6
- package/dist/adapters/next.d.ts.map +1 -1
- package/dist/adapters/next.js +22 -4
- package/dist/adapters/next.js.map +1 -1
- package/dist/agent-card.d.ts +10 -0
- package/dist/agent-card.d.ts.map +1 -1
- package/dist/agent-card.js +26 -0
- package/dist/agent-card.js.map +1 -1
- package/dist/client.d.ts +9 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +67 -17
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +2 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/push-notifications.d.ts +17 -0
- package/dist/push-notifications.d.ts.map +1 -0
- package/dist/push-notifications.js +97 -0
- package/dist/push-notifications.js.map +1 -0
- package/dist/redis-task-store.d.ts +28 -0
- package/dist/redis-task-store.d.ts.map +1 -0
- package/dist/redis-task-store.js +95 -0
- package/dist/redis-task-store.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +139 -16
- package/dist/server.js.map +1 -1
- package/dist/task-manager.d.ts +3 -2
- package/dist/task-manager.d.ts.map +1 -1
- package/dist/task-manager.js +29 -2
- package/dist/task-manager.js.map +1 -1
- package/dist/task-store.d.ts.map +1 -1
- package/dist/task-store.js +6 -1
- package/dist/task-store.js.map +1 -1
- package/dist/types.d.ts +41 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -6
- package/dist/types.js.map +1 -1
- 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
|
-
- **
|
|
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
|
|
127
|
-
|
|
|
128
|
-
| `message/send`
|
|
129
|
-
| `message/stream`
|
|
130
|
-
| `tasks/get`
|
|
131
|
-
| `tasks/cancel`
|
|
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;
|
|
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"}
|
package/dist/adapters/express.js
CHANGED
|
@@ -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
|
|
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.
|
|
30
|
+
if (!res.writableEnded)
|
|
31
|
+
res.write('data: [DONE]\n\n');
|
|
22
32
|
}
|
|
23
33
|
catch (error) {
|
|
24
|
-
res.
|
|
34
|
+
if (!res.writableEnded) {
|
|
35
|
+
res.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
|
|
36
|
+
}
|
|
25
37
|
}
|
|
26
|
-
res.
|
|
38
|
+
if (!res.writableEnded)
|
|
39
|
+
res.end();
|
|
27
40
|
return;
|
|
28
41
|
}
|
|
29
|
-
|
|
30
|
-
|
|
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;
|
|
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;
|
|
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"}
|
package/dist/adapters/fastify.js
CHANGED
|
@@ -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
|
|
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.
|
|
30
|
+
if (!reply.raw.writableEnded)
|
|
31
|
+
reply.raw.write('data: [DONE]\n\n');
|
|
21
32
|
}
|
|
22
33
|
catch (error) {
|
|
23
|
-
reply.raw.
|
|
34
|
+
if (!reply.raw.writableEnded) {
|
|
35
|
+
reply.raw.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
|
|
36
|
+
}
|
|
24
37
|
}
|
|
25
|
-
reply.raw.
|
|
38
|
+
if (!reply.raw.writableEnded)
|
|
39
|
+
reply.raw.end();
|
|
26
40
|
return;
|
|
27
41
|
}
|
|
28
|
-
|
|
29
|
-
|
|
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":"
|
|
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;
|
|
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"}
|
package/dist/adapters/hono.js
CHANGED
|
@@ -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
|
|
11
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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;
|
|
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;
|
|
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"}
|
package/dist/adapters/koa.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
36
|
+
if (!res.writableEnded)
|
|
37
|
+
res.write('data: [DONE]\n\n');
|
|
24
38
|
}
|
|
25
39
|
catch (error) {
|
|
26
|
-
res.
|
|
40
|
+
if (!res.writableEnded) {
|
|
41
|
+
res.write(`data: ${JSON.stringify({ error: String(error) })}\n\n`);
|
|
42
|
+
}
|
|
27
43
|
}
|
|
28
|
-
res.
|
|
44
|
+
if (!res.writableEnded)
|
|
45
|
+
res.end();
|
|
29
46
|
return;
|
|
30
47
|
}
|
|
31
|
-
|
|
32
|
-
|
|
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();
|
package/dist/adapters/koa.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"koa.js","sourceRoot":"","sources":["../../src/adapters/koa.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"koa.js","sourceRoot":"","sources":["../../src/adapters/koa.ts"],"names":[],"mappings":"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"}
|
package/dist/adapters/next.d.ts
CHANGED
|
@@ -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:
|
|
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;
|
|
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"}
|
package/dist/adapters/next.js
CHANGED
|
@@ -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
|
|
9
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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":"
|
|
1
|
+
{"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"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"}
|
package/dist/agent-card.d.ts
CHANGED
|
@@ -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
|
package/dist/agent-card.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-card.d.ts","sourceRoot":"","sources":["../src/agent-card.ts"],"names":[],"mappings":"
|
|
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"}
|