@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
@@ -1,6 +1,25 @@
1
1
  import { applyTargetingInput, resolveTargetingInput } from "../media-buy/targeting-input.mjs";
2
2
  import { scopedStore } from "./state-store.mjs";
3
3
  const DEFAULT_MEDIA_BUY_STORE_COLLECTION = "media_buys_targeting";
4
+ const PACKAGE_IDENTITY_FIELDS = ["package_id", "product_id", "buyer_ref"];
5
+ function compatibleIdentity(left, right) {
6
+ if (!left || !right) return false;
7
+ return PACKAGE_IDENTITY_FIELDS.every((key) => !left[key] || !right[key] || left[key] === right[key]);
8
+ }
9
+ function sharesIdentity(left, right) {
10
+ if (!left || !right) return false;
11
+ return compatibleIdentity(left, right) && PACKAGE_IDENTITY_FIELDS.some((key) => left[key] && left[key] === right[key]);
12
+ }
13
+ function matchContextPackage(requests, responses, index) {
14
+ const matches = requests.filter((request) => sharesIdentity(request, responses[index]));
15
+ if (matches.length === 1 && responses.filter((response) => sharesIdentity(matches[0], response)).length === 1) {
16
+ return matches[0];
17
+ }
18
+ if (requests.length === responses.length && requests.every((request, i) => compatibleIdentity(request, responses[i]))) {
19
+ return requests[index];
20
+ }
21
+ return void 0;
22
+ }
4
23
  function createMediaBuyStore(options) {
5
24
  const collection = options.collection ?? DEFAULT_MEDIA_BUY_STORE_COLLECTION;
6
25
  function viewFor(accountId) {
@@ -18,8 +37,9 @@ function createMediaBuyStore(options) {
18
37
  async persistFromCreate(accountId, request, result) {
19
38
  const requestPackages = request.packages ?? [];
20
39
  const responsePackages = result.packages ?? [];
21
- if (requestPackages.length === 0 || !result.media_buy_id) return;
22
- const persistedPackages = [];
40
+ if (!result.media_buy_id) return;
41
+ const prior = await loadRecord(accountId, result.media_buy_id);
42
+ const byId = new Map((prior?.packages ?? []).map((pkg) => [pkg.package_id, { ...pkg }]));
23
43
  for (let i = 0; i < requestPackages.length; i++) {
24
44
  const reqPkg = requestPackages[i];
25
45
  if (!reqPkg?.targeting_overlay) continue;
@@ -30,12 +50,26 @@ function createMediaBuyStore(options) {
30
50
  if (!packageId) continue;
31
51
  const persistedOverlay = respPkg?.targeting_overlay ?? resolveTargetingInput(reqPkg.targeting_overlay);
32
52
  if (!persistedOverlay) continue;
33
- persistedPackages.push({ package_id: packageId, targeting_overlay: persistedOverlay });
53
+ byId.set(packageId, { ...byId.get(packageId), package_id: packageId, targeting_overlay: persistedOverlay });
34
54
  }
35
- if (persistedPackages.length === 0) return;
55
+ for (const [index, response] of responsePackages.entries()) {
56
+ if (!response.package_id) continue;
57
+ const context2 = matchContextPackage(requestPackages, responsePackages, index)?.context ?? response.context;
58
+ const stored = byId.get(response.package_id);
59
+ if (context2 !== void 0 && stored?.context === void 0) {
60
+ byId.set(response.package_id, {
61
+ ...stored,
62
+ package_id: response.package_id,
63
+ context: structuredClone(context2)
64
+ });
65
+ }
66
+ }
67
+ const context = prior?.context ?? request.context ?? result.context;
68
+ if (byId.size === 0 && context === void 0) return;
36
69
  await writeRecord(accountId, {
37
70
  media_buy_id: result.media_buy_id,
38
- packages: persistedPackages
71
+ ...context !== void 0 ? { context: structuredClone(context) } : {},
72
+ packages: Array.from(byId.values())
39
73
  });
40
74
  },
41
75
  async mergeFromUpdate(accountId, mediaBuyId, patch) {
@@ -43,42 +77,56 @@ function createMediaBuyStore(options) {
43
77
  media_buy_id: mediaBuyId,
44
78
  packages: []
45
79
  };
46
- const byId = new Map(prior.packages.map((p) => [p.package_id, p.targeting_overlay]));
80
+ const byId = new Map(prior.packages.map((p) => [p.package_id, { ...p }]));
47
81
  for (const pkg of patch.packages ?? []) {
48
82
  const packageId = pkg?.package_id;
49
83
  if (!packageId) continue;
50
84
  if (!("targeting_overlay" in pkg)) continue;
51
85
  const incoming = pkg.targeting_overlay;
52
86
  if (incoming === void 0) continue;
53
- const merged = applyTargetingInput(byId.get(packageId), incoming);
54
- if (merged) byId.set(packageId, merged);
55
- else byId.delete(packageId);
87
+ const stored = byId.get(packageId);
88
+ const merged = applyTargetingInput(stored?.targeting_overlay, incoming);
89
+ if (merged) byId.set(packageId, { ...stored, package_id: packageId, targeting_overlay: merged });
90
+ else if (stored?.context !== void 0) {
91
+ byId.set(packageId, { package_id: packageId, context: stored.context });
92
+ } else byId.delete(packageId);
56
93
  }
57
94
  for (const pkg of patch.new_packages ?? []) {
58
95
  if (!pkg?.targeting_overlay || !pkg.package_id) continue;
59
96
  const resolved = resolveTargetingInput(pkg.targeting_overlay);
60
- if (resolved) byId.set(pkg.package_id, resolved);
97
+ if (resolved)
98
+ byId.set(pkg.package_id, {
99
+ ...byId.get(pkg.package_id),
100
+ package_id: pkg.package_id,
101
+ targeting_overlay: resolved
102
+ });
61
103
  }
62
104
  await writeRecord(accountId, {
63
- media_buy_id: mediaBuyId,
64
- packages: Array.from(byId.entries()).map(([package_id, targeting_overlay]) => ({
65
- package_id,
66
- targeting_overlay
67
- }))
105
+ ...prior,
106
+ packages: Array.from(byId.values())
68
107
  });
69
108
  },
70
109
  async backfill(accountId, result) {
71
110
  const buys = result.media_buys;
72
111
  if (!buys || buys.length === 0) return result;
73
112
  for (const buy of buys) {
74
- if (!buy?.media_buy_id || !buy.packages) continue;
113
+ if (!buy?.media_buy_id) continue;
75
114
  const record = await loadRecord(accountId, buy.media_buy_id);
76
115
  if (!record) continue;
77
- const overlayById = new Map(record.packages.map((p) => [p.package_id, p.targeting_overlay]));
78
- for (const pkg of buy.packages) {
79
- if (!pkg?.package_id || pkg.targeting_overlay !== void 0) continue;
80
- const persisted = overlayById.get(pkg.package_id);
81
- if (persisted) pkg.targeting_overlay = persisted;
116
+ if (buy.context === void 0 && record.context !== void 0) {
117
+ buy.context = structuredClone(record.context);
118
+ }
119
+ const byId = new Map(record.packages.map((p) => [p.package_id, p]));
120
+ for (const pkg of buy.packages ?? []) {
121
+ if (!pkg?.package_id) continue;
122
+ const persisted = byId.get(pkg.package_id);
123
+ if (!persisted) continue;
124
+ if (pkg.targeting_overlay === void 0 && persisted.targeting_overlay !== void 0) {
125
+ pkg.targeting_overlay = persisted.targeting_overlay;
126
+ }
127
+ if (pkg.context === void 0 && persisted.context !== void 0) {
128
+ pkg.context = structuredClone(persisted.context);
129
+ }
82
130
  }
83
131
  }
84
132
  return result;
@@ -1,7 +1,7 @@
1
1
  import type { WebhookAttemptSuppressionReason } from '../webhook-emitter.mjs';
2
2
  import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, NotificationSuppressionDisposition, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions, StoredNotificationSubscription } from './types.mjs';
3
3
  export declare const CALLER_NOTIFICATION_TYPES: readonly ["capabilities.changed", "principal.changed"];
4
- export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
4
+ export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "collection_card.updated", "collection_card.removed", "collection_catalog.bulk_change", "proposal.created", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
5
5
  /**
6
6
  * Durable subscription control plane. The supplied emitter factory is called
7
7
  * exactly once with the runtime's mandatory live authorizer, preventing a
@@ -1,7 +1,7 @@
1
1
  import type { WebhookAttemptSuppressionReason } from '../webhook-emitter';
2
2
  import type { NotificationSubscriptionConfigInput, NotificationSubscriptionView, NotificationSuppressionDisposition, PersistentNotificationRuntime, PersistentNotificationRuntimeOptions, StoredNotificationSubscription } from './types';
3
3
  export declare const CALLER_NOTIFICATION_TYPES: readonly ["capabilities.changed", "principal.changed"];
4
- export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
4
+ export declare const ACCOUNT_NOTIFICATION_TYPES: readonly ["creative.status_changed", "creative.assignment_changed", "indicators.changed", "creative.purged", "account.status_changed", "account.change_recorded", "product.created", "product.updated", "product.priced", "product.removed", "signal.created", "signal.updated", "signal.priced", "signal.removed", "wholesale_feed.bulk_change", "collection_card.updated", "collection_card.removed", "collection_catalog.bulk_change", "proposal.created", "reporting.delivery_ready", "reporting.status_changed", "reporting.ledger_changed"];
5
5
  /**
6
6
  * Durable subscription control plane. The supplied emitter factory is called
7
7
  * exactly once with the runtime's mandatory live authorizer, preventing a
@@ -51,6 +51,10 @@ const ACCOUNT_NOTIFICATION_TYPES = Object.freeze([
51
51
  "signal.priced",
52
52
  "signal.removed",
53
53
  "wholesale_feed.bulk_change",
54
+ "collection_card.updated",
55
+ "collection_card.removed",
56
+ "collection_catalog.bulk_change",
57
+ "proposal.created",
54
58
  "reporting.delivery_ready",
55
59
  "reporting.status_changed",
56
60
  "reporting.ledger_changed"
@@ -22,6 +22,10 @@ const ACCOUNT_NOTIFICATION_TYPES = Object.freeze([
22
22
  "signal.priced",
23
23
  "signal.removed",
24
24
  "wholesale_feed.bulk_change",
25
+ "collection_card.updated",
26
+ "collection_card.removed",
27
+ "collection_catalog.bulk_change",
28
+ "proposal.created",
25
29
  "reporting.delivery_ready",
26
30
  "reporting.status_changed",
27
31
  "reporting.ledger_changed"
@@ -60,6 +60,7 @@ __export(responses_exports, {
60
60
  module.exports = __toCommonJS(responses_exports);
61
61
  var import_media_buy_helpers = require('./media-buy-helpers.js');
62
62
  var import_reporting_delivery_config = require('./reporting-delivery-config.js');
63
+ var import_account_response_identity = require('./account-response-identity.js');
63
64
  const explicitResponseSummaries = /* @__PURE__ */ new WeakMap();
64
65
  function _getExplicitResponseSummary(response) {
65
66
  return explicitResponseSummaries.get(response);
@@ -124,7 +125,14 @@ function stripBusinessEntityBank(row, key) {
124
125
  return stripped;
125
126
  }
126
127
  function stripAccountWriteOnlyFields(account) {
127
- const stripped = stripBusinessEntityBank(stripNotificationConfigSecrets(account), "billing_entity");
128
+ const {
129
+ destination_billing_entity: _destination,
130
+ authInfo: _authInfo,
131
+ ctx_metadata: _metadata,
132
+ ...responseFields
133
+ } = account;
134
+ const response = stripBusinessEntityBank(stripNotificationConfigSecrets(responseFields), "billing_entity");
135
+ const stripped = { ...response, ...(0, import_account_response_identity.projectAccountResponseIdentityFields)(response) };
128
136
  const reportingDeliveryConfigs = stripped.reporting_delivery_configs;
129
137
  if (reportingDeliveryConfigs === void 0) return stripped;
130
138
  return {
@@ -1,5 +1,6 @@
1
1
  import { validActionsForStatus } from "./media-buy-helpers.mjs";
2
2
  import { projectReportingDeliveryConfigStates } from "./reporting-delivery-config.mjs";
3
+ import { projectAccountResponseIdentityFields } from "./account-response-identity.mjs";
3
4
  const explicitResponseSummaries = /* @__PURE__ */ new WeakMap();
4
5
  function _getExplicitResponseSummary(response) {
5
6
  return explicitResponseSummaries.get(response);
@@ -64,7 +65,14 @@ function stripBusinessEntityBank(row, key) {
64
65
  return stripped;
65
66
  }
66
67
  function stripAccountWriteOnlyFields(account) {
67
- const stripped = stripBusinessEntityBank(stripNotificationConfigSecrets(account), "billing_entity");
68
+ const {
69
+ destination_billing_entity: _destination,
70
+ authInfo: _authInfo,
71
+ ctx_metadata: _metadata,
72
+ ...responseFields
73
+ } = account;
74
+ const response = stripBusinessEntityBank(stripNotificationConfigSecrets(responseFields), "billing_entity");
75
+ const stripped = { ...response, ...projectAccountResponseIdentityFields(response) };
68
76
  const reportingDeliveryConfigs = stripped.reporting_delivery_configs;
69
77
  if (reportingDeliveryConfigs === void 0) return stripped;
70
78
  return {
@@ -80,7 +80,7 @@ export interface BuildAgentSigningFetchOptions {
80
80
  * 1. Sign immediately when the payload carries webhook authentication.
81
81
  * 2. Resolve the AdCP operation and exact JSON-RPC protocol method.
82
82
  * 3. Consult each capability namespace independently; either can request
83
- * signing. Legacy SDK task polls sign when the seller supports signing.
83
+ * signing. SDK AdCP task polls sign when the seller supports signing.
84
84
  * 4. Resolve the seller's content-digest policy into a per-request toggle.
85
85
  * 5. Delegate to `createSigningFetch` with the decision baked in.
86
86
  */
@@ -80,7 +80,7 @@ export interface BuildAgentSigningFetchOptions {
80
80
  * 1. Sign immediately when the payload carries webhook authentication.
81
81
  * 2. Resolve the AdCP operation and exact JSON-RPC protocol method.
82
82
  * 3. Consult each capability namespace independently; either can request
83
- * signing. Legacy SDK task polls sign when the seller supports signing.
83
+ * signing. SDK AdCP task polls sign when the seller supports signing.
84
84
  * 4. Resolve the seller's content-digest policy into a per-request toggle.
85
85
  * 5. Delegate to `createSigningFetch` with the decision baked in.
86
86
  */
@@ -157,13 +157,13 @@ function buildAgentSigningFetch(options) {
157
157
  }
158
158
  const operation = extractAdcpOperation(init?.body);
159
159
  if (operation === "get_adcp_capabilities" && (0, import_protocol_methods.hasUnsignedCapabilityBootstrap)(signing)) return false;
160
- const isPollOperation = operation === "tasks_get" || operation === "tasks/get";
160
+ const isPollOperation = operation === "get_task_status" || operation === "tasks_get" || operation === "tasks/get";
161
161
  const methods = policyMethods ?? (isPollOperation ? jsonRpcMethodsForSigning(init?.body) : []);
162
162
  const profileCompatible = signing.profile === "web-bot-auth" ? (0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth") : capability?.profiles === void 0 || (0, import_protocol_methods.signingListIncludes)(capability.profiles, "adcp/request-signing/v1");
163
- const legacyPoll = profileCompatible && capability?.supported === true && (operation === "tasks_get" && methods.includes("tools/call") || operation === "tasks/get" && methods.some(
163
+ const signedPoll = profileCompatible && capability?.supported === true && ((operation === "tasks_get" || operation === "get_task_status") && methods.includes("tools/call") || (operation === "tasks/get" || operation === "get_task_status") && methods.some(
164
164
  (method) => ["message/send", "message/stream", "SendMessage", "SendStreamingMessage"].includes(method)
165
165
  ));
166
- const sign = signing.profile === "web-bot-auth" && !!operation && (0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) || legacyPoll;
166
+ const sign = signing.profile === "web-bot-auth" && !!operation && (0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) || signedPoll;
167
167
  if (sign && signing.profile === "web-bot-auth" && !(0, import_protocol_methods.signingListIncludes)(capability?.profiles, "web-bot-auth"))
168
168
  throw new TypeError("Seller did not advertise the Web Bot Auth request signing profile");
169
169
  return sign;
@@ -139,13 +139,13 @@ function buildAgentSigningFetch(options) {
139
139
  }
140
140
  const operation = extractAdcpOperation(init?.body);
141
141
  if (operation === "get_adcp_capabilities" && hasUnsignedCapabilityBootstrap(signing)) return false;
142
- const isPollOperation = operation === "tasks_get" || operation === "tasks/get";
142
+ const isPollOperation = operation === "get_task_status" || operation === "tasks_get" || operation === "tasks/get";
143
143
  const methods = policyMethods ?? (isPollOperation ? jsonRpcMethodsForSigning(init?.body) : []);
144
144
  const profileCompatible = signing.profile === "web-bot-auth" ? signingListIncludes(capability?.profiles, "web-bot-auth") : capability?.profiles === void 0 || signingListIncludes(capability.profiles, "adcp/request-signing/v1");
145
- const legacyPoll = profileCompatible && capability?.supported === true && (operation === "tasks_get" && methods.includes("tools/call") || operation === "tasks/get" && methods.some(
145
+ const signedPoll = profileCompatible && capability?.supported === true && ((operation === "tasks_get" || operation === "get_task_status") && methods.includes("tools/call") || (operation === "tasks/get" || operation === "get_task_status") && methods.some(
146
146
  (method) => ["message/send", "message/stream", "SendMessage", "SendStreamingMessage"].includes(method)
147
147
  ));
148
- const sign = signing.profile === "web-bot-auth" && !!operation && signingListIncludes(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) || legacyPoll;
148
+ const sign = signing.profile === "web-bot-auth" && !!operation && signingListIncludes(capability?.profiles, "web-bot-auth") || shouldSignOperation(operation, capability, signing) || methods.some((method) => shouldSignProtocolMethod(method, capability, signing)) || signedPoll;
149
149
  if (sign && signing.profile === "web-bot-auth" && !signingListIncludes(capability?.profiles, "web-bot-auth"))
150
150
  throw new TypeError("Seller did not advertise the Web Bot Auth request signing profile");
151
151
  return sign;
@@ -89,6 +89,7 @@ schemaAdcpVersion?: string): Promise<{
89
89
  profile: AgentProfile;
90
90
  step: TestStepResult;
91
91
  caughtError?: unknown;
92
+ evidence?: TestStepResult;
92
93
  }>;
93
94
  /**
94
95
  * Discover what channels, pricing models, formats the agent supports
@@ -89,6 +89,7 @@ schemaAdcpVersion?: string): Promise<{
89
89
  profile: AgentProfile;
90
90
  step: TestStepResult;
91
91
  caughtError?: unknown;
92
+ evidence?: TestStepResult;
92
93
  }>;
93
94
  /**
94
95
  * Discover what channels, pricing models, formats the agent supports
@@ -641,23 +641,24 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
641
641
  }
642
642
  const failure = describeProfileDiscoveryFailure(profile);
643
643
  if (!step.passed || failure) {
644
- const evidence = { ...step, ...failure ?? {}, passed: false, duration_ms: step.duration_ms };
645
- evidence.error = (0, import_redact_credential_patterns.redactCredentialPatterns)(evidence.error ?? "Agent discovery failed", false).slice(
644
+ const evidence2 = { ...step, ...failure ?? {}, passed: false, duration_ms: step.duration_ms };
645
+ evidence2.error = (0, import_redact_credential_patterns.redactCredentialPatterns)(evidence2.error ?? "Agent discovery failed", false).slice(
646
646
  0,
647
647
  4096
648
648
  );
649
- profile.capabilities_failure = evidence;
649
+ profile.capabilities_failure = evidence2;
650
650
  }
651
651
  if (!step.passed) step.error = (0, import_redact_credential_patterns.redactCredentialPatterns)(step.error ?? "Agent discovery failed", false);
652
652
  if (!failure && step.passed && (scopeKey === void 0 || scopeKey === client.getCapabilityEvidenceScope().scopeKey)) {
653
653
  seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
654
654
  }
655
+ const evidence = step.passed && !failure ? { ...step } : void 0;
655
656
  if (step.passed && !failure) {
656
657
  delete step.request;
657
658
  delete step.response_record;
658
659
  delete step.adcp_error;
659
660
  }
660
- return { profile, step, ...caughtError !== void 0 && { caughtError } };
661
+ return { profile, step, ...caughtError !== void 0 && { caughtError }, ...evidence && { evidence } };
661
662
  }
662
663
  async function discoverAgentCapabilities(client, profile, options) {
663
664
  const steps = [];
@@ -876,7 +877,7 @@ function validateResponseSchema(toolName, data, responseAdcpVersion) {
876
877
  warnings: [`No Zod schema registered for "${toolName}" \u2014 validation skipped`]
877
878
  };
878
879
  }
879
- const compatData = data && typeof data === "object" && !Array.isArray(data) ? (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(data, { toolName }) : data;
880
+ const compatData = data && typeof data === "object" && !Array.isArray(data) ? (0, import_envelope_status_compat.injectLegacyEnvelopeStatus)(data, { toolName, adcpVersion: responseAdcpVersion }) : data;
880
881
  const result = schema.safeParse((0, import_response_schemas.prepareResponseForSchemaValidation)(toolName, compatData, responseAdcpVersion));
881
882
  if (result.success) {
882
883
  return {
@@ -599,23 +599,24 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
599
599
  }
600
600
  const failure = describeProfileDiscoveryFailure(profile);
601
601
  if (!step.passed || failure) {
602
- const evidence = { ...step, ...failure ?? {}, passed: false, duration_ms: step.duration_ms };
603
- evidence.error = redactCredentialPatterns(evidence.error ?? "Agent discovery failed", false).slice(
602
+ const evidence2 = { ...step, ...failure ?? {}, passed: false, duration_ms: step.duration_ms };
603
+ evidence2.error = redactCredentialPatterns(evidence2.error ?? "Agent discovery failed", false).slice(
604
604
  0,
605
605
  4096
606
606
  );
607
- profile.capabilities_failure = evidence;
607
+ profile.capabilities_failure = evidence2;
608
608
  }
609
609
  if (!step.passed) step.error = redactCredentialPatterns(step.error ?? "Agent discovery failed", false);
610
610
  if (!failure && step.passed && (scopeKey === void 0 || scopeKey === client.getCapabilityEvidenceScope().scopeKey)) {
611
611
  seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
612
612
  }
613
+ const evidence = step.passed && !failure ? { ...step } : void 0;
613
614
  if (step.passed && !failure) {
614
615
  delete step.request;
615
616
  delete step.response_record;
616
617
  delete step.adcp_error;
617
618
  }
618
- return { profile, step, ...caughtError !== void 0 && { caughtError } };
619
+ return { profile, step, ...caughtError !== void 0 && { caughtError }, ...evidence && { evidence } };
619
620
  }
620
621
  async function discoverAgentCapabilities(client, profile, options) {
621
622
  const steps = [];
@@ -834,7 +835,7 @@ function validateResponseSchema(toolName, data, responseAdcpVersion) {
834
835
  warnings: [`No Zod schema registered for "${toolName}" \u2014 validation skipped`]
835
836
  };
836
837
  }
837
- const compatData = data && typeof data === "object" && !Array.isArray(data) ? injectLegacyEnvelopeStatus(data, { toolName }) : data;
838
+ const compatData = data && typeof data === "object" && !Array.isArray(data) ? injectLegacyEnvelopeStatus(data, { toolName, adcpVersion: responseAdcpVersion }) : data;
838
839
  const result = schema.safeParse(prepareResponseForSchemaValidation(toolName, compatData, responseAdcpVersion));
839
840
  if (result.success) {
840
841
  return {
@@ -1,5 +1,5 @@
1
1
  import type { TestClient } from '../client.mjs';
2
- import type { AgentProfile } from '../types.mjs';
2
+ import type { AgentProfile, TestStepResult } from '../types.mjs';
3
3
  import { type AdcpProtocol } from '../../utils/capabilities.mjs';
4
4
  import type { AgentEntry, Storyboard, StoryboardRunOptions, StoryboardStep } from './types.mjs';
5
5
  /** Storyboard applicability is any-of; it does not authorize individual steps. */
@@ -18,6 +18,8 @@ export interface AgentRoutingContext {
18
18
  clients: Map<string, TestClient>;
19
19
  /** Per-agent discovered profile (`get_adcp_capabilities` result). */
20
20
  profiles: Map<string, AgentProfile>;
21
+ /** Actual discovery exchanges, retained separately from compact rollup steps. */
22
+ discoverySteps?: ReadonlyMap<string, TestStepResult>;
21
23
  /** Protocol → keys of agents that claim it. */
22
24
  protocolIndex: Map<AdcpProtocol, string[]>;
23
25
  /** Resolved (key → URL) for echo on the storyboard result. */
@@ -41,7 +43,8 @@ export declare class DiscoveryFailure extends Error {
41
43
  readonly agentKey: string;
42
44
  readonly url: string;
43
45
  readonly underlying: string;
44
- constructor(message: string, agentKey: string, url: string, underlying: string);
46
+ readonly step?: TestStepResult | undefined;
47
+ constructor(message: string, agentKey: string, url: string, underlying: string, step?: TestStepResult | undefined);
45
48
  }
46
49
  /**
47
50
  * Discover every agent in the map in parallel and build the routing index.
@@ -1,5 +1,5 @@
1
1
  import type { TestClient } from '../client';
2
- import type { AgentProfile } from '../types';
2
+ import type { AgentProfile, TestStepResult } from '../types';
3
3
  import { type AdcpProtocol } from '../../utils/capabilities';
4
4
  import type { AgentEntry, Storyboard, StoryboardRunOptions, StoryboardStep } from './types';
5
5
  /** Storyboard applicability is any-of; it does not authorize individual steps. */
@@ -18,6 +18,8 @@ export interface AgentRoutingContext {
18
18
  clients: Map<string, TestClient>;
19
19
  /** Per-agent discovered profile (`get_adcp_capabilities` result). */
20
20
  profiles: Map<string, AgentProfile>;
21
+ /** Actual discovery exchanges, retained separately from compact rollup steps. */
22
+ discoverySteps?: ReadonlyMap<string, TestStepResult>;
21
23
  /** Protocol → keys of agents that claim it. */
22
24
  protocolIndex: Map<AdcpProtocol, string[]>;
23
25
  /** Resolved (key → URL) for echo on the storyboard result. */
@@ -41,7 +43,8 @@ export declare class DiscoveryFailure extends Error {
41
43
  readonly agentKey: string;
42
44
  readonly url: string;
43
45
  readonly underlying: string;
44
- constructor(message: string, agentKey: string, url: string, underlying: string);
46
+ readonly step?: TestStepResult | undefined;
47
+ constructor(message: string, agentKey: string, url: string, underlying: string, step?: TestStepResult | undefined);
45
48
  }
46
49
  /**
47
50
  * Discover every agent in the map in parallel and build the routing index.
@@ -127,16 +127,18 @@ class RoutingError extends Error {
127
127
  hint;
128
128
  }
129
129
  class DiscoveryFailure extends Error {
130
- constructor(message, agentKey, url, underlying) {
130
+ constructor(message, agentKey, url, underlying, step) {
131
131
  super(message);
132
132
  this.agentKey = agentKey;
133
133
  this.url = url;
134
134
  this.underlying = underlying;
135
+ this.step = step;
135
136
  this.name = "DiscoveryFailure";
136
137
  }
137
138
  agentKey;
138
139
  url;
139
140
  underlying;
141
+ step;
140
142
  }
141
143
  async function discoverAgentRouting(options) {
142
144
  const agents = options.agents;
@@ -150,6 +152,7 @@ async function discoverAgentRouting(options) {
150
152
  agentMap[key] = entry.url;
151
153
  }
152
154
  const profiles = /* @__PURE__ */ new Map();
155
+ const discoverySteps = /* @__PURE__ */ new Map();
153
156
  const discoveryFailures = [];
154
157
  if (options._routingProfiles) {
155
158
  for (const [key] of entries) {
@@ -162,6 +165,7 @@ async function discoverAgentRouting(options) {
162
165
  return {
163
166
  clients,
164
167
  profiles,
168
+ discoverySteps,
165
169
  protocolIndex: buildProtocolIndex(profiles),
166
170
  agentMap,
167
171
  discoveryFailures
@@ -171,8 +175,8 @@ async function discoverAgentRouting(options) {
171
175
  entries.map(async ([key, entry]) => {
172
176
  const perAgentOptions = buildAgentOptions(entry, options);
173
177
  try {
174
- const { profile, step } = await (0, import_client.getOrDiscoverStoryboardProfile)(clients.get(key), perAgentOptions);
175
- return { key, profile, step };
178
+ const { profile, step, evidence } = await (0, import_client.getOrDiscoverStoryboardProfile)(clients.get(key), perAgentOptions);
179
+ return { key, profile, step, evidence };
176
180
  } catch (err) {
177
181
  return {
178
182
  key,
@@ -180,6 +184,7 @@ async function discoverAgentRouting(options) {
180
184
  step: {
181
185
  step: "Discover agent capabilities",
182
186
  passed: false,
187
+ duration_ms: 0,
183
188
  error: scrubAuthSecrets(err?.message || String(err))
184
189
  }
185
190
  };
@@ -187,6 +192,7 @@ async function discoverAgentRouting(options) {
187
192
  })
188
193
  );
189
194
  for (const r of discoveryResults) {
195
+ discoverySteps.set(r.key, "evidence" in r && r.evidence ? r.evidence : r.step);
190
196
  if (!r.profile || r.step.passed === false) {
191
197
  const rawDetail = scrubAuthSecrets(r.step.error ?? "Discovery returned no profile.");
192
198
  const detail = rawDetail.length > 512 ? `${rawDetail.slice(0, 512)} \u2026(truncated)` : rawDetail;
@@ -194,7 +200,7 @@ async function discoverAgentRouting(options) {
194
200
  const message = resilient ? baseMessage : `${baseMessage}
195
201
 
196
202
  If this is hello-cluster / exploratory CI and you want unrelated storyboards to complete despite this failure, set \`StoryboardRunOptions.discovery_resilient: true\`. Do NOT set it in production \u2014 a topology with a broken tenant is a hard misconfiguration there.`;
197
- const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail);
203
+ const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail, { ...r.step, error: detail });
198
204
  if (!resilient) throw failure;
199
205
  discoveryFailures.push(failure);
200
206
  continue;
@@ -204,6 +210,7 @@ If this is hello-cluster / exploratory CI and you want unrelated storyboards to
204
210
  return {
205
211
  clients,
206
212
  profiles,
213
+ discoverySteps,
207
214
  protocolIndex: buildProtocolIndex(profiles),
208
215
  agentMap,
209
216
  discoveryFailures
@@ -95,16 +95,18 @@ class RoutingError extends Error {
95
95
  hint;
96
96
  }
97
97
  class DiscoveryFailure extends Error {
98
- constructor(message, agentKey, url, underlying) {
98
+ constructor(message, agentKey, url, underlying, step) {
99
99
  super(message);
100
100
  this.agentKey = agentKey;
101
101
  this.url = url;
102
102
  this.underlying = underlying;
103
+ this.step = step;
103
104
  this.name = "DiscoveryFailure";
104
105
  }
105
106
  agentKey;
106
107
  url;
107
108
  underlying;
109
+ step;
108
110
  }
109
111
  async function discoverAgentRouting(options) {
110
112
  const agents = options.agents;
@@ -118,6 +120,7 @@ async function discoverAgentRouting(options) {
118
120
  agentMap[key] = entry.url;
119
121
  }
120
122
  const profiles = /* @__PURE__ */ new Map();
123
+ const discoverySteps = /* @__PURE__ */ new Map();
121
124
  const discoveryFailures = [];
122
125
  if (options._routingProfiles) {
123
126
  for (const [key] of entries) {
@@ -130,6 +133,7 @@ async function discoverAgentRouting(options) {
130
133
  return {
131
134
  clients,
132
135
  profiles,
136
+ discoverySteps,
133
137
  protocolIndex: buildProtocolIndex(profiles),
134
138
  agentMap,
135
139
  discoveryFailures
@@ -139,8 +143,8 @@ async function discoverAgentRouting(options) {
139
143
  entries.map(async ([key, entry]) => {
140
144
  const perAgentOptions = buildAgentOptions(entry, options);
141
145
  try {
142
- const { profile, step } = await getOrDiscoverStoryboardProfile(clients.get(key), perAgentOptions);
143
- return { key, profile, step };
146
+ const { profile, step, evidence } = await getOrDiscoverStoryboardProfile(clients.get(key), perAgentOptions);
147
+ return { key, profile, step, evidence };
144
148
  } catch (err) {
145
149
  return {
146
150
  key,
@@ -148,6 +152,7 @@ async function discoverAgentRouting(options) {
148
152
  step: {
149
153
  step: "Discover agent capabilities",
150
154
  passed: false,
155
+ duration_ms: 0,
151
156
  error: scrubAuthSecrets(err?.message || String(err))
152
157
  }
153
158
  };
@@ -155,6 +160,7 @@ async function discoverAgentRouting(options) {
155
160
  })
156
161
  );
157
162
  for (const r of discoveryResults) {
163
+ discoverySteps.set(r.key, "evidence" in r && r.evidence ? r.evidence : r.step);
158
164
  if (!r.profile || r.step.passed === false) {
159
165
  const rawDetail = scrubAuthSecrets(r.step.error ?? "Discovery returned no profile.");
160
166
  const detail = rawDetail.length > 512 ? `${rawDetail.slice(0, 512)} \u2026(truncated)` : rawDetail;
@@ -162,7 +168,7 @@ async function discoverAgentRouting(options) {
162
168
  const message = resilient ? baseMessage : `${baseMessage}
163
169
 
164
170
  If this is hello-cluster / exploratory CI and you want unrelated storyboards to complete despite this failure, set \`StoryboardRunOptions.discovery_resilient: true\`. Do NOT set it in production \u2014 a topology with a broken tenant is a hard misconfiguration there.`;
165
- const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail);
171
+ const failure = new DiscoveryFailure(message, r.key, agents[r.key].url, detail, { ...r.step, error: detail });
166
172
  if (!resilient) throw failure;
167
173
  discoveryFailures.push(failure);
168
174
  continue;
@@ -172,6 +178,7 @@ If this is hello-cluster / exploratory CI and you want unrelated storyboards to
172
178
  return {
173
179
  clients,
174
180
  profiles,
181
+ discoverySteps,
175
182
  protocolIndex: buildProtocolIndex(profiles),
176
183
  agentMap,
177
184
  discoveryFailures