@adcp/sdk 12.1.1 → 13.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/README.md +19 -3
  2. package/bin/adcp-fuzz.js +3 -1
  3. package/dist/lib/adapters/content-standards-adapter.d.mts +9 -9
  4. package/dist/lib/adapters/content-standards-adapter.d.ts +9 -9
  5. package/dist/lib/adapters/content-standards-adapter.d.ts.map +1 -1
  6. package/dist/lib/adapters/content-standards-adapter.js +22 -22
  7. package/dist/lib/adapters/content-standards-adapter.js.map +1 -1
  8. package/dist/lib/adapters/content-standards-adapter.mjs +18 -18
  9. package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
  10. package/dist/lib/adapters/index.d.mts +2 -2
  11. package/dist/lib/adapters/index.d.ts +2 -2
  12. package/dist/lib/adapters/index.d.ts.map +1 -1
  13. package/dist/lib/adapters/index.js +10 -10
  14. package/dist/lib/adapters/index.js.map +1 -1
  15. package/dist/lib/adapters/index.mjs +9 -9
  16. package/dist/lib/adapters/index.mjs.map +1 -1
  17. package/dist/lib/auth/oauth/provider-cache.d.mts +7 -0
  18. package/dist/lib/auth/oauth/provider-cache.d.ts +8 -0
  19. package/dist/lib/auth/oauth/provider-cache.d.ts.map +1 -0
  20. package/dist/lib/auth/oauth/provider-cache.js +44 -0
  21. package/dist/lib/auth/oauth/provider-cache.js.map +1 -0
  22. package/dist/lib/auth/oauth/provider-cache.mjs +19 -0
  23. package/dist/lib/auth/oauth/provider-cache.mjs.map +1 -0
  24. package/dist/lib/conformance/invariants/uniformError.js +1 -1
  25. package/dist/lib/conformance/invariants/uniformError.js.map +1 -1
  26. package/dist/lib/conformance/invariants/uniformError.mjs +1 -1
  27. package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
  28. package/dist/lib/conformance/runners.js +1 -1
  29. package/dist/lib/conformance/runners.js.map +1 -1
  30. package/dist/lib/conformance/runners.mjs +1 -1
  31. package/dist/lib/conformance/runners.mjs.map +1 -1
  32. package/dist/lib/conformance/seeder.js +5 -5
  33. package/dist/lib/conformance/seeder.js.map +1 -1
  34. package/dist/lib/conformance/seeder.mjs +5 -5
  35. package/dist/lib/conformance/seeder.mjs.map +1 -1
  36. package/dist/lib/core/ADCPMultiAgentClient.d.mts +26 -29
  37. package/dist/lib/core/ADCPMultiAgentClient.d.ts +26 -29
  38. package/dist/lib/core/ADCPMultiAgentClient.d.ts.map +1 -1
  39. package/dist/lib/core/ADCPMultiAgentClient.js +27 -19
  40. package/dist/lib/core/ADCPMultiAgentClient.js.map +1 -1
  41. package/dist/lib/core/ADCPMultiAgentClient.mjs +27 -19
  42. package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
  43. package/dist/lib/core/AgentClient.d.mts +148 -138
  44. package/dist/lib/core/AgentClient.d.ts +148 -138
  45. package/dist/lib/core/AgentClient.d.ts.map +1 -1
  46. package/dist/lib/core/AgentClient.js +174 -85
  47. package/dist/lib/core/AgentClient.js.map +1 -1
  48. package/dist/lib/core/AgentClient.mjs +174 -85
  49. package/dist/lib/core/AgentClient.mjs.map +1 -1
  50. package/dist/lib/core/AsyncHandler.d.mts +18 -16
  51. package/dist/lib/core/AsyncHandler.d.ts +18 -16
  52. package/dist/lib/core/AsyncHandler.d.ts.map +1 -1
  53. package/dist/lib/core/AsyncHandler.js +22 -1
  54. package/dist/lib/core/AsyncHandler.js.map +1 -1
  55. package/dist/lib/core/AsyncHandler.mjs +22 -1
  56. package/dist/lib/core/AsyncHandler.mjs.map +1 -1
  57. package/dist/lib/core/ConversationTypes.d.mts +6 -2
  58. package/dist/lib/core/ConversationTypes.d.ts +6 -2
  59. package/dist/lib/core/ConversationTypes.d.ts.map +1 -1
  60. package/dist/lib/core/ConversationTypes.js.map +1 -1
  61. package/dist/lib/core/CreativeAgentClient.d.mts +41 -17
  62. package/dist/lib/core/CreativeAgentClient.d.ts +41 -17
  63. package/dist/lib/core/CreativeAgentClient.d.ts.map +1 -1
  64. package/dist/lib/core/CreativeAgentClient.js +39 -12
  65. package/dist/lib/core/CreativeAgentClient.js.map +1 -1
  66. package/dist/lib/core/CreativeAgentClient.mjs +39 -12
  67. package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
  68. package/dist/lib/core/SingleAgentClient.d.mts +127 -50
  69. package/dist/lib/core/SingleAgentClient.d.ts +127 -50
  70. package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
  71. package/dist/lib/core/SingleAgentClient.js +1617 -177
  72. package/dist/lib/core/SingleAgentClient.js.map +1 -1
  73. package/dist/lib/core/SingleAgentClient.mjs +1627 -177
  74. package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
  75. package/dist/lib/core/TaskExecutor.d.mts +9 -0
  76. package/dist/lib/core/TaskExecutor.d.ts +9 -0
  77. package/dist/lib/core/TaskExecutor.d.ts.map +1 -1
  78. package/dist/lib/core/TaskExecutor.js +136 -43
  79. package/dist/lib/core/TaskExecutor.js.map +1 -1
  80. package/dist/lib/core/TaskExecutor.mjs +136 -43
  81. package/dist/lib/core/TaskExecutor.mjs.map +1 -1
  82. package/dist/lib/index.d.mts +111 -17
  83. package/dist/lib/index.d.ts +111 -17
  84. package/dist/lib/index.d.ts.map +1 -1
  85. package/dist/lib/index.js +94 -94
  86. package/dist/lib/index.js.map +1 -1
  87. package/dist/lib/index.mjs +93 -94
  88. package/dist/lib/index.mjs.map +1 -1
  89. package/dist/lib/protocols/index.d.ts.map +1 -1
  90. package/dist/lib/protocols/index.js +6 -15
  91. package/dist/lib/protocols/index.js.map +1 -1
  92. package/dist/lib/protocols/index.mjs +6 -16
  93. package/dist/lib/protocols/index.mjs.map +1 -1
  94. package/dist/lib/protocols/mcp-modern.d.ts.map +1 -1
  95. package/dist/lib/protocols/mcp-modern.js +87 -12
  96. package/dist/lib/protocols/mcp-modern.js.map +1 -1
  97. package/dist/lib/protocols/mcp-modern.mjs +89 -12
  98. package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
  99. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  100. package/dist/lib/server/create-adcp-server.d.mts +6 -0
  101. package/dist/lib/server/create-adcp-server.d.ts +6 -0
  102. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  103. package/dist/lib/server/create-adcp-server.js +295 -48
  104. package/dist/lib/server/create-adcp-server.js.map +1 -1
  105. package/dist/lib/server/create-adcp-server.mjs +301 -50
  106. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  107. package/dist/lib/server/decisioning/assembly-helpers.d.mts +27 -13
  108. package/dist/lib/server/decisioning/assembly-helpers.d.ts +27 -13
  109. package/dist/lib/server/decisioning/assembly-helpers.d.ts.map +1 -1
  110. package/dist/lib/server/decisioning/assembly-helpers.js +136 -14
  111. package/dist/lib/server/decisioning/assembly-helpers.js.map +1 -1
  112. package/dist/lib/server/decisioning/assembly-helpers.mjs +134 -13
  113. package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
  114. package/dist/lib/server/decisioning/index.d.mts +13 -12
  115. package/dist/lib/server/decisioning/index.d.ts +13 -12
  116. package/dist/lib/server/decisioning/index.d.ts.map +1 -1
  117. package/dist/lib/server/decisioning/index.js +6 -0
  118. package/dist/lib/server/decisioning/index.js.map +1 -1
  119. package/dist/lib/server/decisioning/index.mjs +9 -3
  120. package/dist/lib/server/decisioning/index.mjs.map +1 -1
  121. package/dist/lib/server/decisioning/list-helpers.d.mts +13 -3
  122. package/dist/lib/server/decisioning/list-helpers.d.ts +13 -3
  123. package/dist/lib/server/decisioning/list-helpers.d.ts.map +1 -1
  124. package/dist/lib/server/decisioning/list-helpers.js +13 -3
  125. package/dist/lib/server/decisioning/list-helpers.js.map +1 -1
  126. package/dist/lib/server/decisioning/list-helpers.mjs +11 -2
  127. package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
  128. package/dist/lib/server/decisioning/manifest-helpers.d.mts +5 -3
  129. package/dist/lib/server/decisioning/manifest-helpers.d.ts +5 -3
  130. package/dist/lib/server/decisioning/manifest-helpers.d.ts.map +1 -1
  131. package/dist/lib/server/decisioning/manifest-helpers.js.map +1 -1
  132. package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
  133. package/dist/lib/server/decisioning/proposal/dispatch.d.mts +2 -2
  134. package/dist/lib/server/decisioning/proposal/dispatch.d.ts +2 -2
  135. package/dist/lib/server/decisioning/proposal/dispatch.d.ts.map +1 -1
  136. package/dist/lib/server/decisioning/proposal/dispatch.js.map +1 -1
  137. package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
  138. package/dist/lib/server/decisioning/proposal/index.d.mts +1 -1
  139. package/dist/lib/server/decisioning/proposal/index.d.ts +1 -1
  140. package/dist/lib/server/decisioning/proposal/index.d.ts.map +1 -1
  141. package/dist/lib/server/decisioning/proposal/index.js.map +1 -1
  142. package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
  143. package/dist/lib/server/decisioning/proposal/lifecycle.d.mts +3 -2
  144. package/dist/lib/server/decisioning/proposal/lifecycle.d.ts +3 -2
  145. package/dist/lib/server/decisioning/proposal/lifecycle.d.ts.map +1 -1
  146. package/dist/lib/server/decisioning/proposal/lifecycle.js.map +1 -1
  147. package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
  148. package/dist/lib/server/decisioning/proposal/mock-manager.d.mts +3 -3
  149. package/dist/lib/server/decisioning/proposal/mock-manager.d.ts +3 -3
  150. package/dist/lib/server/decisioning/proposal/mock-manager.d.ts.map +1 -1
  151. package/dist/lib/server/decisioning/proposal/mock-manager.js.map +1 -1
  152. package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
  153. package/dist/lib/server/decisioning/proposal/types.d.mts +10 -6
  154. package/dist/lib/server/decisioning/proposal/types.d.ts +10 -6
  155. package/dist/lib/server/decisioning/proposal/types.d.ts.map +1 -1
  156. package/dist/lib/server/decisioning/proposal/types.js.map +1 -1
  157. package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
  158. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +21 -2
  159. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +21 -2
  160. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
  161. package/dist/lib/server/decisioning/runtime/from-platform.js +754 -81
  162. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  163. package/dist/lib/server/decisioning/runtime/from-platform.mjs +763 -81
  164. package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
  165. package/dist/lib/server/decisioning/specialisms/brand-rights.d.mts +9 -9
  166. package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts +9 -9
  167. package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts.map +1 -1
  168. package/dist/lib/server/decisioning/specialisms/brand-rights.js.map +1 -1
  169. package/dist/lib/server/decisioning/specialisms/content-standards.d.mts +16 -16
  170. package/dist/lib/server/decisioning/specialisms/content-standards.d.ts +16 -16
  171. package/dist/lib/server/decisioning/specialisms/content-standards.d.ts.map +1 -1
  172. package/dist/lib/server/decisioning/specialisms/content-standards.js.map +1 -1
  173. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.mts +15 -13
  174. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts +15 -13
  175. package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts.map +1 -1
  176. package/dist/lib/server/decisioning/specialisms/creative-ad-server.js.map +1 -1
  177. package/dist/lib/server/decisioning/specialisms/creative.d.mts +12 -11
  178. package/dist/lib/server/decisioning/specialisms/creative.d.ts +12 -11
  179. package/dist/lib/server/decisioning/specialisms/creative.d.ts.map +1 -1
  180. package/dist/lib/server/decisioning/specialisms/creative.js.map +1 -1
  181. package/dist/lib/server/decisioning/specialisms/sales.d.mts +25 -15
  182. package/dist/lib/server/decisioning/specialisms/sales.d.ts +25 -15
  183. package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -1
  184. package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -1
  185. package/dist/lib/server/index.d.mts +3 -3
  186. package/dist/lib/server/index.d.ts +3 -3
  187. package/dist/lib/server/index.d.ts.map +1 -1
  188. package/dist/lib/server/index.js +72 -72
  189. package/dist/lib/server/index.js.map +1 -1
  190. package/dist/lib/server/index.mjs +36 -36
  191. package/dist/lib/server/index.mjs.map +1 -1
  192. package/dist/lib/server/legacy/v5/index.d.mts +1 -0
  193. package/dist/lib/server/legacy/v5/index.d.ts +1 -0
  194. package/dist/lib/server/legacy/v5/index.d.ts.map +1 -1
  195. package/dist/lib/server/legacy/v5/index.js +74 -1
  196. package/dist/lib/server/legacy/v5/index.js.map +1 -1
  197. package/dist/lib/server/legacy/v5/index.mjs +75 -1
  198. package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
  199. package/dist/lib/server/responses.d.mts +2 -2
  200. package/dist/lib/server/responses.d.ts +2 -2
  201. package/dist/lib/server/responses.js.map +1 -1
  202. package/dist/lib/server/responses.mjs.map +1 -1
  203. package/dist/lib/testing/client.js +1 -1
  204. package/dist/lib/testing/client.js.map +1 -1
  205. package/dist/lib/testing/client.mjs +1 -1
  206. package/dist/lib/testing/client.mjs.map +1 -1
  207. package/dist/lib/testing/scenarios/brand-rights.js +6 -6
  208. package/dist/lib/testing/scenarios/brand-rights.js.map +1 -1
  209. package/dist/lib/testing/scenarios/brand-rights.mjs +6 -6
  210. package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
  211. package/dist/lib/testing/scenarios/creative.js +7 -7
  212. package/dist/lib/testing/scenarios/creative.js.map +1 -1
  213. package/dist/lib/testing/scenarios/creative.mjs +7 -7
  214. package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
  215. package/dist/lib/testing/scenarios/discovery.js +2 -2
  216. package/dist/lib/testing/scenarios/discovery.js.map +1 -1
  217. package/dist/lib/testing/scenarios/discovery.mjs +2 -2
  218. package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
  219. package/dist/lib/testing/scenarios/edge-cases.js +11 -11
  220. package/dist/lib/testing/scenarios/edge-cases.js.map +1 -1
  221. package/dist/lib/testing/scenarios/edge-cases.mjs +11 -11
  222. package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
  223. package/dist/lib/testing/scenarios/governance.d.ts.map +1 -1
  224. package/dist/lib/testing/scenarios/governance.js +16 -22
  225. package/dist/lib/testing/scenarios/governance.js.map +1 -1
  226. package/dist/lib/testing/scenarios/governance.mjs +16 -22
  227. package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
  228. package/dist/lib/testing/scenarios/media-buy.js +5 -5
  229. package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
  230. package/dist/lib/testing/scenarios/media-buy.mjs +5 -5
  231. package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
  232. package/dist/lib/testing/scenarios/schema-compliance.js +1 -1
  233. package/dist/lib/testing/scenarios/schema-compliance.js.map +1 -1
  234. package/dist/lib/testing/scenarios/schema-compliance.mjs +1 -1
  235. package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
  236. package/dist/lib/testing/scenarios/trusted-match.d.ts.map +1 -1
  237. package/dist/lib/testing/scenarios/trusted-match.js +4 -3
  238. package/dist/lib/testing/scenarios/trusted-match.js.map +1 -1
  239. package/dist/lib/testing/scenarios/trusted-match.mjs +4 -3
  240. package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
  241. package/dist/lib/testing/storyboard/shape-drift-hints.d.mts +3 -4
  242. package/dist/lib/testing/storyboard/shape-drift-hints.d.ts +3 -4
  243. package/dist/lib/testing/storyboard/shape-drift-hints.d.ts.map +1 -1
  244. package/dist/lib/testing/storyboard/shape-drift-hints.js +27 -27
  245. package/dist/lib/testing/storyboard/shape-drift-hints.js.map +1 -1
  246. package/dist/lib/testing/storyboard/shape-drift-hints.mjs +27 -27
  247. package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
  248. package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
  249. package/dist/lib/testing/storyboard/task-map.js +43 -5
  250. package/dist/lib/testing/storyboard/task-map.js.map +1 -1
  251. package/dist/lib/testing/storyboard/task-map.mjs +43 -5
  252. package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
  253. package/dist/lib/testing/test-helpers.d.mts +2 -2
  254. package/dist/lib/testing/test-helpers.d.ts +2 -2
  255. package/dist/lib/testing/test-helpers.js.map +1 -1
  256. package/dist/lib/testing/test-helpers.mjs.map +1 -1
  257. package/dist/lib/types/adcp.d.mts +14 -14
  258. package/dist/lib/types/adcp.d.ts +14 -14
  259. package/dist/lib/types/adcp.d.ts.map +1 -1
  260. package/dist/lib/types/adcp.js.map +1 -1
  261. package/dist/lib/types/adcp.mjs.map +1 -1
  262. package/dist/lib/types/index.d.mts +2 -2
  263. package/dist/lib/types/index.d.ts +2 -2
  264. package/dist/lib/types/index.d.ts.map +1 -1
  265. package/dist/lib/types/index.js.map +1 -1
  266. package/dist/lib/types/index.mjs.map +1 -1
  267. package/dist/lib/utils/capabilities.d.mts +6 -0
  268. package/dist/lib/utils/capabilities.d.ts +6 -0
  269. package/dist/lib/utils/capabilities.d.ts.map +1 -1
  270. package/dist/lib/utils/capabilities.js +4 -0
  271. package/dist/lib/utils/capabilities.js.map +1 -1
  272. package/dist/lib/utils/capabilities.mjs +4 -0
  273. package/dist/lib/utils/capabilities.mjs.map +1 -1
  274. package/dist/lib/utils/creative-delivery.d.mts +52 -10
  275. package/dist/lib/utils/creative-delivery.d.ts +52 -10
  276. package/dist/lib/utils/creative-delivery.d.ts.map +1 -1
  277. package/dist/lib/utils/creative-delivery.js +104 -9
  278. package/dist/lib/utils/creative-delivery.js.map +1 -1
  279. package/dist/lib/utils/creative-delivery.mjs +104 -8
  280. package/dist/lib/utils/creative-delivery.mjs.map +1 -1
  281. package/dist/lib/utils/format-assets.d.mts +41 -38
  282. package/dist/lib/utils/format-assets.d.ts +41 -38
  283. package/dist/lib/utils/format-assets.d.ts.map +1 -1
  284. package/dist/lib/utils/format-assets.js +3 -1
  285. package/dist/lib/utils/format-assets.js.map +1 -1
  286. package/dist/lib/utils/format-assets.mjs +3 -1
  287. package/dist/lib/utils/format-assets.mjs.map +1 -1
  288. package/dist/lib/utils/index.d.mts +8 -8
  289. package/dist/lib/utils/index.d.ts +8 -8
  290. package/dist/lib/utils/index.d.ts.map +1 -1
  291. package/dist/lib/utils/index.js +11 -9
  292. package/dist/lib/utils/index.js.map +1 -1
  293. package/dist/lib/utils/index.mjs +9 -8
  294. package/dist/lib/utils/index.mjs.map +1 -1
  295. package/dist/lib/utils/preview-utils.d.mts +11 -8
  296. package/dist/lib/utils/preview-utils.d.ts +11 -8
  297. package/dist/lib/utils/preview-utils.d.ts.map +1 -1
  298. package/dist/lib/utils/preview-utils.js +4 -4
  299. package/dist/lib/utils/preview-utils.js.map +1 -1
  300. package/dist/lib/utils/preview-utils.mjs +3 -3
  301. package/dist/lib/utils/preview-utils.mjs.map +1 -1
  302. package/dist/lib/utils/tool-request-schemas.d.mts +2 -2
  303. package/dist/lib/utils/tool-request-schemas.d.ts +2 -2
  304. package/dist/lib/v2/projection/aao-reference-formats.json +492 -0
  305. package/dist/lib/v2/projection/augment-response.d.mts +31 -11
  306. package/dist/lib/v2/projection/augment-response.d.ts +31 -11
  307. package/dist/lib/v2/projection/augment-response.d.ts.map +1 -1
  308. package/dist/lib/v2/projection/augment-response.js +233 -27
  309. package/dist/lib/v2/projection/augment-response.js.map +1 -1
  310. package/dist/lib/v2/projection/augment-response.mjs +232 -27
  311. package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
  312. package/dist/lib/v2/projection/builders.d.mts +7 -6
  313. package/dist/lib/v2/projection/builders.d.ts +7 -6
  314. package/dist/lib/v2/projection/builders.d.ts.map +1 -1
  315. package/dist/lib/v2/projection/builders.js +11 -8
  316. package/dist/lib/v2/projection/builders.js.map +1 -1
  317. package/dist/lib/v2/projection/builders.mjs +9 -6
  318. package/dist/lib/v2/projection/builders.mjs.map +1 -1
  319. package/dist/lib/v2/projection/catalog-snapshot.d.mts +47 -0
  320. package/dist/lib/v2/projection/catalog-snapshot.d.ts +48 -0
  321. package/dist/lib/v2/projection/catalog-snapshot.d.ts.map +1 -0
  322. package/dist/lib/v2/projection/catalog-snapshot.js +291 -0
  323. package/dist/lib/v2/projection/catalog-snapshot.js.map +1 -0
  324. package/dist/lib/v2/projection/catalog-snapshot.mjs +265 -0
  325. package/dist/lib/v2/projection/catalog-snapshot.mjs.map +1 -0
  326. package/dist/lib/v2/projection/catalog.d.mts +23 -2
  327. package/dist/lib/v2/projection/catalog.d.ts +23 -2
  328. package/dist/lib/v2/projection/catalog.d.ts.map +1 -1
  329. package/dist/lib/v2/projection/catalog.js +34 -10
  330. package/dist/lib/v2/projection/catalog.js.map +1 -1
  331. package/dist/lib/v2/projection/catalog.mjs +33 -10
  332. package/dist/lib/v2/projection/catalog.mjs.map +1 -1
  333. package/dist/lib/v2/projection/creative-delivery.d.mts +157 -0
  334. package/dist/lib/v2/projection/creative-delivery.d.ts +158 -0
  335. package/dist/lib/v2/projection/creative-delivery.d.ts.map +1 -0
  336. package/dist/lib/v2/projection/creative-delivery.js +967 -0
  337. package/dist/lib/v2/projection/creative-delivery.js.map +1 -0
  338. package/dist/lib/v2/projection/creative-delivery.mjs +941 -0
  339. package/dist/lib/v2/projection/creative-delivery.mjs.map +1 -0
  340. package/dist/lib/v2/projection/index.d.mts +8 -6
  341. package/dist/lib/v2/projection/index.d.ts +8 -6
  342. package/dist/lib/v2/projection/index.d.ts.map +1 -1
  343. package/dist/lib/v2/projection/index.js +26 -4
  344. package/dist/lib/v2/projection/index.js.map +1 -1
  345. package/dist/lib/v2/projection/index.mjs +28 -4
  346. package/dist/lib/v2/projection/index.mjs.map +1 -1
  347. package/dist/lib/v2/projection/legacy-metadata.d.mts +21 -0
  348. package/dist/lib/v2/projection/legacy-metadata.d.ts +22 -0
  349. package/dist/lib/v2/projection/legacy-metadata.d.ts.map +1 -0
  350. package/dist/lib/v2/projection/legacy-metadata.js +73 -0
  351. package/dist/lib/v2/projection/legacy-metadata.js.map +1 -0
  352. package/dist/lib/v2/projection/legacy-metadata.mjs +45 -0
  353. package/dist/lib/v2/projection/legacy-metadata.mjs.map +1 -0
  354. package/dist/lib/v2/projection/types.d.mts +29 -23
  355. package/dist/lib/v2/projection/types.d.ts +29 -23
  356. package/dist/lib/v2/projection/types.d.ts.map +1 -1
  357. package/dist/lib/v2/projection/types.js.map +1 -1
  358. package/dist/lib/v2/projection/v1-to-v2.d.mts +29 -6
  359. package/dist/lib/v2/projection/v1-to-v2.d.ts +29 -6
  360. package/dist/lib/v2/projection/v1-to-v2.d.ts.map +1 -1
  361. package/dist/lib/v2/projection/v1-to-v2.js +218 -9
  362. package/dist/lib/v2/projection/v1-to-v2.js.map +1 -1
  363. package/dist/lib/v2/projection/v1-to-v2.mjs +219 -10
  364. package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
  365. package/dist/lib/v2/projection/v2-to-v1.d.mts +31 -2
  366. package/dist/lib/v2/projection/v2-to-v1.d.ts +31 -2
  367. package/dist/lib/v2/projection/v2-to-v1.d.ts.map +1 -1
  368. package/dist/lib/v2/projection/v2-to-v1.js +138 -7
  369. package/dist/lib/v2/projection/v2-to-v1.js.map +1 -1
  370. package/dist/lib/v2/projection/v2-to-v1.mjs +135 -6
  371. package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
  372. package/dist/lib/v2/projection/write-side.d.mts +12 -13
  373. package/dist/lib/v2/projection/write-side.d.ts +12 -13
  374. package/dist/lib/v2/projection/write-side.d.ts.map +1 -1
  375. package/dist/lib/v2/projection/write-side.js +16 -12
  376. package/dist/lib/v2/projection/write-side.js.map +1 -1
  377. package/dist/lib/v2/projection/write-side.mjs +16 -12
  378. package/dist/lib/v2/projection/write-side.mjs.map +1 -1
  379. package/dist/lib/version.d.mts +3 -3
  380. package/dist/lib/version.d.ts +3 -3
  381. package/dist/lib/version.d.ts.map +1 -1
  382. package/dist/lib/version.js +3 -3
  383. package/dist/lib/version.js.map +1 -1
  384. package/dist/lib/version.mjs +3 -3
  385. package/dist/lib/version.mjs.map +1 -1
  386. package/docs/guides/BUILD-AN-AGENT.md +7 -2
  387. package/docs/guides/PREVIEW-ASSET-DURABILITY.md +6 -2
  388. package/docs/llms.txt +1 -0
  389. package/examples/README.md +1 -1
  390. package/examples/batch-preview-test.ts +3 -3
  391. package/examples/conversation-client.ts +2 -2
  392. package/examples/debug-preview-response.ts +1 -1
  393. package/examples/decisioning-platform-broadcast-tv.ts +10 -4
  394. package/examples/decisioning-platform-mock-seller.ts +16 -9
  395. package/examples/decisioning-platform-programmatic.ts +18 -7
  396. package/examples/error-compliant-server.ts +26 -16
  397. package/examples/generative-creative-demo.ts +7 -19
  398. package/examples/hello_creative_adapter_ad_server.ts +37 -16
  399. package/examples/hello_creative_adapter_template.ts +12 -10
  400. package/examples/hello_seller_adapter_guaranteed.ts +52 -23
  401. package/examples/hello_seller_adapter_multi_tenant.ts +6 -3
  402. package/examples/hello_seller_adapter_non_guaranteed.ts +54 -26
  403. package/examples/hello_seller_adapter_proposal_mode.ts +40 -14
  404. package/examples/hello_seller_adapter_social.ts +2 -7
  405. package/examples/inspect-card-formats.ts +1 -1
  406. package/examples/simple-getting-started.ts +1 -1
  407. package/examples/test-helpers-demo.ts +1 -1
  408. package/package.json +2 -2
  409. package/skills/build-decisioning-creative-template/SKILL.md +11 -11
  410. package/skills/build-decisioning-platform/advanced/REFERENCE.md +8 -2
@@ -57,6 +57,7 @@ import {
57
57
  TASK_FEATURE_MAP
58
58
  } from "../utils/capabilities.mjs";
59
59
  import { normalizeRequestParams } from "../utils/request-normalizer.mjs";
60
+ import { globalAsyncLocalStorage } from "../utils/global-async-local-storage.mjs";
60
61
  import { validateUserAgent } from "../utils/validate-user-agent.mjs";
61
62
  import { resolveWebhookUrl, selectWebhookTemplate } from "./webhook-url.mjs";
62
63
  import { getV25Adapter } from "../adapters/legacy/v2-5/index.mjs";
@@ -65,7 +66,388 @@ import {
65
66
  validateProductsAgainstPropertyPolicy
66
67
  } from "../media-buy/property-policy.mjs";
67
68
  import { resolvePropertyList } from "../server/targeting-helpers.mjs";
69
+ import {
70
+ CreativeFormatCapabilityError,
71
+ CreativeFormatProjectionError,
72
+ projectMediaBuyCreativesForDelivery,
73
+ projectCreativeForDelivery,
74
+ projectSyncCreativesForDelivery,
75
+ resolveCreativeFormatWireMode,
76
+ stripLegacyCreativeIdentity
77
+ } from "../v2/projection/creative-delivery.mjs";
78
+ import {
79
+ legacyFormatConverterFromCatalogSnapshots
80
+ } from "../v2/projection/catalog-snapshot.mjs";
81
+ import { toCanonicalOnlyResponse } from "../v2/projection/augment-response.mjs";
82
+ import { legacyFormatRefsForDeclaration } from "../v2/projection/legacy-metadata.mjs";
83
+ import { canonicalize as canonicalizeJson } from "../utils/jcs.mjs";
68
84
  const CAPABILITY_DISCOVERY_CONTEXT = /* @__PURE__ */ Symbol("capabilityDiscoveryContext");
85
+ function creativeSchemaSupport(value, depth = 0) {
86
+ if (depth > 24 || value === null || typeof value !== "object") return "unknown";
87
+ if (Array.isArray(value)) {
88
+ let legacy2 = false;
89
+ for (const item of value) {
90
+ const support = creativeSchemaSupport(item, depth + 1);
91
+ if (support === "canonical") return support;
92
+ if (support === "legacy") legacy2 = true;
93
+ }
94
+ return legacy2 ? "legacy" : "unknown";
95
+ }
96
+ const object = value;
97
+ const properties = object.properties;
98
+ if (properties !== null && typeof properties === "object" && !Array.isArray(properties)) {
99
+ const keys = properties;
100
+ if ("creative_id" in keys && "format_kind" in keys) return "canonical";
101
+ if ("creative_id" in keys && "format_id" in keys) return "legacy";
102
+ }
103
+ let legacy = false;
104
+ for (const child of Object.values(object)) {
105
+ const support = creativeSchemaSupport(child, depth + 1);
106
+ if (support === "canonical") return support;
107
+ if (support === "legacy") legacy = true;
108
+ }
109
+ return legacy ? "legacy" : "unknown";
110
+ }
111
+ function hasMediaBuyCreativeFormatData(request) {
112
+ if (request === null || typeof request !== "object" || Array.isArray(request)) return false;
113
+ const record = request;
114
+ return ["packages", "new_packages"].some((key) => {
115
+ const packages = record[key];
116
+ return Array.isArray(packages) && packages.some((pkg) => {
117
+ if (pkg === null || typeof pkg !== "object" || Array.isArray(pkg)) return false;
118
+ const packageRecord = pkg;
119
+ return Array.isArray(packageRecord.creatives) || Array.isArray(packageRecord.format_option_refs) || Array.isArray(packageRecord.format_ids) || typeof packageRecord.format_kind === "string" || Object.getOwnPropertySymbols(packageRecord).length > 0;
120
+ });
121
+ });
122
+ }
123
+ const CANONICAL_CREATIVE_ACTIVITY_TASKS = /* @__PURE__ */ new Set([
124
+ "get_products",
125
+ "create_media_buy",
126
+ "update_media_buy",
127
+ "sync_creatives",
128
+ "list_creatives",
129
+ "get_media_buys",
130
+ "get_media_buy_delivery",
131
+ "get_creative_delivery"
132
+ ]);
133
+ const TASK_SCOPED_STATE_LIMIT = 1e4;
134
+ const CANONICAL_PACKAGE_ROUTE_TASKS = /* @__PURE__ */ new Set(["create_media_buy", "update_media_buy", "get_media_buys"]);
135
+ const canonicalCreativeRoutingSnapshots = /* @__PURE__ */ new WeakSet();
136
+ function canonicalAccountRoutingSnapshot(value) {
137
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
138
+ const account = value;
139
+ if (typeof account.account_id === "string") return Object.freeze({ account_id: account.account_id });
140
+ if (!account.brand || typeof account.brand !== "object" || Array.isArray(account.brand) || typeof account.operator !== "string") {
141
+ return void 0;
142
+ }
143
+ const sourceBrand = account.brand;
144
+ if (typeof sourceBrand.domain !== "string") return void 0;
145
+ const brand = Object.freeze({
146
+ domain: sourceBrand.domain,
147
+ ...typeof sourceBrand.brand_id === "string" ? { brand_id: sourceBrand.brand_id } : {}
148
+ });
149
+ return Object.freeze({
150
+ brand,
151
+ operator: account.operator,
152
+ ...typeof account.sandbox === "boolean" ? { sandbox: account.sandbox } : {}
153
+ });
154
+ }
155
+ function canonicalOptionRefRoutingSnapshot(value) {
156
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
157
+ const ref = value;
158
+ if (typeof ref.format_option_id !== "string") return void 0;
159
+ if (ref.scope === "publisher" || typeof ref.publisher_domain === "string") {
160
+ if (typeof ref.publisher_domain !== "string") return void 0;
161
+ return Object.freeze({
162
+ scope: "publisher",
163
+ publisher_domain: ref.publisher_domain,
164
+ format_option_id: ref.format_option_id
165
+ });
166
+ }
167
+ return Object.freeze({ scope: "product", format_option_id: ref.format_option_id });
168
+ }
169
+ function canonicalPackageRouteSelectorSnapshot(value) {
170
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
171
+ const selector = value;
172
+ const formatOptionRefs = Array.isArray(selector.format_option_refs) ? selector.format_option_refs.map(canonicalOptionRefRoutingSnapshot).filter((ref) => ref !== void 0) : [];
173
+ const snapshot = {
174
+ ...typeof selector.package_id === "string" ? { package_id: selector.package_id } : {},
175
+ ...typeof selector.product_id === "string" ? { product_id: selector.product_id } : {},
176
+ ...formatOptionRefs.length > 0 ? { format_option_refs: Object.freeze(formatOptionRefs) } : {}
177
+ };
178
+ return Object.keys(snapshot).length > 0 ? Object.freeze(snapshot) : void 0;
179
+ }
180
+ function canonicalCreativeRoutingSnapshot(taskType, request) {
181
+ if (!CANONICAL_PACKAGE_ROUTE_TASKS.has(taskType) || !request || typeof request !== "object" || Array.isArray(request)) {
182
+ return void 0;
183
+ }
184
+ if (canonicalCreativeRoutingSnapshots.has(request)) {
185
+ return request;
186
+ }
187
+ const record = request;
188
+ const account = canonicalAccountRoutingSnapshot(record.account);
189
+ if (!account) return void 0;
190
+ const packageSnapshots = (key) => Object.freeze(
191
+ (Array.isArray(record[key]) ? record[key] : []).map(canonicalPackageRouteSelectorSnapshot).filter((selector) => selector !== void 0)
192
+ );
193
+ const packages = packageSnapshots("packages");
194
+ const newPackages = packageSnapshots("new_packages");
195
+ const snapshot = Object.freeze({
196
+ account,
197
+ ...packages.length > 0 ? { packages } : {},
198
+ ...newPackages.length > 0 ? { new_packages: newPackages } : {}
199
+ });
200
+ canonicalCreativeRoutingSnapshots.add(snapshot);
201
+ return snapshot;
202
+ }
203
+ const canonicalCreativeExecutionStorage = globalAsyncLocalStorage("canonicalCreativeExecution");
204
+ function prepareCanonicalCreativePayload(value, taskType, active = /* @__PURE__ */ new WeakSet(), prepared = /* @__PURE__ */ new WeakMap()) {
205
+ if (value === null || typeof value !== "object") return value;
206
+ for (let owner = value; owner !== null; owner = Object.getPrototypeOf(owner)) {
207
+ const toJSON = Object.getOwnPropertyDescriptor(owner, "toJSON");
208
+ if (toJSON && (!("value" in toJSON) || typeof toJSON.value === "function")) {
209
+ throw new CreativeFormatProjectionError(
210
+ taskType,
211
+ "(response:toJSON)",
212
+ "custom or accessor toJSON hooks cannot cross the canonical creative boundary safely"
213
+ );
214
+ }
215
+ }
216
+ if (active.has(value)) {
217
+ throw new CreativeFormatProjectionError(
218
+ taskType,
219
+ "(response:cycle)",
220
+ "cyclic values cannot cross the canonical creative boundary"
221
+ );
222
+ }
223
+ const cached = prepared.get(value);
224
+ if (cached !== void 0) return cached;
225
+ active.add(value);
226
+ try {
227
+ const isArray = Array.isArray(value);
228
+ const prototype = Object.getPrototypeOf(value);
229
+ const plain = isArray ? prototype === Array.prototype : prototype === Object.prototype || prototype === null;
230
+ const output = isArray ? [] : Object.create(prototype === null ? null : Object.prototype);
231
+ prepared.set(value, output);
232
+ let changed = !plain;
233
+ for (const key of Reflect.ownKeys(value)) {
234
+ if (isArray && key === "length") continue;
235
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
236
+ if (!descriptor) continue;
237
+ if (!("value" in descriptor)) {
238
+ throw new CreativeFormatProjectionError(
239
+ taskType,
240
+ `(response:${String(key)})`,
241
+ "accessors cannot cross the canonical creative boundary safely"
242
+ );
243
+ }
244
+ if (!descriptor.enumerable) continue;
245
+ const safe = prepareCanonicalCreativePayload(descriptor.value, taskType, active, prepared);
246
+ if (safe !== descriptor.value) changed = true;
247
+ Object.defineProperty(output, key, { ...descriptor, value: safe });
248
+ }
249
+ if (!changed) {
250
+ prepared.set(value, value);
251
+ return value;
252
+ }
253
+ return output;
254
+ } finally {
255
+ active.delete(value);
256
+ }
257
+ }
258
+ function projectPreparedCanonicalCreativeResponseValue(value, taskType, legacyFormatConverter, selectorContainer = {}) {
259
+ if (Array.isArray(value)) {
260
+ return value.map(
261
+ (item) => projectPreparedCanonicalCreativeResponseValue(item, taskType, legacyFormatConverter, selectorContainer)
262
+ );
263
+ }
264
+ if (!value || typeof value !== "object") return value;
265
+ let projected = value;
266
+ const isProduct = typeof projected.product_id === "string" && ("name" in projected || "description" in projected) && (Array.isArray(projected.format_ids) || Array.isArray(projected.format_options));
267
+ if (isProduct) {
268
+ const canonical = toCanonicalOnlyResponse(
269
+ { products: [projected] },
270
+ { legacyFormatConverter }
271
+ );
272
+ if (canonical.diagnostics.length > 0 || canonical.response.products.length !== 1) {
273
+ throw new CreativeFormatProjectionError(
274
+ taskType,
275
+ `(product:${String(projected.product_id)})`,
276
+ "legacy product formats in the response have no complete canonical representation"
277
+ );
278
+ }
279
+ projected = canonical.response.products[0];
280
+ } else if ((typeof projected.package_id === "string" || typeof projected.product_id === "string") && Array.isArray(projected.format_ids)) {
281
+ projected = projectMediaBuyCreativesForDelivery(
282
+ { packages: [projected] },
283
+ "canonical",
284
+ taskType === "update_media_buy" ? "update_media_buy" : "create_media_buy",
285
+ legacyFormatConverter
286
+ ).packages[0];
287
+ }
288
+ if (typeof projected.creative_id === "string" && (projected.format_id !== void 0 || typeof projected.format_kind === "string")) {
289
+ projected = projectCreativeForDelivery(
290
+ projected,
291
+ selectorContainer,
292
+ "canonical",
293
+ taskType,
294
+ legacyFormatConverter
295
+ );
296
+ }
297
+ const nextSelector = Array.isArray(projected.format_ids) || Array.isArray(projected.format_options) || Array.isArray(projected.format_option_refs) ? projected : selectorContainer;
298
+ let changed = projected !== value;
299
+ const next = { ...projected };
300
+ for (const [key, child] of Object.entries(projected)) {
301
+ const childProjected = projectPreparedCanonicalCreativeResponseValue(
302
+ child,
303
+ taskType,
304
+ legacyFormatConverter,
305
+ nextSelector
306
+ );
307
+ if (childProjected !== child) {
308
+ next[key] = childProjected;
309
+ changed = true;
310
+ }
311
+ }
312
+ return changed ? next : projected;
313
+ }
314
+ function projectCanonicalCreativeResponseValue(value, taskType, legacyFormatConverter, selectorContainer = {}) {
315
+ return projectPreparedCanonicalCreativeResponseValue(
316
+ prepareCanonicalCreativePayload(value, taskType),
317
+ taskType,
318
+ legacyFormatConverter,
319
+ selectorContainer
320
+ );
321
+ }
322
+ function projectCanonicalCreativeAncillaryValue(value, taskType, legacyFormatConverter) {
323
+ try {
324
+ return stripLegacyCreativeIdentity(projectCanonicalCreativeResponseValue(value, taskType, legacyFormatConverter));
325
+ } catch (error) {
326
+ if (!(error instanceof CreativeFormatProjectionError)) throw error;
327
+ return { omitted: true, reason: "canonical creative payload unavailable" };
328
+ }
329
+ }
330
+ function canonicalCreativeActivity(activity) {
331
+ const active = canonicalCreativeExecutionStorage.getStore();
332
+ const effectiveTaskType = active?.taskType && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(active.taskType) ? active.taskType : activity.task_type;
333
+ if (!CANONICAL_CREATIVE_ACTIVITY_TASKS.has(effectiveTaskType) || activity.payload === void 0) {
334
+ return activity;
335
+ }
336
+ const converter = active?.taskType === effectiveTaskType ? active.legacyFormatConverter : void 0;
337
+ const source = activity.type === "protocol_request" && active?.taskType === effectiveTaskType && active.canonicalRequest !== void 0 ? { params: active.canonicalRequest } : activity.payload;
338
+ try {
339
+ return {
340
+ ...activity,
341
+ payload: stripLegacyCreativeIdentity(projectCanonicalCreativeResponseValue(source, effectiveTaskType, converter))
342
+ };
343
+ } catch (error) {
344
+ if (!(error instanceof CreativeFormatProjectionError)) throw error;
345
+ return { ...activity, payload: { omitted: true, reason: "canonical creative payload unavailable" } };
346
+ }
347
+ }
348
+ function canonicalCreativeDiagnosticBody(body, taskType) {
349
+ if (body === void 0) return void 0;
350
+ try {
351
+ const active = canonicalCreativeExecutionStorage.getStore();
352
+ const converter = active?.taskType === taskType ? active.legacyFormatConverter : void 0;
353
+ return JSON.stringify(
354
+ stripLegacyCreativeIdentity(projectCanonicalCreativeResponseValue(JSON.parse(body), taskType, converter))
355
+ );
356
+ } catch {
357
+ return "[canonical creative payload omitted]";
358
+ }
359
+ }
360
+ function canonicalCreativeTransportActivity(event) {
361
+ const active = canonicalCreativeExecutionStorage.getStore();
362
+ const taskType = active?.taskType && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(active.taskType) ? active.taskType : event.taskType ?? event.tool;
363
+ if (!taskType || !CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) return event;
364
+ return {
365
+ ...event,
366
+ ...event.requestBody !== void 0 && {
367
+ requestBody: canonicalCreativeDiagnosticBody(event.requestBody, taskType)
368
+ },
369
+ ...event.responseBody !== void 0 && {
370
+ responseBody: canonicalCreativeDiagnosticBody(event.responseBody, taskType)
371
+ }
372
+ };
373
+ }
374
+ function canonicalCreativeErrorInstance(error, legacySource) {
375
+ const own = {};
376
+ const descriptors = Object.getOwnPropertyDescriptors(error);
377
+ for (const [key, descriptor] of Object.entries(descriptors)) {
378
+ if ("value" in descriptor) own[key] = descriptor.value;
379
+ }
380
+ const { legacySource: _dropLegacySource, own: safeOwn } = stripLegacyCreativeIdentity({ own, legacySource });
381
+ void _dropLegacySource;
382
+ const clone = Object.create(Object.getPrototypeOf(error));
383
+ for (const [key, value] of Object.entries(safeOwn)) {
384
+ const descriptor = descriptors[key];
385
+ if (!descriptor || !("value" in descriptor)) continue;
386
+ Object.defineProperty(clone, key, { ...descriptor, value });
387
+ }
388
+ for (const symbol of Object.getOwnPropertySymbols(error)) {
389
+ const descriptor = Object.getOwnPropertyDescriptor(error, symbol);
390
+ if (!descriptor || !("value" in descriptor)) continue;
391
+ const safe = stripLegacyCreativeIdentity({ value: descriptor.value, legacySource });
392
+ Object.defineProperty(clone, symbol, { ...descriptor, value: safe.value });
393
+ }
394
+ return stripLegacyCreativeIdentity(clone);
395
+ }
396
+ const PRIMARY_ADCP_TASK_NAMES = {
397
+ get_products: true,
398
+ create_media_buy: true,
399
+ update_media_buy: true,
400
+ sync_creatives: true,
401
+ list_creatives: true,
402
+ get_media_buys: true,
403
+ get_media_buy_delivery: true,
404
+ get_creative_delivery: true,
405
+ provide_performance_feedback: true,
406
+ get_signals: true,
407
+ activate_signal: true,
408
+ get_adcp_capabilities: true,
409
+ list_accounts: true,
410
+ sync_accounts: true,
411
+ sync_audiences: true,
412
+ create_property_list: true,
413
+ get_property_list: true,
414
+ update_property_list: true,
415
+ list_property_lists: true,
416
+ delete_property_list: true,
417
+ si_get_offering: true,
418
+ si_initiate_session: true,
419
+ si_send_message: true,
420
+ si_terminate_session: true,
421
+ get_brand_identity: true,
422
+ sync_plans: true,
423
+ check_governance: true,
424
+ report_plan_outcome: true,
425
+ get_plan_audit_logs: true,
426
+ context_match: true,
427
+ identity_match: true
428
+ };
429
+ const STANDARD_ADCP_TASK_NAMES = /* @__PURE__ */ new Set([
430
+ ...Object.keys(PRIMARY_ADCP_TASK_NAMES),
431
+ "list_creative_formats",
432
+ "list_transformers",
433
+ "preview_creative",
434
+ "build_creative",
435
+ // These standard protocol tools still carry legacy creative `format_id`
436
+ // identity through artifacts, manifests, standards, or rights constraints.
437
+ // They are available only through explicitly named *Legacy APIs until a
438
+ // lossless canonical projection exists.
439
+ "list_content_standards",
440
+ "get_content_standards",
441
+ "create_content_standards",
442
+ "update_content_standards",
443
+ "calibrate_content",
444
+ "validate_content_delivery",
445
+ "get_media_buy_artifacts",
446
+ "get_creative_features",
447
+ "get_rights",
448
+ "acquire_rights",
449
+ "update_rights"
450
+ ]);
69
451
  class UnsupportedFeatureError extends Error {
70
452
  constructor(feature, serverVersion, message) {
71
453
  super(message || `Feature '${feature}' requires AdCP v3 but server is ${serverVersion}`);
@@ -136,6 +518,14 @@ function propertyListReferenceFromRequest(params) {
136
518
  ...typeof ref.auth_token === "string" ? { auth_token: ref.auth_token } : {}
137
519
  };
138
520
  }
521
+ function productPolicyRequestSnapshot(requestParams) {
522
+ const account = canonicalAccountRoutingSnapshot(requestParams.account);
523
+ const propertyList = propertyListReferenceFromRequest(requestParams);
524
+ return Object.freeze({
525
+ ...account ? { account } : {},
526
+ ...propertyList ? { property_list: Object.freeze(propertyList) } : {}
527
+ });
528
+ }
139
529
  function hasProductPropertyPolicyRules(policy) {
140
530
  return Boolean(
141
531
  policy.allowedDomains?.length || policy.allowedPropertyIdentifiers?.length || policy.requireAllowedPropertyMatch || policy.excludedDomains?.length || policy.excludedPropertyIds?.length || policy.strict || policy.unknownSelectorBehavior || policy.missingPublisherPropertiesBehavior
@@ -196,8 +586,8 @@ class SingleAgentClient {
196
586
  ...config.validation?.requests != null && { requests: config.validation.requests },
197
587
  ...config.validation?.responses != null && { responses: config.validation.responses }
198
588
  },
199
- onActivity: config.onActivity,
200
- onTransportActivity: config.onTransportActivity,
589
+ onActivity: config.onActivity ? (activity) => config.onActivity(canonicalCreativeActivity(activity)) : void 0,
590
+ onTransportActivity: config.onTransportActivity ? (event) => config.onTransportActivity(canonicalCreativeTransportActivity(event)) : void 0,
201
591
  governance: config.governance,
202
592
  adcpVersion: this.resolvedAdcpVersion,
203
593
  ...config.wireAdcpVersion !== void 0 && { wireAdcpVersion: config.wireAdcpVersion },
@@ -232,7 +622,237 @@ class SingleAgentClient {
232
622
  _syntheticV2WarningFired = false;
233
623
  // Gate: emit the synthetic-v2 warning once per client instance
234
624
  productPolicyRequestParamsByTask = /* @__PURE__ */ new Map();
625
+ canonicalCreativeTaskAssociations = /* @__PURE__ */ new Map();
626
+ canonicalLegacyRoutes = /* @__PURE__ */ new Map();
235
627
  resolvedAdcpVersion;
628
+ resolveLegacyFormatConverter(override, projectionCatalogs = this.config.projectionCatalogs) {
629
+ return legacyFormatConverterFromCatalogSnapshots(projectionCatalogs, override ?? this.config.legacyFormatConverter);
630
+ }
631
+ canonicalAccountScope(account) {
632
+ if (account === void 0) return "none";
633
+ return canonicalizeJson(canonicalAccountRoutingSnapshot(account) ?? account);
634
+ }
635
+ canonicalLegacyRouteKey(account, productId, ref) {
636
+ return canonicalizeJson([
637
+ this.canonicalAccountScope(account),
638
+ productId,
639
+ ref.scope,
640
+ ref.scope === "publisher" ? ref.publisher_domain.toLowerCase() : "",
641
+ ref.format_option_id
642
+ ]);
643
+ }
644
+ canonicalLegacyPackageRouteKey(account, packageId) {
645
+ return canonicalizeJson([this.canonicalAccountScope(account), "package", packageId]);
646
+ }
647
+ sameCanonicalOptionRef(left, right) {
648
+ return left.scope === right.scope && left.format_option_id === right.format_option_id && (left.scope !== "publisher" || right.scope === "publisher" && left.publisher_domain.toLowerCase() === right.publisher_domain.toLowerCase());
649
+ }
650
+ rememberCanonicalLegacyRoute(key, route) {
651
+ this.canonicalLegacyRoutes.delete(key);
652
+ this.canonicalLegacyRoutes.set(key, {
653
+ ...route,
654
+ refs: Object.freeze(route.refs.map((ref) => Object.freeze({ ...ref })))
655
+ });
656
+ while (this.canonicalLegacyRoutes.size > TASK_SCOPED_STATE_LIMIT) {
657
+ const oldest = this.canonicalLegacyRoutes.keys().next().value;
658
+ if (oldest === void 0) break;
659
+ this.canonicalLegacyRoutes.delete(oldest);
660
+ }
661
+ }
662
+ invalidateCanonicalProductRoutes(products, account) {
663
+ const accountScope = this.canonicalAccountScope(account);
664
+ const productIds = /* @__PURE__ */ new Set();
665
+ for (const value of products) {
666
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
667
+ const productId = value.product_id;
668
+ if (typeof productId === "string") productIds.add(productId);
669
+ }
670
+ if (productIds.size === 0) return;
671
+ for (const [key, route] of this.canonicalLegacyRoutes) {
672
+ if (route.kind === "product" && route.accountScope === accountScope && productIds.has(route.productId)) {
673
+ this.canonicalLegacyRoutes.delete(key);
674
+ }
675
+ }
676
+ }
677
+ rememberCanonicalProductRoutes(products, account, authoritativeProducts = products) {
678
+ this.invalidateCanonicalProductRoutes(authoritativeProducts, account);
679
+ const accountScope = this.canonicalAccountScope(account);
680
+ for (const value of products) {
681
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
682
+ const product = value;
683
+ if (typeof product.product_id !== "string" || !Array.isArray(product.format_options)) continue;
684
+ for (const optionValue of product.format_options) {
685
+ if (!optionValue || typeof optionValue !== "object" || Array.isArray(optionValue)) continue;
686
+ const option = optionValue;
687
+ if (typeof option.format_option_id !== "string") continue;
688
+ const ref = typeof option.publisher_domain === "string" ? {
689
+ scope: "publisher",
690
+ publisher_domain: option.publisher_domain,
691
+ format_option_id: option.format_option_id
692
+ } : { scope: "product", format_option_id: option.format_option_id };
693
+ const refs = legacyFormatRefsForDeclaration(option);
694
+ if (refs.length === 0) continue;
695
+ this.rememberCanonicalLegacyRoute(this.canonicalLegacyRouteKey(account, product.product_id, ref), {
696
+ kind: "product",
697
+ accountScope,
698
+ productId: product.product_id,
699
+ optionRef: ref,
700
+ refs
701
+ });
702
+ }
703
+ }
704
+ }
705
+ routeForOption(account, productId, optionRef) {
706
+ const accountScope = this.canonicalAccountScope(account);
707
+ const exactKey = this.canonicalLegacyRouteKey(account, productId, optionRef);
708
+ const exact = this.canonicalLegacyRoutes.get(exactKey);
709
+ if (exact) {
710
+ this.canonicalLegacyRoutes.delete(exactKey);
711
+ this.canonicalLegacyRoutes.set(exactKey, exact);
712
+ return exact;
713
+ }
714
+ const candidates = [...this.canonicalLegacyRoutes.entries()].filter(
715
+ ([, route]) => route.kind === "product" && route.productId === productId && this.sameCanonicalOptionRef(route.optionRef, optionRef)
716
+ );
717
+ if (candidates.length !== 1) return void 0;
718
+ const [key, candidate] = candidates[0];
719
+ if (accountScope === "none" || candidate.accountScope !== "none") return void 0;
720
+ this.canonicalLegacyRoutes.delete(key);
721
+ this.canonicalLegacyRoutes.set(key, candidate);
722
+ return candidate;
723
+ }
724
+ routeForPackage(account, packageId) {
725
+ const exactKey = this.canonicalLegacyPackageRouteKey(account, packageId);
726
+ const exact = this.canonicalLegacyRoutes.get(exactKey);
727
+ if (exact) {
728
+ this.canonicalLegacyRoutes.delete(exactKey);
729
+ this.canonicalLegacyRoutes.set(exactKey, exact);
730
+ return exact;
731
+ }
732
+ return void 0;
733
+ }
734
+ packageIdsFromSelector(selector) {
735
+ const ids = /* @__PURE__ */ new Set();
736
+ if (typeof selector.package_id === "string") ids.add(selector.package_id);
737
+ if (Array.isArray(selector.selector_containers)) {
738
+ for (const value of selector.selector_containers) {
739
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
740
+ for (const id of this.packageIdsFromSelector(value)) ids.add(id);
741
+ }
742
+ }
743
+ return [...ids];
744
+ }
745
+ cachedCanonicalLegacyRefs(context, account) {
746
+ const selector = context.source === "product" ? context.declaration : context.source === "creative" ? context.selector : context.selector;
747
+ const productId = context.source === "product" ? context.productId : typeof selector.product_id === "string" ? selector.product_id : void 0;
748
+ if (!productId) {
749
+ const packageIds = this.packageIdsFromSelector(selector);
750
+ if (packageIds.length === 0) return void 0;
751
+ const routes = packageIds.map((packageId) => this.routeForPackage(account, packageId));
752
+ if (routes.some((route) => route === void 0)) return void 0;
753
+ const normalized = routes.map(
754
+ (route) => canonicalizeJson(
755
+ route.refs.map((ref) => ({ ...ref })).sort((left, right) => canonicalizeJson(left).localeCompare(canonicalizeJson(right)))
756
+ )
757
+ );
758
+ if (!normalized.every((value) => value === normalized[0])) return void 0;
759
+ return routes[0].refs.map((value) => ({ ...value }));
760
+ }
761
+ const rawRefs = [];
762
+ if (context.source === "product") rawRefs.push(context.declaration);
763
+ if (context.source === "creative" && context.creative.format_option_ref !== void 0) {
764
+ rawRefs.push(context.creative.format_option_ref);
765
+ } else if (Array.isArray(selector.format_option_refs)) {
766
+ rawRefs.push(...selector.format_option_refs);
767
+ }
768
+ const optionRefs = [];
769
+ for (const value of rawRefs) {
770
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
771
+ const record = value;
772
+ if (typeof record.format_option_id !== "string") continue;
773
+ if (record.scope === "publisher" || typeof record.publisher_domain === "string") {
774
+ if (typeof record.publisher_domain !== "string") continue;
775
+ optionRefs.push({
776
+ scope: "publisher",
777
+ publisher_domain: record.publisher_domain,
778
+ format_option_id: record.format_option_id
779
+ });
780
+ } else {
781
+ optionRefs.push({ scope: "product", format_option_id: record.format_option_id });
782
+ }
783
+ }
784
+ if (optionRefs.length === 0) return void 0;
785
+ const resolved = [];
786
+ for (const ref of optionRefs) {
787
+ const route = this.routeForOption(account, productId, ref);
788
+ if (!route) return void 0;
789
+ resolved.push(...route.refs.map((value) => ({ ...value })));
790
+ }
791
+ return resolved;
792
+ }
793
+ rememberCanonicalPackageRoutes(response, request) {
794
+ if (!response || typeof response !== "object" || Array.isArray(response)) return;
795
+ const requestRecord = request && typeof request === "object" && !Array.isArray(request) ? request : void 0;
796
+ const account = requestRecord?.account;
797
+ if (account === void 0) return;
798
+ const accountScope = this.canonicalAccountScope(account);
799
+ const requestPackages = ["packages", "new_packages"].flatMap(
800
+ (key) => Array.isArray(requestRecord?.[key]) ? requestRecord[key].filter(
801
+ (value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
802
+ ) : []
803
+ );
804
+ const responsePackages = [];
805
+ const visit = (value, depth = 0) => {
806
+ if (depth > 8 || !value || typeof value !== "object") return;
807
+ if (Array.isArray(value)) {
808
+ for (const item of value) visit(item, depth + 1);
809
+ return;
810
+ }
811
+ const record = value;
812
+ if (typeof record.package_id === "string") responsePackages.push(record);
813
+ for (const key of ["packages", "affected_packages", "media_buys"]) {
814
+ if (record[key] !== void 0) visit(record[key], depth + 1);
815
+ }
816
+ };
817
+ visit(response);
818
+ for (const pkg of responsePackages) {
819
+ const packageId = pkg.package_id;
820
+ let selector = pkg;
821
+ let refs = this.cachedCanonicalLegacyRefs(
822
+ { source: "selector", selector, operation: "package_route", field: packageId },
823
+ account
824
+ );
825
+ if (!refs) {
826
+ const byPackageId = requestPackages.filter((value) => value.package_id === packageId);
827
+ const productId = typeof pkg.product_id === "string" ? pkg.product_id : void 0;
828
+ const byProduct = productId ? requestPackages.filter((value) => value.product_id === productId) : [];
829
+ const matches = byPackageId.length === 1 ? byPackageId : byProduct.length === 1 ? byProduct : [];
830
+ selector = matches[0];
831
+ if (selector) {
832
+ refs = this.cachedCanonicalLegacyRefs(
833
+ { source: "selector", selector, operation: "package_route", field: packageId },
834
+ account
835
+ );
836
+ }
837
+ }
838
+ if (!refs || refs.length === 0) continue;
839
+ this.rememberCanonicalLegacyRoute(this.canonicalLegacyPackageRouteKey(account, packageId), {
840
+ kind: "package",
841
+ accountScope,
842
+ packageId,
843
+ refs
844
+ });
845
+ }
846
+ }
847
+ rememberCanonicalPackageRoutesForTask(taskType, response, request) {
848
+ if (taskType === "create_media_buy" || taskType === "update_media_buy" || taskType === "get_media_buys") {
849
+ this.rememberCanonicalPackageRoutes(response, request);
850
+ }
851
+ }
852
+ resolveCanonicalFormatLegacyResolver(override, account) {
853
+ const configured = this.config.canonicalFormatLegacyResolver;
854
+ return (context) => override?.(context) ?? this.cachedCanonicalLegacyRefs(context, account) ?? configured?.(context);
855
+ }
236
856
  /**
237
857
  * Returns the AdCP protocol version this client is configured to speak.
238
858
  *
@@ -269,6 +889,10 @@ class SingleAgentClient {
269
889
  ...this.normalizedAgent,
270
890
  agent_uri: this.discoveredEndpoint
271
891
  };
892
+ if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
893
+ const { shareNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.mjs");
894
+ shareNonInteractiveOAuthProvider(this.normalizedAgent, this.discoveredAgent);
895
+ }
272
896
  return this.discoveredAgent;
273
897
  }
274
898
  if (this.normalizedAgent.oauth_client_credentials) {
@@ -281,7 +905,12 @@ class SingleAgentClient {
281
905
  }
282
906
  const discoveredEndpoint = await this.discoverMCPEndpoint(this.normalizedAgent.agent_uri, options);
283
907
  if (usesScopedFetch) {
284
- return { ...this.normalizedAgent, agent_uri: discoveredEndpoint };
908
+ const discoveredAgent = { ...this.normalizedAgent, agent_uri: discoveredEndpoint };
909
+ if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
910
+ const { shareNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.mjs");
911
+ shareNonInteractiveOAuthProvider(this.normalizedAgent, discoveredAgent);
912
+ }
913
+ return discoveredAgent;
285
914
  }
286
915
  this.discoveredEndpoint = discoveredEndpoint;
287
916
  this.canonicalBaseUrl = this.computeBaseUrl(this.discoveredEndpoint);
@@ -289,6 +918,10 @@ class SingleAgentClient {
289
918
  ...this.normalizedAgent,
290
919
  agent_uri: this.discoveredEndpoint
291
920
  };
921
+ if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
922
+ const { shareNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.mjs");
923
+ shareNonInteractiveOAuthProvider(this.normalizedAgent, this.discoveredAgent);
924
+ }
292
925
  return this.discoveredAgent;
293
926
  }
294
927
  /**
@@ -444,8 +1077,10 @@ class SingleAgentClient {
444
1077
  const authToken = this.normalizedAgent.oauth_client_credentials ? this.normalizedAgent.oauth_tokens?.access_token : this.agent.auth_token;
445
1078
  const agentHeaders = this.agent.headers;
446
1079
  const authHeaders = { ...agentHeaders, ...createMCPAuthHeaders(authToken) };
447
- const authProvider = this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials ? (await import("../auth/oauth/index.mjs")).createNonInteractiveOAuthProvider(this.normalizedAgent, {
1080
+ const oauth = this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials ? await import("../auth/oauth/index.mjs") : void 0;
1081
+ const authProvider = oauth ? (await import("../auth/oauth/provider-cache.mjs")).getNonInteractiveOAuthProvider(this.normalizedAgent, {
448
1082
  agentHint: this.normalizedAgent.id,
1083
+ storage: oauth.getAgentStorage(this.normalizedAgent),
449
1084
  allowHttp: isLikelyPrivateUrl(this.normalizedAgent.agent_uri)
450
1085
  }) : void 0;
451
1086
  const testEndpoint = async (url) => {
@@ -643,8 +1278,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
643
1278
  * This is the lower-level receiver primitive for integrations that need to
644
1279
  * map malformed webhooks to precise HTTP responses. It verifies the legacy
645
1280
  * HMAC profile when `webhookSecret` is configured, parses raw JSON bodies,
646
- * validates the transport envelope shape, and returns the unwrapped AdCP
647
- * result plus routing metadata.
1281
+ * validates the transport envelope shape, and returns the canonicalized
1282
+ * AdCP result plus routing metadata. Legacy wire inspection is intentionally
1283
+ * confined to the transport adapter and is not returned by this primary API.
648
1284
  */
649
1285
  async verifyAndParseWebhook(options) {
650
1286
  const rawBody = options.rawBody ?? rawBodyFromUnknown(options.body);
@@ -676,37 +1312,107 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
676
1312
  if (!parsedPayload.ok) {
677
1313
  return parsedPayload;
678
1314
  }
1315
+ const parsedTaskType = isObjectRecord(parsedPayload.payload) && typeof parsedPayload.payload.task_type === "string" ? parsedPayload.payload.task_type : void 0;
1316
+ const payloadRecord = isObjectRecord(parsedPayload.payload) ? parsedPayload.payload : void 0;
1317
+ const associatedTaskTypes = new Set(
1318
+ [
1319
+ options.operationId,
1320
+ typeof payloadRecord?.operation_id === "string" ? payloadRecord.operation_id : void 0,
1321
+ typeof payloadRecord?.task_id === "string" ? payloadRecord.task_id : void 0,
1322
+ typeof payloadRecord?.context_id === "string" ? payloadRecord.context_id : void 0
1323
+ ].flatMap((id) => {
1324
+ const taskType = this.canonicalCreativeTaskAssociation(id)?.taskType;
1325
+ return taskType ? [taskType] : [];
1326
+ })
1327
+ );
1328
+ const associatedTaskType = associatedTaskTypes.size === 1 ? [...associatedTaskTypes][0] : void 0;
1329
+ const routedTaskType = options.taskType === "unknown" ? void 0 : options.taskType;
1330
+ const declaredTaskType = routedTaskType ?? parsedTaskType;
1331
+ if (associatedTaskTypes.size > 1 || associatedTaskType !== void 0 && declaredTaskType !== void 0 && associatedTaskType !== declaredTaskType) {
1332
+ return {
1333
+ ok: false,
1334
+ code: "webhook_envelope_invalid",
1335
+ message: "Webhook task_type does not match the locally tracked task association."
1336
+ };
1337
+ }
1338
+ let normalizedTaskType = associatedTaskType ?? declaredTaskType;
679
1339
  try {
680
1340
  const normalizedPayload = this.normalizeWebhookPayload(
681
1341
  parsedPayload.payload,
682
- options.taskType ?? "unknown",
1342
+ normalizedTaskType ?? "unknown",
683
1343
  options.operationId ?? "unknown"
684
1344
  );
1345
+ normalizedTaskType = normalizedPayload.task_type;
1346
+ if (associatedTaskType !== void 0 && normalizedPayload.task_type !== associatedTaskType) {
1347
+ return {
1348
+ ok: false,
1349
+ code: "webhook_envelope_invalid",
1350
+ message: "Webhook task_type does not match the locally tracked task association."
1351
+ };
1352
+ }
1353
+ const metadata = {
1354
+ operation_id: normalizedPayload.operation_id,
1355
+ context_id: normalizedPayload.context_id,
1356
+ task_id: normalizedPayload.task_id,
1357
+ agent_id: this.agent.id,
1358
+ task_type: normalizedPayload.task_type,
1359
+ status: normalizedPayload.status,
1360
+ message: normalizedPayload.message,
1361
+ timestamp: normalizedPayload.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
1362
+ idempotency_key: normalizedPayload.idempotency_key,
1363
+ protocol: normalizedPayload.protocol ?? "mcp"
1364
+ };
1365
+ const canonicalResult = this.canonicalizeWebhookCreativeResult(metadata, normalizedPayload.result);
1366
+ const canonicalCreativeTask = CANONICAL_CREATIVE_ACTIVITY_TASKS.has(normalizedPayload.task_type);
1367
+ const legacyFormatConverter = this.legacyFormatConverterForWebhook(metadata);
1368
+ const canonicalEnvelope = canonicalCreativeTask ? stripLegacyCreativeIdentity(
1369
+ projectCanonicalCreativeResponseValue(
1370
+ parsedPayload.payload,
1371
+ normalizedPayload.task_type,
1372
+ legacyFormatConverter
1373
+ )
1374
+ ) : parsedPayload.payload;
1375
+ const canonicalMessage = canonicalCreativeTask ? stripLegacyCreativeIdentity({
1376
+ message: normalizedPayload.message,
1377
+ legacySource: parsedPayload.payload
1378
+ }).message : normalizedPayload.message;
685
1379
  return {
686
1380
  ok: true,
687
1381
  protocol: normalizedPayload.protocol ?? "mcp",
688
- envelope: parsedPayload.payload,
689
- result: normalizedPayload.result,
1382
+ envelope: canonicalEnvelope,
1383
+ result: canonicalResult,
690
1384
  metadata: {
691
1385
  operationId: normalizedPayload.operation_id,
692
1386
  contextId: normalizedPayload.context_id,
693
1387
  taskId: normalizedPayload.task_id,
694
1388
  taskType: normalizedPayload.task_type,
695
1389
  status: normalizedPayload.status,
696
- message: normalizedPayload.message,
1390
+ message: canonicalMessage,
697
1391
  timestamp: normalizedPayload.timestamp,
698
1392
  idempotencyKey: normalizedPayload.idempotency_key
699
1393
  }
700
1394
  };
701
1395
  } catch (error) {
1396
+ const canonicalCreativeTask = normalizedTaskType !== void 0 && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(normalizedTaskType);
702
1397
  if (error instanceof WebhookDispatchError) {
703
- return { ok: false, code: error.code, message: error.message, cause: error.cause };
1398
+ if (!canonicalCreativeTask) {
1399
+ return { ok: false, code: error.code, message: error.message };
1400
+ }
1401
+ const safe = stripLegacyCreativeIdentity({
1402
+ message: error.message,
1403
+ legacySource: parsedPayload.payload
1404
+ });
1405
+ return { ok: false, code: error.code, message: safe.message };
1406
+ }
1407
+ const message = error instanceof Error ? error.message : "Webhook payload could not be normalized.";
1408
+ if (canonicalCreativeTask) {
1409
+ const safe = stripLegacyCreativeIdentity({ message, legacySource: parsedPayload.payload });
1410
+ return { ok: false, code: "webhook_result_invalid", message: safe.message };
704
1411
  }
705
1412
  return {
706
1413
  ok: false,
707
1414
  code: "webhook_result_invalid",
708
- message: error instanceof Error ? error.message : "Webhook payload could not be normalized.",
709
- cause: error
1415
+ message: "Webhook payload could not be normalized."
710
1416
  };
711
1417
  }
712
1418
  }
@@ -722,36 +1428,88 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
722
1428
  timestamp: parsed.metadata.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
723
1429
  idempotency_key: parsed.metadata.idempotencyKey,
724
1430
  protocol: parsed.protocol,
725
- rawHTTPPayload: parsed.envelope
1431
+ rawHTTPPayload: CANONICAL_CREATIVE_ACTIVITY_TASKS.has(parsed.metadata.taskType) ? stripLegacyCreativeIdentity(parsed.envelope) : parsed.envelope
726
1432
  };
727
- const policyDispatch = await this.applyProductPropertyPolicyToWebhookResult(
728
- parsed.result,
729
- metadata
730
- );
731
- const webhookResult = policyDispatch.result;
732
- metadata = policyDispatch.metadata;
733
- await this.config.onActivity?.({
734
- type: "webhook_received",
735
- operation_id: metadata.operation_id,
736
- agent_id: metadata.agent_id,
737
- context_id: metadata.context_id,
738
- task_id: metadata.task_id,
739
- task_type: metadata.task_type,
740
- status: metadata.status,
741
- payload: parsed.result,
742
- timestamp: metadata.timestamp
743
- });
744
- if (policyDispatch.suppressHandler) {
1433
+ this.rememberCanonicalCreativeWebhookContext(metadata);
1434
+ try {
1435
+ const canonicalResult = this.canonicalizeWebhookCreativeResult(metadata, parsed.result);
1436
+ const policyDispatch = await this.applyProductPropertyPolicyToWebhookResult(
1437
+ canonicalResult,
1438
+ metadata
1439
+ );
1440
+ const webhookResult = policyDispatch.result;
1441
+ metadata = policyDispatch.metadata;
1442
+ await this.config.onActivity?.(
1443
+ canonicalCreativeActivity({
1444
+ type: "webhook_received",
1445
+ operation_id: metadata.operation_id,
1446
+ agent_id: metadata.agent_id,
1447
+ context_id: metadata.context_id,
1448
+ task_id: metadata.task_id,
1449
+ task_type: metadata.task_type,
1450
+ status: metadata.status,
1451
+ payload: canonicalResult,
1452
+ timestamp: metadata.timestamp
1453
+ })
1454
+ );
1455
+ if (policyDispatch.suppressHandler) return true;
1456
+ if (this.asyncHandler) {
1457
+ await this.asyncHandler.handleWebhook({ result: webhookResult, metadata });
1458
+ return true;
1459
+ }
1460
+ return false;
1461
+ } finally {
1462
+ this.executor.observeExternalTaskStatus(
1463
+ metadata.operation_id,
1464
+ metadata.status,
1465
+ metadata.rawHTTPPayload
1466
+ );
745
1467
  this.forgetProductPolicyRequestParams(metadata);
746
- return true;
747
1468
  }
748
- if (this.asyncHandler) {
749
- await this.asyncHandler.handleWebhook({ result: webhookResult, metadata });
750
- this.forgetProductPolicyRequestParams(metadata);
751
- return true;
1469
+ }
1470
+ rememberCanonicalCreativeWebhookContext(metadata) {
1471
+ if (!metadata.context_id || !CANONICAL_CREATIVE_ACTIVITY_TASKS.has(metadata.task_type)) return;
1472
+ const association = this.canonicalCreativeTaskAssociation(metadata.operation_id) ?? this.canonicalCreativeTaskAssociation(metadata.task_id) ?? this.canonicalCreativeTaskAssociation(metadata.context_id);
1473
+ if (!association) return;
1474
+ this.rememberCanonicalCreativeTaskAssociation(
1475
+ metadata.context_id,
1476
+ association.taskType,
1477
+ association.legacyFormatConverter,
1478
+ association.routingSnapshot
1479
+ );
1480
+ }
1481
+ canonicalizeWebhookCreativeResult(metadata, result) {
1482
+ if (!result || typeof result !== "object" || Array.isArray(result)) return result;
1483
+ const taskType = metadata.task_type;
1484
+ const legacyFormatConverter = this.legacyFormatConverterForWebhook(metadata);
1485
+ const response = result;
1486
+ if (taskType === "get_products" && Array.isArray(response.products)) {
1487
+ const { response: canonical2, diagnostics } = toCanonicalOnlyResponse(
1488
+ response,
1489
+ { legacyFormatConverter }
1490
+ );
1491
+ const requestParams = this.productPolicyRequestParamsForWebhook(metadata);
1492
+ this.rememberCanonicalProductRoutes(canonical2.products, requestParams.account, response.products);
1493
+ const { _message: _dropLegacyMessage, ...safe } = canonical2;
1494
+ void _dropLegacyMessage;
1495
+ return stripLegacyCreativeIdentity({ ...safe, projection: { diagnostics } });
1496
+ }
1497
+ if (taskType === "list_creatives" && Array.isArray(response.creatives)) {
1498
+ const { _message: _dropLegacyMessage, ...safe } = response;
1499
+ void _dropLegacyMessage;
1500
+ return stripLegacyCreativeIdentity({
1501
+ ...safe,
1502
+ creatives: response.creatives.map(
1503
+ (creative) => projectCreativeForDelivery(creative, {}, "canonical", "list_creatives", legacyFormatConverter)
1504
+ )
1505
+ });
1506
+ }
1507
+ const canonical = CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType) ? stripLegacyCreativeIdentity(projectCanonicalCreativeResponseValue(result, taskType, legacyFormatConverter)) : result;
1508
+ const association = this.canonicalCreativeTaskAssociation(metadata.operation_id) ?? this.canonicalCreativeTaskAssociation(metadata.task_id) ?? this.canonicalCreativeTaskAssociation(metadata.context_id);
1509
+ if (metadata.status === "completed") {
1510
+ this.rememberCanonicalPackageRoutesForTask(taskType, canonical, association?.routingSnapshot);
752
1511
  }
753
- this.forgetProductPolicyRequestParams(metadata);
754
- return false;
1512
+ return canonical;
755
1513
  }
756
1514
  /**
757
1515
  * Normalize webhook payload - handles both MCP and A2A webhook formats
@@ -790,7 +1548,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
790
1548
  if (typeof payload.status !== "string" || !WEBHOOK_TASK_STATUSES.has(payload.status)) {
791
1549
  throw new WebhookDispatchError(
792
1550
  "webhook_envelope_invalid",
793
- `Invalid MCP webhook envelope: unsupported top-level status ${JSON.stringify(payload.status)}. Expected one of ${Array.from(WEBHOOK_TASK_STATUSES).join(", ")}.`
1551
+ `Invalid MCP webhook envelope: unsupported top-level status. Expected one of ${Array.from(WEBHOOK_TASK_STATUSES).join(", ")}.`
794
1552
  );
795
1553
  }
796
1554
  if (typeof payload.timestamp !== "string" || Number.isNaN(Date.parse(payload.timestamp))) {
@@ -830,7 +1588,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
830
1588
  } catch (error) {
831
1589
  throw new WebhookDispatchError(
832
1590
  "webhook_result_invalid",
833
- `Failed to unwrap A2A webhook payload artifacts: ${error instanceof Error ? error.message : "unknown error"}`,
1591
+ "Failed to unwrap A2A webhook payload artifacts.",
834
1592
  error
835
1593
  );
836
1594
  }
@@ -862,7 +1620,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
862
1620
  }
863
1621
  throw new WebhookDispatchError(
864
1622
  "webhook_unsupported_payload",
865
- `Unsupported webhook payload format. Expected an MCP webhook envelope with top-level idempotency_key, operation_id, task_id, task_type, status, timestamp, and result, or an A2A Task/TaskStatusUpdateEvent with AdCP data nested in status.message.parts[].data or task artifacts. Received: ${safeJsonPreview(payload)}`
1623
+ "Unsupported webhook payload format. Expected an MCP webhook envelope with top-level idempotency_key, operation_id, task_id, task_type, status, timestamp, and result, or an A2A Task/TaskStatusUpdateEvent with AdCP data nested in status.message.parts[].data or task artifacts."
866
1624
  );
867
1625
  }
868
1626
  /**
@@ -1003,7 +1761,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1003
1761
  *
1004
1762
  * Automatically adapts requests for v2 servers and normalizes responses.
1005
1763
  */
1006
- async executeAndHandle(taskType, handlerName, params, inputHandler, options) {
1764
+ async executeAndHandle(taskType, handlerName, params, inputHandler, options, transformCompletedResponse, legacyFormatConverter, canonicalRequest) {
1007
1765
  throwIfAborted(options?.signal);
1008
1766
  let normalizedParams = normalizeRequestParams(taskType, params, {
1009
1767
  skipIdempotencyAutoInject: options?.skipIdempotencyAutoInject,
@@ -1051,13 +1809,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1051
1809
  if (serverVersion === "v2") {
1052
1810
  this.executor.validateAdaptedRequestAgainstV2(taskType, adaptedParams, v25DriftLogs);
1053
1811
  }
1054
- let result = await this.executor.executeTask(
1055
- agent,
1056
- taskType,
1057
- adaptedParams,
1058
- inputHandler,
1059
- effectiveOptions,
1060
- serverVersion
1812
+ const canonicalInputHandler = this.canonicalCreativeInputHandler(taskType, inputHandler);
1813
+ let result = await canonicalCreativeExecutionStorage.run(
1814
+ { taskType, legacyFormatConverter, canonicalRequest: canonicalRequest ?? normalizedParams },
1815
+ () => this.executor.executeTask(
1816
+ agent,
1817
+ taskType,
1818
+ adaptedParams,
1819
+ canonicalInputHandler,
1820
+ effectiveOptions,
1821
+ serverVersion
1822
+ )
1061
1823
  );
1062
1824
  const postAdapterLogs = [...inputSchemaStripLogs, ...v25DriftLogs];
1063
1825
  if (postAdapterLogs.length > 0) {
@@ -1066,9 +1828,26 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1066
1828
  if (result.success && result.data) {
1067
1829
  result.data = this.normalizeResponseToV3(taskType, result.data);
1068
1830
  }
1069
- result = this.wrapProductPolicySubmittedContinuation(result, taskType, normalizedParams);
1070
- this.rememberProductPolicyRequestParams(taskType, normalizedParams, result, options);
1831
+ result = this.wrapProductPolicySubmittedContinuation(result, taskType, normalizedParams, options);
1832
+ if (result.status === "working") {
1833
+ this.rememberProductPolicyRequestParams(taskType, normalizedParams, result, options);
1834
+ }
1835
+ this.rememberLegacyFormatConverter(taskType, legacyFormatConverter, result, options);
1071
1836
  result = await this.applyProductPropertyPolicy(result, taskType, normalizedParams);
1837
+ if (CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) {
1838
+ const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, canonicalRequest ?? normalizedParams);
1839
+ result = this.canonicalizeCreativeTaskResult(result, taskType, transformCompletedResponse, legacyFormatConverter);
1840
+ result = this.wrapCanonicalCreativeContinuations(
1841
+ result,
1842
+ taskType,
1843
+ transformCompletedResponse,
1844
+ legacyFormatConverter,
1845
+ routingSnapshot
1846
+ );
1847
+ this.rememberCanonicalCreativeTaskIds(result, taskType, legacyFormatConverter, routingSnapshot);
1848
+ } else if (result.status === "completed" && result.success && result.data && transformCompletedResponse) {
1849
+ result = { ...result, data: transformCompletedResponse(result.data) };
1850
+ }
1072
1851
  if (result.status === "completed" && result.success && this.asyncHandler) {
1073
1852
  const handler = this.config.handlers?.[handlerName];
1074
1853
  if (handler) {
@@ -1078,6 +1857,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1078
1857
  task_id: result.metadata.taskId,
1079
1858
  agent_id: this.agent.id,
1080
1859
  task_type: taskType,
1860
+ status: result.status,
1081
1861
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1082
1862
  };
1083
1863
  await handler(result.data, metadata);
@@ -1085,6 +1865,255 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1085
1865
  }
1086
1866
  return result;
1087
1867
  }
1868
+ canonicalCreativeInputHandler(taskType, inputHandler) {
1869
+ if (!inputHandler || !CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) return inputHandler;
1870
+ return async (context) => {
1871
+ const active = canonicalCreativeExecutionStorage.getStore();
1872
+ const converter = this.resolveLegacyFormatConverter(
1873
+ active?.taskType === taskType ? active.legacyFormatConverter : void 0
1874
+ );
1875
+ const project = (value) => projectCanonicalCreativeAncillaryValue(value, taskType, converter);
1876
+ const messages = context.messages.map((message) => ({
1877
+ ...message,
1878
+ content: project(message.content)
1879
+ }));
1880
+ const safeContext = {
1881
+ ...context,
1882
+ messages,
1883
+ inputRequest: project(context.inputRequest),
1884
+ getSummary: () => messages.map((message) => `${message.role}: ${JSON.stringify(message.content)}`).join("\n"),
1885
+ getPreviousResponse: (field) => project(context.getPreviousResponse(field))
1886
+ };
1887
+ return inputHandler(safeContext);
1888
+ };
1889
+ }
1890
+ projectCanonicalCreativeData(taskType, data, transform, legacyFormatConverter) {
1891
+ let projected = this.normalizeResponseToV3(taskType, data);
1892
+ const record = projected && typeof projected === "object" ? projected : void 0;
1893
+ const canProjectRead = taskType === "get_products" ? Array.isArray(record?.products) : taskType === "list_creatives" ? Array.isArray(record?.creatives) : true;
1894
+ if (transform && canProjectRead) {
1895
+ projected = transform(projected);
1896
+ } else if (canProjectRead && taskType === "get_products" && record) {
1897
+ const active = canonicalCreativeExecutionStorage.getStore();
1898
+ const { response, diagnostics } = toCanonicalOnlyResponse(record, {
1899
+ legacyFormatConverter: this.resolveLegacyFormatConverter(
1900
+ legacyFormatConverter ?? (active?.taskType === taskType ? active.legacyFormatConverter : void 0)
1901
+ ),
1902
+ projectionCatalogs: this.config.projectionCatalogs
1903
+ });
1904
+ const { _message: _dropLegacyMessage, ...canonical } = response;
1905
+ void _dropLegacyMessage;
1906
+ projected = { ...canonical, projection: { diagnostics } };
1907
+ } else if (canProjectRead && taskType === "list_creatives" && record) {
1908
+ const active = canonicalCreativeExecutionStorage.getStore();
1909
+ const activeLegacyFormatConverter = this.resolveLegacyFormatConverter(
1910
+ legacyFormatConverter ?? (active?.taskType === taskType ? active.legacyFormatConverter : void 0)
1911
+ );
1912
+ const { _message: _dropLegacyMessage, ...safe } = record;
1913
+ void _dropLegacyMessage;
1914
+ projected = {
1915
+ ...safe,
1916
+ creatives: record.creatives.map(
1917
+ (creative) => projectCreativeForDelivery(
1918
+ creative,
1919
+ {},
1920
+ "canonical",
1921
+ "list_creatives",
1922
+ activeLegacyFormatConverter
1923
+ )
1924
+ )
1925
+ };
1926
+ } else if (canProjectRead && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) {
1927
+ const active = canonicalCreativeExecutionStorage.getStore();
1928
+ projected = projectCanonicalCreativeResponseValue(
1929
+ projected,
1930
+ taskType,
1931
+ this.resolveLegacyFormatConverter(
1932
+ legacyFormatConverter ?? (active?.taskType === taskType ? active.legacyFormatConverter : void 0)
1933
+ )
1934
+ );
1935
+ }
1936
+ return stripLegacyCreativeIdentity(projected);
1937
+ }
1938
+ canonicalizeCreativeTaskResult(result, taskType, transform, legacyFormatConverter) {
1939
+ const projectedData = result.data !== void 0 ? this.projectCanonicalCreativeData(taskType, result.data, transform, legacyFormatConverter) : void 0;
1940
+ const errorInstance = result.errorInstance;
1941
+ const converter = this.resolveLegacyFormatConverter(legacyFormatConverter);
1942
+ const metadataRecord = result.metadata;
1943
+ const semanticMetadata = {
1944
+ ...metadataRecord,
1945
+ ...metadataRecord.inputRequest !== void 0 && {
1946
+ inputRequest: projectCanonicalCreativeAncillaryValue(metadataRecord.inputRequest, taskType, converter)
1947
+ }
1948
+ };
1949
+ const semanticConversation = result.conversation?.map((message) => ({
1950
+ ...message,
1951
+ content: projectCanonicalCreativeAncillaryValue(message.content, taskType, converter)
1952
+ }));
1953
+ const safe = stripLegacyCreativeIdentity({
1954
+ data: projectedData,
1955
+ metadata: semanticMetadata,
1956
+ conversation: semanticConversation,
1957
+ debug_logs: result.debug_logs,
1958
+ adcpError: result.adcpError,
1959
+ error: result.error,
1960
+ governance: result.governance,
1961
+ governanceOutcome: result.governanceOutcome,
1962
+ governanceOutcomeError: result.governanceOutcomeError,
1963
+ deferredQuestion: result.deferred?.question,
1964
+ // Token source only: discarded below, but lets the sanitizer remove exact
1965
+ // legacy IDs/URLs when the seller repeats them in messages or diagnostics.
1966
+ legacySource: result.data
1967
+ });
1968
+ const safeErrorInstance = errorInstance ? canonicalCreativeErrorInstance(errorInstance, result.data) : void 0;
1969
+ const safeDeferred = result.deferred ? { ...result.deferred, ...result.deferred.question !== void 0 && { question: safe.deferredQuestion } } : void 0;
1970
+ return attachMatch({
1971
+ ...result,
1972
+ ...result.data !== void 0 && { data: safe.data },
1973
+ metadata: safe.metadata,
1974
+ ...result.conversation !== void 0 && { conversation: safe.conversation },
1975
+ ...result.debug_logs !== void 0 && { debug_logs: safe.debug_logs },
1976
+ ...result.adcpError !== void 0 && { adcpError: safe.adcpError },
1977
+ ...result.error !== void 0 && { error: safe.error },
1978
+ ...result.governance !== void 0 && { governance: safe.governance },
1979
+ ...result.governanceOutcome !== void 0 && { governanceOutcome: safe.governanceOutcome },
1980
+ ...result.governanceOutcomeError !== void 0 && { governanceOutcomeError: safe.governanceOutcomeError },
1981
+ ...safeDeferred !== void 0 && { deferred: safeDeferred },
1982
+ ...safeErrorInstance !== void 0 && { errorInstance: safeErrorInstance }
1983
+ });
1984
+ }
1985
+ canonicalizeCreativeTaskInfo(taskInfo, taskType, transform, legacyFormatConverter) {
1986
+ const source = taskInfo.result;
1987
+ const projected = source !== void 0 ? this.projectCanonicalCreativeData(taskType, source, transform, legacyFormatConverter) : void 0;
1988
+ const { legacySource: _dropLegacySource, ...safe } = stripLegacyCreativeIdentity({
1989
+ ...taskInfo,
1990
+ taskType,
1991
+ ...source !== void 0 && { result: projected },
1992
+ legacySource: source
1993
+ });
1994
+ void _dropLegacySource;
1995
+ return safe;
1996
+ }
1997
+ wrapCanonicalCreativeContinuations(result, taskType, transform, legacyFormatConverter, routingRequest) {
1998
+ const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, routingRequest);
1999
+ if (result.submitted) {
2000
+ const submitted = result.submitted;
2001
+ result = {
2002
+ ...result,
2003
+ submitted: {
2004
+ ...submitted,
2005
+ track: async (transport) => {
2006
+ const canonical = this.canonicalizeCreativeTaskInfo(
2007
+ await canonicalCreativeExecutionStorage.run(
2008
+ { taskType, legacyFormatConverter },
2009
+ () => submitted.track(transport)
2010
+ ),
2011
+ taskType,
2012
+ transform,
2013
+ legacyFormatConverter
2014
+ );
2015
+ if (canonical.status === "completed" && canonical.result !== void 0) {
2016
+ this.rememberCanonicalPackageRoutesForTask(taskType, canonical.result, routingSnapshot);
2017
+ }
2018
+ return canonical;
2019
+ },
2020
+ waitForCompletion: async (pollInterval, signal) => {
2021
+ const completed = await canonicalCreativeExecutionStorage.run(
2022
+ { taskType, legacyFormatConverter },
2023
+ () => submitted.waitForCompletion(pollInterval, signal)
2024
+ );
2025
+ const canonical = this.canonicalizeCreativeTaskResult(
2026
+ completed,
2027
+ taskType,
2028
+ transform,
2029
+ legacyFormatConverter
2030
+ );
2031
+ if (canonical.success && canonical.status === "completed" && canonical.data !== void 0) {
2032
+ this.rememberCanonicalPackageRoutesForTask(taskType, canonical.data, routingSnapshot);
2033
+ }
2034
+ this.rememberCanonicalCreativeTaskIds(canonical, taskType, legacyFormatConverter, routingSnapshot);
2035
+ return this.wrapCanonicalCreativeContinuations(
2036
+ canonical,
2037
+ taskType,
2038
+ transform,
2039
+ legacyFormatConverter,
2040
+ routingSnapshot
2041
+ );
2042
+ }
2043
+ }
2044
+ };
2045
+ }
2046
+ if (result.deferred) {
2047
+ const deferred = result.deferred;
2048
+ result = {
2049
+ ...result,
2050
+ deferred: {
2051
+ ...deferred,
2052
+ resume: async (input) => {
2053
+ const resumed = await canonicalCreativeExecutionStorage.run(
2054
+ { taskType, legacyFormatConverter },
2055
+ () => deferred.resume(input)
2056
+ );
2057
+ const canonical = this.canonicalizeCreativeTaskResult(resumed, taskType, transform, legacyFormatConverter);
2058
+ if (canonical.success && canonical.status === "completed" && canonical.data !== void 0) {
2059
+ this.rememberCanonicalPackageRoutesForTask(taskType, canonical.data, routingSnapshot);
2060
+ }
2061
+ this.rememberCanonicalCreativeTaskIds(canonical, taskType, legacyFormatConverter, routingSnapshot);
2062
+ return this.wrapCanonicalCreativeContinuations(
2063
+ canonical,
2064
+ taskType,
2065
+ transform,
2066
+ legacyFormatConverter,
2067
+ routingSnapshot
2068
+ );
2069
+ }
2070
+ }
2071
+ };
2072
+ }
2073
+ return attachMatch(result);
2074
+ }
2075
+ rememberCanonicalCreativeTaskIds(result, taskType, legacyFormatConverter, routingRequest) {
2076
+ const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, routingRequest);
2077
+ const keys = [
2078
+ result.metadata.taskId,
2079
+ result.metadata.contextId,
2080
+ result.metadata.serverTaskId,
2081
+ result.submitted?.taskId
2082
+ ];
2083
+ for (const key of keys) {
2084
+ if (!key) continue;
2085
+ this.rememberCanonicalCreativeTaskAssociation(key, taskType, legacyFormatConverter, routingSnapshot);
2086
+ }
2087
+ }
2088
+ rememberCanonicalCreativeTaskAssociation(key, taskType, legacyFormatConverter, canonicalRequest) {
2089
+ const previous = this.canonicalCreativeTaskAssociations.get(key);
2090
+ const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, canonicalRequest);
2091
+ const effectiveRoutingSnapshot = routingSnapshot ?? (previous?.taskType === taskType ? previous.routingSnapshot : void 0);
2092
+ this.canonicalCreativeTaskAssociations.delete(key);
2093
+ this.canonicalCreativeTaskAssociations.set(key, {
2094
+ taskType,
2095
+ legacyFormatConverter,
2096
+ ...effectiveRoutingSnapshot ? { routingSnapshot: effectiveRoutingSnapshot } : {}
2097
+ });
2098
+ while (this.canonicalCreativeTaskAssociations.size > TASK_SCOPED_STATE_LIMIT) {
2099
+ const oldest = this.canonicalCreativeTaskAssociations.keys().next().value;
2100
+ if (oldest === void 0) break;
2101
+ this.canonicalCreativeTaskAssociations.delete(oldest);
2102
+ }
2103
+ }
2104
+ canonicalCreativeTaskAssociation(key) {
2105
+ if (!key) return void 0;
2106
+ const association = this.canonicalCreativeTaskAssociations.get(key);
2107
+ if (!association) return void 0;
2108
+ this.canonicalCreativeTaskAssociations.delete(key);
2109
+ this.canonicalCreativeTaskAssociations.set(key, association);
2110
+ return association;
2111
+ }
2112
+ forgetCanonicalCreativeTaskAssociationKeys(keys) {
2113
+ for (const key of keys) {
2114
+ if (key) this.canonicalCreativeTaskAssociations.delete(key);
2115
+ }
2116
+ }
1088
2117
  /**
1089
2118
  * Drop products that arrive without a usable `pricing_options[]` array from a
1090
2119
  * completed `get_products` response. `pricing_options` is required and
@@ -1295,20 +2324,62 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1295
2324
  return result;
1296
2325
  }
1297
2326
  rememberProductPolicyRequestParams(taskType, requestParams, result, options) {
2327
+ this.rememberProductPolicyRequestState(
2328
+ taskType,
2329
+ { request: productPolicyRequestSnapshot(requestParams) },
2330
+ result,
2331
+ options
2332
+ );
2333
+ }
2334
+ rememberProductPolicyRequestState(taskType, requestState, result, options) {
1298
2335
  if (taskType !== "get_products") return;
1299
2336
  if (result.status !== "submitted" && result.status !== "working") return;
1300
2337
  const keys = /* @__PURE__ */ new Set();
1301
2338
  if (result.metadata.taskId) keys.add(result.metadata.taskId);
1302
2339
  if (result.metadata.contextId) keys.add(result.metadata.contextId);
1303
2340
  if (result.metadata.serverTaskId) keys.add(result.metadata.serverTaskId);
2341
+ if (result.submitted?.taskId) keys.add(result.submitted.taskId);
1304
2342
  if (options?.taskId) keys.add(options.taskId);
1305
2343
  if (options?.contextId) keys.add(options.contextId);
1306
2344
  for (const key of keys) {
1307
- this.productPolicyRequestParamsByTask.set(key, requestParams);
2345
+ this.productPolicyRequestParamsByTask.delete(key);
2346
+ this.productPolicyRequestParamsByTask.set(key, requestState);
2347
+ while (this.productPolicyRequestParamsByTask.size > TASK_SCOPED_STATE_LIMIT) {
2348
+ const oldest = this.productPolicyRequestParamsByTask.keys().next().value;
2349
+ if (oldest === void 0) break;
2350
+ this.productPolicyRequestParamsByTask.delete(oldest);
2351
+ }
1308
2352
  }
1309
2353
  }
2354
+ rememberLegacyFormatConverter(taskType, converter, result, options) {
2355
+ if (!converter || taskType !== "get_products" && taskType !== "list_creatives") return;
2356
+ const metadata = result.metadata;
2357
+ const keys = [
2358
+ metadata.operationId,
2359
+ metadata.taskId,
2360
+ metadata.contextId,
2361
+ metadata.serverTaskId,
2362
+ options?.taskId,
2363
+ options?.contextId
2364
+ ];
2365
+ for (const key of keys) {
2366
+ if (key) this.rememberCanonicalCreativeTaskAssociation(key, taskType, converter);
2367
+ }
2368
+ }
2369
+ legacyFormatConverterForWebhook(metadata) {
2370
+ return this.canonicalCreativeTaskAssociation(metadata.operation_id)?.legacyFormatConverter ?? this.canonicalCreativeTaskAssociation(metadata.task_id)?.legacyFormatConverter ?? this.canonicalCreativeTaskAssociation(metadata.context_id)?.legacyFormatConverter ?? this.resolveLegacyFormatConverter();
2371
+ }
1310
2372
  forgetProductPolicyRequestParams(metadata) {
1311
- this.forgetProductPolicyRequestParamKeys([metadata.operation_id, metadata.task_id, metadata.context_id]);
2373
+ const aliases = [metadata.operation_id, metadata.task_id, metadata.context_id];
2374
+ const states = new Set(
2375
+ aliases.filter((key) => key !== void 0).map((key) => this.productPolicyRequestParamsByTask.get(key)).filter((value) => value !== void 0)
2376
+ );
2377
+ for (const state of states) state.request = void 0;
2378
+ this.forgetProductPolicyRequestParamKeys(aliases);
2379
+ if (states.size === 0) return;
2380
+ for (const [key, state] of this.productPolicyRequestParamsByTask) {
2381
+ if (states.has(state)) this.productPolicyRequestParamsByTask.delete(key);
2382
+ }
1312
2383
  }
1313
2384
  forgetProductPolicyRequestParamKeys(keys) {
1314
2385
  for (const key of keys) {
@@ -1316,38 +2387,61 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1316
2387
  this.productPolicyRequestParamsByTask.delete(key);
1317
2388
  }
1318
2389
  }
1319
- wrapProductPolicySubmittedContinuation(result, taskType, requestParams) {
2390
+ wrapProductPolicySubmittedContinuation(result, taskType, requestParams, options) {
1320
2391
  if (taskType !== "get_products" || result.status !== "submitted" || !result.submitted) return result;
1321
2392
  const submitted = result.submitted;
2393
+ const policyState = {
2394
+ request: productPolicyRequestSnapshot(requestParams)
2395
+ };
2396
+ this.rememberProductPolicyRequestState(taskType, policyState, result, options);
2397
+ const retainedKeys = [
2398
+ result.metadata.taskId,
2399
+ result.metadata.contextId,
2400
+ result.metadata.serverTaskId,
2401
+ submitted.taskId,
2402
+ options?.taskId,
2403
+ options?.contextId
2404
+ ];
1322
2405
  result.submitted = {
1323
2406
  ...submitted,
1324
2407
  track: async (transport) => {
1325
2408
  const taskInfo = await submitted.track(transport);
1326
- const processed = await this.applyProductPropertyPolicyToTaskInfo(taskInfo, taskType, requestParams);
1327
- if (["completed", "failed", "rejected", "canceled"].includes(processed.status)) {
1328
- this.forgetProductPolicyRequestParamKeys([
1329
- result.metadata.taskId,
1330
- result.metadata.serverTaskId,
1331
- processed.taskId
1332
- ]);
2409
+ const terminal = ["completed", "failed", "rejected", "canceled"].includes(taskInfo.status);
2410
+ try {
2411
+ return await this.applyProductPropertyPolicyToTaskInfo(
2412
+ taskInfo,
2413
+ taskType,
2414
+ policyState.request ?? {}
2415
+ );
2416
+ } finally {
2417
+ if (terminal) {
2418
+ policyState.request = void 0;
2419
+ this.forgetProductPolicyRequestParamKeys([...retainedKeys, taskInfo.taskId]);
2420
+ }
1333
2421
  }
1334
- return processed;
1335
2422
  },
1336
2423
  waitForCompletion: async (pollInterval, signal) => {
1337
2424
  let completed = await submitted.waitForCompletion(pollInterval, signal);
1338
2425
  if (completed.success && completed.data) {
1339
2426
  completed.data = this.normalizeResponseToV3(taskType, completed.data);
1340
2427
  }
1341
- const processed = await this.applyProductPropertyPolicy(completed, taskType, requestParams);
1342
- if (processed.status === "completed" || processed.status === "failed") {
1343
- this.forgetProductPolicyRequestParamKeys([
1344
- result.metadata.taskId,
1345
- result.metadata.serverTaskId,
1346
- processed.metadata.taskId,
1347
- processed.metadata.serverTaskId
1348
- ]);
2428
+ const terminal = completed.status === "completed" || completed.status === "failed";
2429
+ try {
2430
+ return await this.applyProductPropertyPolicy(
2431
+ completed,
2432
+ taskType,
2433
+ policyState.request ?? {}
2434
+ );
2435
+ } finally {
2436
+ if (terminal) {
2437
+ policyState.request = void 0;
2438
+ this.forgetProductPolicyRequestParamKeys([
2439
+ ...retainedKeys,
2440
+ completed.metadata.taskId,
2441
+ completed.metadata.serverTaskId
2442
+ ]);
2443
+ }
1349
2444
  }
1350
- return processed;
1351
2445
  }
1352
2446
  };
1353
2447
  return result;
@@ -1385,7 +2479,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1385
2479
  };
1386
2480
  }
1387
2481
  productPolicyRequestParamsForWebhook(metadata) {
1388
- return this.executor.getRequestParams(metadata.operation_id) ?? this.executor.getRequestParams(metadata.task_id) ?? this.productPolicyRequestParamsByTask.get(metadata.operation_id) ?? this.productPolicyRequestParamsByTask.get(metadata.task_id) ?? (metadata.context_id ? this.productPolicyRequestParamsByTask.get(metadata.context_id) : void 0) ?? {};
2482
+ return this.executor.getRequestParams(metadata.operation_id) ?? this.executor.getRequestParams(metadata.task_id) ?? this.productPolicyRequestParamsForKey(metadata.operation_id) ?? this.productPolicyRequestParamsForKey(metadata.task_id) ?? this.productPolicyRequestParamsForKey(metadata.context_id) ?? {};
2483
+ }
2484
+ productPolicyRequestParamsForKey(key) {
2485
+ if (!key) return void 0;
2486
+ const state = this.productPolicyRequestParamsByTask.get(key);
2487
+ if (!state?.request) return void 0;
2488
+ this.productPolicyRequestParamsByTask.delete(key);
2489
+ this.productPolicyRequestParamsByTask.set(key, state);
2490
+ return state.request;
1389
2491
  }
1390
2492
  async applyProductPropertyPolicyToWebhookResult(result, metadata) {
1391
2493
  if (metadata.task_type !== "get_products" || metadata.status !== "completed" || !result) {
@@ -1580,30 +2682,57 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1580
2682
  * ```
1581
2683
  */
1582
2684
  async getProducts(params, inputHandler, options) {
2685
+ const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
2686
+ const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
2687
+ legacyFormatConverter,
2688
+ projectionCatalogs ?? this.config.projectionCatalogs
2689
+ );
2690
+ const account = canonicalAccountRoutingSnapshot(params.account);
1583
2691
  return this.executeAndHandle(
1584
2692
  "get_products",
1585
2693
  "onGetProductsStatusChange",
1586
2694
  params,
1587
2695
  inputHandler,
1588
- options
2696
+ taskOptions,
2697
+ (data) => {
2698
+ const { response, diagnostics } = toCanonicalOnlyResponse(data, {
2699
+ legacyFormatConverter: effectiveLegacyFormatConverter,
2700
+ projectionCatalogs: projectionCatalogs ?? this.config.projectionCatalogs
2701
+ });
2702
+ const authoritativeProducts = Array.isArray(data.products) ? data.products : response.products;
2703
+ this.rememberCanonicalProductRoutes(response.products, account, authoritativeProducts);
2704
+ const { _message: _dropLegacyMessage, ...canonical } = response;
2705
+ void _dropLegacyMessage;
2706
+ return { ...canonical, projection: { diagnostics } };
2707
+ },
2708
+ effectiveLegacyFormatConverter
1589
2709
  );
1590
2710
  }
2711
+ /** @deprecated Explicit raw-wire escape hatch for migration tooling. */
2712
+ async getProductsLegacy(params, inputHandler, options) {
2713
+ return this.executeTaskUnprojected("get_products", params, inputHandler, options);
2714
+ }
1591
2715
  /**
1592
- * List available creative formats
2716
+ * List a legacy named-format catalog for migration tooling.
1593
2717
  *
1594
2718
  * @param params - Format listing parameters
1595
2719
  * @param inputHandler - Handler for clarification requests
1596
2720
  * @param options - Task execution options
2721
+ * @deprecated Canonical applications discover `format_options[]` through `getProducts()`.
1597
2722
  */
1598
- async listCreativeFormats(params, inputHandler, options) {
2723
+ async listCreativeFormatsLegacy(params, inputHandler, options) {
1599
2724
  return this.executeAndHandle(
1600
2725
  "list_creative_formats",
1601
- "onListCreativeFormatsStatusChange",
2726
+ "onListCreativeFormatsLegacyStatusChange",
1602
2727
  params,
1603
2728
  inputHandler,
1604
2729
  options
1605
2730
  );
1606
2731
  }
2732
+ /** @deprecated Migration-only access to legacy creative transformer declarations. */
2733
+ async listTransformersLegacy(params, inputHandler, options) {
2734
+ return this.executeTaskUnprojected("list_transformers", params, inputHandler, options);
2735
+ }
1607
2736
  /**
1608
2737
  * Create a new media buy
1609
2738
  *
@@ -1612,6 +2741,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1612
2741
  * @param options - Task execution options
1613
2742
  */
1614
2743
  async createMediaBuy(params, inputHandler, options) {
2744
+ const { legacyFormatConverter, projectionCatalogs, canonicalFormatLegacyResolver, ...taskOptions } = options ?? {};
2745
+ const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
2746
+ legacyFormatConverter,
2747
+ projectionCatalogs ?? this.config.projectionCatalogs
2748
+ );
2749
+ const effectiveCanonicalFormatLegacyResolver = this.resolveCanonicalFormatLegacyResolver(
2750
+ canonicalFormatLegacyResolver,
2751
+ params.account
2752
+ );
2753
+ const hasCreativeFormatData = hasMediaBuyCreativeFormatData(params);
2754
+ if (hasCreativeFormatData) {
2755
+ this.validateBeforeCreativeCapabilityProbe("create_media_buy", params, taskOptions);
2756
+ }
2757
+ const wireMode = hasCreativeFormatData ? this.resolveCreativeFormatWireMode(
2758
+ "create_media_buy",
2759
+ await this.getCapabilities({ signal: taskOptions.signal, transport: taskOptions.transport })
2760
+ ) : "canonical";
1615
2761
  if (this.config.webhookUrlTemplate && !options?.disableWebhook) {
1616
2762
  const now = /* @__PURE__ */ new Date();
1617
2763
  const year = now.getUTCFullYear();
@@ -1646,9 +2792,28 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1646
2792
  };
1647
2793
  }
1648
2794
  }
1649
- return this.executeAndHandle(
2795
+ const result = await this.executeAndHandle(
1650
2796
  "create_media_buy",
1651
2797
  "onCreateMediaBuyStatusChange",
2798
+ projectMediaBuyCreativesForDelivery(
2799
+ params,
2800
+ wireMode,
2801
+ "create_media_buy",
2802
+ effectiveLegacyFormatConverter,
2803
+ effectiveCanonicalFormatLegacyResolver
2804
+ ),
2805
+ inputHandler,
2806
+ taskOptions,
2807
+ void 0,
2808
+ effectiveLegacyFormatConverter,
2809
+ params
2810
+ );
2811
+ if (result.data !== void 0) this.rememberCanonicalPackageRoutes(result.data, params);
2812
+ return result;
2813
+ }
2814
+ /** @deprecated Compatibility-only entry point for callers still holding legacy creative `format_id` values. */
2815
+ async createMediaBuyLegacy(params, inputHandler, options) {
2816
+ return await this.createMediaBuy(
1652
2817
  params,
1653
2818
  inputHandler,
1654
2819
  options
@@ -1662,9 +2827,45 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1662
2827
  * @param options - Task execution options
1663
2828
  */
1664
2829
  async updateMediaBuy(params, inputHandler, options) {
1665
- return this.executeAndHandle(
2830
+ const { legacyFormatConverter, projectionCatalogs, canonicalFormatLegacyResolver, ...taskOptions } = options ?? {};
2831
+ const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
2832
+ legacyFormatConverter,
2833
+ projectionCatalogs ?? this.config.projectionCatalogs
2834
+ );
2835
+ const effectiveCanonicalFormatLegacyResolver = this.resolveCanonicalFormatLegacyResolver(
2836
+ canonicalFormatLegacyResolver,
2837
+ params.account
2838
+ );
2839
+ const hasCreativeFormatData = hasMediaBuyCreativeFormatData(params);
2840
+ if (hasCreativeFormatData) {
2841
+ this.validateBeforeCreativeCapabilityProbe("update_media_buy", params, taskOptions);
2842
+ }
2843
+ const wireMode = hasCreativeFormatData ? this.resolveCreativeFormatWireMode(
2844
+ "update_media_buy",
2845
+ await this.getCapabilities({ signal: taskOptions.signal, transport: taskOptions.transport })
2846
+ ) : "canonical";
2847
+ const result = await this.executeAndHandle(
1666
2848
  "update_media_buy",
1667
2849
  "onUpdateMediaBuyStatusChange",
2850
+ projectMediaBuyCreativesForDelivery(
2851
+ params,
2852
+ wireMode,
2853
+ "update_media_buy",
2854
+ effectiveLegacyFormatConverter,
2855
+ effectiveCanonicalFormatLegacyResolver
2856
+ ),
2857
+ inputHandler,
2858
+ taskOptions,
2859
+ void 0,
2860
+ effectiveLegacyFormatConverter,
2861
+ params
2862
+ );
2863
+ if (result.data !== void 0) this.rememberCanonicalPackageRoutes(result.data, params);
2864
+ return result;
2865
+ }
2866
+ /** @deprecated Compatibility-only entry point for callers still holding legacy creative `format_id` values. */
2867
+ async updateMediaBuyLegacy(params, inputHandler, options) {
2868
+ return await this.updateMediaBuy(
1668
2869
  params,
1669
2870
  inputHandler,
1670
2871
  options
@@ -1678,41 +2879,149 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1678
2879
  * @param options - Task execution options
1679
2880
  */
1680
2881
  async syncCreatives(params, inputHandler, options) {
2882
+ const {
2883
+ creativeFormatProjection,
2884
+ legacyFormatConverter,
2885
+ projectionCatalogs,
2886
+ canonicalFormatLegacyResolver,
2887
+ ...taskOptions
2888
+ } = options ?? {};
2889
+ const effectiveCanonicalFormatLegacyResolver = this.resolveCanonicalFormatLegacyResolver(
2890
+ canonicalFormatLegacyResolver,
2891
+ params.account
2892
+ );
2893
+ const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
2894
+ creativeFormatProjection?.legacyFormatConverter ?? legacyFormatConverter,
2895
+ projectionCatalogs ?? this.config.projectionCatalogs
2896
+ );
2897
+ this.validateBeforeCreativeCapabilityProbe("sync_creatives", params, taskOptions);
2898
+ const wireMode = this.resolveCreativeFormatWireMode(
2899
+ "sync_creatives",
2900
+ await this.getCapabilities({ signal: taskOptions.signal, transport: taskOptions.transport })
2901
+ );
2902
+ const configuredSelectorContainers = [
2903
+ ...creativeFormatProjection?.selectorContainers ?? []
2904
+ ];
2905
+ const configuredPackageIds = new Set(
2906
+ configuredSelectorContainers.flatMap(
2907
+ (container) => typeof container.package_id === "string" ? [container.package_id] : []
2908
+ )
2909
+ );
2910
+ const assignmentPackageContainers = Array.isArray(params.assignments) ? params.assignments.flatMap(
2911
+ (assignment) => typeof assignment.package_id === "string" && !configuredPackageIds.has(assignment.package_id) ? [{ package_id: assignment.package_id }] : []
2912
+ ) : [];
2913
+ const wireParams = projectSyncCreativesForDelivery(
2914
+ params,
2915
+ [...configuredSelectorContainers, ...assignmentPackageContainers],
2916
+ wireMode,
2917
+ effectiveLegacyFormatConverter,
2918
+ effectiveCanonicalFormatLegacyResolver
2919
+ );
1681
2920
  return this.executeAndHandle(
1682
2921
  "sync_creatives",
1683
2922
  "onSyncCreativesStatusChange",
2923
+ wireParams,
2924
+ inputHandler,
2925
+ taskOptions,
2926
+ void 0,
2927
+ effectiveLegacyFormatConverter,
2928
+ params
2929
+ );
2930
+ }
2931
+ /** @deprecated Compatibility-only entry point for callers still holding legacy creative `format_id` values. */
2932
+ async syncCreativesLegacy(params, inputHandler, options) {
2933
+ return await this.syncCreatives(
1684
2934
  params,
1685
2935
  inputHandler,
1686
2936
  options
1687
2937
  );
1688
2938
  }
2939
+ resolveCreativeFormatWireMode(taskType, capabilities) {
2940
+ const wireRelease = this.config.wireAdcpVersion ?? this.resolvedAdcpVersion;
2941
+ const declared = resolveCreativeFormatWireMode(capabilities, wireRelease);
2942
+ const schema = creativeSchemaSupport(this.cachedToolSchemas?.get(taskType));
2943
+ if (declared !== "unknown" && schema !== "unknown" && declared !== schema) {
2944
+ throw new CreativeFormatCapabilityError(
2945
+ `Seller capability and ${taskType} input schema disagree about canonical creative support`
2946
+ );
2947
+ }
2948
+ const resolved = declared !== "unknown" ? declared : schema;
2949
+ const release = /^v?(\d+)\.(\d+)(?:\.|-|$)/.exec(wireRelease.trim());
2950
+ const canonicalRequiredByBuyerPin = release !== null && (Number(release[1]) > 3 || Number(release[1]) === 3 && Number(release[2]) >= 2);
2951
+ if (resolved === "unknown" && canonicalRequiredByBuyerPin) {
2952
+ throw new CreativeFormatCapabilityError(
2953
+ `Cannot prove which AdCP release the seller serves for ${taskType}; a 3.2+ client will not guess a legacy creative wire shape`
2954
+ );
2955
+ }
2956
+ return resolved;
2957
+ }
2958
+ /** Validate malformed creative payloads before capability discovery can perform I/O. */
2959
+ validateBeforeCreativeCapabilityProbe(taskType, params, options) {
2960
+ if (options.skipIdempotencyAutoInject || options.skipAccountValidation) return;
2961
+ let normalizedParams = normalizeRequestParams(taskType, params);
2962
+ if (isMutatingTask(taskType) && normalizedParams && typeof normalizedParams === "object" && !normalizedParams.idempotency_key) {
2963
+ normalizedParams = { ...normalizedParams, idempotency_key: generateIdempotencyKey() };
2964
+ }
2965
+ this.validateRequest(taskType, normalizedParams);
2966
+ }
1689
2967
  /**
1690
- * List creative assets
2968
+ * List creatives through the canonical SDK boundary.
2969
+ *
2970
+ * Legacy format filters are rejected and returned creative identities are
2971
+ * projected to `format_kind` / `format_option_ref`. Migration tooling that
2972
+ * needs the negotiated raw wire shape must call `listCreativesLegacy()`.
1691
2973
  *
1692
2974
  * @param params - Creative listing parameters
1693
2975
  * @param inputHandler - Handler for clarification requests
1694
2976
  * @param options - Task execution options
1695
2977
  */
1696
2978
  async listCreatives(params, inputHandler, options) {
2979
+ const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
2980
+ const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
2981
+ legacyFormatConverter,
2982
+ projectionCatalogs ?? this.config.projectionCatalogs
2983
+ );
1697
2984
  return this.executeAndHandle(
1698
2985
  "list_creatives",
1699
2986
  "onListCreativesStatusChange",
1700
2987
  params,
1701
2988
  inputHandler,
1702
- options
2989
+ taskOptions,
2990
+ (data) => {
2991
+ const { _message: _dropLegacyMessage, ...safe } = data;
2992
+ void _dropLegacyMessage;
2993
+ return {
2994
+ ...safe,
2995
+ creatives: data.creatives.map(
2996
+ (creative) => projectCreativeForDelivery(
2997
+ creative,
2998
+ {},
2999
+ "canonical",
3000
+ "list_creatives",
3001
+ effectiveLegacyFormatConverter
3002
+ )
3003
+ )
3004
+ };
3005
+ },
3006
+ effectiveLegacyFormatConverter
1703
3007
  );
1704
3008
  }
3009
+ /** @deprecated Explicit raw-wire escape hatch for migration tooling. */
3010
+ async listCreativesLegacy(params, inputHandler, options) {
3011
+ return this.executeTaskUnprojected("list_creatives", params, inputHandler, options);
3012
+ }
1705
3013
  /**
1706
- * Preview a creative
3014
+ * Preview a creative through the legacy named-format protocol.
1707
3015
  *
1708
3016
  * @param params - Preview creative parameters
1709
3017
  * @param inputHandler - Handler for clarification requests
1710
3018
  * @param options - Task execution options
3019
+ * @deprecated Migration-only access to `format_id`-based creative preview.
1711
3020
  */
1712
- async previewCreative(params, inputHandler, options) {
3021
+ async previewCreativeLegacy(params, inputHandler, options) {
1713
3022
  return this.executeAndHandle(
1714
3023
  "preview_creative",
1715
- "onPreviewCreativeStatusChange",
3024
+ "onPreviewCreativeLegacyStatusChange",
1716
3025
  params,
1717
3026
  inputHandler,
1718
3027
  options
@@ -1726,13 +3035,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1726
3035
  * @param options - Task execution options
1727
3036
  */
1728
3037
  async getMediaBuys(params, inputHandler, options) {
1729
- return this.executeAndHandle(
3038
+ const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
3039
+ const result = await this.executeAndHandle(
1730
3040
  "get_media_buys",
1731
3041
  "onGetMediaBuysStatusChange",
1732
3042
  params,
1733
3043
  inputHandler,
1734
- options
3044
+ taskOptions,
3045
+ void 0,
3046
+ this.resolveLegacyFormatConverter(legacyFormatConverter, projectionCatalogs ?? this.config.projectionCatalogs)
1735
3047
  );
3048
+ if (result.data !== void 0) this.rememberCanonicalPackageRoutes(result.data, params);
3049
+ return result;
1736
3050
  }
1737
3051
  /**
1738
3052
  * Get media buy delivery information
@@ -1742,12 +3056,28 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1742
3056
  * @param options - Task execution options
1743
3057
  */
1744
3058
  async getMediaBuyDelivery(params, inputHandler, options) {
3059
+ const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
1745
3060
  return this.executeAndHandle(
1746
3061
  "get_media_buy_delivery",
1747
3062
  "onGetMediaBuyDeliveryStatusChange",
1748
3063
  params,
1749
3064
  inputHandler,
1750
- options
3065
+ taskOptions,
3066
+ void 0,
3067
+ this.resolveLegacyFormatConverter(legacyFormatConverter, projectionCatalogs ?? this.config.projectionCatalogs)
3068
+ );
3069
+ }
3070
+ /** Retrieve canonical creative-level and variant-level delivery metrics. */
3071
+ async getCreativeDelivery(params, inputHandler, options) {
3072
+ const { legacyFormatConverter, ...taskOptions } = options ?? {};
3073
+ return this.executeAndHandle(
3074
+ "get_creative_delivery",
3075
+ "onGetCreativeDeliveryStatusChange",
3076
+ params,
3077
+ inputHandler,
3078
+ taskOptions,
3079
+ void 0,
3080
+ legacyFormatConverter
1751
3081
  );
1752
3082
  }
1753
3083
  /**
@@ -1874,12 +3204,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1874
3204
  }
1875
3205
  // ====== CREATIVE BUILD TASKS ======
1876
3206
  /**
1877
- * Build a creative from a format and brand context
3207
+ * Build a creative through the legacy named-format protocol.
3208
+ * @deprecated Migration-only access to `target_format_id`-based creative building.
1878
3209
  */
1879
- async buildCreative(params, inputHandler, options) {
3210
+ async buildCreativeLegacy(params, inputHandler, options) {
1880
3211
  return this.executeAndHandle(
1881
3212
  "build_creative",
1882
- "onBuildCreativeStatusChange",
3213
+ "onBuildCreativeLegacyStatusChange",
1883
3214
  params,
1884
3215
  inputHandler,
1885
3216
  options
@@ -1986,10 +3317,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1986
3317
  /**
1987
3318
  * List content standards
1988
3319
  */
1989
- async listContentStandards(params, inputHandler, options) {
3320
+ async listContentStandardsLegacy(params, inputHandler, options) {
1990
3321
  return this.executeAndHandle(
1991
3322
  "list_content_standards",
1992
- "onListContentStandardsStatusChange",
3323
+ "onListContentStandardsLegacyStatusChange",
1993
3324
  params,
1994
3325
  inputHandler,
1995
3326
  options
@@ -1998,10 +3329,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
1998
3329
  /**
1999
3330
  * Get content standards
2000
3331
  */
2001
- async getContentStandards(params, inputHandler, options) {
3332
+ async getContentStandardsLegacy(params, inputHandler, options) {
2002
3333
  return this.executeAndHandle(
2003
3334
  "get_content_standards",
2004
- "onGetContentStandardsStatusChange",
3335
+ "onGetContentStandardsLegacyStatusChange",
2005
3336
  params,
2006
3337
  inputHandler,
2007
3338
  options
@@ -2010,10 +3341,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2010
3341
  /**
2011
3342
  * Calibrate content against standards
2012
3343
  */
2013
- async calibrateContent(params, inputHandler, options) {
3344
+ async calibrateContentLegacy(params, inputHandler, options) {
2014
3345
  return this.executeAndHandle(
2015
3346
  "calibrate_content",
2016
- "onCalibrateContentStatusChange",
3347
+ "onCalibrateContentLegacyStatusChange",
2017
3348
  params,
2018
3349
  inputHandler,
2019
3350
  options
@@ -2022,10 +3353,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2022
3353
  /**
2023
3354
  * Validate content delivery
2024
3355
  */
2025
- async validateContentDelivery(params, inputHandler, options) {
3356
+ async validateContentDeliveryLegacy(params, inputHandler, options) {
2026
3357
  return this.executeAndHandle(
2027
3358
  "validate_content_delivery",
2028
- "onValidateContentDeliveryStatusChange",
3359
+ "onValidateContentDeliveryLegacyStatusChange",
2029
3360
  params,
2030
3361
  inputHandler,
2031
3362
  options
@@ -2080,25 +3411,62 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2080
3411
  options
2081
3412
  );
2082
3413
  }
2083
- // ====== GENERIC TASK EXECUTION ======
3414
+ async executeTask(taskName, params, inputHandler, options) {
3415
+ switch (taskName) {
3416
+ case "get_products":
3417
+ return this.getProducts(params, inputHandler, options);
3418
+ case "create_media_buy":
3419
+ return await this.createMediaBuy(
3420
+ params,
3421
+ inputHandler,
3422
+ options
3423
+ );
3424
+ case "update_media_buy":
3425
+ return await this.updateMediaBuy(
3426
+ params,
3427
+ inputHandler,
3428
+ options
3429
+ );
3430
+ case "sync_creatives":
3431
+ return await this.syncCreatives(
3432
+ params,
3433
+ inputHandler,
3434
+ options
3435
+ );
3436
+ case "list_creatives":
3437
+ return this.listCreatives(params, inputHandler, options);
3438
+ case "get_media_buys":
3439
+ return this.getMediaBuys(params, inputHandler, options);
3440
+ case "get_media_buy_delivery":
3441
+ return this.getMediaBuyDelivery(params, inputHandler, options);
3442
+ case "get_creative_delivery":
3443
+ return this.getCreativeDelivery(params, inputHandler, options);
3444
+ }
3445
+ return this.executeTaskUnprojected(taskName, params, inputHandler, options);
3446
+ }
2084
3447
  /**
2085
- * Execute any task by name with type safety
3448
+ * Execute an extension task that is not part of the standard AdCP task set.
2086
3449
  *
2087
- * @param taskName - Name of the task to execute
2088
- * @param params - Task parameters
2089
- * @param inputHandler - Handler for clarification requests
2090
- * @param options - Task execution options
2091
- *
2092
- * @example
2093
- * ```typescript
2094
- * const result = await client.executeTask(
2095
- * 'get_products',
2096
- * { brief: 'Coffee brands' },
2097
- * handler
2098
- * );
2099
- * ```
3450
+ * Keeping custom tasks on an explicitly named API prevents a response-type
3451
+ * generic from weakening the canonical request types enforced by
3452
+ * `executeTask()` for standard creative-boundary tasks.
2100
3453
  */
2101
- async executeTask(taskName, params, inputHandler, options) {
3454
+ async executeCustomTask(taskName, params, inputHandler, options) {
3455
+ if (STANDARD_ADCP_TASK_NAMES.has(taskName)) {
3456
+ throw new Error(
3457
+ `executeCustomTask() cannot execute standard AdCP task "${taskName}". Use its typed primary method, or an explicitly named *Legacy method for legacy creative tools.`
3458
+ );
3459
+ }
3460
+ return this.executeTaskUnprojected(taskName, params, inputHandler, options);
3461
+ }
3462
+ /**
3463
+ * Explicit raw-task compatibility escape hatch for conformance and migration tooling.
3464
+ * @deprecated Application code should use typed primary methods or `executeTask()`.
3465
+ */
3466
+ async executeTaskLegacy(taskName, params, inputHandler, options) {
3467
+ return this.executeTaskUnprojected(taskName, params, inputHandler, options);
3468
+ }
3469
+ async executeTaskUnprojected(taskName, params, inputHandler, options) {
2102
3470
  throwIfAborted(options?.signal);
2103
3471
  const startTime = Date.now();
2104
3472
  try {
@@ -2153,8 +3521,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2153
3521
  if (result.success && result.data) {
2154
3522
  result.data = this.normalizeResponseToV3(taskName, result.data);
2155
3523
  }
2156
- result = this.wrapProductPolicySubmittedContinuation(result, taskName, normalizedParams);
2157
- this.rememberProductPolicyRequestParams(taskName, normalizedParams, result, options);
3524
+ result = this.wrapProductPolicySubmittedContinuation(result, taskName, normalizedParams, options);
3525
+ if (result.status === "working") {
3526
+ this.rememberProductPolicyRequestParams(taskName, normalizedParams, result, options);
3527
+ }
2158
3528
  result = await this.applyProductPropertyPolicy(result, taskName, normalizedParams);
2159
3529
  return result;
2160
3530
  } catch (error) {
@@ -2232,19 +3602,58 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2232
3602
  */
2233
3603
  async continueConversation(message, contextId, inputHandler) {
2234
3604
  const agent = await this.ensureEndpointDiscovered();
2235
- return this.executor.executeTask(agent, "continue_conversation", { message }, inputHandler, { contextId });
3605
+ const creativeAssociation = this.canonicalCreativeTaskAssociation(contextId);
3606
+ if (!creativeAssociation) {
3607
+ return this.executor.executeTask(agent, "continue_conversation", { message }, inputHandler, { contextId });
3608
+ }
3609
+ const { taskType: creativeTaskType } = creativeAssociation;
3610
+ const legacyFormatConverter = this.resolveLegacyFormatConverter(creativeAssociation.legacyFormatConverter);
3611
+ const result = await canonicalCreativeExecutionStorage.run(
3612
+ { taskType: creativeTaskType, legacyFormatConverter },
3613
+ () => this.executor.executeTask(
3614
+ agent,
3615
+ "continue_conversation",
3616
+ { message },
3617
+ this.canonicalCreativeInputHandler(creativeTaskType, inputHandler),
3618
+ { contextId }
3619
+ )
3620
+ );
3621
+ const canonical = this.canonicalizeCreativeTaskResult(result, creativeTaskType, void 0, legacyFormatConverter);
3622
+ this.rememberCanonicalCreativeTaskIds(
3623
+ canonical,
3624
+ creativeTaskType,
3625
+ legacyFormatConverter,
3626
+ creativeAssociation.routingSnapshot
3627
+ );
3628
+ return this.wrapCanonicalCreativeContinuations(
3629
+ canonical,
3630
+ creativeTaskType,
3631
+ void 0,
3632
+ legacyFormatConverter,
3633
+ creativeAssociation.routingSnapshot
3634
+ );
2236
3635
  }
2237
3636
  /**
2238
3637
  * Get conversation history for a task
2239
3638
  */
2240
3639
  getConversationHistory(taskId) {
2241
- return this.executor.getConversationHistory(taskId);
3640
+ const history = this.executor.getConversationHistory(taskId);
3641
+ const association = this.canonicalCreativeTaskAssociation(taskId);
3642
+ if (!association) return history;
3643
+ const { taskType } = association;
3644
+ const converter = this.resolveLegacyFormatConverter(association.legacyFormatConverter);
3645
+ return history?.map((message) => ({
3646
+ ...message,
3647
+ content: projectCanonicalCreativeAncillaryValue(message.content, taskType, converter)
3648
+ }));
2242
3649
  }
2243
3650
  /**
2244
3651
  * Clear conversation history for a task
2245
3652
  */
2246
3653
  clearConversationHistory(taskId) {
2247
3654
  this.executor.clearConversationHistory(taskId);
3655
+ this.forgetCanonicalCreativeTaskAssociationKeys([taskId]);
3656
+ this.productPolicyRequestParamsByTask.delete(taskId);
2248
3657
  }
2249
3658
  // ====== AGENT INFORMATION ======
2250
3659
  /**
@@ -2385,7 +3794,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2385
3794
  * Get active tasks for this agent
2386
3795
  */
2387
3796
  getActiveTasks() {
2388
- return this.executor.getActiveTasks().filter((task) => task.agent.id === this.agent.id);
3797
+ return this.executor.getActiveTasks().filter((task) => task.agent.id === this.agent.id).map((task) => {
3798
+ if (!CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskName)) return task;
3799
+ const converter = this.resolveLegacyFormatConverter(
3800
+ this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter
3801
+ );
3802
+ return stripLegacyCreativeIdentity({
3803
+ ...task,
3804
+ params: projectCanonicalCreativeAncillaryValue(task.params, task.taskName, converter),
3805
+ messages: task.messages.map((message) => ({
3806
+ ...message,
3807
+ content: projectCanonicalCreativeAncillaryValue(message.content, task.taskName, converter)
3808
+ })),
3809
+ ...task.pendingInput !== void 0 && {
3810
+ pendingInput: projectCanonicalCreativeAncillaryValue(task.pendingInput, task.taskName, converter)
3811
+ }
3812
+ });
3813
+ });
2389
3814
  }
2390
3815
  // ====== TASK MANAGEMENT & NOTIFICATIONS ======
2391
3816
  /**
@@ -2402,7 +3827,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2402
3827
  * ```
2403
3828
  */
2404
3829
  async listTasks() {
2405
- return this.executor.getTaskList(this.agent.id);
3830
+ const tasks = await this.executor.getTaskList(this.agent.id);
3831
+ return tasks.map(
3832
+ (task) => CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
3833
+ task,
3834
+ task.taskType,
3835
+ void 0,
3836
+ this.resolveLegacyFormatConverter(this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter)
3837
+ ) : task
3838
+ );
2406
3839
  }
2407
3840
  /**
2408
3841
  * Get detailed information about a specific task
@@ -2411,7 +3844,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2411
3844
  * @returns Promise resolving to task information
2412
3845
  */
2413
3846
  async getTaskInfo(taskId) {
2414
- return this.executor.getTaskInfo(taskId);
3847
+ const task = await this.executor.getTaskInfo(taskId);
3848
+ return task && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
3849
+ task,
3850
+ task.taskType,
3851
+ void 0,
3852
+ this.resolveLegacyFormatConverter(this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter)
3853
+ ) : task;
2415
3854
  }
2416
3855
  /**
2417
3856
  * Subscribe to task notifications for this agent
@@ -2433,7 +3872,19 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2433
3872
  * ```
2434
3873
  */
2435
3874
  onTaskUpdate(callback) {
2436
- return this.executor.onTaskUpdate(this.agent.id, callback);
3875
+ return this.executor.onTaskUpdate(
3876
+ this.agent.id,
3877
+ (task) => callback(
3878
+ CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
3879
+ task,
3880
+ task.taskType,
3881
+ void 0,
3882
+ this.resolveLegacyFormatConverter(
3883
+ this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter
3884
+ )
3885
+ ) : task
3886
+ )
3887
+ );
2437
3888
  }
2438
3889
  /**
2439
3890
  * Subscribe to all task events (create, update, complete, error)
@@ -2442,7 +3893,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2442
3893
  * @returns Unsubscribe function
2443
3894
  */
2444
3895
  onTaskEvents(callbacks) {
2445
- return this.executor.onTaskEvents(this.agent.id, callbacks);
3896
+ const safe = (task) => CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
3897
+ task,
3898
+ task.taskType,
3899
+ void 0,
3900
+ this.resolveLegacyFormatConverter(this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter)
3901
+ ) : task;
3902
+ return this.executor.onTaskEvents(this.agent.id, {
3903
+ ...callbacks.onTaskCreated && { onTaskCreated: (task) => callbacks.onTaskCreated(safe(task)) },
3904
+ ...callbacks.onTaskUpdated && { onTaskUpdated: (task) => callbacks.onTaskUpdated(safe(task)) },
3905
+ ...callbacks.onTaskCompleted && { onTaskCompleted: (task) => callbacks.onTaskCompleted(safe(task)) },
3906
+ ...callbacks.onTaskFailed && {
3907
+ onTaskFailed: (task, error) => {
3908
+ const safeTask = safe(task);
3909
+ callbacks.onTaskFailed(safeTask, safeTask.error ?? stripLegacyCreativeIdentity(error));
3910
+ }
3911
+ }
3912
+ });
2446
3913
  }
2447
3914
  /**
2448
3915
  * Register webhook URL for receiving task notifications
@@ -2556,9 +4023,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2556
4023
  }
2557
4024
  let authProvider;
2558
4025
  if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
2559
- const { createNonInteractiveOAuthProvider } = await import("../auth/oauth/index.mjs");
2560
- authProvider = createNonInteractiveOAuthProvider(this.normalizedAgent, {
4026
+ const { getAgentStorage } = await import("../auth/oauth/index.mjs");
4027
+ const { getNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.mjs");
4028
+ authProvider = getNonInteractiveOAuthProvider(this.normalizedAgent, {
2561
4029
  agentHint: this.normalizedAgent.id,
4030
+ storage: getAgentStorage(this.normalizedAgent),
2562
4031
  allowHttp: isLikelyPrivateUrl(this.normalizedAgent.agent_uri)
2563
4032
  });
2564
4033
  connectOptions.authProvider = authProvider;
@@ -2728,7 +4197,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2728
4197
  );
2729
4198
  if (discoveryContext) discoveryContext.toolSchemas = discoveredToolSchemas;
2730
4199
  if (!usesScopedFetch) this.cachedToolSchemas = discoveredToolSchemas;
2731
- const hasCapabilitiesTool = tools.some((t) => t.name === "get_adcp_capabilities");
4200
+ const advertisesCapabilitiesTool = tools.some((t) => t.name === "get_adcp_capabilities");
4201
+ const officialA2ALifecycle = this.normalizedAgent.protocol === "a2a" && tools.some((tool) => ["tasks/get", "get_task_status", "list_tasks"].includes(tool.name));
4202
+ const hasCapabilitiesTool = advertisesCapabilitiesTool || officialA2ALifecycle;
2732
4203
  if (hasCapabilitiesTool) {
2733
4204
  try {
2734
4205
  const agent = await this.ensureEndpointDiscovered(options);
@@ -2741,10 +4212,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2741
4212
  throw createTimeoutError(requestTimeoutMs);
2742
4213
  }
2743
4214
  if (result.success && result.data) {
2744
- const capabilities3 = augmentCapabilitiesFromTools(parseCapabilitiesResponse(result.data), tools);
2745
- if (!usesScopedFetch) this.cachedCapabilities = capabilities3;
2746
- this.maybeWarnV2Sunset(capabilities3);
2747
- return capabilities3;
4215
+ const capabilities2 = augmentCapabilitiesFromTools(parseCapabilitiesResponse(result.data), tools);
4216
+ if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
4217
+ this.maybeWarnV2Sunset(capabilities2);
4218
+ return capabilities2;
4219
+ }
4220
+ if (!advertisesCapabilitiesTool) {
4221
+ throw new Error("unadvertised official A2A capability probe was not supported");
2748
4222
  }
2749
4223
  if (result.data && looksLikeV3Capabilities(result.data)) {
2750
4224
  console.warn(
@@ -2757,10 +4231,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2757
4231
  version: "v3",
2758
4232
  majorVersions: parsed.majorVersions.includes(3) ? parsed.majorVersions : [3]
2759
4233
  };
2760
- const capabilities3 = augmentCapabilitiesFromTools(v3Capabilities, tools);
2761
- if (!usesScopedFetch) this.cachedCapabilities = capabilities3;
2762
- this.maybeWarnV2Sunset(capabilities3);
2763
- return capabilities3;
4234
+ const capabilities2 = augmentCapabilitiesFromTools(v3Capabilities, tools);
4235
+ if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
4236
+ this.maybeWarnV2Sunset(capabilities2);
4237
+ return capabilities2;
2764
4238
  }
2765
4239
  console.warn(
2766
4240
  `[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.`,
@@ -2774,14 +4248,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2774
4248
  if (error instanceof AuthenticationRequiredError || error instanceof TaskTimeoutError || isAbortOrTimeoutError(error)) {
2775
4249
  throw error;
2776
4250
  }
2777
- console.warn(
2778
- `[AdCP] Agent "${this.agent.id}" advertises get_adcp_capabilities but the call threw \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.`
2779
- );
4251
+ if (advertisesCapabilitiesTool) {
4252
+ console.warn(
4253
+ `[AdCP] Agent "${this.agent.id}" advertises get_adcp_capabilities but the call threw \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.`
4254
+ );
4255
+ }
4256
+ }
4257
+ if (advertisesCapabilitiesTool) {
4258
+ const capabilities2 = augmentCapabilitiesFromTools(buildSyntheticV3Capabilities(tools), tools);
4259
+ if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
4260
+ this.maybeWarnV2Sunset(capabilities2);
4261
+ return capabilities2;
2780
4262
  }
2781
- const capabilities2 = augmentCapabilitiesFromTools(buildSyntheticV3Capabilities(tools), tools);
2782
- if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
2783
- this.maybeWarnV2Sunset(capabilities2);
2784
- return capabilities2;
2785
4263
  }
2786
4264
  console.warn(
2787
4265
  `[AdCP] Agent "${this.agent.id}" detected as v2 (no get_adcp_capabilities tool). Tools: [${tools.map((t) => t.name).join(", ")}]`
@@ -3101,38 +4579,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3101
4579
  }
3102
4580
  // ====== STATIC HELPER METHODS ======
3103
4581
  /**
3104
- * Query a creative agent to discover available creative formats
4582
+ * Query a legacy creative-agent named-format catalog.
3105
4583
  *
3106
- * This is a static utility method that allows you to query any creative agent
3107
- * (like creative.adcontextprotocol.org) to discover what formats are available
3108
- * before creating a media buy.
4584
+ * Canonical applications discover seller-supported declarations through
4585
+ * `AgentClient.getProducts()` and consume `format_options[]` instead.
3109
4586
  *
3110
4587
  * @param creativeAgentUrl - URL of the creative agent (e.g., 'https://creative.adcontextprotocol.org/mcp')
3111
4588
  * @param protocol - Protocol to use ('mcp' or 'a2a'), defaults to 'mcp'
3112
4589
  * @returns Promise resolving to the list of available formats
3113
4590
  *
3114
- * @example
3115
- * ```typescript
3116
- * // Discover formats from the standard creative agent
3117
- * const formats = await SingleAgentClient.discoverCreativeFormats(
3118
- * 'https://creative.adcontextprotocol.org/mcp'
3119
- * );
3120
- *
3121
- * // Find a specific format
3122
- * const banner = formats.find(f => f.format_id.id === 'display_300x250_image');
3123
- *
3124
- * // Use the format in a media buy
3125
- * await salesAgent.createMediaBuy({
3126
- * packages: [{
3127
- * format_ids: [{
3128
- * agent_url: banner.format_id.agent_url,
3129
- * id: banner.format_id.id
3130
- * }]
3131
- * }]
3132
- * });
3133
- * ```
4591
+ * @deprecated Migration-only helper for the legacy named-format protocol.
3134
4592
  */
3135
- static async discoverCreativeFormats(creativeAgentUrl, protocol = "mcp") {
4593
+ static async discoverCreativeFormatsLegacy(creativeAgentUrl, protocol = "mcp") {
3136
4594
  const client = new SingleAgentClient(
3137
4595
  {
3138
4596
  id: "creative_agent_discovery",
@@ -3142,7 +4600,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
3142
4600
  },
3143
4601
  {}
3144
4602
  );
3145
- const result = await client.listCreativeFormats({});
4603
+ const result = await client.listCreativeFormatsLegacy({});
3146
4604
  if (!result.success || !result.data) {
3147
4605
  throw new Error(`Failed to discover creative formats: ${result.error || "Unknown error"}`);
3148
4606
  }
@@ -3222,12 +4680,11 @@ function parseWebhookBody(value) {
3222
4680
  const raw = Buffer.isBuffer(value) || value instanceof Uint8Array ? Buffer.from(value).toString("utf8") : value;
3223
4681
  try {
3224
4682
  return { ok: true, payload: JSON.parse(raw) };
3225
- } catch (error) {
4683
+ } catch {
3226
4684
  return {
3227
4685
  ok: false,
3228
4686
  code: "webhook_envelope_invalid",
3229
- message: "Webhook body must be valid JSON.",
3230
- cause: error
4687
+ message: "Webhook body must be valid JSON."
3231
4688
  };
3232
4689
  }
3233
4690
  }
@@ -3248,13 +4705,6 @@ function missingMcpWebhookFields(payload) {
3248
4705
  return typeof value !== "string" || value.length === 0;
3249
4706
  });
3250
4707
  }
3251
- function safeJsonPreview(value) {
3252
- try {
3253
- return JSON.stringify(value).substring(0, 200);
3254
- } catch {
3255
- return "[unserializable payload]";
3256
- }
3257
- }
3258
4708
  function webhookErrorHttpStatus(error) {
3259
4709
  if (error instanceof WebhookDispatchError) {
3260
4710
  if (error.code === "webhook_signature_invalid" || error.code === "webhook_timestamp_invalid") {