@adcp/sdk 16.0.0-beta.7 → 16.0.0-beta.9
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/AGENTS.md +3 -3
- package/README.md +20 -0
- package/bin/adcp.js +10 -13
- package/dist/lib/conformance/index.d.mts +2 -0
- package/dist/lib/conformance/index.d.ts +2 -0
- package/dist/lib/conformance/index.js +3 -0
- package/dist/lib/conformance/index.mjs +2 -0
- package/dist/lib/conformance/property-lists.d.mts +14 -0
- package/dist/lib/conformance/property-lists.d.ts +14 -0
- package/dist/lib/conformance/property-lists.js +45 -0
- package/dist/lib/conformance/property-lists.mjs +21 -0
- package/dist/lib/conformance/runConformance.js +20 -1
- package/dist/lib/conformance/runConformance.mjs +20 -1
- package/dist/lib/conformance/types.d.mts +3 -0
- package/dist/lib/conformance/types.d.ts +3 -0
- package/dist/lib/core/AgentClient.d.mts +8 -5
- package/dist/lib/core/AgentClient.d.ts +8 -5
- package/dist/lib/core/AgentClient.js +9 -4
- package/dist/lib/core/AgentClient.mjs +9 -4
- package/dist/lib/core/SingleAgentClient.d.mts +32 -115
- package/dist/lib/core/SingleAgentClient.d.ts +32 -115
- package/dist/lib/core/SingleAgentClient.js +379 -273
- package/dist/lib/core/SingleAgentClient.mjs +387 -275
- package/dist/lib/core/TaskExecutor.d.mts +1 -16
- package/dist/lib/core/TaskExecutor.d.ts +1 -16
- package/dist/lib/core/TaskExecutor.js +34 -51
- package/dist/lib/core/TaskExecutor.mjs +12 -29
- package/dist/lib/core/product-cache.d.mts +3 -1
- package/dist/lib/core/product-cache.d.ts +3 -1
- package/dist/lib/core/product-cache.js +2 -1
- package/dist/lib/core/product-cache.mjs +2 -1
- package/dist/lib/errors/index.d.mts +2 -8
- package/dist/lib/errors/index.d.ts +2 -8
- package/dist/lib/errors/index.js +4 -4
- package/dist/lib/errors/index.mjs +4 -4
- package/dist/lib/identifiers.d.mts +53 -0
- package/dist/lib/identifiers.d.ts +53 -0
- package/dist/lib/identifiers.js +212 -0
- package/dist/lib/identifiers.mjs +163 -0
- package/dist/lib/index.d.mts +7 -5
- package/dist/lib/index.d.ts +7 -5
- package/dist/lib/index.js +2 -14
- package/dist/lib/index.mjs +1 -14
- package/dist/lib/media-buy/compatibility.d.mts +1 -1
- package/dist/lib/media-buy/compatibility.d.ts +1 -1
- package/dist/lib/media-buy/compatibility.js +26 -45
- package/dist/lib/media-buy/compatibility.mjs +26 -45
- package/dist/lib/media-buy/index.d.mts +1 -1
- package/dist/lib/media-buy/index.d.ts +1 -1
- package/dist/lib/media-buy/legacy-purchase-continuation.d.mts +2 -2
- package/dist/lib/media-buy/legacy-purchase-continuation.d.ts +2 -2
- package/dist/lib/media-buy/property-policy.d.mts +15 -1
- package/dist/lib/media-buy/property-policy.d.ts +15 -1
- package/dist/lib/media-buy/property-policy.js +135 -3
- package/dist/lib/media-buy/property-policy.mjs +134 -3
- package/dist/lib/protocols/index.js +14 -22
- package/dist/lib/protocols/index.mjs +5 -13
- package/dist/lib/registry/index.d.mts +12 -0
- package/dist/lib/registry/index.d.ts +12 -0
- package/dist/lib/registry/index.js +159 -5
- package/dist/lib/registry/index.mjs +156 -4
- package/dist/lib/registry/types.d.mts +26 -2
- package/dist/lib/registry/types.d.ts +26 -2
- package/dist/lib/registry/types.generated.d.mts +51 -11
- package/dist/lib/registry/types.generated.d.ts +51 -11
- package/dist/lib/reporting/source/conformance.d.mts +8 -8
- package/dist/lib/reporting/source/conformance.d.ts +8 -8
- package/dist/lib/reporting/source/manifest.d.mts +27 -27
- package/dist/lib/reporting/source/manifest.d.ts +27 -27
- package/dist/lib/server/create-adcp-server.js +6 -0
- package/dist/lib/server/create-adcp-server.mjs +6 -0
- package/dist/lib/server/decisioning/specialisms/lists.d.mts +4 -4
- package/dist/lib/server/decisioning/specialisms/lists.d.ts +4 -4
- package/dist/lib/server/index.d.mts +3 -0
- package/dist/lib/server/index.d.ts +3 -0
- package/dist/lib/server/index.js +8 -1
- package/dist/lib/server/index.mjs +4 -0
- package/dist/lib/server/property-lists.d.mts +36 -0
- package/dist/lib/server/property-lists.d.ts +36 -0
- package/dist/lib/server/property-lists.js +154 -0
- package/dist/lib/server/property-lists.mjs +129 -0
- package/dist/lib/server/targeting-helpers.d.mts +2 -0
- package/dist/lib/server/targeting-helpers.d.ts +2 -0
- package/dist/lib/server/targeting-helpers.js +28 -1
- package/dist/lib/server/targeting-helpers.mjs +18 -1
- package/dist/lib/signing/parser.js +2 -2
- package/dist/lib/signing/parser.mjs +2 -2
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.mjs +5 -1
- package/dist/lib/signing/webhook-verifier.d.mts +11 -0
- package/dist/lib/signing/webhook-verifier.d.ts +11 -0
- package/dist/lib/signing/webhook-verifier.js +11 -3
- package/dist/lib/signing/webhook-verifier.mjs +11 -3
- package/dist/lib/supply-path/verify.js +12 -2
- package/dist/lib/supply-path/verify.mjs +2 -2
- package/dist/lib/testing/compliance/comply.js +0 -8
- package/dist/lib/testing/compliance/comply.mjs +0 -8
- package/dist/lib/testing/compliance/storyboard-tracks.js +11 -0
- package/dist/lib/testing/compliance/storyboard-tracks.mjs +11 -0
- package/dist/lib/testing/index.d.mts +2 -0
- package/dist/lib/testing/index.d.ts +2 -0
- package/dist/lib/testing/index.js +5 -0
- package/dist/lib/testing/index.mjs +3 -0
- package/dist/lib/testing/scenarios/capabilities.d.mts +2 -2
- package/dist/lib/testing/scenarios/capabilities.d.ts +2 -2
- package/dist/lib/testing/scenarios/capabilities.js +8 -41
- package/dist/lib/testing/scenarios/capabilities.mjs +9 -42
- package/dist/lib/testing/storyboard/creative-build-probe.d.mts +34 -0
- package/dist/lib/testing/storyboard/creative-build-probe.d.ts +34 -0
- package/dist/lib/testing/storyboard/creative-build-probe.js +395 -0
- package/dist/lib/testing/storyboard/creative-build-probe.mjs +373 -0
- package/dist/lib/testing/storyboard/index.d.mts +2 -0
- package/dist/lib/testing/storyboard/index.d.ts +2 -0
- package/dist/lib/testing/storyboard/index.js +5 -0
- package/dist/lib/testing/storyboard/index.mjs +3 -0
- package/dist/lib/testing/storyboard/loader.js +12 -0
- package/dist/lib/testing/storyboard/loader.mjs +12 -0
- package/dist/lib/testing/storyboard/property-list-reference.d.mts +15 -0
- package/dist/lib/testing/storyboard/property-list-reference.d.ts +15 -0
- package/dist/lib/testing/storyboard/property-list-reference.js +514 -0
- package/dist/lib/testing/storyboard/property-list-reference.mjs +487 -0
- package/dist/lib/testing/storyboard/runner.js +318 -58
- package/dist/lib/testing/storyboard/runner.mjs +322 -58
- package/dist/lib/testing/storyboard/types.d.mts +38 -16
- package/dist/lib/testing/storyboard/types.d.ts +38 -16
- package/dist/lib/testing/storyboard/types.js +1 -0
- package/dist/lib/testing/storyboard/types.mjs +1 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.js +64 -0
- package/dist/lib/testing/storyboard/validations.mjs +67 -1
- package/dist/lib/testing/types.d.mts +15 -1
- package/dist/lib/testing/types.d.ts +15 -1
- package/dist/lib/types/schemas.generated.d.ts +65 -65
- package/dist/lib/types/wellknown-schemas.generated.d.mts +21 -21
- package/dist/lib/types/wellknown-schemas.generated.d.ts +21 -21
- package/dist/lib/utils/adcp-version-config.js +6 -0
- package/dist/lib/utils/adcp-version-config.mjs +6 -0
- package/dist/lib/utils/capabilities.d.mts +7 -9
- package/dist/lib/utils/capabilities.d.ts +7 -9
- package/dist/lib/utils/capabilities.js +14 -28
- package/dist/lib/utils/capabilities.mjs +14 -27
- package/dist/lib/utils/creative-adapter.d.mts +15 -113
- package/dist/lib/utils/creative-adapter.d.ts +15 -113
- package/dist/lib/utils/creative-adapter.js +7 -106
- package/dist/lib/utils/creative-adapter.mjs +7 -102
- package/dist/lib/utils/format-renders.d.mts +20 -80
- package/dist/lib/utils/format-renders.d.ts +20 -80
- package/dist/lib/utils/format-renders.js +7 -67
- package/dist/lib/utils/format-renders.mjs +7 -66
- package/dist/lib/utils/index.d.mts +1 -2
- package/dist/lib/utils/index.d.ts +1 -2
- package/dist/lib/utils/index.js +0 -7
- package/dist/lib/utils/index.mjs +0 -6
- package/dist/lib/utils/preview-normalizer.d.mts +31 -80
- package/dist/lib/utils/preview-normalizer.d.ts +31 -80
- package/dist/lib/utils/preview-normalizer.js +5 -50
- package/dist/lib/utils/preview-normalizer.mjs +5 -49
- package/dist/lib/utils/pricing-adapter.d.mts +2 -36
- package/dist/lib/utils/pricing-adapter.d.ts +2 -36
- package/dist/lib/utils/pricing-adapter.js +0 -105
- package/dist/lib/utils/pricing-adapter.mjs +0 -100
- package/dist/lib/utils/request-normalizer.d.mts +1 -2
- package/dist/lib/utils/request-normalizer.d.ts +1 -2
- package/dist/lib/v2/projection/creative-delivery.d.mts +2 -0
- package/dist/lib/v2/projection/creative-delivery.d.ts +2 -0
- package/dist/lib/v2/projection/creative-delivery.js +7 -0
- package/dist/lib/v2/projection/creative-delivery.mjs +6 -0
- package/dist/lib/v2/projection/legacy-metadata.d.mts +12 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +12 -0
- package/dist/lib/v2/projection/legacy-metadata.js +41 -1
- package/dist/lib/v2/projection/legacy-metadata.mjs +37 -1
- package/dist/lib/v2/projection/legacy-normalization.d.mts +1 -1
- package/dist/lib/v2/projection/legacy-normalization.d.ts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.js +13 -0
- package/dist/lib/v2/projection/v1-to-v2.mjs +14 -0
- package/dist/lib/validation/client-hooks.d.mts +1 -4
- package/dist/lib/validation/client-hooks.d.ts +1 -4
- package/dist/lib/validation/get-products-request.d.mts +1 -1
- package/dist/lib/validation/get-products-request.d.ts +1 -1
- package/dist/lib/validation/schema-loader.js +6 -0
- package/dist/lib/validation/schema-loader.mjs +6 -0
- package/dist/lib/validation/schema-validator.js +1 -26
- package/dist/lib/validation/schema-validator.mjs +1 -26
- package/dist/lib/version.d.mts +5 -5
- package/dist/lib/version.d.ts +5 -5
- package/dist/lib/version.js +3 -5
- package/dist/lib/version.mjs +3 -5
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/development/PROTOCOL_DIFFERENCES.md +1 -1
- package/docs/guides/CONFORMANCE.md +25 -0
- package/docs/guides/CREATIVE-BUILD-PROBE.md +156 -0
- package/docs/guides/CREATIVE-DELIVERY.md +45 -6
- package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +15 -18
- package/docs/guides/PROPERTY-LISTS.md +264 -0
- package/docs/guides/SIGNING-GUIDE.md +25 -0
- package/docs/guides/VALIDATE-YOUR-AGENT.md +5 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-13-to-14.md +20 -16
- package/docs/migration-14.x-rc-worksheet.md +5 -5
- package/docs/migration-4.x-to-5.x.md +12 -7
- package/docs/migration-drop-adcp-2.md +25 -0
- package/package.json +3 -18
- package/skills/call-adcp-agent/SKILL.md +23 -25
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.d.mts +0 -3
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.d.ts +0 -3
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/create_media_buy.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/get_products.d.mts +0 -8
- package/dist/lib/adapters/legacy/v2-5/get_products.d.ts +0 -8
- package/dist/lib/adapters/legacy/v2-5/get_products.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/get_products.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/index.d.mts +0 -34
- package/dist/lib/adapters/legacy/v2-5/index.d.ts +0 -34
- package/dist/lib/adapters/legacy/v2-5/index.js +0 -50
- package/dist/lib/adapters/legacy/v2-5/index.mjs +0 -25
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.d.mts +0 -8
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.d.ts +0 -8
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/list_creative_formats.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/preview_creative.d.mts +0 -3
- package/dist/lib/adapters/legacy/v2-5/preview_creative.d.ts +0 -3
- package/dist/lib/adapters/legacy/v2-5/preview_creative.js +0 -33
- package/dist/lib/adapters/legacy/v2-5/preview_creative.mjs +0 -9
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.d.mts +0 -11
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.d.ts +0 -11
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.js +0 -32
- package/dist/lib/adapters/legacy/v2-5/sync_creatives.mjs +0 -8
- package/dist/lib/adapters/legacy/v2-5/types.d.mts +0 -39
- package/dist/lib/adapters/legacy/v2-5/types.d.ts +0 -39
- package/dist/lib/adapters/legacy/v2-5/types.js +0 -16
- package/dist/lib/adapters/legacy/v2-5/types.mjs +0 -0
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.d.mts +0 -3
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.d.ts +0 -3
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.js +0 -35
- package/dist/lib/adapters/legacy/v2-5/update_media_buy.mjs +0 -11
- package/dist/lib/schemas-data/v2.5/_provenance.json +0 -8
- package/dist/lib/schemas-data/v2.5/adagents.json +0 -494
- package/dist/lib/schemas-data/v2.5/core/activation-key.json +0 -50
- package/dist/lib/schemas-data/v2.5/core/assets/audio-asset.json +0 -32
- package/dist/lib/schemas-data/v2.5/core/assets/css-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/daast-asset.json +0 -87
- package/dist/lib/schemas-data/v2.5/core/assets/html-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/image-asset.json +0 -38
- package/dist/lib/schemas-data/v2.5/core/assets/javascript-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/markdown-asset.json +0 -31
- package/dist/lib/schemas-data/v2.5/core/assets/text-asset.json +0 -21
- package/dist/lib/schemas-data/v2.5/core/assets/url-asset.json +0 -26
- package/dist/lib/schemas-data/v2.5/core/assets/vast-asset.json +0 -87
- package/dist/lib/schemas-data/v2.5/core/assets/video-asset.json +0 -44
- package/dist/lib/schemas-data/v2.5/core/assets/webhook-asset.json +0 -71
- package/dist/lib/schemas-data/v2.5/core/async-response-data.json +0 -88
- package/dist/lib/schemas-data/v2.5/core/brand-manifest-ref.json +0 -33
- package/dist/lib/schemas-data/v2.5/core/brand-manifest.json +0 -409
- package/dist/lib/schemas-data/v2.5/core/context.json +0 -8
- package/dist/lib/schemas-data/v2.5/core/creative-asset.json +0 -125
- package/dist/lib/schemas-data/v2.5/core/creative-assignment.json +0 -31
- package/dist/lib/schemas-data/v2.5/core/creative-filters.json +0 -111
- package/dist/lib/schemas-data/v2.5/core/creative-manifest.json +0 -72
- package/dist/lib/schemas-data/v2.5/core/creative-policy.json +0 -27
- package/dist/lib/schemas-data/v2.5/core/delivery-metrics.json +0 -171
- package/dist/lib/schemas-data/v2.5/core/deployment.json +0 -93
- package/dist/lib/schemas-data/v2.5/core/destination.json +0 -53
- package/dist/lib/schemas-data/v2.5/core/error.json +0 -40
- package/dist/lib/schemas-data/v2.5/core/ext.json +0 -8
- package/dist/lib/schemas-data/v2.5/core/format-id.json +0 -47
- package/dist/lib/schemas-data/v2.5/core/format.json +0 -324
- package/dist/lib/schemas-data/v2.5/core/frequency-cap.json +0 -18
- package/dist/lib/schemas-data/v2.5/core/mcp-webhook-payload.json +0 -152
- package/dist/lib/schemas-data/v2.5/core/measurement.json +0 -48
- package/dist/lib/schemas-data/v2.5/core/media-buy.json +0 -62
- package/dist/lib/schemas-data/v2.5/core/package.json +0 -72
- package/dist/lib/schemas-data/v2.5/core/performance-feedback.json +0 -90
- package/dist/lib/schemas-data/v2.5/core/placement.json +0 -34
- package/dist/lib/schemas-data/v2.5/core/pricing-option.json +0 -35
- package/dist/lib/schemas-data/v2.5/core/product-filters.json +0 -102
- package/dist/lib/schemas-data/v2.5/core/product.json +0 -153
- package/dist/lib/schemas-data/v2.5/core/promoted-offerings.json +0 -115
- package/dist/lib/schemas-data/v2.5/core/promoted-products.json +0 -67
- package/dist/lib/schemas-data/v2.5/core/property-id.json +0 -14
- package/dist/lib/schemas-data/v2.5/core/property-tag.json +0 -16
- package/dist/lib/schemas-data/v2.5/core/property.json +0 -62
- package/dist/lib/schemas-data/v2.5/core/protocol-envelope.json +0 -146
- package/dist/lib/schemas-data/v2.5/core/publisher-property-selector.json +0 -92
- package/dist/lib/schemas-data/v2.5/core/push-notification-config.json +0 -48
- package/dist/lib/schemas-data/v2.5/core/reporting-capabilities.json +0 -71
- package/dist/lib/schemas-data/v2.5/core/response.json +0 -24
- package/dist/lib/schemas-data/v2.5/core/signal-filters.json +0 -35
- package/dist/lib/schemas-data/v2.5/core/start-timing.json +0 -18
- package/dist/lib/schemas-data/v2.5/core/sub-asset.json +0 -79
- package/dist/lib/schemas-data/v2.5/core/targeting.json +0 -50
- package/dist/lib/schemas-data/v2.5/core/tasks-get-request.json +0 -43
- package/dist/lib/schemas-data/v2.5/core/tasks-get-response.json +0 -166
- package/dist/lib/schemas-data/v2.5/core/tasks-list-request.json +0 -192
- package/dist/lib/schemas-data/v2.5/core/tasks-list-response.json +0 -183
- package/dist/lib/schemas-data/v2.5/creative/asset-types/index.json +0 -101
- package/dist/lib/schemas-data/v2.5/creative/list-creative-formats-request.json +0 -73
- package/dist/lib/schemas-data/v2.5/creative/list-creative-formats-response.json +0 -61
- package/dist/lib/schemas-data/v2.5/creative/preview-creative-request.json +0 -164
- package/dist/lib/schemas-data/v2.5/creative/preview-creative-response.json +0 -245
- package/dist/lib/schemas-data/v2.5/creative/preview-render.json +0 -225
- package/dist/lib/schemas-data/v2.5/enums/adcp-domain.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/asset-content-type.json +0 -22
- package/dist/lib/schemas-data/v2.5/enums/auth-scheme.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/available-metric.json +0 -18
- package/dist/lib/schemas-data/v2.5/enums/channels.json +0 -18
- package/dist/lib/schemas-data/v2.5/enums/co-branding-requirement.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/creative-action.json +0 -14
- package/dist/lib/schemas-data/v2.5/enums/creative-agent-capability.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/creative-sort-field.json +0 -15
- package/dist/lib/schemas-data/v2.5/enums/creative-status.json +0 -19
- package/dist/lib/schemas-data/v2.5/enums/daast-tracking-event.json +0 -20
- package/dist/lib/schemas-data/v2.5/enums/daast-version.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/delivery-type.json +0 -15
- package/dist/lib/schemas-data/v2.5/enums/dimension-unit.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/feed-format.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/feedback-source.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/format-category.json +0 -16
- package/dist/lib/schemas-data/v2.5/enums/format-id-parameter.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/frequency-cap-scope.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/history-entry-type.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/http-method.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/identifier-types.json +0 -34
- package/dist/lib/schemas-data/v2.5/enums/javascript-module-type.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/landing-page-requirement.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/markdown-flavor.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/media-buy-status.json +0 -19
- package/dist/lib/schemas-data/v2.5/enums/metric-type.json +0 -17
- package/dist/lib/schemas-data/v2.5/enums/notification-type.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/pacing.json +0 -17
- package/dist/lib/schemas-data/v2.5/enums/preview-output-format.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/pricing-model.json +0 -25
- package/dist/lib/schemas-data/v2.5/enums/property-type.json +0 -16
- package/dist/lib/schemas-data/v2.5/enums/publisher-identifier-types.json +0 -19
- package/dist/lib/schemas-data/v2.5/enums/reporting-frequency.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/signal-catalog-type.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/sort-direction.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/standard-format-ids.json +0 -103
- package/dist/lib/schemas-data/v2.5/enums/task-status.json +0 -29
- package/dist/lib/schemas-data/v2.5/enums/task-type.json +0 -27
- package/dist/lib/schemas-data/v2.5/enums/update-frequency.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/url-asset-type.json +0 -12
- package/dist/lib/schemas-data/v2.5/enums/validation-mode.json +0 -11
- package/dist/lib/schemas-data/v2.5/enums/vast-tracking-event.json +0 -25
- package/dist/lib/schemas-data/v2.5/enums/vast-version.json +0 -14
- package/dist/lib/schemas-data/v2.5/enums/webhook-response-type.json +0 -13
- package/dist/lib/schemas-data/v2.5/enums/webhook-security-method.json +0 -12
- package/dist/lib/schemas-data/v2.5/index.json +0 -604
- package/dist/lib/schemas-data/v2.5/media-buy/build-creative-request.json +0 -31
- package/dist/lib/schemas-data/v2.5/media-buy/build-creative-response.json +0 -65
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-input-required.json +0 -31
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-submitted.json +0 -16
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-async-response-working.json +0 -36
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-request.json +0 -126
- package/dist/lib/schemas-data/v2.5/media-buy/create-media-buy-response.json +0 -97
- package/dist/lib/schemas-data/v2.5/media-buy/get-media-buy-delivery-request.json +0 -54
- package/dist/lib/schemas-data/v2.5/media-buy/get-media-buy-delivery-response.json +0 -285
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-input-required.json +0 -38
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-submitted.json +0 -21
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-async-response-working.json +0 -34
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-request.json +0 -28
- package/dist/lib/schemas-data/v2.5/media-buy/get-products-response.json +0 -33
- package/dist/lib/schemas-data/v2.5/media-buy/list-authorized-properties-request.json +0 -26
- package/dist/lib/schemas-data/v2.5/media-buy/list-authorized-properties-response.json +0 -70
- package/dist/lib/schemas-data/v2.5/media-buy/list-creative-formats-request.json +0 -58
- package/dist/lib/schemas-data/v2.5/media-buy/list-creative-formats-response.json +0 -61
- package/dist/lib/schemas-data/v2.5/media-buy/list-creatives-request.json +0 -137
- package/dist/lib/schemas-data/v2.5/media-buy/list-creatives-response.json +0 -437
- package/dist/lib/schemas-data/v2.5/media-buy/package-request.json +0 -80
- package/dist/lib/schemas-data/v2.5/media-buy/provide-performance-feedback-request.json +0 -88
- package/dist/lib/schemas-data/v2.5/media-buy/provide-performance-feedback-response.json +0 -66
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-input-required.json +0 -25
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-submitted.json +0 -16
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-async-response-working.json +0 -46
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-request.json +0 -178
- package/dist/lib/schemas-data/v2.5/media-buy/sync-creatives-response.json +0 -149
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-input-required.json +0 -24
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-submitted.json +0 -16
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-async-response-working.json +0 -36
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-request.json +0 -129
- package/dist/lib/schemas-data/v2.5/media-buy/update-media-buy-response.json +0 -99
- package/dist/lib/schemas-data/v2.5/pricing-options/cpc-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/pricing-options/cpcv-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/pricing-options/cpm-auction-option.json +0 -81
- package/dist/lib/schemas-data/v2.5/pricing-options/cpm-fixed-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/pricing-options/cpp-option.json +0 -73
- package/dist/lib/schemas-data/v2.5/pricing-options/cpv-option.json +0 -88
- package/dist/lib/schemas-data/v2.5/pricing-options/flat-rate-option.json +0 -93
- package/dist/lib/schemas-data/v2.5/pricing-options/vcpm-auction-option.json +0 -81
- package/dist/lib/schemas-data/v2.5/pricing-options/vcpm-fixed-option.json +0 -52
- package/dist/lib/schemas-data/v2.5/protocols/adcp-extension.json +0 -33
- package/dist/lib/schemas-data/v2.5/signals/activate-signal-request.json +0 -32
- package/dist/lib/schemas-data/v2.5/signals/activate-signal-response.json +0 -68
- package/dist/lib/schemas-data/v2.5/signals/get-signals-request.json +0 -59
- package/dist/lib/schemas-data/v2.5/signals/get-signals-response.json +0 -100
- package/dist/lib/types/v2-5/index.d.mts +0 -1
- package/dist/lib/types/v2-5/index.d.ts +0 -1
- package/dist/lib/types/v2-5/index.js +0 -22
- package/dist/lib/types/v2-5/index.mjs +0 -1
- package/dist/lib/types/v2-5/tools.generated.d.mts +0 -3568
- package/dist/lib/types/v2-5/tools.generated.d.ts +0 -3568
- package/dist/lib/types/v2-5/tools.generated.js +0 -16
- package/dist/lib/types/v2-5/tools.generated.mjs +0 -0
- package/dist/lib/utils/sync-creatives-adapter.d.mts +0 -33
- package/dist/lib/utils/sync-creatives-adapter.d.ts +0 -33
- package/dist/lib/utils/sync-creatives-adapter.js +0 -83
- package/dist/lib/utils/sync-creatives-adapter.mjs +0 -59
|
@@ -3,6 +3,9 @@ import { dirname as __adcpDirname } from "node:path";
|
|
|
3
3
|
import { createRequire as __adcpCreateRequire } from "node:module";
|
|
4
4
|
const __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));
|
|
5
5
|
const require2 = __adcpCreateRequire(import.meta.url);
|
|
6
|
+
import { normalizeGetProductsResponse } from "../utils/pricing-adapter.mjs";
|
|
7
|
+
import { normalizeMediaBuyResponse } from "../utils/creative-adapter.mjs";
|
|
8
|
+
import { normalizeFormatsResponse } from "../utils/format-renders.mjs";
|
|
6
9
|
import {
|
|
7
10
|
isIdentity33SchemaScope,
|
|
8
11
|
withIdentity33SchemaScope,
|
|
@@ -131,7 +134,6 @@ import {
|
|
|
131
134
|
validateAgentDiscoveryCacheConfig
|
|
132
135
|
} from "./agent-discovery-cache.mjs";
|
|
133
136
|
import {
|
|
134
|
-
buildSyntheticCapabilities,
|
|
135
137
|
buildSyntheticV3Capabilities,
|
|
136
138
|
augmentCapabilitiesFromTools,
|
|
137
139
|
looksLikeV3Capabilities,
|
|
@@ -160,15 +162,17 @@ import { normalizeRequestParams } from "../utils/request-normalizer.mjs";
|
|
|
160
162
|
import { globalAsyncLocalStorage } from "../utils/global-async-local-storage.mjs";
|
|
161
163
|
import { validateUserAgent } from "../utils/validate-user-agent.mjs";
|
|
162
164
|
import { resolveWebhookUrl, selectWebhookTemplate } from "./webhook-url.mjs";
|
|
163
|
-
import { getV25Adapter } from "../adapters/legacy/v2-5/index.mjs";
|
|
164
165
|
import {
|
|
165
166
|
ProductPropertyPolicyError,
|
|
166
|
-
validateProductsAgainstPropertyPolicy
|
|
167
|
+
validateProductsAgainstPropertyPolicy,
|
|
168
|
+
isSupportedPropertyIdentifierType,
|
|
169
|
+
normalizeDomainForPropertyPolicy
|
|
167
170
|
} from "../media-buy/property-policy.mjs";
|
|
168
171
|
import { resolvePropertyList } from "../server/targeting-helpers.mjs";
|
|
169
172
|
import {
|
|
170
173
|
CreativeFormatCapabilityError,
|
|
171
174
|
CreativeFormatProjectionError,
|
|
175
|
+
canUseProductOptionsForCreativeWire,
|
|
172
176
|
projectMediaBuyCreativesForDelivery,
|
|
173
177
|
projectCreativeForDelivery,
|
|
174
178
|
projectSyncCreativesForDelivery,
|
|
@@ -188,6 +192,10 @@ import {
|
|
|
188
192
|
import { toCanonicalOnlyResponse } from "../v2/projection/augment-response.mjs";
|
|
189
193
|
import {
|
|
190
194
|
legacyFormatRefsForDeclaration,
|
|
195
|
+
isSynthesizedFormatOption,
|
|
196
|
+
selectedFormatOptions,
|
|
197
|
+
rememberSellerFormatEvidence,
|
|
198
|
+
sellerFormatEvidence,
|
|
191
199
|
rememberSellerDeclaredFormatOption,
|
|
192
200
|
sellerDeclaredFormatOption,
|
|
193
201
|
structuredCloneWithLegacyCreativeMetadata
|
|
@@ -311,6 +319,56 @@ const RECORDLESS_HMAC_READ_ONLY_TASKS = /* @__PURE__ */ new Set([
|
|
|
311
319
|
]);
|
|
312
320
|
const TASK_SCOPED_STATE_LIMIT = 1e4;
|
|
313
321
|
const WEBHOOK_JWKS_RESOLVER_LIMIT = 1024;
|
|
322
|
+
function creativeMatchesProductOption(creative, declaration) {
|
|
323
|
+
const params = isPlainRecord(declaration.params) ? declaration.params : {};
|
|
324
|
+
const assets = isPlainRecord(creative.assets) ? creative.assets : {};
|
|
325
|
+
const slots = Array.isArray(params.slots) ? params.slots : [];
|
|
326
|
+
if (!slots.every((slot) => {
|
|
327
|
+
if (!isPlainRecord(slot) || typeof slot.asset_group_id !== "string") return false;
|
|
328
|
+
const value = assets[slot.asset_group_id];
|
|
329
|
+
const entries = value === void 0 ? [] : Array.isArray(value) ? value : [value];
|
|
330
|
+
const minimum = Math.max(typeof slot.min === "number" ? slot.min : 0, slot.required === true ? 1 : 0);
|
|
331
|
+
if (entries.length < minimum || typeof slot.max === "number" && entries.length > slot.max) return false;
|
|
332
|
+
return entries.every(
|
|
333
|
+
(asset) => isPlainRecord(asset) && (typeof slot.asset_type !== "string" || asset.asset_type === slot.asset_type)
|
|
334
|
+
);
|
|
335
|
+
}))
|
|
336
|
+
return false;
|
|
337
|
+
const formatParams = isPlainRecord(creative.format_parameters) ? creative.format_parameters : {};
|
|
338
|
+
const kind = String(creative.format_kind);
|
|
339
|
+
const mediaType = kind.startsWith("image") ? "image" : kind.startsWith("video") ? "video" : kind.startsWith("audio") ? "audio" : kind === "html5" ? "html" : void 0;
|
|
340
|
+
const assetTypes = mediaType === "video" ? ["video", "vast"] : mediaType === "audio" ? ["audio", "vast", "daast"] : mediaType === "html" ? ["html", "zip"] : mediaType ? [mediaType] : ["image", "video", "audio", "html", "zip", "vast", "daast"];
|
|
341
|
+
const requiredMediaSlots = slots.filter(
|
|
342
|
+
(slot) => isPlainRecord(slot) && (slot.required === true || typeof slot.min === "number" && slot.min > 0) && assetTypes.includes(String(slot.asset_type))
|
|
343
|
+
);
|
|
344
|
+
const preferredGroups = mediaType ? [`${mediaType}_main`, mediaType, kind, ...assetTypes] : [];
|
|
345
|
+
const primaryGroup = (requiredMediaSlots.length === 1 ? String(requiredMediaSlots[0].asset_group_id) : void 0) ?? preferredGroups.find((group) => assets[group] !== void 0);
|
|
346
|
+
const sourceAssets = primaryGroup ? [assets[primaryGroup]] : Object.values(assets);
|
|
347
|
+
const dimensionalAssets = sourceAssets.flatMap((value) => Array.isArray(value) ? value : [value]).filter(
|
|
348
|
+
(value) => isPlainRecord(value) && assetTypes.includes(String(value.asset_type))
|
|
349
|
+
);
|
|
350
|
+
return (dimensionalAssets.length > 0 ? dimensionalAssets : [{}]).every((asset) => {
|
|
351
|
+
const actual = { ...asset, ...formatParams };
|
|
352
|
+
for (const key of ["width", "height"]) {
|
|
353
|
+
if (typeof params[key] === "number" && actual[key] !== params[key]) return false;
|
|
354
|
+
const min = params[`min_${key}`];
|
|
355
|
+
const max = params[`max_${key}`];
|
|
356
|
+
if (typeof min === "number" && (typeof actual[key] !== "number" || actual[key] < min)) return false;
|
|
357
|
+
if (typeof max === "number" && (typeof actual[key] !== "number" || actual[key] > max)) return false;
|
|
358
|
+
}
|
|
359
|
+
if (Array.isArray(params.sizes) && !params.sizes.some((size) => isPlainRecord(size) && size.width === actual.width && size.height === actual.height))
|
|
360
|
+
return false;
|
|
361
|
+
const duration = actual.duration_ms ?? actual.duration_ms_exact;
|
|
362
|
+
const exact = params.duration_ms_exact ?? params.duration_ms;
|
|
363
|
+
if (typeof exact === "number" && duration !== exact) return false;
|
|
364
|
+
if (typeof exact !== "number" && Array.isArray(params.duration_ms_range)) {
|
|
365
|
+
const [min, max] = params.duration_ms_range;
|
|
366
|
+
if (typeof duration !== "number" || typeof min === "number" && duration < min || typeof max === "number" && duration > max)
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
return true;
|
|
370
|
+
});
|
|
371
|
+
}
|
|
314
372
|
function isDeferredClientFinalizationContext(value) {
|
|
315
373
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
316
374
|
const context = value;
|
|
@@ -757,24 +815,7 @@ function isToolSchemaRecord(value) {
|
|
|
757
815
|
function isCapabilityEvidence(value) {
|
|
758
816
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
759
817
|
const candidate = value;
|
|
760
|
-
return
|
|
761
|
-
}
|
|
762
|
-
function valueMatchesSchemaType(value, propSchema) {
|
|
763
|
-
if (!propSchema || typeof propSchema !== "object") return false;
|
|
764
|
-
const schema = propSchema;
|
|
765
|
-
if (schema.$ref) return true;
|
|
766
|
-
const valueType = Array.isArray(value) ? "array" : value === null ? "null" : typeof value === "object" ? "object" : typeof value;
|
|
767
|
-
for (const key of ["anyOf", "oneOf"]) {
|
|
768
|
-
const variants = schema[key];
|
|
769
|
-
if (Array.isArray(variants)) {
|
|
770
|
-
return variants.some((v) => valueMatchesSchemaType(value, v));
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
const declared = schema.type;
|
|
774
|
-
if (declared === void 0) return false;
|
|
775
|
-
if (typeof declared === "string") return declared === valueType;
|
|
776
|
-
if (Array.isArray(declared)) return declared.includes(valueType);
|
|
777
|
-
return false;
|
|
818
|
+
return candidate.version === "v3" && Array.isArray(candidate.majorVersions) && candidate.majorVersions.includes(3) && candidate.majorVersions.every((version) => Number.isSafeInteger(version) && version > 0) && Array.isArray(candidate.protocols) && candidate.protocols.every((protocol) => typeof protocol === "string") && typeof candidate.features === "object" && candidate.features !== null && !Array.isArray(candidate.features) && Array.isArray(candidate.extensions) && candidate.extensions.every((extension) => typeof extension === "string") && typeof candidate._synthetic === "boolean";
|
|
778
819
|
}
|
|
779
820
|
function productHasPricingOptions(product) {
|
|
780
821
|
if (!product || typeof product !== "object") return false;
|
|
@@ -787,7 +828,9 @@ function productIdForPricingDiagnostics(product) {
|
|
|
787
828
|
return typeof id === "string" ? id : void 0;
|
|
788
829
|
}
|
|
789
830
|
function propertyListReferenceFromRequest(params) {
|
|
790
|
-
const
|
|
831
|
+
const filters = params.filters;
|
|
832
|
+
const nested = filters && typeof filters === "object" && !Array.isArray(filters) && Object.hasOwn(filters, "property_list") && filters.property_list !== void 0;
|
|
833
|
+
const value = nested ? filters.property_list : params.property_list;
|
|
791
834
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
792
835
|
const ref = value;
|
|
793
836
|
if (typeof ref.agent_url !== "string" || typeof ref.list_id !== "string") return void 0;
|
|
@@ -800,21 +843,37 @@ function propertyListReferenceFromRequest(params) {
|
|
|
800
843
|
function productPolicyRequestSnapshot(requestParams) {
|
|
801
844
|
const account = canonicalAccountRoutingSnapshot(requestParams.account);
|
|
802
845
|
const propertyList = propertyListReferenceFromRequest(requestParams);
|
|
846
|
+
const referenceError = propertyListReferenceError(requestParams);
|
|
803
847
|
return Object.freeze({
|
|
804
848
|
...account ? { account } : {},
|
|
805
|
-
...propertyList ? { property_list: Object.freeze(propertyList) } : {}
|
|
849
|
+
...propertyList ? { property_list: Object.freeze(propertyList) } : {},
|
|
850
|
+
...referenceError ? { property_list_error: referenceError } : {}
|
|
806
851
|
});
|
|
807
852
|
}
|
|
853
|
+
function propertyListReferenceError(params) {
|
|
854
|
+
if (typeof params.property_list_error === "string") return params.property_list_error;
|
|
855
|
+
const filters = params.filters;
|
|
856
|
+
if (params.property_list !== void 0 && !propertyListReferenceFromRequest({ property_list: params.property_list }))
|
|
857
|
+
return "property_list_invalid_reference";
|
|
858
|
+
if (!filters || typeof filters !== "object" || Array.isArray(filters) || !Object.hasOwn(filters, "property_list") || filters.property_list === void 0)
|
|
859
|
+
return void 0;
|
|
860
|
+
const nested = propertyListReferenceFromRequest(params);
|
|
861
|
+
if (!nested) return "property_list_invalid_reference";
|
|
862
|
+
if (params.property_list !== void 0) {
|
|
863
|
+
const legacy = propertyListReferenceFromRequest({ property_list: params.property_list });
|
|
864
|
+
if (!legacy || nested.agent_url !== legacy.agent_url || nested.list_id !== legacy.list_id || nested.auth_token !== legacy.auth_token) {
|
|
865
|
+
return "property_list_conflicting_references";
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return void 0;
|
|
869
|
+
}
|
|
808
870
|
function hasProductPropertyPolicyRules(policy) {
|
|
809
871
|
return Boolean(
|
|
810
872
|
policy.allowedDomains?.length || policy.allowedPropertyIdentifiers?.length || policy.requireAllowedPropertyMatch || policy.excludedDomains?.length || policy.excludedPropertyIds?.length || policy.strict || policy.unknownSelectorBehavior || policy.missingPublisherPropertiesBehavior
|
|
811
873
|
);
|
|
812
874
|
}
|
|
813
|
-
function comparablePropertyIdentifiers(identifiers) {
|
|
814
|
-
return identifiers.filter((identifier) => identifier.type === "domain" || identifier.type === "subdomain").map((identifier) => ({ type: identifier.type, value: identifier.value }));
|
|
815
|
-
}
|
|
816
875
|
function unsupportedPropertyIdentifiers(identifiers) {
|
|
817
|
-
return identifiers.filter((identifier) => identifier.type
|
|
876
|
+
return identifiers.filter((identifier) => !isSupportedPropertyIdentifierType(identifier.type)).map((identifier) => ({ type: identifier.type }));
|
|
818
877
|
}
|
|
819
878
|
function sanitizeDiagnosticUrl(value) {
|
|
820
879
|
try {
|
|
@@ -1198,12 +1257,8 @@ class SingleAgentClient {
|
|
|
1198
1257
|
// shared invalidation epoch of that key when the evidence was obtained
|
|
1199
1258
|
sharedEvidenceKey;
|
|
1200
1259
|
// discoveryCache key the local capability cache was obtained under
|
|
1201
|
-
_v2WarningFired = false;
|
|
1202
|
-
// Gate: emit the v2-sunset warning once per client instance
|
|
1203
1260
|
_syntheticV3WarningFired = false;
|
|
1204
1261
|
// Gate: emit the synthetic-v3 warning once per client instance
|
|
1205
|
-
_syntheticV2WarningFired = false;
|
|
1206
|
-
// Gate: emit the synthetic-v2 warning once per client instance
|
|
1207
1262
|
productPolicyRequestParamsByTask = /* @__PURE__ */ new Map();
|
|
1208
1263
|
canonicalCreativeTaskAssociations = /* @__PURE__ */ new Map();
|
|
1209
1264
|
previewCreativeHandlersByTask = /* @__PURE__ */ new Map();
|
|
@@ -1411,8 +1466,17 @@ class SingleAgentClient {
|
|
|
1411
1466
|
}
|
|
1412
1467
|
assertDurablePropertyListCredentialSupported(taskType, requestParams) {
|
|
1413
1468
|
if (!this.config.deferredStorage || taskType !== "get_products") return;
|
|
1414
|
-
const
|
|
1415
|
-
|
|
1469
|
+
const filters = requestParams.filters;
|
|
1470
|
+
const references = [
|
|
1471
|
+
requestParams.property_list,
|
|
1472
|
+
filters && typeof filters === "object" ? filters.property_list : void 0
|
|
1473
|
+
];
|
|
1474
|
+
const hasCredential = references.some((reference) => {
|
|
1475
|
+
if (!reference || typeof reference !== "object") return false;
|
|
1476
|
+
const token = reference.auth_token;
|
|
1477
|
+
return token !== void 0 && token !== null && token !== "";
|
|
1478
|
+
});
|
|
1479
|
+
if (!hasCredential) return;
|
|
1416
1480
|
const policyConfig = this.config.validation?.productPropertyPolicy;
|
|
1417
1481
|
if (policyConfig === false || policyConfig?.enforceRequestPropertyList === false) return;
|
|
1418
1482
|
throw new ConfigurationError(
|
|
@@ -1465,7 +1529,7 @@ class SingleAgentClient {
|
|
|
1465
1529
|
}
|
|
1466
1530
|
}
|
|
1467
1531
|
}
|
|
1468
|
-
rememberCanonicalProductRoutes(products, account, authoritativeProducts) {
|
|
1532
|
+
rememberCanonicalProductRoutes(products, account, authoritativeProducts, evidence) {
|
|
1469
1533
|
this.invalidateCanonicalProductRoutes(authoritativeProducts ?? products, account);
|
|
1470
1534
|
const accountScope = this.canonicalAccountScope(account);
|
|
1471
1535
|
const declaredOptions = authoritativeProducts ? this.sellerDeclaredFormatOptions(authoritativeProducts) : void 0;
|
|
@@ -1485,12 +1549,15 @@ class SingleAgentClient {
|
|
|
1485
1549
|
const refs = legacyFormatRefsForDeclaration(option);
|
|
1486
1550
|
const declared = declaredOptions ? declaredOptions.get(product.product_id)?.some((declaredRef) => this.sameCanonicalOptionRef(declaredRef, ref)) : sellerDeclaredFormatOption(option);
|
|
1487
1551
|
if (declared !== void 0) rememberSellerDeclaredFormatOption(option, declared);
|
|
1552
|
+
if (declared === true && evidence)
|
|
1553
|
+
rememberSellerFormatEvidence(option, { ...evidence, productId: product.product_id });
|
|
1488
1554
|
this.rememberCanonicalLegacyRoute(this.canonicalLegacyRouteKey(account, product.product_id, ref), {
|
|
1489
1555
|
kind: "product",
|
|
1490
1556
|
accountScope,
|
|
1491
1557
|
productId: product.product_id,
|
|
1492
1558
|
optionRef: ref,
|
|
1493
1559
|
refs,
|
|
1560
|
+
...declared === true && sellerFormatEvidence(option) ? { declaration: structuredCloneWithLegacyCreativeMetadata(option) } : {},
|
|
1494
1561
|
...declared === false ? { undeclaredSelector: undeclaredFormatOptionSelector(option) } : {}
|
|
1495
1562
|
});
|
|
1496
1563
|
}
|
|
@@ -3472,7 +3539,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3472
3539
|
/**
|
|
3473
3540
|
* Execute task and call appropriate handler on completion
|
|
3474
3541
|
*
|
|
3475
|
-
*
|
|
3542
|
+
* Adapts requests for maintained AdCP 3 releases and normalizes product responses.
|
|
3476
3543
|
*/
|
|
3477
3544
|
async executeAndHandle(taskType, handlerName, params, inputHandler, options, transformCompletedResponse, legacyFormatConverter, canonicalRequest, projectionCatalogs) {
|
|
3478
3545
|
const requestParamsSnapshot = structuredClone(params);
|
|
@@ -3517,11 +3584,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3517
3584
|
await this.requireSupportedMajor(taskType, options);
|
|
3518
3585
|
throwIfAborted(options?.signal);
|
|
3519
3586
|
}
|
|
3520
|
-
const earlyResult = await this.getEarlyResultForUnsupportedFeatures(taskType, normalizedParams, options);
|
|
3521
|
-
throwIfAborted(options?.signal);
|
|
3522
|
-
if (earlyResult) {
|
|
3523
|
-
return attachMatch(earlyResult);
|
|
3524
|
-
}
|
|
3525
3587
|
const agent = await this.ensureEndpointDiscovered(options);
|
|
3526
3588
|
throwIfAborted(options?.signal);
|
|
3527
3589
|
if (!options?.skipIdempotencyAutoInject && !options?.skipAccountValidation && !options?.skipRequestValidation && !options?.preserveGovernedPayload) {
|
|
@@ -3560,11 +3622,8 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3560
3622
|
capabilityDiscoveryContext.toolSchemas,
|
|
3561
3623
|
capabilityDiscoveryContext.capabilities
|
|
3562
3624
|
);
|
|
3563
|
-
const
|
|
3564
|
-
if (webhookDriftLog)
|
|
3565
|
-
if (serverVersion === "v2") {
|
|
3566
|
-
this.executor.validateAdaptedRequestAgainstV2(taskType, adaptedParams, v25DriftLogs);
|
|
3567
|
-
}
|
|
3625
|
+
const adaptationLogs = [...adaptDriftLogs];
|
|
3626
|
+
if (webhookDriftLog) adaptationLogs.push(webhookDriftLog);
|
|
3568
3627
|
const canonicalInputHandler = this.canonicalCreativeInputHandler(
|
|
3569
3628
|
taskType,
|
|
3570
3629
|
inputHandler,
|
|
@@ -3611,7 +3670,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3611
3670
|
);
|
|
3612
3671
|
throwIfAborted(effectiveOptions?.signal);
|
|
3613
3672
|
if (!result.success) await this.invalidateDiscoveryOnCapabilityError(result.adcpError?.code, effectiveOptions);
|
|
3614
|
-
const postAdapterLogs = [...inputSchemaStripLogs, ...
|
|
3673
|
+
const postAdapterLogs = [...inputSchemaStripLogs, ...adaptationLogs];
|
|
3615
3674
|
if (postAdapterLogs.length > 0) {
|
|
3616
3675
|
result.debug_logs = [...result.debug_logs ?? [], ...postAdapterLogs];
|
|
3617
3676
|
}
|
|
@@ -3707,7 +3766,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3707
3766
|
const rawSubmittedWaitForCompletion = result.submitted?.waitForCompletion;
|
|
3708
3767
|
const finalizerLegacyFormatConverter = legacyFormatConverter ?? this.resolveLegacyFormatConverter(void 0, context.projectionCatalogs);
|
|
3709
3768
|
if (result.success && result.data) {
|
|
3710
|
-
result.data = this.
|
|
3769
|
+
result.data = this.normalizeEstablishedResponse(taskType, result.data);
|
|
3711
3770
|
}
|
|
3712
3771
|
result = this.wrapProductPolicySubmittedContinuation(
|
|
3713
3772
|
result,
|
|
@@ -3853,7 +3912,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3853
3912
|
};
|
|
3854
3913
|
}
|
|
3855
3914
|
projectCanonicalCreativeData(taskType, data, transform, legacyFormatConverter) {
|
|
3856
|
-
let projected = this.
|
|
3915
|
+
let projected = this.normalizeEstablishedResponse(taskType, data);
|
|
3857
3916
|
const record = projected && typeof projected === "object" ? projected : void 0;
|
|
3858
3917
|
const canProjectRead = taskType === "get_products" ? Array.isArray(record?.products) : taskType === "list_creatives" ? Array.isArray(record?.creatives) : true;
|
|
3859
3918
|
if (transform && canProjectRead) {
|
|
@@ -4223,39 +4282,40 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4223
4282
|
message = "Property list not adhered to",
|
|
4224
4283
|
enforceRequestPropertyList = true,
|
|
4225
4284
|
propertyListResolveOptions,
|
|
4285
|
+
resolvePublisherProperties,
|
|
4286
|
+
maxPublisherLookups = 100,
|
|
4287
|
+
publisherLookupTimeoutMs = 1e4,
|
|
4288
|
+
publisherLookupBudgetMs = 1e4,
|
|
4226
4289
|
...explicitPolicy
|
|
4227
4290
|
} = policyConfig || {};
|
|
4228
4291
|
const policy = {
|
|
4229
4292
|
...explicitPolicy
|
|
4230
4293
|
};
|
|
4231
4294
|
let resolvedRequestPropertyList;
|
|
4232
|
-
|
|
4295
|
+
const referenceError = propertyListReferenceError(requestParams);
|
|
4296
|
+
if ((requestPropertyList || referenceError) && enforceRequestPropertyList) {
|
|
4233
4297
|
try {
|
|
4298
|
+
if (referenceError) throw new Error(referenceError);
|
|
4234
4299
|
const resolved = await resolvePropertyList(requestPropertyList, propertyListResolveOptions);
|
|
4235
|
-
const comparableIdentifiers = comparablePropertyIdentifiers(resolved.identifiers);
|
|
4236
4300
|
const unsupportedIdentifiers = unsupportedPropertyIdentifiers(resolved.identifiers);
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
}
|
|
4240
|
-
if (comparableIdentifiers.length > 0 || resolved.identifiers.length === 0) {
|
|
4241
|
-
policy.allowedPropertyIdentifiers = [...policy.allowedPropertyIdentifiers ?? [], ...comparableIdentifiers];
|
|
4242
|
-
policy.requireAllowedPropertyMatch = true;
|
|
4243
|
-
}
|
|
4301
|
+
policy.allowedPropertyIdentifiers = [...policy.allowedPropertyIdentifiers ?? [], ...resolved.identifiers];
|
|
4302
|
+
policy.requireAllowedPropertyMatch = true;
|
|
4244
4303
|
policy.strict = policy.strict ?? true;
|
|
4245
4304
|
resolvedRequestPropertyList = {
|
|
4246
4305
|
listId: resolved.listId,
|
|
4247
4306
|
agentUrl: resolved.agentUrl,
|
|
4248
4307
|
identifierCount: resolved.identifiers.length,
|
|
4308
|
+
unsupportedIdentifierTypes: [...new Set(unsupportedIdentifiers.map((identifier) => identifier.type))],
|
|
4249
4309
|
...resolved.cacheValidUntil ? { cacheValidUntil: resolved.cacheValidUntil } : {}
|
|
4250
4310
|
};
|
|
4251
4311
|
} catch (err) {
|
|
4252
4312
|
const errorCode = propertyListResolutionErrorCode(err);
|
|
4253
|
-
const diagnosticAgentUrl = sanitizeDiagnosticUrl(requestPropertyList.agent_url);
|
|
4313
|
+
const diagnosticAgentUrl = requestPropertyList ? sanitizeDiagnosticUrl(requestPropertyList.agent_url) : "invalid_url";
|
|
4254
4314
|
return attachMatch({
|
|
4255
4315
|
success: false,
|
|
4256
4316
|
status: "failed",
|
|
4257
4317
|
data: response,
|
|
4258
|
-
error: `${message}: could not resolve property_list
|
|
4318
|
+
error: `${message}: could not resolve property_list`,
|
|
4259
4319
|
metadata: {
|
|
4260
4320
|
...result.metadata,
|
|
4261
4321
|
status: "failed",
|
|
@@ -4268,7 +4328,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4268
4328
|
message,
|
|
4269
4329
|
diagnostics: [],
|
|
4270
4330
|
request_property_list: {
|
|
4271
|
-
list_id: requestPropertyList
|
|
4331
|
+
list_id: requestPropertyList?.list_id ?? "invalid_reference",
|
|
4272
4332
|
agent_url: diagnosticAgentUrl,
|
|
4273
4333
|
resolution_error: errorCode
|
|
4274
4334
|
}
|
|
@@ -4283,7 +4343,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4283
4343
|
mode,
|
|
4284
4344
|
ok: false,
|
|
4285
4345
|
request_property_list: {
|
|
4286
|
-
list_id: requestPropertyList
|
|
4346
|
+
list_id: requestPropertyList?.list_id,
|
|
4287
4347
|
agent_url: diagnosticAgentUrl,
|
|
4288
4348
|
resolution_error: errorCode
|
|
4289
4349
|
}
|
|
@@ -4293,6 +4353,65 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4293
4353
|
}
|
|
4294
4354
|
}
|
|
4295
4355
|
if (!hasProductPropertyPolicyRules(policy)) return result;
|
|
4356
|
+
if (resolvePublisherProperties && policy.allowedPropertyIdentifiers?.some(
|
|
4357
|
+
(identifier) => identifier.type !== "domain" && identifier.type !== "subdomain"
|
|
4358
|
+
)) {
|
|
4359
|
+
if (!Number.isSafeInteger(maxPublisherLookups) || maxPublisherLookups < 1 || !Number.isSafeInteger(publisherLookupTimeoutMs) || publisherLookupTimeoutMs < 1 || publisherLookupTimeoutMs > 2147483647 || !Number.isSafeInteger(publisherLookupBudgetMs) || publisherLookupBudgetMs < 1 || publisherLookupBudgetMs > 2147483647) {
|
|
4360
|
+
throw new ConfigurationError("Publisher lookup limits must be positive bounded integers");
|
|
4361
|
+
}
|
|
4362
|
+
const { validatePublisherDomain } = await import("../identifiers.mjs");
|
|
4363
|
+
const catalogs = Object.assign(
|
|
4364
|
+
/* @__PURE__ */ Object.create(null),
|
|
4365
|
+
policy.publisherProperties
|
|
4366
|
+
);
|
|
4367
|
+
const domains = new Set(
|
|
4368
|
+
response.products.flatMap(
|
|
4369
|
+
(product) => Array.isArray(product.publisher_properties) ? product.publisher_properties.flatMap(
|
|
4370
|
+
(selector) => selector && typeof selector === "object" && "publisher_domain" in selector ? [selector.publisher_domain] : []
|
|
4371
|
+
) : []
|
|
4372
|
+
)
|
|
4373
|
+
);
|
|
4374
|
+
const hosts = [
|
|
4375
|
+
...new Set(
|
|
4376
|
+
[...domains].flatMap(
|
|
4377
|
+
(domain) => typeof domain === "string" ? [normalizeDomainForPropertyPolicy(domain)?.host] : []
|
|
4378
|
+
)
|
|
4379
|
+
)
|
|
4380
|
+
].filter((host) => typeof host === "string" && !Object.hasOwn(catalogs, host));
|
|
4381
|
+
for (const host of hosts) catalogs[host] = void 0;
|
|
4382
|
+
const lookupStartedAt = performance.now();
|
|
4383
|
+
for (const host of hosts.slice(0, maxPublisherLookups)) {
|
|
4384
|
+
throwIfAborted(taskSignal);
|
|
4385
|
+
const remainingBudgetMs = publisherLookupBudgetMs - (performance.now() - lookupStartedAt);
|
|
4386
|
+
if (remainingBudgetMs <= 0) break;
|
|
4387
|
+
if (!validatePublisherDomain(host).ok || isLikelyPrivateUrl(`https://${host}`)) continue;
|
|
4388
|
+
const controller = new AbortController();
|
|
4389
|
+
const signal = taskSignal ? AbortSignal.any([taskSignal, controller.signal]) : controller.signal;
|
|
4390
|
+
let timeout;
|
|
4391
|
+
let budgetExpired = false;
|
|
4392
|
+
try {
|
|
4393
|
+
catalogs[host] = await Promise.race([
|
|
4394
|
+
resolvePublisherProperties(host, { signal }),
|
|
4395
|
+
new Promise((_, reject) => {
|
|
4396
|
+
timeout = setTimeout(
|
|
4397
|
+
() => {
|
|
4398
|
+
if (remainingBudgetMs <= publisherLookupTimeoutMs) budgetExpired = true;
|
|
4399
|
+
controller.abort();
|
|
4400
|
+
reject(new Error("publisher_catalog_timeout"));
|
|
4401
|
+
},
|
|
4402
|
+
Math.min(publisherLookupTimeoutMs, remainingBudgetMs)
|
|
4403
|
+
);
|
|
4404
|
+
})
|
|
4405
|
+
]);
|
|
4406
|
+
} catch {
|
|
4407
|
+
catalogs[host] = void 0;
|
|
4408
|
+
} finally {
|
|
4409
|
+
if (timeout) clearTimeout(timeout);
|
|
4410
|
+
}
|
|
4411
|
+
if (budgetExpired) break;
|
|
4412
|
+
}
|
|
4413
|
+
policy.publisherProperties = catalogs;
|
|
4414
|
+
}
|
|
4296
4415
|
let validation;
|
|
4297
4416
|
try {
|
|
4298
4417
|
validation = validateProductsAgainstPropertyPolicy({
|
|
@@ -4316,6 +4435,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4316
4435
|
list_id: resolvedRequestPropertyList.listId,
|
|
4317
4436
|
agent_url: sanitizeDiagnosticUrl(resolvedRequestPropertyList.agentUrl),
|
|
4318
4437
|
identifier_count: resolvedRequestPropertyList.identifierCount,
|
|
4438
|
+
unsupported_identifier_types: resolvedRequestPropertyList.unsupportedIdentifierTypes,
|
|
4319
4439
|
...resolvedRequestPropertyList.cacheValidUntil ? { cache_valid_until: resolvedRequestPropertyList.cacheValidUntil } : {}
|
|
4320
4440
|
}
|
|
4321
4441
|
} : {},
|
|
@@ -4465,7 +4585,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4465
4585
|
waitForCompletion: async (pollInterval, signal) => {
|
|
4466
4586
|
let completed = await submitted.waitForCompletion(pollInterval, signal);
|
|
4467
4587
|
if (completed.success && completed.data) {
|
|
4468
|
-
completed.data = this.
|
|
4588
|
+
completed.data = this.normalizeEstablishedResponse(taskType, completed.data);
|
|
4469
4589
|
}
|
|
4470
4590
|
const terminal = completed.status === "completed" || completed.status === "failed";
|
|
4471
4591
|
try {
|
|
@@ -4496,7 +4616,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4496
4616
|
attachMatch({
|
|
4497
4617
|
success: true,
|
|
4498
4618
|
status: "completed",
|
|
4499
|
-
data: this.
|
|
4619
|
+
data: this.normalizeEstablishedResponse(taskType, taskInfo.result),
|
|
4500
4620
|
metadata: {
|
|
4501
4621
|
taskId: taskInfo.taskId,
|
|
4502
4622
|
taskName: taskInfo.taskType,
|
|
@@ -4572,8 +4692,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4572
4692
|
}
|
|
4573
4693
|
/**
|
|
4574
4694
|
* Adapt a request for the detected server wire version and the seller's
|
|
4575
|
-
* AdCP protocol version. Applies
|
|
4576
|
-
* to a v2 server, then applies protocol-version adapters (e.g. stripping
|
|
4695
|
+
* AdCP protocol version. Applies protocol-version adapters (e.g. stripping
|
|
4577
4696
|
* 3.1-only fields for a 3.0 seller). Returns the adapted params and any
|
|
4578
4697
|
* drift log entries describing what was changed.
|
|
4579
4698
|
*
|
|
@@ -4581,22 +4700,14 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4581
4700
|
* current call's tool schemas can be supplied without cross-tenant caching.
|
|
4582
4701
|
*/
|
|
4583
4702
|
adaptRequest(taskType, params, serverVersion, debugLogs, perCallToolSchemas, perCallCapabilities) {
|
|
4584
|
-
const driftLogs = [];
|
|
4585
|
-
let adapted = params;
|
|
4586
4703
|
if (serverVersion !== "v3") {
|
|
4587
|
-
|
|
4588
|
-
if (pair) adapted = pair.adaptRequest(adapted);
|
|
4704
|
+
throw new VersionUnsupportedError(taskType, "version", "v2", this.agent.agent_uri);
|
|
4589
4705
|
}
|
|
4706
|
+
const driftLogs = [];
|
|
4707
|
+
let adapted = params;
|
|
4590
4708
|
const toolSchema = (perCallToolSchemas ?? this.cachedToolSchemas)?.get(taskType);
|
|
4591
4709
|
if (toolSchema && Object.keys(toolSchema).length > 0) {
|
|
4592
4710
|
const declaredFields = new Set(Object.keys(toolSchema));
|
|
4593
|
-
const adapterAliases = [["brand_manifest", "brand"]];
|
|
4594
|
-
for (const [adapterField, schemaField] of adapterAliases) {
|
|
4595
|
-
if (adapted[adapterField] !== void 0 && !declaredFields.has(adapterField) && declaredFields.has(schemaField) && adapted[schemaField] === void 0 && valueMatchesSchemaType(adapted[adapterField], toolSchema[schemaField])) {
|
|
4596
|
-
adapted[schemaField] = adapted[adapterField];
|
|
4597
|
-
delete adapted[adapterField];
|
|
4598
|
-
}
|
|
4599
|
-
}
|
|
4600
4711
|
const envelopeFields = ADCP_ENVELOPE_FIELDS;
|
|
4601
4712
|
const filtered = {};
|
|
4602
4713
|
const schemaStripped = [];
|
|
@@ -4644,67 +4755,19 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4644
4755
|
}
|
|
4645
4756
|
return { params: adapted, driftLogs };
|
|
4646
4757
|
}
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
*
|
|
4660
|
-
* Returns an early empty result if the request requires v3 features
|
|
4661
|
-
* that the server doesn't support. This treats "products matching unsupported
|
|
4662
|
-
* capability" as an empty result set rather than an error.
|
|
4663
|
-
*
|
|
4664
|
-
* @returns TaskResult with empty data if v3 features are unsupported, null to proceed normally
|
|
4665
|
-
*/
|
|
4666
|
-
async getEarlyResultForUnsupportedFeatures(taskType, params, options) {
|
|
4667
|
-
if (taskType !== "get_products") {
|
|
4668
|
-
return null;
|
|
4669
|
-
}
|
|
4670
|
-
const capabilities = await this.getCapabilities(options);
|
|
4671
|
-
if (capabilities.version === "v3") {
|
|
4672
|
-
return null;
|
|
4673
|
-
}
|
|
4674
|
-
const usesUnsupportedFeature = (
|
|
4675
|
-
// required_features: content_standards requires contentStandards
|
|
4676
|
-
params.filters?.required_features?.includes("content_standards") && !capabilities.features.contentStandards
|
|
4677
|
-
);
|
|
4678
|
-
if (!usesUnsupportedFeature) {
|
|
4679
|
-
return null;
|
|
4758
|
+
normalizeEstablishedResponse(taskType, data) {
|
|
4759
|
+
if (!data) return data;
|
|
4760
|
+
switch (taskType) {
|
|
4761
|
+
case "get_products":
|
|
4762
|
+
return normalizeGetProductsResponse(data);
|
|
4763
|
+
case "create_media_buy":
|
|
4764
|
+
case "update_media_buy":
|
|
4765
|
+
return normalizeMediaBuyResponse(data);
|
|
4766
|
+
case "list_creative_formats":
|
|
4767
|
+
return normalizeFormatsResponse(data);
|
|
4768
|
+
default:
|
|
4769
|
+
return data;
|
|
4680
4770
|
}
|
|
4681
|
-
console.warn(
|
|
4682
|
-
`[AdCP] v3-only features not supported by server "${this.agent.id}" (${capabilities.version}). Returning empty results.`
|
|
4683
|
-
);
|
|
4684
|
-
const emptyResponse = {
|
|
4685
|
-
products: [],
|
|
4686
|
-
property_list_applied: false
|
|
4687
|
-
};
|
|
4688
|
-
return {
|
|
4689
|
-
success: true,
|
|
4690
|
-
status: "completed",
|
|
4691
|
-
data: emptyResponse,
|
|
4692
|
-
metadata: {
|
|
4693
|
-
taskId: `early_${Date.now()}`,
|
|
4694
|
-
taskName: taskType,
|
|
4695
|
-
agent: {
|
|
4696
|
-
id: this.agent.id,
|
|
4697
|
-
name: this.agent.name,
|
|
4698
|
-
protocol: this.normalizedAgent.protocol
|
|
4699
|
-
},
|
|
4700
|
-
responseTimeMs: 0,
|
|
4701
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4702
|
-
clarificationRounds: 0,
|
|
4703
|
-
status: "completed",
|
|
4704
|
-
serverVersion: capabilities.version,
|
|
4705
|
-
serverVersionSynthetic: capabilities._synthetic
|
|
4706
|
-
}
|
|
4707
|
-
};
|
|
4708
4771
|
}
|
|
4709
4772
|
// ====== MEDIA BUY TASKS ======
|
|
4710
4773
|
/**
|
|
@@ -4804,6 +4867,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4804
4867
|
}
|
|
4805
4868
|
}
|
|
4806
4869
|
const conditionalSnapshot = skipCacheRead ? void 0 : cache?.read(cacheScope, cacheParams, true);
|
|
4870
|
+
const productEvidence = this.usesScopedDiscoveryTransport(
|
|
4871
|
+
effectiveOptions
|
|
4872
|
+
) ? void 0 : {
|
|
4873
|
+
scopeKey: this.getCapabilityEvidenceScope().scopeKey,
|
|
4874
|
+
accountScope: this.canonicalAccountScope(account),
|
|
4875
|
+
expiresAt: Date.now() + resolveAgentDiscoveryTtlMs(this.config.discoveryCache?.ttlMs)
|
|
4876
|
+
};
|
|
4807
4877
|
const result = await this.executeAndHandle(
|
|
4808
4878
|
"get_products",
|
|
4809
4879
|
"onGetProductsStatusChange",
|
|
@@ -4816,7 +4886,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4816
4886
|
projectionCatalogs: projectionCatalogs ?? this.config.projectionCatalogs
|
|
4817
4887
|
});
|
|
4818
4888
|
const authoritativeProducts = Array.isArray(data.products) ? data.products : response.products;
|
|
4819
|
-
this.rememberCanonicalProductRoutes(response.products, account, authoritativeProducts);
|
|
4889
|
+
this.rememberCanonicalProductRoutes(response.products, account, authoritativeProducts, productEvidence);
|
|
4820
4890
|
const { _message: _dropLegacyMessage, ...canonical } = response;
|
|
4821
4891
|
void _dropLegacyMessage;
|
|
4822
4892
|
return { ...canonical, projection: { diagnostics } };
|
|
@@ -4827,7 +4897,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
4827
4897
|
);
|
|
4828
4898
|
const finishCache = async (completed) => {
|
|
4829
4899
|
if (!cache) return completed;
|
|
4830
|
-
const cachedResult = cache.write(cacheScope, cacheParams, completed, conditionalSnapshot)
|
|
4900
|
+
const cachedResult = cache.write(cacheScope, cacheParams, completed, conditionalSnapshot, (materialized) => {
|
|
4901
|
+
this.rememberCanonicalProductRoutes(materialized.data?.products ?? [], account, void 0, productEvidence);
|
|
4902
|
+
});
|
|
4831
4903
|
if (cachedResult.success && cachedResult.status === "completed") {
|
|
4832
4904
|
if (!skipCacheRead && cacheParams.if_wholesale_feed_version === void 0 && cacheParams.if_pricing_version === void 0 && cachedResult.data.unchanged === true) {
|
|
4833
4905
|
return this.getProducts(params, inputHandler, {
|
|
@@ -5005,7 +5077,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
5005
5077
|
if (hasCreativeFormatData) {
|
|
5006
5078
|
this.validateBeforeCreativeCapabilityProbe("create_media_buy", params, taskOptions);
|
|
5007
5079
|
}
|
|
5008
|
-
const wireMode = hasCreativeFormatData ? await this.
|
|
5080
|
+
const wireMode = hasCreativeFormatData ? await this.resolveCreativeWireMode(
|
|
5081
|
+
"create_media_buy",
|
|
5082
|
+
taskOptions,
|
|
5083
|
+
true,
|
|
5084
|
+
() => this.productOptionsSupportCanonicalWire("create_media_buy", params, [], options)
|
|
5085
|
+
) : "canonical";
|
|
5009
5086
|
const wireParams = params;
|
|
5010
5087
|
const result = await this.executeAndHandle(
|
|
5011
5088
|
"create_media_buy",
|
|
@@ -5093,7 +5170,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
5093
5170
|
if (hasCreativeFormatData) {
|
|
5094
5171
|
this.validateBeforeCreativeCapabilityProbe("update_media_buy", params, taskOptions);
|
|
5095
5172
|
}
|
|
5096
|
-
const wireMode = hasCreativeFormatData ? await this.
|
|
5173
|
+
const wireMode = hasCreativeFormatData ? await this.resolveCreativeWireMode(
|
|
5174
|
+
"update_media_buy",
|
|
5175
|
+
taskOptions,
|
|
5176
|
+
true,
|
|
5177
|
+
() => this.productOptionsSupportCanonicalWire("update_media_buy", params, [], options)
|
|
5178
|
+
) : "canonical";
|
|
5097
5179
|
const result = await this.executeAndHandle(
|
|
5098
5180
|
"update_media_buy",
|
|
5099
5181
|
"onUpdateMediaBuyStatusChange",
|
|
@@ -5182,7 +5264,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
5182
5264
|
projectionCatalogs ?? this.config.projectionCatalogs
|
|
5183
5265
|
);
|
|
5184
5266
|
this.validateBeforeCreativeCapabilityProbe("sync_creatives", params, taskOptions);
|
|
5185
|
-
const wireMode = await this.resolveCreativeFormatWireMode("sync_creatives", taskOptions);
|
|
5186
5267
|
const configuredSelectorContainers = [
|
|
5187
5268
|
...creativeFormatProjection?.selectorContainers ?? []
|
|
5188
5269
|
];
|
|
@@ -5194,10 +5275,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
5194
5275
|
const assignmentPackageContainers = Array.isArray(params.assignments) ? params.assignments.flatMap(
|
|
5195
5276
|
(assignment) => typeof assignment.package_id === "string" && !configuredPackageIds.has(assignment.package_id) ? [{ package_id: assignment.package_id }] : []
|
|
5196
5277
|
) : [];
|
|
5278
|
+
const selectorContainers = [...configuredSelectorContainers, ...assignmentPackageContainers];
|
|
5279
|
+
const wireMode = await this.resolveCreativeWireMode(
|
|
5280
|
+
"sync_creatives",
|
|
5281
|
+
taskOptions,
|
|
5282
|
+
true,
|
|
5283
|
+
() => this.productOptionsSupportCanonicalWire("sync_creatives", params, selectorContainers, options)
|
|
5284
|
+
);
|
|
5197
5285
|
const wireParams = this.projectUndeclaredFormatOptions(
|
|
5198
5286
|
projectSyncCreativesForDelivery(
|
|
5199
5287
|
params,
|
|
5200
|
-
|
|
5288
|
+
selectorContainers,
|
|
5201
5289
|
wireMode,
|
|
5202
5290
|
effectiveLegacyFormatConverter,
|
|
5203
5291
|
effectiveCanonicalFormatLegacyResolver
|
|
@@ -5237,16 +5325,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
5237
5325
|
* sending a mutation. Discovers capabilities and the current tool's input
|
|
5238
5326
|
* schema, or reuses fresh cached/primed evidence, with this client's wire pin.
|
|
5239
5327
|
*
|
|
5240
|
-
* `unknown`
|
|
5241
|
-
*
|
|
5242
|
-
*
|
|
5328
|
+
* This context-free check returns `unknown` when capabilities and schema do
|
|
5329
|
+
* not establish support. A write to a proven 3.1 seller can still select
|
|
5330
|
+
* canonical delivery from matching seller-advertised product options;
|
|
5331
|
+
* otherwise projection requires an unambiguous legacy reference.
|
|
5243
5332
|
* Conflicting evidence and unproven support with a 3.2+ buyer pin throw
|
|
5244
5333
|
* `CreativeFormatCapabilityError`, just as they do during a write.
|
|
5245
5334
|
*/
|
|
5246
5335
|
async resolveCreativeFormatWireMode(taskType, options) {
|
|
5247
5336
|
return this.resolveCreativeWireMode(taskType, options, true);
|
|
5248
5337
|
}
|
|
5249
|
-
async resolveCreativeWireMode(taskType, options, canRediscover) {
|
|
5338
|
+
async resolveCreativeWireMode(taskType, options, canRediscover, matchingProductOptions) {
|
|
5250
5339
|
const discoveryContext = {};
|
|
5251
5340
|
const capabilities = await this.getCapabilities({
|
|
5252
5341
|
...options,
|
|
@@ -5265,13 +5354,16 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
5265
5354
|
`Seller capability and ${taskType} input schema disagree about canonical creative support`
|
|
5266
5355
|
);
|
|
5267
5356
|
}
|
|
5268
|
-
|
|
5357
|
+
let resolved = declared !== "unknown" ? declared : schema;
|
|
5358
|
+
if (resolved === "unknown" && canUseProductOptionsForCreativeWire(capabilities, wireRelease) && matchingProductOptions?.()) {
|
|
5359
|
+
resolved = "canonical";
|
|
5360
|
+
}
|
|
5269
5361
|
const release = /^v?(\d+)\.(\d+)(?:\.|-|$)/.exec(wireRelease.trim());
|
|
5270
5362
|
const canonicalRequiredByBuyerPin = release !== null && (Number(release[1]) > 3 || Number(release[1]) === 3 && Number(release[2]) >= 2);
|
|
5271
5363
|
if (resolved === "unknown" && canonicalRequiredByBuyerPin) {
|
|
5272
5364
|
if (canRediscover && !usesScopedFetch && this.normalizedAgent.protocol === "mcp" && this.capabilitiesFromSharedCache && toolSchemas?.has(taskType) && !toolInputSchemasByProperties.has(toolSchemas)) {
|
|
5273
5365
|
await this.invalidateDiscoveryCache(options);
|
|
5274
|
-
return this.resolveCreativeWireMode(taskType, options, false);
|
|
5366
|
+
return this.resolveCreativeWireMode(taskType, options, false, matchingProductOptions);
|
|
5275
5367
|
}
|
|
5276
5368
|
throw new CreativeFormatCapabilityError(
|
|
5277
5369
|
`Cannot prove which AdCP release the seller serves for ${taskType}; a 3.2+ client will not guess a legacy creative wire shape`
|
|
@@ -5279,6 +5371,112 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
5279
5371
|
}
|
|
5280
5372
|
return resolved;
|
|
5281
5373
|
}
|
|
5374
|
+
/** Product evidence applies to this request only; it must never prime a tool-wide capability. */
|
|
5375
|
+
productOptionsSupportCanonicalWire(taskType, request, selectorContainers = [], options) {
|
|
5376
|
+
if (!isPlainRecord(request) || this.usesScopedDiscoveryTransport(options)) return false;
|
|
5377
|
+
const scopeKey = this.getCapabilityEvidenceScope().scopeKey;
|
|
5378
|
+
const accountScope = this.canonicalAccountScope(request.account);
|
|
5379
|
+
const optionRef = (value) => {
|
|
5380
|
+
if (!isPlainRecord(value) || typeof value.format_option_id !== "string" || !value.format_option_id) {
|
|
5381
|
+
return void 0;
|
|
5382
|
+
}
|
|
5383
|
+
if (typeof value.publisher_domain === "string") {
|
|
5384
|
+
return {
|
|
5385
|
+
scope: "publisher",
|
|
5386
|
+
publisher_domain: value.publisher_domain,
|
|
5387
|
+
format_option_id: value.format_option_id
|
|
5388
|
+
};
|
|
5389
|
+
}
|
|
5390
|
+
if (value.scope !== void 0 && value.scope !== "product") return void 0;
|
|
5391
|
+
return { scope: "product", format_option_id: value.format_option_id };
|
|
5392
|
+
};
|
|
5393
|
+
const accepts = (container, creative, depth = 0) => {
|
|
5394
|
+
if (depth > 32) return false;
|
|
5395
|
+
if (Array.isArray(container.selector_containers)) {
|
|
5396
|
+
return container.selector_containers.length > 0 && container.selector_containers.every((nested) => accepts(nested, creative, depth + 1));
|
|
5397
|
+
}
|
|
5398
|
+
const refs = Array.isArray(container.format_option_refs) ? container.format_option_refs.map(optionRef) : [];
|
|
5399
|
+
if (refs.some((ref) => ref === void 0)) return false;
|
|
5400
|
+
const creativeRef = isPlainRecord(creative) ? optionRef(creative.format_option_ref) : void 0;
|
|
5401
|
+
if (isPlainRecord(creative) && creative.format_option_ref !== void 0 && !creativeRef) return false;
|
|
5402
|
+
const isSellerDeclaration = (value) => {
|
|
5403
|
+
if (!isPlainRecord(value) || sellerDeclaredFormatOption(value) !== true || isSynthesizedFormatOption(value)) {
|
|
5404
|
+
return false;
|
|
5405
|
+
}
|
|
5406
|
+
const evidence2 = sellerFormatEvidence(value);
|
|
5407
|
+
if (!evidence2 || evidence2.scopeKey !== scopeKey || typeof container.product_id === "string" && evidence2.productId !== container.product_id || evidence2.expiresAt <= Date.now() || evidence2.accountScope !== accountScope && evidence2.accountScope !== "none")
|
|
5408
|
+
return false;
|
|
5409
|
+
const ref = optionRef(value);
|
|
5410
|
+
if (ref && formatOptionOriginFromRoutes(
|
|
5411
|
+
options?.canonicalFormatLegacyResolver,
|
|
5412
|
+
ref,
|
|
5413
|
+
typeof container.product_id === "string" ? container.product_id : void 0
|
|
5414
|
+
)?.seller_declared === false)
|
|
5415
|
+
return false;
|
|
5416
|
+
return !ref || typeof container.product_id !== "string" || this.cachedFormatOptionOrigin(request.account, ref, container.product_id)?.seller_declared !== false;
|
|
5417
|
+
};
|
|
5418
|
+
const declarations = [
|
|
5419
|
+
...(Array.isArray(container.format_options) ? container.format_options : []).filter(isSellerDeclaration),
|
|
5420
|
+
...selectedFormatOptions(container).filter(isSellerDeclaration)
|
|
5421
|
+
];
|
|
5422
|
+
if (typeof container.product_id === "string") {
|
|
5423
|
+
for (const ref of [...refs, ...creativeRef ? [creativeRef] : []]) {
|
|
5424
|
+
if (!ref) continue;
|
|
5425
|
+
const route = this.routeForOption(request.account, container.product_id, ref);
|
|
5426
|
+
if (route?.kind === "product" && route.declaration && isSellerDeclaration(route.declaration))
|
|
5427
|
+
declarations.push(route.declaration);
|
|
5428
|
+
}
|
|
5429
|
+
}
|
|
5430
|
+
const available = declarations.filter((declaration) => declaration.experimental !== true);
|
|
5431
|
+
const matchesRef = (declaration, ref) => {
|
|
5432
|
+
const declaredRef = optionRef(declaration);
|
|
5433
|
+
return declaredRef !== void 0 && sameFormatOptionRef(declaredRef, ref);
|
|
5434
|
+
};
|
|
5435
|
+
if (!refs.every((ref) => available.some((declaration) => matchesRef(declaration, ref)))) return false;
|
|
5436
|
+
const selected = available.filter(
|
|
5437
|
+
(declaration) => refs.length === 0 || refs.some((ref) => matchesRef(declaration, ref))
|
|
5438
|
+
);
|
|
5439
|
+
if (creative === void 0) return refs.length > 0 && selected.length > 0;
|
|
5440
|
+
if (!isPlainRecord(creative) || typeof creative.format_kind !== "string" || creative.format_id !== void 0)
|
|
5441
|
+
return false;
|
|
5442
|
+
return selected.some(
|
|
5443
|
+
(declaration) => declaration.format_kind === creative.format_kind && (!creativeRef || matchesRef(declaration, creativeRef)) && creativeMatchesProductOption(creative, declaration)
|
|
5444
|
+
);
|
|
5445
|
+
};
|
|
5446
|
+
if (taskType === "sync_creatives") {
|
|
5447
|
+
if (!Array.isArray(request.creatives) || request.creatives.length === 0) return false;
|
|
5448
|
+
const creatives = request.creatives;
|
|
5449
|
+
const assignments = Array.isArray(request.assignments) ? request.assignments : [];
|
|
5450
|
+
if (!assignments.every(
|
|
5451
|
+
(value) => isPlainRecord(value) && typeof value.package_id === "string" && typeof value.creative_id === "string" && creatives.some((creative) => isPlainRecord(creative) && creative.creative_id === value.creative_id)
|
|
5452
|
+
))
|
|
5453
|
+
return false;
|
|
5454
|
+
return creatives.every((creative) => {
|
|
5455
|
+
if (!isPlainRecord(creative)) return false;
|
|
5456
|
+
const assigned = new Set(
|
|
5457
|
+
assignments.flatMap(
|
|
5458
|
+
(value) => isPlainRecord(value) && value.creative_id === creative.creative_id && typeof value.package_id === "string" ? [value.package_id] : []
|
|
5459
|
+
)
|
|
5460
|
+
);
|
|
5461
|
+
const relevant = assigned.size === 0 ? selectorContainers : selectorContainers.filter(
|
|
5462
|
+
(container) => typeof container.package_id === "string" && assigned.has(container.package_id)
|
|
5463
|
+
);
|
|
5464
|
+
return relevant.length > 0 && [...assigned].every((id) => relevant.some((container) => container.package_id === id)) && relevant.every((container) => accepts(container, creative));
|
|
5465
|
+
});
|
|
5466
|
+
}
|
|
5467
|
+
const packages = ["packages", "new_packages"].flatMap((key) => Array.isArray(request[key]) ? request[key] : []);
|
|
5468
|
+
let evidence = false;
|
|
5469
|
+
return packages.length > 0 && packages.every((pkg) => {
|
|
5470
|
+
if (!isPlainRecord(pkg)) return false;
|
|
5471
|
+
const creatives = Array.isArray(pkg.creatives) ? pkg.creatives : [];
|
|
5472
|
+
const hasSelectors = Array.isArray(pkg.format_option_refs) && pkg.format_option_refs.length > 0;
|
|
5473
|
+
if (!hasSelectors && creatives.length === 0) {
|
|
5474
|
+
return pkg.format_kind === void 0 && pkg.format_ids === void 0;
|
|
5475
|
+
}
|
|
5476
|
+
evidence = true;
|
|
5477
|
+
return (!hasSelectors || accepts(pkg)) && creatives.every((creative) => accepts(pkg, creative));
|
|
5478
|
+
}) && evidence;
|
|
5479
|
+
}
|
|
5282
5480
|
/** Validate malformed creative payloads before capability discovery can perform I/O. */
|
|
5283
5481
|
validateBeforeCreativeCapabilityProbe(taskType, params, options) {
|
|
5284
5482
|
if (options.skipIdempotencyAutoInject || options.skipAccountValidation || options.skipRequestValidation) return;
|
|
@@ -6187,11 +6385,8 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6187
6385
|
capabilityDiscoveryContext.toolSchemas,
|
|
6188
6386
|
capabilityDiscoveryContext.capabilities
|
|
6189
6387
|
);
|
|
6190
|
-
const
|
|
6191
|
-
if (webhookDriftLog)
|
|
6192
|
-
if (serverVersion === "v2") {
|
|
6193
|
-
this.executor.validateAdaptedRequestAgainstV2(taskName, adaptedParams, v25DriftLogs);
|
|
6194
|
-
}
|
|
6388
|
+
const adaptationLogs = [...adaptDriftLogs];
|
|
6389
|
+
if (webhookDriftLog) adaptationLogs.push(webhookDriftLog);
|
|
6195
6390
|
const deferredClientContext = {
|
|
6196
6391
|
kind: "single-agent",
|
|
6197
6392
|
taskType: taskName,
|
|
@@ -6221,7 +6416,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6221
6416
|
deferredClientContext
|
|
6222
6417
|
);
|
|
6223
6418
|
if (!result.success) await this.invalidateDiscoveryOnCapabilityError(result.adcpError?.code, effectiveOptions);
|
|
6224
|
-
const postAdapterLogs = [...inputSchemaStripLogs, ...
|
|
6419
|
+
const postAdapterLogs = [...inputSchemaStripLogs, ...adaptationLogs];
|
|
6225
6420
|
if (postAdapterLogs.length > 0) {
|
|
6226
6421
|
result.debug_logs = [...result.debug_logs ?? [], ...postAdapterLogs];
|
|
6227
6422
|
}
|
|
@@ -6411,6 +6606,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6411
6606
|
getProtocol() {
|
|
6412
6607
|
return this.normalizedAgent.protocol;
|
|
6413
6608
|
}
|
|
6609
|
+
/** Resolved MCP endpoint already used by this client; never performs discovery. */
|
|
6610
|
+
getDiscoveredMcpEndpoint() {
|
|
6611
|
+
return this.discoveredEndpoint;
|
|
6612
|
+
}
|
|
6414
6613
|
/**
|
|
6415
6614
|
* Get the canonical base URL for this agent
|
|
6416
6615
|
*
|
|
@@ -6912,7 +7111,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6912
7111
|
* Get agent capabilities, including AdCP version support
|
|
6913
7112
|
*
|
|
6914
7113
|
* For v3 servers, calls get_adcp_capabilities tool.
|
|
6915
|
-
*
|
|
7114
|
+
* Requires AdCP 3 capability discovery; retired AdCP 2 agents are rejected.
|
|
6916
7115
|
*
|
|
6917
7116
|
* @returns Promise resolving to normalized capabilities object
|
|
6918
7117
|
*
|
|
@@ -6949,7 +7148,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
6949
7148
|
}
|
|
6950
7149
|
if (!usesScopedFetch && this.cachedCapabilities) {
|
|
6951
7150
|
if (discoveryContext) discoveryContext.toolSchemas = this.cachedToolSchemas;
|
|
6952
|
-
this.
|
|
7151
|
+
this.assertSupportedServer(this.cachedCapabilities);
|
|
6953
7152
|
return this.cachedCapabilities;
|
|
6954
7153
|
}
|
|
6955
7154
|
if (!usesScopedFetch && this.config.discoveryCache) {
|
|
@@ -7033,7 +7232,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7033
7232
|
this.capabilitiesFromSharedCache = true;
|
|
7034
7233
|
this.recordSharedEvidence(key);
|
|
7035
7234
|
if (discoveryContext) discoveryContext.toolSchemas = this.cachedToolSchemas;
|
|
7036
|
-
this.
|
|
7235
|
+
this.assertSupportedServer(installed);
|
|
7037
7236
|
return installed;
|
|
7038
7237
|
}
|
|
7039
7238
|
async discoverCapabilitiesLive(options, usesScopedFetch, discoveryContext) {
|
|
@@ -7083,16 +7282,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7083
7282
|
throw createTimeoutError(requestTimeoutMs);
|
|
7084
7283
|
}
|
|
7085
7284
|
if (result.success && result.data) {
|
|
7086
|
-
const
|
|
7285
|
+
const capabilities = augmentCapabilitiesFromTools(parseCapabilitiesResponse(result.data), tools);
|
|
7286
|
+
this.assertSupportedServer(capabilities);
|
|
7087
7287
|
if (!usesScopedFetch && !superseded()) {
|
|
7088
|
-
this.cachedCapabilities =
|
|
7288
|
+
this.cachedCapabilities = capabilities;
|
|
7089
7289
|
this.capabilitiesFromSharedCache = false;
|
|
7090
|
-
if (!
|
|
7290
|
+
if (!capabilities._synthetic && this.config.discoveryCache) {
|
|
7091
7291
|
this.recordSharedEvidence(this.sharedDiscoveryKey(options));
|
|
7092
7292
|
const stored = await this.writeSharedDiscovery(
|
|
7093
7293
|
options,
|
|
7094
7294
|
{
|
|
7095
|
-
capabilities: structuredClone(
|
|
7295
|
+
capabilities: structuredClone(capabilities),
|
|
7096
7296
|
toolSchemas: Object.fromEntries(discoveredToolSchemas),
|
|
7097
7297
|
toolInputSchemas: Object.fromEntries(discoveredInputSchemas)
|
|
7098
7298
|
},
|
|
@@ -7100,7 +7300,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7100
7300
|
startedAtEpoch
|
|
7101
7301
|
);
|
|
7102
7302
|
if (superseded()) {
|
|
7103
|
-
if (this.cachedCapabilities ===
|
|
7303
|
+
if (this.cachedCapabilities === capabilities) {
|
|
7104
7304
|
this.cachedCapabilities = void 0;
|
|
7105
7305
|
this.cachedToolSchemas = void 0;
|
|
7106
7306
|
this.primedCapabilitiesExpiresAt = void 0;
|
|
@@ -7110,31 +7310,26 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7110
7310
|
}
|
|
7111
7311
|
}
|
|
7112
7312
|
}
|
|
7113
|
-
this.
|
|
7114
|
-
return
|
|
7313
|
+
this.assertSupportedServer(capabilities);
|
|
7314
|
+
return capabilities;
|
|
7115
7315
|
}
|
|
7116
7316
|
if (!advertisesCapabilitiesTool) {
|
|
7117
7317
|
throw new Error("unadvertised official A2A capability probe was not supported");
|
|
7118
7318
|
}
|
|
7119
7319
|
if (result.data && looksLikeV3Capabilities(result.data)) {
|
|
7320
|
+
const capabilities = augmentCapabilitiesFromTools(parseCapabilitiesResponse(result.data), tools);
|
|
7321
|
+
this.assertSupportedServer(capabilities);
|
|
7120
7322
|
console.warn(
|
|
7121
7323
|
`[AdCP] Agent "${this.agent.id}" returned a get_adcp_capabilities response that failed validation, but the response is structurally v3-shaped. Treating as v3 (the agent has a wire-shape bug \u2014 that's the thing to fix).`,
|
|
7122
7324
|
{ hasError: !!result.error, hasData: !!result.data }
|
|
7123
7325
|
);
|
|
7124
|
-
const parsed = parseCapabilitiesResponse(result.data);
|
|
7125
|
-
const v3Capabilities = {
|
|
7126
|
-
...parsed,
|
|
7127
|
-
version: "v3",
|
|
7128
|
-
majorVersions: parsed.majorVersions.includes(3) ? parsed.majorVersions : [3]
|
|
7129
|
-
};
|
|
7130
|
-
const capabilities2 = augmentCapabilitiesFromTools(v3Capabilities, tools);
|
|
7131
7326
|
if (!usesScopedFetch && !superseded()) {
|
|
7132
|
-
this.cachedCapabilities =
|
|
7327
|
+
this.cachedCapabilities = capabilities;
|
|
7133
7328
|
this.capabilitiesFromSharedCache = false;
|
|
7134
7329
|
this.recordSharedEvidence(this.sharedDiscoveryKey(options));
|
|
7135
7330
|
}
|
|
7136
|
-
this.
|
|
7137
|
-
return
|
|
7331
|
+
this.assertSupportedServer(capabilities);
|
|
7332
|
+
return capabilities;
|
|
7138
7333
|
}
|
|
7139
7334
|
console.warn(
|
|
7140
7335
|
`[AdCP] Agent "${this.agent.id}" advertises get_adcp_capabilities but the call returned non-success and the response is not v3-shaped \u2014 treating as v3 (synthetic) since the agent has the v3-only discovery tool. This client routes to v3 adapters, but calls reading capability details (idempotency TTL, supported_versions, feature flags) will fail until the agent operator fixes the capabilities endpoint.`,
|
|
@@ -7145,7 +7340,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7145
7340
|
}
|
|
7146
7341
|
);
|
|
7147
7342
|
} catch (error) {
|
|
7148
|
-
if (error instanceof AuthenticationRequiredError || error instanceof ConfigurationError || error instanceof TaskTimeoutError || isAbortOrTimeoutError(error)) {
|
|
7343
|
+
if (error instanceof AuthenticationRequiredError || error instanceof VersionUnsupportedError || error instanceof ConfigurationError || error instanceof TaskTimeoutError || isAbortOrTimeoutError(error)) {
|
|
7149
7344
|
throw error;
|
|
7150
7345
|
}
|
|
7151
7346
|
if (advertisesCapabilitiesTool) {
|
|
@@ -7155,26 +7350,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7155
7350
|
}
|
|
7156
7351
|
}
|
|
7157
7352
|
if (advertisesCapabilitiesTool) {
|
|
7158
|
-
const
|
|
7353
|
+
const capabilities = augmentCapabilitiesFromTools(buildSyntheticV3Capabilities(tools), tools);
|
|
7159
7354
|
if (!usesScopedFetch && !superseded()) {
|
|
7160
|
-
this.cachedCapabilities =
|
|
7355
|
+
this.cachedCapabilities = capabilities;
|
|
7161
7356
|
this.capabilitiesFromSharedCache = false;
|
|
7162
7357
|
this.recordSharedEvidence(this.sharedDiscoveryKey(options));
|
|
7163
7358
|
}
|
|
7164
|
-
this.
|
|
7165
|
-
return
|
|
7359
|
+
this.assertSupportedServer(capabilities);
|
|
7360
|
+
return capabilities;
|
|
7166
7361
|
}
|
|
7167
7362
|
}
|
|
7168
|
-
|
|
7169
|
-
`[AdCP] Agent "${this.agent.id}" detected as v2 (no get_adcp_capabilities tool). Tools: [${tools.map((t) => t.name).join(", ")}]`
|
|
7170
|
-
);
|
|
7171
|
-
const capabilities = buildSyntheticCapabilities(tools);
|
|
7172
|
-
if (!usesScopedFetch && !superseded()) {
|
|
7173
|
-
this.cachedCapabilities = capabilities;
|
|
7174
|
-
this.capabilitiesFromSharedCache = false;
|
|
7175
|
-
this.recordSharedEvidence(this.sharedDiscoveryKey(options));
|
|
7176
|
-
}
|
|
7177
|
-
return capabilities;
|
|
7363
|
+
throw new VersionUnsupportedError("get_adcp_capabilities", "synthetic", "v2", this.agent.agent_uri);
|
|
7178
7364
|
}
|
|
7179
7365
|
/**
|
|
7180
7366
|
* Return the client-bound scope required by {@link primeCapabilities}.
|
|
@@ -7689,28 +7875,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7689
7875
|
if (!this.config.discoveryCache || !code || !CAPABILITY_STALE_ERROR_CODES.has(code)) return;
|
|
7690
7876
|
await this.invalidateDiscoveryCache(options);
|
|
7691
7877
|
}
|
|
7692
|
-
/**
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
* against an unsupported agent should hear about it loudly.
|
|
7698
|
-
*
|
|
7699
|
-
* Synthetic capabilities (no `get_adcp_capabilities` tool available) don't
|
|
7700
|
-
* trigger the warning — we don't actually know the agent's version, and
|
|
7701
|
-
* shouting at legitimately-unversioned agents would be noise.
|
|
7702
|
-
*
|
|
7703
|
-
* Suppression: `process.env.ADCP_ALLOW_V2 === '1'`.
|
|
7704
|
-
*/
|
|
7705
|
-
maybeWarnV2Sunset(capabilities) {
|
|
7706
|
-
if (this._v2WarningFired) return;
|
|
7707
|
-
if (capabilities.version === "v3") return;
|
|
7708
|
-
if (capabilities._synthetic) return;
|
|
7709
|
-
if (process.env.ADCP_ALLOW_V2 === "1") return;
|
|
7710
|
-
this._v2WarningFired = true;
|
|
7711
|
-
console.warn(
|
|
7712
|
-
`[adcp] Warning: agent ${this.agent.agent_uri} reports v2 capabilities. v2 went unsupported on 2026-04-20 (AdCP 3.0 GA). Upgrade the agent to v3 or set ADCP_ALLOW_V2=1 to suppress this warning. See https://github.com/adcontextprotocol/adcp/issues/2220`
|
|
7713
|
-
);
|
|
7878
|
+
/** Reject retired protocol generations before caching or dispatching. */
|
|
7879
|
+
assertSupportedServer(capabilities) {
|
|
7880
|
+
if (capabilities.version !== "v3" || !capabilities.majorVersions.includes(3)) {
|
|
7881
|
+
throw new VersionUnsupportedError("get_adcp_capabilities", "version", capabilities.version, this.agent.agent_uri);
|
|
7882
|
+
}
|
|
7714
7883
|
}
|
|
7715
7884
|
/**
|
|
7716
7885
|
* Warn once per client when `requireSupportedMajor` accepts synthetic v3
|
|
@@ -7731,24 +7900,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7731
7900
|
`[adcp] Warning: agent ${this.agent.agent_uri} advertises get_adcp_capabilities (v3-only) but the call failed. Treating as v3 (synthetic) \u2014 version + idempotency-TTL checks skipped. Calls to getIdempotencyReplayTtlSeconds() will throw until the agent's capabilities endpoint is fixed. Report the wire-shape bug to the agent operator at ${this.agent.agent_uri}.`
|
|
7732
7901
|
);
|
|
7733
7902
|
}
|
|
7734
|
-
/**
|
|
7735
|
-
* Warn once per client when `requireSupportedMajor` routes a synthetic-v2
|
|
7736
|
-
* seller through the v2 adapter — the agent did not expose
|
|
7737
|
-
* `get_adcp_capabilities`, so the version was inferred from `tools/list`.
|
|
7738
|
-
* A compliant v3 seller would declare itself; absence of a declaration is
|
|
7739
|
-
* read as v2. Idempotency-TTL guarantees are unknown for these sellers,
|
|
7740
|
-
* so BYOK retry callers should treat them as such.
|
|
7741
|
-
*
|
|
7742
|
-
* One-shot via `_syntheticV2WarningFired` (matches `maybeWarnV2Sunset`
|
|
7743
|
-
* cadence).
|
|
7744
|
-
*/
|
|
7745
|
-
maybeWarnSyntheticV2() {
|
|
7746
|
-
if (this._syntheticV2WarningFired) return;
|
|
7747
|
-
this._syntheticV2WarningFired = true;
|
|
7748
|
-
console.warn(
|
|
7749
|
-
`[adcp] Warning: agent ${this.agent.agent_uri} does not expose get_adcp_capabilities. Routing as v2 (synthetic) \u2014 idempotency-TTL guarantee is unknown. Ask the agent operator to declare v3 via get_adcp_capabilities if v3 routing is intended. Branch on client.isSyntheticV2() to tighten retry policies for these sellers.`
|
|
7750
|
-
);
|
|
7751
|
-
}
|
|
7752
7903
|
/**
|
|
7753
7904
|
* Detect server AdCP version
|
|
7754
7905
|
*
|
|
@@ -7758,36 +7909,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7758
7909
|
const capabilities = await this.getCapabilities(options);
|
|
7759
7910
|
const discoveryContext = options?.[CAPABILITY_DISCOVERY_CONTEXT];
|
|
7760
7911
|
if (discoveryContext) discoveryContext.capabilities = capabilities;
|
|
7912
|
+
this.assertSupportedServer(capabilities);
|
|
7761
7913
|
return capabilities.version;
|
|
7762
7914
|
}
|
|
7763
|
-
/**
|
|
7764
|
-
* Whether the seller's capabilities are synthesized from `tools/list`
|
|
7765
|
-
* with no authoritative `get_adcp_capabilities` response — i.e. the
|
|
7766
|
-
* dispatcher routes through the v2 adapter and idempotency-TTL is
|
|
7767
|
-
* unknown. Use this to gate retry behavior for sellers whose retry
|
|
7768
|
-
* safety can't be derived from declared capabilities (lower attempt
|
|
7769
|
-
* caps, longer backoff, or fall back to natural-key recovery).
|
|
7770
|
-
*
|
|
7771
|
-
* Returns `false` for declared v2 sellers, declared v3 sellers, and
|
|
7772
|
-
* synthetic v3 sellers (which advertise the v3 discovery tool even
|
|
7773
|
-
* when the call itself failed).
|
|
7774
|
-
*
|
|
7775
|
-
* Caveat for synthetic v3: the predicate returns `false`, but TTL is
|
|
7776
|
-
* still unknown for those sellers — `getIdempotencyReplayTtlSeconds()`
|
|
7777
|
-
* throws until the agent's capabilities endpoint is fixed (issue
|
|
7778
|
-
* #1217). Retry-policy consumers that need a complete "TTL unknown"
|
|
7779
|
-
* gate should additionally check `getCapabilities()._synthetic`.
|
|
7780
|
-
*/
|
|
7781
|
-
async isSyntheticV2() {
|
|
7782
|
-
const capabilities = await this.getCapabilities();
|
|
7783
|
-
return capabilities._synthetic === true && capabilities.version === "v2";
|
|
7784
|
-
}
|
|
7785
7915
|
/**
|
|
7786
7916
|
* Check if server supports a specific AdCP major version
|
|
7787
7917
|
*/
|
|
7788
7918
|
async supportsVersion(version) {
|
|
7789
7919
|
const capabilities = await this.getCapabilities();
|
|
7790
|
-
return capabilities.majorVersions.includes(
|
|
7920
|
+
return version === 3 && capabilities.majorVersions.includes(3);
|
|
7791
7921
|
}
|
|
7792
7922
|
/**
|
|
7793
7923
|
* Return the seller's declared `adcp.idempotency.replay_ttl_seconds`.
|
|
@@ -7798,8 +7928,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7798
7928
|
*
|
|
7799
7929
|
* Fails closed when the seller is v3 but does not declare the field: the
|
|
7800
7930
|
* spec makes the declaration REQUIRED, and silently defaulting to 24h
|
|
7801
|
-
* would mislead buyers about retry safety.
|
|
7802
|
-
* `undefined` instead of a throw — v2 pre-dates the idempotency envelope.
|
|
7931
|
+
* would mislead buyers about retry safety.
|
|
7803
7932
|
*/
|
|
7804
7933
|
async getIdempotencyReplayTtlSeconds() {
|
|
7805
7934
|
const capabilities = await this.getCapabilities();
|
|
@@ -7808,7 +7937,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
7808
7937
|
assertValidIdempotencyReplayTtlSeconds(capabilities.idempotency.replayTtlSeconds);
|
|
7809
7938
|
return capabilities.idempotency.replayTtlSeconds;
|
|
7810
7939
|
}
|
|
7811
|
-
if (capabilities.version !== "v3") return void 0;
|
|
7812
7940
|
throw new ConfigurationError(
|
|
7813
7941
|
`Agent "${this.agent.id}" is v3 but does not declare adcp.idempotency.replay_ttl_seconds. The spec requires this for v3 sellers \u2014 treating the agent as non-compliant rather than defaulting to 24h, which would silently mislead retry-sensitive flows.`,
|
|
7814
7942
|
"adcp.idempotency.replay_ttl_seconds"
|
|
@@ -8119,28 +8247,16 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
8119
8247
|
* 2. `capabilities.idempotency.replayTtlSeconds` present (spec-required
|
|
8120
8248
|
* for real major-3+ sellers)
|
|
8121
8249
|
*
|
|
8122
|
-
*
|
|
8123
|
-
*
|
|
8124
|
-
* compliant v3 seller would declare itself, so absence of a declaration
|
|
8125
|
-
* is taken as evidence of v2. The dispatcher routes the request through
|
|
8126
|
-
* the v2 wire-shape adapter. A one-time warning surfaces the routing
|
|
8127
|
-
* decision so adopters can audit it; retry-safety (idempotency TTL) is
|
|
8128
|
-
* unknown for these sellers and BYOK callers should treat them as such.
|
|
8129
|
-
*
|
|
8130
|
-
* Per-client `allowV2: true` or, when that's undefined,
|
|
8131
|
-
* `ADCP_ALLOW_V2=1` in the environment bypasses the guard entirely.
|
|
8250
|
+
* Synthetic v3 evidence is accepted only when the agent advertises discovery.
|
|
8251
|
+
* Agents without discovery and AdCP 2-only agents are rejected.
|
|
8132
8252
|
*
|
|
8133
8253
|
* Throws `VersionUnsupportedError` with the specific reason on failure.
|
|
8134
8254
|
*/
|
|
8135
8255
|
async requireSupportedMajor(taskType = "request", options) {
|
|
8136
|
-
if (this.isV2Allowed()) return;
|
|
8137
8256
|
const capabilities = await this.getCapabilities(options);
|
|
8257
|
+
this.assertSupportedServer(capabilities);
|
|
8138
8258
|
if (capabilities._synthetic) {
|
|
8139
|
-
|
|
8140
|
-
this.maybeWarnSyntheticV3();
|
|
8141
|
-
} else {
|
|
8142
|
-
this.maybeWarnSyntheticV2();
|
|
8143
|
-
}
|
|
8259
|
+
this.maybeWarnSyntheticV3();
|
|
8144
8260
|
return;
|
|
8145
8261
|
}
|
|
8146
8262
|
const supportedVersions = capabilities.supportedVersions;
|
|
@@ -8171,10 +8287,6 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
8171
8287
|
async requireV3(taskType = "request") {
|
|
8172
8288
|
return this.requireSupportedMajor(taskType);
|
|
8173
8289
|
}
|
|
8174
|
-
isV2Allowed() {
|
|
8175
|
-
if (this.config.allowV2 !== void 0) return this.config.allowV2 === true;
|
|
8176
|
-
return process.env.ADCP_ALLOW_V2 === "1";
|
|
8177
|
-
}
|
|
8178
8290
|
// ====== STATIC HELPER METHODS ======
|
|
8179
8291
|
/**
|
|
8180
8292
|
* Query a legacy creative-agent named-format catalog.
|