@adcp/sdk 12.1.1 → 13.0.0-rc.0
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/README.md +19 -3
- package/bin/adcp-fuzz.js +3 -1
- package/dist/lib/adapters/content-standards-adapter.d.mts +9 -9
- package/dist/lib/adapters/content-standards-adapter.d.ts +9 -9
- package/dist/lib/adapters/content-standards-adapter.d.ts.map +1 -1
- package/dist/lib/adapters/content-standards-adapter.js +22 -22
- package/dist/lib/adapters/content-standards-adapter.js.map +1 -1
- package/dist/lib/adapters/content-standards-adapter.mjs +18 -18
- package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
- package/dist/lib/adapters/index.d.mts +2 -2
- package/dist/lib/adapters/index.d.ts +2 -2
- package/dist/lib/adapters/index.d.ts.map +1 -1
- package/dist/lib/adapters/index.js +10 -10
- package/dist/lib/adapters/index.js.map +1 -1
- package/dist/lib/adapters/index.mjs +9 -9
- package/dist/lib/adapters/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/provider-cache.d.mts +7 -0
- package/dist/lib/auth/oauth/provider-cache.d.ts +8 -0
- package/dist/lib/auth/oauth/provider-cache.d.ts.map +1 -0
- package/dist/lib/auth/oauth/provider-cache.js +44 -0
- package/dist/lib/auth/oauth/provider-cache.js.map +1 -0
- package/dist/lib/auth/oauth/provider-cache.mjs +19 -0
- package/dist/lib/auth/oauth/provider-cache.mjs.map +1 -0
- package/dist/lib/conformance/invariants/uniformError.js +1 -1
- package/dist/lib/conformance/invariants/uniformError.js.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
- package/dist/lib/conformance/runners.js +1 -1
- package/dist/lib/conformance/runners.js.map +1 -1
- package/dist/lib/conformance/runners.mjs +1 -1
- package/dist/lib/conformance/runners.mjs.map +1 -1
- package/dist/lib/conformance/seeder.js +5 -5
- package/dist/lib/conformance/seeder.js.map +1 -1
- package/dist/lib/conformance/seeder.mjs +5 -5
- package/dist/lib/conformance/seeder.mjs.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.d.mts +26 -29
- package/dist/lib/core/ADCPMultiAgentClient.d.ts +26 -29
- package/dist/lib/core/ADCPMultiAgentClient.d.ts.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.js +27 -19
- package/dist/lib/core/ADCPMultiAgentClient.js.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.mjs +27 -19
- package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
- package/dist/lib/core/AgentClient.d.mts +148 -138
- package/dist/lib/core/AgentClient.d.ts +148 -138
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/AgentClient.js +174 -85
- package/dist/lib/core/AgentClient.js.map +1 -1
- package/dist/lib/core/AgentClient.mjs +174 -85
- package/dist/lib/core/AgentClient.mjs.map +1 -1
- package/dist/lib/core/AsyncHandler.d.mts +18 -16
- package/dist/lib/core/AsyncHandler.d.ts +18 -16
- package/dist/lib/core/AsyncHandler.d.ts.map +1 -1
- package/dist/lib/core/AsyncHandler.js +22 -1
- package/dist/lib/core/AsyncHandler.js.map +1 -1
- package/dist/lib/core/AsyncHandler.mjs +22 -1
- package/dist/lib/core/AsyncHandler.mjs.map +1 -1
- package/dist/lib/core/ConversationTypes.d.mts +6 -2
- package/dist/lib/core/ConversationTypes.d.ts +6 -2
- package/dist/lib/core/ConversationTypes.d.ts.map +1 -1
- package/dist/lib/core/ConversationTypes.js.map +1 -1
- package/dist/lib/core/CreativeAgentClient.d.mts +41 -17
- package/dist/lib/core/CreativeAgentClient.d.ts +41 -17
- package/dist/lib/core/CreativeAgentClient.d.ts.map +1 -1
- package/dist/lib/core/CreativeAgentClient.js +39 -12
- package/dist/lib/core/CreativeAgentClient.js.map +1 -1
- package/dist/lib/core/CreativeAgentClient.mjs +39 -12
- package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +127 -50
- package/dist/lib/core/SingleAgentClient.d.ts +127 -50
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +1617 -177
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +1627 -177
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/core/TaskExecutor.d.mts +9 -0
- package/dist/lib/core/TaskExecutor.d.ts +9 -0
- package/dist/lib/core/TaskExecutor.d.ts.map +1 -1
- package/dist/lib/core/TaskExecutor.js +136 -43
- package/dist/lib/core/TaskExecutor.js.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +136 -43
- package/dist/lib/core/TaskExecutor.mjs.map +1 -1
- package/dist/lib/index.d.mts +111 -17
- package/dist/lib/index.d.ts +111 -17
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +94 -94
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +93 -94
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/protocols/index.d.ts.map +1 -1
- package/dist/lib/protocols/index.js +6 -15
- package/dist/lib/protocols/index.js.map +1 -1
- package/dist/lib/protocols/index.mjs +6 -16
- package/dist/lib/protocols/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-modern.js +87 -12
- package/dist/lib/protocols/mcp-modern.js.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +89 -12
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +6 -0
- package/dist/lib/server/create-adcp-server.d.ts +6 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +295 -48
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +301 -50
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.d.mts +27 -13
- package/dist/lib/server/decisioning/assembly-helpers.d.ts +27 -13
- package/dist/lib/server/decisioning/assembly-helpers.d.ts.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.js +136 -14
- package/dist/lib/server/decisioning/assembly-helpers.js.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.mjs +134 -13
- package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.d.mts +13 -12
- package/dist/lib/server/decisioning/index.d.ts +13 -12
- package/dist/lib/server/decisioning/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.js +6 -0
- package/dist/lib/server/decisioning/index.js.map +1 -1
- package/dist/lib/server/decisioning/index.mjs +9 -3
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.d.mts +13 -3
- package/dist/lib/server/decisioning/list-helpers.d.ts +13 -3
- package/dist/lib/server/decisioning/list-helpers.d.ts.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.js +13 -3
- package/dist/lib/server/decisioning/list-helpers.js.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.mjs +11 -2
- package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.d.mts +5 -3
- package/dist/lib/server/decisioning/manifest-helpers.d.ts +5 -3
- package/dist/lib/server/decisioning/manifest-helpers.d.ts.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.js.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/dispatch.d.mts +2 -2
- package/dist/lib/server/decisioning/proposal/dispatch.d.ts +2 -2
- package/dist/lib/server/decisioning/proposal/dispatch.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/dispatch.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.d.mts +1 -1
- package/dist/lib/server/decisioning/proposal/index.d.ts +1 -1
- package/dist/lib/server/decisioning/proposal/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.d.mts +3 -2
- package/dist/lib/server/decisioning/proposal/lifecycle.d.ts +3 -2
- package/dist/lib/server/decisioning/proposal/lifecycle.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.d.mts +3 -3
- package/dist/lib/server/decisioning/proposal/mock-manager.d.ts +3 -3
- package/dist/lib/server/decisioning/proposal/mock-manager.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.d.mts +10 -6
- package/dist/lib/server/decisioning/proposal/types.d.ts +10 -6
- package/dist/lib/server/decisioning/proposal/types.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +21 -2
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +21 -2
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +754 -81
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +763 -81
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/brand-rights.d.mts +9 -9
- package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts +9 -9
- package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/brand-rights.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/content-standards.d.mts +16 -16
- package/dist/lib/server/decisioning/specialisms/content-standards.d.ts +16 -16
- package/dist/lib/server/decisioning/specialisms/content-standards.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/content-standards.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.mts +15 -13
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts +15 -13
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative.d.mts +12 -11
- package/dist/lib/server/decisioning/specialisms/creative.d.ts +12 -11
- package/dist/lib/server/decisioning/specialisms/creative.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/sales.d.mts +25 -15
- package/dist/lib/server/decisioning/specialisms/sales.d.ts +25 -15
- package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -1
- package/dist/lib/server/index.d.mts +3 -3
- package/dist/lib/server/index.d.ts +3 -3
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +72 -72
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs +36 -36
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/legacy/v5/index.d.mts +1 -0
- package/dist/lib/server/legacy/v5/index.d.ts +1 -0
- package/dist/lib/server/legacy/v5/index.d.ts.map +1 -1
- package/dist/lib/server/legacy/v5/index.js +74 -1
- package/dist/lib/server/legacy/v5/index.js.map +1 -1
- package/dist/lib/server/legacy/v5/index.mjs +75 -1
- package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
- package/dist/lib/server/responses.d.mts +2 -2
- package/dist/lib/server/responses.d.ts +2 -2
- package/dist/lib/server/responses.js.map +1 -1
- package/dist/lib/server/responses.mjs.map +1 -1
- package/dist/lib/testing/client.js +1 -1
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/client.mjs +1 -1
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.js +6 -6
- package/dist/lib/testing/scenarios/brand-rights.js.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.mjs +6 -6
- package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
- package/dist/lib/testing/scenarios/creative.js +7 -7
- package/dist/lib/testing/scenarios/creative.js.map +1 -1
- package/dist/lib/testing/scenarios/creative.mjs +7 -7
- package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
- package/dist/lib/testing/scenarios/discovery.js +2 -2
- package/dist/lib/testing/scenarios/discovery.js.map +1 -1
- package/dist/lib/testing/scenarios/discovery.mjs +2 -2
- package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
- package/dist/lib/testing/scenarios/edge-cases.js +11 -11
- package/dist/lib/testing/scenarios/edge-cases.js.map +1 -1
- package/dist/lib/testing/scenarios/edge-cases.mjs +11 -11
- package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
- package/dist/lib/testing/scenarios/governance.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/governance.js +16 -22
- package/dist/lib/testing/scenarios/governance.js.map +1 -1
- package/dist/lib/testing/scenarios/governance.mjs +16 -22
- package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.js +5 -5
- package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.mjs +5 -5
- package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.js +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.js.map +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.mjs +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.js +4 -3
- package/dist/lib/testing/scenarios/trusted-match.js.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.mjs +4 -3
- package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.d.mts +3 -4
- package/dist/lib/testing/storyboard/shape-drift-hints.d.ts +3 -4
- package/dist/lib/testing/storyboard/shape-drift-hints.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.js +27 -27
- package/dist/lib/testing/storyboard/shape-drift-hints.js.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs +27 -27
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/task-map.js +43 -5
- package/dist/lib/testing/storyboard/task-map.js.map +1 -1
- package/dist/lib/testing/storyboard/task-map.mjs +43 -5
- package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
- package/dist/lib/testing/test-helpers.d.mts +2 -2
- package/dist/lib/testing/test-helpers.d.ts +2 -2
- package/dist/lib/testing/test-helpers.js.map +1 -1
- package/dist/lib/testing/test-helpers.mjs.map +1 -1
- package/dist/lib/types/adcp.d.mts +14 -14
- package/dist/lib/types/adcp.d.ts +14 -14
- package/dist/lib/types/adcp.d.ts.map +1 -1
- package/dist/lib/types/adcp.js.map +1 -1
- package/dist/lib/types/adcp.mjs.map +1 -1
- package/dist/lib/types/index.d.mts +2 -2
- package/dist/lib/types/index.d.ts +2 -2
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/types/index.js.map +1 -1
- package/dist/lib/types/index.mjs.map +1 -1
- package/dist/lib/utils/capabilities.d.mts +6 -0
- package/dist/lib/utils/capabilities.d.ts +6 -0
- package/dist/lib/utils/capabilities.d.ts.map +1 -1
- package/dist/lib/utils/capabilities.js +4 -0
- package/dist/lib/utils/capabilities.js.map +1 -1
- package/dist/lib/utils/capabilities.mjs +4 -0
- package/dist/lib/utils/capabilities.mjs.map +1 -1
- package/dist/lib/utils/creative-delivery.d.mts +52 -10
- package/dist/lib/utils/creative-delivery.d.ts +52 -10
- package/dist/lib/utils/creative-delivery.d.ts.map +1 -1
- package/dist/lib/utils/creative-delivery.js +104 -9
- package/dist/lib/utils/creative-delivery.js.map +1 -1
- package/dist/lib/utils/creative-delivery.mjs +104 -8
- package/dist/lib/utils/creative-delivery.mjs.map +1 -1
- package/dist/lib/utils/format-assets.d.mts +41 -38
- package/dist/lib/utils/format-assets.d.ts +41 -38
- package/dist/lib/utils/format-assets.d.ts.map +1 -1
- package/dist/lib/utils/format-assets.js +3 -1
- package/dist/lib/utils/format-assets.js.map +1 -1
- package/dist/lib/utils/format-assets.mjs +3 -1
- package/dist/lib/utils/format-assets.mjs.map +1 -1
- package/dist/lib/utils/index.d.mts +8 -8
- package/dist/lib/utils/index.d.ts +8 -8
- package/dist/lib/utils/index.d.ts.map +1 -1
- package/dist/lib/utils/index.js +11 -9
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/lib/utils/index.mjs +9 -8
- package/dist/lib/utils/index.mjs.map +1 -1
- package/dist/lib/utils/preview-utils.d.mts +11 -8
- package/dist/lib/utils/preview-utils.d.ts +11 -8
- package/dist/lib/utils/preview-utils.d.ts.map +1 -1
- package/dist/lib/utils/preview-utils.js +4 -4
- package/dist/lib/utils/preview-utils.js.map +1 -1
- package/dist/lib/utils/preview-utils.mjs +3 -3
- package/dist/lib/utils/preview-utils.mjs.map +1 -1
- package/dist/lib/utils/tool-request-schemas.d.mts +2 -2
- package/dist/lib/utils/tool-request-schemas.d.ts +2 -2
- package/dist/lib/v2/projection/aao-reference-formats.json +492 -0
- package/dist/lib/v2/projection/augment-response.d.mts +31 -11
- package/dist/lib/v2/projection/augment-response.d.ts +31 -11
- package/dist/lib/v2/projection/augment-response.d.ts.map +1 -1
- package/dist/lib/v2/projection/augment-response.js +233 -27
- package/dist/lib/v2/projection/augment-response.js.map +1 -1
- package/dist/lib/v2/projection/augment-response.mjs +232 -27
- package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
- package/dist/lib/v2/projection/builders.d.mts +7 -6
- package/dist/lib/v2/projection/builders.d.ts +7 -6
- package/dist/lib/v2/projection/builders.d.ts.map +1 -1
- package/dist/lib/v2/projection/builders.js +11 -8
- package/dist/lib/v2/projection/builders.js.map +1 -1
- package/dist/lib/v2/projection/builders.mjs +9 -6
- package/dist/lib/v2/projection/builders.mjs.map +1 -1
- package/dist/lib/v2/projection/catalog-snapshot.d.mts +47 -0
- package/dist/lib/v2/projection/catalog-snapshot.d.ts +48 -0
- package/dist/lib/v2/projection/catalog-snapshot.d.ts.map +1 -0
- package/dist/lib/v2/projection/catalog-snapshot.js +291 -0
- package/dist/lib/v2/projection/catalog-snapshot.js.map +1 -0
- package/dist/lib/v2/projection/catalog-snapshot.mjs +265 -0
- package/dist/lib/v2/projection/catalog-snapshot.mjs.map +1 -0
- package/dist/lib/v2/projection/catalog.d.mts +23 -2
- package/dist/lib/v2/projection/catalog.d.ts +23 -2
- package/dist/lib/v2/projection/catalog.d.ts.map +1 -1
- package/dist/lib/v2/projection/catalog.js +34 -10
- package/dist/lib/v2/projection/catalog.js.map +1 -1
- package/dist/lib/v2/projection/catalog.mjs +33 -10
- package/dist/lib/v2/projection/catalog.mjs.map +1 -1
- package/dist/lib/v2/projection/creative-delivery.d.mts +157 -0
- package/dist/lib/v2/projection/creative-delivery.d.ts +158 -0
- package/dist/lib/v2/projection/creative-delivery.d.ts.map +1 -0
- package/dist/lib/v2/projection/creative-delivery.js +967 -0
- package/dist/lib/v2/projection/creative-delivery.js.map +1 -0
- package/dist/lib/v2/projection/creative-delivery.mjs +941 -0
- package/dist/lib/v2/projection/creative-delivery.mjs.map +1 -0
- package/dist/lib/v2/projection/index.d.mts +8 -6
- package/dist/lib/v2/projection/index.d.ts +8 -6
- package/dist/lib/v2/projection/index.d.ts.map +1 -1
- package/dist/lib/v2/projection/index.js +26 -4
- package/dist/lib/v2/projection/index.js.map +1 -1
- package/dist/lib/v2/projection/index.mjs +28 -4
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/v2/projection/legacy-metadata.d.mts +21 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +22 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts.map +1 -0
- package/dist/lib/v2/projection/legacy-metadata.js +73 -0
- package/dist/lib/v2/projection/legacy-metadata.js.map +1 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs +45 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs.map +1 -0
- package/dist/lib/v2/projection/types.d.mts +29 -23
- package/dist/lib/v2/projection/types.d.ts +29 -23
- package/dist/lib/v2/projection/types.d.ts.map +1 -1
- package/dist/lib/v2/projection/types.js.map +1 -1
- package/dist/lib/v2/projection/v1-to-v2.d.mts +29 -6
- package/dist/lib/v2/projection/v1-to-v2.d.ts +29 -6
- package/dist/lib/v2/projection/v1-to-v2.d.ts.map +1 -1
- package/dist/lib/v2/projection/v1-to-v2.js +218 -9
- package/dist/lib/v2/projection/v1-to-v2.js.map +1 -1
- package/dist/lib/v2/projection/v1-to-v2.mjs +219 -10
- package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.d.mts +31 -2
- package/dist/lib/v2/projection/v2-to-v1.d.ts +31 -2
- package/dist/lib/v2/projection/v2-to-v1.d.ts.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.js +138 -7
- package/dist/lib/v2/projection/v2-to-v1.js.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.mjs +135 -6
- package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
- package/dist/lib/v2/projection/write-side.d.mts +12 -13
- package/dist/lib/v2/projection/write-side.d.ts +12 -13
- package/dist/lib/v2/projection/write-side.d.ts.map +1 -1
- package/dist/lib/v2/projection/write-side.js +16 -12
- package/dist/lib/v2/projection/write-side.js.map +1 -1
- package/dist/lib/v2/projection/write-side.mjs +16 -12
- package/dist/lib/v2/projection/write-side.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/guides/BUILD-AN-AGENT.md +7 -2
- package/docs/guides/PREVIEW-ASSET-DURABILITY.md +6 -2
- package/docs/llms.txt +1 -0
- package/examples/README.md +1 -1
- package/examples/batch-preview-test.ts +3 -3
- package/examples/conversation-client.ts +2 -2
- package/examples/debug-preview-response.ts +1 -1
- package/examples/decisioning-platform-broadcast-tv.ts +10 -4
- package/examples/decisioning-platform-mock-seller.ts +16 -9
- package/examples/decisioning-platform-programmatic.ts +18 -7
- package/examples/error-compliant-server.ts +26 -16
- package/examples/generative-creative-demo.ts +7 -19
- package/examples/hello_creative_adapter_ad_server.ts +37 -16
- package/examples/hello_creative_adapter_template.ts +12 -10
- package/examples/hello_seller_adapter_guaranteed.ts +52 -23
- package/examples/hello_seller_adapter_multi_tenant.ts +6 -3
- package/examples/hello_seller_adapter_non_guaranteed.ts +54 -26
- package/examples/hello_seller_adapter_proposal_mode.ts +40 -14
- package/examples/hello_seller_adapter_social.ts +2 -7
- package/examples/inspect-card-formats.ts +1 -1
- package/examples/simple-getting-started.ts +1 -1
- package/examples/test-helpers-demo.ts +1 -1
- package/package.json +2 -2
- package/skills/build-decisioning-creative-template/SKILL.md +11 -11
- package/skills/build-decisioning-platform/advanced/REFERENCE.md +8 -2
|
@@ -59,13 +59,385 @@ var crypto = __toESM(require("crypto"));
|
|
|
59
59
|
var import_abort2 = require('../protocols/abort.js');
|
|
60
60
|
var import_capabilities = require('../utils/capabilities.js');
|
|
61
61
|
var import_request_normalizer = require('../utils/request-normalizer.js');
|
|
62
|
+
var import_global_async_local_storage = require('../utils/global-async-local-storage.js');
|
|
62
63
|
var import_validate_user_agent = require('../utils/validate-user-agent.js');
|
|
63
64
|
var import_webhook_url = require('./webhook-url.js');
|
|
64
65
|
var import_v2_5 = require('../adapters/legacy/v2-5/index.js');
|
|
65
66
|
var import_property_policy = require('../media-buy/property-policy.js');
|
|
66
67
|
var import_targeting_helpers = require('../server/targeting-helpers.js');
|
|
68
|
+
var import_creative_delivery = require('../v2/projection/creative-delivery.js');
|
|
69
|
+
var import_catalog_snapshot = require('../v2/projection/catalog-snapshot.js');
|
|
70
|
+
var import_augment_response = require('../v2/projection/augment-response.js');
|
|
71
|
+
var import_legacy_metadata = require('../v2/projection/legacy-metadata.js');
|
|
72
|
+
var import_jcs = require('../utils/jcs.js');
|
|
67
73
|
const A2AClient = import_client.A2AClient;
|
|
68
74
|
const CAPABILITY_DISCOVERY_CONTEXT = /* @__PURE__ */ Symbol("capabilityDiscoveryContext");
|
|
75
|
+
function creativeSchemaSupport(value, depth = 0) {
|
|
76
|
+
if (depth > 24 || value === null || typeof value !== "object") return "unknown";
|
|
77
|
+
if (Array.isArray(value)) {
|
|
78
|
+
let legacy2 = false;
|
|
79
|
+
for (const item of value) {
|
|
80
|
+
const support = creativeSchemaSupport(item, depth + 1);
|
|
81
|
+
if (support === "canonical") return support;
|
|
82
|
+
if (support === "legacy") legacy2 = true;
|
|
83
|
+
}
|
|
84
|
+
return legacy2 ? "legacy" : "unknown";
|
|
85
|
+
}
|
|
86
|
+
const object = value;
|
|
87
|
+
const properties = object.properties;
|
|
88
|
+
if (properties !== null && typeof properties === "object" && !Array.isArray(properties)) {
|
|
89
|
+
const keys = properties;
|
|
90
|
+
if ("creative_id" in keys && "format_kind" in keys) return "canonical";
|
|
91
|
+
if ("creative_id" in keys && "format_id" in keys) return "legacy";
|
|
92
|
+
}
|
|
93
|
+
let legacy = false;
|
|
94
|
+
for (const child of Object.values(object)) {
|
|
95
|
+
const support = creativeSchemaSupport(child, depth + 1);
|
|
96
|
+
if (support === "canonical") return support;
|
|
97
|
+
if (support === "legacy") legacy = true;
|
|
98
|
+
}
|
|
99
|
+
return legacy ? "legacy" : "unknown";
|
|
100
|
+
}
|
|
101
|
+
function hasMediaBuyCreativeFormatData(request) {
|
|
102
|
+
if (request === null || typeof request !== "object" || Array.isArray(request)) return false;
|
|
103
|
+
const record = request;
|
|
104
|
+
return ["packages", "new_packages"].some((key) => {
|
|
105
|
+
const packages = record[key];
|
|
106
|
+
return Array.isArray(packages) && packages.some((pkg) => {
|
|
107
|
+
if (pkg === null || typeof pkg !== "object" || Array.isArray(pkg)) return false;
|
|
108
|
+
const packageRecord = pkg;
|
|
109
|
+
return Array.isArray(packageRecord.creatives) || Array.isArray(packageRecord.format_option_refs) || Array.isArray(packageRecord.format_ids) || typeof packageRecord.format_kind === "string" || Object.getOwnPropertySymbols(packageRecord).length > 0;
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const CANONICAL_CREATIVE_ACTIVITY_TASKS = /* @__PURE__ */ new Set([
|
|
114
|
+
"get_products",
|
|
115
|
+
"create_media_buy",
|
|
116
|
+
"update_media_buy",
|
|
117
|
+
"sync_creatives",
|
|
118
|
+
"list_creatives",
|
|
119
|
+
"get_media_buys",
|
|
120
|
+
"get_media_buy_delivery",
|
|
121
|
+
"get_creative_delivery"
|
|
122
|
+
]);
|
|
123
|
+
const TASK_SCOPED_STATE_LIMIT = 1e4;
|
|
124
|
+
const CANONICAL_PACKAGE_ROUTE_TASKS = /* @__PURE__ */ new Set(["create_media_buy", "update_media_buy", "get_media_buys"]);
|
|
125
|
+
const canonicalCreativeRoutingSnapshots = /* @__PURE__ */ new WeakSet();
|
|
126
|
+
function canonicalAccountRoutingSnapshot(value) {
|
|
127
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
128
|
+
const account = value;
|
|
129
|
+
if (typeof account.account_id === "string") return Object.freeze({ account_id: account.account_id });
|
|
130
|
+
if (!account.brand || typeof account.brand !== "object" || Array.isArray(account.brand) || typeof account.operator !== "string") {
|
|
131
|
+
return void 0;
|
|
132
|
+
}
|
|
133
|
+
const sourceBrand = account.brand;
|
|
134
|
+
if (typeof sourceBrand.domain !== "string") return void 0;
|
|
135
|
+
const brand = Object.freeze({
|
|
136
|
+
domain: sourceBrand.domain,
|
|
137
|
+
...typeof sourceBrand.brand_id === "string" ? { brand_id: sourceBrand.brand_id } : {}
|
|
138
|
+
});
|
|
139
|
+
return Object.freeze({
|
|
140
|
+
brand,
|
|
141
|
+
operator: account.operator,
|
|
142
|
+
...typeof account.sandbox === "boolean" ? { sandbox: account.sandbox } : {}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function canonicalOptionRefRoutingSnapshot(value) {
|
|
146
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
147
|
+
const ref = value;
|
|
148
|
+
if (typeof ref.format_option_id !== "string") return void 0;
|
|
149
|
+
if (ref.scope === "publisher" || typeof ref.publisher_domain === "string") {
|
|
150
|
+
if (typeof ref.publisher_domain !== "string") return void 0;
|
|
151
|
+
return Object.freeze({
|
|
152
|
+
scope: "publisher",
|
|
153
|
+
publisher_domain: ref.publisher_domain,
|
|
154
|
+
format_option_id: ref.format_option_id
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return Object.freeze({ scope: "product", format_option_id: ref.format_option_id });
|
|
158
|
+
}
|
|
159
|
+
function canonicalPackageRouteSelectorSnapshot(value) {
|
|
160
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
161
|
+
const selector = value;
|
|
162
|
+
const formatOptionRefs = Array.isArray(selector.format_option_refs) ? selector.format_option_refs.map(canonicalOptionRefRoutingSnapshot).filter((ref) => ref !== void 0) : [];
|
|
163
|
+
const snapshot = {
|
|
164
|
+
...typeof selector.package_id === "string" ? { package_id: selector.package_id } : {},
|
|
165
|
+
...typeof selector.product_id === "string" ? { product_id: selector.product_id } : {},
|
|
166
|
+
...formatOptionRefs.length > 0 ? { format_option_refs: Object.freeze(formatOptionRefs) } : {}
|
|
167
|
+
};
|
|
168
|
+
return Object.keys(snapshot).length > 0 ? Object.freeze(snapshot) : void 0;
|
|
169
|
+
}
|
|
170
|
+
function canonicalCreativeRoutingSnapshot(taskType, request) {
|
|
171
|
+
if (!CANONICAL_PACKAGE_ROUTE_TASKS.has(taskType) || !request || typeof request !== "object" || Array.isArray(request)) {
|
|
172
|
+
return void 0;
|
|
173
|
+
}
|
|
174
|
+
if (canonicalCreativeRoutingSnapshots.has(request)) {
|
|
175
|
+
return request;
|
|
176
|
+
}
|
|
177
|
+
const record = request;
|
|
178
|
+
const account = canonicalAccountRoutingSnapshot(record.account);
|
|
179
|
+
if (!account) return void 0;
|
|
180
|
+
const packageSnapshots = (key) => Object.freeze(
|
|
181
|
+
(Array.isArray(record[key]) ? record[key] : []).map(canonicalPackageRouteSelectorSnapshot).filter((selector) => selector !== void 0)
|
|
182
|
+
);
|
|
183
|
+
const packages = packageSnapshots("packages");
|
|
184
|
+
const newPackages = packageSnapshots("new_packages");
|
|
185
|
+
const snapshot = Object.freeze({
|
|
186
|
+
account,
|
|
187
|
+
...packages.length > 0 ? { packages } : {},
|
|
188
|
+
...newPackages.length > 0 ? { new_packages: newPackages } : {}
|
|
189
|
+
});
|
|
190
|
+
canonicalCreativeRoutingSnapshots.add(snapshot);
|
|
191
|
+
return snapshot;
|
|
192
|
+
}
|
|
193
|
+
const canonicalCreativeExecutionStorage = (0, import_global_async_local_storage.globalAsyncLocalStorage)("canonicalCreativeExecution");
|
|
194
|
+
function prepareCanonicalCreativePayload(value, taskType, active = /* @__PURE__ */ new WeakSet(), prepared = /* @__PURE__ */ new WeakMap()) {
|
|
195
|
+
if (value === null || typeof value !== "object") return value;
|
|
196
|
+
for (let owner = value; owner !== null; owner = Object.getPrototypeOf(owner)) {
|
|
197
|
+
const toJSON = Object.getOwnPropertyDescriptor(owner, "toJSON");
|
|
198
|
+
if (toJSON && (!("value" in toJSON) || typeof toJSON.value === "function")) {
|
|
199
|
+
throw new import_creative_delivery.CreativeFormatProjectionError(
|
|
200
|
+
taskType,
|
|
201
|
+
"(response:toJSON)",
|
|
202
|
+
"custom or accessor toJSON hooks cannot cross the canonical creative boundary safely"
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (active.has(value)) {
|
|
207
|
+
throw new import_creative_delivery.CreativeFormatProjectionError(
|
|
208
|
+
taskType,
|
|
209
|
+
"(response:cycle)",
|
|
210
|
+
"cyclic values cannot cross the canonical creative boundary"
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
const cached = prepared.get(value);
|
|
214
|
+
if (cached !== void 0) return cached;
|
|
215
|
+
active.add(value);
|
|
216
|
+
try {
|
|
217
|
+
const isArray = Array.isArray(value);
|
|
218
|
+
const prototype = Object.getPrototypeOf(value);
|
|
219
|
+
const plain = isArray ? prototype === Array.prototype : prototype === Object.prototype || prototype === null;
|
|
220
|
+
const output = isArray ? [] : Object.create(prototype === null ? null : Object.prototype);
|
|
221
|
+
prepared.set(value, output);
|
|
222
|
+
let changed = !plain;
|
|
223
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
224
|
+
if (isArray && key === "length") continue;
|
|
225
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
226
|
+
if (!descriptor) continue;
|
|
227
|
+
if (!("value" in descriptor)) {
|
|
228
|
+
throw new import_creative_delivery.CreativeFormatProjectionError(
|
|
229
|
+
taskType,
|
|
230
|
+
`(response:${String(key)})`,
|
|
231
|
+
"accessors cannot cross the canonical creative boundary safely"
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
if (!descriptor.enumerable) continue;
|
|
235
|
+
const safe = prepareCanonicalCreativePayload(descriptor.value, taskType, active, prepared);
|
|
236
|
+
if (safe !== descriptor.value) changed = true;
|
|
237
|
+
Object.defineProperty(output, key, { ...descriptor, value: safe });
|
|
238
|
+
}
|
|
239
|
+
if (!changed) {
|
|
240
|
+
prepared.set(value, value);
|
|
241
|
+
return value;
|
|
242
|
+
}
|
|
243
|
+
return output;
|
|
244
|
+
} finally {
|
|
245
|
+
active.delete(value);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function projectPreparedCanonicalCreativeResponseValue(value, taskType, legacyFormatConverter, selectorContainer = {}) {
|
|
249
|
+
if (Array.isArray(value)) {
|
|
250
|
+
return value.map(
|
|
251
|
+
(item) => projectPreparedCanonicalCreativeResponseValue(item, taskType, legacyFormatConverter, selectorContainer)
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
if (!value || typeof value !== "object") return value;
|
|
255
|
+
let projected = value;
|
|
256
|
+
const isProduct = typeof projected.product_id === "string" && ("name" in projected || "description" in projected) && (Array.isArray(projected.format_ids) || Array.isArray(projected.format_options));
|
|
257
|
+
if (isProduct) {
|
|
258
|
+
const canonical = (0, import_augment_response.toCanonicalOnlyResponse)(
|
|
259
|
+
{ products: [projected] },
|
|
260
|
+
{ legacyFormatConverter }
|
|
261
|
+
);
|
|
262
|
+
if (canonical.diagnostics.length > 0 || canonical.response.products.length !== 1) {
|
|
263
|
+
throw new import_creative_delivery.CreativeFormatProjectionError(
|
|
264
|
+
taskType,
|
|
265
|
+
`(product:${String(projected.product_id)})`,
|
|
266
|
+
"legacy product formats in the response have no complete canonical representation"
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
projected = canonical.response.products[0];
|
|
270
|
+
} else if ((typeof projected.package_id === "string" || typeof projected.product_id === "string") && Array.isArray(projected.format_ids)) {
|
|
271
|
+
projected = (0, import_creative_delivery.projectMediaBuyCreativesForDelivery)(
|
|
272
|
+
{ packages: [projected] },
|
|
273
|
+
"canonical",
|
|
274
|
+
taskType === "update_media_buy" ? "update_media_buy" : "create_media_buy",
|
|
275
|
+
legacyFormatConverter
|
|
276
|
+
).packages[0];
|
|
277
|
+
}
|
|
278
|
+
if (typeof projected.creative_id === "string" && (projected.format_id !== void 0 || typeof projected.format_kind === "string")) {
|
|
279
|
+
projected = (0, import_creative_delivery.projectCreativeForDelivery)(
|
|
280
|
+
projected,
|
|
281
|
+
selectorContainer,
|
|
282
|
+
"canonical",
|
|
283
|
+
taskType,
|
|
284
|
+
legacyFormatConverter
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
const nextSelector = Array.isArray(projected.format_ids) || Array.isArray(projected.format_options) || Array.isArray(projected.format_option_refs) ? projected : selectorContainer;
|
|
288
|
+
let changed = projected !== value;
|
|
289
|
+
const next = { ...projected };
|
|
290
|
+
for (const [key, child] of Object.entries(projected)) {
|
|
291
|
+
const childProjected = projectPreparedCanonicalCreativeResponseValue(
|
|
292
|
+
child,
|
|
293
|
+
taskType,
|
|
294
|
+
legacyFormatConverter,
|
|
295
|
+
nextSelector
|
|
296
|
+
);
|
|
297
|
+
if (childProjected !== child) {
|
|
298
|
+
next[key] = childProjected;
|
|
299
|
+
changed = true;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return changed ? next : projected;
|
|
303
|
+
}
|
|
304
|
+
function projectCanonicalCreativeResponseValue(value, taskType, legacyFormatConverter, selectorContainer = {}) {
|
|
305
|
+
return projectPreparedCanonicalCreativeResponseValue(
|
|
306
|
+
prepareCanonicalCreativePayload(value, taskType),
|
|
307
|
+
taskType,
|
|
308
|
+
legacyFormatConverter,
|
|
309
|
+
selectorContainer
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
function projectCanonicalCreativeAncillaryValue(value, taskType, legacyFormatConverter) {
|
|
313
|
+
try {
|
|
314
|
+
return (0, import_creative_delivery.stripLegacyCreativeIdentity)(projectCanonicalCreativeResponseValue(value, taskType, legacyFormatConverter));
|
|
315
|
+
} catch (error) {
|
|
316
|
+
if (!(error instanceof import_creative_delivery.CreativeFormatProjectionError)) throw error;
|
|
317
|
+
return { omitted: true, reason: "canonical creative payload unavailable" };
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function canonicalCreativeActivity(activity) {
|
|
321
|
+
const active = canonicalCreativeExecutionStorage.getStore();
|
|
322
|
+
const effectiveTaskType = active?.taskType && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(active.taskType) ? active.taskType : activity.task_type;
|
|
323
|
+
if (!CANONICAL_CREATIVE_ACTIVITY_TASKS.has(effectiveTaskType) || activity.payload === void 0) {
|
|
324
|
+
return activity;
|
|
325
|
+
}
|
|
326
|
+
const converter = active?.taskType === effectiveTaskType ? active.legacyFormatConverter : void 0;
|
|
327
|
+
const source = activity.type === "protocol_request" && active?.taskType === effectiveTaskType && active.canonicalRequest !== void 0 ? { params: active.canonicalRequest } : activity.payload;
|
|
328
|
+
try {
|
|
329
|
+
return {
|
|
330
|
+
...activity,
|
|
331
|
+
payload: (0, import_creative_delivery.stripLegacyCreativeIdentity)(projectCanonicalCreativeResponseValue(source, effectiveTaskType, converter))
|
|
332
|
+
};
|
|
333
|
+
} catch (error) {
|
|
334
|
+
if (!(error instanceof import_creative_delivery.CreativeFormatProjectionError)) throw error;
|
|
335
|
+
return { ...activity, payload: { omitted: true, reason: "canonical creative payload unavailable" } };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function canonicalCreativeDiagnosticBody(body, taskType) {
|
|
339
|
+
if (body === void 0) return void 0;
|
|
340
|
+
try {
|
|
341
|
+
const active = canonicalCreativeExecutionStorage.getStore();
|
|
342
|
+
const converter = active?.taskType === taskType ? active.legacyFormatConverter : void 0;
|
|
343
|
+
return JSON.stringify(
|
|
344
|
+
(0, import_creative_delivery.stripLegacyCreativeIdentity)(projectCanonicalCreativeResponseValue(JSON.parse(body), taskType, converter))
|
|
345
|
+
);
|
|
346
|
+
} catch {
|
|
347
|
+
return "[canonical creative payload omitted]";
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function canonicalCreativeTransportActivity(event) {
|
|
351
|
+
const active = canonicalCreativeExecutionStorage.getStore();
|
|
352
|
+
const taskType = active?.taskType && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(active.taskType) ? active.taskType : event.taskType ?? event.tool;
|
|
353
|
+
if (!taskType || !CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) return event;
|
|
354
|
+
return {
|
|
355
|
+
...event,
|
|
356
|
+
...event.requestBody !== void 0 && {
|
|
357
|
+
requestBody: canonicalCreativeDiagnosticBody(event.requestBody, taskType)
|
|
358
|
+
},
|
|
359
|
+
...event.responseBody !== void 0 && {
|
|
360
|
+
responseBody: canonicalCreativeDiagnosticBody(event.responseBody, taskType)
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function canonicalCreativeErrorInstance(error, legacySource) {
|
|
365
|
+
const own = {};
|
|
366
|
+
const descriptors = Object.getOwnPropertyDescriptors(error);
|
|
367
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
368
|
+
if ("value" in descriptor) own[key] = descriptor.value;
|
|
369
|
+
}
|
|
370
|
+
const { legacySource: _dropLegacySource, own: safeOwn } = (0, import_creative_delivery.stripLegacyCreativeIdentity)({ own, legacySource });
|
|
371
|
+
void _dropLegacySource;
|
|
372
|
+
const clone = Object.create(Object.getPrototypeOf(error));
|
|
373
|
+
for (const [key, value] of Object.entries(safeOwn)) {
|
|
374
|
+
const descriptor = descriptors[key];
|
|
375
|
+
if (!descriptor || !("value" in descriptor)) continue;
|
|
376
|
+
Object.defineProperty(clone, key, { ...descriptor, value });
|
|
377
|
+
}
|
|
378
|
+
for (const symbol of Object.getOwnPropertySymbols(error)) {
|
|
379
|
+
const descriptor = Object.getOwnPropertyDescriptor(error, symbol);
|
|
380
|
+
if (!descriptor || !("value" in descriptor)) continue;
|
|
381
|
+
const safe = (0, import_creative_delivery.stripLegacyCreativeIdentity)({ value: descriptor.value, legacySource });
|
|
382
|
+
Object.defineProperty(clone, symbol, { ...descriptor, value: safe.value });
|
|
383
|
+
}
|
|
384
|
+
return (0, import_creative_delivery.stripLegacyCreativeIdentity)(clone);
|
|
385
|
+
}
|
|
386
|
+
const PRIMARY_ADCP_TASK_NAMES = {
|
|
387
|
+
get_products: true,
|
|
388
|
+
create_media_buy: true,
|
|
389
|
+
update_media_buy: true,
|
|
390
|
+
sync_creatives: true,
|
|
391
|
+
list_creatives: true,
|
|
392
|
+
get_media_buys: true,
|
|
393
|
+
get_media_buy_delivery: true,
|
|
394
|
+
get_creative_delivery: true,
|
|
395
|
+
provide_performance_feedback: true,
|
|
396
|
+
get_signals: true,
|
|
397
|
+
activate_signal: true,
|
|
398
|
+
get_adcp_capabilities: true,
|
|
399
|
+
list_accounts: true,
|
|
400
|
+
sync_accounts: true,
|
|
401
|
+
sync_audiences: true,
|
|
402
|
+
create_property_list: true,
|
|
403
|
+
get_property_list: true,
|
|
404
|
+
update_property_list: true,
|
|
405
|
+
list_property_lists: true,
|
|
406
|
+
delete_property_list: true,
|
|
407
|
+
si_get_offering: true,
|
|
408
|
+
si_initiate_session: true,
|
|
409
|
+
si_send_message: true,
|
|
410
|
+
si_terminate_session: true,
|
|
411
|
+
get_brand_identity: true,
|
|
412
|
+
sync_plans: true,
|
|
413
|
+
check_governance: true,
|
|
414
|
+
report_plan_outcome: true,
|
|
415
|
+
get_plan_audit_logs: true,
|
|
416
|
+
context_match: true,
|
|
417
|
+
identity_match: true
|
|
418
|
+
};
|
|
419
|
+
const STANDARD_ADCP_TASK_NAMES = /* @__PURE__ */ new Set([
|
|
420
|
+
...Object.keys(PRIMARY_ADCP_TASK_NAMES),
|
|
421
|
+
"list_creative_formats",
|
|
422
|
+
"list_transformers",
|
|
423
|
+
"preview_creative",
|
|
424
|
+
"build_creative",
|
|
425
|
+
// These standard protocol tools still carry legacy creative `format_id`
|
|
426
|
+
// identity through artifacts, manifests, standards, or rights constraints.
|
|
427
|
+
// They are available only through explicitly named *Legacy APIs until a
|
|
428
|
+
// lossless canonical projection exists.
|
|
429
|
+
"list_content_standards",
|
|
430
|
+
"get_content_standards",
|
|
431
|
+
"create_content_standards",
|
|
432
|
+
"update_content_standards",
|
|
433
|
+
"calibrate_content",
|
|
434
|
+
"validate_content_delivery",
|
|
435
|
+
"get_media_buy_artifacts",
|
|
436
|
+
"get_creative_features",
|
|
437
|
+
"get_rights",
|
|
438
|
+
"acquire_rights",
|
|
439
|
+
"update_rights"
|
|
440
|
+
]);
|
|
69
441
|
class UnsupportedFeatureError extends Error {
|
|
70
442
|
constructor(feature, serverVersion, message) {
|
|
71
443
|
super(message || `Feature '${feature}' requires AdCP v3 but server is ${serverVersion}`);
|
|
@@ -136,6 +508,14 @@ function propertyListReferenceFromRequest(params) {
|
|
|
136
508
|
...typeof ref.auth_token === "string" ? { auth_token: ref.auth_token } : {}
|
|
137
509
|
};
|
|
138
510
|
}
|
|
511
|
+
function productPolicyRequestSnapshot(requestParams) {
|
|
512
|
+
const account = canonicalAccountRoutingSnapshot(requestParams.account);
|
|
513
|
+
const propertyList = propertyListReferenceFromRequest(requestParams);
|
|
514
|
+
return Object.freeze({
|
|
515
|
+
...account ? { account } : {},
|
|
516
|
+
...propertyList ? { property_list: Object.freeze(propertyList) } : {}
|
|
517
|
+
});
|
|
518
|
+
}
|
|
139
519
|
function hasProductPropertyPolicyRules(policy) {
|
|
140
520
|
return Boolean(
|
|
141
521
|
policy.allowedDomains?.length || policy.allowedPropertyIdentifiers?.length || policy.requireAllowedPropertyMatch || policy.excludedDomains?.length || policy.excludedPropertyIds?.length || policy.strict || policy.unknownSelectorBehavior || policy.missingPublisherPropertiesBehavior
|
|
@@ -196,8 +576,8 @@ class SingleAgentClient {
|
|
|
196
576
|
...config.validation?.requests != null && { requests: config.validation.requests },
|
|
197
577
|
...config.validation?.responses != null && { responses: config.validation.responses }
|
|
198
578
|
},
|
|
199
|
-
onActivity: config.onActivity,
|
|
200
|
-
onTransportActivity: config.onTransportActivity,
|
|
579
|
+
onActivity: config.onActivity ? (activity) => config.onActivity(canonicalCreativeActivity(activity)) : void 0,
|
|
580
|
+
onTransportActivity: config.onTransportActivity ? (event) => config.onTransportActivity(canonicalCreativeTransportActivity(event)) : void 0,
|
|
201
581
|
governance: config.governance,
|
|
202
582
|
adcpVersion: this.resolvedAdcpVersion,
|
|
203
583
|
...config.wireAdcpVersion !== void 0 && { wireAdcpVersion: config.wireAdcpVersion },
|
|
@@ -232,7 +612,237 @@ class SingleAgentClient {
|
|
|
232
612
|
_syntheticV2WarningFired = false;
|
|
233
613
|
// Gate: emit the synthetic-v2 warning once per client instance
|
|
234
614
|
productPolicyRequestParamsByTask = /* @__PURE__ */ new Map();
|
|
615
|
+
canonicalCreativeTaskAssociations = /* @__PURE__ */ new Map();
|
|
616
|
+
canonicalLegacyRoutes = /* @__PURE__ */ new Map();
|
|
235
617
|
resolvedAdcpVersion;
|
|
618
|
+
resolveLegacyFormatConverter(override, projectionCatalogs = this.config.projectionCatalogs) {
|
|
619
|
+
return (0, import_catalog_snapshot.legacyFormatConverterFromCatalogSnapshots)(projectionCatalogs, override ?? this.config.legacyFormatConverter);
|
|
620
|
+
}
|
|
621
|
+
canonicalAccountScope(account) {
|
|
622
|
+
if (account === void 0) return "none";
|
|
623
|
+
return (0, import_jcs.canonicalize)(canonicalAccountRoutingSnapshot(account) ?? account);
|
|
624
|
+
}
|
|
625
|
+
canonicalLegacyRouteKey(account, productId, ref) {
|
|
626
|
+
return (0, import_jcs.canonicalize)([
|
|
627
|
+
this.canonicalAccountScope(account),
|
|
628
|
+
productId,
|
|
629
|
+
ref.scope,
|
|
630
|
+
ref.scope === "publisher" ? ref.publisher_domain.toLowerCase() : "",
|
|
631
|
+
ref.format_option_id
|
|
632
|
+
]);
|
|
633
|
+
}
|
|
634
|
+
canonicalLegacyPackageRouteKey(account, packageId) {
|
|
635
|
+
return (0, import_jcs.canonicalize)([this.canonicalAccountScope(account), "package", packageId]);
|
|
636
|
+
}
|
|
637
|
+
sameCanonicalOptionRef(left, right) {
|
|
638
|
+
return left.scope === right.scope && left.format_option_id === right.format_option_id && (left.scope !== "publisher" || right.scope === "publisher" && left.publisher_domain.toLowerCase() === right.publisher_domain.toLowerCase());
|
|
639
|
+
}
|
|
640
|
+
rememberCanonicalLegacyRoute(key, route) {
|
|
641
|
+
this.canonicalLegacyRoutes.delete(key);
|
|
642
|
+
this.canonicalLegacyRoutes.set(key, {
|
|
643
|
+
...route,
|
|
644
|
+
refs: Object.freeze(route.refs.map((ref) => Object.freeze({ ...ref })))
|
|
645
|
+
});
|
|
646
|
+
while (this.canonicalLegacyRoutes.size > TASK_SCOPED_STATE_LIMIT) {
|
|
647
|
+
const oldest = this.canonicalLegacyRoutes.keys().next().value;
|
|
648
|
+
if (oldest === void 0) break;
|
|
649
|
+
this.canonicalLegacyRoutes.delete(oldest);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
invalidateCanonicalProductRoutes(products, account) {
|
|
653
|
+
const accountScope = this.canonicalAccountScope(account);
|
|
654
|
+
const productIds = /* @__PURE__ */ new Set();
|
|
655
|
+
for (const value of products) {
|
|
656
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
657
|
+
const productId = value.product_id;
|
|
658
|
+
if (typeof productId === "string") productIds.add(productId);
|
|
659
|
+
}
|
|
660
|
+
if (productIds.size === 0) return;
|
|
661
|
+
for (const [key, route] of this.canonicalLegacyRoutes) {
|
|
662
|
+
if (route.kind === "product" && route.accountScope === accountScope && productIds.has(route.productId)) {
|
|
663
|
+
this.canonicalLegacyRoutes.delete(key);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
rememberCanonicalProductRoutes(products, account, authoritativeProducts = products) {
|
|
668
|
+
this.invalidateCanonicalProductRoutes(authoritativeProducts, account);
|
|
669
|
+
const accountScope = this.canonicalAccountScope(account);
|
|
670
|
+
for (const value of products) {
|
|
671
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
672
|
+
const product = value;
|
|
673
|
+
if (typeof product.product_id !== "string" || !Array.isArray(product.format_options)) continue;
|
|
674
|
+
for (const optionValue of product.format_options) {
|
|
675
|
+
if (!optionValue || typeof optionValue !== "object" || Array.isArray(optionValue)) continue;
|
|
676
|
+
const option = optionValue;
|
|
677
|
+
if (typeof option.format_option_id !== "string") continue;
|
|
678
|
+
const ref = typeof option.publisher_domain === "string" ? {
|
|
679
|
+
scope: "publisher",
|
|
680
|
+
publisher_domain: option.publisher_domain,
|
|
681
|
+
format_option_id: option.format_option_id
|
|
682
|
+
} : { scope: "product", format_option_id: option.format_option_id };
|
|
683
|
+
const refs = (0, import_legacy_metadata.legacyFormatRefsForDeclaration)(option);
|
|
684
|
+
if (refs.length === 0) continue;
|
|
685
|
+
this.rememberCanonicalLegacyRoute(this.canonicalLegacyRouteKey(account, product.product_id, ref), {
|
|
686
|
+
kind: "product",
|
|
687
|
+
accountScope,
|
|
688
|
+
productId: product.product_id,
|
|
689
|
+
optionRef: ref,
|
|
690
|
+
refs
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
routeForOption(account, productId, optionRef) {
|
|
696
|
+
const accountScope = this.canonicalAccountScope(account);
|
|
697
|
+
const exactKey = this.canonicalLegacyRouteKey(account, productId, optionRef);
|
|
698
|
+
const exact = this.canonicalLegacyRoutes.get(exactKey);
|
|
699
|
+
if (exact) {
|
|
700
|
+
this.canonicalLegacyRoutes.delete(exactKey);
|
|
701
|
+
this.canonicalLegacyRoutes.set(exactKey, exact);
|
|
702
|
+
return exact;
|
|
703
|
+
}
|
|
704
|
+
const candidates = [...this.canonicalLegacyRoutes.entries()].filter(
|
|
705
|
+
([, route]) => route.kind === "product" && route.productId === productId && this.sameCanonicalOptionRef(route.optionRef, optionRef)
|
|
706
|
+
);
|
|
707
|
+
if (candidates.length !== 1) return void 0;
|
|
708
|
+
const [key, candidate] = candidates[0];
|
|
709
|
+
if (accountScope === "none" || candidate.accountScope !== "none") return void 0;
|
|
710
|
+
this.canonicalLegacyRoutes.delete(key);
|
|
711
|
+
this.canonicalLegacyRoutes.set(key, candidate);
|
|
712
|
+
return candidate;
|
|
713
|
+
}
|
|
714
|
+
routeForPackage(account, packageId) {
|
|
715
|
+
const exactKey = this.canonicalLegacyPackageRouteKey(account, packageId);
|
|
716
|
+
const exact = this.canonicalLegacyRoutes.get(exactKey);
|
|
717
|
+
if (exact) {
|
|
718
|
+
this.canonicalLegacyRoutes.delete(exactKey);
|
|
719
|
+
this.canonicalLegacyRoutes.set(exactKey, exact);
|
|
720
|
+
return exact;
|
|
721
|
+
}
|
|
722
|
+
return void 0;
|
|
723
|
+
}
|
|
724
|
+
packageIdsFromSelector(selector) {
|
|
725
|
+
const ids = /* @__PURE__ */ new Set();
|
|
726
|
+
if (typeof selector.package_id === "string") ids.add(selector.package_id);
|
|
727
|
+
if (Array.isArray(selector.selector_containers)) {
|
|
728
|
+
for (const value of selector.selector_containers) {
|
|
729
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
730
|
+
for (const id of this.packageIdsFromSelector(value)) ids.add(id);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return [...ids];
|
|
734
|
+
}
|
|
735
|
+
cachedCanonicalLegacyRefs(context, account) {
|
|
736
|
+
const selector = context.source === "product" ? context.declaration : context.source === "creative" ? context.selector : context.selector;
|
|
737
|
+
const productId = context.source === "product" ? context.productId : typeof selector.product_id === "string" ? selector.product_id : void 0;
|
|
738
|
+
if (!productId) {
|
|
739
|
+
const packageIds = this.packageIdsFromSelector(selector);
|
|
740
|
+
if (packageIds.length === 0) return void 0;
|
|
741
|
+
const routes = packageIds.map((packageId) => this.routeForPackage(account, packageId));
|
|
742
|
+
if (routes.some((route) => route === void 0)) return void 0;
|
|
743
|
+
const normalized = routes.map(
|
|
744
|
+
(route) => (0, import_jcs.canonicalize)(
|
|
745
|
+
route.refs.map((ref) => ({ ...ref })).sort((left, right) => (0, import_jcs.canonicalize)(left).localeCompare((0, import_jcs.canonicalize)(right)))
|
|
746
|
+
)
|
|
747
|
+
);
|
|
748
|
+
if (!normalized.every((value) => value === normalized[0])) return void 0;
|
|
749
|
+
return routes[0].refs.map((value) => ({ ...value }));
|
|
750
|
+
}
|
|
751
|
+
const rawRefs = [];
|
|
752
|
+
if (context.source === "product") rawRefs.push(context.declaration);
|
|
753
|
+
if (context.source === "creative" && context.creative.format_option_ref !== void 0) {
|
|
754
|
+
rawRefs.push(context.creative.format_option_ref);
|
|
755
|
+
} else if (Array.isArray(selector.format_option_refs)) {
|
|
756
|
+
rawRefs.push(...selector.format_option_refs);
|
|
757
|
+
}
|
|
758
|
+
const optionRefs = [];
|
|
759
|
+
for (const value of rawRefs) {
|
|
760
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
761
|
+
const record = value;
|
|
762
|
+
if (typeof record.format_option_id !== "string") continue;
|
|
763
|
+
if (record.scope === "publisher" || typeof record.publisher_domain === "string") {
|
|
764
|
+
if (typeof record.publisher_domain !== "string") continue;
|
|
765
|
+
optionRefs.push({
|
|
766
|
+
scope: "publisher",
|
|
767
|
+
publisher_domain: record.publisher_domain,
|
|
768
|
+
format_option_id: record.format_option_id
|
|
769
|
+
});
|
|
770
|
+
} else {
|
|
771
|
+
optionRefs.push({ scope: "product", format_option_id: record.format_option_id });
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
if (optionRefs.length === 0) return void 0;
|
|
775
|
+
const resolved = [];
|
|
776
|
+
for (const ref of optionRefs) {
|
|
777
|
+
const route = this.routeForOption(account, productId, ref);
|
|
778
|
+
if (!route) return void 0;
|
|
779
|
+
resolved.push(...route.refs.map((value) => ({ ...value })));
|
|
780
|
+
}
|
|
781
|
+
return resolved;
|
|
782
|
+
}
|
|
783
|
+
rememberCanonicalPackageRoutes(response, request) {
|
|
784
|
+
if (!response || typeof response !== "object" || Array.isArray(response)) return;
|
|
785
|
+
const requestRecord = request && typeof request === "object" && !Array.isArray(request) ? request : void 0;
|
|
786
|
+
const account = requestRecord?.account;
|
|
787
|
+
if (account === void 0) return;
|
|
788
|
+
const accountScope = this.canonicalAccountScope(account);
|
|
789
|
+
const requestPackages = ["packages", "new_packages"].flatMap(
|
|
790
|
+
(key) => Array.isArray(requestRecord?.[key]) ? requestRecord[key].filter(
|
|
791
|
+
(value) => Boolean(value && typeof value === "object" && !Array.isArray(value))
|
|
792
|
+
) : []
|
|
793
|
+
);
|
|
794
|
+
const responsePackages = [];
|
|
795
|
+
const visit = (value, depth = 0) => {
|
|
796
|
+
if (depth > 8 || !value || typeof value !== "object") return;
|
|
797
|
+
if (Array.isArray(value)) {
|
|
798
|
+
for (const item of value) visit(item, depth + 1);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
const record = value;
|
|
802
|
+
if (typeof record.package_id === "string") responsePackages.push(record);
|
|
803
|
+
for (const key of ["packages", "affected_packages", "media_buys"]) {
|
|
804
|
+
if (record[key] !== void 0) visit(record[key], depth + 1);
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
visit(response);
|
|
808
|
+
for (const pkg of responsePackages) {
|
|
809
|
+
const packageId = pkg.package_id;
|
|
810
|
+
let selector = pkg;
|
|
811
|
+
let refs = this.cachedCanonicalLegacyRefs(
|
|
812
|
+
{ source: "selector", selector, operation: "package_route", field: packageId },
|
|
813
|
+
account
|
|
814
|
+
);
|
|
815
|
+
if (!refs) {
|
|
816
|
+
const byPackageId = requestPackages.filter((value) => value.package_id === packageId);
|
|
817
|
+
const productId = typeof pkg.product_id === "string" ? pkg.product_id : void 0;
|
|
818
|
+
const byProduct = productId ? requestPackages.filter((value) => value.product_id === productId) : [];
|
|
819
|
+
const matches = byPackageId.length === 1 ? byPackageId : byProduct.length === 1 ? byProduct : [];
|
|
820
|
+
selector = matches[0];
|
|
821
|
+
if (selector) {
|
|
822
|
+
refs = this.cachedCanonicalLegacyRefs(
|
|
823
|
+
{ source: "selector", selector, operation: "package_route", field: packageId },
|
|
824
|
+
account
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
if (!refs || refs.length === 0) continue;
|
|
829
|
+
this.rememberCanonicalLegacyRoute(this.canonicalLegacyPackageRouteKey(account, packageId), {
|
|
830
|
+
kind: "package",
|
|
831
|
+
accountScope,
|
|
832
|
+
packageId,
|
|
833
|
+
refs
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
rememberCanonicalPackageRoutesForTask(taskType, response, request) {
|
|
838
|
+
if (taskType === "create_media_buy" || taskType === "update_media_buy" || taskType === "get_media_buys") {
|
|
839
|
+
this.rememberCanonicalPackageRoutes(response, request);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
resolveCanonicalFormatLegacyResolver(override, account) {
|
|
843
|
+
const configured = this.config.canonicalFormatLegacyResolver;
|
|
844
|
+
return (context) => override?.(context) ?? this.cachedCanonicalLegacyRefs(context, account) ?? configured?.(context);
|
|
845
|
+
}
|
|
236
846
|
/**
|
|
237
847
|
* Returns the AdCP protocol version this client is configured to speak.
|
|
238
848
|
*
|
|
@@ -269,6 +879,10 @@ class SingleAgentClient {
|
|
|
269
879
|
...this.normalizedAgent,
|
|
270
880
|
agent_uri: this.discoveredEndpoint
|
|
271
881
|
};
|
|
882
|
+
if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
|
|
883
|
+
const { shareNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.js");
|
|
884
|
+
shareNonInteractiveOAuthProvider(this.normalizedAgent, this.discoveredAgent);
|
|
885
|
+
}
|
|
272
886
|
return this.discoveredAgent;
|
|
273
887
|
}
|
|
274
888
|
if (this.normalizedAgent.oauth_client_credentials) {
|
|
@@ -281,7 +895,12 @@ class SingleAgentClient {
|
|
|
281
895
|
}
|
|
282
896
|
const discoveredEndpoint = await this.discoverMCPEndpoint(this.normalizedAgent.agent_uri, options);
|
|
283
897
|
if (usesScopedFetch) {
|
|
284
|
-
|
|
898
|
+
const discoveredAgent = { ...this.normalizedAgent, agent_uri: discoveredEndpoint };
|
|
899
|
+
if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
|
|
900
|
+
const { shareNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.js");
|
|
901
|
+
shareNonInteractiveOAuthProvider(this.normalizedAgent, discoveredAgent);
|
|
902
|
+
}
|
|
903
|
+
return discoveredAgent;
|
|
285
904
|
}
|
|
286
905
|
this.discoveredEndpoint = discoveredEndpoint;
|
|
287
906
|
this.canonicalBaseUrl = this.computeBaseUrl(this.discoveredEndpoint);
|
|
@@ -289,6 +908,10 @@ class SingleAgentClient {
|
|
|
289
908
|
...this.normalizedAgent,
|
|
290
909
|
agent_uri: this.discoveredEndpoint
|
|
291
910
|
};
|
|
911
|
+
if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
|
|
912
|
+
const { shareNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.js");
|
|
913
|
+
shareNonInteractiveOAuthProvider(this.normalizedAgent, this.discoveredAgent);
|
|
914
|
+
}
|
|
292
915
|
return this.discoveredAgent;
|
|
293
916
|
}
|
|
294
917
|
/**
|
|
@@ -444,8 +1067,10 @@ class SingleAgentClient {
|
|
|
444
1067
|
const authToken = this.normalizedAgent.oauth_client_credentials ? this.normalizedAgent.oauth_tokens?.access_token : this.agent.auth_token;
|
|
445
1068
|
const agentHeaders = this.agent.headers;
|
|
446
1069
|
const authHeaders = { ...agentHeaders, ...(0, import_auth.createMCPAuthHeaders)(authToken) };
|
|
447
|
-
const
|
|
1070
|
+
const oauth = this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials ? await import("../auth/oauth/index.js") : void 0;
|
|
1071
|
+
const authProvider = oauth ? (await import("../auth/oauth/provider-cache.js")).getNonInteractiveOAuthProvider(this.normalizedAgent, {
|
|
448
1072
|
agentHint: this.normalizedAgent.id,
|
|
1073
|
+
storage: oauth.getAgentStorage(this.normalizedAgent),
|
|
449
1074
|
allowHttp: (0, import_net.isLikelyPrivateUrl)(this.normalizedAgent.agent_uri)
|
|
450
1075
|
}) : void 0;
|
|
451
1076
|
const testEndpoint = async (url) => {
|
|
@@ -643,8 +1268,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
643
1268
|
* This is the lower-level receiver primitive for integrations that need to
|
|
644
1269
|
* map malformed webhooks to precise HTTP responses. It verifies the legacy
|
|
645
1270
|
* HMAC profile when `webhookSecret` is configured, parses raw JSON bodies,
|
|
646
|
-
* validates the transport envelope shape, and returns the
|
|
647
|
-
* result plus routing metadata.
|
|
1271
|
+
* validates the transport envelope shape, and returns the canonicalized
|
|
1272
|
+
* AdCP result plus routing metadata. Legacy wire inspection is intentionally
|
|
1273
|
+
* confined to the transport adapter and is not returned by this primary API.
|
|
648
1274
|
*/
|
|
649
1275
|
async verifyAndParseWebhook(options) {
|
|
650
1276
|
const rawBody = options.rawBody ?? rawBodyFromUnknown(options.body);
|
|
@@ -676,37 +1302,107 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
676
1302
|
if (!parsedPayload.ok) {
|
|
677
1303
|
return parsedPayload;
|
|
678
1304
|
}
|
|
1305
|
+
const parsedTaskType = isObjectRecord(parsedPayload.payload) && typeof parsedPayload.payload.task_type === "string" ? parsedPayload.payload.task_type : void 0;
|
|
1306
|
+
const payloadRecord = isObjectRecord(parsedPayload.payload) ? parsedPayload.payload : void 0;
|
|
1307
|
+
const associatedTaskTypes = new Set(
|
|
1308
|
+
[
|
|
1309
|
+
options.operationId,
|
|
1310
|
+
typeof payloadRecord?.operation_id === "string" ? payloadRecord.operation_id : void 0,
|
|
1311
|
+
typeof payloadRecord?.task_id === "string" ? payloadRecord.task_id : void 0,
|
|
1312
|
+
typeof payloadRecord?.context_id === "string" ? payloadRecord.context_id : void 0
|
|
1313
|
+
].flatMap((id) => {
|
|
1314
|
+
const taskType = this.canonicalCreativeTaskAssociation(id)?.taskType;
|
|
1315
|
+
return taskType ? [taskType] : [];
|
|
1316
|
+
})
|
|
1317
|
+
);
|
|
1318
|
+
const associatedTaskType = associatedTaskTypes.size === 1 ? [...associatedTaskTypes][0] : void 0;
|
|
1319
|
+
const routedTaskType = options.taskType === "unknown" ? void 0 : options.taskType;
|
|
1320
|
+
const declaredTaskType = routedTaskType ?? parsedTaskType;
|
|
1321
|
+
if (associatedTaskTypes.size > 1 || associatedTaskType !== void 0 && declaredTaskType !== void 0 && associatedTaskType !== declaredTaskType) {
|
|
1322
|
+
return {
|
|
1323
|
+
ok: false,
|
|
1324
|
+
code: "webhook_envelope_invalid",
|
|
1325
|
+
message: "Webhook task_type does not match the locally tracked task association."
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
let normalizedTaskType = associatedTaskType ?? declaredTaskType;
|
|
679
1329
|
try {
|
|
680
1330
|
const normalizedPayload = this.normalizeWebhookPayload(
|
|
681
1331
|
parsedPayload.payload,
|
|
682
|
-
|
|
1332
|
+
normalizedTaskType ?? "unknown",
|
|
683
1333
|
options.operationId ?? "unknown"
|
|
684
1334
|
);
|
|
1335
|
+
normalizedTaskType = normalizedPayload.task_type;
|
|
1336
|
+
if (associatedTaskType !== void 0 && normalizedPayload.task_type !== associatedTaskType) {
|
|
1337
|
+
return {
|
|
1338
|
+
ok: false,
|
|
1339
|
+
code: "webhook_envelope_invalid",
|
|
1340
|
+
message: "Webhook task_type does not match the locally tracked task association."
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
const metadata = {
|
|
1344
|
+
operation_id: normalizedPayload.operation_id,
|
|
1345
|
+
context_id: normalizedPayload.context_id,
|
|
1346
|
+
task_id: normalizedPayload.task_id,
|
|
1347
|
+
agent_id: this.agent.id,
|
|
1348
|
+
task_type: normalizedPayload.task_type,
|
|
1349
|
+
status: normalizedPayload.status,
|
|
1350
|
+
message: normalizedPayload.message,
|
|
1351
|
+
timestamp: normalizedPayload.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
1352
|
+
idempotency_key: normalizedPayload.idempotency_key,
|
|
1353
|
+
protocol: normalizedPayload.protocol ?? "mcp"
|
|
1354
|
+
};
|
|
1355
|
+
const canonicalResult = this.canonicalizeWebhookCreativeResult(metadata, normalizedPayload.result);
|
|
1356
|
+
const canonicalCreativeTask = CANONICAL_CREATIVE_ACTIVITY_TASKS.has(normalizedPayload.task_type);
|
|
1357
|
+
const legacyFormatConverter = this.legacyFormatConverterForWebhook(metadata);
|
|
1358
|
+
const canonicalEnvelope = canonicalCreativeTask ? (0, import_creative_delivery.stripLegacyCreativeIdentity)(
|
|
1359
|
+
projectCanonicalCreativeResponseValue(
|
|
1360
|
+
parsedPayload.payload,
|
|
1361
|
+
normalizedPayload.task_type,
|
|
1362
|
+
legacyFormatConverter
|
|
1363
|
+
)
|
|
1364
|
+
) : parsedPayload.payload;
|
|
1365
|
+
const canonicalMessage = canonicalCreativeTask ? (0, import_creative_delivery.stripLegacyCreativeIdentity)({
|
|
1366
|
+
message: normalizedPayload.message,
|
|
1367
|
+
legacySource: parsedPayload.payload
|
|
1368
|
+
}).message : normalizedPayload.message;
|
|
685
1369
|
return {
|
|
686
1370
|
ok: true,
|
|
687
1371
|
protocol: normalizedPayload.protocol ?? "mcp",
|
|
688
|
-
envelope:
|
|
689
|
-
result:
|
|
1372
|
+
envelope: canonicalEnvelope,
|
|
1373
|
+
result: canonicalResult,
|
|
690
1374
|
metadata: {
|
|
691
1375
|
operationId: normalizedPayload.operation_id,
|
|
692
1376
|
contextId: normalizedPayload.context_id,
|
|
693
1377
|
taskId: normalizedPayload.task_id,
|
|
694
1378
|
taskType: normalizedPayload.task_type,
|
|
695
1379
|
status: normalizedPayload.status,
|
|
696
|
-
message:
|
|
1380
|
+
message: canonicalMessage,
|
|
697
1381
|
timestamp: normalizedPayload.timestamp,
|
|
698
1382
|
idempotencyKey: normalizedPayload.idempotency_key
|
|
699
1383
|
}
|
|
700
1384
|
};
|
|
701
1385
|
} catch (error) {
|
|
1386
|
+
const canonicalCreativeTask = normalizedTaskType !== void 0 && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(normalizedTaskType);
|
|
702
1387
|
if (error instanceof WebhookDispatchError) {
|
|
703
|
-
|
|
1388
|
+
if (!canonicalCreativeTask) {
|
|
1389
|
+
return { ok: false, code: error.code, message: error.message };
|
|
1390
|
+
}
|
|
1391
|
+
const safe = (0, import_creative_delivery.stripLegacyCreativeIdentity)({
|
|
1392
|
+
message: error.message,
|
|
1393
|
+
legacySource: parsedPayload.payload
|
|
1394
|
+
});
|
|
1395
|
+
return { ok: false, code: error.code, message: safe.message };
|
|
1396
|
+
}
|
|
1397
|
+
const message = error instanceof Error ? error.message : "Webhook payload could not be normalized.";
|
|
1398
|
+
if (canonicalCreativeTask) {
|
|
1399
|
+
const safe = (0, import_creative_delivery.stripLegacyCreativeIdentity)({ message, legacySource: parsedPayload.payload });
|
|
1400
|
+
return { ok: false, code: "webhook_result_invalid", message: safe.message };
|
|
704
1401
|
}
|
|
705
1402
|
return {
|
|
706
1403
|
ok: false,
|
|
707
1404
|
code: "webhook_result_invalid",
|
|
708
|
-
message:
|
|
709
|
-
cause: error
|
|
1405
|
+
message: "Webhook payload could not be normalized."
|
|
710
1406
|
};
|
|
711
1407
|
}
|
|
712
1408
|
}
|
|
@@ -722,36 +1418,88 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
722
1418
|
timestamp: parsed.metadata.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
723
1419
|
idempotency_key: parsed.metadata.idempotencyKey,
|
|
724
1420
|
protocol: parsed.protocol,
|
|
725
|
-
rawHTTPPayload: parsed.envelope
|
|
1421
|
+
rawHTTPPayload: CANONICAL_CREATIVE_ACTIVITY_TASKS.has(parsed.metadata.taskType) ? (0, import_creative_delivery.stripLegacyCreativeIdentity)(parsed.envelope) : parsed.envelope
|
|
726
1422
|
};
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
metadata
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
1423
|
+
this.rememberCanonicalCreativeWebhookContext(metadata);
|
|
1424
|
+
try {
|
|
1425
|
+
const canonicalResult = this.canonicalizeWebhookCreativeResult(metadata, parsed.result);
|
|
1426
|
+
const policyDispatch = await this.applyProductPropertyPolicyToWebhookResult(
|
|
1427
|
+
canonicalResult,
|
|
1428
|
+
metadata
|
|
1429
|
+
);
|
|
1430
|
+
const webhookResult = policyDispatch.result;
|
|
1431
|
+
metadata = policyDispatch.metadata;
|
|
1432
|
+
await this.config.onActivity?.(
|
|
1433
|
+
canonicalCreativeActivity({
|
|
1434
|
+
type: "webhook_received",
|
|
1435
|
+
operation_id: metadata.operation_id,
|
|
1436
|
+
agent_id: metadata.agent_id,
|
|
1437
|
+
context_id: metadata.context_id,
|
|
1438
|
+
task_id: metadata.task_id,
|
|
1439
|
+
task_type: metadata.task_type,
|
|
1440
|
+
status: metadata.status,
|
|
1441
|
+
payload: canonicalResult,
|
|
1442
|
+
timestamp: metadata.timestamp
|
|
1443
|
+
})
|
|
1444
|
+
);
|
|
1445
|
+
if (policyDispatch.suppressHandler) return true;
|
|
1446
|
+
if (this.asyncHandler) {
|
|
1447
|
+
await this.asyncHandler.handleWebhook({ result: webhookResult, metadata });
|
|
1448
|
+
return true;
|
|
1449
|
+
}
|
|
1450
|
+
return false;
|
|
1451
|
+
} finally {
|
|
1452
|
+
this.executor.observeExternalTaskStatus(
|
|
1453
|
+
metadata.operation_id,
|
|
1454
|
+
metadata.status,
|
|
1455
|
+
metadata.rawHTTPPayload
|
|
1456
|
+
);
|
|
745
1457
|
this.forgetProductPolicyRequestParams(metadata);
|
|
746
|
-
return true;
|
|
747
1458
|
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1459
|
+
}
|
|
1460
|
+
rememberCanonicalCreativeWebhookContext(metadata) {
|
|
1461
|
+
if (!metadata.context_id || !CANONICAL_CREATIVE_ACTIVITY_TASKS.has(metadata.task_type)) return;
|
|
1462
|
+
const association = this.canonicalCreativeTaskAssociation(metadata.operation_id) ?? this.canonicalCreativeTaskAssociation(metadata.task_id) ?? this.canonicalCreativeTaskAssociation(metadata.context_id);
|
|
1463
|
+
if (!association) return;
|
|
1464
|
+
this.rememberCanonicalCreativeTaskAssociation(
|
|
1465
|
+
metadata.context_id,
|
|
1466
|
+
association.taskType,
|
|
1467
|
+
association.legacyFormatConverter,
|
|
1468
|
+
association.routingSnapshot
|
|
1469
|
+
);
|
|
1470
|
+
}
|
|
1471
|
+
canonicalizeWebhookCreativeResult(metadata, result) {
|
|
1472
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) return result;
|
|
1473
|
+
const taskType = metadata.task_type;
|
|
1474
|
+
const legacyFormatConverter = this.legacyFormatConverterForWebhook(metadata);
|
|
1475
|
+
const response = result;
|
|
1476
|
+
if (taskType === "get_products" && Array.isArray(response.products)) {
|
|
1477
|
+
const { response: canonical2, diagnostics } = (0, import_augment_response.toCanonicalOnlyResponse)(
|
|
1478
|
+
response,
|
|
1479
|
+
{ legacyFormatConverter }
|
|
1480
|
+
);
|
|
1481
|
+
const requestParams = this.productPolicyRequestParamsForWebhook(metadata);
|
|
1482
|
+
this.rememberCanonicalProductRoutes(canonical2.products, requestParams.account, response.products);
|
|
1483
|
+
const { _message: _dropLegacyMessage, ...safe } = canonical2;
|
|
1484
|
+
void _dropLegacyMessage;
|
|
1485
|
+
return (0, import_creative_delivery.stripLegacyCreativeIdentity)({ ...safe, projection: { diagnostics } });
|
|
1486
|
+
}
|
|
1487
|
+
if (taskType === "list_creatives" && Array.isArray(response.creatives)) {
|
|
1488
|
+
const { _message: _dropLegacyMessage, ...safe } = response;
|
|
1489
|
+
void _dropLegacyMessage;
|
|
1490
|
+
return (0, import_creative_delivery.stripLegacyCreativeIdentity)({
|
|
1491
|
+
...safe,
|
|
1492
|
+
creatives: response.creatives.map(
|
|
1493
|
+
(creative) => (0, import_creative_delivery.projectCreativeForDelivery)(creative, {}, "canonical", "list_creatives", legacyFormatConverter)
|
|
1494
|
+
)
|
|
1495
|
+
});
|
|
752
1496
|
}
|
|
753
|
-
|
|
754
|
-
|
|
1497
|
+
const canonical = CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType) ? (0, import_creative_delivery.stripLegacyCreativeIdentity)(projectCanonicalCreativeResponseValue(result, taskType, legacyFormatConverter)) : result;
|
|
1498
|
+
const association = this.canonicalCreativeTaskAssociation(metadata.operation_id) ?? this.canonicalCreativeTaskAssociation(metadata.task_id) ?? this.canonicalCreativeTaskAssociation(metadata.context_id);
|
|
1499
|
+
if (metadata.status === "completed") {
|
|
1500
|
+
this.rememberCanonicalPackageRoutesForTask(taskType, canonical, association?.routingSnapshot);
|
|
1501
|
+
}
|
|
1502
|
+
return canonical;
|
|
755
1503
|
}
|
|
756
1504
|
/**
|
|
757
1505
|
* Normalize webhook payload - handles both MCP and A2A webhook formats
|
|
@@ -790,7 +1538,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
790
1538
|
if (typeof payload.status !== "string" || !WEBHOOK_TASK_STATUSES.has(payload.status)) {
|
|
791
1539
|
throw new WebhookDispatchError(
|
|
792
1540
|
"webhook_envelope_invalid",
|
|
793
|
-
`Invalid MCP webhook envelope: unsupported top-level status
|
|
1541
|
+
`Invalid MCP webhook envelope: unsupported top-level status. Expected one of ${Array.from(WEBHOOK_TASK_STATUSES).join(", ")}.`
|
|
794
1542
|
);
|
|
795
1543
|
}
|
|
796
1544
|
if (typeof payload.timestamp !== "string" || Number.isNaN(Date.parse(payload.timestamp))) {
|
|
@@ -830,7 +1578,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
830
1578
|
} catch (error) {
|
|
831
1579
|
throw new WebhookDispatchError(
|
|
832
1580
|
"webhook_result_invalid",
|
|
833
|
-
|
|
1581
|
+
"Failed to unwrap A2A webhook payload artifacts.",
|
|
834
1582
|
error
|
|
835
1583
|
);
|
|
836
1584
|
}
|
|
@@ -862,7 +1610,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
862
1610
|
}
|
|
863
1611
|
throw new WebhookDispatchError(
|
|
864
1612
|
"webhook_unsupported_payload",
|
|
865
|
-
|
|
1613
|
+
"Unsupported webhook payload format. Expected an MCP webhook envelope with top-level idempotency_key, operation_id, task_id, task_type, status, timestamp, and result, or an A2A Task/TaskStatusUpdateEvent with AdCP data nested in status.message.parts[].data or task artifacts."
|
|
866
1614
|
);
|
|
867
1615
|
}
|
|
868
1616
|
/**
|
|
@@ -1003,7 +1751,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1003
1751
|
*
|
|
1004
1752
|
* Automatically adapts requests for v2 servers and normalizes responses.
|
|
1005
1753
|
*/
|
|
1006
|
-
async executeAndHandle(taskType, handlerName, params, inputHandler, options) {
|
|
1754
|
+
async executeAndHandle(taskType, handlerName, params, inputHandler, options, transformCompletedResponse, legacyFormatConverter, canonicalRequest) {
|
|
1007
1755
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
1008
1756
|
let normalizedParams = (0, import_request_normalizer.normalizeRequestParams)(taskType, params, {
|
|
1009
1757
|
skipIdempotencyAutoInject: options?.skipIdempotencyAutoInject,
|
|
@@ -1051,13 +1799,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1051
1799
|
if (serverVersion === "v2") {
|
|
1052
1800
|
this.executor.validateAdaptedRequestAgainstV2(taskType, adaptedParams, v25DriftLogs);
|
|
1053
1801
|
}
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
taskType,
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1802
|
+
const canonicalInputHandler = this.canonicalCreativeInputHandler(taskType, inputHandler);
|
|
1803
|
+
let result = await canonicalCreativeExecutionStorage.run(
|
|
1804
|
+
{ taskType, legacyFormatConverter, canonicalRequest: canonicalRequest ?? normalizedParams },
|
|
1805
|
+
() => this.executor.executeTask(
|
|
1806
|
+
agent,
|
|
1807
|
+
taskType,
|
|
1808
|
+
adaptedParams,
|
|
1809
|
+
canonicalInputHandler,
|
|
1810
|
+
effectiveOptions,
|
|
1811
|
+
serverVersion
|
|
1812
|
+
)
|
|
1061
1813
|
);
|
|
1062
1814
|
const postAdapterLogs = [...inputSchemaStripLogs, ...v25DriftLogs];
|
|
1063
1815
|
if (postAdapterLogs.length > 0) {
|
|
@@ -1066,9 +1818,26 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1066
1818
|
if (result.success && result.data) {
|
|
1067
1819
|
result.data = this.normalizeResponseToV3(taskType, result.data);
|
|
1068
1820
|
}
|
|
1069
|
-
result = this.wrapProductPolicySubmittedContinuation(result, taskType, normalizedParams);
|
|
1070
|
-
|
|
1821
|
+
result = this.wrapProductPolicySubmittedContinuation(result, taskType, normalizedParams, options);
|
|
1822
|
+
if (result.status === "working") {
|
|
1823
|
+
this.rememberProductPolicyRequestParams(taskType, normalizedParams, result, options);
|
|
1824
|
+
}
|
|
1825
|
+
this.rememberLegacyFormatConverter(taskType, legacyFormatConverter, result, options);
|
|
1071
1826
|
result = await this.applyProductPropertyPolicy(result, taskType, normalizedParams);
|
|
1827
|
+
if (CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) {
|
|
1828
|
+
const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, canonicalRequest ?? normalizedParams);
|
|
1829
|
+
result = this.canonicalizeCreativeTaskResult(result, taskType, transformCompletedResponse, legacyFormatConverter);
|
|
1830
|
+
result = this.wrapCanonicalCreativeContinuations(
|
|
1831
|
+
result,
|
|
1832
|
+
taskType,
|
|
1833
|
+
transformCompletedResponse,
|
|
1834
|
+
legacyFormatConverter,
|
|
1835
|
+
routingSnapshot
|
|
1836
|
+
);
|
|
1837
|
+
this.rememberCanonicalCreativeTaskIds(result, taskType, legacyFormatConverter, routingSnapshot);
|
|
1838
|
+
} else if (result.status === "completed" && result.success && result.data && transformCompletedResponse) {
|
|
1839
|
+
result = { ...result, data: transformCompletedResponse(result.data) };
|
|
1840
|
+
}
|
|
1072
1841
|
if (result.status === "completed" && result.success && this.asyncHandler) {
|
|
1073
1842
|
const handler = this.config.handlers?.[handlerName];
|
|
1074
1843
|
if (handler) {
|
|
@@ -1078,6 +1847,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1078
1847
|
task_id: result.metadata.taskId,
|
|
1079
1848
|
agent_id: this.agent.id,
|
|
1080
1849
|
task_type: taskType,
|
|
1850
|
+
status: result.status,
|
|
1081
1851
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1082
1852
|
};
|
|
1083
1853
|
await handler(result.data, metadata);
|
|
@@ -1085,6 +1855,255 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1085
1855
|
}
|
|
1086
1856
|
return result;
|
|
1087
1857
|
}
|
|
1858
|
+
canonicalCreativeInputHandler(taskType, inputHandler) {
|
|
1859
|
+
if (!inputHandler || !CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) return inputHandler;
|
|
1860
|
+
return async (context) => {
|
|
1861
|
+
const active = canonicalCreativeExecutionStorage.getStore();
|
|
1862
|
+
const converter = this.resolveLegacyFormatConverter(
|
|
1863
|
+
active?.taskType === taskType ? active.legacyFormatConverter : void 0
|
|
1864
|
+
);
|
|
1865
|
+
const project = (value) => projectCanonicalCreativeAncillaryValue(value, taskType, converter);
|
|
1866
|
+
const messages = context.messages.map((message) => ({
|
|
1867
|
+
...message,
|
|
1868
|
+
content: project(message.content)
|
|
1869
|
+
}));
|
|
1870
|
+
const safeContext = {
|
|
1871
|
+
...context,
|
|
1872
|
+
messages,
|
|
1873
|
+
inputRequest: project(context.inputRequest),
|
|
1874
|
+
getSummary: () => messages.map((message) => `${message.role}: ${JSON.stringify(message.content)}`).join("\n"),
|
|
1875
|
+
getPreviousResponse: (field) => project(context.getPreviousResponse(field))
|
|
1876
|
+
};
|
|
1877
|
+
return inputHandler(safeContext);
|
|
1878
|
+
};
|
|
1879
|
+
}
|
|
1880
|
+
projectCanonicalCreativeData(taskType, data, transform, legacyFormatConverter) {
|
|
1881
|
+
let projected = this.normalizeResponseToV3(taskType, data);
|
|
1882
|
+
const record = projected && typeof projected === "object" ? projected : void 0;
|
|
1883
|
+
const canProjectRead = taskType === "get_products" ? Array.isArray(record?.products) : taskType === "list_creatives" ? Array.isArray(record?.creatives) : true;
|
|
1884
|
+
if (transform && canProjectRead) {
|
|
1885
|
+
projected = transform(projected);
|
|
1886
|
+
} else if (canProjectRead && taskType === "get_products" && record) {
|
|
1887
|
+
const active = canonicalCreativeExecutionStorage.getStore();
|
|
1888
|
+
const { response, diagnostics } = (0, import_augment_response.toCanonicalOnlyResponse)(record, {
|
|
1889
|
+
legacyFormatConverter: this.resolveLegacyFormatConverter(
|
|
1890
|
+
legacyFormatConverter ?? (active?.taskType === taskType ? active.legacyFormatConverter : void 0)
|
|
1891
|
+
),
|
|
1892
|
+
projectionCatalogs: this.config.projectionCatalogs
|
|
1893
|
+
});
|
|
1894
|
+
const { _message: _dropLegacyMessage, ...canonical } = response;
|
|
1895
|
+
void _dropLegacyMessage;
|
|
1896
|
+
projected = { ...canonical, projection: { diagnostics } };
|
|
1897
|
+
} else if (canProjectRead && taskType === "list_creatives" && record) {
|
|
1898
|
+
const active = canonicalCreativeExecutionStorage.getStore();
|
|
1899
|
+
const activeLegacyFormatConverter = this.resolveLegacyFormatConverter(
|
|
1900
|
+
legacyFormatConverter ?? (active?.taskType === taskType ? active.legacyFormatConverter : void 0)
|
|
1901
|
+
);
|
|
1902
|
+
const { _message: _dropLegacyMessage, ...safe } = record;
|
|
1903
|
+
void _dropLegacyMessage;
|
|
1904
|
+
projected = {
|
|
1905
|
+
...safe,
|
|
1906
|
+
creatives: record.creatives.map(
|
|
1907
|
+
(creative) => (0, import_creative_delivery.projectCreativeForDelivery)(
|
|
1908
|
+
creative,
|
|
1909
|
+
{},
|
|
1910
|
+
"canonical",
|
|
1911
|
+
"list_creatives",
|
|
1912
|
+
activeLegacyFormatConverter
|
|
1913
|
+
)
|
|
1914
|
+
)
|
|
1915
|
+
};
|
|
1916
|
+
} else if (canProjectRead && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(taskType)) {
|
|
1917
|
+
const active = canonicalCreativeExecutionStorage.getStore();
|
|
1918
|
+
projected = projectCanonicalCreativeResponseValue(
|
|
1919
|
+
projected,
|
|
1920
|
+
taskType,
|
|
1921
|
+
this.resolveLegacyFormatConverter(
|
|
1922
|
+
legacyFormatConverter ?? (active?.taskType === taskType ? active.legacyFormatConverter : void 0)
|
|
1923
|
+
)
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1926
|
+
return (0, import_creative_delivery.stripLegacyCreativeIdentity)(projected);
|
|
1927
|
+
}
|
|
1928
|
+
canonicalizeCreativeTaskResult(result, taskType, transform, legacyFormatConverter) {
|
|
1929
|
+
const projectedData = result.data !== void 0 ? this.projectCanonicalCreativeData(taskType, result.data, transform, legacyFormatConverter) : void 0;
|
|
1930
|
+
const errorInstance = result.errorInstance;
|
|
1931
|
+
const converter = this.resolveLegacyFormatConverter(legacyFormatConverter);
|
|
1932
|
+
const metadataRecord = result.metadata;
|
|
1933
|
+
const semanticMetadata = {
|
|
1934
|
+
...metadataRecord,
|
|
1935
|
+
...metadataRecord.inputRequest !== void 0 && {
|
|
1936
|
+
inputRequest: projectCanonicalCreativeAncillaryValue(metadataRecord.inputRequest, taskType, converter)
|
|
1937
|
+
}
|
|
1938
|
+
};
|
|
1939
|
+
const semanticConversation = result.conversation?.map((message) => ({
|
|
1940
|
+
...message,
|
|
1941
|
+
content: projectCanonicalCreativeAncillaryValue(message.content, taskType, converter)
|
|
1942
|
+
}));
|
|
1943
|
+
const safe = (0, import_creative_delivery.stripLegacyCreativeIdentity)({
|
|
1944
|
+
data: projectedData,
|
|
1945
|
+
metadata: semanticMetadata,
|
|
1946
|
+
conversation: semanticConversation,
|
|
1947
|
+
debug_logs: result.debug_logs,
|
|
1948
|
+
adcpError: result.adcpError,
|
|
1949
|
+
error: result.error,
|
|
1950
|
+
governance: result.governance,
|
|
1951
|
+
governanceOutcome: result.governanceOutcome,
|
|
1952
|
+
governanceOutcomeError: result.governanceOutcomeError,
|
|
1953
|
+
deferredQuestion: result.deferred?.question,
|
|
1954
|
+
// Token source only: discarded below, but lets the sanitizer remove exact
|
|
1955
|
+
// legacy IDs/URLs when the seller repeats them in messages or diagnostics.
|
|
1956
|
+
legacySource: result.data
|
|
1957
|
+
});
|
|
1958
|
+
const safeErrorInstance = errorInstance ? canonicalCreativeErrorInstance(errorInstance, result.data) : void 0;
|
|
1959
|
+
const safeDeferred = result.deferred ? { ...result.deferred, ...result.deferred.question !== void 0 && { question: safe.deferredQuestion } } : void 0;
|
|
1960
|
+
return (0, import_match.attachMatch)({
|
|
1961
|
+
...result,
|
|
1962
|
+
...result.data !== void 0 && { data: safe.data },
|
|
1963
|
+
metadata: safe.metadata,
|
|
1964
|
+
...result.conversation !== void 0 && { conversation: safe.conversation },
|
|
1965
|
+
...result.debug_logs !== void 0 && { debug_logs: safe.debug_logs },
|
|
1966
|
+
...result.adcpError !== void 0 && { adcpError: safe.adcpError },
|
|
1967
|
+
...result.error !== void 0 && { error: safe.error },
|
|
1968
|
+
...result.governance !== void 0 && { governance: safe.governance },
|
|
1969
|
+
...result.governanceOutcome !== void 0 && { governanceOutcome: safe.governanceOutcome },
|
|
1970
|
+
...result.governanceOutcomeError !== void 0 && { governanceOutcomeError: safe.governanceOutcomeError },
|
|
1971
|
+
...safeDeferred !== void 0 && { deferred: safeDeferred },
|
|
1972
|
+
...safeErrorInstance !== void 0 && { errorInstance: safeErrorInstance }
|
|
1973
|
+
});
|
|
1974
|
+
}
|
|
1975
|
+
canonicalizeCreativeTaskInfo(taskInfo, taskType, transform, legacyFormatConverter) {
|
|
1976
|
+
const source = taskInfo.result;
|
|
1977
|
+
const projected = source !== void 0 ? this.projectCanonicalCreativeData(taskType, source, transform, legacyFormatConverter) : void 0;
|
|
1978
|
+
const { legacySource: _dropLegacySource, ...safe } = (0, import_creative_delivery.stripLegacyCreativeIdentity)({
|
|
1979
|
+
...taskInfo,
|
|
1980
|
+
taskType,
|
|
1981
|
+
...source !== void 0 && { result: projected },
|
|
1982
|
+
legacySource: source
|
|
1983
|
+
});
|
|
1984
|
+
void _dropLegacySource;
|
|
1985
|
+
return safe;
|
|
1986
|
+
}
|
|
1987
|
+
wrapCanonicalCreativeContinuations(result, taskType, transform, legacyFormatConverter, routingRequest) {
|
|
1988
|
+
const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, routingRequest);
|
|
1989
|
+
if (result.submitted) {
|
|
1990
|
+
const submitted = result.submitted;
|
|
1991
|
+
result = {
|
|
1992
|
+
...result,
|
|
1993
|
+
submitted: {
|
|
1994
|
+
...submitted,
|
|
1995
|
+
track: async (transport) => {
|
|
1996
|
+
const canonical = this.canonicalizeCreativeTaskInfo(
|
|
1997
|
+
await canonicalCreativeExecutionStorage.run(
|
|
1998
|
+
{ taskType, legacyFormatConverter },
|
|
1999
|
+
() => submitted.track(transport)
|
|
2000
|
+
),
|
|
2001
|
+
taskType,
|
|
2002
|
+
transform,
|
|
2003
|
+
legacyFormatConverter
|
|
2004
|
+
);
|
|
2005
|
+
if (canonical.status === "completed" && canonical.result !== void 0) {
|
|
2006
|
+
this.rememberCanonicalPackageRoutesForTask(taskType, canonical.result, routingSnapshot);
|
|
2007
|
+
}
|
|
2008
|
+
return canonical;
|
|
2009
|
+
},
|
|
2010
|
+
waitForCompletion: async (pollInterval, signal) => {
|
|
2011
|
+
const completed = await canonicalCreativeExecutionStorage.run(
|
|
2012
|
+
{ taskType, legacyFormatConverter },
|
|
2013
|
+
() => submitted.waitForCompletion(pollInterval, signal)
|
|
2014
|
+
);
|
|
2015
|
+
const canonical = this.canonicalizeCreativeTaskResult(
|
|
2016
|
+
completed,
|
|
2017
|
+
taskType,
|
|
2018
|
+
transform,
|
|
2019
|
+
legacyFormatConverter
|
|
2020
|
+
);
|
|
2021
|
+
if (canonical.success && canonical.status === "completed" && canonical.data !== void 0) {
|
|
2022
|
+
this.rememberCanonicalPackageRoutesForTask(taskType, canonical.data, routingSnapshot);
|
|
2023
|
+
}
|
|
2024
|
+
this.rememberCanonicalCreativeTaskIds(canonical, taskType, legacyFormatConverter, routingSnapshot);
|
|
2025
|
+
return this.wrapCanonicalCreativeContinuations(
|
|
2026
|
+
canonical,
|
|
2027
|
+
taskType,
|
|
2028
|
+
transform,
|
|
2029
|
+
legacyFormatConverter,
|
|
2030
|
+
routingSnapshot
|
|
2031
|
+
);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
if (result.deferred) {
|
|
2037
|
+
const deferred = result.deferred;
|
|
2038
|
+
result = {
|
|
2039
|
+
...result,
|
|
2040
|
+
deferred: {
|
|
2041
|
+
...deferred,
|
|
2042
|
+
resume: async (input) => {
|
|
2043
|
+
const resumed = await canonicalCreativeExecutionStorage.run(
|
|
2044
|
+
{ taskType, legacyFormatConverter },
|
|
2045
|
+
() => deferred.resume(input)
|
|
2046
|
+
);
|
|
2047
|
+
const canonical = this.canonicalizeCreativeTaskResult(resumed, taskType, transform, legacyFormatConverter);
|
|
2048
|
+
if (canonical.success && canonical.status === "completed" && canonical.data !== void 0) {
|
|
2049
|
+
this.rememberCanonicalPackageRoutesForTask(taskType, canonical.data, routingSnapshot);
|
|
2050
|
+
}
|
|
2051
|
+
this.rememberCanonicalCreativeTaskIds(canonical, taskType, legacyFormatConverter, routingSnapshot);
|
|
2052
|
+
return this.wrapCanonicalCreativeContinuations(
|
|
2053
|
+
canonical,
|
|
2054
|
+
taskType,
|
|
2055
|
+
transform,
|
|
2056
|
+
legacyFormatConverter,
|
|
2057
|
+
routingSnapshot
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
return (0, import_match.attachMatch)(result);
|
|
2064
|
+
}
|
|
2065
|
+
rememberCanonicalCreativeTaskIds(result, taskType, legacyFormatConverter, routingRequest) {
|
|
2066
|
+
const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, routingRequest);
|
|
2067
|
+
const keys = [
|
|
2068
|
+
result.metadata.taskId,
|
|
2069
|
+
result.metadata.contextId,
|
|
2070
|
+
result.metadata.serverTaskId,
|
|
2071
|
+
result.submitted?.taskId
|
|
2072
|
+
];
|
|
2073
|
+
for (const key of keys) {
|
|
2074
|
+
if (!key) continue;
|
|
2075
|
+
this.rememberCanonicalCreativeTaskAssociation(key, taskType, legacyFormatConverter, routingSnapshot);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
rememberCanonicalCreativeTaskAssociation(key, taskType, legacyFormatConverter, canonicalRequest) {
|
|
2079
|
+
const previous = this.canonicalCreativeTaskAssociations.get(key);
|
|
2080
|
+
const routingSnapshot = canonicalCreativeRoutingSnapshot(taskType, canonicalRequest);
|
|
2081
|
+
const effectiveRoutingSnapshot = routingSnapshot ?? (previous?.taskType === taskType ? previous.routingSnapshot : void 0);
|
|
2082
|
+
this.canonicalCreativeTaskAssociations.delete(key);
|
|
2083
|
+
this.canonicalCreativeTaskAssociations.set(key, {
|
|
2084
|
+
taskType,
|
|
2085
|
+
legacyFormatConverter,
|
|
2086
|
+
...effectiveRoutingSnapshot ? { routingSnapshot: effectiveRoutingSnapshot } : {}
|
|
2087
|
+
});
|
|
2088
|
+
while (this.canonicalCreativeTaskAssociations.size > TASK_SCOPED_STATE_LIMIT) {
|
|
2089
|
+
const oldest = this.canonicalCreativeTaskAssociations.keys().next().value;
|
|
2090
|
+
if (oldest === void 0) break;
|
|
2091
|
+
this.canonicalCreativeTaskAssociations.delete(oldest);
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
canonicalCreativeTaskAssociation(key) {
|
|
2095
|
+
if (!key) return void 0;
|
|
2096
|
+
const association = this.canonicalCreativeTaskAssociations.get(key);
|
|
2097
|
+
if (!association) return void 0;
|
|
2098
|
+
this.canonicalCreativeTaskAssociations.delete(key);
|
|
2099
|
+
this.canonicalCreativeTaskAssociations.set(key, association);
|
|
2100
|
+
return association;
|
|
2101
|
+
}
|
|
2102
|
+
forgetCanonicalCreativeTaskAssociationKeys(keys) {
|
|
2103
|
+
for (const key of keys) {
|
|
2104
|
+
if (key) this.canonicalCreativeTaskAssociations.delete(key);
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
1088
2107
|
/**
|
|
1089
2108
|
* Drop products that arrive without a usable `pricing_options[]` array from a
|
|
1090
2109
|
* completed `get_products` response. `pricing_options` is required and
|
|
@@ -1295,20 +2314,62 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1295
2314
|
return result;
|
|
1296
2315
|
}
|
|
1297
2316
|
rememberProductPolicyRequestParams(taskType, requestParams, result, options) {
|
|
2317
|
+
this.rememberProductPolicyRequestState(
|
|
2318
|
+
taskType,
|
|
2319
|
+
{ request: productPolicyRequestSnapshot(requestParams) },
|
|
2320
|
+
result,
|
|
2321
|
+
options
|
|
2322
|
+
);
|
|
2323
|
+
}
|
|
2324
|
+
rememberProductPolicyRequestState(taskType, requestState, result, options) {
|
|
1298
2325
|
if (taskType !== "get_products") return;
|
|
1299
2326
|
if (result.status !== "submitted" && result.status !== "working") return;
|
|
1300
2327
|
const keys = /* @__PURE__ */ new Set();
|
|
1301
2328
|
if (result.metadata.taskId) keys.add(result.metadata.taskId);
|
|
1302
2329
|
if (result.metadata.contextId) keys.add(result.metadata.contextId);
|
|
1303
2330
|
if (result.metadata.serverTaskId) keys.add(result.metadata.serverTaskId);
|
|
2331
|
+
if (result.submitted?.taskId) keys.add(result.submitted.taskId);
|
|
1304
2332
|
if (options?.taskId) keys.add(options.taskId);
|
|
1305
2333
|
if (options?.contextId) keys.add(options.contextId);
|
|
1306
2334
|
for (const key of keys) {
|
|
1307
|
-
this.productPolicyRequestParamsByTask.
|
|
2335
|
+
this.productPolicyRequestParamsByTask.delete(key);
|
|
2336
|
+
this.productPolicyRequestParamsByTask.set(key, requestState);
|
|
2337
|
+
while (this.productPolicyRequestParamsByTask.size > TASK_SCOPED_STATE_LIMIT) {
|
|
2338
|
+
const oldest = this.productPolicyRequestParamsByTask.keys().next().value;
|
|
2339
|
+
if (oldest === void 0) break;
|
|
2340
|
+
this.productPolicyRequestParamsByTask.delete(oldest);
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
rememberLegacyFormatConverter(taskType, converter, result, options) {
|
|
2345
|
+
if (!converter || taskType !== "get_products" && taskType !== "list_creatives") return;
|
|
2346
|
+
const metadata = result.metadata;
|
|
2347
|
+
const keys = [
|
|
2348
|
+
metadata.operationId,
|
|
2349
|
+
metadata.taskId,
|
|
2350
|
+
metadata.contextId,
|
|
2351
|
+
metadata.serverTaskId,
|
|
2352
|
+
options?.taskId,
|
|
2353
|
+
options?.contextId
|
|
2354
|
+
];
|
|
2355
|
+
for (const key of keys) {
|
|
2356
|
+
if (key) this.rememberCanonicalCreativeTaskAssociation(key, taskType, converter);
|
|
1308
2357
|
}
|
|
1309
2358
|
}
|
|
2359
|
+
legacyFormatConverterForWebhook(metadata) {
|
|
2360
|
+
return this.canonicalCreativeTaskAssociation(metadata.operation_id)?.legacyFormatConverter ?? this.canonicalCreativeTaskAssociation(metadata.task_id)?.legacyFormatConverter ?? this.canonicalCreativeTaskAssociation(metadata.context_id)?.legacyFormatConverter ?? this.resolveLegacyFormatConverter();
|
|
2361
|
+
}
|
|
1310
2362
|
forgetProductPolicyRequestParams(metadata) {
|
|
1311
|
-
|
|
2363
|
+
const aliases = [metadata.operation_id, metadata.task_id, metadata.context_id];
|
|
2364
|
+
const states = new Set(
|
|
2365
|
+
aliases.filter((key) => key !== void 0).map((key) => this.productPolicyRequestParamsByTask.get(key)).filter((value) => value !== void 0)
|
|
2366
|
+
);
|
|
2367
|
+
for (const state of states) state.request = void 0;
|
|
2368
|
+
this.forgetProductPolicyRequestParamKeys(aliases);
|
|
2369
|
+
if (states.size === 0) return;
|
|
2370
|
+
for (const [key, state] of this.productPolicyRequestParamsByTask) {
|
|
2371
|
+
if (states.has(state)) this.productPolicyRequestParamsByTask.delete(key);
|
|
2372
|
+
}
|
|
1312
2373
|
}
|
|
1313
2374
|
forgetProductPolicyRequestParamKeys(keys) {
|
|
1314
2375
|
for (const key of keys) {
|
|
@@ -1316,38 +2377,61 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1316
2377
|
this.productPolicyRequestParamsByTask.delete(key);
|
|
1317
2378
|
}
|
|
1318
2379
|
}
|
|
1319
|
-
wrapProductPolicySubmittedContinuation(result, taskType, requestParams) {
|
|
2380
|
+
wrapProductPolicySubmittedContinuation(result, taskType, requestParams, options) {
|
|
1320
2381
|
if (taskType !== "get_products" || result.status !== "submitted" || !result.submitted) return result;
|
|
1321
2382
|
const submitted = result.submitted;
|
|
2383
|
+
const policyState = {
|
|
2384
|
+
request: productPolicyRequestSnapshot(requestParams)
|
|
2385
|
+
};
|
|
2386
|
+
this.rememberProductPolicyRequestState(taskType, policyState, result, options);
|
|
2387
|
+
const retainedKeys = [
|
|
2388
|
+
result.metadata.taskId,
|
|
2389
|
+
result.metadata.contextId,
|
|
2390
|
+
result.metadata.serverTaskId,
|
|
2391
|
+
submitted.taskId,
|
|
2392
|
+
options?.taskId,
|
|
2393
|
+
options?.contextId
|
|
2394
|
+
];
|
|
1322
2395
|
result.submitted = {
|
|
1323
2396
|
...submitted,
|
|
1324
2397
|
track: async (transport) => {
|
|
1325
2398
|
const taskInfo = await submitted.track(transport);
|
|
1326
|
-
const
|
|
1327
|
-
|
|
1328
|
-
this.
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
2399
|
+
const terminal = ["completed", "failed", "rejected", "canceled"].includes(taskInfo.status);
|
|
2400
|
+
try {
|
|
2401
|
+
return await this.applyProductPropertyPolicyToTaskInfo(
|
|
2402
|
+
taskInfo,
|
|
2403
|
+
taskType,
|
|
2404
|
+
policyState.request ?? {}
|
|
2405
|
+
);
|
|
2406
|
+
} finally {
|
|
2407
|
+
if (terminal) {
|
|
2408
|
+
policyState.request = void 0;
|
|
2409
|
+
this.forgetProductPolicyRequestParamKeys([...retainedKeys, taskInfo.taskId]);
|
|
2410
|
+
}
|
|
1333
2411
|
}
|
|
1334
|
-
return processed;
|
|
1335
2412
|
},
|
|
1336
2413
|
waitForCompletion: async (pollInterval, signal) => {
|
|
1337
2414
|
let completed = await submitted.waitForCompletion(pollInterval, signal);
|
|
1338
2415
|
if (completed.success && completed.data) {
|
|
1339
2416
|
completed.data = this.normalizeResponseToV3(taskType, completed.data);
|
|
1340
2417
|
}
|
|
1341
|
-
const
|
|
1342
|
-
|
|
1343
|
-
this.
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
2418
|
+
const terminal = completed.status === "completed" || completed.status === "failed";
|
|
2419
|
+
try {
|
|
2420
|
+
return await this.applyProductPropertyPolicy(
|
|
2421
|
+
completed,
|
|
2422
|
+
taskType,
|
|
2423
|
+
policyState.request ?? {}
|
|
2424
|
+
);
|
|
2425
|
+
} finally {
|
|
2426
|
+
if (terminal) {
|
|
2427
|
+
policyState.request = void 0;
|
|
2428
|
+
this.forgetProductPolicyRequestParamKeys([
|
|
2429
|
+
...retainedKeys,
|
|
2430
|
+
completed.metadata.taskId,
|
|
2431
|
+
completed.metadata.serverTaskId
|
|
2432
|
+
]);
|
|
2433
|
+
}
|
|
1349
2434
|
}
|
|
1350
|
-
return processed;
|
|
1351
2435
|
}
|
|
1352
2436
|
};
|
|
1353
2437
|
return result;
|
|
@@ -1385,7 +2469,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1385
2469
|
};
|
|
1386
2470
|
}
|
|
1387
2471
|
productPolicyRequestParamsForWebhook(metadata) {
|
|
1388
|
-
return this.executor.getRequestParams(metadata.operation_id) ?? this.executor.getRequestParams(metadata.task_id) ?? this.
|
|
2472
|
+
return this.executor.getRequestParams(metadata.operation_id) ?? this.executor.getRequestParams(metadata.task_id) ?? this.productPolicyRequestParamsForKey(metadata.operation_id) ?? this.productPolicyRequestParamsForKey(metadata.task_id) ?? this.productPolicyRequestParamsForKey(metadata.context_id) ?? {};
|
|
2473
|
+
}
|
|
2474
|
+
productPolicyRequestParamsForKey(key) {
|
|
2475
|
+
if (!key) return void 0;
|
|
2476
|
+
const state = this.productPolicyRequestParamsByTask.get(key);
|
|
2477
|
+
if (!state?.request) return void 0;
|
|
2478
|
+
this.productPolicyRequestParamsByTask.delete(key);
|
|
2479
|
+
this.productPolicyRequestParamsByTask.set(key, state);
|
|
2480
|
+
return state.request;
|
|
1389
2481
|
}
|
|
1390
2482
|
async applyProductPropertyPolicyToWebhookResult(result, metadata) {
|
|
1391
2483
|
if (metadata.task_type !== "get_products" || metadata.status !== "completed" || !result) {
|
|
@@ -1580,30 +2672,57 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1580
2672
|
* ```
|
|
1581
2673
|
*/
|
|
1582
2674
|
async getProducts(params, inputHandler, options) {
|
|
2675
|
+
const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
|
|
2676
|
+
const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
|
|
2677
|
+
legacyFormatConverter,
|
|
2678
|
+
projectionCatalogs ?? this.config.projectionCatalogs
|
|
2679
|
+
);
|
|
2680
|
+
const account = canonicalAccountRoutingSnapshot(params.account);
|
|
1583
2681
|
return this.executeAndHandle(
|
|
1584
2682
|
"get_products",
|
|
1585
2683
|
"onGetProductsStatusChange",
|
|
1586
2684
|
params,
|
|
1587
2685
|
inputHandler,
|
|
1588
|
-
|
|
2686
|
+
taskOptions,
|
|
2687
|
+
(data) => {
|
|
2688
|
+
const { response, diagnostics } = (0, import_augment_response.toCanonicalOnlyResponse)(data, {
|
|
2689
|
+
legacyFormatConverter: effectiveLegacyFormatConverter,
|
|
2690
|
+
projectionCatalogs: projectionCatalogs ?? this.config.projectionCatalogs
|
|
2691
|
+
});
|
|
2692
|
+
const authoritativeProducts = Array.isArray(data.products) ? data.products : response.products;
|
|
2693
|
+
this.rememberCanonicalProductRoutes(response.products, account, authoritativeProducts);
|
|
2694
|
+
const { _message: _dropLegacyMessage, ...canonical } = response;
|
|
2695
|
+
void _dropLegacyMessage;
|
|
2696
|
+
return { ...canonical, projection: { diagnostics } };
|
|
2697
|
+
},
|
|
2698
|
+
effectiveLegacyFormatConverter
|
|
1589
2699
|
);
|
|
1590
2700
|
}
|
|
2701
|
+
/** @deprecated Explicit raw-wire escape hatch for migration tooling. */
|
|
2702
|
+
async getProductsLegacy(params, inputHandler, options) {
|
|
2703
|
+
return this.executeTaskUnprojected("get_products", params, inputHandler, options);
|
|
2704
|
+
}
|
|
1591
2705
|
/**
|
|
1592
|
-
* List
|
|
2706
|
+
* List a legacy named-format catalog for migration tooling.
|
|
1593
2707
|
*
|
|
1594
2708
|
* @param params - Format listing parameters
|
|
1595
2709
|
* @param inputHandler - Handler for clarification requests
|
|
1596
2710
|
* @param options - Task execution options
|
|
2711
|
+
* @deprecated Canonical applications discover `format_options[]` through `getProducts()`.
|
|
1597
2712
|
*/
|
|
1598
|
-
async
|
|
2713
|
+
async listCreativeFormatsLegacy(params, inputHandler, options) {
|
|
1599
2714
|
return this.executeAndHandle(
|
|
1600
2715
|
"list_creative_formats",
|
|
1601
|
-
"
|
|
2716
|
+
"onListCreativeFormatsLegacyStatusChange",
|
|
1602
2717
|
params,
|
|
1603
2718
|
inputHandler,
|
|
1604
2719
|
options
|
|
1605
2720
|
);
|
|
1606
2721
|
}
|
|
2722
|
+
/** @deprecated Migration-only access to legacy creative transformer declarations. */
|
|
2723
|
+
async listTransformersLegacy(params, inputHandler, options) {
|
|
2724
|
+
return this.executeTaskUnprojected("list_transformers", params, inputHandler, options);
|
|
2725
|
+
}
|
|
1607
2726
|
/**
|
|
1608
2727
|
* Create a new media buy
|
|
1609
2728
|
*
|
|
@@ -1612,6 +2731,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1612
2731
|
* @param options - Task execution options
|
|
1613
2732
|
*/
|
|
1614
2733
|
async createMediaBuy(params, inputHandler, options) {
|
|
2734
|
+
const { legacyFormatConverter, projectionCatalogs, canonicalFormatLegacyResolver, ...taskOptions } = options ?? {};
|
|
2735
|
+
const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
|
|
2736
|
+
legacyFormatConverter,
|
|
2737
|
+
projectionCatalogs ?? this.config.projectionCatalogs
|
|
2738
|
+
);
|
|
2739
|
+
const effectiveCanonicalFormatLegacyResolver = this.resolveCanonicalFormatLegacyResolver(
|
|
2740
|
+
canonicalFormatLegacyResolver,
|
|
2741
|
+
params.account
|
|
2742
|
+
);
|
|
2743
|
+
const hasCreativeFormatData = hasMediaBuyCreativeFormatData(params);
|
|
2744
|
+
if (hasCreativeFormatData) {
|
|
2745
|
+
this.validateBeforeCreativeCapabilityProbe("create_media_buy", params, taskOptions);
|
|
2746
|
+
}
|
|
2747
|
+
const wireMode = hasCreativeFormatData ? this.resolveCreativeFormatWireMode(
|
|
2748
|
+
"create_media_buy",
|
|
2749
|
+
await this.getCapabilities({ signal: taskOptions.signal, transport: taskOptions.transport })
|
|
2750
|
+
) : "canonical";
|
|
1615
2751
|
if (this.config.webhookUrlTemplate && !options?.disableWebhook) {
|
|
1616
2752
|
const now = /* @__PURE__ */ new Date();
|
|
1617
2753
|
const year = now.getUTCFullYear();
|
|
@@ -1646,9 +2782,28 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1646
2782
|
};
|
|
1647
2783
|
}
|
|
1648
2784
|
}
|
|
1649
|
-
|
|
2785
|
+
const result = await this.executeAndHandle(
|
|
1650
2786
|
"create_media_buy",
|
|
1651
2787
|
"onCreateMediaBuyStatusChange",
|
|
2788
|
+
(0, import_creative_delivery.projectMediaBuyCreativesForDelivery)(
|
|
2789
|
+
params,
|
|
2790
|
+
wireMode,
|
|
2791
|
+
"create_media_buy",
|
|
2792
|
+
effectiveLegacyFormatConverter,
|
|
2793
|
+
effectiveCanonicalFormatLegacyResolver
|
|
2794
|
+
),
|
|
2795
|
+
inputHandler,
|
|
2796
|
+
taskOptions,
|
|
2797
|
+
void 0,
|
|
2798
|
+
effectiveLegacyFormatConverter,
|
|
2799
|
+
params
|
|
2800
|
+
);
|
|
2801
|
+
if (result.data !== void 0) this.rememberCanonicalPackageRoutes(result.data, params);
|
|
2802
|
+
return result;
|
|
2803
|
+
}
|
|
2804
|
+
/** @deprecated Compatibility-only entry point for callers still holding legacy creative `format_id` values. */
|
|
2805
|
+
async createMediaBuyLegacy(params, inputHandler, options) {
|
|
2806
|
+
return await this.createMediaBuy(
|
|
1652
2807
|
params,
|
|
1653
2808
|
inputHandler,
|
|
1654
2809
|
options
|
|
@@ -1662,9 +2817,45 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1662
2817
|
* @param options - Task execution options
|
|
1663
2818
|
*/
|
|
1664
2819
|
async updateMediaBuy(params, inputHandler, options) {
|
|
1665
|
-
|
|
2820
|
+
const { legacyFormatConverter, projectionCatalogs, canonicalFormatLegacyResolver, ...taskOptions } = options ?? {};
|
|
2821
|
+
const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
|
|
2822
|
+
legacyFormatConverter,
|
|
2823
|
+
projectionCatalogs ?? this.config.projectionCatalogs
|
|
2824
|
+
);
|
|
2825
|
+
const effectiveCanonicalFormatLegacyResolver = this.resolveCanonicalFormatLegacyResolver(
|
|
2826
|
+
canonicalFormatLegacyResolver,
|
|
2827
|
+
params.account
|
|
2828
|
+
);
|
|
2829
|
+
const hasCreativeFormatData = hasMediaBuyCreativeFormatData(params);
|
|
2830
|
+
if (hasCreativeFormatData) {
|
|
2831
|
+
this.validateBeforeCreativeCapabilityProbe("update_media_buy", params, taskOptions);
|
|
2832
|
+
}
|
|
2833
|
+
const wireMode = hasCreativeFormatData ? this.resolveCreativeFormatWireMode(
|
|
2834
|
+
"update_media_buy",
|
|
2835
|
+
await this.getCapabilities({ signal: taskOptions.signal, transport: taskOptions.transport })
|
|
2836
|
+
) : "canonical";
|
|
2837
|
+
const result = await this.executeAndHandle(
|
|
1666
2838
|
"update_media_buy",
|
|
1667
2839
|
"onUpdateMediaBuyStatusChange",
|
|
2840
|
+
(0, import_creative_delivery.projectMediaBuyCreativesForDelivery)(
|
|
2841
|
+
params,
|
|
2842
|
+
wireMode,
|
|
2843
|
+
"update_media_buy",
|
|
2844
|
+
effectiveLegacyFormatConverter,
|
|
2845
|
+
effectiveCanonicalFormatLegacyResolver
|
|
2846
|
+
),
|
|
2847
|
+
inputHandler,
|
|
2848
|
+
taskOptions,
|
|
2849
|
+
void 0,
|
|
2850
|
+
effectiveLegacyFormatConverter,
|
|
2851
|
+
params
|
|
2852
|
+
);
|
|
2853
|
+
if (result.data !== void 0) this.rememberCanonicalPackageRoutes(result.data, params);
|
|
2854
|
+
return result;
|
|
2855
|
+
}
|
|
2856
|
+
/** @deprecated Compatibility-only entry point for callers still holding legacy creative `format_id` values. */
|
|
2857
|
+
async updateMediaBuyLegacy(params, inputHandler, options) {
|
|
2858
|
+
return await this.updateMediaBuy(
|
|
1668
2859
|
params,
|
|
1669
2860
|
inputHandler,
|
|
1670
2861
|
options
|
|
@@ -1678,41 +2869,149 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1678
2869
|
* @param options - Task execution options
|
|
1679
2870
|
*/
|
|
1680
2871
|
async syncCreatives(params, inputHandler, options) {
|
|
2872
|
+
const {
|
|
2873
|
+
creativeFormatProjection,
|
|
2874
|
+
legacyFormatConverter,
|
|
2875
|
+
projectionCatalogs,
|
|
2876
|
+
canonicalFormatLegacyResolver,
|
|
2877
|
+
...taskOptions
|
|
2878
|
+
} = options ?? {};
|
|
2879
|
+
const effectiveCanonicalFormatLegacyResolver = this.resolveCanonicalFormatLegacyResolver(
|
|
2880
|
+
canonicalFormatLegacyResolver,
|
|
2881
|
+
params.account
|
|
2882
|
+
);
|
|
2883
|
+
const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
|
|
2884
|
+
creativeFormatProjection?.legacyFormatConverter ?? legacyFormatConverter,
|
|
2885
|
+
projectionCatalogs ?? this.config.projectionCatalogs
|
|
2886
|
+
);
|
|
2887
|
+
this.validateBeforeCreativeCapabilityProbe("sync_creatives", params, taskOptions);
|
|
2888
|
+
const wireMode = this.resolveCreativeFormatWireMode(
|
|
2889
|
+
"sync_creatives",
|
|
2890
|
+
await this.getCapabilities({ signal: taskOptions.signal, transport: taskOptions.transport })
|
|
2891
|
+
);
|
|
2892
|
+
const configuredSelectorContainers = [
|
|
2893
|
+
...creativeFormatProjection?.selectorContainers ?? []
|
|
2894
|
+
];
|
|
2895
|
+
const configuredPackageIds = new Set(
|
|
2896
|
+
configuredSelectorContainers.flatMap(
|
|
2897
|
+
(container) => typeof container.package_id === "string" ? [container.package_id] : []
|
|
2898
|
+
)
|
|
2899
|
+
);
|
|
2900
|
+
const assignmentPackageContainers = Array.isArray(params.assignments) ? params.assignments.flatMap(
|
|
2901
|
+
(assignment) => typeof assignment.package_id === "string" && !configuredPackageIds.has(assignment.package_id) ? [{ package_id: assignment.package_id }] : []
|
|
2902
|
+
) : [];
|
|
2903
|
+
const wireParams = (0, import_creative_delivery.projectSyncCreativesForDelivery)(
|
|
2904
|
+
params,
|
|
2905
|
+
[...configuredSelectorContainers, ...assignmentPackageContainers],
|
|
2906
|
+
wireMode,
|
|
2907
|
+
effectiveLegacyFormatConverter,
|
|
2908
|
+
effectiveCanonicalFormatLegacyResolver
|
|
2909
|
+
);
|
|
1681
2910
|
return this.executeAndHandle(
|
|
1682
2911
|
"sync_creatives",
|
|
1683
2912
|
"onSyncCreativesStatusChange",
|
|
2913
|
+
wireParams,
|
|
2914
|
+
inputHandler,
|
|
2915
|
+
taskOptions,
|
|
2916
|
+
void 0,
|
|
2917
|
+
effectiveLegacyFormatConverter,
|
|
2918
|
+
params
|
|
2919
|
+
);
|
|
2920
|
+
}
|
|
2921
|
+
/** @deprecated Compatibility-only entry point for callers still holding legacy creative `format_id` values. */
|
|
2922
|
+
async syncCreativesLegacy(params, inputHandler, options) {
|
|
2923
|
+
return await this.syncCreatives(
|
|
1684
2924
|
params,
|
|
1685
2925
|
inputHandler,
|
|
1686
2926
|
options
|
|
1687
2927
|
);
|
|
1688
2928
|
}
|
|
2929
|
+
resolveCreativeFormatWireMode(taskType, capabilities) {
|
|
2930
|
+
const wireRelease = this.config.wireAdcpVersion ?? this.resolvedAdcpVersion;
|
|
2931
|
+
const declared = (0, import_creative_delivery.resolveCreativeFormatWireMode)(capabilities, wireRelease);
|
|
2932
|
+
const schema = creativeSchemaSupport(this.cachedToolSchemas?.get(taskType));
|
|
2933
|
+
if (declared !== "unknown" && schema !== "unknown" && declared !== schema) {
|
|
2934
|
+
throw new import_creative_delivery.CreativeFormatCapabilityError(
|
|
2935
|
+
`Seller capability and ${taskType} input schema disagree about canonical creative support`
|
|
2936
|
+
);
|
|
2937
|
+
}
|
|
2938
|
+
const resolved = declared !== "unknown" ? declared : schema;
|
|
2939
|
+
const release = /^v?(\d+)\.(\d+)(?:\.|-|$)/.exec(wireRelease.trim());
|
|
2940
|
+
const canonicalRequiredByBuyerPin = release !== null && (Number(release[1]) > 3 || Number(release[1]) === 3 && Number(release[2]) >= 2);
|
|
2941
|
+
if (resolved === "unknown" && canonicalRequiredByBuyerPin) {
|
|
2942
|
+
throw new import_creative_delivery.CreativeFormatCapabilityError(
|
|
2943
|
+
`Cannot prove which AdCP release the seller serves for ${taskType}; a 3.2+ client will not guess a legacy creative wire shape`
|
|
2944
|
+
);
|
|
2945
|
+
}
|
|
2946
|
+
return resolved;
|
|
2947
|
+
}
|
|
2948
|
+
/** Validate malformed creative payloads before capability discovery can perform I/O. */
|
|
2949
|
+
validateBeforeCreativeCapabilityProbe(taskType, params, options) {
|
|
2950
|
+
if (options.skipIdempotencyAutoInject || options.skipAccountValidation) return;
|
|
2951
|
+
let normalizedParams = (0, import_request_normalizer.normalizeRequestParams)(taskType, params);
|
|
2952
|
+
if ((0, import_idempotency.isMutatingTask)(taskType) && normalizedParams && typeof normalizedParams === "object" && !normalizedParams.idempotency_key) {
|
|
2953
|
+
normalizedParams = { ...normalizedParams, idempotency_key: (0, import_idempotency.generateIdempotencyKey)() };
|
|
2954
|
+
}
|
|
2955
|
+
this.validateRequest(taskType, normalizedParams);
|
|
2956
|
+
}
|
|
1689
2957
|
/**
|
|
1690
|
-
* List
|
|
2958
|
+
* List creatives through the canonical SDK boundary.
|
|
2959
|
+
*
|
|
2960
|
+
* Legacy format filters are rejected and returned creative identities are
|
|
2961
|
+
* projected to `format_kind` / `format_option_ref`. Migration tooling that
|
|
2962
|
+
* needs the negotiated raw wire shape must call `listCreativesLegacy()`.
|
|
1691
2963
|
*
|
|
1692
2964
|
* @param params - Creative listing parameters
|
|
1693
2965
|
* @param inputHandler - Handler for clarification requests
|
|
1694
2966
|
* @param options - Task execution options
|
|
1695
2967
|
*/
|
|
1696
2968
|
async listCreatives(params, inputHandler, options) {
|
|
2969
|
+
const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
|
|
2970
|
+
const effectiveLegacyFormatConverter = this.resolveLegacyFormatConverter(
|
|
2971
|
+
legacyFormatConverter,
|
|
2972
|
+
projectionCatalogs ?? this.config.projectionCatalogs
|
|
2973
|
+
);
|
|
1697
2974
|
return this.executeAndHandle(
|
|
1698
2975
|
"list_creatives",
|
|
1699
2976
|
"onListCreativesStatusChange",
|
|
1700
2977
|
params,
|
|
1701
2978
|
inputHandler,
|
|
1702
|
-
|
|
2979
|
+
taskOptions,
|
|
2980
|
+
(data) => {
|
|
2981
|
+
const { _message: _dropLegacyMessage, ...safe } = data;
|
|
2982
|
+
void _dropLegacyMessage;
|
|
2983
|
+
return {
|
|
2984
|
+
...safe,
|
|
2985
|
+
creatives: data.creatives.map(
|
|
2986
|
+
(creative) => (0, import_creative_delivery.projectCreativeForDelivery)(
|
|
2987
|
+
creative,
|
|
2988
|
+
{},
|
|
2989
|
+
"canonical",
|
|
2990
|
+
"list_creatives",
|
|
2991
|
+
effectiveLegacyFormatConverter
|
|
2992
|
+
)
|
|
2993
|
+
)
|
|
2994
|
+
};
|
|
2995
|
+
},
|
|
2996
|
+
effectiveLegacyFormatConverter
|
|
1703
2997
|
);
|
|
1704
2998
|
}
|
|
2999
|
+
/** @deprecated Explicit raw-wire escape hatch for migration tooling. */
|
|
3000
|
+
async listCreativesLegacy(params, inputHandler, options) {
|
|
3001
|
+
return this.executeTaskUnprojected("list_creatives", params, inputHandler, options);
|
|
3002
|
+
}
|
|
1705
3003
|
/**
|
|
1706
|
-
* Preview a creative
|
|
3004
|
+
* Preview a creative through the legacy named-format protocol.
|
|
1707
3005
|
*
|
|
1708
3006
|
* @param params - Preview creative parameters
|
|
1709
3007
|
* @param inputHandler - Handler for clarification requests
|
|
1710
3008
|
* @param options - Task execution options
|
|
3009
|
+
* @deprecated Migration-only access to `format_id`-based creative preview.
|
|
1711
3010
|
*/
|
|
1712
|
-
async
|
|
3011
|
+
async previewCreativeLegacy(params, inputHandler, options) {
|
|
1713
3012
|
return this.executeAndHandle(
|
|
1714
3013
|
"preview_creative",
|
|
1715
|
-
"
|
|
3014
|
+
"onPreviewCreativeLegacyStatusChange",
|
|
1716
3015
|
params,
|
|
1717
3016
|
inputHandler,
|
|
1718
3017
|
options
|
|
@@ -1726,13 +3025,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1726
3025
|
* @param options - Task execution options
|
|
1727
3026
|
*/
|
|
1728
3027
|
async getMediaBuys(params, inputHandler, options) {
|
|
1729
|
-
|
|
3028
|
+
const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
|
|
3029
|
+
const result = await this.executeAndHandle(
|
|
1730
3030
|
"get_media_buys",
|
|
1731
3031
|
"onGetMediaBuysStatusChange",
|
|
1732
3032
|
params,
|
|
1733
3033
|
inputHandler,
|
|
1734
|
-
|
|
3034
|
+
taskOptions,
|
|
3035
|
+
void 0,
|
|
3036
|
+
this.resolveLegacyFormatConverter(legacyFormatConverter, projectionCatalogs ?? this.config.projectionCatalogs)
|
|
1735
3037
|
);
|
|
3038
|
+
if (result.data !== void 0) this.rememberCanonicalPackageRoutes(result.data, params);
|
|
3039
|
+
return result;
|
|
1736
3040
|
}
|
|
1737
3041
|
/**
|
|
1738
3042
|
* Get media buy delivery information
|
|
@@ -1742,12 +3046,28 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1742
3046
|
* @param options - Task execution options
|
|
1743
3047
|
*/
|
|
1744
3048
|
async getMediaBuyDelivery(params, inputHandler, options) {
|
|
3049
|
+
const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
|
|
1745
3050
|
return this.executeAndHandle(
|
|
1746
3051
|
"get_media_buy_delivery",
|
|
1747
3052
|
"onGetMediaBuyDeliveryStatusChange",
|
|
1748
3053
|
params,
|
|
1749
3054
|
inputHandler,
|
|
1750
|
-
|
|
3055
|
+
taskOptions,
|
|
3056
|
+
void 0,
|
|
3057
|
+
this.resolveLegacyFormatConverter(legacyFormatConverter, projectionCatalogs ?? this.config.projectionCatalogs)
|
|
3058
|
+
);
|
|
3059
|
+
}
|
|
3060
|
+
/** Retrieve canonical creative-level and variant-level delivery metrics. */
|
|
3061
|
+
async getCreativeDelivery(params, inputHandler, options) {
|
|
3062
|
+
const { legacyFormatConverter, ...taskOptions } = options ?? {};
|
|
3063
|
+
return this.executeAndHandle(
|
|
3064
|
+
"get_creative_delivery",
|
|
3065
|
+
"onGetCreativeDeliveryStatusChange",
|
|
3066
|
+
params,
|
|
3067
|
+
inputHandler,
|
|
3068
|
+
taskOptions,
|
|
3069
|
+
void 0,
|
|
3070
|
+
legacyFormatConverter
|
|
1751
3071
|
);
|
|
1752
3072
|
}
|
|
1753
3073
|
/**
|
|
@@ -1874,12 +3194,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1874
3194
|
}
|
|
1875
3195
|
// ====== CREATIVE BUILD TASKS ======
|
|
1876
3196
|
/**
|
|
1877
|
-
* Build a creative
|
|
3197
|
+
* Build a creative through the legacy named-format protocol.
|
|
3198
|
+
* @deprecated Migration-only access to `target_format_id`-based creative building.
|
|
1878
3199
|
*/
|
|
1879
|
-
async
|
|
3200
|
+
async buildCreativeLegacy(params, inputHandler, options) {
|
|
1880
3201
|
return this.executeAndHandle(
|
|
1881
3202
|
"build_creative",
|
|
1882
|
-
"
|
|
3203
|
+
"onBuildCreativeLegacyStatusChange",
|
|
1883
3204
|
params,
|
|
1884
3205
|
inputHandler,
|
|
1885
3206
|
options
|
|
@@ -1986,10 +3307,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1986
3307
|
/**
|
|
1987
3308
|
* List content standards
|
|
1988
3309
|
*/
|
|
1989
|
-
async
|
|
3310
|
+
async listContentStandardsLegacy(params, inputHandler, options) {
|
|
1990
3311
|
return this.executeAndHandle(
|
|
1991
3312
|
"list_content_standards",
|
|
1992
|
-
"
|
|
3313
|
+
"onListContentStandardsLegacyStatusChange",
|
|
1993
3314
|
params,
|
|
1994
3315
|
inputHandler,
|
|
1995
3316
|
options
|
|
@@ -1998,10 +3319,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1998
3319
|
/**
|
|
1999
3320
|
* Get content standards
|
|
2000
3321
|
*/
|
|
2001
|
-
async
|
|
3322
|
+
async getContentStandardsLegacy(params, inputHandler, options) {
|
|
2002
3323
|
return this.executeAndHandle(
|
|
2003
3324
|
"get_content_standards",
|
|
2004
|
-
"
|
|
3325
|
+
"onGetContentStandardsLegacyStatusChange",
|
|
2005
3326
|
params,
|
|
2006
3327
|
inputHandler,
|
|
2007
3328
|
options
|
|
@@ -2010,10 +3331,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2010
3331
|
/**
|
|
2011
3332
|
* Calibrate content against standards
|
|
2012
3333
|
*/
|
|
2013
|
-
async
|
|
3334
|
+
async calibrateContentLegacy(params, inputHandler, options) {
|
|
2014
3335
|
return this.executeAndHandle(
|
|
2015
3336
|
"calibrate_content",
|
|
2016
|
-
"
|
|
3337
|
+
"onCalibrateContentLegacyStatusChange",
|
|
2017
3338
|
params,
|
|
2018
3339
|
inputHandler,
|
|
2019
3340
|
options
|
|
@@ -2022,10 +3343,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2022
3343
|
/**
|
|
2023
3344
|
* Validate content delivery
|
|
2024
3345
|
*/
|
|
2025
|
-
async
|
|
3346
|
+
async validateContentDeliveryLegacy(params, inputHandler, options) {
|
|
2026
3347
|
return this.executeAndHandle(
|
|
2027
3348
|
"validate_content_delivery",
|
|
2028
|
-
"
|
|
3349
|
+
"onValidateContentDeliveryLegacyStatusChange",
|
|
2029
3350
|
params,
|
|
2030
3351
|
inputHandler,
|
|
2031
3352
|
options
|
|
@@ -2080,25 +3401,62 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2080
3401
|
options
|
|
2081
3402
|
);
|
|
2082
3403
|
}
|
|
2083
|
-
|
|
3404
|
+
async executeTask(taskName, params, inputHandler, options) {
|
|
3405
|
+
switch (taskName) {
|
|
3406
|
+
case "get_products":
|
|
3407
|
+
return this.getProducts(params, inputHandler, options);
|
|
3408
|
+
case "create_media_buy":
|
|
3409
|
+
return await this.createMediaBuy(
|
|
3410
|
+
params,
|
|
3411
|
+
inputHandler,
|
|
3412
|
+
options
|
|
3413
|
+
);
|
|
3414
|
+
case "update_media_buy":
|
|
3415
|
+
return await this.updateMediaBuy(
|
|
3416
|
+
params,
|
|
3417
|
+
inputHandler,
|
|
3418
|
+
options
|
|
3419
|
+
);
|
|
3420
|
+
case "sync_creatives":
|
|
3421
|
+
return await this.syncCreatives(
|
|
3422
|
+
params,
|
|
3423
|
+
inputHandler,
|
|
3424
|
+
options
|
|
3425
|
+
);
|
|
3426
|
+
case "list_creatives":
|
|
3427
|
+
return this.listCreatives(params, inputHandler, options);
|
|
3428
|
+
case "get_media_buys":
|
|
3429
|
+
return this.getMediaBuys(params, inputHandler, options);
|
|
3430
|
+
case "get_media_buy_delivery":
|
|
3431
|
+
return this.getMediaBuyDelivery(params, inputHandler, options);
|
|
3432
|
+
case "get_creative_delivery":
|
|
3433
|
+
return this.getCreativeDelivery(params, inputHandler, options);
|
|
3434
|
+
}
|
|
3435
|
+
return this.executeTaskUnprojected(taskName, params, inputHandler, options);
|
|
3436
|
+
}
|
|
2084
3437
|
/**
|
|
2085
|
-
* Execute
|
|
3438
|
+
* Execute an extension task that is not part of the standard AdCP task set.
|
|
2086
3439
|
*
|
|
2087
|
-
*
|
|
2088
|
-
*
|
|
2089
|
-
*
|
|
2090
|
-
* @param options - Task execution options
|
|
2091
|
-
*
|
|
2092
|
-
* @example
|
|
2093
|
-
* ```typescript
|
|
2094
|
-
* const result = await client.executeTask(
|
|
2095
|
-
* 'get_products',
|
|
2096
|
-
* { brief: 'Coffee brands' },
|
|
2097
|
-
* handler
|
|
2098
|
-
* );
|
|
2099
|
-
* ```
|
|
3440
|
+
* Keeping custom tasks on an explicitly named API prevents a response-type
|
|
3441
|
+
* generic from weakening the canonical request types enforced by
|
|
3442
|
+
* `executeTask()` for standard creative-boundary tasks.
|
|
2100
3443
|
*/
|
|
2101
|
-
async
|
|
3444
|
+
async executeCustomTask(taskName, params, inputHandler, options) {
|
|
3445
|
+
if (STANDARD_ADCP_TASK_NAMES.has(taskName)) {
|
|
3446
|
+
throw new Error(
|
|
3447
|
+
`executeCustomTask() cannot execute standard AdCP task "${taskName}". Use its typed primary method, or an explicitly named *Legacy method for legacy creative tools.`
|
|
3448
|
+
);
|
|
3449
|
+
}
|
|
3450
|
+
return this.executeTaskUnprojected(taskName, params, inputHandler, options);
|
|
3451
|
+
}
|
|
3452
|
+
/**
|
|
3453
|
+
* Explicit raw-task compatibility escape hatch for conformance and migration tooling.
|
|
3454
|
+
* @deprecated Application code should use typed primary methods or `executeTask()`.
|
|
3455
|
+
*/
|
|
3456
|
+
async executeTaskLegacy(taskName, params, inputHandler, options) {
|
|
3457
|
+
return this.executeTaskUnprojected(taskName, params, inputHandler, options);
|
|
3458
|
+
}
|
|
3459
|
+
async executeTaskUnprojected(taskName, params, inputHandler, options) {
|
|
2102
3460
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
2103
3461
|
const startTime = Date.now();
|
|
2104
3462
|
try {
|
|
@@ -2153,8 +3511,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2153
3511
|
if (result.success && result.data) {
|
|
2154
3512
|
result.data = this.normalizeResponseToV3(taskName, result.data);
|
|
2155
3513
|
}
|
|
2156
|
-
result = this.wrapProductPolicySubmittedContinuation(result, taskName, normalizedParams);
|
|
2157
|
-
|
|
3514
|
+
result = this.wrapProductPolicySubmittedContinuation(result, taskName, normalizedParams, options);
|
|
3515
|
+
if (result.status === "working") {
|
|
3516
|
+
this.rememberProductPolicyRequestParams(taskName, normalizedParams, result, options);
|
|
3517
|
+
}
|
|
2158
3518
|
result = await this.applyProductPropertyPolicy(result, taskName, normalizedParams);
|
|
2159
3519
|
return result;
|
|
2160
3520
|
} catch (error) {
|
|
@@ -2232,19 +3592,58 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2232
3592
|
*/
|
|
2233
3593
|
async continueConversation(message, contextId, inputHandler) {
|
|
2234
3594
|
const agent = await this.ensureEndpointDiscovered();
|
|
2235
|
-
|
|
3595
|
+
const creativeAssociation = this.canonicalCreativeTaskAssociation(contextId);
|
|
3596
|
+
if (!creativeAssociation) {
|
|
3597
|
+
return this.executor.executeTask(agent, "continue_conversation", { message }, inputHandler, { contextId });
|
|
3598
|
+
}
|
|
3599
|
+
const { taskType: creativeTaskType } = creativeAssociation;
|
|
3600
|
+
const legacyFormatConverter = this.resolveLegacyFormatConverter(creativeAssociation.legacyFormatConverter);
|
|
3601
|
+
const result = await canonicalCreativeExecutionStorage.run(
|
|
3602
|
+
{ taskType: creativeTaskType, legacyFormatConverter },
|
|
3603
|
+
() => this.executor.executeTask(
|
|
3604
|
+
agent,
|
|
3605
|
+
"continue_conversation",
|
|
3606
|
+
{ message },
|
|
3607
|
+
this.canonicalCreativeInputHandler(creativeTaskType, inputHandler),
|
|
3608
|
+
{ contextId }
|
|
3609
|
+
)
|
|
3610
|
+
);
|
|
3611
|
+
const canonical = this.canonicalizeCreativeTaskResult(result, creativeTaskType, void 0, legacyFormatConverter);
|
|
3612
|
+
this.rememberCanonicalCreativeTaskIds(
|
|
3613
|
+
canonical,
|
|
3614
|
+
creativeTaskType,
|
|
3615
|
+
legacyFormatConverter,
|
|
3616
|
+
creativeAssociation.routingSnapshot
|
|
3617
|
+
);
|
|
3618
|
+
return this.wrapCanonicalCreativeContinuations(
|
|
3619
|
+
canonical,
|
|
3620
|
+
creativeTaskType,
|
|
3621
|
+
void 0,
|
|
3622
|
+
legacyFormatConverter,
|
|
3623
|
+
creativeAssociation.routingSnapshot
|
|
3624
|
+
);
|
|
2236
3625
|
}
|
|
2237
3626
|
/**
|
|
2238
3627
|
* Get conversation history for a task
|
|
2239
3628
|
*/
|
|
2240
3629
|
getConversationHistory(taskId) {
|
|
2241
|
-
|
|
3630
|
+
const history = this.executor.getConversationHistory(taskId);
|
|
3631
|
+
const association = this.canonicalCreativeTaskAssociation(taskId);
|
|
3632
|
+
if (!association) return history;
|
|
3633
|
+
const { taskType } = association;
|
|
3634
|
+
const converter = this.resolveLegacyFormatConverter(association.legacyFormatConverter);
|
|
3635
|
+
return history?.map((message) => ({
|
|
3636
|
+
...message,
|
|
3637
|
+
content: projectCanonicalCreativeAncillaryValue(message.content, taskType, converter)
|
|
3638
|
+
}));
|
|
2242
3639
|
}
|
|
2243
3640
|
/**
|
|
2244
3641
|
* Clear conversation history for a task
|
|
2245
3642
|
*/
|
|
2246
3643
|
clearConversationHistory(taskId) {
|
|
2247
3644
|
this.executor.clearConversationHistory(taskId);
|
|
3645
|
+
this.forgetCanonicalCreativeTaskAssociationKeys([taskId]);
|
|
3646
|
+
this.productPolicyRequestParamsByTask.delete(taskId);
|
|
2248
3647
|
}
|
|
2249
3648
|
// ====== AGENT INFORMATION ======
|
|
2250
3649
|
/**
|
|
@@ -2385,7 +3784,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2385
3784
|
* Get active tasks for this agent
|
|
2386
3785
|
*/
|
|
2387
3786
|
getActiveTasks() {
|
|
2388
|
-
return this.executor.getActiveTasks().filter((task) => task.agent.id === this.agent.id)
|
|
3787
|
+
return this.executor.getActiveTasks().filter((task) => task.agent.id === this.agent.id).map((task) => {
|
|
3788
|
+
if (!CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskName)) return task;
|
|
3789
|
+
const converter = this.resolveLegacyFormatConverter(
|
|
3790
|
+
this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter
|
|
3791
|
+
);
|
|
3792
|
+
return (0, import_creative_delivery.stripLegacyCreativeIdentity)({
|
|
3793
|
+
...task,
|
|
3794
|
+
params: projectCanonicalCreativeAncillaryValue(task.params, task.taskName, converter),
|
|
3795
|
+
messages: task.messages.map((message) => ({
|
|
3796
|
+
...message,
|
|
3797
|
+
content: projectCanonicalCreativeAncillaryValue(message.content, task.taskName, converter)
|
|
3798
|
+
})),
|
|
3799
|
+
...task.pendingInput !== void 0 && {
|
|
3800
|
+
pendingInput: projectCanonicalCreativeAncillaryValue(task.pendingInput, task.taskName, converter)
|
|
3801
|
+
}
|
|
3802
|
+
});
|
|
3803
|
+
});
|
|
2389
3804
|
}
|
|
2390
3805
|
// ====== TASK MANAGEMENT & NOTIFICATIONS ======
|
|
2391
3806
|
/**
|
|
@@ -2402,7 +3817,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2402
3817
|
* ```
|
|
2403
3818
|
*/
|
|
2404
3819
|
async listTasks() {
|
|
2405
|
-
|
|
3820
|
+
const tasks = await this.executor.getTaskList(this.agent.id);
|
|
3821
|
+
return tasks.map(
|
|
3822
|
+
(task) => CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
|
|
3823
|
+
task,
|
|
3824
|
+
task.taskType,
|
|
3825
|
+
void 0,
|
|
3826
|
+
this.resolveLegacyFormatConverter(this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter)
|
|
3827
|
+
) : task
|
|
3828
|
+
);
|
|
2406
3829
|
}
|
|
2407
3830
|
/**
|
|
2408
3831
|
* Get detailed information about a specific task
|
|
@@ -2411,7 +3834,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2411
3834
|
* @returns Promise resolving to task information
|
|
2412
3835
|
*/
|
|
2413
3836
|
async getTaskInfo(taskId) {
|
|
2414
|
-
|
|
3837
|
+
const task = await this.executor.getTaskInfo(taskId);
|
|
3838
|
+
return task && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
|
|
3839
|
+
task,
|
|
3840
|
+
task.taskType,
|
|
3841
|
+
void 0,
|
|
3842
|
+
this.resolveLegacyFormatConverter(this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter)
|
|
3843
|
+
) : task;
|
|
2415
3844
|
}
|
|
2416
3845
|
/**
|
|
2417
3846
|
* Subscribe to task notifications for this agent
|
|
@@ -2433,7 +3862,19 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2433
3862
|
* ```
|
|
2434
3863
|
*/
|
|
2435
3864
|
onTaskUpdate(callback) {
|
|
2436
|
-
return this.executor.onTaskUpdate(
|
|
3865
|
+
return this.executor.onTaskUpdate(
|
|
3866
|
+
this.agent.id,
|
|
3867
|
+
(task) => callback(
|
|
3868
|
+
CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
|
|
3869
|
+
task,
|
|
3870
|
+
task.taskType,
|
|
3871
|
+
void 0,
|
|
3872
|
+
this.resolveLegacyFormatConverter(
|
|
3873
|
+
this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter
|
|
3874
|
+
)
|
|
3875
|
+
) : task
|
|
3876
|
+
)
|
|
3877
|
+
);
|
|
2437
3878
|
}
|
|
2438
3879
|
/**
|
|
2439
3880
|
* Subscribe to all task events (create, update, complete, error)
|
|
@@ -2442,7 +3883,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2442
3883
|
* @returns Unsubscribe function
|
|
2443
3884
|
*/
|
|
2444
3885
|
onTaskEvents(callbacks) {
|
|
2445
|
-
|
|
3886
|
+
const safe = (task) => CANONICAL_CREATIVE_ACTIVITY_TASKS.has(task.taskType) ? this.canonicalizeCreativeTaskInfo(
|
|
3887
|
+
task,
|
|
3888
|
+
task.taskType,
|
|
3889
|
+
void 0,
|
|
3890
|
+
this.resolveLegacyFormatConverter(this.canonicalCreativeTaskAssociation(task.taskId)?.legacyFormatConverter)
|
|
3891
|
+
) : task;
|
|
3892
|
+
return this.executor.onTaskEvents(this.agent.id, {
|
|
3893
|
+
...callbacks.onTaskCreated && { onTaskCreated: (task) => callbacks.onTaskCreated(safe(task)) },
|
|
3894
|
+
...callbacks.onTaskUpdated && { onTaskUpdated: (task) => callbacks.onTaskUpdated(safe(task)) },
|
|
3895
|
+
...callbacks.onTaskCompleted && { onTaskCompleted: (task) => callbacks.onTaskCompleted(safe(task)) },
|
|
3896
|
+
...callbacks.onTaskFailed && {
|
|
3897
|
+
onTaskFailed: (task, error) => {
|
|
3898
|
+
const safeTask = safe(task);
|
|
3899
|
+
callbacks.onTaskFailed(safeTask, safeTask.error ?? (0, import_creative_delivery.stripLegacyCreativeIdentity)(error));
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
});
|
|
2446
3903
|
}
|
|
2447
3904
|
/**
|
|
2448
3905
|
* Register webhook URL for receiving task notifications
|
|
@@ -2556,9 +4013,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2556
4013
|
}
|
|
2557
4014
|
let authProvider;
|
|
2558
4015
|
if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
|
|
2559
|
-
const {
|
|
2560
|
-
|
|
4016
|
+
const { getAgentStorage } = await import("../auth/oauth/index.js");
|
|
4017
|
+
const { getNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.js");
|
|
4018
|
+
authProvider = getNonInteractiveOAuthProvider(this.normalizedAgent, {
|
|
2561
4019
|
agentHint: this.normalizedAgent.id,
|
|
4020
|
+
storage: getAgentStorage(this.normalizedAgent),
|
|
2562
4021
|
allowHttp: (0, import_net.isLikelyPrivateUrl)(this.normalizedAgent.agent_uri)
|
|
2563
4022
|
});
|
|
2564
4023
|
connectOptions.authProvider = authProvider;
|
|
@@ -2728,7 +4187,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2728
4187
|
);
|
|
2729
4188
|
if (discoveryContext) discoveryContext.toolSchemas = discoveredToolSchemas;
|
|
2730
4189
|
if (!usesScopedFetch) this.cachedToolSchemas = discoveredToolSchemas;
|
|
2731
|
-
const
|
|
4190
|
+
const advertisesCapabilitiesTool = tools.some((t) => t.name === "get_adcp_capabilities");
|
|
4191
|
+
const officialA2ALifecycle = this.normalizedAgent.protocol === "a2a" && tools.some((tool) => ["tasks/get", "get_task_status", "list_tasks"].includes(tool.name));
|
|
4192
|
+
const hasCapabilitiesTool = advertisesCapabilitiesTool || officialA2ALifecycle;
|
|
2732
4193
|
if (hasCapabilitiesTool) {
|
|
2733
4194
|
try {
|
|
2734
4195
|
const agent = await this.ensureEndpointDiscovered(options);
|
|
@@ -2741,10 +4202,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2741
4202
|
throw (0, import_abort2.createTimeoutError)(requestTimeoutMs);
|
|
2742
4203
|
}
|
|
2743
4204
|
if (result.success && result.data) {
|
|
2744
|
-
const
|
|
2745
|
-
if (!usesScopedFetch) this.cachedCapabilities =
|
|
2746
|
-
this.maybeWarnV2Sunset(
|
|
2747
|
-
return
|
|
4205
|
+
const capabilities2 = (0, import_capabilities.augmentCapabilitiesFromTools)((0, import_capabilities.parseCapabilitiesResponse)(result.data), tools);
|
|
4206
|
+
if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
|
|
4207
|
+
this.maybeWarnV2Sunset(capabilities2);
|
|
4208
|
+
return capabilities2;
|
|
4209
|
+
}
|
|
4210
|
+
if (!advertisesCapabilitiesTool) {
|
|
4211
|
+
throw new Error("unadvertised official A2A capability probe was not supported");
|
|
2748
4212
|
}
|
|
2749
4213
|
if (result.data && (0, import_capabilities.looksLikeV3Capabilities)(result.data)) {
|
|
2750
4214
|
console.warn(
|
|
@@ -2757,10 +4221,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2757
4221
|
version: "v3",
|
|
2758
4222
|
majorVersions: parsed.majorVersions.includes(3) ? parsed.majorVersions : [3]
|
|
2759
4223
|
};
|
|
2760
|
-
const
|
|
2761
|
-
if (!usesScopedFetch) this.cachedCapabilities =
|
|
2762
|
-
this.maybeWarnV2Sunset(
|
|
2763
|
-
return
|
|
4224
|
+
const capabilities2 = (0, import_capabilities.augmentCapabilitiesFromTools)(v3Capabilities, tools);
|
|
4225
|
+
if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
|
|
4226
|
+
this.maybeWarnV2Sunset(capabilities2);
|
|
4227
|
+
return capabilities2;
|
|
2764
4228
|
}
|
|
2765
4229
|
console.warn(
|
|
2766
4230
|
`[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.`,
|
|
@@ -2774,14 +4238,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2774
4238
|
if (error instanceof import_errors.AuthenticationRequiredError || error instanceof import_errors.TaskTimeoutError || (0, import_abort.isAbortOrTimeoutError)(error)) {
|
|
2775
4239
|
throw error;
|
|
2776
4240
|
}
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
4241
|
+
if (advertisesCapabilitiesTool) {
|
|
4242
|
+
console.warn(
|
|
4243
|
+
`[AdCP] Agent "${this.agent.id}" advertises get_adcp_capabilities but the call threw \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.`
|
|
4244
|
+
);
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
if (advertisesCapabilitiesTool) {
|
|
4248
|
+
const capabilities2 = (0, import_capabilities.augmentCapabilitiesFromTools)((0, import_capabilities.buildSyntheticV3Capabilities)(tools), tools);
|
|
4249
|
+
if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
|
|
4250
|
+
this.maybeWarnV2Sunset(capabilities2);
|
|
4251
|
+
return capabilities2;
|
|
2780
4252
|
}
|
|
2781
|
-
const capabilities2 = (0, import_capabilities.augmentCapabilitiesFromTools)((0, import_capabilities.buildSyntheticV3Capabilities)(tools), tools);
|
|
2782
|
-
if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
|
|
2783
|
-
this.maybeWarnV2Sunset(capabilities2);
|
|
2784
|
-
return capabilities2;
|
|
2785
4253
|
}
|
|
2786
4254
|
console.warn(
|
|
2787
4255
|
`[AdCP] Agent "${this.agent.id}" detected as v2 (no get_adcp_capabilities tool). Tools: [${tools.map((t) => t.name).join(", ")}]`
|
|
@@ -3101,38 +4569,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3101
4569
|
}
|
|
3102
4570
|
// ====== STATIC HELPER METHODS ======
|
|
3103
4571
|
/**
|
|
3104
|
-
* Query a creative
|
|
4572
|
+
* Query a legacy creative-agent named-format catalog.
|
|
3105
4573
|
*
|
|
3106
|
-
*
|
|
3107
|
-
* (
|
|
3108
|
-
* before creating a media buy.
|
|
4574
|
+
* Canonical applications discover seller-supported declarations through
|
|
4575
|
+
* `AgentClient.getProducts()` and consume `format_options[]` instead.
|
|
3109
4576
|
*
|
|
3110
4577
|
* @param creativeAgentUrl - URL of the creative agent (e.g., 'https://creative.adcontextprotocol.org/mcp')
|
|
3111
4578
|
* @param protocol - Protocol to use ('mcp' or 'a2a'), defaults to 'mcp'
|
|
3112
4579
|
* @returns Promise resolving to the list of available formats
|
|
3113
4580
|
*
|
|
3114
|
-
* @
|
|
3115
|
-
* ```typescript
|
|
3116
|
-
* // Discover formats from the standard creative agent
|
|
3117
|
-
* const formats = await SingleAgentClient.discoverCreativeFormats(
|
|
3118
|
-
* 'https://creative.adcontextprotocol.org/mcp'
|
|
3119
|
-
* );
|
|
3120
|
-
*
|
|
3121
|
-
* // Find a specific format
|
|
3122
|
-
* const banner = formats.find(f => f.format_id.id === 'display_300x250_image');
|
|
3123
|
-
*
|
|
3124
|
-
* // Use the format in a media buy
|
|
3125
|
-
* await salesAgent.createMediaBuy({
|
|
3126
|
-
* packages: [{
|
|
3127
|
-
* format_ids: [{
|
|
3128
|
-
* agent_url: banner.format_id.agent_url,
|
|
3129
|
-
* id: banner.format_id.id
|
|
3130
|
-
* }]
|
|
3131
|
-
* }]
|
|
3132
|
-
* });
|
|
3133
|
-
* ```
|
|
4581
|
+
* @deprecated Migration-only helper for the legacy named-format protocol.
|
|
3134
4582
|
*/
|
|
3135
|
-
static async
|
|
4583
|
+
static async discoverCreativeFormatsLegacy(creativeAgentUrl, protocol = "mcp") {
|
|
3136
4584
|
const client = new SingleAgentClient(
|
|
3137
4585
|
{
|
|
3138
4586
|
id: "creative_agent_discovery",
|
|
@@ -3142,7 +4590,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3142
4590
|
},
|
|
3143
4591
|
{}
|
|
3144
4592
|
);
|
|
3145
|
-
const result = await client.
|
|
4593
|
+
const result = await client.listCreativeFormatsLegacy({});
|
|
3146
4594
|
if (!result.success || !result.data) {
|
|
3147
4595
|
throw new Error(`Failed to discover creative formats: ${result.error || "Unknown error"}`);
|
|
3148
4596
|
}
|
|
@@ -3222,12 +4670,11 @@ function parseWebhookBody(value) {
|
|
|
3222
4670
|
const raw = Buffer.isBuffer(value) || value instanceof Uint8Array ? Buffer.from(value).toString("utf8") : value;
|
|
3223
4671
|
try {
|
|
3224
4672
|
return { ok: true, payload: JSON.parse(raw) };
|
|
3225
|
-
} catch
|
|
4673
|
+
} catch {
|
|
3226
4674
|
return {
|
|
3227
4675
|
ok: false,
|
|
3228
4676
|
code: "webhook_envelope_invalid",
|
|
3229
|
-
message: "Webhook body must be valid JSON."
|
|
3230
|
-
cause: error
|
|
4677
|
+
message: "Webhook body must be valid JSON."
|
|
3231
4678
|
};
|
|
3232
4679
|
}
|
|
3233
4680
|
}
|
|
@@ -3248,13 +4695,6 @@ function missingMcpWebhookFields(payload) {
|
|
|
3248
4695
|
return typeof value !== "string" || value.length === 0;
|
|
3249
4696
|
});
|
|
3250
4697
|
}
|
|
3251
|
-
function safeJsonPreview(value) {
|
|
3252
|
-
try {
|
|
3253
|
-
return JSON.stringify(value).substring(0, 200);
|
|
3254
|
-
} catch {
|
|
3255
|
-
return "[unserializable payload]";
|
|
3256
|
-
}
|
|
3257
|
-
}
|
|
3258
4698
|
function webhookErrorHttpStatus(error) {
|
|
3259
4699
|
if (error instanceof WebhookDispatchError) {
|
|
3260
4700
|
if (error.code === "webhook_signature_invalid" || error.code === "webhook_timestamp_invalid") {
|