@adcp/sdk 16.0.0-beta.7 → 16.0.0-beta.9

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 (408) hide show
  1. package/AGENTS.md +3 -3
  2. package/README.md +20 -0
  3. package/bin/adcp.js +10 -13
  4. package/dist/lib/conformance/index.d.mts +2 -0
  5. package/dist/lib/conformance/index.d.ts +2 -0
  6. package/dist/lib/conformance/index.js +3 -0
  7. package/dist/lib/conformance/index.mjs +2 -0
  8. package/dist/lib/conformance/property-lists.d.mts +14 -0
  9. package/dist/lib/conformance/property-lists.d.ts +14 -0
  10. package/dist/lib/conformance/property-lists.js +45 -0
  11. package/dist/lib/conformance/property-lists.mjs +21 -0
  12. package/dist/lib/conformance/runConformance.js +20 -1
  13. package/dist/lib/conformance/runConformance.mjs +20 -1
  14. package/dist/lib/conformance/types.d.mts +3 -0
  15. package/dist/lib/conformance/types.d.ts +3 -0
  16. package/dist/lib/core/AgentClient.d.mts +8 -5
  17. package/dist/lib/core/AgentClient.d.ts +8 -5
  18. package/dist/lib/core/AgentClient.js +9 -4
  19. package/dist/lib/core/AgentClient.mjs +9 -4
  20. package/dist/lib/core/SingleAgentClient.d.mts +32 -115
  21. package/dist/lib/core/SingleAgentClient.d.ts +32 -115
  22. package/dist/lib/core/SingleAgentClient.js +379 -273
  23. package/dist/lib/core/SingleAgentClient.mjs +387 -275
  24. package/dist/lib/core/TaskExecutor.d.mts +1 -16
  25. package/dist/lib/core/TaskExecutor.d.ts +1 -16
  26. package/dist/lib/core/TaskExecutor.js +34 -51
  27. package/dist/lib/core/TaskExecutor.mjs +12 -29
  28. package/dist/lib/core/product-cache.d.mts +3 -1
  29. package/dist/lib/core/product-cache.d.ts +3 -1
  30. package/dist/lib/core/product-cache.js +2 -1
  31. package/dist/lib/core/product-cache.mjs +2 -1
  32. package/dist/lib/errors/index.d.mts +2 -8
  33. package/dist/lib/errors/index.d.ts +2 -8
  34. package/dist/lib/errors/index.js +4 -4
  35. package/dist/lib/errors/index.mjs +4 -4
  36. package/dist/lib/identifiers.d.mts +53 -0
  37. package/dist/lib/identifiers.d.ts +53 -0
  38. package/dist/lib/identifiers.js +212 -0
  39. package/dist/lib/identifiers.mjs +163 -0
  40. package/dist/lib/index.d.mts +7 -5
  41. package/dist/lib/index.d.ts +7 -5
  42. package/dist/lib/index.js +2 -14
  43. package/dist/lib/index.mjs +1 -14
  44. package/dist/lib/media-buy/compatibility.d.mts +1 -1
  45. package/dist/lib/media-buy/compatibility.d.ts +1 -1
  46. package/dist/lib/media-buy/compatibility.js +26 -45
  47. package/dist/lib/media-buy/compatibility.mjs +26 -45
  48. package/dist/lib/media-buy/index.d.mts +1 -1
  49. package/dist/lib/media-buy/index.d.ts +1 -1
  50. package/dist/lib/media-buy/legacy-purchase-continuation.d.mts +2 -2
  51. package/dist/lib/media-buy/legacy-purchase-continuation.d.ts +2 -2
  52. package/dist/lib/media-buy/property-policy.d.mts +15 -1
  53. package/dist/lib/media-buy/property-policy.d.ts +15 -1
  54. package/dist/lib/media-buy/property-policy.js +135 -3
  55. package/dist/lib/media-buy/property-policy.mjs +134 -3
  56. package/dist/lib/protocols/index.js +14 -22
  57. package/dist/lib/protocols/index.mjs +5 -13
  58. package/dist/lib/registry/index.d.mts +12 -0
  59. package/dist/lib/registry/index.d.ts +12 -0
  60. package/dist/lib/registry/index.js +159 -5
  61. package/dist/lib/registry/index.mjs +156 -4
  62. package/dist/lib/registry/types.d.mts +26 -2
  63. package/dist/lib/registry/types.d.ts +26 -2
  64. package/dist/lib/registry/types.generated.d.mts +51 -11
  65. package/dist/lib/registry/types.generated.d.ts +51 -11
  66. package/dist/lib/reporting/source/conformance.d.mts +8 -8
  67. package/dist/lib/reporting/source/conformance.d.ts +8 -8
  68. package/dist/lib/reporting/source/manifest.d.mts +27 -27
  69. package/dist/lib/reporting/source/manifest.d.ts +27 -27
  70. package/dist/lib/server/create-adcp-server.js +6 -0
  71. package/dist/lib/server/create-adcp-server.mjs +6 -0
  72. package/dist/lib/server/decisioning/specialisms/lists.d.mts +4 -4
  73. package/dist/lib/server/decisioning/specialisms/lists.d.ts +4 -4
  74. package/dist/lib/server/index.d.mts +3 -0
  75. package/dist/lib/server/index.d.ts +3 -0
  76. package/dist/lib/server/index.js +8 -1
  77. package/dist/lib/server/index.mjs +4 -0
  78. package/dist/lib/server/property-lists.d.mts +36 -0
  79. package/dist/lib/server/property-lists.d.ts +36 -0
  80. package/dist/lib/server/property-lists.js +154 -0
  81. package/dist/lib/server/property-lists.mjs +129 -0
  82. package/dist/lib/server/targeting-helpers.d.mts +2 -0
  83. package/dist/lib/server/targeting-helpers.d.ts +2 -0
  84. package/dist/lib/server/targeting-helpers.js +28 -1
  85. package/dist/lib/server/targeting-helpers.mjs +18 -1
  86. package/dist/lib/signing/parser.js +2 -2
  87. package/dist/lib/signing/parser.mjs +2 -2
  88. package/dist/lib/signing/server.d.mts +1 -1
  89. package/dist/lib/signing/server.d.ts +1 -1
  90. package/dist/lib/signing/server.mjs +5 -1
  91. package/dist/lib/signing/webhook-verifier.d.mts +11 -0
  92. package/dist/lib/signing/webhook-verifier.d.ts +11 -0
  93. package/dist/lib/signing/webhook-verifier.js +11 -3
  94. package/dist/lib/signing/webhook-verifier.mjs +11 -3
  95. package/dist/lib/supply-path/verify.js +12 -2
  96. package/dist/lib/supply-path/verify.mjs +2 -2
  97. package/dist/lib/testing/compliance/comply.js +0 -8
  98. package/dist/lib/testing/compliance/comply.mjs +0 -8
  99. package/dist/lib/testing/compliance/storyboard-tracks.js +11 -0
  100. package/dist/lib/testing/compliance/storyboard-tracks.mjs +11 -0
  101. package/dist/lib/testing/index.d.mts +2 -0
  102. package/dist/lib/testing/index.d.ts +2 -0
  103. package/dist/lib/testing/index.js +5 -0
  104. package/dist/lib/testing/index.mjs +3 -0
  105. package/dist/lib/testing/scenarios/capabilities.d.mts +2 -2
  106. package/dist/lib/testing/scenarios/capabilities.d.ts +2 -2
  107. package/dist/lib/testing/scenarios/capabilities.js +8 -41
  108. package/dist/lib/testing/scenarios/capabilities.mjs +9 -42
  109. package/dist/lib/testing/storyboard/creative-build-probe.d.mts +34 -0
  110. package/dist/lib/testing/storyboard/creative-build-probe.d.ts +34 -0
  111. package/dist/lib/testing/storyboard/creative-build-probe.js +395 -0
  112. package/dist/lib/testing/storyboard/creative-build-probe.mjs +373 -0
  113. package/dist/lib/testing/storyboard/index.d.mts +2 -0
  114. package/dist/lib/testing/storyboard/index.d.ts +2 -0
  115. package/dist/lib/testing/storyboard/index.js +5 -0
  116. package/dist/lib/testing/storyboard/index.mjs +3 -0
  117. package/dist/lib/testing/storyboard/loader.js +12 -0
  118. package/dist/lib/testing/storyboard/loader.mjs +12 -0
  119. package/dist/lib/testing/storyboard/property-list-reference.d.mts +15 -0
  120. package/dist/lib/testing/storyboard/property-list-reference.d.ts +15 -0
  121. package/dist/lib/testing/storyboard/property-list-reference.js +514 -0
  122. package/dist/lib/testing/storyboard/property-list-reference.mjs +487 -0
  123. package/dist/lib/testing/storyboard/runner.js +318 -58
  124. package/dist/lib/testing/storyboard/runner.mjs +322 -58
  125. package/dist/lib/testing/storyboard/types.d.mts +38 -16
  126. package/dist/lib/testing/storyboard/types.d.ts +38 -16
  127. package/dist/lib/testing/storyboard/types.js +1 -0
  128. package/dist/lib/testing/storyboard/types.mjs +1 -0
  129. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  130. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  131. package/dist/lib/testing/storyboard/validations.js +64 -0
  132. package/dist/lib/testing/storyboard/validations.mjs +67 -1
  133. package/dist/lib/testing/types.d.mts +15 -1
  134. package/dist/lib/testing/types.d.ts +15 -1
  135. package/dist/lib/types/schemas.generated.d.ts +65 -65
  136. package/dist/lib/types/wellknown-schemas.generated.d.mts +21 -21
  137. package/dist/lib/types/wellknown-schemas.generated.d.ts +21 -21
  138. package/dist/lib/utils/adcp-version-config.js +6 -0
  139. package/dist/lib/utils/adcp-version-config.mjs +6 -0
  140. package/dist/lib/utils/capabilities.d.mts +7 -9
  141. package/dist/lib/utils/capabilities.d.ts +7 -9
  142. package/dist/lib/utils/capabilities.js +14 -28
  143. package/dist/lib/utils/capabilities.mjs +14 -27
  144. package/dist/lib/utils/creative-adapter.d.mts +15 -113
  145. package/dist/lib/utils/creative-adapter.d.ts +15 -113
  146. package/dist/lib/utils/creative-adapter.js +7 -106
  147. package/dist/lib/utils/creative-adapter.mjs +7 -102
  148. package/dist/lib/utils/format-renders.d.mts +20 -80
  149. package/dist/lib/utils/format-renders.d.ts +20 -80
  150. package/dist/lib/utils/format-renders.js +7 -67
  151. package/dist/lib/utils/format-renders.mjs +7 -66
  152. package/dist/lib/utils/index.d.mts +1 -2
  153. package/dist/lib/utils/index.d.ts +1 -2
  154. package/dist/lib/utils/index.js +0 -7
  155. package/dist/lib/utils/index.mjs +0 -6
  156. package/dist/lib/utils/preview-normalizer.d.mts +31 -80
  157. package/dist/lib/utils/preview-normalizer.d.ts +31 -80
  158. package/dist/lib/utils/preview-normalizer.js +5 -50
  159. package/dist/lib/utils/preview-normalizer.mjs +5 -49
  160. package/dist/lib/utils/pricing-adapter.d.mts +2 -36
  161. package/dist/lib/utils/pricing-adapter.d.ts +2 -36
  162. package/dist/lib/utils/pricing-adapter.js +0 -105
  163. package/dist/lib/utils/pricing-adapter.mjs +0 -100
  164. package/dist/lib/utils/request-normalizer.d.mts +1 -2
  165. package/dist/lib/utils/request-normalizer.d.ts +1 -2
  166. package/dist/lib/v2/projection/creative-delivery.d.mts +2 -0
  167. package/dist/lib/v2/projection/creative-delivery.d.ts +2 -0
  168. package/dist/lib/v2/projection/creative-delivery.js +7 -0
  169. package/dist/lib/v2/projection/creative-delivery.mjs +6 -0
  170. package/dist/lib/v2/projection/legacy-metadata.d.mts +12 -0
  171. package/dist/lib/v2/projection/legacy-metadata.d.ts +12 -0
  172. package/dist/lib/v2/projection/legacy-metadata.js +41 -1
  173. package/dist/lib/v2/projection/legacy-metadata.mjs +37 -1
  174. package/dist/lib/v2/projection/legacy-normalization.d.mts +1 -1
  175. package/dist/lib/v2/projection/legacy-normalization.d.ts +1 -1
  176. package/dist/lib/v2/projection/v1-to-v2.js +13 -0
  177. package/dist/lib/v2/projection/v1-to-v2.mjs +14 -0
  178. package/dist/lib/validation/client-hooks.d.mts +1 -4
  179. package/dist/lib/validation/client-hooks.d.ts +1 -4
  180. package/dist/lib/validation/get-products-request.d.mts +1 -1
  181. package/dist/lib/validation/get-products-request.d.ts +1 -1
  182. package/dist/lib/validation/schema-loader.js +6 -0
  183. package/dist/lib/validation/schema-loader.mjs +6 -0
  184. package/dist/lib/validation/schema-validator.js +1 -26
  185. package/dist/lib/validation/schema-validator.mjs +1 -26
  186. package/dist/lib/version.d.mts +5 -5
  187. package/dist/lib/version.d.ts +5 -5
  188. package/dist/lib/version.js +3 -5
  189. package/dist/lib/version.mjs +3 -5
  190. package/docs/TYPE-SUMMARY.md +2 -2
  191. package/docs/development/PROTOCOL_DIFFERENCES.md +1 -1
  192. package/docs/guides/CONFORMANCE.md +25 -0
  193. package/docs/guides/CREATIVE-BUILD-PROBE.md +156 -0
  194. package/docs/guides/CREATIVE-DELIVERY.md +45 -6
  195. package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +15 -18
  196. package/docs/guides/PROPERTY-LISTS.md +264 -0
  197. package/docs/guides/SIGNING-GUIDE.md +25 -0
  198. package/docs/guides/VALIDATE-YOUR-AGENT.md +5 -0
  199. package/docs/llms.txt +2 -2
  200. package/docs/migration-13-to-14.md +20 -16
  201. package/docs/migration-14.x-rc-worksheet.md +5 -5
  202. package/docs/migration-4.x-to-5.x.md +12 -7
  203. package/docs/migration-drop-adcp-2.md +25 -0
  204. package/package.json +3 -18
  205. package/skills/call-adcp-agent/SKILL.md +23 -25
  206. package/dist/lib/adapters/legacy/v2-5/create_media_buy.d.mts +0 -3
  207. package/dist/lib/adapters/legacy/v2-5/create_media_buy.d.ts +0 -3
  208. package/dist/lib/adapters/legacy/v2-5/create_media_buy.js +0 -33
  209. package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -9
  210. package/dist/lib/adapters/legacy/v2-5/get_products.d.mts +0 -8
  211. package/dist/lib/adapters/legacy/v2-5/get_products.d.ts +0 -8
  212. package/dist/lib/adapters/legacy/v2-5/get_products.js +0 -33
  213. package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -9
  214. package/dist/lib/adapters/legacy/v2-5/index.d.mts +0 -34
  215. package/dist/lib/adapters/legacy/v2-5/index.d.ts +0 -34
  216. package/dist/lib/adapters/legacy/v2-5/index.js +0 -50
  217. package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -25
  218. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.d.mts +0 -8
  219. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.d.ts +0 -8
  220. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.js +0 -33
  221. package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -9
  222. package/dist/lib/adapters/legacy/v2-5/preview_creative.d.mts +0 -3
  223. package/dist/lib/adapters/legacy/v2-5/preview_creative.d.ts +0 -3
  224. package/dist/lib/adapters/legacy/v2-5/preview_creative.js +0 -33
  225. package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -9
  226. package/dist/lib/adapters/legacy/v2-5/sync_creatives.d.mts +0 -11
  227. package/dist/lib/adapters/legacy/v2-5/sync_creatives.d.ts +0 -11
  228. package/dist/lib/adapters/legacy/v2-5/sync_creatives.js +0 -32
  229. package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -8
  230. package/dist/lib/adapters/legacy/v2-5/types.d.mts +0 -39
  231. package/dist/lib/adapters/legacy/v2-5/types.d.ts +0 -39
  232. package/dist/lib/adapters/legacy/v2-5/types.js +0 -16
  233. package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -0
  234. package/dist/lib/adapters/legacy/v2-5/update_media_buy.d.mts +0 -3
  235. package/dist/lib/adapters/legacy/v2-5/update_media_buy.d.ts +0 -3
  236. package/dist/lib/adapters/legacy/v2-5/update_media_buy.js +0 -35
  237. package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -11
  238. package/dist/lib/schemas-data/v2.5/_provenance.json +0 -8
  239. package/dist/lib/schemas-data/v2.5/adagents.json +0 -494
  240. package/dist/lib/schemas-data/v2.5/core/activation-key.json +0 -50
  241. package/dist/lib/schemas-data/v2.5/core/assets/audio-asset.json +0 -32
  242. package/dist/lib/schemas-data/v2.5/core/assets/css-asset.json +0 -21
  243. package/dist/lib/schemas-data/v2.5/core/assets/daast-asset.json +0 -87
  244. package/dist/lib/schemas-data/v2.5/core/assets/html-asset.json +0 -21
  245. package/dist/lib/schemas-data/v2.5/core/assets/image-asset.json +0 -38
  246. package/dist/lib/schemas-data/v2.5/core/assets/javascript-asset.json +0 -21
  247. package/dist/lib/schemas-data/v2.5/core/assets/markdown-asset.json +0 -31
  248. package/dist/lib/schemas-data/v2.5/core/assets/text-asset.json +0 -21
  249. package/dist/lib/schemas-data/v2.5/core/assets/url-asset.json +0 -26
  250. package/dist/lib/schemas-data/v2.5/core/assets/vast-asset.json +0 -87
  251. package/dist/lib/schemas-data/v2.5/core/assets/video-asset.json +0 -44
  252. package/dist/lib/schemas-data/v2.5/core/assets/webhook-asset.json +0 -71
  253. package/dist/lib/schemas-data/v2.5/core/async-response-data.json +0 -88
  254. package/dist/lib/schemas-data/v2.5/core/brand-manifest-ref.json +0 -33
  255. package/dist/lib/schemas-data/v2.5/core/brand-manifest.json +0 -409
  256. package/dist/lib/schemas-data/v2.5/core/context.json +0 -8
  257. package/dist/lib/schemas-data/v2.5/core/creative-asset.json +0 -125
  258. package/dist/lib/schemas-data/v2.5/core/creative-assignment.json +0 -31
  259. package/dist/lib/schemas-data/v2.5/core/creative-filters.json +0 -111
  260. package/dist/lib/schemas-data/v2.5/core/creative-manifest.json +0 -72
  261. package/dist/lib/schemas-data/v2.5/core/creative-policy.json +0 -27
  262. package/dist/lib/schemas-data/v2.5/core/delivery-metrics.json +0 -171
  263. package/dist/lib/schemas-data/v2.5/core/deployment.json +0 -93
  264. package/dist/lib/schemas-data/v2.5/core/destination.json +0 -53
  265. package/dist/lib/schemas-data/v2.5/core/error.json +0 -40
  266. package/dist/lib/schemas-data/v2.5/core/ext.json +0 -8
  267. package/dist/lib/schemas-data/v2.5/core/format-id.json +0 -47
  268. package/dist/lib/schemas-data/v2.5/core/format.json +0 -324
  269. package/dist/lib/schemas-data/v2.5/core/frequency-cap.json +0 -18
  270. package/dist/lib/schemas-data/v2.5/core/mcp-webhook-payload.json +0 -152
  271. package/dist/lib/schemas-data/v2.5/core/measurement.json +0 -48
  272. package/dist/lib/schemas-data/v2.5/core/media-buy.json +0 -62
  273. package/dist/lib/schemas-data/v2.5/core/package.json +0 -72
  274. package/dist/lib/schemas-data/v2.5/core/performance-feedback.json +0 -90
  275. package/dist/lib/schemas-data/v2.5/core/placement.json +0 -34
  276. package/dist/lib/schemas-data/v2.5/core/pricing-option.json +0 -35
  277. package/dist/lib/schemas-data/v2.5/core/product-filters.json +0 -102
  278. package/dist/lib/schemas-data/v2.5/core/product.json +0 -153
  279. package/dist/lib/schemas-data/v2.5/core/promoted-offerings.json +0 -115
  280. package/dist/lib/schemas-data/v2.5/core/promoted-products.json +0 -67
  281. package/dist/lib/schemas-data/v2.5/core/property-id.json +0 -14
  282. package/dist/lib/schemas-data/v2.5/core/property-tag.json +0 -16
  283. package/dist/lib/schemas-data/v2.5/core/property.json +0 -62
  284. package/dist/lib/schemas-data/v2.5/core/protocol-envelope.json +0 -146
  285. package/dist/lib/schemas-data/v2.5/core/publisher-property-selector.json +0 -92
  286. package/dist/lib/schemas-data/v2.5/core/push-notification-config.json +0 -48
  287. package/dist/lib/schemas-data/v2.5/core/reporting-capabilities.json +0 -71
  288. package/dist/lib/schemas-data/v2.5/core/response.json +0 -24
  289. package/dist/lib/schemas-data/v2.5/core/signal-filters.json +0 -35
  290. package/dist/lib/schemas-data/v2.5/core/start-timing.json +0 -18
  291. package/dist/lib/schemas-data/v2.5/core/sub-asset.json +0 -79
  292. package/dist/lib/schemas-data/v2.5/core/targeting.json +0 -50
  293. package/dist/lib/schemas-data/v2.5/core/tasks-get-request.json +0 -43
  294. package/dist/lib/schemas-data/v2.5/core/tasks-get-response.json +0 -166
  295. package/dist/lib/schemas-data/v2.5/core/tasks-list-request.json +0 -192
  296. package/dist/lib/schemas-data/v2.5/core/tasks-list-response.json +0 -183
  297. package/dist/lib/schemas-data/v2.5/creative/asset-types/index.json +0 -101
  298. package/dist/lib/schemas-data/v2.5/creative/list-creative-formats-request.json +0 -73
  299. package/dist/lib/schemas-data/v2.5/creative/list-creative-formats-response.json +0 -61
  300. package/dist/lib/schemas-data/v2.5/creative/preview-creative-request.json +0 -164
  301. package/dist/lib/schemas-data/v2.5/creative/preview-creative-response.json +0 -245
  302. package/dist/lib/schemas-data/v2.5/creative/preview-render.json +0 -225
  303. package/dist/lib/schemas-data/v2.5/enums/adcp-domain.json +0 -11
  304. package/dist/lib/schemas-data/v2.5/enums/asset-content-type.json +0 -22
  305. package/dist/lib/schemas-data/v2.5/enums/auth-scheme.json +0 -11
  306. package/dist/lib/schemas-data/v2.5/enums/available-metric.json +0 -18
  307. package/dist/lib/schemas-data/v2.5/enums/channels.json +0 -18
  308. package/dist/lib/schemas-data/v2.5/enums/co-branding-requirement.json +0 -12
  309. package/dist/lib/schemas-data/v2.5/enums/creative-action.json +0 -14
  310. package/dist/lib/schemas-data/v2.5/enums/creative-agent-capability.json +0 -13
  311. package/dist/lib/schemas-data/v2.5/enums/creative-sort-field.json +0 -15
  312. package/dist/lib/schemas-data/v2.5/enums/creative-status.json +0 -19
  313. package/dist/lib/schemas-data/v2.5/enums/daast-tracking-event.json +0 -20
  314. package/dist/lib/schemas-data/v2.5/enums/daast-version.json +0 -11
  315. package/dist/lib/schemas-data/v2.5/enums/delivery-type.json +0 -15
  316. package/dist/lib/schemas-data/v2.5/enums/dimension-unit.json +0 -13
  317. package/dist/lib/schemas-data/v2.5/enums/feed-format.json +0 -12
  318. package/dist/lib/schemas-data/v2.5/enums/feedback-source.json +0 -13
  319. package/dist/lib/schemas-data/v2.5/enums/format-category.json +0 -16
  320. package/dist/lib/schemas-data/v2.5/enums/format-id-parameter.json +0 -11
  321. package/dist/lib/schemas-data/v2.5/enums/frequency-cap-scope.json +0 -13
  322. package/dist/lib/schemas-data/v2.5/enums/history-entry-type.json +0 -11
  323. package/dist/lib/schemas-data/v2.5/enums/http-method.json +0 -11
  324. package/dist/lib/schemas-data/v2.5/enums/identifier-types.json +0 -34
  325. package/dist/lib/schemas-data/v2.5/enums/javascript-module-type.json +0 -12
  326. package/dist/lib/schemas-data/v2.5/enums/landing-page-requirement.json +0 -12
  327. package/dist/lib/schemas-data/v2.5/enums/markdown-flavor.json +0 -11
  328. package/dist/lib/schemas-data/v2.5/enums/media-buy-status.json +0 -19
  329. package/dist/lib/schemas-data/v2.5/enums/metric-type.json +0 -17
  330. package/dist/lib/schemas-data/v2.5/enums/notification-type.json +0 -13
  331. package/dist/lib/schemas-data/v2.5/enums/pacing.json +0 -17
  332. package/dist/lib/schemas-data/v2.5/enums/preview-output-format.json +0 -11
  333. package/dist/lib/schemas-data/v2.5/enums/pricing-model.json +0 -25
  334. package/dist/lib/schemas-data/v2.5/enums/property-type.json +0 -16
  335. package/dist/lib/schemas-data/v2.5/enums/publisher-identifier-types.json +0 -19
  336. package/dist/lib/schemas-data/v2.5/enums/reporting-frequency.json +0 -12
  337. package/dist/lib/schemas-data/v2.5/enums/signal-catalog-type.json +0 -12
  338. package/dist/lib/schemas-data/v2.5/enums/sort-direction.json +0 -11
  339. package/dist/lib/schemas-data/v2.5/enums/standard-format-ids.json +0 -103
  340. package/dist/lib/schemas-data/v2.5/enums/task-status.json +0 -29
  341. package/dist/lib/schemas-data/v2.5/enums/task-type.json +0 -27
  342. package/dist/lib/schemas-data/v2.5/enums/update-frequency.json +0 -13
  343. package/dist/lib/schemas-data/v2.5/enums/url-asset-type.json +0 -12
  344. package/dist/lib/schemas-data/v2.5/enums/validation-mode.json +0 -11
  345. package/dist/lib/schemas-data/v2.5/enums/vast-tracking-event.json +0 -25
  346. package/dist/lib/schemas-data/v2.5/enums/vast-version.json +0 -14
  347. package/dist/lib/schemas-data/v2.5/enums/webhook-response-type.json +0 -13
  348. package/dist/lib/schemas-data/v2.5/enums/webhook-security-method.json +0 -12
  349. package/dist/lib/schemas-data/v2.5/index.json +0 -604
  350. package/dist/lib/schemas-data/v2.5/media-buy/build-creative-request.json +0 -31
  351. package/dist/lib/schemas-data/v2.5/media-buy/build-creative-response.json +0 -65
  352. package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-input-required.json +0 -31
  353. package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-submitted.json +0 -16
  354. package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-working.json +0 -36
  355. package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-request.json +0 -126
  356. package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-response.json +0 -97
  357. package/dist/lib/schemas-data/v2.5/media-buy/get-media-buy-delivery-request.json +0 -54
  358. package/dist/lib/schemas-data/v2.5/media-buy/get-media-buy-delivery-response.json +0 -285
  359. package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-input-required.json +0 -38
  360. package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-submitted.json +0 -21
  361. package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-working.json +0 -34
  362. package/dist/lib/schemas-data/v2.5/media-buy/get-products-request.json +0 -28
  363. package/dist/lib/schemas-data/v2.5/media-buy/get-products-response.json +0 -33
  364. package/dist/lib/schemas-data/v2.5/media-buy/list-authorized-properties-request.json +0 -26
  365. package/dist/lib/schemas-data/v2.5/media-buy/list-authorized-properties-response.json +0 -70
  366. package/dist/lib/schemas-data/v2.5/media-buy/list-creative-formats-request.json +0 -58
  367. package/dist/lib/schemas-data/v2.5/media-buy/list-creative-formats-response.json +0 -61
  368. package/dist/lib/schemas-data/v2.5/media-buy/list-creatives-request.json +0 -137
  369. package/dist/lib/schemas-data/v2.5/media-buy/list-creatives-response.json +0 -437
  370. package/dist/lib/schemas-data/v2.5/media-buy/package-request.json +0 -80
  371. package/dist/lib/schemas-data/v2.5/media-buy/provide-performance-feedback-request.json +0 -88
  372. package/dist/lib/schemas-data/v2.5/media-buy/provide-performance-feedback-response.json +0 -66
  373. package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-input-required.json +0 -25
  374. package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-submitted.json +0 -16
  375. package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-working.json +0 -46
  376. package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-request.json +0 -178
  377. package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-response.json +0 -149
  378. package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-input-required.json +0 -24
  379. package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-submitted.json +0 -16
  380. package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-working.json +0 -36
  381. package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-request.json +0 -129
  382. package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-response.json +0 -99
  383. package/dist/lib/schemas-data/v2.5/pricing-options/cpc-option.json +0 -52
  384. package/dist/lib/schemas-data/v2.5/pricing-options/cpcv-option.json +0 -52
  385. package/dist/lib/schemas-data/v2.5/pricing-options/cpm-auction-option.json +0 -81
  386. package/dist/lib/schemas-data/v2.5/pricing-options/cpm-fixed-option.json +0 -52
  387. package/dist/lib/schemas-data/v2.5/pricing-options/cpp-option.json +0 -73
  388. package/dist/lib/schemas-data/v2.5/pricing-options/cpv-option.json +0 -88
  389. package/dist/lib/schemas-data/v2.5/pricing-options/flat-rate-option.json +0 -93
  390. package/dist/lib/schemas-data/v2.5/pricing-options/vcpm-auction-option.json +0 -81
  391. package/dist/lib/schemas-data/v2.5/pricing-options/vcpm-fixed-option.json +0 -52
  392. package/dist/lib/schemas-data/v2.5/protocols/adcp-extension.json +0 -33
  393. package/dist/lib/schemas-data/v2.5/signals/activate-signal-request.json +0 -32
  394. package/dist/lib/schemas-data/v2.5/signals/activate-signal-response.json +0 -68
  395. package/dist/lib/schemas-data/v2.5/signals/get-signals-request.json +0 -59
  396. package/dist/lib/schemas-data/v2.5/signals/get-signals-response.json +0 -100
  397. package/dist/lib/types/v2-5/index.d.mts +0 -1
  398. package/dist/lib/types/v2-5/index.d.ts +0 -1
  399. package/dist/lib/types/v2-5/index.js +0 -22
  400. package/dist/lib/types/v2-5/index.mjs +0 -1
  401. package/dist/lib/types/v2-5/tools.generated.d.mts +0 -3568
  402. package/dist/lib/types/v2-5/tools.generated.d.ts +0 -3568
  403. package/dist/lib/types/v2-5/tools.generated.js +0 -16
  404. package/dist/lib/types/v2-5/tools.generated.mjs +0 -0
  405. package/dist/lib/utils/sync-creatives-adapter.d.mts +0 -33
  406. package/dist/lib/utils/sync-creatives-adapter.d.ts +0 -33
  407. package/dist/lib/utils/sync-creatives-adapter.js +0 -83
  408. package/dist/lib/utils/sync-creatives-adapter.mjs +0 -59
@@ -3,6 +3,9 @@ import { dirname as __adcpDirname } from "node:path";
3
3
  import { createRequire as __adcpCreateRequire } from "node:module";
4
4
  const __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));
5
5
  const require2 = __adcpCreateRequire(import.meta.url);
6
+ import { normalizeGetProductsResponse } from "../utils/pricing-adapter.mjs";
7
+ import { normalizeMediaBuyResponse } from "../utils/creative-adapter.mjs";
8
+ import { normalizeFormatsResponse } from "../utils/format-renders.mjs";
6
9
  import {
7
10
  isIdentity33SchemaScope,
8
11
  withIdentity33SchemaScope,
@@ -131,7 +134,6 @@ import {
131
134
  validateAgentDiscoveryCacheConfig
132
135
  } from "./agent-discovery-cache.mjs";
133
136
  import {
134
- buildSyntheticCapabilities,
135
137
  buildSyntheticV3Capabilities,
136
138
  augmentCapabilitiesFromTools,
137
139
  looksLikeV3Capabilities,
@@ -160,15 +162,17 @@ import { normalizeRequestParams } from "../utils/request-normalizer.mjs";
160
162
  import { globalAsyncLocalStorage } from "../utils/global-async-local-storage.mjs";
161
163
  import { validateUserAgent } from "../utils/validate-user-agent.mjs";
162
164
  import { resolveWebhookUrl, selectWebhookTemplate } from "./webhook-url.mjs";
163
- import { getV25Adapter } from "../adapters/legacy/v2-5/index.mjs";
164
165
  import {
165
166
  ProductPropertyPolicyError,
166
- validateProductsAgainstPropertyPolicy
167
+ validateProductsAgainstPropertyPolicy,
168
+ isSupportedPropertyIdentifierType,
169
+ normalizeDomainForPropertyPolicy
167
170
  } from "../media-buy/property-policy.mjs";
168
171
  import { resolvePropertyList } from "../server/targeting-helpers.mjs";
169
172
  import {
170
173
  CreativeFormatCapabilityError,
171
174
  CreativeFormatProjectionError,
175
+ canUseProductOptionsForCreativeWire,
172
176
  projectMediaBuyCreativesForDelivery,
173
177
  projectCreativeForDelivery,
174
178
  projectSyncCreativesForDelivery,
@@ -188,6 +192,10 @@ import {
188
192
  import { toCanonicalOnlyResponse } from "../v2/projection/augment-response.mjs";
189
193
  import {
190
194
  legacyFormatRefsForDeclaration,
195
+ isSynthesizedFormatOption,
196
+ selectedFormatOptions,
197
+ rememberSellerFormatEvidence,
198
+ sellerFormatEvidence,
191
199
  rememberSellerDeclaredFormatOption,
192
200
  sellerDeclaredFormatOption,
193
201
  structuredCloneWithLegacyCreativeMetadata
@@ -311,6 +319,56 @@ const RECORDLESS_HMAC_READ_ONLY_TASKS = /* @__PURE__ */ new Set([
311
319
  ]);
312
320
  const TASK_SCOPED_STATE_LIMIT = 1e4;
313
321
  const WEBHOOK_JWKS_RESOLVER_LIMIT = 1024;
322
+ function creativeMatchesProductOption(creative, declaration) {
323
+ const params = isPlainRecord(declaration.params) ? declaration.params : {};
324
+ const assets = isPlainRecord(creative.assets) ? creative.assets : {};
325
+ const slots = Array.isArray(params.slots) ? params.slots : [];
326
+ if (!slots.every((slot) => {
327
+ if (!isPlainRecord(slot) || typeof slot.asset_group_id !== "string") return false;
328
+ const value = assets[slot.asset_group_id];
329
+ const entries = value === void 0 ? [] : Array.isArray(value) ? value : [value];
330
+ const minimum = Math.max(typeof slot.min === "number" ? slot.min : 0, slot.required === true ? 1 : 0);
331
+ if (entries.length < minimum || typeof slot.max === "number" && entries.length > slot.max) return false;
332
+ return entries.every(
333
+ (asset) => isPlainRecord(asset) && (typeof slot.asset_type !== "string" || asset.asset_type === slot.asset_type)
334
+ );
335
+ }))
336
+ return false;
337
+ const formatParams = isPlainRecord(creative.format_parameters) ? creative.format_parameters : {};
338
+ const kind = String(creative.format_kind);
339
+ const mediaType = kind.startsWith("image") ? "image" : kind.startsWith("video") ? "video" : kind.startsWith("audio") ? "audio" : kind === "html5" ? "html" : void 0;
340
+ const assetTypes = mediaType === "video" ? ["video", "vast"] : mediaType === "audio" ? ["audio", "vast", "daast"] : mediaType === "html" ? ["html", "zip"] : mediaType ? [mediaType] : ["image", "video", "audio", "html", "zip", "vast", "daast"];
341
+ const requiredMediaSlots = slots.filter(
342
+ (slot) => isPlainRecord(slot) && (slot.required === true || typeof slot.min === "number" && slot.min > 0) && assetTypes.includes(String(slot.asset_type))
343
+ );
344
+ const preferredGroups = mediaType ? [`${mediaType}_main`, mediaType, kind, ...assetTypes] : [];
345
+ const primaryGroup = (requiredMediaSlots.length === 1 ? String(requiredMediaSlots[0].asset_group_id) : void 0) ?? preferredGroups.find((group) => assets[group] !== void 0);
346
+ const sourceAssets = primaryGroup ? [assets[primaryGroup]] : Object.values(assets);
347
+ const dimensionalAssets = sourceAssets.flatMap((value) => Array.isArray(value) ? value : [value]).filter(
348
+ (value) => isPlainRecord(value) && assetTypes.includes(String(value.asset_type))
349
+ );
350
+ return (dimensionalAssets.length > 0 ? dimensionalAssets : [{}]).every((asset) => {
351
+ const actual = { ...asset, ...formatParams };
352
+ for (const key of ["width", "height"]) {
353
+ if (typeof params[key] === "number" && actual[key] !== params[key]) return false;
354
+ const min = params[`min_${key}`];
355
+ const max = params[`max_${key}`];
356
+ if (typeof min === "number" && (typeof actual[key] !== "number" || actual[key] < min)) return false;
357
+ if (typeof max === "number" && (typeof actual[key] !== "number" || actual[key] > max)) return false;
358
+ }
359
+ if (Array.isArray(params.sizes) && !params.sizes.some((size) => isPlainRecord(size) && size.width === actual.width && size.height === actual.height))
360
+ return false;
361
+ const duration = actual.duration_ms ?? actual.duration_ms_exact;
362
+ const exact = params.duration_ms_exact ?? params.duration_ms;
363
+ if (typeof exact === "number" && duration !== exact) return false;
364
+ if (typeof exact !== "number" && Array.isArray(params.duration_ms_range)) {
365
+ const [min, max] = params.duration_ms_range;
366
+ if (typeof duration !== "number" || typeof min === "number" && duration < min || typeof max === "number" && duration > max)
367
+ return false;
368
+ }
369
+ return true;
370
+ });
371
+ }
314
372
  function isDeferredClientFinalizationContext(value) {
315
373
  if (!value || typeof value !== "object" || Array.isArray(value)) return false;
316
374
  const context = value;
@@ -757,24 +815,7 @@ function isToolSchemaRecord(value) {
757
815
  function isCapabilityEvidence(value) {
758
816
  if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
759
817
  const candidate = value;
760
- return (candidate.version === "v2" || candidate.version === "v3") && Array.isArray(candidate.majorVersions) && candidate.majorVersions.length > 0 && candidate.majorVersions.every((version) => version === 2 || version === 3) && Array.isArray(candidate.protocols) && candidate.protocols.every((protocol) => typeof protocol === "string") && typeof candidate.features === "object" && candidate.features !== null && !Array.isArray(candidate.features) && Array.isArray(candidate.extensions) && candidate.extensions.every((extension) => typeof extension === "string") && typeof candidate._synthetic === "boolean";
761
- }
762
- function valueMatchesSchemaType(value, propSchema) {
763
- if (!propSchema || typeof propSchema !== "object") return false;
764
- const schema = propSchema;
765
- if (schema.$ref) return true;
766
- const valueType = Array.isArray(value) ? "array" : value === null ? "null" : typeof value === "object" ? "object" : typeof value;
767
- for (const key of ["anyOf", "oneOf"]) {
768
- const variants = schema[key];
769
- if (Array.isArray(variants)) {
770
- return variants.some((v) => valueMatchesSchemaType(value, v));
771
- }
772
- }
773
- const declared = schema.type;
774
- if (declared === void 0) return false;
775
- if (typeof declared === "string") return declared === valueType;
776
- if (Array.isArray(declared)) return declared.includes(valueType);
777
- return false;
818
+ return candidate.version === "v3" && Array.isArray(candidate.majorVersions) && candidate.majorVersions.includes(3) && candidate.majorVersions.every((version) => Number.isSafeInteger(version) && version > 0) && Array.isArray(candidate.protocols) && candidate.protocols.every((protocol) => typeof protocol === "string") && typeof candidate.features === "object" && candidate.features !== null && !Array.isArray(candidate.features) && Array.isArray(candidate.extensions) && candidate.extensions.every((extension) => typeof extension === "string") && typeof candidate._synthetic === "boolean";
778
819
  }
779
820
  function productHasPricingOptions(product) {
780
821
  if (!product || typeof product !== "object") return false;
@@ -787,7 +828,9 @@ function productIdForPricingDiagnostics(product) {
787
828
  return typeof id === "string" ? id : void 0;
788
829
  }
789
830
  function propertyListReferenceFromRequest(params) {
790
- const value = params.property_list;
831
+ const filters = params.filters;
832
+ const nested = filters && typeof filters === "object" && !Array.isArray(filters) && Object.hasOwn(filters, "property_list") && filters.property_list !== void 0;
833
+ const value = nested ? filters.property_list : params.property_list;
791
834
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
792
835
  const ref = value;
793
836
  if (typeof ref.agent_url !== "string" || typeof ref.list_id !== "string") return void 0;
@@ -800,21 +843,37 @@ function propertyListReferenceFromRequest(params) {
800
843
  function productPolicyRequestSnapshot(requestParams) {
801
844
  const account = canonicalAccountRoutingSnapshot(requestParams.account);
802
845
  const propertyList = propertyListReferenceFromRequest(requestParams);
846
+ const referenceError = propertyListReferenceError(requestParams);
803
847
  return Object.freeze({
804
848
  ...account ? { account } : {},
805
- ...propertyList ? { property_list: Object.freeze(propertyList) } : {}
849
+ ...propertyList ? { property_list: Object.freeze(propertyList) } : {},
850
+ ...referenceError ? { property_list_error: referenceError } : {}
806
851
  });
807
852
  }
853
+ function propertyListReferenceError(params) {
854
+ if (typeof params.property_list_error === "string") return params.property_list_error;
855
+ const filters = params.filters;
856
+ if (params.property_list !== void 0 && !propertyListReferenceFromRequest({ property_list: params.property_list }))
857
+ return "property_list_invalid_reference";
858
+ if (!filters || typeof filters !== "object" || Array.isArray(filters) || !Object.hasOwn(filters, "property_list") || filters.property_list === void 0)
859
+ return void 0;
860
+ const nested = propertyListReferenceFromRequest(params);
861
+ if (!nested) return "property_list_invalid_reference";
862
+ if (params.property_list !== void 0) {
863
+ const legacy = propertyListReferenceFromRequest({ property_list: params.property_list });
864
+ if (!legacy || nested.agent_url !== legacy.agent_url || nested.list_id !== legacy.list_id || nested.auth_token !== legacy.auth_token) {
865
+ return "property_list_conflicting_references";
866
+ }
867
+ }
868
+ return void 0;
869
+ }
808
870
  function hasProductPropertyPolicyRules(policy) {
809
871
  return Boolean(
810
872
  policy.allowedDomains?.length || policy.allowedPropertyIdentifiers?.length || policy.requireAllowedPropertyMatch || policy.excludedDomains?.length || policy.excludedPropertyIds?.length || policy.strict || policy.unknownSelectorBehavior || policy.missingPublisherPropertiesBehavior
811
873
  );
812
874
  }
813
- function comparablePropertyIdentifiers(identifiers) {
814
- return identifiers.filter((identifier) => identifier.type === "domain" || identifier.type === "subdomain").map((identifier) => ({ type: identifier.type, value: identifier.value }));
815
- }
816
875
  function unsupportedPropertyIdentifiers(identifiers) {
817
- return identifiers.filter((identifier) => identifier.type !== "domain" && identifier.type !== "subdomain").map((identifier) => ({ type: identifier.type }));
876
+ return identifiers.filter((identifier) => !isSupportedPropertyIdentifierType(identifier.type)).map((identifier) => ({ type: identifier.type }));
818
877
  }
819
878
  function sanitizeDiagnosticUrl(value) {
820
879
  try {
@@ -1198,12 +1257,8 @@ class SingleAgentClient {
1198
1257
  // shared invalidation epoch of that key when the evidence was obtained
1199
1258
  sharedEvidenceKey;
1200
1259
  // discoveryCache key the local capability cache was obtained under
1201
- _v2WarningFired = false;
1202
- // Gate: emit the v2-sunset warning once per client instance
1203
1260
  _syntheticV3WarningFired = false;
1204
1261
  // Gate: emit the synthetic-v3 warning once per client instance
1205
- _syntheticV2WarningFired = false;
1206
- // Gate: emit the synthetic-v2 warning once per client instance
1207
1262
  productPolicyRequestParamsByTask = /* @__PURE__ */ new Map();
1208
1263
  canonicalCreativeTaskAssociations = /* @__PURE__ */ new Map();
1209
1264
  previewCreativeHandlersByTask = /* @__PURE__ */ new Map();
@@ -1411,8 +1466,17 @@ class SingleAgentClient {
1411
1466
  }
1412
1467
  assertDurablePropertyListCredentialSupported(taskType, requestParams) {
1413
1468
  if (!this.config.deferredStorage || taskType !== "get_products") return;
1414
- const propertyList = propertyListReferenceFromRequest(requestParams);
1415
- if (!propertyList?.auth_token) return;
1469
+ const filters = requestParams.filters;
1470
+ const references = [
1471
+ requestParams.property_list,
1472
+ filters && typeof filters === "object" ? filters.property_list : void 0
1473
+ ];
1474
+ const hasCredential = references.some((reference) => {
1475
+ if (!reference || typeof reference !== "object") return false;
1476
+ const token = reference.auth_token;
1477
+ return token !== void 0 && token !== null && token !== "";
1478
+ });
1479
+ if (!hasCredential) return;
1416
1480
  const policyConfig = this.config.validation?.productPropertyPolicy;
1417
1481
  if (policyConfig === false || policyConfig?.enforceRequestPropertyList === false) return;
1418
1482
  throw new ConfigurationError(
@@ -1465,7 +1529,7 @@ class SingleAgentClient {
1465
1529
  }
1466
1530
  }
1467
1531
  }
1468
- rememberCanonicalProductRoutes(products, account, authoritativeProducts) {
1532
+ rememberCanonicalProductRoutes(products, account, authoritativeProducts, evidence) {
1469
1533
  this.invalidateCanonicalProductRoutes(authoritativeProducts ?? products, account);
1470
1534
  const accountScope = this.canonicalAccountScope(account);
1471
1535
  const declaredOptions = authoritativeProducts ? this.sellerDeclaredFormatOptions(authoritativeProducts) : void 0;
@@ -1485,12 +1549,15 @@ class SingleAgentClient {
1485
1549
  const refs = legacyFormatRefsForDeclaration(option);
1486
1550
  const declared = declaredOptions ? declaredOptions.get(product.product_id)?.some((declaredRef) => this.sameCanonicalOptionRef(declaredRef, ref)) : sellerDeclaredFormatOption(option);
1487
1551
  if (declared !== void 0) rememberSellerDeclaredFormatOption(option, declared);
1552
+ if (declared === true && evidence)
1553
+ rememberSellerFormatEvidence(option, { ...evidence, productId: product.product_id });
1488
1554
  this.rememberCanonicalLegacyRoute(this.canonicalLegacyRouteKey(account, product.product_id, ref), {
1489
1555
  kind: "product",
1490
1556
  accountScope,
1491
1557
  productId: product.product_id,
1492
1558
  optionRef: ref,
1493
1559
  refs,
1560
+ ...declared === true && sellerFormatEvidence(option) ? { declaration: structuredCloneWithLegacyCreativeMetadata(option) } : {},
1494
1561
  ...declared === false ? { undeclaredSelector: undeclaredFormatOptionSelector(option) } : {}
1495
1562
  });
1496
1563
  }
@@ -3472,7 +3539,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3472
3539
  /**
3473
3540
  * Execute task and call appropriate handler on completion
3474
3541
  *
3475
- * Automatically adapts requests for v2 servers and normalizes responses.
3542
+ * Adapts requests for maintained AdCP 3 releases and normalizes product responses.
3476
3543
  */
3477
3544
  async executeAndHandle(taskType, handlerName, params, inputHandler, options, transformCompletedResponse, legacyFormatConverter, canonicalRequest, projectionCatalogs) {
3478
3545
  const requestParamsSnapshot = structuredClone(params);
@@ -3517,11 +3584,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3517
3584
  await this.requireSupportedMajor(taskType, options);
3518
3585
  throwIfAborted(options?.signal);
3519
3586
  }
3520
- const earlyResult = await this.getEarlyResultForUnsupportedFeatures(taskType, normalizedParams, options);
3521
- throwIfAborted(options?.signal);
3522
- if (earlyResult) {
3523
- return attachMatch(earlyResult);
3524
- }
3525
3587
  const agent = await this.ensureEndpointDiscovered(options);
3526
3588
  throwIfAborted(options?.signal);
3527
3589
  if (!options?.skipIdempotencyAutoInject && !options?.skipAccountValidation && !options?.skipRequestValidation && !options?.preserveGovernedPayload) {
@@ -3560,11 +3622,8 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3560
3622
  capabilityDiscoveryContext.toolSchemas,
3561
3623
  capabilityDiscoveryContext.capabilities
3562
3624
  );
3563
- const v25DriftLogs = [...adaptDriftLogs];
3564
- if (webhookDriftLog) v25DriftLogs.push(webhookDriftLog);
3565
- if (serverVersion === "v2") {
3566
- this.executor.validateAdaptedRequestAgainstV2(taskType, adaptedParams, v25DriftLogs);
3567
- }
3625
+ const adaptationLogs = [...adaptDriftLogs];
3626
+ if (webhookDriftLog) adaptationLogs.push(webhookDriftLog);
3568
3627
  const canonicalInputHandler = this.canonicalCreativeInputHandler(
3569
3628
  taskType,
3570
3629
  inputHandler,
@@ -3611,7 +3670,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3611
3670
  );
3612
3671
  throwIfAborted(effectiveOptions?.signal);
3613
3672
  if (!result.success) await this.invalidateDiscoveryOnCapabilityError(result.adcpError?.code, effectiveOptions);
3614
- const postAdapterLogs = [...inputSchemaStripLogs, ...v25DriftLogs];
3673
+ const postAdapterLogs = [...inputSchemaStripLogs, ...adaptationLogs];
3615
3674
  if (postAdapterLogs.length > 0) {
3616
3675
  result.debug_logs = [...result.debug_logs ?? [], ...postAdapterLogs];
3617
3676
  }
@@ -3707,7 +3766,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3707
3766
  const rawSubmittedWaitForCompletion = result.submitted?.waitForCompletion;
3708
3767
  const finalizerLegacyFormatConverter = legacyFormatConverter ?? this.resolveLegacyFormatConverter(void 0, context.projectionCatalogs);
3709
3768
  if (result.success && result.data) {
3710
- result.data = this.normalizeResponseToV3(taskType, result.data);
3769
+ result.data = this.normalizeEstablishedResponse(taskType, result.data);
3711
3770
  }
3712
3771
  result = this.wrapProductPolicySubmittedContinuation(
3713
3772
  result,
@@ -3853,7 +3912,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3853
3912
  };
3854
3913
  }
3855
3914
  projectCanonicalCreativeData(taskType, data, transform, legacyFormatConverter) {
3856
- let projected = this.normalizeResponseToV3(taskType, data);
3915
+ let projected = this.normalizeEstablishedResponse(taskType, data);
3857
3916
  const record = projected && typeof projected === "object" ? projected : void 0;
3858
3917
  const canProjectRead = taskType === "get_products" ? Array.isArray(record?.products) : taskType === "list_creatives" ? Array.isArray(record?.creatives) : true;
3859
3918
  if (transform && canProjectRead) {
@@ -4223,39 +4282,40 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4223
4282
  message = "Property list not adhered to",
4224
4283
  enforceRequestPropertyList = true,
4225
4284
  propertyListResolveOptions,
4285
+ resolvePublisherProperties,
4286
+ maxPublisherLookups = 100,
4287
+ publisherLookupTimeoutMs = 1e4,
4288
+ publisherLookupBudgetMs = 1e4,
4226
4289
  ...explicitPolicy
4227
4290
  } = policyConfig || {};
4228
4291
  const policy = {
4229
4292
  ...explicitPolicy
4230
4293
  };
4231
4294
  let resolvedRequestPropertyList;
4232
- if (requestPropertyList && enforceRequestPropertyList) {
4295
+ const referenceError = propertyListReferenceError(requestParams);
4296
+ if ((requestPropertyList || referenceError) && enforceRequestPropertyList) {
4233
4297
  try {
4298
+ if (referenceError) throw new Error(referenceError);
4234
4299
  const resolved = await resolvePropertyList(requestPropertyList, propertyListResolveOptions);
4235
- const comparableIdentifiers = comparablePropertyIdentifiers(resolved.identifiers);
4236
4300
  const unsupportedIdentifiers = unsupportedPropertyIdentifiers(resolved.identifiers);
4237
- if (unsupportedIdentifiers.length > 0) {
4238
- throw new Error("property_list_unsupported_identifier_types");
4239
- }
4240
- if (comparableIdentifiers.length > 0 || resolved.identifiers.length === 0) {
4241
- policy.allowedPropertyIdentifiers = [...policy.allowedPropertyIdentifiers ?? [], ...comparableIdentifiers];
4242
- policy.requireAllowedPropertyMatch = true;
4243
- }
4301
+ policy.allowedPropertyIdentifiers = [...policy.allowedPropertyIdentifiers ?? [], ...resolved.identifiers];
4302
+ policy.requireAllowedPropertyMatch = true;
4244
4303
  policy.strict = policy.strict ?? true;
4245
4304
  resolvedRequestPropertyList = {
4246
4305
  listId: resolved.listId,
4247
4306
  agentUrl: resolved.agentUrl,
4248
4307
  identifierCount: resolved.identifiers.length,
4308
+ unsupportedIdentifierTypes: [...new Set(unsupportedIdentifiers.map((identifier) => identifier.type))],
4249
4309
  ...resolved.cacheValidUntil ? { cacheValidUntil: resolved.cacheValidUntil } : {}
4250
4310
  };
4251
4311
  } catch (err) {
4252
4312
  const errorCode = propertyListResolutionErrorCode(err);
4253
- const diagnosticAgentUrl = sanitizeDiagnosticUrl(requestPropertyList.agent_url);
4313
+ const diagnosticAgentUrl = requestPropertyList ? sanitizeDiagnosticUrl(requestPropertyList.agent_url) : "invalid_url";
4254
4314
  return attachMatch({
4255
4315
  success: false,
4256
4316
  status: "failed",
4257
4317
  data: response,
4258
- error: `${message}: could not resolve property_list ${requestPropertyList.list_id}`,
4318
+ error: `${message}: could not resolve property_list`,
4259
4319
  metadata: {
4260
4320
  ...result.metadata,
4261
4321
  status: "failed",
@@ -4268,7 +4328,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4268
4328
  message,
4269
4329
  diagnostics: [],
4270
4330
  request_property_list: {
4271
- list_id: requestPropertyList.list_id,
4331
+ list_id: requestPropertyList?.list_id ?? "invalid_reference",
4272
4332
  agent_url: diagnosticAgentUrl,
4273
4333
  resolution_error: errorCode
4274
4334
  }
@@ -4283,7 +4343,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4283
4343
  mode,
4284
4344
  ok: false,
4285
4345
  request_property_list: {
4286
- list_id: requestPropertyList.list_id,
4346
+ list_id: requestPropertyList?.list_id,
4287
4347
  agent_url: diagnosticAgentUrl,
4288
4348
  resolution_error: errorCode
4289
4349
  }
@@ -4293,6 +4353,65 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4293
4353
  }
4294
4354
  }
4295
4355
  if (!hasProductPropertyPolicyRules(policy)) return result;
4356
+ if (resolvePublisherProperties && policy.allowedPropertyIdentifiers?.some(
4357
+ (identifier) => identifier.type !== "domain" && identifier.type !== "subdomain"
4358
+ )) {
4359
+ if (!Number.isSafeInteger(maxPublisherLookups) || maxPublisherLookups < 1 || !Number.isSafeInteger(publisherLookupTimeoutMs) || publisherLookupTimeoutMs < 1 || publisherLookupTimeoutMs > 2147483647 || !Number.isSafeInteger(publisherLookupBudgetMs) || publisherLookupBudgetMs < 1 || publisherLookupBudgetMs > 2147483647) {
4360
+ throw new ConfigurationError("Publisher lookup limits must be positive bounded integers");
4361
+ }
4362
+ const { validatePublisherDomain } = await import("../identifiers.mjs");
4363
+ const catalogs = Object.assign(
4364
+ /* @__PURE__ */ Object.create(null),
4365
+ policy.publisherProperties
4366
+ );
4367
+ const domains = new Set(
4368
+ response.products.flatMap(
4369
+ (product) => Array.isArray(product.publisher_properties) ? product.publisher_properties.flatMap(
4370
+ (selector) => selector && typeof selector === "object" && "publisher_domain" in selector ? [selector.publisher_domain] : []
4371
+ ) : []
4372
+ )
4373
+ );
4374
+ const hosts = [
4375
+ ...new Set(
4376
+ [...domains].flatMap(
4377
+ (domain) => typeof domain === "string" ? [normalizeDomainForPropertyPolicy(domain)?.host] : []
4378
+ )
4379
+ )
4380
+ ].filter((host) => typeof host === "string" && !Object.hasOwn(catalogs, host));
4381
+ for (const host of hosts) catalogs[host] = void 0;
4382
+ const lookupStartedAt = performance.now();
4383
+ for (const host of hosts.slice(0, maxPublisherLookups)) {
4384
+ throwIfAborted(taskSignal);
4385
+ const remainingBudgetMs = publisherLookupBudgetMs - (performance.now() - lookupStartedAt);
4386
+ if (remainingBudgetMs <= 0) break;
4387
+ if (!validatePublisherDomain(host).ok || isLikelyPrivateUrl(`https://${host}`)) continue;
4388
+ const controller = new AbortController();
4389
+ const signal = taskSignal ? AbortSignal.any([taskSignal, controller.signal]) : controller.signal;
4390
+ let timeout;
4391
+ let budgetExpired = false;
4392
+ try {
4393
+ catalogs[host] = await Promise.race([
4394
+ resolvePublisherProperties(host, { signal }),
4395
+ new Promise((_, reject) => {
4396
+ timeout = setTimeout(
4397
+ () => {
4398
+ if (remainingBudgetMs <= publisherLookupTimeoutMs) budgetExpired = true;
4399
+ controller.abort();
4400
+ reject(new Error("publisher_catalog_timeout"));
4401
+ },
4402
+ Math.min(publisherLookupTimeoutMs, remainingBudgetMs)
4403
+ );
4404
+ })
4405
+ ]);
4406
+ } catch {
4407
+ catalogs[host] = void 0;
4408
+ } finally {
4409
+ if (timeout) clearTimeout(timeout);
4410
+ }
4411
+ if (budgetExpired) break;
4412
+ }
4413
+ policy.publisherProperties = catalogs;
4414
+ }
4296
4415
  let validation;
4297
4416
  try {
4298
4417
  validation = validateProductsAgainstPropertyPolicy({
@@ -4316,6 +4435,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4316
4435
  list_id: resolvedRequestPropertyList.listId,
4317
4436
  agent_url: sanitizeDiagnosticUrl(resolvedRequestPropertyList.agentUrl),
4318
4437
  identifier_count: resolvedRequestPropertyList.identifierCount,
4438
+ unsupported_identifier_types: resolvedRequestPropertyList.unsupportedIdentifierTypes,
4319
4439
  ...resolvedRequestPropertyList.cacheValidUntil ? { cache_valid_until: resolvedRequestPropertyList.cacheValidUntil } : {}
4320
4440
  }
4321
4441
  } : {},
@@ -4465,7 +4585,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4465
4585
  waitForCompletion: async (pollInterval, signal) => {
4466
4586
  let completed = await submitted.waitForCompletion(pollInterval, signal);
4467
4587
  if (completed.success && completed.data) {
4468
- completed.data = this.normalizeResponseToV3(taskType, completed.data);
4588
+ completed.data = this.normalizeEstablishedResponse(taskType, completed.data);
4469
4589
  }
4470
4590
  const terminal = completed.status === "completed" || completed.status === "failed";
4471
4591
  try {
@@ -4496,7 +4616,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4496
4616
  attachMatch({
4497
4617
  success: true,
4498
4618
  status: "completed",
4499
- data: this.normalizeResponseToV3(taskType, taskInfo.result),
4619
+ data: this.normalizeEstablishedResponse(taskType, taskInfo.result),
4500
4620
  metadata: {
4501
4621
  taskId: taskInfo.taskId,
4502
4622
  taskName: taskInfo.taskType,
@@ -4572,8 +4692,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4572
4692
  }
4573
4693
  /**
4574
4694
  * Adapt a request for the detected server wire version and the seller's
4575
- * AdCP protocol version. Applies wire-format adapters (v2.5) when talking
4576
- * to a v2 server, then applies protocol-version adapters (e.g. stripping
4695
+ * AdCP protocol version. Applies protocol-version adapters (e.g. stripping
4577
4696
  * 3.1-only fields for a 3.0 seller). Returns the adapted params and any
4578
4697
  * drift log entries describing what was changed.
4579
4698
  *
@@ -4581,22 +4700,14 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4581
4700
  * current call's tool schemas can be supplied without cross-tenant caching.
4582
4701
  */
4583
4702
  adaptRequest(taskType, params, serverVersion, debugLogs, perCallToolSchemas, perCallCapabilities) {
4584
- const driftLogs = [];
4585
- let adapted = params;
4586
4703
  if (serverVersion !== "v3") {
4587
- const pair = getV25Adapter(taskType);
4588
- if (pair) adapted = pair.adaptRequest(adapted);
4704
+ throw new VersionUnsupportedError(taskType, "version", "v2", this.agent.agent_uri);
4589
4705
  }
4706
+ const driftLogs = [];
4707
+ let adapted = params;
4590
4708
  const toolSchema = (perCallToolSchemas ?? this.cachedToolSchemas)?.get(taskType);
4591
4709
  if (toolSchema && Object.keys(toolSchema).length > 0) {
4592
4710
  const declaredFields = new Set(Object.keys(toolSchema));
4593
- const adapterAliases = [["brand_manifest", "brand"]];
4594
- for (const [adapterField, schemaField] of adapterAliases) {
4595
- if (adapted[adapterField] !== void 0 && !declaredFields.has(adapterField) && declaredFields.has(schemaField) && adapted[schemaField] === void 0 && valueMatchesSchemaType(adapted[adapterField], toolSchema[schemaField])) {
4596
- adapted[schemaField] = adapted[adapterField];
4597
- delete adapted[adapterField];
4598
- }
4599
- }
4600
4711
  const envelopeFields = ADCP_ENVELOPE_FIELDS;
4601
4712
  const filtered = {};
4602
4713
  const schemaStripped = [];
@@ -4644,67 +4755,19 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4644
4755
  }
4645
4756
  return { params: adapted, driftLogs };
4646
4757
  }
4647
- /**
4648
- * Normalize response to v3 format
4649
- *
4650
- * Converts v2 responses to v3 structure for consistent API surface.
4651
- */
4652
- normalizeResponseToV3(taskType, data) {
4653
- const pair = getV25Adapter(taskType);
4654
- if (pair?.normalizeResponse) return pair.normalizeResponse(data);
4655
- return data;
4656
- }
4657
- /**
4658
- * Check if request uses v3 features that the server doesn't support
4659
- *
4660
- * Returns an early empty result if the request requires v3 features
4661
- * that the server doesn't support. This treats "products matching unsupported
4662
- * capability" as an empty result set rather than an error.
4663
- *
4664
- * @returns TaskResult with empty data if v3 features are unsupported, null to proceed normally
4665
- */
4666
- async getEarlyResultForUnsupportedFeatures(taskType, params, options) {
4667
- if (taskType !== "get_products") {
4668
- return null;
4669
- }
4670
- const capabilities = await this.getCapabilities(options);
4671
- if (capabilities.version === "v3") {
4672
- return null;
4673
- }
4674
- const usesUnsupportedFeature = (
4675
- // required_features: content_standards requires contentStandards
4676
- params.filters?.required_features?.includes("content_standards") && !capabilities.features.contentStandards
4677
- );
4678
- if (!usesUnsupportedFeature) {
4679
- return null;
4758
+ normalizeEstablishedResponse(taskType, data) {
4759
+ if (!data) return data;
4760
+ switch (taskType) {
4761
+ case "get_products":
4762
+ return normalizeGetProductsResponse(data);
4763
+ case "create_media_buy":
4764
+ case "update_media_buy":
4765
+ return normalizeMediaBuyResponse(data);
4766
+ case "list_creative_formats":
4767
+ return normalizeFormatsResponse(data);
4768
+ default:
4769
+ return data;
4680
4770
  }
4681
- console.warn(
4682
- `[AdCP] v3-only features not supported by server "${this.agent.id}" (${capabilities.version}). Returning empty results.`
4683
- );
4684
- const emptyResponse = {
4685
- products: [],
4686
- property_list_applied: false
4687
- };
4688
- return {
4689
- success: true,
4690
- status: "completed",
4691
- data: emptyResponse,
4692
- metadata: {
4693
- taskId: `early_${Date.now()}`,
4694
- taskName: taskType,
4695
- agent: {
4696
- id: this.agent.id,
4697
- name: this.agent.name,
4698
- protocol: this.normalizedAgent.protocol
4699
- },
4700
- responseTimeMs: 0,
4701
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4702
- clarificationRounds: 0,
4703
- status: "completed",
4704
- serverVersion: capabilities.version,
4705
- serverVersionSynthetic: capabilities._synthetic
4706
- }
4707
- };
4708
4771
  }
4709
4772
  // ====== MEDIA BUY TASKS ======
4710
4773
  /**
@@ -4804,6 +4867,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4804
4867
  }
4805
4868
  }
4806
4869
  const conditionalSnapshot = skipCacheRead ? void 0 : cache?.read(cacheScope, cacheParams, true);
4870
+ const productEvidence = this.usesScopedDiscoveryTransport(
4871
+ effectiveOptions
4872
+ ) ? void 0 : {
4873
+ scopeKey: this.getCapabilityEvidenceScope().scopeKey,
4874
+ accountScope: this.canonicalAccountScope(account),
4875
+ expiresAt: Date.now() + resolveAgentDiscoveryTtlMs(this.config.discoveryCache?.ttlMs)
4876
+ };
4807
4877
  const result = await this.executeAndHandle(
4808
4878
  "get_products",
4809
4879
  "onGetProductsStatusChange",
@@ -4816,7 +4886,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4816
4886
  projectionCatalogs: projectionCatalogs ?? this.config.projectionCatalogs
4817
4887
  });
4818
4888
  const authoritativeProducts = Array.isArray(data.products) ? data.products : response.products;
4819
- this.rememberCanonicalProductRoutes(response.products, account, authoritativeProducts);
4889
+ this.rememberCanonicalProductRoutes(response.products, account, authoritativeProducts, productEvidence);
4820
4890
  const { _message: _dropLegacyMessage, ...canonical } = response;
4821
4891
  void _dropLegacyMessage;
4822
4892
  return { ...canonical, projection: { diagnostics } };
@@ -4827,7 +4897,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4827
4897
  );
4828
4898
  const finishCache = async (completed) => {
4829
4899
  if (!cache) return completed;
4830
- const cachedResult = cache.write(cacheScope, cacheParams, completed, conditionalSnapshot);
4900
+ const cachedResult = cache.write(cacheScope, cacheParams, completed, conditionalSnapshot, (materialized) => {
4901
+ this.rememberCanonicalProductRoutes(materialized.data?.products ?? [], account, void 0, productEvidence);
4902
+ });
4831
4903
  if (cachedResult.success && cachedResult.status === "completed") {
4832
4904
  if (!skipCacheRead && cacheParams.if_wholesale_feed_version === void 0 && cacheParams.if_pricing_version === void 0 && cachedResult.data.unchanged === true) {
4833
4905
  return this.getProducts(params, inputHandler, {
@@ -5005,7 +5077,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
5005
5077
  if (hasCreativeFormatData) {
5006
5078
  this.validateBeforeCreativeCapabilityProbe("create_media_buy", params, taskOptions);
5007
5079
  }
5008
- const wireMode = hasCreativeFormatData ? await this.resolveCreativeFormatWireMode("create_media_buy", taskOptions) : "canonical";
5080
+ const wireMode = hasCreativeFormatData ? await this.resolveCreativeWireMode(
5081
+ "create_media_buy",
5082
+ taskOptions,
5083
+ true,
5084
+ () => this.productOptionsSupportCanonicalWire("create_media_buy", params, [], options)
5085
+ ) : "canonical";
5009
5086
  const wireParams = params;
5010
5087
  const result = await this.executeAndHandle(
5011
5088
  "create_media_buy",
@@ -5093,7 +5170,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
5093
5170
  if (hasCreativeFormatData) {
5094
5171
  this.validateBeforeCreativeCapabilityProbe("update_media_buy", params, taskOptions);
5095
5172
  }
5096
- const wireMode = hasCreativeFormatData ? await this.resolveCreativeFormatWireMode("update_media_buy", taskOptions) : "canonical";
5173
+ const wireMode = hasCreativeFormatData ? await this.resolveCreativeWireMode(
5174
+ "update_media_buy",
5175
+ taskOptions,
5176
+ true,
5177
+ () => this.productOptionsSupportCanonicalWire("update_media_buy", params, [], options)
5178
+ ) : "canonical";
5097
5179
  const result = await this.executeAndHandle(
5098
5180
  "update_media_buy",
5099
5181
  "onUpdateMediaBuyStatusChange",
@@ -5182,7 +5264,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
5182
5264
  projectionCatalogs ?? this.config.projectionCatalogs
5183
5265
  );
5184
5266
  this.validateBeforeCreativeCapabilityProbe("sync_creatives", params, taskOptions);
5185
- const wireMode = await this.resolveCreativeFormatWireMode("sync_creatives", taskOptions);
5186
5267
  const configuredSelectorContainers = [
5187
5268
  ...creativeFormatProjection?.selectorContainers ?? []
5188
5269
  ];
@@ -5194,10 +5275,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
5194
5275
  const assignmentPackageContainers = Array.isArray(params.assignments) ? params.assignments.flatMap(
5195
5276
  (assignment) => typeof assignment.package_id === "string" && !configuredPackageIds.has(assignment.package_id) ? [{ package_id: assignment.package_id }] : []
5196
5277
  ) : [];
5278
+ const selectorContainers = [...configuredSelectorContainers, ...assignmentPackageContainers];
5279
+ const wireMode = await this.resolveCreativeWireMode(
5280
+ "sync_creatives",
5281
+ taskOptions,
5282
+ true,
5283
+ () => this.productOptionsSupportCanonicalWire("sync_creatives", params, selectorContainers, options)
5284
+ );
5197
5285
  const wireParams = this.projectUndeclaredFormatOptions(
5198
5286
  projectSyncCreativesForDelivery(
5199
5287
  params,
5200
- [...configuredSelectorContainers, ...assignmentPackageContainers],
5288
+ selectorContainers,
5201
5289
  wireMode,
5202
5290
  effectiveLegacyFormatConverter,
5203
5291
  effectiveCanonicalFormatLegacyResolver
@@ -5237,16 +5325,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
5237
5325
  * sending a mutation. Discovers capabilities and the current tool's input
5238
5326
  * schema, or reuses fresh cached/primed evidence, with this client's wire pin.
5239
5327
  *
5240
- * `unknown` preserves the conservative legacy projection for older peers
5241
- * whose capabilities and schema do not establish support. Projection still
5242
- * requires an unambiguous legacy reference for each creative in that case.
5328
+ * This context-free check returns `unknown` when capabilities and schema do
5329
+ * not establish support. A write to a proven 3.1 seller can still select
5330
+ * canonical delivery from matching seller-advertised product options;
5331
+ * otherwise projection requires an unambiguous legacy reference.
5243
5332
  * Conflicting evidence and unproven support with a 3.2+ buyer pin throw
5244
5333
  * `CreativeFormatCapabilityError`, just as they do during a write.
5245
5334
  */
5246
5335
  async resolveCreativeFormatWireMode(taskType, options) {
5247
5336
  return this.resolveCreativeWireMode(taskType, options, true);
5248
5337
  }
5249
- async resolveCreativeWireMode(taskType, options, canRediscover) {
5338
+ async resolveCreativeWireMode(taskType, options, canRediscover, matchingProductOptions) {
5250
5339
  const discoveryContext = {};
5251
5340
  const capabilities = await this.getCapabilities({
5252
5341
  ...options,
@@ -5265,13 +5354,16 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
5265
5354
  `Seller capability and ${taskType} input schema disagree about canonical creative support`
5266
5355
  );
5267
5356
  }
5268
- const resolved = declared !== "unknown" ? declared : schema;
5357
+ let resolved = declared !== "unknown" ? declared : schema;
5358
+ if (resolved === "unknown" && canUseProductOptionsForCreativeWire(capabilities, wireRelease) && matchingProductOptions?.()) {
5359
+ resolved = "canonical";
5360
+ }
5269
5361
  const release = /^v?(\d+)\.(\d+)(?:\.|-|$)/.exec(wireRelease.trim());
5270
5362
  const canonicalRequiredByBuyerPin = release !== null && (Number(release[1]) > 3 || Number(release[1]) === 3 && Number(release[2]) >= 2);
5271
5363
  if (resolved === "unknown" && canonicalRequiredByBuyerPin) {
5272
5364
  if (canRediscover && !usesScopedFetch && this.normalizedAgent.protocol === "mcp" && this.capabilitiesFromSharedCache && toolSchemas?.has(taskType) && !toolInputSchemasByProperties.has(toolSchemas)) {
5273
5365
  await this.invalidateDiscoveryCache(options);
5274
- return this.resolveCreativeWireMode(taskType, options, false);
5366
+ return this.resolveCreativeWireMode(taskType, options, false, matchingProductOptions);
5275
5367
  }
5276
5368
  throw new CreativeFormatCapabilityError(
5277
5369
  `Cannot prove which AdCP release the seller serves for ${taskType}; a 3.2+ client will not guess a legacy creative wire shape`
@@ -5279,6 +5371,112 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
5279
5371
  }
5280
5372
  return resolved;
5281
5373
  }
5374
+ /** Product evidence applies to this request only; it must never prime a tool-wide capability. */
5375
+ productOptionsSupportCanonicalWire(taskType, request, selectorContainers = [], options) {
5376
+ if (!isPlainRecord(request) || this.usesScopedDiscoveryTransport(options)) return false;
5377
+ const scopeKey = this.getCapabilityEvidenceScope().scopeKey;
5378
+ const accountScope = this.canonicalAccountScope(request.account);
5379
+ const optionRef = (value) => {
5380
+ if (!isPlainRecord(value) || typeof value.format_option_id !== "string" || !value.format_option_id) {
5381
+ return void 0;
5382
+ }
5383
+ if (typeof value.publisher_domain === "string") {
5384
+ return {
5385
+ scope: "publisher",
5386
+ publisher_domain: value.publisher_domain,
5387
+ format_option_id: value.format_option_id
5388
+ };
5389
+ }
5390
+ if (value.scope !== void 0 && value.scope !== "product") return void 0;
5391
+ return { scope: "product", format_option_id: value.format_option_id };
5392
+ };
5393
+ const accepts = (container, creative, depth = 0) => {
5394
+ if (depth > 32) return false;
5395
+ if (Array.isArray(container.selector_containers)) {
5396
+ return container.selector_containers.length > 0 && container.selector_containers.every((nested) => accepts(nested, creative, depth + 1));
5397
+ }
5398
+ const refs = Array.isArray(container.format_option_refs) ? container.format_option_refs.map(optionRef) : [];
5399
+ if (refs.some((ref) => ref === void 0)) return false;
5400
+ const creativeRef = isPlainRecord(creative) ? optionRef(creative.format_option_ref) : void 0;
5401
+ if (isPlainRecord(creative) && creative.format_option_ref !== void 0 && !creativeRef) return false;
5402
+ const isSellerDeclaration = (value) => {
5403
+ if (!isPlainRecord(value) || sellerDeclaredFormatOption(value) !== true || isSynthesizedFormatOption(value)) {
5404
+ return false;
5405
+ }
5406
+ const evidence2 = sellerFormatEvidence(value);
5407
+ if (!evidence2 || evidence2.scopeKey !== scopeKey || typeof container.product_id === "string" && evidence2.productId !== container.product_id || evidence2.expiresAt <= Date.now() || evidence2.accountScope !== accountScope && evidence2.accountScope !== "none")
5408
+ return false;
5409
+ const ref = optionRef(value);
5410
+ if (ref && formatOptionOriginFromRoutes(
5411
+ options?.canonicalFormatLegacyResolver,
5412
+ ref,
5413
+ typeof container.product_id === "string" ? container.product_id : void 0
5414
+ )?.seller_declared === false)
5415
+ return false;
5416
+ return !ref || typeof container.product_id !== "string" || this.cachedFormatOptionOrigin(request.account, ref, container.product_id)?.seller_declared !== false;
5417
+ };
5418
+ const declarations = [
5419
+ ...(Array.isArray(container.format_options) ? container.format_options : []).filter(isSellerDeclaration),
5420
+ ...selectedFormatOptions(container).filter(isSellerDeclaration)
5421
+ ];
5422
+ if (typeof container.product_id === "string") {
5423
+ for (const ref of [...refs, ...creativeRef ? [creativeRef] : []]) {
5424
+ if (!ref) continue;
5425
+ const route = this.routeForOption(request.account, container.product_id, ref);
5426
+ if (route?.kind === "product" && route.declaration && isSellerDeclaration(route.declaration))
5427
+ declarations.push(route.declaration);
5428
+ }
5429
+ }
5430
+ const available = declarations.filter((declaration) => declaration.experimental !== true);
5431
+ const matchesRef = (declaration, ref) => {
5432
+ const declaredRef = optionRef(declaration);
5433
+ return declaredRef !== void 0 && sameFormatOptionRef(declaredRef, ref);
5434
+ };
5435
+ if (!refs.every((ref) => available.some((declaration) => matchesRef(declaration, ref)))) return false;
5436
+ const selected = available.filter(
5437
+ (declaration) => refs.length === 0 || refs.some((ref) => matchesRef(declaration, ref))
5438
+ );
5439
+ if (creative === void 0) return refs.length > 0 && selected.length > 0;
5440
+ if (!isPlainRecord(creative) || typeof creative.format_kind !== "string" || creative.format_id !== void 0)
5441
+ return false;
5442
+ return selected.some(
5443
+ (declaration) => declaration.format_kind === creative.format_kind && (!creativeRef || matchesRef(declaration, creativeRef)) && creativeMatchesProductOption(creative, declaration)
5444
+ );
5445
+ };
5446
+ if (taskType === "sync_creatives") {
5447
+ if (!Array.isArray(request.creatives) || request.creatives.length === 0) return false;
5448
+ const creatives = request.creatives;
5449
+ const assignments = Array.isArray(request.assignments) ? request.assignments : [];
5450
+ if (!assignments.every(
5451
+ (value) => isPlainRecord(value) && typeof value.package_id === "string" && typeof value.creative_id === "string" && creatives.some((creative) => isPlainRecord(creative) && creative.creative_id === value.creative_id)
5452
+ ))
5453
+ return false;
5454
+ return creatives.every((creative) => {
5455
+ if (!isPlainRecord(creative)) return false;
5456
+ const assigned = new Set(
5457
+ assignments.flatMap(
5458
+ (value) => isPlainRecord(value) && value.creative_id === creative.creative_id && typeof value.package_id === "string" ? [value.package_id] : []
5459
+ )
5460
+ );
5461
+ const relevant = assigned.size === 0 ? selectorContainers : selectorContainers.filter(
5462
+ (container) => typeof container.package_id === "string" && assigned.has(container.package_id)
5463
+ );
5464
+ return relevant.length > 0 && [...assigned].every((id) => relevant.some((container) => container.package_id === id)) && relevant.every((container) => accepts(container, creative));
5465
+ });
5466
+ }
5467
+ const packages = ["packages", "new_packages"].flatMap((key) => Array.isArray(request[key]) ? request[key] : []);
5468
+ let evidence = false;
5469
+ return packages.length > 0 && packages.every((pkg) => {
5470
+ if (!isPlainRecord(pkg)) return false;
5471
+ const creatives = Array.isArray(pkg.creatives) ? pkg.creatives : [];
5472
+ const hasSelectors = Array.isArray(pkg.format_option_refs) && pkg.format_option_refs.length > 0;
5473
+ if (!hasSelectors && creatives.length === 0) {
5474
+ return pkg.format_kind === void 0 && pkg.format_ids === void 0;
5475
+ }
5476
+ evidence = true;
5477
+ return (!hasSelectors || accepts(pkg)) && creatives.every((creative) => accepts(pkg, creative));
5478
+ }) && evidence;
5479
+ }
5282
5480
  /** Validate malformed creative payloads before capability discovery can perform I/O. */
5283
5481
  validateBeforeCreativeCapabilityProbe(taskType, params, options) {
5284
5482
  if (options.skipIdempotencyAutoInject || options.skipAccountValidation || options.skipRequestValidation) return;
@@ -6187,11 +6385,8 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
6187
6385
  capabilityDiscoveryContext.toolSchemas,
6188
6386
  capabilityDiscoveryContext.capabilities
6189
6387
  );
6190
- const v25DriftLogs = [...adaptDriftLogs];
6191
- if (webhookDriftLog) v25DriftLogs.push(webhookDriftLog);
6192
- if (serverVersion === "v2") {
6193
- this.executor.validateAdaptedRequestAgainstV2(taskName, adaptedParams, v25DriftLogs);
6194
- }
6388
+ const adaptationLogs = [...adaptDriftLogs];
6389
+ if (webhookDriftLog) adaptationLogs.push(webhookDriftLog);
6195
6390
  const deferredClientContext = {
6196
6391
  kind: "single-agent",
6197
6392
  taskType: taskName,
@@ -6221,7 +6416,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
6221
6416
  deferredClientContext
6222
6417
  );
6223
6418
  if (!result.success) await this.invalidateDiscoveryOnCapabilityError(result.adcpError?.code, effectiveOptions);
6224
- const postAdapterLogs = [...inputSchemaStripLogs, ...v25DriftLogs];
6419
+ const postAdapterLogs = [...inputSchemaStripLogs, ...adaptationLogs];
6225
6420
  if (postAdapterLogs.length > 0) {
6226
6421
  result.debug_logs = [...result.debug_logs ?? [], ...postAdapterLogs];
6227
6422
  }
@@ -6411,6 +6606,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
6411
6606
  getProtocol() {
6412
6607
  return this.normalizedAgent.protocol;
6413
6608
  }
6609
+ /** Resolved MCP endpoint already used by this client; never performs discovery. */
6610
+ getDiscoveredMcpEndpoint() {
6611
+ return this.discoveredEndpoint;
6612
+ }
6414
6613
  /**
6415
6614
  * Get the canonical base URL for this agent
6416
6615
  *
@@ -6912,7 +7111,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
6912
7111
  * Get agent capabilities, including AdCP version support
6913
7112
  *
6914
7113
  * For v3 servers, calls get_adcp_capabilities tool.
6915
- * For v2 servers, builds synthetic capabilities from available tools.
7114
+ * Requires AdCP 3 capability discovery; retired AdCP 2 agents are rejected.
6916
7115
  *
6917
7116
  * @returns Promise resolving to normalized capabilities object
6918
7117
  *
@@ -6949,7 +7148,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
6949
7148
  }
6950
7149
  if (!usesScopedFetch && this.cachedCapabilities) {
6951
7150
  if (discoveryContext) discoveryContext.toolSchemas = this.cachedToolSchemas;
6952
- this.maybeWarnV2Sunset(this.cachedCapabilities);
7151
+ this.assertSupportedServer(this.cachedCapabilities);
6953
7152
  return this.cachedCapabilities;
6954
7153
  }
6955
7154
  if (!usesScopedFetch && this.config.discoveryCache) {
@@ -7033,7 +7232,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7033
7232
  this.capabilitiesFromSharedCache = true;
7034
7233
  this.recordSharedEvidence(key);
7035
7234
  if (discoveryContext) discoveryContext.toolSchemas = this.cachedToolSchemas;
7036
- this.maybeWarnV2Sunset(installed);
7235
+ this.assertSupportedServer(installed);
7037
7236
  return installed;
7038
7237
  }
7039
7238
  async discoverCapabilitiesLive(options, usesScopedFetch, discoveryContext) {
@@ -7083,16 +7282,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7083
7282
  throw createTimeoutError(requestTimeoutMs);
7084
7283
  }
7085
7284
  if (result.success && result.data) {
7086
- const capabilities2 = augmentCapabilitiesFromTools(parseCapabilitiesResponse(result.data), tools);
7285
+ const capabilities = augmentCapabilitiesFromTools(parseCapabilitiesResponse(result.data), tools);
7286
+ this.assertSupportedServer(capabilities);
7087
7287
  if (!usesScopedFetch && !superseded()) {
7088
- this.cachedCapabilities = capabilities2;
7288
+ this.cachedCapabilities = capabilities;
7089
7289
  this.capabilitiesFromSharedCache = false;
7090
- if (!capabilities2._synthetic && this.config.discoveryCache) {
7290
+ if (!capabilities._synthetic && this.config.discoveryCache) {
7091
7291
  this.recordSharedEvidence(this.sharedDiscoveryKey(options));
7092
7292
  const stored = await this.writeSharedDiscovery(
7093
7293
  options,
7094
7294
  {
7095
- capabilities: structuredClone(capabilities2),
7295
+ capabilities: structuredClone(capabilities),
7096
7296
  toolSchemas: Object.fromEntries(discoveredToolSchemas),
7097
7297
  toolInputSchemas: Object.fromEntries(discoveredInputSchemas)
7098
7298
  },
@@ -7100,7 +7300,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7100
7300
  startedAtEpoch
7101
7301
  );
7102
7302
  if (superseded()) {
7103
- if (this.cachedCapabilities === capabilities2) {
7303
+ if (this.cachedCapabilities === capabilities) {
7104
7304
  this.cachedCapabilities = void 0;
7105
7305
  this.cachedToolSchemas = void 0;
7106
7306
  this.primedCapabilitiesExpiresAt = void 0;
@@ -7110,31 +7310,26 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7110
7310
  }
7111
7311
  }
7112
7312
  }
7113
- this.maybeWarnV2Sunset(capabilities2);
7114
- return capabilities2;
7313
+ this.assertSupportedServer(capabilities);
7314
+ return capabilities;
7115
7315
  }
7116
7316
  if (!advertisesCapabilitiesTool) {
7117
7317
  throw new Error("unadvertised official A2A capability probe was not supported");
7118
7318
  }
7119
7319
  if (result.data && looksLikeV3Capabilities(result.data)) {
7320
+ const capabilities = augmentCapabilitiesFromTools(parseCapabilitiesResponse(result.data), tools);
7321
+ this.assertSupportedServer(capabilities);
7120
7322
  console.warn(
7121
7323
  `[AdCP] Agent "${this.agent.id}" returned a get_adcp_capabilities response that failed validation, but the response is structurally v3-shaped. Treating as v3 (the agent has a wire-shape bug \u2014 that's the thing to fix).`,
7122
7324
  { hasError: !!result.error, hasData: !!result.data }
7123
7325
  );
7124
- const parsed = parseCapabilitiesResponse(result.data);
7125
- const v3Capabilities = {
7126
- ...parsed,
7127
- version: "v3",
7128
- majorVersions: parsed.majorVersions.includes(3) ? parsed.majorVersions : [3]
7129
- };
7130
- const capabilities2 = augmentCapabilitiesFromTools(v3Capabilities, tools);
7131
7326
  if (!usesScopedFetch && !superseded()) {
7132
- this.cachedCapabilities = capabilities2;
7327
+ this.cachedCapabilities = capabilities;
7133
7328
  this.capabilitiesFromSharedCache = false;
7134
7329
  this.recordSharedEvidence(this.sharedDiscoveryKey(options));
7135
7330
  }
7136
- this.maybeWarnV2Sunset(capabilities2);
7137
- return capabilities2;
7331
+ this.assertSupportedServer(capabilities);
7332
+ return capabilities;
7138
7333
  }
7139
7334
  console.warn(
7140
7335
  `[AdCP] Agent "${this.agent.id}" advertises get_adcp_capabilities but the call returned non-success and the response is not v3-shaped \u2014 treating as v3 (synthetic) since the agent has the v3-only discovery tool. This client routes to v3 adapters, but calls reading capability details (idempotency TTL, supported_versions, feature flags) will fail until the agent operator fixes the capabilities endpoint.`,
@@ -7145,7 +7340,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7145
7340
  }
7146
7341
  );
7147
7342
  } catch (error) {
7148
- if (error instanceof AuthenticationRequiredError || error instanceof ConfigurationError || error instanceof TaskTimeoutError || isAbortOrTimeoutError(error)) {
7343
+ if (error instanceof AuthenticationRequiredError || error instanceof VersionUnsupportedError || error instanceof ConfigurationError || error instanceof TaskTimeoutError || isAbortOrTimeoutError(error)) {
7149
7344
  throw error;
7150
7345
  }
7151
7346
  if (advertisesCapabilitiesTool) {
@@ -7155,26 +7350,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7155
7350
  }
7156
7351
  }
7157
7352
  if (advertisesCapabilitiesTool) {
7158
- const capabilities2 = augmentCapabilitiesFromTools(buildSyntheticV3Capabilities(tools), tools);
7353
+ const capabilities = augmentCapabilitiesFromTools(buildSyntheticV3Capabilities(tools), tools);
7159
7354
  if (!usesScopedFetch && !superseded()) {
7160
- this.cachedCapabilities = capabilities2;
7355
+ this.cachedCapabilities = capabilities;
7161
7356
  this.capabilitiesFromSharedCache = false;
7162
7357
  this.recordSharedEvidence(this.sharedDiscoveryKey(options));
7163
7358
  }
7164
- this.maybeWarnV2Sunset(capabilities2);
7165
- return capabilities2;
7359
+ this.assertSupportedServer(capabilities);
7360
+ return capabilities;
7166
7361
  }
7167
7362
  }
7168
- console.warn(
7169
- `[AdCP] Agent "${this.agent.id}" detected as v2 (no get_adcp_capabilities tool). Tools: [${tools.map((t) => t.name).join(", ")}]`
7170
- );
7171
- const capabilities = buildSyntheticCapabilities(tools);
7172
- if (!usesScopedFetch && !superseded()) {
7173
- this.cachedCapabilities = capabilities;
7174
- this.capabilitiesFromSharedCache = false;
7175
- this.recordSharedEvidence(this.sharedDiscoveryKey(options));
7176
- }
7177
- return capabilities;
7363
+ throw new VersionUnsupportedError("get_adcp_capabilities", "synthetic", "v2", this.agent.agent_uri);
7178
7364
  }
7179
7365
  /**
7180
7366
  * Return the client-bound scope required by {@link primeCapabilities}.
@@ -7689,28 +7875,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7689
7875
  if (!this.config.discoveryCache || !code || !CAPABILITY_STALE_ERROR_CODES.has(code)) return;
7690
7876
  await this.invalidateDiscoveryCache(options);
7691
7877
  }
7692
- /**
7693
- * Emit a one-time warning when the agent reports v2 capabilities.
7694
- *
7695
- * v2 went unsupported on 2026-04-20 (AdCP 3.0 GA — adcp#2220). We still
7696
- * execute v2 code paths (no behaviour change), but clients integrating
7697
- * against an unsupported agent should hear about it loudly.
7698
- *
7699
- * Synthetic capabilities (no `get_adcp_capabilities` tool available) don't
7700
- * trigger the warning — we don't actually know the agent's version, and
7701
- * shouting at legitimately-unversioned agents would be noise.
7702
- *
7703
- * Suppression: `process.env.ADCP_ALLOW_V2 === '1'`.
7704
- */
7705
- maybeWarnV2Sunset(capabilities) {
7706
- if (this._v2WarningFired) return;
7707
- if (capabilities.version === "v3") return;
7708
- if (capabilities._synthetic) return;
7709
- if (process.env.ADCP_ALLOW_V2 === "1") return;
7710
- this._v2WarningFired = true;
7711
- console.warn(
7712
- `[adcp] Warning: agent ${this.agent.agent_uri} reports v2 capabilities. v2 went unsupported on 2026-04-20 (AdCP 3.0 GA). Upgrade the agent to v3 or set ADCP_ALLOW_V2=1 to suppress this warning. See https://github.com/adcontextprotocol/adcp/issues/2220`
7713
- );
7878
+ /** Reject retired protocol generations before caching or dispatching. */
7879
+ assertSupportedServer(capabilities) {
7880
+ if (capabilities.version !== "v3" || !capabilities.majorVersions.includes(3)) {
7881
+ throw new VersionUnsupportedError("get_adcp_capabilities", "version", capabilities.version, this.agent.agent_uri);
7882
+ }
7714
7883
  }
7715
7884
  /**
7716
7885
  * Warn once per client when `requireSupportedMajor` accepts synthetic v3
@@ -7731,24 +7900,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7731
7900
  `[adcp] Warning: agent ${this.agent.agent_uri} advertises get_adcp_capabilities (v3-only) but the call failed. Treating as v3 (synthetic) \u2014 version + idempotency-TTL checks skipped. Calls to getIdempotencyReplayTtlSeconds() will throw until the agent's capabilities endpoint is fixed. Report the wire-shape bug to the agent operator at ${this.agent.agent_uri}.`
7732
7901
  );
7733
7902
  }
7734
- /**
7735
- * Warn once per client when `requireSupportedMajor` routes a synthetic-v2
7736
- * seller through the v2 adapter — the agent did not expose
7737
- * `get_adcp_capabilities`, so the version was inferred from `tools/list`.
7738
- * A compliant v3 seller would declare itself; absence of a declaration is
7739
- * read as v2. Idempotency-TTL guarantees are unknown for these sellers,
7740
- * so BYOK retry callers should treat them as such.
7741
- *
7742
- * One-shot via `_syntheticV2WarningFired` (matches `maybeWarnV2Sunset`
7743
- * cadence).
7744
- */
7745
- maybeWarnSyntheticV2() {
7746
- if (this._syntheticV2WarningFired) return;
7747
- this._syntheticV2WarningFired = true;
7748
- console.warn(
7749
- `[adcp] Warning: agent ${this.agent.agent_uri} does not expose get_adcp_capabilities. Routing as v2 (synthetic) \u2014 idempotency-TTL guarantee is unknown. Ask the agent operator to declare v3 via get_adcp_capabilities if v3 routing is intended. Branch on client.isSyntheticV2() to tighten retry policies for these sellers.`
7750
- );
7751
- }
7752
7903
  /**
7753
7904
  * Detect server AdCP version
7754
7905
  *
@@ -7758,36 +7909,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7758
7909
  const capabilities = await this.getCapabilities(options);
7759
7910
  const discoveryContext = options?.[CAPABILITY_DISCOVERY_CONTEXT];
7760
7911
  if (discoveryContext) discoveryContext.capabilities = capabilities;
7912
+ this.assertSupportedServer(capabilities);
7761
7913
  return capabilities.version;
7762
7914
  }
7763
- /**
7764
- * Whether the seller's capabilities are synthesized from `tools/list`
7765
- * with no authoritative `get_adcp_capabilities` response — i.e. the
7766
- * dispatcher routes through the v2 adapter and idempotency-TTL is
7767
- * unknown. Use this to gate retry behavior for sellers whose retry
7768
- * safety can't be derived from declared capabilities (lower attempt
7769
- * caps, longer backoff, or fall back to natural-key recovery).
7770
- *
7771
- * Returns `false` for declared v2 sellers, declared v3 sellers, and
7772
- * synthetic v3 sellers (which advertise the v3 discovery tool even
7773
- * when the call itself failed).
7774
- *
7775
- * Caveat for synthetic v3: the predicate returns `false`, but TTL is
7776
- * still unknown for those sellers — `getIdempotencyReplayTtlSeconds()`
7777
- * throws until the agent's capabilities endpoint is fixed (issue
7778
- * #1217). Retry-policy consumers that need a complete "TTL unknown"
7779
- * gate should additionally check `getCapabilities()._synthetic`.
7780
- */
7781
- async isSyntheticV2() {
7782
- const capabilities = await this.getCapabilities();
7783
- return capabilities._synthetic === true && capabilities.version === "v2";
7784
- }
7785
7915
  /**
7786
7916
  * Check if server supports a specific AdCP major version
7787
7917
  */
7788
7918
  async supportsVersion(version) {
7789
7919
  const capabilities = await this.getCapabilities();
7790
- return capabilities.majorVersions.includes(version);
7920
+ return version === 3 && capabilities.majorVersions.includes(3);
7791
7921
  }
7792
7922
  /**
7793
7923
  * Return the seller's declared `adcp.idempotency.replay_ttl_seconds`.
@@ -7798,8 +7928,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7798
7928
  *
7799
7929
  * Fails closed when the seller is v3 but does not declare the field: the
7800
7930
  * spec makes the declaration REQUIRED, and silently defaulting to 24h
7801
- * would mislead buyers about retry safety. Callers on v2 servers get
7802
- * `undefined` instead of a throw — v2 pre-dates the idempotency envelope.
7931
+ * would mislead buyers about retry safety.
7803
7932
  */
7804
7933
  async getIdempotencyReplayTtlSeconds() {
7805
7934
  const capabilities = await this.getCapabilities();
@@ -7808,7 +7937,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
7808
7937
  assertValidIdempotencyReplayTtlSeconds(capabilities.idempotency.replayTtlSeconds);
7809
7938
  return capabilities.idempotency.replayTtlSeconds;
7810
7939
  }
7811
- if (capabilities.version !== "v3") return void 0;
7812
7940
  throw new ConfigurationError(
7813
7941
  `Agent "${this.agent.id}" is v3 but does not declare adcp.idempotency.replay_ttl_seconds. The spec requires this for v3 sellers \u2014 treating the agent as non-compliant rather than defaulting to 24h, which would silently mislead retry-sensitive flows.`,
7814
7942
  "adcp.idempotency.replay_ttl_seconds"
@@ -8119,28 +8247,16 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
8119
8247
  * 2. `capabilities.idempotency.replayTtlSeconds` present (spec-required
8120
8248
  * for real major-3+ sellers)
8121
8249
  *
8122
- * Sellers whose capabilities are synthesized from `tools/list` (no
8123
- * authoritative `get_adcp_capabilities` response) are treated as v2: a
8124
- * compliant v3 seller would declare itself, so absence of a declaration
8125
- * is taken as evidence of v2. The dispatcher routes the request through
8126
- * the v2 wire-shape adapter. A one-time warning surfaces the routing
8127
- * decision so adopters can audit it; retry-safety (idempotency TTL) is
8128
- * unknown for these sellers and BYOK callers should treat them as such.
8129
- *
8130
- * Per-client `allowV2: true` or, when that's undefined,
8131
- * `ADCP_ALLOW_V2=1` in the environment bypasses the guard entirely.
8250
+ * Synthetic v3 evidence is accepted only when the agent advertises discovery.
8251
+ * Agents without discovery and AdCP 2-only agents are rejected.
8132
8252
  *
8133
8253
  * Throws `VersionUnsupportedError` with the specific reason on failure.
8134
8254
  */
8135
8255
  async requireSupportedMajor(taskType = "request", options) {
8136
- if (this.isV2Allowed()) return;
8137
8256
  const capabilities = await this.getCapabilities(options);
8257
+ this.assertSupportedServer(capabilities);
8138
8258
  if (capabilities._synthetic) {
8139
- if (capabilities.version === "v3") {
8140
- this.maybeWarnSyntheticV3();
8141
- } else {
8142
- this.maybeWarnSyntheticV2();
8143
- }
8259
+ this.maybeWarnSyntheticV3();
8144
8260
  return;
8145
8261
  }
8146
8262
  const supportedVersions = capabilities.supportedVersions;
@@ -8171,10 +8287,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
8171
8287
  async requireV3(taskType = "request") {
8172
8288
  return this.requireSupportedMajor(taskType);
8173
8289
  }
8174
- isV2Allowed() {
8175
- if (this.config.allowV2 !== void 0) return this.config.allowV2 === true;
8176
- return process.env.ADCP_ALLOW_V2 === "1";
8177
- }
8178
8290
  // ====== STATIC HELPER METHODS ======
8179
8291
  /**
8180
8292
  * Query a legacy creative-agent named-format catalog.