@adcp/sdk 16.2.0 → 16.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/AGENTS.md +2 -0
  2. package/dist/lib/adapters/version/3.1/assignments.d.mts +12 -0
  3. package/dist/lib/adapters/version/3.1/assignments.d.ts +12 -0
  4. package/dist/lib/adapters/version/3.1/assignments.js +67 -0
  5. package/dist/lib/adapters/version/3.1/assignments.mjs +43 -0
  6. package/dist/lib/adapters/version/3.1/bidding.d.mts +3 -0
  7. package/dist/lib/adapters/version/3.1/bidding.d.ts +3 -0
  8. package/dist/lib/adapters/version/3.1/bidding.js +115 -0
  9. package/dist/lib/adapters/version/3.1/bidding.mjs +90 -0
  10. package/dist/lib/adapters/version/3.1/delivery.d.mts +7 -0
  11. package/dist/lib/adapters/version/3.1/delivery.d.ts +7 -0
  12. package/dist/lib/adapters/version/3.1/delivery.js +78 -0
  13. package/dist/lib/adapters/version/3.1/delivery.mjs +54 -0
  14. package/dist/lib/adapters/version/3.1/index.d.mts +3 -0
  15. package/dist/lib/adapters/version/3.1/index.d.ts +3 -0
  16. package/dist/lib/adapters/version/3.1/index.js +36 -0
  17. package/dist/lib/adapters/version/3.1/index.mjs +12 -0
  18. package/dist/lib/adapters/version/index.d.mts +59 -7
  19. package/dist/lib/adapters/version/index.d.ts +59 -7
  20. package/dist/lib/adapters/version/index.js +51 -2
  21. package/dist/lib/adapters/version/index.mjs +49 -1
  22. package/dist/lib/adapters/version/negotiate.d.mts +71 -0
  23. package/dist/lib/adapters/version/negotiate.d.ts +71 -0
  24. package/dist/lib/adapters/version/negotiate.js +101 -0
  25. package/dist/lib/adapters/version/negotiate.mjs +73 -0
  26. package/dist/lib/adapters/version/schema-projection.d.mts +33 -0
  27. package/dist/lib/adapters/version/schema-projection.d.ts +33 -0
  28. package/dist/lib/adapters/version/schema-projection.js +294 -0
  29. package/dist/lib/adapters/version/schema-projection.mjs +269 -0
  30. package/dist/lib/adapters/version/translate.d.mts +122 -0
  31. package/dist/lib/adapters/version/translate.d.ts +122 -0
  32. package/dist/lib/adapters/version/translate.js +169 -0
  33. package/dist/lib/adapters/version/translate.mjs +141 -0
  34. package/dist/lib/adapters/version/types.d.mts +51 -10
  35. package/dist/lib/adapters/version/types.d.ts +51 -10
  36. package/dist/lib/core/AgentClient.d.mts +1 -1
  37. package/dist/lib/core/AgentClient.d.ts +1 -1
  38. package/dist/lib/core/AgentClient.js +17 -1
  39. package/dist/lib/core/AgentClient.mjs +17 -1
  40. package/dist/lib/core/ConversationTypes.d.mts +7 -0
  41. package/dist/lib/core/ConversationTypes.d.ts +7 -0
  42. package/dist/lib/core/SingleAgentClient.d.mts +82 -0
  43. package/dist/lib/core/SingleAgentClient.d.ts +82 -0
  44. package/dist/lib/core/SingleAgentClient.js +336 -15
  45. package/dist/lib/core/SingleAgentClient.mjs +350 -17
  46. package/dist/lib/core/TaskExecutor.d.mts +1 -1
  47. package/dist/lib/core/TaskExecutor.d.ts +1 -1
  48. package/dist/lib/core/TaskExecutor.js +182 -31
  49. package/dist/lib/core/TaskExecutor.mjs +183 -32
  50. package/dist/lib/core/account-reduction.d.mts +36 -0
  51. package/dist/lib/core/account-reduction.d.ts +36 -0
  52. package/dist/lib/core/account-reduction.js +127 -0
  53. package/dist/lib/core/account-reduction.mjs +98 -0
  54. package/dist/lib/core/buyer-account-registry.d.mts +52 -0
  55. package/dist/lib/core/buyer-account-registry.d.ts +52 -0
  56. package/dist/lib/core/buyer-account-registry.js +142 -6
  57. package/dist/lib/core/buyer-account-registry.mjs +142 -6
  58. package/dist/lib/errors/index.d.mts +34 -0
  59. package/dist/lib/errors/index.d.ts +34 -0
  60. package/dist/lib/errors/index.js +11 -0
  61. package/dist/lib/errors/index.mjs +10 -0
  62. package/dist/lib/index.d.mts +1 -1
  63. package/dist/lib/index.d.ts +1 -1
  64. package/dist/lib/index.js +2 -0
  65. package/dist/lib/index.mjs +2 -0
  66. package/dist/lib/media-buy/action-contracts.js +4 -4
  67. package/dist/lib/media-buy/action-contracts.mjs +4 -4
  68. package/dist/lib/media-buy/action-types.d.mts +3 -2
  69. package/dist/lib/media-buy/action-types.d.ts +3 -2
  70. package/dist/lib/media-buy/compatibility.d.mts +1 -0
  71. package/dist/lib/media-buy/compatibility.d.ts +1 -0
  72. package/dist/lib/media-buy/compatibility.js +33 -10
  73. package/dist/lib/media-buy/compatibility.mjs +32 -14
  74. package/dist/lib/media-buy/update-fields.generated.d.mts +3 -2
  75. package/dist/lib/media-buy/update-fields.generated.d.ts +3 -2
  76. package/dist/lib/negotiation/buyer.js +11 -5
  77. package/dist/lib/negotiation/buyer.mjs +11 -5
  78. package/dist/lib/negotiation/types.d.mts +4 -2
  79. package/dist/lib/negotiation/types.d.ts +4 -2
  80. package/dist/lib/negotiation/verification.d.mts +15 -6
  81. package/dist/lib/negotiation/verification.d.ts +15 -6
  82. package/dist/lib/negotiation/verification.js +146 -27
  83. package/dist/lib/negotiation/verification.mjs +146 -28
  84. package/dist/lib/negotiation/version.d.mts +6 -0
  85. package/dist/lib/negotiation/version.d.ts +6 -0
  86. package/dist/lib/negotiation/version.js +60 -0
  87. package/dist/lib/negotiation/version.mjs +33 -0
  88. package/dist/lib/registry/types.generated.d.mts +1 -1
  89. package/dist/lib/registry/types.generated.d.ts +1 -1
  90. package/dist/lib/server/create-adcp-server.d.mts +21 -0
  91. package/dist/lib/server/create-adcp-server.d.ts +21 -0
  92. package/dist/lib/server/create-adcp-server.js +98 -16
  93. package/dist/lib/server/create-adcp-server.mjs +84 -2
  94. package/dist/lib/server/error-arm-tools.d.mts +10 -10
  95. package/dist/lib/server/error-arm-tools.d.ts +10 -10
  96. package/dist/lib/server/error-arm-tools.js +22 -58
  97. package/dist/lib/server/error-arm-tools.mjs +30 -65
  98. package/dist/lib/server/index.d.mts +1 -1
  99. package/dist/lib/server/index.d.ts +1 -1
  100. package/dist/lib/storage/interfaces.d.mts +2 -0
  101. package/dist/lib/storage/interfaces.d.ts +2 -0
  102. package/dist/lib/testing/compliance/comply.js +17 -0
  103. package/dist/lib/testing/compliance/comply.mjs +17 -0
  104. package/dist/lib/testing/index.d.mts +3 -0
  105. package/dist/lib/testing/index.d.ts +3 -0
  106. package/dist/lib/testing/index.js +44 -2
  107. package/dist/lib/testing/index.mjs +42 -0
  108. package/dist/lib/testing/storyboard/collection-selection.d.mts +259 -0
  109. package/dist/lib/testing/storyboard/collection-selection.d.ts +259 -0
  110. package/dist/lib/testing/storyboard/collection-selection.js +384 -0
  111. package/dist/lib/testing/storyboard/collection-selection.mjs +348 -0
  112. package/dist/lib/testing/storyboard/context.js +12 -6
  113. package/dist/lib/testing/storyboard/context.mjs +12 -6
  114. package/dist/lib/testing/storyboard/fixture-resolution.d.mts +39 -1
  115. package/dist/lib/testing/storyboard/fixture-resolution.d.ts +39 -1
  116. package/dist/lib/testing/storyboard/fixture-resolution.js +216 -12
  117. package/dist/lib/testing/storyboard/fixture-resolution.mjs +218 -12
  118. package/dist/lib/testing/storyboard/index.d.mts +9 -2
  119. package/dist/lib/testing/storyboard/index.d.ts +9 -2
  120. package/dist/lib/testing/storyboard/index.js +51 -2
  121. package/dist/lib/testing/storyboard/index.mjs +49 -1
  122. package/dist/lib/testing/storyboard/prepared-fixtures.d.mts +471 -0
  123. package/dist/lib/testing/storyboard/prepared-fixtures.d.ts +471 -0
  124. package/dist/lib/testing/storyboard/prepared-fixtures.js +434 -0
  125. package/dist/lib/testing/storyboard/prepared-fixtures.mjs +389 -0
  126. package/dist/lib/testing/storyboard/protected-context.d.mts +127 -0
  127. package/dist/lib/testing/storyboard/protected-context.d.ts +127 -0
  128. package/dist/lib/testing/storyboard/protected-context.js +301 -0
  129. package/dist/lib/testing/storyboard/protected-context.mjs +267 -0
  130. package/dist/lib/testing/storyboard/rejection-hints.js +13 -4
  131. package/dist/lib/testing/storyboard/rejection-hints.mjs +13 -4
  132. package/dist/lib/testing/storyboard/runner.d.mts +24 -0
  133. package/dist/lib/testing/storyboard/runner.d.ts +24 -0
  134. package/dist/lib/testing/storyboard/runner.js +1061 -105
  135. package/dist/lib/testing/storyboard/runner.mjs +1075 -106
  136. package/dist/lib/testing/storyboard/seeding.d.mts +15 -1
  137. package/dist/lib/testing/storyboard/seeding.d.ts +15 -1
  138. package/dist/lib/testing/storyboard/seeding.js +272 -12
  139. package/dist/lib/testing/storyboard/seeding.mjs +274 -13
  140. package/dist/lib/testing/storyboard/types.d.mts +207 -10
  141. package/dist/lib/testing/storyboard/types.d.ts +207 -10
  142. package/dist/lib/testing/storyboard/types.js +1 -1
  143. package/dist/lib/testing/storyboard/types.mjs +1 -1
  144. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  145. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  146. package/dist/lib/testing/storyboard/validations.js +95 -0
  147. package/dist/lib/testing/storyboard/validations.mjs +95 -0
  148. package/dist/lib/validation/bundled-schema-store.js +5 -0
  149. package/dist/lib/validation/bundled-schema-store.mjs +4 -0
  150. package/dist/lib/validation/schema-loader.js +19 -2
  151. package/dist/lib/validation/schema-loader.mjs +22 -3
  152. package/dist/lib/version.d.mts +3 -3
  153. package/dist/lib/version.d.ts +3 -3
  154. package/dist/lib/version.js +3 -3
  155. package/dist/lib/version.mjs +3 -3
  156. package/docs/TYPE-SUMMARY.md +2 -2
  157. package/docs/guides/COLLECTION-FIXTURE-FOUNDATION.md +850 -0
  158. package/docs/guides/PROPOSAL-TERMS-VERIFICATION.md +66 -0
  159. package/docs/llms.txt +4 -3
  160. package/docs/migration-14.x-rc-worksheet.md +4 -4
  161. package/package.json +1 -1
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var schema_projection_exports = {};
20
+ __export(schema_projection_exports, {
21
+ projectToolPayload: () => projectToolPayload,
22
+ releaseDefinesTool: () => releaseDefinesTool
23
+ });
24
+ module.exports = __toCommonJS(schema_projection_exports);
25
+ var import_schema_loader = require('../../validation/schema-loader.js');
26
+ const OMIT = /* @__PURE__ */ Symbol("omit");
27
+ const MAX_DEPTH = 64;
28
+ const SCHEMA_HOST = "https://adcontextprotocol.org";
29
+ function isObject(value) {
30
+ return value !== null && typeof value === "object" && !Array.isArray(value);
31
+ }
32
+ function absoluteBase(id) {
33
+ if (typeof id !== "string" || id.length === 0) return `${SCHEMA_HOST}/schemas/unknown/root.json`;
34
+ if (id.startsWith("/")) return `${SCHEMA_HOST}${id}`;
35
+ return id;
36
+ }
37
+ function documentFor(version, ref) {
38
+ let url;
39
+ try {
40
+ url = new URL(ref);
41
+ } catch {
42
+ return void 0;
43
+ }
44
+ const match = /^\/schemas\/[^/]+\/(.+)$/.exec(url.pathname);
45
+ if (!match?.[1]) return void 0;
46
+ const resolved = (0, import_schema_loader.getSchemaDocumentByRef)(match[1], version);
47
+ if (!resolved) return void 0;
48
+ return { root: resolved.schema, base: url.origin + url.pathname, version };
49
+ }
50
+ function pointer(root, fragment) {
51
+ if (fragment === "" || fragment === "/") return root;
52
+ let current = root;
53
+ for (const encoded of fragment.replace(/^\//, "").split("/")) {
54
+ if (!isObject(current)) return void 0;
55
+ current = current[decodeURIComponent(encoded).replace(/~1/g, "/").replace(/~0/g, "~")];
56
+ }
57
+ return isObject(current) ? current : void 0;
58
+ }
59
+ function resolveRef(node, depth) {
60
+ let current = node;
61
+ for (let hop = 0; hop < 16 && depth + hop < MAX_DEPTH; hop++) {
62
+ const ref = current.schema.$ref;
63
+ if (typeof ref !== "string") return current;
64
+ if (ref.startsWith("#")) {
65
+ const target2 = pointer(current.doc.root, ref.slice(1));
66
+ if (!target2) return current;
67
+ current = { schema: target2, doc: current.doc };
68
+ continue;
69
+ }
70
+ let absolute;
71
+ try {
72
+ absolute = new URL(ref, current.doc.base);
73
+ } catch {
74
+ return current;
75
+ }
76
+ const doc = documentFor(current.doc.version, absolute.origin + absolute.pathname);
77
+ if (!doc) return current;
78
+ const target = pointer(doc.root, absolute.hash.replace(/^#/, ""));
79
+ if (!target) return current;
80
+ current = { schema: target, doc };
81
+ }
82
+ return current;
83
+ }
84
+ function child(node, value) {
85
+ return isObject(value) ? { schema: value, doc: node.doc } : void 0;
86
+ }
87
+ function discriminatorMatch(node, value, depth) {
88
+ if (!isObject(value)) return void 0;
89
+ const resolved = resolveRef(node, depth);
90
+ const properties = resolved.schema.properties;
91
+ if (!isObject(properties)) return void 0;
92
+ let found = false;
93
+ for (const [key, propertySchema] of Object.entries(properties)) {
94
+ if (!isObject(propertySchema)) continue;
95
+ const prop = resolveRef({ schema: propertySchema, doc: resolved.doc }, depth + 1).schema;
96
+ if (!Object.hasOwn(prop, "const")) continue;
97
+ found = true;
98
+ if (!Object.hasOwn(value, key) || value[key] !== prop.const) return false;
99
+ }
100
+ return found ? true : void 0;
101
+ }
102
+ function expand(node, value, depth = 0) {
103
+ if (depth > MAX_DEPTH) return { nodes: [], unmatchedVariant: false };
104
+ const resolved = resolveRef(node, depth);
105
+ const nodes = [resolved];
106
+ let unmatchedVariant = false;
107
+ const add = (expansion) => {
108
+ nodes.push(...expansion.nodes);
109
+ unmatchedVariant ||= expansion.unmatchedVariant;
110
+ };
111
+ for (const keyword of ["allOf"]) {
112
+ const branches = resolved.schema[keyword];
113
+ if (!Array.isArray(branches)) continue;
114
+ for (const branch of branches) {
115
+ const branchNode = child(resolved, branch);
116
+ if (branchNode) add(expand(branchNode, value, depth + 1));
117
+ }
118
+ }
119
+ for (const keyword of ["then", "else"]) {
120
+ const branchNode = child(resolved, resolved.schema[keyword]);
121
+ if (branchNode) add(expand(branchNode, value, depth + 1));
122
+ }
123
+ for (const keyword of ["oneOf", "anyOf"]) {
124
+ const branches = resolved.schema[keyword];
125
+ if (!Array.isArray(branches)) continue;
126
+ const branchNodes = branches.map((branch) => child(resolved, branch)).filter((b) => !!b);
127
+ const matches = branchNodes.map((branch) => discriminatorMatch(branch, value, depth + 1));
128
+ const matched = branchNodes.filter((_, index) => matches[index] === true);
129
+ const discriminated = matches.some((match) => match !== void 0);
130
+ if (discriminated && matched.length === 0 && matches.every((match) => match === false)) unmatchedVariant = true;
131
+ for (const branch of matched.length > 0 ? matched : branchNodes) add(expand(branch, value, depth + 1));
132
+ }
133
+ return { nodes, unmatchedVariant };
134
+ }
135
+ function allowedScalars(nodes) {
136
+ let values;
137
+ for (const { schema } of nodes) {
138
+ if (Array.isArray(schema.enum)) values = [...values ?? [], ...schema.enum];
139
+ if (Object.hasOwn(schema, "const")) values = [...values ?? [], schema.const];
140
+ }
141
+ return values;
142
+ }
143
+ function hasScalarConstraint(nodes) {
144
+ return nodes.some(({ schema }) => Array.isArray(schema.enum) || Object.hasOwn(schema, "const"));
145
+ }
146
+ function scalarType(value) {
147
+ if (value === null) return "null";
148
+ if (typeof value === "number") return Number.isInteger(value) ? "integer" : "number";
149
+ return typeof value;
150
+ }
151
+ function acceptsScalarOpenly(nodes, value) {
152
+ const type = scalarType(value);
153
+ return nodes.some(({ schema }) => {
154
+ if (Array.isArray(schema.enum) || Object.hasOwn(schema, "const")) return false;
155
+ const declared = Array.isArray(schema.type) ? schema.type : schema.type === void 0 ? [] : [schema.type];
156
+ return declared.includes(type) || type === "integer" && declared.includes("number");
157
+ });
158
+ }
159
+ function indexProperties(nodes) {
160
+ const index = { declares: false, schemas: /* @__PURE__ */ new Map(), patterns: [], additional: [] };
161
+ for (const node of nodes) {
162
+ const { properties, patternProperties, additionalProperties } = node.schema;
163
+ if (isObject(properties)) {
164
+ index.declares = true;
165
+ for (const [key, value] of Object.entries(properties)) {
166
+ const propertyNode = child(node, value);
167
+ if (!propertyNode) continue;
168
+ index.schemas.set(key, [...index.schemas.get(key) ?? [], propertyNode]);
169
+ }
170
+ }
171
+ if (isObject(patternProperties)) {
172
+ index.declares = true;
173
+ for (const [pattern, value] of Object.entries(patternProperties)) {
174
+ const propertyNode = child(node, value);
175
+ if (!propertyNode) continue;
176
+ try {
177
+ index.patterns.push({ pattern: new RegExp(pattern, "u"), node: propertyNode });
178
+ } catch {
179
+ }
180
+ }
181
+ }
182
+ const additionalNode = child(node, additionalProperties);
183
+ if (additionalNode) index.additional.push(additionalNode);
184
+ }
185
+ return index;
186
+ }
187
+ function schemasForKey(index, key) {
188
+ const declared = index.schemas.get(key);
189
+ const patterned = index.patterns.filter(({ pattern }) => pattern.test(key)).map(({ node }) => node);
190
+ if (declared || patterned.length > 0) return [...declared ?? [], ...patterned];
191
+ return void 0;
192
+ }
193
+ function nonEmpty(values) {
194
+ return values.length > 0 ? values : void 0;
195
+ }
196
+ function joinPath(path, key) {
197
+ return path ? `${path}.${key}` : key;
198
+ }
199
+ function project(value, source, target, path, dropped, depth) {
200
+ if (depth > MAX_DEPTH || source.length === 0 || target.length === 0) return value;
201
+ const sourceExpansions = source.map((node) => expand(node, value, depth));
202
+ const targetExpansions = target.map((node) => expand(node, value, depth));
203
+ const sourceNodes = sourceExpansions.flatMap((e) => e.nodes);
204
+ const targetNodes = targetExpansions.flatMap((e) => e.nodes);
205
+ if (targetExpansions.some((e) => e.unmatchedVariant) && !sourceExpansions.some((e) => e.unmatchedVariant) && path !== "") {
206
+ dropped.push({ path, kind: "variant" });
207
+ return OMIT;
208
+ }
209
+ if (!isObject(value) && !Array.isArray(value)) {
210
+ if (!hasScalarConstraint(targetNodes) || acceptsScalarOpenly(targetNodes, value)) return value;
211
+ const targetAllowed = allowedScalars(targetNodes) ?? [];
212
+ if (targetAllowed.some((allowed) => Object.is(allowed, value))) return value;
213
+ const sourceAllowed = allowedScalars(sourceNodes);
214
+ if (sourceAllowed?.some((allowed) => Object.is(allowed, value))) {
215
+ dropped.push({ path, kind: "enum_value" });
216
+ return OMIT;
217
+ }
218
+ return value;
219
+ }
220
+ if (Array.isArray(value)) {
221
+ const sourceItems = sourceNodes.map((node) => child(node, node.schema.items)).filter((n) => !!n);
222
+ const targetItems = targetNodes.map((node) => child(node, node.schema.items)).filter((n) => !!n);
223
+ if (sourceItems.length === 0 || targetItems.length === 0) return value;
224
+ let changed2 = false;
225
+ const items = [];
226
+ value.forEach((item, index) => {
227
+ const projected = project(item, sourceItems, targetItems, `${path}[${index}]`, dropped, depth + 1);
228
+ if (projected !== item) changed2 = true;
229
+ if (projected !== OMIT) items.push(projected);
230
+ });
231
+ return changed2 ? items : value;
232
+ }
233
+ const sourceIndex = indexProperties(sourceNodes);
234
+ const targetIndex = indexProperties(targetNodes);
235
+ let changed = false;
236
+ const out = {};
237
+ for (const [key, entry] of Object.entries(value)) {
238
+ if (entry === void 0) {
239
+ out[key] = entry;
240
+ continue;
241
+ }
242
+ const sourceSchemas = schemasForKey(sourceIndex, key) ?? nonEmpty(sourceIndex.additional);
243
+ const targetSchemas = schemasForKey(targetIndex, key) ?? nonEmpty(targetIndex.additional);
244
+ const entryPath = joinPath(path, key);
245
+ if (sourceIndex.declares && targetIndex.declares && schemasForKey(sourceIndex, key) && !targetSchemas) {
246
+ dropped.push({ path: entryPath, kind: "field" });
247
+ changed = true;
248
+ continue;
249
+ }
250
+ if (!sourceSchemas?.length || !targetSchemas?.length) {
251
+ out[key] = entry;
252
+ continue;
253
+ }
254
+ const projected = project(entry, sourceSchemas, targetSchemas, entryPath, dropped, depth + 1);
255
+ if (projected === OMIT) {
256
+ changed = true;
257
+ continue;
258
+ }
259
+ if (projected !== entry) changed = true;
260
+ out[key] = projected;
261
+ }
262
+ return changed ? out : value;
263
+ }
264
+ function toolRoot(toolName, direction, version) {
265
+ let document;
266
+ try {
267
+ document = (0, import_schema_loader.getToolSchemaDocument)(toolName, direction, version);
268
+ } catch {
269
+ return void 0;
270
+ }
271
+ if (!document) return void 0;
272
+ const root = document.schema;
273
+ return { schema: root, doc: { root, base: absoluteBase(root.$id), version } };
274
+ }
275
+ function projectToolPayload(toolName, direction, payload, fromVersion, toVersion) {
276
+ const source = toolRoot(toolName, direction, fromVersion);
277
+ const target = toolRoot(toolName, direction, toVersion);
278
+ if (!source || !target || !isObject(payload)) return { value: payload, dropped: [] };
279
+ const dropped = [];
280
+ const projected = project(payload, [source], [target], "", dropped, 0);
281
+ return { value: projected === OMIT ? payload : projected, dropped };
282
+ }
283
+ function releaseDefinesTool(toolName, version) {
284
+ try {
285
+ return (0, import_schema_loader.getToolSchemaDocument)(toolName, "request", version) !== void 0;
286
+ } catch {
287
+ return false;
288
+ }
289
+ }
290
+ // Annotate the CommonJS export names for ESM import in node:
291
+ 0 && (module.exports = {
292
+ projectToolPayload,
293
+ releaseDefinesTool
294
+ });
@@ -0,0 +1,269 @@
1
+ import { getSchemaDocumentByRef, getToolSchemaDocument } from "../../validation/schema-loader.mjs";
2
+ const OMIT = /* @__PURE__ */ Symbol("omit");
3
+ const MAX_DEPTH = 64;
4
+ const SCHEMA_HOST = "https://adcontextprotocol.org";
5
+ function isObject(value) {
6
+ return value !== null && typeof value === "object" && !Array.isArray(value);
7
+ }
8
+ function absoluteBase(id) {
9
+ if (typeof id !== "string" || id.length === 0) return `${SCHEMA_HOST}/schemas/unknown/root.json`;
10
+ if (id.startsWith("/")) return `${SCHEMA_HOST}${id}`;
11
+ return id;
12
+ }
13
+ function documentFor(version, ref) {
14
+ let url;
15
+ try {
16
+ url = new URL(ref);
17
+ } catch {
18
+ return void 0;
19
+ }
20
+ const match = /^\/schemas\/[^/]+\/(.+)$/.exec(url.pathname);
21
+ if (!match?.[1]) return void 0;
22
+ const resolved = getSchemaDocumentByRef(match[1], version);
23
+ if (!resolved) return void 0;
24
+ return { root: resolved.schema, base: url.origin + url.pathname, version };
25
+ }
26
+ function pointer(root, fragment) {
27
+ if (fragment === "" || fragment === "/") return root;
28
+ let current = root;
29
+ for (const encoded of fragment.replace(/^\//, "").split("/")) {
30
+ if (!isObject(current)) return void 0;
31
+ current = current[decodeURIComponent(encoded).replace(/~1/g, "/").replace(/~0/g, "~")];
32
+ }
33
+ return isObject(current) ? current : void 0;
34
+ }
35
+ function resolveRef(node, depth) {
36
+ let current = node;
37
+ for (let hop = 0; hop < 16 && depth + hop < MAX_DEPTH; hop++) {
38
+ const ref = current.schema.$ref;
39
+ if (typeof ref !== "string") return current;
40
+ if (ref.startsWith("#")) {
41
+ const target2 = pointer(current.doc.root, ref.slice(1));
42
+ if (!target2) return current;
43
+ current = { schema: target2, doc: current.doc };
44
+ continue;
45
+ }
46
+ let absolute;
47
+ try {
48
+ absolute = new URL(ref, current.doc.base);
49
+ } catch {
50
+ return current;
51
+ }
52
+ const doc = documentFor(current.doc.version, absolute.origin + absolute.pathname);
53
+ if (!doc) return current;
54
+ const target = pointer(doc.root, absolute.hash.replace(/^#/, ""));
55
+ if (!target) return current;
56
+ current = { schema: target, doc };
57
+ }
58
+ return current;
59
+ }
60
+ function child(node, value) {
61
+ return isObject(value) ? { schema: value, doc: node.doc } : void 0;
62
+ }
63
+ function discriminatorMatch(node, value, depth) {
64
+ if (!isObject(value)) return void 0;
65
+ const resolved = resolveRef(node, depth);
66
+ const properties = resolved.schema.properties;
67
+ if (!isObject(properties)) return void 0;
68
+ let found = false;
69
+ for (const [key, propertySchema] of Object.entries(properties)) {
70
+ if (!isObject(propertySchema)) continue;
71
+ const prop = resolveRef({ schema: propertySchema, doc: resolved.doc }, depth + 1).schema;
72
+ if (!Object.hasOwn(prop, "const")) continue;
73
+ found = true;
74
+ if (!Object.hasOwn(value, key) || value[key] !== prop.const) return false;
75
+ }
76
+ return found ? true : void 0;
77
+ }
78
+ function expand(node, value, depth = 0) {
79
+ if (depth > MAX_DEPTH) return { nodes: [], unmatchedVariant: false };
80
+ const resolved = resolveRef(node, depth);
81
+ const nodes = [resolved];
82
+ let unmatchedVariant = false;
83
+ const add = (expansion) => {
84
+ nodes.push(...expansion.nodes);
85
+ unmatchedVariant ||= expansion.unmatchedVariant;
86
+ };
87
+ for (const keyword of ["allOf"]) {
88
+ const branches = resolved.schema[keyword];
89
+ if (!Array.isArray(branches)) continue;
90
+ for (const branch of branches) {
91
+ const branchNode = child(resolved, branch);
92
+ if (branchNode) add(expand(branchNode, value, depth + 1));
93
+ }
94
+ }
95
+ for (const keyword of ["then", "else"]) {
96
+ const branchNode = child(resolved, resolved.schema[keyword]);
97
+ if (branchNode) add(expand(branchNode, value, depth + 1));
98
+ }
99
+ for (const keyword of ["oneOf", "anyOf"]) {
100
+ const branches = resolved.schema[keyword];
101
+ if (!Array.isArray(branches)) continue;
102
+ const branchNodes = branches.map((branch) => child(resolved, branch)).filter((b) => !!b);
103
+ const matches = branchNodes.map((branch) => discriminatorMatch(branch, value, depth + 1));
104
+ const matched = branchNodes.filter((_, index) => matches[index] === true);
105
+ const discriminated = matches.some((match) => match !== void 0);
106
+ if (discriminated && matched.length === 0 && matches.every((match) => match === false)) unmatchedVariant = true;
107
+ for (const branch of matched.length > 0 ? matched : branchNodes) add(expand(branch, value, depth + 1));
108
+ }
109
+ return { nodes, unmatchedVariant };
110
+ }
111
+ function allowedScalars(nodes) {
112
+ let values;
113
+ for (const { schema } of nodes) {
114
+ if (Array.isArray(schema.enum)) values = [...values ?? [], ...schema.enum];
115
+ if (Object.hasOwn(schema, "const")) values = [...values ?? [], schema.const];
116
+ }
117
+ return values;
118
+ }
119
+ function hasScalarConstraint(nodes) {
120
+ return nodes.some(({ schema }) => Array.isArray(schema.enum) || Object.hasOwn(schema, "const"));
121
+ }
122
+ function scalarType(value) {
123
+ if (value === null) return "null";
124
+ if (typeof value === "number") return Number.isInteger(value) ? "integer" : "number";
125
+ return typeof value;
126
+ }
127
+ function acceptsScalarOpenly(nodes, value) {
128
+ const type = scalarType(value);
129
+ return nodes.some(({ schema }) => {
130
+ if (Array.isArray(schema.enum) || Object.hasOwn(schema, "const")) return false;
131
+ const declared = Array.isArray(schema.type) ? schema.type : schema.type === void 0 ? [] : [schema.type];
132
+ return declared.includes(type) || type === "integer" && declared.includes("number");
133
+ });
134
+ }
135
+ function indexProperties(nodes) {
136
+ const index = { declares: false, schemas: /* @__PURE__ */ new Map(), patterns: [], additional: [] };
137
+ for (const node of nodes) {
138
+ const { properties, patternProperties, additionalProperties } = node.schema;
139
+ if (isObject(properties)) {
140
+ index.declares = true;
141
+ for (const [key, value] of Object.entries(properties)) {
142
+ const propertyNode = child(node, value);
143
+ if (!propertyNode) continue;
144
+ index.schemas.set(key, [...index.schemas.get(key) ?? [], propertyNode]);
145
+ }
146
+ }
147
+ if (isObject(patternProperties)) {
148
+ index.declares = true;
149
+ for (const [pattern, value] of Object.entries(patternProperties)) {
150
+ const propertyNode = child(node, value);
151
+ if (!propertyNode) continue;
152
+ try {
153
+ index.patterns.push({ pattern: new RegExp(pattern, "u"), node: propertyNode });
154
+ } catch {
155
+ }
156
+ }
157
+ }
158
+ const additionalNode = child(node, additionalProperties);
159
+ if (additionalNode) index.additional.push(additionalNode);
160
+ }
161
+ return index;
162
+ }
163
+ function schemasForKey(index, key) {
164
+ const declared = index.schemas.get(key);
165
+ const patterned = index.patterns.filter(({ pattern }) => pattern.test(key)).map(({ node }) => node);
166
+ if (declared || patterned.length > 0) return [...declared ?? [], ...patterned];
167
+ return void 0;
168
+ }
169
+ function nonEmpty(values) {
170
+ return values.length > 0 ? values : void 0;
171
+ }
172
+ function joinPath(path, key) {
173
+ return path ? `${path}.${key}` : key;
174
+ }
175
+ function project(value, source, target, path, dropped, depth) {
176
+ if (depth > MAX_DEPTH || source.length === 0 || target.length === 0) return value;
177
+ const sourceExpansions = source.map((node) => expand(node, value, depth));
178
+ const targetExpansions = target.map((node) => expand(node, value, depth));
179
+ const sourceNodes = sourceExpansions.flatMap((e) => e.nodes);
180
+ const targetNodes = targetExpansions.flatMap((e) => e.nodes);
181
+ if (targetExpansions.some((e) => e.unmatchedVariant) && !sourceExpansions.some((e) => e.unmatchedVariant) && path !== "") {
182
+ dropped.push({ path, kind: "variant" });
183
+ return OMIT;
184
+ }
185
+ if (!isObject(value) && !Array.isArray(value)) {
186
+ if (!hasScalarConstraint(targetNodes) || acceptsScalarOpenly(targetNodes, value)) return value;
187
+ const targetAllowed = allowedScalars(targetNodes) ?? [];
188
+ if (targetAllowed.some((allowed) => Object.is(allowed, value))) return value;
189
+ const sourceAllowed = allowedScalars(sourceNodes);
190
+ if (sourceAllowed?.some((allowed) => Object.is(allowed, value))) {
191
+ dropped.push({ path, kind: "enum_value" });
192
+ return OMIT;
193
+ }
194
+ return value;
195
+ }
196
+ if (Array.isArray(value)) {
197
+ const sourceItems = sourceNodes.map((node) => child(node, node.schema.items)).filter((n) => !!n);
198
+ const targetItems = targetNodes.map((node) => child(node, node.schema.items)).filter((n) => !!n);
199
+ if (sourceItems.length === 0 || targetItems.length === 0) return value;
200
+ let changed2 = false;
201
+ const items = [];
202
+ value.forEach((item, index) => {
203
+ const projected = project(item, sourceItems, targetItems, `${path}[${index}]`, dropped, depth + 1);
204
+ if (projected !== item) changed2 = true;
205
+ if (projected !== OMIT) items.push(projected);
206
+ });
207
+ return changed2 ? items : value;
208
+ }
209
+ const sourceIndex = indexProperties(sourceNodes);
210
+ const targetIndex = indexProperties(targetNodes);
211
+ let changed = false;
212
+ const out = {};
213
+ for (const [key, entry] of Object.entries(value)) {
214
+ if (entry === void 0) {
215
+ out[key] = entry;
216
+ continue;
217
+ }
218
+ const sourceSchemas = schemasForKey(sourceIndex, key) ?? nonEmpty(sourceIndex.additional);
219
+ const targetSchemas = schemasForKey(targetIndex, key) ?? nonEmpty(targetIndex.additional);
220
+ const entryPath = joinPath(path, key);
221
+ if (sourceIndex.declares && targetIndex.declares && schemasForKey(sourceIndex, key) && !targetSchemas) {
222
+ dropped.push({ path: entryPath, kind: "field" });
223
+ changed = true;
224
+ continue;
225
+ }
226
+ if (!sourceSchemas?.length || !targetSchemas?.length) {
227
+ out[key] = entry;
228
+ continue;
229
+ }
230
+ const projected = project(entry, sourceSchemas, targetSchemas, entryPath, dropped, depth + 1);
231
+ if (projected === OMIT) {
232
+ changed = true;
233
+ continue;
234
+ }
235
+ if (projected !== entry) changed = true;
236
+ out[key] = projected;
237
+ }
238
+ return changed ? out : value;
239
+ }
240
+ function toolRoot(toolName, direction, version) {
241
+ let document;
242
+ try {
243
+ document = getToolSchemaDocument(toolName, direction, version);
244
+ } catch {
245
+ return void 0;
246
+ }
247
+ if (!document) return void 0;
248
+ const root = document.schema;
249
+ return { schema: root, doc: { root, base: absoluteBase(root.$id), version } };
250
+ }
251
+ function projectToolPayload(toolName, direction, payload, fromVersion, toVersion) {
252
+ const source = toolRoot(toolName, direction, fromVersion);
253
+ const target = toolRoot(toolName, direction, toVersion);
254
+ if (!source || !target || !isObject(payload)) return { value: payload, dropped: [] };
255
+ const dropped = [];
256
+ const projected = project(payload, [source], [target], "", dropped, 0);
257
+ return { value: projected === OMIT ? payload : projected, dropped };
258
+ }
259
+ function releaseDefinesTool(toolName, version) {
260
+ try {
261
+ return getToolSchemaDocument(toolName, "request", version) !== void 0;
262
+ } catch {
263
+ return false;
264
+ }
265
+ }
266
+ export {
267
+ projectToolPayload,
268
+ releaseDefinesTool
269
+ };
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Chained conversion between AdCP minor releases.
3
+ *
4
+ * Application code builds requests in the shape of the client's own release
5
+ * and reads responses in that shape. When the negotiated wire release is
6
+ * older, requests are converted down one minor at a time (3.2 → 3.1 → 3.0)
7
+ * and responses are converted back up the same steps in reverse.
8
+ *
9
+ * Each downward step runs the step's hand-written adapter (renames and moves)
10
+ * and then the schema projection, which removes whatever the older release
11
+ * cannot express and reports it. Upward steps run hand-written adapters only:
12
+ * a field an older seller sends that the newer release dropped is left for
13
+ * the caller rather than silently discarded.
14
+ */
15
+ import type { VersionAdapter, VersionDrift } from './types.mjs';
16
+ /**
17
+ * How to convert a request whose account key uses fields the target release
18
+ * cannot express (AdCP 3.2 added `operator_unit`, `currency` and `timezone`
19
+ * to the account natural key, and `countries` to brand references).
20
+ *
21
+ * - `'refuse'`: fail the call before it is sent.
22
+ * - `'reduce'`: send the older key when that is unambiguous, and refuse when
23
+ * it would merge accounts. The client claims each reduced key for the one
24
+ * buyer key it came from; a second buyer key that would reach the same
25
+ * seller account is refused with `account_identity_collision`, so no two
26
+ * buyer accounts ever share one seller account. Every reduction is reported
27
+ * as an `account_identity_reduced` drift entry.
28
+ */
29
+ export type AccountIdentityDowngrade = 'refuse' | 'reduce';
30
+ export interface TranslationStep {
31
+ /** Release the step converts from (downward) / to (upward). */
32
+ upper: string;
33
+ /** Release the step converts to (downward) / from (upward). Also the adapter key. */
34
+ lower: string;
35
+ /** Registry key for the step's hand-written adapters, e.g. `'3.1'`. */
36
+ key: string;
37
+ }
38
+ export interface RequestTranslation<T = unknown> {
39
+ params: T;
40
+ drifts: VersionDrift[];
41
+ /**
42
+ * Account-identity fields the target release cannot express, with the
43
+ * release line that introduced each. Under `'refuse'` the caller must not
44
+ * send the request when this is non-empty.
45
+ */
46
+ identityFields: Array<{
47
+ path: string;
48
+ introducedIn: string;
49
+ }>;
50
+ /**
51
+ * Fields of a mutating request the target release cannot express and whose
52
+ * loss would change what the seller does. The caller must not send the
53
+ * request when this is non-empty.
54
+ */
55
+ refusedFields: Array<{
56
+ path: string;
57
+ introducedIn: string;
58
+ }>;
59
+ }
60
+ export interface ResponseTranslation<T = unknown> {
61
+ data: T;
62
+ drifts: VersionDrift[];
63
+ }
64
+ type AdapterLookup = (key: string, toolName: string) => VersionAdapter | undefined;
65
+ /**
66
+ * Steps between two releases, newest first. Empty when both are on the same
67
+ * minor line or `lower` is not older than `upper`.
68
+ */
69
+ export declare function translationSteps(upperVersion: string, lowerVersion: string): TranslationStep[];
70
+ /**
71
+ * Convert a request from `fromVersion` down to `toVersion`.
72
+ *
73
+ * Returns the original params reference when nothing changes. Identity
74
+ * fields are always reported in `identityFields`; they are removed only under
75
+ * `'reduce'`, which is also the only policy that emits
76
+ * `account_identity_reduced` drift.
77
+ */
78
+ export declare function convertRequestToRelease<T>(toolName: string, params: T, options: {
79
+ fromVersion: string;
80
+ toVersion: string;
81
+ accountIdentity: AccountIdentityDowngrade;
82
+ adapters: AdapterLookup;
83
+ /** Whether the request changes seller state (`isMutatingTask`). */
84
+ mutating: boolean;
85
+ }): RequestTranslation<T>;
86
+ /**
87
+ * Convert a response from the wire release `fromVersion` up to the client's
88
+ * `toVersion` through each step's hand-written `adaptResponse`.
89
+ */
90
+ export declare function convertResponseFromRelease<T>(toolName: string, data: T, options: {
91
+ fromVersion: string;
92
+ toVersion: string;
93
+ adapters: AdapterLookup;
94
+ }): ResponseTranslation<T>;
95
+ /**
96
+ * Server side: convert an older buyer's request from the served release
97
+ * `fromVersion` up to the server's release `toVersion` through each step's
98
+ * `upgradeRequest`. Upward steps never remove fields.
99
+ */
100
+ export declare function convertRequestFromRelease<T>(toolName: string, params: T, options: {
101
+ fromVersion: string;
102
+ toVersion: string;
103
+ adapters: AdapterLookup;
104
+ }): {
105
+ params: T;
106
+ drifts: VersionDrift[];
107
+ };
108
+ /**
109
+ * Server side: convert a handler's response from the server's release
110
+ * `fromVersion` down to the served release `toVersion`. Each step runs the
111
+ * hand-written `downgradeResponse`, then removes and reports what the older
112
+ * release's response schema cannot express.
113
+ */
114
+ export declare function convertResponseToRelease<T>(toolName: string, data: T, options: {
115
+ fromVersion: string;
116
+ toVersion: string;
117
+ adapters: AdapterLookup;
118
+ }): {
119
+ data: T;
120
+ drifts: VersionDrift[];
121
+ };
122
+ export {};