@adcp/sdk 15.9.0 → 16.0.0-beta.1

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 (295) hide show
  1. package/bin/adcp-identity.js +74 -0
  2. package/bin/adcp.js +2 -0
  3. package/dist/lib/adapters/keyed-account-backend.d.mts +37 -0
  4. package/dist/lib/adapters/keyed-account-backend.d.ts +37 -0
  5. package/dist/lib/adapters/keyed-account-backend.js +121 -0
  6. package/dist/lib/adapters/keyed-account-backend.mjs +94 -0
  7. package/dist/lib/adapters/keyed-account-store.d.mts +28 -0
  8. package/dist/lib/adapters/keyed-account-store.d.ts +28 -0
  9. package/dist/lib/adapters/keyed-account-store.js +227 -0
  10. package/dist/lib/adapters/keyed-account-store.mjs +203 -0
  11. package/dist/lib/core/SingleAgentClient.d.mts +16 -2
  12. package/dist/lib/core/SingleAgentClient.d.ts +16 -2
  13. package/dist/lib/core/SingleAgentClient.js +259 -62
  14. package/dist/lib/core/SingleAgentClient.mjs +261 -57
  15. package/dist/lib/core/TaskExecutor.d.mts +6 -0
  16. package/dist/lib/core/TaskExecutor.d.ts +6 -0
  17. package/dist/lib/core/TaskExecutor.js +66 -5
  18. package/dist/lib/core/TaskExecutor.mjs +71 -5
  19. package/dist/lib/core/postgres-webhook-registration-store.js +32 -5
  20. package/dist/lib/core/postgres-webhook-registration-store.mjs +32 -5
  21. package/dist/lib/core/redis-webhook-registration-store.js +23 -1
  22. package/dist/lib/core/redis-webhook-registration-store.mjs +23 -1
  23. package/dist/lib/core/webhook-registration.d.mts +7 -1
  24. package/dist/lib/core/webhook-registration.d.ts +7 -1
  25. package/dist/lib/core/webhook-registration.js +24 -2
  26. package/dist/lib/core/webhook-registration.mjs +23 -2
  27. package/dist/lib/identity-3.3/index.d.mts +10 -0
  28. package/dist/lib/identity-3.3/index.d.ts +10 -0
  29. package/dist/lib/identity-3.3/index.js +75 -0
  30. package/dist/lib/identity-3.3/index.mjs +46 -0
  31. package/dist/lib/identity-3.3/lifecycle.d.mts +113 -0
  32. package/dist/lib/identity-3.3/lifecycle.d.ts +113 -0
  33. package/dist/lib/identity-3.3/lifecycle.js +267 -0
  34. package/dist/lib/identity-3.3/lifecycle.mjs +240 -0
  35. package/dist/lib/identity-3.3/revocation.d.mts +50 -0
  36. package/dist/lib/identity-3.3/revocation.d.ts +50 -0
  37. package/dist/lib/identity-3.3/revocation.js +238 -0
  38. package/dist/lib/identity-3.3/revocation.mjs +216 -0
  39. package/dist/lib/identity-3.3/schemas.draft.d.mts +2472 -0
  40. package/dist/lib/identity-3.3/schemas.draft.d.ts +2472 -0
  41. package/dist/lib/identity-3.3/schemas.draft.js +1448 -0
  42. package/dist/lib/identity-3.3/schemas.draft.mjs +1428 -0
  43. package/dist/lib/identity-3.3/server.d.mts +34 -0
  44. package/dist/lib/identity-3.3/server.d.ts +34 -0
  45. package/dist/lib/identity-3.3/server.js +219 -0
  46. package/dist/lib/identity-3.3/server.mjs +194 -0
  47. package/dist/lib/identity-3.3/store.d.mts +24 -0
  48. package/dist/lib/identity-3.3/store.d.ts +24 -0
  49. package/dist/lib/identity-3.3/store.js +191 -0
  50. package/dist/lib/identity-3.3/store.mjs +169 -0
  51. package/dist/lib/identity-3.3/trust.d.mts +94 -0
  52. package/dist/lib/identity-3.3/trust.d.ts +94 -0
  53. package/dist/lib/identity-3.3/trust.js +278 -0
  54. package/dist/lib/identity-3.3/trust.mjs +239 -0
  55. package/dist/lib/identity-3.3/types.d.mts +127 -0
  56. package/dist/lib/identity-3.3/types.d.ts +127 -0
  57. package/dist/lib/identity-3.3/types.js +16 -0
  58. package/dist/lib/identity-3.3/types.mjs +0 -0
  59. package/dist/lib/identity-3.3/validation.d.mts +2 -0
  60. package/dist/lib/identity-3.3/validation.d.ts +2 -0
  61. package/dist/lib/identity-3.3/validation.js +125 -0
  62. package/dist/lib/identity-3.3/validation.mjs +91 -0
  63. package/dist/lib/index.d.mts +1 -1
  64. package/dist/lib/index.d.ts +1 -1
  65. package/dist/lib/reporting/azure/index.d.mts +5 -0
  66. package/dist/lib/reporting/azure/index.d.ts +5 -0
  67. package/dist/lib/reporting/azure/index.js +26 -7
  68. package/dist/lib/reporting/azure/index.mjs +26 -7
  69. package/dist/lib/reporting/bigquery/index.d.mts +80 -25
  70. package/dist/lib/reporting/bigquery/index.d.ts +80 -25
  71. package/dist/lib/reporting/bigquery/index.js +184 -81
  72. package/dist/lib/reporting/bigquery/index.mjs +182 -80
  73. package/dist/lib/reporting/gcs/adapter.d.mts +8 -1
  74. package/dist/lib/reporting/gcs/adapter.d.ts +8 -1
  75. package/dist/lib/reporting/gcs/errors.d.mts +6 -0
  76. package/dist/lib/reporting/gcs/errors.d.ts +6 -0
  77. package/dist/lib/reporting/gcs/fence.d.mts +5 -0
  78. package/dist/lib/reporting/gcs/fence.d.ts +5 -0
  79. package/dist/lib/reporting/gcs/index.d.mts +9 -0
  80. package/dist/lib/reporting/gcs/index.d.ts +9 -0
  81. package/dist/lib/reporting/gcs/reader.d.mts +27 -3
  82. package/dist/lib/reporting/gcs/reader.d.ts +27 -3
  83. package/dist/lib/reporting/gcs/row-provider.d.mts +7 -0
  84. package/dist/lib/reporting/gcs/row-provider.d.ts +7 -0
  85. package/dist/lib/reporting/gcs/row-provider.js +34 -14
  86. package/dist/lib/reporting/gcs/row-provider.mjs +34 -14
  87. package/dist/lib/reporting/ledger/change-feed.d.mts +22 -1
  88. package/dist/lib/reporting/ledger/change-feed.d.ts +22 -1
  89. package/dist/lib/reporting/ledger/index.d.mts +11 -0
  90. package/dist/lib/reporting/ledger/index.d.ts +11 -0
  91. package/dist/lib/reporting/ledger/managed-postgres.d.mts +8 -0
  92. package/dist/lib/reporting/ledger/managed-postgres.d.ts +8 -0
  93. package/dist/lib/reporting/ledger/managed-router.d.mts +27 -2
  94. package/dist/lib/reporting/ledger/managed-router.d.ts +27 -2
  95. package/dist/lib/reporting/ledger/managed.d.mts +86 -6
  96. package/dist/lib/reporting/ledger/managed.d.ts +86 -6
  97. package/dist/lib/reporting/ledger/notification-activity.d.mts +65 -3
  98. package/dist/lib/reporting/ledger/notification-activity.d.ts +65 -3
  99. package/dist/lib/reporting/ledger/object-writes.d.mts +64 -5
  100. package/dist/lib/reporting/ledger/object-writes.d.ts +64 -5
  101. package/dist/lib/reporting/ledger/postgres.d.mts +43 -9
  102. package/dist/lib/reporting/ledger/postgres.d.ts +43 -9
  103. package/dist/lib/reporting/ledger/postgres.js +43 -27
  104. package/dist/lib/reporting/ledger/postgres.mjs +43 -27
  105. package/dist/lib/reporting/ledger/row-encoding.d.mts +92 -6
  106. package/dist/lib/reporting/ledger/row-encoding.d.ts +92 -6
  107. package/dist/lib/reporting/ledger/row-encoding.js +8 -4
  108. package/dist/lib/reporting/ledger/row-encoding.mjs +6 -3
  109. package/dist/lib/reporting/ledger/row-storage-errors.d.mts +11 -1
  110. package/dist/lib/reporting/ledger/row-storage-errors.d.ts +11 -1
  111. package/dist/lib/reporting/ledger/row-storage-migration.d.mts +19 -1
  112. package/dist/lib/reporting/ledger/row-storage-migration.d.ts +19 -1
  113. package/dist/lib/reporting/ledger/row-storage-migration.js +133 -18
  114. package/dist/lib/reporting/ledger/row-storage-migration.mjs +133 -18
  115. package/dist/lib/reporting/ledger/row-storage-object.d.mts +103 -12
  116. package/dist/lib/reporting/ledger/row-storage-object.d.ts +103 -12
  117. package/dist/lib/reporting/ledger/row-storage-object.js +106 -31
  118. package/dist/lib/reporting/ledger/row-storage-object.mjs +104 -31
  119. package/dist/lib/reporting/ledger/row-storage.d.mts +87 -20
  120. package/dist/lib/reporting/ledger/row-storage.d.ts +87 -20
  121. package/dist/lib/reporting/ledger/row-storage.js +126 -66
  122. package/dist/lib/reporting/ledger/row-storage.mjs +129 -67
  123. package/dist/lib/reporting/ledger/schedule.d.mts +13 -0
  124. package/dist/lib/reporting/ledger/schedule.d.ts +13 -0
  125. package/dist/lib/reporting/ledger/schedule.js +24 -0
  126. package/dist/lib/reporting/ledger/schedule.mjs +23 -0
  127. package/dist/lib/reporting/ledger/types.d.mts +23 -1
  128. package/dist/lib/reporting/ledger/types.d.ts +23 -1
  129. package/dist/lib/reporting/s3/index.d.mts +5 -0
  130. package/dist/lib/reporting/s3/index.d.ts +5 -0
  131. package/dist/lib/reporting/s3/index.js +37 -14
  132. package/dist/lib/reporting/s3/index.mjs +37 -14
  133. package/dist/lib/reporting/service/index.d.mts +10 -0
  134. package/dist/lib/reporting/service/index.d.ts +10 -0
  135. package/dist/lib/reporting/service/maintenance.d.mts +28 -2
  136. package/dist/lib/reporting/service/maintenance.d.ts +28 -2
  137. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  138. package/dist/lib/server/account-sync-contract.d.mts +14 -0
  139. package/dist/lib/server/account-sync-contract.d.ts +14 -0
  140. package/dist/lib/server/account-sync-contract.js +225 -0
  141. package/dist/lib/server/account-sync-contract.mjs +197 -0
  142. package/dist/lib/server/adcp-server.js +5 -0
  143. package/dist/lib/server/adcp-server.mjs +10 -0
  144. package/dist/lib/server/auth-signature.d.mts +10 -0
  145. package/dist/lib/server/auth-signature.d.ts +10 -0
  146. package/dist/lib/server/auth-signature.js +61 -2
  147. package/dist/lib/server/auth-signature.mjs +65 -2
  148. package/dist/lib/server/auth.d.mts +6 -0
  149. package/dist/lib/server/auth.d.ts +6 -0
  150. package/dist/lib/server/auth.js +6 -0
  151. package/dist/lib/server/auth.mjs +6 -0
  152. package/dist/lib/server/create-adcp-server.d.mts +19 -5
  153. package/dist/lib/server/create-adcp-server.d.ts +19 -5
  154. package/dist/lib/server/create-adcp-server.js +238 -19
  155. package/dist/lib/server/create-adcp-server.mjs +240 -10
  156. package/dist/lib/server/decisioning/account.d.mts +24 -1
  157. package/dist/lib/server/decisioning/account.d.ts +24 -1
  158. package/dist/lib/server/decisioning/index.d.mts +1 -1
  159. package/dist/lib/server/decisioning/index.d.ts +1 -1
  160. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +0 -50
  161. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +0 -50
  162. package/dist/lib/server/decisioning/runtime/from-platform.js +61 -11
  163. package/dist/lib/server/decisioning/runtime/from-platform.mjs +65 -12
  164. package/dist/lib/server/index.d.mts +2 -0
  165. package/dist/lib/server/index.d.ts +2 -0
  166. package/dist/lib/server/index.js +12 -0
  167. package/dist/lib/server/index.mjs +12 -0
  168. package/dist/lib/server/notification-subscriptions/runtime.js +9 -1
  169. package/dist/lib/server/notification-subscriptions/runtime.mjs +9 -1
  170. package/dist/lib/server/notification-subscriptions/types.d.mts +5 -0
  171. package/dist/lib/server/notification-subscriptions/types.d.ts +5 -0
  172. package/dist/lib/server/principal/types.d.mts +1 -1
  173. package/dist/lib/server/principal/types.d.ts +1 -1
  174. package/dist/lib/server/serve.js +5 -0
  175. package/dist/lib/server/serve.mjs +5 -0
  176. package/dist/lib/server/webhook-delivery/recovery.d.mts +1 -0
  177. package/dist/lib/server/webhook-delivery/recovery.d.ts +1 -0
  178. package/dist/lib/server/webhook-delivery/recovery.js +4 -0
  179. package/dist/lib/server/webhook-delivery/recovery.mjs +4 -0
  180. package/dist/lib/server/webhook-emitter.d.mts +10 -0
  181. package/dist/lib/server/webhook-emitter.d.ts +10 -0
  182. package/dist/lib/server/webhook-emitter.js +22 -0
  183. package/dist/lib/server/webhook-emitter.mjs +22 -0
  184. package/dist/lib/signing/agent-context.d.mts +0 -5
  185. package/dist/lib/signing/agent-context.d.ts +0 -5
  186. package/dist/lib/signing/agent-context.js +9 -1
  187. package/dist/lib/signing/agent-context.mjs +9 -1
  188. package/dist/lib/signing/agent-fetch.js +27 -2
  189. package/dist/lib/signing/agent-fetch.mjs +32 -2
  190. package/dist/lib/signing/agent-resolver/canonicalize.d.mts +10 -15
  191. package/dist/lib/signing/agent-resolver/canonicalize.d.ts +10 -15
  192. package/dist/lib/signing/agent-resolver/canonicalize.js +17 -5
  193. package/dist/lib/signing/agent-resolver/canonicalize.mjs +16 -5
  194. package/dist/lib/signing/agent-resolver/index.d.mts +1 -0
  195. package/dist/lib/signing/agent-resolver/index.d.ts +1 -0
  196. package/dist/lib/signing/agent-resolver/index.js +5 -0
  197. package/dist/lib/signing/agent-resolver/index.mjs +3 -0
  198. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +3 -2
  199. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +3 -2
  200. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +30 -3
  201. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +30 -3
  202. package/dist/lib/signing/agent-resolver/strict-json.d.mts +2 -2
  203. package/dist/lib/signing/agent-resolver/strict-json.d.ts +2 -2
  204. package/dist/lib/signing/agent-resolver/strict-json.js +5 -3
  205. package/dist/lib/signing/agent-resolver/strict-json.mjs +5 -3
  206. package/dist/lib/signing/brand-jwks.d.mts +2 -2
  207. package/dist/lib/signing/brand-jwks.d.ts +2 -2
  208. package/dist/lib/signing/brand-jwks.js +4 -4
  209. package/dist/lib/signing/brand-jwks.mjs +4 -4
  210. package/dist/lib/signing/client.d.mts +1 -0
  211. package/dist/lib/signing/client.d.ts +1 -0
  212. package/dist/lib/signing/client.js +5 -0
  213. package/dist/lib/signing/client.mjs +3 -0
  214. package/dist/lib/signing/jwks-https.d.mts +1 -1
  215. package/dist/lib/signing/jwks-https.d.ts +1 -1
  216. package/dist/lib/signing/jwks-https.js +1 -1
  217. package/dist/lib/signing/jwks-https.mjs +1 -1
  218. package/dist/lib/signing/jwks.d.mts +11 -3
  219. package/dist/lib/signing/jwks.d.ts +11 -3
  220. package/dist/lib/signing/jwks.js +1 -1
  221. package/dist/lib/signing/jwks.mjs +1 -1
  222. package/dist/lib/signing/parser.d.mts +1 -1
  223. package/dist/lib/signing/parser.d.ts +1 -1
  224. package/dist/lib/signing/parser.js +5 -3
  225. package/dist/lib/signing/parser.mjs +6 -4
  226. package/dist/lib/signing/revocation.d.mts +4 -1
  227. package/dist/lib/signing/revocation.d.ts +4 -1
  228. package/dist/lib/signing/revocation.js +33 -3
  229. package/dist/lib/signing/revocation.mjs +31 -2
  230. package/dist/lib/signing/server.d.mts +1 -1
  231. package/dist/lib/signing/server.d.ts +1 -1
  232. package/dist/lib/signing/server.js +4 -0
  233. package/dist/lib/signing/server.mjs +4 -0
  234. package/dist/lib/signing/types.d.mts +3 -0
  235. package/dist/lib/signing/types.d.ts +3 -0
  236. package/dist/lib/signing/web-bot-auth.d.mts +117 -0
  237. package/dist/lib/signing/web-bot-auth.d.ts +117 -0
  238. package/dist/lib/signing/web-bot-auth.js +660 -0
  239. package/dist/lib/signing/web-bot-auth.mjs +624 -0
  240. package/dist/lib/testing/client.d.mts +1 -4
  241. package/dist/lib/testing/client.d.ts +1 -4
  242. package/dist/lib/testing/client.js +141 -20
  243. package/dist/lib/testing/client.mjs +137 -19
  244. package/dist/lib/testing/compliance/comply.js +29 -10
  245. package/dist/lib/testing/compliance/comply.mjs +37 -11
  246. package/dist/lib/testing/storyboard/account-sync-contract.d.mts +3 -0
  247. package/dist/lib/testing/storyboard/account-sync-contract.d.ts +3 -0
  248. package/dist/lib/testing/storyboard/account-sync-contract.js +79 -0
  249. package/dist/lib/testing/storyboard/account-sync-contract.mjs +55 -0
  250. package/dist/lib/testing/storyboard/default-invariants.js +2 -0
  251. package/dist/lib/testing/storyboard/default-invariants.mjs +2 -0
  252. package/dist/lib/testing/storyboard/runner.js +23 -8
  253. package/dist/lib/testing/storyboard/runner.mjs +24 -8
  254. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  255. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  256. package/dist/lib/types/adcp.d.mts +4 -0
  257. package/dist/lib/types/adcp.d.ts +4 -0
  258. package/dist/lib/types/schemas.generated.d.ts +6 -6
  259. package/dist/lib/utils/capabilities.d.mts +1 -0
  260. package/dist/lib/utils/capabilities.d.ts +1 -0
  261. package/dist/lib/utils/capabilities.js +5 -0
  262. package/dist/lib/utils/capabilities.mjs +5 -0
  263. package/dist/lib/v2/projection/creative-delivery.d.mts +3 -1
  264. package/dist/lib/v2/projection/creative-delivery.d.ts +3 -1
  265. package/dist/lib/v2/projection/creative-delivery.js +26 -10
  266. package/dist/lib/v2/projection/creative-delivery.mjs +26 -10
  267. package/dist/lib/v2/projection/index.d.mts +1 -1
  268. package/dist/lib/v2/projection/index.d.ts +1 -1
  269. package/dist/lib/v2/projection/legacy-routes.d.mts +24 -2
  270. package/dist/lib/v2/projection/legacy-routes.d.ts +24 -2
  271. package/dist/lib/v2/projection/legacy-routes.js +28 -2
  272. package/dist/lib/v2/projection/legacy-routes.mjs +26 -2
  273. package/dist/lib/validation/schema-loader.d.mts +2 -0
  274. package/dist/lib/validation/schema-loader.d.ts +2 -0
  275. package/dist/lib/validation/schema-loader.js +43 -4
  276. package/dist/lib/validation/schema-loader.mjs +39 -3
  277. package/dist/lib/version.d.mts +3 -3
  278. package/dist/lib/version.d.ts +3 -3
  279. package/dist/lib/version.js +3 -3
  280. package/dist/lib/version.mjs +3 -3
  281. package/docs/TYPE-SUMMARY.md +2 -2
  282. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +4 -0
  283. package/docs/guides/REPORTING-LEDGER-CUTOVER.md +1 -1
  284. package/docs/guides/REPORTING-LEDGER.md +132 -46
  285. package/docs/guides/REPORTING-OPERATIONS.md +25 -4
  286. package/docs/guides/REPORTING-STABILITY.md +76 -0
  287. package/docs/guides/account-resolution.md +101 -0
  288. package/docs/llms.txt +3 -2
  289. package/docs/migration-12-to-13.md +7 -0
  290. package/docs/migration-14.x-rc-worksheet.md +4 -4
  291. package/docs/migration-agent-identity-3.3.md +355 -0
  292. package/docs/migration-agent-resolution-3.3.md +5 -0
  293. package/docs/migration-reporting-row-storage-alignment.md +137 -0
  294. package/examples/storyboards/account-sync-contract.yaml +57 -0
  295. package/package.json +15 -1
@@ -28,14 +28,17 @@ __export(client_exports, {
28
28
  getOrCreateClient: () => getOrCreateClient,
29
29
  getOrCreateClientResolution: () => getOrCreateClientResolution,
30
30
  getOrDiscoverProfile: () => getOrDiscoverProfile,
31
+ hasTestClientScope: () => hasTestClientScope,
31
32
  resolveAccount: () => resolveAccount,
32
33
  resolveAuthPrincipal: () => resolveAuthPrincipal,
33
34
  resolveBrand: () => resolveBrand,
34
35
  runStep: () => runStep,
36
+ seedAuthRejectedTestClientProfile: () => seedAuthRejectedTestClientProfile,
35
37
  seedTestClientSigningCapability: () => seedTestClientSigningCapability,
36
38
  setAgentTesterLogger: () => setAgentTesterLogger,
37
39
  testClientWireAdcpVersion: () => testClientWireAdcpVersion,
38
- validateResponseSchema: () => validateResponseSchema
40
+ validateResponseSchema: () => validateResponseSchema,
41
+ withTestClientScope: () => withTestClientScope
39
42
  });
40
43
  module.exports = __toCommonJS(client_exports);
41
44
  var import_ADCPMultiAgentClient = require('../core/ADCPMultiAgentClient.js');
@@ -48,13 +51,36 @@ var import_capabilities = require('../utils/capabilities.js');
48
51
  var import_probe_policy = require('../utils/probe-policy.js');
49
52
  var import_ssrf_fetch = require('../net/ssrf-fetch.js');
50
53
  var import_version = require('../version.js');
54
+ var import_protocols = require('../protocols/index.js');
51
55
  var import_node_crypto = require("node:crypto");
56
+ var import_node_async_hooks = require("node:async_hooks");
52
57
  var import_client_hooks = require('../validation/client-hooks.js');
53
58
  var import_error_extraction = require('../utils/error-extraction.js');
54
59
  var import_client = require('../signing/client.js');
55
60
  var import_storage_registry = require('../auth/oauth/storage-registry.js');
56
61
  const TEST_CLIENT_VERSION_OPTIONS = /* @__PURE__ */ Symbol("adcp.testClientVersionOptions");
57
62
  const TEST_CLIENT_SCOPE_SALT = (0, import_node_crypto.randomBytes)(32);
63
+ const testClientScope = new import_node_async_hooks.AsyncLocalStorage();
64
+ async function withTestClientScope(fn) {
65
+ const scope = {
66
+ clients: [],
67
+ profiles: /* @__PURE__ */ new WeakMap(),
68
+ profileScopes: /* @__PURE__ */ new WeakMap(),
69
+ authRejectedProfiles: /* @__PURE__ */ new WeakSet(),
70
+ active: true
71
+ };
72
+ return testClientScope.run(scope, async () => {
73
+ try {
74
+ return await fn();
75
+ } finally {
76
+ scope.active = false;
77
+ scope.clients.length = 0;
78
+ }
79
+ });
80
+ }
81
+ function hasTestClientScope() {
82
+ return testClientScope.getStore()?.active === true;
83
+ }
58
84
  function resolveAuthPrincipal(options) {
59
85
  if (!options.auth) return void 0;
60
86
  switch (options.auth.type) {
@@ -95,6 +121,7 @@ function getLogger() {
95
121
  }
96
122
  function createTestClient(agentUrl, protocol = "mcp", options = {}) {
97
123
  options = withTestKitAuthDefaults(options);
124
+ const transport = (0, import_protocols.normalizeTransportOptions)(options.transport);
98
125
  const policy = (0, import_probe_policy.classifyProbeUrl)(agentUrl);
99
126
  if (!policy.allowed) {
100
127
  const hostname = new URL(agentUrl).hostname.replace(/^\[|\]$/g, "");
@@ -115,11 +142,20 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
115
142
  protocol
116
143
  };
117
144
  if (options.headers && Object.keys(options.headers).length > 0) {
118
- agentConfig.headers = { ...options.headers };
145
+ agentConfig.headers = normalizeTestClientHeaders(options.headers);
146
+ for (const name of ["Authorization", "User-Agent", "Content-Type"]) {
147
+ const lower = name.toLowerCase();
148
+ const value = agentConfig.headers[lower];
149
+ if (value !== void 0) {
150
+ delete agentConfig.headers[lower];
151
+ agentConfig.headers[name] = value;
152
+ }
153
+ }
119
154
  }
120
155
  if (options.auth) {
121
156
  if (options.auth.type === "basic") {
122
157
  const encoded = Buffer.from(`${options.auth.username}:${options.auth.password}`).toString("base64");
158
+ if (agentConfig.headers) delete agentConfig.headers.authorization;
123
159
  agentConfig.headers = { ...agentConfig.headers, Authorization: `Basic ${encoded}` };
124
160
  } else if (options.auth.type === "oauth") {
125
161
  agentConfig.oauth_tokens = options.auth.tokens;
@@ -135,6 +171,7 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
135
171
  if (options.functional_request_signing) {
136
172
  agentConfig.request_signing = options.functional_request_signing;
137
173
  }
174
+ const scope = testClientScope.getStore();
138
175
  const multiClient = new import_ADCPMultiAgentClient.ADCPMultiAgentClient([agentConfig], {
139
176
  headers,
140
177
  validation: {
@@ -145,7 +182,10 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
145
182
  ...options.wireAdcpVersion !== void 0 && { wireAdcpVersion: options.wireAdcpVersion },
146
183
  ...options.versionEnvelope !== void 0 && { versionEnvelope: options.versionEnvelope },
147
184
  ...options.userAgent && { userAgent: options.userAgent },
148
- ...options.transport && { transport: options.transport }
185
+ ...transport && { transport },
186
+ ...scope?.active && {
187
+ _reuseConfiguredDiscovery: () => scope.active && testClientScope.getStore() === scope
188
+ }
149
189
  });
150
190
  const client = multiClient.agent("test");
151
191
  const authMode = authReuseMode(options);
@@ -163,20 +203,21 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
163
203
  ...requestScopeMode !== void 0 && { requestScopeMode },
164
204
  ...requestSigningMode !== void 0 && { requestSigningMode },
165
205
  ...options.auth?.type === "oauth" && options.auth.storage && { oauthStorage: options.auth.storage },
166
- ...options.transport?.trustedFetchFn && { fetchFn: options.transport.trustedFetchFn },
167
- ...options.transport?.allowPrivateIp !== void 0 && { allowPrivateIp: options.transport.allowPrivateIp },
168
- ...options.transport?.maxResponseBytes !== void 0 && {
169
- maxResponseBytes: options.transport.maxResponseBytes
206
+ ...transport?.trustedFetchFn && { fetchFn: transport.trustedFetchFn },
207
+ ...transport?.allowPrivateIp !== void 0 && { allowPrivateIp: transport.allowPrivateIp },
208
+ ...transport?.maxResponseBytes !== void 0 && {
209
+ maxResponseBytes: transport.maxResponseBytes
170
210
  },
171
- ...options.transport?.requestTimeoutMs !== void 0 && {
172
- requestTimeoutMs: options.transport.requestTimeoutMs
211
+ ...transport?.requestTimeoutMs !== void 0 && {
212
+ requestTimeoutMs: transport.requestTimeoutMs
173
213
  },
174
- ...options.transport?.legacyCompat?.enabled !== void 0 && {
175
- legacyCompatEnabled: options.transport.legacyCompat.enabled
214
+ ...transport?.legacyCompat?.enabled !== void 0 && {
215
+ legacyCompatEnabled: transport.legacyCompat.enabled
176
216
  }
177
217
  },
178
218
  enumerable: false
179
219
  });
220
+ if (hasTestClientScope()) testClientScope.getStore().clients.push(client);
180
221
  return client;
181
222
  }
182
223
  function getOrCreateClient(agentUrl, options) {
@@ -187,6 +228,8 @@ function getOrCreateClientResolution(agentUrl, options) {
187
228
  if (shared && isExecutableTestClient(shared) && testClientMatchesVersionOptions(shared, agentUrl, options)) {
188
229
  return { client: shared, reusedShared: true };
189
230
  }
231
+ const pooled = testClientScope.getStore()?.clients.find((client) => testClientMatchesVersionOptions(client, agentUrl, options));
232
+ if (pooled) return { client: pooled, reusedShared: true };
190
233
  return { client: createTestClient(agentUrl, options.protocol || "mcp", options), reusedShared: false };
191
234
  }
192
235
  function isExecutableTestClient(client) {
@@ -197,6 +240,7 @@ function isExecutableTestClient(client) {
197
240
  }
198
241
  function testClientMatchesVersionOptions(client, agentUrl, options) {
199
242
  const effectiveOptions = withTestKitAuthDefaults(options);
243
+ const expectedTransport = (0, import_protocols.normalizeTransportOptions)(effectiveOptions.transport);
200
244
  const meta = client[TEST_CLIENT_VERSION_OPTIONS];
201
245
  const expectedAuthMode = authReuseMode(effectiveOptions);
202
246
  const expectedRequestScopeMode = requestScopeReuseMode(effectiveOptions);
@@ -208,7 +252,7 @@ function testClientMatchesVersionOptions(client, agentUrl, options) {
208
252
  const expectedAdcpVersion = effectiveOptions.adcpVersion ?? import_version.ADCP_VERSION;
209
253
  const expectedWireAdcpVersion = effectiveOptions.wireAdcpVersion;
210
254
  const expectedVersionEnvelope = effectiveOptions.versionEnvelope ?? "auto";
211
- return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.oauthStorage === expectedOAuthStorage && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.allowPrivateIp === effectiveOptions.transport?.allowPrivateIp && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs && meta.legacyCompatEnabled === effectiveOptions.transport?.legacyCompat?.enabled;
255
+ return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.oauthStorage === expectedOAuthStorage && meta.fetchFn === expectedTransport?.trustedFetchFn && meta.allowPrivateIp === expectedTransport?.allowPrivateIp && meta.maxResponseBytes === expectedTransport?.maxResponseBytes && meta.requestTimeoutMs === expectedTransport?.requestTimeoutMs && meta.legacyCompatEnabled === expectedTransport?.legacyCompat?.enabled;
212
256
  }
213
257
  function withTestKitAuthDefaults(options) {
214
258
  if (options.auth) return options;
@@ -239,9 +283,16 @@ function withTestKitAuthDefaults(options) {
239
283
  function authReuseMode(options) {
240
284
  return options.auth?.type;
241
285
  }
286
+ function normalizeTestClientHeaders(headers) {
287
+ const normalized = {};
288
+ new Headers(headers).forEach((value, name) => {
289
+ normalized[name] = value;
290
+ });
291
+ return normalized;
292
+ }
242
293
  function requestScopeReuseMode(options) {
243
294
  const headers = options.headers ? Object.fromEntries(
244
- Object.entries(options.headers).map(([name, value]) => [name.toLowerCase(), value]).sort(([a], [b]) => a.localeCompare(b))
295
+ Object.entries(normalizeTestClientHeaders(options.headers)).sort(([a], [b]) => a.localeCompare(b))
245
296
  ) : void 0;
246
297
  if (!options.auth && !headers && !options.test_session_id && !options.userAgent) return void 0;
247
298
  const auth = options.auth?.type === "oauth" ? { ...options.auth, storage: void 0 } : options.auth;
@@ -264,11 +315,13 @@ function requestSigningReuseMode(config) {
264
315
  algorithm: config.provider.algorithm,
265
316
  keyid: config.provider.keyid,
266
317
  adcpUse: config.provider.adcpUse,
267
- fingerprint: config.provider.fingerprint
318
+ fingerprint: config.provider.fingerprint,
319
+ publicKey: config.public_key
268
320
  } : { algorithm: config.alg, keyid: config.kid, privateKey: config.private_key };
269
321
  const fingerprint = (0, import_node_crypto.createHmac)("sha256", "").update(
270
322
  JSON.stringify({
271
323
  identity,
324
+ profile: config.profile ?? "rfc9421",
272
325
  agentUrl: config.agent_url,
273
326
  jwksUri: config.jwks_uri,
274
327
  signSupported: config.sign_supported === true,
@@ -277,17 +330,79 @@ function requestSigningReuseMode(config) {
277
330
  ).digest("hex").slice(0, 16);
278
331
  return `${kind}:${fingerprint}`;
279
332
  }
280
- async function getOrDiscoverProfile(client, options) {
281
- if (options._profile) {
282
- seedTestClientSigningCapability(client, options._profile, options.adcpVersion);
333
+ async function getOrDiscoverProfile(client, options, schemaAdcpVersion) {
334
+ const scope = testClientScope.getStore();
335
+ const profileBinding = options._profile ? scope?.profileScopes.get(client)?.get(options._profile) : void 0;
336
+ schemaAdcpVersion ??= profileBinding?.schemaAdcpVersion ?? options.adcpVersion;
337
+ options.signal?.throwIfAborted();
338
+ const scopeKey = scope?.active ? client.getCapabilityEvidenceScope().scopeKey : void 0;
339
+ if (options._profile && (!scope?.active || scope.authRejectedProfiles.has(options._profile) || !options._profile.capabilities_probe_error && options._client === client && profileBinding?.scopeKey === scopeKey)) {
340
+ seedTestClientSigningCapability(client, options._profile, schemaAdcpVersion);
283
341
  return {
284
342
  profile: options._profile,
285
343
  step: { step: "Discover agent capabilities", passed: true, duration_ms: 0 }
286
344
  };
287
345
  }
288
- return discoverAgentProfile(client, options.signal, options.adcpVersion);
346
+ if (!scope?.active) return discoverAgentProfile(client, options.signal, schemaAdcpVersion);
347
+ const key = `${scopeKey}:${schemaAdcpVersion ?? client.getAdcpVersion()}`;
348
+ let profiles = scope.profiles.get(client);
349
+ if (!profiles) {
350
+ profiles = /* @__PURE__ */ new Map();
351
+ scope.profiles.set(client, profiles);
352
+ }
353
+ let discovery = profiles.get(key);
354
+ if (discovery?.failed && discovery.pass !== options._discoveryPass) {
355
+ profiles.delete(key);
356
+ discovery = void 0;
357
+ }
358
+ if (!discovery) {
359
+ const evict = () => {
360
+ if (profiles.get(key) === discovery) profiles.delete(key);
361
+ };
362
+ const promise = discoverAgentProfile(client, options.signal, schemaAdcpVersion).then(
363
+ (result) => {
364
+ if (options.signal?.aborted) {
365
+ evict();
366
+ } else if (!result.step.passed || result.profile.capabilities_probe_error) {
367
+ if (options._discoveryPass && discovery) discovery.failed = true;
368
+ else evict();
369
+ }
370
+ return result;
371
+ },
372
+ (error) => {
373
+ evict();
374
+ throw error;
375
+ }
376
+ );
377
+ discovery = { promise, signal: options.signal, pass: options._discoveryPass };
378
+ profiles.set(key, discovery);
379
+ }
380
+ try {
381
+ const result = await raceWithSignal(discovery.promise, options.signal);
382
+ if (!discovery.signal?.aborted || options.signal?.aborted) return result;
383
+ } catch (error) {
384
+ if (!discovery.signal?.aborted || options.signal?.aborted) throw error;
385
+ }
386
+ if (profiles.get(key) === discovery) profiles.delete(key);
387
+ return getOrDiscoverProfile(client, options, schemaAdcpVersion);
388
+ }
389
+ function seedAuthRejectedTestClientProfile(client, profile, adcpVersion) {
390
+ const scope = testClientScope.getStore();
391
+ if (scope?.active && profile.tools.length === 0 && profile.raw_capabilities === void 0) {
392
+ scope.authRejectedProfiles.add(profile);
393
+ }
394
+ seedTestClientSigningCapability(client, profile, adcpVersion);
289
395
  }
290
396
  function seedTestClientSigningCapability(client, profile, adcpVersion) {
397
+ const scope = testClientScope.getStore();
398
+ if (scope?.active) {
399
+ let profiles = scope.profileScopes.get(client);
400
+ if (!profiles) {
401
+ profiles = /* @__PURE__ */ new WeakMap();
402
+ scope.profileScopes.set(client, profiles);
403
+ }
404
+ profiles.set(profile, { scopeKey: client.getCapabilityEvidenceScope().scopeKey, schemaAdcpVersion: adcpVersion });
405
+ }
291
406
  const raw = profile.raw_capabilities;
292
407
  if (!raw || typeof raw !== "object") return;
293
408
  const clientAccess = client;
@@ -379,6 +494,7 @@ function describeVersionUnsupported(result, requestedVersion) {
379
494
  return `VERSION_UNSUPPORTED: ${requestedText}${supportedText}`;
380
495
  }
381
496
  async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
497
+ const scopeKey = hasTestClientScope() ? client.getCapabilityEvidenceScope().scopeKey : void 0;
382
498
  const {
383
499
  result: agentInfo,
384
500
  step,
@@ -448,7 +564,9 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
448
564
  profile.capabilities_probe_error = err?.message || String(err);
449
565
  }
450
566
  }
451
- seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
567
+ if (scopeKey === void 0 || scopeKey === client.getCapabilityEvidenceScope().scopeKey) {
568
+ seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
569
+ }
452
570
  return { profile, step, ...caughtError !== void 0 && { caughtError } };
453
571
  }
454
572
  async function discoverAgentCapabilities(client, profile, options) {
@@ -759,12 +877,15 @@ function zodCodeToKeyword(code) {
759
877
  getOrCreateClient,
760
878
  getOrCreateClientResolution,
761
879
  getOrDiscoverProfile,
880
+ hasTestClientScope,
762
881
  resolveAccount,
763
882
  resolveAuthPrincipal,
764
883
  resolveBrand,
765
884
  runStep,
885
+ seedAuthRejectedTestClientProfile,
766
886
  seedTestClientSigningCapability,
767
887
  setAgentTesterLogger,
768
888
  testClientWireAdcpVersion,
769
- validateResponseSchema
889
+ validateResponseSchema,
890
+ withTestClientScope
770
891
  });
@@ -8,13 +8,36 @@ import { parseCapabilitiesResponse } from "../utils/capabilities.mjs";
8
8
  import { classifyProbeUrl } from "../utils/probe-policy.mjs";
9
9
  import { SsrfRefusedError } from "../net/ssrf-fetch.mjs";
10
10
  import { ADCP_VERSION, toReleasePrecisionVersion } from "../version.mjs";
11
+ import { normalizeTransportOptions } from "../protocols/index.mjs";
11
12
  import { createHmac, hkdfSync, randomBytes } from "node:crypto";
13
+ import { AsyncLocalStorage } from "node:async_hooks";
12
14
  import { validateIncomingResponse } from "../validation/client-hooks.mjs";
13
15
  import { extractVersionUnsupportedDetails } from "../utils/error-extraction.mjs";
14
16
  import { buildAgentSigningContext } from "../signing/client.mjs";
15
17
  import { bindAgentStorage } from "../auth/oauth/storage-registry.mjs";
16
18
  const TEST_CLIENT_VERSION_OPTIONS = /* @__PURE__ */ Symbol("adcp.testClientVersionOptions");
17
19
  const TEST_CLIENT_SCOPE_SALT = randomBytes(32);
20
+ const testClientScope = new AsyncLocalStorage();
21
+ async function withTestClientScope(fn) {
22
+ const scope = {
23
+ clients: [],
24
+ profiles: /* @__PURE__ */ new WeakMap(),
25
+ profileScopes: /* @__PURE__ */ new WeakMap(),
26
+ authRejectedProfiles: /* @__PURE__ */ new WeakSet(),
27
+ active: true
28
+ };
29
+ return testClientScope.run(scope, async () => {
30
+ try {
31
+ return await fn();
32
+ } finally {
33
+ scope.active = false;
34
+ scope.clients.length = 0;
35
+ }
36
+ });
37
+ }
38
+ function hasTestClientScope() {
39
+ return testClientScope.getStore()?.active === true;
40
+ }
18
41
  function resolveAuthPrincipal(options) {
19
42
  if (!options.auth) return void 0;
20
43
  switch (options.auth.type) {
@@ -55,6 +78,7 @@ function getLogger() {
55
78
  }
56
79
  function createTestClient(agentUrl, protocol = "mcp", options = {}) {
57
80
  options = withTestKitAuthDefaults(options);
81
+ const transport = normalizeTransportOptions(options.transport);
58
82
  const policy = classifyProbeUrl(agentUrl);
59
83
  if (!policy.allowed) {
60
84
  const hostname = new URL(agentUrl).hostname.replace(/^\[|\]$/g, "");
@@ -75,11 +99,20 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
75
99
  protocol
76
100
  };
77
101
  if (options.headers && Object.keys(options.headers).length > 0) {
78
- agentConfig.headers = { ...options.headers };
102
+ agentConfig.headers = normalizeTestClientHeaders(options.headers);
103
+ for (const name of ["Authorization", "User-Agent", "Content-Type"]) {
104
+ const lower = name.toLowerCase();
105
+ const value = agentConfig.headers[lower];
106
+ if (value !== void 0) {
107
+ delete agentConfig.headers[lower];
108
+ agentConfig.headers[name] = value;
109
+ }
110
+ }
79
111
  }
80
112
  if (options.auth) {
81
113
  if (options.auth.type === "basic") {
82
114
  const encoded = Buffer.from(`${options.auth.username}:${options.auth.password}`).toString("base64");
115
+ if (agentConfig.headers) delete agentConfig.headers.authorization;
83
116
  agentConfig.headers = { ...agentConfig.headers, Authorization: `Basic ${encoded}` };
84
117
  } else if (options.auth.type === "oauth") {
85
118
  agentConfig.oauth_tokens = options.auth.tokens;
@@ -95,6 +128,7 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
95
128
  if (options.functional_request_signing) {
96
129
  agentConfig.request_signing = options.functional_request_signing;
97
130
  }
131
+ const scope = testClientScope.getStore();
98
132
  const multiClient = new ADCPMultiAgentClient([agentConfig], {
99
133
  headers,
100
134
  validation: {
@@ -105,7 +139,10 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
105
139
  ...options.wireAdcpVersion !== void 0 && { wireAdcpVersion: options.wireAdcpVersion },
106
140
  ...options.versionEnvelope !== void 0 && { versionEnvelope: options.versionEnvelope },
107
141
  ...options.userAgent && { userAgent: options.userAgent },
108
- ...options.transport && { transport: options.transport }
142
+ ...transport && { transport },
143
+ ...scope?.active && {
144
+ _reuseConfiguredDiscovery: () => scope.active && testClientScope.getStore() === scope
145
+ }
109
146
  });
110
147
  const client = multiClient.agent("test");
111
148
  const authMode = authReuseMode(options);
@@ -123,20 +160,21 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
123
160
  ...requestScopeMode !== void 0 && { requestScopeMode },
124
161
  ...requestSigningMode !== void 0 && { requestSigningMode },
125
162
  ...options.auth?.type === "oauth" && options.auth.storage && { oauthStorage: options.auth.storage },
126
- ...options.transport?.trustedFetchFn && { fetchFn: options.transport.trustedFetchFn },
127
- ...options.transport?.allowPrivateIp !== void 0 && { allowPrivateIp: options.transport.allowPrivateIp },
128
- ...options.transport?.maxResponseBytes !== void 0 && {
129
- maxResponseBytes: options.transport.maxResponseBytes
163
+ ...transport?.trustedFetchFn && { fetchFn: transport.trustedFetchFn },
164
+ ...transport?.allowPrivateIp !== void 0 && { allowPrivateIp: transport.allowPrivateIp },
165
+ ...transport?.maxResponseBytes !== void 0 && {
166
+ maxResponseBytes: transport.maxResponseBytes
130
167
  },
131
- ...options.transport?.requestTimeoutMs !== void 0 && {
132
- requestTimeoutMs: options.transport.requestTimeoutMs
168
+ ...transport?.requestTimeoutMs !== void 0 && {
169
+ requestTimeoutMs: transport.requestTimeoutMs
133
170
  },
134
- ...options.transport?.legacyCompat?.enabled !== void 0 && {
135
- legacyCompatEnabled: options.transport.legacyCompat.enabled
171
+ ...transport?.legacyCompat?.enabled !== void 0 && {
172
+ legacyCompatEnabled: transport.legacyCompat.enabled
136
173
  }
137
174
  },
138
175
  enumerable: false
139
176
  });
177
+ if (hasTestClientScope()) testClientScope.getStore().clients.push(client);
140
178
  return client;
141
179
  }
142
180
  function getOrCreateClient(agentUrl, options) {
@@ -147,6 +185,8 @@ function getOrCreateClientResolution(agentUrl, options) {
147
185
  if (shared && isExecutableTestClient(shared) && testClientMatchesVersionOptions(shared, agentUrl, options)) {
148
186
  return { client: shared, reusedShared: true };
149
187
  }
188
+ const pooled = testClientScope.getStore()?.clients.find((client) => testClientMatchesVersionOptions(client, agentUrl, options));
189
+ if (pooled) return { client: pooled, reusedShared: true };
150
190
  return { client: createTestClient(agentUrl, options.protocol || "mcp", options), reusedShared: false };
151
191
  }
152
192
  function isExecutableTestClient(client) {
@@ -157,6 +197,7 @@ function isExecutableTestClient(client) {
157
197
  }
158
198
  function testClientMatchesVersionOptions(client, agentUrl, options) {
159
199
  const effectiveOptions = withTestKitAuthDefaults(options);
200
+ const expectedTransport = normalizeTransportOptions(effectiveOptions.transport);
160
201
  const meta = client[TEST_CLIENT_VERSION_OPTIONS];
161
202
  const expectedAuthMode = authReuseMode(effectiveOptions);
162
203
  const expectedRequestScopeMode = requestScopeReuseMode(effectiveOptions);
@@ -168,7 +209,7 @@ function testClientMatchesVersionOptions(client, agentUrl, options) {
168
209
  const expectedAdcpVersion = effectiveOptions.adcpVersion ?? ADCP_VERSION;
169
210
  const expectedWireAdcpVersion = effectiveOptions.wireAdcpVersion;
170
211
  const expectedVersionEnvelope = effectiveOptions.versionEnvelope ?? "auto";
171
- return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.oauthStorage === expectedOAuthStorage && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.allowPrivateIp === effectiveOptions.transport?.allowPrivateIp && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs && meta.legacyCompatEnabled === effectiveOptions.transport?.legacyCompat?.enabled;
212
+ return meta.agentUrl === agentUrl && meta.protocol === (effectiveOptions.protocol ?? "mcp") && meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.requestScopeMode === expectedRequestScopeMode && meta.requestSigningMode === expectedRequestSigningMode && meta.oauthStorage === expectedOAuthStorage && meta.fetchFn === expectedTransport?.trustedFetchFn && meta.allowPrivateIp === expectedTransport?.allowPrivateIp && meta.maxResponseBytes === expectedTransport?.maxResponseBytes && meta.requestTimeoutMs === expectedTransport?.requestTimeoutMs && meta.legacyCompatEnabled === expectedTransport?.legacyCompat?.enabled;
172
213
  }
173
214
  function withTestKitAuthDefaults(options) {
174
215
  if (options.auth) return options;
@@ -199,9 +240,16 @@ function withTestKitAuthDefaults(options) {
199
240
  function authReuseMode(options) {
200
241
  return options.auth?.type;
201
242
  }
243
+ function normalizeTestClientHeaders(headers) {
244
+ const normalized = {};
245
+ new Headers(headers).forEach((value, name) => {
246
+ normalized[name] = value;
247
+ });
248
+ return normalized;
249
+ }
202
250
  function requestScopeReuseMode(options) {
203
251
  const headers = options.headers ? Object.fromEntries(
204
- Object.entries(options.headers).map(([name, value]) => [name.toLowerCase(), value]).sort(([a], [b]) => a.localeCompare(b))
252
+ Object.entries(normalizeTestClientHeaders(options.headers)).sort(([a], [b]) => a.localeCompare(b))
205
253
  ) : void 0;
206
254
  if (!options.auth && !headers && !options.test_session_id && !options.userAgent) return void 0;
207
255
  const auth = options.auth?.type === "oauth" ? { ...options.auth, storage: void 0 } : options.auth;
@@ -224,11 +272,13 @@ function requestSigningReuseMode(config) {
224
272
  algorithm: config.provider.algorithm,
225
273
  keyid: config.provider.keyid,
226
274
  adcpUse: config.provider.adcpUse,
227
- fingerprint: config.provider.fingerprint
275
+ fingerprint: config.provider.fingerprint,
276
+ publicKey: config.public_key
228
277
  } : { algorithm: config.alg, keyid: config.kid, privateKey: config.private_key };
229
278
  const fingerprint = createHmac("sha256", "").update(
230
279
  JSON.stringify({
231
280
  identity,
281
+ profile: config.profile ?? "rfc9421",
232
282
  agentUrl: config.agent_url,
233
283
  jwksUri: config.jwks_uri,
234
284
  signSupported: config.sign_supported === true,
@@ -237,17 +287,79 @@ function requestSigningReuseMode(config) {
237
287
  ).digest("hex").slice(0, 16);
238
288
  return `${kind}:${fingerprint}`;
239
289
  }
240
- async function getOrDiscoverProfile(client, options) {
241
- if (options._profile) {
242
- seedTestClientSigningCapability(client, options._profile, options.adcpVersion);
290
+ async function getOrDiscoverProfile(client, options, schemaAdcpVersion) {
291
+ const scope = testClientScope.getStore();
292
+ const profileBinding = options._profile ? scope?.profileScopes.get(client)?.get(options._profile) : void 0;
293
+ schemaAdcpVersion ??= profileBinding?.schemaAdcpVersion ?? options.adcpVersion;
294
+ options.signal?.throwIfAborted();
295
+ const scopeKey = scope?.active ? client.getCapabilityEvidenceScope().scopeKey : void 0;
296
+ if (options._profile && (!scope?.active || scope.authRejectedProfiles.has(options._profile) || !options._profile.capabilities_probe_error && options._client === client && profileBinding?.scopeKey === scopeKey)) {
297
+ seedTestClientSigningCapability(client, options._profile, schemaAdcpVersion);
243
298
  return {
244
299
  profile: options._profile,
245
300
  step: { step: "Discover agent capabilities", passed: true, duration_ms: 0 }
246
301
  };
247
302
  }
248
- return discoverAgentProfile(client, options.signal, options.adcpVersion);
303
+ if (!scope?.active) return discoverAgentProfile(client, options.signal, schemaAdcpVersion);
304
+ const key = `${scopeKey}:${schemaAdcpVersion ?? client.getAdcpVersion()}`;
305
+ let profiles = scope.profiles.get(client);
306
+ if (!profiles) {
307
+ profiles = /* @__PURE__ */ new Map();
308
+ scope.profiles.set(client, profiles);
309
+ }
310
+ let discovery = profiles.get(key);
311
+ if (discovery?.failed && discovery.pass !== options._discoveryPass) {
312
+ profiles.delete(key);
313
+ discovery = void 0;
314
+ }
315
+ if (!discovery) {
316
+ const evict = () => {
317
+ if (profiles.get(key) === discovery) profiles.delete(key);
318
+ };
319
+ const promise = discoverAgentProfile(client, options.signal, schemaAdcpVersion).then(
320
+ (result) => {
321
+ if (options.signal?.aborted) {
322
+ evict();
323
+ } else if (!result.step.passed || result.profile.capabilities_probe_error) {
324
+ if (options._discoveryPass && discovery) discovery.failed = true;
325
+ else evict();
326
+ }
327
+ return result;
328
+ },
329
+ (error) => {
330
+ evict();
331
+ throw error;
332
+ }
333
+ );
334
+ discovery = { promise, signal: options.signal, pass: options._discoveryPass };
335
+ profiles.set(key, discovery);
336
+ }
337
+ try {
338
+ const result = await raceWithSignal(discovery.promise, options.signal);
339
+ if (!discovery.signal?.aborted || options.signal?.aborted) return result;
340
+ } catch (error) {
341
+ if (!discovery.signal?.aborted || options.signal?.aborted) throw error;
342
+ }
343
+ if (profiles.get(key) === discovery) profiles.delete(key);
344
+ return getOrDiscoverProfile(client, options, schemaAdcpVersion);
345
+ }
346
+ function seedAuthRejectedTestClientProfile(client, profile, adcpVersion) {
347
+ const scope = testClientScope.getStore();
348
+ if (scope?.active && profile.tools.length === 0 && profile.raw_capabilities === void 0) {
349
+ scope.authRejectedProfiles.add(profile);
350
+ }
351
+ seedTestClientSigningCapability(client, profile, adcpVersion);
249
352
  }
250
353
  function seedTestClientSigningCapability(client, profile, adcpVersion) {
354
+ const scope = testClientScope.getStore();
355
+ if (scope?.active) {
356
+ let profiles = scope.profileScopes.get(client);
357
+ if (!profiles) {
358
+ profiles = /* @__PURE__ */ new WeakMap();
359
+ scope.profileScopes.set(client, profiles);
360
+ }
361
+ profiles.set(profile, { scopeKey: client.getCapabilityEvidenceScope().scopeKey, schemaAdcpVersion: adcpVersion });
362
+ }
251
363
  const raw = profile.raw_capabilities;
252
364
  if (!raw || typeof raw !== "object") return;
253
365
  const clientAccess = client;
@@ -339,6 +451,7 @@ function describeVersionUnsupported(result, requestedVersion) {
339
451
  return `VERSION_UNSUPPORTED: ${requestedText}${supportedText}`;
340
452
  }
341
453
  async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
454
+ const scopeKey = hasTestClientScope() ? client.getCapabilityEvidenceScope().scopeKey : void 0;
342
455
  const {
343
456
  result: agentInfo,
344
457
  step,
@@ -408,7 +521,9 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
408
521
  profile.capabilities_probe_error = err?.message || String(err);
409
522
  }
410
523
  }
411
- seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
524
+ if (scopeKey === void 0 || scopeKey === client.getCapabilityEvidenceScope().scopeKey) {
525
+ seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
526
+ }
412
527
  return { profile, step, ...caughtError !== void 0 && { caughtError } };
413
528
  }
414
529
  async function discoverAgentCapabilities(client, profile, options) {
@@ -718,12 +833,15 @@ export {
718
833
  getOrCreateClient,
719
834
  getOrCreateClientResolution,
720
835
  getOrDiscoverProfile,
836
+ hasTestClientScope,
721
837
  resolveAccount,
722
838
  resolveAuthPrincipal,
723
839
  resolveBrand,
724
840
  runStep,
841
+ seedAuthRejectedTestClientProfile,
725
842
  seedTestClientSigningCapability,
726
843
  setAgentTesterLogger,
727
844
  testClientWireAdcpVersion,
728
- validateResponseSchema
845
+ validateResponseSchema,
846
+ withTestClientScope
729
847
  };