@adcp/sdk 13.0.4 → 13.1.1
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-grade.js +4 -3
- package/bin/adcp.js +18 -0
- package/dist/lib/conformance/invariants/uniformError.d.ts.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.js +21 -0
- package/dist/lib/conformance/invariants/uniformError.js.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs +22 -1
- package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
- package/dist/lib/core/AgentClient.d.mts +1 -1
- package/dist/lib/core/AgentClient.d.ts +1 -1
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/AgentClient.js +1 -1
- package/dist/lib/core/AgentClient.js.map +1 -1
- package/dist/lib/core/AgentClient.mjs +1 -1
- package/dist/lib/core/AgentClient.mjs.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +1 -1
- package/dist/lib/core/SingleAgentClient.d.ts +1 -1
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +88 -48
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +88 -48
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/core/TaskExecutor.d.ts.map +1 -1
- package/dist/lib/core/TaskExecutor.js +8 -4
- package/dist/lib/core/TaskExecutor.js.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +8 -4
- package/dist/lib/core/TaskExecutor.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/net/agent-transport-fetch.d.mts +15 -0
- package/dist/lib/net/agent-transport-fetch.d.ts +15 -0
- package/dist/lib/net/agent-transport-fetch.d.ts.map +1 -1
- package/dist/lib/net/agent-transport-fetch.js +37 -2
- package/dist/lib/net/agent-transport-fetch.js.map +1 -1
- package/dist/lib/net/agent-transport-fetch.mjs +37 -2
- package/dist/lib/net/agent-transport-fetch.mjs.map +1 -1
- package/dist/lib/net/credential-headers.d.mts +1 -0
- package/dist/lib/net/credential-headers.d.ts +2 -0
- package/dist/lib/net/credential-headers.d.ts.map +1 -0
- package/dist/lib/net/credential-headers.js +34 -0
- package/dist/lib/net/credential-headers.js.map +1 -0
- package/dist/lib/net/credential-headers.mjs +10 -0
- package/dist/lib/net/credential-headers.mjs.map +1 -0
- package/dist/lib/protocols/a2a-native-v1.d.mts +18 -0
- package/dist/lib/protocols/a2a-native-v1.d.ts +19 -0
- package/dist/lib/protocols/a2a-native-v1.d.ts.map +1 -0
- package/dist/lib/protocols/a2a-native-v1.js +183 -0
- package/dist/lib/protocols/a2a-native-v1.js.map +1 -0
- package/dist/lib/protocols/a2a-native-v1.mjs +167 -0
- package/dist/lib/protocols/a2a-native-v1.mjs.map +1 -0
- package/dist/lib/protocols/a2a-push-notification.d.mts +13 -0
- package/dist/lib/protocols/a2a-push-notification.d.ts +14 -0
- package/dist/lib/protocols/a2a-push-notification.d.ts.map +1 -0
- package/dist/lib/protocols/a2a-push-notification.js +42 -0
- package/dist/lib/protocols/a2a-push-notification.js.map +1 -0
- package/dist/lib/protocols/a2a-push-notification.mjs +23 -0
- package/dist/lib/protocols/a2a-push-notification.mjs.map +1 -0
- package/dist/lib/protocols/a2a.d.mts +15 -5
- package/dist/lib/protocols/a2a.d.ts +15 -5
- package/dist/lib/protocols/a2a.d.ts.map +1 -1
- package/dist/lib/protocols/a2a.js +102 -13
- package/dist/lib/protocols/a2a.js.map +1 -1
- package/dist/lib/protocols/a2a.mjs +90 -12
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/protocols/index.d.mts +3 -0
- package/dist/lib/protocols/index.d.ts +3 -0
- package/dist/lib/protocols/index.d.ts.map +1 -1
- package/dist/lib/protocols/index.js +18 -6
- package/dist/lib/protocols/index.js.map +1 -1
- package/dist/lib/protocols/index.mjs +18 -6
- package/dist/lib/protocols/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-modern.js +3 -1
- package/dist/lib/protocols/mcp-modern.js.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +3 -1
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/protocols/mcp-tasks.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-tasks.js +2 -1
- package/dist/lib/protocols/mcp-tasks.js.map +1 -1
- package/dist/lib/protocols/mcp-tasks.mjs +2 -1
- package/dist/lib/protocols/mcp-tasks.mjs.map +1 -1
- package/dist/lib/protocols/mcp.d.mts +8 -5
- package/dist/lib/protocols/mcp.d.ts +8 -5
- package/dist/lib/protocols/mcp.d.ts.map +1 -1
- package/dist/lib/protocols/mcp.js +12 -4
- package/dist/lib/protocols/mcp.js.map +1 -1
- package/dist/lib/protocols/mcp.mjs +12 -4
- package/dist/lib/protocols/mcp.mjs.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.d.mts +9 -1
- package/dist/lib/protocols/rawResponseCapture.d.ts +9 -1
- package/dist/lib/protocols/rawResponseCapture.d.ts.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.js +153 -10
- package/dist/lib/protocols/rawResponseCapture.js.map +1 -1
- package/dist/lib/protocols/rawResponseCapture.mjs +153 -10
- package/dist/lib/protocols/rawResponseCapture.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/signing/agent-fetch.d.mts +3 -1
- package/dist/lib/signing/agent-fetch.d.ts +3 -1
- package/dist/lib/signing/agent-fetch.d.ts.map +1 -1
- package/dist/lib/signing/agent-fetch.js +4 -2
- package/dist/lib/signing/agent-fetch.js.map +1 -1
- package/dist/lib/signing/agent-fetch.mjs +4 -2
- package/dist/lib/signing/agent-fetch.mjs.map +1 -1
- package/dist/lib/signing/protocol-methods.d.mts +24 -0
- package/dist/lib/signing/protocol-methods.d.ts +25 -0
- package/dist/lib/signing/protocol-methods.d.ts.map +1 -0
- package/dist/lib/signing/protocol-methods.js +51 -0
- package/dist/lib/signing/protocol-methods.js.map +1 -0
- package/dist/lib/signing/protocol-methods.mjs +25 -0
- package/dist/lib/signing/protocol-methods.mjs.map +1 -0
- package/dist/lib/signing/types.d.mts +2 -0
- package/dist/lib/signing/types.d.ts +2 -0
- package/dist/lib/signing/types.d.ts.map +1 -1
- package/dist/lib/signing/types.js.map +1 -1
- package/dist/lib/signing/types.mjs.map +1 -1
- package/dist/lib/signing/verifier.d.ts.map +1 -1
- package/dist/lib/signing/verifier.js +6 -2
- package/dist/lib/signing/verifier.js.map +1 -1
- package/dist/lib/signing/verifier.mjs +6 -2
- package/dist/lib/signing/verifier.mjs.map +1 -1
- package/dist/lib/testing/client.d.ts.map +1 -1
- package/dist/lib/testing/client.js +4 -1
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/client.mjs +4 -1
- 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 +3 -0
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +3 -0
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.d.mts +3 -1
- package/dist/lib/testing/storyboard/agent-routing.d.ts +3 -1
- package/dist/lib/testing/storyboard/agent-routing.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.js +5 -2
- package/dist/lib/testing/storyboard/agent-routing.js.map +1 -1
- package/dist/lib/testing/storyboard/agent-routing.mjs +4 -2
- package/dist/lib/testing/storyboard/agent-routing.mjs.map +1 -1
- package/dist/lib/testing/storyboard/compliance.d.mts +1 -1
- package/dist/lib/testing/storyboard/compliance.d.ts +1 -1
- package/dist/lib/testing/storyboard/compliance.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/compliance.js +4 -1
- package/dist/lib/testing/storyboard/compliance.js.map +1 -1
- package/dist/lib/testing/storyboard/compliance.mjs +4 -1
- package/dist/lib/testing/storyboard/compliance.mjs.map +1 -1
- package/dist/lib/testing/storyboard/native-a2a-compliance.d.mts +7 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.d.ts +8 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.js +45 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.js.map +1 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.mjs +21 -0
- package/dist/lib/testing/storyboard/native-a2a-compliance.mjs.map +1 -0
- package/dist/lib/testing/storyboard/probes.d.mts +2 -0
- package/dist/lib/testing/storyboard/probes.d.ts +2 -0
- package/dist/lib/testing/storyboard/probes.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/probes.js +3 -2
- package/dist/lib/testing/storyboard/probes.js.map +1 -1
- package/dist/lib/testing/storyboard/probes.mjs +3 -2
- package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.mts +31 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.ts +32 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.d.ts.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.js +279 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.js.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.mjs +244 -0
- package/dist/lib/testing/storyboard/request-signing/a2a-dispatch.mjs.map +1 -0
- package/dist/lib/testing/storyboard/request-signing/builder.d.mts +4 -1
- package/dist/lib/testing/storyboard/request-signing/builder.d.ts +4 -1
- package/dist/lib/testing/storyboard/request-signing/builder.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.js +19 -0
- package/dist/lib/testing/storyboard/request-signing/builder.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +19 -0
- package/dist/lib/testing/storyboard/request-signing/builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.d.mts +5 -6
- package/dist/lib/testing/storyboard/request-signing/grader.d.ts +5 -6
- package/dist/lib/testing/storyboard/request-signing/grader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.js +82 -13
- package/dist/lib/testing/storyboard/request-signing/grader.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/grader.mjs +86 -13
- package/dist/lib/testing/storyboard/request-signing/grader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.d.mts +1 -0
- package/dist/lib/testing/storyboard/request-signing/index.d.ts +1 -0
- package/dist/lib/testing/storyboard/request-signing/index.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.js +7 -0
- package/dist/lib/testing/storyboard/request-signing/index.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/index.mjs +8 -0
- package/dist/lib/testing/storyboard/request-signing/index.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.mts +2 -2
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts +2 -2
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js +6 -5
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs +6 -5
- package/dist/lib/testing/storyboard/request-signing/probe-dispatch.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.d.mts +1 -0
- package/dist/lib/testing/storyboard/request-signing/types.d.ts +1 -0
- package/dist/lib/testing/storyboard/request-signing/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js +1 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +1 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.mts +28 -1
- package/dist/lib/testing/storyboard/runner.d.ts +28 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +251 -55
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +255 -60
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.d.mts +4 -2
- package/dist/lib/testing/storyboard/types.d.ts +4 -2
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js +1 -0
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs +1 -0
- package/dist/lib/testing/storyboard/types.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 +97 -22
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +98 -22
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- 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 +1 -1
- package/docs/llms.txt +5 -3
- package/package.json +2 -1
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var a2a_dispatch_exports = {};
|
|
30
|
+
__export(a2a_dispatch_exports, {
|
|
31
|
+
captureA2aRequest: () => captureA2aRequest,
|
|
32
|
+
createCachedA2aCardFetch: () => createCachedA2aCardFetch,
|
|
33
|
+
operationFromVectorUrl: () => operationFromVectorUrl,
|
|
34
|
+
resolveA2aDispatchTarget: () => resolveA2aDispatchTarget
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(a2a_dispatch_exports);
|
|
37
|
+
var import_agent_transport_fetch = require('../../../net/agent-transport-fetch.js');
|
|
38
|
+
var import_abort = require('../../../protocols/abort.js');
|
|
39
|
+
var import_a2a_discovery = require('../../../utils/a2a-discovery.js');
|
|
40
|
+
var import_a2a_push_notification = require('../../../protocols/a2a-push-notification.js');
|
|
41
|
+
const DEFAULT_CARD_FETCH_TIMEOUT_MS = 1e4;
|
|
42
|
+
const MAX_CACHED_AGENT_CARD_BYTES = 1048576;
|
|
43
|
+
const ADCP_A2A_EXTENSION = "https://adcontextprotocol.org/extensions/adcp/v3";
|
|
44
|
+
const CARD_DRIVEN_LEGACY_COMPAT = Object.freeze({ enabled: true });
|
|
45
|
+
class RequestCaptured extends Error {
|
|
46
|
+
constructor(captured) {
|
|
47
|
+
super("a2a request captured");
|
|
48
|
+
this.captured = captured;
|
|
49
|
+
}
|
|
50
|
+
captured;
|
|
51
|
+
}
|
|
52
|
+
async function captureA2aRequest(agentUrl, call, options = {}) {
|
|
53
|
+
const { ClientFactory, JsonRpcTransportFactory, ServiceParameters, withA2AExtensions } = await import("@a2a-js/sdk-v1/client");
|
|
54
|
+
const { Role } = await import("@a2a-js/sdk-v1");
|
|
55
|
+
const capturingFetch = async (input, init) => {
|
|
56
|
+
const request = new Request(input, init);
|
|
57
|
+
const headers = {};
|
|
58
|
+
request.headers.forEach((value, name) => {
|
|
59
|
+
headers[name] = value;
|
|
60
|
+
});
|
|
61
|
+
throw new RequestCaptured({
|
|
62
|
+
url: request.url,
|
|
63
|
+
method: request.method,
|
|
64
|
+
headers,
|
|
65
|
+
body: await request.text()
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
const cardFetch = buildGuardedCardFetch(agentUrl, options);
|
|
69
|
+
const factory = new ClientFactory({
|
|
70
|
+
transports: [new JsonRpcTransportFactory({ fetchImpl: capturingFetch, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],
|
|
71
|
+
cardResolver: new (await import("@a2a-js/sdk-v1/client")).DefaultAgentCardResolver({
|
|
72
|
+
fetchImpl: cardFetch,
|
|
73
|
+
legacyCompat: CARD_DRIVEN_LEGACY_COMPAT
|
|
74
|
+
})
|
|
75
|
+
});
|
|
76
|
+
const client = await createCardDrivenClient(agentUrl, factory);
|
|
77
|
+
const legacyWire = client.protocolVersion?.startsWith("0.") ?? false;
|
|
78
|
+
try {
|
|
79
|
+
if (call.kind === "cancelTask") {
|
|
80
|
+
await client.cancelTask({ tenant: "", id: call.taskId, metadata: void 0 });
|
|
81
|
+
} else {
|
|
82
|
+
const pushNotificationConfig = call.args.push_notification_config;
|
|
83
|
+
const invocation = legacyWire ? {
|
|
84
|
+
skill: call.operation,
|
|
85
|
+
// The maintained 0.3 runtime carries the AdCP application-layer
|
|
86
|
+
// registration in skill parameters. Do not reinterpret it as the
|
|
87
|
+
// native 1.0 transport facility while capturing signing bytes.
|
|
88
|
+
parameters: call.args
|
|
89
|
+
} : {
|
|
90
|
+
skill: call.operation,
|
|
91
|
+
// Native A2A transport registration cannot represent AdCP-only
|
|
92
|
+
// fields such as operation_id. Keep the complete application
|
|
93
|
+
// registration in skill input, matching the runtime path.
|
|
94
|
+
input: call.args
|
|
95
|
+
};
|
|
96
|
+
const request = {
|
|
97
|
+
tenant: "",
|
|
98
|
+
message: {
|
|
99
|
+
messageId: globalThis.crypto.randomUUID(),
|
|
100
|
+
contextId: "",
|
|
101
|
+
taskId: "",
|
|
102
|
+
role: Role.ROLE_USER,
|
|
103
|
+
parts: [
|
|
104
|
+
{
|
|
105
|
+
content: { $case: "data", value: invocation },
|
|
106
|
+
metadata: void 0,
|
|
107
|
+
filename: "",
|
|
108
|
+
mediaType: "application/json"
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
metadata: void 0,
|
|
112
|
+
extensions: legacyWire ? [] : [ADCP_A2A_EXTENSION],
|
|
113
|
+
referenceTaskIds: []
|
|
114
|
+
},
|
|
115
|
+
configuration: !legacyWire && pushNotificationConfig != null && typeof pushNotificationConfig === "object" && !Array.isArray(pushNotificationConfig) ? {
|
|
116
|
+
acceptedOutputModes: ["application/json"],
|
|
117
|
+
taskPushNotificationConfig: (0, import_a2a_push_notification.toA2ATaskPushNotificationConfig)(
|
|
118
|
+
pushNotificationConfig
|
|
119
|
+
),
|
|
120
|
+
returnImmediately: false
|
|
121
|
+
} : void 0,
|
|
122
|
+
metadata: void 0
|
|
123
|
+
};
|
|
124
|
+
await client.sendMessage(request, {
|
|
125
|
+
...legacyWire ? {} : { serviceParameters: ServiceParameters.create(withA2AExtensions(ADCP_A2A_EXTENSION)) }
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (error instanceof RequestCaptured) {
|
|
130
|
+
assertSameOriginEndpoint(agentUrl, error.captured.url);
|
|
131
|
+
return error.captured;
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
throw new Error(`the A2A client returned without issuing a request for ${call.kind}`);
|
|
136
|
+
}
|
|
137
|
+
async function createCardDrivenClient(agentUrl, factory) {
|
|
138
|
+
let lastError;
|
|
139
|
+
for (const cardUrl of (0, import_a2a_discovery.buildCardUrls)(agentUrl)) {
|
|
140
|
+
try {
|
|
141
|
+
return await factory.createFromUrl(cardUrl, "");
|
|
142
|
+
} catch (error) {
|
|
143
|
+
if ((0, import_abort.isAbortOrTimeoutError)(error)) throw error;
|
|
144
|
+
lastError = error;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
throw new Error("A2A agent card discovery failed", { cause: lastError });
|
|
148
|
+
}
|
|
149
|
+
function buildGuardedCardFetch(agentUrl, options) {
|
|
150
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_CARD_FETCH_TIMEOUT_MS;
|
|
151
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > import_abort.MAX_TIMER_DELAY_MS) {
|
|
152
|
+
throw new RangeError(`A2A card timeoutMs must be a finite positive number <= ${import_abort.MAX_TIMER_DELAY_MS}`);
|
|
153
|
+
}
|
|
154
|
+
const transportFetch = (0, import_agent_transport_fetch.createAgentTransportFetch)(agentUrl, {
|
|
155
|
+
...options.cardFetch ? { trustedFetchFn: options.cardFetch } : {},
|
|
156
|
+
allowPrivateIp: options.allowPrivateIp === true
|
|
157
|
+
});
|
|
158
|
+
return ((input, init = {}) => (0, import_abort.withAbortSignal)([init.signal], timeoutMs, async (signal) => {
|
|
159
|
+
const response = await transportFetch(input, { ...init, ...signal ? { signal } : {} });
|
|
160
|
+
const body = await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES, signal);
|
|
161
|
+
return new Response(body.byteLength > 0 ? Uint8Array.from(body).buffer : null, {
|
|
162
|
+
status: response.status,
|
|
163
|
+
statusText: response.statusText,
|
|
164
|
+
headers: response.headers
|
|
165
|
+
});
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
function createCachedA2aCardFetch(agentUrl, options = {}) {
|
|
169
|
+
const upstream = buildGuardedCardFetch(agentUrl, options);
|
|
170
|
+
const responses = /* @__PURE__ */ new Map();
|
|
171
|
+
return async (input, init) => {
|
|
172
|
+
const request = new Request(input, init);
|
|
173
|
+
if (request.method !== "GET") return upstream(input, init);
|
|
174
|
+
let pending = responses.get(request.url);
|
|
175
|
+
if (!pending) {
|
|
176
|
+
pending = upstream(input, init).then(async (response) => ({
|
|
177
|
+
status: response.status,
|
|
178
|
+
statusText: response.statusText,
|
|
179
|
+
headers: (() => {
|
|
180
|
+
const entries = [];
|
|
181
|
+
response.headers.forEach((value, name) => entries.push([name, value]));
|
|
182
|
+
return entries;
|
|
183
|
+
})(),
|
|
184
|
+
body: await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES)
|
|
185
|
+
}));
|
|
186
|
+
responses.set(request.url, pending);
|
|
187
|
+
pending.catch(() => responses.delete(request.url));
|
|
188
|
+
}
|
|
189
|
+
const cached = await pending;
|
|
190
|
+
return new Response(cached.body.slice(), {
|
|
191
|
+
status: cached.status,
|
|
192
|
+
statusText: cached.statusText,
|
|
193
|
+
headers: cached.headers
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
async function readCardBodyBounded(response, maxBytes, signal) {
|
|
198
|
+
const declaredLength = Number(response.headers.get("content-length"));
|
|
199
|
+
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
|
200
|
+
void response.body?.cancel().catch(() => void 0);
|
|
201
|
+
throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);
|
|
202
|
+
}
|
|
203
|
+
if (!response.body) return new Uint8Array();
|
|
204
|
+
const reader = response.body.getReader();
|
|
205
|
+
const cancel = () => void reader.cancel(signal?.reason).catch(() => void 0);
|
|
206
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
207
|
+
try {
|
|
208
|
+
const chunks = [];
|
|
209
|
+
let length = 0;
|
|
210
|
+
while (true) {
|
|
211
|
+
const { done, value } = await reader.read();
|
|
212
|
+
if (done) break;
|
|
213
|
+
length += value.byteLength;
|
|
214
|
+
if (length > maxBytes) {
|
|
215
|
+
void reader.cancel().catch(() => void 0);
|
|
216
|
+
throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);
|
|
217
|
+
}
|
|
218
|
+
chunks.push(value);
|
|
219
|
+
}
|
|
220
|
+
const body = new Uint8Array(length);
|
|
221
|
+
let offset = 0;
|
|
222
|
+
for (const chunk of chunks) {
|
|
223
|
+
body.set(chunk, offset);
|
|
224
|
+
offset += chunk.byteLength;
|
|
225
|
+
}
|
|
226
|
+
return body;
|
|
227
|
+
} finally {
|
|
228
|
+
signal?.removeEventListener("abort", cancel);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function operationFromVectorUrl(vectorUrl) {
|
|
232
|
+
const last = new URL(vectorUrl).pathname.split("/").filter(Boolean).at(-1);
|
|
233
|
+
if (!last || !/^[a-z][a-z0-9_]*$/.test(last)) {
|
|
234
|
+
throw new Error(`Cannot extract an AdCP operation name from vector URL: ${vectorUrl}`);
|
|
235
|
+
}
|
|
236
|
+
return last;
|
|
237
|
+
}
|
|
238
|
+
async function resolveA2aDispatchTarget(agentUrl, options = {}) {
|
|
239
|
+
const { ClientFactory, DefaultAgentCardResolver, JsonRpcTransportFactory } = await import("@a2a-js/sdk-v1/client");
|
|
240
|
+
let endpoint = "";
|
|
241
|
+
const noteEndpoint = async (input, init) => {
|
|
242
|
+
endpoint = new Request(input, init).url;
|
|
243
|
+
throw new RequestCaptured({ url: endpoint, method: "POST", headers: {}, body: "" });
|
|
244
|
+
};
|
|
245
|
+
const factory = new ClientFactory({
|
|
246
|
+
transports: [new JsonRpcTransportFactory({ fetchImpl: noteEndpoint, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],
|
|
247
|
+
cardResolver: new DefaultAgentCardResolver({
|
|
248
|
+
fetchImpl: buildGuardedCardFetch(agentUrl, options),
|
|
249
|
+
legacyCompat: CARD_DRIVEN_LEGACY_COMPAT
|
|
250
|
+
})
|
|
251
|
+
});
|
|
252
|
+
const client = await createCardDrivenClient(agentUrl, factory);
|
|
253
|
+
try {
|
|
254
|
+
await client.cancelTask({ tenant: "", id: "a2a-dispatch-probe", metadata: void 0 });
|
|
255
|
+
} catch (error) {
|
|
256
|
+
if (error instanceof RequestCaptured) {
|
|
257
|
+
assertSameOriginEndpoint(agentUrl, endpoint);
|
|
258
|
+
return { endpoint };
|
|
259
|
+
}
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
throw new Error("the A2A client returned without issuing a dispatch probe");
|
|
263
|
+
}
|
|
264
|
+
function assertSameOriginEndpoint(agentUrl, endpoint) {
|
|
265
|
+
const agentOrigin = new URL(agentUrl).origin;
|
|
266
|
+
const endpointOrigin = new URL(endpoint).origin;
|
|
267
|
+
if (endpointOrigin === agentOrigin) return;
|
|
268
|
+
throw new Error(
|
|
269
|
+
`A2A request-signing probes refuse a cross-origin card endpoint (${endpointOrigin}); expected ${agentOrigin}`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
273
|
+
0 && (module.exports = {
|
|
274
|
+
captureA2aRequest,
|
|
275
|
+
createCachedA2aCardFetch,
|
|
276
|
+
operationFromVectorUrl,
|
|
277
|
+
resolveA2aDispatchTarget
|
|
278
|
+
});
|
|
279
|
+
//# sourceMappingURL=a2a-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/a2a-dispatch.ts"],"sourcesContent":["/**\n * Capture requests emitted by the official A2A 1.x client for RFC 9421\n * signing. The SDK owns endpoint selection, method names, version headers,\n * and proto-JSON encoding; this module only intercepts its fetch seam.\n */\nimport { createAgentTransportFetch } from '../../../net/agent-transport-fetch';\nimport { isAbortOrTimeoutError, MAX_TIMER_DELAY_MS, withAbortSignal } from '../../../protocols/abort';\nimport { buildCardUrls } from '../../../utils/a2a-discovery';\nimport {\n toA2ATaskPushNotificationConfig,\n type A2APushNotificationConfig,\n} from '../../../protocols/a2a-push-notification';\nimport type { SendMessageRequest } from '@a2a-js/sdk-v1';\nimport type { Client } from '@a2a-js/sdk-v1/client';\n\nconst DEFAULT_CARD_FETCH_TIMEOUT_MS = 10_000;\nconst MAX_CACHED_AGENT_CARD_BYTES = 1_048_576;\nconst ADCP_A2A_EXTENSION = 'https://adcontextprotocol.org/extensions/adcp/v3';\n// Defined by the AdCP A2A profile extension and its canonical test vector:\n// docs/building/by-layer/L0/a2a-profile-extension.mdx\n// static/test-vectors/a2a-profile-extension-v3.json\nconst CARD_DRIVEN_LEGACY_COMPAT = Object.freeze({ enabled: true });\n\nexport interface CapturedA2aRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n body: string;\n}\n\nexport type A2aCall =\n | { kind: 'sendMessage'; operation: string; args: Record<string, unknown> }\n | { kind: 'cancelTask'; taskId: string };\n\nexport interface A2aDispatchOptions {\n timeoutMs?: number;\n allowPrivateIp?: boolean;\n /** Trusted fetch used only for agent-card discovery. */\n cardFetch?: typeof fetch;\n}\n\nclass RequestCaptured extends Error {\n constructor(readonly captured: CapturedA2aRequest) {\n super('a2a request captured');\n }\n}\n\nexport async function captureA2aRequest(\n agentUrl: string,\n call: A2aCall,\n options: A2aDispatchOptions = {}\n): Promise<CapturedA2aRequest> {\n const { ClientFactory, JsonRpcTransportFactory, ServiceParameters, withA2AExtensions } =\n await import('@a2a-js/sdk-v1/client');\n const { Role } = await import('@a2a-js/sdk-v1');\n\n const capturingFetch: typeof fetch = async (input, init) => {\n const request = new Request(input as RequestInfo, init);\n const headers: Record<string, string> = {};\n request.headers.forEach((value, name) => {\n headers[name] = value;\n });\n throw new RequestCaptured({\n url: request.url,\n method: request.method,\n headers,\n body: await request.text(),\n });\n };\n\n const cardFetch = buildGuardedCardFetch(agentUrl, options);\n const factory = new ClientFactory({\n transports: [new JsonRpcTransportFactory({ fetchImpl: capturingFetch, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],\n cardResolver: new (await import('@a2a-js/sdk-v1/client')).DefaultAgentCardResolver({\n fetchImpl: cardFetch,\n legacyCompat: CARD_DRIVEN_LEGACY_COMPAT,\n }),\n });\n const client = await createCardDrivenClient(agentUrl, factory);\n const legacyWire = client.protocolVersion?.startsWith('0.') ?? false;\n\n try {\n if (call.kind === 'cancelTask') {\n await client.cancelTask({ tenant: '', id: call.taskId, metadata: undefined });\n } else {\n const pushNotificationConfig = call.args.push_notification_config;\n const invocation = legacyWire\n ? {\n skill: call.operation,\n // The maintained 0.3 runtime carries the AdCP application-layer\n // registration in skill parameters. Do not reinterpret it as the\n // native 1.0 transport facility while capturing signing bytes.\n parameters: call.args,\n }\n : {\n skill: call.operation,\n // Native A2A transport registration cannot represent AdCP-only\n // fields such as operation_id. Keep the complete application\n // registration in skill input, matching the runtime path.\n input: call.args,\n };\n const request: SendMessageRequest = {\n tenant: '',\n message: {\n messageId: globalThis.crypto.randomUUID(),\n contextId: '',\n taskId: '',\n role: Role.ROLE_USER,\n parts: [\n {\n content: { $case: 'data', value: invocation },\n metadata: undefined,\n filename: '',\n mediaType: 'application/json',\n },\n ],\n metadata: undefined,\n extensions: legacyWire ? [] : [ADCP_A2A_EXTENSION],\n referenceTaskIds: [],\n },\n configuration:\n !legacyWire &&\n pushNotificationConfig != null &&\n typeof pushNotificationConfig === 'object' &&\n !Array.isArray(pushNotificationConfig)\n ? {\n acceptedOutputModes: ['application/json'],\n taskPushNotificationConfig: toA2ATaskPushNotificationConfig(\n pushNotificationConfig as A2APushNotificationConfig\n ),\n returnImmediately: false,\n }\n : undefined,\n metadata: undefined,\n };\n await client.sendMessage(request, {\n ...(legacyWire ? {} : { serviceParameters: ServiceParameters.create(withA2AExtensions(ADCP_A2A_EXTENSION)) }),\n });\n }\n } catch (error) {\n if (error instanceof RequestCaptured) {\n assertSameOriginEndpoint(agentUrl, error.captured.url);\n return error.captured;\n }\n throw error;\n }\n throw new Error(`the A2A client returned without issuing a request for ${call.kind}`);\n}\n\nasync function createCardDrivenClient(\n agentUrl: string,\n factory: { createFromUrl(baseUrl: string, path?: string): Promise<Client> }\n): Promise<Client> {\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n return await factory.createFromUrl(cardUrl, '');\n } catch (error) {\n if (isAbortOrTimeoutError(error)) throw error;\n lastError = error;\n }\n }\n throw new Error('A2A agent card discovery failed', { cause: lastError });\n}\n\nfunction buildGuardedCardFetch(agentUrl: string, options: A2aDispatchOptions): typeof fetch {\n const timeoutMs = options.timeoutMs ?? DEFAULT_CARD_FETCH_TIMEOUT_MS;\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > MAX_TIMER_DELAY_MS) {\n throw new RangeError(`A2A card timeoutMs must be a finite positive number <= ${MAX_TIMER_DELAY_MS}`);\n }\n const transportFetch = createAgentTransportFetch(agentUrl, {\n ...(options.cardFetch ? { trustedFetchFn: options.cardFetch } : {}),\n allowPrivateIp: options.allowPrivateIp === true,\n });\n return ((input: RequestInfo | URL, init: RequestInit = {}) =>\n withAbortSignal([init.signal], timeoutMs, async signal => {\n const response = await transportFetch(input, { ...init, ...(signal ? { signal } : {}) });\n // Keep the same discovery deadline active through body consumption. A\n // peer can otherwise return headers plus one byte and stall grading\n // forever while the official resolver waits for JSON completion.\n const body = await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES, signal);\n return new Response(body.byteLength > 0 ? Uint8Array.from(body).buffer : null, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n })) as typeof fetch;\n}\n\n/**\n * Cache discovery within one grading run without turning the platform fetch\n * into a trusted fetch override. The guarded transport performs DNS/private\n * address enforcement before this wrapper sees a response.\n */\nexport function createCachedA2aCardFetch(agentUrl: string, options: A2aDispatchOptions = {}): typeof fetch {\n const upstream = buildGuardedCardFetch(agentUrl, options);\n const responses = new Map<\n string,\n Promise<{ status: number; statusText: string; headers: [string, string][]; body: Uint8Array }>\n >();\n return async (input, init) => {\n const request = new Request(input as RequestInfo, init);\n if (request.method !== 'GET') return upstream(input, init);\n let pending = responses.get(request.url);\n if (!pending) {\n pending = upstream(input, init).then(async response => ({\n status: response.status,\n statusText: response.statusText,\n headers: (() => {\n const entries: [string, string][] = [];\n response.headers.forEach((value, name) => entries.push([name, value]));\n return entries;\n })(),\n body: await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES),\n }));\n responses.set(request.url, pending);\n pending.catch(() => responses.delete(request.url));\n }\n const cached = await pending;\n return new Response(cached.body.slice(), {\n status: cached.status,\n statusText: cached.statusText,\n headers: cached.headers,\n });\n };\n}\n\nasync function readCardBodyBounded(response: Response, maxBytes: number, signal?: AbortSignal): Promise<Uint8Array> {\n const declaredLength = Number(response.headers.get('content-length'));\n if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {\n void response.body?.cancel().catch(() => undefined);\n throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);\n }\n if (!response.body) return new Uint8Array();\n const reader = response.body.getReader();\n const cancel = () => void reader.cancel(signal?.reason).catch(() => undefined);\n signal?.addEventListener('abort', cancel, { once: true });\n try {\n const chunks: Uint8Array[] = [];\n let length = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n length += value.byteLength;\n if (length > maxBytes) {\n void reader.cancel().catch(() => undefined);\n throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);\n }\n chunks.push(value);\n }\n const body = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n body.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return body;\n } finally {\n signal?.removeEventListener('abort', cancel);\n }\n}\n\nexport function operationFromVectorUrl(vectorUrl: string): string {\n const last = new URL(vectorUrl).pathname.split('/').filter(Boolean).at(-1);\n if (!last || !/^[a-z][a-z0-9_]*$/.test(last)) {\n throw new Error(`Cannot extract an AdCP operation name from vector URL: ${vectorUrl}`);\n }\n return last;\n}\n\nexport async function resolveA2aDispatchTarget(\n agentUrl: string,\n options: A2aDispatchOptions = {}\n): Promise<{ endpoint: string }> {\n const { ClientFactory, DefaultAgentCardResolver, JsonRpcTransportFactory } = await import('@a2a-js/sdk-v1/client');\n let endpoint = '';\n const noteEndpoint: typeof fetch = async (input, init) => {\n endpoint = new Request(input as RequestInfo, init).url;\n throw new RequestCaptured({ url: endpoint, method: 'POST', headers: {}, body: '' });\n };\n const factory = new ClientFactory({\n transports: [new JsonRpcTransportFactory({ fetchImpl: noteEndpoint, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],\n cardResolver: new DefaultAgentCardResolver({\n fetchImpl: buildGuardedCardFetch(agentUrl, options),\n legacyCompat: CARD_DRIVEN_LEGACY_COMPAT,\n }),\n });\n const client = await createCardDrivenClient(agentUrl, factory);\n try {\n await client.cancelTask({ tenant: '', id: 'a2a-dispatch-probe', metadata: undefined });\n } catch (error) {\n if (error instanceof RequestCaptured) {\n assertSameOriginEndpoint(agentUrl, endpoint);\n return { endpoint };\n }\n throw error;\n }\n throw new Error('the A2A client returned without issuing a dispatch probe');\n}\n\nfunction assertSameOriginEndpoint(agentUrl: string, endpoint: string): void {\n const agentOrigin = new URL(agentUrl).origin;\n const endpointOrigin = new URL(endpoint).origin;\n if (endpointOrigin === agentOrigin) return;\n throw new Error(\n `A2A request-signing probes refuse a cross-origin card endpoint (${endpointOrigin}); expected ${agentOrigin}`\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { createAgentTransportFetch } from "../../../net/agent-transport-fetch.mjs";
|
|
2
|
+
import { isAbortOrTimeoutError, MAX_TIMER_DELAY_MS, withAbortSignal } from "../../../protocols/abort.mjs";
|
|
3
|
+
import { buildCardUrls } from "../../../utils/a2a-discovery.mjs";
|
|
4
|
+
import {
|
|
5
|
+
toA2ATaskPushNotificationConfig
|
|
6
|
+
} from "../../../protocols/a2a-push-notification.mjs";
|
|
7
|
+
const DEFAULT_CARD_FETCH_TIMEOUT_MS = 1e4;
|
|
8
|
+
const MAX_CACHED_AGENT_CARD_BYTES = 1048576;
|
|
9
|
+
const ADCP_A2A_EXTENSION = "https://adcontextprotocol.org/extensions/adcp/v3";
|
|
10
|
+
const CARD_DRIVEN_LEGACY_COMPAT = Object.freeze({ enabled: true });
|
|
11
|
+
class RequestCaptured extends Error {
|
|
12
|
+
constructor(captured) {
|
|
13
|
+
super("a2a request captured");
|
|
14
|
+
this.captured = captured;
|
|
15
|
+
}
|
|
16
|
+
captured;
|
|
17
|
+
}
|
|
18
|
+
async function captureA2aRequest(agentUrl, call, options = {}) {
|
|
19
|
+
const { ClientFactory, JsonRpcTransportFactory, ServiceParameters, withA2AExtensions } = await import("@a2a-js/sdk-v1/client");
|
|
20
|
+
const { Role } = await import("@a2a-js/sdk-v1");
|
|
21
|
+
const capturingFetch = async (input, init) => {
|
|
22
|
+
const request = new Request(input, init);
|
|
23
|
+
const headers = {};
|
|
24
|
+
request.headers.forEach((value, name) => {
|
|
25
|
+
headers[name] = value;
|
|
26
|
+
});
|
|
27
|
+
throw new RequestCaptured({
|
|
28
|
+
url: request.url,
|
|
29
|
+
method: request.method,
|
|
30
|
+
headers,
|
|
31
|
+
body: await request.text()
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const cardFetch = buildGuardedCardFetch(agentUrl, options);
|
|
35
|
+
const factory = new ClientFactory({
|
|
36
|
+
transports: [new JsonRpcTransportFactory({ fetchImpl: capturingFetch, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],
|
|
37
|
+
cardResolver: new (await import("@a2a-js/sdk-v1/client")).DefaultAgentCardResolver({
|
|
38
|
+
fetchImpl: cardFetch,
|
|
39
|
+
legacyCompat: CARD_DRIVEN_LEGACY_COMPAT
|
|
40
|
+
})
|
|
41
|
+
});
|
|
42
|
+
const client = await createCardDrivenClient(agentUrl, factory);
|
|
43
|
+
const legacyWire = client.protocolVersion?.startsWith("0.") ?? false;
|
|
44
|
+
try {
|
|
45
|
+
if (call.kind === "cancelTask") {
|
|
46
|
+
await client.cancelTask({ tenant: "", id: call.taskId, metadata: void 0 });
|
|
47
|
+
} else {
|
|
48
|
+
const pushNotificationConfig = call.args.push_notification_config;
|
|
49
|
+
const invocation = legacyWire ? {
|
|
50
|
+
skill: call.operation,
|
|
51
|
+
// The maintained 0.3 runtime carries the AdCP application-layer
|
|
52
|
+
// registration in skill parameters. Do not reinterpret it as the
|
|
53
|
+
// native 1.0 transport facility while capturing signing bytes.
|
|
54
|
+
parameters: call.args
|
|
55
|
+
} : {
|
|
56
|
+
skill: call.operation,
|
|
57
|
+
// Native A2A transport registration cannot represent AdCP-only
|
|
58
|
+
// fields such as operation_id. Keep the complete application
|
|
59
|
+
// registration in skill input, matching the runtime path.
|
|
60
|
+
input: call.args
|
|
61
|
+
};
|
|
62
|
+
const request = {
|
|
63
|
+
tenant: "",
|
|
64
|
+
message: {
|
|
65
|
+
messageId: globalThis.crypto.randomUUID(),
|
|
66
|
+
contextId: "",
|
|
67
|
+
taskId: "",
|
|
68
|
+
role: Role.ROLE_USER,
|
|
69
|
+
parts: [
|
|
70
|
+
{
|
|
71
|
+
content: { $case: "data", value: invocation },
|
|
72
|
+
metadata: void 0,
|
|
73
|
+
filename: "",
|
|
74
|
+
mediaType: "application/json"
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
metadata: void 0,
|
|
78
|
+
extensions: legacyWire ? [] : [ADCP_A2A_EXTENSION],
|
|
79
|
+
referenceTaskIds: []
|
|
80
|
+
},
|
|
81
|
+
configuration: !legacyWire && pushNotificationConfig != null && typeof pushNotificationConfig === "object" && !Array.isArray(pushNotificationConfig) ? {
|
|
82
|
+
acceptedOutputModes: ["application/json"],
|
|
83
|
+
taskPushNotificationConfig: toA2ATaskPushNotificationConfig(
|
|
84
|
+
pushNotificationConfig
|
|
85
|
+
),
|
|
86
|
+
returnImmediately: false
|
|
87
|
+
} : void 0,
|
|
88
|
+
metadata: void 0
|
|
89
|
+
};
|
|
90
|
+
await client.sendMessage(request, {
|
|
91
|
+
...legacyWire ? {} : { serviceParameters: ServiceParameters.create(withA2AExtensions(ADCP_A2A_EXTENSION)) }
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (error instanceof RequestCaptured) {
|
|
96
|
+
assertSameOriginEndpoint(agentUrl, error.captured.url);
|
|
97
|
+
return error.captured;
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
throw new Error(`the A2A client returned without issuing a request for ${call.kind}`);
|
|
102
|
+
}
|
|
103
|
+
async function createCardDrivenClient(agentUrl, factory) {
|
|
104
|
+
let lastError;
|
|
105
|
+
for (const cardUrl of buildCardUrls(agentUrl)) {
|
|
106
|
+
try {
|
|
107
|
+
return await factory.createFromUrl(cardUrl, "");
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (isAbortOrTimeoutError(error)) throw error;
|
|
110
|
+
lastError = error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
throw new Error("A2A agent card discovery failed", { cause: lastError });
|
|
114
|
+
}
|
|
115
|
+
function buildGuardedCardFetch(agentUrl, options) {
|
|
116
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_CARD_FETCH_TIMEOUT_MS;
|
|
117
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > MAX_TIMER_DELAY_MS) {
|
|
118
|
+
throw new RangeError(`A2A card timeoutMs must be a finite positive number <= ${MAX_TIMER_DELAY_MS}`);
|
|
119
|
+
}
|
|
120
|
+
const transportFetch = createAgentTransportFetch(agentUrl, {
|
|
121
|
+
...options.cardFetch ? { trustedFetchFn: options.cardFetch } : {},
|
|
122
|
+
allowPrivateIp: options.allowPrivateIp === true
|
|
123
|
+
});
|
|
124
|
+
return ((input, init = {}) => withAbortSignal([init.signal], timeoutMs, async (signal) => {
|
|
125
|
+
const response = await transportFetch(input, { ...init, ...signal ? { signal } : {} });
|
|
126
|
+
const body = await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES, signal);
|
|
127
|
+
return new Response(body.byteLength > 0 ? Uint8Array.from(body).buffer : null, {
|
|
128
|
+
status: response.status,
|
|
129
|
+
statusText: response.statusText,
|
|
130
|
+
headers: response.headers
|
|
131
|
+
});
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
function createCachedA2aCardFetch(agentUrl, options = {}) {
|
|
135
|
+
const upstream = buildGuardedCardFetch(agentUrl, options);
|
|
136
|
+
const responses = /* @__PURE__ */ new Map();
|
|
137
|
+
return async (input, init) => {
|
|
138
|
+
const request = new Request(input, init);
|
|
139
|
+
if (request.method !== "GET") return upstream(input, init);
|
|
140
|
+
let pending = responses.get(request.url);
|
|
141
|
+
if (!pending) {
|
|
142
|
+
pending = upstream(input, init).then(async (response) => ({
|
|
143
|
+
status: response.status,
|
|
144
|
+
statusText: response.statusText,
|
|
145
|
+
headers: (() => {
|
|
146
|
+
const entries = [];
|
|
147
|
+
response.headers.forEach((value, name) => entries.push([name, value]));
|
|
148
|
+
return entries;
|
|
149
|
+
})(),
|
|
150
|
+
body: await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES)
|
|
151
|
+
}));
|
|
152
|
+
responses.set(request.url, pending);
|
|
153
|
+
pending.catch(() => responses.delete(request.url));
|
|
154
|
+
}
|
|
155
|
+
const cached = await pending;
|
|
156
|
+
return new Response(cached.body.slice(), {
|
|
157
|
+
status: cached.status,
|
|
158
|
+
statusText: cached.statusText,
|
|
159
|
+
headers: cached.headers
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
async function readCardBodyBounded(response, maxBytes, signal) {
|
|
164
|
+
const declaredLength = Number(response.headers.get("content-length"));
|
|
165
|
+
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
|
166
|
+
void response.body?.cancel().catch(() => void 0);
|
|
167
|
+
throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);
|
|
168
|
+
}
|
|
169
|
+
if (!response.body) return new Uint8Array();
|
|
170
|
+
const reader = response.body.getReader();
|
|
171
|
+
const cancel = () => void reader.cancel(signal?.reason).catch(() => void 0);
|
|
172
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
173
|
+
try {
|
|
174
|
+
const chunks = [];
|
|
175
|
+
let length = 0;
|
|
176
|
+
while (true) {
|
|
177
|
+
const { done, value } = await reader.read();
|
|
178
|
+
if (done) break;
|
|
179
|
+
length += value.byteLength;
|
|
180
|
+
if (length > maxBytes) {
|
|
181
|
+
void reader.cancel().catch(() => void 0);
|
|
182
|
+
throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);
|
|
183
|
+
}
|
|
184
|
+
chunks.push(value);
|
|
185
|
+
}
|
|
186
|
+
const body = new Uint8Array(length);
|
|
187
|
+
let offset = 0;
|
|
188
|
+
for (const chunk of chunks) {
|
|
189
|
+
body.set(chunk, offset);
|
|
190
|
+
offset += chunk.byteLength;
|
|
191
|
+
}
|
|
192
|
+
return body;
|
|
193
|
+
} finally {
|
|
194
|
+
signal?.removeEventListener("abort", cancel);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function operationFromVectorUrl(vectorUrl) {
|
|
198
|
+
const last = new URL(vectorUrl).pathname.split("/").filter(Boolean).at(-1);
|
|
199
|
+
if (!last || !/^[a-z][a-z0-9_]*$/.test(last)) {
|
|
200
|
+
throw new Error(`Cannot extract an AdCP operation name from vector URL: ${vectorUrl}`);
|
|
201
|
+
}
|
|
202
|
+
return last;
|
|
203
|
+
}
|
|
204
|
+
async function resolveA2aDispatchTarget(agentUrl, options = {}) {
|
|
205
|
+
const { ClientFactory, DefaultAgentCardResolver, JsonRpcTransportFactory } = await import("@a2a-js/sdk-v1/client");
|
|
206
|
+
let endpoint = "";
|
|
207
|
+
const noteEndpoint = async (input, init) => {
|
|
208
|
+
endpoint = new Request(input, init).url;
|
|
209
|
+
throw new RequestCaptured({ url: endpoint, method: "POST", headers: {}, body: "" });
|
|
210
|
+
};
|
|
211
|
+
const factory = new ClientFactory({
|
|
212
|
+
transports: [new JsonRpcTransportFactory({ fetchImpl: noteEndpoint, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],
|
|
213
|
+
cardResolver: new DefaultAgentCardResolver({
|
|
214
|
+
fetchImpl: buildGuardedCardFetch(agentUrl, options),
|
|
215
|
+
legacyCompat: CARD_DRIVEN_LEGACY_COMPAT
|
|
216
|
+
})
|
|
217
|
+
});
|
|
218
|
+
const client = await createCardDrivenClient(agentUrl, factory);
|
|
219
|
+
try {
|
|
220
|
+
await client.cancelTask({ tenant: "", id: "a2a-dispatch-probe", metadata: void 0 });
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (error instanceof RequestCaptured) {
|
|
223
|
+
assertSameOriginEndpoint(agentUrl, endpoint);
|
|
224
|
+
return { endpoint };
|
|
225
|
+
}
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
throw new Error("the A2A client returned without issuing a dispatch probe");
|
|
229
|
+
}
|
|
230
|
+
function assertSameOriginEndpoint(agentUrl, endpoint) {
|
|
231
|
+
const agentOrigin = new URL(agentUrl).origin;
|
|
232
|
+
const endpointOrigin = new URL(endpoint).origin;
|
|
233
|
+
if (endpointOrigin === agentOrigin) return;
|
|
234
|
+
throw new Error(
|
|
235
|
+
`A2A request-signing probes refuse a cross-origin card endpoint (${endpointOrigin}); expected ${agentOrigin}`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
export {
|
|
239
|
+
captureA2aRequest,
|
|
240
|
+
createCachedA2aCardFetch,
|
|
241
|
+
operationFromVectorUrl,
|
|
242
|
+
resolveA2aDispatchTarget
|
|
243
|
+
};
|
|
244
|
+
//# sourceMappingURL=a2a-dispatch.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/testing/storyboard/request-signing/a2a-dispatch.ts"],"sourcesContent":["/**\n * Capture requests emitted by the official A2A 1.x client for RFC 9421\n * signing. The SDK owns endpoint selection, method names, version headers,\n * and proto-JSON encoding; this module only intercepts its fetch seam.\n */\nimport { createAgentTransportFetch } from '../../../net/agent-transport-fetch';\nimport { isAbortOrTimeoutError, MAX_TIMER_DELAY_MS, withAbortSignal } from '../../../protocols/abort';\nimport { buildCardUrls } from '../../../utils/a2a-discovery';\nimport {\n toA2ATaskPushNotificationConfig,\n type A2APushNotificationConfig,\n} from '../../../protocols/a2a-push-notification';\nimport type { SendMessageRequest } from '@a2a-js/sdk-v1';\nimport type { Client } from '@a2a-js/sdk-v1/client';\n\nconst DEFAULT_CARD_FETCH_TIMEOUT_MS = 10_000;\nconst MAX_CACHED_AGENT_CARD_BYTES = 1_048_576;\nconst ADCP_A2A_EXTENSION = 'https://adcontextprotocol.org/extensions/adcp/v3';\n// Defined by the AdCP A2A profile extension and its canonical test vector:\n// docs/building/by-layer/L0/a2a-profile-extension.mdx\n// static/test-vectors/a2a-profile-extension-v3.json\nconst CARD_DRIVEN_LEGACY_COMPAT = Object.freeze({ enabled: true });\n\nexport interface CapturedA2aRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n body: string;\n}\n\nexport type A2aCall =\n | { kind: 'sendMessage'; operation: string; args: Record<string, unknown> }\n | { kind: 'cancelTask'; taskId: string };\n\nexport interface A2aDispatchOptions {\n timeoutMs?: number;\n allowPrivateIp?: boolean;\n /** Trusted fetch used only for agent-card discovery. */\n cardFetch?: typeof fetch;\n}\n\nclass RequestCaptured extends Error {\n constructor(readonly captured: CapturedA2aRequest) {\n super('a2a request captured');\n }\n}\n\nexport async function captureA2aRequest(\n agentUrl: string,\n call: A2aCall,\n options: A2aDispatchOptions = {}\n): Promise<CapturedA2aRequest> {\n const { ClientFactory, JsonRpcTransportFactory, ServiceParameters, withA2AExtensions } =\n await import('@a2a-js/sdk-v1/client');\n const { Role } = await import('@a2a-js/sdk-v1');\n\n const capturingFetch: typeof fetch = async (input, init) => {\n const request = new Request(input as RequestInfo, init);\n const headers: Record<string, string> = {};\n request.headers.forEach((value, name) => {\n headers[name] = value;\n });\n throw new RequestCaptured({\n url: request.url,\n method: request.method,\n headers,\n body: await request.text(),\n });\n };\n\n const cardFetch = buildGuardedCardFetch(agentUrl, options);\n const factory = new ClientFactory({\n transports: [new JsonRpcTransportFactory({ fetchImpl: capturingFetch, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],\n cardResolver: new (await import('@a2a-js/sdk-v1/client')).DefaultAgentCardResolver({\n fetchImpl: cardFetch,\n legacyCompat: CARD_DRIVEN_LEGACY_COMPAT,\n }),\n });\n const client = await createCardDrivenClient(agentUrl, factory);\n const legacyWire = client.protocolVersion?.startsWith('0.') ?? false;\n\n try {\n if (call.kind === 'cancelTask') {\n await client.cancelTask({ tenant: '', id: call.taskId, metadata: undefined });\n } else {\n const pushNotificationConfig = call.args.push_notification_config;\n const invocation = legacyWire\n ? {\n skill: call.operation,\n // The maintained 0.3 runtime carries the AdCP application-layer\n // registration in skill parameters. Do not reinterpret it as the\n // native 1.0 transport facility while capturing signing bytes.\n parameters: call.args,\n }\n : {\n skill: call.operation,\n // Native A2A transport registration cannot represent AdCP-only\n // fields such as operation_id. Keep the complete application\n // registration in skill input, matching the runtime path.\n input: call.args,\n };\n const request: SendMessageRequest = {\n tenant: '',\n message: {\n messageId: globalThis.crypto.randomUUID(),\n contextId: '',\n taskId: '',\n role: Role.ROLE_USER,\n parts: [\n {\n content: { $case: 'data', value: invocation },\n metadata: undefined,\n filename: '',\n mediaType: 'application/json',\n },\n ],\n metadata: undefined,\n extensions: legacyWire ? [] : [ADCP_A2A_EXTENSION],\n referenceTaskIds: [],\n },\n configuration:\n !legacyWire &&\n pushNotificationConfig != null &&\n typeof pushNotificationConfig === 'object' &&\n !Array.isArray(pushNotificationConfig)\n ? {\n acceptedOutputModes: ['application/json'],\n taskPushNotificationConfig: toA2ATaskPushNotificationConfig(\n pushNotificationConfig as A2APushNotificationConfig\n ),\n returnImmediately: false,\n }\n : undefined,\n metadata: undefined,\n };\n await client.sendMessage(request, {\n ...(legacyWire ? {} : { serviceParameters: ServiceParameters.create(withA2AExtensions(ADCP_A2A_EXTENSION)) }),\n });\n }\n } catch (error) {\n if (error instanceof RequestCaptured) {\n assertSameOriginEndpoint(agentUrl, error.captured.url);\n return error.captured;\n }\n throw error;\n }\n throw new Error(`the A2A client returned without issuing a request for ${call.kind}`);\n}\n\nasync function createCardDrivenClient(\n agentUrl: string,\n factory: { createFromUrl(baseUrl: string, path?: string): Promise<Client> }\n): Promise<Client> {\n let lastError: unknown;\n for (const cardUrl of buildCardUrls(agentUrl)) {\n try {\n return await factory.createFromUrl(cardUrl, '');\n } catch (error) {\n if (isAbortOrTimeoutError(error)) throw error;\n lastError = error;\n }\n }\n throw new Error('A2A agent card discovery failed', { cause: lastError });\n}\n\nfunction buildGuardedCardFetch(agentUrl: string, options: A2aDispatchOptions): typeof fetch {\n const timeoutMs = options.timeoutMs ?? DEFAULT_CARD_FETCH_TIMEOUT_MS;\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > MAX_TIMER_DELAY_MS) {\n throw new RangeError(`A2A card timeoutMs must be a finite positive number <= ${MAX_TIMER_DELAY_MS}`);\n }\n const transportFetch = createAgentTransportFetch(agentUrl, {\n ...(options.cardFetch ? { trustedFetchFn: options.cardFetch } : {}),\n allowPrivateIp: options.allowPrivateIp === true,\n });\n return ((input: RequestInfo | URL, init: RequestInit = {}) =>\n withAbortSignal([init.signal], timeoutMs, async signal => {\n const response = await transportFetch(input, { ...init, ...(signal ? { signal } : {}) });\n // Keep the same discovery deadline active through body consumption. A\n // peer can otherwise return headers plus one byte and stall grading\n // forever while the official resolver waits for JSON completion.\n const body = await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES, signal);\n return new Response(body.byteLength > 0 ? Uint8Array.from(body).buffer : null, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n })) as typeof fetch;\n}\n\n/**\n * Cache discovery within one grading run without turning the platform fetch\n * into a trusted fetch override. The guarded transport performs DNS/private\n * address enforcement before this wrapper sees a response.\n */\nexport function createCachedA2aCardFetch(agentUrl: string, options: A2aDispatchOptions = {}): typeof fetch {\n const upstream = buildGuardedCardFetch(agentUrl, options);\n const responses = new Map<\n string,\n Promise<{ status: number; statusText: string; headers: [string, string][]; body: Uint8Array }>\n >();\n return async (input, init) => {\n const request = new Request(input as RequestInfo, init);\n if (request.method !== 'GET') return upstream(input, init);\n let pending = responses.get(request.url);\n if (!pending) {\n pending = upstream(input, init).then(async response => ({\n status: response.status,\n statusText: response.statusText,\n headers: (() => {\n const entries: [string, string][] = [];\n response.headers.forEach((value, name) => entries.push([name, value]));\n return entries;\n })(),\n body: await readCardBodyBounded(response, MAX_CACHED_AGENT_CARD_BYTES),\n }));\n responses.set(request.url, pending);\n pending.catch(() => responses.delete(request.url));\n }\n const cached = await pending;\n return new Response(cached.body.slice(), {\n status: cached.status,\n statusText: cached.statusText,\n headers: cached.headers,\n });\n };\n}\n\nasync function readCardBodyBounded(response: Response, maxBytes: number, signal?: AbortSignal): Promise<Uint8Array> {\n const declaredLength = Number(response.headers.get('content-length'));\n if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {\n void response.body?.cancel().catch(() => undefined);\n throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);\n }\n if (!response.body) return new Uint8Array();\n const reader = response.body.getReader();\n const cancel = () => void reader.cancel(signal?.reason).catch(() => undefined);\n signal?.addEventListener('abort', cancel, { once: true });\n try {\n const chunks: Uint8Array[] = [];\n let length = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n length += value.byteLength;\n if (length > maxBytes) {\n void reader.cancel().catch(() => undefined);\n throw new Error(`A2A agent card exceeds the ${maxBytes}-byte discovery limit`);\n }\n chunks.push(value);\n }\n const body = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n body.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return body;\n } finally {\n signal?.removeEventListener('abort', cancel);\n }\n}\n\nexport function operationFromVectorUrl(vectorUrl: string): string {\n const last = new URL(vectorUrl).pathname.split('/').filter(Boolean).at(-1);\n if (!last || !/^[a-z][a-z0-9_]*$/.test(last)) {\n throw new Error(`Cannot extract an AdCP operation name from vector URL: ${vectorUrl}`);\n }\n return last;\n}\n\nexport async function resolveA2aDispatchTarget(\n agentUrl: string,\n options: A2aDispatchOptions = {}\n): Promise<{ endpoint: string }> {\n const { ClientFactory, DefaultAgentCardResolver, JsonRpcTransportFactory } = await import('@a2a-js/sdk-v1/client');\n let endpoint = '';\n const noteEndpoint: typeof fetch = async (input, init) => {\n endpoint = new Request(input as RequestInfo, init).url;\n throw new RequestCaptured({ url: endpoint, method: 'POST', headers: {}, body: '' });\n };\n const factory = new ClientFactory({\n transports: [new JsonRpcTransportFactory({ fetchImpl: noteEndpoint, legacyCompat: CARD_DRIVEN_LEGACY_COMPAT })],\n cardResolver: new DefaultAgentCardResolver({\n fetchImpl: buildGuardedCardFetch(agentUrl, options),\n legacyCompat: CARD_DRIVEN_LEGACY_COMPAT,\n }),\n });\n const client = await createCardDrivenClient(agentUrl, factory);\n try {\n await client.cancelTask({ tenant: '', id: 'a2a-dispatch-probe', metadata: undefined });\n } catch (error) {\n if (error instanceof RequestCaptured) {\n assertSameOriginEndpoint(agentUrl, endpoint);\n return { endpoint };\n }\n throw error;\n }\n throw new Error('the A2A client returned without issuing a dispatch probe');\n}\n\nfunction assertSameOriginEndpoint(agentUrl: string, endpoint: string): void {\n const agentOrigin = new URL(agentUrl).origin;\n const endpointOrigin = new URL(endpoint).origin;\n if (endpointOrigin === agentOrigin) return;\n throw new Error(\n `A2A request-signing probes refuse a cross-origin card endpoint (${endpointOrigin}); expected ${agentOrigin}`\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NegativeVector, PositiveVector, TestKeyset } from './types.mjs';
|
|
2
|
+
import type { CapturedA2aRequest } from './a2a-dispatch.mjs';
|
|
2
3
|
export interface BuildOptions {
|
|
3
4
|
/** Override the signer clock (unix seconds). Defaults to `Date.now()/1000`. */
|
|
4
5
|
now?: number;
|
|
@@ -30,7 +31,9 @@ export interface BuildOptions {
|
|
|
30
31
|
* 005–008 fold into plain POSTs against the MCP endpoint, but the grader
|
|
31
32
|
* works against any MCP agent that wires a verifier at the HTTP layer.
|
|
32
33
|
*/
|
|
33
|
-
transport?: 'raw' | 'mcp';
|
|
34
|
+
transport?: 'raw' | 'mcp' | 'a2a';
|
|
35
|
+
/** Request emitted by the official A2A SDK; required for A2A transport. */
|
|
36
|
+
a2aRequest?: CapturedA2aRequest;
|
|
34
37
|
/**
|
|
35
38
|
* JSON-RPC `id` for the MCP envelope. Defaults to `crypto.randomUUID()`
|
|
36
39
|
* so concurrent runs never collide. Override for tests that need a stable
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NegativeVector, PositiveVector, TestKeyset } from './types';
|
|
2
|
+
import type { CapturedA2aRequest } from './a2a-dispatch';
|
|
2
3
|
export interface BuildOptions {
|
|
3
4
|
/** Override the signer clock (unix seconds). Defaults to `Date.now()/1000`. */
|
|
4
5
|
now?: number;
|
|
@@ -30,7 +31,9 @@ export interface BuildOptions {
|
|
|
30
31
|
* 005–008 fold into plain POSTs against the MCP endpoint, but the grader
|
|
31
32
|
* works against any MCP agent that wires a verifier at the HTTP layer.
|
|
32
33
|
*/
|
|
33
|
-
transport?: 'raw' | 'mcp';
|
|
34
|
+
transport?: 'raw' | 'mcp' | 'a2a';
|
|
35
|
+
/** Request emitted by the official A2A SDK; required for A2A transport. */
|
|
36
|
+
a2aRequest?: CapturedA2aRequest;
|
|
34
37
|
/**
|
|
35
38
|
* JSON-RPC `id` for the MCP envelope. Defaults to `crypto.randomUUID()`
|
|
36
39
|
* so concurrent runs never collide. Override for tests that need a stable
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/builder.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAe,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../../../src/lib/testing/storyboard/request-signing/builder.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAe,MAAM,SAAS,CAAC;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IAClC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,YAAiB,GACzB,iBAAiB,CAMnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,YAAiB,GACzB,iBAAiB,CAMnB;AAED,wBAAgB,4BAA4B,IAAI,MAAM,EAAE,CAEvD"}
|