@adcp/sdk 15.9.4 → 15.9.5
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/dist/lib/core/TaskExecutor.d.mts +1 -0
- package/dist/lib/core/TaskExecutor.d.ts +1 -0
- package/dist/lib/core/TaskExecutor.js +48 -34
- package/dist/lib/core/TaskExecutor.mjs +49 -35
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/client.js +3 -5
- package/dist/lib/testing/client.mjs +4 -6
- package/dist/lib/testing/compliance/comply.js +7 -2
- package/dist/lib/testing/compliance/comply.mjs +8 -3
- package/dist/lib/testing/index.d.mts +1 -1
- package/dist/lib/testing/index.d.ts +1 -1
- package/dist/lib/testing/index.js +4 -2
- package/dist/lib/testing/index.mjs +8 -2
- package/dist/lib/testing/storyboard/runner.js +12 -12
- package/dist/lib/testing/storyboard/runner.mjs +14 -13
- 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.js +23 -1
- package/dist/lib/testing/storyboard/validations.mjs +28 -2
- package/dist/lib/testing/types.d.mts +39 -0
- package/dist/lib/testing/types.d.ts +39 -0
- package/dist/lib/validation/index.d.mts +1 -1
- package/dist/lib/validation/index.d.ts +1 -1
- package/dist/lib/validation/index.js +4 -2
- package/dist/lib/validation/index.mjs +4 -2
- package/dist/lib/validation/schema-loader.d.mts +26 -0
- package/dist/lib/validation/schema-loader.d.ts +26 -0
- package/dist/lib/validation/schema-loader.js +98 -14
- package/dist/lib/validation/schema-loader.mjs +95 -13
- 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.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/VALIDATE-YOUR-AGENT.md +34 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/package.json +1 -1
|
@@ -58,6 +58,45 @@ export interface TestOptions {
|
|
|
58
58
|
* authoritative over the SDK's generated Zod snapshot for the run.
|
|
59
59
|
*/
|
|
60
60
|
schemaRoot?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Schema roots for releases the agent may echo in its
|
|
63
|
+
* `get_adcp_capabilities` response, keyed by AdCP version (`'3.2'`,
|
|
64
|
+
* `'3.2.5'`, `'3.3.0-beta.1'`). Values are schema-data roots in the same
|
|
65
|
+
* shape as `schemaRoot`.
|
|
66
|
+
*
|
|
67
|
+
* A 3.0 pin sends only `adcp_major_version`, so an agent may serve and echo
|
|
68
|
+
* a newer release in the same major (versioning spec, "Server echoes").
|
|
69
|
+
* The SDK validates that capabilities response against the echoed release
|
|
70
|
+
* when the echo is the pin's major, is listed in the response's
|
|
71
|
+
* `adcp.supported_versions`, and has a schema root: an entry here, an
|
|
72
|
+
* external root registered for it, or the SDK's bundled schemas. That
|
|
73
|
+
* applies to discovery's capability notices, `getAdcpCapabilities()` and
|
|
74
|
+
* storyboard `response_schema` checks on `get_adcp_capabilities`, including
|
|
75
|
+
* when `schemaRoot` is set for the pin. Otherwise validation stays on the
|
|
76
|
+
* pin.
|
|
77
|
+
*
|
|
78
|
+
* Entries are used for that capabilities validation only. Every other
|
|
79
|
+
* task's response, storyboard selection and grading stay on the pin. Each
|
|
80
|
+
* root is checked against its key once per process; a malformed map throws
|
|
81
|
+
* before the run starts. Honored by `comply()`, `runStoryboard()` and
|
|
82
|
+
* `runStoryboardStep()`; other callers can use `withServedReleaseSchemaRoots`.
|
|
83
|
+
* The echo is compared with the run's pin, so storyboard checks apply it
|
|
84
|
+
* only when the run has one (`adcpVersion`, or the storyboard or compliance
|
|
85
|
+
* bundle's `adcp_version`); `comply()` always does.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* await comply(agentUrl, {
|
|
90
|
+
* complianceDir: hosted30.complianceDir,
|
|
91
|
+
* schemaRoot: hosted30.schemaRoot,
|
|
92
|
+
* servedReleaseSchemaRoots: {
|
|
93
|
+
* '3.1.29': hosted31.schemaRoot,
|
|
94
|
+
* '3.2.5': hosted32.schemaRoot,
|
|
95
|
+
* },
|
|
96
|
+
* });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
servedReleaseSchemaRoots?: Readonly<Record<string, string>>;
|
|
61
100
|
/**
|
|
62
101
|
* Whether strict AJV response-schema failures contribute to storyboard
|
|
63
102
|
* grading. Defaults to `true`, matching the hosted compliance grader.
|
|
@@ -58,6 +58,45 @@ export interface TestOptions {
|
|
|
58
58
|
* authoritative over the SDK's generated Zod snapshot for the run.
|
|
59
59
|
*/
|
|
60
60
|
schemaRoot?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Schema roots for releases the agent may echo in its
|
|
63
|
+
* `get_adcp_capabilities` response, keyed by AdCP version (`'3.2'`,
|
|
64
|
+
* `'3.2.5'`, `'3.3.0-beta.1'`). Values are schema-data roots in the same
|
|
65
|
+
* shape as `schemaRoot`.
|
|
66
|
+
*
|
|
67
|
+
* A 3.0 pin sends only `adcp_major_version`, so an agent may serve and echo
|
|
68
|
+
* a newer release in the same major (versioning spec, "Server echoes").
|
|
69
|
+
* The SDK validates that capabilities response against the echoed release
|
|
70
|
+
* when the echo is the pin's major, is listed in the response's
|
|
71
|
+
* `adcp.supported_versions`, and has a schema root: an entry here, an
|
|
72
|
+
* external root registered for it, or the SDK's bundled schemas. That
|
|
73
|
+
* applies to discovery's capability notices, `getAdcpCapabilities()` and
|
|
74
|
+
* storyboard `response_schema` checks on `get_adcp_capabilities`, including
|
|
75
|
+
* when `schemaRoot` is set for the pin. Otherwise validation stays on the
|
|
76
|
+
* pin.
|
|
77
|
+
*
|
|
78
|
+
* Entries are used for that capabilities validation only. Every other
|
|
79
|
+
* task's response, storyboard selection and grading stay on the pin. Each
|
|
80
|
+
* root is checked against its key once per process; a malformed map throws
|
|
81
|
+
* before the run starts. Honored by `comply()`, `runStoryboard()` and
|
|
82
|
+
* `runStoryboardStep()`; other callers can use `withServedReleaseSchemaRoots`.
|
|
83
|
+
* The echo is compared with the run's pin, so storyboard checks apply it
|
|
84
|
+
* only when the run has one (`adcpVersion`, or the storyboard or compliance
|
|
85
|
+
* bundle's `adcp_version`); `comply()` always does.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* await comply(agentUrl, {
|
|
90
|
+
* complianceDir: hosted30.complianceDir,
|
|
91
|
+
* schemaRoot: hosted30.schemaRoot,
|
|
92
|
+
* servedReleaseSchemaRoots: {
|
|
93
|
+
* '3.1.29': hosted31.schemaRoot,
|
|
94
|
+
* '3.2.5': hosted32.schemaRoot,
|
|
95
|
+
* },
|
|
96
|
+
* });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
servedReleaseSchemaRoots?: Readonly<Record<string, string>>;
|
|
61
100
|
/**
|
|
62
101
|
* Whether strict AJV response-schema failures contribute to storyboard
|
|
63
102
|
* grading. Defaults to `true`, matching the hosted compliance grader.
|
|
@@ -6,7 +6,7 @@ export { validateRequest, validateResponse, formatIssues } from './schema-valida
|
|
|
6
6
|
export type { ValidationIssue, ValidationOutcome } from './schema-validator.mjs';
|
|
7
7
|
export { buildValidationError, buildAdcpValidationErrorPayload } from './schema-errors.mjs';
|
|
8
8
|
export type { ValidationErrorDetails, AdcpValidationErrorDetails } from './schema-errors.mjs';
|
|
9
|
-
export { getValidator, listValidatorKeys, resolveBundleKey, hasSchemaBundle, registerExternalSchemaRoot, unregisterExternalSchemaRoot, withExternalSchemaRoot, } from './schema-loader.mjs';
|
|
9
|
+
export { getValidator, listValidatorKeys, resolveBundleKey, hasSchemaBundle, registerExternalSchemaRoot, unregisterExternalSchemaRoot, withExternalSchemaRoot, withServedReleaseSchemaRoots, } from './schema-loader.mjs';
|
|
10
10
|
export type { Direction, ResponseVariant } from './schema-loader.mjs';
|
|
11
11
|
export { validateOutgoingRequest, validateIncomingResponse, resolveValidationModes } from './client-hooks.mjs';
|
|
12
12
|
export type { ValidationMode, ValidationHookConfig } from './client-hooks.mjs';
|
|
@@ -6,7 +6,7 @@ export { validateRequest, validateResponse, formatIssues } from './schema-valida
|
|
|
6
6
|
export type { ValidationIssue, ValidationOutcome } from './schema-validator';
|
|
7
7
|
export { buildValidationError, buildAdcpValidationErrorPayload } from './schema-errors';
|
|
8
8
|
export type { ValidationErrorDetails, AdcpValidationErrorDetails } from './schema-errors';
|
|
9
|
-
export { getValidator, listValidatorKeys, resolveBundleKey, hasSchemaBundle, registerExternalSchemaRoot, unregisterExternalSchemaRoot, withExternalSchemaRoot, } from './schema-loader';
|
|
9
|
+
export { getValidator, listValidatorKeys, resolveBundleKey, hasSchemaBundle, registerExternalSchemaRoot, unregisterExternalSchemaRoot, withExternalSchemaRoot, withServedReleaseSchemaRoots, } from './schema-loader';
|
|
10
10
|
export type { Direction, ResponseVariant } from './schema-loader';
|
|
11
11
|
export { validateOutgoingRequest, validateIncomingResponse, resolveValidationModes } from './client-hooks';
|
|
12
12
|
export type { ValidationMode, ValidationHookConfig } from './client-hooks';
|
|
@@ -36,7 +36,8 @@ __export(validation_exports, {
|
|
|
36
36
|
validateOutgoingRequest: () => import_client_hooks.validateOutgoingRequest,
|
|
37
37
|
validateRequest: () => import_schema_validator.validateRequest,
|
|
38
38
|
validateResponse: () => import_schema_validator.validateResponse,
|
|
39
|
-
withExternalSchemaRoot: () => import_schema_loader.withExternalSchemaRoot
|
|
39
|
+
withExternalSchemaRoot: () => import_schema_loader.withExternalSchemaRoot,
|
|
40
|
+
withServedReleaseSchemaRoots: () => import_schema_loader.withServedReleaseSchemaRoots
|
|
40
41
|
});
|
|
41
42
|
module.exports = __toCommonJS(validation_exports);
|
|
42
43
|
var import_probe_policy = require('../utils/probe-policy.js');
|
|
@@ -201,5 +202,6 @@ async function handleAdCPResponse(response, expectedSchema, agentName) {
|
|
|
201
202
|
validateOutgoingRequest,
|
|
202
203
|
validateRequest,
|
|
203
204
|
validateResponse,
|
|
204
|
-
withExternalSchemaRoot
|
|
205
|
+
withExternalSchemaRoot,
|
|
206
|
+
withServedReleaseSchemaRoots
|
|
205
207
|
});
|
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
hasSchemaBundle,
|
|
9
9
|
registerExternalSchemaRoot,
|
|
10
10
|
unregisterExternalSchemaRoot,
|
|
11
|
-
withExternalSchemaRoot
|
|
11
|
+
withExternalSchemaRoot,
|
|
12
|
+
withServedReleaseSchemaRoots
|
|
12
13
|
} from "./schema-loader.mjs";
|
|
13
14
|
import { validateOutgoingRequest, validateIncomingResponse, resolveValidationModes } from "./client-hooks.mjs";
|
|
14
15
|
function getExpectedSchema(toolName) {
|
|
@@ -167,5 +168,6 @@ export {
|
|
|
167
168
|
validateOutgoingRequest,
|
|
168
169
|
validateRequest,
|
|
169
170
|
validateResponse,
|
|
170
|
-
withExternalSchemaRoot
|
|
171
|
+
withExternalSchemaRoot,
|
|
172
|
+
withServedReleaseSchemaRoots
|
|
171
173
|
};
|
|
@@ -168,6 +168,32 @@ export { SCHEMA_FILENAME_SUFFIX };
|
|
|
168
168
|
* we don't have schemas for.
|
|
169
169
|
*/
|
|
170
170
|
export declare function hasSchemaBundle(version: string): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Run `fn` with schema roots for the releases an agent may echo in its
|
|
173
|
+
* `get_adcp_capabilities` response.
|
|
174
|
+
*
|
|
175
|
+
* Keys are AdCP versions in any form the SDK accepts for a pin (`'3.2'`,
|
|
176
|
+
* `'3.2.5'`, `'3.3.0-beta.1'`); values are schema-data roots in the same
|
|
177
|
+
* shape as `schemaRoot` (a directory holding `bundled/`, e.g. a hosted
|
|
178
|
+
* `dist/schemas/3.2.5`). Each root is checked against its key the same way
|
|
179
|
+
* `withExternalSchemaRoot` checks one, and a malformed map throws before `fn`
|
|
180
|
+
* runs.
|
|
181
|
+
*
|
|
182
|
+
* The roots are consulted only when validating a `get_adcp_capabilities`
|
|
183
|
+
* response against the release the agent echoed (see
|
|
184
|
+
* {@link resolveServedValidationVersion}): discovery's capability notices,
|
|
185
|
+
* `getAdcpCapabilities()` response validation and storyboard
|
|
186
|
+
* `response_schema` checks on that task. They are not activated for any other
|
|
187
|
+
* task, so every other response, storyboard selection and grading stay on the
|
|
188
|
+
* pin. A supplied root takes precedence over an external root registered for
|
|
189
|
+
* the same release and over the SDK's bundled schemas for it.
|
|
190
|
+
*
|
|
191
|
+
* Scoped to the current async execution chain; nested calls add to the
|
|
192
|
+
* enclosing scope, with the innermost entry for a release winning.
|
|
193
|
+
* `comply()` and `runStoryboard()` accept the same map as
|
|
194
|
+
* `servedReleaseSchemaRoots` and call this for you.
|
|
195
|
+
*/
|
|
196
|
+
export declare function withServedReleaseSchemaRoots<T>(roots: Readonly<Record<string, string>> | undefined, fn: () => T): T;
|
|
171
197
|
/** Load the exact self-contained request projection from an MCP role profile. */
|
|
172
198
|
export declare function getMcpProfileInputSchema(toolName: string, profile: string, version?: string): Readonly<Record<string, unknown>> | undefined;
|
|
173
199
|
/**
|
|
@@ -168,6 +168,32 @@ export { SCHEMA_FILENAME_SUFFIX };
|
|
|
168
168
|
* we don't have schemas for.
|
|
169
169
|
*/
|
|
170
170
|
export declare function hasSchemaBundle(version: string): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Run `fn` with schema roots for the releases an agent may echo in its
|
|
173
|
+
* `get_adcp_capabilities` response.
|
|
174
|
+
*
|
|
175
|
+
* Keys are AdCP versions in any form the SDK accepts for a pin (`'3.2'`,
|
|
176
|
+
* `'3.2.5'`, `'3.3.0-beta.1'`); values are schema-data roots in the same
|
|
177
|
+
* shape as `schemaRoot` (a directory holding `bundled/`, e.g. a hosted
|
|
178
|
+
* `dist/schemas/3.2.5`). Each root is checked against its key the same way
|
|
179
|
+
* `withExternalSchemaRoot` checks one, and a malformed map throws before `fn`
|
|
180
|
+
* runs.
|
|
181
|
+
*
|
|
182
|
+
* The roots are consulted only when validating a `get_adcp_capabilities`
|
|
183
|
+
* response against the release the agent echoed (see
|
|
184
|
+
* {@link resolveServedValidationVersion}): discovery's capability notices,
|
|
185
|
+
* `getAdcpCapabilities()` response validation and storyboard
|
|
186
|
+
* `response_schema` checks on that task. They are not activated for any other
|
|
187
|
+
* task, so every other response, storyboard selection and grading stay on the
|
|
188
|
+
* pin. A supplied root takes precedence over an external root registered for
|
|
189
|
+
* the same release and over the SDK's bundled schemas for it.
|
|
190
|
+
*
|
|
191
|
+
* Scoped to the current async execution chain; nested calls add to the
|
|
192
|
+
* enclosing scope, with the innermost entry for a release winning.
|
|
193
|
+
* `comply()` and `runStoryboard()` accept the same map as
|
|
194
|
+
* `servedReleaseSchemaRoots` and call this for you.
|
|
195
|
+
*/
|
|
196
|
+
export declare function withServedReleaseSchemaRoots<T>(roots: Readonly<Record<string, string>> | undefined, fn: () => T): T;
|
|
171
197
|
/** Load the exact self-contained request projection from an MCP role profile. */
|
|
172
198
|
export declare function getMcpProfileInputSchema(toolName: string, profile: string, version?: string): Readonly<Record<string, unknown>> | undefined;
|
|
173
199
|
/**
|
|
@@ -51,7 +51,9 @@ __export(schema_loader_exports, {
|
|
|
51
51
|
toReleasePrecisionWire: () => toReleasePrecisionWire,
|
|
52
52
|
unregisterExternalSchemaRoot: () => unregisterExternalSchemaRoot,
|
|
53
53
|
validateAdcpVersionWire: () => validateAdcpVersionWire,
|
|
54
|
-
withExternalSchemaRoot: () => withExternalSchemaRoot
|
|
54
|
+
withExternalSchemaRoot: () => withExternalSchemaRoot,
|
|
55
|
+
withServedReleaseSchemaRoots: () => withServedReleaseSchemaRoots,
|
|
56
|
+
withServedValidationVersion: () => withServedValidationVersion
|
|
55
57
|
});
|
|
56
58
|
module.exports = __toCommonJS(schema_loader_exports);
|
|
57
59
|
var import_ajv = __toESM(require("ajv"));
|
|
@@ -719,28 +721,108 @@ function hasSchemaBundle(version) {
|
|
|
719
721
|
return false;
|
|
720
722
|
}
|
|
721
723
|
}
|
|
722
|
-
const
|
|
723
|
-
const
|
|
724
|
-
function
|
|
725
|
-
|
|
726
|
-
if (
|
|
724
|
+
const servedReleaseSchemaRootScope = new import_async_hooks.AsyncLocalStorage();
|
|
725
|
+
const servedReleaseRootAliases = /* @__PURE__ */ new Map();
|
|
726
|
+
function withServedReleaseSchemaRoots(roots, fn) {
|
|
727
|
+
if (roots === void 0) return fn();
|
|
728
|
+
if (roots === null || typeof roots !== "object" || Array.isArray(roots)) {
|
|
729
|
+
throw new TypeError("servedReleaseSchemaRoots must be an object mapping AdCP versions to schema roots");
|
|
730
|
+
}
|
|
731
|
+
const entries = [];
|
|
732
|
+
for (const [version, root] of Object.entries(roots)) {
|
|
733
|
+
resolveBundleKey(version);
|
|
734
|
+
if (typeof root !== "string" || root.length === 0) {
|
|
735
|
+
throw new TypeError(`servedReleaseSchemaRoots["${version}"] must be a non-empty schema root path`);
|
|
736
|
+
}
|
|
737
|
+
const memoKey = `${version}\0${root}`;
|
|
738
|
+
let aliases = servedReleaseRootAliases.get(memoKey);
|
|
739
|
+
if (!aliases) {
|
|
740
|
+
if (!hasSchemaRootShape(root)) {
|
|
741
|
+
throw new Error(`Served-release AdCP schema root for version "${version}" not found or empty at ${root}`);
|
|
742
|
+
}
|
|
743
|
+
aliases = assertSchemaRootMatchesVersion(version, root);
|
|
744
|
+
servedReleaseRootAliases.set(memoKey, aliases);
|
|
745
|
+
}
|
|
746
|
+
const conflict = entries.find((entry) => entry.root !== root && [...aliases].some((alias) => entry.aliases.has(alias)));
|
|
747
|
+
if (conflict) {
|
|
748
|
+
throw new Error(
|
|
749
|
+
`servedReleaseSchemaRoots["${version}"] and servedReleaseSchemaRoots["${conflict.version}"] name the same release with different schema roots (${root}, ${conflict.root})`
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
entries.push({ version, root, aliases });
|
|
753
|
+
}
|
|
754
|
+
if (entries.length === 0) return fn();
|
|
755
|
+
const parent = servedReleaseSchemaRootScope.getStore() ?? [];
|
|
756
|
+
return servedReleaseSchemaRootScope.run([...entries, ...parent], fn);
|
|
757
|
+
}
|
|
758
|
+
function findServedReleaseSchemaRoot(release) {
|
|
759
|
+
const entries = servedReleaseSchemaRootScope.getStore();
|
|
760
|
+
if (!entries?.length) return void 0;
|
|
761
|
+
let key;
|
|
727
762
|
try {
|
|
728
|
-
|
|
763
|
+
key = resolveBundleKey(release);
|
|
729
764
|
} catch {
|
|
730
|
-
return
|
|
765
|
+
return void 0;
|
|
731
766
|
}
|
|
732
|
-
|
|
733
|
-
|
|
767
|
+
return entries.find((entry) => entry.aliases.has(key) || entry.aliases.has(release));
|
|
768
|
+
}
|
|
769
|
+
const SERVED_RELEASE_MAJOR = /^(\d+)\.\d+(?:-[a-zA-Z0-9.-]+)?$/;
|
|
770
|
+
const NUMERIC_PIN_MAJOR = /^(\d+)\.\d+/;
|
|
771
|
+
function listsSupportedRelease(response, release) {
|
|
772
|
+
const adcp = response.adcp;
|
|
773
|
+
if (adcp === null || typeof adcp !== "object") return false;
|
|
774
|
+
const supported = adcp.supported_versions;
|
|
775
|
+
if (!Array.isArray(supported)) return false;
|
|
776
|
+
return supported.some((entry) => {
|
|
777
|
+
if (typeof entry !== "string") return false;
|
|
778
|
+
if (entry === release) return true;
|
|
779
|
+
try {
|
|
780
|
+
return toReleasePrecisionWire(entry) === release;
|
|
781
|
+
} catch {
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
function selectServedValidationVersion(response, pinnedVersion) {
|
|
787
|
+
const pin = { version: pinnedVersion };
|
|
788
|
+
const pinMajor = NUMERIC_PIN_MAJOR.exec(pinnedVersion)?.[1];
|
|
789
|
+
if (pinMajor === void 0) return pin;
|
|
790
|
+
if (response === null || typeof response !== "object") return pin;
|
|
791
|
+
const echoed = response.adcp_version;
|
|
792
|
+
if (typeof echoed !== "string") return pin;
|
|
734
793
|
const echoMajor = SERVED_RELEASE_MAJOR.exec(echoed)?.[1];
|
|
735
|
-
if (echoMajor === void 0 || echoMajor !== pinMajor) return
|
|
794
|
+
if (echoMajor === void 0 || echoMajor !== pinMajor) return pin;
|
|
736
795
|
let pinnedRelease;
|
|
737
796
|
try {
|
|
738
797
|
pinnedRelease = toReleasePrecisionWire(pinnedVersion);
|
|
798
|
+
} catch {
|
|
799
|
+
return pin;
|
|
800
|
+
}
|
|
801
|
+
if (echoed === pinnedRelease) return pin;
|
|
802
|
+
if (!listsSupportedRelease(response, echoed)) return pin;
|
|
803
|
+
const served = findServedReleaseSchemaRoot(echoed);
|
|
804
|
+
if (served) return { version: echoed, served };
|
|
805
|
+
return hasSchemaBundle(echoed) ? { version: echoed } : pin;
|
|
806
|
+
}
|
|
807
|
+
function resolveServedValidationVersion(response, pinnedVersion) {
|
|
808
|
+
try {
|
|
809
|
+
return selectServedValidationVersion(response, pinnedVersion).version;
|
|
739
810
|
} catch {
|
|
740
811
|
return pinnedVersion;
|
|
741
812
|
}
|
|
742
|
-
|
|
743
|
-
|
|
813
|
+
}
|
|
814
|
+
function withServedValidationVersion(response, pinnedVersion, fn) {
|
|
815
|
+
let selection;
|
|
816
|
+
try {
|
|
817
|
+
selection = selectServedValidationVersion(response, pinnedVersion);
|
|
818
|
+
} catch {
|
|
819
|
+
selection = { version: pinnedVersion };
|
|
820
|
+
}
|
|
821
|
+
const { version, served } = selection;
|
|
822
|
+
if (!served) return fn(version);
|
|
823
|
+
const next = new Map(scopedExternalSchemaRoots.getStore());
|
|
824
|
+
for (const alias of served.aliases) next.set(alias, served.root);
|
|
825
|
+
return scopedExternalSchemaRoots.run(next, () => fn(version));
|
|
744
826
|
}
|
|
745
827
|
const mcpToolSchemaCache = /* @__PURE__ */ new Map();
|
|
746
828
|
const mcpToolSummaryCache = /* @__PURE__ */ new Map();
|
|
@@ -1010,5 +1092,7 @@ function cloneJsonValue(value) {
|
|
|
1010
1092
|
toReleasePrecisionWire,
|
|
1011
1093
|
unregisterExternalSchemaRoot,
|
|
1012
1094
|
validateAdcpVersionWire,
|
|
1013
|
-
withExternalSchemaRoot
|
|
1095
|
+
withExternalSchemaRoot,
|
|
1096
|
+
withServedReleaseSchemaRoots,
|
|
1097
|
+
withServedValidationVersion
|
|
1014
1098
|
});
|
|
@@ -668,28 +668,108 @@ function hasSchemaBundle(version) {
|
|
|
668
668
|
return false;
|
|
669
669
|
}
|
|
670
670
|
}
|
|
671
|
-
const
|
|
672
|
-
const
|
|
673
|
-
function
|
|
674
|
-
|
|
675
|
-
if (
|
|
671
|
+
const servedReleaseSchemaRootScope = new AsyncLocalStorage();
|
|
672
|
+
const servedReleaseRootAliases = /* @__PURE__ */ new Map();
|
|
673
|
+
function withServedReleaseSchemaRoots(roots, fn) {
|
|
674
|
+
if (roots === void 0) return fn();
|
|
675
|
+
if (roots === null || typeof roots !== "object" || Array.isArray(roots)) {
|
|
676
|
+
throw new TypeError("servedReleaseSchemaRoots must be an object mapping AdCP versions to schema roots");
|
|
677
|
+
}
|
|
678
|
+
const entries = [];
|
|
679
|
+
for (const [version, root] of Object.entries(roots)) {
|
|
680
|
+
resolveBundleKey(version);
|
|
681
|
+
if (typeof root !== "string" || root.length === 0) {
|
|
682
|
+
throw new TypeError(`servedReleaseSchemaRoots["${version}"] must be a non-empty schema root path`);
|
|
683
|
+
}
|
|
684
|
+
const memoKey = `${version}\0${root}`;
|
|
685
|
+
let aliases = servedReleaseRootAliases.get(memoKey);
|
|
686
|
+
if (!aliases) {
|
|
687
|
+
if (!hasSchemaRootShape(root)) {
|
|
688
|
+
throw new Error(`Served-release AdCP schema root for version "${version}" not found or empty at ${root}`);
|
|
689
|
+
}
|
|
690
|
+
aliases = assertSchemaRootMatchesVersion(version, root);
|
|
691
|
+
servedReleaseRootAliases.set(memoKey, aliases);
|
|
692
|
+
}
|
|
693
|
+
const conflict = entries.find((entry) => entry.root !== root && [...aliases].some((alias) => entry.aliases.has(alias)));
|
|
694
|
+
if (conflict) {
|
|
695
|
+
throw new Error(
|
|
696
|
+
`servedReleaseSchemaRoots["${version}"] and servedReleaseSchemaRoots["${conflict.version}"] name the same release with different schema roots (${root}, ${conflict.root})`
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
entries.push({ version, root, aliases });
|
|
700
|
+
}
|
|
701
|
+
if (entries.length === 0) return fn();
|
|
702
|
+
const parent = servedReleaseSchemaRootScope.getStore() ?? [];
|
|
703
|
+
return servedReleaseSchemaRootScope.run([...entries, ...parent], fn);
|
|
704
|
+
}
|
|
705
|
+
function findServedReleaseSchemaRoot(release) {
|
|
706
|
+
const entries = servedReleaseSchemaRootScope.getStore();
|
|
707
|
+
if (!entries?.length) return void 0;
|
|
708
|
+
let key;
|
|
676
709
|
try {
|
|
677
|
-
|
|
710
|
+
key = resolveBundleKey(release);
|
|
678
711
|
} catch {
|
|
679
|
-
return
|
|
712
|
+
return void 0;
|
|
680
713
|
}
|
|
681
|
-
|
|
682
|
-
|
|
714
|
+
return entries.find((entry) => entry.aliases.has(key) || entry.aliases.has(release));
|
|
715
|
+
}
|
|
716
|
+
const SERVED_RELEASE_MAJOR = /^(\d+)\.\d+(?:-[a-zA-Z0-9.-]+)?$/;
|
|
717
|
+
const NUMERIC_PIN_MAJOR = /^(\d+)\.\d+/;
|
|
718
|
+
function listsSupportedRelease(response, release) {
|
|
719
|
+
const adcp = response.adcp;
|
|
720
|
+
if (adcp === null || typeof adcp !== "object") return false;
|
|
721
|
+
const supported = adcp.supported_versions;
|
|
722
|
+
if (!Array.isArray(supported)) return false;
|
|
723
|
+
return supported.some((entry) => {
|
|
724
|
+
if (typeof entry !== "string") return false;
|
|
725
|
+
if (entry === release) return true;
|
|
726
|
+
try {
|
|
727
|
+
return toReleasePrecisionWire(entry) === release;
|
|
728
|
+
} catch {
|
|
729
|
+
return false;
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
function selectServedValidationVersion(response, pinnedVersion) {
|
|
734
|
+
const pin = { version: pinnedVersion };
|
|
735
|
+
const pinMajor = NUMERIC_PIN_MAJOR.exec(pinnedVersion)?.[1];
|
|
736
|
+
if (pinMajor === void 0) return pin;
|
|
737
|
+
if (response === null || typeof response !== "object") return pin;
|
|
738
|
+
const echoed = response.adcp_version;
|
|
739
|
+
if (typeof echoed !== "string") return pin;
|
|
683
740
|
const echoMajor = SERVED_RELEASE_MAJOR.exec(echoed)?.[1];
|
|
684
|
-
if (echoMajor === void 0 || echoMajor !== pinMajor) return
|
|
741
|
+
if (echoMajor === void 0 || echoMajor !== pinMajor) return pin;
|
|
685
742
|
let pinnedRelease;
|
|
686
743
|
try {
|
|
687
744
|
pinnedRelease = toReleasePrecisionWire(pinnedVersion);
|
|
745
|
+
} catch {
|
|
746
|
+
return pin;
|
|
747
|
+
}
|
|
748
|
+
if (echoed === pinnedRelease) return pin;
|
|
749
|
+
if (!listsSupportedRelease(response, echoed)) return pin;
|
|
750
|
+
const served = findServedReleaseSchemaRoot(echoed);
|
|
751
|
+
if (served) return { version: echoed, served };
|
|
752
|
+
return hasSchemaBundle(echoed) ? { version: echoed } : pin;
|
|
753
|
+
}
|
|
754
|
+
function resolveServedValidationVersion(response, pinnedVersion) {
|
|
755
|
+
try {
|
|
756
|
+
return selectServedValidationVersion(response, pinnedVersion).version;
|
|
688
757
|
} catch {
|
|
689
758
|
return pinnedVersion;
|
|
690
759
|
}
|
|
691
|
-
|
|
692
|
-
|
|
760
|
+
}
|
|
761
|
+
function withServedValidationVersion(response, pinnedVersion, fn) {
|
|
762
|
+
let selection;
|
|
763
|
+
try {
|
|
764
|
+
selection = selectServedValidationVersion(response, pinnedVersion);
|
|
765
|
+
} catch {
|
|
766
|
+
selection = { version: pinnedVersion };
|
|
767
|
+
}
|
|
768
|
+
const { version, served } = selection;
|
|
769
|
+
if (!served) return fn(version);
|
|
770
|
+
const next = new Map(scopedExternalSchemaRoots.getStore());
|
|
771
|
+
for (const alias of served.aliases) next.set(alias, served.root);
|
|
772
|
+
return scopedExternalSchemaRoots.run(next, () => fn(version));
|
|
693
773
|
}
|
|
694
774
|
const mcpToolSchemaCache = /* @__PURE__ */ new Map();
|
|
695
775
|
const mcpToolSummaryCache = /* @__PURE__ */ new Map();
|
|
@@ -958,5 +1038,7 @@ export {
|
|
|
958
1038
|
toReleasePrecisionWire,
|
|
959
1039
|
unregisterExternalSchemaRoot,
|
|
960
1040
|
validateAdcpVersionWire,
|
|
961
|
-
withExternalSchemaRoot
|
|
1041
|
+
withExternalSchemaRoot,
|
|
1042
|
+
withServedReleaseSchemaRoots,
|
|
1043
|
+
withServedValidationVersion
|
|
962
1044
|
};
|
package/dist/lib/version.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "15.9.
|
|
4
|
+
export declare const LIBRARY_VERSION = "15.9.5";
|
|
5
5
|
/**
|
|
6
6
|
* AdCP specification version this library is built for
|
|
7
7
|
*/
|
|
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
|
|
|
33
33
|
* Full version information
|
|
34
34
|
*/
|
|
35
35
|
export declare const VERSION_INFO: {
|
|
36
|
-
readonly library: "15.9.
|
|
36
|
+
readonly library: "15.9.5";
|
|
37
37
|
readonly adcp: "3.2.5";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.1.25", "3.1.26", "3.1.27", "3.1.28", "3.1.29", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4", "3.2.5"];
|
|
39
|
-
readonly generatedAt: "2026-10-
|
|
39
|
+
readonly generatedAt: "2026-10-17T14:24:48.482Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "15.9.
|
|
4
|
+
export declare const LIBRARY_VERSION = "15.9.5";
|
|
5
5
|
/**
|
|
6
6
|
* AdCP specification version this library is built for
|
|
7
7
|
*/
|
|
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
|
|
|
33
33
|
* Full version information
|
|
34
34
|
*/
|
|
35
35
|
export declare const VERSION_INFO: {
|
|
36
|
-
readonly library: "15.9.
|
|
36
|
+
readonly library: "15.9.5";
|
|
37
37
|
readonly adcp: "3.2.5";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.1.25", "3.1.26", "3.1.27", "3.1.28", "3.1.29", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4", "3.2.5"];
|
|
39
|
-
readonly generatedAt: "2026-10-
|
|
39
|
+
readonly generatedAt: "2026-10-17T14:24:48.482Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.js
CHANGED
|
@@ -31,7 +31,7 @@ __export(version_exports, {
|
|
|
31
31
|
toReleasePrecisionVersion: () => toReleasePrecisionVersion
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(version_exports);
|
|
34
|
-
const LIBRARY_VERSION = "15.9.
|
|
34
|
+
const LIBRARY_VERSION = "15.9.5";
|
|
35
35
|
const ADCP_VERSION = "3.2.5";
|
|
36
36
|
const ADCP_MAJOR_VERSION = 3;
|
|
37
37
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -104,10 +104,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
104
104
|
"3.2.5"
|
|
105
105
|
];
|
|
106
106
|
const VERSION_INFO = {
|
|
107
|
-
library: "15.9.
|
|
107
|
+
library: "15.9.5",
|
|
108
108
|
adcp: "3.2.5",
|
|
109
109
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
110
|
-
generatedAt: "2026-10-
|
|
110
|
+
generatedAt: "2026-10-17T14:24:48.482Z"
|
|
111
111
|
};
|
|
112
112
|
function getAdcpVersion() {
|
|
113
113
|
return ADCP_VERSION;
|
package/dist/lib/version.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const LIBRARY_VERSION = "15.9.
|
|
1
|
+
const LIBRARY_VERSION = "15.9.5";
|
|
2
2
|
const ADCP_VERSION = "3.2.5";
|
|
3
3
|
const ADCP_MAJOR_VERSION = 3;
|
|
4
4
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -71,10 +71,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
71
71
|
"3.2.5"
|
|
72
72
|
];
|
|
73
73
|
const VERSION_INFO = {
|
|
74
|
-
library: "15.9.
|
|
74
|
+
library: "15.9.5",
|
|
75
75
|
adcp: "3.2.5",
|
|
76
76
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
77
|
-
generatedAt: "2026-10-
|
|
77
|
+
generatedAt: "2026-10-17T14:24:48.482Z"
|
|
78
78
|
};
|
|
79
79
|
function getAdcpVersion() {
|
|
80
80
|
return ADCP_VERSION;
|
package/docs/TYPE-SUMMARY.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AdCP Type Summary
|
|
2
2
|
|
|
3
|
-
> Generated at: 2026-10-
|
|
4
|
-
> @adcp/sdk v15.9.
|
|
3
|
+
> Generated at: 2026-10-17
|
|
4
|
+
> @adcp/sdk v15.9.5
|
|
5
5
|
|
|
6
6
|
Curated reference of the types that matter for using the AdCP client. For full generated types see `src/lib/types/tools.generated.ts` and `src/lib/types/core.generated.ts`.
|
|
7
7
|
|
|
@@ -187,6 +187,40 @@ await comply(agentUrl, {
|
|
|
187
187
|
});
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
+
**Capabilities served at a newer release.** A 3.0 pin sends only
|
|
191
|
+
`adcp_major_version: 3`, so a conformant agent may serve and echo its highest
|
|
192
|
+
3.x release in `get_adcp_capabilities` (versioning spec, "Server echoes"). The
|
|
193
|
+
runner validates that one response against the echoed release when the echo is
|
|
194
|
+
the pin's major, is listed in the response's own `adcp.supported_versions`, and
|
|
195
|
+
has a schema root. That covers discovery's `capabilities_response_schema_invalid`
|
|
196
|
+
notices, `getAdcpCapabilities()` and every storyboard `response_schema` check on
|
|
197
|
+
`get_adcp_capabilities`, even with `schemaRoot` set for the pin. Otherwise it
|
|
198
|
+
validates strictly against the pin. Every other task's response, storyboard
|
|
199
|
+
selection, the run's `adcp_version` and grading stay on the pin.
|
|
200
|
+
|
|
201
|
+
The echoed release's schemas come from the SDK's bundle by default. A grader
|
|
202
|
+
that ships its own roots per release can supply them with
|
|
203
|
+
`servedReleaseSchemaRoots` (on `comply()`, `runStoryboard()` and
|
|
204
|
+
`runStoryboardStep()`), keyed by AdCP version:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
await comply(agentUrl, {
|
|
208
|
+
version: '3.0.27',
|
|
209
|
+
complianceDir: '/app/dist/compliance/3.0.27',
|
|
210
|
+
schemaRoot: '/app/dist/schemas/3.0.27',
|
|
211
|
+
servedReleaseSchemaRoots: {
|
|
212
|
+
'3.1.29': '/app/dist/schemas/3.1.29',
|
|
213
|
+
'3.2.5': '/app/dist/schemas/3.2.5',
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Those roots are used only for that capabilities validation. Each one is checked
|
|
219
|
+
against its key once per process, and a mismatched or missing root throws
|
|
220
|
+
before the run starts. Callers that validate outside `comply()` and the runner
|
|
221
|
+
can scope the same map with `withServedReleaseSchemaRoots(roots, fn)` from
|
|
222
|
+
`@adcp/sdk/testing`.
|
|
223
|
+
|
|
190
224
|
**Multi-agent storyboards under `comply()`.** `comply()` grades one agent, so
|
|
191
225
|
storyboards that declare `requires: [multi_agent]` (for example the
|
|
192
226
|
governance-aware seller scenarios) skip with `requirement_unmet` and cap their
|
package/docs/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Ad Context Protocol (AdCP)
|
|
2
2
|
|
|
3
|
-
> Generated at: 2026-10-
|
|
4
|
-
> Library: @adcp/sdk v15.9.
|
|
3
|
+
> Generated at: 2026-10-17
|
|
4
|
+
> Library: @adcp/sdk v15.9.5
|
|
5
5
|
> AdCP major version: 3
|
|
6
6
|
> Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
|
|
7
7
|
> Note: the `Library` stamp reflects the package.json version at doc-generation time. The narrative below describes the surface that lands on the next-published minor — including any 6.7 helpers documented here ahead of the release tag.
|