@a2a-js/sdk 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,49 @@
1
+ import { E as Extensions, ae as AgentCard, x as MessageSendParams, F as Message, ay as Task, aQ as TaskStatusUpdateEvent, aS as TaskArtifactUpdateEvent, X as TaskQueryParams, Z as TaskIdParams, $ as TaskPushNotificationConfig, a3 as GetTaskPushNotificationConfigParams, a7 as ListTaskPushNotificationConfigParams, a9 as DeleteTaskPushNotificationConfigParams } from './extensions-DvruCIzw.cjs';
2
+
3
+ /**
4
+ * Represents a user accessing A2A server.
5
+ */
6
+ interface User {
7
+ /**
8
+ * Indicates whether the user is authenticated.
9
+ */
10
+ get isAuthenticated(): boolean;
11
+ /**
12
+ * A unique name (identifier) for the user.
13
+ */
14
+ get userName(): string;
15
+ }
16
+ /**
17
+ * An implementation of {@link User} representing an unauthenticated user.
18
+ */
19
+ declare class UnauthenticatedUser implements User {
20
+ get isAuthenticated(): boolean;
21
+ get userName(): string;
22
+ }
23
+
24
+ declare class ServerCallContext {
25
+ private readonly _requestedExtensions?;
26
+ private readonly _user?;
27
+ private _activatedExtensions?;
28
+ constructor(requestedExtensions?: Extensions, user?: User);
29
+ get user(): User | undefined;
30
+ get activatedExtensions(): Extensions | undefined;
31
+ get requestedExtensions(): Extensions | undefined;
32
+ addActivatedExtension(uri: string): void;
33
+ }
34
+
35
+ interface A2ARequestHandler {
36
+ getAgentCard(): Promise<AgentCard>;
37
+ getAuthenticatedExtendedAgentCard(context?: ServerCallContext): Promise<AgentCard>;
38
+ sendMessage(params: MessageSendParams, context?: ServerCallContext): Promise<Message | Task>;
39
+ sendMessageStream(params: MessageSendParams, context?: ServerCallContext): AsyncGenerator<Message | Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent, void, undefined>;
40
+ getTask(params: TaskQueryParams, context?: ServerCallContext): Promise<Task>;
41
+ cancelTask(params: TaskIdParams, context?: ServerCallContext): Promise<Task>;
42
+ setTaskPushNotificationConfig(params: TaskPushNotificationConfig, context?: ServerCallContext): Promise<TaskPushNotificationConfig>;
43
+ getTaskPushNotificationConfig(params: TaskIdParams | GetTaskPushNotificationConfigParams, context?: ServerCallContext): Promise<TaskPushNotificationConfig>;
44
+ listTaskPushNotificationConfigs(params: ListTaskPushNotificationConfigParams, context?: ServerCallContext): Promise<TaskPushNotificationConfig[]>;
45
+ deleteTaskPushNotificationConfig(params: DeleteTaskPushNotificationConfigParams, context?: ServerCallContext): Promise<void>;
46
+ resubscribe(params: TaskIdParams, context?: ServerCallContext): AsyncGenerator<Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent, void, undefined>;
47
+ }
48
+
49
+ export { type A2ARequestHandler as A, ServerCallContext as S, type User as U, UnauthenticatedUser as a };
@@ -0,0 +1,49 @@
1
+ import { E as Extensions, ae as AgentCard, x as MessageSendParams, F as Message, ay as Task, aQ as TaskStatusUpdateEvent, aS as TaskArtifactUpdateEvent, X as TaskQueryParams, Z as TaskIdParams, $ as TaskPushNotificationConfig, a3 as GetTaskPushNotificationConfigParams, a7 as ListTaskPushNotificationConfigParams, a9 as DeleteTaskPushNotificationConfigParams } from './extensions-DvruCIzw.js';
2
+
3
+ /**
4
+ * Represents a user accessing A2A server.
5
+ */
6
+ interface User {
7
+ /**
8
+ * Indicates whether the user is authenticated.
9
+ */
10
+ get isAuthenticated(): boolean;
11
+ /**
12
+ * A unique name (identifier) for the user.
13
+ */
14
+ get userName(): string;
15
+ }
16
+ /**
17
+ * An implementation of {@link User} representing an unauthenticated user.
18
+ */
19
+ declare class UnauthenticatedUser implements User {
20
+ get isAuthenticated(): boolean;
21
+ get userName(): string;
22
+ }
23
+
24
+ declare class ServerCallContext {
25
+ private readonly _requestedExtensions?;
26
+ private readonly _user?;
27
+ private _activatedExtensions?;
28
+ constructor(requestedExtensions?: Extensions, user?: User);
29
+ get user(): User | undefined;
30
+ get activatedExtensions(): Extensions | undefined;
31
+ get requestedExtensions(): Extensions | undefined;
32
+ addActivatedExtension(uri: string): void;
33
+ }
34
+
35
+ interface A2ARequestHandler {
36
+ getAgentCard(): Promise<AgentCard>;
37
+ getAuthenticatedExtendedAgentCard(context?: ServerCallContext): Promise<AgentCard>;
38
+ sendMessage(params: MessageSendParams, context?: ServerCallContext): Promise<Message | Task>;
39
+ sendMessageStream(params: MessageSendParams, context?: ServerCallContext): AsyncGenerator<Message | Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent, void, undefined>;
40
+ getTask(params: TaskQueryParams, context?: ServerCallContext): Promise<Task>;
41
+ cancelTask(params: TaskIdParams, context?: ServerCallContext): Promise<Task>;
42
+ setTaskPushNotificationConfig(params: TaskPushNotificationConfig, context?: ServerCallContext): Promise<TaskPushNotificationConfig>;
43
+ getTaskPushNotificationConfig(params: TaskIdParams | GetTaskPushNotificationConfigParams, context?: ServerCallContext): Promise<TaskPushNotificationConfig>;
44
+ listTaskPushNotificationConfigs(params: ListTaskPushNotificationConfigParams, context?: ServerCallContext): Promise<TaskPushNotificationConfig[]>;
45
+ deleteTaskPushNotificationConfig(params: DeleteTaskPushNotificationConfigParams, context?: ServerCallContext): Promise<void>;
46
+ resubscribe(params: TaskIdParams, context?: ServerCallContext): AsyncGenerator<Task | TaskStatusUpdateEvent | TaskArtifactUpdateEvent, void, undefined>;
47
+ }
48
+
49
+ export { type A2ARequestHandler as A, ServerCallContext as S, type User as U, UnauthenticatedUser as a };
@@ -0,0 +1,8 @@
1
+ // src/constants.ts
2
+ var AGENT_CARD_PATH = ".well-known/agent-card.json";
3
+ var HTTP_EXTENSION_HEADER = "X-A2A-Extensions";
4
+
5
+ export {
6
+ AGENT_CARD_PATH,
7
+ HTTP_EXTENSION_HEADER
8
+ };
@@ -1,3 +1,7 @@
1
+ import {
2
+ Extensions
3
+ } from "./chunk-ZX6KNMCP.js";
4
+
1
5
  // src/server/error.ts
2
6
  var A2AError = class _A2AError extends Error {
3
7
  code;
@@ -32,10 +36,7 @@ var A2AError = class _A2AError extends Error {
32
36
  return new _A2AError(-32600, message, data);
33
37
  }
34
38
  static methodNotFound(method) {
35
- return new _A2AError(
36
- -32601,
37
- `Method not found: ${method}`
38
- );
39
+ return new _A2AError(-32601, `Method not found: ${method}`);
39
40
  }
40
41
  static invalidParams(message, data) {
41
42
  return new _A2AError(-32602, message, data);
@@ -44,42 +45,46 @@ var A2AError = class _A2AError extends Error {
44
45
  return new _A2AError(-32603, message, data);
45
46
  }
46
47
  static taskNotFound(taskId) {
47
- return new _A2AError(
48
- -32001,
49
- `Task not found: ${taskId}`,
50
- void 0,
51
- taskId
52
- );
48
+ return new _A2AError(-32001, `Task not found: ${taskId}`, void 0, taskId);
53
49
  }
54
50
  static taskNotCancelable(taskId) {
55
- return new _A2AError(
56
- -32002,
57
- `Task not cancelable: ${taskId}`,
58
- void 0,
59
- taskId
60
- );
51
+ return new _A2AError(-32002, `Task not cancelable: ${taskId}`, void 0, taskId);
61
52
  }
62
53
  static pushNotificationNotSupported() {
63
- return new _A2AError(
64
- -32003,
65
- "Push Notification is not supported"
66
- );
54
+ return new _A2AError(-32003, "Push Notification is not supported");
67
55
  }
68
56
  static unsupportedOperation(operation) {
69
- return new _A2AError(
70
- -32004,
71
- `Unsupported operation: ${operation}`
72
- );
57
+ return new _A2AError(-32004, `Unsupported operation: ${operation}`);
73
58
  }
74
59
  static authenticatedExtendedCardNotConfigured() {
75
- return new _A2AError(
76
- -32007,
77
- `Extended card not configured.`
78
- );
60
+ return new _A2AError(-32007, `Extended card not configured.`);
79
61
  }
80
62
  };
81
63
 
82
- // src/server/transports/jsonrpc_transport_handler.ts
64
+ // src/server/context.ts
65
+ var ServerCallContext = class {
66
+ _requestedExtensions;
67
+ _user;
68
+ _activatedExtensions;
69
+ constructor(requestedExtensions, user) {
70
+ this._requestedExtensions = requestedExtensions;
71
+ this._user = user;
72
+ }
73
+ get user() {
74
+ return this._user;
75
+ }
76
+ get activatedExtensions() {
77
+ return this._activatedExtensions;
78
+ }
79
+ get requestedExtensions() {
80
+ return this._requestedExtensions;
81
+ }
82
+ addActivatedExtension(uri) {
83
+ this._activatedExtensions = Extensions.createFrom(this._activatedExtensions, uri);
84
+ }
85
+ };
86
+
87
+ // src/server/transports/jsonrpc/jsonrpc_transport_handler.ts
83
88
  var JsonRpcTransportHandler = class {
84
89
  requestHandler;
85
90
  constructor(requestHandler) {
@@ -90,7 +95,7 @@ var JsonRpcTransportHandler = class {
90
95
  * For streaming methods, it returns an AsyncGenerator of JSONRPCResult.
91
96
  * For non-streaming methods, it returns a Promise of a single JSONRPCMessage (Result or ErrorResponse).
92
97
  */
93
- async handle(requestBody) {
98
+ async handle(requestBody, context) {
94
99
  let rpcRequest;
95
100
  try {
96
101
  if (typeof requestBody === "string") {
@@ -100,31 +105,23 @@ var JsonRpcTransportHandler = class {
100
105
  } else {
101
106
  throw A2AError.parseError("Invalid request body type.");
102
107
  }
103
- if (rpcRequest.jsonrpc !== "2.0" || !rpcRequest.method || typeof rpcRequest.method !== "string") {
104
- throw A2AError.invalidRequest(
105
- "Invalid JSON-RPC request structure."
106
- );
108
+ if (!this.isRequestValid(rpcRequest)) {
109
+ throw A2AError.invalidRequest("Invalid JSON-RPC Request.");
107
110
  }
108
111
  } catch (error) {
109
- const a2aError = error instanceof A2AError ? error : A2AError.parseError(error.message || "Failed to parse JSON request.");
112
+ const a2aError = error instanceof A2AError ? error : A2AError.parseError(
113
+ error instanceof SyntaxError && error.message || "Failed to parse JSON request."
114
+ );
110
115
  return {
111
116
  jsonrpc: "2.0",
112
- id: typeof rpcRequest?.id !== "undefined" ? rpcRequest.id : null,
117
+ id: rpcRequest?.id !== void 0 ? rpcRequest.id : null,
113
118
  error: a2aError.toJSONRPCError()
114
119
  };
115
120
  }
116
121
  const { method, id: requestId = null } = rpcRequest;
117
122
  try {
118
- if (method === "agent/getAuthenticatedExtendedCard") {
119
- const result = await this.requestHandler.getAuthenticatedExtendedAgentCard();
120
- return {
121
- jsonrpc: "2.0",
122
- id: requestId,
123
- result
124
- };
125
- }
126
- if (!rpcRequest.params) {
127
- throw A2AError.invalidParams(`'params' is required for '${method}'`);
123
+ if (method !== "agent/getAuthenticatedExtendedCard" && !this.paramsAreValid(rpcRequest.params)) {
124
+ throw A2AError.invalidParams(`Invalid method parameters.`);
128
125
  }
129
126
  if (method === "message/stream" || method === "tasks/resubscribe") {
130
127
  const params = rpcRequest.params;
@@ -132,8 +129,8 @@ var JsonRpcTransportHandler = class {
132
129
  if (!agentCard.capabilities.streaming) {
133
130
  throw A2AError.unsupportedOperation(`Method ${method} requires streaming capability.`);
134
131
  }
135
- const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params) : this.requestHandler.resubscribe(params);
136
- return async function* jsonRpcEventStream() {
132
+ const agentEventStream = method === "message/stream" ? this.requestHandler.sendMessageStream(params, context) : this.requestHandler.resubscribe(params, context);
133
+ return (async function* jsonRpcEventStream() {
137
134
  try {
138
135
  for await (const event of agentEventStream) {
139
136
  yield {
@@ -144,43 +141,50 @@ var JsonRpcTransportHandler = class {
144
141
  };
145
142
  }
146
143
  } catch (streamError) {
147
- console.error(`Error in agent event stream for ${method} (request ${requestId}):`, streamError);
144
+ console.error(
145
+ `Error in agent event stream for ${method} (request ${requestId}):`,
146
+ streamError
147
+ );
148
148
  throw streamError;
149
149
  }
150
- }();
150
+ })();
151
151
  } else {
152
152
  let result;
153
153
  switch (method) {
154
154
  case "message/send":
155
- result = await this.requestHandler.sendMessage(rpcRequest.params);
155
+ result = await this.requestHandler.sendMessage(rpcRequest.params, context);
156
156
  break;
157
157
  case "tasks/get":
158
- result = await this.requestHandler.getTask(rpcRequest.params);
158
+ result = await this.requestHandler.getTask(rpcRequest.params, context);
159
159
  break;
160
160
  case "tasks/cancel":
161
- result = await this.requestHandler.cancelTask(rpcRequest.params);
161
+ result = await this.requestHandler.cancelTask(rpcRequest.params, context);
162
162
  break;
163
163
  case "tasks/pushNotificationConfig/set":
164
164
  result = await this.requestHandler.setTaskPushNotificationConfig(
165
- rpcRequest.params
165
+ rpcRequest.params,
166
+ context
166
167
  );
167
168
  break;
168
169
  case "tasks/pushNotificationConfig/get":
169
170
  result = await this.requestHandler.getTaskPushNotificationConfig(
170
- rpcRequest.params
171
+ rpcRequest.params,
172
+ context
171
173
  );
172
174
  break;
173
175
  case "tasks/pushNotificationConfig/delete":
174
- await this.requestHandler.deleteTaskPushNotificationConfig(
175
- rpcRequest.params
176
- );
176
+ await this.requestHandler.deleteTaskPushNotificationConfig(rpcRequest.params, context);
177
177
  result = null;
178
178
  break;
179
179
  case "tasks/pushNotificationConfig/list":
180
180
  result = await this.requestHandler.listTaskPushNotificationConfigs(
181
- rpcRequest.params
181
+ rpcRequest.params,
182
+ context
182
183
  );
183
184
  break;
185
+ case "agent/getAuthenticatedExtendedCard":
186
+ result = await this.requestHandler.getAuthenticatedExtendedAgentCard(context);
187
+ break;
184
188
  default:
185
189
  throw A2AError.methodNotFound(method);
186
190
  }
@@ -191,7 +195,14 @@ var JsonRpcTransportHandler = class {
191
195
  };
192
196
  }
193
197
  } catch (error) {
194
- const a2aError = error instanceof A2AError ? error : A2AError.internalError(error.message || "An unexpected error occurred.");
198
+ let a2aError;
199
+ if (error instanceof A2AError) {
200
+ a2aError = error;
201
+ } else {
202
+ a2aError = A2AError.internalError(
203
+ error instanceof Error && error.message || "An unexpected error occurred."
204
+ );
205
+ }
195
206
  return {
196
207
  jsonrpc: "2.0",
197
208
  id: requestId,
@@ -199,9 +210,52 @@ var JsonRpcTransportHandler = class {
199
210
  };
200
211
  }
201
212
  }
213
+ // Validates the basic structure of a JSON-RPC request
214
+ isRequestValid(rpcRequest) {
215
+ if (rpcRequest.jsonrpc !== "2.0") {
216
+ return false;
217
+ }
218
+ if ("id" in rpcRequest) {
219
+ const id = rpcRequest.id;
220
+ const isString = typeof id === "string";
221
+ const isInteger = typeof id === "number" && Number.isInteger(id);
222
+ const isNull = id === null;
223
+ if (!isString && !isInteger && !isNull) {
224
+ return false;
225
+ }
226
+ }
227
+ if (!rpcRequest.method || typeof rpcRequest.method !== "string") {
228
+ return false;
229
+ }
230
+ return true;
231
+ }
232
+ // Validates that params is an object with non-empty string keys
233
+ paramsAreValid(params) {
234
+ if (typeof params !== "object" || params === null || Array.isArray(params)) {
235
+ return false;
236
+ }
237
+ for (const key of Object.keys(params)) {
238
+ if (key === "") {
239
+ return false;
240
+ }
241
+ }
242
+ return true;
243
+ }
244
+ };
245
+
246
+ // src/server/authentication/user.ts
247
+ var UnauthenticatedUser = class {
248
+ get isAuthenticated() {
249
+ return false;
250
+ }
251
+ get userName() {
252
+ return "";
253
+ }
202
254
  };
203
255
 
204
256
  export {
205
257
  A2AError,
206
- JsonRpcTransportHandler
258
+ ServerCallContext,
259
+ JsonRpcTransportHandler,
260
+ UnauthenticatedUser
207
261
  };
@@ -0,0 +1,38 @@
1
+ // src/extensions.ts
2
+ var Extensions = {
3
+ /**
4
+ * Creates new {@link Extensions} from `current` and `additional`.
5
+ * If `current` already contains `additional` it is returned unmodified.
6
+ */
7
+ createFrom: (current, additional) => {
8
+ if (current?.includes(additional)) {
9
+ return current;
10
+ }
11
+ return [...current ?? [], additional];
12
+ },
13
+ /**
14
+ * Creates {@link Extensions} from comma separated extensions identifiers as per
15
+ * https://a2a-protocol.org/latest/specification/#326-service-parameters.
16
+ * Parses the output of `toServiceParameter`.
17
+ */
18
+ parseServiceParameter: (value) => {
19
+ if (!value) {
20
+ return [];
21
+ }
22
+ const unique = new Set(
23
+ value.split(",").map((ext) => ext.trim()).filter((ext) => ext.length > 0)
24
+ );
25
+ return Array.from(unique);
26
+ },
27
+ /**
28
+ * Converts {@link Extensions} to comma separated extensions identifiers as per
29
+ * https://a2a-protocol.org/latest/specification/#326-service-parameters.
30
+ */
31
+ toServiceParameter: (value) => {
32
+ return value.join(",");
33
+ }
34
+ };
35
+
36
+ export {
37
+ Extensions
38
+ };