@adcp/sdk 12.1.1 → 13.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -3
- package/bin/adcp-fuzz.js +3 -1
- package/dist/lib/adapters/content-standards-adapter.d.mts +9 -9
- package/dist/lib/adapters/content-standards-adapter.d.ts +9 -9
- package/dist/lib/adapters/content-standards-adapter.d.ts.map +1 -1
- package/dist/lib/adapters/content-standards-adapter.js +22 -22
- package/dist/lib/adapters/content-standards-adapter.js.map +1 -1
- package/dist/lib/adapters/content-standards-adapter.mjs +18 -18
- package/dist/lib/adapters/content-standards-adapter.mjs.map +1 -1
- package/dist/lib/adapters/index.d.mts +2 -2
- package/dist/lib/adapters/index.d.ts +2 -2
- package/dist/lib/adapters/index.d.ts.map +1 -1
- package/dist/lib/adapters/index.js +10 -10
- package/dist/lib/adapters/index.js.map +1 -1
- package/dist/lib/adapters/index.mjs +9 -9
- package/dist/lib/adapters/index.mjs.map +1 -1
- package/dist/lib/auth/oauth/provider-cache.d.mts +7 -0
- package/dist/lib/auth/oauth/provider-cache.d.ts +8 -0
- package/dist/lib/auth/oauth/provider-cache.d.ts.map +1 -0
- package/dist/lib/auth/oauth/provider-cache.js +44 -0
- package/dist/lib/auth/oauth/provider-cache.js.map +1 -0
- package/dist/lib/auth/oauth/provider-cache.mjs +19 -0
- package/dist/lib/auth/oauth/provider-cache.mjs.map +1 -0
- package/dist/lib/conformance/invariants/uniformError.js +1 -1
- package/dist/lib/conformance/invariants/uniformError.js.map +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs +1 -1
- package/dist/lib/conformance/invariants/uniformError.mjs.map +1 -1
- package/dist/lib/conformance/runners.js +1 -1
- package/dist/lib/conformance/runners.js.map +1 -1
- package/dist/lib/conformance/runners.mjs +1 -1
- package/dist/lib/conformance/runners.mjs.map +1 -1
- package/dist/lib/conformance/seeder.js +5 -5
- package/dist/lib/conformance/seeder.js.map +1 -1
- package/dist/lib/conformance/seeder.mjs +5 -5
- package/dist/lib/conformance/seeder.mjs.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.d.mts +26 -29
- package/dist/lib/core/ADCPMultiAgentClient.d.ts +26 -29
- package/dist/lib/core/ADCPMultiAgentClient.d.ts.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.js +27 -19
- package/dist/lib/core/ADCPMultiAgentClient.js.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.mjs +27 -19
- package/dist/lib/core/ADCPMultiAgentClient.mjs.map +1 -1
- package/dist/lib/core/AgentClient.d.mts +148 -138
- package/dist/lib/core/AgentClient.d.ts +148 -138
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/AgentClient.js +174 -85
- package/dist/lib/core/AgentClient.js.map +1 -1
- package/dist/lib/core/AgentClient.mjs +174 -85
- package/dist/lib/core/AgentClient.mjs.map +1 -1
- package/dist/lib/core/AsyncHandler.d.mts +18 -16
- package/dist/lib/core/AsyncHandler.d.ts +18 -16
- package/dist/lib/core/AsyncHandler.d.ts.map +1 -1
- package/dist/lib/core/AsyncHandler.js +22 -1
- package/dist/lib/core/AsyncHandler.js.map +1 -1
- package/dist/lib/core/AsyncHandler.mjs +22 -1
- package/dist/lib/core/AsyncHandler.mjs.map +1 -1
- package/dist/lib/core/ConversationTypes.d.mts +6 -2
- package/dist/lib/core/ConversationTypes.d.ts +6 -2
- package/dist/lib/core/ConversationTypes.d.ts.map +1 -1
- package/dist/lib/core/ConversationTypes.js.map +1 -1
- package/dist/lib/core/CreativeAgentClient.d.mts +41 -17
- package/dist/lib/core/CreativeAgentClient.d.ts +41 -17
- package/dist/lib/core/CreativeAgentClient.d.ts.map +1 -1
- package/dist/lib/core/CreativeAgentClient.js +39 -12
- package/dist/lib/core/CreativeAgentClient.js.map +1 -1
- package/dist/lib/core/CreativeAgentClient.mjs +39 -12
- package/dist/lib/core/CreativeAgentClient.mjs.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +127 -50
- package/dist/lib/core/SingleAgentClient.d.ts +127 -50
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +1617 -177
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +1627 -177
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/core/TaskExecutor.d.mts +9 -0
- package/dist/lib/core/TaskExecutor.d.ts +9 -0
- package/dist/lib/core/TaskExecutor.d.ts.map +1 -1
- package/dist/lib/core/TaskExecutor.js +136 -43
- package/dist/lib/core/TaskExecutor.js.map +1 -1
- package/dist/lib/core/TaskExecutor.mjs +136 -43
- package/dist/lib/core/TaskExecutor.mjs.map +1 -1
- package/dist/lib/index.d.mts +111 -17
- package/dist/lib/index.d.ts +111 -17
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +94 -94
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +93 -94
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/protocols/index.d.ts.map +1 -1
- package/dist/lib/protocols/index.js +6 -15
- package/dist/lib/protocols/index.js.map +1 -1
- package/dist/lib/protocols/index.mjs +6 -16
- package/dist/lib/protocols/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-modern.js +87 -12
- package/dist/lib/protocols/mcp-modern.js.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +89 -12
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +6 -0
- package/dist/lib/server/create-adcp-server.d.ts +6 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +295 -48
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +301 -50
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.d.mts +27 -13
- package/dist/lib/server/decisioning/assembly-helpers.d.ts +27 -13
- package/dist/lib/server/decisioning/assembly-helpers.d.ts.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.js +136 -14
- package/dist/lib/server/decisioning/assembly-helpers.js.map +1 -1
- package/dist/lib/server/decisioning/assembly-helpers.mjs +134 -13
- package/dist/lib/server/decisioning/assembly-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.d.mts +13 -12
- package/dist/lib/server/decisioning/index.d.ts +13 -12
- package/dist/lib/server/decisioning/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.js +6 -0
- package/dist/lib/server/decisioning/index.js.map +1 -1
- package/dist/lib/server/decisioning/index.mjs +9 -3
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.d.mts +13 -3
- package/dist/lib/server/decisioning/list-helpers.d.ts +13 -3
- package/dist/lib/server/decisioning/list-helpers.d.ts.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.js +13 -3
- package/dist/lib/server/decisioning/list-helpers.js.map +1 -1
- package/dist/lib/server/decisioning/list-helpers.mjs +11 -2
- package/dist/lib/server/decisioning/list-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.d.mts +5 -3
- package/dist/lib/server/decisioning/manifest-helpers.d.ts +5 -3
- package/dist/lib/server/decisioning/manifest-helpers.d.ts.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.js.map +1 -1
- package/dist/lib/server/decisioning/manifest-helpers.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/dispatch.d.mts +2 -2
- package/dist/lib/server/decisioning/proposal/dispatch.d.ts +2 -2
- package/dist/lib/server/decisioning/proposal/dispatch.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/dispatch.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/dispatch.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.d.mts +1 -1
- package/dist/lib/server/decisioning/proposal/index.d.ts +1 -1
- package/dist/lib/server/decisioning/proposal/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.d.mts +3 -2
- package/dist/lib/server/decisioning/proposal/lifecycle.d.ts +3 -2
- package/dist/lib/server/decisioning/proposal/lifecycle.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/lifecycle.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.d.mts +3 -3
- package/dist/lib/server/decisioning/proposal/mock-manager.d.ts +3 -3
- package/dist/lib/server/decisioning/proposal/mock-manager.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/mock-manager.mjs.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.d.mts +10 -6
- package/dist/lib/server/decisioning/proposal/types.d.ts +10 -6
- package/dist/lib/server/decisioning/proposal/types.d.ts.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.js.map +1 -1
- package/dist/lib/server/decisioning/proposal/types.mjs.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +21 -2
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +21 -2
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +754 -81
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +763 -81
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/brand-rights.d.mts +9 -9
- package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts +9 -9
- package/dist/lib/server/decisioning/specialisms/brand-rights.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/brand-rights.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/content-standards.d.mts +16 -16
- package/dist/lib/server/decisioning/specialisms/content-standards.d.ts +16 -16
- package/dist/lib/server/decisioning/specialisms/content-standards.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/content-standards.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.mts +15 -13
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts +15 -13
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative-ad-server.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative.d.mts +12 -11
- package/dist/lib/server/decisioning/specialisms/creative.d.ts +12 -11
- package/dist/lib/server/decisioning/specialisms/creative.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/creative.js.map +1 -1
- package/dist/lib/server/decisioning/specialisms/sales.d.mts +25 -15
- package/dist/lib/server/decisioning/specialisms/sales.d.ts +25 -15
- package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -1
- package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -1
- package/dist/lib/server/index.d.mts +3 -3
- package/dist/lib/server/index.d.ts +3 -3
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +72 -72
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs +36 -36
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/legacy/v5/index.d.mts +1 -0
- package/dist/lib/server/legacy/v5/index.d.ts +1 -0
- package/dist/lib/server/legacy/v5/index.d.ts.map +1 -1
- package/dist/lib/server/legacy/v5/index.js +74 -1
- package/dist/lib/server/legacy/v5/index.js.map +1 -1
- package/dist/lib/server/legacy/v5/index.mjs +75 -1
- package/dist/lib/server/legacy/v5/index.mjs.map +1 -1
- package/dist/lib/server/responses.d.mts +2 -2
- package/dist/lib/server/responses.d.ts +2 -2
- package/dist/lib/server/responses.js.map +1 -1
- package/dist/lib/server/responses.mjs.map +1 -1
- package/dist/lib/testing/client.js +1 -1
- package/dist/lib/testing/client.js.map +1 -1
- package/dist/lib/testing/client.mjs +1 -1
- package/dist/lib/testing/client.mjs.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.js +6 -6
- package/dist/lib/testing/scenarios/brand-rights.js.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.mjs +6 -6
- package/dist/lib/testing/scenarios/brand-rights.mjs.map +1 -1
- package/dist/lib/testing/scenarios/creative.js +7 -7
- package/dist/lib/testing/scenarios/creative.js.map +1 -1
- package/dist/lib/testing/scenarios/creative.mjs +7 -7
- package/dist/lib/testing/scenarios/creative.mjs.map +1 -1
- package/dist/lib/testing/scenarios/discovery.js +2 -2
- package/dist/lib/testing/scenarios/discovery.js.map +1 -1
- package/dist/lib/testing/scenarios/discovery.mjs +2 -2
- package/dist/lib/testing/scenarios/discovery.mjs.map +1 -1
- package/dist/lib/testing/scenarios/edge-cases.js +11 -11
- package/dist/lib/testing/scenarios/edge-cases.js.map +1 -1
- package/dist/lib/testing/scenarios/edge-cases.mjs +11 -11
- package/dist/lib/testing/scenarios/edge-cases.mjs.map +1 -1
- package/dist/lib/testing/scenarios/governance.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/governance.js +16 -22
- package/dist/lib/testing/scenarios/governance.js.map +1 -1
- package/dist/lib/testing/scenarios/governance.mjs +16 -22
- package/dist/lib/testing/scenarios/governance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.js +5 -5
- package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.mjs +5 -5
- package/dist/lib/testing/scenarios/media-buy.mjs.map +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.js +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.js.map +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.mjs +1 -1
- package/dist/lib/testing/scenarios/schema-compliance.mjs.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.js +4 -3
- package/dist/lib/testing/scenarios/trusted-match.js.map +1 -1
- package/dist/lib/testing/scenarios/trusted-match.mjs +4 -3
- package/dist/lib/testing/scenarios/trusted-match.mjs.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.d.mts +3 -4
- package/dist/lib/testing/storyboard/shape-drift-hints.d.ts +3 -4
- package/dist/lib/testing/storyboard/shape-drift-hints.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.js +27 -27
- package/dist/lib/testing/storyboard/shape-drift-hints.js.map +1 -1
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs +27 -27
- package/dist/lib/testing/storyboard/shape-drift-hints.mjs.map +1 -1
- package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/task-map.js +43 -5
- package/dist/lib/testing/storyboard/task-map.js.map +1 -1
- package/dist/lib/testing/storyboard/task-map.mjs +43 -5
- package/dist/lib/testing/storyboard/task-map.mjs.map +1 -1
- package/dist/lib/testing/test-helpers.d.mts +2 -2
- package/dist/lib/testing/test-helpers.d.ts +2 -2
- package/dist/lib/testing/test-helpers.js.map +1 -1
- package/dist/lib/testing/test-helpers.mjs.map +1 -1
- package/dist/lib/types/adcp.d.mts +14 -14
- package/dist/lib/types/adcp.d.ts +14 -14
- package/dist/lib/types/adcp.d.ts.map +1 -1
- package/dist/lib/types/adcp.js.map +1 -1
- package/dist/lib/types/adcp.mjs.map +1 -1
- package/dist/lib/types/index.d.mts +2 -2
- package/dist/lib/types/index.d.ts +2 -2
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/types/index.js.map +1 -1
- package/dist/lib/types/index.mjs.map +1 -1
- package/dist/lib/utils/capabilities.d.mts +6 -0
- package/dist/lib/utils/capabilities.d.ts +6 -0
- package/dist/lib/utils/capabilities.d.ts.map +1 -1
- package/dist/lib/utils/capabilities.js +4 -0
- package/dist/lib/utils/capabilities.js.map +1 -1
- package/dist/lib/utils/capabilities.mjs +4 -0
- package/dist/lib/utils/capabilities.mjs.map +1 -1
- package/dist/lib/utils/creative-delivery.d.mts +52 -10
- package/dist/lib/utils/creative-delivery.d.ts +52 -10
- package/dist/lib/utils/creative-delivery.d.ts.map +1 -1
- package/dist/lib/utils/creative-delivery.js +104 -9
- package/dist/lib/utils/creative-delivery.js.map +1 -1
- package/dist/lib/utils/creative-delivery.mjs +104 -8
- package/dist/lib/utils/creative-delivery.mjs.map +1 -1
- package/dist/lib/utils/format-assets.d.mts +41 -38
- package/dist/lib/utils/format-assets.d.ts +41 -38
- package/dist/lib/utils/format-assets.d.ts.map +1 -1
- package/dist/lib/utils/format-assets.js +3 -1
- package/dist/lib/utils/format-assets.js.map +1 -1
- package/dist/lib/utils/format-assets.mjs +3 -1
- package/dist/lib/utils/format-assets.mjs.map +1 -1
- package/dist/lib/utils/index.d.mts +8 -8
- package/dist/lib/utils/index.d.ts +8 -8
- package/dist/lib/utils/index.d.ts.map +1 -1
- package/dist/lib/utils/index.js +11 -9
- package/dist/lib/utils/index.js.map +1 -1
- package/dist/lib/utils/index.mjs +9 -8
- package/dist/lib/utils/index.mjs.map +1 -1
- package/dist/lib/utils/preview-utils.d.mts +11 -8
- package/dist/lib/utils/preview-utils.d.ts +11 -8
- package/dist/lib/utils/preview-utils.d.ts.map +1 -1
- package/dist/lib/utils/preview-utils.js +4 -4
- package/dist/lib/utils/preview-utils.js.map +1 -1
- package/dist/lib/utils/preview-utils.mjs +3 -3
- package/dist/lib/utils/preview-utils.mjs.map +1 -1
- package/dist/lib/utils/tool-request-schemas.d.mts +2 -2
- package/dist/lib/utils/tool-request-schemas.d.ts +2 -2
- package/dist/lib/v2/projection/aao-reference-formats.json +492 -0
- package/dist/lib/v2/projection/augment-response.d.mts +31 -11
- package/dist/lib/v2/projection/augment-response.d.ts +31 -11
- package/dist/lib/v2/projection/augment-response.d.ts.map +1 -1
- package/dist/lib/v2/projection/augment-response.js +233 -27
- package/dist/lib/v2/projection/augment-response.js.map +1 -1
- package/dist/lib/v2/projection/augment-response.mjs +232 -27
- package/dist/lib/v2/projection/augment-response.mjs.map +1 -1
- package/dist/lib/v2/projection/builders.d.mts +7 -6
- package/dist/lib/v2/projection/builders.d.ts +7 -6
- package/dist/lib/v2/projection/builders.d.ts.map +1 -1
- package/dist/lib/v2/projection/builders.js +11 -8
- package/dist/lib/v2/projection/builders.js.map +1 -1
- package/dist/lib/v2/projection/builders.mjs +9 -6
- package/dist/lib/v2/projection/builders.mjs.map +1 -1
- package/dist/lib/v2/projection/catalog-snapshot.d.mts +47 -0
- package/dist/lib/v2/projection/catalog-snapshot.d.ts +48 -0
- package/dist/lib/v2/projection/catalog-snapshot.d.ts.map +1 -0
- package/dist/lib/v2/projection/catalog-snapshot.js +291 -0
- package/dist/lib/v2/projection/catalog-snapshot.js.map +1 -0
- package/dist/lib/v2/projection/catalog-snapshot.mjs +265 -0
- package/dist/lib/v2/projection/catalog-snapshot.mjs.map +1 -0
- package/dist/lib/v2/projection/catalog.d.mts +23 -2
- package/dist/lib/v2/projection/catalog.d.ts +23 -2
- package/dist/lib/v2/projection/catalog.d.ts.map +1 -1
- package/dist/lib/v2/projection/catalog.js +34 -10
- package/dist/lib/v2/projection/catalog.js.map +1 -1
- package/dist/lib/v2/projection/catalog.mjs +33 -10
- package/dist/lib/v2/projection/catalog.mjs.map +1 -1
- package/dist/lib/v2/projection/creative-delivery.d.mts +157 -0
- package/dist/lib/v2/projection/creative-delivery.d.ts +158 -0
- package/dist/lib/v2/projection/creative-delivery.d.ts.map +1 -0
- package/dist/lib/v2/projection/creative-delivery.js +967 -0
- package/dist/lib/v2/projection/creative-delivery.js.map +1 -0
- package/dist/lib/v2/projection/creative-delivery.mjs +941 -0
- package/dist/lib/v2/projection/creative-delivery.mjs.map +1 -0
- package/dist/lib/v2/projection/index.d.mts +8 -6
- package/dist/lib/v2/projection/index.d.ts +8 -6
- package/dist/lib/v2/projection/index.d.ts.map +1 -1
- package/dist/lib/v2/projection/index.js +26 -4
- package/dist/lib/v2/projection/index.js.map +1 -1
- package/dist/lib/v2/projection/index.mjs +28 -4
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/v2/projection/legacy-metadata.d.mts +21 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +22 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts.map +1 -0
- package/dist/lib/v2/projection/legacy-metadata.js +73 -0
- package/dist/lib/v2/projection/legacy-metadata.js.map +1 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs +45 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs.map +1 -0
- package/dist/lib/v2/projection/types.d.mts +29 -23
- package/dist/lib/v2/projection/types.d.ts +29 -23
- package/dist/lib/v2/projection/types.d.ts.map +1 -1
- package/dist/lib/v2/projection/types.js.map +1 -1
- package/dist/lib/v2/projection/v1-to-v2.d.mts +29 -6
- package/dist/lib/v2/projection/v1-to-v2.d.ts +29 -6
- package/dist/lib/v2/projection/v1-to-v2.d.ts.map +1 -1
- package/dist/lib/v2/projection/v1-to-v2.js +218 -9
- package/dist/lib/v2/projection/v1-to-v2.js.map +1 -1
- package/dist/lib/v2/projection/v1-to-v2.mjs +219 -10
- package/dist/lib/v2/projection/v1-to-v2.mjs.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.d.mts +31 -2
- package/dist/lib/v2/projection/v2-to-v1.d.ts +31 -2
- package/dist/lib/v2/projection/v2-to-v1.d.ts.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.js +138 -7
- package/dist/lib/v2/projection/v2-to-v1.js.map +1 -1
- package/dist/lib/v2/projection/v2-to-v1.mjs +135 -6
- package/dist/lib/v2/projection/v2-to-v1.mjs.map +1 -1
- package/dist/lib/v2/projection/write-side.d.mts +12 -13
- package/dist/lib/v2/projection/write-side.d.ts +12 -13
- package/dist/lib/v2/projection/write-side.d.ts.map +1 -1
- package/dist/lib/v2/projection/write-side.js +16 -12
- package/dist/lib/v2/projection/write-side.js.map +1 -1
- package/dist/lib/v2/projection/write-side.mjs +16 -12
- package/dist/lib/v2/projection/write-side.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/guides/BUILD-AN-AGENT.md +7 -2
- package/docs/guides/PREVIEW-ASSET-DURABILITY.md +6 -2
- package/docs/llms.txt +1 -0
- package/examples/README.md +1 -1
- package/examples/batch-preview-test.ts +3 -3
- package/examples/conversation-client.ts +2 -2
- package/examples/debug-preview-response.ts +1 -1
- package/examples/decisioning-platform-broadcast-tv.ts +10 -4
- package/examples/decisioning-platform-mock-seller.ts +16 -9
- package/examples/decisioning-platform-programmatic.ts +18 -7
- package/examples/error-compliant-server.ts +26 -16
- package/examples/generative-creative-demo.ts +7 -19
- package/examples/hello_creative_adapter_ad_server.ts +37 -16
- package/examples/hello_creative_adapter_template.ts +12 -10
- package/examples/hello_seller_adapter_guaranteed.ts +52 -23
- package/examples/hello_seller_adapter_multi_tenant.ts +6 -3
- package/examples/hello_seller_adapter_non_guaranteed.ts +54 -26
- package/examples/hello_seller_adapter_proposal_mode.ts +40 -14
- package/examples/hello_seller_adapter_social.ts +2 -7
- package/examples/inspect-card-formats.ts +1 -1
- package/examples/simple-getting-started.ts +1 -1
- package/examples/test-helpers-demo.ts +1 -1
- package/package.json +2 -2
- package/skills/build-decisioning-creative-template/SKILL.md +11 -11
- package/skills/build-decisioning-platform/advanced/REFERENCE.md +8 -2
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
const HELPER_MIN_VERSION = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
2
|
+
legacyBuildCreativeResponse: "13.0.0",
|
|
3
|
+
legacyListCreativesResponse: "13.0.0",
|
|
4
|
+
legacyListCreativeFormatsResponse: "13.0.0",
|
|
5
|
+
legacyListAccountsResponse: "13.0.0",
|
|
6
|
+
legacyProductsResponse: "13.0.0",
|
|
7
|
+
legacyGetMediaBuysResponse: "13.0.0",
|
|
8
|
+
legacyGetSignalsResponse: "13.0.0",
|
|
9
|
+
legacyListPropertyListsResponse: "13.0.0",
|
|
10
|
+
legacyListCollectionListsResponse: "13.0.0",
|
|
11
|
+
legacyListContentStandardsResponse: "13.0.0",
|
|
12
|
+
legacyGetPlanAuditLogsResponse: "13.0.0",
|
|
13
|
+
legacySyncCreativesResponse: "13.0.0",
|
|
14
|
+
legacyPreviewCreativeResponse: "13.0.0"
|
|
15
15
|
};
|
|
16
16
|
function semverLessThan(a, b) {
|
|
17
17
|
const normalize = (v) => v.replace(/^.*@/, "").replace(/-.*$/, "");
|
|
@@ -23,16 +23,16 @@ function semverLessThan(a, b) {
|
|
|
23
23
|
return aPatch < bPatch;
|
|
24
24
|
}
|
|
25
25
|
const LIST_WRAPPER_TOOLS = {
|
|
26
|
-
list_creatives: { wrapperKey: "creatives", helper: "
|
|
27
|
-
list_creative_formats: { wrapperKey: "formats", helper: "
|
|
28
|
-
list_accounts: { wrapperKey: "accounts", helper: "
|
|
29
|
-
get_products: { wrapperKey: "products", helper: "
|
|
30
|
-
get_media_buys: { wrapperKey: "media_buys", helper: "
|
|
31
|
-
get_signals: { wrapperKey: "signals", helper: "
|
|
32
|
-
list_property_lists: { wrapperKey: "lists", helper: "
|
|
33
|
-
list_collection_lists: { wrapperKey: "lists", helper: "
|
|
34
|
-
list_content_standards: { wrapperKey: "standards", helper: "
|
|
35
|
-
get_plan_audit_logs: { wrapperKey: "plans", helper: "
|
|
26
|
+
list_creatives: { wrapperKey: "creatives", helper: "legacyListCreativesResponse" },
|
|
27
|
+
list_creative_formats: { wrapperKey: "formats", helper: "legacyListCreativeFormatsResponse" },
|
|
28
|
+
list_accounts: { wrapperKey: "accounts", helper: "legacyListAccountsResponse" },
|
|
29
|
+
get_products: { wrapperKey: "products", helper: "legacyProductsResponse" },
|
|
30
|
+
get_media_buys: { wrapperKey: "media_buys", helper: "legacyGetMediaBuysResponse" },
|
|
31
|
+
get_signals: { wrapperKey: "signals", helper: "legacyGetSignalsResponse" },
|
|
32
|
+
list_property_lists: { wrapperKey: "lists", helper: "legacyListPropertyListsResponse" },
|
|
33
|
+
list_collection_lists: { wrapperKey: "lists", helper: "legacyListCollectionListsResponse" },
|
|
34
|
+
list_content_standards: { wrapperKey: "standards", helper: "legacyListContentStandardsResponse" },
|
|
35
|
+
get_plan_audit_logs: { wrapperKey: "plans", helper: "legacyGetPlanAuditLogsResponse" }
|
|
36
36
|
};
|
|
37
37
|
function detectShapeDriftHints(taskName, payload, libraryVersion) {
|
|
38
38
|
const hint = detect(taskName, payload);
|
|
@@ -76,7 +76,7 @@ function detect(taskName, payload) {
|
|
|
76
76
|
observed_variant: "platform_native_fields",
|
|
77
77
|
expected_variant: "{ creative_manifest: { format_id, assets } }",
|
|
78
78
|
instance_path: "",
|
|
79
|
-
message: `build_creative returned platform-native fields at the top level (${platformNativePresent.join(", ")}). Required: { creative_manifest: { format_id, assets } }. Use
|
|
79
|
+
message: `build_creative returned platform-native fields at the top level (${platformNativePresent.join(", ")}). Required: { creative_manifest: { format_id, assets } }. Use legacyBuildCreativeResponse() from @adcp/sdk/server.`
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -91,7 +91,7 @@ function detect(taskName, payload) {
|
|
|
91
91
|
observed_variant: "per_item_shape",
|
|
92
92
|
expected_variant: "{ creatives: [{ creative_id, action, ... }] }",
|
|
93
93
|
instance_path: "",
|
|
94
|
-
message: `sync_creatives returned a single creative's inner shape at the top level (${perItemPresent.join(", ")}). Required: { creatives: [{ creative_id, action, ... }] } (or { errors: [...] } / { status: 'submitted', task_id }). Use
|
|
94
|
+
message: `sync_creatives returned a single creative's inner shape at the top level (${perItemPresent.join(", ")}). Required: { creatives: [{ creative_id, action, ... }] } (or { errors: [...] } / { status: 'submitted', task_id }). Use legacySyncCreativesResponse() from @adcp/sdk/server.`
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
const results = p.results;
|
|
@@ -105,7 +105,7 @@ function detect(taskName, payload) {
|
|
|
105
105
|
observed_variant: "wrong_wrapper_key",
|
|
106
106
|
expected_variant: "{ creatives: [{ creative_id, action, ... }] }",
|
|
107
107
|
instance_path: "/results",
|
|
108
|
-
message: `sync_creatives returned { results: [...] } instead of { creatives: [...] } \u2014 wrong wrapper key. Required: { creatives: [{ creative_id, action, ... }] }. Use
|
|
108
|
+
message: `sync_creatives returned { results: [...] } instead of { creatives: [...] } \u2014 wrong wrapper key. Required: { creatives: [{ creative_id, action, ... }] }. Use legacySyncCreativesResponse() from @adcp/sdk/server.`
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -122,7 +122,7 @@ function detect(taskName, payload) {
|
|
|
122
122
|
observed_variant: "raw_render_fields",
|
|
123
123
|
expected_variant: "{ response_type: 'single', previews: [{ renders: [...] }], expires_at }",
|
|
124
124
|
instance_path: "",
|
|
125
|
-
message: `preview_creative returned raw render fields at the top level (${driftSignal.join(", ")}). Required: { response_type: 'single', previews: [{ renders: [{ preview_url | preview_html }] }], expires_at }. Use
|
|
125
|
+
message: `preview_creative returned raw render fields at the top level (${driftSignal.join(", ")}). Required: { response_type: 'single', previews: [{ renders: [{ preview_url | preview_html }] }], expires_at }. Use legacyPreviewCreativeResponse() from @adcp/sdk/server.`
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/shape-drift-hints.ts"],"sourcesContent":["/**\n * Structured shape-drift hint detection (issue #935).\n *\n * The runner emits one `ShapeDriftHint` per response when it recognizes a\n * common payload-shape mistake — bare arrays from list tools, platform-\n * native fields from `build_creative`, missing wrappers on `sync_creatives`\n * / `preview_creative`. Each hint carries the same prose the legacy\n * `detectShapeDriftHint` returned, plus structured fields (`tool`,\n * `observed_variant`, `expected_variant`, `instance_path`) so renderers\n * (CLI, Addie, JUnit, SARIF) can build per-case fix plans without re-\n * parsing the message.\n *\n * The string-only `detectShapeDriftHint` in `validations.ts` is a thin\n * shim over this detector — kept so existing unit tests and external\n * callers keep working, but the canonical path is structured.\n *\n * Fires unconditionally (regardless of step pass/fail) — same gate as\n * `ValidationResult.warning` carried previously. The caller (`runner.ts`)\n * merges the result into `StoryboardStepResult.hints[]`.\n */\nimport type { ShapeDriftHint } from './types';\n\n/**\n * Minimum @adcp/client version in which each server-side helper first shipped.\n * Used to suffix shape-drift hints when the agent reports an older SDK version.\n * Keys match the helper name referenced in the hint `message`.\n */\nconst HELPER_MIN_VERSION: Record<string, string> = {\n buildCreativeResponse: '5.14.0',\n listCreativesResponse: '5.10.0',\n listCreativeFormatsResponse: '5.10.0',\n listAccountsResponse: '5.10.0',\n productsResponse: '5.10.0',\n getMediaBuysResponse: '5.10.0',\n getSignalsResponse: '5.10.0',\n listPropertyListsResponse: '5.10.0',\n listCollectionListsResponse: '5.10.0',\n listContentStandardsResponse: '5.10.0',\n getPlanAuditLogsResponse: '5.10.0',\n syncCreativesResponse: '5.10.0',\n previewCreativeResponse: '5.10.0',\n};\n\n/**\n * Compare two semver strings using numeric segment ordering.\n * Returns true when `a` is strictly less than `b`.\n * Handles `@adcp/client@X.Y.Z` format by stripping the package prefix.\n */\nfunction semverLessThan(a: string, b: string): boolean {\n // Strip package prefix (e.g. \"@adcp/client@\") and pre-release suffix (e.g. \"-beta.1\")\n const normalize = (v: string) => v.replace(/^.*@/, '').replace(/-.*$/, '');\n const segs = (v: string) =>\n normalize(v)\n .split('.')\n .map(s => parseInt(s, 10) || 0);\n const [aMaj = 0, aMin = 0, aPatch = 0] = segs(a);\n const [bMaj = 0, bMin = 0, bPatch = 0] = segs(b);\n if (aMaj !== bMaj) return aMaj < bMaj;\n if (aMin !== bMin) return aMin < bMin;\n return aPatch < bPatch;\n}\n\n/**\n * List-shaped tools where handlers commonly return the bare inner array\n * (`[{...}]`) at the top level instead of wrapping it in the required\n * object envelope. Each entry names the wrapper key and the response\n * helper that builds the correct shape.\n *\n * Helper names aren't uniformly prefixed — `get_products` uses\n * `productsResponse` (no `get` prefix) while `get_media_buys` uses\n * `getMediaBuysResponse`. Names match the exports in\n * `src/lib/server/responses.ts` verbatim so a developer can grep\n * straight from the hint.\n */\nexport const LIST_WRAPPER_TOOLS: Record<string, { wrapperKey: string; helper: string }> = {\n list_creatives: { wrapperKey: 'creatives', helper: 'listCreativesResponse' },\n list_creative_formats: { wrapperKey: 'formats', helper: 'listCreativeFormatsResponse' },\n list_accounts: { wrapperKey: 'accounts', helper: 'listAccountsResponse' },\n get_products: { wrapperKey: 'products', helper: 'productsResponse' },\n get_media_buys: { wrapperKey: 'media_buys', helper: 'getMediaBuysResponse' },\n get_signals: { wrapperKey: 'signals', helper: 'getSignalsResponse' },\n list_property_lists: { wrapperKey: 'lists', helper: 'listPropertyListsResponse' },\n list_collection_lists: { wrapperKey: 'lists', helper: 'listCollectionListsResponse' },\n list_content_standards: { wrapperKey: 'standards', helper: 'listContentStandardsResponse' },\n get_plan_audit_logs: { wrapperKey: 'plans', helper: 'getPlanAuditLogsResponse' },\n};\n\n/**\n * Detect shape-drift and return the structured hints that apply (zero or\n * one — the detector emits at most one hint per response, but returns an\n * array so callers can spread it into `step.hints[]` without a guard).\n *\n * @param taskName — tool name (snake_case) the storyboard dispatched under\n * @param payload — raw response payload, after the runner's `_message`\n * pre-strip. `unknown` rather than `Record<string, unknown>` so bare-\n * array payloads are recognizable at the top level; object branches\n * guard internally.\n * @param libraryVersion — optional SDK version string the agent self-reported\n * in `get_adcp_capabilities` (e.g. `\"@adcp/client@4.16.2\"`). When present\n * and below the helper's minimum version, the hint message is suffixed with\n * an upgrade note so developers know to update their SDK dep.\n */\nexport function detectShapeDriftHints(taskName: string, payload: unknown, libraryVersion?: string): ShapeDriftHint[] {\n const hint = detect(taskName, payload);\n if (!hint) return [];\n if (libraryVersion) hint.message = appendVersionSuffix(hint.message, libraryVersion);\n return [hint];\n}\n\n/**\n * If the hint message references a helper that requires a minimum SDK\n * version and the agent's reported version is below it, append an upgrade\n * note to the message. Returns the message unchanged if no version data or\n * no match.\n */\nfunction appendVersionSuffix(message: string, libraryVersion: string): string {\n // Skip non-numeric version strings (e.g. \"local-dev\") to avoid spurious suffixes\n const stripped = libraryVersion.replace(/^.*@/, '').replace(/-.*$/, '');\n if (!/^\\d+\\.\\d+/.test(stripped)) return message;\n for (const [helper, minVersion] of Object.entries(HELPER_MIN_VERSION)) {\n if (message.includes(helper) && semverLessThan(libraryVersion, minVersion)) {\n return (\n message +\n ` (Note: your agent reports ${libraryVersion} — ${helper}() ships in @adcp/client ≥${minVersion}. Upgrade your SDK dep.)`\n );\n }\n }\n return message;\n}\n\nfunction detect(taskName: string, payload: unknown): ShapeDriftHint | undefined {\n if (Array.isArray(payload)) {\n const listMeta = LIST_WRAPPER_TOOLS[taskName];\n if (!listMeta) return undefined;\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'bare_array',\n expected_variant: `{ ${listMeta.wrapperKey}: [...] }`,\n instance_path: '',\n message:\n `${taskName} returned a bare array at the top level. ` +\n `Required: { ${listMeta.wrapperKey}: [...] }. ` +\n `Use ${listMeta.helper}() from @adcp/sdk/server.`,\n };\n }\n\n if (typeof payload !== 'object' || payload === null) return undefined;\n const p = payload as Record<string, unknown>;\n\n if (taskName === 'build_creative') {\n const hasManifest = 'creative_manifest' in p || 'creative_manifests' in p;\n const platformNativeKeys = ['tag_url', 'creative_id', 'media_type', 'tag_type'];\n const platformNativePresent = platformNativeKeys.filter(k => k in p);\n if (!hasManifest && platformNativePresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'platform_native_fields',\n expected_variant: '{ creative_manifest: { format_id, assets } }',\n instance_path: '',\n message:\n `build_creative returned platform-native fields at the top level (${platformNativePresent.join(', ')}). ` +\n `Required: { creative_manifest: { format_id, assets } }. ` +\n `Use buildCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n if (taskName === 'sync_creatives') {\n const hasValidWrapper = 'creatives' in p || 'errors' in p || 'task_id' in p;\n const perItemKeys = ['creative_id', 'platform_id', 'action'];\n const perItemPresent = perItemKeys.filter(k => k in p);\n if (!hasValidWrapper && perItemPresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'per_item_shape',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '',\n message:\n `sync_creatives returned a single creative's inner shape at the top level (${perItemPresent.join(', ')}). ` +\n `Required: { creatives: [{ creative_id, action, ... }] } (or { errors: [...] } / { status: 'submitted', task_id }). ` +\n `Use syncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n\n const results = p.results;\n if (!hasValidWrapper && Array.isArray(results) && results.length > 0) {\n const firstRow = results[0];\n const looksLikeCreativeRow =\n firstRow != null && typeof firstRow === 'object' && ('creative_id' in firstRow || 'action' in firstRow);\n if (looksLikeCreativeRow) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'wrong_wrapper_key',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '/results',\n message:\n `sync_creatives returned { results: [...] } instead of { creatives: [...] } — wrong wrapper key. ` +\n `Required: { creatives: [{ creative_id, action, ... }] }. ` +\n `Use syncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n }\n }\n\n if (taskName === 'preview_creative') {\n const hasValidWrapper = 'response_type' in p || 'previews' in p || 'results' in p;\n const rawRenderKeys = ['preview_url', 'preview_html', 'interactive_url'];\n const rawRenderPresent = rawRenderKeys.filter(k => k in p);\n const driftSignal = rawRenderPresent.filter(k => k !== 'interactive_url');\n if (!hasValidWrapper && driftSignal.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'raw_render_fields',\n expected_variant: \"{ response_type: 'single', previews: [{ renders: [...] }], expires_at }\",\n instance_path: '',\n message:\n `preview_creative returned raw render fields at the top level (${driftSignal.join(', ')}). ` +\n `Required: { response_type: 'single', previews: [{ renders: [{ preview_url | preview_html }] }], expires_at }. ` +\n `Use previewCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/shape-drift-hints.ts"],"sourcesContent":["/**\n * Structured shape-drift hint detection (issue #935).\n *\n * The runner emits one `ShapeDriftHint` per response when it recognizes a\n * common payload-shape mistake — bare arrays from list tools, platform-\n * native fields from `build_creative`, missing wrappers on `sync_creatives`\n * / `preview_creative`. Each hint carries the same prose the legacy\n * `detectShapeDriftHint` returned, plus structured fields (`tool`,\n * `observed_variant`, `expected_variant`, `instance_path`) so renderers\n * (CLI, Addie, JUnit, SARIF) can build per-case fix plans without re-\n * parsing the message.\n *\n * The string-only `detectShapeDriftHint` in `validations.ts` is a thin\n * shim over this detector — kept so existing unit tests and external\n * callers keep working, but the canonical path is structured.\n *\n * Fires unconditionally (regardless of step pass/fail) — same gate as\n * `ValidationResult.warning` carried previously. The caller (`runner.ts`)\n * merges the result into `StoryboardStepResult.hints[]`.\n */\nimport type { ShapeDriftHint } from './types';\n\n/**\n * Minimum @adcp/client version in which each server-side helper first shipped.\n * Used to suffix shape-drift hints when the agent reports an older SDK version.\n * Keys match the helper name referenced in the hint `message`.\n */\nconst HELPER_MIN_VERSION: Record<string, string> = {\n legacyBuildCreativeResponse: '13.0.0',\n legacyListCreativesResponse: '13.0.0',\n legacyListCreativeFormatsResponse: '13.0.0',\n legacyListAccountsResponse: '13.0.0',\n legacyProductsResponse: '13.0.0',\n legacyGetMediaBuysResponse: '13.0.0',\n legacyGetSignalsResponse: '13.0.0',\n legacyListPropertyListsResponse: '13.0.0',\n legacyListCollectionListsResponse: '13.0.0',\n legacyListContentStandardsResponse: '13.0.0',\n legacyGetPlanAuditLogsResponse: '13.0.0',\n legacySyncCreativesResponse: '13.0.0',\n legacyPreviewCreativeResponse: '13.0.0',\n};\n\n/**\n * Compare two semver strings using numeric segment ordering.\n * Returns true when `a` is strictly less than `b`.\n * Handles `@adcp/client@X.Y.Z` format by stripping the package prefix.\n */\nfunction semverLessThan(a: string, b: string): boolean {\n // Strip package prefix (e.g. \"@adcp/client@\") and pre-release suffix (e.g. \"-beta.1\")\n const normalize = (v: string) => v.replace(/^.*@/, '').replace(/-.*$/, '');\n const segs = (v: string) =>\n normalize(v)\n .split('.')\n .map(s => parseInt(s, 10) || 0);\n const [aMaj = 0, aMin = 0, aPatch = 0] = segs(a);\n const [bMaj = 0, bMin = 0, bPatch = 0] = segs(b);\n if (aMaj !== bMaj) return aMaj < bMaj;\n if (aMin !== bMin) return aMin < bMin;\n return aPatch < bPatch;\n}\n\n/**\n * List-shaped tools where handlers commonly return the bare inner array\n * (`[{...}]`) at the top level instead of wrapping it in the required\n * object envelope. Each entry names the wrapper key and the response\n * helper that builds the correct shape.\n *\n * Helper names aren't uniformly prefixed — `get_products` uses\n * `legacyProductsResponse` (no `get` prefix) while `get_media_buys` uses\n * `legacyGetMediaBuysResponse`. Names match the explicit compatibility\n * aliases on `@adcp/sdk/server`.\n */\nexport const LIST_WRAPPER_TOOLS: Record<string, { wrapperKey: string; helper: string }> = {\n list_creatives: { wrapperKey: 'creatives', helper: 'legacyListCreativesResponse' },\n list_creative_formats: { wrapperKey: 'formats', helper: 'legacyListCreativeFormatsResponse' },\n list_accounts: { wrapperKey: 'accounts', helper: 'legacyListAccountsResponse' },\n get_products: { wrapperKey: 'products', helper: 'legacyProductsResponse' },\n get_media_buys: { wrapperKey: 'media_buys', helper: 'legacyGetMediaBuysResponse' },\n get_signals: { wrapperKey: 'signals', helper: 'legacyGetSignalsResponse' },\n list_property_lists: { wrapperKey: 'lists', helper: 'legacyListPropertyListsResponse' },\n list_collection_lists: { wrapperKey: 'lists', helper: 'legacyListCollectionListsResponse' },\n list_content_standards: { wrapperKey: 'standards', helper: 'legacyListContentStandardsResponse' },\n get_plan_audit_logs: { wrapperKey: 'plans', helper: 'legacyGetPlanAuditLogsResponse' },\n};\n\n/**\n * Detect shape-drift and return the structured hints that apply (zero or\n * one — the detector emits at most one hint per response, but returns an\n * array so callers can spread it into `step.hints[]` without a guard).\n *\n * @param taskName — tool name (snake_case) the storyboard dispatched under\n * @param payload — raw response payload, after the runner's `_message`\n * pre-strip. `unknown` rather than `Record<string, unknown>` so bare-\n * array payloads are recognizable at the top level; object branches\n * guard internally.\n * @param libraryVersion — optional SDK version string the agent self-reported\n * in `get_adcp_capabilities` (e.g. `\"@adcp/client@4.16.2\"`). When present\n * and below the helper's minimum version, the hint message is suffixed with\n * an upgrade note so developers know to update their SDK dep.\n */\nexport function detectShapeDriftHints(taskName: string, payload: unknown, libraryVersion?: string): ShapeDriftHint[] {\n const hint = detect(taskName, payload);\n if (!hint) return [];\n if (libraryVersion) hint.message = appendVersionSuffix(hint.message, libraryVersion);\n return [hint];\n}\n\n/**\n * If the hint message references a helper that requires a minimum SDK\n * version and the agent's reported version is below it, append an upgrade\n * note to the message. Returns the message unchanged if no version data or\n * no match.\n */\nfunction appendVersionSuffix(message: string, libraryVersion: string): string {\n // Skip non-numeric version strings (e.g. \"local-dev\") to avoid spurious suffixes\n const stripped = libraryVersion.replace(/^.*@/, '').replace(/-.*$/, '');\n if (!/^\\d+\\.\\d+/.test(stripped)) return message;\n for (const [helper, minVersion] of Object.entries(HELPER_MIN_VERSION)) {\n if (message.includes(helper) && semverLessThan(libraryVersion, minVersion)) {\n return (\n message +\n ` (Note: your agent reports ${libraryVersion} — ${helper}() ships in @adcp/client ≥${minVersion}. Upgrade your SDK dep.)`\n );\n }\n }\n return message;\n}\n\nfunction detect(taskName: string, payload: unknown): ShapeDriftHint | undefined {\n if (Array.isArray(payload)) {\n const listMeta = LIST_WRAPPER_TOOLS[taskName];\n if (!listMeta) return undefined;\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'bare_array',\n expected_variant: `{ ${listMeta.wrapperKey}: [...] }`,\n instance_path: '',\n message:\n `${taskName} returned a bare array at the top level. ` +\n `Required: { ${listMeta.wrapperKey}: [...] }. ` +\n `Use ${listMeta.helper}() from @adcp/sdk/server.`,\n };\n }\n\n if (typeof payload !== 'object' || payload === null) return undefined;\n const p = payload as Record<string, unknown>;\n\n if (taskName === 'build_creative') {\n const hasManifest = 'creative_manifest' in p || 'creative_manifests' in p;\n const platformNativeKeys = ['tag_url', 'creative_id', 'media_type', 'tag_type'];\n const platformNativePresent = platformNativeKeys.filter(k => k in p);\n if (!hasManifest && platformNativePresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'platform_native_fields',\n expected_variant: '{ creative_manifest: { format_id, assets } }',\n instance_path: '',\n message:\n `build_creative returned platform-native fields at the top level (${platformNativePresent.join(', ')}). ` +\n `Required: { creative_manifest: { format_id, assets } }. ` +\n `Use legacyBuildCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n if (taskName === 'sync_creatives') {\n const hasValidWrapper = 'creatives' in p || 'errors' in p || 'task_id' in p;\n const perItemKeys = ['creative_id', 'platform_id', 'action'];\n const perItemPresent = perItemKeys.filter(k => k in p);\n if (!hasValidWrapper && perItemPresent.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'per_item_shape',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '',\n message:\n `sync_creatives returned a single creative's inner shape at the top level (${perItemPresent.join(', ')}). ` +\n `Required: { creatives: [{ creative_id, action, ... }] } (or { errors: [...] } / { status: 'submitted', task_id }). ` +\n `Use legacySyncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n\n const results = p.results;\n if (!hasValidWrapper && Array.isArray(results) && results.length > 0) {\n const firstRow = results[0];\n const looksLikeCreativeRow =\n firstRow != null && typeof firstRow === 'object' && ('creative_id' in firstRow || 'action' in firstRow);\n if (looksLikeCreativeRow) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'wrong_wrapper_key',\n expected_variant: '{ creatives: [{ creative_id, action, ... }] }',\n instance_path: '/results',\n message:\n `sync_creatives returned { results: [...] } instead of { creatives: [...] } — wrong wrapper key. ` +\n `Required: { creatives: [{ creative_id, action, ... }] }. ` +\n `Use legacySyncCreativesResponse() from @adcp/sdk/server.`,\n };\n }\n }\n }\n\n if (taskName === 'preview_creative') {\n const hasValidWrapper = 'response_type' in p || 'previews' in p || 'results' in p;\n const rawRenderKeys = ['preview_url', 'preview_html', 'interactive_url'];\n const rawRenderPresent = rawRenderKeys.filter(k => k in p);\n const driftSignal = rawRenderPresent.filter(k => k !== 'interactive_url');\n if (!hasValidWrapper && driftSignal.length > 0) {\n return {\n kind: 'shape_drift',\n tool: taskName,\n observed_variant: 'raw_render_fields',\n expected_variant: \"{ response_type: 'single', previews: [{ renders: [...] }], expires_at }\",\n instance_path: '',\n message:\n `preview_creative returned raw render fields at the top level (${driftSignal.join(', ')}). ` +\n `Required: { response_type: 'single', previews: [{ renders: [{ preview_url | preview_html }] }], expires_at }. ` +\n `Use legacyPreviewCreativeResponse() from @adcp/sdk/server.`,\n };\n }\n }\n\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-map.d.ts","sourceRoot":"","sources":["../../../../src/lib/testing/storyboard/task-map.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsDjD,CAAC;
|
|
1
|
+
{"version":3,"file":"task-map.d.ts","sourceRoot":"","sources":["../../../../src/lib/testing/storyboard/task-map.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsDjD,CAAC;AAwFF;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAEzC,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,GAAE;IAAE,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACxG,OAAO,CAAC,UAAU,CAAC,CA0FrB"}
|
|
@@ -37,8 +37,8 @@ const TASK_TO_METHOD = {
|
|
|
37
37
|
provide_performance_feedback: "providePerformanceFeedback",
|
|
38
38
|
// Creative
|
|
39
39
|
list_creative_formats: "listCreativeFormats",
|
|
40
|
-
build_creative: "
|
|
41
|
-
preview_creative: "
|
|
40
|
+
build_creative: "buildCreativeLegacy",
|
|
41
|
+
preview_creative: "previewCreativeLegacy",
|
|
42
42
|
sync_creatives: "syncCreatives",
|
|
43
43
|
list_creatives: "listCreatives",
|
|
44
44
|
// Signals
|
|
@@ -71,9 +71,45 @@ const TASK_TO_METHOD = {
|
|
|
71
71
|
si_send_message: "siSendMessage",
|
|
72
72
|
si_terminate_session: "siTerminateSession"
|
|
73
73
|
};
|
|
74
|
+
const LEGACY_CREATIVE_TASK_TO_METHOD = {
|
|
75
|
+
get_products: "getProductsLegacy",
|
|
76
|
+
create_media_buy: "createMediaBuyLegacy",
|
|
77
|
+
update_media_buy: "updateMediaBuyLegacy",
|
|
78
|
+
sync_creatives: "syncCreativesLegacy",
|
|
79
|
+
list_creatives: "listCreativesLegacy"
|
|
80
|
+
};
|
|
81
|
+
function gradesLegacyCreativeWire(client) {
|
|
82
|
+
if (client === null || typeof client !== "object") return false;
|
|
83
|
+
const getAdcpVersion = client.getAdcpVersion;
|
|
84
|
+
if (typeof getAdcpVersion !== "function") return false;
|
|
85
|
+
let version;
|
|
86
|
+
try {
|
|
87
|
+
version = getAdcpVersion.call(client);
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
if (typeof version !== "string") return false;
|
|
92
|
+
const match = /^v?(\d+)(?:\.(\d+))?/.exec(version.trim());
|
|
93
|
+
if (!match) return false;
|
|
94
|
+
const major = Number(match[1]);
|
|
95
|
+
const minor = Number(match[2] ?? 0);
|
|
96
|
+
return major < 3 || major === 3 && minor < 2;
|
|
97
|
+
}
|
|
74
98
|
function isRecord(value) {
|
|
75
99
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
76
100
|
}
|
|
101
|
+
function withLegacyCreativeWireHint(params) {
|
|
102
|
+
const ext = isRecord(params.ext) ? params.ext : {};
|
|
103
|
+
const adcp = isRecord(ext.adcp) ? ext.adcp : {};
|
|
104
|
+
if (adcp.creative_wire === "legacy" || adcp.creative_wire === "canonical") return params;
|
|
105
|
+
return {
|
|
106
|
+
...params,
|
|
107
|
+
ext: {
|
|
108
|
+
...ext,
|
|
109
|
+
adcp: { ...adcp, creative_wire: "legacy" }
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
77
113
|
function readAdcpError(value) {
|
|
78
114
|
if (!isRecord(value)) return void 0;
|
|
79
115
|
const error = value.adcp_error;
|
|
@@ -108,7 +144,9 @@ function normalizeStoryboardTaskSuccess(result, taskName, terminalDataError, adc
|
|
|
108
144
|
return true;
|
|
109
145
|
}
|
|
110
146
|
async function executeStoryboardTask(client, taskName, params, opts = {}) {
|
|
111
|
-
const
|
|
147
|
+
const legacyMethodName = gradesLegacyCreativeWire(client) ? LEGACY_CREATIVE_TASK_TO_METHOD[taskName] : void 0;
|
|
148
|
+
const methodName = legacyMethodName ?? (Object.hasOwn(TASK_TO_METHOD, taskName) ? TASK_TO_METHOD[taskName] : void 0);
|
|
149
|
+
const callParams = legacyMethodName ? withLegacyCreativeWireHint(params) : params;
|
|
112
150
|
const taskOptions = opts.skipIdempotencyAutoInject || opts.skipAccountValidation ? {
|
|
113
151
|
...opts.skipIdempotencyAutoInject && { skipIdempotencyAutoInject: true },
|
|
114
152
|
...opts.skipAccountValidation && { skipAccountValidation: true }
|
|
@@ -116,9 +154,9 @@ async function executeStoryboardTask(client, taskName, params, opts = {}) {
|
|
|
116
154
|
let result;
|
|
117
155
|
const invoke = async () => {
|
|
118
156
|
if (methodName && typeof client[methodName] === "function") {
|
|
119
|
-
return taskOptions ? client[methodName](
|
|
157
|
+
return taskOptions ? client[methodName](callParams, void 0, taskOptions) : client[methodName](callParams);
|
|
120
158
|
}
|
|
121
|
-
return client.executeTask(taskName,
|
|
159
|
+
return client.executeTask(taskName, callParams, void 0, taskOptions);
|
|
122
160
|
};
|
|
123
161
|
const MAX_RETRIES = 3;
|
|
124
162
|
const BASE_DELAY_MS = 2e3;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/task-map.ts"],"sourcesContent":["/**\n * Maps AdCP task names (from storyboard YAML) to SingleAgentClient method names.\n *\n * Each storyboard step has a `task` field like \"sync_accounts\" or \"get_products\".\n * This map resolves those to the camelCase method on SingleAgentClient.\n *\n * Tasks without a dedicated method fall through to `executeTask()`.\n */\n\nimport type { TaskResult } from '../types';\nimport type { AdcpErrorInfo } from '../../core/ConversationTypes';\nimport { isTerminalAdcpError, readExtractionPath } from '../../utils/response-unwrapper';\n\n/**\n * Map of AdCP task names to SingleAgentClient method names.\n * Only includes tasks that have dedicated typed methods.\n */\nexport const TASK_TO_METHOD: Record<string, string> = {\n // Account & audience\n sync_accounts: 'syncAccounts',\n list_accounts: 'listAccounts',\n sync_audiences: 'syncAudiences',\n\n // Product discovery & media buy\n get_products: 'getProducts',\n create_media_buy: 'createMediaBuy',\n update_media_buy: 'updateMediaBuy',\n get_media_buys: 'getMediaBuys',\n get_media_buy_delivery: 'getMediaBuyDelivery',\n provide_performance_feedback: 'providePerformanceFeedback',\n\n // Creative\n list_creative_formats: 'listCreativeFormats',\n build_creative: 'buildCreative',\n preview_creative: 'previewCreative',\n sync_creatives: 'syncCreatives',\n list_creatives: 'listCreatives',\n\n // Signals\n get_signals: 'getSignals',\n activate_signal: 'activateSignal',\n\n // Capabilities\n get_adcp_capabilities: 'getAdcpCapabilities',\n\n // Governance\n sync_plans: 'syncPlans',\n check_governance: 'checkGovernance',\n get_plan_audit_logs: 'getPlanAuditLogs',\n create_property_list: 'createPropertyList',\n get_property_list: 'getPropertyList',\n update_property_list: 'updatePropertyList',\n list_property_lists: 'listPropertyLists',\n delete_property_list: 'deletePropertyList',\n list_collection_lists: 'listCollectionLists',\n list_content_standards: 'listContentStandards',\n get_content_standards: 'getContentStandards',\n create_content_standards: 'createContentStandards',\n update_content_standards: 'updateContentStandards',\n calibrate_content: 'calibrateContent',\n validate_content_delivery: 'validateContentDelivery',\n\n // Account\n get_account_financials: 'getAccountFinancials',\n log_event: 'logEvent',\n\n // Sponsored Intelligence\n si_get_offering: 'siGetOffering',\n si_initiate_session: 'siInitiateSession',\n si_send_message: 'siSendMessage',\n si_terminate_session: 'siTerminateSession',\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readAdcpError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value)) return undefined;\n const error = value.adcp_error;\n if (!isRecord(error) || typeof error.code !== 'string') return undefined;\n return error as unknown as AdcpErrorInfo;\n}\n\nfunction readFirstError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value) || !Array.isArray(value.errors)) return undefined;\n const first = value.errors[0];\n if (!isRecord(first) || typeof first.code !== 'string') return undefined;\n return {\n code: first.code,\n message: typeof first.message === 'string' ? first.message : String(first.code),\n ...(typeof first.recovery === 'string' && { recovery: first.recovery as AdcpErrorInfo['recovery'] }),\n ...(typeof first.field === 'string' && { field: first.field }),\n ...(typeof first.suggestion === 'string' && { suggestion: first.suggestion }),\n ...(typeof first.retry_after === 'number' && { retry_after: first.retry_after }),\n ...(isRecord(first.details) && { details: first.details }),\n };\n}\n\nfunction errorMessageFrom(error: AdcpErrorInfo | undefined, fallback: unknown): string | undefined {\n if (typeof error?.message === 'string' && error.message.length > 0) return error.message;\n if (typeof error?.code === 'string') return error.code;\n return typeof fallback === 'string' && fallback.length > 0 ? fallback : undefined;\n}\n\nfunction normalizeStoryboardTaskSuccess(\n result: unknown,\n taskName: string,\n terminalDataError?: boolean,\n adcpError?: AdcpErrorInfo\n): boolean {\n if (!isRecord(result)) return true;\n if (typeof result.success === 'boolean') return result.success;\n if (result.status === 'failed' || result.status === 'rejected') return false;\n if (adcpError || result.adcpError || result.adcp_error) return false;\n if (terminalDataError ?? isTerminalAdcpError(result.data, taskName)) return false;\n return true;\n}\n\n/**\n * Execute a storyboard task against a SingleAgentClient.\n *\n * Uses the typed method if one exists, otherwise falls back to executeTask().\n * When the agent returns an async status (working/submitted), waits for\n * completion before returning — storyboard steps expect final results.\n */\nexport async function executeStoryboardTask(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- dynamic dispatch requires any\n client: any,\n taskName: string,\n params: Record<string, unknown>,\n opts: { skipIdempotencyAutoInject?: boolean; skipAccountValidation?: boolean; signal?: AbortSignal } = {}\n): Promise<TaskResult> {\n const methodName = Object.hasOwn(TASK_TO_METHOD, taskName) ? TASK_TO_METHOD[taskName] : undefined;\n\n // Only pass TaskOptions when a flag is actually set — avoids changing\n // behavior for the common path that relies on method defaults.\n const taskOptions =\n opts.skipIdempotencyAutoInject || opts.skipAccountValidation\n ? {\n ...(opts.skipIdempotencyAutoInject && { skipIdempotencyAutoInject: true }),\n ...(opts.skipAccountValidation && { skipAccountValidation: true }),\n }\n : undefined;\n\n let result;\n const invoke = async () => {\n if (methodName && typeof client[methodName] === 'function') {\n // Typed methods take (params, inputHandler?, options?). Pass options\n // only when set, otherwise they take their defaults.\n return taskOptions ? client[methodName](params, undefined, taskOptions) : client[methodName](params);\n }\n return client.executeTask(taskName, params, undefined, taskOptions);\n };\n\n // Retry with exponential backoff on rate limit errors\n const MAX_RETRIES = 3;\n const BASE_DELAY_MS = 2000;\n for (let attempt = 0; ; attempt++) {\n try {\n result = await raceWithSignal(invoke(), opts.signal);\n break;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isRateLimit =\n /rate limit/i.test(msg) || (/\"code\":\\s*-32000/.test(msg) && /rate.?limit|too many|throttl/i.test(msg));\n if (isRateLimit && attempt < MAX_RETRIES) {\n const jitter = Math.random() * 1000;\n const delay = BASE_DELAY_MS * 2 ** attempt + jitter;\n await raceWithSignal(new Promise(resolve => setTimeout(resolve, delay)), opts.signal);\n continue;\n }\n throw err;\n }\n }\n\n // If the agent returned an async status but included data in the initial\n // response (common for agents that process synchronously but report as\n // submitted), use that data. Only poll when there's no data at all.\n const hasData = result.data !== undefined && result.data !== null;\n const isAsync = result.status === 'submitted' || result.status === 'working';\n const prePollingDebugLogs = Array.isArray(result.debug_logs) ? [...result.debug_logs] : [];\n let replacedByPolling = false;\n if (!hasData && isAsync && result.submitted?.waitForCompletion) {\n try {\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('Task polling timeout')), 30_000)\n );\n result = await raceWithSignal(\n Promise.race([result.submitted.waitForCompletion(2000, opts.signal), timeout]),\n opts.signal\n );\n replacedByPolling = true;\n } catch (err) {\n if (opts.signal?.aborted) throw err;\n // Polling failed or timed out — return the intermediate result as-is\n }\n }\n\n const terminalDataError = isTerminalAdcpError(result.data, taskName);\n const adcpError =\n result.adcpError ??\n result.adcp_error ??\n readAdcpError(result.data) ??\n (terminalDataError ? readFirstError(result.data) : undefined);\n const data = result.data ?? (adcpError ? { adcp_error: adcpError } : undefined);\n const success = normalizeStoryboardTaskSuccess(result, taskName, terminalDataError, adcpError);\n const error = result.error ?? (!success ? errorMessageFrom(adcpError, undefined) : undefined);\n const extractionPath = readExtractionPath(data);\n const debugLogs = Array.isArray(result.debug_logs) ? result.debug_logs : [];\n const mergedDebugLogs = replacedByPolling ? [...prePollingDebugLogs, ...debugLogs] : debugLogs;\n return {\n success,\n data,\n error,\n ...(adcpError && { adcp_error: adcpError }),\n ...(extractionPath !== undefined && { _extraction_path: extractionPath }),\n ...(mergedDebugLogs.length > 0 && { debug_logs: mergedDebugLogs }),\n };\n}\n\nfunction raceWithSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('aborted'));\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(signal.reason ?? new Error('aborted'));\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/task-map.ts"],"sourcesContent":["/**\n * Maps AdCP task names (from storyboard YAML) to SingleAgentClient method names.\n *\n * Each storyboard step has a `task` field like \"sync_accounts\" or \"get_products\".\n * This map resolves those to the camelCase method on SingleAgentClient.\n *\n * Tasks without a dedicated method fall through to `executeTask()`.\n */\n\nimport type { TaskResult } from '../types';\nimport type { AdcpErrorInfo } from '../../core/ConversationTypes';\nimport { isTerminalAdcpError, readExtractionPath } from '../../utils/response-unwrapper';\n\n/**\n * Map of AdCP task names to SingleAgentClient method names.\n * Only includes tasks that have dedicated typed methods.\n */\nexport const TASK_TO_METHOD: Record<string, string> = {\n // Account & audience\n sync_accounts: 'syncAccounts',\n list_accounts: 'listAccounts',\n sync_audiences: 'syncAudiences',\n\n // Product discovery & media buy\n get_products: 'getProducts',\n create_media_buy: 'createMediaBuy',\n update_media_buy: 'updateMediaBuy',\n get_media_buys: 'getMediaBuys',\n get_media_buy_delivery: 'getMediaBuyDelivery',\n provide_performance_feedback: 'providePerformanceFeedback',\n\n // Creative\n list_creative_formats: 'listCreativeFormats',\n build_creative: 'buildCreativeLegacy',\n preview_creative: 'previewCreativeLegacy',\n sync_creatives: 'syncCreatives',\n list_creatives: 'listCreatives',\n\n // Signals\n get_signals: 'getSignals',\n activate_signal: 'activateSignal',\n\n // Capabilities\n get_adcp_capabilities: 'getAdcpCapabilities',\n\n // Governance\n sync_plans: 'syncPlans',\n check_governance: 'checkGovernance',\n get_plan_audit_logs: 'getPlanAuditLogs',\n create_property_list: 'createPropertyList',\n get_property_list: 'getPropertyList',\n update_property_list: 'updatePropertyList',\n list_property_lists: 'listPropertyLists',\n delete_property_list: 'deletePropertyList',\n list_collection_lists: 'listCollectionLists',\n list_content_standards: 'listContentStandards',\n get_content_standards: 'getContentStandards',\n create_content_standards: 'createContentStandards',\n update_content_standards: 'updateContentStandards',\n calibrate_content: 'calibrateContent',\n validate_content_delivery: 'validateContentDelivery',\n\n // Account\n get_account_financials: 'getAccountFinancials',\n log_event: 'logEvent',\n\n // Sponsored Intelligence\n si_get_offering: 'siGetOffering',\n si_initiate_session: 'siInitiateSession',\n si_send_message: 'siSendMessage',\n si_terminate_session: 'siTerminateSession',\n};\n\n/** Storyboards grade the selected protocol wire, not the SDK's canonical API. */\nconst LEGACY_CREATIVE_TASK_TO_METHOD: Readonly<Record<string, string>> = {\n get_products: 'getProductsLegacy',\n create_media_buy: 'createMediaBuyLegacy',\n update_media_buy: 'updateMediaBuyLegacy',\n sync_creatives: 'syncCreativesLegacy',\n list_creatives: 'listCreativesLegacy',\n};\n\nfunction gradesLegacyCreativeWire(client: unknown): boolean {\n if (client === null || typeof client !== 'object') return false;\n const getAdcpVersion = (client as { getAdcpVersion?: unknown }).getAdcpVersion;\n if (typeof getAdcpVersion !== 'function') return false;\n let version: unknown;\n try {\n version = getAdcpVersion.call(client);\n } catch {\n return false;\n }\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)(?:\\.(\\d+))?/.exec(version.trim());\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2] ?? 0);\n return major < 3 || (major === 3 && minor < 2);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction withLegacyCreativeWireHint(params: Record<string, unknown>): Record<string, unknown> {\n const ext = isRecord(params.ext) ? params.ext : {};\n const adcp = isRecord(ext.adcp) ? ext.adcp : {};\n if (adcp.creative_wire === 'legacy' || adcp.creative_wire === 'canonical') return params;\n return {\n ...params,\n ext: {\n ...ext,\n adcp: { ...adcp, creative_wire: 'legacy' },\n },\n };\n}\n\nfunction readAdcpError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value)) return undefined;\n const error = value.adcp_error;\n if (!isRecord(error) || typeof error.code !== 'string') return undefined;\n return error as unknown as AdcpErrorInfo;\n}\n\nfunction readFirstError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value) || !Array.isArray(value.errors)) return undefined;\n const first = value.errors[0];\n if (!isRecord(first) || typeof first.code !== 'string') return undefined;\n return {\n code: first.code,\n message: typeof first.message === 'string' ? first.message : String(first.code),\n ...(typeof first.recovery === 'string' && { recovery: first.recovery as AdcpErrorInfo['recovery'] }),\n ...(typeof first.field === 'string' && { field: first.field }),\n ...(typeof first.suggestion === 'string' && { suggestion: first.suggestion }),\n ...(typeof first.retry_after === 'number' && { retry_after: first.retry_after }),\n ...(isRecord(first.details) && { details: first.details }),\n };\n}\n\nfunction errorMessageFrom(error: AdcpErrorInfo | undefined, fallback: unknown): string | undefined {\n if (typeof error?.message === 'string' && error.message.length > 0) return error.message;\n if (typeof error?.code === 'string') return error.code;\n return typeof fallback === 'string' && fallback.length > 0 ? fallback : undefined;\n}\n\nfunction normalizeStoryboardTaskSuccess(\n result: unknown,\n taskName: string,\n terminalDataError?: boolean,\n adcpError?: AdcpErrorInfo\n): boolean {\n if (!isRecord(result)) return true;\n if (typeof result.success === 'boolean') return result.success;\n if (result.status === 'failed' || result.status === 'rejected') return false;\n if (adcpError || result.adcpError || result.adcp_error) return false;\n if (terminalDataError ?? isTerminalAdcpError(result.data, taskName)) return false;\n return true;\n}\n\n/**\n * Execute a storyboard task against a SingleAgentClient.\n *\n * Uses the typed method if one exists, otherwise falls back to executeTask().\n * When the agent returns an async status (working/submitted), waits for\n * completion before returning — storyboard steps expect final results.\n */\nexport async function executeStoryboardTask(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- dynamic dispatch requires any\n client: any,\n taskName: string,\n params: Record<string, unknown>,\n opts: { skipIdempotencyAutoInject?: boolean; skipAccountValidation?: boolean; signal?: AbortSignal } = {}\n): Promise<TaskResult> {\n const legacyMethodName = gradesLegacyCreativeWire(client) ? LEGACY_CREATIVE_TASK_TO_METHOD[taskName] : undefined;\n const methodName =\n legacyMethodName ?? (Object.hasOwn(TASK_TO_METHOD, taskName) ? TASK_TO_METHOD[taskName] : undefined);\n const callParams = legacyMethodName ? withLegacyCreativeWireHint(params) : params;\n\n // Only pass TaskOptions when a flag is actually set — avoids changing\n // behavior for the common path that relies on method defaults.\n const taskOptions =\n opts.skipIdempotencyAutoInject || opts.skipAccountValidation\n ? {\n ...(opts.skipIdempotencyAutoInject && { skipIdempotencyAutoInject: true }),\n ...(opts.skipAccountValidation && { skipAccountValidation: true }),\n }\n : undefined;\n\n let result;\n const invoke = async () => {\n if (methodName && typeof client[methodName] === 'function') {\n // Typed methods take (params, inputHandler?, options?). Pass options\n // only when set, otherwise they take their defaults.\n return taskOptions ? client[methodName](callParams, undefined, taskOptions) : client[methodName](callParams);\n }\n return client.executeTask(taskName, callParams, undefined, taskOptions);\n };\n\n // Retry with exponential backoff on rate limit errors\n const MAX_RETRIES = 3;\n const BASE_DELAY_MS = 2000;\n for (let attempt = 0; ; attempt++) {\n try {\n result = await raceWithSignal(invoke(), opts.signal);\n break;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isRateLimit =\n /rate limit/i.test(msg) || (/\"code\":\\s*-32000/.test(msg) && /rate.?limit|too many|throttl/i.test(msg));\n if (isRateLimit && attempt < MAX_RETRIES) {\n const jitter = Math.random() * 1000;\n const delay = BASE_DELAY_MS * 2 ** attempt + jitter;\n await raceWithSignal(new Promise(resolve => setTimeout(resolve, delay)), opts.signal);\n continue;\n }\n throw err;\n }\n }\n\n // If the agent returned an async status but included data in the initial\n // response (common for agents that process synchronously but report as\n // submitted), use that data. Only poll when there's no data at all.\n const hasData = result.data !== undefined && result.data !== null;\n const isAsync = result.status === 'submitted' || result.status === 'working';\n const prePollingDebugLogs = Array.isArray(result.debug_logs) ? [...result.debug_logs] : [];\n let replacedByPolling = false;\n if (!hasData && isAsync && result.submitted?.waitForCompletion) {\n try {\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('Task polling timeout')), 30_000)\n );\n result = await raceWithSignal(\n Promise.race([result.submitted.waitForCompletion(2000, opts.signal), timeout]),\n opts.signal\n );\n replacedByPolling = true;\n } catch (err) {\n if (opts.signal?.aborted) throw err;\n // Polling failed or timed out — return the intermediate result as-is\n }\n }\n\n const terminalDataError = isTerminalAdcpError(result.data, taskName);\n const adcpError =\n result.adcpError ??\n result.adcp_error ??\n readAdcpError(result.data) ??\n (terminalDataError ? readFirstError(result.data) : undefined);\n const data = result.data ?? (adcpError ? { adcp_error: adcpError } : undefined);\n const success = normalizeStoryboardTaskSuccess(result, taskName, terminalDataError, adcpError);\n const error = result.error ?? (!success ? errorMessageFrom(adcpError, undefined) : undefined);\n const extractionPath = readExtractionPath(data);\n const debugLogs = Array.isArray(result.debug_logs) ? result.debug_logs : [];\n const mergedDebugLogs = replacedByPolling ? [...prePollingDebugLogs, ...debugLogs] : debugLogs;\n return {\n success,\n data,\n error,\n ...(adcpError && { adcp_error: adcpError }),\n ...(extractionPath !== undefined && { _extraction_path: extractionPath }),\n ...(mergedDebugLogs.length > 0 && { debug_logs: mergedDebugLogs }),\n };\n}\n\nfunction raceWithSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('aborted'));\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(signal.reason ?? new Error('aborted'));\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -13,8 +13,8 @@ const TASK_TO_METHOD = {
|
|
|
13
13
|
provide_performance_feedback: "providePerformanceFeedback",
|
|
14
14
|
// Creative
|
|
15
15
|
list_creative_formats: "listCreativeFormats",
|
|
16
|
-
build_creative: "
|
|
17
|
-
preview_creative: "
|
|
16
|
+
build_creative: "buildCreativeLegacy",
|
|
17
|
+
preview_creative: "previewCreativeLegacy",
|
|
18
18
|
sync_creatives: "syncCreatives",
|
|
19
19
|
list_creatives: "listCreatives",
|
|
20
20
|
// Signals
|
|
@@ -47,9 +47,45 @@ const TASK_TO_METHOD = {
|
|
|
47
47
|
si_send_message: "siSendMessage",
|
|
48
48
|
si_terminate_session: "siTerminateSession"
|
|
49
49
|
};
|
|
50
|
+
const LEGACY_CREATIVE_TASK_TO_METHOD = {
|
|
51
|
+
get_products: "getProductsLegacy",
|
|
52
|
+
create_media_buy: "createMediaBuyLegacy",
|
|
53
|
+
update_media_buy: "updateMediaBuyLegacy",
|
|
54
|
+
sync_creatives: "syncCreativesLegacy",
|
|
55
|
+
list_creatives: "listCreativesLegacy"
|
|
56
|
+
};
|
|
57
|
+
function gradesLegacyCreativeWire(client) {
|
|
58
|
+
if (client === null || typeof client !== "object") return false;
|
|
59
|
+
const getAdcpVersion = client.getAdcpVersion;
|
|
60
|
+
if (typeof getAdcpVersion !== "function") return false;
|
|
61
|
+
let version;
|
|
62
|
+
try {
|
|
63
|
+
version = getAdcpVersion.call(client);
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (typeof version !== "string") return false;
|
|
68
|
+
const match = /^v?(\d+)(?:\.(\d+))?/.exec(version.trim());
|
|
69
|
+
if (!match) return false;
|
|
70
|
+
const major = Number(match[1]);
|
|
71
|
+
const minor = Number(match[2] ?? 0);
|
|
72
|
+
return major < 3 || major === 3 && minor < 2;
|
|
73
|
+
}
|
|
50
74
|
function isRecord(value) {
|
|
51
75
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
52
76
|
}
|
|
77
|
+
function withLegacyCreativeWireHint(params) {
|
|
78
|
+
const ext = isRecord(params.ext) ? params.ext : {};
|
|
79
|
+
const adcp = isRecord(ext.adcp) ? ext.adcp : {};
|
|
80
|
+
if (adcp.creative_wire === "legacy" || adcp.creative_wire === "canonical") return params;
|
|
81
|
+
return {
|
|
82
|
+
...params,
|
|
83
|
+
ext: {
|
|
84
|
+
...ext,
|
|
85
|
+
adcp: { ...adcp, creative_wire: "legacy" }
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
53
89
|
function readAdcpError(value) {
|
|
54
90
|
if (!isRecord(value)) return void 0;
|
|
55
91
|
const error = value.adcp_error;
|
|
@@ -84,7 +120,9 @@ function normalizeStoryboardTaskSuccess(result, taskName, terminalDataError, adc
|
|
|
84
120
|
return true;
|
|
85
121
|
}
|
|
86
122
|
async function executeStoryboardTask(client, taskName, params, opts = {}) {
|
|
87
|
-
const
|
|
123
|
+
const legacyMethodName = gradesLegacyCreativeWire(client) ? LEGACY_CREATIVE_TASK_TO_METHOD[taskName] : void 0;
|
|
124
|
+
const methodName = legacyMethodName ?? (Object.hasOwn(TASK_TO_METHOD, taskName) ? TASK_TO_METHOD[taskName] : void 0);
|
|
125
|
+
const callParams = legacyMethodName ? withLegacyCreativeWireHint(params) : params;
|
|
88
126
|
const taskOptions = opts.skipIdempotencyAutoInject || opts.skipAccountValidation ? {
|
|
89
127
|
...opts.skipIdempotencyAutoInject && { skipIdempotencyAutoInject: true },
|
|
90
128
|
...opts.skipAccountValidation && { skipAccountValidation: true }
|
|
@@ -92,9 +130,9 @@ async function executeStoryboardTask(client, taskName, params, opts = {}) {
|
|
|
92
130
|
let result;
|
|
93
131
|
const invoke = async () => {
|
|
94
132
|
if (methodName && typeof client[methodName] === "function") {
|
|
95
|
-
return taskOptions ? client[methodName](
|
|
133
|
+
return taskOptions ? client[methodName](callParams, void 0, taskOptions) : client[methodName](callParams);
|
|
96
134
|
}
|
|
97
|
-
return client.executeTask(taskName,
|
|
135
|
+
return client.executeTask(taskName, callParams, void 0, taskOptions);
|
|
98
136
|
};
|
|
99
137
|
const MAX_RETRIES = 3;
|
|
100
138
|
const BASE_DELAY_MS = 2e3;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/task-map.ts"],"sourcesContent":["/**\n * Maps AdCP task names (from storyboard YAML) to SingleAgentClient method names.\n *\n * Each storyboard step has a `task` field like \"sync_accounts\" or \"get_products\".\n * This map resolves those to the camelCase method on SingleAgentClient.\n *\n * Tasks without a dedicated method fall through to `executeTask()`.\n */\n\nimport type { TaskResult } from '../types';\nimport type { AdcpErrorInfo } from '../../core/ConversationTypes';\nimport { isTerminalAdcpError, readExtractionPath } from '../../utils/response-unwrapper';\n\n/**\n * Map of AdCP task names to SingleAgentClient method names.\n * Only includes tasks that have dedicated typed methods.\n */\nexport const TASK_TO_METHOD: Record<string, string> = {\n // Account & audience\n sync_accounts: 'syncAccounts',\n list_accounts: 'listAccounts',\n sync_audiences: 'syncAudiences',\n\n // Product discovery & media buy\n get_products: 'getProducts',\n create_media_buy: 'createMediaBuy',\n update_media_buy: 'updateMediaBuy',\n get_media_buys: 'getMediaBuys',\n get_media_buy_delivery: 'getMediaBuyDelivery',\n provide_performance_feedback: 'providePerformanceFeedback',\n\n // Creative\n list_creative_formats: 'listCreativeFormats',\n build_creative: 'buildCreative',\n preview_creative: 'previewCreative',\n sync_creatives: 'syncCreatives',\n list_creatives: 'listCreatives',\n\n // Signals\n get_signals: 'getSignals',\n activate_signal: 'activateSignal',\n\n // Capabilities\n get_adcp_capabilities: 'getAdcpCapabilities',\n\n // Governance\n sync_plans: 'syncPlans',\n check_governance: 'checkGovernance',\n get_plan_audit_logs: 'getPlanAuditLogs',\n create_property_list: 'createPropertyList',\n get_property_list: 'getPropertyList',\n update_property_list: 'updatePropertyList',\n list_property_lists: 'listPropertyLists',\n delete_property_list: 'deletePropertyList',\n list_collection_lists: 'listCollectionLists',\n list_content_standards: 'listContentStandards',\n get_content_standards: 'getContentStandards',\n create_content_standards: 'createContentStandards',\n update_content_standards: 'updateContentStandards',\n calibrate_content: 'calibrateContent',\n validate_content_delivery: 'validateContentDelivery',\n\n // Account\n get_account_financials: 'getAccountFinancials',\n log_event: 'logEvent',\n\n // Sponsored Intelligence\n si_get_offering: 'siGetOffering',\n si_initiate_session: 'siInitiateSession',\n si_send_message: 'siSendMessage',\n si_terminate_session: 'siTerminateSession',\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readAdcpError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value)) return undefined;\n const error = value.adcp_error;\n if (!isRecord(error) || typeof error.code !== 'string') return undefined;\n return error as unknown as AdcpErrorInfo;\n}\n\nfunction readFirstError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value) || !Array.isArray(value.errors)) return undefined;\n const first = value.errors[0];\n if (!isRecord(first) || typeof first.code !== 'string') return undefined;\n return {\n code: first.code,\n message: typeof first.message === 'string' ? first.message : String(first.code),\n ...(typeof first.recovery === 'string' && { recovery: first.recovery as AdcpErrorInfo['recovery'] }),\n ...(typeof first.field === 'string' && { field: first.field }),\n ...(typeof first.suggestion === 'string' && { suggestion: first.suggestion }),\n ...(typeof first.retry_after === 'number' && { retry_after: first.retry_after }),\n ...(isRecord(first.details) && { details: first.details }),\n };\n}\n\nfunction errorMessageFrom(error: AdcpErrorInfo | undefined, fallback: unknown): string | undefined {\n if (typeof error?.message === 'string' && error.message.length > 0) return error.message;\n if (typeof error?.code === 'string') return error.code;\n return typeof fallback === 'string' && fallback.length > 0 ? fallback : undefined;\n}\n\nfunction normalizeStoryboardTaskSuccess(\n result: unknown,\n taskName: string,\n terminalDataError?: boolean,\n adcpError?: AdcpErrorInfo\n): boolean {\n if (!isRecord(result)) return true;\n if (typeof result.success === 'boolean') return result.success;\n if (result.status === 'failed' || result.status === 'rejected') return false;\n if (adcpError || result.adcpError || result.adcp_error) return false;\n if (terminalDataError ?? isTerminalAdcpError(result.data, taskName)) return false;\n return true;\n}\n\n/**\n * Execute a storyboard task against a SingleAgentClient.\n *\n * Uses the typed method if one exists, otherwise falls back to executeTask().\n * When the agent returns an async status (working/submitted), waits for\n * completion before returning — storyboard steps expect final results.\n */\nexport async function executeStoryboardTask(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- dynamic dispatch requires any\n client: any,\n taskName: string,\n params: Record<string, unknown>,\n opts: { skipIdempotencyAutoInject?: boolean; skipAccountValidation?: boolean; signal?: AbortSignal } = {}\n): Promise<TaskResult> {\n const methodName = Object.hasOwn(TASK_TO_METHOD, taskName) ? TASK_TO_METHOD[taskName] : undefined;\n\n // Only pass TaskOptions when a flag is actually set — avoids changing\n // behavior for the common path that relies on method defaults.\n const taskOptions =\n opts.skipIdempotencyAutoInject || opts.skipAccountValidation\n ? {\n ...(opts.skipIdempotencyAutoInject && { skipIdempotencyAutoInject: true }),\n ...(opts.skipAccountValidation && { skipAccountValidation: true }),\n }\n : undefined;\n\n let result;\n const invoke = async () => {\n if (methodName && typeof client[methodName] === 'function') {\n // Typed methods take (params, inputHandler?, options?). Pass options\n // only when set, otherwise they take their defaults.\n return taskOptions ? client[methodName](params, undefined, taskOptions) : client[methodName](params);\n }\n return client.executeTask(taskName, params, undefined, taskOptions);\n };\n\n // Retry with exponential backoff on rate limit errors\n const MAX_RETRIES = 3;\n const BASE_DELAY_MS = 2000;\n for (let attempt = 0; ; attempt++) {\n try {\n result = await raceWithSignal(invoke(), opts.signal);\n break;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isRateLimit =\n /rate limit/i.test(msg) || (/\"code\":\\s*-32000/.test(msg) && /rate.?limit|too many|throttl/i.test(msg));\n if (isRateLimit && attempt < MAX_RETRIES) {\n const jitter = Math.random() * 1000;\n const delay = BASE_DELAY_MS * 2 ** attempt + jitter;\n await raceWithSignal(new Promise(resolve => setTimeout(resolve, delay)), opts.signal);\n continue;\n }\n throw err;\n }\n }\n\n // If the agent returned an async status but included data in the initial\n // response (common for agents that process synchronously but report as\n // submitted), use that data. Only poll when there's no data at all.\n const hasData = result.data !== undefined && result.data !== null;\n const isAsync = result.status === 'submitted' || result.status === 'working';\n const prePollingDebugLogs = Array.isArray(result.debug_logs) ? [...result.debug_logs] : [];\n let replacedByPolling = false;\n if (!hasData && isAsync && result.submitted?.waitForCompletion) {\n try {\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('Task polling timeout')), 30_000)\n );\n result = await raceWithSignal(\n Promise.race([result.submitted.waitForCompletion(2000, opts.signal), timeout]),\n opts.signal\n );\n replacedByPolling = true;\n } catch (err) {\n if (opts.signal?.aborted) throw err;\n // Polling failed or timed out — return the intermediate result as-is\n }\n }\n\n const terminalDataError = isTerminalAdcpError(result.data, taskName);\n const adcpError =\n result.adcpError ??\n result.adcp_error ??\n readAdcpError(result.data) ??\n (terminalDataError ? readFirstError(result.data) : undefined);\n const data = result.data ?? (adcpError ? { adcp_error: adcpError } : undefined);\n const success = normalizeStoryboardTaskSuccess(result, taskName, terminalDataError, adcpError);\n const error = result.error ?? (!success ? errorMessageFrom(adcpError, undefined) : undefined);\n const extractionPath = readExtractionPath(data);\n const debugLogs = Array.isArray(result.debug_logs) ? result.debug_logs : [];\n const mergedDebugLogs = replacedByPolling ? [...prePollingDebugLogs, ...debugLogs] : debugLogs;\n return {\n success,\n data,\n error,\n ...(adcpError && { adcp_error: adcpError }),\n ...(extractionPath !== undefined && { _extraction_path: extractionPath }),\n ...(mergedDebugLogs.length > 0 && { debug_logs: mergedDebugLogs }),\n };\n}\n\nfunction raceWithSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('aborted'));\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(signal.reason ?? new Error('aborted'));\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/task-map.ts"],"sourcesContent":["/**\n * Maps AdCP task names (from storyboard YAML) to SingleAgentClient method names.\n *\n * Each storyboard step has a `task` field like \"sync_accounts\" or \"get_products\".\n * This map resolves those to the camelCase method on SingleAgentClient.\n *\n * Tasks without a dedicated method fall through to `executeTask()`.\n */\n\nimport type { TaskResult } from '../types';\nimport type { AdcpErrorInfo } from '../../core/ConversationTypes';\nimport { isTerminalAdcpError, readExtractionPath } from '../../utils/response-unwrapper';\n\n/**\n * Map of AdCP task names to SingleAgentClient method names.\n * Only includes tasks that have dedicated typed methods.\n */\nexport const TASK_TO_METHOD: Record<string, string> = {\n // Account & audience\n sync_accounts: 'syncAccounts',\n list_accounts: 'listAccounts',\n sync_audiences: 'syncAudiences',\n\n // Product discovery & media buy\n get_products: 'getProducts',\n create_media_buy: 'createMediaBuy',\n update_media_buy: 'updateMediaBuy',\n get_media_buys: 'getMediaBuys',\n get_media_buy_delivery: 'getMediaBuyDelivery',\n provide_performance_feedback: 'providePerformanceFeedback',\n\n // Creative\n list_creative_formats: 'listCreativeFormats',\n build_creative: 'buildCreativeLegacy',\n preview_creative: 'previewCreativeLegacy',\n sync_creatives: 'syncCreatives',\n list_creatives: 'listCreatives',\n\n // Signals\n get_signals: 'getSignals',\n activate_signal: 'activateSignal',\n\n // Capabilities\n get_adcp_capabilities: 'getAdcpCapabilities',\n\n // Governance\n sync_plans: 'syncPlans',\n check_governance: 'checkGovernance',\n get_plan_audit_logs: 'getPlanAuditLogs',\n create_property_list: 'createPropertyList',\n get_property_list: 'getPropertyList',\n update_property_list: 'updatePropertyList',\n list_property_lists: 'listPropertyLists',\n delete_property_list: 'deletePropertyList',\n list_collection_lists: 'listCollectionLists',\n list_content_standards: 'listContentStandards',\n get_content_standards: 'getContentStandards',\n create_content_standards: 'createContentStandards',\n update_content_standards: 'updateContentStandards',\n calibrate_content: 'calibrateContent',\n validate_content_delivery: 'validateContentDelivery',\n\n // Account\n get_account_financials: 'getAccountFinancials',\n log_event: 'logEvent',\n\n // Sponsored Intelligence\n si_get_offering: 'siGetOffering',\n si_initiate_session: 'siInitiateSession',\n si_send_message: 'siSendMessage',\n si_terminate_session: 'siTerminateSession',\n};\n\n/** Storyboards grade the selected protocol wire, not the SDK's canonical API. */\nconst LEGACY_CREATIVE_TASK_TO_METHOD: Readonly<Record<string, string>> = {\n get_products: 'getProductsLegacy',\n create_media_buy: 'createMediaBuyLegacy',\n update_media_buy: 'updateMediaBuyLegacy',\n sync_creatives: 'syncCreativesLegacy',\n list_creatives: 'listCreativesLegacy',\n};\n\nfunction gradesLegacyCreativeWire(client: unknown): boolean {\n if (client === null || typeof client !== 'object') return false;\n const getAdcpVersion = (client as { getAdcpVersion?: unknown }).getAdcpVersion;\n if (typeof getAdcpVersion !== 'function') return false;\n let version: unknown;\n try {\n version = getAdcpVersion.call(client);\n } catch {\n return false;\n }\n if (typeof version !== 'string') return false;\n const match = /^v?(\\d+)(?:\\.(\\d+))?/.exec(version.trim());\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2] ?? 0);\n return major < 3 || (major === 3 && minor < 2);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction withLegacyCreativeWireHint(params: Record<string, unknown>): Record<string, unknown> {\n const ext = isRecord(params.ext) ? params.ext : {};\n const adcp = isRecord(ext.adcp) ? ext.adcp : {};\n if (adcp.creative_wire === 'legacy' || adcp.creative_wire === 'canonical') return params;\n return {\n ...params,\n ext: {\n ...ext,\n adcp: { ...adcp, creative_wire: 'legacy' },\n },\n };\n}\n\nfunction readAdcpError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value)) return undefined;\n const error = value.adcp_error;\n if (!isRecord(error) || typeof error.code !== 'string') return undefined;\n return error as unknown as AdcpErrorInfo;\n}\n\nfunction readFirstError(value: unknown): AdcpErrorInfo | undefined {\n if (!isRecord(value) || !Array.isArray(value.errors)) return undefined;\n const first = value.errors[0];\n if (!isRecord(first) || typeof first.code !== 'string') return undefined;\n return {\n code: first.code,\n message: typeof first.message === 'string' ? first.message : String(first.code),\n ...(typeof first.recovery === 'string' && { recovery: first.recovery as AdcpErrorInfo['recovery'] }),\n ...(typeof first.field === 'string' && { field: first.field }),\n ...(typeof first.suggestion === 'string' && { suggestion: first.suggestion }),\n ...(typeof first.retry_after === 'number' && { retry_after: first.retry_after }),\n ...(isRecord(first.details) && { details: first.details }),\n };\n}\n\nfunction errorMessageFrom(error: AdcpErrorInfo | undefined, fallback: unknown): string | undefined {\n if (typeof error?.message === 'string' && error.message.length > 0) return error.message;\n if (typeof error?.code === 'string') return error.code;\n return typeof fallback === 'string' && fallback.length > 0 ? fallback : undefined;\n}\n\nfunction normalizeStoryboardTaskSuccess(\n result: unknown,\n taskName: string,\n terminalDataError?: boolean,\n adcpError?: AdcpErrorInfo\n): boolean {\n if (!isRecord(result)) return true;\n if (typeof result.success === 'boolean') return result.success;\n if (result.status === 'failed' || result.status === 'rejected') return false;\n if (adcpError || result.adcpError || result.adcp_error) return false;\n if (terminalDataError ?? isTerminalAdcpError(result.data, taskName)) return false;\n return true;\n}\n\n/**\n * Execute a storyboard task against a SingleAgentClient.\n *\n * Uses the typed method if one exists, otherwise falls back to executeTask().\n * When the agent returns an async status (working/submitted), waits for\n * completion before returning — storyboard steps expect final results.\n */\nexport async function executeStoryboardTask(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- dynamic dispatch requires any\n client: any,\n taskName: string,\n params: Record<string, unknown>,\n opts: { skipIdempotencyAutoInject?: boolean; skipAccountValidation?: boolean; signal?: AbortSignal } = {}\n): Promise<TaskResult> {\n const legacyMethodName = gradesLegacyCreativeWire(client) ? LEGACY_CREATIVE_TASK_TO_METHOD[taskName] : undefined;\n const methodName =\n legacyMethodName ?? (Object.hasOwn(TASK_TO_METHOD, taskName) ? TASK_TO_METHOD[taskName] : undefined);\n const callParams = legacyMethodName ? withLegacyCreativeWireHint(params) : params;\n\n // Only pass TaskOptions when a flag is actually set — avoids changing\n // behavior for the common path that relies on method defaults.\n const taskOptions =\n opts.skipIdempotencyAutoInject || opts.skipAccountValidation\n ? {\n ...(opts.skipIdempotencyAutoInject && { skipIdempotencyAutoInject: true }),\n ...(opts.skipAccountValidation && { skipAccountValidation: true }),\n }\n : undefined;\n\n let result;\n const invoke = async () => {\n if (methodName && typeof client[methodName] === 'function') {\n // Typed methods take (params, inputHandler?, options?). Pass options\n // only when set, otherwise they take their defaults.\n return taskOptions ? client[methodName](callParams, undefined, taskOptions) : client[methodName](callParams);\n }\n return client.executeTask(taskName, callParams, undefined, taskOptions);\n };\n\n // Retry with exponential backoff on rate limit errors\n const MAX_RETRIES = 3;\n const BASE_DELAY_MS = 2000;\n for (let attempt = 0; ; attempt++) {\n try {\n result = await raceWithSignal(invoke(), opts.signal);\n break;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n const isRateLimit =\n /rate limit/i.test(msg) || (/\"code\":\\s*-32000/.test(msg) && /rate.?limit|too many|throttl/i.test(msg));\n if (isRateLimit && attempt < MAX_RETRIES) {\n const jitter = Math.random() * 1000;\n const delay = BASE_DELAY_MS * 2 ** attempt + jitter;\n await raceWithSignal(new Promise(resolve => setTimeout(resolve, delay)), opts.signal);\n continue;\n }\n throw err;\n }\n }\n\n // If the agent returned an async status but included data in the initial\n // response (common for agents that process synchronously but report as\n // submitted), use that data. Only poll when there's no data at all.\n const hasData = result.data !== undefined && result.data !== null;\n const isAsync = result.status === 'submitted' || result.status === 'working';\n const prePollingDebugLogs = Array.isArray(result.debug_logs) ? [...result.debug_logs] : [];\n let replacedByPolling = false;\n if (!hasData && isAsync && result.submitted?.waitForCompletion) {\n try {\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('Task polling timeout')), 30_000)\n );\n result = await raceWithSignal(\n Promise.race([result.submitted.waitForCompletion(2000, opts.signal), timeout]),\n opts.signal\n );\n replacedByPolling = true;\n } catch (err) {\n if (opts.signal?.aborted) throw err;\n // Polling failed or timed out — return the intermediate result as-is\n }\n }\n\n const terminalDataError = isTerminalAdcpError(result.data, taskName);\n const adcpError =\n result.adcpError ??\n result.adcp_error ??\n readAdcpError(result.data) ??\n (terminalDataError ? readFirstError(result.data) : undefined);\n const data = result.data ?? (adcpError ? { adcp_error: adcpError } : undefined);\n const success = normalizeStoryboardTaskSuccess(result, taskName, terminalDataError, adcpError);\n const error = result.error ?? (!success ? errorMessageFrom(adcpError, undefined) : undefined);\n const extractionPath = readExtractionPath(data);\n const debugLogs = Array.isArray(result.debug_logs) ? result.debug_logs : [];\n const mergedDebugLogs = replacedByPolling ? [...prePollingDebugLogs, ...debugLogs] : debugLogs;\n return {\n success,\n data,\n error,\n ...(adcpError && { adcp_error: adcpError }),\n ...(extractionPath !== undefined && { _extraction_path: extractionPath }),\n ...(mergedDebugLogs.length > 0 && { debug_logs: mergedDebugLogs }),\n };\n}\n\nfunction raceWithSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('aborted'));\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(signal.reason ?? new Error('aborted'));\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n value => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n err => {\n signal.removeEventListener('abort', onAbort);\n reject(err);\n }\n );\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -191,14 +191,14 @@ export declare function createTestAgent(overrides?: Partial<AgentConfig>): Agent
|
|
|
191
191
|
* import { creativeAgent } from '@adcp/sdk/testing';
|
|
192
192
|
*
|
|
193
193
|
* // List available creative formats
|
|
194
|
-
* const formats = await creativeAgent.
|
|
194
|
+
* const formats = await creativeAgent.listFormatsLegacy();
|
|
195
195
|
* console.log(`Found ${formats.length} creative formats`);
|
|
196
196
|
* ```
|
|
197
197
|
*
|
|
198
198
|
* @example
|
|
199
199
|
* ```typescript
|
|
200
200
|
* // Find formats by dimensions
|
|
201
|
-
* const formats = await creativeAgent.
|
|
201
|
+
* const formats = await creativeAgent.listFormatsLegacy();
|
|
202
202
|
* const banner = formats.find(f =>
|
|
203
203
|
* f.renders?.[0]?.dimensions?.width === 300 &&
|
|
204
204
|
* f.renders?.[0]?.dimensions?.height === 250
|
|
@@ -191,14 +191,14 @@ export declare function createTestAgent(overrides?: Partial<AgentConfig>): Agent
|
|
|
191
191
|
* import { creativeAgent } from '@adcp/sdk/testing';
|
|
192
192
|
*
|
|
193
193
|
* // List available creative formats
|
|
194
|
-
* const formats = await creativeAgent.
|
|
194
|
+
* const formats = await creativeAgent.listFormatsLegacy();
|
|
195
195
|
* console.log(`Found ${formats.length} creative formats`);
|
|
196
196
|
* ```
|
|
197
197
|
*
|
|
198
198
|
* @example
|
|
199
199
|
* ```typescript
|
|
200
200
|
* // Find formats by dimensions
|
|
201
|
-
* const formats = await creativeAgent.
|
|
201
|
+
* const formats = await creativeAgent.listFormatsLegacy();
|
|
202
202
|
* const banner = formats.find(f =>
|
|
203
203
|
* f.renders?.[0]?.dimensions?.width === 300 &&
|
|
204
204
|
* f.renders?.[0]?.dimensions?.height === 250
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/testing/test-helpers.ts"],"sourcesContent":["// Test agent helpers for easy examples and quick testing\n// These provide pre-configured access to AdCP's public test agent\n\nimport { ADCPMultiAgentClient } from '../core/ADCPMultiAgentClient';\nimport { CreativeAgentClient, STANDARD_CREATIVE_AGENTS } from '../core/CreativeAgentClient';\nimport type { AgentClient } from '../core/AgentClient';\nimport type { AgentConfig } from '../types';\n\n/**\n * Public test agent auth token\n * This token is public and rate-limited, for testing/examples only.\n */\nexport const TEST_AGENT_TOKEN = '1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ';\n\n/**\n * Public test agent configuration - MCP protocol\n * This is the raw configuration object if you need to customize it\n */\nexport const TEST_AGENT_MCP_CONFIG: AgentConfig = {\n id: 'test-agent-mcp',\n name: 'AdCP Public Test Agent (MCP)',\n agent_uri: 'https://test-agent.adcontextprotocol.org/mcp/',\n protocol: 'mcp',\n auth_token: TEST_AGENT_TOKEN,\n};\n\n/**\n * Public test agent configuration - A2A protocol\n * This is the raw configuration object if you need to customize it\n */\nexport const TEST_AGENT_A2A_CONFIG: AgentConfig = {\n id: 'test-agent-a2a',\n name: 'AdCP Public Test Agent (A2A)',\n agent_uri: 'https://test-agent.adcontextprotocol.org',\n protocol: 'a2a',\n auth_token: TEST_AGENT_TOKEN,\n};\n\n/**\n * Public test agent configuration without authentication - MCP protocol\n * Demonstrates unauthenticated agent access patterns\n */\nexport const TEST_AGENT_NO_AUTH_MCP_CONFIG: AgentConfig = {\n id: 'test-agent-no-auth-mcp',\n name: 'AdCP Public Test Agent (MCP, No Auth)',\n agent_uri: 'https://test-agent.adcontextprotocol.org/mcp/',\n protocol: 'mcp',\n};\n\n/**\n * Public test agent configuration without authentication - A2A protocol\n * Demonstrates unauthenticated agent access patterns\n */\nexport const TEST_AGENT_NO_AUTH_A2A_CONFIG: AgentConfig = {\n id: 'test-agent-no-auth-a2a',\n name: 'AdCP Public Test Agent (A2A, No Auth)',\n agent_uri: 'https://test-agent.adcontextprotocol.org',\n protocol: 'a2a',\n};\n\n/**\n * Pre-configured test agent client using MCP protocol.\n * Ready to use for examples, documentation, and quick testing.\n *\n * @example\n * ```typescript\n * import { testAgent } from '@adcp/sdk/testing';\n *\n * // Simple getProducts call\n * const result = await testAgent.getProducts({\n * brief: 'Coffee subscription service for busy professionals',\n * promoted_offering: 'Premium monthly coffee deliveries'\n * });\n *\n * if (result.success) {\n * console.log(`Found ${result.data.products.length} products`);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With AI test orchestration (natural language instructions)\n * const result = await testAgent.createMediaBuy({\n * brief: 'Test campaign',\n * promoted_offering: 'Wait 10 seconds before responding',\n * products: ['prod_123'],\n * budget: 10000\n * });\n * ```\n *\n * @remarks\n * This agent is rate-limited and intended for testing/examples only.\n * The auth token is public and may be rotated without notice.\n * DO NOT use in production applications.\n */\nexport const testAgent: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_MCP_CONFIG]).agent('test-agent-mcp');\n\n/**\n * Pre-configured test agent client using A2A protocol.\n * Identical functionality to testAgent but uses A2A instead of MCP.\n *\n * @example\n * ```typescript\n * import { testAgentA2A } from '@adcp/sdk/testing';\n *\n * const result = await testAgentA2A.getProducts({\n * brief: 'Sustainable fashion brands',\n * promoted_offering: 'Eco-friendly clothing'\n * });\n * ```\n *\n * @remarks\n * This agent is rate-limited and intended for testing/examples only.\n * The auth token is public and may be rotated without notice.\n * DO NOT use in production applications.\n */\nexport const testAgentA2A: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_A2A_CONFIG]).agent('test-agent-a2a');\n\n/**\n * Pre-configured test agent client WITHOUT authentication (MCP protocol).\n * Demonstrates what happens when calling authenticated endpoints without auth.\n * Useful for testing error handling and showing auth vs no-auth differences.\n *\n * @example\n * ```typescript\n * import { testAgentNoAuth } from '@adcp/sdk/testing';\n *\n * // This will fail with authentication error\n * try {\n * const result = await testAgentNoAuth.getProducts({\n * brief: 'Coffee subscription',\n * promoted_offering: 'Premium coffee'\n * });\n * } catch (error) {\n * console.log('Expected auth error:', error.message);\n * }\n * ```\n *\n * @remarks\n * This agent intentionally does NOT include authentication.\n * Use it to demonstrate authentication requirements and error handling.\n */\nexport const testAgentNoAuth: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_NO_AUTH_MCP_CONFIG]).agent(\n 'test-agent-no-auth-mcp'\n);\n\n/**\n * Pre-configured test agent client WITHOUT authentication (A2A protocol).\n * Demonstrates what happens when calling authenticated endpoints without auth.\n * Useful for testing error handling and showing auth vs no-auth differences.\n *\n * @example\n * ```typescript\n * import { testAgentNoAuthA2A } from '@adcp/sdk/testing';\n *\n * // Compare authenticated vs unauthenticated\n * import { testAgentA2A } from '@adcp/sdk/testing';\n *\n * // This works (has auth)\n * const authResult = await testAgentA2A.getProducts({ brief: 'Test' });\n *\n * // This fails (no auth)\n * const noAuthResult = await testAgentNoAuthA2A.getProducts({ brief: 'Test' });\n * ```\n *\n * @remarks\n * This agent intentionally does NOT include authentication.\n * Use it to demonstrate authentication requirements and error handling.\n */\nexport const testAgentNoAuthA2A: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_NO_AUTH_A2A_CONFIG]).agent(\n 'test-agent-no-auth-a2a'\n);\n\n/**\n * Multi-agent client with both test agents configured.\n * Useful for testing multi-agent patterns and protocol comparisons.\n *\n * @example\n * ```typescript\n * import { testAgentClient } from '@adcp/sdk/testing';\n *\n * // Access individual agents\n * const mcpAgent = testAgentClient.agent('test-agent-mcp');\n * const a2aAgent = testAgentClient.agent('test-agent-a2a');\n *\n * // Or use agent collection for parallel operations\n * const results = await testAgentClient.allAgents().getProducts({\n * brief: 'Premium coffee brands',\n * promoted_offering: 'Artisan coffee'\n * });\n * ```\n *\n * @remarks\n * This client is rate-limited and intended for testing/examples only.\n * DO NOT use in production applications.\n */\nexport const testAgentClient = new ADCPMultiAgentClient([TEST_AGENT_MCP_CONFIG, TEST_AGENT_A2A_CONFIG]);\n\n/**\n * Create a custom test agent configuration.\n * Useful when you need to modify the default test agent setup.\n *\n * @param overrides - Partial agent config to override defaults\n * @returns Complete agent configuration\n *\n * @example\n * ```typescript\n * import { createTestAgent, AdCPClient } from '@adcp/sdk/testing';\n *\n * // Use default test agent with custom ID\n * const config = createTestAgent({ id: 'my-test-agent' });\n * const client = new AdCPClient([config]);\n * ```\n *\n * @example\n * ```typescript\n * // Use A2A protocol instead of MCP\n * const config = createTestAgent({\n * protocol: 'a2a',\n * agent_uri: 'https://test-agent.adcontextprotocol.org'\n * });\n * ```\n */\nexport function createTestAgent(overrides?: Partial<AgentConfig>): AgentConfig {\n return {\n ...TEST_AGENT_MCP_CONFIG,\n ...overrides,\n };\n}\n\n// ====== CREATIVE AGENT HELPERS ======\n\n/**\n * Pre-configured creative agent client using MCP protocol.\n * Ready to use for creative generation and format listing.\n *\n * @example\n * ```typescript\n * import { creativeAgent } from '@adcp/sdk/testing';\n *\n * // List available creative formats\n * const formats = await creativeAgent.
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/testing/test-helpers.ts"],"sourcesContent":["// Test agent helpers for easy examples and quick testing\n// These provide pre-configured access to AdCP's public test agent\n\nimport { ADCPMultiAgentClient } from '../core/ADCPMultiAgentClient';\nimport { CreativeAgentClient, STANDARD_CREATIVE_AGENTS } from '../core/CreativeAgentClient';\nimport type { AgentClient } from '../core/AgentClient';\nimport type { AgentConfig } from '../types';\n\n/**\n * Public test agent auth token\n * This token is public and rate-limited, for testing/examples only.\n */\nexport const TEST_AGENT_TOKEN = '1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ';\n\n/**\n * Public test agent configuration - MCP protocol\n * This is the raw configuration object if you need to customize it\n */\nexport const TEST_AGENT_MCP_CONFIG: AgentConfig = {\n id: 'test-agent-mcp',\n name: 'AdCP Public Test Agent (MCP)',\n agent_uri: 'https://test-agent.adcontextprotocol.org/mcp/',\n protocol: 'mcp',\n auth_token: TEST_AGENT_TOKEN,\n};\n\n/**\n * Public test agent configuration - A2A protocol\n * This is the raw configuration object if you need to customize it\n */\nexport const TEST_AGENT_A2A_CONFIG: AgentConfig = {\n id: 'test-agent-a2a',\n name: 'AdCP Public Test Agent (A2A)',\n agent_uri: 'https://test-agent.adcontextprotocol.org',\n protocol: 'a2a',\n auth_token: TEST_AGENT_TOKEN,\n};\n\n/**\n * Public test agent configuration without authentication - MCP protocol\n * Demonstrates unauthenticated agent access patterns\n */\nexport const TEST_AGENT_NO_AUTH_MCP_CONFIG: AgentConfig = {\n id: 'test-agent-no-auth-mcp',\n name: 'AdCP Public Test Agent (MCP, No Auth)',\n agent_uri: 'https://test-agent.adcontextprotocol.org/mcp/',\n protocol: 'mcp',\n};\n\n/**\n * Public test agent configuration without authentication - A2A protocol\n * Demonstrates unauthenticated agent access patterns\n */\nexport const TEST_AGENT_NO_AUTH_A2A_CONFIG: AgentConfig = {\n id: 'test-agent-no-auth-a2a',\n name: 'AdCP Public Test Agent (A2A, No Auth)',\n agent_uri: 'https://test-agent.adcontextprotocol.org',\n protocol: 'a2a',\n};\n\n/**\n * Pre-configured test agent client using MCP protocol.\n * Ready to use for examples, documentation, and quick testing.\n *\n * @example\n * ```typescript\n * import { testAgent } from '@adcp/sdk/testing';\n *\n * // Simple getProducts call\n * const result = await testAgent.getProducts({\n * brief: 'Coffee subscription service for busy professionals',\n * promoted_offering: 'Premium monthly coffee deliveries'\n * });\n *\n * if (result.success) {\n * console.log(`Found ${result.data.products.length} products`);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With AI test orchestration (natural language instructions)\n * const result = await testAgent.createMediaBuy({\n * brief: 'Test campaign',\n * promoted_offering: 'Wait 10 seconds before responding',\n * products: ['prod_123'],\n * budget: 10000\n * });\n * ```\n *\n * @remarks\n * This agent is rate-limited and intended for testing/examples only.\n * The auth token is public and may be rotated without notice.\n * DO NOT use in production applications.\n */\nexport const testAgent: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_MCP_CONFIG]).agent('test-agent-mcp');\n\n/**\n * Pre-configured test agent client using A2A protocol.\n * Identical functionality to testAgent but uses A2A instead of MCP.\n *\n * @example\n * ```typescript\n * import { testAgentA2A } from '@adcp/sdk/testing';\n *\n * const result = await testAgentA2A.getProducts({\n * brief: 'Sustainable fashion brands',\n * promoted_offering: 'Eco-friendly clothing'\n * });\n * ```\n *\n * @remarks\n * This agent is rate-limited and intended for testing/examples only.\n * The auth token is public and may be rotated without notice.\n * DO NOT use in production applications.\n */\nexport const testAgentA2A: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_A2A_CONFIG]).agent('test-agent-a2a');\n\n/**\n * Pre-configured test agent client WITHOUT authentication (MCP protocol).\n * Demonstrates what happens when calling authenticated endpoints without auth.\n * Useful for testing error handling and showing auth vs no-auth differences.\n *\n * @example\n * ```typescript\n * import { testAgentNoAuth } from '@adcp/sdk/testing';\n *\n * // This will fail with authentication error\n * try {\n * const result = await testAgentNoAuth.getProducts({\n * brief: 'Coffee subscription',\n * promoted_offering: 'Premium coffee'\n * });\n * } catch (error) {\n * console.log('Expected auth error:', error.message);\n * }\n * ```\n *\n * @remarks\n * This agent intentionally does NOT include authentication.\n * Use it to demonstrate authentication requirements and error handling.\n */\nexport const testAgentNoAuth: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_NO_AUTH_MCP_CONFIG]).agent(\n 'test-agent-no-auth-mcp'\n);\n\n/**\n * Pre-configured test agent client WITHOUT authentication (A2A protocol).\n * Demonstrates what happens when calling authenticated endpoints without auth.\n * Useful for testing error handling and showing auth vs no-auth differences.\n *\n * @example\n * ```typescript\n * import { testAgentNoAuthA2A } from '@adcp/sdk/testing';\n *\n * // Compare authenticated vs unauthenticated\n * import { testAgentA2A } from '@adcp/sdk/testing';\n *\n * // This works (has auth)\n * const authResult = await testAgentA2A.getProducts({ brief: 'Test' });\n *\n * // This fails (no auth)\n * const noAuthResult = await testAgentNoAuthA2A.getProducts({ brief: 'Test' });\n * ```\n *\n * @remarks\n * This agent intentionally does NOT include authentication.\n * Use it to demonstrate authentication requirements and error handling.\n */\nexport const testAgentNoAuthA2A: AgentClient = new ADCPMultiAgentClient([TEST_AGENT_NO_AUTH_A2A_CONFIG]).agent(\n 'test-agent-no-auth-a2a'\n);\n\n/**\n * Multi-agent client with both test agents configured.\n * Useful for testing multi-agent patterns and protocol comparisons.\n *\n * @example\n * ```typescript\n * import { testAgentClient } from '@adcp/sdk/testing';\n *\n * // Access individual agents\n * const mcpAgent = testAgentClient.agent('test-agent-mcp');\n * const a2aAgent = testAgentClient.agent('test-agent-a2a');\n *\n * // Or use agent collection for parallel operations\n * const results = await testAgentClient.allAgents().getProducts({\n * brief: 'Premium coffee brands',\n * promoted_offering: 'Artisan coffee'\n * });\n * ```\n *\n * @remarks\n * This client is rate-limited and intended for testing/examples only.\n * DO NOT use in production applications.\n */\nexport const testAgentClient = new ADCPMultiAgentClient([TEST_AGENT_MCP_CONFIG, TEST_AGENT_A2A_CONFIG]);\n\n/**\n * Create a custom test agent configuration.\n * Useful when you need to modify the default test agent setup.\n *\n * @param overrides - Partial agent config to override defaults\n * @returns Complete agent configuration\n *\n * @example\n * ```typescript\n * import { createTestAgent, AdCPClient } from '@adcp/sdk/testing';\n *\n * // Use default test agent with custom ID\n * const config = createTestAgent({ id: 'my-test-agent' });\n * const client = new AdCPClient([config]);\n * ```\n *\n * @example\n * ```typescript\n * // Use A2A protocol instead of MCP\n * const config = createTestAgent({\n * protocol: 'a2a',\n * agent_uri: 'https://test-agent.adcontextprotocol.org'\n * });\n * ```\n */\nexport function createTestAgent(overrides?: Partial<AgentConfig>): AgentConfig {\n return {\n ...TEST_AGENT_MCP_CONFIG,\n ...overrides,\n };\n}\n\n// ====== CREATIVE AGENT HELPERS ======\n\n/**\n * Pre-configured creative agent client using MCP protocol.\n * Ready to use for creative generation and format listing.\n *\n * @example\n * ```typescript\n * import { creativeAgent } from '@adcp/sdk/testing';\n *\n * // List available creative formats\n * const formats = await creativeAgent.listFormatsLegacy();\n * console.log(`Found ${formats.length} creative formats`);\n * ```\n *\n * @example\n * ```typescript\n * // Find formats by dimensions\n * const formats = await creativeAgent.listFormatsLegacy();\n * const banner = formats.find(f =>\n * f.renders?.[0]?.dimensions?.width === 300 &&\n * f.renders?.[0]?.dimensions?.height === 250\n * );\n * ```\n *\n * @remarks\n * This is the official AdCP reference creative agent.\n * No authentication required for public endpoints.\n */\nexport const creativeAgent: CreativeAgentClient = new CreativeAgentClient({\n agentUrl: STANDARD_CREATIVE_AGENTS.ADCP_REFERENCE,\n protocol: 'mcp',\n});\n\n// Note: creativeAgentA2A is not exported because A2A protocol is not yet supported\n// on the creative agent. Only MCP is currently available.\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kCAAqC;AACrC,iCAA8D;AAQvD,MAAM,mBAAmB;AAMzB,MAAM,wBAAqC;AAAA,EAChD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AACd;AAMO,MAAM,wBAAqC;AAAA,EAChD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AACd;AAMO,MAAM,gCAA6C;AAAA,EACxD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AACZ;AAMO,MAAM,gCAA6C;AAAA,EACxD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AACZ;AAqCO,MAAM,YAAyB,IAAI,iDAAqB,CAAC,qBAAqB,CAAC,EAAE,MAAM,gBAAgB;AAqBvG,MAAM,eAA4B,IAAI,iDAAqB,CAAC,qBAAqB,CAAC,EAAE,MAAM,gBAAgB;AA0B1G,MAAM,kBAA+B,IAAI,iDAAqB,CAAC,6BAA6B,CAAC,EAAE;AAAA,EACpG;AACF;AAyBO,MAAM,qBAAkC,IAAI,iDAAqB,CAAC,6BAA6B,CAAC,EAAE;AAAA,EACvG;AACF;AAyBO,MAAM,kBAAkB,IAAI,iDAAqB,CAAC,uBAAuB,qBAAqB,CAAC;AA2B/F,SAAS,gBAAgB,WAA+C;AAC7E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AA+BO,MAAM,gBAAqC,IAAI,+CAAoB;AAAA,EACxE,UAAU,oDAAyB;AAAA,EACnC,UAAU;AACZ,CAAC;","names":[]}
|