@adcp/sdk 13.0.2 → 13.0.4
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.
- package/bin/adcp.js +37 -2
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/decisioning/capabilities.d.mts +5 -5
- package/dist/lib/server/decisioning/capabilities.d.ts +5 -5
- package/dist/lib/server/decisioning/capabilities.js.map +1 -1
- package/dist/lib/server/decisioning/capabilities.mjs.map +1 -1
- package/dist/lib/testing/client.d.ts.map +1 -1
- package/dist/lib/testing/client.js +6 -2
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/client.mjs +6 -2
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
- package/dist/lib/testing/compliance/comply.js +27 -18
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +25 -17
- package/dist/lib/testing/compliance/comply.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +18 -4
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +18 -4
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/types.d.mts +83 -29
- package/dist/lib/testing/storyboard/types.d.ts +83 -29
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/storyboard/types.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +3 -1
- package/dist/lib/testing/storyboard/validations.d.ts +3 -1
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.js +83 -23
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +83 -24
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/testing/types.d.mts +11 -0
- package/dist/lib/testing/types.d.ts +11 -0
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/testing/types.js.map +1 -1
- package/dist/lib/validation/schema-loader.d.ts.map +1 -1
- package/dist/lib/validation/schema-loader.js +9 -0
- package/dist/lib/validation/schema-loader.js.map +1 -1
- package/dist/lib/validation/schema-loader.mjs +8 -0
- package/dist/lib/validation/schema-loader.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/package.json +3 -3
package/bin/adcp.js
CHANGED
|
@@ -1047,6 +1047,10 @@ function parseAgentOptions(args) {
|
|
|
1047
1047
|
const debug = args.includes('--debug') || process.env.ADCP_DEBUG === 'true';
|
|
1048
1048
|
const dryRun = args.includes('--dry-run');
|
|
1049
1049
|
const allowHttp = args.includes('--allow-http');
|
|
1050
|
+
// Migration escape hatch for compatibility harnesses that are testing
|
|
1051
|
+
// transport/version behavior against a known schema-invalid legacy seller.
|
|
1052
|
+
// Normal local compliance runs remain strict by default.
|
|
1053
|
+
const strictResponseSchemaValidation = !args.includes('--no-strict-response-schema-validation');
|
|
1050
1054
|
// `--no-sandbox` forces `account.sandbox: false` (production) on every
|
|
1051
1055
|
// request the runner builds. The default behavior leaves the field unset
|
|
1052
1056
|
// (spec-equivalent to false), but agents that key sandbox routing on
|
|
@@ -1185,6 +1189,7 @@ function parseAgentOptions(args) {
|
|
|
1185
1189
|
debug,
|
|
1186
1190
|
dryRun,
|
|
1187
1191
|
allowHttp,
|
|
1192
|
+
strictResponseSchemaValidation,
|
|
1188
1193
|
noSandbox,
|
|
1189
1194
|
assertsSeededState,
|
|
1190
1195
|
positionalArgs,
|
|
@@ -1963,6 +1968,11 @@ SUBCOMMANDS:
|
|
|
1963
1968
|
step <agent> <id> <step_id> Run a single step (stateless, LLM-friendly)
|
|
1964
1969
|
|
|
1965
1970
|
RUN OPTIONS (full assessment):
|
|
1971
|
+
Response-schema checks are strict and grading by default, matching the
|
|
1972
|
+
hosted compliance grader. JSON output includes strict_validation_summary.
|
|
1973
|
+
--no-strict-response-schema-validation
|
|
1974
|
+
Keep packaged-schema strict failures diagnostic-only.
|
|
1975
|
+
Intended only for temporary legacy migration harnesses.
|
|
1966
1976
|
--tracks TRACKS Comma-separated tracks to include in the report
|
|
1967
1977
|
--storyboards IDS Comma-separated storyboard/bundle IDs to run
|
|
1968
1978
|
--compliance-version VERSION
|
|
@@ -2851,6 +2861,7 @@ async function handleStoryboardRun(args) {
|
|
|
2851
2861
|
...(fileComplianceOptions.complianceDir && { complianceDir: fileComplianceOptions.complianceDir }),
|
|
2852
2862
|
...(fileComplianceOptions.adcpVersion && { adcpVersion: fileComplianceOptions.adcpVersion }),
|
|
2853
2863
|
...(fileComplianceOptions.schemaRoot && { schemaRoot: fileComplianceOptions.schemaRoot }),
|
|
2864
|
+
...(!opts.strictResponseSchemaValidation && { strictResponseSchemaValidation: false }),
|
|
2854
2865
|
...(opts.noSandbox && { sandbox: false, disable_sandbox: true }),
|
|
2855
2866
|
...(opts.assertsSeededState && { assertsSeededState: true }),
|
|
2856
2867
|
...(mergedRunHeaders && { headers: mergedRunHeaders }),
|
|
@@ -3689,6 +3700,7 @@ async function handleLocalAgentStoryboardRun(modulePath, args, opts) {
|
|
|
3689
3700
|
compliance: resolveOptions,
|
|
3690
3701
|
...(opts.complianceVersion ||
|
|
3691
3702
|
opts.schemaRoot ||
|
|
3703
|
+
!opts.strictResponseSchemaValidation ||
|
|
3692
3704
|
opts.noSandbox ||
|
|
3693
3705
|
opts.assertsSeededState ||
|
|
3694
3706
|
opts.loadedTestKit !== undefined
|
|
@@ -3696,6 +3708,7 @@ async function handleLocalAgentStoryboardRun(modulePath, args, opts) {
|
|
|
3696
3708
|
runStoryboardOptions: {
|
|
3697
3709
|
...(opts.complianceVersion && !opts.complianceDir && { adcpVersion: opts.complianceVersion }),
|
|
3698
3710
|
...(opts.schemaRoot && { schemaRoot: opts.schemaRoot }),
|
|
3711
|
+
...(!opts.strictResponseSchemaValidation && { strictResponseSchemaValidation: false }),
|
|
3699
3712
|
...(opts.noSandbox && { sandbox: false, disable_sandbox: true }),
|
|
3700
3713
|
...(opts.assertsSeededState && { assertsSeededState: true }),
|
|
3701
3714
|
...(opts.loadedTestKit !== undefined && { test_kit: opts.loadedTestKit }),
|
|
@@ -4129,6 +4142,7 @@ async function handleMultiInstanceStoryboardRun(args, opts, urls) {
|
|
|
4129
4142
|
...(runComplianceDir && { complianceDir: runComplianceDir }),
|
|
4130
4143
|
...(runAdcpVersion && { adcpVersion: runAdcpVersion }),
|
|
4131
4144
|
...(runSchemaRoot && { schemaRoot: runSchemaRoot }),
|
|
4145
|
+
...(!opts.strictResponseSchemaValidation && { strictResponseSchemaValidation: false }),
|
|
4132
4146
|
...(opts.noSandbox && { sandbox: false, disable_sandbox: true }),
|
|
4133
4147
|
...(opts.assertsSeededState && { assertsSeededState: true }),
|
|
4134
4148
|
...(opts.loadedTestKit !== undefined && { test_kit: opts.loadedTestKit }),
|
|
@@ -4409,6 +4423,7 @@ async function handleAgentsRoutedStoryboardRun(args, opts, routing) {
|
|
|
4409
4423
|
...(runComplianceDir && { complianceDir: runComplianceDir }),
|
|
4410
4424
|
...(runAdcpVersion && { adcpVersion: runAdcpVersion }),
|
|
4411
4425
|
...(runSchemaRoot && { schemaRoot: runSchemaRoot }),
|
|
4426
|
+
...(!opts.strictResponseSchemaValidation && { strictResponseSchemaValidation: false }),
|
|
4412
4427
|
...(opts.noSandbox && { sandbox: false, disable_sandbox: true }),
|
|
4413
4428
|
...(opts.assertsSeededState && { assertsSeededState: true }),
|
|
4414
4429
|
...(opts.loadedTestKit !== undefined && { test_kit: opts.loadedTestKit }),
|
|
@@ -4621,6 +4636,7 @@ async function runFullAssessment(agentArg, rawArgs, parsedOpts) {
|
|
|
4621
4636
|
...(opts.complianceVersion && { version: opts.complianceVersion }),
|
|
4622
4637
|
...(opts.complianceDir && { complianceDir: opts.complianceDir }),
|
|
4623
4638
|
...(opts.schemaRoot && { schemaRoot: opts.schemaRoot }),
|
|
4639
|
+
...(!opts.strictResponseSchemaValidation && { strictResponseSchemaValidation: false }),
|
|
4624
4640
|
...(opts.hostedStableLineAlias && { hostedStableLineAlias: opts.hostedStableLineAlias }),
|
|
4625
4641
|
};
|
|
4626
4642
|
|
|
@@ -4762,7 +4778,16 @@ async function runFullAssessment(agentArg, rawArgs, parsedOpts) {
|
|
|
4762
4778
|
async function handleStoryboardStepCmd(args) {
|
|
4763
4779
|
const { getComplianceStoryboardById, runStoryboardStep } = await import('../dist/lib/testing/storyboard/index.js');
|
|
4764
4780
|
let opts = parseAgentOptions(args);
|
|
4765
|
-
let {
|
|
4781
|
+
let {
|
|
4782
|
+
authToken,
|
|
4783
|
+
authScheme,
|
|
4784
|
+
protocolFlag,
|
|
4785
|
+
jsonOutput,
|
|
4786
|
+
positionalArgs,
|
|
4787
|
+
complianceVersion,
|
|
4788
|
+
schemaRoot,
|
|
4789
|
+
strictResponseSchemaValidation,
|
|
4790
|
+
} = opts;
|
|
4766
4791
|
|
|
4767
4792
|
enforceStrictFlags(args, warnRemovedFlags(args));
|
|
4768
4793
|
|
|
@@ -4774,7 +4799,16 @@ async function handleStoryboardStepCmd(args) {
|
|
|
4774
4799
|
exitTestKitSelectionError(err, jsonOutput);
|
|
4775
4800
|
}
|
|
4776
4801
|
|
|
4777
|
-
({
|
|
4802
|
+
({
|
|
4803
|
+
authToken,
|
|
4804
|
+
authScheme,
|
|
4805
|
+
protocolFlag,
|
|
4806
|
+
jsonOutput,
|
|
4807
|
+
positionalArgs,
|
|
4808
|
+
complianceVersion,
|
|
4809
|
+
schemaRoot,
|
|
4810
|
+
strictResponseSchemaValidation,
|
|
4811
|
+
} = opts);
|
|
4778
4812
|
const { resolveOptions } = parseComplianceSelection(args);
|
|
4779
4813
|
|
|
4780
4814
|
const agentArg = positionalArgs[0];
|
|
@@ -4830,6 +4864,7 @@ async function handleStoryboardStepCmd(args) {
|
|
|
4830
4864
|
...(opts.complianceDir && { complianceDir: opts.complianceDir }),
|
|
4831
4865
|
...(schemaRoot && { schemaRoot }),
|
|
4832
4866
|
...(opts.loadedTestKit !== undefined && { test_kit: opts.loadedTestKit }),
|
|
4867
|
+
...(!strictResponseSchemaValidation && { strictResponseSchemaValidation: false }),
|
|
4833
4868
|
...buildResolvedAuthOption({
|
|
4834
4869
|
resolvedAuth,
|
|
4835
4870
|
resolvedAuthScheme,
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
"source_sha": "4e553ad955f83b49c7d221ab5c3ff78237ad02e3",
|
|
5
5
|
"source_tarball_sha256": "580656d6466ef9f0d1119985e6726c2efea718dc671e2ad30957fcb2fd54af0f",
|
|
6
6
|
"upstream_adcp_version": "2.5.3",
|
|
7
|
-
"synced_at": "2026-09-
|
|
7
|
+
"synced_at": "2026-09-14T12:59:06.841Z"
|
|
8
8
|
}
|
|
@@ -454,11 +454,11 @@ export type BrandCapabilities = NonNullable<NonNullable<GetAdCPCapabilitiesRespo
|
|
|
454
454
|
*/
|
|
455
455
|
export interface ComplianceTestingCapabilities {
|
|
456
456
|
/**
|
|
457
|
-
* Scenarios this agent advertises support for.
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
* when omitted.
|
|
457
|
+
* Scenarios this agent advertises support for. The wire field is open to
|
|
458
|
+
* implementation-specific string values; canonical controller scenarios
|
|
459
|
+
* are recommendations, not an enum constraint. `list_scenarios` remains a
|
|
460
|
+
* discovery operation rather than a test capability. Framework defaults
|
|
461
|
+
* this from the adopter-supplied `complyTest` adapter set when omitted.
|
|
462
462
|
*/
|
|
463
463
|
scenarios?: ReadonlyArray<_ComplianceTestingScenario>;
|
|
464
464
|
}
|
|
@@ -454,11 +454,11 @@ export type BrandCapabilities = NonNullable<NonNullable<GetAdCPCapabilitiesRespo
|
|
|
454
454
|
*/
|
|
455
455
|
export interface ComplianceTestingCapabilities {
|
|
456
456
|
/**
|
|
457
|
-
* Scenarios this agent advertises support for.
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
* when omitted.
|
|
457
|
+
* Scenarios this agent advertises support for. The wire field is open to
|
|
458
|
+
* implementation-specific string values; canonical controller scenarios
|
|
459
|
+
* are recommendations, not an enum constraint. `list_scenarios` remains a
|
|
460
|
+
* discovery operation rather than a test capability. Framework defaults
|
|
461
|
+
* this from the adopter-supplied `complyTest` adapter set when omitted.
|
|
462
462
|
*/
|
|
463
463
|
scenarios?: ReadonlyArray<_ComplianceTestingScenario>;
|
|
464
464
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/server/decisioning/capabilities.ts"],"sourcesContent":["/**\n * DecisioningCapabilities — single source of truth for `get_adcp_capabilities`\n * response and any admin UI surface a host wants to render.\n *\n * Adopters declare once. Framework wires the wire-protocol response;\n * adopters' admin tools (or the SDK CLI's `validate_platform_config`) consume\n * the same dataclass so there's no drift between \"what the agent says it\n * supports\" and \"what it actually does.\"\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type { ZodSchema } from 'zod';\nimport type {\n AdCPSpecialism,\n MediaChannel,\n PaymentTerms,\n PricingModel,\n GetAdCPCapabilitiesResponse,\n PostalAreaSupport,\n} from '../../types/tools.generated';\nimport type { ProductMetricOptimizationLike } from '../../utils/capability-rollups';\nimport type { MediaBuyFeatures, AccountCapabilities, CreativeCapabilities } from '../../utils/capabilities';\nimport type { AdcpCapabilitiesOverrides } from '../create-adcp-server';\n\n/**\n * Pre-resolved alias for the wire `media_buy` block. Used as the projection\n * source for the five `media_buy.*` capability fields below so each typed\n * field references a single resolved shape instead of re-walking the\n * `GetAdCPCapabilitiesResponse` type graph independently. Without the\n * alias, `strict + skipLibCheck:false` adopters hit the TS instantiation\n * budget on the published `.d.ts` and tsc OOMs.\n */\ntype _MediaBuyCapabilities = NonNullable<GetAdCPCapabilitiesResponse['media_buy']>;\ntype _MediaBuyTargetingCapabilities = NonNullable<NonNullable<_MediaBuyCapabilities['execution']>['targeting']>;\ntype _ComplianceTestingScenario = NonNullable<\n NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']\n>[number];\n\nexport interface DecisioningCapabilities<TConfig = unknown> {\n /**\n * Specialisms claimed; framework type-checks these against implemented platform\n * interfaces. Arrays are `readonly` so adopters can declare with `as const`\n * (load-bearing for the `RequiredPlatformsFor<S>` compile-time gate).\n */\n specialisms: readonly AdCPSpecialism[];\n\n /**\n * Creative agents this seller composes with. Framework fetches format catalogs\n * from each (1h cache) and unions them on `list_creative_formats`. Self-hosting\n * sellers point at their own `agent_url`; framework calls into their\n * `CreativePlatform.listFormats()` locally instead of HTTP-fetching.\n *\n * `format_ids` filter (optional) subsets a single creative agent's catalog.\n * Useful when a creative agent hosts 50 formats but this seller only accepts\n * 10 of them. Filter scope is per-creative-agent: `[{ agent_url: A, format_ids: ['x'] }, { agent_url: B }]`\n * means \"from A only format x; from B all formats.\"\n *\n * Omit for signals-only platforms (`signal-marketplace`, `signal-owned`) — they\n * sell audience data access, not media inventory, and don't compose with creative agents.\n */\n creative_agents?: readonly CreativeAgentRef[];\n\n /**\n * Channels this platform sells.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channels to declare. Applies to signals (`signal-marketplace`, `signal-owned`),\n * governance (`governance-spend-authority`, `governance-delivery-monitor`,\n * `property-lists`, `collection-lists`, `content-standards`), creative-only\n * (`creative-ad-server`, `creative-template`, `creative-generative`), and\n * brand (`brand-rights`) platforms.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n channels?: readonly MediaChannel[];\n\n /**\n * Pricing models this platform supports.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channel-level pricing to declare. For signals platforms specifically, pricing\n * is declared per-signal in the signal descriptor's `pricing_options[]` instead.\n * Same non-media-buy specialism set as `channels` above.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n pricingModels?: readonly PricingModel[];\n\n /** Targeting capabilities. Optional — framework infers reasonable defaults if omitted. */\n targeting?: TargetingCapabilities;\n\n /** Reporting capabilities. Optional — framework infers reasonable defaults if omitted. */\n reporting?: ReportingCapabilities;\n\n /**\n * Audience-matching capabilities — projected onto\n * `get_adcp_capabilities.media_buy.audience_targeting`. Required for\n * audience-sync adopters (CRM-list adopters that accept hashed\n * identifiers + UID types) so buyers know which identifier shapes\n * the platform will match against and what minimum audience size /\n * matching latency to expect. Omit when the platform doesn't accept\n * external audience uploads.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.audience_targeting`.\n */\n audience_targeting?: NonNullable<_MediaBuyCapabilities['audience_targeting']>;\n\n /**\n * Conversion-tracking capabilities — projected onto\n * `get_adcp_capabilities.media_buy.conversion_tracking`. Required for\n * adopters that accept conversion events via `sync_event_sources` /\n * `log_event` so buyers know which event types, action sources,\n * attribution windows, and identifier shapes the platform supports.\n * Omit when the platform doesn't track conversions.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.conversion_tracking`.\n */\n conversion_tracking?: NonNullable<_MediaBuyCapabilities['conversion_tracking']>;\n\n /**\n * Content-standards capabilities — projected onto\n * `get_adcp_capabilities.media_buy.content_standards`. Required for\n * adopters claiming the `content-standards` specialism so buyers know\n * whether the platform runs local evaluation, which channels it\n * covers, and whether it supports webhook artifact delivery. Omit\n * when the platform doesn't ship content-standards artifacts.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.content_standards`.\n */\n content_standards?: NonNullable<_MediaBuyCapabilities['content_standards']>;\n\n /**\n * Seller-level rollup of optimization metrics — projected onto\n * `get_adcp_capabilities.media_buy.supported_optimization_metrics`.\n * Added in AdCP 3.1 (adcp#4669). The array union of every product's\n * `metric_optimization.supported_metrics`. Storyboard runners gate\n * `metric_optimization`-using scenarios on this field; declaring it\n * gives buyers an upfront signal of which optimization metrics the\n * seller can compute against (clicks, views, completed_views, etc.).\n *\n * Adopters can compute the rollup from their catalog using the\n * exported {@link rollupOptimizationMetricsFromProducts} helper —\n * keeps the declaration in sync with what products actually offer.\n * Empty arrays are normalized away and the wire field is omitted; use\n * omission to mean \"no seller-level metric rollup advertised\".\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.supported_optimization_metrics`.\n */\n supported_optimization_metrics?: NonNullable<_MediaBuyCapabilities['supported_optimization_metrics']>;\n\n /**\n * Static product-metric summary used for capability rollups.\n *\n * When this is present and `supported_optimization_metrics` is omitted,\n * the framework derives `media_buy.supported_optimization_metrics` as the\n * sorted union of every product summary's\n * `metric_optimization.supported_metrics`. Full AdCP `Product` objects work,\n * but this field is not a general product-discovery surface; a lightweight\n * startup summary with just the `metric_optimization` block is enough.\n * Dynamic per-account catalogs should continue to pass an explicit\n * `supported_optimization_metrics` override. If the derived union is empty,\n * the framework omits `supported_optimization_metrics` from the wire\n * capabilities response.\n */\n productCatalog?: ReadonlyArray<ProductMetricOptimizationLike>;\n\n /**\n * Frequency-cap support declaration — projected onto\n * `get_adcp_capabilities.media_buy.frequency_capping`. Added in AdCP\n * 3.1 (adcp#4670). Presence-only object with `supported_per_units` /\n * `supported_window_units` sub-fields declaring which frequency-cap\n * shapes the platform honors. Omit when the platform doesn't accept\n * frequency caps at all; buyers will avoid the field on `pacing.*`.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.frequency_capping`.\n */\n frequency_capping?: NonNullable<_MediaBuyCapabilities['frequency_capping']>;\n\n /**\n * Whether this seller commits to the proposal lifecycle on get_products.\n * Projected onto `get_adcp_capabilities.media_buy.supports_proposals`.\n * Direct-buy sellers should declare `false` so proposal-only compliance\n * storyboards are skipped; sellers with a ProposalManager are auto-derived\n * as `true` unless they override this explicitly.\n */\n supportsProposals?: boolean;\n\n /**\n * Brand-protocol capabilities. Projected onto the wire `brand` block of\n * `get_adcp_capabilities` (`brand: { rights, right_types, available_uses,\n * generation_providers, description }`). The framework auto-derives\n * `rights: true` when `BrandRightsPlatform` is supplied; adopters\n * declare the rest (right_types they license, RightUses they support,\n * generation providers they issue credentials for).\n *\n * REQUIRED when claiming the `'brand-rights'` specialism — enforced at\n * compile-time via `RequiredCapabilitiesFor<S>`.\n */\n brand?: BrandCapabilities;\n\n /**\n * Compliance-testing capabilities. The presence of this block declares\n * the deployment supports deterministic state-machine testing via the\n * `comply_test_controller` wire tool. Keep this block declared when using\n * `createAdcpServerFromPlatform(..., { complyTest })`; the framework makes\n * live principals byte-identical to a production seller that never wired the\n * controller by hiding this block, filtering `tools/list`, and returning MCP\n * method-not-found for direct live calls.\n *\n * When this block is present, `createAdcpServerFromPlatform` REQUIRES\n * `opts.complyTest` (the `ComplyControllerConfig` adapter set) to be\n * supplied — claiming the capability without implementing the\n * controller is a `PlatformConfigError` at construction.\n *\n * Inversely, supplying `opts.complyTest` without declaring this\n * capability is also caught — the framework derives `scenarios` from\n * the declared force/simulate/seed adapters and emits the discovery\n * field on `get_adcp_capabilities` automatically for sandbox/mock\n * principals. Live principals do not see the block.\n */\n compliance_testing?: ComplianceTestingCapabilities;\n\n /**\n * Billing parties this platform supports. `'operator'` = retail-media model\n * (Criteo, Amazon — operator pays the publisher and bills the brand).\n * `'agent'` = pass-through model (buyer's agent settles directly with the\n * platform). `'advertiser'` = seller invoices the advertiser directly,\n * bypassing operator settlement (advertiser-direct sell-side platforms where\n * the brand is the direct contractual counterparty). Defaults to `['agent']`\n * when omitted. To express advertiser-direct billing per account, set\n * `billing.invoicedTo` to a `BrandReference` (the framework maps any\n * `BrandReference` to `'advertiser'` on the wire).\n */\n supportedBillings?: ReadonlyArray<'operator' | 'agent' | 'advertiser'>;\n\n /**\n * Payment terms this platform accepts on `sync_accounts.payment_terms`.\n * Omit to leave terms validation to `accounts.upsert` (or to accept any\n * schema-valid value). When present, the framework rejects unsupported\n * requested terms with `PAYMENT_TERMS_NOT_SUPPORTED` before dispatching\n * the account entry to the adopter.\n */\n supportedPaymentTerms?: ReadonlyArray<PaymentTerms>;\n\n /**\n * If true, this platform refuses transactions without an authenticated\n * operator principal (operator-billed retail-media). Framework emits\n * `AUTH_REQUIRED` envelope before dispatching to the platform.\n */\n requireOperatorAuth?: boolean;\n\n /**\n * Media-buy feature flags forwarded into `get_adcp_capabilities.media_buy.features`.\n * Adopter values serve as the base; auto-derived `audience_targeting`,\n * `conversion_tracking`, and `content_standards` booleans take precedence\n * for those three keys (overlaid by the framework via the per-domain\n * `media_buy` override on the inner createAdcpServer call). Use this to\n * declare `inlineCreativeManagement` and `propertyListFiltering` directly\n * from `definePlatform`; declare not-supported feature blocks (e.g.\n * `inlineCreativeManagement: false`) so the conformance runner grades\n * them `not_applicable` instead of `fail`.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n features?: Partial<MediaBuyFeatures>;\n\n /**\n * Creative-protocol capabilities forwarded into `get_adcp_capabilities.creative`.\n * Use to declare `supportsCompliance`, `hasCreativeLibrary`,\n * `supportsGeneration`, and `supportsTransformation` from `definePlatform`.\n * Adopters that don't run a provenance-verification pipeline should\n * declare the relevant fields as `false` so creative storyboards gate\n * cleanly.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n creative?: Partial<CreativeCapabilities>;\n\n /**\n * Account capabilities forwarded into `get_adcp_capabilities.account` as a\n * base layer. The framework's existing `requireOperatorAuth` and\n * `supportedBillings` projections overlay on top via the per-domain\n * `account` override, so explicit projections win on those keys.\n * `authorizationEndpoint`, `defaultBilling`, `requiredForProducts`, and\n * `sandbox` are pure adopter-driven additions exposed through this slot.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n account?: Partial<AccountCapabilities>;\n\n /**\n * Deep-merge overrides applied to the wire `get_adcp_capabilities`\n * response. Use this for fields that the top-level `DecisioningCapabilities`\n * shape doesn't model — `media_buy.propagation_surfaces`,\n * `media_buy.measurement_terms`, `signals.discovery_modes`, etc. The\n * framework's per-domain projections (auto-derived `media_buy`, `brand`,\n * `account`, `compliance_testing` blocks) are merged AFTER adopter\n * overrides, so framework-derived values remain authoritative on the keys\n * the projection engine handles.\n *\n * Mirrors `AdcpCapabilitiesConfig.overrides` on the lower-level\n * `createAdcpServer` API. Resolves the `definePlatform` passthrough gap\n * noted in adcp-client#2199.\n */\n overrides?: AdcpCapabilitiesOverrides;\n\n /**\n * Release-precision AdCP versions this platform supports (e.g. `[\"3.0\", \"3.1\"]`).\n * Forwarded into `get_adcp_capabilities.adcp.supported_versions`. 3.1+\n * sellers should declare here the same release-precision strings they\n * emit in `adcp_version` on responses; 3.0-pinned sellers can omit.\n *\n * Resolves the same gap previously noted for `supported_versions` —\n * was unreachable through `definePlatform` because\n * `CreateAdcpServerFromPlatformOptions` omits `'capabilities'` from\n * `AdcpServerConfig`. See adcp-client#2199.\n */\n supported_versions?: string[];\n\n /**\n * Platform-specific config. Strongly typed when the adopter uses the generic.\n * Example: `class GAM extends DecisioningPlatform<{ networkId: string }>`.\n */\n config: TConfig;\n\n /**\n * Optional Zod schema for runtime validation of `config`. When provided,\n * framework validates at platform construction time; missing or wrong-shaped\n * config rejects the agent at boot rather than at first request.\n */\n configSchema?: ZodSchema<TConfig>;\n}\n\nexport interface CreativeAgentRef {\n agent_url: string;\n /** Human-readable label for this creative agent. */\n name?: string;\n /** Optional allowlist of `format_id.id` values from THIS agent's catalog. Omit to include all. */\n format_ids?: string[];\n}\n\n/**\n * Targeting capabilities the platform supports in `create_media_buy`. Maps\n * to AdCP `GetAdcpCapabilitiesResponse.media_buy.execution.targeting`.\n *\n * Shape converged across two independently-evolved peer codebases (Scope3\n * `agentic-adapters`, Prebid `salesagent`). Per-geo-system flags rather than\n * coarse enums because the two implementations agreed: real platforms support\n * specific geo identifier formats (Nielsen DMA, Eurostat NUTS2, US ZIP+4), not\n * abstract \"metro\" / \"postal\" categories.\n */\nexport interface TargetingCapabilities {\n geo_countries?: boolean;\n geo_regions?: boolean;\n\n /** Metro / DMA identifier systems. */\n geo_metros?: {\n nielsen_dma?: boolean;\n uk_itl1?: boolean;\n uk_itl2?: boolean;\n eurostat_nuts2?: boolean;\n };\n\n /**\n * Postal-code identifier systems.\n *\n * AdCP 3.1.0-rc.10 prefers country-keyed arrays, e.g.\n * `{ US: ['zip'], GB: ['outward'] }`. Deprecated country-fused booleans\n * such as `{ us_zip: true }` remain accepted for 3.x adopters; the\n * framework projects both forms with `normalizePostalAreaSupport()` so old\n * and new buyers can read the capability safely during the migration.\n */\n geo_postal_areas?: TargetingPostalAreaSupport;\n\n /** Geographic-proximity targeting (radius / drive-time / arbitrary geometry). */\n geo_proximity?: {\n radius?: boolean;\n travel_time?: boolean;\n geometry?: boolean;\n transport_modes?: ReadonlyArray<'walking' | 'cycling' | 'driving' | 'public_transport'>;\n };\n\n /** Age-restriction targeting; `verification_methods` enumerates the assurance levels accepted. */\n age_restriction?: {\n supported?: boolean;\n verification_methods?: ReadonlyArray<\n 'facial_age_estimation' | 'id_document' | 'digital_id' | 'credit_card' | 'world_id'\n >;\n };\n\n device_platform?: boolean;\n device_type?: boolean;\n language?: boolean;\n audience_include?: boolean;\n audience_exclude?: boolean;\n\n /** Keyword-targeting match types accepted on positive-match terms. */\n keyword_targets?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n\n /** Negative-keyword match types accepted. */\n negative_keywords?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n}\n\nexport type TargetingPostalAreaSupport = {\n US?: readonly ('zip' | 'zip_plus_four')[];\n GB?: readonly ('outward' | 'full')[];\n CA?: readonly ('fsa' | 'full')[];\n DE?: readonly 'plz'[];\n CH?: readonly 'plz'[];\n AT?: readonly 'plz'[];\n FR?: readonly 'code_postal'[];\n AU?: readonly 'postcode'[];\n BR?: readonly 'cep'[];\n IN?: readonly 'pin'[];\n ZA?: readonly 'postal_code'[];\n /** @deprecated Use `US: ['zip']`. */\n us_zip?: boolean;\n /** @deprecated Use `US: ['zip_plus_four']`. */\n us_zip_plus_four?: boolean;\n /** @deprecated Use `GB: ['outward']`. */\n gb_outward?: boolean;\n /** @deprecated Use `GB: ['full']`. */\n gb_full?: boolean;\n /** @deprecated Use `CA: ['fsa']`. */\n ca_fsa?: boolean;\n /** @deprecated Use `CA: ['full']`. */\n ca_full?: boolean;\n /** @deprecated Use `DE: ['plz']`. */\n de_plz?: boolean;\n /** @deprecated Use `FR: ['code_postal']`. */\n fr_code_postal?: boolean;\n /** @deprecated Use `AU: ['postcode']`. */\n au_postcode?: boolean;\n /** @deprecated Use `CH: ['plz']`. */\n ch_plz?: boolean;\n /** @deprecated Use `AT: ['plz']`. */\n at_plz?: boolean;\n [country: `${Uppercase<string>}`]:\n | readonly (\n | 'zip'\n | 'zip_plus_four'\n | 'outward'\n | 'full'\n | 'fsa'\n | 'plz'\n | 'code_postal'\n | 'postcode'\n | 'cep'\n | 'pin'\n | 'postal_code'\n | 'custom'\n )[]\n | undefined;\n};\n\nconst LEGACY_POSTAL_SYSTEMS = {\n us_zip: { country: 'US', system: 'zip' },\n us_zip_plus_four: { country: 'US', system: 'zip_plus_four' },\n gb_outward: { country: 'GB', system: 'outward' },\n gb_full: { country: 'GB', system: 'full' },\n ca_fsa: { country: 'CA', system: 'fsa' },\n ca_full: { country: 'CA', system: 'full' },\n de_plz: { country: 'DE', system: 'plz' },\n fr_code_postal: { country: 'FR', system: 'code_postal' },\n au_postcode: { country: 'AU', system: 'postcode' },\n ch_plz: { country: 'CH', system: 'plz' },\n at_plz: { country: 'AT', system: 'plz' },\n} as const;\n\nconst LEGACY_POSTAL_BY_COUNTRY_SYSTEM = new Map(\n Object.entries(LEGACY_POSTAL_SYSTEMS).map(([legacy, { country, system }]) => [`${country}:${system}`, legacy])\n);\n\nconst POSTAL_SYSTEMS_BY_COUNTRY: Record<string, readonly string[]> = {\n US: ['zip', 'zip_plus_four'],\n GB: ['outward', 'full'],\n CA: ['fsa', 'full'],\n DE: ['plz'],\n CH: ['plz'],\n AT: ['plz'],\n FR: ['code_postal'],\n AU: ['postcode'],\n BR: ['cep'],\n IN: ['pin'],\n ZA: ['postal_code'],\n};\n\nconst GENERIC_POSTAL_SYSTEMS = ['postal_code', 'custom'] as const;\nconst POSTAL_COUNTRY_KEY_PATTERN = /^[A-Z]{2}$/;\n\nfunction appendUnique(target: string[], value: string): void {\n if (!target.includes(value)) target.push(value);\n}\n\nfunction assertSupportedPostalSystems(country: string, systems: readonly string[]): void {\n const allowed = POSTAL_SYSTEMS_BY_COUNTRY[country] ?? GENERIC_POSTAL_SYSTEMS;\n const invalid = systems.filter(system => !allowed.includes(system));\n if (invalid.length > 0) {\n throw new Error(\n `Invalid geo_postal_areas support for ${country}: ${invalid.join(', ')}. ` +\n `Supported systems are: ${allowed.join(', ')}.`\n );\n }\n}\n\n/**\n * Normalize postal-area capabilities across the AdCP 3.1.0-rc.10 migration.\n *\n * The wire schema now prefers `{ US: ['zip'] }` style country-local systems,\n * while the old `{ us_zip: true }` booleans stay deprecated but accepted\n * through 3.x. This helper is deliberately bidirectional:\n *\n * - legacy booleans add their country-keyed system;\n * - country-keyed systems backfill the matching legacy boolean when one exists;\n * - explicit unsupported legacy booleans are omitted unless the system is\n * otherwise advertised.\n */\nexport function normalizePostalAreaSupport(input: TargetingPostalAreaSupport): PostalAreaSupport {\n const normalized: Record<string, string[] | boolean> = {};\n\n for (const [key, value] of Object.entries(input)) {\n if (Array.isArray(value)) {\n if (!POSTAL_COUNTRY_KEY_PATTERN.test(key)) {\n throw new Error(\n `Invalid geo_postal_areas key \"${key}\". Use an ISO 3166-1 alpha-2 country code or a deprecated legacy boolean alias.`\n );\n }\n assertSupportedPostalSystems(key, value);\n const systems = (normalized[key] = Array.isArray(normalized[key]) ? (normalized[key] as string[]) : []);\n for (const system of value) appendUnique(systems, system);\n continue;\n }\n if (value === true && key in LEGACY_POSTAL_SYSTEMS) {\n const { country, system } = LEGACY_POSTAL_SYSTEMS[key as keyof typeof LEGACY_POSTAL_SYSTEMS];\n const systems = (normalized[country] = Array.isArray(normalized[country])\n ? (normalized[country] as string[])\n : []);\n appendUnique(systems, system);\n continue;\n }\n if (value === true) {\n throw new Error(\n `Invalid geo_postal_areas legacy alias \"${key}\". Use an ISO 3166-1 alpha-2 country key with supported postal systems.`\n );\n }\n }\n\n for (const [country, value] of Object.entries(normalized)) {\n if (!Array.isArray(value)) continue;\n for (const system of value) {\n const legacy = LEGACY_POSTAL_BY_COUNTRY_SYSTEM.get(`${country}:${system}`);\n if (legacy) normalized[legacy] = true;\n }\n }\n\n return normalized as PostalAreaSupport;\n}\n\nexport function normalizeTargetingCapabilities(input: TargetingCapabilities): _MediaBuyTargetingCapabilities {\n return {\n ...input,\n ...(input.geo_postal_areas && { geo_postal_areas: normalizePostalAreaSupport(input.geo_postal_areas) }),\n } as _MediaBuyTargetingCapabilities;\n}\n\n/**\n * Reporting capabilities the platform supports in `get_media_buy_delivery`.\n *\n * `availableDimensions` is the breakdown axes the platform can group\n * delivery rows by. Vocabulary converged across Scope3 and Prebid.\n */\nexport interface ReportingCapabilities {\n frequencies: ReadonlyArray<'hourly' | 'daily' | 'weekly'>;\n expected_delay_minutes: number;\n timezone: string;\n metrics: string[];\n date_range_support: 'date_range' | 'fixed_only';\n supports_webhooks: boolean;\n availableDimensions?: ReadonlyArray<\n 'geo' | 'device_type' | 'device_platform' | 'audience' | 'placement' | 'creative' | 'keyword' | 'catalog_item'\n >;\n}\n\n/**\n * Brand-protocol capabilities — projected onto the wire `brand` block of\n * `get_adcp_capabilities` via the framework's `overrides.brand` deep-merge\n * seam. Adopters who also implement `BrandRightsPlatform` get\n * `rights: true` auto-derived; the other four fields (`right_types`,\n * `available_uses`, `generation_providers`, `description`) are\n * adopter-declared.\n *\n * Wire spec: `protocol/get-adcp-capabilities-response.json#brand`.\n */\nexport type BrandCapabilities = NonNullable<NonNullable<GetAdCPCapabilitiesResponse['brand']>>;\n\n/**\n * Compliance-testing capabilities — projected onto the wire-side\n * `compliance_testing` block of `get_adcp_capabilities` so buyers and\n * conformance harnesses can discover which `comply_test_controller`\n * scenarios the agent supports.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#compliance_testing`.\n *\n * The `scenarios` array MUST be non-empty when this block is declared\n * (per the spec). `'list_scenarios'` is implicit — adopters don't need\n * to enumerate it.\n */\nexport interface ComplianceTestingCapabilities {\n /**\n * Scenarios this agent advertises support for. Wire enum is the\n * canonical scenario enum, excluding `list_scenarios` because that\n * is a discovery operation rather than a test capability. Framework\n * defaults this from the adopter-supplied `complyTest` adapter set\n * when omitted.\n */\n scenarios?: ReadonlyArray<_ComplianceTestingScenario>;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/server/decisioning/capabilities.ts"],"sourcesContent":["/**\n * DecisioningCapabilities — single source of truth for `get_adcp_capabilities`\n * response and any admin UI surface a host wants to render.\n *\n * Adopters declare once. Framework wires the wire-protocol response;\n * adopters' admin tools (or the SDK CLI's `validate_platform_config`) consume\n * the same dataclass so there's no drift between \"what the agent says it\n * supports\" and \"what it actually does.\"\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type { ZodSchema } from 'zod';\nimport type {\n AdCPSpecialism,\n MediaChannel,\n PaymentTerms,\n PricingModel,\n GetAdCPCapabilitiesResponse,\n PostalAreaSupport,\n} from '../../types/tools.generated';\nimport type { ProductMetricOptimizationLike } from '../../utils/capability-rollups';\nimport type { MediaBuyFeatures, AccountCapabilities, CreativeCapabilities } from '../../utils/capabilities';\nimport type { AdcpCapabilitiesOverrides } from '../create-adcp-server';\n\n/**\n * Pre-resolved alias for the wire `media_buy` block. Used as the projection\n * source for the five `media_buy.*` capability fields below so each typed\n * field references a single resolved shape instead of re-walking the\n * `GetAdCPCapabilitiesResponse` type graph independently. Without the\n * alias, `strict + skipLibCheck:false` adopters hit the TS instantiation\n * budget on the published `.d.ts` and tsc OOMs.\n */\ntype _MediaBuyCapabilities = NonNullable<GetAdCPCapabilitiesResponse['media_buy']>;\ntype _MediaBuyTargetingCapabilities = NonNullable<NonNullable<_MediaBuyCapabilities['execution']>['targeting']>;\ntype _ComplianceTestingScenario = NonNullable<\n NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']\n>[number];\n\nexport interface DecisioningCapabilities<TConfig = unknown> {\n /**\n * Specialisms claimed; framework type-checks these against implemented platform\n * interfaces. Arrays are `readonly` so adopters can declare with `as const`\n * (load-bearing for the `RequiredPlatformsFor<S>` compile-time gate).\n */\n specialisms: readonly AdCPSpecialism[];\n\n /**\n * Creative agents this seller composes with. Framework fetches format catalogs\n * from each (1h cache) and unions them on `list_creative_formats`. Self-hosting\n * sellers point at their own `agent_url`; framework calls into their\n * `CreativePlatform.listFormats()` locally instead of HTTP-fetching.\n *\n * `format_ids` filter (optional) subsets a single creative agent's catalog.\n * Useful when a creative agent hosts 50 formats but this seller only accepts\n * 10 of them. Filter scope is per-creative-agent: `[{ agent_url: A, format_ids: ['x'] }, { agent_url: B }]`\n * means \"from A only format x; from B all formats.\"\n *\n * Omit for signals-only platforms (`signal-marketplace`, `signal-owned`) — they\n * sell audience data access, not media inventory, and don't compose with creative agents.\n */\n creative_agents?: readonly CreativeAgentRef[];\n\n /**\n * Channels this platform sells.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channels to declare. Applies to signals (`signal-marketplace`, `signal-owned`),\n * governance (`governance-spend-authority`, `governance-delivery-monitor`,\n * `property-lists`, `collection-lists`, `content-standards`), creative-only\n * (`creative-ad-server`, `creative-template`, `creative-generative`), and\n * brand (`brand-rights`) platforms.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n channels?: readonly MediaChannel[];\n\n /**\n * Pricing models this platform supports.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channel-level pricing to declare. For signals platforms specifically, pricing\n * is declared per-signal in the signal descriptor's `pricing_options[]` instead.\n * Same non-media-buy specialism set as `channels` above.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n pricingModels?: readonly PricingModel[];\n\n /** Targeting capabilities. Optional — framework infers reasonable defaults if omitted. */\n targeting?: TargetingCapabilities;\n\n /** Reporting capabilities. Optional — framework infers reasonable defaults if omitted. */\n reporting?: ReportingCapabilities;\n\n /**\n * Audience-matching capabilities — projected onto\n * `get_adcp_capabilities.media_buy.audience_targeting`. Required for\n * audience-sync adopters (CRM-list adopters that accept hashed\n * identifiers + UID types) so buyers know which identifier shapes\n * the platform will match against and what minimum audience size /\n * matching latency to expect. Omit when the platform doesn't accept\n * external audience uploads.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.audience_targeting`.\n */\n audience_targeting?: NonNullable<_MediaBuyCapabilities['audience_targeting']>;\n\n /**\n * Conversion-tracking capabilities — projected onto\n * `get_adcp_capabilities.media_buy.conversion_tracking`. Required for\n * adopters that accept conversion events via `sync_event_sources` /\n * `log_event` so buyers know which event types, action sources,\n * attribution windows, and identifier shapes the platform supports.\n * Omit when the platform doesn't track conversions.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.conversion_tracking`.\n */\n conversion_tracking?: NonNullable<_MediaBuyCapabilities['conversion_tracking']>;\n\n /**\n * Content-standards capabilities — projected onto\n * `get_adcp_capabilities.media_buy.content_standards`. Required for\n * adopters claiming the `content-standards` specialism so buyers know\n * whether the platform runs local evaluation, which channels it\n * covers, and whether it supports webhook artifact delivery. Omit\n * when the platform doesn't ship content-standards artifacts.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.content_standards`.\n */\n content_standards?: NonNullable<_MediaBuyCapabilities['content_standards']>;\n\n /**\n * Seller-level rollup of optimization metrics — projected onto\n * `get_adcp_capabilities.media_buy.supported_optimization_metrics`.\n * Added in AdCP 3.1 (adcp#4669). The array union of every product's\n * `metric_optimization.supported_metrics`. Storyboard runners gate\n * `metric_optimization`-using scenarios on this field; declaring it\n * gives buyers an upfront signal of which optimization metrics the\n * seller can compute against (clicks, views, completed_views, etc.).\n *\n * Adopters can compute the rollup from their catalog using the\n * exported {@link rollupOptimizationMetricsFromProducts} helper —\n * keeps the declaration in sync with what products actually offer.\n * Empty arrays are normalized away and the wire field is omitted; use\n * omission to mean \"no seller-level metric rollup advertised\".\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.supported_optimization_metrics`.\n */\n supported_optimization_metrics?: NonNullable<_MediaBuyCapabilities['supported_optimization_metrics']>;\n\n /**\n * Static product-metric summary used for capability rollups.\n *\n * When this is present and `supported_optimization_metrics` is omitted,\n * the framework derives `media_buy.supported_optimization_metrics` as the\n * sorted union of every product summary's\n * `metric_optimization.supported_metrics`. Full AdCP `Product` objects work,\n * but this field is not a general product-discovery surface; a lightweight\n * startup summary with just the `metric_optimization` block is enough.\n * Dynamic per-account catalogs should continue to pass an explicit\n * `supported_optimization_metrics` override. If the derived union is empty,\n * the framework omits `supported_optimization_metrics` from the wire\n * capabilities response.\n */\n productCatalog?: ReadonlyArray<ProductMetricOptimizationLike>;\n\n /**\n * Frequency-cap support declaration — projected onto\n * `get_adcp_capabilities.media_buy.frequency_capping`. Added in AdCP\n * 3.1 (adcp#4670). Presence-only object with `supported_per_units` /\n * `supported_window_units` sub-fields declaring which frequency-cap\n * shapes the platform honors. Omit when the platform doesn't accept\n * frequency caps at all; buyers will avoid the field on `pacing.*`.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.frequency_capping`.\n */\n frequency_capping?: NonNullable<_MediaBuyCapabilities['frequency_capping']>;\n\n /**\n * Whether this seller commits to the proposal lifecycle on get_products.\n * Projected onto `get_adcp_capabilities.media_buy.supports_proposals`.\n * Direct-buy sellers should declare `false` so proposal-only compliance\n * storyboards are skipped; sellers with a ProposalManager are auto-derived\n * as `true` unless they override this explicitly.\n */\n supportsProposals?: boolean;\n\n /**\n * Brand-protocol capabilities. Projected onto the wire `brand` block of\n * `get_adcp_capabilities` (`brand: { rights, right_types, available_uses,\n * generation_providers, description }`). The framework auto-derives\n * `rights: true` when `BrandRightsPlatform` is supplied; adopters\n * declare the rest (right_types they license, RightUses they support,\n * generation providers they issue credentials for).\n *\n * REQUIRED when claiming the `'brand-rights'` specialism — enforced at\n * compile-time via `RequiredCapabilitiesFor<S>`.\n */\n brand?: BrandCapabilities;\n\n /**\n * Compliance-testing capabilities. The presence of this block declares\n * the deployment supports deterministic state-machine testing via the\n * `comply_test_controller` wire tool. Keep this block declared when using\n * `createAdcpServerFromPlatform(..., { complyTest })`; the framework makes\n * live principals byte-identical to a production seller that never wired the\n * controller by hiding this block, filtering `tools/list`, and returning MCP\n * method-not-found for direct live calls.\n *\n * When this block is present, `createAdcpServerFromPlatform` REQUIRES\n * `opts.complyTest` (the `ComplyControllerConfig` adapter set) to be\n * supplied — claiming the capability without implementing the\n * controller is a `PlatformConfigError` at construction.\n *\n * Inversely, supplying `opts.complyTest` without declaring this\n * capability is also caught — the framework derives `scenarios` from\n * the declared force/simulate/seed adapters and emits the discovery\n * field on `get_adcp_capabilities` automatically for sandbox/mock\n * principals. Live principals do not see the block.\n */\n compliance_testing?: ComplianceTestingCapabilities;\n\n /**\n * Billing parties this platform supports. `'operator'` = retail-media model\n * (Criteo, Amazon — operator pays the publisher and bills the brand).\n * `'agent'` = pass-through model (buyer's agent settles directly with the\n * platform). `'advertiser'` = seller invoices the advertiser directly,\n * bypassing operator settlement (advertiser-direct sell-side platforms where\n * the brand is the direct contractual counterparty). Defaults to `['agent']`\n * when omitted. To express advertiser-direct billing per account, set\n * `billing.invoicedTo` to a `BrandReference` (the framework maps any\n * `BrandReference` to `'advertiser'` on the wire).\n */\n supportedBillings?: ReadonlyArray<'operator' | 'agent' | 'advertiser'>;\n\n /**\n * Payment terms this platform accepts on `sync_accounts.payment_terms`.\n * Omit to leave terms validation to `accounts.upsert` (or to accept any\n * schema-valid value). When present, the framework rejects unsupported\n * requested terms with `PAYMENT_TERMS_NOT_SUPPORTED` before dispatching\n * the account entry to the adopter.\n */\n supportedPaymentTerms?: ReadonlyArray<PaymentTerms>;\n\n /**\n * If true, this platform refuses transactions without an authenticated\n * operator principal (operator-billed retail-media). Framework emits\n * `AUTH_REQUIRED` envelope before dispatching to the platform.\n */\n requireOperatorAuth?: boolean;\n\n /**\n * Media-buy feature flags forwarded into `get_adcp_capabilities.media_buy.features`.\n * Adopter values serve as the base; auto-derived `audience_targeting`,\n * `conversion_tracking`, and `content_standards` booleans take precedence\n * for those three keys (overlaid by the framework via the per-domain\n * `media_buy` override on the inner createAdcpServer call). Use this to\n * declare `inlineCreativeManagement` and `propertyListFiltering` directly\n * from `definePlatform`; declare not-supported feature blocks (e.g.\n * `inlineCreativeManagement: false`) so the conformance runner grades\n * them `not_applicable` instead of `fail`.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n features?: Partial<MediaBuyFeatures>;\n\n /**\n * Creative-protocol capabilities forwarded into `get_adcp_capabilities.creative`.\n * Use to declare `supportsCompliance`, `hasCreativeLibrary`,\n * `supportsGeneration`, and `supportsTransformation` from `definePlatform`.\n * Adopters that don't run a provenance-verification pipeline should\n * declare the relevant fields as `false` so creative storyboards gate\n * cleanly.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n creative?: Partial<CreativeCapabilities>;\n\n /**\n * Account capabilities forwarded into `get_adcp_capabilities.account` as a\n * base layer. The framework's existing `requireOperatorAuth` and\n * `supportedBillings` projections overlay on top via the per-domain\n * `account` override, so explicit projections win on those keys.\n * `authorizationEndpoint`, `defaultBilling`, `requiredForProducts`, and\n * `sandbox` are pure adopter-driven additions exposed through this slot.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n account?: Partial<AccountCapabilities>;\n\n /**\n * Deep-merge overrides applied to the wire `get_adcp_capabilities`\n * response. Use this for fields that the top-level `DecisioningCapabilities`\n * shape doesn't model — `media_buy.propagation_surfaces`,\n * `media_buy.measurement_terms`, `signals.discovery_modes`, etc. The\n * framework's per-domain projections (auto-derived `media_buy`, `brand`,\n * `account`, `compliance_testing` blocks) are merged AFTER adopter\n * overrides, so framework-derived values remain authoritative on the keys\n * the projection engine handles.\n *\n * Mirrors `AdcpCapabilitiesConfig.overrides` on the lower-level\n * `createAdcpServer` API. Resolves the `definePlatform` passthrough gap\n * noted in adcp-client#2199.\n */\n overrides?: AdcpCapabilitiesOverrides;\n\n /**\n * Release-precision AdCP versions this platform supports (e.g. `[\"3.0\", \"3.1\"]`).\n * Forwarded into `get_adcp_capabilities.adcp.supported_versions`. 3.1+\n * sellers should declare here the same release-precision strings they\n * emit in `adcp_version` on responses; 3.0-pinned sellers can omit.\n *\n * Resolves the same gap previously noted for `supported_versions` —\n * was unreachable through `definePlatform` because\n * `CreateAdcpServerFromPlatformOptions` omits `'capabilities'` from\n * `AdcpServerConfig`. See adcp-client#2199.\n */\n supported_versions?: string[];\n\n /**\n * Platform-specific config. Strongly typed when the adopter uses the generic.\n * Example: `class GAM extends DecisioningPlatform<{ networkId: string }>`.\n */\n config: TConfig;\n\n /**\n * Optional Zod schema for runtime validation of `config`. When provided,\n * framework validates at platform construction time; missing or wrong-shaped\n * config rejects the agent at boot rather than at first request.\n */\n configSchema?: ZodSchema<TConfig>;\n}\n\nexport interface CreativeAgentRef {\n agent_url: string;\n /** Human-readable label for this creative agent. */\n name?: string;\n /** Optional allowlist of `format_id.id` values from THIS agent's catalog. Omit to include all. */\n format_ids?: string[];\n}\n\n/**\n * Targeting capabilities the platform supports in `create_media_buy`. Maps\n * to AdCP `GetAdcpCapabilitiesResponse.media_buy.execution.targeting`.\n *\n * Shape converged across two independently-evolved peer codebases (Scope3\n * `agentic-adapters`, Prebid `salesagent`). Per-geo-system flags rather than\n * coarse enums because the two implementations agreed: real platforms support\n * specific geo identifier formats (Nielsen DMA, Eurostat NUTS2, US ZIP+4), not\n * abstract \"metro\" / \"postal\" categories.\n */\nexport interface TargetingCapabilities {\n geo_countries?: boolean;\n geo_regions?: boolean;\n\n /** Metro / DMA identifier systems. */\n geo_metros?: {\n nielsen_dma?: boolean;\n uk_itl1?: boolean;\n uk_itl2?: boolean;\n eurostat_nuts2?: boolean;\n };\n\n /**\n * Postal-code identifier systems.\n *\n * AdCP 3.1.0-rc.10 prefers country-keyed arrays, e.g.\n * `{ US: ['zip'], GB: ['outward'] }`. Deprecated country-fused booleans\n * such as `{ us_zip: true }` remain accepted for 3.x adopters; the\n * framework projects both forms with `normalizePostalAreaSupport()` so old\n * and new buyers can read the capability safely during the migration.\n */\n geo_postal_areas?: TargetingPostalAreaSupport;\n\n /** Geographic-proximity targeting (radius / drive-time / arbitrary geometry). */\n geo_proximity?: {\n radius?: boolean;\n travel_time?: boolean;\n geometry?: boolean;\n transport_modes?: ReadonlyArray<'walking' | 'cycling' | 'driving' | 'public_transport'>;\n };\n\n /** Age-restriction targeting; `verification_methods` enumerates the assurance levels accepted. */\n age_restriction?: {\n supported?: boolean;\n verification_methods?: ReadonlyArray<\n 'facial_age_estimation' | 'id_document' | 'digital_id' | 'credit_card' | 'world_id'\n >;\n };\n\n device_platform?: boolean;\n device_type?: boolean;\n language?: boolean;\n audience_include?: boolean;\n audience_exclude?: boolean;\n\n /** Keyword-targeting match types accepted on positive-match terms. */\n keyword_targets?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n\n /** Negative-keyword match types accepted. */\n negative_keywords?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n}\n\nexport type TargetingPostalAreaSupport = {\n US?: readonly ('zip' | 'zip_plus_four')[];\n GB?: readonly ('outward' | 'full')[];\n CA?: readonly ('fsa' | 'full')[];\n DE?: readonly 'plz'[];\n CH?: readonly 'plz'[];\n AT?: readonly 'plz'[];\n FR?: readonly 'code_postal'[];\n AU?: readonly 'postcode'[];\n BR?: readonly 'cep'[];\n IN?: readonly 'pin'[];\n ZA?: readonly 'postal_code'[];\n /** @deprecated Use `US: ['zip']`. */\n us_zip?: boolean;\n /** @deprecated Use `US: ['zip_plus_four']`. */\n us_zip_plus_four?: boolean;\n /** @deprecated Use `GB: ['outward']`. */\n gb_outward?: boolean;\n /** @deprecated Use `GB: ['full']`. */\n gb_full?: boolean;\n /** @deprecated Use `CA: ['fsa']`. */\n ca_fsa?: boolean;\n /** @deprecated Use `CA: ['full']`. */\n ca_full?: boolean;\n /** @deprecated Use `DE: ['plz']`. */\n de_plz?: boolean;\n /** @deprecated Use `FR: ['code_postal']`. */\n fr_code_postal?: boolean;\n /** @deprecated Use `AU: ['postcode']`. */\n au_postcode?: boolean;\n /** @deprecated Use `CH: ['plz']`. */\n ch_plz?: boolean;\n /** @deprecated Use `AT: ['plz']`. */\n at_plz?: boolean;\n [country: `${Uppercase<string>}`]:\n | readonly (\n | 'zip'\n | 'zip_plus_four'\n | 'outward'\n | 'full'\n | 'fsa'\n | 'plz'\n | 'code_postal'\n | 'postcode'\n | 'cep'\n | 'pin'\n | 'postal_code'\n | 'custom'\n )[]\n | undefined;\n};\n\nconst LEGACY_POSTAL_SYSTEMS = {\n us_zip: { country: 'US', system: 'zip' },\n us_zip_plus_four: { country: 'US', system: 'zip_plus_four' },\n gb_outward: { country: 'GB', system: 'outward' },\n gb_full: { country: 'GB', system: 'full' },\n ca_fsa: { country: 'CA', system: 'fsa' },\n ca_full: { country: 'CA', system: 'full' },\n de_plz: { country: 'DE', system: 'plz' },\n fr_code_postal: { country: 'FR', system: 'code_postal' },\n au_postcode: { country: 'AU', system: 'postcode' },\n ch_plz: { country: 'CH', system: 'plz' },\n at_plz: { country: 'AT', system: 'plz' },\n} as const;\n\nconst LEGACY_POSTAL_BY_COUNTRY_SYSTEM = new Map(\n Object.entries(LEGACY_POSTAL_SYSTEMS).map(([legacy, { country, system }]) => [`${country}:${system}`, legacy])\n);\n\nconst POSTAL_SYSTEMS_BY_COUNTRY: Record<string, readonly string[]> = {\n US: ['zip', 'zip_plus_four'],\n GB: ['outward', 'full'],\n CA: ['fsa', 'full'],\n DE: ['plz'],\n CH: ['plz'],\n AT: ['plz'],\n FR: ['code_postal'],\n AU: ['postcode'],\n BR: ['cep'],\n IN: ['pin'],\n ZA: ['postal_code'],\n};\n\nconst GENERIC_POSTAL_SYSTEMS = ['postal_code', 'custom'] as const;\nconst POSTAL_COUNTRY_KEY_PATTERN = /^[A-Z]{2}$/;\n\nfunction appendUnique(target: string[], value: string): void {\n if (!target.includes(value)) target.push(value);\n}\n\nfunction assertSupportedPostalSystems(country: string, systems: readonly string[]): void {\n const allowed = POSTAL_SYSTEMS_BY_COUNTRY[country] ?? GENERIC_POSTAL_SYSTEMS;\n const invalid = systems.filter(system => !allowed.includes(system));\n if (invalid.length > 0) {\n throw new Error(\n `Invalid geo_postal_areas support for ${country}: ${invalid.join(', ')}. ` +\n `Supported systems are: ${allowed.join(', ')}.`\n );\n }\n}\n\n/**\n * Normalize postal-area capabilities across the AdCP 3.1.0-rc.10 migration.\n *\n * The wire schema now prefers `{ US: ['zip'] }` style country-local systems,\n * while the old `{ us_zip: true }` booleans stay deprecated but accepted\n * through 3.x. This helper is deliberately bidirectional:\n *\n * - legacy booleans add their country-keyed system;\n * - country-keyed systems backfill the matching legacy boolean when one exists;\n * - explicit unsupported legacy booleans are omitted unless the system is\n * otherwise advertised.\n */\nexport function normalizePostalAreaSupport(input: TargetingPostalAreaSupport): PostalAreaSupport {\n const normalized: Record<string, string[] | boolean> = {};\n\n for (const [key, value] of Object.entries(input)) {\n if (Array.isArray(value)) {\n if (!POSTAL_COUNTRY_KEY_PATTERN.test(key)) {\n throw new Error(\n `Invalid geo_postal_areas key \"${key}\". Use an ISO 3166-1 alpha-2 country code or a deprecated legacy boolean alias.`\n );\n }\n assertSupportedPostalSystems(key, value);\n const systems = (normalized[key] = Array.isArray(normalized[key]) ? (normalized[key] as string[]) : []);\n for (const system of value) appendUnique(systems, system);\n continue;\n }\n if (value === true && key in LEGACY_POSTAL_SYSTEMS) {\n const { country, system } = LEGACY_POSTAL_SYSTEMS[key as keyof typeof LEGACY_POSTAL_SYSTEMS];\n const systems = (normalized[country] = Array.isArray(normalized[country])\n ? (normalized[country] as string[])\n : []);\n appendUnique(systems, system);\n continue;\n }\n if (value === true) {\n throw new Error(\n `Invalid geo_postal_areas legacy alias \"${key}\". Use an ISO 3166-1 alpha-2 country key with supported postal systems.`\n );\n }\n }\n\n for (const [country, value] of Object.entries(normalized)) {\n if (!Array.isArray(value)) continue;\n for (const system of value) {\n const legacy = LEGACY_POSTAL_BY_COUNTRY_SYSTEM.get(`${country}:${system}`);\n if (legacy) normalized[legacy] = true;\n }\n }\n\n return normalized as PostalAreaSupport;\n}\n\nexport function normalizeTargetingCapabilities(input: TargetingCapabilities): _MediaBuyTargetingCapabilities {\n return {\n ...input,\n ...(input.geo_postal_areas && { geo_postal_areas: normalizePostalAreaSupport(input.geo_postal_areas) }),\n } as _MediaBuyTargetingCapabilities;\n}\n\n/**\n * Reporting capabilities the platform supports in `get_media_buy_delivery`.\n *\n * `availableDimensions` is the breakdown axes the platform can group\n * delivery rows by. Vocabulary converged across Scope3 and Prebid.\n */\nexport interface ReportingCapabilities {\n frequencies: ReadonlyArray<'hourly' | 'daily' | 'weekly'>;\n expected_delay_minutes: number;\n timezone: string;\n metrics: string[];\n date_range_support: 'date_range' | 'fixed_only';\n supports_webhooks: boolean;\n availableDimensions?: ReadonlyArray<\n 'geo' | 'device_type' | 'device_platform' | 'audience' | 'placement' | 'creative' | 'keyword' | 'catalog_item'\n >;\n}\n\n/**\n * Brand-protocol capabilities — projected onto the wire `brand` block of\n * `get_adcp_capabilities` via the framework's `overrides.brand` deep-merge\n * seam. Adopters who also implement `BrandRightsPlatform` get\n * `rights: true` auto-derived; the other four fields (`right_types`,\n * `available_uses`, `generation_providers`, `description`) are\n * adopter-declared.\n *\n * Wire spec: `protocol/get-adcp-capabilities-response.json#brand`.\n */\nexport type BrandCapabilities = NonNullable<NonNullable<GetAdCPCapabilitiesResponse['brand']>>;\n\n/**\n * Compliance-testing capabilities — projected onto the wire-side\n * `compliance_testing` block of `get_adcp_capabilities` so buyers and\n * conformance harnesses can discover which `comply_test_controller`\n * scenarios the agent supports.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#compliance_testing`.\n *\n * The `scenarios` array MUST be non-empty when this block is declared\n * (per the spec). `'list_scenarios'` is implicit — adopters don't need\n * to enumerate it.\n */\nexport interface ComplianceTestingCapabilities {\n /**\n * Scenarios this agent advertises support for. The wire field is open to\n * implementation-specific string values; canonical controller scenarios\n * are recommendations, not an enum constraint. `list_scenarios` remains a\n * discovery operation rather than a test capability. Framework defaults\n * this from the adopter-supplied `complyTest` adapter set when omitted.\n */\n scenarios?: ReadonlyArray<_ComplianceTestingScenario>;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/server/decisioning/capabilities.ts"],"sourcesContent":["/**\n * DecisioningCapabilities — single source of truth for `get_adcp_capabilities`\n * response and any admin UI surface a host wants to render.\n *\n * Adopters declare once. Framework wires the wire-protocol response;\n * adopters' admin tools (or the SDK CLI's `validate_platform_config`) consume\n * the same dataclass so there's no drift between \"what the agent says it\n * supports\" and \"what it actually does.\"\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type { ZodSchema } from 'zod';\nimport type {\n AdCPSpecialism,\n MediaChannel,\n PaymentTerms,\n PricingModel,\n GetAdCPCapabilitiesResponse,\n PostalAreaSupport,\n} from '../../types/tools.generated';\nimport type { ProductMetricOptimizationLike } from '../../utils/capability-rollups';\nimport type { MediaBuyFeatures, AccountCapabilities, CreativeCapabilities } from '../../utils/capabilities';\nimport type { AdcpCapabilitiesOverrides } from '../create-adcp-server';\n\n/**\n * Pre-resolved alias for the wire `media_buy` block. Used as the projection\n * source for the five `media_buy.*` capability fields below so each typed\n * field references a single resolved shape instead of re-walking the\n * `GetAdCPCapabilitiesResponse` type graph independently. Without the\n * alias, `strict + skipLibCheck:false` adopters hit the TS instantiation\n * budget on the published `.d.ts` and tsc OOMs.\n */\ntype _MediaBuyCapabilities = NonNullable<GetAdCPCapabilitiesResponse['media_buy']>;\ntype _MediaBuyTargetingCapabilities = NonNullable<NonNullable<_MediaBuyCapabilities['execution']>['targeting']>;\ntype _ComplianceTestingScenario = NonNullable<\n NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']\n>[number];\n\nexport interface DecisioningCapabilities<TConfig = unknown> {\n /**\n * Specialisms claimed; framework type-checks these against implemented platform\n * interfaces. Arrays are `readonly` so adopters can declare with `as const`\n * (load-bearing for the `RequiredPlatformsFor<S>` compile-time gate).\n */\n specialisms: readonly AdCPSpecialism[];\n\n /**\n * Creative agents this seller composes with. Framework fetches format catalogs\n * from each (1h cache) and unions them on `list_creative_formats`. Self-hosting\n * sellers point at their own `agent_url`; framework calls into their\n * `CreativePlatform.listFormats()` locally instead of HTTP-fetching.\n *\n * `format_ids` filter (optional) subsets a single creative agent's catalog.\n * Useful when a creative agent hosts 50 formats but this seller only accepts\n * 10 of them. Filter scope is per-creative-agent: `[{ agent_url: A, format_ids: ['x'] }, { agent_url: B }]`\n * means \"from A only format x; from B all formats.\"\n *\n * Omit for signals-only platforms (`signal-marketplace`, `signal-owned`) — they\n * sell audience data access, not media inventory, and don't compose with creative agents.\n */\n creative_agents?: readonly CreativeAgentRef[];\n\n /**\n * Channels this platform sells.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channels to declare. Applies to signals (`signal-marketplace`, `signal-owned`),\n * governance (`governance-spend-authority`, `governance-delivery-monitor`,\n * `property-lists`, `collection-lists`, `content-standards`), creative-only\n * (`creative-ad-server`, `creative-template`, `creative-generative`), and\n * brand (`brand-rights`) platforms.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n channels?: readonly MediaChannel[];\n\n /**\n * Pricing models this platform supports.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channel-level pricing to declare. For signals platforms specifically, pricing\n * is declared per-signal in the signal descriptor's `pricing_options[]` instead.\n * Same non-media-buy specialism set as `channels` above.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n pricingModels?: readonly PricingModel[];\n\n /** Targeting capabilities. Optional — framework infers reasonable defaults if omitted. */\n targeting?: TargetingCapabilities;\n\n /** Reporting capabilities. Optional — framework infers reasonable defaults if omitted. */\n reporting?: ReportingCapabilities;\n\n /**\n * Audience-matching capabilities — projected onto\n * `get_adcp_capabilities.media_buy.audience_targeting`. Required for\n * audience-sync adopters (CRM-list adopters that accept hashed\n * identifiers + UID types) so buyers know which identifier shapes\n * the platform will match against and what minimum audience size /\n * matching latency to expect. Omit when the platform doesn't accept\n * external audience uploads.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.audience_targeting`.\n */\n audience_targeting?: NonNullable<_MediaBuyCapabilities['audience_targeting']>;\n\n /**\n * Conversion-tracking capabilities — projected onto\n * `get_adcp_capabilities.media_buy.conversion_tracking`. Required for\n * adopters that accept conversion events via `sync_event_sources` /\n * `log_event` so buyers know which event types, action sources,\n * attribution windows, and identifier shapes the platform supports.\n * Omit when the platform doesn't track conversions.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.conversion_tracking`.\n */\n conversion_tracking?: NonNullable<_MediaBuyCapabilities['conversion_tracking']>;\n\n /**\n * Content-standards capabilities — projected onto\n * `get_adcp_capabilities.media_buy.content_standards`. Required for\n * adopters claiming the `content-standards` specialism so buyers know\n * whether the platform runs local evaluation, which channels it\n * covers, and whether it supports webhook artifact delivery. Omit\n * when the platform doesn't ship content-standards artifacts.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.content_standards`.\n */\n content_standards?: NonNullable<_MediaBuyCapabilities['content_standards']>;\n\n /**\n * Seller-level rollup of optimization metrics — projected onto\n * `get_adcp_capabilities.media_buy.supported_optimization_metrics`.\n * Added in AdCP 3.1 (adcp#4669). The array union of every product's\n * `metric_optimization.supported_metrics`. Storyboard runners gate\n * `metric_optimization`-using scenarios on this field; declaring it\n * gives buyers an upfront signal of which optimization metrics the\n * seller can compute against (clicks, views, completed_views, etc.).\n *\n * Adopters can compute the rollup from their catalog using the\n * exported {@link rollupOptimizationMetricsFromProducts} helper —\n * keeps the declaration in sync with what products actually offer.\n * Empty arrays are normalized away and the wire field is omitted; use\n * omission to mean \"no seller-level metric rollup advertised\".\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.supported_optimization_metrics`.\n */\n supported_optimization_metrics?: NonNullable<_MediaBuyCapabilities['supported_optimization_metrics']>;\n\n /**\n * Static product-metric summary used for capability rollups.\n *\n * When this is present and `supported_optimization_metrics` is omitted,\n * the framework derives `media_buy.supported_optimization_metrics` as the\n * sorted union of every product summary's\n * `metric_optimization.supported_metrics`. Full AdCP `Product` objects work,\n * but this field is not a general product-discovery surface; a lightweight\n * startup summary with just the `metric_optimization` block is enough.\n * Dynamic per-account catalogs should continue to pass an explicit\n * `supported_optimization_metrics` override. If the derived union is empty,\n * the framework omits `supported_optimization_metrics` from the wire\n * capabilities response.\n */\n productCatalog?: ReadonlyArray<ProductMetricOptimizationLike>;\n\n /**\n * Frequency-cap support declaration — projected onto\n * `get_adcp_capabilities.media_buy.frequency_capping`. Added in AdCP\n * 3.1 (adcp#4670). Presence-only object with `supported_per_units` /\n * `supported_window_units` sub-fields declaring which frequency-cap\n * shapes the platform honors. Omit when the platform doesn't accept\n * frequency caps at all; buyers will avoid the field on `pacing.*`.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.frequency_capping`.\n */\n frequency_capping?: NonNullable<_MediaBuyCapabilities['frequency_capping']>;\n\n /**\n * Whether this seller commits to the proposal lifecycle on get_products.\n * Projected onto `get_adcp_capabilities.media_buy.supports_proposals`.\n * Direct-buy sellers should declare `false` so proposal-only compliance\n * storyboards are skipped; sellers with a ProposalManager are auto-derived\n * as `true` unless they override this explicitly.\n */\n supportsProposals?: boolean;\n\n /**\n * Brand-protocol capabilities. Projected onto the wire `brand` block of\n * `get_adcp_capabilities` (`brand: { rights, right_types, available_uses,\n * generation_providers, description }`). The framework auto-derives\n * `rights: true` when `BrandRightsPlatform` is supplied; adopters\n * declare the rest (right_types they license, RightUses they support,\n * generation providers they issue credentials for).\n *\n * REQUIRED when claiming the `'brand-rights'` specialism — enforced at\n * compile-time via `RequiredCapabilitiesFor<S>`.\n */\n brand?: BrandCapabilities;\n\n /**\n * Compliance-testing capabilities. The presence of this block declares\n * the deployment supports deterministic state-machine testing via the\n * `comply_test_controller` wire tool. Keep this block declared when using\n * `createAdcpServerFromPlatform(..., { complyTest })`; the framework makes\n * live principals byte-identical to a production seller that never wired the\n * controller by hiding this block, filtering `tools/list`, and returning MCP\n * method-not-found for direct live calls.\n *\n * When this block is present, `createAdcpServerFromPlatform` REQUIRES\n * `opts.complyTest` (the `ComplyControllerConfig` adapter set) to be\n * supplied — claiming the capability without implementing the\n * controller is a `PlatformConfigError` at construction.\n *\n * Inversely, supplying `opts.complyTest` without declaring this\n * capability is also caught — the framework derives `scenarios` from\n * the declared force/simulate/seed adapters and emits the discovery\n * field on `get_adcp_capabilities` automatically for sandbox/mock\n * principals. Live principals do not see the block.\n */\n compliance_testing?: ComplianceTestingCapabilities;\n\n /**\n * Billing parties this platform supports. `'operator'` = retail-media model\n * (Criteo, Amazon — operator pays the publisher and bills the brand).\n * `'agent'` = pass-through model (buyer's agent settles directly with the\n * platform). `'advertiser'` = seller invoices the advertiser directly,\n * bypassing operator settlement (advertiser-direct sell-side platforms where\n * the brand is the direct contractual counterparty). Defaults to `['agent']`\n * when omitted. To express advertiser-direct billing per account, set\n * `billing.invoicedTo` to a `BrandReference` (the framework maps any\n * `BrandReference` to `'advertiser'` on the wire).\n */\n supportedBillings?: ReadonlyArray<'operator' | 'agent' | 'advertiser'>;\n\n /**\n * Payment terms this platform accepts on `sync_accounts.payment_terms`.\n * Omit to leave terms validation to `accounts.upsert` (or to accept any\n * schema-valid value). When present, the framework rejects unsupported\n * requested terms with `PAYMENT_TERMS_NOT_SUPPORTED` before dispatching\n * the account entry to the adopter.\n */\n supportedPaymentTerms?: ReadonlyArray<PaymentTerms>;\n\n /**\n * If true, this platform refuses transactions without an authenticated\n * operator principal (operator-billed retail-media). Framework emits\n * `AUTH_REQUIRED` envelope before dispatching to the platform.\n */\n requireOperatorAuth?: boolean;\n\n /**\n * Media-buy feature flags forwarded into `get_adcp_capabilities.media_buy.features`.\n * Adopter values serve as the base; auto-derived `audience_targeting`,\n * `conversion_tracking`, and `content_standards` booleans take precedence\n * for those three keys (overlaid by the framework via the per-domain\n * `media_buy` override on the inner createAdcpServer call). Use this to\n * declare `inlineCreativeManagement` and `propertyListFiltering` directly\n * from `definePlatform`; declare not-supported feature blocks (e.g.\n * `inlineCreativeManagement: false`) so the conformance runner grades\n * them `not_applicable` instead of `fail`.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n features?: Partial<MediaBuyFeatures>;\n\n /**\n * Creative-protocol capabilities forwarded into `get_adcp_capabilities.creative`.\n * Use to declare `supportsCompliance`, `hasCreativeLibrary`,\n * `supportsGeneration`, and `supportsTransformation` from `definePlatform`.\n * Adopters that don't run a provenance-verification pipeline should\n * declare the relevant fields as `false` so creative storyboards gate\n * cleanly.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n creative?: Partial<CreativeCapabilities>;\n\n /**\n * Account capabilities forwarded into `get_adcp_capabilities.account` as a\n * base layer. The framework's existing `requireOperatorAuth` and\n * `supportedBillings` projections overlay on top via the per-domain\n * `account` override, so explicit projections win on those keys.\n * `authorizationEndpoint`, `defaultBilling`, `requiredForProducts`, and\n * `sandbox` are pure adopter-driven additions exposed through this slot.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n account?: Partial<AccountCapabilities>;\n\n /**\n * Deep-merge overrides applied to the wire `get_adcp_capabilities`\n * response. Use this for fields that the top-level `DecisioningCapabilities`\n * shape doesn't model — `media_buy.propagation_surfaces`,\n * `media_buy.measurement_terms`, `signals.discovery_modes`, etc. The\n * framework's per-domain projections (auto-derived `media_buy`, `brand`,\n * `account`, `compliance_testing` blocks) are merged AFTER adopter\n * overrides, so framework-derived values remain authoritative on the keys\n * the projection engine handles.\n *\n * Mirrors `AdcpCapabilitiesConfig.overrides` on the lower-level\n * `createAdcpServer` API. Resolves the `definePlatform` passthrough gap\n * noted in adcp-client#2199.\n */\n overrides?: AdcpCapabilitiesOverrides;\n\n /**\n * Release-precision AdCP versions this platform supports (e.g. `[\"3.0\", \"3.1\"]`).\n * Forwarded into `get_adcp_capabilities.adcp.supported_versions`. 3.1+\n * sellers should declare here the same release-precision strings they\n * emit in `adcp_version` on responses; 3.0-pinned sellers can omit.\n *\n * Resolves the same gap previously noted for `supported_versions` —\n * was unreachable through `definePlatform` because\n * `CreateAdcpServerFromPlatformOptions` omits `'capabilities'` from\n * `AdcpServerConfig`. See adcp-client#2199.\n */\n supported_versions?: string[];\n\n /**\n * Platform-specific config. Strongly typed when the adopter uses the generic.\n * Example: `class GAM extends DecisioningPlatform<{ networkId: string }>`.\n */\n config: TConfig;\n\n /**\n * Optional Zod schema for runtime validation of `config`. When provided,\n * framework validates at platform construction time; missing or wrong-shaped\n * config rejects the agent at boot rather than at first request.\n */\n configSchema?: ZodSchema<TConfig>;\n}\n\nexport interface CreativeAgentRef {\n agent_url: string;\n /** Human-readable label for this creative agent. */\n name?: string;\n /** Optional allowlist of `format_id.id` values from THIS agent's catalog. Omit to include all. */\n format_ids?: string[];\n}\n\n/**\n * Targeting capabilities the platform supports in `create_media_buy`. Maps\n * to AdCP `GetAdcpCapabilitiesResponse.media_buy.execution.targeting`.\n *\n * Shape converged across two independently-evolved peer codebases (Scope3\n * `agentic-adapters`, Prebid `salesagent`). Per-geo-system flags rather than\n * coarse enums because the two implementations agreed: real platforms support\n * specific geo identifier formats (Nielsen DMA, Eurostat NUTS2, US ZIP+4), not\n * abstract \"metro\" / \"postal\" categories.\n */\nexport interface TargetingCapabilities {\n geo_countries?: boolean;\n geo_regions?: boolean;\n\n /** Metro / DMA identifier systems. */\n geo_metros?: {\n nielsen_dma?: boolean;\n uk_itl1?: boolean;\n uk_itl2?: boolean;\n eurostat_nuts2?: boolean;\n };\n\n /**\n * Postal-code identifier systems.\n *\n * AdCP 3.1.0-rc.10 prefers country-keyed arrays, e.g.\n * `{ US: ['zip'], GB: ['outward'] }`. Deprecated country-fused booleans\n * such as `{ us_zip: true }` remain accepted for 3.x adopters; the\n * framework projects both forms with `normalizePostalAreaSupport()` so old\n * and new buyers can read the capability safely during the migration.\n */\n geo_postal_areas?: TargetingPostalAreaSupport;\n\n /** Geographic-proximity targeting (radius / drive-time / arbitrary geometry). */\n geo_proximity?: {\n radius?: boolean;\n travel_time?: boolean;\n geometry?: boolean;\n transport_modes?: ReadonlyArray<'walking' | 'cycling' | 'driving' | 'public_transport'>;\n };\n\n /** Age-restriction targeting; `verification_methods` enumerates the assurance levels accepted. */\n age_restriction?: {\n supported?: boolean;\n verification_methods?: ReadonlyArray<\n 'facial_age_estimation' | 'id_document' | 'digital_id' | 'credit_card' | 'world_id'\n >;\n };\n\n device_platform?: boolean;\n device_type?: boolean;\n language?: boolean;\n audience_include?: boolean;\n audience_exclude?: boolean;\n\n /** Keyword-targeting match types accepted on positive-match terms. */\n keyword_targets?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n\n /** Negative-keyword match types accepted. */\n negative_keywords?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n}\n\nexport type TargetingPostalAreaSupport = {\n US?: readonly ('zip' | 'zip_plus_four')[];\n GB?: readonly ('outward' | 'full')[];\n CA?: readonly ('fsa' | 'full')[];\n DE?: readonly 'plz'[];\n CH?: readonly 'plz'[];\n AT?: readonly 'plz'[];\n FR?: readonly 'code_postal'[];\n AU?: readonly 'postcode'[];\n BR?: readonly 'cep'[];\n IN?: readonly 'pin'[];\n ZA?: readonly 'postal_code'[];\n /** @deprecated Use `US: ['zip']`. */\n us_zip?: boolean;\n /** @deprecated Use `US: ['zip_plus_four']`. */\n us_zip_plus_four?: boolean;\n /** @deprecated Use `GB: ['outward']`. */\n gb_outward?: boolean;\n /** @deprecated Use `GB: ['full']`. */\n gb_full?: boolean;\n /** @deprecated Use `CA: ['fsa']`. */\n ca_fsa?: boolean;\n /** @deprecated Use `CA: ['full']`. */\n ca_full?: boolean;\n /** @deprecated Use `DE: ['plz']`. */\n de_plz?: boolean;\n /** @deprecated Use `FR: ['code_postal']`. */\n fr_code_postal?: boolean;\n /** @deprecated Use `AU: ['postcode']`. */\n au_postcode?: boolean;\n /** @deprecated Use `CH: ['plz']`. */\n ch_plz?: boolean;\n /** @deprecated Use `AT: ['plz']`. */\n at_plz?: boolean;\n [country: `${Uppercase<string>}`]:\n | readonly (\n | 'zip'\n | 'zip_plus_four'\n | 'outward'\n | 'full'\n | 'fsa'\n | 'plz'\n | 'code_postal'\n | 'postcode'\n | 'cep'\n | 'pin'\n | 'postal_code'\n | 'custom'\n )[]\n | undefined;\n};\n\nconst LEGACY_POSTAL_SYSTEMS = {\n us_zip: { country: 'US', system: 'zip' },\n us_zip_plus_four: { country: 'US', system: 'zip_plus_four' },\n gb_outward: { country: 'GB', system: 'outward' },\n gb_full: { country: 'GB', system: 'full' },\n ca_fsa: { country: 'CA', system: 'fsa' },\n ca_full: { country: 'CA', system: 'full' },\n de_plz: { country: 'DE', system: 'plz' },\n fr_code_postal: { country: 'FR', system: 'code_postal' },\n au_postcode: { country: 'AU', system: 'postcode' },\n ch_plz: { country: 'CH', system: 'plz' },\n at_plz: { country: 'AT', system: 'plz' },\n} as const;\n\nconst LEGACY_POSTAL_BY_COUNTRY_SYSTEM = new Map(\n Object.entries(LEGACY_POSTAL_SYSTEMS).map(([legacy, { country, system }]) => [`${country}:${system}`, legacy])\n);\n\nconst POSTAL_SYSTEMS_BY_COUNTRY: Record<string, readonly string[]> = {\n US: ['zip', 'zip_plus_four'],\n GB: ['outward', 'full'],\n CA: ['fsa', 'full'],\n DE: ['plz'],\n CH: ['plz'],\n AT: ['plz'],\n FR: ['code_postal'],\n AU: ['postcode'],\n BR: ['cep'],\n IN: ['pin'],\n ZA: ['postal_code'],\n};\n\nconst GENERIC_POSTAL_SYSTEMS = ['postal_code', 'custom'] as const;\nconst POSTAL_COUNTRY_KEY_PATTERN = /^[A-Z]{2}$/;\n\nfunction appendUnique(target: string[], value: string): void {\n if (!target.includes(value)) target.push(value);\n}\n\nfunction assertSupportedPostalSystems(country: string, systems: readonly string[]): void {\n const allowed = POSTAL_SYSTEMS_BY_COUNTRY[country] ?? GENERIC_POSTAL_SYSTEMS;\n const invalid = systems.filter(system => !allowed.includes(system));\n if (invalid.length > 0) {\n throw new Error(\n `Invalid geo_postal_areas support for ${country}: ${invalid.join(', ')}. ` +\n `Supported systems are: ${allowed.join(', ')}.`\n );\n }\n}\n\n/**\n * Normalize postal-area capabilities across the AdCP 3.1.0-rc.10 migration.\n *\n * The wire schema now prefers `{ US: ['zip'] }` style country-local systems,\n * while the old `{ us_zip: true }` booleans stay deprecated but accepted\n * through 3.x. This helper is deliberately bidirectional:\n *\n * - legacy booleans add their country-keyed system;\n * - country-keyed systems backfill the matching legacy boolean when one exists;\n * - explicit unsupported legacy booleans are omitted unless the system is\n * otherwise advertised.\n */\nexport function normalizePostalAreaSupport(input: TargetingPostalAreaSupport): PostalAreaSupport {\n const normalized: Record<string, string[] | boolean> = {};\n\n for (const [key, value] of Object.entries(input)) {\n if (Array.isArray(value)) {\n if (!POSTAL_COUNTRY_KEY_PATTERN.test(key)) {\n throw new Error(\n `Invalid geo_postal_areas key \"${key}\". Use an ISO 3166-1 alpha-2 country code or a deprecated legacy boolean alias.`\n );\n }\n assertSupportedPostalSystems(key, value);\n const systems = (normalized[key] = Array.isArray(normalized[key]) ? (normalized[key] as string[]) : []);\n for (const system of value) appendUnique(systems, system);\n continue;\n }\n if (value === true && key in LEGACY_POSTAL_SYSTEMS) {\n const { country, system } = LEGACY_POSTAL_SYSTEMS[key as keyof typeof LEGACY_POSTAL_SYSTEMS];\n const systems = (normalized[country] = Array.isArray(normalized[country])\n ? (normalized[country] as string[])\n : []);\n appendUnique(systems, system);\n continue;\n }\n if (value === true) {\n throw new Error(\n `Invalid geo_postal_areas legacy alias \"${key}\". Use an ISO 3166-1 alpha-2 country key with supported postal systems.`\n );\n }\n }\n\n for (const [country, value] of Object.entries(normalized)) {\n if (!Array.isArray(value)) continue;\n for (const system of value) {\n const legacy = LEGACY_POSTAL_BY_COUNTRY_SYSTEM.get(`${country}:${system}`);\n if (legacy) normalized[legacy] = true;\n }\n }\n\n return normalized as PostalAreaSupport;\n}\n\nexport function normalizeTargetingCapabilities(input: TargetingCapabilities): _MediaBuyTargetingCapabilities {\n return {\n ...input,\n ...(input.geo_postal_areas && { geo_postal_areas: normalizePostalAreaSupport(input.geo_postal_areas) }),\n } as _MediaBuyTargetingCapabilities;\n}\n\n/**\n * Reporting capabilities the platform supports in `get_media_buy_delivery`.\n *\n * `availableDimensions` is the breakdown axes the platform can group\n * delivery rows by. Vocabulary converged across Scope3 and Prebid.\n */\nexport interface ReportingCapabilities {\n frequencies: ReadonlyArray<'hourly' | 'daily' | 'weekly'>;\n expected_delay_minutes: number;\n timezone: string;\n metrics: string[];\n date_range_support: 'date_range' | 'fixed_only';\n supports_webhooks: boolean;\n availableDimensions?: ReadonlyArray<\n 'geo' | 'device_type' | 'device_platform' | 'audience' | 'placement' | 'creative' | 'keyword' | 'catalog_item'\n >;\n}\n\n/**\n * Brand-protocol capabilities — projected onto the wire `brand` block of\n * `get_adcp_capabilities` via the framework's `overrides.brand` deep-merge\n * seam. Adopters who also implement `BrandRightsPlatform` get\n * `rights: true` auto-derived; the other four fields (`right_types`,\n * `available_uses`, `generation_providers`, `description`) are\n * adopter-declared.\n *\n * Wire spec: `protocol/get-adcp-capabilities-response.json#brand`.\n */\nexport type BrandCapabilities = NonNullable<NonNullable<GetAdCPCapabilitiesResponse['brand']>>;\n\n/**\n * Compliance-testing capabilities — projected onto the wire-side\n * `compliance_testing` block of `get_adcp_capabilities` so buyers and\n * conformance harnesses can discover which `comply_test_controller`\n * scenarios the agent supports.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#compliance_testing`.\n *\n * The `scenarios` array MUST be non-empty when this block is declared\n * (per the spec). `'list_scenarios'` is implicit — adopters don't need\n * to enumerate it.\n */\nexport interface ComplianceTestingCapabilities {\n /**\n * Scenarios this agent advertises support for. Wire enum is the\n * canonical scenario enum, excluding `list_scenarios` because that\n * is a discovery operation rather than a test capability. Framework\n * defaults this from the adopter-supplied `complyTest` adapter set\n * when omitted.\n */\n scenarios?: ReadonlyArray<_ComplianceTestingScenario>;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/server/decisioning/capabilities.ts"],"sourcesContent":["/**\n * DecisioningCapabilities — single source of truth for `get_adcp_capabilities`\n * response and any admin UI surface a host wants to render.\n *\n * Adopters declare once. Framework wires the wire-protocol response;\n * adopters' admin tools (or the SDK CLI's `validate_platform_config`) consume\n * the same dataclass so there's no drift between \"what the agent says it\n * supports\" and \"what it actually does.\"\n *\n * Status: Preview / 6.0.\n *\n * @public\n */\n\nimport type { ZodSchema } from 'zod';\nimport type {\n AdCPSpecialism,\n MediaChannel,\n PaymentTerms,\n PricingModel,\n GetAdCPCapabilitiesResponse,\n PostalAreaSupport,\n} from '../../types/tools.generated';\nimport type { ProductMetricOptimizationLike } from '../../utils/capability-rollups';\nimport type { MediaBuyFeatures, AccountCapabilities, CreativeCapabilities } from '../../utils/capabilities';\nimport type { AdcpCapabilitiesOverrides } from '../create-adcp-server';\n\n/**\n * Pre-resolved alias for the wire `media_buy` block. Used as the projection\n * source for the five `media_buy.*` capability fields below so each typed\n * field references a single resolved shape instead of re-walking the\n * `GetAdCPCapabilitiesResponse` type graph independently. Without the\n * alias, `strict + skipLibCheck:false` adopters hit the TS instantiation\n * budget on the published `.d.ts` and tsc OOMs.\n */\ntype _MediaBuyCapabilities = NonNullable<GetAdCPCapabilitiesResponse['media_buy']>;\ntype _MediaBuyTargetingCapabilities = NonNullable<NonNullable<_MediaBuyCapabilities['execution']>['targeting']>;\ntype _ComplianceTestingScenario = NonNullable<\n NonNullable<GetAdCPCapabilitiesResponse['compliance_testing']>['scenarios']\n>[number];\n\nexport interface DecisioningCapabilities<TConfig = unknown> {\n /**\n * Specialisms claimed; framework type-checks these against implemented platform\n * interfaces. Arrays are `readonly` so adopters can declare with `as const`\n * (load-bearing for the `RequiredPlatformsFor<S>` compile-time gate).\n */\n specialisms: readonly AdCPSpecialism[];\n\n /**\n * Creative agents this seller composes with. Framework fetches format catalogs\n * from each (1h cache) and unions them on `list_creative_formats`. Self-hosting\n * sellers point at their own `agent_url`; framework calls into their\n * `CreativePlatform.listFormats()` locally instead of HTTP-fetching.\n *\n * `format_ids` filter (optional) subsets a single creative agent's catalog.\n * Useful when a creative agent hosts 50 formats but this seller only accepts\n * 10 of them. Filter scope is per-creative-agent: `[{ agent_url: A, format_ids: ['x'] }, { agent_url: B }]`\n * means \"from A only format x; from B all formats.\"\n *\n * Omit for signals-only platforms (`signal-marketplace`, `signal-owned`) — they\n * sell audience data access, not media inventory, and don't compose with creative agents.\n */\n creative_agents?: readonly CreativeAgentRef[];\n\n /**\n * Channels this platform sells.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channels to declare. Applies to signals (`signal-marketplace`, `signal-owned`),\n * governance (`governance-spend-authority`, `governance-delivery-monitor`,\n * `property-lists`, `collection-lists`, `content-standards`), creative-only\n * (`creative-ad-server`, `creative-template`, `creative-generative`), and\n * brand (`brand-rights`) platforms.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n channels?: readonly MediaChannel[];\n\n /**\n * Pricing models this platform supports.\n *\n * Omit for non-media-buy platforms — they don't sell ad inventory and have no\n * channel-level pricing to declare. For signals platforms specifically, pricing\n * is declared per-signal in the signal descriptor's `pricing_options[]` instead.\n * Same non-media-buy specialism set as `channels` above.\n *\n * **Required at runtime for media-buy platforms.** `validatePlatform` (called\n * by `createAdcpServerFromPlatform`) throws `PlatformConfigError` when any\n * `sales-*` specialism is claimed and this field is absent.\n */\n pricingModels?: readonly PricingModel[];\n\n /** Targeting capabilities. Optional — framework infers reasonable defaults if omitted. */\n targeting?: TargetingCapabilities;\n\n /** Reporting capabilities. Optional — framework infers reasonable defaults if omitted. */\n reporting?: ReportingCapabilities;\n\n /**\n * Audience-matching capabilities — projected onto\n * `get_adcp_capabilities.media_buy.audience_targeting`. Required for\n * audience-sync adopters (CRM-list adopters that accept hashed\n * identifiers + UID types) so buyers know which identifier shapes\n * the platform will match against and what minimum audience size /\n * matching latency to expect. Omit when the platform doesn't accept\n * external audience uploads.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.audience_targeting`.\n */\n audience_targeting?: NonNullable<_MediaBuyCapabilities['audience_targeting']>;\n\n /**\n * Conversion-tracking capabilities — projected onto\n * `get_adcp_capabilities.media_buy.conversion_tracking`. Required for\n * adopters that accept conversion events via `sync_event_sources` /\n * `log_event` so buyers know which event types, action sources,\n * attribution windows, and identifier shapes the platform supports.\n * Omit when the platform doesn't track conversions.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.conversion_tracking`.\n */\n conversion_tracking?: NonNullable<_MediaBuyCapabilities['conversion_tracking']>;\n\n /**\n * Content-standards capabilities — projected onto\n * `get_adcp_capabilities.media_buy.content_standards`. Required for\n * adopters claiming the `content-standards` specialism so buyers know\n * whether the platform runs local evaluation, which channels it\n * covers, and whether it supports webhook artifact delivery. Omit\n * when the platform doesn't ship content-standards artifacts.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.content_standards`.\n */\n content_standards?: NonNullable<_MediaBuyCapabilities['content_standards']>;\n\n /**\n * Seller-level rollup of optimization metrics — projected onto\n * `get_adcp_capabilities.media_buy.supported_optimization_metrics`.\n * Added in AdCP 3.1 (adcp#4669). The array union of every product's\n * `metric_optimization.supported_metrics`. Storyboard runners gate\n * `metric_optimization`-using scenarios on this field; declaring it\n * gives buyers an upfront signal of which optimization metrics the\n * seller can compute against (clicks, views, completed_views, etc.).\n *\n * Adopters can compute the rollup from their catalog using the\n * exported {@link rollupOptimizationMetricsFromProducts} helper —\n * keeps the declaration in sync with what products actually offer.\n * Empty arrays are normalized away and the wire field is omitted; use\n * omission to mean \"no seller-level metric rollup advertised\".\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.supported_optimization_metrics`.\n */\n supported_optimization_metrics?: NonNullable<_MediaBuyCapabilities['supported_optimization_metrics']>;\n\n /**\n * Static product-metric summary used for capability rollups.\n *\n * When this is present and `supported_optimization_metrics` is omitted,\n * the framework derives `media_buy.supported_optimization_metrics` as the\n * sorted union of every product summary's\n * `metric_optimization.supported_metrics`. Full AdCP `Product` objects work,\n * but this field is not a general product-discovery surface; a lightweight\n * startup summary with just the `metric_optimization` block is enough.\n * Dynamic per-account catalogs should continue to pass an explicit\n * `supported_optimization_metrics` override. If the derived union is empty,\n * the framework omits `supported_optimization_metrics` from the wire\n * capabilities response.\n */\n productCatalog?: ReadonlyArray<ProductMetricOptimizationLike>;\n\n /**\n * Frequency-cap support declaration — projected onto\n * `get_adcp_capabilities.media_buy.frequency_capping`. Added in AdCP\n * 3.1 (adcp#4670). Presence-only object with `supported_per_units` /\n * `supported_window_units` sub-fields declaring which frequency-cap\n * shapes the platform honors. Omit when the platform doesn't accept\n * frequency caps at all; buyers will avoid the field on `pacing.*`.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#media_buy.frequency_capping`.\n */\n frequency_capping?: NonNullable<_MediaBuyCapabilities['frequency_capping']>;\n\n /**\n * Whether this seller commits to the proposal lifecycle on get_products.\n * Projected onto `get_adcp_capabilities.media_buy.supports_proposals`.\n * Direct-buy sellers should declare `false` so proposal-only compliance\n * storyboards are skipped; sellers with a ProposalManager are auto-derived\n * as `true` unless they override this explicitly.\n */\n supportsProposals?: boolean;\n\n /**\n * Brand-protocol capabilities. Projected onto the wire `brand` block of\n * `get_adcp_capabilities` (`brand: { rights, right_types, available_uses,\n * generation_providers, description }`). The framework auto-derives\n * `rights: true` when `BrandRightsPlatform` is supplied; adopters\n * declare the rest (right_types they license, RightUses they support,\n * generation providers they issue credentials for).\n *\n * REQUIRED when claiming the `'brand-rights'` specialism — enforced at\n * compile-time via `RequiredCapabilitiesFor<S>`.\n */\n brand?: BrandCapabilities;\n\n /**\n * Compliance-testing capabilities. The presence of this block declares\n * the deployment supports deterministic state-machine testing via the\n * `comply_test_controller` wire tool. Keep this block declared when using\n * `createAdcpServerFromPlatform(..., { complyTest })`; the framework makes\n * live principals byte-identical to a production seller that never wired the\n * controller by hiding this block, filtering `tools/list`, and returning MCP\n * method-not-found for direct live calls.\n *\n * When this block is present, `createAdcpServerFromPlatform` REQUIRES\n * `opts.complyTest` (the `ComplyControllerConfig` adapter set) to be\n * supplied — claiming the capability without implementing the\n * controller is a `PlatformConfigError` at construction.\n *\n * Inversely, supplying `opts.complyTest` without declaring this\n * capability is also caught — the framework derives `scenarios` from\n * the declared force/simulate/seed adapters and emits the discovery\n * field on `get_adcp_capabilities` automatically for sandbox/mock\n * principals. Live principals do not see the block.\n */\n compliance_testing?: ComplianceTestingCapabilities;\n\n /**\n * Billing parties this platform supports. `'operator'` = retail-media model\n * (Criteo, Amazon — operator pays the publisher and bills the brand).\n * `'agent'` = pass-through model (buyer's agent settles directly with the\n * platform). `'advertiser'` = seller invoices the advertiser directly,\n * bypassing operator settlement (advertiser-direct sell-side platforms where\n * the brand is the direct contractual counterparty). Defaults to `['agent']`\n * when omitted. To express advertiser-direct billing per account, set\n * `billing.invoicedTo` to a `BrandReference` (the framework maps any\n * `BrandReference` to `'advertiser'` on the wire).\n */\n supportedBillings?: ReadonlyArray<'operator' | 'agent' | 'advertiser'>;\n\n /**\n * Payment terms this platform accepts on `sync_accounts.payment_terms`.\n * Omit to leave terms validation to `accounts.upsert` (or to accept any\n * schema-valid value). When present, the framework rejects unsupported\n * requested terms with `PAYMENT_TERMS_NOT_SUPPORTED` before dispatching\n * the account entry to the adopter.\n */\n supportedPaymentTerms?: ReadonlyArray<PaymentTerms>;\n\n /**\n * If true, this platform refuses transactions without an authenticated\n * operator principal (operator-billed retail-media). Framework emits\n * `AUTH_REQUIRED` envelope before dispatching to the platform.\n */\n requireOperatorAuth?: boolean;\n\n /**\n * Media-buy feature flags forwarded into `get_adcp_capabilities.media_buy.features`.\n * Adopter values serve as the base; auto-derived `audience_targeting`,\n * `conversion_tracking`, and `content_standards` booleans take precedence\n * for those three keys (overlaid by the framework via the per-domain\n * `media_buy` override on the inner createAdcpServer call). Use this to\n * declare `inlineCreativeManagement` and `propertyListFiltering` directly\n * from `definePlatform`; declare not-supported feature blocks (e.g.\n * `inlineCreativeManagement: false`) so the conformance runner grades\n * them `not_applicable` instead of `fail`.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n features?: Partial<MediaBuyFeatures>;\n\n /**\n * Creative-protocol capabilities forwarded into `get_adcp_capabilities.creative`.\n * Use to declare `supportsCompliance`, `hasCreativeLibrary`,\n * `supportsGeneration`, and `supportsTransformation` from `definePlatform`.\n * Adopters that don't run a provenance-verification pipeline should\n * declare the relevant fields as `false` so creative storyboards gate\n * cleanly.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n creative?: Partial<CreativeCapabilities>;\n\n /**\n * Account capabilities forwarded into `get_adcp_capabilities.account` as a\n * base layer. The framework's existing `requireOperatorAuth` and\n * `supportedBillings` projections overlay on top via the per-domain\n * `account` override, so explicit projections win on those keys.\n * `authorizationEndpoint`, `defaultBilling`, `requiredForProducts`, and\n * `sandbox` are pure adopter-driven additions exposed through this slot.\n *\n * Resolves the `definePlatform` passthrough gap noted in adcp-client#2199.\n */\n account?: Partial<AccountCapabilities>;\n\n /**\n * Deep-merge overrides applied to the wire `get_adcp_capabilities`\n * response. Use this for fields that the top-level `DecisioningCapabilities`\n * shape doesn't model — `media_buy.propagation_surfaces`,\n * `media_buy.measurement_terms`, `signals.discovery_modes`, etc. The\n * framework's per-domain projections (auto-derived `media_buy`, `brand`,\n * `account`, `compliance_testing` blocks) are merged AFTER adopter\n * overrides, so framework-derived values remain authoritative on the keys\n * the projection engine handles.\n *\n * Mirrors `AdcpCapabilitiesConfig.overrides` on the lower-level\n * `createAdcpServer` API. Resolves the `definePlatform` passthrough gap\n * noted in adcp-client#2199.\n */\n overrides?: AdcpCapabilitiesOverrides;\n\n /**\n * Release-precision AdCP versions this platform supports (e.g. `[\"3.0\", \"3.1\"]`).\n * Forwarded into `get_adcp_capabilities.adcp.supported_versions`. 3.1+\n * sellers should declare here the same release-precision strings they\n * emit in `adcp_version` on responses; 3.0-pinned sellers can omit.\n *\n * Resolves the same gap previously noted for `supported_versions` —\n * was unreachable through `definePlatform` because\n * `CreateAdcpServerFromPlatformOptions` omits `'capabilities'` from\n * `AdcpServerConfig`. See adcp-client#2199.\n */\n supported_versions?: string[];\n\n /**\n * Platform-specific config. Strongly typed when the adopter uses the generic.\n * Example: `class GAM extends DecisioningPlatform<{ networkId: string }>`.\n */\n config: TConfig;\n\n /**\n * Optional Zod schema for runtime validation of `config`. When provided,\n * framework validates at platform construction time; missing or wrong-shaped\n * config rejects the agent at boot rather than at first request.\n */\n configSchema?: ZodSchema<TConfig>;\n}\n\nexport interface CreativeAgentRef {\n agent_url: string;\n /** Human-readable label for this creative agent. */\n name?: string;\n /** Optional allowlist of `format_id.id` values from THIS agent's catalog. Omit to include all. */\n format_ids?: string[];\n}\n\n/**\n * Targeting capabilities the platform supports in `create_media_buy`. Maps\n * to AdCP `GetAdcpCapabilitiesResponse.media_buy.execution.targeting`.\n *\n * Shape converged across two independently-evolved peer codebases (Scope3\n * `agentic-adapters`, Prebid `salesagent`). Per-geo-system flags rather than\n * coarse enums because the two implementations agreed: real platforms support\n * specific geo identifier formats (Nielsen DMA, Eurostat NUTS2, US ZIP+4), not\n * abstract \"metro\" / \"postal\" categories.\n */\nexport interface TargetingCapabilities {\n geo_countries?: boolean;\n geo_regions?: boolean;\n\n /** Metro / DMA identifier systems. */\n geo_metros?: {\n nielsen_dma?: boolean;\n uk_itl1?: boolean;\n uk_itl2?: boolean;\n eurostat_nuts2?: boolean;\n };\n\n /**\n * Postal-code identifier systems.\n *\n * AdCP 3.1.0-rc.10 prefers country-keyed arrays, e.g.\n * `{ US: ['zip'], GB: ['outward'] }`. Deprecated country-fused booleans\n * such as `{ us_zip: true }` remain accepted for 3.x adopters; the\n * framework projects both forms with `normalizePostalAreaSupport()` so old\n * and new buyers can read the capability safely during the migration.\n */\n geo_postal_areas?: TargetingPostalAreaSupport;\n\n /** Geographic-proximity targeting (radius / drive-time / arbitrary geometry). */\n geo_proximity?: {\n radius?: boolean;\n travel_time?: boolean;\n geometry?: boolean;\n transport_modes?: ReadonlyArray<'walking' | 'cycling' | 'driving' | 'public_transport'>;\n };\n\n /** Age-restriction targeting; `verification_methods` enumerates the assurance levels accepted. */\n age_restriction?: {\n supported?: boolean;\n verification_methods?: ReadonlyArray<\n 'facial_age_estimation' | 'id_document' | 'digital_id' | 'credit_card' | 'world_id'\n >;\n };\n\n device_platform?: boolean;\n device_type?: boolean;\n language?: boolean;\n audience_include?: boolean;\n audience_exclude?: boolean;\n\n /** Keyword-targeting match types accepted on positive-match terms. */\n keyword_targets?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n\n /** Negative-keyword match types accepted. */\n negative_keywords?: {\n supported_match_types: ReadonlyArray<'broad' | 'phrase' | 'exact'>;\n };\n}\n\nexport type TargetingPostalAreaSupport = {\n US?: readonly ('zip' | 'zip_plus_four')[];\n GB?: readonly ('outward' | 'full')[];\n CA?: readonly ('fsa' | 'full')[];\n DE?: readonly 'plz'[];\n CH?: readonly 'plz'[];\n AT?: readonly 'plz'[];\n FR?: readonly 'code_postal'[];\n AU?: readonly 'postcode'[];\n BR?: readonly 'cep'[];\n IN?: readonly 'pin'[];\n ZA?: readonly 'postal_code'[];\n /** @deprecated Use `US: ['zip']`. */\n us_zip?: boolean;\n /** @deprecated Use `US: ['zip_plus_four']`. */\n us_zip_plus_four?: boolean;\n /** @deprecated Use `GB: ['outward']`. */\n gb_outward?: boolean;\n /** @deprecated Use `GB: ['full']`. */\n gb_full?: boolean;\n /** @deprecated Use `CA: ['fsa']`. */\n ca_fsa?: boolean;\n /** @deprecated Use `CA: ['full']`. */\n ca_full?: boolean;\n /** @deprecated Use `DE: ['plz']`. */\n de_plz?: boolean;\n /** @deprecated Use `FR: ['code_postal']`. */\n fr_code_postal?: boolean;\n /** @deprecated Use `AU: ['postcode']`. */\n au_postcode?: boolean;\n /** @deprecated Use `CH: ['plz']`. */\n ch_plz?: boolean;\n /** @deprecated Use `AT: ['plz']`. */\n at_plz?: boolean;\n [country: `${Uppercase<string>}`]:\n | readonly (\n | 'zip'\n | 'zip_plus_four'\n | 'outward'\n | 'full'\n | 'fsa'\n | 'plz'\n | 'code_postal'\n | 'postcode'\n | 'cep'\n | 'pin'\n | 'postal_code'\n | 'custom'\n )[]\n | undefined;\n};\n\nconst LEGACY_POSTAL_SYSTEMS = {\n us_zip: { country: 'US', system: 'zip' },\n us_zip_plus_four: { country: 'US', system: 'zip_plus_four' },\n gb_outward: { country: 'GB', system: 'outward' },\n gb_full: { country: 'GB', system: 'full' },\n ca_fsa: { country: 'CA', system: 'fsa' },\n ca_full: { country: 'CA', system: 'full' },\n de_plz: { country: 'DE', system: 'plz' },\n fr_code_postal: { country: 'FR', system: 'code_postal' },\n au_postcode: { country: 'AU', system: 'postcode' },\n ch_plz: { country: 'CH', system: 'plz' },\n at_plz: { country: 'AT', system: 'plz' },\n} as const;\n\nconst LEGACY_POSTAL_BY_COUNTRY_SYSTEM = new Map(\n Object.entries(LEGACY_POSTAL_SYSTEMS).map(([legacy, { country, system }]) => [`${country}:${system}`, legacy])\n);\n\nconst POSTAL_SYSTEMS_BY_COUNTRY: Record<string, readonly string[]> = {\n US: ['zip', 'zip_plus_four'],\n GB: ['outward', 'full'],\n CA: ['fsa', 'full'],\n DE: ['plz'],\n CH: ['plz'],\n AT: ['plz'],\n FR: ['code_postal'],\n AU: ['postcode'],\n BR: ['cep'],\n IN: ['pin'],\n ZA: ['postal_code'],\n};\n\nconst GENERIC_POSTAL_SYSTEMS = ['postal_code', 'custom'] as const;\nconst POSTAL_COUNTRY_KEY_PATTERN = /^[A-Z]{2}$/;\n\nfunction appendUnique(target: string[], value: string): void {\n if (!target.includes(value)) target.push(value);\n}\n\nfunction assertSupportedPostalSystems(country: string, systems: readonly string[]): void {\n const allowed = POSTAL_SYSTEMS_BY_COUNTRY[country] ?? GENERIC_POSTAL_SYSTEMS;\n const invalid = systems.filter(system => !allowed.includes(system));\n if (invalid.length > 0) {\n throw new Error(\n `Invalid geo_postal_areas support for ${country}: ${invalid.join(', ')}. ` +\n `Supported systems are: ${allowed.join(', ')}.`\n );\n }\n}\n\n/**\n * Normalize postal-area capabilities across the AdCP 3.1.0-rc.10 migration.\n *\n * The wire schema now prefers `{ US: ['zip'] }` style country-local systems,\n * while the old `{ us_zip: true }` booleans stay deprecated but accepted\n * through 3.x. This helper is deliberately bidirectional:\n *\n * - legacy booleans add their country-keyed system;\n * - country-keyed systems backfill the matching legacy boolean when one exists;\n * - explicit unsupported legacy booleans are omitted unless the system is\n * otherwise advertised.\n */\nexport function normalizePostalAreaSupport(input: TargetingPostalAreaSupport): PostalAreaSupport {\n const normalized: Record<string, string[] | boolean> = {};\n\n for (const [key, value] of Object.entries(input)) {\n if (Array.isArray(value)) {\n if (!POSTAL_COUNTRY_KEY_PATTERN.test(key)) {\n throw new Error(\n `Invalid geo_postal_areas key \"${key}\". Use an ISO 3166-1 alpha-2 country code or a deprecated legacy boolean alias.`\n );\n }\n assertSupportedPostalSystems(key, value);\n const systems = (normalized[key] = Array.isArray(normalized[key]) ? (normalized[key] as string[]) : []);\n for (const system of value) appendUnique(systems, system);\n continue;\n }\n if (value === true && key in LEGACY_POSTAL_SYSTEMS) {\n const { country, system } = LEGACY_POSTAL_SYSTEMS[key as keyof typeof LEGACY_POSTAL_SYSTEMS];\n const systems = (normalized[country] = Array.isArray(normalized[country])\n ? (normalized[country] as string[])\n : []);\n appendUnique(systems, system);\n continue;\n }\n if (value === true) {\n throw new Error(\n `Invalid geo_postal_areas legacy alias \"${key}\". Use an ISO 3166-1 alpha-2 country key with supported postal systems.`\n );\n }\n }\n\n for (const [country, value] of Object.entries(normalized)) {\n if (!Array.isArray(value)) continue;\n for (const system of value) {\n const legacy = LEGACY_POSTAL_BY_COUNTRY_SYSTEM.get(`${country}:${system}`);\n if (legacy) normalized[legacy] = true;\n }\n }\n\n return normalized as PostalAreaSupport;\n}\n\nexport function normalizeTargetingCapabilities(input: TargetingCapabilities): _MediaBuyTargetingCapabilities {\n return {\n ...input,\n ...(input.geo_postal_areas && { geo_postal_areas: normalizePostalAreaSupport(input.geo_postal_areas) }),\n } as _MediaBuyTargetingCapabilities;\n}\n\n/**\n * Reporting capabilities the platform supports in `get_media_buy_delivery`.\n *\n * `availableDimensions` is the breakdown axes the platform can group\n * delivery rows by. Vocabulary converged across Scope3 and Prebid.\n */\nexport interface ReportingCapabilities {\n frequencies: ReadonlyArray<'hourly' | 'daily' | 'weekly'>;\n expected_delay_minutes: number;\n timezone: string;\n metrics: string[];\n date_range_support: 'date_range' | 'fixed_only';\n supports_webhooks: boolean;\n availableDimensions?: ReadonlyArray<\n 'geo' | 'device_type' | 'device_platform' | 'audience' | 'placement' | 'creative' | 'keyword' | 'catalog_item'\n >;\n}\n\n/**\n * Brand-protocol capabilities — projected onto the wire `brand` block of\n * `get_adcp_capabilities` via the framework's `overrides.brand` deep-merge\n * seam. Adopters who also implement `BrandRightsPlatform` get\n * `rights: true` auto-derived; the other four fields (`right_types`,\n * `available_uses`, `generation_providers`, `description`) are\n * adopter-declared.\n *\n * Wire spec: `protocol/get-adcp-capabilities-response.json#brand`.\n */\nexport type BrandCapabilities = NonNullable<NonNullable<GetAdCPCapabilitiesResponse['brand']>>;\n\n/**\n * Compliance-testing capabilities — projected onto the wire-side\n * `compliance_testing` block of `get_adcp_capabilities` so buyers and\n * conformance harnesses can discover which `comply_test_controller`\n * scenarios the agent supports.\n *\n * Wire spec: `core/get-adcp-capabilities-response.json#compliance_testing`.\n *\n * The `scenarios` array MUST be non-empty when this block is declared\n * (per the spec). `'list_scenarios'` is implicit — adopters don't need\n * to enumerate it.\n */\nexport interface ComplianceTestingCapabilities {\n /**\n * Scenarios this agent advertises support for. The wire field is open to\n * implementation-specific string values; canonical controller scenarios\n * are recommendations, not an enum constraint. `list_scenarios` remains a\n * discovery operation rather than a test capability. Framework defaults\n * this from the adopter-supplied `complyTest` adapter set when omitted.\n */\n scenarios?: ReadonlyArray<_ComplianceTestingScenario>;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAIV,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/lib/testing/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAIV,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAc,MAAM,EAAE,MAAM,SAAS,CAAC;AAuB7F;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAU7E;AAID;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAMjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,gBAAgB,CAOrE;AAaD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAE/D;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,KAAK,GAAG,KAAa,EAAE,OAAO,GAAE,WAAgB,4BA+G5G;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC7D,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,UAAU,CAEpF;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,oBAAoB,CAMxG;AA0ED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC,CAQ1D;AAqDD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,OAAO,CAAC,CAAC,EAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CA4B5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,UAAU,EAClB,MAAM,CAAC,EAAE,WAAW;AACpB,iFAAiF;AACjF,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC,CAuE1D;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAAC,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAkF3E;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAC,mBAAmB,CAAC,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC,CAsF/E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IACT,OAAO,EAAE,YAAY,CAAC,mBAAmB,CAAC,CAAC;IAC3C,UAAU,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B,CAAC,CAoFD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,CAAC,EAAE,MAAM,GAAG,cAAc,CAqEpH"}
|
|
@@ -125,7 +125,10 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
|
|
|
125
125
|
}
|
|
126
126
|
const multiClient = new import_ADCPMultiAgentClient.ADCPMultiAgentClient([agentConfig], {
|
|
127
127
|
headers,
|
|
128
|
-
validation: {
|
|
128
|
+
validation: {
|
|
129
|
+
responses: options.strictResponseSchemaValidation === false ? "warn" : "strict",
|
|
130
|
+
logSchemaViolations: false
|
|
131
|
+
},
|
|
129
132
|
...options.adcpVersion !== void 0 && { adcpVersion: options.adcpVersion },
|
|
130
133
|
...options.wireAdcpVersion !== void 0 && { wireAdcpVersion: options.wireAdcpVersion },
|
|
131
134
|
...options.versionEnvelope !== void 0 && { versionEnvelope: options.versionEnvelope },
|
|
@@ -139,6 +142,7 @@ function createTestClient(agentUrl, protocol = "mcp", options = {}) {
|
|
|
139
142
|
adcpVersion: multiClient.getAdcpVersion(),
|
|
140
143
|
...options.wireAdcpVersion !== void 0 && { wireAdcpVersion: options.wireAdcpVersion },
|
|
141
144
|
versionEnvelope: options.versionEnvelope ?? "auto",
|
|
145
|
+
strictResponseSchemaValidation: options.strictResponseSchemaValidation !== false,
|
|
142
146
|
...authMode !== void 0 && { authMode },
|
|
143
147
|
...options.transport?.trustedFetchFn && { fetchFn: options.transport.trustedFetchFn },
|
|
144
148
|
...options.transport?.maxResponseBytes !== void 0 && {
|
|
@@ -178,7 +182,7 @@ function testClientMatchesVersionOptions(client, options) {
|
|
|
178
182
|
const expectedAdcpVersion = effectiveOptions.adcpVersion ?? import_version.ADCP_VERSION;
|
|
179
183
|
const expectedWireAdcpVersion = effectiveOptions.wireAdcpVersion;
|
|
180
184
|
const expectedVersionEnvelope = effectiveOptions.versionEnvelope ?? "auto";
|
|
181
|
-
return meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.authMode === expectedAuthMode && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs;
|
|
185
|
+
return meta.adcpVersion === expectedAdcpVersion && meta.wireAdcpVersion === expectedWireAdcpVersion && meta.versionEnvelope === expectedVersionEnvelope && meta.strictResponseSchemaValidation === (effectiveOptions.strictResponseSchemaValidation !== false) && meta.authMode === expectedAuthMode && meta.fetchFn === effectiveOptions.transport?.trustedFetchFn && meta.maxResponseBytes === effectiveOptions.transport?.maxResponseBytes && meta.requestTimeoutMs === effectiveOptions.transport?.requestTimeoutMs;
|
|
182
186
|
}
|
|
183
187
|
function withTestKitAuthDefaults(options) {
|
|
184
188
|
if (options.auth) return options;
|