@adcp/sdk 16.5.0 → 16.6.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 (236) hide show
  1. package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
  2. package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
  3. package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
  4. package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
  5. package/dist/lib/adapters/version/3.0/index.js +6 -0
  6. package/dist/lib/adapters/version/3.0/index.mjs +7 -1
  7. package/dist/lib/adapters/version/3.1/bidding.js +1 -1
  8. package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
  9. package/dist/lib/adapters/version/types.d.mts +5 -0
  10. package/dist/lib/adapters/version/types.d.ts +5 -0
  11. package/dist/lib/canonical-references/index.js +2 -0
  12. package/dist/lib/canonical-references/index.mjs +2 -0
  13. package/dist/lib/client/account-changes.d.mts +3 -1
  14. package/dist/lib/client/account-changes.d.ts +3 -1
  15. package/dist/lib/client/account-changes.js +22 -2
  16. package/dist/lib/client/account-changes.mjs +22 -2
  17. package/dist/lib/conformance/oracle.js +3 -2
  18. package/dist/lib/conformance/oracle.mjs +3 -2
  19. package/dist/lib/core/AgentClient.d.mts +165 -1
  20. package/dist/lib/core/AgentClient.d.ts +165 -1
  21. package/dist/lib/core/AgentClient.js +446 -8
  22. package/dist/lib/core/AgentClient.mjs +446 -8
  23. package/dist/lib/core/ConversationTypes.d.mts +8 -0
  24. package/dist/lib/core/ConversationTypes.d.ts +8 -0
  25. package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
  26. package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
  27. package/dist/lib/core/ProtocolResponseParser.js +28 -18
  28. package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
  29. package/dist/lib/core/ResponseValidator.js +1 -1
  30. package/dist/lib/core/ResponseValidator.mjs +1 -1
  31. package/dist/lib/core/SingleAgentClient.d.mts +116 -6
  32. package/dist/lib/core/SingleAgentClient.d.ts +116 -6
  33. package/dist/lib/core/SingleAgentClient.js +556 -84
  34. package/dist/lib/core/SingleAgentClient.mjs +545 -72
  35. package/dist/lib/core/TaskExecutor.d.mts +7 -0
  36. package/dist/lib/core/TaskExecutor.d.ts +7 -0
  37. package/dist/lib/core/TaskExecutor.js +23 -8
  38. package/dist/lib/core/TaskExecutor.mjs +23 -8
  39. package/dist/lib/core/task-status.d.mts +2 -0
  40. package/dist/lib/core/task-status.d.ts +2 -0
  41. package/dist/lib/core/task-status.js +11 -2
  42. package/dist/lib/core/task-status.mjs +9 -1
  43. package/dist/lib/errors/index.d.mts +22 -0
  44. package/dist/lib/errors/index.d.ts +22 -0
  45. package/dist/lib/errors/index.js +43 -0
  46. package/dist/lib/errors/index.mjs +42 -0
  47. package/dist/lib/identity-3.3/trust.d.mts +1 -4
  48. package/dist/lib/identity-3.3/trust.d.ts +1 -4
  49. package/dist/lib/identity-3.3/trust.js +34 -21
  50. package/dist/lib/identity-3.3/trust.mjs +34 -21
  51. package/dist/lib/identity-3.3/validation.js +5 -3
  52. package/dist/lib/identity-3.3/validation.mjs +6 -4
  53. package/dist/lib/index.d.mts +8 -54
  54. package/dist/lib/index.d.ts +8 -54
  55. package/dist/lib/index.js +15 -0
  56. package/dist/lib/index.mjs +11 -0
  57. package/dist/lib/media-buy/action-assessment.js +29 -3
  58. package/dist/lib/media-buy/action-assessment.mjs +32 -4
  59. package/dist/lib/media-buy/action-contracts.d.mts +3 -0
  60. package/dist/lib/media-buy/action-contracts.d.ts +3 -0
  61. package/dist/lib/media-buy/action-contracts.js +24 -1
  62. package/dist/lib/media-buy/action-contracts.mjs +22 -1
  63. package/dist/lib/media-buy/compatibility.js +6 -1
  64. package/dist/lib/media-buy/compatibility.mjs +6 -1
  65. package/dist/lib/media-buy/preflight.js +1 -1
  66. package/dist/lib/media-buy/preflight.mjs +3 -2
  67. package/dist/lib/media-buy/types.d.mts +6 -1
  68. package/dist/lib/media-buy/types.d.ts +6 -1
  69. package/dist/lib/protocols/mcp-modern.d.mts +2 -0
  70. package/dist/lib/protocols/mcp-modern.d.ts +2 -0
  71. package/dist/lib/protocols/mcp-modern.js +31 -5
  72. package/dist/lib/protocols/mcp-modern.mjs +31 -5
  73. package/dist/lib/protocols/mcp-scope.d.mts +6 -1
  74. package/dist/lib/protocols/mcp-scope.d.ts +6 -1
  75. package/dist/lib/protocols/mcp-scope.js +25 -3
  76. package/dist/lib/protocols/mcp-scope.mjs +24 -3
  77. package/dist/lib/protocols/mcp.js +12 -6
  78. package/dist/lib/protocols/mcp.mjs +13 -6
  79. package/dist/lib/reporting/inspection.js +1 -0
  80. package/dist/lib/reporting/inspection.mjs +1 -0
  81. package/dist/lib/schemas/browser.d.mts +2 -0
  82. package/dist/lib/schemas/browser.d.ts +2 -0
  83. package/dist/lib/schemas/browser.js +3 -0
  84. package/dist/lib/schemas/browser.mjs +2 -0
  85. package/dist/lib/schemas/index.d.mts +5 -2
  86. package/dist/lib/schemas/index.d.ts +5 -2
  87. package/dist/lib/schemas/index.js +5 -0
  88. package/dist/lib/schemas/index.mjs +4 -0
  89. package/dist/lib/server/account-response-identity.d.mts +17 -0
  90. package/dist/lib/server/account-response-identity.d.ts +17 -0
  91. package/dist/lib/server/account-response-identity.js +52 -0
  92. package/dist/lib/server/account-response-identity.mjs +28 -0
  93. package/dist/lib/server/account-sync-contract.js +1 -0
  94. package/dist/lib/server/account-sync-contract.mjs +1 -0
  95. package/dist/lib/server/create-adcp-server.js +32 -19
  96. package/dist/lib/server/create-adcp-server.mjs +36 -12
  97. package/dist/lib/server/decisioning/account.d.mts +13 -6
  98. package/dist/lib/server/decisioning/account.d.ts +13 -6
  99. package/dist/lib/server/decisioning/account.js +37 -15
  100. package/dist/lib/server/decisioning/account.mjs +37 -15
  101. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
  102. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
  103. package/dist/lib/server/decisioning/runtime/from-platform.js +6 -6
  104. package/dist/lib/server/decisioning/runtime/from-platform.mjs +6 -6
  105. package/dist/lib/server/index.d.mts +1 -1
  106. package/dist/lib/server/index.d.ts +1 -1
  107. package/dist/lib/server/index.js +2 -0
  108. package/dist/lib/server/index.mjs +2 -0
  109. package/dist/lib/server/media-buy-action-resolver.d.mts +3 -0
  110. package/dist/lib/server/media-buy-action-resolver.d.ts +3 -0
  111. package/dist/lib/server/media-buy-action-resolver.js +32 -0
  112. package/dist/lib/server/media-buy-action-resolver.mjs +32 -0
  113. package/dist/lib/server/media-buy-store.d.mts +26 -12
  114. package/dist/lib/server/media-buy-store.d.ts +26 -12
  115. package/dist/lib/server/media-buy-store.js +69 -21
  116. package/dist/lib/server/media-buy-store.mjs +69 -21
  117. package/dist/lib/server/responses.js +9 -1
  118. package/dist/lib/server/responses.mjs +9 -1
  119. package/dist/lib/server/state-machine.d.mts +10 -11
  120. package/dist/lib/server/state-machine.d.ts +10 -11
  121. package/dist/lib/server/state-machine.js +20 -5
  122. package/dist/lib/server/state-machine.mjs +19 -5
  123. package/dist/lib/signing/agent-fetch.d.mts +1 -1
  124. package/dist/lib/signing/agent-fetch.d.ts +1 -1
  125. package/dist/lib/signing/agent-fetch.js +3 -3
  126. package/dist/lib/signing/agent-fetch.mjs +3 -3
  127. package/dist/lib/testing/client.d.mts +1 -0
  128. package/dist/lib/testing/client.d.ts +1 -0
  129. package/dist/lib/testing/client.js +6 -5
  130. package/dist/lib/testing/client.mjs +6 -5
  131. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
  132. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
  133. package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
  134. package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
  135. package/dist/lib/testing/storyboard/compliance.js +62 -13
  136. package/dist/lib/testing/storyboard/compliance.mjs +63 -14
  137. package/dist/lib/testing/storyboard/context.d.mts +13 -3
  138. package/dist/lib/testing/storyboard/context.d.ts +13 -3
  139. package/dist/lib/testing/storyboard/context.js +15 -10
  140. package/dist/lib/testing/storyboard/context.mjs +15 -10
  141. package/dist/lib/testing/storyboard/default-invariants.js +10 -8
  142. package/dist/lib/testing/storyboard/default-invariants.mjs +11 -9
  143. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  144. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  145. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
  146. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
  147. package/dist/lib/testing/storyboard/runner.js +23 -10
  148. package/dist/lib/testing/storyboard/runner.mjs +23 -10
  149. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  150. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  151. package/dist/lib/testing/storyboard/validations.js +4 -1
  152. package/dist/lib/testing/storyboard/validations.mjs +4 -1
  153. package/dist/lib/testing/test-controller.js +3 -0
  154. package/dist/lib/testing/test-controller.mjs +3 -0
  155. package/dist/lib/types/asset-instances.d.mts +1 -1
  156. package/dist/lib/types/asset-instances.d.ts +1 -1
  157. package/dist/lib/types/index.d.mts +5 -0
  158. package/dist/lib/types/index.d.ts +5 -0
  159. package/dist/lib/types/index.js +6 -1
  160. package/dist/lib/types/index.mjs +4 -1
  161. package/dist/lib/types/inline-enums.generated.d.mts +30 -4
  162. package/dist/lib/types/inline-enums.generated.d.ts +30 -4
  163. package/dist/lib/types/inline-enums.generated.js +41 -2
  164. package/dist/lib/types/inline-enums.generated.mjs +28 -2
  165. package/dist/lib/types/media-buy-delivery-report.d.mts +4 -0
  166. package/dist/lib/types/media-buy-delivery-report.d.ts +4 -0
  167. package/dist/lib/types/media-buy-delivery-report.js +16 -0
  168. package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
  169. package/dist/lib/types/schemas.generated.d.ts +20 -69
  170. package/dist/lib/types/schemas.generated.js +29 -46
  171. package/dist/lib/types/schemas.generated.mjs +29 -46
  172. package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
  173. package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
  174. package/dist/lib/types/targeting-keys.generated.js +105 -0
  175. package/dist/lib/types/targeting-keys.generated.mjs +80 -0
  176. package/dist/lib/utils/adcp-version-config.js +5 -2
  177. package/dist/lib/utils/adcp-version-config.mjs +5 -2
  178. package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
  179. package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
  180. package/dist/lib/utils/envelope-status-compat.js +11 -5
  181. package/dist/lib/utils/envelope-status-compat.mjs +11 -5
  182. package/dist/lib/utils/response-unwrapper.js +18 -10
  183. package/dist/lib/utils/response-unwrapper.mjs +18 -10
  184. package/dist/lib/v2/format-schema/resolver.js +1 -1
  185. package/dist/lib/v2/format-schema/resolver.mjs +1 -1
  186. package/dist/lib/v2/projection/creative-delivery.js +123 -30
  187. package/dist/lib/v2/projection/creative-delivery.mjs +127 -30
  188. package/dist/lib/v2/projection/index.d.mts +1 -0
  189. package/dist/lib/v2/projection/index.d.ts +1 -0
  190. package/dist/lib/v2/projection/index.js +3 -0
  191. package/dist/lib/v2/projection/index.mjs +2 -0
  192. package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
  193. package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
  194. package/dist/lib/v2/projection/legacy-metadata.js +91 -0
  195. package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
  196. package/dist/lib/validation/compact-schema.d.mts +27 -0
  197. package/dist/lib/validation/compact-schema.d.ts +27 -0
  198. package/dist/lib/validation/compact-schema.js +276 -0
  199. package/dist/lib/validation/compact-schema.mjs +250 -0
  200. package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
  201. package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
  202. package/dist/lib/validation/media-buy-delivery-report.js +31 -0
  203. package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
  204. package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
  205. package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
  206. package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
  207. package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
  208. package/dist/lib/validation/schema-loader.js +86 -16
  209. package/dist/lib/validation/schema-loader.mjs +82 -16
  210. package/dist/lib/validation/schema-validator.d.mts +10 -19
  211. package/dist/lib/validation/schema-validator.d.ts +10 -19
  212. package/dist/lib/validation/schema-validator.js +136 -43
  213. package/dist/lib/validation/schema-validator.mjs +140 -44
  214. package/dist/lib/version.d.mts +3 -3
  215. package/dist/lib/version.d.ts +3 -3
  216. package/dist/lib/version.js +3 -3
  217. package/dist/lib/version.mjs +3 -3
  218. package/dist/lib/webhooks/index.d.mts +3 -0
  219. package/dist/lib/webhooks/index.d.ts +3 -0
  220. package/dist/lib/webhooks/index.js +3 -0
  221. package/dist/lib/webhooks/index.mjs +2 -0
  222. package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
  223. package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
  224. package/dist/lib/webhooks/media-buy-delivery.js +119 -0
  225. package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
  226. package/docs/TYPE-SUMMARY.md +2 -2
  227. package/docs/guides/BUILD-AN-AGENT.md +9 -1
  228. package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +135 -0
  229. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +15 -0
  230. package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
  231. package/docs/llms.txt +3 -3
  232. package/docs/migration-14.x-rc-worksheet.md +4 -4
  233. package/docs/migration-6.6-to-6.7.md +14 -0
  234. package/docs/migration-account-change-feed.md +19 -0
  235. package/docs/releases/sdk-16.6-adoption-fixes.md +33 -0
  236. package/package.json +2 -2
@@ -36,27 +36,18 @@ export interface ValidationIssue {
36
36
  message: string;
37
37
  /** AJV keyword that rejected the payload (e.g., `required`, `type`). */
38
38
  keyword: string;
39
- /** Path inside the schema that rejected the payload. */
39
+ /**
40
+ * AJV's original function-relative path in the compiled runtime schema.
41
+ * Factoring can change paths; they are diagnostic details rather than stable
42
+ * selectors into the public bundled document. Synthetic origin IDs stay internal.
43
+ */
40
44
  schemaPath: string;
41
45
  /**
42
- * `$id` of the rejecting schema. Resolved by finding the longest
43
- * registered AJV `$id` that prefixes {@link schemaPath}.
44
- *
45
- * Bundling caveat: AdCP ships most tools through `schemas/cache/<v>/bundled/`
46
- * with `$ref`s pre-resolved and inner `$id`s stripped at bundle time. For
47
- * those tools, `schemaId` resolves to the response root (e.g.
48
- * `/schemas/3.0.4/bundled/signals/activate-signal-response.json`), not
49
- * the deeper sub-schema. Tools served from the flat tree (`governance/`,
50
- * `brand/`, etc.) preserve sub-schema `$id`s, so `schemaId` can land on
51
- * something deeper like `/schemas/3.0.4/core/activation-key.json`. Either
52
- * way, the field names exactly the schema the validator looked at.
53
- *
54
- * Always projected — the `$id` is the published spec URI, not internal
55
- * handler shape. (Same precedent as {@link ValidationIssue.variants} and
56
- * {@link ValidationIssue.allowedValues}, both of which already ship
57
- * always-on with the same rationale.)
58
- *
59
- * Absent only when the rejecting schema didn't declare an `$id`.
46
+ * Effective `$id` of the rejecting resource, including embedded resources.
47
+ * Bundled documents may strip nested IDs, in which case the tool root is
48
+ * the available identity. Unsupported origin metadata conservatively falls
49
+ * back to the compiled root ID; anonymous resources can omit this field.
50
+ * Always projected because published schema IDs are protocol metadata.
60
51
  */
61
52
  schemaId?: string;
62
53
  /**
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var schema_validator_exports = {};
20
20
  __export(schema_validator_exports, {
21
+ compactUnionErrors: () => compactUnionErrors,
21
22
  formatDiscriminator: () => formatDiscriminator,
22
23
  formatIssueLine: () => formatIssueLine,
23
24
  formatIssues: () => formatIssues,
@@ -46,17 +47,18 @@ function extractSchemaId(schemaPath, rootSchema, registeredIds) {
46
47
  }
47
48
  function formatIssue(err, ctx) {
48
49
  const instancePath = err.instancePath || "";
49
- const missingProperty = err.keyword === "required" && err.params && typeof err.params.missingProperty === "string" ? `/${err.params.missingProperty}` : "";
50
+ const missingProperty = err.keyword === "required" && err.params && typeof err.params.missingProperty === "string" ? `/${err.params.missingProperty.replace(/~/g, "~0").replace(/\//g, "~1")}` : "";
50
51
  const isEnum = err.keyword === "enum" && err.params != null && Array.isArray(err.params.allowedValues);
51
52
  const allowedValues = isEnum ? err.params.allowedValues : void 0;
52
53
  const message = isEnum ? `must be one of: ${allowedValues.map((v) => JSON.stringify(v)).join(", ")}` : err.message ?? "validation failed";
53
- const schemaId = extractSchemaId(err.schemaPath, ctx.rootSchema, ctx.registeredIds);
54
+ const origin = ctx.diagnosticOrigin?.(err.__adcp_originSchemaPath ?? err.schemaPath);
55
+ const schemaId = origin ? origin.schemaId : extractSchemaId(err.schemaPath, ctx.rootSchema, ctx.registeredIds) ?? ctx.rootSchemaId;
54
56
  const discriminator = err.__adcp_discriminator;
55
57
  const issue = {
56
58
  pointer: `${instancePath}${missingProperty}` || "/",
57
59
  message,
58
60
  keyword: err.keyword,
59
- schemaPath: err.schemaPath,
61
+ schemaPath: err.schemaPath === "" ? "" : origin?.schemaPath ?? err.schemaPath,
60
62
  ...schemaId !== void 0 && { schemaId },
61
63
  ...discriminator !== void 0 && discriminator.length > 0 && { discriminator },
62
64
  ...allowedValues !== void 0 && { allowedValues }
@@ -65,24 +67,19 @@ function formatIssue(err, ctx) {
65
67
  if (hint !== void 0) issue.hint = hint;
66
68
  return issue;
67
69
  }
68
- const FORBIDDEN_SCHEMA_PATH_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
69
- function resolveSchemaPath(rootSchema, schemaPath) {
70
- if (rootSchema == null) return void 0;
71
- const clean = schemaPath.replace(/^#\/?/, "");
72
- if (clean.length === 0) return rootSchema;
73
- let cursor = rootSchema;
74
- for (const raw of clean.split("/")) {
75
- if (cursor == null || typeof cursor !== "object" && !Array.isArray(cursor)) return void 0;
76
- const decoded = raw.replace(/~1/g, "/").replace(/~0/g, "~");
77
- if (FORBIDDEN_SCHEMA_PATH_SEGMENTS.has(decoded)) return void 0;
78
- if (!Object.prototype.hasOwnProperty.call(cursor, decoded)) return void 0;
79
- cursor = cursor[decoded];
80
- }
81
- return cursor;
70
+ function createDiagnosticOriginResolver(validator) {
71
+ const memo = /* @__PURE__ */ new Map();
72
+ return (schemaPath) => {
73
+ if (memo.has(schemaPath)) return memo.get(schemaPath);
74
+ if (memo.size >= 1024) return void 0;
75
+ const resolved = (0, import_schema_loader.getValidatorDiagnosticOrigin)(validator, schemaPath);
76
+ memo.set(schemaPath, resolved);
77
+ return resolved;
78
+ };
82
79
  }
83
- function* expandNotErrors(errors, rootSchema, payload) {
80
+ function* expandNotErrors(errors, resolveDiagnosticPath, payload) {
84
81
  for (const error of errors) {
85
- const rule = error.keyword === "not" ? resolveSchemaPath(rootSchema, error.schemaPath) : void 0;
82
+ const rule = error.keyword === "not" ? resolveDiagnosticPath(error.instancePath, error.schemaPath) : void 0;
86
83
  const branches = rule && typeof rule === "object" ? rule.anyOf : void 0;
87
84
  if (!Array.isArray(branches) || branches.length === 0 || Object.keys(rule).length !== 1) {
88
85
  yield error;
@@ -126,47 +123,118 @@ function* expandNotErrors(errors, rootSchema, payload) {
126
123
  }
127
124
  }
128
125
  function formatValidationIssues(errors, ctx, payload) {
126
+ const resolveDiagnosticPath = (_instancePath, path) => ctx.diagnosticOrigin?.(path)?.schema;
129
127
  function* formatted() {
130
- for (const error of expandNotErrors(compactUnionErrors(errors, ctx.rootSchema), ctx.rootSchema, payload)) {
131
- yield enrichWithVariants(formatIssue(error, ctx), ctx.rootSchema);
128
+ for (const error of expandNotErrors(
129
+ compactUnionErrors(errors, resolveDiagnosticPath),
130
+ resolveDiagnosticPath,
131
+ payload
132
+ )) {
133
+ yield enrichWithVariants(
134
+ formatIssue(error, ctx),
135
+ (_instance, _publicPath) => resolveDiagnosticPath(error.instancePath, error.schemaPath)
136
+ );
132
137
  }
133
138
  }
134
139
  return ctx.toolName === "sync_accounts" ? [...formatted()] : (0, import_diagnostic_limits.boundValidationIssues)(formatted());
135
140
  }
136
- function compactUnionErrors(errors, rootSchema) {
137
- if (errors.length === 0) return [...errors];
138
- const errorsByOneOfPath = /* @__PURE__ */ new Map();
139
- for (const e of errors) {
140
- const m = e.schemaPath.match(/^(.*\/(?:oneOf|anyOf))\/\d+(?:\/|$)/);
141
- if (!m) continue;
142
- const root = m[1];
143
- const bucket = errorsByOneOfPath.get(root);
144
- if (bucket) bucket.push(e);
145
- else errorsByOneOfPath.set(root, [e]);
141
+ function inlineUnionOwner(error, unionPath, variants) {
142
+ const instance = error.instancePath ? error.instancePath.slice(1).split("/") : [];
143
+ let pointer;
144
+ try {
145
+ pointer = error.schemaPath.slice(unionPath.length + 1).split("/").map((segment) => decodeURIComponent(segment).replace(/~1/g, "/").replace(/~0/g, "~"));
146
+ } catch {
147
+ return void 0;
148
+ }
149
+ let cursor = variants;
150
+ const consumed = [];
151
+ for (let index = 0; index < pointer.length - 1; index++) {
152
+ if (!cursor || typeof cursor !== "object") return void 0;
153
+ const keyword = pointer[index];
154
+ if (!Array.isArray(cursor) && ["properties", "patternProperties"].includes(keyword)) {
155
+ const property = pointer[++index];
156
+ if (property === void 0) return void 0;
157
+ consumed.push(keyword === "properties" ? property : void 0);
158
+ cursor = cursor[keyword]?.[property];
159
+ } else if (!Array.isArray(cursor) && [
160
+ "items",
161
+ "prefixItems",
162
+ "additionalItems",
163
+ "contains",
164
+ "additionalProperties",
165
+ "unevaluatedProperties",
166
+ "unevaluatedItems"
167
+ ].includes(keyword)) {
168
+ consumed.push(void 0);
169
+ cursor = cursor[keyword];
170
+ if (Array.isArray(cursor)) cursor = cursor[Number(pointer[++index])];
171
+ } else cursor = cursor[keyword];
146
172
  }
173
+ if (consumed.length > instance.length) return void 0;
174
+ for (let index = 0; index < consumed.length; index++) {
175
+ const expected = consumed[index];
176
+ const actual = instance[instance.length - consumed.length + index].replace(/~1/g, "/").replace(/~0/g, "~");
177
+ if (expected !== void 0 && actual !== expected) return void 0;
178
+ }
179
+ return consumed.length ? instance.length === consumed.length ? "" : "/" + instance.slice(0, -consumed.length).join("/") : error.instancePath;
180
+ }
181
+ function compactUnionErrors(errors, resolveDiagnosticPath) {
182
+ if (errors.length === 0) return [...errors];
147
183
  const dropped = /* @__PURE__ */ new Set();
148
184
  const added = [];
149
- const unionRoots = errors.filter((e) => e.keyword === "oneOf" || e.keyword === "anyOf").slice().sort((a, b) => b.schemaPath.length - a.schemaPath.length);
185
+ const unionRoots = errors.filter((e) => e.keyword === "oneOf" || e.keyword === "anyOf").slice().sort((a, b) => b.instancePath.length - a.instancePath.length || b.schemaPath.length - a.schemaPath.length);
186
+ const unionOwners = /* @__PURE__ */ new Map();
187
+ for (const root of unionRoots) {
188
+ const owners = unionOwners.get(root.schemaPath) ?? /* @__PURE__ */ new Set();
189
+ owners.add(root.instancePath);
190
+ unionOwners.set(root.schemaPath, owners);
191
+ }
192
+ const errorsByOwner = /* @__PURE__ */ new Map();
193
+ for (const error of errors) {
194
+ const match = error.schemaPath.match(/^(.*\/(?:oneOf|anyOf))\/\d+(?:\/|$)/);
195
+ if (!match) continue;
196
+ const schemaPath = match[1];
197
+ const owners = unionOwners.get(schemaPath);
198
+ if (!owners) continue;
199
+ const variants = resolveDiagnosticPath(error.instancePath, schemaPath);
200
+ const nearest = inlineUnionOwner(error, schemaPath, variants);
201
+ if (nearest === void 0 || !owners.has(nearest)) continue;
202
+ const locations = errorsByOwner.get(schemaPath) ?? /* @__PURE__ */ new Map();
203
+ const bucket = locations.get(nearest) ?? [];
204
+ bucket.push(error);
205
+ locations.set(nearest, bucket);
206
+ errorsByOwner.set(schemaPath, locations);
207
+ }
208
+ const processedRoots = /* @__PURE__ */ new Map();
150
209
  for (const root of unionRoots) {
151
210
  if (dropped.has(root)) continue;
152
211
  const oneOfPath = root.schemaPath;
153
212
  const rootInstance = root.instancePath;
154
- const candidateErrors = errorsByOneOfPath.get(oneOfPath) ?? [];
213
+ if (root.keyword === "oneOf" && Array.isArray(root.params.passingSchemas) && root.params.passingSchemas.length > 1)
214
+ continue;
215
+ const variantSchemas = resolveDiagnosticPath(rootInstance, oneOfPath);
216
+ if (!Array.isArray(variantSchemas)) continue;
217
+ const processed = processedRoots.get(oneOfPath) ?? /* @__PURE__ */ new Set();
218
+ if (processed.has(rootInstance)) {
219
+ dropped.add(root);
220
+ continue;
221
+ }
222
+ processed.add(rootInstance);
223
+ processedRoots.set(oneOfPath, processed);
224
+ const candidateErrors = errorsByOwner.get(oneOfPath)?.get(rootInstance) ?? [];
155
225
  const byVariant = /* @__PURE__ */ new Map();
156
226
  for (const e of candidateErrors) {
157
227
  if (e === root || dropped.has(e)) continue;
158
228
  const tail = e.schemaPath.slice(oneOfPath.length + 1);
159
229
  const m = tail.match(/^(\d+)(?:\/|$)/);
160
230
  if (!m) continue;
161
- if (e.instancePath !== rootInstance && !e.instancePath.startsWith(rootInstance + "/")) continue;
162
231
  const idx = parseInt(m[1], 10);
163
232
  const bucket = byVariant.get(idx);
164
233
  if (bucket) bucket.push(e);
165
234
  else byVariant.set(idx, [e]);
166
235
  }
167
236
  if (byVariant.size === 0) continue;
168
- const variantSchemas = resolveSchemaPath(rootSchema, oneOfPath);
169
- const variantArr = Array.isArray(variantSchemas) ? variantSchemas : [];
237
+ const variantArr = variantSchemas;
170
238
  const constAsserters = /* @__PURE__ */ new Map();
171
239
  for (let i = 0; i < variantArr.length; i++) {
172
240
  const variant = variantArr[i];
@@ -213,6 +281,7 @@ function compactUnionErrors(errors, rootSchema) {
213
281
  ...sample,
214
282
  keyword: "enum",
215
283
  schemaPath: "",
284
+ __adcp_originSchemaPath: sample.schemaPath,
216
285
  message: `must be one of: ${allowedValues.map((v) => JSON.stringify(v)).join(", ")}`,
217
286
  params: { allowedValues }
218
287
  });
@@ -243,12 +312,23 @@ function compactUnionErrors(errors, rootSchema) {
243
312
  }
244
313
  }
245
314
  }
246
- const allVariantsHaveNot = variantsWithNotFailure.size === byVariant.size && byVariant.size > 0;
315
+ const allVariantsHaveNot = variantsWithNotFailure.size === variantSchemas.length && variantSchemas.length > 0;
316
+ const contradictedVariants = /* @__PURE__ */ new Set();
317
+ for (const [relativePath, asserters] of constAsserters) {
318
+ const emitted = /* @__PURE__ */ new Set();
319
+ for (const [index, residual] of residualByVariant) {
320
+ if (residual.some((error) => error.keyword === "const" && error.instancePath === rootInstance + relativePath))
321
+ emitted.add(index);
322
+ }
323
+ if ([...asserters.keys()].some((index) => !emitted.has(index))) {
324
+ for (const index of emitted) if (asserters.has(index)) contradictedVariants.add(index);
325
+ }
326
+ }
247
327
  let bestIdx = -1;
248
328
  let bestCount = Infinity;
249
329
  let bestConsts = Infinity;
250
330
  for (const [idx, residual] of residualByVariant) {
251
- if (!allVariantsHaveNot && variantsWithNotFailure.has(idx)) continue;
331
+ if (!allVariantsHaveNot && variantsWithNotFailure.has(idx) || contradictedVariants.has(idx)) continue;
252
332
  const constCount = residual.reduce((n, e) => e.keyword === "const" ? n + 1 : n, 0);
253
333
  if (residual.length < bestCount || residual.length === bestCount && constCount < bestConsts) {
254
334
  bestIdx = idx;
@@ -278,9 +358,9 @@ function compactUnionErrors(errors, rootSchema) {
278
358
  }
279
359
  return [...errors.filter((e) => !dropped.has(e)), ...added];
280
360
  }
281
- function enrichWithVariants(issue, rootSchema) {
361
+ function enrichWithVariants(issue, resolveDiagnosticPath) {
282
362
  if (issue.keyword !== "oneOf" && issue.keyword !== "anyOf") return issue;
283
- const resolved = resolveSchemaPath(rootSchema, issue.schemaPath);
363
+ const resolved = resolveDiagnosticPath(issue.pointer === "/" ? "" : issue.pointer, issue.schemaPath);
284
364
  if (!Array.isArray(resolved)) return issue;
285
365
  const variants = resolved.map((variant, index) => {
286
366
  if (variant == null || typeof variant !== "object") {
@@ -301,7 +381,13 @@ function validateRequest(toolName, payload, version) {
301
381
  const rootSchemaId = rootSchema && typeof rootSchema === "object" && typeof rootSchema.$id === "string" ? rootSchema.$id : void 0;
302
382
  if (valid) return { valid: true, issues: [], variant: "request", ...rootSchemaId && { schemaId: rootSchemaId } };
303
383
  const registeredIds = (0, import_schema_loader.getRegisteredSchemaIds)(version);
304
- const ctx = { rootSchema, registeredIds, toolName };
384
+ const ctx = {
385
+ rootSchema,
386
+ rootSchemaId,
387
+ registeredIds,
388
+ toolName,
389
+ diagnosticOrigin: createDiagnosticOriginResolver(validator)
390
+ };
305
391
  return {
306
392
  valid: false,
307
393
  issues: formatValidationIssues(validator.errors ?? [], ctx, payload),
@@ -319,7 +405,7 @@ function selectResponseVariant(payload) {
319
405
  return "sync";
320
406
  }
321
407
  function validateResponse(toolName, payload, version) {
322
- const compatPayload = payload && typeof payload === "object" && !Array.isArray(payload) ? (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(payload, { toolName }) : payload;
408
+ const compatPayload = payload && typeof payload === "object" && !Array.isArray(payload) ? (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(payload, { toolName, adcpVersion: version }) : payload;
323
409
  const variant = selectResponseVariant(compatPayload);
324
410
  const validator = (0, import_schema_loader.getValidator)(toolName, variant, version);
325
411
  const effective = validator ?? (variant !== "sync" ? (0, import_schema_loader.getValidator)(toolName, "sync", version) : void 0);
@@ -341,7 +427,13 @@ function validateResponse(toolName, payload, version) {
341
427
  };
342
428
  }
343
429
  const registeredIds = (0, import_schema_loader.getRegisteredSchemaIds)(version);
344
- const ctx = { rootSchema, registeredIds, toolName };
430
+ const ctx = {
431
+ rootSchema,
432
+ rootSchemaId,
433
+ registeredIds,
434
+ toolName,
435
+ diagnosticOrigin: createDiagnosticOriginResolver(effective)
436
+ };
345
437
  return {
346
438
  valid: false,
347
439
  issues: formatValidationIssues(effective.errors ?? [], ctx, normalizedPayload),
@@ -375,6 +467,7 @@ function formatIssues(issues, limit = 3, options = {}) {
375
467
  }
376
468
  // Annotate the CommonJS export names for ESM import in node:
377
469
  0 && (module.exports = {
470
+ compactUnionErrors,
378
471
  formatDiscriminator,
379
472
  formatIssueLine,
380
473
  formatIssues,
@@ -1,4 +1,8 @@
1
- import { getValidator, getRegisteredSchemaIds } from "./schema-loader.mjs";
1
+ import {
2
+ getValidator,
3
+ getValidatorDiagnosticOrigin,
4
+ getRegisteredSchemaIds
5
+ } from "./schema-loader.mjs";
2
6
  import { findHint } from "./hints.mjs";
3
7
  import { injectLegacyEnvelopeStatus } from "../utils/envelope-status-compat.mjs";
4
8
  import { boundValidationIssues } from "./diagnostic-limits.mjs";
@@ -19,17 +23,18 @@ function extractSchemaId(schemaPath, rootSchema, registeredIds) {
19
23
  }
20
24
  function formatIssue(err, ctx) {
21
25
  const instancePath = err.instancePath || "";
22
- const missingProperty = err.keyword === "required" && err.params && typeof err.params.missingProperty === "string" ? `/${err.params.missingProperty}` : "";
26
+ const missingProperty = err.keyword === "required" && err.params && typeof err.params.missingProperty === "string" ? `/${err.params.missingProperty.replace(/~/g, "~0").replace(/\//g, "~1")}` : "";
23
27
  const isEnum = err.keyword === "enum" && err.params != null && Array.isArray(err.params.allowedValues);
24
28
  const allowedValues = isEnum ? err.params.allowedValues : void 0;
25
29
  const message = isEnum ? `must be one of: ${allowedValues.map((v) => JSON.stringify(v)).join(", ")}` : err.message ?? "validation failed";
26
- const schemaId = extractSchemaId(err.schemaPath, ctx.rootSchema, ctx.registeredIds);
30
+ const origin = ctx.diagnosticOrigin?.(err.__adcp_originSchemaPath ?? err.schemaPath);
31
+ const schemaId = origin ? origin.schemaId : extractSchemaId(err.schemaPath, ctx.rootSchema, ctx.registeredIds) ?? ctx.rootSchemaId;
27
32
  const discriminator = err.__adcp_discriminator;
28
33
  const issue = {
29
34
  pointer: `${instancePath}${missingProperty}` || "/",
30
35
  message,
31
36
  keyword: err.keyword,
32
- schemaPath: err.schemaPath,
37
+ schemaPath: err.schemaPath === "" ? "" : origin?.schemaPath ?? err.schemaPath,
33
38
  ...schemaId !== void 0 && { schemaId },
34
39
  ...discriminator !== void 0 && discriminator.length > 0 && { discriminator },
35
40
  ...allowedValues !== void 0 && { allowedValues }
@@ -38,24 +43,19 @@ function formatIssue(err, ctx) {
38
43
  if (hint !== void 0) issue.hint = hint;
39
44
  return issue;
40
45
  }
41
- const FORBIDDEN_SCHEMA_PATH_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
42
- function resolveSchemaPath(rootSchema, schemaPath) {
43
- if (rootSchema == null) return void 0;
44
- const clean = schemaPath.replace(/^#\/?/, "");
45
- if (clean.length === 0) return rootSchema;
46
- let cursor = rootSchema;
47
- for (const raw of clean.split("/")) {
48
- if (cursor == null || typeof cursor !== "object" && !Array.isArray(cursor)) return void 0;
49
- const decoded = raw.replace(/~1/g, "/").replace(/~0/g, "~");
50
- if (FORBIDDEN_SCHEMA_PATH_SEGMENTS.has(decoded)) return void 0;
51
- if (!Object.prototype.hasOwnProperty.call(cursor, decoded)) return void 0;
52
- cursor = cursor[decoded];
53
- }
54
- return cursor;
46
+ function createDiagnosticOriginResolver(validator) {
47
+ const memo = /* @__PURE__ */ new Map();
48
+ return (schemaPath) => {
49
+ if (memo.has(schemaPath)) return memo.get(schemaPath);
50
+ if (memo.size >= 1024) return void 0;
51
+ const resolved = getValidatorDiagnosticOrigin(validator, schemaPath);
52
+ memo.set(schemaPath, resolved);
53
+ return resolved;
54
+ };
55
55
  }
56
- function* expandNotErrors(errors, rootSchema, payload) {
56
+ function* expandNotErrors(errors, resolveDiagnosticPath, payload) {
57
57
  for (const error of errors) {
58
- const rule = error.keyword === "not" ? resolveSchemaPath(rootSchema, error.schemaPath) : void 0;
58
+ const rule = error.keyword === "not" ? resolveDiagnosticPath(error.instancePath, error.schemaPath) : void 0;
59
59
  const branches = rule && typeof rule === "object" ? rule.anyOf : void 0;
60
60
  if (!Array.isArray(branches) || branches.length === 0 || Object.keys(rule).length !== 1) {
61
61
  yield error;
@@ -99,47 +99,118 @@ function* expandNotErrors(errors, rootSchema, payload) {
99
99
  }
100
100
  }
101
101
  function formatValidationIssues(errors, ctx, payload) {
102
+ const resolveDiagnosticPath = (_instancePath, path) => ctx.diagnosticOrigin?.(path)?.schema;
102
103
  function* formatted() {
103
- for (const error of expandNotErrors(compactUnionErrors(errors, ctx.rootSchema), ctx.rootSchema, payload)) {
104
- yield enrichWithVariants(formatIssue(error, ctx), ctx.rootSchema);
104
+ for (const error of expandNotErrors(
105
+ compactUnionErrors(errors, resolveDiagnosticPath),
106
+ resolveDiagnosticPath,
107
+ payload
108
+ )) {
109
+ yield enrichWithVariants(
110
+ formatIssue(error, ctx),
111
+ (_instance, _publicPath) => resolveDiagnosticPath(error.instancePath, error.schemaPath)
112
+ );
105
113
  }
106
114
  }
107
115
  return ctx.toolName === "sync_accounts" ? [...formatted()] : boundValidationIssues(formatted());
108
116
  }
109
- function compactUnionErrors(errors, rootSchema) {
110
- if (errors.length === 0) return [...errors];
111
- const errorsByOneOfPath = /* @__PURE__ */ new Map();
112
- for (const e of errors) {
113
- const m = e.schemaPath.match(/^(.*\/(?:oneOf|anyOf))\/\d+(?:\/|$)/);
114
- if (!m) continue;
115
- const root = m[1];
116
- const bucket = errorsByOneOfPath.get(root);
117
- if (bucket) bucket.push(e);
118
- else errorsByOneOfPath.set(root, [e]);
117
+ function inlineUnionOwner(error, unionPath, variants) {
118
+ const instance = error.instancePath ? error.instancePath.slice(1).split("/") : [];
119
+ let pointer;
120
+ try {
121
+ pointer = error.schemaPath.slice(unionPath.length + 1).split("/").map((segment) => decodeURIComponent(segment).replace(/~1/g, "/").replace(/~0/g, "~"));
122
+ } catch {
123
+ return void 0;
124
+ }
125
+ let cursor = variants;
126
+ const consumed = [];
127
+ for (let index = 0; index < pointer.length - 1; index++) {
128
+ if (!cursor || typeof cursor !== "object") return void 0;
129
+ const keyword = pointer[index];
130
+ if (!Array.isArray(cursor) && ["properties", "patternProperties"].includes(keyword)) {
131
+ const property = pointer[++index];
132
+ if (property === void 0) return void 0;
133
+ consumed.push(keyword === "properties" ? property : void 0);
134
+ cursor = cursor[keyword]?.[property];
135
+ } else if (!Array.isArray(cursor) && [
136
+ "items",
137
+ "prefixItems",
138
+ "additionalItems",
139
+ "contains",
140
+ "additionalProperties",
141
+ "unevaluatedProperties",
142
+ "unevaluatedItems"
143
+ ].includes(keyword)) {
144
+ consumed.push(void 0);
145
+ cursor = cursor[keyword];
146
+ if (Array.isArray(cursor)) cursor = cursor[Number(pointer[++index])];
147
+ } else cursor = cursor[keyword];
119
148
  }
149
+ if (consumed.length > instance.length) return void 0;
150
+ for (let index = 0; index < consumed.length; index++) {
151
+ const expected = consumed[index];
152
+ const actual = instance[instance.length - consumed.length + index].replace(/~1/g, "/").replace(/~0/g, "~");
153
+ if (expected !== void 0 && actual !== expected) return void 0;
154
+ }
155
+ return consumed.length ? instance.length === consumed.length ? "" : "/" + instance.slice(0, -consumed.length).join("/") : error.instancePath;
156
+ }
157
+ function compactUnionErrors(errors, resolveDiagnosticPath) {
158
+ if (errors.length === 0) return [...errors];
120
159
  const dropped = /* @__PURE__ */ new Set();
121
160
  const added = [];
122
- const unionRoots = errors.filter((e) => e.keyword === "oneOf" || e.keyword === "anyOf").slice().sort((a, b) => b.schemaPath.length - a.schemaPath.length);
161
+ const unionRoots = errors.filter((e) => e.keyword === "oneOf" || e.keyword === "anyOf").slice().sort((a, b) => b.instancePath.length - a.instancePath.length || b.schemaPath.length - a.schemaPath.length);
162
+ const unionOwners = /* @__PURE__ */ new Map();
163
+ for (const root of unionRoots) {
164
+ const owners = unionOwners.get(root.schemaPath) ?? /* @__PURE__ */ new Set();
165
+ owners.add(root.instancePath);
166
+ unionOwners.set(root.schemaPath, owners);
167
+ }
168
+ const errorsByOwner = /* @__PURE__ */ new Map();
169
+ for (const error of errors) {
170
+ const match = error.schemaPath.match(/^(.*\/(?:oneOf|anyOf))\/\d+(?:\/|$)/);
171
+ if (!match) continue;
172
+ const schemaPath = match[1];
173
+ const owners = unionOwners.get(schemaPath);
174
+ if (!owners) continue;
175
+ const variants = resolveDiagnosticPath(error.instancePath, schemaPath);
176
+ const nearest = inlineUnionOwner(error, schemaPath, variants);
177
+ if (nearest === void 0 || !owners.has(nearest)) continue;
178
+ const locations = errorsByOwner.get(schemaPath) ?? /* @__PURE__ */ new Map();
179
+ const bucket = locations.get(nearest) ?? [];
180
+ bucket.push(error);
181
+ locations.set(nearest, bucket);
182
+ errorsByOwner.set(schemaPath, locations);
183
+ }
184
+ const processedRoots = /* @__PURE__ */ new Map();
123
185
  for (const root of unionRoots) {
124
186
  if (dropped.has(root)) continue;
125
187
  const oneOfPath = root.schemaPath;
126
188
  const rootInstance = root.instancePath;
127
- const candidateErrors = errorsByOneOfPath.get(oneOfPath) ?? [];
189
+ if (root.keyword === "oneOf" && Array.isArray(root.params.passingSchemas) && root.params.passingSchemas.length > 1)
190
+ continue;
191
+ const variantSchemas = resolveDiagnosticPath(rootInstance, oneOfPath);
192
+ if (!Array.isArray(variantSchemas)) continue;
193
+ const processed = processedRoots.get(oneOfPath) ?? /* @__PURE__ */ new Set();
194
+ if (processed.has(rootInstance)) {
195
+ dropped.add(root);
196
+ continue;
197
+ }
198
+ processed.add(rootInstance);
199
+ processedRoots.set(oneOfPath, processed);
200
+ const candidateErrors = errorsByOwner.get(oneOfPath)?.get(rootInstance) ?? [];
128
201
  const byVariant = /* @__PURE__ */ new Map();
129
202
  for (const e of candidateErrors) {
130
203
  if (e === root || dropped.has(e)) continue;
131
204
  const tail = e.schemaPath.slice(oneOfPath.length + 1);
132
205
  const m = tail.match(/^(\d+)(?:\/|$)/);
133
206
  if (!m) continue;
134
- if (e.instancePath !== rootInstance && !e.instancePath.startsWith(rootInstance + "/")) continue;
135
207
  const idx = parseInt(m[1], 10);
136
208
  const bucket = byVariant.get(idx);
137
209
  if (bucket) bucket.push(e);
138
210
  else byVariant.set(idx, [e]);
139
211
  }
140
212
  if (byVariant.size === 0) continue;
141
- const variantSchemas = resolveSchemaPath(rootSchema, oneOfPath);
142
- const variantArr = Array.isArray(variantSchemas) ? variantSchemas : [];
213
+ const variantArr = variantSchemas;
143
214
  const constAsserters = /* @__PURE__ */ new Map();
144
215
  for (let i = 0; i < variantArr.length; i++) {
145
216
  const variant = variantArr[i];
@@ -186,6 +257,7 @@ function compactUnionErrors(errors, rootSchema) {
186
257
  ...sample,
187
258
  keyword: "enum",
188
259
  schemaPath: "",
260
+ __adcp_originSchemaPath: sample.schemaPath,
189
261
  message: `must be one of: ${allowedValues.map((v) => JSON.stringify(v)).join(", ")}`,
190
262
  params: { allowedValues }
191
263
  });
@@ -216,12 +288,23 @@ function compactUnionErrors(errors, rootSchema) {
216
288
  }
217
289
  }
218
290
  }
219
- const allVariantsHaveNot = variantsWithNotFailure.size === byVariant.size && byVariant.size > 0;
291
+ const allVariantsHaveNot = variantsWithNotFailure.size === variantSchemas.length && variantSchemas.length > 0;
292
+ const contradictedVariants = /* @__PURE__ */ new Set();
293
+ for (const [relativePath, asserters] of constAsserters) {
294
+ const emitted = /* @__PURE__ */ new Set();
295
+ for (const [index, residual] of residualByVariant) {
296
+ if (residual.some((error) => error.keyword === "const" && error.instancePath === rootInstance + relativePath))
297
+ emitted.add(index);
298
+ }
299
+ if ([...asserters.keys()].some((index) => !emitted.has(index))) {
300
+ for (const index of emitted) if (asserters.has(index)) contradictedVariants.add(index);
301
+ }
302
+ }
220
303
  let bestIdx = -1;
221
304
  let bestCount = Infinity;
222
305
  let bestConsts = Infinity;
223
306
  for (const [idx, residual] of residualByVariant) {
224
- if (!allVariantsHaveNot && variantsWithNotFailure.has(idx)) continue;
307
+ if (!allVariantsHaveNot && variantsWithNotFailure.has(idx) || contradictedVariants.has(idx)) continue;
225
308
  const constCount = residual.reduce((n, e) => e.keyword === "const" ? n + 1 : n, 0);
226
309
  if (residual.length < bestCount || residual.length === bestCount && constCount < bestConsts) {
227
310
  bestIdx = idx;
@@ -251,9 +334,9 @@ function compactUnionErrors(errors, rootSchema) {
251
334
  }
252
335
  return [...errors.filter((e) => !dropped.has(e)), ...added];
253
336
  }
254
- function enrichWithVariants(issue, rootSchema) {
337
+ function enrichWithVariants(issue, resolveDiagnosticPath) {
255
338
  if (issue.keyword !== "oneOf" && issue.keyword !== "anyOf") return issue;
256
- const resolved = resolveSchemaPath(rootSchema, issue.schemaPath);
339
+ const resolved = resolveDiagnosticPath(issue.pointer === "/" ? "" : issue.pointer, issue.schemaPath);
257
340
  if (!Array.isArray(resolved)) return issue;
258
341
  const variants = resolved.map((variant, index) => {
259
342
  if (variant == null || typeof variant !== "object") {
@@ -274,7 +357,13 @@ function validateRequest(toolName, payload, version) {
274
357
  const rootSchemaId = rootSchema && typeof rootSchema === "object" && typeof rootSchema.$id === "string" ? rootSchema.$id : void 0;
275
358
  if (valid) return { valid: true, issues: [], variant: "request", ...rootSchemaId && { schemaId: rootSchemaId } };
276
359
  const registeredIds = getRegisteredSchemaIds(version);
277
- const ctx = { rootSchema, registeredIds, toolName };
360
+ const ctx = {
361
+ rootSchema,
362
+ rootSchemaId,
363
+ registeredIds,
364
+ toolName,
365
+ diagnosticOrigin: createDiagnosticOriginResolver(validator)
366
+ };
278
367
  return {
279
368
  valid: false,
280
369
  issues: formatValidationIssues(validator.errors ?? [], ctx, payload),
@@ -292,7 +381,7 @@ function selectResponseVariant(payload) {
292
381
  return "sync";
293
382
  }
294
383
  function validateResponse(toolName, payload, version) {
295
- const compatPayload = payload && typeof payload === "object" && !Array.isArray(payload) ? injectLegacyEnvelopeStatus(payload, { toolName }) : payload;
384
+ const compatPayload = payload && typeof payload === "object" && !Array.isArray(payload) ? injectLegacyEnvelopeStatus(payload, { toolName, adcpVersion: version }) : payload;
296
385
  const variant = selectResponseVariant(compatPayload);
297
386
  const validator = getValidator(toolName, variant, version);
298
387
  const effective = validator ?? (variant !== "sync" ? getValidator(toolName, "sync", version) : void 0);
@@ -314,7 +403,13 @@ function validateResponse(toolName, payload, version) {
314
403
  };
315
404
  }
316
405
  const registeredIds = getRegisteredSchemaIds(version);
317
- const ctx = { rootSchema, registeredIds, toolName };
406
+ const ctx = {
407
+ rootSchema,
408
+ rootSchemaId,
409
+ registeredIds,
410
+ toolName,
411
+ diagnosticOrigin: createDiagnosticOriginResolver(effective)
412
+ };
318
413
  return {
319
414
  valid: false,
320
415
  issues: formatValidationIssues(effective.errors ?? [], ctx, normalizedPayload),
@@ -347,6 +442,7 @@ function formatIssues(issues, limit = 3, options = {}) {
347
442
  return rest > 0 ? `${head} (+${rest} more)` : head;
348
443
  }
349
444
  export {
445
+ compactUnionErrors,
350
446
  formatDiscriminator,
351
447
  formatIssueLine,
352
448
  formatIssues,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "16.5.0";
4
+ export declare const LIBRARY_VERSION = "16.6.0";
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: "16.5.0";
36
+ readonly library: "16.6.0";
37
37
  readonly adcp: "3.2.7";
38
38
  readonly compatibleVersions: readonly ["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", "3.2.6", "3.2.7"];
39
- readonly generatedAt: "2026-10-25T14:43:55.588Z";
39
+ readonly generatedAt: "2026-10-27T06:39:57.335Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for