@adcp/sdk 17.0.0-beta.0 → 17.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 (70) hide show
  1. package/dist/lib/adapters/version/3.1/bidding.js +1 -1
  2. package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
  3. package/dist/lib/core/ResponseValidator.js +1 -1
  4. package/dist/lib/core/ResponseValidator.mjs +1 -1
  5. package/dist/lib/core/SingleAgentClient.d.mts +7 -5
  6. package/dist/lib/core/SingleAgentClient.d.ts +7 -5
  7. package/dist/lib/core/SingleAgentClient.js +57 -32
  8. package/dist/lib/core/SingleAgentClient.mjs +59 -33
  9. package/dist/lib/core/TaskExecutor.js +5 -3
  10. package/dist/lib/core/TaskExecutor.mjs +5 -3
  11. package/dist/lib/errors/index.d.mts +22 -0
  12. package/dist/lib/errors/index.d.ts +22 -0
  13. package/dist/lib/errors/index.js +43 -0
  14. package/dist/lib/errors/index.mjs +42 -0
  15. package/dist/lib/index.d.mts +1 -1
  16. package/dist/lib/index.d.ts +1 -1
  17. package/dist/lib/index.js +2 -0
  18. package/dist/lib/index.mjs +2 -0
  19. package/dist/lib/protocols/mcp-modern.d.mts +2 -0
  20. package/dist/lib/protocols/mcp-modern.d.ts +2 -0
  21. package/dist/lib/protocols/mcp-modern.js +31 -5
  22. package/dist/lib/protocols/mcp-modern.mjs +31 -5
  23. package/dist/lib/protocols/mcp-scope.d.mts +3 -1
  24. package/dist/lib/protocols/mcp-scope.d.ts +3 -1
  25. package/dist/lib/protocols/mcp-scope.js +19 -2
  26. package/dist/lib/protocols/mcp-scope.mjs +18 -2
  27. package/dist/lib/protocols/mcp.js +12 -6
  28. package/dist/lib/protocols/mcp.mjs +13 -6
  29. package/dist/lib/testing/client.d.mts +1 -0
  30. package/dist/lib/testing/client.d.ts +1 -0
  31. package/dist/lib/testing/client.js +6 -5
  32. package/dist/lib/testing/client.mjs +6 -5
  33. package/dist/lib/testing/storyboard/agent-routing.d.mts +5 -2
  34. package/dist/lib/testing/storyboard/agent-routing.d.ts +5 -2
  35. package/dist/lib/testing/storyboard/agent-routing.js +11 -4
  36. package/dist/lib/testing/storyboard/agent-routing.mjs +11 -4
  37. package/dist/lib/testing/storyboard/context.d.mts +13 -3
  38. package/dist/lib/testing/storyboard/context.d.ts +13 -3
  39. package/dist/lib/testing/storyboard/context.js +15 -10
  40. package/dist/lib/testing/storyboard/context.mjs +15 -10
  41. package/dist/lib/testing/storyboard/runner.js +141 -13
  42. package/dist/lib/testing/storyboard/runner.mjs +141 -13
  43. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  44. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  45. package/dist/lib/testing/storyboard/validations.js +4 -1
  46. package/dist/lib/testing/storyboard/validations.mjs +4 -1
  47. package/dist/lib/testing/test-controller.js +3 -0
  48. package/dist/lib/testing/test-controller.mjs +3 -0
  49. package/dist/lib/utils/envelope-status-compat.d.mts +18 -1
  50. package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
  51. package/dist/lib/utils/envelope-status-compat.js +11 -5
  52. package/dist/lib/utils/envelope-status-compat.mjs +11 -5
  53. package/dist/lib/utils/response-unwrapper.js +12 -9
  54. package/dist/lib/utils/response-unwrapper.mjs +12 -9
  55. package/dist/lib/v2/projection/creative-delivery.js +56 -11
  56. package/dist/lib/v2/projection/creative-delivery.mjs +56 -11
  57. package/dist/lib/validation/schema-validator.js +1 -1
  58. package/dist/lib/validation/schema-validator.mjs +1 -1
  59. package/dist/lib/version.d.mts +3 -3
  60. package/dist/lib/version.d.ts +3 -3
  61. package/dist/lib/version.js +3 -3
  62. package/dist/lib/version.mjs +3 -3
  63. package/docs/TYPE-SUMMARY.md +2 -2
  64. package/docs/guides/COLLECTION-FIXTURE-FOUNDATION.md +11 -0
  65. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +12 -1
  66. package/docs/llms.txt +2 -2
  67. package/docs/migration-14.x-rc-worksheet.md +4 -4
  68. package/docs/migration-16-to-17.md +24 -1
  69. package/docs/migration-reporting-storage-package.md +1 -1
  70. package/package.json +1 -1
@@ -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
@@ -10,12 +10,22 @@
10
10
  * (context_outputs/context_inputs) while still enabling stateful flows.
11
11
  */
12
12
  import type { StoryboardContext, ContextOutput, ContextInput, ContextProvenanceEntry } from './types.mjs';
13
- type ContextExtractor = (data: unknown) => Record<string, unknown>;
13
+ /**
14
+ * `adcpVersion` is the release the step was requested at. Media-buy mutation
15
+ * extractors use it to tell a 3.1+ task-envelope `status` from a 3.0
16
+ * lifecycle `status` when the response does not echo its version.
17
+ */
18
+ type ContextExtractor = (data: unknown, adcpVersion?: string) => Record<string, unknown>;
14
19
  export declare const CONTEXT_EXTRACTORS: Record<string, ContextExtractor>;
15
20
  /**
16
21
  * Extract context values from a task response.
22
+ *
23
+ * @param adcpVersion - Optional AdCP release the request was sent at. Used
24
+ * only when the response does not echo `adcp_version`, to read a
25
+ * create/update top-level `status` as the 3.1+ task status rather than a
26
+ * 3.0 media-buy lifecycle.
17
27
  */
18
- export declare function extractContext(taskName: string, data: unknown): Record<string, unknown>;
28
+ export declare function extractContext(taskName: string, data: unknown, adcpVersion?: string): Record<string, unknown>;
19
29
  /**
20
30
  * Propagate the alias cache from one context to another — call after
21
31
  * shallow-cloning context between storyboard steps so replay tests
@@ -132,7 +142,7 @@ export interface ContextWriteResult {
132
142
  * tagging it as a convention-based extraction. `response_path` is absent
133
143
  * for convention extractors — they're hardcoded functions, not YAML paths.
134
144
  */
135
- export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string): ContextWriteResult;
145
+ export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string, adcpVersion?: string): ContextWriteResult;
136
146
  /**
137
147
  * Like `applyContextOutputs`, but also returns provenance for each written
138
148
  * key carrying the YAML `response_path` so diagnostics can cite it verbatim.
@@ -10,12 +10,22 @@
10
10
  * (context_outputs/context_inputs) while still enabling stateful flows.
11
11
  */
12
12
  import type { StoryboardContext, ContextOutput, ContextInput, ContextProvenanceEntry } from './types';
13
- type ContextExtractor = (data: unknown) => Record<string, unknown>;
13
+ /**
14
+ * `adcpVersion` is the release the step was requested at. Media-buy mutation
15
+ * extractors use it to tell a 3.1+ task-envelope `status` from a 3.0
16
+ * lifecycle `status` when the response does not echo its version.
17
+ */
18
+ type ContextExtractor = (data: unknown, adcpVersion?: string) => Record<string, unknown>;
14
19
  export declare const CONTEXT_EXTRACTORS: Record<string, ContextExtractor>;
15
20
  /**
16
21
  * Extract context values from a task response.
22
+ *
23
+ * @param adcpVersion - Optional AdCP release the request was sent at. Used
24
+ * only when the response does not echo `adcp_version`, to read a
25
+ * create/update top-level `status` as the 3.1+ task status rather than a
26
+ * 3.0 media-buy lifecycle.
17
27
  */
18
- export declare function extractContext(taskName: string, data: unknown): Record<string, unknown>;
28
+ export declare function extractContext(taskName: string, data: unknown, adcpVersion?: string): Record<string, unknown>;
19
29
  /**
20
30
  * Propagate the alias cache from one context to another — call after
21
31
  * shallow-cloning context between storyboard steps so replay tests
@@ -132,7 +142,7 @@ export interface ContextWriteResult {
132
142
  * tagging it as a convention-based extraction. `response_path` is absent
133
143
  * for convention extractors — they're hardcoded functions, not YAML paths.
134
144
  */
135
- export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string): ContextWriteResult;
145
+ export declare function extractContextWithProvenance(taskName: string, data: unknown, stepId: string, adcpVersion?: string): ContextWriteResult;
136
146
  /**
137
147
  * Like `applyContextOutputs`, but also returns provenance for each written
138
148
  * key carrying the YAML `response_path` so diagnostics can cite it verbatim.
@@ -59,14 +59,19 @@ function asRecord(value) {
59
59
  function readMediaBuyStatus(record) {
60
60
  return (0, import_media_buy_status.getAuthoritativeMediaBuyStatus)(record);
61
61
  }
62
- function readMediaBuyFields(data) {
62
+ function readMediaBuyFields(data, adcpVersion) {
63
63
  const outer = asRecord(data);
64
64
  const nested = asRecord(outer?.media_buy);
65
65
  return {
66
66
  mediaBuyId: nested?.media_buy_id ?? outer?.media_buy_id,
67
- status: readMediaBuyStatus(nested) ?? readMediaBuyStatus(outer)
67
+ status: readMediaBuyStatus(nested) ?? readMediaBuyStatus(withRequestedVersion(outer, adcpVersion))
68
68
  };
69
69
  }
70
+ function withRequestedVersion(record, adcpVersion) {
71
+ if (!record || !adcpVersion) return record;
72
+ if (typeof record.adcp_version === "string" || typeof record.adcp_major_version === "number") return record;
73
+ return { ...record, adcp_version: adcpVersion };
74
+ }
70
75
  function readProposalFields(proposal) {
71
76
  if (!proposal) return {};
72
77
  const extracted = {};
@@ -181,15 +186,15 @@ const CONTEXT_EXTRACTORS = {
181
186
  control_media_buy(data) {
182
187
  return readCompactMediaBuyFields(data);
183
188
  },
184
- create_media_buy(data) {
185
- const { mediaBuyId, status } = readMediaBuyFields(data);
189
+ create_media_buy(data, adcpVersion) {
190
+ const { mediaBuyId, status } = readMediaBuyFields(data, adcpVersion);
186
191
  const extracted = {};
187
192
  if (mediaBuyId) extracted.media_buy_id = mediaBuyId;
188
193
  if (status) extracted.media_buy_status = status;
189
194
  return extracted;
190
195
  },
191
- update_media_buy(data) {
192
- const { mediaBuyId, status } = readMediaBuyFields(data);
196
+ update_media_buy(data, adcpVersion) {
197
+ const { mediaBuyId, status } = readMediaBuyFields(data, adcpVersion);
193
198
  const extracted = {};
194
199
  if (mediaBuyId) extracted.media_buy_id = mediaBuyId;
195
200
  if (status) extracted.media_buy_status = status;
@@ -381,11 +386,11 @@ const CONTEXT_EXTRACTORS = {
381
386
  return extracted;
382
387
  }
383
388
  };
384
- function extractContext(taskName, data) {
389
+ function extractContext(taskName, data, adcpVersion) {
385
390
  const extractor = CONTEXT_EXTRACTORS[taskName];
386
391
  if (!extractor) return {};
387
392
  try {
388
- return extractor(data);
393
+ return extractor(data, adcpVersion);
389
394
  } catch {
390
395
  return {};
391
396
  }
@@ -482,8 +487,8 @@ function applyContextOutputs(data, outputs) {
482
487
  }
483
488
  return result;
484
489
  }
485
- function extractContextWithProvenance(taskName, data, stepId) {
486
- const values = extractContext(taskName, data);
490
+ function extractContextWithProvenance(taskName, data, stepId, adcpVersion) {
491
+ const values = extractContext(taskName, data, adcpVersion);
487
492
  const clearGroups = (() => {
488
493
  const response = asRecord(data);
489
494
  switch (taskName) {
@@ -26,14 +26,19 @@ function asRecord(value) {
26
26
  function readMediaBuyStatus(record) {
27
27
  return getAuthoritativeMediaBuyStatus(record);
28
28
  }
29
- function readMediaBuyFields(data) {
29
+ function readMediaBuyFields(data, adcpVersion) {
30
30
  const outer = asRecord(data);
31
31
  const nested = asRecord(outer?.media_buy);
32
32
  return {
33
33
  mediaBuyId: nested?.media_buy_id ?? outer?.media_buy_id,
34
- status: readMediaBuyStatus(nested) ?? readMediaBuyStatus(outer)
34
+ status: readMediaBuyStatus(nested) ?? readMediaBuyStatus(withRequestedVersion(outer, adcpVersion))
35
35
  };
36
36
  }
37
+ function withRequestedVersion(record, adcpVersion) {
38
+ if (!record || !adcpVersion) return record;
39
+ if (typeof record.adcp_version === "string" || typeof record.adcp_major_version === "number") return record;
40
+ return { ...record, adcp_version: adcpVersion };
41
+ }
37
42
  function readProposalFields(proposal) {
38
43
  if (!proposal) return {};
39
44
  const extracted = {};
@@ -148,15 +153,15 @@ const CONTEXT_EXTRACTORS = {
148
153
  control_media_buy(data) {
149
154
  return readCompactMediaBuyFields(data);
150
155
  },
151
- create_media_buy(data) {
152
- const { mediaBuyId, status } = readMediaBuyFields(data);
156
+ create_media_buy(data, adcpVersion) {
157
+ const { mediaBuyId, status } = readMediaBuyFields(data, adcpVersion);
153
158
  const extracted = {};
154
159
  if (mediaBuyId) extracted.media_buy_id = mediaBuyId;
155
160
  if (status) extracted.media_buy_status = status;
156
161
  return extracted;
157
162
  },
158
- update_media_buy(data) {
159
- const { mediaBuyId, status } = readMediaBuyFields(data);
163
+ update_media_buy(data, adcpVersion) {
164
+ const { mediaBuyId, status } = readMediaBuyFields(data, adcpVersion);
160
165
  const extracted = {};
161
166
  if (mediaBuyId) extracted.media_buy_id = mediaBuyId;
162
167
  if (status) extracted.media_buy_status = status;
@@ -348,11 +353,11 @@ const CONTEXT_EXTRACTORS = {
348
353
  return extracted;
349
354
  }
350
355
  };
351
- function extractContext(taskName, data) {
356
+ function extractContext(taskName, data, adcpVersion) {
352
357
  const extractor = CONTEXT_EXTRACTORS[taskName];
353
358
  if (!extractor) return {};
354
359
  try {
355
- return extractor(data);
360
+ return extractor(data, adcpVersion);
356
361
  } catch {
357
362
  return {};
358
363
  }
@@ -449,8 +454,8 @@ function applyContextOutputs(data, outputs) {
449
454
  }
450
455
  return result;
451
456
  }
452
- function extractContextWithProvenance(taskName, data, stepId) {
453
- const values = extractContext(taskName, data);
457
+ function extractContextWithProvenance(taskName, data, stepId, adcpVersion) {
458
+ const values = extractContext(taskName, data, adcpVersion);
454
459
  const clearGroups = (() => {
455
460
  const response = asRecord(data);
456
461
  switch (taskName) {