@adcp/sdk 12.1.0 → 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/authorization-required.d.mts +3 -0
- package/dist/lib/auth/oauth/authorization-required.d.ts +3 -0
- package/dist/lib/auth/oauth/authorization-required.d.ts.map +1 -1
- package/dist/lib/auth/oauth/authorization-required.js +12 -9
- package/dist/lib/auth/oauth/authorization-required.js.map +1 -1
- package/dist/lib/auth/oauth/authorization-required.mjs +12 -9
- package/dist/lib/auth/oauth/authorization-required.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 +129 -52
- package/dist/lib/core/SingleAgentClient.d.ts +129 -52
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +1748 -218
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +1758 -218
- 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 +137 -44
- package/dist/lib/core/TaskExecutor.js.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +137 -44
- 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/net/ssrf-fetch.d.mts +13 -1
- package/dist/lib/net/ssrf-fetch.d.ts +13 -1
- package/dist/lib/net/ssrf-fetch.d.ts.map +1 -1
- package/dist/lib/net/ssrf-fetch.js +14 -7
- package/dist/lib/net/ssrf-fetch.js.map +1 -1
- package/dist/lib/net/ssrf-fetch.mjs +14 -7
- package/dist/lib/net/ssrf-fetch.mjs.map +1 -1
- package/dist/lib/protocols/a2a.d.mts +2 -2
- package/dist/lib/protocols/a2a.d.ts +2 -2
- package/dist/lib/protocols/a2a.d.ts.map +1 -1
- package/dist/lib/protocols/a2a.js +14 -9
- package/dist/lib/protocols/a2a.js.map +1 -1
- package/dist/lib/protocols/a2a.mjs +14 -9
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/protocols/index.d.mts +20 -3
- package/dist/lib/protocols/index.d.ts +20 -3
- package/dist/lib/protocols/index.d.ts.map +1 -1
- package/dist/lib/protocols/index.js +44 -31
- package/dist/lib/protocols/index.js.map +1 -1
- package/dist/lib/protocols/index.mjs +44 -32
- 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/protocols/mcp-tasks.d.mts +3 -0
- package/dist/lib/protocols/mcp-tasks.d.ts +3 -0
- package/dist/lib/protocols/mcp-tasks.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-tasks.js +21 -11
- package/dist/lib/protocols/mcp-tasks.js.map +1 -1
- package/dist/lib/protocols/mcp-tasks.mjs +21 -11
- package/dist/lib/protocols/mcp-tasks.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.d.ts.map +1 -1
- package/dist/lib/testing/client.js +13 -5
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/client.mjs +13 -5
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/compliance/comply.d.mts +1 -1
- package/dist/lib/testing/compliance/comply.d.ts +1 -1
- package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
- package/dist/lib/testing/compliance/comply.js +16 -6
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/comply.mjs +16 -6
- package/dist/lib/testing/compliance/comply.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/probes.d.mts +6 -0
- package/dist/lib/testing/storyboard/probes.d.ts +6 -0
- package/dist/lib/testing/storyboard/probes.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/probes.js +16 -5
- package/dist/lib/testing/storyboard/probes.js.map +1 -1
- package/dist/lib/testing/storyboard/probes.mjs +16 -5
- package/dist/lib/testing/storyboard/probes.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +6 -2
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +6 -2
- package/dist/lib/testing/storyboard/runner.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/testing/types.d.mts +7 -1
- package/dist/lib/testing/types.d.ts +7 -1
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/testing/types.js.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,12 +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;
|
|
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
|
+
]);
|
|
68
441
|
class UnsupportedFeatureError extends Error {
|
|
69
442
|
constructor(feature, serverVersion, message) {
|
|
70
443
|
super(message || `Feature '${feature}' requires AdCP v3 but server is ${serverVersion}`);
|
|
@@ -135,6 +508,14 @@ function propertyListReferenceFromRequest(params) {
|
|
|
135
508
|
...typeof ref.auth_token === "string" ? { auth_token: ref.auth_token } : {}
|
|
136
509
|
};
|
|
137
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
|
+
}
|
|
138
519
|
function hasProductPropertyPolicyRules(policy) {
|
|
139
520
|
return Boolean(
|
|
140
521
|
policy.allowedDomains?.length || policy.allowedPropertyIdentifiers?.length || policy.requireAllowedPropertyMatch || policy.excludedDomains?.length || policy.excludedPropertyIds?.length || policy.strict || policy.unknownSelectorBehavior || policy.missingPublisherPropertiesBehavior
|
|
@@ -195,8 +576,8 @@ class SingleAgentClient {
|
|
|
195
576
|
...config.validation?.requests != null && { requests: config.validation.requests },
|
|
196
577
|
...config.validation?.responses != null && { responses: config.validation.responses }
|
|
197
578
|
},
|
|
198
|
-
onActivity: config.onActivity,
|
|
199
|
-
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,
|
|
200
581
|
governance: config.governance,
|
|
201
582
|
adcpVersion: this.resolvedAdcpVersion,
|
|
202
583
|
...config.wireAdcpVersion !== void 0 && { wireAdcpVersion: config.wireAdcpVersion },
|
|
@@ -231,7 +612,237 @@ class SingleAgentClient {
|
|
|
231
612
|
_syntheticV2WarningFired = false;
|
|
232
613
|
// Gate: emit the synthetic-v2 warning once per client instance
|
|
233
614
|
productPolicyRequestParamsByTask = /* @__PURE__ */ new Map();
|
|
615
|
+
canonicalCreativeTaskAssociations = /* @__PURE__ */ new Map();
|
|
616
|
+
canonicalLegacyRoutes = /* @__PURE__ */ new Map();
|
|
234
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
|
+
}
|
|
235
846
|
/**
|
|
236
847
|
* Returns the AdCP protocol version this client is configured to speak.
|
|
237
848
|
*
|
|
@@ -255,25 +866,52 @@ class SingleAgentClient {
|
|
|
255
866
|
async ensureEndpointDiscovered(options) {
|
|
256
867
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
257
868
|
const needsDiscovery = this.normalizedAgent._needsDiscovery;
|
|
869
|
+
const transport = options?.transport ?? this.config.transport;
|
|
870
|
+
const usesScopedFetch = transport?.fetchFn !== void 0;
|
|
258
871
|
if (!needsDiscovery) {
|
|
259
872
|
return this.normalizedAgent;
|
|
260
873
|
}
|
|
261
|
-
if (this.discoveredAgent) {
|
|
874
|
+
if (!usesScopedFetch && this.discoveredAgent) {
|
|
262
875
|
return this.discoveredAgent;
|
|
263
876
|
}
|
|
264
|
-
if (this.discoveredEndpoint) {
|
|
877
|
+
if (!usesScopedFetch && this.discoveredEndpoint) {
|
|
265
878
|
this.discoveredAgent = {
|
|
266
879
|
...this.normalizedAgent,
|
|
267
880
|
agent_uri: this.discoveredEndpoint
|
|
268
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
|
+
}
|
|
269
886
|
return this.discoveredAgent;
|
|
270
887
|
}
|
|
271
|
-
|
|
888
|
+
if (this.normalizedAgent.oauth_client_credentials) {
|
|
889
|
+
const { ensureClientCredentialsTokens, getAgentStorage } = await import("../auth/oauth/index.js");
|
|
890
|
+
await ensureClientCredentialsTokens(this.normalizedAgent, {
|
|
891
|
+
storage: getAgentStorage(this.normalizedAgent),
|
|
892
|
+
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(this.normalizedAgent.agent_uri),
|
|
893
|
+
fetch: transport?.fetchFn
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
const discoveredEndpoint = await this.discoverMCPEndpoint(this.normalizedAgent.agent_uri, options);
|
|
897
|
+
if (usesScopedFetch) {
|
|
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;
|
|
904
|
+
}
|
|
905
|
+
this.discoveredEndpoint = discoveredEndpoint;
|
|
272
906
|
this.canonicalBaseUrl = this.computeBaseUrl(this.discoveredEndpoint);
|
|
273
907
|
this.discoveredAgent = {
|
|
274
908
|
...this.normalizedAgent,
|
|
275
909
|
agent_uri: this.discoveredEndpoint
|
|
276
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
|
+
}
|
|
277
915
|
return this.discoveredAgent;
|
|
278
916
|
}
|
|
279
917
|
/**
|
|
@@ -285,17 +923,27 @@ class SingleAgentClient {
|
|
|
285
923
|
async ensureCanonicalUrlResolved(options) {
|
|
286
924
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
287
925
|
const needsCanonicalUrl = this.normalizedAgent._needsCanonicalUrl;
|
|
926
|
+
const transport = options?.transport ?? this.config.transport;
|
|
927
|
+
const usesScopedFetch = transport?.fetchFn !== void 0;
|
|
288
928
|
if (!needsCanonicalUrl) {
|
|
289
929
|
return this.normalizedAgent;
|
|
290
930
|
}
|
|
291
|
-
if (this.canonicalBaseUrl) {
|
|
931
|
+
if (!usesScopedFetch && this.canonicalBaseUrl) {
|
|
292
932
|
return {
|
|
293
933
|
...this.normalizedAgent,
|
|
294
934
|
agent_uri: this.canonicalBaseUrl
|
|
295
935
|
};
|
|
296
936
|
}
|
|
937
|
+
if (this.normalizedAgent.oauth_client_credentials) {
|
|
938
|
+
const { ensureClientCredentialsTokens, getAgentStorage } = await import("../auth/oauth/index.js");
|
|
939
|
+
await ensureClientCredentialsTokens(this.normalizedAgent, {
|
|
940
|
+
storage: getAgentStorage(this.normalizedAgent),
|
|
941
|
+
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(this.normalizedAgent.agent_uri),
|
|
942
|
+
fetch: transport?.fetchFn
|
|
943
|
+
});
|
|
944
|
+
}
|
|
297
945
|
const canonicalUrl = await this.fetchA2ACanonicalUrl(this.normalizedAgent.agent_uri, options);
|
|
298
|
-
this.canonicalBaseUrl = canonicalUrl;
|
|
946
|
+
if (!usesScopedFetch) this.canonicalBaseUrl = canonicalUrl;
|
|
299
947
|
return {
|
|
300
948
|
...this.normalizedAgent,
|
|
301
949
|
agent_uri: canonicalUrl
|
|
@@ -313,8 +961,10 @@ class SingleAgentClient {
|
|
|
313
961
|
const transport = readOptions?.transport ?? this.config.transport;
|
|
314
962
|
const maxResponseBytes = transport?.maxResponseBytes;
|
|
315
963
|
const requestTimeoutMs = (0, import_abort2.resolveRequestTimeoutMs)(transport?.requestTimeoutMs, import_abort2.DEFAULT_REQUEST_TIMEOUT_MS);
|
|
316
|
-
const sizeLimitedFetch = wrapFetchWithSizeLimit(
|
|
317
|
-
|
|
964
|
+
const sizeLimitedFetch = wrapFetchWithSizeLimit(
|
|
965
|
+
(input, init) => transport?.fetchFn ? transport.fetchFn(input, init) : fetch(input, init)
|
|
966
|
+
);
|
|
967
|
+
const authToken = this.normalizedAgent.oauth_client_credentials ? this.normalizedAgent.oauth_tokens?.access_token : this.normalizedAgent.auth_token;
|
|
318
968
|
let got401 = false;
|
|
319
969
|
const fetchImpl = async (url, requestInit) => {
|
|
320
970
|
const headers = {
|
|
@@ -362,13 +1012,17 @@ class SingleAgentClient {
|
|
|
362
1012
|
} catch (error) {
|
|
363
1013
|
if ((0, import_errors.is401Error)(error, got401)) {
|
|
364
1014
|
const requirements = await (0, import_authorization_required.discoverAuthorizationRequirements)(agentUri, {
|
|
365
|
-
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(agentUri)
|
|
1015
|
+
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(agentUri),
|
|
1016
|
+
fetchFn: transport?.fetchFn
|
|
366
1017
|
});
|
|
367
1018
|
if (requirements) {
|
|
368
1019
|
throw new import_authorization_required.NeedsAuthorizationError(requirements);
|
|
369
1020
|
}
|
|
370
|
-
const challenge = await (0, import_authorization_required.probeAuthChallenge)(agentUri, {
|
|
371
|
-
|
|
1021
|
+
const challenge = await (0, import_authorization_required.probeAuthChallenge)(agentUri, {
|
|
1022
|
+
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(agentUri),
|
|
1023
|
+
fetchFn: transport?.fetchFn
|
|
1024
|
+
});
|
|
1025
|
+
const oauthMetadata = await (0, import_discovery.discoverOAuthMetadata)(agentUri, { fetch: transport?.fetchFn });
|
|
372
1026
|
throw new import_errors.AuthenticationRequiredError(agentUri, oauthMetadata || void 0, void 0, challenge ?? void 0);
|
|
373
1027
|
}
|
|
374
1028
|
throw error;
|
|
@@ -409,31 +1063,47 @@ class SingleAgentClient {
|
|
|
409
1063
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
410
1064
|
const { connectMCPWithFallback } = await import("../protocols/mcp.js");
|
|
411
1065
|
const { probeModernMCPConnection } = await import("../protocols/mcp-modern.js");
|
|
412
|
-
const
|
|
1066
|
+
const usesScopedFetch = (options?.transport ?? this.config.transport)?.fetchFn !== void 0;
|
|
1067
|
+
const authToken = this.normalizedAgent.oauth_client_credentials ? this.normalizedAgent.oauth_tokens?.access_token : this.agent.auth_token;
|
|
413
1068
|
const agentHeaders = this.agent.headers;
|
|
414
1069
|
const authHeaders = { ...agentHeaders, ...(0, import_auth.createMCPAuthHeaders)(authToken) };
|
|
415
|
-
const
|
|
416
|
-
|
|
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, {
|
|
1072
|
+
agentHint: this.normalizedAgent.id,
|
|
1073
|
+
storage: oauth.getAgentStorage(this.normalizedAgent),
|
|
1074
|
+
allowHttp: (0, import_net.isLikelyPrivateUrl)(this.normalizedAgent.agent_uri)
|
|
417
1075
|
}) : void 0;
|
|
418
1076
|
const testEndpoint = async (url) => {
|
|
419
1077
|
try {
|
|
420
1078
|
const modern = await probeModernMCPConnection(url, authToken, agentHeaders, {
|
|
421
1079
|
authProvider,
|
|
422
1080
|
signal: options?.signal,
|
|
423
|
-
requestTimeoutMs: options?.transport?.requestTimeoutMs ?? this.config.transport?.requestTimeoutMs
|
|
1081
|
+
requestTimeoutMs: options?.transport?.requestTimeoutMs ?? this.config.transport?.requestTimeoutMs,
|
|
1082
|
+
fetchFn: options?.transport?.fetchFn ?? this.config.transport?.fetchFn
|
|
424
1083
|
});
|
|
425
1084
|
if (modern.connected) {
|
|
426
|
-
|
|
427
|
-
|
|
1085
|
+
if (!usesScopedFetch) {
|
|
1086
|
+
this.discoveredMcpEra = modern.era;
|
|
1087
|
+
this.discoveredMcpEraAt = Date.now();
|
|
1088
|
+
}
|
|
428
1089
|
return { success: true };
|
|
429
1090
|
}
|
|
430
|
-
const client = await connectMCPWithFallback(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
1091
|
+
const client = await connectMCPWithFallback(
|
|
1092
|
+
new URL(url),
|
|
1093
|
+
authHeaders,
|
|
1094
|
+
[],
|
|
1095
|
+
"endpoint discovery",
|
|
1096
|
+
options?.transport?.fetchFn ?? this.config.transport?.fetchFn,
|
|
1097
|
+
{
|
|
1098
|
+
signal: options?.signal,
|
|
1099
|
+
requestTimeoutMs: options?.transport?.requestTimeoutMs ?? this.config.transport?.requestTimeoutMs
|
|
1100
|
+
}
|
|
1101
|
+
);
|
|
434
1102
|
await client.close();
|
|
435
|
-
|
|
436
|
-
|
|
1103
|
+
if (!usesScopedFetch) {
|
|
1104
|
+
this.discoveredMcpEra = "legacy";
|
|
1105
|
+
this.discoveredMcpEraAt = Date.now();
|
|
1106
|
+
}
|
|
437
1107
|
return { success: true };
|
|
438
1108
|
} catch (error) {
|
|
439
1109
|
if ((0, import_abort.isAbortOrTimeoutError)(error)) {
|
|
@@ -475,13 +1145,19 @@ class SingleAgentClient {
|
|
|
475
1145
|
}
|
|
476
1146
|
if (got401) {
|
|
477
1147
|
const requirements = await (0, import_authorization_required.discoverAuthorizationRequirements)(providedUri, {
|
|
478
|
-
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(providedUri)
|
|
1148
|
+
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(providedUri),
|
|
1149
|
+
fetchFn: options?.transport?.fetchFn ?? this.config.transport?.fetchFn
|
|
479
1150
|
});
|
|
480
1151
|
if (requirements) {
|
|
481
1152
|
throw new import_authorization_required.NeedsAuthorizationError(requirements);
|
|
482
1153
|
}
|
|
483
|
-
const challenge = await (0, import_authorization_required.probeAuthChallenge)(providedUri, {
|
|
484
|
-
|
|
1154
|
+
const challenge = await (0, import_authorization_required.probeAuthChallenge)(providedUri, {
|
|
1155
|
+
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(providedUri),
|
|
1156
|
+
fetchFn: options?.transport?.fetchFn ?? this.config.transport?.fetchFn
|
|
1157
|
+
});
|
|
1158
|
+
const oauthMetadata = await (0, import_discovery.discoverOAuthMetadata)(providedUri, {
|
|
1159
|
+
fetch: options?.transport?.fetchFn ?? this.config.transport?.fetchFn
|
|
1160
|
+
});
|
|
485
1161
|
throw new import_errors.AuthenticationRequiredError(providedUri, oauthMetadata || void 0, void 0, challenge ?? void 0);
|
|
486
1162
|
}
|
|
487
1163
|
throw new Error(
|
|
@@ -592,8 +1268,9 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
592
1268
|
* This is the lower-level receiver primitive for integrations that need to
|
|
593
1269
|
* map malformed webhooks to precise HTTP responses. It verifies the legacy
|
|
594
1270
|
* HMAC profile when `webhookSecret` is configured, parses raw JSON bodies,
|
|
595
|
-
* validates the transport envelope shape, and returns the
|
|
596
|
-
* 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.
|
|
597
1274
|
*/
|
|
598
1275
|
async verifyAndParseWebhook(options) {
|
|
599
1276
|
const rawBody = options.rawBody ?? rawBodyFromUnknown(options.body);
|
|
@@ -625,37 +1302,107 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
625
1302
|
if (!parsedPayload.ok) {
|
|
626
1303
|
return parsedPayload;
|
|
627
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;
|
|
628
1329
|
try {
|
|
629
1330
|
const normalizedPayload = this.normalizeWebhookPayload(
|
|
630
1331
|
parsedPayload.payload,
|
|
631
|
-
|
|
1332
|
+
normalizedTaskType ?? "unknown",
|
|
632
1333
|
options.operationId ?? "unknown"
|
|
633
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;
|
|
634
1369
|
return {
|
|
635
1370
|
ok: true,
|
|
636
1371
|
protocol: normalizedPayload.protocol ?? "mcp",
|
|
637
|
-
envelope:
|
|
638
|
-
result:
|
|
1372
|
+
envelope: canonicalEnvelope,
|
|
1373
|
+
result: canonicalResult,
|
|
639
1374
|
metadata: {
|
|
640
1375
|
operationId: normalizedPayload.operation_id,
|
|
641
1376
|
contextId: normalizedPayload.context_id,
|
|
642
1377
|
taskId: normalizedPayload.task_id,
|
|
643
1378
|
taskType: normalizedPayload.task_type,
|
|
644
1379
|
status: normalizedPayload.status,
|
|
645
|
-
message:
|
|
1380
|
+
message: canonicalMessage,
|
|
646
1381
|
timestamp: normalizedPayload.timestamp,
|
|
647
1382
|
idempotencyKey: normalizedPayload.idempotency_key
|
|
648
1383
|
}
|
|
649
1384
|
};
|
|
650
1385
|
} catch (error) {
|
|
1386
|
+
const canonicalCreativeTask = normalizedTaskType !== void 0 && CANONICAL_CREATIVE_ACTIVITY_TASKS.has(normalizedTaskType);
|
|
651
1387
|
if (error instanceof WebhookDispatchError) {
|
|
652
|
-
|
|
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 };
|
|
653
1401
|
}
|
|
654
1402
|
return {
|
|
655
1403
|
ok: false,
|
|
656
1404
|
code: "webhook_result_invalid",
|
|
657
|
-
message:
|
|
658
|
-
cause: error
|
|
1405
|
+
message: "Webhook payload could not be normalized."
|
|
659
1406
|
};
|
|
660
1407
|
}
|
|
661
1408
|
}
|
|
@@ -671,36 +1418,88 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
671
1418
|
timestamp: parsed.metadata.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
672
1419
|
idempotency_key: parsed.metadata.idempotencyKey,
|
|
673
1420
|
protocol: parsed.protocol,
|
|
674
|
-
rawHTTPPayload: parsed.envelope
|
|
1421
|
+
rawHTTPPayload: CANONICAL_CREATIVE_ACTIVITY_TASKS.has(parsed.metadata.taskType) ? (0, import_creative_delivery.stripLegacyCreativeIdentity)(parsed.envelope) : parsed.envelope
|
|
675
1422
|
};
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
metadata
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
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
|
+
);
|
|
694
1457
|
this.forgetProductPolicyRequestParams(metadata);
|
|
695
|
-
return true;
|
|
696
1458
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
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
|
+
});
|
|
1496
|
+
}
|
|
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);
|
|
701
1501
|
}
|
|
702
|
-
|
|
703
|
-
return false;
|
|
1502
|
+
return canonical;
|
|
704
1503
|
}
|
|
705
1504
|
/**
|
|
706
1505
|
* Normalize webhook payload - handles both MCP and A2A webhook formats
|
|
@@ -739,7 +1538,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
739
1538
|
if (typeof payload.status !== "string" || !WEBHOOK_TASK_STATUSES.has(payload.status)) {
|
|
740
1539
|
throw new WebhookDispatchError(
|
|
741
1540
|
"webhook_envelope_invalid",
|
|
742
|
-
`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(", ")}.`
|
|
743
1542
|
);
|
|
744
1543
|
}
|
|
745
1544
|
if (typeof payload.timestamp !== "string" || Number.isNaN(Date.parse(payload.timestamp))) {
|
|
@@ -779,7 +1578,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
779
1578
|
} catch (error) {
|
|
780
1579
|
throw new WebhookDispatchError(
|
|
781
1580
|
"webhook_result_invalid",
|
|
782
|
-
|
|
1581
|
+
"Failed to unwrap A2A webhook payload artifacts.",
|
|
783
1582
|
error
|
|
784
1583
|
);
|
|
785
1584
|
}
|
|
@@ -811,7 +1610,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
811
1610
|
}
|
|
812
1611
|
throw new WebhookDispatchError(
|
|
813
1612
|
"webhook_unsupported_payload",
|
|
814
|
-
|
|
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."
|
|
815
1614
|
);
|
|
816
1615
|
}
|
|
817
1616
|
/**
|
|
@@ -952,7 +1751,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
952
1751
|
*
|
|
953
1752
|
* Automatically adapts requests for v2 servers and normalizes responses.
|
|
954
1753
|
*/
|
|
955
|
-
async executeAndHandle(taskType, handlerName, params, inputHandler, options) {
|
|
1754
|
+
async executeAndHandle(taskType, handlerName, params, inputHandler, options, transformCompletedResponse, legacyFormatConverter, canonicalRequest) {
|
|
956
1755
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
957
1756
|
let normalizedParams = (0, import_request_normalizer.normalizeRequestParams)(taskType, params, {
|
|
958
1757
|
skipIdempotencyAutoInject: options?.skipIdempotencyAutoInject,
|
|
@@ -981,26 +1780,36 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
981
1780
|
if (!options?.skipIdempotencyAutoInject && !options?.skipAccountValidation) {
|
|
982
1781
|
this.executor.validateRequest(taskType, normalizedParams);
|
|
983
1782
|
}
|
|
984
|
-
const
|
|
1783
|
+
const capabilityDiscoveryContext = {};
|
|
1784
|
+
const detectionOptions = {
|
|
1785
|
+
...options,
|
|
1786
|
+
[CAPABILITY_DISCOVERY_CONTEXT]: capabilityDiscoveryContext
|
|
1787
|
+
};
|
|
1788
|
+
const serverVersion = await this.detectServerVersion(detectionOptions);
|
|
985
1789
|
const inputSchemaStripLogs = [];
|
|
986
1790
|
const { params: adaptedParams, driftLogs: adaptDriftLogs } = this.adaptRequest(
|
|
987
1791
|
taskType,
|
|
988
1792
|
normalizedParams,
|
|
989
1793
|
serverVersion,
|
|
990
|
-
inputSchemaStripLogs
|
|
1794
|
+
inputSchemaStripLogs,
|
|
1795
|
+
capabilityDiscoveryContext.toolSchemas
|
|
991
1796
|
);
|
|
992
1797
|
const v25DriftLogs = [...adaptDriftLogs];
|
|
993
1798
|
if (webhookDriftLog) v25DriftLogs.push(webhookDriftLog);
|
|
994
1799
|
if (serverVersion === "v2") {
|
|
995
1800
|
this.executor.validateAdaptedRequestAgainstV2(taskType, adaptedParams, v25DriftLogs);
|
|
996
1801
|
}
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
taskType,
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
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
|
+
)
|
|
1004
1813
|
);
|
|
1005
1814
|
const postAdapterLogs = [...inputSchemaStripLogs, ...v25DriftLogs];
|
|
1006
1815
|
if (postAdapterLogs.length > 0) {
|
|
@@ -1009,9 +1818,26 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1009
1818
|
if (result.success && result.data) {
|
|
1010
1819
|
result.data = this.normalizeResponseToV3(taskType, result.data);
|
|
1011
1820
|
}
|
|
1012
|
-
result = this.wrapProductPolicySubmittedContinuation(result, taskType, normalizedParams);
|
|
1013
|
-
|
|
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);
|
|
1014
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
|
+
}
|
|
1015
1841
|
if (result.status === "completed" && result.success && this.asyncHandler) {
|
|
1016
1842
|
const handler = this.config.handlers?.[handlerName];
|
|
1017
1843
|
if (handler) {
|
|
@@ -1021,6 +1847,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1021
1847
|
task_id: result.metadata.taskId,
|
|
1022
1848
|
agent_id: this.agent.id,
|
|
1023
1849
|
task_type: taskType,
|
|
1850
|
+
status: result.status,
|
|
1024
1851
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1025
1852
|
};
|
|
1026
1853
|
await handler(result.data, metadata);
|
|
@@ -1028,6 +1855,255 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1028
1855
|
}
|
|
1029
1856
|
return result;
|
|
1030
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
|
+
}
|
|
1031
2107
|
/**
|
|
1032
2108
|
* Drop products that arrive without a usable `pricing_options[]` array from a
|
|
1033
2109
|
* completed `get_products` response. `pricing_options` is required and
|
|
@@ -1238,20 +2314,62 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1238
2314
|
return result;
|
|
1239
2315
|
}
|
|
1240
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) {
|
|
1241
2325
|
if (taskType !== "get_products") return;
|
|
1242
2326
|
if (result.status !== "submitted" && result.status !== "working") return;
|
|
1243
2327
|
const keys = /* @__PURE__ */ new Set();
|
|
1244
2328
|
if (result.metadata.taskId) keys.add(result.metadata.taskId);
|
|
1245
2329
|
if (result.metadata.contextId) keys.add(result.metadata.contextId);
|
|
1246
2330
|
if (result.metadata.serverTaskId) keys.add(result.metadata.serverTaskId);
|
|
2331
|
+
if (result.submitted?.taskId) keys.add(result.submitted.taskId);
|
|
1247
2332
|
if (options?.taskId) keys.add(options.taskId);
|
|
1248
2333
|
if (options?.contextId) keys.add(options.contextId);
|
|
1249
2334
|
for (const key of keys) {
|
|
1250
|
-
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
|
+
}
|
|
1251
2342
|
}
|
|
1252
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);
|
|
2357
|
+
}
|
|
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
|
+
}
|
|
1253
2362
|
forgetProductPolicyRequestParams(metadata) {
|
|
1254
|
-
|
|
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
|
+
}
|
|
1255
2373
|
}
|
|
1256
2374
|
forgetProductPolicyRequestParamKeys(keys) {
|
|
1257
2375
|
for (const key of keys) {
|
|
@@ -1259,38 +2377,61 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1259
2377
|
this.productPolicyRequestParamsByTask.delete(key);
|
|
1260
2378
|
}
|
|
1261
2379
|
}
|
|
1262
|
-
wrapProductPolicySubmittedContinuation(result, taskType, requestParams) {
|
|
2380
|
+
wrapProductPolicySubmittedContinuation(result, taskType, requestParams, options) {
|
|
1263
2381
|
if (taskType !== "get_products" || result.status !== "submitted" || !result.submitted) return result;
|
|
1264
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
|
+
];
|
|
1265
2395
|
result.submitted = {
|
|
1266
2396
|
...submitted,
|
|
1267
2397
|
track: async (transport) => {
|
|
1268
2398
|
const taskInfo = await submitted.track(transport);
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
this.
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
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
|
+
}
|
|
1276
2411
|
}
|
|
1277
|
-
return processed;
|
|
1278
2412
|
},
|
|
1279
2413
|
waitForCompletion: async (pollInterval, signal) => {
|
|
1280
2414
|
let completed = await submitted.waitForCompletion(pollInterval, signal);
|
|
1281
2415
|
if (completed.success && completed.data) {
|
|
1282
2416
|
completed.data = this.normalizeResponseToV3(taskType, completed.data);
|
|
1283
2417
|
}
|
|
1284
|
-
const
|
|
1285
|
-
|
|
1286
|
-
this.
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
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
|
+
}
|
|
1292
2434
|
}
|
|
1293
|
-
return processed;
|
|
1294
2435
|
}
|
|
1295
2436
|
};
|
|
1296
2437
|
return result;
|
|
@@ -1328,7 +2469,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1328
2469
|
};
|
|
1329
2470
|
}
|
|
1330
2471
|
productPolicyRequestParamsForWebhook(metadata) {
|
|
1331
|
-
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;
|
|
1332
2481
|
}
|
|
1333
2482
|
async applyProductPropertyPolicyToWebhookResult(result, metadata) {
|
|
1334
2483
|
if (metadata.task_type !== "get_products" || metadata.status !== "completed" || !result) {
|
|
@@ -1373,17 +2522,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1373
2522
|
* 3.1-only fields for a 3.0 seller). Returns the adapted params and any
|
|
1374
2523
|
* drift log entries describing what was changed.
|
|
1375
2524
|
*
|
|
1376
|
-
* Runs after `detectServerVersion` so
|
|
1377
|
-
*
|
|
2525
|
+
* Runs after `detectServerVersion` so capabilities are available and the
|
|
2526
|
+
* current call's tool schemas can be supplied without cross-tenant caching.
|
|
1378
2527
|
*/
|
|
1379
|
-
adaptRequest(taskType, params, serverVersion, debugLogs) {
|
|
2528
|
+
adaptRequest(taskType, params, serverVersion, debugLogs, perCallToolSchemas) {
|
|
1380
2529
|
const driftLogs = [];
|
|
1381
2530
|
let adapted = params;
|
|
1382
2531
|
if (serverVersion !== "v3") {
|
|
1383
2532
|
const pair = (0, import_v2_5.getV25Adapter)(taskType);
|
|
1384
2533
|
if (pair) adapted = pair.adaptRequest(adapted);
|
|
1385
2534
|
}
|
|
1386
|
-
const toolSchema = this.cachedToolSchemas?.get(taskType);
|
|
2535
|
+
const toolSchema = (perCallToolSchemas ?? this.cachedToolSchemas)?.get(taskType);
|
|
1387
2536
|
if (toolSchema && Object.keys(toolSchema).length > 0) {
|
|
1388
2537
|
const declaredFields = new Set(Object.keys(toolSchema));
|
|
1389
2538
|
const adapterAliases = [["brand_manifest", "brand"]];
|
|
@@ -1523,30 +2672,57 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1523
2672
|
* ```
|
|
1524
2673
|
*/
|
|
1525
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);
|
|
1526
2681
|
return this.executeAndHandle(
|
|
1527
2682
|
"get_products",
|
|
1528
2683
|
"onGetProductsStatusChange",
|
|
1529
2684
|
params,
|
|
1530
2685
|
inputHandler,
|
|
1531
|
-
|
|
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
|
|
1532
2699
|
);
|
|
1533
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
|
+
}
|
|
1534
2705
|
/**
|
|
1535
|
-
* List
|
|
2706
|
+
* List a legacy named-format catalog for migration tooling.
|
|
1536
2707
|
*
|
|
1537
2708
|
* @param params - Format listing parameters
|
|
1538
2709
|
* @param inputHandler - Handler for clarification requests
|
|
1539
2710
|
* @param options - Task execution options
|
|
2711
|
+
* @deprecated Canonical applications discover `format_options[]` through `getProducts()`.
|
|
1540
2712
|
*/
|
|
1541
|
-
async
|
|
2713
|
+
async listCreativeFormatsLegacy(params, inputHandler, options) {
|
|
1542
2714
|
return this.executeAndHandle(
|
|
1543
2715
|
"list_creative_formats",
|
|
1544
|
-
"
|
|
2716
|
+
"onListCreativeFormatsLegacyStatusChange",
|
|
1545
2717
|
params,
|
|
1546
2718
|
inputHandler,
|
|
1547
2719
|
options
|
|
1548
2720
|
);
|
|
1549
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
|
+
}
|
|
1550
2726
|
/**
|
|
1551
2727
|
* Create a new media buy
|
|
1552
2728
|
*
|
|
@@ -1555,6 +2731,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1555
2731
|
* @param options - Task execution options
|
|
1556
2732
|
*/
|
|
1557
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";
|
|
1558
2751
|
if (this.config.webhookUrlTemplate && !options?.disableWebhook) {
|
|
1559
2752
|
const now = /* @__PURE__ */ new Date();
|
|
1560
2753
|
const year = now.getUTCFullYear();
|
|
@@ -1589,9 +2782,28 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1589
2782
|
};
|
|
1590
2783
|
}
|
|
1591
2784
|
}
|
|
1592
|
-
|
|
2785
|
+
const result = await this.executeAndHandle(
|
|
1593
2786
|
"create_media_buy",
|
|
1594
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(
|
|
1595
2807
|
params,
|
|
1596
2808
|
inputHandler,
|
|
1597
2809
|
options
|
|
@@ -1605,9 +2817,45 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1605
2817
|
* @param options - Task execution options
|
|
1606
2818
|
*/
|
|
1607
2819
|
async updateMediaBuy(params, inputHandler, options) {
|
|
1608
|
-
|
|
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(
|
|
1609
2838
|
"update_media_buy",
|
|
1610
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(
|
|
1611
2859
|
params,
|
|
1612
2860
|
inputHandler,
|
|
1613
2861
|
options
|
|
@@ -1621,41 +2869,149 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1621
2869
|
* @param options - Task execution options
|
|
1622
2870
|
*/
|
|
1623
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
|
+
);
|
|
1624
2910
|
return this.executeAndHandle(
|
|
1625
2911
|
"sync_creatives",
|
|
1626
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(
|
|
1627
2924
|
params,
|
|
1628
2925
|
inputHandler,
|
|
1629
2926
|
options
|
|
1630
2927
|
);
|
|
1631
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
|
+
}
|
|
1632
2957
|
/**
|
|
1633
|
-
* 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()`.
|
|
1634
2963
|
*
|
|
1635
2964
|
* @param params - Creative listing parameters
|
|
1636
2965
|
* @param inputHandler - Handler for clarification requests
|
|
1637
2966
|
* @param options - Task execution options
|
|
1638
2967
|
*/
|
|
1639
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
|
+
);
|
|
1640
2974
|
return this.executeAndHandle(
|
|
1641
2975
|
"list_creatives",
|
|
1642
2976
|
"onListCreativesStatusChange",
|
|
1643
2977
|
params,
|
|
1644
2978
|
inputHandler,
|
|
1645
|
-
|
|
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
|
|
1646
2997
|
);
|
|
1647
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
|
+
}
|
|
1648
3003
|
/**
|
|
1649
|
-
* Preview a creative
|
|
3004
|
+
* Preview a creative through the legacy named-format protocol.
|
|
1650
3005
|
*
|
|
1651
3006
|
* @param params - Preview creative parameters
|
|
1652
3007
|
* @param inputHandler - Handler for clarification requests
|
|
1653
3008
|
* @param options - Task execution options
|
|
3009
|
+
* @deprecated Migration-only access to `format_id`-based creative preview.
|
|
1654
3010
|
*/
|
|
1655
|
-
async
|
|
3011
|
+
async previewCreativeLegacy(params, inputHandler, options) {
|
|
1656
3012
|
return this.executeAndHandle(
|
|
1657
3013
|
"preview_creative",
|
|
1658
|
-
"
|
|
3014
|
+
"onPreviewCreativeLegacyStatusChange",
|
|
1659
3015
|
params,
|
|
1660
3016
|
inputHandler,
|
|
1661
3017
|
options
|
|
@@ -1669,13 +3025,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1669
3025
|
* @param options - Task execution options
|
|
1670
3026
|
*/
|
|
1671
3027
|
async getMediaBuys(params, inputHandler, options) {
|
|
1672
|
-
|
|
3028
|
+
const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
|
|
3029
|
+
const result = await this.executeAndHandle(
|
|
1673
3030
|
"get_media_buys",
|
|
1674
3031
|
"onGetMediaBuysStatusChange",
|
|
1675
3032
|
params,
|
|
1676
3033
|
inputHandler,
|
|
1677
|
-
|
|
3034
|
+
taskOptions,
|
|
3035
|
+
void 0,
|
|
3036
|
+
this.resolveLegacyFormatConverter(legacyFormatConverter, projectionCatalogs ?? this.config.projectionCatalogs)
|
|
1678
3037
|
);
|
|
3038
|
+
if (result.data !== void 0) this.rememberCanonicalPackageRoutes(result.data, params);
|
|
3039
|
+
return result;
|
|
1679
3040
|
}
|
|
1680
3041
|
/**
|
|
1681
3042
|
* Get media buy delivery information
|
|
@@ -1685,12 +3046,28 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1685
3046
|
* @param options - Task execution options
|
|
1686
3047
|
*/
|
|
1687
3048
|
async getMediaBuyDelivery(params, inputHandler, options) {
|
|
3049
|
+
const { legacyFormatConverter, projectionCatalogs, ...taskOptions } = options ?? {};
|
|
1688
3050
|
return this.executeAndHandle(
|
|
1689
3051
|
"get_media_buy_delivery",
|
|
1690
3052
|
"onGetMediaBuyDeliveryStatusChange",
|
|
1691
3053
|
params,
|
|
1692
3054
|
inputHandler,
|
|
1693
|
-
|
|
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
|
|
1694
3071
|
);
|
|
1695
3072
|
}
|
|
1696
3073
|
/**
|
|
@@ -1817,12 +3194,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1817
3194
|
}
|
|
1818
3195
|
// ====== CREATIVE BUILD TASKS ======
|
|
1819
3196
|
/**
|
|
1820
|
-
* 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.
|
|
1821
3199
|
*/
|
|
1822
|
-
async
|
|
3200
|
+
async buildCreativeLegacy(params, inputHandler, options) {
|
|
1823
3201
|
return this.executeAndHandle(
|
|
1824
3202
|
"build_creative",
|
|
1825
|
-
"
|
|
3203
|
+
"onBuildCreativeLegacyStatusChange",
|
|
1826
3204
|
params,
|
|
1827
3205
|
inputHandler,
|
|
1828
3206
|
options
|
|
@@ -1929,10 +3307,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1929
3307
|
/**
|
|
1930
3308
|
* List content standards
|
|
1931
3309
|
*/
|
|
1932
|
-
async
|
|
3310
|
+
async listContentStandardsLegacy(params, inputHandler, options) {
|
|
1933
3311
|
return this.executeAndHandle(
|
|
1934
3312
|
"list_content_standards",
|
|
1935
|
-
"
|
|
3313
|
+
"onListContentStandardsLegacyStatusChange",
|
|
1936
3314
|
params,
|
|
1937
3315
|
inputHandler,
|
|
1938
3316
|
options
|
|
@@ -1941,10 +3319,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1941
3319
|
/**
|
|
1942
3320
|
* Get content standards
|
|
1943
3321
|
*/
|
|
1944
|
-
async
|
|
3322
|
+
async getContentStandardsLegacy(params, inputHandler, options) {
|
|
1945
3323
|
return this.executeAndHandle(
|
|
1946
3324
|
"get_content_standards",
|
|
1947
|
-
"
|
|
3325
|
+
"onGetContentStandardsLegacyStatusChange",
|
|
1948
3326
|
params,
|
|
1949
3327
|
inputHandler,
|
|
1950
3328
|
options
|
|
@@ -1953,10 +3331,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1953
3331
|
/**
|
|
1954
3332
|
* Calibrate content against standards
|
|
1955
3333
|
*/
|
|
1956
|
-
async
|
|
3334
|
+
async calibrateContentLegacy(params, inputHandler, options) {
|
|
1957
3335
|
return this.executeAndHandle(
|
|
1958
3336
|
"calibrate_content",
|
|
1959
|
-
"
|
|
3337
|
+
"onCalibrateContentLegacyStatusChange",
|
|
1960
3338
|
params,
|
|
1961
3339
|
inputHandler,
|
|
1962
3340
|
options
|
|
@@ -1965,10 +3343,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
1965
3343
|
/**
|
|
1966
3344
|
* Validate content delivery
|
|
1967
3345
|
*/
|
|
1968
|
-
async
|
|
3346
|
+
async validateContentDeliveryLegacy(params, inputHandler, options) {
|
|
1969
3347
|
return this.executeAndHandle(
|
|
1970
3348
|
"validate_content_delivery",
|
|
1971
|
-
"
|
|
3349
|
+
"onValidateContentDeliveryLegacyStatusChange",
|
|
1972
3350
|
params,
|
|
1973
3351
|
inputHandler,
|
|
1974
3352
|
options
|
|
@@ -2023,25 +3401,62 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2023
3401
|
options
|
|
2024
3402
|
);
|
|
2025
3403
|
}
|
|
2026
|
-
|
|
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
|
+
}
|
|
2027
3437
|
/**
|
|
2028
|
-
* Execute
|
|
2029
|
-
*
|
|
2030
|
-
* @param taskName - Name of the task to execute
|
|
2031
|
-
* @param params - Task parameters
|
|
2032
|
-
* @param inputHandler - Handler for clarification requests
|
|
2033
|
-
* @param options - Task execution options
|
|
3438
|
+
* Execute an extension task that is not part of the standard AdCP task set.
|
|
2034
3439
|
*
|
|
2035
|
-
*
|
|
2036
|
-
*
|
|
2037
|
-
*
|
|
2038
|
-
* 'get_products',
|
|
2039
|
-
* { brief: 'Coffee brands' },
|
|
2040
|
-
* handler
|
|
2041
|
-
* );
|
|
2042
|
-
* ```
|
|
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.
|
|
2043
3443
|
*/
|
|
2044
|
-
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) {
|
|
2045
3460
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
2046
3461
|
const startTime = Date.now();
|
|
2047
3462
|
try {
|
|
@@ -2062,13 +3477,19 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2062
3477
|
if (!options?.skipIdempotencyAutoInject && !options?.skipAccountValidation) {
|
|
2063
3478
|
this.executor.validateRequest(taskName, normalizedParams);
|
|
2064
3479
|
}
|
|
2065
|
-
const
|
|
3480
|
+
const capabilityDiscoveryContext = {};
|
|
3481
|
+
const detectionOptions = {
|
|
3482
|
+
...options,
|
|
3483
|
+
[CAPABILITY_DISCOVERY_CONTEXT]: capabilityDiscoveryContext
|
|
3484
|
+
};
|
|
3485
|
+
const serverVersion = await this.detectServerVersion(detectionOptions);
|
|
2066
3486
|
const inputSchemaStripLogs = [];
|
|
2067
3487
|
const { params: adaptedParams, driftLogs: adaptDriftLogs } = this.adaptRequest(
|
|
2068
3488
|
taskName,
|
|
2069
3489
|
normalizedParams,
|
|
2070
3490
|
serverVersion,
|
|
2071
|
-
inputSchemaStripLogs
|
|
3491
|
+
inputSchemaStripLogs,
|
|
3492
|
+
capabilityDiscoveryContext.toolSchemas
|
|
2072
3493
|
);
|
|
2073
3494
|
const v25DriftLogs = [...adaptDriftLogs];
|
|
2074
3495
|
if (webhookDriftLog) v25DriftLogs.push(webhookDriftLog);
|
|
@@ -2090,8 +3511,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2090
3511
|
if (result.success && result.data) {
|
|
2091
3512
|
result.data = this.normalizeResponseToV3(taskName, result.data);
|
|
2092
3513
|
}
|
|
2093
|
-
result = this.wrapProductPolicySubmittedContinuation(result, taskName, normalizedParams);
|
|
2094
|
-
|
|
3514
|
+
result = this.wrapProductPolicySubmittedContinuation(result, taskName, normalizedParams, options);
|
|
3515
|
+
if (result.status === "working") {
|
|
3516
|
+
this.rememberProductPolicyRequestParams(taskName, normalizedParams, result, options);
|
|
3517
|
+
}
|
|
2095
3518
|
result = await this.applyProductPropertyPolicy(result, taskName, normalizedParams);
|
|
2096
3519
|
return result;
|
|
2097
3520
|
} catch (error) {
|
|
@@ -2169,19 +3592,58 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2169
3592
|
*/
|
|
2170
3593
|
async continueConversation(message, contextId, inputHandler) {
|
|
2171
3594
|
const agent = await this.ensureEndpointDiscovered();
|
|
2172
|
-
|
|
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
|
+
);
|
|
2173
3625
|
}
|
|
2174
3626
|
/**
|
|
2175
3627
|
* Get conversation history for a task
|
|
2176
3628
|
*/
|
|
2177
3629
|
getConversationHistory(taskId) {
|
|
2178
|
-
|
|
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
|
+
}));
|
|
2179
3639
|
}
|
|
2180
3640
|
/**
|
|
2181
3641
|
* Clear conversation history for a task
|
|
2182
3642
|
*/
|
|
2183
3643
|
clearConversationHistory(taskId) {
|
|
2184
3644
|
this.executor.clearConversationHistory(taskId);
|
|
3645
|
+
this.forgetCanonicalCreativeTaskAssociationKeys([taskId]);
|
|
3646
|
+
this.productPolicyRequestParamsByTask.delete(taskId);
|
|
2185
3647
|
}
|
|
2186
3648
|
// ====== AGENT INFORMATION ======
|
|
2187
3649
|
/**
|
|
@@ -2322,7 +3784,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2322
3784
|
* Get active tasks for this agent
|
|
2323
3785
|
*/
|
|
2324
3786
|
getActiveTasks() {
|
|
2325
|
-
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
|
+
});
|
|
2326
3804
|
}
|
|
2327
3805
|
// ====== TASK MANAGEMENT & NOTIFICATIONS ======
|
|
2328
3806
|
/**
|
|
@@ -2339,7 +3817,15 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2339
3817
|
* ```
|
|
2340
3818
|
*/
|
|
2341
3819
|
async listTasks() {
|
|
2342
|
-
|
|
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
|
+
);
|
|
2343
3829
|
}
|
|
2344
3830
|
/**
|
|
2345
3831
|
* Get detailed information about a specific task
|
|
@@ -2348,7 +3834,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2348
3834
|
* @returns Promise resolving to task information
|
|
2349
3835
|
*/
|
|
2350
3836
|
async getTaskInfo(taskId) {
|
|
2351
|
-
|
|
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;
|
|
2352
3844
|
}
|
|
2353
3845
|
/**
|
|
2354
3846
|
* Subscribe to task notifications for this agent
|
|
@@ -2370,7 +3862,19 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2370
3862
|
* ```
|
|
2371
3863
|
*/
|
|
2372
3864
|
onTaskUpdate(callback) {
|
|
2373
|
-
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
|
+
);
|
|
2374
3878
|
}
|
|
2375
3879
|
/**
|
|
2376
3880
|
* Subscribe to all task events (create, update, complete, error)
|
|
@@ -2379,7 +3883,23 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2379
3883
|
* @returns Unsubscribe function
|
|
2380
3884
|
*/
|
|
2381
3885
|
onTaskEvents(callbacks) {
|
|
2382
|
-
|
|
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
|
+
});
|
|
2383
3903
|
}
|
|
2384
3904
|
/**
|
|
2385
3905
|
* Register webhook URL for receiving task notifications
|
|
@@ -2443,6 +3963,16 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2443
3963
|
...options?.signal && { signal: options.signal },
|
|
2444
3964
|
...clientRequestTimeoutMs !== void 0 && { timeout: clientRequestTimeoutMs }
|
|
2445
3965
|
};
|
|
3966
|
+
const ensureReadAuthToken = async () => {
|
|
3967
|
+
if (!this.normalizedAgent.oauth_client_credentials) return this.normalizedAgent.auth_token;
|
|
3968
|
+
const { ensureClientCredentialsTokens, getAgentStorage } = await import("../auth/oauth/index.js");
|
|
3969
|
+
await ensureClientCredentialsTokens(this.normalizedAgent, {
|
|
3970
|
+
storage: getAgentStorage(this.normalizedAgent),
|
|
3971
|
+
allowPrivateIp: (0, import_net.isLikelyPrivateUrl)(this.normalizedAgent.agent_uri),
|
|
3972
|
+
fetch: transport?.fetchFn
|
|
3973
|
+
});
|
|
3974
|
+
return this.normalizedAgent.oauth_tokens?.access_token;
|
|
3975
|
+
};
|
|
2446
3976
|
if (this.normalizedAgent.protocol === "mcp") {
|
|
2447
3977
|
if (this.normalizedAgent._inProcessMcpClient) {
|
|
2448
3978
|
const mcpClient2 = this.normalizedAgent._inProcessMcpClient;
|
|
@@ -2464,6 +3994,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2464
3994
|
tools
|
|
2465
3995
|
};
|
|
2466
3996
|
}
|
|
3997
|
+
const readAuthToken = await ensureReadAuthToken();
|
|
2467
3998
|
const agent = await this.ensureEndpointDiscovered(options);
|
|
2468
3999
|
const { connectMCP } = await import("../protocols/mcp.js");
|
|
2469
4000
|
const { tryListModernMCPTools } = await import("../protocols/mcp-modern.js");
|
|
@@ -2474,25 +4005,32 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2474
4005
|
if (transport?.requestTimeoutMs !== void 0) {
|
|
2475
4006
|
connectOptions.requestTimeoutMs = transport.requestTimeoutMs;
|
|
2476
4007
|
}
|
|
4008
|
+
if (transport?.fetchFn) {
|
|
4009
|
+
connectOptions.fetchFn = transport.fetchFn;
|
|
4010
|
+
}
|
|
2477
4011
|
if (this.normalizedAgent.headers && Object.keys(this.normalizedAgent.headers).length > 0) {
|
|
2478
4012
|
connectOptions.customHeaders = this.normalizedAgent.headers;
|
|
2479
4013
|
}
|
|
2480
4014
|
let authProvider;
|
|
2481
|
-
if (this.normalizedAgent.oauth_tokens) {
|
|
2482
|
-
const {
|
|
2483
|
-
|
|
2484
|
-
|
|
4015
|
+
if (this.normalizedAgent.oauth_tokens && !this.normalizedAgent.oauth_client_credentials) {
|
|
4016
|
+
const { getAgentStorage } = await import("../auth/oauth/index.js");
|
|
4017
|
+
const { getNonInteractiveOAuthProvider } = await import("../auth/oauth/provider-cache.js");
|
|
4018
|
+
authProvider = getNonInteractiveOAuthProvider(this.normalizedAgent, {
|
|
4019
|
+
agentHint: this.normalizedAgent.id,
|
|
4020
|
+
storage: getAgentStorage(this.normalizedAgent),
|
|
4021
|
+
allowHttp: (0, import_net.isLikelyPrivateUrl)(this.normalizedAgent.agent_uri)
|
|
2485
4022
|
});
|
|
2486
4023
|
connectOptions.authProvider = authProvider;
|
|
2487
|
-
} else if (
|
|
2488
|
-
connectOptions.authToken =
|
|
4024
|
+
} else if (readAuthToken) {
|
|
4025
|
+
connectOptions.authToken = readAuthToken;
|
|
2489
4026
|
}
|
|
2490
|
-
const modernTools = this.discoveredMcpEra === "legacy" && Date.now() - this.discoveredMcpEraAt < 5 * 60 * 1e3 ? { handled: false } : await withResponseSizeLimit(
|
|
4027
|
+
const modernTools = !transport?.fetchFn && this.discoveredMcpEra === "legacy" && Date.now() - this.discoveredMcpEraAt < 5 * 60 * 1e3 ? { handled: false } : await withResponseSizeLimit(
|
|
2491
4028
|
maxResponseBytes,
|
|
2492
|
-
() => tryListModernMCPTools(agent.agent_uri,
|
|
4029
|
+
() => tryListModernMCPTools(agent.agent_uri, readAuthToken, this.normalizedAgent.headers, {
|
|
2493
4030
|
authProvider,
|
|
2494
4031
|
signal: options?.signal,
|
|
2495
|
-
requestTimeoutMs: transport?.requestTimeoutMs
|
|
4032
|
+
requestTimeoutMs: transport?.requestTimeoutMs,
|
|
4033
|
+
fetchFn: transport?.fetchFn
|
|
2496
4034
|
})
|
|
2497
4035
|
);
|
|
2498
4036
|
if (modernTools.handled) {
|
|
@@ -2537,9 +4075,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2537
4075
|
}
|
|
2538
4076
|
} else if (this.normalizedAgent.protocol === "a2a") {
|
|
2539
4077
|
const { wrapFetchWithSizeLimit } = await import("../protocols/responseSizeLimit.js");
|
|
2540
|
-
const authToken =
|
|
4078
|
+
const authToken = await ensureReadAuthToken();
|
|
2541
4079
|
const agentHeaders = this.normalizedAgent.headers ?? {};
|
|
2542
|
-
const sizeLimitedFetch = wrapFetchWithSizeLimit(
|
|
4080
|
+
const sizeLimitedFetch = wrapFetchWithSizeLimit(
|
|
4081
|
+
(input, init) => transport?.fetchFn ? transport.fetchFn(input, init) : fetch(input, init)
|
|
4082
|
+
);
|
|
2543
4083
|
const normalizeHeaders = (headers) => {
|
|
2544
4084
|
const normalized = {};
|
|
2545
4085
|
if (!headers) return normalized;
|
|
@@ -2630,7 +4170,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2630
4170
|
*/
|
|
2631
4171
|
async getCapabilities(options) {
|
|
2632
4172
|
(0, import_abort2.throwIfAborted)(options?.signal);
|
|
2633
|
-
|
|
4173
|
+
const discoveryContext = options?.[CAPABILITY_DISCOVERY_CONTEXT];
|
|
4174
|
+
const usesScopedFetch = (options?.transport ?? this.config.transport)?.fetchFn !== void 0;
|
|
4175
|
+
if (!usesScopedFetch && this.cachedCapabilities) {
|
|
4176
|
+
if (discoveryContext) discoveryContext.toolSchemas = this.cachedToolSchemas;
|
|
2634
4177
|
this.maybeWarnV2Sunset(this.cachedCapabilities);
|
|
2635
4178
|
return this.cachedCapabilities;
|
|
2636
4179
|
}
|
|
@@ -2639,10 +4182,14 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2639
4182
|
name: t.name,
|
|
2640
4183
|
description: t.description
|
|
2641
4184
|
}));
|
|
2642
|
-
|
|
4185
|
+
const discoveredToolSchemas = new Map(
|
|
2643
4186
|
agentInfo.tools.filter((t) => t.inputSchema?.properties).map((t) => [t.name, t.inputSchema.properties])
|
|
2644
4187
|
);
|
|
2645
|
-
|
|
4188
|
+
if (discoveryContext) discoveryContext.toolSchemas = discoveredToolSchemas;
|
|
4189
|
+
if (!usesScopedFetch) this.cachedToolSchemas = discoveredToolSchemas;
|
|
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;
|
|
2646
4193
|
if (hasCapabilitiesTool) {
|
|
2647
4194
|
try {
|
|
2648
4195
|
const agent = await this.ensureEndpointDiscovered(options);
|
|
@@ -2655,9 +4202,13 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2655
4202
|
throw (0, import_abort2.createTimeoutError)(requestTimeoutMs);
|
|
2656
4203
|
}
|
|
2657
4204
|
if (result.success && result.data) {
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
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");
|
|
2661
4212
|
}
|
|
2662
4213
|
if (result.data && (0, import_capabilities.looksLikeV3Capabilities)(result.data)) {
|
|
2663
4214
|
console.warn(
|
|
@@ -2670,9 +4221,10 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2670
4221
|
version: "v3",
|
|
2671
4222
|
majorVersions: parsed.majorVersions.includes(3) ? parsed.majorVersions : [3]
|
|
2672
4223
|
};
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
4224
|
+
const capabilities2 = (0, import_capabilities.augmentCapabilitiesFromTools)(v3Capabilities, tools);
|
|
4225
|
+
if (!usesScopedFetch) this.cachedCapabilities = capabilities2;
|
|
4226
|
+
this.maybeWarnV2Sunset(capabilities2);
|
|
4227
|
+
return capabilities2;
|
|
2676
4228
|
}
|
|
2677
4229
|
console.warn(
|
|
2678
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.`,
|
|
@@ -2686,19 +4238,25 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
2686
4238
|
if (error instanceof import_errors.AuthenticationRequiredError || error instanceof import_errors.TaskTimeoutError || (0, import_abort.isAbortOrTimeoutError)(error)) {
|
|
2687
4239
|
throw error;
|
|
2688
4240
|
}
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
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;
|
|
2692
4252
|
}
|
|
2693
|
-
this.cachedCapabilities = (0, import_capabilities.augmentCapabilitiesFromTools)((0, import_capabilities.buildSyntheticV3Capabilities)(tools), tools);
|
|
2694
|
-
this.maybeWarnV2Sunset(this.cachedCapabilities);
|
|
2695
|
-
return this.cachedCapabilities;
|
|
2696
4253
|
}
|
|
2697
4254
|
console.warn(
|
|
2698
4255
|
`[AdCP] Agent "${this.agent.id}" detected as v2 (no get_adcp_capabilities tool). Tools: [${tools.map((t) => t.name).join(", ")}]`
|
|
2699
4256
|
);
|
|
2700
|
-
|
|
2701
|
-
|
|
4257
|
+
const capabilities = (0, import_capabilities.buildSyntheticCapabilities)(tools);
|
|
4258
|
+
if (!usesScopedFetch) this.cachedCapabilities = capabilities;
|
|
4259
|
+
return capabilities;
|
|
2702
4260
|
}
|
|
2703
4261
|
/**
|
|
2704
4262
|
* Emit a one-time warning when the agent reports v2 capabilities.
|
|
@@ -3011,38 +4569,18 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3011
4569
|
}
|
|
3012
4570
|
// ====== STATIC HELPER METHODS ======
|
|
3013
4571
|
/**
|
|
3014
|
-
* Query a creative
|
|
4572
|
+
* Query a legacy creative-agent named-format catalog.
|
|
3015
4573
|
*
|
|
3016
|
-
*
|
|
3017
|
-
* (
|
|
3018
|
-
* before creating a media buy.
|
|
4574
|
+
* Canonical applications discover seller-supported declarations through
|
|
4575
|
+
* `AgentClient.getProducts()` and consume `format_options[]` instead.
|
|
3019
4576
|
*
|
|
3020
4577
|
* @param creativeAgentUrl - URL of the creative agent (e.g., 'https://creative.adcontextprotocol.org/mcp')
|
|
3021
4578
|
* @param protocol - Protocol to use ('mcp' or 'a2a'), defaults to 'mcp'
|
|
3022
4579
|
* @returns Promise resolving to the list of available formats
|
|
3023
4580
|
*
|
|
3024
|
-
* @
|
|
3025
|
-
* ```typescript
|
|
3026
|
-
* // Discover formats from the standard creative agent
|
|
3027
|
-
* const formats = await SingleAgentClient.discoverCreativeFormats(
|
|
3028
|
-
* 'https://creative.adcontextprotocol.org/mcp'
|
|
3029
|
-
* );
|
|
3030
|
-
*
|
|
3031
|
-
* // Find a specific format
|
|
3032
|
-
* const banner = formats.find(f => f.format_id.id === 'display_300x250_image');
|
|
3033
|
-
*
|
|
3034
|
-
* // Use the format in a media buy
|
|
3035
|
-
* await salesAgent.createMediaBuy({
|
|
3036
|
-
* packages: [{
|
|
3037
|
-
* format_ids: [{
|
|
3038
|
-
* agent_url: banner.format_id.agent_url,
|
|
3039
|
-
* id: banner.format_id.id
|
|
3040
|
-
* }]
|
|
3041
|
-
* }]
|
|
3042
|
-
* });
|
|
3043
|
-
* ```
|
|
4581
|
+
* @deprecated Migration-only helper for the legacy named-format protocol.
|
|
3044
4582
|
*/
|
|
3045
|
-
static async
|
|
4583
|
+
static async discoverCreativeFormatsLegacy(creativeAgentUrl, protocol = "mcp") {
|
|
3046
4584
|
const client = new SingleAgentClient(
|
|
3047
4585
|
{
|
|
3048
4586
|
id: "creative_agent_discovery",
|
|
@@ -3052,7 +4590,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
|
|
|
3052
4590
|
},
|
|
3053
4591
|
{}
|
|
3054
4592
|
);
|
|
3055
|
-
const result = await client.
|
|
4593
|
+
const result = await client.listCreativeFormatsLegacy({});
|
|
3056
4594
|
if (!result.success || !result.data) {
|
|
3057
4595
|
throw new Error(`Failed to discover creative formats: ${result.error || "Unknown error"}`);
|
|
3058
4596
|
}
|
|
@@ -3132,12 +4670,11 @@ function parseWebhookBody(value) {
|
|
|
3132
4670
|
const raw = Buffer.isBuffer(value) || value instanceof Uint8Array ? Buffer.from(value).toString("utf8") : value;
|
|
3133
4671
|
try {
|
|
3134
4672
|
return { ok: true, payload: JSON.parse(raw) };
|
|
3135
|
-
} catch
|
|
4673
|
+
} catch {
|
|
3136
4674
|
return {
|
|
3137
4675
|
ok: false,
|
|
3138
4676
|
code: "webhook_envelope_invalid",
|
|
3139
|
-
message: "Webhook body must be valid JSON."
|
|
3140
|
-
cause: error
|
|
4677
|
+
message: "Webhook body must be valid JSON."
|
|
3141
4678
|
};
|
|
3142
4679
|
}
|
|
3143
4680
|
}
|
|
@@ -3158,13 +4695,6 @@ function missingMcpWebhookFields(payload) {
|
|
|
3158
4695
|
return typeof value !== "string" || value.length === 0;
|
|
3159
4696
|
});
|
|
3160
4697
|
}
|
|
3161
|
-
function safeJsonPreview(value) {
|
|
3162
|
-
try {
|
|
3163
|
-
return JSON.stringify(value).substring(0, 200);
|
|
3164
|
-
} catch {
|
|
3165
|
-
return "[unserializable payload]";
|
|
3166
|
-
}
|
|
3167
|
-
}
|
|
3168
4698
|
function webhookErrorHttpStatus(error) {
|
|
3169
4699
|
if (error instanceof WebhookDispatchError) {
|
|
3170
4700
|
if (error.code === "webhook_signature_invalid" || error.code === "webhook_timestamp_invalid") {
|