@adcp/sdk 14.0.0-beta.10 → 14.0.0-beta.12

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 (208) hide show
  1. package/bin/adcp-storyboard-sandbox.js +16 -0
  2. package/bin/adcp.js +28 -30
  3. package/dist/lib/core/AgentClient.d.ts.map +1 -1
  4. package/dist/lib/core/SingleAgentClient.d.mts +2 -1
  5. package/dist/lib/core/SingleAgentClient.d.ts +2 -1
  6. package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
  7. package/dist/lib/core/SingleAgentClient.js +113 -64
  8. package/dist/lib/core/SingleAgentClient.js.map +1 -1
  9. package/dist/lib/core/SingleAgentClient.mjs +113 -64
  10. package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
  11. package/dist/lib/index.d.mts +1 -1
  12. package/dist/lib/index.d.ts +1 -1
  13. package/dist/lib/index.d.ts.map +1 -1
  14. package/dist/lib/index.js.map +1 -1
  15. package/dist/lib/index.mjs.map +1 -1
  16. package/dist/lib/protocols/a2a.d.mts +10 -3
  17. package/dist/lib/protocols/a2a.d.ts +10 -3
  18. package/dist/lib/protocols/a2a.d.ts.map +1 -1
  19. package/dist/lib/protocols/a2a.js +162 -34
  20. package/dist/lib/protocols/a2a.js.map +1 -1
  21. package/dist/lib/protocols/a2a.mjs +166 -34
  22. package/dist/lib/protocols/a2a.mjs.map +1 -1
  23. package/dist/lib/schemas/index.d.mts +385 -1
  24. package/dist/lib/schemas/index.d.ts +385 -1
  25. package/dist/lib/schemas/index.d.ts.map +1 -1
  26. package/dist/lib/schemas/index.js +13 -0
  27. package/dist/lib/schemas/index.js.map +1 -1
  28. package/dist/lib/schemas/index.mjs +11 -0
  29. package/dist/lib/schemas/index.mjs.map +1 -1
  30. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  31. package/dist/lib/server/a2a-adapter.d.mts +59 -33
  32. package/dist/lib/server/a2a-adapter.d.ts +59 -33
  33. package/dist/lib/server/a2a-adapter.d.ts.map +1 -1
  34. package/dist/lib/server/a2a-adapter.js +278 -67
  35. package/dist/lib/server/a2a-adapter.js.map +1 -1
  36. package/dist/lib/server/a2a-adapter.mjs +280 -68
  37. package/dist/lib/server/a2a-adapter.mjs.map +1 -1
  38. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  39. package/dist/lib/server/create-adcp-server.js +35 -108
  40. package/dist/lib/server/create-adcp-server.js.map +1 -1
  41. package/dist/lib/server/create-adcp-server.mjs +37 -109
  42. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  43. package/dist/lib/server/decisioning/index.d.mts +2 -0
  44. package/dist/lib/server/decisioning/index.d.ts +2 -0
  45. package/dist/lib/server/decisioning/index.d.ts.map +1 -1
  46. package/dist/lib/server/decisioning/index.js +5 -2
  47. package/dist/lib/server/decisioning/index.js.map +1 -1
  48. package/dist/lib/server/decisioning/index.mjs +3 -1
  49. package/dist/lib/server/decisioning/index.mjs.map +1 -1
  50. package/dist/lib/server/decisioning/response-summary.d.mts +33 -0
  51. package/dist/lib/server/decisioning/response-summary.d.ts +34 -0
  52. package/dist/lib/server/decisioning/response-summary.d.ts.map +1 -0
  53. package/dist/lib/server/decisioning/response-summary.js +62 -0
  54. package/dist/lib/server/decisioning/response-summary.js.map +1 -0
  55. package/dist/lib/server/decisioning/response-summary.mjs +37 -0
  56. package/dist/lib/server/decisioning/response-summary.mjs.map +1 -0
  57. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
  58. package/dist/lib/server/decisioning/runtime/from-platform.js +27 -5
  59. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  60. package/dist/lib/server/decisioning/runtime/from-platform.mjs +27 -5
  61. package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
  62. package/dist/lib/server/decisioning/specialisms/sales.d.mts +7 -1
  63. package/dist/lib/server/decisioning/specialisms/sales.d.ts +7 -1
  64. package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -1
  65. package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -1
  66. package/dist/lib/server/index.d.mts +1 -1
  67. package/dist/lib/server/index.d.ts +1 -1
  68. package/dist/lib/server/index.d.ts.map +1 -1
  69. package/dist/lib/server/index.js.map +1 -1
  70. package/dist/lib/server/index.mjs.map +1 -1
  71. package/dist/lib/server/responses.d.ts.map +1 -1
  72. package/dist/lib/server/responses.js +9 -1
  73. package/dist/lib/server/responses.js.map +1 -1
  74. package/dist/lib/server/responses.mjs +8 -1
  75. package/dist/lib/server/responses.mjs.map +1 -1
  76. package/dist/lib/signing/agent-context.d.mts +1 -0
  77. package/dist/lib/signing/agent-context.d.ts +1 -0
  78. package/dist/lib/signing/agent-context.d.ts.map +1 -1
  79. package/dist/lib/signing/agent-context.js +37 -2
  80. package/dist/lib/signing/agent-context.js.map +1 -1
  81. package/dist/lib/signing/agent-context.mjs +38 -3
  82. package/dist/lib/signing/agent-context.mjs.map +1 -1
  83. package/dist/lib/signing/agent-fetch.d.mts +1 -2
  84. package/dist/lib/signing/agent-fetch.d.ts +1 -2
  85. package/dist/lib/signing/agent-fetch.d.ts.map +1 -1
  86. package/dist/lib/signing/agent-fetch.js +2 -0
  87. package/dist/lib/signing/agent-fetch.js.map +1 -1
  88. package/dist/lib/signing/agent-fetch.mjs +2 -0
  89. package/dist/lib/signing/agent-fetch.mjs.map +1 -1
  90. package/dist/lib/signing/agent-resolver/etld.js.map +1 -1
  91. package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
  92. package/dist/lib/testing/client.d.mts +6 -0
  93. package/dist/lib/testing/client.d.ts +6 -0
  94. package/dist/lib/testing/client.d.ts.map +1 -1
  95. package/dist/lib/testing/client.js +76 -4
  96. package/dist/lib/testing/client.js.map +1 -1
  97. package/dist/lib/testing/client.mjs +75 -4
  98. package/dist/lib/testing/client.mjs.map +1 -1
  99. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  100. package/dist/lib/testing/compliance/comply.js +6 -0
  101. package/dist/lib/testing/compliance/comply.js.map +1 -1
  102. package/dist/lib/testing/compliance/comply.mjs +7 -1
  103. package/dist/lib/testing/compliance/comply.mjs.map +1 -1
  104. package/dist/lib/testing/storyboard/context.d.ts.map +1 -1
  105. package/dist/lib/testing/storyboard/context.js +9 -4
  106. package/dist/lib/testing/storyboard/context.js.map +1 -1
  107. package/dist/lib/testing/storyboard/context.mjs +9 -4
  108. package/dist/lib/testing/storyboard/context.mjs.map +1 -1
  109. package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -1
  110. package/dist/lib/testing/storyboard/request-builder.js +28 -4
  111. package/dist/lib/testing/storyboard/request-builder.js.map +1 -1
  112. package/dist/lib/testing/storyboard/request-builder.mjs +28 -4
  113. package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
  114. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.mts +15 -0
  115. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts +16 -0
  116. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts.map +1 -0
  117. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js +106 -0
  118. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js.map +1 -0
  119. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs +82 -0
  120. package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs.map +1 -0
  121. package/dist/lib/testing/storyboard/request-signing/test-kit.d.mts +15 -0
  122. package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts +15 -0
  123. package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts.map +1 -1
  124. package/dist/lib/testing/storyboard/request-signing/test-kit.js +58 -0
  125. package/dist/lib/testing/storyboard/request-signing/test-kit.js.map +1 -1
  126. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +58 -0
  127. package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
  128. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  129. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  130. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts.map +1 -1
  131. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +7 -1
  132. package/dist/lib/testing/storyboard/request-signing/vector-loader.js.map +1 -1
  133. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +6 -1
  134. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
  135. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  136. package/dist/lib/testing/storyboard/runner.js +31 -7
  137. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  138. package/dist/lib/testing/storyboard/runner.mjs +31 -7
  139. package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
  140. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  141. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  142. package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
  143. package/dist/lib/testing/storyboard/validations.js +18 -7
  144. package/dist/lib/testing/storyboard/validations.js.map +1 -1
  145. package/dist/lib/testing/storyboard/validations.mjs +18 -7
  146. package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
  147. package/dist/lib/testing/storyboard/webhook-receiver.d.ts.map +1 -1
  148. package/dist/lib/testing/storyboard/webhook-receiver.js +32 -20
  149. package/dist/lib/testing/storyboard/webhook-receiver.js.map +1 -1
  150. package/dist/lib/testing/storyboard/webhook-receiver.mjs +32 -20
  151. package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
  152. package/dist/lib/testing/types.d.mts +10 -0
  153. package/dist/lib/testing/types.d.ts +10 -0
  154. package/dist/lib/testing/types.d.ts.map +1 -1
  155. package/dist/lib/testing/types.js.map +1 -1
  156. package/dist/lib/types/comply-test-controller.d.ts +1 -14
  157. package/dist/lib/types/core.generated.d.mts +1 -1
  158. package/dist/lib/types/core.generated.d.ts +1 -1
  159. package/dist/lib/types/core.generated.d.ts.map +1 -1
  160. package/dist/lib/types/core.generated.js.map +1 -1
  161. package/dist/lib/types/get-products.d.ts +1 -14
  162. package/dist/lib/types/schemas.generated.d.ts +519 -571
  163. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  164. package/dist/lib/types/schemas.generated.js +2 -2
  165. package/dist/lib/types/schemas.generated.js.map +1 -1
  166. package/dist/lib/types/schemas.generated.mjs +2 -2
  167. package/dist/lib/types/schemas.generated.mjs.map +1 -1
  168. package/dist/lib/types/tools.generated.d.mts +1 -1
  169. package/dist/lib/types/tools.generated.d.ts +1 -1
  170. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  171. package/dist/lib/types/tools.generated.js.map +1 -1
  172. package/dist/lib/utils/a2a-artifacts.d.ts.map +1 -1
  173. package/dist/lib/utils/a2a-artifacts.js +2 -2
  174. package/dist/lib/utils/a2a-artifacts.js.map +1 -1
  175. package/dist/lib/utils/a2a-artifacts.mjs +2 -2
  176. package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
  177. package/dist/lib/utils/a2a-discovery.d.mts +3 -3
  178. package/dist/lib/utils/a2a-discovery.d.ts +3 -3
  179. package/dist/lib/utils/a2a-discovery.js +1 -1
  180. package/dist/lib/utils/a2a-discovery.js.map +1 -1
  181. package/dist/lib/utils/a2a-discovery.mjs +1 -1
  182. package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
  183. package/dist/lib/utils/tool-request-schemas.d.mts +31 -31
  184. package/dist/lib/utils/tool-request-schemas.d.ts +31 -31
  185. package/dist/lib/v2/projection/index.d.mts +2 -0
  186. package/dist/lib/v2/projection/index.d.ts +2 -0
  187. package/dist/lib/v2/projection/index.d.ts.map +1 -1
  188. package/dist/lib/v2/projection/index.js +3 -0
  189. package/dist/lib/v2/projection/index.js.map +1 -1
  190. package/dist/lib/v2/projection/index.mjs +2 -0
  191. package/dist/lib/v2/projection/index.mjs.map +1 -1
  192. package/dist/lib/v2/projection/legacy-normalization.d.mts +24 -0
  193. package/dist/lib/v2/projection/legacy-normalization.d.ts +25 -0
  194. package/dist/lib/v2/projection/legacy-normalization.d.ts.map +1 -0
  195. package/dist/lib/v2/projection/legacy-normalization.js +32 -0
  196. package/dist/lib/v2/projection/legacy-normalization.js.map +1 -0
  197. package/dist/lib/v2/projection/legacy-normalization.mjs +8 -0
  198. package/dist/lib/v2/projection/legacy-normalization.mjs.map +1 -0
  199. package/dist/lib/version.d.mts +3 -3
  200. package/dist/lib/version.d.ts +3 -3
  201. package/dist/lib/version.js +3 -3
  202. package/dist/lib/version.js.map +1 -1
  203. package/dist/lib/version.mjs +3 -3
  204. package/dist/lib/version.mjs.map +1 -1
  205. package/docs/guides/BUILD-AN-AGENT.md +42 -6
  206. package/docs/llms.txt +2 -2
  207. package/docs/migration-13-to-14.md +17 -0
  208. package/package.json +44 -41
@@ -1,11 +1,30 @@
1
1
  import {
2
2
  DefaultRequestHandler,
3
3
  InMemoryTaskStore as SdkInMemoryTaskStore,
4
- DefaultExecutionEventBusManager
4
+ DefaultExecutionEventBusManager,
5
+ AgentEvent
5
6
  } from "@a2a-js/sdk/server";
6
7
  import { jsonRpcHandler, agentCardHandler } from "@a2a-js/sdk/server/express";
8
+ import { AgentCard, Role, TaskState } from "@a2a-js/sdk";
9
+ import { duplicateInterfacesForLegacy } from "@a2a-js/sdk/compat/v0_3";
7
10
  import { randomUUID } from "node:crypto";
11
+ import { redactSecrets } from "../utils/redact-secrets.mjs";
8
12
  import { getSdkServer, listRegisteredToolNames } from "./adcp-server.mjs";
13
+ class RedactingA2ATaskStore {
14
+ constructor(delegate) {
15
+ this.delegate = delegate;
16
+ }
17
+ delegate;
18
+ save(task, context) {
19
+ return this.delegate.save(redactSecrets(task), context);
20
+ }
21
+ load(taskId, context) {
22
+ return this.delegate.load(taskId, context);
23
+ }
24
+ list(params, context) {
25
+ return this.delegate.list(params, context);
26
+ }
27
+ }
9
28
  function buildAuthenticatedUser(authInfo) {
10
29
  const clientId = authInfo.clientId;
11
30
  return {
@@ -32,11 +51,13 @@ function getAdcpAuthInfo(context) {
32
51
  const user = context?.user;
33
52
  return user?.adcpAuthInfo;
34
53
  }
35
- function extractInvocation(message) {
54
+ function extractInvocation(message, allowLegacyParameters = false) {
36
55
  if (!Array.isArray(message.parts) || message.parts.length === 0) {
37
56
  throw new A2AInvocationError("Message must carry at least one part with a `data` kind.");
38
57
  }
39
- const dataParts = message.parts.filter((p) => p?.kind === "data");
58
+ const dataParts = message.parts.filter(
59
+ (part) => part.content?.$case === "data"
60
+ );
40
61
  if (dataParts.length === 0) {
41
62
  throw new A2AInvocationError(
42
63
  "Message must include a DataPart with { skill, input } \u2014 text-only messages aren't routable to AdCP tools."
@@ -44,24 +65,27 @@ function extractInvocation(message) {
44
65
  }
45
66
  if (dataParts.length > 1) {
46
67
  throw new A2AInvocationError(
47
- "Message must include exactly one DataPart \u2014 multi-part invocations are not supported in v0."
68
+ "Message must include exactly one DataPart \u2014 multi-part invocations are not supported."
48
69
  );
49
70
  }
50
71
  const firstDataPart = dataParts[0];
51
- const rawData = firstDataPart.data;
72
+ const rawData = firstDataPart.content.value;
52
73
  if (rawData == null || typeof rawData !== "object" || Array.isArray(rawData)) {
53
74
  throw new A2AInvocationError("DataPart `data` must be an object containing { skill, input }.");
54
75
  }
55
76
  const payload = rawData;
56
77
  const skill = payload.skill;
57
- const input = payload.input ?? payload.parameters;
78
+ const input = payload.input ?? (allowLegacyParameters ? payload.parameters : void 0);
58
79
  if (typeof skill !== "string" || skill.length === 0) {
59
80
  throw new A2AInvocationError("DataPart must include a non-empty string `skill` field naming the AdCP tool.");
60
81
  }
61
82
  if (input != null && (typeof input !== "object" || Array.isArray(input))) {
62
- throw new A2AInvocationError("DataPart `input` (or legacy `parameters`) must be an object (or omitted).");
83
+ throw new A2AInvocationError("DataPart `input` must be an object.");
84
+ }
85
+ if (input == null) {
86
+ throw new A2AInvocationError("DataPart must include an `input` object.");
63
87
  }
64
- return { skill, input: input ?? {} };
88
+ return { skill, input };
65
89
  }
66
90
  class A2AInvocationError extends Error {
67
91
  constructor(message) {
@@ -107,12 +131,25 @@ class AdcpA2AAgentExecutor {
107
131
  async execute(requestContext, eventBus) {
108
132
  const { taskId, contextId, userMessage } = requestContext;
109
133
  const authInfo = getAdcpAuthInfo(requestContext.context);
134
+ const requestedExtensions = requestContext.context.requestedExtensions;
135
+ const requestedAdcpExtension = Array.isArray(requestedExtensions) && requestedExtensions.some((extension) => extension === ADCP_A2A_EXTENSION);
136
+ const legacyWire = requestContext.context.requestedVersion.startsWith("0.");
110
137
  this.taskContextIds.set(taskId, contextId);
111
138
  try {
112
139
  this.publishInitialTask(eventBus, taskId, contextId, userMessage);
140
+ if (!legacyWire) {
141
+ if (!requestedAdcpExtension) {
142
+ this.emitFailure(eventBus, taskId, contextId, {
143
+ reason: "REQUIRED_EXTENSION_MISSING",
144
+ message: `A2A requests must activate ${ADCP_A2A_EXTENSION}`
145
+ });
146
+ return;
147
+ }
148
+ requestContext.context.addActivatedExtension(ADCP_A2A_EXTENSION);
149
+ }
113
150
  let invocation;
114
151
  try {
115
- invocation = extractInvocation(userMessage);
152
+ invocation = extractInvocation(userMessage, legacyWire);
116
153
  } catch (err) {
117
154
  const message = err instanceof Error ? err.message : "Invalid A2A invocation";
118
155
  this.emitFailure(eventBus, taskId, contextId, {
@@ -152,7 +189,7 @@ class AdcpA2AAgentExecutor {
152
189
  });
153
190
  this.emitFailure(eventBus, taskId, contextId, {
154
191
  reason: "HANDLER_THREW",
155
- message
192
+ message: "The A2A tool invocation failed."
156
193
  });
157
194
  return;
158
195
  }
@@ -164,17 +201,16 @@ class AdcpA2AAgentExecutor {
164
201
  return;
165
202
  }
166
203
  if (this.canceled.has(taskId)) {
167
- this.publishStatus(eventBus, taskId, contextId, "canceled", true);
204
+ this.publishStatus(eventBus, taskId, contextId, TaskState.TASK_STATE_CANCELED);
168
205
  return;
169
206
  }
170
207
  const classified = classifyResponse(response);
171
- this.publishArtifact(eventBus, taskId, contextId, classified);
208
+ this.publishArtifact(eventBus, taskId, contextId, classified, legacyWire);
172
209
  this.publishStatus(
173
210
  eventBus,
174
211
  taskId,
175
212
  contextId,
176
- classified.kind === "success" || classified.kind === "submitted" || classified.kind === "paused" ? "completed" : "failed",
177
- true
213
+ classified.kind === "success" || classified.kind === "submitted" || classified.kind === "paused" || !legacyWire && classified.kind === "error_arm" ? TaskState.TASK_STATE_COMPLETED : TaskState.TASK_STATE_FAILED
178
214
  );
179
215
  } finally {
180
216
  this.canceled.delete(taskId);
@@ -185,80 +221,98 @@ class AdcpA2AAgentExecutor {
185
221
  async cancelTask(taskId, eventBus) {
186
222
  this.canceled.add(taskId);
187
223
  const contextId = this.taskContextIds.get(taskId) ?? "";
188
- this.publishStatus(eventBus, taskId, contextId, "canceled", true);
224
+ this.publishStatus(eventBus, taskId, contextId, TaskState.TASK_STATE_CANCELED);
189
225
  }
190
226
  publishInitialTask(eventBus, taskId, contextId, userMessage) {
191
227
  const task = {
192
- kind: "task",
193
228
  id: taskId,
194
229
  contextId,
195
230
  status: {
196
- state: "working",
231
+ state: TaskState.TASK_STATE_WORKING,
232
+ message: void 0,
197
233
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
198
234
  },
199
- history: [userMessage]
235
+ artifacts: [],
236
+ history: [userMessage],
237
+ metadata: void 0
200
238
  };
201
- eventBus.publish(task);
239
+ eventBus.publish(AgentEvent.task(task));
202
240
  }
203
- publishStatus(eventBus, taskId, contextId, state, final, messageData) {
241
+ publishStatus(eventBus, taskId, contextId, state, messageData) {
204
242
  const event = {
205
- kind: "status-update",
206
243
  taskId,
207
244
  contextId,
208
245
  status: {
209
246
  state,
210
247
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
211
- ...messageData && {
212
- message: {
213
- kind: "message",
214
- messageId: randomUUID(),
215
- role: "agent",
216
- parts: [{ kind: "data", data: messageData }]
217
- }
218
- }
248
+ message: messageData ? {
249
+ messageId: randomUUID(),
250
+ contextId,
251
+ taskId,
252
+ role: Role.ROLE_AGENT,
253
+ parts: [dataPart(messageData)],
254
+ metadata: void 0,
255
+ extensions: [],
256
+ referenceTaskIds: []
257
+ } : void 0
219
258
  },
220
- final
259
+ metadata: void 0
221
260
  };
222
- eventBus.publish(event);
261
+ eventBus.publish(AgentEvent.statusUpdate(event));
223
262
  }
224
- publishArtifact(eventBus, taskId, contextId, classified) {
263
+ publishArtifact(eventBus, taskId, contextId, classified, legacyWire) {
225
264
  const artifactName = classified.kind === "success" ? "result" : classified.kind === "submitted" ? "submitted" : classified.kind === "paused" ? "result" : "error";
226
265
  const artifact = {
227
266
  artifactId: randomUUID(),
228
267
  name: artifactName,
229
- parts: [{ kind: "data", data: classified.data }],
230
- metadata: {
268
+ description: "",
269
+ parts: [dataPart(classified.data)],
270
+ metadata: legacyWire ? {
231
271
  adcp_status: classified.kind === "submitted" ? "submitted" : classified.kind === "paused" ? classified.status : classified.kind === "success" ? "completed" : "failed",
232
272
  ...classified.kind === "submitted" && { adcp_task_id: classified.adcpTaskId }
233
- }
273
+ } : void 0,
274
+ extensions: []
234
275
  };
235
276
  const event = {
236
- kind: "artifact-update",
237
277
  taskId,
238
278
  contextId,
239
279
  artifact,
240
280
  append: false,
241
- lastChunk: true
281
+ lastChunk: true,
282
+ metadata: void 0
242
283
  };
243
- eventBus.publish(event);
284
+ eventBus.publish(AgentEvent.artifactUpdate(event));
244
285
  }
245
286
  emitFailure(eventBus, taskId, contextId, payload) {
246
287
  const artifact = {
247
288
  artifactId: randomUUID(),
248
289
  name: "error",
249
- parts: [{ kind: "data", data: payload }]
290
+ description: "",
291
+ parts: [dataPart(payload)],
292
+ metadata: void 0,
293
+ extensions: []
250
294
  };
251
- eventBus.publish({
252
- kind: "artifact-update",
253
- taskId,
254
- contextId,
255
- artifact,
256
- append: false,
257
- lastChunk: true
258
- });
259
- this.publishStatus(eventBus, taskId, contextId, "failed", true);
295
+ eventBus.publish(
296
+ AgentEvent.artifactUpdate({
297
+ taskId,
298
+ contextId,
299
+ artifact,
300
+ append: false,
301
+ lastChunk: true,
302
+ metadata: void 0
303
+ })
304
+ );
305
+ this.publishStatus(eventBus, taskId, contextId, TaskState.TASK_STATE_FAILED);
260
306
  }
261
307
  }
308
+ function dataPart(value) {
309
+ return {
310
+ content: { $case: "data", value },
311
+ metadata: void 0,
312
+ filename: "",
313
+ mediaType: "application/json"
314
+ };
315
+ }
262
316
  function isToolNotRegistered(err, toolName) {
263
317
  return err instanceof Error && err.message.includes(`tool "${toolName}" is not registered`);
264
318
  }
@@ -266,7 +320,8 @@ function a2aSkillToServerToolNames(skill) {
266
320
  return skill === "tasks/get" ? ["tasks_get", "tasks/get"] : [skill];
267
321
  }
268
322
  const DEFAULT_MODES = ["application/json"];
269
- const DEFAULT_PROTOCOL_VERSION = "0.3.0";
323
+ const DEFAULT_PROTOCOL_VERSION = "1.0";
324
+ const ADCP_A2A_EXTENSION = "https://adcontextprotocol.org/extensions/adcp/v3";
270
325
  const PUBLIC_AGENT_CARD_EXCLUDED_SKILLS = /* @__PURE__ */ new Set(["comply_test_controller"]);
271
326
  function deriveSkills(toolNames) {
272
327
  const publicNames = new Set(toolNames.map(toA2ASkillName));
@@ -274,7 +329,11 @@ function deriveSkills(toolNames) {
274
329
  id: name,
275
330
  name,
276
331
  description: `AdCP tool: ${name}. Send { skill: "${name}", input: { ... } } as a DataPart.`,
277
- tags: ["adcp"]
332
+ tags: ["adcp"],
333
+ examples: [],
334
+ inputModes: [],
335
+ outputModes: [],
336
+ securityRequirements: []
278
337
  }));
279
338
  }
280
339
  function toA2ASkillName(toolName) {
@@ -292,42 +351,177 @@ function filterPublicAgentCardSkills(skills) {
292
351
  return !(id != null && PUBLIC_AGENT_CARD_EXCLUDED_SKILLS.has(id) || name != null && PUBLIC_AGENT_CARD_EXCLUDED_SKILLS.has(name));
293
352
  });
294
353
  }
354
+ function normalizeAgentCardSkills(skills) {
355
+ return skills.map((skill) => ({
356
+ ...skill,
357
+ examples: skill.examples ?? [],
358
+ inputModes: skill.inputModes ?? [],
359
+ outputModes: skill.outputModes ?? [],
360
+ securityRequirements: skill.securityRequirements ?? []
361
+ }));
362
+ }
295
363
  function buildAgentCard(server, overrides) {
364
+ if (overrides.preferredTransport && overrides.preferredTransport.toUpperCase() !== "JSONRPC") {
365
+ throw new Error("createA2AAdapter: only the JSONRPC A2A transport is supported");
366
+ }
296
367
  const tools = listRegisteredTools(server);
297
- const skills = filterPublicAgentCardSkills(overrides.skills ?? deriveSkills(tools));
368
+ const skills = filterPublicAgentCardSkills(
369
+ overrides.skills ? normalizeAgentCardSkills(overrides.skills) : deriveSkills(tools)
370
+ );
298
371
  if (tools.includes("get_adcp_capabilities") && !skills.some((skill) => skill.id === "get_adcp_capabilities" || skill.name === "get_adcp_capabilities")) {
299
372
  skills.push(...deriveSkills(["get_adcp_capabilities"]));
300
373
  }
301
374
  const card = {
302
375
  name: overrides.name,
303
376
  description: overrides.description,
304
- url: overrides.url,
377
+ supportedInterfaces: duplicateInterfacesForLegacy(
378
+ [
379
+ {
380
+ url: overrides.url,
381
+ protocolBinding: "JSONRPC",
382
+ protocolVersion: DEFAULT_PROTOCOL_VERSION,
383
+ tenant: ""
384
+ }
385
+ ],
386
+ ["JSONRPC"]
387
+ ),
305
388
  version: overrides.version,
306
- protocolVersion: overrides.protocolVersion ?? DEFAULT_PROTOCOL_VERSION,
307
389
  defaultInputModes: overrides.defaultInputModes ?? [...DEFAULT_MODES],
308
390
  defaultOutputModes: overrides.defaultOutputModes ?? [...DEFAULT_MODES],
309
- capabilities: overrides.capabilities ?? {
310
- streaming: false,
311
- pushNotifications: false
391
+ capabilities: {
392
+ streaming: overrides.capabilities?.streaming ?? false,
393
+ pushNotifications: overrides.capabilities?.pushNotifications ?? false,
394
+ extendedAgentCard: overrides.capabilities?.extendedAgentCard,
395
+ extensions: [
396
+ ...(overrides.capabilities?.extensions ?? []).filter((extension) => extension.uri !== ADCP_A2A_EXTENSION),
397
+ {
398
+ uri: ADCP_A2A_EXTENSION,
399
+ description: "AdCP structured task invocation profile",
400
+ required: true,
401
+ params: void 0
402
+ }
403
+ ]
312
404
  },
313
405
  skills,
314
- ...overrides.provider && { provider: overrides.provider },
406
+ provider: overrides.provider,
407
+ securitySchemes: normalizeSecuritySchemes(overrides.securitySchemes),
408
+ securityRequirements: (overrides.security ?? []).map((requirement) => ({
409
+ schemes: Object.fromEntries(Object.entries(requirement).map(([name, scopes]) => [name, { list: scopes }]))
410
+ })),
411
+ signatures: [],
315
412
  ...overrides.documentationUrl && { documentationUrl: overrides.documentationUrl },
316
- ...overrides.iconUrl && { iconUrl: overrides.iconUrl },
317
- ...overrides.securitySchemes && { securitySchemes: overrides.securitySchemes },
318
- ...overrides.security && { security: overrides.security },
319
- ...overrides.preferredTransport && { preferredTransport: overrides.preferredTransport }
413
+ ...overrides.iconUrl && { iconUrl: overrides.iconUrl }
320
414
  };
415
+ Object.defineProperties(card, {
416
+ url: { value: overrides.url, enumerable: false },
417
+ protocolVersion: { value: DEFAULT_PROTOCOL_VERSION, enumerable: false },
418
+ // The SDK's Express card middleware currently calls JSON.stringify on the
419
+ // ts-proto in-memory shape. Supply the official JSON projection so v1
420
+ // security-scheme unions serialize as `type`/`scheme`, not `$case`.
421
+ toJSON: { value: () => AgentCard.toJSON(card), enumerable: false }
422
+ });
321
423
  validateAgentCard(card);
322
424
  return card;
323
425
  }
426
+ function normalizeSecuritySchemes(schemes) {
427
+ return Object.fromEntries(
428
+ Object.entries(schemes ?? {}).map(([name, value]) => {
429
+ const candidate = value;
430
+ if (candidate.scheme && typeof candidate.scheme === "object" && "$case" in candidate.scheme) {
431
+ return [name, value];
432
+ }
433
+ const legacy = value;
434
+ switch (legacy.type) {
435
+ case "apiKey":
436
+ return [
437
+ name,
438
+ {
439
+ scheme: {
440
+ $case: "apiKeySecurityScheme",
441
+ value: { description: legacy.description ?? "", location: legacy.in, name: legacy.name }
442
+ }
443
+ }
444
+ ];
445
+ case "http":
446
+ return [
447
+ name,
448
+ {
449
+ scheme: {
450
+ $case: "httpAuthSecurityScheme",
451
+ value: {
452
+ description: legacy.description ?? "",
453
+ scheme: legacy.scheme,
454
+ bearerFormat: legacy.bearerFormat ?? ""
455
+ }
456
+ }
457
+ }
458
+ ];
459
+ case "oauth2":
460
+ return [
461
+ name,
462
+ {
463
+ scheme: {
464
+ $case: "oauth2SecurityScheme",
465
+ value: {
466
+ description: legacy.description ?? "",
467
+ oauth2MetadataUrl: legacy.oauth2MetadataUrl ?? "",
468
+ flows: normalizeLegacyOAuthFlows(legacy.flows)
469
+ }
470
+ }
471
+ }
472
+ ];
473
+ case "openIdConnect":
474
+ return [
475
+ name,
476
+ {
477
+ scheme: {
478
+ $case: "openIdConnectSecurityScheme",
479
+ value: {
480
+ description: legacy.description ?? "",
481
+ openIdConnectUrl: legacy.openIdConnectUrl
482
+ }
483
+ }
484
+ }
485
+ ];
486
+ case "mutualTLS":
487
+ return [
488
+ name,
489
+ {
490
+ scheme: {
491
+ $case: "mtlsSecurityScheme",
492
+ value: { description: legacy.description ?? "" }
493
+ }
494
+ }
495
+ ];
496
+ }
497
+ throw new Error(`createA2AAdapter: unsupported security scheme shape for "${name}"`);
498
+ })
499
+ );
500
+ }
501
+ function normalizeLegacyOAuthFlows(flows) {
502
+ const selected = flows.authorizationCode ? ["authorizationCode", flows.authorizationCode] : flows.clientCredentials ? ["clientCredentials", flows.clientCredentials] : flows.implicit ? ["implicit", flows.implicit] : flows.password ? ["password", flows.password] : void 0;
503
+ if (!selected) return void 0;
504
+ const [kind, flow] = selected;
505
+ return {
506
+ flow: {
507
+ $case: kind,
508
+ value: {
509
+ authorizationUrl: flow.authorizationUrl ?? "",
510
+ tokenUrl: flow.tokenUrl ?? "",
511
+ refreshUrl: flow.refreshUrl ?? "",
512
+ scopes: flow.scopes,
513
+ ...kind === "authorizationCode" && { pkceRequired: false }
514
+ }
515
+ }
516
+ };
517
+ }
324
518
  function validateAgentCard(card) {
325
519
  const missing = [];
326
520
  if (!card.name) missing.push("name");
327
521
  if (!card.description) missing.push("description");
328
- if (!card.url) missing.push("url");
522
+ if (!card.supportedInterfaces?.[0]?.url) missing.push("supportedInterfaces[0].url");
329
523
  if (!card.version) missing.push("version");
330
- if (!card.protocolVersion) missing.push("protocolVersion");
524
+ if (card.supportedInterfaces?.[0]?.protocolVersion !== DEFAULT_PROTOCOL_VERSION) missing.push("protocolVersion=1.0");
331
525
  if (!card.capabilities) missing.push("capabilities");
332
526
  if (!Array.isArray(card.defaultInputModes) || card.defaultInputModes.length === 0) {
333
527
  missing.push("defaultInputModes");
@@ -356,10 +550,22 @@ const DEFAULT_LOGGER = {
356
550
  function createA2AAdapter(options) {
357
551
  const logger = options.logger ?? DEFAULT_LOGGER;
358
552
  const card = buildAgentCard(options.server, options.agentCard);
359
- const taskStore = options.taskStore ?? new SdkInMemoryTaskStore();
553
+ const handlerCard = structuredClone(card);
554
+ if (handlerCard.capabilities?.extensions) {
555
+ handlerCard.capabilities.extensions = handlerCard.capabilities.extensions.map(
556
+ (extension) => extension.uri === ADCP_A2A_EXTENSION ? { ...extension, required: false } : extension
557
+ );
558
+ }
559
+ const development = process.env.NODE_ENV === "test" || process.env.NODE_ENV === "development";
560
+ if (!options.taskStore && !development) {
561
+ throw new Error(
562
+ "createA2AAdapter: production requires a bounded durable taskStore; the SDK in-memory store is available only under NODE_ENV=test or NODE_ENV=development"
563
+ );
564
+ }
565
+ const taskStore = new RedactingA2ATaskStore(options.taskStore ?? new SdkInMemoryTaskStore());
360
566
  const executor = new AdcpA2AAgentExecutor(options.server, logger);
361
567
  const eventBusManager = new DefaultExecutionEventBusManager();
362
- const requestHandler = new DefaultRequestHandler(card, taskStore, executor, eventBusManager);
568
+ const requestHandler = new DefaultRequestHandler(handlerCard, taskStore, executor, eventBusManager);
363
569
  const userBuilder = async (req) => {
364
570
  if (!options.authenticate) return buildAnonymousUser();
365
571
  const authInfo = await options.authenticate(req);
@@ -368,11 +574,17 @@ function createA2AAdapter(options) {
368
574
  }
369
575
  return buildAuthenticatedUser(authInfo);
370
576
  };
371
- const jsonRpc = jsonRpcHandler({ requestHandler, userBuilder });
372
- const agentCardMiddleware = agentCardHandler({ agentCardProvider: requestHandler });
577
+ const legacyCompat = { enabled: true };
578
+ const jsonRpc = jsonRpcHandler({ requestHandler, userBuilder, legacyCompat });
579
+ const nativeAgentCardMiddleware = agentCardHandler({ agentCardProvider: async () => card });
580
+ const legacyAgentCardMiddleware = agentCardHandler({ agentCardProvider: async () => handlerCard, legacyCompat });
581
+ const agentCardMiddleware = (req, res, next) => {
582
+ const requestedVersion = req.header("A2A-Version");
583
+ return requestedVersion && !requestedVersion.startsWith("0.") ? nativeAgentCardMiddleware(req, res, next) : legacyAgentCardMiddleware(req, res, next);
584
+ };
373
585
  const defaultBasePath = (() => {
374
586
  try {
375
- const parsed = new URL(card.url);
587
+ const parsed = new URL(card.supportedInterfaces[0].url);
376
588
  const pathname = parsed.pathname.replace(/\/+$/, "");
377
589
  return pathname.length > 0 ? pathname : "/a2a";
378
590
  } catch {