@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.
- package/bin/adcp-storyboard-sandbox.js +16 -0
- package/bin/adcp.js +28 -30
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +2 -1
- package/dist/lib/core/SingleAgentClient.d.ts +2 -1
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +113 -64
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +113 -64
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/protocols/a2a.d.mts +10 -3
- package/dist/lib/protocols/a2a.d.ts +10 -3
- package/dist/lib/protocols/a2a.d.ts.map +1 -1
- package/dist/lib/protocols/a2a.js +162 -34
- package/dist/lib/protocols/a2a.js.map +1 -1
- package/dist/lib/protocols/a2a.mjs +166 -34
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/schemas/index.d.mts +385 -1
- package/dist/lib/schemas/index.d.ts +385 -1
- package/dist/lib/schemas/index.d.ts.map +1 -1
- package/dist/lib/schemas/index.js +13 -0
- package/dist/lib/schemas/index.js.map +1 -1
- package/dist/lib/schemas/index.mjs +11 -0
- package/dist/lib/schemas/index.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/a2a-adapter.d.mts +59 -33
- package/dist/lib/server/a2a-adapter.d.ts +59 -33
- package/dist/lib/server/a2a-adapter.d.ts.map +1 -1
- package/dist/lib/server/a2a-adapter.js +278 -67
- package/dist/lib/server/a2a-adapter.js.map +1 -1
- package/dist/lib/server/a2a-adapter.mjs +280 -68
- package/dist/lib/server/a2a-adapter.mjs.map +1 -1
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +35 -108
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +37 -109
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.d.mts +2 -0
- package/dist/lib/server/decisioning/index.d.ts +2 -0
- package/dist/lib/server/decisioning/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.js +5 -2
- package/dist/lib/server/decisioning/index.js.map +1 -1
- package/dist/lib/server/decisioning/index.mjs +3 -1
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/response-summary.d.mts +33 -0
- package/dist/lib/server/decisioning/response-summary.d.ts +34 -0
- package/dist/lib/server/decisioning/response-summary.d.ts.map +1 -0
- package/dist/lib/server/decisioning/response-summary.js +62 -0
- package/dist/lib/server/decisioning/response-summary.js.map +1 -0
- package/dist/lib/server/decisioning/response-summary.mjs +37 -0
- package/dist/lib/server/decisioning/response-summary.mjs.map +1 -0
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +27 -5
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +27 -5
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/sales.d.mts +7 -1
- package/dist/lib/server/decisioning/specialisms/sales.d.ts +7 -1
- package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -1
- package/dist/lib/server/index.d.mts +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/responses.d.ts.map +1 -1
- package/dist/lib/server/responses.js +9 -1
- package/dist/lib/server/responses.js.map +1 -1
- package/dist/lib/server/responses.mjs +8 -1
- package/dist/lib/server/responses.mjs.map +1 -1
- package/dist/lib/signing/agent-context.d.mts +1 -0
- package/dist/lib/signing/agent-context.d.ts +1 -0
- package/dist/lib/signing/agent-context.d.ts.map +1 -1
- package/dist/lib/signing/agent-context.js +37 -2
- package/dist/lib/signing/agent-context.js.map +1 -1
- package/dist/lib/signing/agent-context.mjs +38 -3
- package/dist/lib/signing/agent-context.mjs.map +1 -1
- package/dist/lib/signing/agent-fetch.d.mts +1 -2
- package/dist/lib/signing/agent-fetch.d.ts +1 -2
- package/dist/lib/signing/agent-fetch.d.ts.map +1 -1
- package/dist/lib/signing/agent-fetch.js +2 -0
- package/dist/lib/signing/agent-fetch.js.map +1 -1
- package/dist/lib/signing/agent-fetch.mjs +2 -0
- package/dist/lib/signing/agent-fetch.mjs.map +1 -1
- package/dist/lib/signing/agent-resolver/etld.js.map +1 -1
- package/dist/lib/signing/agent-resolver/etld.mjs.map +1 -1
- package/dist/lib/testing/client.d.mts +6 -0
- package/dist/lib/testing/client.d.ts +6 -0
- package/dist/lib/testing/client.d.ts.map +1 -1
- package/dist/lib/testing/client.js +76 -4
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/client.mjs +75 -4
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
- package/dist/lib/testing/compliance/comply.js +6 -0
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +7 -1
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/storyboard/context.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/context.js +9 -4
- package/dist/lib/testing/storyboard/context.js.map +1 -1
- package/dist/lib/testing/storyboard/context.mjs +9 -4
- package/dist/lib/testing/storyboard/context.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.js +28 -4
- package/dist/lib/testing/storyboard/request-builder.js.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.mjs +28 -4
- package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.mts +15 -0
- package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts +16 -0
- package/dist/lib/testing/storyboard/request-signing/functional-dispatch.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js +106 -0
- package/dist/lib/testing/storyboard/request-signing/functional-dispatch.js.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs +82 -0
- package/dist/lib/testing/storyboard/request-signing/functional-dispatch.mjs.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/test-kit.d.mts +15 -0
- package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts +15 -0
- package/dist/lib/testing/storyboard/request-signing/test-kit.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/test-kit.js +58 -0
- package/dist/lib/testing/storyboard/request-signing/test-kit.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs +58 -0
- package/dist/lib/testing/storyboard/request-signing/test-kit.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js +7 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +6 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +31 -7
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +31 -7
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.js +18 -7
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +18 -7
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.js +32 -20
- package/dist/lib/testing/storyboard/webhook-receiver.js.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.mjs +32 -20
- package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
- package/dist/lib/testing/types.d.mts +10 -0
- package/dist/lib/testing/types.d.ts +10 -0
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/testing/types.js.map +1 -1
- package/dist/lib/types/comply-test-controller.d.ts +1 -14
- package/dist/lib/types/core.generated.d.mts +1 -1
- package/dist/lib/types/core.generated.d.ts +1 -1
- package/dist/lib/types/core.generated.d.ts.map +1 -1
- package/dist/lib/types/core.generated.js.map +1 -1
- package/dist/lib/types/get-products.d.ts +1 -14
- package/dist/lib/types/schemas.generated.d.ts +519 -571
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js +2 -2
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/types/schemas.generated.mjs +2 -2
- package/dist/lib/types/schemas.generated.mjs.map +1 -1
- package/dist/lib/types/tools.generated.d.mts +1 -1
- package/dist/lib/types/tools.generated.d.ts +1 -1
- package/dist/lib/types/tools.generated.d.ts.map +1 -1
- package/dist/lib/types/tools.generated.js.map +1 -1
- package/dist/lib/utils/a2a-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/a2a-artifacts.js +2 -2
- package/dist/lib/utils/a2a-artifacts.js.map +1 -1
- package/dist/lib/utils/a2a-artifacts.mjs +2 -2
- package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
- package/dist/lib/utils/a2a-discovery.d.mts +3 -3
- package/dist/lib/utils/a2a-discovery.d.ts +3 -3
- package/dist/lib/utils/a2a-discovery.js +1 -1
- package/dist/lib/utils/a2a-discovery.js.map +1 -1
- package/dist/lib/utils/a2a-discovery.mjs +1 -1
- package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
- package/dist/lib/utils/tool-request-schemas.d.mts +31 -31
- package/dist/lib/utils/tool-request-schemas.d.ts +31 -31
- package/dist/lib/v2/projection/index.d.mts +2 -0
- package/dist/lib/v2/projection/index.d.ts +2 -0
- package/dist/lib/v2/projection/index.d.ts.map +1 -1
- package/dist/lib/v2/projection/index.js +3 -0
- package/dist/lib/v2/projection/index.js.map +1 -1
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/v2/projection/legacy-normalization.d.mts +24 -0
- package/dist/lib/v2/projection/legacy-normalization.d.ts +25 -0
- package/dist/lib/v2/projection/legacy-normalization.d.ts.map +1 -0
- package/dist/lib/v2/projection/legacy-normalization.js +32 -0
- package/dist/lib/v2/projection/legacy-normalization.js.map +1 -0
- package/dist/lib/v2/projection/legacy-normalization.mjs +8 -0
- package/dist/lib/v2/projection/legacy-normalization.mjs.map +1 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/guides/BUILD-AN-AGENT.md +42 -6
- package/docs/llms.txt +2 -2
- package/docs/migration-13-to-14.md +17 -0
- package/package.json +44 -41
|
@@ -20,10 +20,13 @@ var a2a_exports = {};
|
|
|
20
20
|
__export(a2a_exports, {
|
|
21
21
|
callA2ATool: () => callA2ATool,
|
|
22
22
|
cancelA2ATask: () => cancelA2ATask,
|
|
23
|
-
closeA2AConnections: () => closeA2AConnections
|
|
23
|
+
closeA2AConnections: () => closeA2AConnections,
|
|
24
|
+
createA2AClientFromCardUrl: () => createA2AClientFromCardUrl,
|
|
25
|
+
legacyA2AClientTestShim: () => legacyA2AClientTestShim
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(a2a_exports);
|
|
26
28
|
var import_client = require("@a2a-js/sdk/client");
|
|
29
|
+
var import_sdk = require("@a2a-js/sdk");
|
|
27
30
|
var import_node_async_hooks = require("node:async_hooks");
|
|
28
31
|
var import_errors = require('../errors/index.js');
|
|
29
32
|
var import_discovery = require('../auth/oauth/discovery.js');
|
|
@@ -42,10 +45,9 @@ var import_abort = require('./abort.js');
|
|
|
42
45
|
var import_a2a_artifacts = require('../utils/a2a-artifacts.js');
|
|
43
46
|
var import_agent_transport_fetch = require('../net/agent-transport-fetch.js');
|
|
44
47
|
var import_address_guards = require('../net/address-guards.js');
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
48
|
+
const ADCP_A2A_EXTENSION = "https://adcontextprotocol.org/extensions/adcp/v3";
|
|
49
|
+
const defaultTestFromCardUrl = (cardUrl, options) => createNativeA2AClientFromCardUrl(cardUrl, options.fetchImpl);
|
|
50
|
+
const legacyA2AClientTestShim = { fromCardUrl: defaultTestFromCardUrl };
|
|
49
51
|
const callContextStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
50
52
|
const a2aClientCache = /* @__PURE__ */ new Map();
|
|
51
53
|
const pendingA2AClients = /* @__PURE__ */ new Map();
|
|
@@ -133,14 +135,14 @@ async function cancelA2ATask(agent, taskId, fetchFn, allowPrivateIp) {
|
|
|
133
135
|
let lastError;
|
|
134
136
|
for (const cardUrl of (0, import_a2a_discovery.buildCardUrls)(agentUrl)) {
|
|
135
137
|
try {
|
|
136
|
-
client = await
|
|
138
|
+
client = await createA2AClientFromCardUrl(cardUrl, fetchImpl);
|
|
137
139
|
break;
|
|
138
140
|
} catch (err) {
|
|
139
141
|
lastError = err;
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
144
|
if (!client) throw lastError instanceof Error ? lastError : new Error("A2A agent card discovery failed");
|
|
143
|
-
await client.cancelTask({ id: taskId });
|
|
145
|
+
await client.cancelTask({ tenant: "", id: taskId, metadata: void 0 });
|
|
144
146
|
}
|
|
145
147
|
async function getOrCreateA2AClient(agentUrl, authToken, customHeaders, bypassCache = false) {
|
|
146
148
|
const signingContext = import_client2.signingContextStorage.getStore();
|
|
@@ -187,7 +189,7 @@ async function createA2AClient(agentUrl, authToken) {
|
|
|
187
189
|
let lastError = new Error(`A2A agent card not found at ${cardUrls.join(", ")}`);
|
|
188
190
|
for (const cardUrl of cardUrls) {
|
|
189
191
|
try {
|
|
190
|
-
client = await
|
|
192
|
+
client = await createA2AClientFromCardUrl(cardUrl, fetchImpl);
|
|
191
193
|
break;
|
|
192
194
|
} catch (err) {
|
|
193
195
|
lastError = err;
|
|
@@ -197,6 +199,108 @@ async function createA2AClient(agentUrl, authToken) {
|
|
|
197
199
|
if (!client) throw lastError;
|
|
198
200
|
return client;
|
|
199
201
|
}
|
|
202
|
+
async function createA2AClientFromCardUrl(cardUrl, fetchImpl) {
|
|
203
|
+
if (process.env.NODE_ENV === "test" && legacyA2AClientTestShim.fromCardUrl !== defaultTestFromCardUrl) {
|
|
204
|
+
return legacyA2AClientTestShim.fromCardUrl(cardUrl, { fetchImpl });
|
|
205
|
+
}
|
|
206
|
+
return createNativeA2AClientFromCardUrl(cardUrl, fetchImpl);
|
|
207
|
+
}
|
|
208
|
+
async function createNativeA2AClientFromCardUrl(cardUrl, fetchImpl) {
|
|
209
|
+
const legacyCompat = { enabled: true };
|
|
210
|
+
const factory = new import_client.ClientFactory({
|
|
211
|
+
transports: [new import_client.JsonRpcTransportFactory({ fetchImpl, legacyCompat })],
|
|
212
|
+
cardResolver: new import_client.DefaultAgentCardResolver({ fetchImpl, legacyCompat })
|
|
213
|
+
});
|
|
214
|
+
return factory.createFromUrl(cardUrl, "");
|
|
215
|
+
}
|
|
216
|
+
function toA2APushNotificationConfig(config) {
|
|
217
|
+
const authentication = config.authentication;
|
|
218
|
+
return {
|
|
219
|
+
tenant: "",
|
|
220
|
+
id: "",
|
|
221
|
+
taskId: "",
|
|
222
|
+
url: config.url,
|
|
223
|
+
token: config.token ?? "",
|
|
224
|
+
authentication: authentication ? {
|
|
225
|
+
scheme: authentication.schemes?.[0] ?? "",
|
|
226
|
+
credentials: authentication.credentials ?? ""
|
|
227
|
+
} : void 0
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function normalizeA2APart(part) {
|
|
231
|
+
switch (part?.content?.$case) {
|
|
232
|
+
case "data":
|
|
233
|
+
return { kind: "data", data: part.content.value, metadata: part.metadata };
|
|
234
|
+
case "text":
|
|
235
|
+
return { kind: "text", text: part.content.value, metadata: part.metadata };
|
|
236
|
+
case "url":
|
|
237
|
+
return {
|
|
238
|
+
kind: "file",
|
|
239
|
+
file: { uri: part.content.value, name: part.filename, mimeType: part.mediaType },
|
|
240
|
+
metadata: part.metadata
|
|
241
|
+
};
|
|
242
|
+
case "raw":
|
|
243
|
+
return {
|
|
244
|
+
kind: "file",
|
|
245
|
+
file: { bytes: part.content.value, name: part.filename, mimeType: part.mediaType },
|
|
246
|
+
metadata: part.metadata
|
|
247
|
+
};
|
|
248
|
+
default:
|
|
249
|
+
return part;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function taskStateName(state) {
|
|
253
|
+
switch (state) {
|
|
254
|
+
case import_sdk.TaskState.TASK_STATE_SUBMITTED:
|
|
255
|
+
return "submitted";
|
|
256
|
+
case import_sdk.TaskState.TASK_STATE_WORKING:
|
|
257
|
+
return "working";
|
|
258
|
+
case import_sdk.TaskState.TASK_STATE_COMPLETED:
|
|
259
|
+
return "completed";
|
|
260
|
+
case import_sdk.TaskState.TASK_STATE_FAILED:
|
|
261
|
+
return "failed";
|
|
262
|
+
case import_sdk.TaskState.TASK_STATE_CANCELED:
|
|
263
|
+
return "canceled";
|
|
264
|
+
case import_sdk.TaskState.TASK_STATE_INPUT_REQUIRED:
|
|
265
|
+
return "input-required";
|
|
266
|
+
case import_sdk.TaskState.TASK_STATE_REJECTED:
|
|
267
|
+
return "rejected";
|
|
268
|
+
case import_sdk.TaskState.TASK_STATE_AUTH_REQUIRED:
|
|
269
|
+
return "auth-required";
|
|
270
|
+
default:
|
|
271
|
+
return void 0;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function normalizeA2AResult(result) {
|
|
275
|
+
if (result && typeof result === "object" && ("result" in result || "error" in result)) {
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
if (result && Array.isArray(result.artifacts)) {
|
|
279
|
+
return {
|
|
280
|
+
result: {
|
|
281
|
+
...result,
|
|
282
|
+
kind: "task",
|
|
283
|
+
status: result.status ? {
|
|
284
|
+
...result.status,
|
|
285
|
+
state: taskStateName(result.status.state),
|
|
286
|
+
message: result.status.message ? {
|
|
287
|
+
...result.status.message,
|
|
288
|
+
kind: "message",
|
|
289
|
+
parts: result.status.message.parts.map(normalizeA2APart)
|
|
290
|
+
} : void 0
|
|
291
|
+
} : void 0,
|
|
292
|
+
artifacts: result.artifacts.map((artifact) => ({
|
|
293
|
+
...artifact,
|
|
294
|
+
parts: artifact.parts?.map(normalizeA2APart) ?? []
|
|
295
|
+
}))
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
if (result && Array.isArray(result.parts)) {
|
|
300
|
+
return { result: { ...result, kind: "message", parts: result.parts.map(normalizeA2APart) } };
|
|
301
|
+
}
|
|
302
|
+
return { result };
|
|
303
|
+
}
|
|
200
304
|
function buildFetchImpl(authToken, agentUrl) {
|
|
201
305
|
const signingContext = import_client2.signingContextStorage.getStore();
|
|
202
306
|
const pinnedFetch = (0, import_agent_transport_fetch.createAgentTransportFetch)(agentUrl, {
|
|
@@ -208,6 +312,9 @@ function buildFetchImpl(authToken, agentUrl) {
|
|
|
208
312
|
);
|
|
209
313
|
const baseFetch = async (url, options) => {
|
|
210
314
|
const context = callContextStorage.getStore();
|
|
315
|
+
const urlString = typeof url === "string" ? url : url instanceof URL ? url.toString() : url.url;
|
|
316
|
+
const credentialOrigin = new URL(agentUrl).origin;
|
|
317
|
+
const sameOrigin = new URL(urlString).origin === credentialOrigin;
|
|
211
318
|
const existingHeaders = {};
|
|
212
319
|
if (options?.headers) {
|
|
213
320
|
if (options.headers instanceof Headers) {
|
|
@@ -222,15 +329,21 @@ function buildFetchImpl(authToken, agentUrl) {
|
|
|
222
329
|
Object.assign(existingHeaders, options.headers);
|
|
223
330
|
}
|
|
224
331
|
}
|
|
225
|
-
|
|
332
|
+
if (!sameOrigin) {
|
|
333
|
+
for (const key of Object.keys(existingHeaders)) {
|
|
334
|
+
if (!["accept", "content-type", "a2a-version", "a2a-extensions"].includes(key.toLowerCase())) {
|
|
335
|
+
delete existingHeaders[key];
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
226
339
|
const isDiscoveryRequest = (0, import_a2a_discovery.isAgentCardPath)(urlString);
|
|
227
|
-
const traceHeaders = isDiscoveryRequest ? {} : (0, import_tracing.injectTraceHeaders)();
|
|
340
|
+
const traceHeaders = isDiscoveryRequest || !sameOrigin ? {} : (0, import_tracing.injectTraceHeaders)();
|
|
228
341
|
const requestTimeoutMs = isDiscoveryRequest ? (0, import_abort.resolveRequestTimeoutMs)(context?.requestTimeoutMs, import_abort.DEFAULT_REQUEST_TIMEOUT_MS) : (0, import_abort.resolveRequestTimeoutMs)(context?.requestTimeoutMs);
|
|
229
342
|
const headers = {
|
|
230
343
|
...existingHeaders,
|
|
231
344
|
...traceHeaders,
|
|
232
|
-
...context?.customHeaders,
|
|
233
|
-
...authToken && {
|
|
345
|
+
...sameOrigin ? context?.customHeaders : void 0,
|
|
346
|
+
...sameOrigin && authToken && {
|
|
234
347
|
Authorization: `Bearer ${authToken}`,
|
|
235
348
|
"x-adcp-auth": authToken
|
|
236
349
|
}
|
|
@@ -316,47 +429,56 @@ async function callA2AToolImpl(agentUrl, toolName, parameters, authToken, debugL
|
|
|
316
429
|
context.customHeaders,
|
|
317
430
|
!!context.signal || context.requestTimeoutMs !== void 0
|
|
318
431
|
);
|
|
432
|
+
const legacyWire = client.protocolVersion?.startsWith("0.") ?? false;
|
|
433
|
+
const invocation = legacyWire ? { skill: toolName, parameters } : { skill: toolName, input: parameters };
|
|
319
434
|
const requestPayload = {
|
|
435
|
+
tenant: "",
|
|
320
436
|
message: {
|
|
321
437
|
messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
322
|
-
role:
|
|
323
|
-
kind: "message",
|
|
438
|
+
role: import_sdk.Role.ROLE_USER,
|
|
324
439
|
parts: [
|
|
325
440
|
{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
441
|
+
content: {
|
|
442
|
+
$case: "data",
|
|
443
|
+
value: invocation
|
|
444
|
+
},
|
|
445
|
+
metadata: void 0,
|
|
446
|
+
filename: "",
|
|
447
|
+
mediaType: "application/json"
|
|
331
448
|
}
|
|
332
449
|
],
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
450
|
+
contextId: session?.contextId ?? "",
|
|
451
|
+
taskId: session?.taskId ?? "",
|
|
452
|
+
metadata: void 0,
|
|
453
|
+
extensions: legacyWire ? [] : [ADCP_A2A_EXTENSION],
|
|
454
|
+
referenceTaskIds: []
|
|
455
|
+
},
|
|
456
|
+
configuration: pushNotificationConfig ? {
|
|
457
|
+
acceptedOutputModes: ["application/json"],
|
|
458
|
+
taskPushNotificationConfig: toA2APushNotificationConfig(pushNotificationConfig),
|
|
459
|
+
returnImmediately: false
|
|
460
|
+
} : void 0,
|
|
461
|
+
metadata: void 0
|
|
336
462
|
};
|
|
337
|
-
if (pushNotificationConfig) {
|
|
338
|
-
requestPayload.configuration = {
|
|
339
|
-
pushNotificationConfig
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
463
|
const payloadSize = JSON.stringify(requestPayload).length;
|
|
343
464
|
const redactedParameters = (0, import_redact_args.redactArgsForLog)(parameters);
|
|
465
|
+
const redactedInvocation = legacyWire ? { skill: toolName, parameters: redactedParameters } : { skill: toolName, input: redactedParameters };
|
|
344
466
|
const redactedPayload = {
|
|
345
467
|
...requestPayload,
|
|
346
468
|
message: {
|
|
347
469
|
...requestPayload.message,
|
|
348
470
|
parts: [
|
|
349
471
|
{
|
|
350
|
-
|
|
351
|
-
|
|
472
|
+
content: { $case: "data", value: redactedInvocation },
|
|
473
|
+
metadata: void 0,
|
|
474
|
+
filename: "",
|
|
475
|
+
mediaType: "application/json"
|
|
352
476
|
}
|
|
353
477
|
]
|
|
354
478
|
},
|
|
355
479
|
...requestPayload.configuration && {
|
|
356
480
|
configuration: {
|
|
357
|
-
|
|
358
|
-
requestPayload.configuration.pushNotificationConfig
|
|
359
|
-
)
|
|
481
|
+
taskPushNotificationConfig: redactPushNotificationConfigForDebug(pushNotificationConfig)
|
|
360
482
|
}
|
|
361
483
|
}
|
|
362
484
|
};
|
|
@@ -375,7 +497,11 @@ async function callA2AToolImpl(agentUrl, toolName, parameters, authToken, debugL
|
|
|
375
497
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
376
498
|
skill: toolName
|
|
377
499
|
});
|
|
378
|
-
const
|
|
500
|
+
const result = await client.sendMessage(requestPayload, {
|
|
501
|
+
...legacyWire ? {} : { serviceParameters: import_client.ServiceParameters.create((0, import_client.withA2AExtensions)(ADCP_A2A_EXTENSION)) },
|
|
502
|
+
signal: context.signal
|
|
503
|
+
});
|
|
504
|
+
const messageResponse = normalizeA2AResult(result);
|
|
379
505
|
debugLogs.push({
|
|
380
506
|
type: messageResponse?.error ? "error" : "success",
|
|
381
507
|
message: `A2A: Response received (${messageResponse?.error ? "error" : "success"})`,
|
|
@@ -425,6 +551,8 @@ async function callA2AToolImpl(agentUrl, toolName, parameters, authToken, debugL
|
|
|
425
551
|
0 && (module.exports = {
|
|
426
552
|
callA2ATool,
|
|
427
553
|
cancelA2ATask,
|
|
428
|
-
closeA2AConnections
|
|
554
|
+
closeA2AConnections,
|
|
555
|
+
createA2AClientFromCardUrl,
|
|
556
|
+
legacyA2AClientTestShim
|
|
429
557
|
});
|
|
430
558
|
//# sourceMappingURL=a2a.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/protocols/a2a.ts"],"sourcesContent":["// Official A2A client implementation - NO FALLBACKS\nimport { A2AClient as A2AClientImpl } from '@a2a-js/sdk/client';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { PushNotificationConfig } from '../types/tools.generated';\nimport type { DebugLogEntry } from '../types/adcp';\nimport { AuthenticationRequiredError, is401Error } from '../errors';\nimport { discoverOAuthMetadata } from '../auth/oauth/discovery';\nimport { probeAuthChallenge } from '../auth/oauth/authorization-required';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { isAgentCardPath, buildCardUrls } from '../utils/a2a-discovery';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport { toSignerKey, isInlineSigningConfig, isProviderSigningConfig } from '../signing/agent-fetch';\nimport { createSigningFetch, type FetchLike } from '../signing/fetch';\nimport { createSigningFetchAsync } from '../signing/fetch-async';\nimport type { AgentConfig } from '../types/adcp';\nimport { redactArgsForLog } from '../utils/redact-args';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\nimport { DEFAULT_REQUEST_TIMEOUT_MS, resolveRequestTimeoutMs, withAbortSignal } from './abort';\nimport { getLatestA2ADataPartFromResponse } from '../utils/a2a-artifacts';\nimport { createAgentTransportFetch } from '../net/agent-transport-fetch';\nimport { isLikelyPrivateUrl } from '../net/address-guards';\n\n// The A2A SDK client is used untyped: request/response shapes are validated at\n// runtime against the AdCP wire contract, not against the SDK's exported\n// types. Preserves the prior behaviour of the CommonJS `require` form.\nconst A2AClient: any = A2AClientImpl;\n\nif (!A2AClient) {\n throw new Error('A2A SDK client is required. Please install @a2a-js/sdk');\n}\n\n/**\n * Per-call state flowed through AsyncLocalStorage so concurrent callers\n * that share a cached A2AClient don't clobber each other's debugLogs,\n * customHeaders, or 401 flag.\n */\ninterface A2ACallContext {\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n got401Ref: { value: boolean };\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n allowPrivateIp?: boolean;\n}\n\nconst callContextStorage = new AsyncLocalStorage<A2ACallContext>();\n\n/**\n * Cached A2AClient keyed by (agentUrl, authToken hash). Avoids re-fetching\n * /.well-known/agent.json on every tool call. The cached client's fetchImpl\n * reads per-call state from callContextStorage, so concurrent calls to the\n * same cache entry are safe.\n *\n * Process-global singleton — not suitable for multi-tenant servers that\n * want per-tenant isolation (use separate processes or explicit cache keys).\n */\nconst a2aClientCache = new Map<string, InstanceType<typeof A2AClient>>();\nconst pendingA2AClients = new Map<string, Promise<InstanceType<typeof A2AClient>>>();\nconst MAX_CACHED_A2A_CLIENTS = 20;\nlet a2aClientGeneration = 0;\n\nfunction getCachedA2AClient(cacheKey: string): InstanceType<typeof A2AClient> | undefined {\n const client = a2aClientCache.get(cacheKey);\n if (!client) return undefined;\n a2aClientCache.delete(cacheKey);\n a2aClientCache.set(cacheKey, client);\n return client;\n}\n\nfunction evictLeastRecentlyUsedA2AClients(): void {\n while (a2aClientCache.size > MAX_CACHED_A2A_CLIENTS) {\n const oldestKey = a2aClientCache.keys().next().value as string | undefined;\n if (oldestKey === undefined) return;\n a2aClientCache.delete(oldestKey);\n }\n}\n\n/**\n * Build the A2A connection-cache key. Mirrors the rationale in\n * `src/lib/protocols/mcp.ts:connectionCacheKey`: when the caller is using a\n * non-bearer scheme (RFC 7617 Basic from the CLI's `--auth-scheme basic`\n * shape, or any future caller-injected `Authorization` header), `authToken`\n * is undefined and the credential rides on the customHeaders bag. Hashing\n * only `authToken` would let two callers with different `user:pass`\n * credentials share a single cached A2AClient — single-CLI-process safe,\n * multi-tenant SDK consumer not safe.\n *\n * `customHeaders` also feed the key so tenant/routing headers cannot reuse a\n * card/client discovered for another caller. Scoped fetch calls bypass this\n * cache entirely (see `getOrCreateA2AClient`).\n */\nfunction a2aCacheKey(\n agentUrl: string,\n authToken?: string,\n signingCacheKey?: string,\n customHeaders?: Record<string, string>,\n allowPrivateIp = false\n): string {\n // Use the exact credential/header material in this private, in-memory key.\n // The cached client already retains the same credential, so hashing would\n // not reduce secret lifetime and would introduce a collision boundary.\n // This key is never logged or persisted.\n const fingerprint = authToken ?? extractA2AAuthHeader(customHeaders);\n const headersKey = headersCacheMaterial(customHeaders);\n // A serialized tuple avoids delimiter ambiguity between attacker-controlled\n // URLs and the policy/auth suffixes (for example, a URL ending in a suffix).\n return JSON.stringify([agentUrl, fingerprint ?? null, headersKey ?? null, signingCacheKey ?? null, allowPrivateIp]);\n}\n\n/**\n * Case-insensitive lookup of `Authorization` on a header bag. Mirrors the\n * MCP-side helper; A2A keeps its own copy because the two protocol modules\n * intentionally don't share runtime imports.\n */\nfunction extractA2AAuthHeader(headers: Record<string, string> | undefined): string | undefined {\n if (!headers) return undefined;\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization' && value) return value;\n }\n return undefined;\n}\n\nfunction headersCacheMaterial(headers?: Record<string, string>): string | undefined {\n const entries = Object.entries(headers ?? {})\n .filter(([key]) => {\n const lower = key.toLowerCase();\n return lower !== 'traceparent' && lower !== 'tracestate' && lower !== 'baggage';\n })\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([a], [b]) => a.localeCompare(b));\n return entries.length > 0 ? JSON.stringify(entries) : undefined;\n}\n\nfunction redactHeadersForDebug(headers: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(headers).map(key => [key, '***']));\n}\n\nfunction redactPushNotificationConfigForDebug(\n config: PushNotificationConfig | undefined\n): PushNotificationConfig | undefined {\n if (!config) return undefined;\n return {\n ...config,\n ...(config.token && { token: '***' }),\n ...(config.authentication && {\n authentication: {\n ...config.authentication,\n ...(config.authentication.credentials && { credentials: '***' }),\n },\n }),\n };\n}\n\n/**\n * Clear all cached A2A clients. Called by closeConnections('a2a').\n * A2A clients hold no persistent network resources (unlike MCP), so this\n * is just cache eviction.\n */\nexport function closeA2AConnections(): void {\n a2aClientGeneration++;\n a2aClientCache.clear();\n pendingA2AClients.clear();\n}\n\n/**\n * Wall-clock cap on a fire-and-forget cancel. A2A sellers that accept the\n * TCP connect but never respond would otherwise pin the event loop past the\n * buyer's abort, which defeats the whole point of fire-and-forget.\n */\nconst CANCEL_TIMEOUT_MS = 5000;\n\n/**\n * Fire-and-forget A2A tasks/cancel for an in-flight task (A2A 0.3.0 §7.4).\n *\n * Sends a raw JSON-RPC 2.0 POST directly to the agent endpoint with the same\n * auth header shape as `callA2AToolImpl` (Bearer + x-adcp-auth). Does NOT\n * enter `callContextStorage` — debug-log capture and 401-cache-eviction are\n * intentionally skipped for best-effort cancellation.\n *\n * **Auth-code OAuth gap:** `authToken` is resolved by `getAuthToken(agent)`,\n * which returns `undefined` for authorization-code-flow sellers (those tokens\n * are managed by the OAuth provider path in `ProtocolClient.callTool`, not\n * accessible here). Cancel calls to those sellers go out unauthenticated and\n * will likely 401 non-fatally.\n *\n * **Phase 2 (adcp-client#1617 follow-up):** when `agent.request_signing` is\n * configured, the cancel POST is signed with the agent's signer key. The\n * `signingContextStorage` ALS scope around `callA2AToolImpl` does NOT extend\n * into `pollTaskCompletion` (sibling promise trees), so we can't replay the\n * captured ALS context — instead we rebuild a one-shot signer fetch from\n * `agent.request_signing` directly and use it for this single POST. Inline\n * keys go through `createSigningFetch` (sync); provider-backed configs use\n * `createSigningFetchAsync`. A `signed-requests` seller that requires\n * signing on `tasks/cancel` (or applies a uniform \"all mutating POSTs must\n * be signed\" policy) now accepts the cancel; one without signing config on\n * the agent gets the Phase 1 unsigned path.\n *\n * The caller is responsible for swallowing errors: cancel failure\n * (TaskNotCancelable, network error, auth rejection, network timeout) is\n * non-fatal because the buyer is already abandoning the task.\n *\n * @param agent The agent config (used for URL, auth token, signing).\n * @param taskId The server-assigned A2A Task.id to cancel.\n */\nexport async function cancelA2ATask(\n agent: AgentConfig,\n taskId: string,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<void> {\n // Defense-in-depth (ad-tech-protocol-expert review of #1640): the cancel\n // POST is JSON-RPC at the bare A2A endpoint. Calling this on an MCP agent\n // would POST `tasks/cancel` JSON-RPC at an MCP endpoint and 404. The\n // single call site (`pollTaskCompletion`) already gates on\n // `agent.protocol === 'a2a'`; this assertion catches future call sites\n // that forget the gate.\n if (agent.protocol !== 'a2a') {\n return;\n }\n const agentUrl = agent.agent_uri;\n const transportFetch = createAgentTransportFetch(agentUrl, { trustedFetchFn: fetchFn, allowPrivateIp });\n const authToken = agent.auth_token;\n\n // adcp-client#1617 Phase 2: sign the cancel POST when the agent has a\n // signer configured. We bypass the `buildAgentSigningFetch` capability-\n // gate path because `tasks/cancel` is an A2A protocol method, not an\n // AdCP tool — the seller's `request_signing.supported_for` typically\n // lists AdCP tool names, not protocol-level methods. The right model\n // here: if the agent claims signing AT ALL, sign every mutating POST\n // we send to it on the cancel path. Sellers with uniform \"must be\n // signed\" policies accept this; sellers that only check signing on\n // specific AdCP tools simply ignore the extra signature.\n //\n // TODO(adcp#4318, adcp-client#1617): when the AdCP spec adds explicit\n // verifier coverage for A2A protocol methods (likely in 3.1 as a new\n // `protocol_methods_supported_for` / `protocol_methods_required_for`\n // field on `request_signing`), narrow this default by reading the\n // seller's advertised coverage from `getCapability()` and gating on\n // the `tasks/cancel` membership. The over-sign default stays as the\n // fallback for spec-silent sellers (3.0.x and earlier).\n let requestFetch: FetchLike = (input, init) => transportFetch(input as RequestInfo | URL, init);\n if (agent.request_signing && isInlineSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetch(requestFetch, toSignerKey(agent.request_signing));\n } else if (agent.request_signing && isProviderSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetchAsync(requestFetch, agent.request_signing.provider);\n }\n\n const timeoutSignal = AbortSignal.timeout(CANCEL_TIMEOUT_MS);\n const fetchImpl: typeof fetch = (input, init = {}) => {\n const headers = new Headers(init.headers);\n if (authToken) {\n headers.set('authorization', `Bearer ${authToken}`);\n headers.set('x-adcp-auth', authToken);\n }\n const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return requestFetch(input, { ...init, headers, signal }) as Promise<Response>;\n };\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err) {\n lastError = err;\n }\n }\n if (!client) throw lastError instanceof Error ? lastError : new Error('A2A agent card discovery failed');\n await client.cancelTask({ id: taskId });\n}\n\nasync function getOrCreateA2AClient(\n agentUrl: string,\n authToken: string | undefined,\n customHeaders?: Record<string, string>,\n bypassCache = false\n): Promise<InstanceType<typeof A2AClient>> {\n const signingContext = signingContextStorage.getStore();\n const callContext = callContextStorage.getStore();\n const fetchFn = callContext?.fetchFn;\n const cacheKey = a2aCacheKey(\n agentUrl,\n authToken,\n signingContext?.cacheKey,\n customHeaders,\n callContext?.allowPrivateIp === true\n );\n // Scoped fetchers often carry request/tenant-specific egress policy. Keep\n // those calls one-shot so neither agent-card discovery nor a client created\n // under one policy can be reused by another caller, and so short-lived\n // closure identities do not grow the global cache without bound.\n if (bypassCache || fetchFn) {\n return createA2AClient(agentUrl, authToken);\n }\n const cached = getCachedA2AClient(cacheKey);\n if (cached) return cached;\n\n const pending = pendingA2AClients.get(cacheKey);\n if (pending) return pending;\n\n const generation = a2aClientGeneration;\n const promise = createA2AClient(agentUrl, authToken)\n .then(client => {\n if (generation !== a2aClientGeneration) {\n throw new Error('A2A agent-card discovery completed after connection teardown');\n }\n a2aClientCache.set(cacheKey, client);\n evictLeastRecentlyUsedA2AClients();\n return client;\n })\n .finally(() => {\n if (pendingA2AClients.get(cacheKey) === promise) pendingA2AClients.delete(cacheKey);\n });\n\n pendingA2AClients.set(cacheKey, promise);\n return promise;\n}\n\nasync function createA2AClient(\n agentUrl: string,\n authToken: string | undefined\n): Promise<InstanceType<typeof A2AClient>> {\n const fetchImpl = buildFetchImpl(authToken, agentUrl);\n const cardUrls = buildCardUrls(agentUrl);\n\n const context = callContextStorage.getStore();\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Discovering agent card at ${cardUrls.join(', ')}`,\n timestamp: new Date().toISOString(),\n });\n\n let client: InstanceType<typeof A2AClient> | undefined;\n let lastError: Error = new Error(`A2A agent card not found at ${cardUrls.join(', ')}`);\n for (const cardUrl of cardUrls) {\n try {\n client = await A2AClient.fromCardUrl(cardUrl, { fetchImpl });\n break;\n } catch (err: unknown) {\n lastError = err as Error;\n if (context?.got401Ref.value) break;\n }\n }\n if (!client) throw lastError;\n\n return client;\n}\n\nfunction buildFetchImpl(authToken: string | undefined, agentUrl: string) {\n // The A2A client is cached per (url, authToken, signingCacheKey). We capture\n // the signing context at client-creation time so all subsequent calls that\n // share this cached client use the same signing identity — changing identity\n // requires a different cache entry, built on a separate call that enters ALS\n // with a different context.\n const signingContext = signingContextStorage.getStore();\n const pinnedFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: callContextStorage.getStore()?.fetchFn,\n allowPrivateIp: callContextStorage.getStore()?.allowPrivateIp,\n });\n\n // Innermost wrapper: enforce response body size cap from the active\n // `responseSizeLimitStorage` slot. Pass-through when no slot is set.\n const networkFetch = wrapFetchWithTransportDiagnostics(\n wrapFetchWithSizeLimit((input, init) => pinnedFetch(input, init))\n );\n\n // Inner fetch handles auth/header injection and 401 detection. If the\n // agent has request-signing configured, we wrap it with the AdCP signing\n // fetch so the signature covers the exact bytes we're about to send (auth\n // headers included, since the signer re-reads the final header record).\n const baseFetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {\n const context = callContextStorage.getStore();\n\n const existingHeaders: Record<string, string> = {};\n if (options?.headers) {\n if (options.headers instanceof Headers) {\n options.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(options.headers)) {\n for (const [key, value] of options.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, options.headers);\n }\n }\n\n // Only inject trace context headers for actual tool requests, not discovery.\n // The agent card endpoint is external/untrusted — don't leak trace IDs to it.\n const urlString = typeof url === 'string' ? url : url.toString();\n const isDiscoveryRequest = isAgentCardPath(urlString);\n const traceHeaders = isDiscoveryRequest ? {} : injectTraceHeaders();\n const requestTimeoutMs = isDiscoveryRequest\n ? resolveRequestTimeoutMs(context?.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS)\n : resolveRequestTimeoutMs(context?.requestTimeoutMs);\n\n // Merge: existing < trace < custom < auth (auth always wins)\n const headers: Record<string, string> = {\n ...existingHeaders,\n ...traceHeaders,\n ...context?.customHeaders,\n ...(authToken && {\n Authorization: `Bearer ${authToken}`,\n 'x-adcp-auth': authToken,\n }),\n };\n\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Fetch to ${urlString}`,\n timestamp: new Date().toISOString(),\n hasAuth: !!authToken,\n headers: redactHeadersForDebug(headers),\n });\n\n const response = await withAbortSignal<Response>([context?.signal, options?.signal], requestTimeoutMs, signal =>\n networkFetch(url as any, { ...options, headers, signal })\n );\n\n if (response.status === 401 && context) {\n context.got401Ref.value = true;\n }\n\n return response;\n };\n\n if (!signingContext) return wrapFetchWithCapture(baseFetch);\n\n // The signing wrapper assembles headers into the signature base. We invoke\n // it first so the signer sees the caller-supplied headers; baseFetch then\n // overlays auth/trace headers afterwards — A2A's auth scheme (bearer) is\n // not among the MANDATORY_COMPONENTS and is injected by the counterparty's\n // transport layer, not signed.\n const signingFetch = buildAgentSigningFetch({\n upstream: (input, init) => baseFetch(input as any, init),\n signing: signingContext.signing,\n getCapability: signingContext.getCapability,\n adcpVersion: signingContext.adcpVersion,\n });\n return wrapFetchWithCapture(signingFetch as typeof fetch);\n}\n\n/**\n * Terminal A2A task states per A2A 0.3.0 §3.4. Only these can carry the\n * AdCP-mandated artifact + DataPart envelope (per transport-errors §A2A\n * Binding); intermediate states (`working`, `submitted`, `input-required`,\n * `auth-required`) carry no completion artifact.\n */\nconst TERMINAL_A2A_STATES = new Set(['completed', 'failed', 'rejected', 'canceled']);\n\n/**\n * Detect whether a JSON-RPC response carries a spec-compliant terminal-state\n * Task with at least one artifact containing a structured DataPart payload.\n * Per AdCP transport-errors §A2A Binding, the artifact's DataPart is the\n * canonical envelope for both the success arm (`completed`) and the error\n * arms (`failed` / `rejected` / `canceled`). The criterion intentionally\n * matches the unwrapper's terminal-state extraction in\n * `unwrapA2AResponse` — keeping protocol layer and unwrapper in lockstep\n * across all terminal states, not just the error arms.\n *\n * Used to short-circuit the generic \"A2A agent returned error\" throw when\n * a non-conformant seller surfaces both a transport-level `result.error`\n * hint and the canonical artifact envelope side-by-side. The DataPart is\n * authoritative; the throw would otherwise swallow it.\n */\nfunction hasTerminalTaskWithDataArtifact(response: unknown): boolean {\n if (!response || typeof response !== 'object') return false;\n const result = (response as { result?: unknown }).result;\n if (!result || typeof result !== 'object') return false;\n const r = result as { kind?: unknown; status?: unknown; artifacts?: unknown };\n if (r.kind !== 'task') return false;\n const status = r.status as { state?: unknown } | undefined;\n if (typeof status?.state !== 'string' || !TERMINAL_A2A_STATES.has(status.state)) return false;\n return getLatestA2ADataPartFromResponse(response) !== undefined;\n}\n\n/**\n * Protocol-level session identifiers that ride on the A2A Message envelope\n * (not in the skill parameters). `contextId` binds sends to a server-side\n * conversation; `taskId` resumes an existing non-terminal task.\n *\n * Callers (buyers) typically retain these across calls on a per-conversation\n * AgentClient. `getPendingTaskId()` returns this transport Task.id, not the\n * AdCP work handle used by `tasks/get`; see `TaskResult.metadata.serverTaskId`.\n */\nexport interface A2ASessionIds {\n contextId?: string;\n taskId?: string;\n}\n\nexport async function callA2ATool(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n pushNotificationConfig?: PushNotificationConfig,\n customHeaders?: Record<string, string>,\n signingContext?: AgentSigningContext,\n session?: A2ASessionIds,\n signal?: AbortSignal,\n requestTimeoutMs?: number,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<unknown> {\n return withSpan(\n 'adcp.a2a.call_tool',\n {\n 'adcp.tool': toolName,\n 'http.url': agentUrl,\n },\n async () => {\n const context: A2ACallContext = {\n customHeaders,\n debugLogs,\n got401Ref: { value: false },\n signal,\n requestTimeoutMs,\n fetchFn,\n allowPrivateIp,\n };\n return signingContextStorage.run(signingContext, () =>\n callContextStorage.run(context, () =>\n callA2AToolImpl(\n agentUrl,\n toolName,\n parameters,\n authToken,\n debugLogs,\n pushNotificationConfig,\n context,\n session\n )\n )\n );\n }\n );\n}\n\nasync function callA2AToolImpl(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken: string | undefined,\n debugLogs: DebugLogEntry[],\n pushNotificationConfig: PushNotificationConfig | undefined,\n context: A2ACallContext,\n session: A2ASessionIds | undefined\n): Promise<unknown> {\n try {\n const client = await getOrCreateA2AClient(\n agentUrl,\n authToken,\n context.customHeaders,\n !!context.signal || context.requestTimeoutMs !== undefined\n );\n\n const requestPayload: {\n message: {\n messageId: string;\n role: string;\n kind: string;\n parts: Array<{ kind: string; data: { skill: string; parameters: Record<string, unknown> } }>;\n contextId?: string;\n taskId?: string;\n };\n configuration?: { pushNotificationConfig: PushNotificationConfig };\n } = {\n message: {\n messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n role: 'user',\n kind: 'message',\n parts: [\n {\n kind: 'data',\n data: {\n skill: toolName,\n parameters: parameters,\n },\n },\n ],\n ...(session?.contextId && { contextId: session.contextId }),\n ...(session?.taskId && { taskId: session.taskId }),\n },\n };\n\n if (pushNotificationConfig) {\n requestPayload.configuration = {\n pushNotificationConfig: pushNotificationConfig,\n };\n }\n\n const payloadSize = JSON.stringify(requestPayload).length;\n const redactedParameters = redactArgsForLog(parameters);\n const redactedPayload = {\n ...requestPayload,\n message: {\n ...requestPayload.message,\n parts: [\n {\n kind: 'data',\n data: { skill: toolName, parameters: redactedParameters },\n },\n ],\n },\n ...(requestPayload.configuration && {\n configuration: {\n pushNotificationConfig: redactPushNotificationConfigForDebug(\n requestPayload.configuration.pushNotificationConfig\n )!,\n },\n }),\n };\n debugLogs.push({\n type: 'info',\n message: `A2A: Calling skill ${toolName} with parameters: ${JSON.stringify(\n redactedParameters\n )}. Payload size: ${payloadSize} bytes`,\n timestamp: new Date().toISOString(),\n payloadSize,\n actualPayload: redactedPayload,\n });\n\n debugLogs.push({\n type: 'info',\n message: `A2A: Sending message via sendMessage()`,\n timestamp: new Date().toISOString(),\n skill: toolName,\n });\n\n const messageResponse = await client.sendMessage(requestPayload);\n\n debugLogs.push({\n type: messageResponse?.error ? 'error' : 'success',\n message: `A2A: Response received (${messageResponse?.error ? 'error' : 'success'})`,\n timestamp: new Date().toISOString(),\n response: messageResponse,\n skill: toolName,\n });\n\n if (messageResponse?.error || messageResponse?.result?.error) {\n // adcp-client#1575: when the seller emits a spec-compliant terminal-state\n // Task carrying an `adcp_error` DataPart (per AdCP transport-errors §A2A\n // Binding), the structured artifact is canonical — even if the seller\n // also surfaced a transport-level error string. Pass the response\n // through so the upstream unwrapper extracts `adcp_error.code` instead\n // of throwing a generic message that loses the AdCP error envelope.\n if (!hasTerminalTaskWithDataArtifact(messageResponse)) {\n const errorObj = messageResponse.error || messageResponse.result?.error;\n const errorMessage = errorObj.message || JSON.stringify(errorObj);\n throw new Error(`A2A agent returned error: ${errorMessage}`);\n }\n }\n\n return messageResponse;\n } catch (error: unknown) {\n if (is401Error(error, context.got401Ref.value)) {\n // Evict this cache entry — credential may have expired or been\n // revoked. Same disambiguator as the original `getOrCreateA2AClient`\n // call: when the credential rode on customHeaders.Authorization (Basic\n // case) rather than authToken, the cache key must reflect that or we\n // evict the wrong entry.\n const signingContext = signingContextStorage.getStore();\n a2aClientCache.delete(\n a2aCacheKey(\n agentUrl,\n authToken,\n signingContext?.cacheKey,\n context.customHeaders,\n context.allowPrivateIp === true\n )\n );\n\n debugLogs.push({\n type: 'error',\n message: `A2A: Authentication required for ${agentUrl}`,\n timestamp: new Date().toISOString(),\n });\n\n // Re-probe to surface the WWW-Authenticate scheme on the error envelope.\n // Basic-fronted agents (Apigee/Kong/AWS API GW with a BasicAuthentication\n // policy) would otherwise leave consumers chasing OAuth metadata that\n // doesn't exist. Matches the MCP discovery throw site in\n // `SingleAgentClient.discoverMCPEndpoint`.\n const challenge = await probeAuthChallenge(agentUrl, {\n fetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n const oauthMetadata = await discoverOAuthMetadata(agentUrl, {\n trustedFetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n throw new AuthenticationRequiredError(agentUrl, oauthMetadata || undefined, undefined, challenge ?? undefined);\n }\n\n throw error;\n }\n}\n"],"mappings":"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","names":["import_client","A2AClientImpl"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/protocols/a2a.ts"],"sourcesContent":["// Official A2A client implementation - NO FALLBACKS\nimport {\n ClientFactory,\n DefaultAgentCardResolver,\n JsonRpcTransportFactory,\n ServiceParameters,\n withA2AExtensions,\n type Client,\n} from '@a2a-js/sdk/client';\nimport { Role, TaskState, type SendMessageRequest, type TaskPushNotificationConfig } from '@a2a-js/sdk';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport type { PushNotificationConfig } from '../types/tools.generated';\nimport type { DebugLogEntry } from '../types/adcp';\nimport { AuthenticationRequiredError, is401Error } from '../errors';\nimport { discoverOAuthMetadata } from '../auth/oauth/discovery';\nimport { probeAuthChallenge } from '../auth/oauth/authorization-required';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { isAgentCardPath, buildCardUrls } from '../utils/a2a-discovery';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport { toSignerKey, isInlineSigningConfig, isProviderSigningConfig } from '../signing/agent-fetch';\nimport { createSigningFetch, type FetchLike } from '../signing/fetch';\nimport { createSigningFetchAsync } from '../signing/fetch-async';\nimport type { AgentConfig } from '../types/adcp';\nimport { redactArgsForLog } from '../utils/redact-args';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\nimport { DEFAULT_REQUEST_TIMEOUT_MS, resolveRequestTimeoutMs, withAbortSignal } from './abort';\nimport { getLatestA2ADataPartFromResponse } from '../utils/a2a-artifacts';\nimport { createAgentTransportFetch } from '../net/agent-transport-fetch';\nimport { isLikelyPrivateUrl } from '../net/address-guards';\n\nconst ADCP_A2A_EXTENSION = 'https://adcontextprotocol.org/extensions/adcp/v3';\nconst defaultTestFromCardUrl = (cardUrl: string, options: { fetchImpl: typeof fetch }) =>\n createNativeA2AClientFromCardUrl(cardUrl, options.fetchImpl);\nexport const legacyA2AClientTestShim = { fromCardUrl: defaultTestFromCardUrl };\n\n/**\n * Per-call state flowed through AsyncLocalStorage so concurrent callers\n * that share a cached A2AClient don't clobber each other's debugLogs,\n * customHeaders, or 401 flag.\n */\ninterface A2ACallContext {\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n got401Ref: { value: boolean };\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n allowPrivateIp?: boolean;\n}\n\nconst callContextStorage = new AsyncLocalStorage<A2ACallContext>();\n\n/**\n * Cached A2AClient keyed by (agentUrl, authToken hash). Avoids re-fetching\n * /.well-known/agent.json on every tool call. The cached client's fetchImpl\n * reads per-call state from callContextStorage, so concurrent calls to the\n * same cache entry are safe.\n *\n * Process-global singleton — not suitable for multi-tenant servers that\n * want per-tenant isolation (use separate processes or explicit cache keys).\n */\nconst a2aClientCache = new Map<string, Client>();\nconst pendingA2AClients = new Map<string, Promise<Client>>();\nconst MAX_CACHED_A2A_CLIENTS = 20;\nlet a2aClientGeneration = 0;\n\nfunction getCachedA2AClient(cacheKey: string): Client | undefined {\n const client = a2aClientCache.get(cacheKey);\n if (!client) return undefined;\n a2aClientCache.delete(cacheKey);\n a2aClientCache.set(cacheKey, client);\n return client;\n}\n\nfunction evictLeastRecentlyUsedA2AClients(): void {\n while (a2aClientCache.size > MAX_CACHED_A2A_CLIENTS) {\n const oldestKey = a2aClientCache.keys().next().value as string | undefined;\n if (oldestKey === undefined) return;\n a2aClientCache.delete(oldestKey);\n }\n}\n\n/**\n * Build the A2A connection-cache key. Mirrors the rationale in\n * `src/lib/protocols/mcp.ts:connectionCacheKey`: when the caller is using a\n * non-bearer scheme (RFC 7617 Basic from the CLI's `--auth-scheme basic`\n * shape, or any future caller-injected `Authorization` header), `authToken`\n * is undefined and the credential rides on the customHeaders bag. Hashing\n * only `authToken` would let two callers with different `user:pass`\n * credentials share a single cached A2AClient — single-CLI-process safe,\n * multi-tenant SDK consumer not safe.\n *\n * `customHeaders` also feed the key so tenant/routing headers cannot reuse a\n * card/client discovered for another caller. Scoped fetch calls bypass this\n * cache entirely (see `getOrCreateA2AClient`).\n */\nfunction a2aCacheKey(\n agentUrl: string,\n authToken?: string,\n signingCacheKey?: string,\n customHeaders?: Record<string, string>,\n allowPrivateIp = false\n): string {\n // Use the exact credential/header material in this private, in-memory key.\n // The cached client already retains the same credential, so hashing would\n // not reduce secret lifetime and would introduce a collision boundary.\n // This key is never logged or persisted.\n const fingerprint = authToken ?? extractA2AAuthHeader(customHeaders);\n const headersKey = headersCacheMaterial(customHeaders);\n // A serialized tuple avoids delimiter ambiguity between attacker-controlled\n // URLs and the policy/auth suffixes (for example, a URL ending in a suffix).\n return JSON.stringify([agentUrl, fingerprint ?? null, headersKey ?? null, signingCacheKey ?? null, allowPrivateIp]);\n}\n\n/**\n * Case-insensitive lookup of `Authorization` on a header bag. Mirrors the\n * MCP-side helper; A2A keeps its own copy because the two protocol modules\n * intentionally don't share runtime imports.\n */\nfunction extractA2AAuthHeader(headers: Record<string, string> | undefined): string | undefined {\n if (!headers) return undefined;\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === 'authorization' && value) return value;\n }\n return undefined;\n}\n\nfunction headersCacheMaterial(headers?: Record<string, string>): string | undefined {\n const entries = Object.entries(headers ?? {})\n .filter(([key]) => {\n const lower = key.toLowerCase();\n return lower !== 'traceparent' && lower !== 'tracestate' && lower !== 'baggage';\n })\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([a], [b]) => a.localeCompare(b));\n return entries.length > 0 ? JSON.stringify(entries) : undefined;\n}\n\nfunction redactHeadersForDebug(headers: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(headers).map(key => [key, '***']));\n}\n\nfunction redactPushNotificationConfigForDebug(\n config: PushNotificationConfig | undefined\n): PushNotificationConfig | undefined {\n if (!config) return undefined;\n return {\n ...config,\n ...(config.token && { token: '***' }),\n ...(config.authentication && {\n authentication: {\n ...config.authentication,\n ...(config.authentication.credentials && { credentials: '***' }),\n },\n }),\n };\n}\n\n/**\n * Clear all cached A2A clients. Called by closeConnections('a2a').\n * A2A clients hold no persistent network resources (unlike MCP), so this\n * is just cache eviction.\n */\nexport function closeA2AConnections(): void {\n a2aClientGeneration++;\n a2aClientCache.clear();\n pendingA2AClients.clear();\n}\n\n/**\n * Wall-clock cap on a fire-and-forget cancel. A2A sellers that accept the\n * TCP connect but never respond would otherwise pin the event loop past the\n * buyer's abort, which defeats the whole point of fire-and-forget.\n */\nconst CANCEL_TIMEOUT_MS = 5000;\n\n/**\n * Fire-and-forget A2A CancelTask for an in-flight task.\n *\n * Uses the official A2A 1.0 client with the same auth header shape as\n * `callA2AToolImpl` (Bearer + x-adcp-auth). Does NOT\n * enter `callContextStorage` — debug-log capture and 401-cache-eviction are\n * intentionally skipped for best-effort cancellation.\n *\n * **Auth-code OAuth gap:** `authToken` is resolved by `getAuthToken(agent)`,\n * which returns `undefined` for authorization-code-flow sellers (those tokens\n * are managed by the OAuth provider path in `ProtocolClient.callTool`, not\n * accessible here). Cancel calls to those sellers go out unauthenticated and\n * will likely 401 non-fatally.\n *\n * **Phase 2 (adcp-client#1617 follow-up):** when `agent.request_signing` is\n * configured, the cancel POST is signed with the agent's signer key. The\n * `signingContextStorage` ALS scope around `callA2AToolImpl` does NOT extend\n * into `pollTaskCompletion` (sibling promise trees), so we can't replay the\n * captured ALS context — instead we rebuild a one-shot signer fetch from\n * `agent.request_signing` directly and use it for this single POST. Inline\n * keys go through `createSigningFetch` (sync); provider-backed configs use\n * `createSigningFetchAsync`. A `signed-requests` seller that requires\n * signing on `tasks/cancel` (or applies a uniform \"all mutating POSTs must\n * be signed\" policy) now accepts the cancel; one without signing config on\n * the agent gets the Phase 1 unsigned path.\n *\n * The caller is responsible for swallowing errors: cancel failure\n * (TaskNotCancelable, network error, auth rejection, network timeout) is\n * non-fatal because the buyer is already abandoning the task.\n *\n * @param agent The agent config (used for URL, auth token, signing).\n * @param taskId The server-assigned A2A Task.id to cancel.\n */\nexport async function cancelA2ATask(\n agent: AgentConfig,\n taskId: string,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<void> {\n // Defense-in-depth (ad-tech-protocol-expert review of #1640): the cancel\n // request targets the discovered A2A endpoint. Calling this on an MCP agent\n // would attempt A2A discovery against an MCP endpoint. The\n // single call site (`pollTaskCompletion`) already gates on\n // `agent.protocol === 'a2a'`; this assertion catches future call sites\n // that forget the gate.\n if (agent.protocol !== 'a2a') {\n return;\n }\n const agentUrl = agent.agent_uri;\n const transportFetch = createAgentTransportFetch(agentUrl, { trustedFetchFn: fetchFn, allowPrivateIp });\n const authToken = agent.auth_token;\n\n // adcp-client#1617 Phase 2: sign the cancel POST when the agent has a\n // signer configured. We bypass the `buildAgentSigningFetch` capability-\n // gate path because `tasks/cancel` is an A2A protocol method, not an\n // AdCP tool — the seller's `request_signing.supported_for` typically\n // lists AdCP tool names, not protocol-level methods. The right model\n // here: if the agent claims signing AT ALL, sign every mutating POST\n // we send to it on the cancel path. Sellers with uniform \"must be\n // signed\" policies accept this; sellers that only check signing on\n // specific AdCP tools simply ignore the extra signature.\n //\n // TODO(adcp#4318, adcp-client#1617): when the AdCP spec adds explicit\n // verifier coverage for A2A protocol methods (likely in 3.1 as a new\n // `protocol_methods_supported_for` / `protocol_methods_required_for`\n // field on `request_signing`), narrow this default by reading the\n // seller's advertised coverage from `getCapability()` and gating on\n // the `tasks/cancel` membership. The over-sign default stays as the\n // fallback for spec-silent sellers (3.0.x and earlier).\n let requestFetch: FetchLike = (input, init) => transportFetch(input as RequestInfo | URL, init);\n if (agent.request_signing && isInlineSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetch(requestFetch, toSignerKey(agent.request_signing));\n } else if (agent.request_signing && isProviderSigningConfig(agent.request_signing)) {\n requestFetch = createSigningFetchAsync(requestFetch, agent.request_signing.provider);\n }\n\n const timeoutSignal = AbortSignal.timeout(CANCEL_TIMEOUT_MS);\n const fetchImpl: typeof fetch = (input, init = {}) => {\n const headers = new Headers(init.headers);\n if (authToken) {\n headers.set('authorization', `Bearer ${authToken}`);\n headers.set('x-adcp-auth', authToken);\n }\n const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return requestFetch(input, { ...init, headers, signal }) as Promise<Response>;\n };\n\n let client: Client | undefined;\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n client = await createA2AClientFromCardUrl(cardUrl, fetchImpl);\n break;\n } catch (err) {\n lastError = err;\n }\n }\n if (!client) throw lastError instanceof Error ? lastError : new Error('A2A agent card discovery failed');\n await client.cancelTask({ tenant: '', id: taskId, metadata: undefined });\n}\n\nasync function getOrCreateA2AClient(\n agentUrl: string,\n authToken: string | undefined,\n customHeaders?: Record<string, string>,\n bypassCache = false\n): Promise<Client> {\n const signingContext = signingContextStorage.getStore();\n const callContext = callContextStorage.getStore();\n const fetchFn = callContext?.fetchFn;\n const cacheKey = a2aCacheKey(\n agentUrl,\n authToken,\n signingContext?.cacheKey,\n customHeaders,\n callContext?.allowPrivateIp === true\n );\n // Scoped fetchers often carry request/tenant-specific egress policy. Keep\n // those calls one-shot so neither agent-card discovery nor a client created\n // under one policy can be reused by another caller, and so short-lived\n // closure identities do not grow the global cache without bound.\n if (bypassCache || fetchFn) {\n return createA2AClient(agentUrl, authToken);\n }\n const cached = getCachedA2AClient(cacheKey);\n if (cached) return cached;\n\n const pending = pendingA2AClients.get(cacheKey);\n if (pending) return pending;\n\n const generation = a2aClientGeneration;\n const promise = createA2AClient(agentUrl, authToken)\n .then(client => {\n if (generation !== a2aClientGeneration) {\n throw new Error('A2A agent-card discovery completed after connection teardown');\n }\n a2aClientCache.set(cacheKey, client);\n evictLeastRecentlyUsedA2AClients();\n return client;\n })\n .finally(() => {\n if (pendingA2AClients.get(cacheKey) === promise) pendingA2AClients.delete(cacheKey);\n });\n\n pendingA2AClients.set(cacheKey, promise);\n return promise;\n}\n\nasync function createA2AClient(agentUrl: string, authToken: string | undefined): Promise<Client> {\n const fetchImpl = buildFetchImpl(authToken, agentUrl);\n const cardUrls = buildCardUrls(agentUrl);\n\n const context = callContextStorage.getStore();\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Discovering agent card at ${cardUrls.join(', ')}`,\n timestamp: new Date().toISOString(),\n });\n\n let client: Client | undefined;\n let lastError: Error = new Error(`A2A agent card not found at ${cardUrls.join(', ')}`);\n for (const cardUrl of cardUrls) {\n try {\n client = await createA2AClientFromCardUrl(cardUrl, fetchImpl);\n break;\n } catch (err: unknown) {\n lastError = err as Error;\n if (context?.got401Ref.value) break;\n }\n }\n if (!client) throw lastError;\n\n return client;\n}\n\nexport async function createA2AClientFromCardUrl(cardUrl: string, fetchImpl: typeof fetch): Promise<Client> {\n // Keep the long-standing unit-test seam while production uses the v1\n // factory. Existing tests replace this shim with deterministic stubs;\n // never consult it outside tests.\n if (process.env.NODE_ENV === 'test' && legacyA2AClientTestShim.fromCardUrl !== defaultTestFromCardUrl) {\n return legacyA2AClientTestShim.fromCardUrl(cardUrl, { fetchImpl }) as unknown as Client;\n }\n return createNativeA2AClientFromCardUrl(cardUrl, fetchImpl);\n}\n\nasync function createNativeA2AClientFromCardUrl(cardUrl: string, fetchImpl: typeof fetch): Promise<Client> {\n const legacyCompat = { enabled: true } as const;\n const factory = new ClientFactory({\n transports: [new JsonRpcTransportFactory({ fetchImpl, legacyCompat })],\n cardResolver: new DefaultAgentCardResolver({ fetchImpl, legacyCompat }),\n });\n return factory.createFromUrl(cardUrl, '');\n}\n\nfunction toA2APushNotificationConfig(config: PushNotificationConfig): TaskPushNotificationConfig {\n const authentication = config.authentication as { schemes?: string[]; credentials?: string } | undefined;\n return {\n tenant: '',\n id: '',\n taskId: '',\n url: config.url,\n token: config.token ?? '',\n authentication: authentication\n ? {\n scheme: authentication.schemes?.[0] ?? '',\n credentials: authentication.credentials ?? '',\n }\n : undefined,\n };\n}\n\nfunction normalizeA2APart(part: any): Record<string, unknown> {\n switch (part?.content?.$case) {\n case 'data':\n return { kind: 'data', data: part.content.value, metadata: part.metadata };\n case 'text':\n return { kind: 'text', text: part.content.value, metadata: part.metadata };\n case 'url':\n return {\n kind: 'file',\n file: { uri: part.content.value, name: part.filename, mimeType: part.mediaType },\n metadata: part.metadata,\n };\n case 'raw':\n return {\n kind: 'file',\n file: { bytes: part.content.value, name: part.filename, mimeType: part.mediaType },\n metadata: part.metadata,\n };\n default:\n return part;\n }\n}\n\nfunction taskStateName(state: TaskState | undefined): string | undefined {\n switch (state) {\n case TaskState.TASK_STATE_SUBMITTED:\n return 'submitted';\n case TaskState.TASK_STATE_WORKING:\n return 'working';\n case TaskState.TASK_STATE_COMPLETED:\n return 'completed';\n case TaskState.TASK_STATE_FAILED:\n return 'failed';\n case TaskState.TASK_STATE_CANCELED:\n return 'canceled';\n case TaskState.TASK_STATE_INPUT_REQUIRED:\n return 'input-required';\n case TaskState.TASK_STATE_REJECTED:\n return 'rejected';\n case TaskState.TASK_STATE_AUTH_REQUIRED:\n return 'auth-required';\n default:\n return undefined;\n }\n}\n\nfunction normalizeA2AResult(result: any): { result: unknown } {\n if (result && typeof result === 'object' && ('result' in result || 'error' in result)) {\n return result;\n }\n if (result && Array.isArray(result.artifacts)) {\n return {\n result: {\n ...result,\n kind: 'task',\n status: result.status\n ? {\n ...result.status,\n state: taskStateName(result.status.state),\n message: result.status.message\n ? {\n ...result.status.message,\n kind: 'message',\n parts: result.status.message.parts.map(normalizeA2APart),\n }\n : undefined,\n }\n : undefined,\n artifacts: result.artifacts.map((artifact: any) => ({\n ...artifact,\n parts: artifact.parts?.map(normalizeA2APart) ?? [],\n })),\n },\n };\n }\n if (result && Array.isArray(result.parts)) {\n return { result: { ...result, kind: 'message', parts: result.parts.map(normalizeA2APart) } };\n }\n return { result };\n}\n\nfunction buildFetchImpl(authToken: string | undefined, agentUrl: string) {\n // The A2A client is cached per (url, authToken, signingCacheKey). We capture\n // the signing context at client-creation time so all subsequent calls that\n // share this cached client use the same signing identity — changing identity\n // requires a different cache entry, built on a separate call that enters ALS\n // with a different context.\n const signingContext = signingContextStorage.getStore();\n const pinnedFetch = createAgentTransportFetch(agentUrl, {\n trustedFetchFn: callContextStorage.getStore()?.fetchFn,\n allowPrivateIp: callContextStorage.getStore()?.allowPrivateIp,\n });\n\n // Innermost wrapper: enforce response body size cap from the active\n // `responseSizeLimitStorage` slot. Pass-through when no slot is set.\n const networkFetch = wrapFetchWithTransportDiagnostics(\n wrapFetchWithSizeLimit((input, init) => pinnedFetch(input, init))\n );\n\n // Inner fetch handles auth/header injection and 401 detection. If the\n // agent has request-signing configured, we wrap it with the AdCP signing\n // fetch so the signature covers the exact bytes we're about to send (auth\n // headers included, since the signer re-reads the final header record).\n const baseFetch = async (url: string | URL | Request, options?: RequestInit): Promise<Response> => {\n const context = callContextStorage.getStore();\n const urlString = typeof url === 'string' ? url : url instanceof URL ? url.toString() : url.url;\n const credentialOrigin = new URL(agentUrl).origin;\n const sameOrigin = new URL(urlString).origin === credentialOrigin;\n\n const existingHeaders: Record<string, string> = {};\n if (options?.headers) {\n if (options.headers instanceof Headers) {\n options.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n } else if (Array.isArray(options.headers)) {\n for (const [key, value] of options.headers) {\n existingHeaders[key] = value;\n }\n } else {\n Object.assign(existingHeaders, options.headers);\n }\n }\n\n // Agent Cards are untrusted and may advertise an RPC or extended-card URL\n // on another origin. The transport fetch still applies DNS/IP validation\n // there, but credentials, tenant routing, traces, and request signatures\n // are scoped to the explicitly configured agent origin.\n if (!sameOrigin) {\n for (const key of Object.keys(existingHeaders)) {\n if (!['accept', 'content-type', 'a2a-version', 'a2a-extensions'].includes(key.toLowerCase())) {\n delete existingHeaders[key];\n }\n }\n }\n\n // Only inject trace context headers for actual tool requests, not discovery.\n // The agent card endpoint is external/untrusted — don't leak trace IDs to it.\n const isDiscoveryRequest = isAgentCardPath(urlString);\n const traceHeaders = isDiscoveryRequest || !sameOrigin ? {} : injectTraceHeaders();\n const requestTimeoutMs = isDiscoveryRequest\n ? resolveRequestTimeoutMs(context?.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS)\n : resolveRequestTimeoutMs(context?.requestTimeoutMs);\n\n // Merge: existing < trace < custom < auth (auth always wins)\n const headers: Record<string, string> = {\n ...existingHeaders,\n ...traceHeaders,\n ...(sameOrigin ? context?.customHeaders : undefined),\n ...(sameOrigin &&\n authToken && {\n Authorization: `Bearer ${authToken}`,\n 'x-adcp-auth': authToken,\n }),\n };\n\n context?.debugLogs.push({\n type: 'info',\n message: `A2A: Fetch to ${urlString}`,\n timestamp: new Date().toISOString(),\n hasAuth: !!authToken,\n headers: redactHeadersForDebug(headers),\n });\n\n const response = await withAbortSignal<Response>([context?.signal, options?.signal], requestTimeoutMs, signal =>\n networkFetch(url as any, { ...options, headers, signal })\n );\n\n if (response.status === 401 && context) {\n context.got401Ref.value = true;\n }\n\n return response;\n };\n\n if (!signingContext) return wrapFetchWithCapture(baseFetch);\n\n // The signing wrapper assembles headers into the signature base. We invoke\n // it first so the signer sees the caller-supplied headers; baseFetch then\n // overlays auth/trace headers afterwards — A2A's auth scheme (bearer) is\n // not among the MANDATORY_COMPONENTS and is injected by the counterparty's\n // transport layer, not signed.\n const signingFetch = buildAgentSigningFetch({\n upstream: (input, init) => baseFetch(input as any, init),\n signing: signingContext.signing,\n getCapability: signingContext.getCapability,\n adcpVersion: signingContext.adcpVersion,\n });\n return wrapFetchWithCapture(signingFetch as typeof fetch);\n}\n\n/**\n * Terminal A2A task states. Only these can carry the\n * AdCP-mandated artifact + DataPart envelope (per transport-errors §A2A\n * Binding); intermediate states (`working`, `submitted`, `input-required`,\n * `auth-required`) carry no completion artifact.\n */\nconst TERMINAL_A2A_STATES = new Set(['completed', 'failed', 'rejected', 'canceled']);\n\n/**\n * Detect whether a JSON-RPC response carries a spec-compliant terminal-state\n * Task with at least one artifact containing a structured DataPart payload.\n * Per AdCP transport-errors §A2A Binding, the artifact's DataPart is the\n * canonical envelope for both the success arm (`completed`) and the error\n * arms (`failed` / `rejected` / `canceled`). The criterion intentionally\n * matches the unwrapper's terminal-state extraction in\n * `unwrapA2AResponse` — keeping protocol layer and unwrapper in lockstep\n * across all terminal states, not just the error arms.\n *\n * Used to short-circuit the generic \"A2A agent returned error\" throw when\n * a non-conformant seller surfaces both a transport-level `result.error`\n * hint and the canonical artifact envelope side-by-side. The DataPart is\n * authoritative; the throw would otherwise swallow it.\n */\nfunction hasTerminalTaskWithDataArtifact(response: unknown): boolean {\n if (!response || typeof response !== 'object') return false;\n const result = (response as { result?: unknown }).result;\n if (!result || typeof result !== 'object') return false;\n const r = result as { kind?: unknown; status?: unknown; artifacts?: unknown };\n if (r.kind !== 'task') return false;\n const status = r.status as { state?: unknown } | undefined;\n if (typeof status?.state !== 'string' || !TERMINAL_A2A_STATES.has(status.state)) return false;\n return getLatestA2ADataPartFromResponse(response) !== undefined;\n}\n\n/**\n * Protocol-level session identifiers that ride on the A2A Message envelope\n * (not in the skill parameters). `contextId` binds sends to a server-side\n * conversation; `taskId` resumes an existing non-terminal task.\n *\n * Callers (buyers) typically retain these across calls on a per-conversation\n * AgentClient. `getPendingTaskId()` returns this transport Task.id, not the\n * AdCP work handle used by `tasks/get`; see `TaskResult.metadata.serverTaskId`.\n */\nexport interface A2ASessionIds {\n contextId?: string;\n taskId?: string;\n}\n\nexport async function callA2ATool(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n pushNotificationConfig?: PushNotificationConfig,\n customHeaders?: Record<string, string>,\n signingContext?: AgentSigningContext,\n session?: A2ASessionIds,\n signal?: AbortSignal,\n requestTimeoutMs?: number,\n fetchFn?: typeof fetch,\n allowPrivateIp?: boolean\n): Promise<unknown> {\n return withSpan(\n 'adcp.a2a.call_tool',\n {\n 'adcp.tool': toolName,\n 'http.url': agentUrl,\n },\n async () => {\n const context: A2ACallContext = {\n customHeaders,\n debugLogs,\n got401Ref: { value: false },\n signal,\n requestTimeoutMs,\n fetchFn,\n allowPrivateIp,\n };\n return signingContextStorage.run(signingContext, () =>\n callContextStorage.run(context, () =>\n callA2AToolImpl(\n agentUrl,\n toolName,\n parameters,\n authToken,\n debugLogs,\n pushNotificationConfig,\n context,\n session\n )\n )\n );\n }\n );\n}\n\nasync function callA2AToolImpl(\n agentUrl: string,\n toolName: string,\n parameters: Record<string, unknown>,\n authToken: string | undefined,\n debugLogs: DebugLogEntry[],\n pushNotificationConfig: PushNotificationConfig | undefined,\n context: A2ACallContext,\n session: A2ASessionIds | undefined\n): Promise<unknown> {\n try {\n const client = await getOrCreateA2AClient(\n agentUrl,\n authToken,\n context.customHeaders,\n !!context.signal || context.requestTimeoutMs !== undefined\n );\n const legacyWire = client.protocolVersion?.startsWith('0.') ?? false;\n const invocation = legacyWire ? { skill: toolName, parameters } : { skill: toolName, input: parameters };\n\n const requestPayload: SendMessageRequest = {\n tenant: '',\n message: {\n messageId: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n role: Role.ROLE_USER,\n parts: [\n {\n content: {\n $case: 'data',\n value: invocation,\n },\n metadata: undefined,\n filename: '',\n mediaType: 'application/json',\n },\n ],\n contextId: session?.contextId ?? '',\n taskId: session?.taskId ?? '',\n metadata: undefined,\n extensions: legacyWire ? [] : [ADCP_A2A_EXTENSION],\n referenceTaskIds: [],\n },\n configuration: pushNotificationConfig\n ? {\n acceptedOutputModes: ['application/json'],\n taskPushNotificationConfig: toA2APushNotificationConfig(pushNotificationConfig),\n returnImmediately: false,\n }\n : undefined,\n metadata: undefined,\n };\n\n const payloadSize = JSON.stringify(requestPayload).length;\n const redactedParameters = redactArgsForLog(parameters);\n const redactedInvocation = legacyWire\n ? { skill: toolName, parameters: redactedParameters }\n : { skill: toolName, input: redactedParameters };\n const redactedPayload = {\n ...requestPayload,\n message: {\n ...requestPayload.message,\n parts: [\n {\n content: { $case: 'data', value: redactedInvocation },\n metadata: undefined,\n filename: '',\n mediaType: 'application/json',\n },\n ],\n },\n ...(requestPayload.configuration && {\n configuration: {\n taskPushNotificationConfig: redactPushNotificationConfigForDebug(pushNotificationConfig),\n },\n }),\n };\n debugLogs.push({\n type: 'info',\n message: `A2A: Calling skill ${toolName} with parameters: ${JSON.stringify(\n redactedParameters\n )}. Payload size: ${payloadSize} bytes`,\n timestamp: new Date().toISOString(),\n payloadSize,\n actualPayload: redactedPayload,\n });\n\n debugLogs.push({\n type: 'info',\n message: `A2A: Sending message via sendMessage()`,\n timestamp: new Date().toISOString(),\n skill: toolName,\n });\n\n const result = await client.sendMessage(requestPayload, {\n ...(legacyWire ? {} : { serviceParameters: ServiceParameters.create(withA2AExtensions(ADCP_A2A_EXTENSION)) }),\n signal: context.signal,\n });\n const messageResponse: any = normalizeA2AResult(result);\n\n debugLogs.push({\n type: messageResponse?.error ? 'error' : 'success',\n message: `A2A: Response received (${messageResponse?.error ? 'error' : 'success'})`,\n timestamp: new Date().toISOString(),\n response: messageResponse,\n skill: toolName,\n });\n\n if (messageResponse?.error || messageResponse?.result?.error) {\n // adcp-client#1575: when the seller emits a spec-compliant terminal-state\n // Task carrying an `adcp_error` DataPart (per AdCP transport-errors §A2A\n // Binding), the structured artifact is canonical — even if the seller\n // also surfaced a transport-level error string. Pass the response\n // through so the upstream unwrapper extracts `adcp_error.code` instead\n // of throwing a generic message that loses the AdCP error envelope.\n if (!hasTerminalTaskWithDataArtifact(messageResponse)) {\n const errorObj = messageResponse.error || messageResponse.result?.error;\n const errorMessage = errorObj.message || JSON.stringify(errorObj);\n throw new Error(`A2A agent returned error: ${errorMessage}`);\n }\n }\n\n return messageResponse;\n } catch (error: unknown) {\n if (is401Error(error, context.got401Ref.value)) {\n // Evict this cache entry — credential may have expired or been\n // revoked. Same disambiguator as the original `getOrCreateA2AClient`\n // call: when the credential rode on customHeaders.Authorization (Basic\n // case) rather than authToken, the cache key must reflect that or we\n // evict the wrong entry.\n const signingContext = signingContextStorage.getStore();\n a2aClientCache.delete(\n a2aCacheKey(\n agentUrl,\n authToken,\n signingContext?.cacheKey,\n context.customHeaders,\n context.allowPrivateIp === true\n )\n );\n\n debugLogs.push({\n type: 'error',\n message: `A2A: Authentication required for ${agentUrl}`,\n timestamp: new Date().toISOString(),\n });\n\n // Re-probe to surface the WWW-Authenticate scheme on the error envelope.\n // Basic-fronted agents (Apigee/Kong/AWS API GW with a BasicAuthentication\n // policy) would otherwise leave consumers chasing OAuth metadata that\n // doesn't exist. Matches the MCP discovery throw site in\n // `SingleAgentClient.discoverMCPEndpoint`.\n const challenge = await probeAuthChallenge(agentUrl, {\n fetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n const oauthMetadata = await discoverOAuthMetadata(agentUrl, {\n trustedFetchFn: context.fetchFn,\n allowPrivateIp: context.allowPrivateIp ?? isLikelyPrivateUrl(agentUrl),\n });\n throw new AuthenticationRequiredError(agentUrl, oauthMetadata || undefined, undefined, challenge ?? undefined);\n }\n\n throw error;\n }\n}\n"],"mappings":"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","names":["import_client"]}
|