@cogitator-ai/a2a 0.7.8 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +173 -151
  2. package/dist/adapters/express.d.ts +5 -0
  3. package/dist/adapters/express.d.ts.map +1 -1
  4. package/dist/adapters/express.js +53 -30
  5. package/dist/adapters/express.js.map +1 -1
  6. package/dist/adapters/fastify.d.ts +5 -0
  7. package/dist/adapters/fastify.d.ts.map +1 -1
  8. package/dist/adapters/fastify.js +51 -35
  9. package/dist/adapters/fastify.js.map +1 -1
  10. package/dist/adapters/hono.d.ts +5 -0
  11. package/dist/adapters/hono.d.ts.map +1 -1
  12. package/dist/adapters/hono.js +41 -49
  13. package/dist/adapters/hono.js.map +1 -1
  14. package/dist/adapters/koa.d.ts +5 -0
  15. package/dist/adapters/koa.d.ts.map +1 -1
  16. package/dist/adapters/koa.js +39 -32
  17. package/dist/adapters/koa.js.map +1 -1
  18. package/dist/adapters/next.d.ts +13 -2
  19. package/dist/adapters/next.d.ts.map +1 -1
  20. package/dist/adapters/next.js +75 -51
  21. package/dist/adapters/next.js.map +1 -1
  22. package/dist/adapters/shared.d.ts +43 -10
  23. package/dist/adapters/shared.d.ts.map +1 -1
  24. package/dist/adapters/shared.js +156 -23
  25. package/dist/adapters/shared.js.map +1 -1
  26. package/dist/agent-card.d.ts +22 -7
  27. package/dist/agent-card.d.ts.map +1 -1
  28. package/dist/agent-card.js +71 -34
  29. package/dist/agent-card.js.map +1 -1
  30. package/dist/approvals.d.ts +46 -0
  31. package/dist/approvals.d.ts.map +1 -0
  32. package/dist/approvals.js +105 -0
  33. package/dist/approvals.js.map +1 -0
  34. package/dist/client.d.ts +59 -17
  35. package/dist/client.d.ts.map +1 -1
  36. package/dist/client.js +237 -142
  37. package/dist/client.js.map +1 -1
  38. package/dist/errors.d.ts +24 -1
  39. package/dist/errors.d.ts.map +1 -1
  40. package/dist/errors.js +90 -19
  41. package/dist/errors.js.map +1 -1
  42. package/dist/index.d.ts +11 -7
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +7 -5
  45. package/dist/index.js.map +1 -1
  46. package/dist/ownership.d.ts +7 -1
  47. package/dist/ownership.d.ts.map +1 -1
  48. package/dist/ownership.js +24 -3
  49. package/dist/ownership.js.map +1 -1
  50. package/dist/protocol.d.ts +70 -0
  51. package/dist/protocol.d.ts.map +1 -0
  52. package/dist/protocol.js +187 -0
  53. package/dist/protocol.js.map +1 -0
  54. package/dist/push-notifications.d.ts +5 -2
  55. package/dist/push-notifications.d.ts.map +1 -1
  56. package/dist/push-notifications.js +33 -23
  57. package/dist/push-notifications.js.map +1 -1
  58. package/dist/redis-task-store.js +3 -3
  59. package/dist/redis-task-store.js.map +1 -1
  60. package/dist/server.d.ts +75 -12
  61. package/dist/server.d.ts.map +1 -1
  62. package/dist/server.js +324 -270
  63. package/dist/server.js.map +1 -1
  64. package/dist/task-manager.d.ts +57 -11
  65. package/dist/task-manager.d.ts.map +1 -1
  66. package/dist/task-manager.js +264 -116
  67. package/dist/task-manager.js.map +1 -1
  68. package/dist/task-store.js +4 -4
  69. package/dist/task-store.js.map +1 -1
  70. package/dist/types.d.ts +226 -85
  71. package/dist/types.d.ts.map +1 -1
  72. package/dist/types.js +10 -3
  73. package/dist/types.js.map +1 -1
  74. package/dist/url.d.ts +7 -0
  75. package/dist/url.d.ts.map +1 -0
  76. package/dist/url.js +12 -0
  77. package/dist/url.js.map +1 -0
  78. package/package.json +19 -9
  79. package/dist/adapters/sse-error-event.d.ts +0 -3
  80. package/dist/adapters/sse-error-event.d.ts.map +0 -1
  81. package/dist/adapters/sse-error-event.js +0 -12
  82. package/dist/adapters/sse-error-event.js.map +0 -1
@@ -1,59 +1,83 @@
1
1
  import { createErrorResponse } from '../json-rpc.js';
2
2
  import * as errors from '../errors.js';
3
- import { isStreamRequest, pipeJsonRpcStream, SSE_HEADERS } from './shared.js';
3
+ import { AGENT_CARD_PATH } from '../types.js';
4
+ import { handleA2AHttp } from './shared.js';
5
+ import { trimTrailingSlashes } from '../url.js';
6
+ async function agentParam(context) {
7
+ const params = await context?.params;
8
+ const agent = params?.agent;
9
+ return Array.isArray(agent) ? agent[0] : agent;
10
+ }
11
+ function toResponse(response, abort) {
12
+ switch (response.kind) {
13
+ case 'json':
14
+ return Response.json(response.body, { status: response.status, headers: response.headers });
15
+ case 'empty':
16
+ return new Response(null, { status: response.status });
17
+ case 'pass':
18
+ return Response.json(createErrorResponse(null, errors.invalidRequest('Not an A2A route')), {
19
+ status: 404,
20
+ });
21
+ case 'sse': {
22
+ const encoder = new TextEncoder();
23
+ const stream = new ReadableStream({
24
+ async start(controller) {
25
+ await response.pipe((frame) => {
26
+ if (!abort.signal.aborted)
27
+ controller.enqueue(encoder.encode(frame));
28
+ });
29
+ try {
30
+ controller.close();
31
+ }
32
+ catch {
33
+ return;
34
+ }
35
+ },
36
+ cancel() {
37
+ abort.abort();
38
+ },
39
+ });
40
+ return new Response(stream, { headers: response.headers });
41
+ }
42
+ }
43
+ }
44
+ /**
45
+ * Next.js App Router handlers for an A2A server. Export `GET` from the route that serves
46
+ * `/.well-known/agent-card.json` and `POST` from the route at `basePath`. In a dynamic
47
+ * `[agent]` route they serve that agent's own card and endpoint.
48
+ */
4
49
  export function a2aNext(server) {
50
+ const base = trimTrailingSlashes(server.basePath);
51
+ const serve = async (request, relativePath, method) => {
52
+ const controller = new AbortController();
53
+ request.signal?.addEventListener('abort', () => controller.abort(), { once: true });
54
+ try {
55
+ const response = await handleA2AHttp(server, {
56
+ method,
57
+ path: relativePath,
58
+ mountUrl: new URL(request.url).origin,
59
+ header: (name) => request.headers.get(name),
60
+ readBody: () => request.json(),
61
+ signal: controller.signal,
62
+ });
63
+ return toResponse(response, controller);
64
+ }
65
+ catch (error) {
66
+ return Response.json(createErrorResponse(null, errors.clientJsonRpcError(error, 'A2A request failed')));
67
+ }
68
+ };
5
69
  return {
6
- async GET() {
7
- const cards = server.getAgentCards();
8
- return Response.json(cards.length === 1 ? cards[0] : cards);
70
+ async GET(request, context) {
71
+ const agent = await agentParam(context);
72
+ const path = agent
73
+ ? `${base}/${encodeURIComponent(agent)}${AGENT_CARD_PATH}`
74
+ : AGENT_CARD_PATH;
75
+ return serve(request, path, 'GET');
9
76
  },
10
- async POST(request) {
11
- const contentType = request.headers.get('content-type');
12
- if (contentType && !contentType.startsWith('application/json')) {
13
- return Response.json(createErrorResponse(null, errors.contentTypeNotSupported(contentType)));
14
- }
15
- let body;
16
- try {
17
- body = await request.json();
18
- }
19
- catch {
20
- return Response.json(createErrorResponse(null, errors.parseError('Invalid JSON body')));
21
- }
22
- const authToken = server.getAuthToken((name) => request.headers.get(name));
23
- if (isStreamRequest(body)) {
24
- const encoder = new TextEncoder();
25
- const controller = new AbortController();
26
- const abort = () => controller.abort();
27
- request.signal?.addEventListener('abort', abort, { once: true });
28
- const stream = new ReadableStream({
29
- async start(streamController) {
30
- await pipeJsonRpcStream(server, body, authToken, controller.signal, (frame) => {
31
- streamController.enqueue(encoder.encode(frame));
32
- });
33
- request.signal?.removeEventListener('abort', abort);
34
- try {
35
- streamController.close();
36
- }
37
- catch {
38
- return;
39
- }
40
- },
41
- cancel() {
42
- controller.abort();
43
- },
44
- });
45
- return new Response(stream, { headers: SSE_HEADERS });
46
- }
47
- try {
48
- const response = await server.handleJsonRpc(body, authToken);
49
- if (response === null) {
50
- return new Response(null, { status: 204 });
51
- }
52
- return Response.json(response);
53
- }
54
- catch (error) {
55
- return Response.json(createErrorResponse(null, errors.clientJsonRpcError(error, 'A2A request failed')));
56
- }
77
+ async POST(request, context) {
78
+ const agent = await agentParam(context);
79
+ const path = agent ? `${base}/${encodeURIComponent(agent)}` : server.basePath;
80
+ return serve(request, path, 'POST');
57
81
  },
58
82
  };
59
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/adapters/next.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,51 @@
1
1
  import type { A2AServer } from '../server.js';
2
- import type { A2AStreamEvent } from '../types.js';
2
+ import { type JsonRpcResponse } from '../json-rpc.js';
3
3
  export type HeaderValue = string | string[] | null | undefined;
4
+ export declare function firstHeader(value: HeaderValue): string | undefined;
5
+ export declare const SSE_HEADERS: Record<string, string>;
4
6
  /**
5
- * A request streams only for the `message/stream` method; the Accept header
6
- * alone does not switch a `message/send` request to SSE.
7
+ * A request streams when its method is `message/stream` or `tasks/resubscribe`; the Accept
8
+ * header alone does not switch another method to SSE.
7
9
  */
8
10
  export declare function isStreamRequest(body: unknown): boolean;
9
- export declare function firstHeader(value: HeaderValue): string | undefined;
10
- export declare function sseFrame(data: A2AStreamEvent | '[DONE]'): string;
11
- export declare const SSE_HEADERS: Record<string, string>;
11
+ /** One SSE event carrying a JSON-RPC response (A2A v0.3, section 3.3.1). */
12
+ export declare function sseFrame(response: JsonRpcResponse): string;
13
+ /** A request as a framework adapter hands it over. */
14
+ export interface A2AHttpRequest {
15
+ method: string;
16
+ /** The path relative to where the adapter is mounted, e.g. `/a2a` */
17
+ path: string;
18
+ /** Absolute URL the adapter is mounted at (origin plus mount path), for the cards' `url` */
19
+ mountUrl: string;
20
+ header(name: string): string | null | undefined;
21
+ /** The parsed JSON body; throws a SyntaxError when the body is not JSON */
22
+ readBody(): Promise<unknown>;
23
+ /** Aborted when the client disconnects */
24
+ signal: AbortSignal;
25
+ }
26
+ /** What the adapter sends back. */
27
+ export type A2AHttpResponse = {
28
+ kind: 'json';
29
+ status: number;
30
+ headers: Record<string, string>;
31
+ body: unknown;
32
+ } | {
33
+ kind: 'empty';
34
+ status: number;
35
+ } | {
36
+ kind: 'sse';
37
+ headers: Record<string, string>;
38
+ /** Write the stream's frames until it ends or the client disconnects */
39
+ pipe(write: (frame: string) => void | Promise<void>): Promise<void>;
40
+ } | {
41
+ kind: 'pass';
42
+ };
12
43
  /**
13
- * Drive a JSON-RPC stream and write SSE frames until it ends, the client
14
- * disconnects (signal aborted) or a write fails. Errors are reported as a
15
- * final failed status-update frame.
44
+ * Serve an A2A request: the Agent Cards and the JSON-RPC endpoints, with streams as SSE where
45
+ * every event is a JSON-RPC response. Errors before a stream starts are answered as a plain
46
+ * JSON-RPC error, with HTTP 401 for missing or rejected credentials.
16
47
  */
17
- export declare function pipeJsonRpcStream(server: A2AServer, body: unknown, authToken: string | undefined, signal: AbortSignal, write: (frame: string) => void | Promise<void>): Promise<void>;
48
+ export declare function handleA2AHttp(server: A2AServer, request: A2AHttpRequest): Promise<A2AHttpResponse>;
49
+ /** The URL an adapter is mounted at, from the full request URL and the path relative to the mount. */
50
+ export declare function mountUrlOf(requestUrl: URL, relativePath: string): string;
18
51
  //# sourceMappingURL=shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAOtD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAGlE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,GAAG,MAAM,CAEhE;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9C,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAK3E,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AAE/D,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAGlE;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAItD;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAE1D;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,2EAA2E;IAC3E,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,0CAA0C;IAC1C,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,mCAAmC;AACnC,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjC;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,wEAAwE;IACxE,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE,GACD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AA8DrB;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CA+D1B;AA0CD,sGAAsG;AACtG,wBAAgB,UAAU,CAAC,UAAU,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAMxE"}
@@ -1,22 +1,14 @@
1
- import { buildSseErrorEvent } from './sse-error-event.js';
2
- /**
3
- * A request streams only for the `message/stream` method; the Accept header
4
- * alone does not switch a `message/send` request to SSE.
5
- */
6
- export function isStreamRequest(body) {
7
- return (typeof body === 'object' &&
8
- body !== null &&
9
- !Array.isArray(body) &&
10
- body.method === 'message/stream');
11
- }
1
+ import { encodeHeartbeat, startHeartbeat } from '@cogitator-ai/server-shared';
2
+ import { STREAMING_METHODS } from '../server.js';
3
+ import { createErrorResponse } from '../json-rpc.js';
4
+ import * as errors from '../errors.js';
5
+ import { AGENT_CARD_PATH, LEGACY_AGENT_CARD_PATH } from '../types.js';
6
+ import { trimTrailingSlashes } from '../url.js';
12
7
  export function firstHeader(value) {
13
8
  if (Array.isArray(value))
14
9
  return value[0];
15
10
  return value ?? undefined;
16
11
  }
17
- export function sseFrame(data) {
18
- return `data: ${typeof data === 'string' ? data : JSON.stringify(data)}\n\n`;
19
- }
20
12
  export const SSE_HEADERS = {
21
13
  'Content-Type': 'text/event-stream',
22
14
  'Cache-Control': 'no-cache',
@@ -24,29 +16,170 @@ export const SSE_HEADERS = {
24
16
  'X-Accel-Buffering': 'no',
25
17
  };
26
18
  /**
27
- * Drive a JSON-RPC stream and write SSE frames until it ends, the client
28
- * disconnects (signal aborted) or a write fails. Errors are reported as a
29
- * final failed status-update frame.
19
+ * A request streams when its method is `message/stream` or `tasks/resubscribe`; the Accept
20
+ * header alone does not switch another method to SSE.
21
+ */
22
+ export function isStreamRequest(body) {
23
+ if (typeof body !== 'object' || body === null || Array.isArray(body))
24
+ return false;
25
+ const method = body.method;
26
+ return typeof method === 'string' && STREAMING_METHODS.includes(method);
27
+ }
28
+ /** One SSE event carrying a JSON-RPC response (A2A v0.3, section 3.3.1). */
29
+ export function sseFrame(response) {
30
+ return `data: ${JSON.stringify(response)}\n\n`;
31
+ }
32
+ function agentNameFrom(segment) {
33
+ try {
34
+ return decodeURIComponent(segment);
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /**
41
+ * The A2A route a request path names: the Agent Card at the well-known path, the pre-v0.3 card
42
+ * path, the shared JSON-RPC endpoint at `basePath`, or one agent's endpoint and card under
43
+ * `<basePath>/<agent name>`.
44
+ */
45
+ function matchRoute(server, method, path) {
46
+ const basePath = trimTrailingSlashes(server.basePath) || '';
47
+ if (method === 'GET') {
48
+ if (path === AGENT_CARD_PATH)
49
+ return { kind: 'card' };
50
+ if (path === LEGACY_AGENT_CARD_PATH)
51
+ return { kind: 'legacy-card' };
52
+ const prefix = `${basePath}/`;
53
+ if (path.startsWith(prefix) && path.endsWith(AGENT_CARD_PATH)) {
54
+ const segment = path.slice(prefix.length, path.length - AGENT_CARD_PATH.length);
55
+ const agentName = segment.includes('/') ? null : agentNameFrom(segment);
56
+ if (agentName)
57
+ return { kind: 'card', agentName };
58
+ }
59
+ return null;
60
+ }
61
+ if (method === 'POST') {
62
+ if (path === server.basePath || path === basePath)
63
+ return { kind: 'rpc' };
64
+ const prefix = `${basePath}/`;
65
+ if (path.startsWith(prefix)) {
66
+ const segment = path.slice(prefix.length).replace(/\/$/, '');
67
+ const agentName = segment && !segment.includes('/') ? agentNameFrom(segment) : null;
68
+ if (agentName)
69
+ return { kind: 'rpc', agentName };
70
+ }
71
+ }
72
+ return null;
73
+ }
74
+ function json(status, body, headers = {}) {
75
+ return { kind: 'json', status, headers, body };
76
+ }
77
+ /** The HTTP status of a JSON-RPC response: 401 for missing or rejected credentials, else 200. */
78
+ function errorStatus(server, response) {
79
+ if (response.error?.code === errors.A2A_ERROR_CODES.unauthorized) {
80
+ const challenge = server.authChallenge;
81
+ return json(401, response, challenge ? { 'WWW-Authenticate': challenge } : {});
82
+ }
83
+ return json(200, response);
84
+ }
85
+ /**
86
+ * Serve an A2A request: the Agent Cards and the JSON-RPC endpoints, with streams as SSE where
87
+ * every event is a JSON-RPC response. Errors before a stream starts are answered as a plain
88
+ * JSON-RPC error, with HTTP 401 for missing or rejected credentials.
89
+ */
90
+ export async function handleA2AHttp(server, request) {
91
+ const route = matchRoute(server, request.method, request.path);
92
+ if (!route)
93
+ return { kind: 'pass' };
94
+ if (route.kind === 'legacy-card') {
95
+ const cards = server.getAgentCards({ baseUrl: request.mountUrl });
96
+ return json(200, cards.length === 1 ? cards[0] : cards);
97
+ }
98
+ if (route.agentName !== undefined && !server.hasAgent(route.agentName)) {
99
+ return json(404, createErrorResponse(null, errors.agentNotFound(route.agentName)));
100
+ }
101
+ if (route.kind === 'card') {
102
+ return json(200, server.getAgentCard(route.agentName, { baseUrl: request.mountUrl }));
103
+ }
104
+ const contentType = request.header('content-type');
105
+ if (contentType && !contentType.toLowerCase().startsWith('application/json')) {
106
+ return json(415, createErrorResponse(null, errors.invalidRequest('Content-Type must be application/json')));
107
+ }
108
+ let body;
109
+ try {
110
+ body = await request.readBody();
111
+ }
112
+ catch {
113
+ return json(200, createErrorResponse(null, errors.parseError('Invalid JSON body')));
114
+ }
115
+ if (body === undefined) {
116
+ return json(200, createErrorResponse(null, errors.parseError('Request body not parsed. Ensure body-parsing middleware is applied.')));
117
+ }
118
+ const authToken = server.getAuthToken((name) => request.header(name));
119
+ const options = route.agentName !== undefined ? { agentName: route.agentName } : undefined;
120
+ if (!isStreamRequest(body)) {
121
+ const response = await server.handleJsonRpc(body, authToken, options);
122
+ if (response === null)
123
+ return { kind: 'empty', status: 204 };
124
+ return response.error ? errorStatus(server, response) : json(200, response);
125
+ }
126
+ const stream = server.handleJsonRpcStream(body, authToken, request.signal, options);
127
+ const first = await stream.next();
128
+ if (first.done)
129
+ return { kind: 'empty', status: 204 };
130
+ if (first.value.error) {
131
+ await stream.return(undefined);
132
+ return errorStatus(server, first.value);
133
+ }
134
+ return {
135
+ kind: 'sse',
136
+ headers: SSE_HEADERS,
137
+ pipe: (write) => pipeStream(server, first.value, stream, request.signal, write),
138
+ };
139
+ }
140
+ /**
141
+ * Write the frames of a stream until it ends, the client disconnects or a write fails. While the
142
+ * stream is open a heartbeat comment goes out every `server.sseHeartbeatMs`, so a run that waits
143
+ * on a slow tool is not cut off by an idle timeout.
30
144
  */
31
- export async function pipeJsonRpcStream(server, body, authToken, signal, write) {
145
+ async function pipeStream(server, first, rest, signal, write) {
146
+ const stopHeartbeat = startHeartbeat(() => {
147
+ if (signal.aborted)
148
+ return false;
149
+ void Promise.resolve()
150
+ .then(() => write(encodeHeartbeat()))
151
+ .catch(() => undefined);
152
+ return true;
153
+ }, server.sseHeartbeatMs);
32
154
  try {
33
- for await (const event of server.handleJsonRpcStream(body, authToken, signal)) {
155
+ await write(sseFrame(first));
156
+ for await (const response of rest) {
34
157
  if (signal.aborted)
35
158
  return;
36
- await write(sseFrame(event));
159
+ await write(sseFrame(response));
37
160
  }
38
- if (!signal.aborted)
39
- await write(sseFrame('[DONE]'));
40
161
  }
41
162
  catch (error) {
42
163
  if (signal.aborted)
43
164
  return;
44
165
  try {
45
- await write(sseFrame(buildSseErrorEvent(error)));
166
+ await write(sseFrame(createErrorResponse(null, errors.clientJsonRpcError(error, 'A2A stream failed'))));
46
167
  }
47
168
  catch {
48
169
  return;
49
170
  }
50
171
  }
172
+ finally {
173
+ stopHeartbeat();
174
+ await rest.return(undefined);
175
+ }
176
+ }
177
+ /** The URL an adapter is mounted at, from the full request URL and the path relative to the mount. */
178
+ export function mountUrlOf(requestUrl, relativePath) {
179
+ const pathname = requestUrl.pathname;
180
+ const prefix = pathname.endsWith(relativePath)
181
+ ? pathname.slice(0, pathname.length - relativePath.length)
182
+ : '';
183
+ return `${requestUrl.origin}${prefix}`;
51
184
  }
52
185
  //# sourceMappingURL=shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAI1D;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,OAAO,CACL,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QACnB,IAAgC,CAAC,MAAM,KAAK,gBAAgB,CAC9D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAkB;IAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1C,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAA+B;IACtD,OAAO,SAAS,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAA2B;IACjD,cAAc,EAAE,mBAAmB;IACnC,eAAe,EAAE,UAAU;IAC3B,UAAU,EAAE,YAAY;IACxB,mBAAmB,EAAE,IAAI;CAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAiB,EACjB,IAAa,EACb,SAA6B,EAC7B,MAAmB,EACnB,KAA8C;IAE9C,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;YAC9E,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO;YAC3B,MAAM,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO;QAC3B,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,34 @@
1
1
  import type { Agent as IAgent } from '@cogitator-ai/types';
2
2
  import type { AgentCard, AgentProvider, A2ACapabilities } from './types.js';
3
3
  export interface AgentCardOptions {
4
+ /** Absolute URL of the agent's JSON-RPC endpoint */
4
5
  url: string;
5
6
  capabilities?: Partial<A2ACapabilities>;
6
7
  provider?: AgentProvider;
8
+ /** The agent's version (default: '1.0.0') */
9
+ version?: string;
10
+ supportsAuthenticatedExtendedCard?: boolean;
7
11
  }
12
+ /**
13
+ * The A2A v0.3 Agent Card of an agent. It names the agent, its description (never its
14
+ * instructions) and its tools as skills, and declares JSON-RPC at `url` as its transport.
15
+ */
8
16
  export declare function generateAgentCard(agent: IAgent, options: AgentCardOptions): AgentCard;
9
17
  export interface AgentCardSigningOptions {
10
- algorithm?: 'hmac-sha256';
18
+ /** HMAC SHA-256; `hmac-sha256` is the name earlier versions used */
19
+ algorithm?: 'HS256' | 'hmac-sha256';
11
20
  secret: string;
12
21
  }
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;
22
+ /**
23
+ * JSON canonicalization (RFC 8785): object keys sorted by UTF-16 code units, no whitespace,
24
+ * values serialized as JSON. Undefined members are left out as JSON.stringify does.
25
+ */
26
+ export declare function canonicalJson(value: unknown): string;
27
+ /**
28
+ * The card with a JWS signature (RFC 7515, HS256, detached payload) over its canonical JSON
29
+ * (RFC 8785, without `signatures`) in `signatures`, as A2A v0.3 specifies.
30
+ */
31
+ export declare function signAgentCard(card: AgentCard, options: AgentCardSigningOptions): AgentCard;
32
+ /** Whether one of the card's HS256 signatures was made with `secret` over this exact card. */
33
+ export declare function verifyAgentCardSignature(card: AgentCard, secret: string): boolean;
19
34
  //# sourceMappingURL=agent-card.d.ts.map
@@ -1 +1 @@
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;AAkBD,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"}
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,EACV,SAAS,EAGT,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iCAAiC,CAAC,EAAE,OAAO,CAAC;CAC7C;AAaD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA8BrF;AAED,MAAM,WAAW,uBAAuB;IACtC,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAapD;AAkBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,GAAG,SAAS,CAM1F;AAWD,8FAA8F;AAC9F,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQjF"}