@adcp/sdk 17.0.0-beta.0 → 17.0.0-beta.2

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 (277) hide show
  1. package/dist/lib/adapters/keyed-account-store.js +1 -1
  2. package/dist/lib/adapters/keyed-account-store.mjs +1 -1
  3. package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
  4. package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
  5. package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
  6. package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
  7. package/dist/lib/adapters/version/3.0/index.js +6 -0
  8. package/dist/lib/adapters/version/3.0/index.mjs +7 -1
  9. package/dist/lib/adapters/version/3.1/bidding.js +1 -1
  10. package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
  11. package/dist/lib/adapters/version/types.d.mts +5 -0
  12. package/dist/lib/adapters/version/types.d.ts +5 -0
  13. package/dist/lib/canonical-references/index.js +2 -0
  14. package/dist/lib/canonical-references/index.mjs +2 -0
  15. package/dist/lib/client/account-changes.d.mts +3 -1
  16. package/dist/lib/client/account-changes.d.ts +3 -1
  17. package/dist/lib/client/account-changes.js +22 -2
  18. package/dist/lib/client/account-changes.mjs +22 -2
  19. package/dist/lib/conformance/oracle.js +3 -2
  20. package/dist/lib/conformance/oracle.mjs +3 -2
  21. package/dist/lib/core/AgentClient.d.mts +165 -1
  22. package/dist/lib/core/AgentClient.d.ts +165 -1
  23. package/dist/lib/core/AgentClient.js +446 -8
  24. package/dist/lib/core/AgentClient.mjs +446 -8
  25. package/dist/lib/core/ConversationTypes.d.mts +8 -0
  26. package/dist/lib/core/ConversationTypes.d.ts +8 -0
  27. package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
  28. package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
  29. package/dist/lib/core/ProtocolResponseParser.js +28 -18
  30. package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
  31. package/dist/lib/core/ResponseValidator.js +1 -1
  32. package/dist/lib/core/ResponseValidator.mjs +1 -1
  33. package/dist/lib/core/SingleAgentClient.d.mts +122 -7
  34. package/dist/lib/core/SingleAgentClient.d.ts +122 -7
  35. package/dist/lib/core/SingleAgentClient.js +601 -96
  36. package/dist/lib/core/SingleAgentClient.mjs +590 -84
  37. package/dist/lib/core/TaskExecutor.d.mts +7 -0
  38. package/dist/lib/core/TaskExecutor.d.ts +7 -0
  39. package/dist/lib/core/TaskExecutor.js +23 -8
  40. package/dist/lib/core/TaskExecutor.mjs +23 -8
  41. package/dist/lib/core/task-status.d.mts +2 -0
  42. package/dist/lib/core/task-status.d.ts +2 -0
  43. package/dist/lib/core/task-status.js +11 -2
  44. package/dist/lib/core/task-status.mjs +9 -1
  45. package/dist/lib/errors/index.d.mts +22 -0
  46. package/dist/lib/errors/index.d.ts +22 -0
  47. package/dist/lib/errors/index.js +43 -0
  48. package/dist/lib/errors/index.mjs +42 -0
  49. package/dist/lib/identity-3.3/trust.d.mts +1 -4
  50. package/dist/lib/identity-3.3/trust.d.ts +1 -4
  51. package/dist/lib/identity-3.3/trust.js +34 -21
  52. package/dist/lib/identity-3.3/trust.mjs +34 -21
  53. package/dist/lib/identity-3.3/validation.js +5 -3
  54. package/dist/lib/identity-3.3/validation.mjs +6 -4
  55. package/dist/lib/index.d.mts +7 -53
  56. package/dist/lib/index.d.ts +7 -53
  57. package/dist/lib/index.js +13 -0
  58. package/dist/lib/index.mjs +9 -0
  59. package/dist/lib/media-buy/compatibility.js +6 -1
  60. package/dist/lib/media-buy/compatibility.mjs +6 -1
  61. package/dist/lib/protocols/mcp-modern.d.mts +2 -0
  62. package/dist/lib/protocols/mcp-modern.d.ts +2 -0
  63. package/dist/lib/protocols/mcp-modern.js +31 -5
  64. package/dist/lib/protocols/mcp-modern.mjs +31 -5
  65. package/dist/lib/protocols/mcp-scope.d.mts +6 -1
  66. package/dist/lib/protocols/mcp-scope.d.ts +6 -1
  67. package/dist/lib/protocols/mcp-scope.js +25 -3
  68. package/dist/lib/protocols/mcp-scope.mjs +24 -3
  69. package/dist/lib/protocols/mcp.js +12 -6
  70. package/dist/lib/protocols/mcp.mjs +13 -6
  71. package/dist/lib/reporting/inspection.js +1 -0
  72. package/dist/lib/reporting/inspection.mjs +1 -0
  73. package/dist/lib/reporting/ledger/coverage.d.mts +5 -0
  74. package/dist/lib/reporting/ledger/coverage.d.ts +5 -0
  75. package/dist/lib/reporting/ledger/coverage.js +37 -3
  76. package/dist/lib/reporting/ledger/coverage.mjs +36 -3
  77. package/dist/lib/reporting/ledger/handler.js +7 -4
  78. package/dist/lib/reporting/ledger/handler.mjs +7 -4
  79. package/dist/lib/reporting/ledger/producer.js +215 -69
  80. package/dist/lib/reporting/ledger/producer.mjs +217 -70
  81. package/dist/lib/reporting/ledger/schedule.d.mts +2 -2
  82. package/dist/lib/reporting/ledger/schedule.d.ts +2 -2
  83. package/dist/lib/reporting/ledger/schedule.js +8 -5
  84. package/dist/lib/reporting/ledger/schedule.mjs +8 -5
  85. package/dist/lib/reporting/ledger/status-ingest.d.mts +1 -1
  86. package/dist/lib/reporting/ledger/status-ingest.d.ts +1 -1
  87. package/dist/lib/reporting/ledger/status-ingest.js +4 -3
  88. package/dist/lib/reporting/ledger/status-ingest.mjs +4 -3
  89. package/dist/lib/reporting/ledger/types.d.mts +36 -1
  90. package/dist/lib/reporting/ledger/types.d.ts +36 -1
  91. package/dist/lib/reporting/service/index.d.mts +14 -1
  92. package/dist/lib/reporting/service/index.d.ts +14 -1
  93. package/dist/lib/reporting/service/index.js +24 -12
  94. package/dist/lib/reporting/service/index.mjs +24 -12
  95. package/dist/lib/schemas/browser.d.mts +2 -0
  96. package/dist/lib/schemas/browser.d.ts +2 -0
  97. package/dist/lib/schemas/browser.js +3 -0
  98. package/dist/lib/schemas/browser.mjs +2 -0
  99. package/dist/lib/schemas/index.d.mts +5 -3
  100. package/dist/lib/schemas/index.d.ts +5 -3
  101. package/dist/lib/schemas/index.js +5 -0
  102. package/dist/lib/schemas/index.mjs +4 -0
  103. package/dist/lib/server/account-response-identity.d.mts +17 -0
  104. package/dist/lib/server/account-response-identity.d.ts +17 -0
  105. package/dist/lib/server/account-response-identity.js +52 -0
  106. package/dist/lib/server/account-response-identity.mjs +28 -0
  107. package/dist/lib/server/account-sync-contract.js +2 -2
  108. package/dist/lib/server/account-sync-contract.mjs +2 -2
  109. package/dist/lib/server/create-adcp-server.js +33 -20
  110. package/dist/lib/server/create-adcp-server.mjs +36 -12
  111. package/dist/lib/server/decisioning/account.d.mts +36 -10
  112. package/dist/lib/server/decisioning/account.d.ts +36 -10
  113. package/dist/lib/server/decisioning/account.js +33 -14
  114. package/dist/lib/server/decisioning/account.mjs +33 -14
  115. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
  116. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
  117. package/dist/lib/server/decisioning/runtime/from-platform.js +4 -4
  118. package/dist/lib/server/decisioning/runtime/from-platform.mjs +4 -4
  119. package/dist/lib/server/media-buy-store.d.mts +26 -12
  120. package/dist/lib/server/media-buy-store.d.ts +26 -12
  121. package/dist/lib/server/media-buy-store.js +69 -21
  122. package/dist/lib/server/media-buy-store.mjs +69 -21
  123. package/dist/lib/server/notification-subscriptions/runtime.d.mts +1 -1
  124. package/dist/lib/server/notification-subscriptions/runtime.d.ts +1 -1
  125. package/dist/lib/server/notification-subscriptions/runtime.js +4 -0
  126. package/dist/lib/server/notification-subscriptions/runtime.mjs +4 -0
  127. package/dist/lib/server/responses.js +9 -1
  128. package/dist/lib/server/responses.mjs +9 -1
  129. package/dist/lib/signing/agent-fetch.d.mts +1 -1
  130. package/dist/lib/signing/agent-fetch.d.ts +1 -1
  131. package/dist/lib/signing/agent-fetch.js +3 -3
  132. package/dist/lib/signing/agent-fetch.mjs +3 -3
  133. package/dist/lib/testing/client.d.mts +1 -0
  134. package/dist/lib/testing/client.d.ts +1 -0
  135. package/dist/lib/testing/client.js +6 -5
  136. package/dist/lib/testing/client.mjs +6 -5
  137. package/dist/lib/testing/storyboard/agent-routing.d.mts +5 -2
  138. package/dist/lib/testing/storyboard/agent-routing.d.ts +5 -2
  139. package/dist/lib/testing/storyboard/agent-routing.js +11 -4
  140. package/dist/lib/testing/storyboard/agent-routing.mjs +11 -4
  141. package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
  142. package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
  143. package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
  144. package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
  145. package/dist/lib/testing/storyboard/compliance.js +62 -13
  146. package/dist/lib/testing/storyboard/compliance.mjs +63 -14
  147. package/dist/lib/testing/storyboard/context.d.mts +13 -3
  148. package/dist/lib/testing/storyboard/context.d.ts +13 -3
  149. package/dist/lib/testing/storyboard/context.js +15 -10
  150. package/dist/lib/testing/storyboard/context.mjs +15 -10
  151. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
  152. package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
  153. package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
  154. package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
  155. package/dist/lib/testing/storyboard/runner.js +141 -13
  156. package/dist/lib/testing/storyboard/runner.mjs +141 -13
  157. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  158. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  159. package/dist/lib/testing/storyboard/validations.js +4 -1
  160. package/dist/lib/testing/storyboard/validations.mjs +4 -1
  161. package/dist/lib/testing/test-controller.js +3 -0
  162. package/dist/lib/testing/test-controller.mjs +3 -0
  163. package/dist/lib/types/accept-proposal.d.ts +20 -28
  164. package/dist/lib/types/asset-instances.d.mts +1 -1
  165. package/dist/lib/types/asset-instances.d.ts +1 -1
  166. package/dist/lib/types/buy-products.d.ts +20 -28
  167. package/dist/lib/types/check-governance.d.ts +20 -28
  168. package/dist/lib/types/comply-test-controller.d.ts +20 -28
  169. package/dist/lib/types/control-media-buy.d.ts +20 -28
  170. package/dist/lib/types/core.generated.d.mts +273 -184
  171. package/dist/lib/types/core.generated.d.ts +273 -184
  172. package/dist/lib/types/create-media-buy.d.ts +20 -28
  173. package/dist/lib/types/get-media-buys.d.ts +20 -28
  174. package/dist/lib/types/get-products.d.ts +20 -28
  175. package/dist/lib/types/index.d.mts +6 -1
  176. package/dist/lib/types/index.d.ts +6 -1
  177. package/dist/lib/types/index.js +6 -1
  178. package/dist/lib/types/index.mjs +4 -1
  179. package/dist/lib/types/inline-enums.generated.d.mts +30 -4
  180. package/dist/lib/types/inline-enums.generated.d.ts +30 -4
  181. package/dist/lib/types/inline-enums.generated.js +41 -2
  182. package/dist/lib/types/inline-enums.generated.mjs +28 -2
  183. package/dist/lib/types/list-products.d.ts +20 -28
  184. package/dist/lib/types/list-proposals.d.ts +20 -28
  185. package/dist/lib/types/media-buy-delivery-report.d.mts +6 -0
  186. package/dist/lib/types/media-buy-delivery-report.d.ts +6 -0
  187. package/dist/lib/types/media-buy-delivery-report.js +16 -0
  188. package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
  189. package/dist/lib/types/refine-proposals.d.ts +20 -28
  190. package/dist/lib/types/request-proposals.d.ts +20 -28
  191. package/dist/lib/types/schemas.generated.d.ts +63113 -127273
  192. package/dist/lib/types/schemas.generated.js +759 -770
  193. package/dist/lib/types/schemas.generated.mjs +759 -770
  194. package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
  195. package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
  196. package/dist/lib/types/targeting-keys.generated.js +109 -0
  197. package/dist/lib/types/targeting-keys.generated.mjs +84 -0
  198. package/dist/lib/types/tools.generated.d.mts +2 -68
  199. package/dist/lib/types/tools.generated.d.ts +2 -68
  200. package/dist/lib/types/update-media-buy.d.ts +20 -28
  201. package/dist/lib/utils/adcp-version-config.js +5 -2
  202. package/dist/lib/utils/adcp-version-config.mjs +5 -2
  203. package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
  204. package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
  205. package/dist/lib/utils/envelope-status-compat.js +11 -5
  206. package/dist/lib/utils/envelope-status-compat.mjs +11 -5
  207. package/dist/lib/utils/response-unwrapper.js +18 -10
  208. package/dist/lib/utils/response-unwrapper.mjs +18 -10
  209. package/dist/lib/v2/format-schema/resolver.js +1 -1
  210. package/dist/lib/v2/format-schema/resolver.mjs +1 -1
  211. package/dist/lib/v2/projection/creative-delivery.js +159 -39
  212. package/dist/lib/v2/projection/creative-delivery.mjs +163 -39
  213. package/dist/lib/v2/projection/index.d.mts +1 -0
  214. package/dist/lib/v2/projection/index.d.ts +1 -0
  215. package/dist/lib/v2/projection/index.js +3 -0
  216. package/dist/lib/v2/projection/index.mjs +2 -0
  217. package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
  218. package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
  219. package/dist/lib/v2/projection/legacy-metadata.js +91 -0
  220. package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
  221. package/dist/lib/v2/projection/v1-to-v2.d.mts +1 -1
  222. package/dist/lib/v2/projection/v1-to-v2.d.ts +1 -1
  223. package/dist/lib/v2/projection/v1-to-v2.js +12 -9
  224. package/dist/lib/v2/projection/v1-to-v2.mjs +12 -9
  225. package/dist/lib/validation/budget-allocation.d.mts +3 -3
  226. package/dist/lib/validation/budget-allocation.d.ts +3 -3
  227. package/dist/lib/validation/compact-schema.d.mts +27 -0
  228. package/dist/lib/validation/compact-schema.d.ts +27 -0
  229. package/dist/lib/validation/compact-schema.js +276 -0
  230. package/dist/lib/validation/compact-schema.mjs +250 -0
  231. package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
  232. package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
  233. package/dist/lib/validation/media-buy-delivery-report.js +31 -0
  234. package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
  235. package/dist/lib/validation/nonempty-array.d.mts +15 -0
  236. package/dist/lib/validation/nonempty-array.d.ts +15 -0
  237. package/dist/lib/validation/nonempty-array.js +41 -0
  238. package/dist/lib/validation/nonempty-array.mjs +7 -0
  239. package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
  240. package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
  241. package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
  242. package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
  243. package/dist/lib/validation/schema-loader.js +86 -16
  244. package/dist/lib/validation/schema-loader.mjs +82 -16
  245. package/dist/lib/validation/schema-validator.d.mts +10 -19
  246. package/dist/lib/validation/schema-validator.d.ts +10 -19
  247. package/dist/lib/validation/schema-validator.js +136 -43
  248. package/dist/lib/validation/schema-validator.mjs +140 -44
  249. package/dist/lib/validation/sync-creatives.d.mts +22 -22
  250. package/dist/lib/validation/sync-creatives.d.ts +22 -22
  251. package/dist/lib/version.d.mts +3 -3
  252. package/dist/lib/version.d.ts +3 -3
  253. package/dist/lib/version.js +3 -3
  254. package/dist/lib/version.mjs +3 -3
  255. package/dist/lib/webhooks/index.d.mts +3 -0
  256. package/dist/lib/webhooks/index.d.ts +3 -0
  257. package/dist/lib/webhooks/index.js +3 -0
  258. package/dist/lib/webhooks/index.mjs +2 -0
  259. package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
  260. package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
  261. package/dist/lib/webhooks/media-buy-delivery.js +119 -0
  262. package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
  263. package/docs/TYPE-SUMMARY.md +2 -2
  264. package/docs/guides/COLLECTION-FIXTURE-FOUNDATION.md +11 -0
  265. package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +142 -0
  266. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +27 -1
  267. package/docs/guides/REPORTING-LEDGER.md +93 -0
  268. package/docs/guides/REPORTING-STABILITY.md +1 -1
  269. package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
  270. package/docs/llms.txt +2 -2
  271. package/docs/migration-14.x-rc-worksheet.md +4 -4
  272. package/docs/migration-16-to-17.md +202 -2
  273. package/docs/migration-6.6-to-6.7.md +14 -0
  274. package/docs/migration-account-change-feed.md +15 -0
  275. package/docs/migration-reporting-storage-package.md +1 -1
  276. package/docs/recipes/verifying-inbound-webhooks.md +18 -2
  277. package/package.json +2 -2
@@ -95,6 +95,7 @@ interface WebhookManager {
95
95
  registerWebhook(agent: AgentConfig, taskId: string, webhookUrl: string): Promise<void>;
96
96
  processWebhook(token: string, body: any): Promise<void>;
97
97
  }
98
+ type AdcpTaskStatusTool = 'get_task_status' | 'tasks_get' | 'tasks/get';
98
99
  /**
99
100
  * Core task execution engine that handles the conversation loop with agents
100
101
  */
@@ -210,6 +211,11 @@ export declare class TaskExecutor {
210
211
  * dispatches. Per-call options can override individual fields.
211
212
  */
212
213
  transport?: import('../protocols/index.mjs').TransportOptions;
214
+ /** Resolve the advertised AdCP work-status tool using the client's scoped discovery evidence. */
215
+ resolveTaskStatusTool?: (agent: AgentConfig, options: {
216
+ transport?: import('../protocols/index.mjs').TransportOptions;
217
+ signal?: AbortSignal;
218
+ }) => Promise<AdcpTaskStatusTool>;
213
219
  });
214
220
  /**
215
221
  * Access the governance middleware for direct outcome reporting (async tasks).
@@ -328,6 +334,7 @@ export declare class TaskExecutor {
328
334
  * Task tracking methods (PR #78)
329
335
  */
330
336
  listTasks(agent: AgentConfig, transport?: import('../protocols/index.mjs').TransportOptions): Promise<TaskInfo[]>;
337
+ private resolveTaskStatusTool;
331
338
  private getTaskStatusWithRawResponse;
332
339
  getTaskStatus(agent: AgentConfig, taskId: string, transport?: import('../protocols/index.mjs').TransportOptions, signal?: AbortSignal, wireOptions?: {
333
340
  wireAdcpVersion?: string;
@@ -95,6 +95,7 @@ interface WebhookManager {
95
95
  registerWebhook(agent: AgentConfig, taskId: string, webhookUrl: string): Promise<void>;
96
96
  processWebhook(token: string, body: any): Promise<void>;
97
97
  }
98
+ type AdcpTaskStatusTool = 'get_task_status' | 'tasks_get' | 'tasks/get';
98
99
  /**
99
100
  * Core task execution engine that handles the conversation loop with agents
100
101
  */
@@ -210,6 +211,11 @@ export declare class TaskExecutor {
210
211
  * dispatches. Per-call options can override individual fields.
211
212
  */
212
213
  transport?: import('../protocols').TransportOptions;
214
+ /** Resolve the advertised AdCP work-status tool using the client's scoped discovery evidence. */
215
+ resolveTaskStatusTool?: (agent: AgentConfig, options: {
216
+ transport?: import('../protocols').TransportOptions;
217
+ signal?: AbortSignal;
218
+ }) => Promise<AdcpTaskStatusTool>;
213
219
  });
214
220
  /**
215
221
  * Access the governance middleware for direct outcome reporting (async tasks).
@@ -328,6 +334,7 @@ export declare class TaskExecutor {
328
334
  * Task tracking methods (PR #78)
329
335
  */
330
336
  listTasks(agent: AgentConfig, transport?: import('../protocols').TransportOptions): Promise<TaskInfo[]>;
337
+ private resolveTaskStatusTool;
331
338
  private getTaskStatusWithRawResponse;
332
339
  getTaskStatus(agent: AgentConfig, taskId: string, transport?: import('../protocols').TransportOptions, signal?: AbortSignal, wireOptions?: {
333
340
  wireAdcpVersion?: string;
@@ -292,7 +292,7 @@ function assertGovernedPayloadHasNoCallbackCredentials(taskName, payload, option
292
292
  scanResult.path
293
293
  );
294
294
  }
295
- function mapTasksGetResponseToTaskInfo(payload) {
295
+ function mapTasksGetResponseToTaskInfo(payload, adcpVersion) {
296
296
  if (payload == null || typeof payload !== "object") {
297
297
  return { taskId: "", status: "unknown", taskType: "unknown", createdAt: Date.now(), updatedAt: Date.now() };
298
298
  }
@@ -312,7 +312,8 @@ function mapTasksGetResponseToTaskInfo(payload) {
312
312
  if (messageField !== void 0) taskInfo.message = messageField;
313
313
  if (flat.result !== void 0) {
314
314
  taskInfo.result = flat.result != null && typeof flat.result === "object" && !Array.isArray(flat.result) ? (0, import_envelope_status_compat.normalizeLegacyMediaBuyStatusForReturn)(flat.result, {
315
- toolName: taskInfo.taskType
315
+ toolName: taskInfo.taskType,
316
+ adcpVersion
316
317
  }) : flat.result;
317
318
  }
318
319
  return taskInfo;
@@ -732,6 +733,8 @@ class TaskExecutor {
732
733
  status: args.status
733
734
  };
734
735
  const taskState = this.activeTasks.get(args.taskId);
736
+ const wireAdcpVersion = taskState?.wireAdcpVersion ?? this.config.wireAdcpVersion;
737
+ if (wireAdcpVersion !== void 0) meta.wireAdcpVersion = wireAdcpVersion;
735
738
  if (taskState?.serverVersion !== void 0) meta.serverVersion = taskState.serverVersion;
736
739
  if (taskState?.serverVersionSynthetic !== void 0) {
737
740
  meta.serverVersionSynthetic = taskState.serverVersionSynthetic;
@@ -825,6 +828,7 @@ class TaskExecutor {
825
828
  }
826
829
  const taskState = {
827
830
  taskId,
831
+ wireAdcpVersion: wireAdcpVersion ?? options.negotiatedAdcpVersion ?? options.selectedAdcpVersion,
828
832
  taskName,
829
833
  params,
830
834
  status: "pending",
@@ -1095,7 +1099,7 @@ class TaskExecutor {
1095
1099
  () => import_protocols.ProtocolClient.callTool(agent, taskName, dispatchParams, callOptions)
1096
1100
  );
1097
1101
  (0, import_abort.throwIfAborted)(postDispatchOptions.signal);
1098
- const respStatus = this.responseParser.getStatus(response);
1102
+ const respStatus = this.responseParser.getStatus(response, taskName);
1099
1103
  taskState.serverTaskId = this.responseParser.getTaskId(response);
1100
1104
  await this.config.onActivity?.({
1101
1105
  type: "protocol_response",
@@ -1278,7 +1282,7 @@ class TaskExecutor {
1278
1282
  };
1279
1283
  }
1280
1284
  async handleAsyncResponse(agent, taskId, taskName, params, response, messages, inputHandler, options = {}, debugLogs = [], startTime = Date.now(), deferTerminalTaskStatus = false, persistPausedContinuation = true, serverVersion = "v3", deferredClientContext, requireDeferredSettlementResumeAuthorization = false, refinementServedVersion) {
1281
- const status = this.responseParser.getStatus(response);
1285
+ const status = this.responseParser.getStatus(response, taskName);
1282
1286
  const serverTaskId = this.responseParser.getTaskId(response);
1283
1287
  const task = this.activeTasks.get(taskId);
1284
1288
  if (task && serverTaskId) task.serverTaskId = serverTaskId;
@@ -2530,8 +2534,15 @@ class TaskExecutor {
2530
2534
  }
2531
2535
  });
2532
2536
  }
2533
- async getTaskStatusWithRawResponse(agent, taskId, transport, signal, expectedTaskType, serverVersion, wireAdcpVersion, versionEnvelope, operationId) {
2534
- const toolName = agent.protocol === "mcp" ? "tasks_get" : "tasks/get";
2537
+ async resolveTaskStatusTool(agent, transport, signal) {
2538
+ if (this.config.resolveTaskStatusTool) {
2539
+ return this.config.resolveTaskStatusTool(agent, { transport: transport ?? this.config.transport, signal });
2540
+ }
2541
+ return agent.protocol === "mcp" ? "tasks_get" : "tasks/get";
2542
+ }
2543
+ async getTaskStatusWithRawResponse(agent, taskId, transport, signal, expectedTaskType, serverVersion, wireAdcpVersion, versionEnvelope, operationId, pollingTool) {
2544
+ const toolName = pollingTool ?? await this.resolveTaskStatusTool(agent, transport, signal);
2545
+ (0, import_abort.throwIfAborted)(signal);
2535
2546
  const response = await import_protocols.ProtocolClient.callTool(
2536
2547
  agent,
2537
2548
  toolName,
@@ -2554,7 +2565,8 @@ class TaskExecutor {
2554
2565
  }
2555
2566
  }
2556
2567
  );
2557
- const task = mapTasksGetResponseToTaskInfo(response);
2568
+ const resultAdcpVersion = (versionEnvelope ?? this.config.versionEnvelope) === "major-only" ? "3.0" : wireAdcpVersion ?? this.config.wireAdcpVersion ?? this.config.adcpVersion ?? import_version.ADCP_VERSION;
2569
+ const task = mapTasksGetResponseToTaskInfo(response, resultAdcpVersion);
2558
2570
  if (!task.taskId || task.taskId !== taskId) {
2559
2571
  throw new TaskBindingMismatchError(
2560
2572
  "tasks/get returned a task identity that does not match the requested task.",
@@ -2589,6 +2601,7 @@ class TaskExecutor {
2589
2601
  }
2590
2602
  const pollStartTime = Date.now();
2591
2603
  const correlationId = metadataTaskId ?? taskId;
2604
+ let pollingTool;
2592
2605
  const withServerTaskId = (metadata) => ({
2593
2606
  ...metadata,
2594
2607
  serverTaskId: taskId
@@ -2629,6 +2642,7 @@ class TaskExecutor {
2629
2642
  let status;
2630
2643
  let rawResponse;
2631
2644
  try {
2645
+ pollingTool ??= await this.resolveTaskStatusTool(agent, transportSnapshot, signal);
2632
2646
  const pollResult = await this.getTaskStatusWithRawResponse(
2633
2647
  agent,
2634
2648
  taskId,
@@ -2638,7 +2652,8 @@ class TaskExecutor {
2638
2652
  serverVersion,
2639
2653
  wireAdcpVersion,
2640
2654
  versionEnvelope,
2641
- metadataTaskId
2655
+ metadataTaskId,
2656
+ pollingTool
2642
2657
  );
2643
2658
  status = pollResult.task;
2644
2659
  rawResponse = pollResult.rawResponse;
@@ -278,7 +278,7 @@ function assertGovernedPayloadHasNoCallbackCredentials(taskName, payload, option
278
278
  scanResult.path
279
279
  );
280
280
  }
281
- function mapTasksGetResponseToTaskInfo(payload) {
281
+ function mapTasksGetResponseToTaskInfo(payload, adcpVersion) {
282
282
  if (payload == null || typeof payload !== "object") {
283
283
  return { taskId: "", status: "unknown", taskType: "unknown", createdAt: Date.now(), updatedAt: Date.now() };
284
284
  }
@@ -298,7 +298,8 @@ function mapTasksGetResponseToTaskInfo(payload) {
298
298
  if (messageField !== void 0) taskInfo.message = messageField;
299
299
  if (flat.result !== void 0) {
300
300
  taskInfo.result = flat.result != null && typeof flat.result === "object" && !Array.isArray(flat.result) ? normalizeLegacyMediaBuyStatusForReturn(flat.result, {
301
- toolName: taskInfo.taskType
301
+ toolName: taskInfo.taskType,
302
+ adcpVersion
302
303
  }) : flat.result;
303
304
  }
304
305
  return taskInfo;
@@ -718,6 +719,8 @@ class TaskExecutor {
718
719
  status: args.status
719
720
  };
720
721
  const taskState = this.activeTasks.get(args.taskId);
722
+ const wireAdcpVersion = taskState?.wireAdcpVersion ?? this.config.wireAdcpVersion;
723
+ if (wireAdcpVersion !== void 0) meta.wireAdcpVersion = wireAdcpVersion;
721
724
  if (taskState?.serverVersion !== void 0) meta.serverVersion = taskState.serverVersion;
722
725
  if (taskState?.serverVersionSynthetic !== void 0) {
723
726
  meta.serverVersionSynthetic = taskState.serverVersionSynthetic;
@@ -811,6 +814,7 @@ class TaskExecutor {
811
814
  }
812
815
  const taskState = {
813
816
  taskId,
817
+ wireAdcpVersion: wireAdcpVersion ?? options.negotiatedAdcpVersion ?? options.selectedAdcpVersion,
814
818
  taskName,
815
819
  params,
816
820
  status: "pending",
@@ -1081,7 +1085,7 @@ class TaskExecutor {
1081
1085
  () => ProtocolClient.callTool(agent, taskName, dispatchParams, callOptions)
1082
1086
  );
1083
1087
  throwIfAborted(postDispatchOptions.signal);
1084
- const respStatus = this.responseParser.getStatus(response);
1088
+ const respStatus = this.responseParser.getStatus(response, taskName);
1085
1089
  taskState.serverTaskId = this.responseParser.getTaskId(response);
1086
1090
  await this.config.onActivity?.({
1087
1091
  type: "protocol_response",
@@ -1264,7 +1268,7 @@ class TaskExecutor {
1264
1268
  };
1265
1269
  }
1266
1270
  async handleAsyncResponse(agent, taskId, taskName, params, response, messages, inputHandler, options = {}, debugLogs = [], startTime = Date.now(), deferTerminalTaskStatus = false, persistPausedContinuation = true, serverVersion = "v3", deferredClientContext, requireDeferredSettlementResumeAuthorization = false, refinementServedVersion) {
1267
- const status = this.responseParser.getStatus(response);
1271
+ const status = this.responseParser.getStatus(response, taskName);
1268
1272
  const serverTaskId = this.responseParser.getTaskId(response);
1269
1273
  const task = this.activeTasks.get(taskId);
1270
1274
  if (task && serverTaskId) task.serverTaskId = serverTaskId;
@@ -2516,8 +2520,15 @@ class TaskExecutor {
2516
2520
  }
2517
2521
  });
2518
2522
  }
2519
- async getTaskStatusWithRawResponse(agent, taskId, transport, signal, expectedTaskType, serverVersion, wireAdcpVersion, versionEnvelope, operationId) {
2520
- const toolName = agent.protocol === "mcp" ? "tasks_get" : "tasks/get";
2523
+ async resolveTaskStatusTool(agent, transport, signal) {
2524
+ if (this.config.resolveTaskStatusTool) {
2525
+ return this.config.resolveTaskStatusTool(agent, { transport: transport ?? this.config.transport, signal });
2526
+ }
2527
+ return agent.protocol === "mcp" ? "tasks_get" : "tasks/get";
2528
+ }
2529
+ async getTaskStatusWithRawResponse(agent, taskId, transport, signal, expectedTaskType, serverVersion, wireAdcpVersion, versionEnvelope, operationId, pollingTool) {
2530
+ const toolName = pollingTool ?? await this.resolveTaskStatusTool(agent, transport, signal);
2531
+ throwIfAborted(signal);
2521
2532
  const response = await ProtocolClient.callTool(
2522
2533
  agent,
2523
2534
  toolName,
@@ -2540,7 +2551,8 @@ class TaskExecutor {
2540
2551
  }
2541
2552
  }
2542
2553
  );
2543
- const task = mapTasksGetResponseToTaskInfo(response);
2554
+ const resultAdcpVersion = (versionEnvelope ?? this.config.versionEnvelope) === "major-only" ? "3.0" : wireAdcpVersion ?? this.config.wireAdcpVersion ?? this.config.adcpVersion ?? ADCP_VERSION;
2555
+ const task = mapTasksGetResponseToTaskInfo(response, resultAdcpVersion);
2544
2556
  if (!task.taskId || task.taskId !== taskId) {
2545
2557
  throw new TaskBindingMismatchError(
2546
2558
  "tasks/get returned a task identity that does not match the requested task.",
@@ -2575,6 +2587,7 @@ class TaskExecutor {
2575
2587
  }
2576
2588
  const pollStartTime = Date.now();
2577
2589
  const correlationId = metadataTaskId ?? taskId;
2590
+ let pollingTool;
2578
2591
  const withServerTaskId = (metadata) => ({
2579
2592
  ...metadata,
2580
2593
  serverTaskId: taskId
@@ -2615,6 +2628,7 @@ class TaskExecutor {
2615
2628
  let status;
2616
2629
  let rawResponse;
2617
2630
  try {
2631
+ pollingTool ??= await this.resolveTaskStatusTool(agent, transportSnapshot, signal);
2618
2632
  const pollResult = await this.getTaskStatusWithRawResponse(
2619
2633
  agent,
2620
2634
  taskId,
@@ -2624,7 +2638,8 @@ class TaskExecutor {
2624
2638
  serverVersion,
2625
2639
  wireAdcpVersion,
2626
2640
  versionEnvelope,
2627
- metadataTaskId
2641
+ metadataTaskId,
2642
+ pollingTool
2628
2643
  );
2629
2644
  status = pollResult.task;
2630
2645
  rawResponse = pollResult.rawResponse;
@@ -31,3 +31,5 @@ export declare function extractAdcpTaskStatusFromPayload(payload: unknown): ADCP
31
31
  * back to the transport-layer status.
32
32
  */
33
33
  export declare function extractAdcpStatusFromA2aTaskResult(result: unknown): ADCPStatus | undefined;
34
+ /** A status query describes another task; its status/error are data, not the query's lifecycle. */
35
+ export declare function isTaskStatusResponse(value: unknown, toolName?: string): boolean;
@@ -31,3 +31,5 @@ export declare function extractAdcpTaskStatusFromPayload(payload: unknown): ADCP
31
31
  * back to the transport-layer status.
32
32
  */
33
33
  export declare function extractAdcpStatusFromA2aTaskResult(result: unknown): ADCPStatus | undefined;
34
+ /** A status query describes another task; its status/error are data, not the query's lifecycle. */
35
+ export declare function isTaskStatusResponse(value: unknown, toolName?: string): boolean;
@@ -22,7 +22,8 @@ __export(task_status_exports, {
22
22
  TASK_ENVELOPE_FIELDS: () => TASK_ENVELOPE_FIELDS,
23
23
  extractAdcpStatusFromA2aTaskResult: () => extractAdcpStatusFromA2aTaskResult,
24
24
  extractAdcpTaskStatusFromPayload: () => extractAdcpTaskStatusFromPayload,
25
- isAdcpStatus: () => isAdcpStatus
25
+ isAdcpStatus: () => isAdcpStatus,
26
+ isTaskStatusResponse: () => isTaskStatusResponse
26
27
  });
27
28
  module.exports = __toCommonJS(task_status_exports);
28
29
  var import_a2a_artifacts = require('../utils/a2a-artifacts.js');
@@ -80,11 +81,19 @@ function extractAdcpStatusFromA2aTaskResult(result) {
80
81
  const extracted = (0, import_a2a_artifacts.getLatestA2ADataPartFromTask)(result);
81
82
  return extractAdcpTaskStatusFromPayload(extracted?.data);
82
83
  }
84
+ function isTaskStatusResponse(value, toolName) {
85
+ if (toolName !== "get_task_status" || !value || typeof value !== "object" || Array.isArray(value)) return false;
86
+ const record = value;
87
+ return ["task_id", "task_type", "protocol", "status", "created_at", "updated_at"].every(
88
+ (field) => typeof record[field] === "string"
89
+ ) && record.adcp_error === void 0 && record.errors === void 0;
90
+ }
83
91
  // Annotate the CommonJS export names for ESM import in node:
84
92
  0 && (module.exports = {
85
93
  ADCP_STATUS,
86
94
  TASK_ENVELOPE_FIELDS,
87
95
  extractAdcpStatusFromA2aTaskResult,
88
96
  extractAdcpTaskStatusFromPayload,
89
- isAdcpStatus
97
+ isAdcpStatus,
98
+ isTaskStatusResponse
90
99
  });
@@ -53,10 +53,18 @@ function extractAdcpStatusFromA2aTaskResult(result) {
53
53
  const extracted = getLatestA2ADataPartFromTask(result);
54
54
  return extractAdcpTaskStatusFromPayload(extracted?.data);
55
55
  }
56
+ function isTaskStatusResponse(value, toolName) {
57
+ if (toolName !== "get_task_status" || !value || typeof value !== "object" || Array.isArray(value)) return false;
58
+ const record = value;
59
+ return ["task_id", "task_type", "protocol", "status", "created_at", "updated_at"].every(
60
+ (field) => typeof record[field] === "string"
61
+ ) && record.adcp_error === void 0 && record.errors === void 0;
62
+ }
56
63
  export {
57
64
  ADCP_STATUS,
58
65
  TASK_ENVELOPE_FIELDS,
59
66
  extractAdcpStatusFromA2aTaskResult,
60
67
  extractAdcpTaskStatusFromPayload,
61
- isAdcpStatus
68
+ isAdcpStatus,
69
+ isTaskStatusResponse
62
70
  };
@@ -410,6 +410,28 @@ export declare class ResponseTooLargeError extends ADCPError {
410
410
  */
411
411
  contentLengthHeader?: number | undefined);
412
412
  }
413
+ /**
414
+ * Error thrown when an agent rate-limits the SDK's endpoint discovery: a
415
+ * probe answered HTTP 429, or HTTP 503 with a `Retry-After` header.
416
+ *
417
+ * Discovery stops at the first such probe instead of trying the remaining
418
+ * candidate URLs, which would only spend more of the seller's request budget.
419
+ * The rate limit says nothing about whether `agent_uri` is correct.
420
+ *
421
+ * Recovery: `transient`. Wait `retryAfterMs` (when the agent sent
422
+ * `Retry-After`) and retry.
423
+ */
424
+ export declare class AgentRateLimitedError extends ADCPError {
425
+ readonly status: number;
426
+ readonly code = "RATE_LIMITED";
427
+ /** The probed URL, without credentials, query or fragment. */
428
+ readonly agentUrl: string;
429
+ /** `Retry-After` as the agent sent it. Set only when it is valid delta-seconds or an HTTP-date. */
430
+ readonly retryAfter?: string;
431
+ /** Delay from `Retry-After`, in milliseconds. */
432
+ readonly retryAfterMs?: number;
433
+ constructor(agentUrl: string, status: number, retryAfter?: string, cause?: unknown);
434
+ }
413
435
  /**
414
436
  * Error thrown when an `update_media_buy` request is rejected because the
415
437
  * action it maps to isn't currently allowed on the buy (AdCP 3.1, RFC #4480).
@@ -410,6 +410,28 @@ export declare class ResponseTooLargeError extends ADCPError {
410
410
  */
411
411
  contentLengthHeader?: number | undefined);
412
412
  }
413
+ /**
414
+ * Error thrown when an agent rate-limits the SDK's endpoint discovery: a
415
+ * probe answered HTTP 429, or HTTP 503 with a `Retry-After` header.
416
+ *
417
+ * Discovery stops at the first such probe instead of trying the remaining
418
+ * candidate URLs, which would only spend more of the seller's request budget.
419
+ * The rate limit says nothing about whether `agent_uri` is correct.
420
+ *
421
+ * Recovery: `transient`. Wait `retryAfterMs` (when the agent sent
422
+ * `Retry-After`) and retry.
423
+ */
424
+ export declare class AgentRateLimitedError extends ADCPError {
425
+ readonly status: number;
426
+ readonly code = "RATE_LIMITED";
427
+ /** The probed URL, without credentials, query or fragment. */
428
+ readonly agentUrl: string;
429
+ /** `Retry-After` as the agent sent it. Set only when it is valid delta-seconds or an HTTP-date. */
430
+ readonly retryAfter?: string;
431
+ /** Delay from `Retry-After`, in milliseconds. */
432
+ readonly retryAfterMs?: number;
433
+ constructor(agentUrl: string, status: number, retryAfter?: string, cause?: unknown);
434
+ }
413
435
  /**
414
436
  * Error thrown when an `update_media_buy` request is rejected because the
415
437
  * action it maps to isn't currently allowed on the buy (AdCP 3.1, RFC #4480).
@@ -28,6 +28,7 @@ __export(errors_exports, {
28
28
  AccountSetupRequiredError: () => AccountSetupRequiredError,
29
29
  ActionNotAllowedError: () => ActionNotAllowedError,
30
30
  AgentNotFoundError: () => AgentNotFoundError,
31
+ AgentRateLimitedError: () => AgentRateLimitedError,
31
32
  AuthenticationCredentialsRejectedError: () => AuthenticationCredentialsRejectedError,
32
33
  AuthenticationRequiredError: () => AuthenticationRequiredError,
33
34
  BuyerSetupError: () => BuyerSetupError,
@@ -474,6 +475,47 @@ class ResponseTooLargeError extends ADCPError {
474
475
  contentLengthHeader;
475
476
  code = "RESPONSE_TOO_LARGE";
476
477
  }
478
+ class AgentRateLimitedError extends ADCPError {
479
+ constructor(agentUrl, status, retryAfter, cause) {
480
+ const safeAgentUrl = sanitizeAgentUrlForError(agentUrl);
481
+ const retryAfterMs = parseRetryAfterMs(retryAfter);
482
+ const validRetryAfter = retryAfterMs === void 0 ? void 0 : retryAfter?.trim();
483
+ const retryHint = retryAfterMs === void 0 ? "No usable Retry-After header; back off before retrying." : `Retry-After: ${validRetryAfter} (${Math.ceil(retryAfterMs / 1e3)}s).`;
484
+ super(
485
+ `Agent rate limited MCP endpoint discovery: HTTP ${status} from ${safeAgentUrl}. ${retryHint} Discovery stopped at this probe to avoid spending more of the agent's request budget; this does not indicate a wrong agent_uri.`
486
+ );
487
+ this.status = status;
488
+ this.agentUrl = safeAgentUrl;
489
+ if (retryAfterMs !== void 0) {
490
+ this.retryAfter = validRetryAfter;
491
+ this.retryAfterMs = retryAfterMs;
492
+ }
493
+ this.details = {
494
+ agentUrl: safeAgentUrl,
495
+ status,
496
+ ...retryAfterMs !== void 0 && { retryAfter: validRetryAfter, retryAfterMs }
497
+ };
498
+ if (cause !== void 0) {
499
+ Object.defineProperty(this, "cause", { value: cause, enumerable: false, configurable: true });
500
+ }
501
+ }
502
+ status;
503
+ code = "RATE_LIMITED";
504
+ /** The probed URL, without credentials, query or fragment. */
505
+ agentUrl;
506
+ /** `Retry-After` as the agent sent it. Set only when it is valid delta-seconds or an HTTP-date. */
507
+ retryAfter;
508
+ /** Delay from `Retry-After`, in milliseconds. */
509
+ retryAfterMs;
510
+ }
511
+ function parseRetryAfterMs(value) {
512
+ const trimmed = value?.trim();
513
+ if (!trimmed) return void 0;
514
+ if (/^\d{1,10}$/.test(trimmed)) return Number(trimmed) * 1e3;
515
+ if (!/^[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2} GMT$/.test(trimmed)) return void 0;
516
+ const date = Date.parse(trimmed);
517
+ return Number.isNaN(date) ? void 0 : Math.max(0, date - Date.now());
518
+ }
477
519
  class ActionNotAllowedError extends ADCPError {
478
520
  code = "ACTION_NOT_ALLOWED";
479
521
  attemptedAction;
@@ -677,6 +719,7 @@ class PreparedFixturesDeniedError extends ADCPError {
677
719
  AccountSetupRequiredError,
678
720
  ActionNotAllowedError,
679
721
  AgentNotFoundError,
722
+ AgentRateLimitedError,
680
723
  AuthenticationCredentialsRejectedError,
681
724
  AuthenticationRequiredError,
682
725
  BuyerSetupError,
@@ -413,6 +413,47 @@ class ResponseTooLargeError extends ADCPError {
413
413
  contentLengthHeader;
414
414
  code = "RESPONSE_TOO_LARGE";
415
415
  }
416
+ class AgentRateLimitedError extends ADCPError {
417
+ constructor(agentUrl, status, retryAfter, cause) {
418
+ const safeAgentUrl = sanitizeAgentUrlForError(agentUrl);
419
+ const retryAfterMs = parseRetryAfterMs(retryAfter);
420
+ const validRetryAfter = retryAfterMs === void 0 ? void 0 : retryAfter?.trim();
421
+ const retryHint = retryAfterMs === void 0 ? "No usable Retry-After header; back off before retrying." : `Retry-After: ${validRetryAfter} (${Math.ceil(retryAfterMs / 1e3)}s).`;
422
+ super(
423
+ `Agent rate limited MCP endpoint discovery: HTTP ${status} from ${safeAgentUrl}. ${retryHint} Discovery stopped at this probe to avoid spending more of the agent's request budget; this does not indicate a wrong agent_uri.`
424
+ );
425
+ this.status = status;
426
+ this.agentUrl = safeAgentUrl;
427
+ if (retryAfterMs !== void 0) {
428
+ this.retryAfter = validRetryAfter;
429
+ this.retryAfterMs = retryAfterMs;
430
+ }
431
+ this.details = {
432
+ agentUrl: safeAgentUrl,
433
+ status,
434
+ ...retryAfterMs !== void 0 && { retryAfter: validRetryAfter, retryAfterMs }
435
+ };
436
+ if (cause !== void 0) {
437
+ Object.defineProperty(this, "cause", { value: cause, enumerable: false, configurable: true });
438
+ }
439
+ }
440
+ status;
441
+ code = "RATE_LIMITED";
442
+ /** The probed URL, without credentials, query or fragment. */
443
+ agentUrl;
444
+ /** `Retry-After` as the agent sent it. Set only when it is valid delta-seconds or an HTTP-date. */
445
+ retryAfter;
446
+ /** Delay from `Retry-After`, in milliseconds. */
447
+ retryAfterMs;
448
+ }
449
+ function parseRetryAfterMs(value) {
450
+ const trimmed = value?.trim();
451
+ if (!trimmed) return void 0;
452
+ if (/^\d{1,10}$/.test(trimmed)) return Number(trimmed) * 1e3;
453
+ if (!/^[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2} GMT$/.test(trimmed)) return void 0;
454
+ const date = Date.parse(trimmed);
455
+ return Number.isNaN(date) ? void 0 : Math.max(0, date - Date.now());
456
+ }
416
457
  class ActionNotAllowedError extends ADCPError {
417
458
  code = "ACTION_NOT_ALLOWED";
418
459
  attemptedAction;
@@ -615,6 +656,7 @@ export {
615
656
  AccountSetupRequiredError,
616
657
  ActionNotAllowedError,
617
658
  AgentNotFoundError,
659
+ AgentRateLimitedError,
618
660
  AuthenticationCredentialsRejectedError,
619
661
  AuthenticationRequiredError,
620
662
  BuyerSetupError,
@@ -149,10 +149,7 @@ export interface DemandGrantAuthorization {
149
149
  export interface DemandGrantOptions {
150
150
  evaluator: TrustEvaluator;
151
151
  now?: () => number;
152
- /**
153
- * Only evaluated for uncovered claims, never fetch failures, and never for a scope an
154
- * `exclusive_grants: true` record names in any grant.
155
- */
152
+ /** Only evaluated for uncovered claims against a record without `exclusive_grants: true`; never fetch failures. */
156
153
  sellerAuthorization?: (claim: DemandGrantClaim) => Promise<boolean>;
157
154
  /** Only for authoritative absence; never after a 200 or an exclusive record. */
158
155
  legacyAuthorization?: (claim: DemandGrantClaim) => Promise<boolean>;
@@ -149,10 +149,7 @@ export interface DemandGrantAuthorization {
149
149
  export interface DemandGrantOptions {
150
150
  evaluator: TrustEvaluator;
151
151
  now?: () => number;
152
- /**
153
- * Only evaluated for uncovered claims, never fetch failures, and never for a scope an
154
- * `exclusive_grants: true` record names in any grant.
155
- */
152
+ /** Only evaluated for uncovered claims against a record without `exclusive_grants: true`; never fetch failures. */
156
153
  sellerAuthorization?: (claim: DemandGrantClaim) => Promise<boolean>;
157
154
  /** Only for authoritative absence; never after a 200 or an exclusive record. */
158
155
  legacyAuthorization?: (claim: DemandGrantClaim) => Promise<boolean>;
@@ -47,7 +47,7 @@ var import_etld = require('../signing/agent-resolver/etld.js');
47
47
  var import_strict_json = require('../signing/agent-resolver/strict-json.js');
48
48
  var import_tldts = require("tldts");
49
49
  var import_schemas = __toESM(require('./schemas.draft.js'));
50
- const ajv = new import_ajv.default({ strict: false, allErrors: false });
50
+ const ajv = new import_ajv.default({ inlineRefs: false, strict: false, allErrors: false });
51
51
  (0, import_ajv_formats.default)(ajv);
52
52
  for (const schema of import_schemas.default) ajv.addSchema(schema);
53
53
  function validateIdentity33Schema(id, value) {
@@ -335,13 +335,16 @@ function authorityGroup(operator) {
335
335
  const provider = (0, import_tldts.parse)(operator).domain;
336
336
  return `private:${provider ?? operator}`;
337
337
  }
338
+ const INTERMEDIARY_FETCH_CONCURRENCY = 8;
338
339
  function grantsScope(grant, scope) {
339
340
  return grant.scopes.some(
340
341
  (granted) => granted === "*" || granted === scope || granted === "adcp:all" && scope.startsWith("adcp:")
341
342
  );
342
343
  }
343
344
  function grantMatches(grant, target, claim, now) {
344
- if (registrableGrantee(grant.grantee) !== target) return false;
345
+ return registrableGrantee(grant.grantee) === target && grantCovers(grant, claim, now);
346
+ }
347
+ function grantCovers(grant, claim, now) {
345
348
  if (!grantsScope(grant, claim.scope)) return false;
346
349
  if (grant.agents && !grant.agents.some((agent) => grantAgentOrigin(agent.url) === (0, import_canonicalize.canonicalAgentOrigin)(claim.signerOrigin)))
347
350
  return false;
@@ -367,7 +370,6 @@ async function authorizeDemandGrant(claim, options) {
367
370
  ...grants.some((g) => g.valid_until) ? { expiresAt: Math.min(...grants.map((g) => g.valid_until ? Date.parse(g.valid_until) / 1e3 : Infinity)) } : {}
368
371
  });
369
372
  if (brand === operator && account === operator) return result("implicit", [brand]);
370
- if (brand === operator && account !== operator) throw new IdentityAuthorizationError("grant_absent");
371
373
  let house;
372
374
  try {
373
375
  house = await options.resolveBrandHouse?.(claim.brand);
@@ -377,33 +379,44 @@ async function authorizeDemandGrant(claim, options) {
377
379
  unavailable(cause);
378
380
  }
379
381
  const authoritativeBrand = house ? (0, import_etld.eTldPlusOne)(house.domain) : brand;
380
- if (authoritativeBrand === operator && account === operator) return result("implicit", [brand, operator]);
382
+ const self = /* @__PURE__ */ new Set([brand, authoritativeBrand]);
383
+ if (self.has(account) && self.has(operator)) return result("implicit", [.../* @__PURE__ */ new Set([brand, account, operator])]);
381
384
  const grantClaim = house ? { ...claim, brand: { ...claim.brand, brand_id: house.brand_id } } : claim;
382
385
  const record = await options.evaluator.get(authoritativeBrand);
383
386
  if (record.status === "absent") {
384
387
  if (await options.legacyAuthorization?.(claim)) return result("legacy", [brand, account, operator]);
385
388
  throw new IdentityAuthorizationError("grant_absent");
386
389
  }
387
- const first = (record.record.grants ?? []).filter((g) => grantMatches(g, account, grantClaim, now));
388
- if (account === operator && first.length) return result("trust", [brand, operator], [first[0]]);
389
- const selfOperated = account === brand || account === authoritativeBrand;
390
- if (selfOperated && account !== operator) {
391
- const direct = (record.record.grants ?? []).find((g) => grantMatches(g, operator, grantClaim, now));
392
- if (direct) return result("trust", [brand, operator], [direct]);
390
+ const firsts = [];
391
+ for (const grant of record.record.grants ?? []) {
392
+ const grantee = registrableGrantee(grant.grantee);
393
+ if (grantee === void 0 || !grantCovers(grant, grantClaim, now)) continue;
394
+ if (!self.has(account) && account !== grantee) continue;
395
+ if (grantee === operator) return result("trust", [brand, operator], [grant]);
396
+ firsts.push({ grant, grantee });
397
+ }
398
+ const grantees = [...new Set(firsts.map((f) => f.grantee))];
399
+ const records = /* @__PURE__ */ new Map();
400
+ for (let i = 0; i < grantees.length; i += INTERMEDIARY_FETCH_CONCURRENCY) {
401
+ const batch = grantees.slice(i, i + INTERMEDIARY_FETCH_CONCURRENCY);
402
+ const settled = await Promise.allSettled(batch.map((grantee) => options.evaluator.get(grantee)));
403
+ settled.forEach(
404
+ (outcome, j) => records.set(batch[j], outcome.status === "fulfilled" ? outcome.value : { failed: outcome.reason })
405
+ );
393
406
  }
394
- if (account !== operator && account !== brand && first.length) {
395
- const intermediary = await options.evaluator.get(account);
396
- if (intermediary.status === "present") {
397
- const second = (intermediary.record.grants ?? []).find((g) => grantMatches(g, operator, grantClaim, now));
398
- if (second) return result("trust", [brand, account, operator], [first[0], second]);
407
+ let outage;
408
+ for (const { grant: first, grantee } of firsts) {
409
+ const intermediary = records.get(grantee);
410
+ if ("failed" in intermediary) {
411
+ outage ??= intermediary.failed;
412
+ continue;
399
413
  }
414
+ if (intermediary.status !== "present") continue;
415
+ const second = (intermediary.record.grants ?? []).find((g) => grantMatches(g, operator, grantClaim, now));
416
+ if (second) return result("trust", [brand, grantee, operator], [first, second]);
400
417
  }
401
- const covered = (record.record.grants ?? []).some((g) => {
402
- const grantee = registrableGrantee(g.grantee);
403
- return grantee !== void 0 && (grantee === account || selfOperated && grantee === operator) && grantsScope(g, claim.scope);
404
- });
405
- const exclusive = record.record.exclusive_grants === true && (record.record.grants ?? []).some((g) => grantsScope(g, claim.scope));
406
- if (!covered && !exclusive && await options.sellerAuthorization?.(claim))
418
+ if (outage !== void 0) throw outage;
419
+ if (record.record.exclusive_grants !== true && await options.sellerAuthorization?.(claim))
407
420
  return result("seller", [brand, account, operator]);
408
421
  throw new IdentityAuthorizationError("grant_absent");
409
422
  }