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