@adcp/sdk 14.0.0-beta.10 → 14.0.0-beta.11
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/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +2 -1
- package/dist/lib/core/SingleAgentClient.d.ts +2 -1
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +113 -64
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/core/SingleAgentClient.mjs +113 -64
- package/dist/lib/core/SingleAgentClient.mjs.map +1 -1
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/protocols/a2a.d.mts +10 -3
- package/dist/lib/protocols/a2a.d.ts +10 -3
- package/dist/lib/protocols/a2a.d.ts.map +1 -1
- package/dist/lib/protocols/a2a.js +162 -34
- package/dist/lib/protocols/a2a.js.map +1 -1
- package/dist/lib/protocols/a2a.mjs +166 -34
- package/dist/lib/protocols/a2a.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/a2a-adapter.d.mts +59 -33
- package/dist/lib/server/a2a-adapter.d.ts +59 -33
- package/dist/lib/server/a2a-adapter.d.ts.map +1 -1
- package/dist/lib/server/a2a-adapter.js +278 -67
- package/dist/lib/server/a2a-adapter.js.map +1 -1
- package/dist/lib/server/a2a-adapter.mjs +280 -68
- package/dist/lib/server/a2a-adapter.mjs.map +1 -1
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +35 -108
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +37 -109
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/decisioning/index.d.mts +2 -0
- package/dist/lib/server/decisioning/index.d.ts +2 -0
- package/dist/lib/server/decisioning/index.d.ts.map +1 -1
- package/dist/lib/server/decisioning/index.js +5 -2
- package/dist/lib/server/decisioning/index.js.map +1 -1
- package/dist/lib/server/decisioning/index.mjs +3 -1
- package/dist/lib/server/decisioning/index.mjs.map +1 -1
- package/dist/lib/server/decisioning/response-summary.d.mts +33 -0
- package/dist/lib/server/decisioning/response-summary.d.ts +34 -0
- package/dist/lib/server/decisioning/response-summary.d.ts.map +1 -0
- package/dist/lib/server/decisioning/response-summary.js +62 -0
- package/dist/lib/server/decisioning/response-summary.js.map +1 -0
- package/dist/lib/server/decisioning/response-summary.mjs +37 -0
- package/dist/lib/server/decisioning/response-summary.mjs.map +1 -0
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +27 -5
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +27 -5
- package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
- package/dist/lib/server/decisioning/specialisms/sales.d.mts +7 -1
- package/dist/lib/server/decisioning/specialisms/sales.d.ts +7 -1
- 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 +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/responses.d.ts.map +1 -1
- package/dist/lib/server/responses.js +9 -1
- package/dist/lib/server/responses.js.map +1 -1
- package/dist/lib/server/responses.mjs +8 -1
- package/dist/lib/server/responses.mjs.map +1 -1
- package/dist/lib/testing/storyboard/context.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/context.js +9 -4
- package/dist/lib/testing/storyboard/context.js.map +1 -1
- package/dist/lib/testing/storyboard/context.mjs +9 -4
- package/dist/lib/testing/storyboard/context.mjs.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.js +28 -4
- package/dist/lib/testing/storyboard/request-builder.js.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.mjs +28 -4
- package/dist/lib/testing/storyboard/request-builder.mjs.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +21 -6
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.mjs +21 -6
- package/dist/lib/testing/storyboard/runner.mjs.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.js +18 -7
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/testing/storyboard/validations.mjs +18 -7
- package/dist/lib/testing/storyboard/validations.mjs.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.js +32 -20
- package/dist/lib/testing/storyboard/webhook-receiver.js.map +1 -1
- package/dist/lib/testing/storyboard/webhook-receiver.mjs +32 -20
- package/dist/lib/testing/storyboard/webhook-receiver.mjs.map +1 -1
- package/dist/lib/types/schemas.generated.d.ts +516 -516
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/types/schemas.generated.mjs.map +1 -1
- package/dist/lib/utils/a2a-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/a2a-artifacts.js +2 -2
- package/dist/lib/utils/a2a-artifacts.js.map +1 -1
- package/dist/lib/utils/a2a-artifacts.mjs +2 -2
- package/dist/lib/utils/a2a-artifacts.mjs.map +1 -1
- package/dist/lib/utils/a2a-discovery.d.mts +3 -3
- package/dist/lib/utils/a2a-discovery.d.ts +3 -3
- package/dist/lib/utils/a2a-discovery.js +1 -1
- package/dist/lib/utils/a2a-discovery.js.map +1 -1
- package/dist/lib/utils/a2a-discovery.mjs +1 -1
- package/dist/lib/utils/a2a-discovery.mjs.map +1 -1
- package/dist/lib/utils/tool-request-schemas.d.mts +31 -31
- package/dist/lib/utils/tool-request-schemas.d.ts +31 -31
- package/dist/lib/v2/projection/index.d.mts +2 -0
- package/dist/lib/v2/projection/index.d.ts +2 -0
- package/dist/lib/v2/projection/index.d.ts.map +1 -1
- package/dist/lib/v2/projection/index.js +3 -0
- package/dist/lib/v2/projection/index.js.map +1 -1
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/index.mjs.map +1 -1
- package/dist/lib/v2/projection/legacy-normalization.d.mts +24 -0
- package/dist/lib/v2/projection/legacy-normalization.d.ts +25 -0
- package/dist/lib/v2/projection/legacy-normalization.d.ts.map +1 -0
- package/dist/lib/v2/projection/legacy-normalization.js +32 -0
- package/dist/lib/v2/projection/legacy-normalization.js.map +1 -0
- package/dist/lib/v2/projection/legacy-normalization.mjs +8 -0
- package/dist/lib/v2/projection/legacy-normalization.mjs.map +1 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/guides/BUILD-AN-AGENT.md +42 -6
- package/docs/llms.txt +2 -2
- package/docs/migration-13-to-14.md +17 -0
- package/package.json +44 -41
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/server/responses.ts"],"sourcesContent":["/**\n * Typed response builders for AdCP MCP servers.\n *\n * @deprecated For new code, use `createAdcpServerFromPlatform` from\n * `@adcp/sdk/server` instead — it constructs wire responses internally\n * from your typed `DecisioningPlatform` return values, so adopters don't\n * touch these builders. The functions below remain exported for v5\n * adopters wiring raw MCP tool handlers (mid-migration), and for adopters\n * shaping bespoke tools the platform interface doesn't yet model. For new\n * v6 adopters, ignore this whole module — the framework handles wire\n * shaping.\n *\n * Each function takes typed data (compile-time checked against AdCP schemas)\n * and returns an MCP-compatible tool response with `content` (text summary)\n * + `structuredContent` (typed payload).\n *\n * The input parameter enforces the AdCP schema shape at compile time.\n * The return type is compatible with MCP SDK's CallToolResult.\n *\n * @example\n * ```typescript\n * import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n * import { legacyCapabilitiesResponse, legacyProductsResponse, adcpError } from '@adcp/sdk/server';\n * import { GetProductsRequestSchema } from '@adcp/sdk/schemas';\n *\n * const server = new McpServer({ name: 'My Agent', version: '1.0.0' });\n *\n * server.registerTool(\n * 'get_adcp_capabilities',\n * { inputSchema: {} },\n * async () => capabilitiesResponse({ supported_protocols: ['media_buy'] })\n * );\n *\n * server.registerTool(\n * 'get_products',\n * { inputSchema: GetProductsRequestSchema.shape },\n * async (params) => legacyProductsResponse({ products: myProducts, cache_scope: 'account' })\n * );\n * ```\n */\n\nimport type { GetAdCPCapabilitiesResponse } from '../types/tools.generated';\nimport type { GetMediaBuyDeliveryResponse } from '../types/tools.generated';\nimport type { RequireCacheScopeWhenProducts, ServerPayload } from '../types/server-payload';\nimport { validActionsForStatus } from './media-buy-helpers';\nimport type { CancelMediaBuyInput } from './media-buy-helpers';\nimport type {\n ListCreativeFormatsResponse,\n GetProductsResponse,\n CreateMediaBuySuccess,\n UpdateMediaBuySuccess,\n GetMediaBuysResponse,\n ProvidePerformanceFeedbackSuccess,\n BuildCreativeSuccess,\n BuildCreativeMultiSuccess,\n PreviewCreativeSingleResponse,\n PreviewCreativeBatchResponse,\n PreviewCreativeVariantResponse,\n GetCreativeDeliveryResponse,\n ListCreativesResponse,\n SyncCreativesError,\n SyncCreativesSuccess,\n GetSignalsResponse,\n ActivateSignalSuccess,\n ListAccountsResponse,\n ListPropertyListsResponse,\n ListCollectionListsResponse,\n ListContentStandardsResponse,\n GetPlanAuditLogsResponse,\n ReportUsageRequest,\n ReportUsageResponse,\n SyncAccountsResponse,\n SyncGovernanceResponse,\n} from '../types/tools.generated';\nimport type {\n AcquireRightsResponse,\n AcquireRightsAcquired,\n AcquireRightsPendingApproval,\n AcquireRightsRejected,\n UpdateRightsResponse,\n UpdateRightsSuccess,\n CreativeApprovalResponse,\n CreativeApproved,\n CreativeRejected,\n CreativePendingReview,\n CreativeApprovalError,\n} from '../types/core.generated';\n\n/**\n * MCP-compatible tool response shape.\n *\n * `structuredContent` is optional because error responses legitimately carry\n * only `content` (the human-readable error text) — forcing every wrapper to\n * fabricate an empty structuredContent obscures the success/error split.\n * All success builders in this file still populate it.\n *\n * Uses Record<string, unknown> for structuredContent to satisfy\n * MCP SDK's CallToolResult index signature requirement.\n */\nexport interface McpToolResponse {\n [key: string]: unknown;\n content: Array<{ type: 'text'; text: string }>;\n structuredContent?: Record<string, unknown>;\n}\n\n// MCP SDK requires structuredContent to have an index signature ({ [x: string]: unknown }).\n// Generated AdCP types are TypeScript interfaces without index signatures. At runtime,\n// JSON objects are always Records — this bridge is safe.\nexport function toStructuredContent(data: object): Record<string, unknown> {\n return data as unknown as Record<string, unknown>;\n}\n\nconst MEDIA_BUY_STATUS_VALUES = new Set([\n 'pending_creatives',\n 'pending_start',\n 'active',\n 'paused',\n 'completed',\n 'rejected',\n 'canceled',\n]);\n\nfunction completedStructuredContent(data: object, opts?: { splitMediaBuyStatus?: boolean }): Record<string, unknown> {\n const structured = { ...toStructuredContent(data) };\n if (\n opts?.splitMediaBuyStatus === true &&\n typeof structured.status === 'string' &&\n MEDIA_BUY_STATUS_VALUES.has(structured.status)\n ) {\n if (structured.media_buy_status === undefined) structured.media_buy_status = structured.status;\n delete structured.status;\n }\n if (structured.status === undefined) structured.status = 'completed';\n return structured;\n}\n\nfunction failedStructuredContent(data: object): Record<string, unknown> {\n const structured = { ...toStructuredContent(data) };\n if (structured.status === undefined) structured.status = 'failed';\n return structured;\n}\n\nfunction stripNotificationConfigSecrets<T extends object>(row: T): T {\n const notificationConfigs = (row as { notification_configs?: unknown }).notification_configs;\n if (!Array.isArray(notificationConfigs)) return row;\n return {\n ...row,\n notification_configs: notificationConfigs.map(config => {\n if (config == null || typeof config !== 'object') return config;\n const authentication = (config as { authentication?: unknown }).authentication;\n if (authentication == null || typeof authentication !== 'object') return config;\n const { credentials: _credentials, ...authenticationWithoutCredentials } = authentication as Record<\n string,\n unknown\n >;\n const stripped = { ...(config as Record<string, unknown>) };\n if (Object.keys(authenticationWithoutCredentials).length > 0) {\n stripped.authentication = authenticationWithoutCredentials;\n } else {\n delete stripped.authentication;\n }\n return stripped;\n }),\n };\n}\n\nfunction stripBusinessEntityBank<T extends object>(row: T, key: 'billing_entity' | 'invoice_recipient'): T {\n const entity = (row as Record<string, unknown>)[key];\n if (entity == null || typeof entity !== 'object') return row;\n if (!('bank' in entity)) return row;\n const { bank: _bank, ...entityWithoutBank } = entity as Record<string, unknown>;\n const stripped = { ...row } as Record<string, unknown>;\n if (Object.keys(entityWithoutBank).length > 0) {\n stripped[key] = entityWithoutBank;\n } else {\n delete stripped[key];\n }\n return stripped as T;\n}\n\nfunction stripAccountWriteOnlyFields<T extends object>(account: T): T {\n return stripBusinessEntityBank(stripNotificationConfigSecrets(account), 'billing_entity');\n}\n\nfunction stripAccountsWriteOnlyFields<T extends { accounts?: unknown }>(data: T): T {\n if (!Array.isArray(data.accounts)) return data;\n return {\n ...data,\n accounts: data.accounts.map(account =>\n account != null && typeof account === 'object' ? stripAccountWriteOnlyFields(account) : account\n ),\n };\n}\n\nfunction stripMediaBuyWriteOnlyFields<T extends object>(buy: T): T {\n let stripped = stripBusinessEntityBank(buy, 'invoice_recipient');\n const account = (stripped as { account?: unknown }).account;\n if (account == null || typeof account !== 'object') return stripped;\n return {\n ...stripped,\n account: stripAccountWriteOnlyFields(account),\n };\n}\n\nfunction stripMediaBuysWriteOnlyFields<T extends { media_buys?: unknown }>(data: T): T {\n if (!Array.isArray(data.media_buys)) return data;\n return {\n ...data,\n media_buys: data.media_buys.map(buy =>\n buy != null && typeof buy === 'object' ? stripMediaBuyWriteOnlyFields(buy) : buy\n ),\n };\n}\n\n// `setup` is only ever nested inside an `Account` (the IO-signing / pending_approval\n// path). A top-level `setup` on a media buy response means the builder read the\n// storyboard's \"setup.url\" shorthand as a top-level field. The strict handler types\n// would catch this, but `DomainHandler` accepts `Record<string, unknown>` for DX,\n// so the error has to move to runtime.\nfunction assertNoTopLevelSetup(data: unknown, builder: string): void {\n if (data != null && typeof data === 'object' && 'setup' in data) {\n throw new Error(\n `${builder}: \\`setup\\` is not a field on the media buy — it belongs inside \\`account.setup\\`. ` +\n `Move \\`{ setup: { url, message } }\\` to \\`{ account: { ..., setup: { url, message } } }\\`. ` +\n `The setup URL is a property of the Account (returned alongside \\`status: 'pending_approval'\\`), not the MediaBuy.`\n );\n }\n}\n\n/**\n * Build a get_adcp_capabilities response.\n *\n * `supported_protocols` lists AdCP domain protocols (media_buy, signals, governance, etc.),\n * NOT transport protocols (mcp, a2a).\n *\n * Stamps the v3 protocol envelope's required `status: \"completed\"` field at\n * the top level of `structuredContent`. Synchronous task responses MUST carry\n * `status` per `protocol-envelope.json` (AdCP #4876); without it the\n * `v3_envelope_integrity/no_legacy_status_fields` conformance step fails.\n * The status is injected here rather than added to `GetAdCPCapabilitiesResponse`\n * because it's an envelope concern, not a payload field — the wire shape and\n * the typed payload model live at different layers.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function capabilitiesResponse(\n data: ServerPayload<GetAdCPCapabilitiesResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? 'Agent capabilities retrieved' }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_products response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function productsResponse(\n data: RequireCacheScopeWhenProducts<ServerPayload<GetProductsResponse>>,\n summary?: string\n): McpToolResponse {\n const structured = completedStructuredContent(data);\n const defaultSummary =\n data.unchanged === true ? 'Product feed unchanged' : `Found ${(data.products ?? []).length} products`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: structured,\n };\n}\n\n/**\n * Build a successful create_media_buy response.\n *\n * Applies protocol defaults when not explicitly provided:\n * - `revision` defaults to `1` (initial revision for optimistic concurrency)\n * - `confirmed_at` defaults to the current ISO 8601 timestamp\n * - `valid_actions` populated from status via `validActionsForStatus()` when\n * `status` is provided but `valid_actions` is not\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function mediaBuyResponse(data: ServerPayload<CreateMediaBuySuccess>, summary?: string): McpToolResponse {\n assertNoTopLevelSetup(data, 'mediaBuyResponse');\n const withDefaults = { ...stripMediaBuyWriteOnlyFields(data) };\n const legacyStatus = (withDefaults as typeof withDefaults & { status?: unknown }).status;\n if (withDefaults.media_buy_status == null && typeof legacyStatus === 'string') {\n withDefaults.media_buy_status = legacyStatus as NonNullable<typeof withDefaults.media_buy_status>;\n }\n if (withDefaults.revision === undefined) {\n withDefaults.revision = 1;\n }\n if (withDefaults.confirmed_at === undefined) {\n withDefaults.confirmed_at = new Date().toISOString();\n }\n if (withDefaults.valid_actions === undefined && withDefaults.media_buy_status != null) {\n withDefaults.valid_actions = validActionsForStatus(withDefaults.media_buy_status);\n }\n return {\n content: [{ type: 'text', text: summary ?? `Media buy ${withDefaults.media_buy_id} created` }],\n structuredContent: completedStructuredContent(withDefaults, { splitMediaBuyStatus: true }),\n };\n}\n\n/**\n * Build a get_media_buy_delivery response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function deliveryResponse(data: ServerPayload<GetMediaBuyDeliveryResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text:\n summary ??\n `Delivery data for ${data.media_buy_deliveries.length} media buy${data.media_buy_deliveries.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_accounts response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listAccountsResponse(data: ServerPayload<ListAccountsResponse>, summary?: string): McpToolResponse {\n const stripped = stripAccountsWriteOnlyFields(data);\n return {\n content: [{ type: 'text', text: summary ?? `Found ${stripped.accounts.length} accounts` }],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\n/**\n * Build a list_creative_formats response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listCreativeFormatsResponse(\n data: ServerPayload<ListCreativeFormatsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? `Found ${data.formats.length} creative formats` }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful update_media_buy response.\n *\n * When `media_buy_status` is provided but `valid_actions` is not, auto-populates\n * `valid_actions` from `validActionsForStatus()`.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function updateMediaBuyResponse(data: ServerPayload<UpdateMediaBuySuccess>, summary?: string): McpToolResponse {\n assertNoTopLevelSetup(data, 'updateMediaBuyResponse');\n const withDefaults = { ...stripBusinessEntityBank(data, 'invoice_recipient') };\n const legacyStatus = (withDefaults as typeof withDefaults & { status?: unknown }).status;\n if (withDefaults.media_buy_status == null && typeof legacyStatus === 'string') {\n withDefaults.media_buy_status = legacyStatus as NonNullable<typeof withDefaults.media_buy_status>;\n }\n if (withDefaults.valid_actions === undefined && withDefaults.media_buy_status != null) {\n withDefaults.valid_actions = validActionsForStatus(withDefaults.media_buy_status);\n }\n return {\n content: [{ type: 'text', text: summary ?? `Media buy ${withDefaults.media_buy_id} updated` }],\n structuredContent: completedStructuredContent(withDefaults, { splitMediaBuyStatus: true }),\n };\n}\n\n/**\n * Build a get_media_buys response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function getMediaBuysResponse(data: ServerPayload<GetMediaBuysResponse>, summary?: string): McpToolResponse {\n if (Array.isArray(data.media_buys)) {\n for (const buy of data.media_buys) {\n assertNoTopLevelSetup(buy, 'getMediaBuysResponse');\n }\n }\n const stripped = stripMediaBuysWriteOnlyFields(data);\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${stripped.media_buys.length} media buy${stripped.media_buys.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\n/**\n * Build a successful provide_performance_feedback response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function performanceFeedbackResponse(\n data: ServerPayload<ProvidePerformanceFeedbackSuccess>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? 'Performance feedback accepted' }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful build_creative response (single format).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function buildCreativeResponse(data: ServerPayload<BuildCreativeSuccess>, summary?: string): McpToolResponse {\n // Optional-chain the default summary — handler responses that drop\n // `format_id` still reach the wire-level schema validator (which names\n // the missing field), instead of crashing the dispatcher here with an\n // opaque `Cannot read properties of undefined (reading 'id')`.\n const formatId = data.creative_manifest?.format_id?.id;\n return {\n content: [{ type: 'text', text: summary ?? (formatId ? `Creative built: ${formatId}` : 'Creative built') }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful build_creative response (multi-format).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function buildCreativeMultiResponse(\n data: ServerPayload<BuildCreativeMultiSuccess>,\n summary?: string\n): McpToolResponse {\n const count = data.creative_manifests?.length ?? 0;\n return {\n content: [{ type: 'text', text: summary ?? `Built ${count} creative formats` }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a preview_creative response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function previewCreativeResponse(\n data: PreviewCreativeSingleResponse | PreviewCreativeBatchResponse | PreviewCreativeVariantResponse,\n summary?: string\n): McpToolResponse {\n const defaultSummary =\n data.response_type === 'single'\n ? (() => {\n const n = (data as PreviewCreativeSingleResponse).previews.length;\n return `Preview generated: ${n} variant${n === 1 ? '' : 's'}`;\n })()\n : data.response_type === 'batch'\n ? (() => {\n const n = (data as PreviewCreativeBatchResponse).results.length;\n return `Batch preview: ${n} result${n === 1 ? '' : 's'}`;\n })()\n : `Variant preview generated`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_creative_delivery response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function creativeDeliveryResponse(\n data: ServerPayload<GetCreativeDeliveryResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? `Creative delivery data for ${data.currency} report` }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_creatives response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listCreativesResponse(data: ServerPayload<ListCreativesResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text:\n summary ?? `Found ${data.query_summary.total_matching} creatives (${data.query_summary.returned} returned)`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_property_lists response. The governance property-list catalog\n * is returned under the required `lists` wrapper — use this helper so\n * handlers can't accidentally emit a bare array at the top level (which the\n * storyboard runner flags as shape drift).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listPropertyListsResponse(\n data: ServerPayload<ListPropertyListsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${data.lists.length} property list${data.lists.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_collection_lists response. Companion to\n * `listPropertyListsResponse` — same `lists` wrapper shape; parallel\n * governance surface for program-level collections.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listCollectionListsResponse(\n data: ServerPayload<ListCollectionListsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${data.lists.length} collection list${data.lists.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_content_standards response. The response type is a union\n * (success branch with `standards` array, error branch with `errors`) —\n * the helper wraps either shape verbatim; schema-level invariants are\n * enforced at wire validation, not here.\n *\n * Discriminates on `'standards' in data` rather than `'errors' in data` so\n * a legitimate success response that happens to carry advisory `errors`\n * still gets a counted summary. The error-only text fires only when\n * `standards` is absent. Mirrors `acquireRightsResponse`'s success-first\n * discrimination pattern a few screens down.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listContentStandardsResponse(\n data: ServerPayload<ListContentStandardsResponse>,\n summary?: string\n): McpToolResponse {\n const defaultSummary =\n 'standards' in data\n ? `Found ${data.standards.length} content standard${data.standards.length === 1 ? '' : 's'}`\n : 'Content standards lookup error';\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_plan_audit_logs response. Wraps the audit data array under\n * the required `plans` key — handlers that return a bare array trip the\n * storyboard runner's shape-drift hint.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function getPlanAuditLogsResponse(\n data: ServerPayload<GetPlanAuditLogsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Audit data for ${data.plans.length} plan${data.plans.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\ntype SyncCreativesResponsePayload = ServerPayload<SyncCreativesSuccess> | ServerPayload<SyncCreativesError>;\n\nfunction isSyncCreativesErrorPayload(data: SyncCreativesResponsePayload): data is ServerPayload<SyncCreativesError> {\n return (\n Array.isArray((data as { errors?: unknown }).errors) && !Array.isArray((data as { creatives?: unknown }).creatives)\n );\n}\n\n/**\n * Build a sync_creatives response. Accepts both row-level success payloads\n * and operation-level error payloads. If a payload includes `creatives`, the\n * builder treats it as success-shaped even when advisory row errors are also\n * present; operation-level errors are the errors-only arm.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function syncCreativesResponse(data: SyncCreativesResponsePayload, summary?: string): McpToolResponse {\n if (isSyncCreativesErrorPayload(data)) {\n const firstError = data.errors[0];\n const defaultSummary = firstError ? `${firstError.code}: ${firstError.message}` : 'Sync creatives failed';\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n isError: true,\n structuredContent: failedStructuredContent(data),\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Synced ${data.creatives.length} creative${data.creatives.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_signals response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function getSignalsResponse(data: ServerPayload<GetSignalsResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${(data.signals ?? []).length} signal${(data.signals ?? []).length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful activate_signal response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function activateSignalResponse(data: ServerPayload<ActivateSignalSuccess>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text:\n summary ??\n `Signal activated across ${data.deployments.length} deployment${data.deployments.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a cancel response for update_media_buy with action: 'cancel'.\n *\n * Eliminates the cancellation metadata trap by requiring `canceled_by`\n * and auto-setting `canceled_at`, `status: 'canceled'`, and `valid_actions: []`.\n *\n * Note: `cancellation` is not yet on the `UpdateMediaBuySuccess` generated type\n * (it exists on the full `MediaBuy` entity). This builder constructs the response\n * as a plain object to include it. When the upstream schema adds `cancellation`\n * to the update response, this can be tightened.\n *\n * @example\n * ```typescript\n * server.registerTool(\n * 'update_media_buy',\n * { inputSchema: UpdateMediaBuyRequestSchema.shape },\n * async (params) => {\n * if (params.action === 'cancel') {\n * return cancelMediaBuyResponse({\n * media_buy_id: params.media_buy_id,\n * canceled_by: 'buyer',\n * revision: currentRevision + 1,\n * });\n * }\n * // ... handle other actions\n * }\n * );\n * ```\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function cancelMediaBuyResponse(input: CancelMediaBuyInput, summary?: string): McpToolResponse {\n const cancellation: Record<string, unknown> = {\n canceled_at: input.canceled_at ?? new Date().toISOString(),\n canceled_by: input.canceled_by,\n };\n if (input.reason !== undefined) {\n cancellation.reason = input.reason;\n }\n\n const data: Record<string, unknown> = {\n media_buy_id: input.media_buy_id,\n status: 'canceled',\n valid_actions: [],\n revision: input.revision,\n cancellation,\n };\n if (input.affected_packages !== undefined) {\n data.affected_packages = input.affected_packages;\n }\n if (input.sandbox !== undefined) {\n data.sandbox = input.sandbox;\n }\n\n return {\n content: [{ type: 'text', text: summary ?? `Media buy ${input.media_buy_id} canceled` }],\n structuredContent: completedStructuredContent(data, { splitMediaBuyStatus: true }),\n };\n}\n\n/**\n * Build an `acquire_rights` response. Thin envelope wrapper — enforces the\n * discriminated union on `status` at the type level, wraps the domain object\n * in `content` + `structuredContent`, nothing else. Schema-level constraints\n * (credential length, schemes cardinality, required-field presence) belong\n * in wire-level Zod validation, not here.\n *\n * Enable dev-time enforcement via\n * `createAdcpServer({ validation: { responses: 'strict' } })` until it\n * becomes the default.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsResponse(data: ServerPayload<AcquireRightsResponse>, summary?: string): McpToolResponse {\n const dataAsAny = data as AcquireRightsResponse & { rights_status?: string; rights_id?: string };\n const defaultSummary =\n 'errors' in data\n ? 'Rights acquisition error'\n : dataAsAny.rights_status === 'acquired'\n ? `Rights ${dataAsAny.rights_id} acquired`\n : dataAsAny.rights_status === 'rejected'\n ? `Rights ${dataAsAny.rights_id} rejected`\n : `Rights ${dataAsAny.rights_id} pending approval`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Per-variant constructor — builds an `AcquireRightsAcquired` success response\n * and wraps it. Cleaner autocomplete than `acquireRightsResponse({ rights_status: 'acquired', ... })`\n * because a coding agent typing `acquireRightsAcqu…` gets the required-fields\n * shape directly without reading a 4-variant union.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsAcquired(\n data: Omit<AcquireRightsAcquired, 'rights_status'>,\n summary?: string\n): McpToolResponse {\n return acquireRightsResponse({ ...data, rights_status: 'acquired' } as unknown as AcquireRightsResponse, summary);\n}\n\n/** Per-variant constructor for the `pending_approval` branch. */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsPendingApproval(\n data: Omit<AcquireRightsPendingApproval, 'rights_status'>,\n summary?: string\n): McpToolResponse {\n return acquireRightsResponse(\n { ...data, rights_status: 'pending_approval' } as unknown as AcquireRightsResponse,\n summary\n );\n}\n\n/** Per-variant constructor for the `rejected` branch. */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsRejected(\n data: Omit<AcquireRightsRejected, 'rights_status'>,\n summary?: string\n): McpToolResponse {\n return acquireRightsResponse({ ...data, rights_status: 'rejected' } as unknown as AcquireRightsResponse, summary);\n}\n\n/**\n * Build an `update_rights` response. Wraps a `UpdateRightsResponse` (success\n * or error arm — discriminated structurally on `errors` presence) in the\n * standard `content` + `structuredContent` envelope. The framework auto-\n * applies this wrapper for v6 typed-platform handlers; direct callers are\n * v5 raw-handler adopters only.\n *\n * Mirrors `acquireRightsResponse`'s shape conventions (success-first\n * default summary, error pass-through).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function updateRightsResponse(data: ServerPayload<UpdateRightsResponse>, summary?: string): McpToolResponse {\n const defaultSummary =\n 'errors' in data\n ? 'Rights update error'\n : data.implementation_date == null\n ? `Rights ${data.rights_id} update pending approval`\n : `Rights ${data.rights_id} updated`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Per-variant constructor for the success arm. The wire spec doesn't\n * carry a `status` discriminator on `update_rights` (unlike\n * `acquire_rights`); success is identified structurally by absence of\n * `errors`. The narrow constructor is still useful — it gives autocomplete\n * the success-shape fields (`terms`, `generation_credentials`,\n * `rights_constraint`) without crossing the union.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function updateRightsSuccess(data: ServerPayload<UpdateRightsSuccess>, summary?: string): McpToolResponse {\n return updateRightsResponse(data as unknown as UpdateRightsResponse, summary);\n}\n\n/**\n * Build a `creative_approval` webhook response.\n *\n * Unlike the other builders in this module, `creative_approval` is NOT an\n * MCP/A2A tool — the spec models it as an HTTP webhook. The buyer POSTs\n * a `CreativeApprovalRequest` to the `approval_webhook` URL returned in\n * `acquire_rights`; the brand-rights agent reviews and returns one of four\n * arms (Approved / Rejected / PendingReview / Error). Adopters wire this\n * builder into their HTTP server's response path — see the\n * `BrandRightsPlatform.reviewCreativeApproval` Platform method and the\n * skill at `skills/build-brand-rights-agent/SKILL.md` for the receiver\n * pattern.\n *\n * Returns the raw JSON-serializable payload, NOT an `McpToolResponse` —\n * webhooks have no `content` envelope. Adopters serialize this to JSON and\n * write to the HTTP response body.\n */\nexport function creativeApprovalResponse(data: CreativeApprovalResponse): CreativeApprovalResponse {\n return data;\n}\n\n/** Per-variant constructor for the `approved` branch — webhook payload. */\nexport function creativeApprovalApproved(data: Omit<CreativeApproved, 'status'>): CreativeApproved {\n return { ...data, status: 'approved' } as CreativeApproved;\n}\n\n/** Per-variant constructor for the `rejected` branch — webhook payload. */\nexport function creativeApprovalRejected(data: Omit<CreativeRejected, 'status'>): CreativeRejected {\n return { ...data, status: 'rejected' } as CreativeRejected;\n}\n\n/** Per-variant constructor for the `pending_review` branch — webhook payload. */\nexport function creativeApprovalPendingReview(data: Omit<CreativePendingReview, 'status'>): CreativePendingReview {\n return { ...data, status: 'pending_review' } as CreativePendingReview;\n}\n\n/** Per-variant constructor for the multi-error arm — webhook payload. */\nexport function creativeApprovalError(data: CreativeApprovalError): CreativeApprovalError {\n return data;\n}\n\n/**\n * Build a `sync_accounts` response. Thin envelope wrapper accepting the full\n * `SyncAccountsResponse` union; error payloads pass through.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function syncAccountsResponse(data: ServerPayload<SyncAccountsResponse>, summary?: string): McpToolResponse {\n const stripped = 'accounts' in data ? stripAccountsWriteOnlyFields(data) : data;\n const defaultSummary =\n 'errors' in stripped\n ? 'Account sync error'\n : `Synced ${stripped.accounts?.length ?? 0} account${stripped.accounts?.length === 1 ? '' : 's'}`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\n/**\n * Build a sync_governance response. The spec permits two top-level shapes\n * (success / error); the type union enforces discrimination on `status`.\n *\n * Strips `governance_agents[i].authentication` from every row before emit:\n * the spec marks `authentication.credentials` write-only (the buyer sends\n * the bearer; the seller persists it for outbound `check_governance` calls\n * but MUST NOT echo it back). The natural `{ ...entry.governance_agents[i] }`\n * echo idiom would compile silently against the typed return shape and ship\n * credentials over the wire AND into the idempotency replay cache, arming\n * the buyer (and any subsequent caller hitting the same key) to impersonate\n * the seller against the governance agent. Strip is enforced at the wire-\n * emit boundary so both v5 (`opts.accounts.syncGovernance`) and v6\n * (`AccountStore.syncGovernance`) paths are protected.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function syncGovernanceResponse(data: ServerPayload<SyncGovernanceResponse>, summary?: string): McpToolResponse {\n const stripped = stripGovernanceAgentSecrets(data);\n return {\n content: [{ type: 'text', text: summary ?? 'Governance registration synced' }],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\nfunction stripGovernanceAgentSecrets(\n data: ServerPayload<SyncGovernanceResponse>\n): ServerPayload<SyncGovernanceResponse> {\n if (!('accounts' in data) || !Array.isArray(data.accounts)) return data;\n return {\n ...data,\n accounts: data.accounts.map(row => {\n if (!row.governance_agents) return row;\n return {\n ...row,\n // AdCP 3.1.0-beta.2 narrowed the wire shape to `{ url }` only;\n // `categories` was removed (per-agent category signaling moved\n // out of band) and `authentication` remains write-only. Project\n // explicitly to defeat JS / `as any` smuggling of either field.\n governance_agents: row.governance_agents.map(a => ({ url: a.url })),\n };\n }),\n };\n}\n\n/**\n * Build a `report_usage` response. Thin envelope wrapper. Schema-level\n * `accepted` requiredness is enforced at the type level (via\n * `ReportUsageResponse.accepted: number`) and at wire-level validation;\n * this builder does not re-assert it.\n *\n * @example\n * ```typescript\n * // Explicit:\n * reportUsage: async (params) =>\n * reportUsageResponse({ accepted: 8, errors: [{ usage_index: 2, message: 'invalid' }] })\n *\n * // Ack every usage[] row with optional errors (shortcut):\n * reportUsage: async (params) => reportUsageResponse.acceptAll(params)\n * ```\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function reportUsageResponse(data: ServerPayload<ReportUsageResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n { type: 'text', text: summary ?? `Accepted ${data.accepted} usage record${data.accepted === 1 ? '' : 's'}` },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Shortcut for the common case: accept all rows in the request, optionally\n * minus any `errors[]` the caller computed. Sets\n * `accepted = (request.usage?.length ?? 0) - errors.length`.\n *\n * Use with honest errors — passing no `errors` when rows failed validation\n * is lying to buyers and the audit trail.\n */\nreportUsageResponse.acceptAll = function acceptAll(\n request: ReportUsageRequest,\n opts?: { errors?: ReportUsageResponse['errors']; summary?: string }\n): McpToolResponse {\n const total = request.usage?.length ?? 0;\n const errors = opts?.errors ?? [];\n const accepted = Math.max(0, total - errors.length);\n return reportUsageResponse(\n {\n status: errors.length > 0 ? 'failed' : 'completed',\n accepted,\n ...(errors.length > 0 ? { errors } : {}),\n } as ReportUsageResponse,\n opts?.summary\n );\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/server/responses.ts"],"sourcesContent":["/**\n * Typed response builders for AdCP MCP servers.\n *\n * @deprecated For new code, use `createAdcpServerFromPlatform` from\n * `@adcp/sdk/server` instead — it constructs wire responses internally\n * from your typed `DecisioningPlatform` return values, so adopters don't\n * touch these builders. The functions below remain exported for v5\n * adopters wiring raw MCP tool handlers (mid-migration), and for adopters\n * shaping bespoke tools the platform interface doesn't yet model. For new\n * v6 adopters, ignore this whole module — the framework handles wire\n * shaping.\n *\n * Each function takes typed data (compile-time checked against AdCP schemas)\n * and returns an MCP-compatible tool response with `content` (text summary)\n * + `structuredContent` (typed payload).\n *\n * The input parameter enforces the AdCP schema shape at compile time.\n * The return type is compatible with MCP SDK's CallToolResult.\n *\n * @example\n * ```typescript\n * import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n * import { legacyCapabilitiesResponse, legacyProductsResponse, adcpError } from '@adcp/sdk/server';\n * import { GetProductsRequestSchema } from '@adcp/sdk/schemas';\n *\n * const server = new McpServer({ name: 'My Agent', version: '1.0.0' });\n *\n * server.registerTool(\n * 'get_adcp_capabilities',\n * { inputSchema: {} },\n * async () => capabilitiesResponse({ supported_protocols: ['media_buy'] })\n * );\n *\n * server.registerTool(\n * 'get_products',\n * { inputSchema: GetProductsRequestSchema.shape },\n * async (params) => legacyProductsResponse({ products: myProducts, cache_scope: 'account' })\n * );\n * ```\n */\n\nimport type { GetAdCPCapabilitiesResponse } from '../types/tools.generated';\nimport type { GetMediaBuyDeliveryResponse } from '../types/tools.generated';\nimport type { RequireCacheScopeWhenProducts, ServerPayload } from '../types/server-payload';\nimport { validActionsForStatus } from './media-buy-helpers';\nimport type { CancelMediaBuyInput } from './media-buy-helpers';\nimport type {\n ListCreativeFormatsResponse,\n GetProductsResponse,\n CreateMediaBuySuccess,\n UpdateMediaBuySuccess,\n GetMediaBuysResponse,\n ProvidePerformanceFeedbackSuccess,\n BuildCreativeSuccess,\n BuildCreativeMultiSuccess,\n PreviewCreativeSingleResponse,\n PreviewCreativeBatchResponse,\n PreviewCreativeVariantResponse,\n GetCreativeDeliveryResponse,\n ListCreativesResponse,\n SyncCreativesError,\n SyncCreativesSuccess,\n GetSignalsResponse,\n ActivateSignalSuccess,\n ListAccountsResponse,\n ListPropertyListsResponse,\n ListCollectionListsResponse,\n ListContentStandardsResponse,\n GetPlanAuditLogsResponse,\n ReportUsageRequest,\n ReportUsageResponse,\n SyncAccountsResponse,\n SyncGovernanceResponse,\n} from '../types/tools.generated';\nimport type {\n AcquireRightsResponse,\n AcquireRightsAcquired,\n AcquireRightsPendingApproval,\n AcquireRightsRejected,\n UpdateRightsResponse,\n UpdateRightsSuccess,\n CreativeApprovalResponse,\n CreativeApproved,\n CreativeRejected,\n CreativePendingReview,\n CreativeApprovalError,\n} from '../types/core.generated';\n\n/**\n * MCP-compatible tool response shape.\n *\n * `structuredContent` is optional because error responses legitimately carry\n * only `content` (the human-readable error text) — forcing every wrapper to\n * fabricate an empty structuredContent obscures the success/error split.\n * All success builders in this file still populate it.\n *\n * Uses Record<string, unknown> for structuredContent to satisfy\n * MCP SDK's CallToolResult index signature requirement.\n */\nexport interface McpToolResponse {\n [key: string]: unknown;\n content: Array<{ type: 'text'; text: string }>;\n structuredContent?: Record<string, unknown>;\n}\n\n// Explicit summaries are framework metadata, not wire data. Keep the marker\n// out-of-band so later framework-owned response rewrites can preserve an\n// adopter disclosure without serializing bookkeeping into structuredContent.\nconst explicitResponseSummaries = new WeakMap<object, string>();\n\n/** @internal */\nexport function _getExplicitResponseSummary(response: McpToolResponse): string | undefined {\n return explicitResponseSummaries.get(response);\n}\n\n// MCP SDK requires structuredContent to have an index signature ({ [x: string]: unknown }).\n// Generated AdCP types are TypeScript interfaces without index signatures. At runtime,\n// JSON objects are always Records — this bridge is safe.\nexport function toStructuredContent(data: object): Record<string, unknown> {\n return data as unknown as Record<string, unknown>;\n}\n\nconst MEDIA_BUY_STATUS_VALUES = new Set([\n 'pending_creatives',\n 'pending_start',\n 'active',\n 'paused',\n 'completed',\n 'rejected',\n 'canceled',\n]);\n\nfunction completedStructuredContent(data: object, opts?: { splitMediaBuyStatus?: boolean }): Record<string, unknown> {\n const structured = { ...toStructuredContent(data) };\n if (\n opts?.splitMediaBuyStatus === true &&\n typeof structured.status === 'string' &&\n MEDIA_BUY_STATUS_VALUES.has(structured.status)\n ) {\n if (structured.media_buy_status === undefined) structured.media_buy_status = structured.status;\n delete structured.status;\n }\n if (structured.status === undefined) structured.status = 'completed';\n return structured;\n}\n\nfunction failedStructuredContent(data: object): Record<string, unknown> {\n const structured = { ...toStructuredContent(data) };\n if (structured.status === undefined) structured.status = 'failed';\n return structured;\n}\n\nfunction stripNotificationConfigSecrets<T extends object>(row: T): T {\n const notificationConfigs = (row as { notification_configs?: unknown }).notification_configs;\n if (!Array.isArray(notificationConfigs)) return row;\n return {\n ...row,\n notification_configs: notificationConfigs.map(config => {\n if (config == null || typeof config !== 'object') return config;\n const authentication = (config as { authentication?: unknown }).authentication;\n if (authentication == null || typeof authentication !== 'object') return config;\n const { credentials: _credentials, ...authenticationWithoutCredentials } = authentication as Record<\n string,\n unknown\n >;\n const stripped = { ...(config as Record<string, unknown>) };\n if (Object.keys(authenticationWithoutCredentials).length > 0) {\n stripped.authentication = authenticationWithoutCredentials;\n } else {\n delete stripped.authentication;\n }\n return stripped;\n }),\n };\n}\n\nfunction stripBusinessEntityBank<T extends object>(row: T, key: 'billing_entity' | 'invoice_recipient'): T {\n const entity = (row as Record<string, unknown>)[key];\n if (entity == null || typeof entity !== 'object') return row;\n if (!('bank' in entity)) return row;\n const { bank: _bank, ...entityWithoutBank } = entity as Record<string, unknown>;\n const stripped = { ...row } as Record<string, unknown>;\n if (Object.keys(entityWithoutBank).length > 0) {\n stripped[key] = entityWithoutBank;\n } else {\n delete stripped[key];\n }\n return stripped as T;\n}\n\nfunction stripAccountWriteOnlyFields<T extends object>(account: T): T {\n return stripBusinessEntityBank(stripNotificationConfigSecrets(account), 'billing_entity');\n}\n\nfunction stripAccountsWriteOnlyFields<T extends { accounts?: unknown }>(data: T): T {\n if (!Array.isArray(data.accounts)) return data;\n return {\n ...data,\n accounts: data.accounts.map(account =>\n account != null && typeof account === 'object' ? stripAccountWriteOnlyFields(account) : account\n ),\n };\n}\n\nfunction stripMediaBuyWriteOnlyFields<T extends object>(buy: T): T {\n let stripped = stripBusinessEntityBank(buy, 'invoice_recipient');\n const account = (stripped as { account?: unknown }).account;\n if (account == null || typeof account !== 'object') return stripped;\n return {\n ...stripped,\n account: stripAccountWriteOnlyFields(account),\n };\n}\n\nfunction stripMediaBuysWriteOnlyFields<T extends { media_buys?: unknown }>(data: T): T {\n if (!Array.isArray(data.media_buys)) return data;\n return {\n ...data,\n media_buys: data.media_buys.map(buy =>\n buy != null && typeof buy === 'object' ? stripMediaBuyWriteOnlyFields(buy) : buy\n ),\n };\n}\n\n// `setup` is only ever nested inside an `Account` (the IO-signing / pending_approval\n// path). A top-level `setup` on a media buy response means the builder read the\n// storyboard's \"setup.url\" shorthand as a top-level field. The strict handler types\n// would catch this, but `DomainHandler` accepts `Record<string, unknown>` for DX,\n// so the error has to move to runtime.\nfunction assertNoTopLevelSetup(data: unknown, builder: string): void {\n if (data != null && typeof data === 'object' && 'setup' in data) {\n throw new Error(\n `${builder}: \\`setup\\` is not a field on the media buy — it belongs inside \\`account.setup\\`. ` +\n `Move \\`{ setup: { url, message } }\\` to \\`{ account: { ..., setup: { url, message } } }\\`. ` +\n `The setup URL is a property of the Account (returned alongside \\`status: 'pending_approval'\\`), not the MediaBuy.`\n );\n }\n}\n\n/**\n * Build a get_adcp_capabilities response.\n *\n * `supported_protocols` lists AdCP domain protocols (media_buy, signals, governance, etc.),\n * NOT transport protocols (mcp, a2a).\n *\n * Stamps the v3 protocol envelope's required `status: \"completed\"` field at\n * the top level of `structuredContent`. Synchronous task responses MUST carry\n * `status` per `protocol-envelope.json` (AdCP #4876); without it the\n * `v3_envelope_integrity/no_legacy_status_fields` conformance step fails.\n * The status is injected here rather than added to `GetAdCPCapabilitiesResponse`\n * because it's an envelope concern, not a payload field — the wire shape and\n * the typed payload model live at different layers.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function capabilitiesResponse(\n data: ServerPayload<GetAdCPCapabilitiesResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? 'Agent capabilities retrieved' }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_products response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function productsResponse(\n data: RequireCacheScopeWhenProducts<ServerPayload<GetProductsResponse>>,\n summary?: string\n): McpToolResponse {\n const structured = completedStructuredContent(data);\n const defaultSummary =\n data.unchanged === true ? 'Product feed unchanged' : `Found ${(data.products ?? []).length} products`;\n const response: McpToolResponse = {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: structured,\n };\n if (summary !== undefined) explicitResponseSummaries.set(response, summary);\n return response;\n}\n\n/**\n * Build a successful create_media_buy response.\n *\n * Applies protocol defaults when not explicitly provided:\n * - `revision` defaults to `1` (initial revision for optimistic concurrency)\n * - `confirmed_at` defaults to the current ISO 8601 timestamp\n * - `valid_actions` populated from status via `validActionsForStatus()` when\n * `status` is provided but `valid_actions` is not\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function mediaBuyResponse(data: ServerPayload<CreateMediaBuySuccess>, summary?: string): McpToolResponse {\n assertNoTopLevelSetup(data, 'mediaBuyResponse');\n const withDefaults = { ...stripMediaBuyWriteOnlyFields(data) };\n const legacyStatus = (withDefaults as typeof withDefaults & { status?: unknown }).status;\n if (withDefaults.media_buy_status == null && typeof legacyStatus === 'string') {\n withDefaults.media_buy_status = legacyStatus as NonNullable<typeof withDefaults.media_buy_status>;\n }\n if (withDefaults.revision === undefined) {\n withDefaults.revision = 1;\n }\n if (withDefaults.confirmed_at === undefined) {\n withDefaults.confirmed_at = new Date().toISOString();\n }\n if (withDefaults.valid_actions === undefined && withDefaults.media_buy_status != null) {\n withDefaults.valid_actions = validActionsForStatus(withDefaults.media_buy_status);\n }\n return {\n content: [{ type: 'text', text: summary ?? `Media buy ${withDefaults.media_buy_id} created` }],\n structuredContent: completedStructuredContent(withDefaults, { splitMediaBuyStatus: true }),\n };\n}\n\n/**\n * Build a get_media_buy_delivery response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function deliveryResponse(data: ServerPayload<GetMediaBuyDeliveryResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text:\n summary ??\n `Delivery data for ${data.media_buy_deliveries.length} media buy${data.media_buy_deliveries.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_accounts response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listAccountsResponse(data: ServerPayload<ListAccountsResponse>, summary?: string): McpToolResponse {\n const stripped = stripAccountsWriteOnlyFields(data);\n return {\n content: [{ type: 'text', text: summary ?? `Found ${stripped.accounts.length} accounts` }],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\n/**\n * Build a list_creative_formats response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listCreativeFormatsResponse(\n data: ServerPayload<ListCreativeFormatsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? `Found ${data.formats.length} creative formats` }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful update_media_buy response.\n *\n * When `media_buy_status` is provided but `valid_actions` is not, auto-populates\n * `valid_actions` from `validActionsForStatus()`.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function updateMediaBuyResponse(data: ServerPayload<UpdateMediaBuySuccess>, summary?: string): McpToolResponse {\n assertNoTopLevelSetup(data, 'updateMediaBuyResponse');\n const withDefaults = { ...stripBusinessEntityBank(data, 'invoice_recipient') };\n const legacyStatus = (withDefaults as typeof withDefaults & { status?: unknown }).status;\n if (withDefaults.media_buy_status == null && typeof legacyStatus === 'string') {\n withDefaults.media_buy_status = legacyStatus as NonNullable<typeof withDefaults.media_buy_status>;\n }\n if (withDefaults.valid_actions === undefined && withDefaults.media_buy_status != null) {\n withDefaults.valid_actions = validActionsForStatus(withDefaults.media_buy_status);\n }\n return {\n content: [{ type: 'text', text: summary ?? `Media buy ${withDefaults.media_buy_id} updated` }],\n structuredContent: completedStructuredContent(withDefaults, { splitMediaBuyStatus: true }),\n };\n}\n\n/**\n * Build a get_media_buys response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function getMediaBuysResponse(data: ServerPayload<GetMediaBuysResponse>, summary?: string): McpToolResponse {\n if (Array.isArray(data.media_buys)) {\n for (const buy of data.media_buys) {\n assertNoTopLevelSetup(buy, 'getMediaBuysResponse');\n }\n }\n const stripped = stripMediaBuysWriteOnlyFields(data);\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${stripped.media_buys.length} media buy${stripped.media_buys.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\n/**\n * Build a successful provide_performance_feedback response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function performanceFeedbackResponse(\n data: ServerPayload<ProvidePerformanceFeedbackSuccess>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? 'Performance feedback accepted' }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful build_creative response (single format).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function buildCreativeResponse(data: ServerPayload<BuildCreativeSuccess>, summary?: string): McpToolResponse {\n // Optional-chain the default summary — handler responses that drop\n // `format_id` still reach the wire-level schema validator (which names\n // the missing field), instead of crashing the dispatcher here with an\n // opaque `Cannot read properties of undefined (reading 'id')`.\n const formatId = data.creative_manifest?.format_id?.id;\n return {\n content: [{ type: 'text', text: summary ?? (formatId ? `Creative built: ${formatId}` : 'Creative built') }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful build_creative response (multi-format).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function buildCreativeMultiResponse(\n data: ServerPayload<BuildCreativeMultiSuccess>,\n summary?: string\n): McpToolResponse {\n const count = data.creative_manifests?.length ?? 0;\n return {\n content: [{ type: 'text', text: summary ?? `Built ${count} creative formats` }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a preview_creative response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function previewCreativeResponse(\n data: PreviewCreativeSingleResponse | PreviewCreativeBatchResponse | PreviewCreativeVariantResponse,\n summary?: string\n): McpToolResponse {\n const defaultSummary =\n data.response_type === 'single'\n ? (() => {\n const n = (data as PreviewCreativeSingleResponse).previews.length;\n return `Preview generated: ${n} variant${n === 1 ? '' : 's'}`;\n })()\n : data.response_type === 'batch'\n ? (() => {\n const n = (data as PreviewCreativeBatchResponse).results.length;\n return `Batch preview: ${n} result${n === 1 ? '' : 's'}`;\n })()\n : `Variant preview generated`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_creative_delivery response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function creativeDeliveryResponse(\n data: ServerPayload<GetCreativeDeliveryResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [{ type: 'text', text: summary ?? `Creative delivery data for ${data.currency} report` }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_creatives response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listCreativesResponse(data: ServerPayload<ListCreativesResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text:\n summary ?? `Found ${data.query_summary.total_matching} creatives (${data.query_summary.returned} returned)`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_property_lists response. The governance property-list catalog\n * is returned under the required `lists` wrapper — use this helper so\n * handlers can't accidentally emit a bare array at the top level (which the\n * storyboard runner flags as shape drift).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listPropertyListsResponse(\n data: ServerPayload<ListPropertyListsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${data.lists.length} property list${data.lists.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_collection_lists response. Companion to\n * `listPropertyListsResponse` — same `lists` wrapper shape; parallel\n * governance surface for program-level collections.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listCollectionListsResponse(\n data: ServerPayload<ListCollectionListsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${data.lists.length} collection list${data.lists.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a list_content_standards response. The response type is a union\n * (success branch with `standards` array, error branch with `errors`) —\n * the helper wraps either shape verbatim; schema-level invariants are\n * enforced at wire validation, not here.\n *\n * Discriminates on `'standards' in data` rather than `'errors' in data` so\n * a legitimate success response that happens to carry advisory `errors`\n * still gets a counted summary. The error-only text fires only when\n * `standards` is absent. Mirrors `acquireRightsResponse`'s success-first\n * discrimination pattern a few screens down.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function listContentStandardsResponse(\n data: ServerPayload<ListContentStandardsResponse>,\n summary?: string\n): McpToolResponse {\n const defaultSummary =\n 'standards' in data\n ? `Found ${data.standards.length} content standard${data.standards.length === 1 ? '' : 's'}`\n : 'Content standards lookup error';\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_plan_audit_logs response. Wraps the audit data array under\n * the required `plans` key — handlers that return a bare array trip the\n * storyboard runner's shape-drift hint.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function getPlanAuditLogsResponse(\n data: ServerPayload<GetPlanAuditLogsResponse>,\n summary?: string\n): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Audit data for ${data.plans.length} plan${data.plans.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\ntype SyncCreativesResponsePayload = ServerPayload<SyncCreativesSuccess> | ServerPayload<SyncCreativesError>;\n\nfunction isSyncCreativesErrorPayload(data: SyncCreativesResponsePayload): data is ServerPayload<SyncCreativesError> {\n return (\n Array.isArray((data as { errors?: unknown }).errors) && !Array.isArray((data as { creatives?: unknown }).creatives)\n );\n}\n\n/**\n * Build a sync_creatives response. Accepts both row-level success payloads\n * and operation-level error payloads. If a payload includes `creatives`, the\n * builder treats it as success-shaped even when advisory row errors are also\n * present; operation-level errors are the errors-only arm.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function syncCreativesResponse(data: SyncCreativesResponsePayload, summary?: string): McpToolResponse {\n if (isSyncCreativesErrorPayload(data)) {\n const firstError = data.errors[0];\n const defaultSummary = firstError ? `${firstError.code}: ${firstError.message}` : 'Sync creatives failed';\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n isError: true,\n structuredContent: failedStructuredContent(data),\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Synced ${data.creatives.length} creative${data.creatives.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a get_signals response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function getSignalsResponse(data: ServerPayload<GetSignalsResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text: summary ?? `Found ${(data.signals ?? []).length} signal${(data.signals ?? []).length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a successful activate_signal response.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function activateSignalResponse(data: ServerPayload<ActivateSignalSuccess>, summary?: string): McpToolResponse {\n return {\n content: [\n {\n type: 'text',\n text:\n summary ??\n `Signal activated across ${data.deployments.length} deployment${data.deployments.length === 1 ? '' : 's'}`,\n },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Build a cancel response for update_media_buy with action: 'cancel'.\n *\n * Eliminates the cancellation metadata trap by requiring `canceled_by`\n * and auto-setting `canceled_at`, `status: 'canceled'`, and `valid_actions: []`.\n *\n * Note: `cancellation` is not yet on the `UpdateMediaBuySuccess` generated type\n * (it exists on the full `MediaBuy` entity). This builder constructs the response\n * as a plain object to include it. When the upstream schema adds `cancellation`\n * to the update response, this can be tightened.\n *\n * @example\n * ```typescript\n * server.registerTool(\n * 'update_media_buy',\n * { inputSchema: UpdateMediaBuyRequestSchema.shape },\n * async (params) => {\n * if (params.action === 'cancel') {\n * return cancelMediaBuyResponse({\n * media_buy_id: params.media_buy_id,\n * canceled_by: 'buyer',\n * revision: currentRevision + 1,\n * });\n * }\n * // ... handle other actions\n * }\n * );\n * ```\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function cancelMediaBuyResponse(input: CancelMediaBuyInput, summary?: string): McpToolResponse {\n const cancellation: Record<string, unknown> = {\n canceled_at: input.canceled_at ?? new Date().toISOString(),\n canceled_by: input.canceled_by,\n };\n if (input.reason !== undefined) {\n cancellation.reason = input.reason;\n }\n\n const data: Record<string, unknown> = {\n media_buy_id: input.media_buy_id,\n status: 'canceled',\n valid_actions: [],\n revision: input.revision,\n cancellation,\n };\n if (input.affected_packages !== undefined) {\n data.affected_packages = input.affected_packages;\n }\n if (input.sandbox !== undefined) {\n data.sandbox = input.sandbox;\n }\n\n return {\n content: [{ type: 'text', text: summary ?? `Media buy ${input.media_buy_id} canceled` }],\n structuredContent: completedStructuredContent(data, { splitMediaBuyStatus: true }),\n };\n}\n\n/**\n * Build an `acquire_rights` response. Thin envelope wrapper — enforces the\n * discriminated union on `status` at the type level, wraps the domain object\n * in `content` + `structuredContent`, nothing else. Schema-level constraints\n * (credential length, schemes cardinality, required-field presence) belong\n * in wire-level Zod validation, not here.\n *\n * Enable dev-time enforcement via\n * `createAdcpServer({ validation: { responses: 'strict' } })` until it\n * becomes the default.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsResponse(data: ServerPayload<AcquireRightsResponse>, summary?: string): McpToolResponse {\n const dataAsAny = data as AcquireRightsResponse & { rights_status?: string; rights_id?: string };\n const defaultSummary =\n 'errors' in data\n ? 'Rights acquisition error'\n : dataAsAny.rights_status === 'acquired'\n ? `Rights ${dataAsAny.rights_id} acquired`\n : dataAsAny.rights_status === 'rejected'\n ? `Rights ${dataAsAny.rights_id} rejected`\n : `Rights ${dataAsAny.rights_id} pending approval`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Per-variant constructor — builds an `AcquireRightsAcquired` success response\n * and wraps it. Cleaner autocomplete than `acquireRightsResponse({ rights_status: 'acquired', ... })`\n * because a coding agent typing `acquireRightsAcqu…` gets the required-fields\n * shape directly without reading a 4-variant union.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsAcquired(\n data: Omit<AcquireRightsAcquired, 'rights_status'>,\n summary?: string\n): McpToolResponse {\n return acquireRightsResponse({ ...data, rights_status: 'acquired' } as unknown as AcquireRightsResponse, summary);\n}\n\n/** Per-variant constructor for the `pending_approval` branch. */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsPendingApproval(\n data: Omit<AcquireRightsPendingApproval, 'rights_status'>,\n summary?: string\n): McpToolResponse {\n return acquireRightsResponse(\n { ...data, rights_status: 'pending_approval' } as unknown as AcquireRightsResponse,\n summary\n );\n}\n\n/** Per-variant constructor for the `rejected` branch. */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function acquireRightsRejected(\n data: Omit<AcquireRightsRejected, 'rights_status'>,\n summary?: string\n): McpToolResponse {\n return acquireRightsResponse({ ...data, rights_status: 'rejected' } as unknown as AcquireRightsResponse, summary);\n}\n\n/**\n * Build an `update_rights` response. Wraps a `UpdateRightsResponse` (success\n * or error arm — discriminated structurally on `errors` presence) in the\n * standard `content` + `structuredContent` envelope. The framework auto-\n * applies this wrapper for v6 typed-platform handlers; direct callers are\n * v5 raw-handler adopters only.\n *\n * Mirrors `acquireRightsResponse`'s shape conventions (success-first\n * default summary, error pass-through).\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function updateRightsResponse(data: ServerPayload<UpdateRightsResponse>, summary?: string): McpToolResponse {\n const defaultSummary =\n 'errors' in data\n ? 'Rights update error'\n : data.implementation_date == null\n ? `Rights ${data.rights_id} update pending approval`\n : `Rights ${data.rights_id} updated`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Per-variant constructor for the success arm. The wire spec doesn't\n * carry a `status` discriminator on `update_rights` (unlike\n * `acquire_rights`); success is identified structurally by absence of\n * `errors`. The narrow constructor is still useful — it gives autocomplete\n * the success-shape fields (`terms`, `generation_credentials`,\n * `rights_constraint`) without crossing the union.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function updateRightsSuccess(data: ServerPayload<UpdateRightsSuccess>, summary?: string): McpToolResponse {\n return updateRightsResponse(data as unknown as UpdateRightsResponse, summary);\n}\n\n/**\n * Build a `creative_approval` webhook response.\n *\n * Unlike the other builders in this module, `creative_approval` is NOT an\n * MCP/A2A tool — the spec models it as an HTTP webhook. The buyer POSTs\n * a `CreativeApprovalRequest` to the `approval_webhook` URL returned in\n * `acquire_rights`; the brand-rights agent reviews and returns one of four\n * arms (Approved / Rejected / PendingReview / Error). Adopters wire this\n * builder into their HTTP server's response path — see the\n * `BrandRightsPlatform.reviewCreativeApproval` Platform method and the\n * skill at `skills/build-brand-rights-agent/SKILL.md` for the receiver\n * pattern.\n *\n * Returns the raw JSON-serializable payload, NOT an `McpToolResponse` —\n * webhooks have no `content` envelope. Adopters serialize this to JSON and\n * write to the HTTP response body.\n */\nexport function creativeApprovalResponse(data: CreativeApprovalResponse): CreativeApprovalResponse {\n return data;\n}\n\n/** Per-variant constructor for the `approved` branch — webhook payload. */\nexport function creativeApprovalApproved(data: Omit<CreativeApproved, 'status'>): CreativeApproved {\n return { ...data, status: 'approved' } as CreativeApproved;\n}\n\n/** Per-variant constructor for the `rejected` branch — webhook payload. */\nexport function creativeApprovalRejected(data: Omit<CreativeRejected, 'status'>): CreativeRejected {\n return { ...data, status: 'rejected' } as CreativeRejected;\n}\n\n/** Per-variant constructor for the `pending_review` branch — webhook payload. */\nexport function creativeApprovalPendingReview(data: Omit<CreativePendingReview, 'status'>): CreativePendingReview {\n return { ...data, status: 'pending_review' } as CreativePendingReview;\n}\n\n/** Per-variant constructor for the multi-error arm — webhook payload. */\nexport function creativeApprovalError(data: CreativeApprovalError): CreativeApprovalError {\n return data;\n}\n\n/**\n * Build a `sync_accounts` response. Thin envelope wrapper accepting the full\n * `SyncAccountsResponse` union; error payloads pass through.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function syncAccountsResponse(data: ServerPayload<SyncAccountsResponse>, summary?: string): McpToolResponse {\n const stripped = 'accounts' in data ? stripAccountsWriteOnlyFields(data) : data;\n const defaultSummary =\n 'errors' in stripped\n ? 'Account sync error'\n : `Synced ${stripped.accounts?.length ?? 0} account${stripped.accounts?.length === 1 ? '' : 's'}`;\n return {\n content: [{ type: 'text', text: summary ?? defaultSummary }],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\n/**\n * Build a sync_governance response. The spec permits two top-level shapes\n * (success / error); the type union enforces discrimination on `status`.\n *\n * Strips `governance_agents[i].authentication` from every row before emit:\n * the spec marks `authentication.credentials` write-only (the buyer sends\n * the bearer; the seller persists it for outbound `check_governance` calls\n * but MUST NOT echo it back). The natural `{ ...entry.governance_agents[i] }`\n * echo idiom would compile silently against the typed return shape and ship\n * credentials over the wire AND into the idempotency replay cache, arming\n * the buyer (and any subsequent caller hitting the same key) to impersonate\n * the seller against the governance agent. Strip is enforced at the wire-\n * emit boundary so both v5 (`opts.accounts.syncGovernance`) and v6\n * (`AccountStore.syncGovernance`) paths are protected.\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function syncGovernanceResponse(data: ServerPayload<SyncGovernanceResponse>, summary?: string): McpToolResponse {\n const stripped = stripGovernanceAgentSecrets(data);\n return {\n content: [{ type: 'text', text: summary ?? 'Governance registration synced' }],\n structuredContent: completedStructuredContent(stripped),\n };\n}\n\nfunction stripGovernanceAgentSecrets(\n data: ServerPayload<SyncGovernanceResponse>\n): ServerPayload<SyncGovernanceResponse> {\n if (!('accounts' in data) || !Array.isArray(data.accounts)) return data;\n return {\n ...data,\n accounts: data.accounts.map(row => {\n if (!row.governance_agents) return row;\n return {\n ...row,\n // AdCP 3.1.0-beta.2 narrowed the wire shape to `{ url }` only;\n // `categories` was removed (per-agent category signaling moved\n // out of band) and `authentication` remains write-only. Project\n // explicitly to defeat JS / `as any` smuggling of either field.\n governance_agents: row.governance_agents.map(a => ({ url: a.url })),\n };\n }),\n };\n}\n\n/**\n * Build a `report_usage` response. Thin envelope wrapper. Schema-level\n * `accepted` requiredness is enforced at the type level (via\n * `ReportUsageResponse.accepted: number`) and at wire-level validation;\n * this builder does not re-assert it.\n *\n * @example\n * ```typescript\n * // Explicit:\n * reportUsage: async (params) =>\n * reportUsageResponse({ accepted: 8, errors: [{ usage_index: 2, message: 'invalid' }] })\n *\n * // Ack every usage[] row with optional errors (shortcut):\n * reportUsage: async (params) => reportUsageResponse.acceptAll(params)\n * ```\n */\n/** @deprecated v6: `createAdcpServerFromPlatform` constructs wire responses from typed platform returns. Direct use is for v5 raw-handler adopters mid-migration only. */\nexport function reportUsageResponse(data: ServerPayload<ReportUsageResponse>, summary?: string): McpToolResponse {\n return {\n content: [\n { type: 'text', text: summary ?? `Accepted ${data.accepted} usage record${data.accepted === 1 ? '' : 's'}` },\n ],\n structuredContent: completedStructuredContent(data),\n };\n}\n\n/**\n * Shortcut for the common case: accept all rows in the request, optionally\n * minus any `errors[]` the caller computed. Sets\n * `accepted = (request.usage?.length ?? 0) - errors.length`.\n *\n * Use with honest errors — passing no `errors` when rows failed validation\n * is lying to buyers and the audit trail.\n */\nreportUsageResponse.acceptAll = function acceptAll(\n request: ReportUsageRequest,\n opts?: { errors?: ReportUsageResponse['errors']; summary?: string }\n): McpToolResponse {\n const total = request.usage?.length ?? 0;\n const errors = opts?.errors ?? [];\n const accepted = Math.max(0, total - errors.length);\n return reportUsageResponse(\n {\n status: errors.length > 0 ? 'failed' : 'completed',\n accepted,\n ...(errors.length > 0 ? { errors } : {}),\n } as ReportUsageResponse,\n opts?.summary\n );\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/lib/testing/storyboard/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAQtG,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA2EnE,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/lib/testing/storyboard/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -119,13 +119,18 @@ const CONTEXT_EXTRACTORS = {
|
|
|
119
119
|
return { account_id: accounts[0].account_id };
|
|
120
120
|
},
|
|
121
121
|
get_products(data) {
|
|
122
|
-
const d = data;
|
|
122
|
+
const d = asRecord(data);
|
|
123
123
|
const products = d?.products;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
const extracted = {};
|
|
125
|
+
if (products?.[0]) {
|
|
126
|
+
extracted.products = products;
|
|
127
|
+
if (products[0].product_id) extracted.product_id = products[0].product_id;
|
|
128
|
+
}
|
|
127
129
|
const proposals = d?.proposals;
|
|
128
130
|
if (proposals?.[0]?.proposal_id) extracted.proposal_id = proposals[0].proposal_id;
|
|
131
|
+
if (d?.wholesale_feed_version !== void 0) extracted.wholesale_feed_version = d.wholesale_feed_version;
|
|
132
|
+
if (d?.pricing_version !== void 0) extracted.pricing_version = d.pricing_version;
|
|
133
|
+
if (d?.cache_scope !== void 0) extracted.cache_scope = d.cache_scope;
|
|
129
134
|
return extracted;
|
|
130
135
|
},
|
|
131
136
|
list_products(data) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/testing/storyboard/context.ts"],"sourcesContent":["/**\n * Context propagation for storyboard steps.\n *\n * After each successful step, known IDs and references are extracted\n * from the response and accumulated in a StoryboardContext. Before\n * executing a step, context values are injected into the request via\n * \"$context.<key>\" placeholders.\n *\n * This convention-based approach avoids requiring YAML enrichment\n * (context_outputs/context_inputs) while still enabling stateful flows.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { StoryboardContext, ContextOutput, ContextInput, ContextProvenanceEntry } from './types';\nimport { resolvePath, setPath } from './path';\nimport { getAuthoritativeMediaBuyStatus } from '../../utils/media-buy-status';\n\n// ────────────────────────────────────────────────────────────\n// Context extraction: pull known IDs from task responses\n// ────────────────────────────────────────────────────────────\n\ntype ContextExtractor = (data: unknown) => Record<string, unknown>;\n\nconst PRODUCT_CONTEXT_KEYS = [\n 'product',\n 'products',\n 'product_id',\n 'pricing_option',\n 'pricing_option_id',\n 'feed_version',\n 'pricing_version',\n];\nconst PROPOSAL_CONTEXT_KEYS = [\n 'proposal',\n 'proposals',\n 'proposal_id',\n 'proposal_status',\n 'proposal_kind',\n 'terms_digest',\n 'proposal_terms_digest',\n];\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction readMediaBuyStatus(record: Record<string, unknown> | undefined): unknown {\n return getAuthoritativeMediaBuyStatus(record);\n}\n\nfunction readMediaBuyFields(data: unknown): { mediaBuyId?: unknown; status?: unknown } {\n const outer = asRecord(data);\n const nested = asRecord(outer?.media_buy);\n return {\n mediaBuyId: nested?.media_buy_id ?? outer?.media_buy_id,\n status: readMediaBuyStatus(nested) ?? readMediaBuyStatus(outer),\n };\n}\n\nfunction readProposalFields(proposal: Record<string, unknown> | undefined): Record<string, unknown> {\n if (!proposal) return {};\n const extracted: Record<string, unknown> = {};\n if (proposal.proposal_id) extracted.proposal_id = proposal.proposal_id;\n if (proposal.proposal_status) extracted.proposal_status = proposal.proposal_status;\n if (proposal.proposal_kind) extracted.proposal_kind = proposal.proposal_kind;\n if (proposal.terms_digest) {\n extracted.terms_digest = proposal.terms_digest;\n extracted.proposal_terms_digest = proposal.terms_digest;\n }\n return extracted;\n}\n\nfunction readCompactMediaBuyFields(data: unknown): Record<string, unknown> {\n const outer = asRecord(data);\n if (!outer || outer.status !== 'completed') return {};\n const mediaBuyId = outer.media_buy_id;\n // Compact responses use `status` for task completion and\n // `media_buy_status` for lifecycle state. Never reinterpret a bare\n // `status: completed` as the MediaBuy's status when the optional lifecycle\n // field is absent.\n const status = readMediaBuyStatus({ media_buy_status: outer.media_buy_status });\n const acceptedProposal = asRecord(outer.accepted_proposal);\n const extracted: Record<string, unknown> = {};\n if (mediaBuyId) extracted.media_buy_id = mediaBuyId;\n if (status) extracted.media_buy_status = status;\n if (outer.revision) {\n extracted.revision = outer.revision;\n extracted.media_buy_revision = outer.revision;\n }\n if (acceptedProposal) {\n Object.assign(extracted, readProposalFields(acceptedProposal));\n }\n if (Array.isArray(outer.available_actions)) extracted.available_actions = outer.available_actions;\n return extracted;\n}\n\nexport const CONTEXT_EXTRACTORS: Record<string, ContextExtractor> = {\n sync_accounts(data) {\n const d = data as Record<string, unknown> | undefined;\n const accounts = d?.accounts as Array<Record<string, unknown>> | undefined;\n if (!accounts?.[0]) return {};\n const first = accounts[0];\n const extracted: Record<string, unknown> = {};\n if (first.account_id) extracted.account_id = first.account_id;\n if (first.status) extracted.account_status = first.status;\n // Build an account reference for downstream steps. Only include fields\n // the response actually carries — propagating `operator: undefined`\n // would serialize away on the wire (JSON.stringify drops undefined),\n // leaving the natural-key arm short of its required `operator` field\n // (#1419). The brand/operator pair stays paired or both absent.\n const accountRef: Record<string, unknown> = {};\n if (first.brand) accountRef.brand = first.brand;\n if (first.operator) accountRef.operator = first.operator;\n extracted.account = accountRef;\n return extracted;\n },\n\n list_accounts(data) {\n const d = data as Record<string, unknown> | undefined;\n const accounts = d?.accounts as Array<Record<string, unknown>> | undefined;\n if (!accounts?.[0]) return {};\n return { account_id: accounts[0].account_id };\n },\n\n get_products(data) {\n const d = data as Record<string, unknown> | undefined;\n const products = d?.products as Array<Record<string, unknown>> | undefined;\n if (!products?.[0]) return {};\n const extracted: Record<string, unknown> = { products };\n if (products[0].product_id) extracted.product_id = products[0].product_id;\n // Extract proposal_id if proposals are returned\n const proposals = d?.proposals as Array<Record<string, unknown>> | undefined;\n if (proposals?.[0]?.proposal_id) extracted.proposal_id = proposals[0].proposal_id;\n return extracted;\n },\n\n list_products(data) {\n const d = asRecord(data);\n const products = d?.products as Array<Record<string, unknown>> | undefined;\n if (!products?.[0]) return {};\n const first = products[0];\n const pricingOptions = first.pricing_options as Array<Record<string, unknown>> | undefined;\n const extracted: Record<string, unknown> = {};\n if (first.product_id) extracted.product_id = first.product_id;\n if (pricingOptions?.[0]) {\n if (pricingOptions[0].pricing_option_id) extracted.pricing_option_id = pricingOptions[0].pricing_option_id;\n }\n if (d?.feed_version) extracted.feed_version = d.feed_version;\n if (d?.pricing_version) extracted.pricing_version = d.pricing_version;\n return extracted;\n },\n\n request_proposals(data) {\n const d = asRecord(data);\n const proposals = d?.proposals as Array<Record<string, unknown>> | undefined;\n if (!proposals?.[0]) return {};\n return readProposalFields(proposals[0]);\n },\n\n refine_proposals(data) {\n const d = asRecord(data);\n const results = d?.results as Array<Record<string, unknown>> | undefined;\n if (!results?.length) return {};\n const proposalResult = results.find(result => asRecord(result.proposal) || Array.isArray(result.proposals));\n const proposal =\n asRecord(proposalResult?.proposal) ??\n (proposalResult?.proposals as Array<Record<string, unknown>> | undefined)?.[0] ??\n undefined;\n return proposal ? readProposalFields(proposal) : {};\n },\n\n decline_proposals() {\n return {};\n },\n\n buy_products(data) {\n return readCompactMediaBuyFields(data);\n },\n\n accept_proposal(data) {\n return readCompactMediaBuyFields(data);\n },\n\n control_media_buy(data) {\n return readCompactMediaBuyFields(data);\n },\n\n create_media_buy(data) {\n const { mediaBuyId, status } = readMediaBuyFields(data);\n const extracted: Record<string, unknown> = {};\n if (mediaBuyId) extracted.media_buy_id = mediaBuyId;\n if (status) extracted.media_buy_status = status;\n return extracted;\n },\n\n update_media_buy(data) {\n const { mediaBuyId, status } = readMediaBuyFields(data);\n const extracted: Record<string, unknown> = {};\n if (mediaBuyId) extracted.media_buy_id = mediaBuyId;\n if (status) extracted.media_buy_status = status;\n return extracted;\n },\n\n get_media_buys(data) {\n const d = data as Record<string, unknown> | undefined;\n const buys = d?.media_buys as Array<Record<string, unknown>> | undefined;\n if (!buys?.[0]) return {};\n // Don't extract a single-resource ID from a broad-list page. When\n // has_more: true the caller is mid-pagination walk and buys[0] is not\n // the canonical buy — extracting it here causes the enricher to inject\n // media_buy_ids: [that_id] on the next step, turning a continuation into\n // an ID-lookup. Conservative: === true matches the codebase convention\n // (absent has_more is treated as terminal, not as a list-in-progress).\n const pagination = d?.pagination as Record<string, unknown> | undefined;\n if (pagination?.has_more === true) return {};\n const extracted: Record<string, unknown> = {\n media_buy_id: buys[0].media_buy_id,\n media_buy_status: readMediaBuyStatus(buys[0]),\n };\n if (buys[0].revision) {\n extracted.revision = buys[0].revision;\n extracted.media_buy_revision = buys[0].revision;\n }\n if (Array.isArray(buys[0].available_actions)) extracted.available_actions = buys[0].available_actions;\n return extracted;\n },\n\n list_creative_formats(data) {\n const d = data as Record<string, unknown> | undefined;\n const formats = d?.formats as Array<Record<string, unknown>> | undefined;\n if (!formats?.[0]) return {};\n return {\n formats,\n format_id: formats[0].format_id,\n };\n },\n\n build_creative(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n // Single response: creative_manifest\n const manifest = d?.creative_manifest as Record<string, unknown> | undefined;\n if (manifest) {\n extracted.creative_manifest = manifest;\n if (manifest.format_id) extracted.format_id = manifest.format_id;\n }\n // Multi response: creative_manifests\n const manifests = d?.creative_manifests as Array<Record<string, unknown>> | undefined;\n if (manifests?.[0]) {\n extracted.creative_manifests = manifests;\n if (manifests[0].format_id) extracted.format_id = manifests[0].format_id;\n }\n // Variant response: creatives[].variants[] (BuildCreativeVariantSuccess).\n const creatives = d?.creatives as Array<Record<string, unknown>> | undefined;\n if (creatives?.[0]) {\n extracted.creatives = creatives;\n\n const variants = creatives.flatMap(creative => {\n const creativeVariants = creative.variants as Array<Record<string, unknown>> | undefined;\n return Array.isArray(creativeVariants) ? creativeVariants : [];\n });\n if (variants[0]) {\n extracted.variants = variants;\n if (variants[0].build_variant_id) extracted.build_variant_id = variants[0].build_variant_id;\n\n const variantManifest = variants[0].creative_manifest as Record<string, unknown> | undefined;\n if (variantManifest) {\n extracted.creative_manifest ??= variantManifest;\n if (!extracted.format_id && variantManifest.format_id) extracted.format_id = variantManifest.format_id;\n }\n }\n }\n return extracted;\n },\n\n sync_creatives(data) {\n const d = data as Record<string, unknown> | undefined;\n const results = d?.creatives as Array<Record<string, unknown>> | undefined;\n if (!results?.length) return {};\n return { creative_results: results };\n },\n\n list_creatives(data) {\n const d = data as Record<string, unknown> | undefined;\n const creatives = d?.creatives as Array<Record<string, unknown>> | undefined;\n if (!creatives?.[0]) return {};\n const extracted: Record<string, unknown> = { creatives };\n if (creatives[0].creative_id) extracted.creative_id = creatives[0].creative_id;\n return extracted;\n },\n\n preview_creative(data) {\n const d = data as Record<string, unknown> | undefined;\n const previews = d?.previews as Array<Record<string, unknown>> | undefined;\n if (!previews?.length) return {};\n return { previews };\n },\n\n get_signals(data) {\n const d = data as Record<string, unknown> | undefined;\n const signals = d?.signals as Array<Record<string, unknown>> | undefined;\n if (!signals?.[0]) return {};\n return {\n signals,\n signal_id: signals[0].signal_id,\n };\n },\n\n activate_signal(data) {\n const d = data as Record<string, unknown> | undefined;\n const deployments = d?.deployments as Array<Record<string, unknown>> | undefined;\n if (!deployments?.[0]) return {};\n const first = deployments[0];\n const extracted: Record<string, unknown> = { deployments };\n if (first.activation_key) extracted.activation_key = first.activation_key;\n if (first.type) extracted.deployment_type = first.type;\n return extracted;\n },\n\n sync_catalogs(data) {\n const d = data as Record<string, unknown> | undefined;\n const catalogs = d?.catalogs as Array<Record<string, unknown>> | undefined;\n if (!catalogs?.[0]) return {};\n const extracted: Record<string, unknown> = { catalogs };\n if (catalogs[0].catalog_id) extracted.catalog_id = catalogs[0].catalog_id;\n return extracted;\n },\n\n sync_audiences(data) {\n const d = data as Record<string, unknown> | undefined;\n const audiences = d?.audiences as Array<Record<string, unknown>> | undefined;\n if (!audiences?.[0]) return {};\n const extracted: Record<string, unknown> = { audiences };\n if (audiences[0].audience_id) extracted.audience_id = audiences[0].audience_id;\n return extracted;\n },\n\n sync_event_sources(data) {\n const d = data as Record<string, unknown> | undefined;\n const sources = d?.event_sources as Array<Record<string, unknown>> | undefined;\n if (!sources?.[0]) return {};\n const extracted: Record<string, unknown> = { event_sources: sources };\n if (sources[0].event_source_id) extracted.event_source_id = sources[0].event_source_id;\n return extracted;\n },\n\n si_initiate_session(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.session_id) extracted.session_id = d.session_id;\n return extracted;\n },\n\n si_get_offering(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.offering_id) extracted.offering_id = d.offering_id;\n const offerings = d?.offerings as Array<Record<string, unknown>> | undefined;\n if (offerings?.[0]?.offering_id) extracted.offering_id = offerings[0].offering_id;\n return extracted;\n },\n\n sync_plans(data) {\n const d = data as Record<string, unknown> | undefined;\n const plans = d?.plans as Array<Record<string, unknown>> | undefined;\n if (!plans?.[0]) return {};\n return { plan_id: plans[0].plan_id };\n },\n\n create_property_list(data) {\n const d = data as Record<string, unknown> | undefined;\n const list = d?.list as Record<string, unknown> | undefined;\n if (!list) return {};\n const extracted: Record<string, unknown> = {};\n if (list.list_id) extracted.property_list_id = list.list_id;\n if (list.name) extracted.property_list_name = list.name;\n // auth_token intentionally not extracted — avoid leaking credentials into\n // storyboard context which may appear in logs or compliance reports.\n return extracted;\n },\n\n create_content_standards(data) {\n const d = data as Record<string, unknown> | undefined;\n if (!d?.standards_id) return {};\n return { content_standards_id: d.standards_id };\n },\n\n get_rights(data) {\n const d = data as Record<string, unknown> | undefined;\n const rights = d?.rights as Array<Record<string, unknown>> | undefined;\n if (!rights?.[0]?.rights_id) return {};\n return { rights_id: rights[0].rights_id };\n },\n\n acquire_rights(data) {\n const d = data as Record<string, unknown> | undefined;\n if (!d?.rights_grant_id) return {};\n return { rights_grant_id: d.rights_grant_id, rights_id: d.rights_id };\n },\n\n sync_governance(data) {\n // Governance registration — no IDs to extract, just confirmation\n return { governance_synced: true, governance_response: data };\n },\n\n check_governance(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.governance_context) extracted.governance_context = d.governance_context;\n if (d?.check_id) extracted.check_id = d.check_id;\n if (d?.plan_id) extracted.plan_id = d.plan_id;\n if (d?.verdict) extracted.governance_status = d.verdict;\n return extracted;\n },\n\n report_plan_outcome(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.outcome_id) extracted.outcome_id = d.outcome_id;\n if (d?.outcome_state) extracted.outcome_status = d.outcome_state;\n return extracted;\n },\n};\n\n/**\n * Extract context values from a task response.\n */\nexport function extractContext(taskName: string, data: unknown): Record<string, unknown> {\n const extractor = CONTEXT_EXTRACTORS[taskName];\n if (!extractor) return {};\n try {\n return extractor(data);\n } catch {\n return {};\n }\n}\n\n// ────────────────────────────────────────────────────────────\n// Context injection: substitute $context.<key> in requests\n// ────────────────────────────────────────────────────────────\n\n/**\n * Per-context alias cache for `$generate:uuid_v4#<alias>` placeholders.\n *\n * A WeakMap keyed off the StoryboardContext identity avoids landing\n * implementation-detail keys on the serialized context object and avoids\n * fragility when context is shallow-cloned between steps — the cache\n * follows the context reference rather than riding as an owned key.\n *\n * Propagation across steps is handled by `forwardAliasCache` (called by\n * the runner when it rolls context forward to the next step), keeping\n * this a deliberate design choice rather than an invisible by-reference\n * leak through `{ ...context }`.\n */\nconst aliasCaches = new WeakMap<StoryboardContext, Record<string, string>>();\n\n/**\n * Ensure an alias cache exists for the given context and return it.\n */\nfunction getAliasCache(context: StoryboardContext): Record<string, string> {\n let cache = aliasCaches.get(context);\n if (!cache) {\n cache = {};\n aliasCaches.set(context, cache);\n }\n return cache;\n}\n\n/**\n * Propagate the alias cache from one context to another — call after\n * shallow-cloning context between storyboard steps so replay tests\n * (initial + replay sharing `$generate:uuid_v4#<alias>`) resolve to the\n * same UUID. No-op when `from` has no cache.\n */\nexport function forwardAliasCache(from: StoryboardContext, to: StoryboardContext): void {\n const cache = aliasCaches.get(from);\n if (cache) aliasCaches.set(to, cache);\n}\n\n/**\n * Runner-owned substitution variables.\n *\n * Parallels `$context.*` but lives outside the serialized context object so\n * implementation details (the receiver's bound URL, per-step operation ids)\n * stay off the compliance report. Expanded within strings (embedded\n * substitution), unlike `$context.*` which matches whole strings only.\n *\n * Supported patterns:\n * - `{{runner.webhook_base}}` — base URL of the receiver.\n * - `{{runner.webhook_url:<step_id>}}` — per-step webhook URL\n * (`<base>/step/<step_id>/<operation_id>`). The operation_id is minted\n * lazily on first expansion and cached for the rest of the run so the\n * matching `{{prior_step.<step_id>.operation_id}}` reference downstream\n * resolves to the same value.\n * - `{{prior_step.<step_id>.operation_id}}` — operation_id the runner\n * allocated when expanding `{{runner.webhook_url:<step_id>}}`.\n */\nexport interface RunnerVariables {\n /** Millisecond timestamp captured once at run start for deterministic enrichment. */\n runStartMs?: number;\n /** Base URL of the runner's webhook receiver, when enabled. */\n webhookBase?: string;\n /** step_id → operation_id, filled lazily on expansion. */\n stepOperationIds: Map<string, string>;\n /**\n * Free-form slot for cross-step run state that isn't user-facing. Used\n * today to share a single `InMemoryReplayStore` / `InMemoryRevocationStore`\n * across every `expect_webhook_signature_valid` call in a run so a\n * replayed (keyid, nonce) across two deliveries of the same event is\n * actually detected. Untyped here to keep the context module free of\n * signing-module imports.\n */\n runState: Map<string, unknown>;\n}\n\nexport function createRunnerVariables(opts: { webhookBase?: string } = {}): RunnerVariables {\n return {\n runStartMs: Date.now(),\n ...(opts.webhookBase !== undefined && { webhookBase: opts.webhookBase }),\n stepOperationIds: new Map(),\n runState: new Map(),\n };\n}\n\n/**\n * Deep-walk an object and replace recognized placeholder strings:\n *\n * - `$context.<key>` → value from `context[key]` (anchored whole-string match)\n * - `$generate:uuid_v4` → fresh UUID v4 per occurrence (anchored)\n * - `$generate:uuid_v4#<alias>` → fresh UUID v4 on first occurrence, then the\n * same UUID for every subsequent occurrence of the same alias within this\n * run (anchored)\n * - `{{runner.*}}` / `{{prior_step.<id>.operation_id}}` → embedded runner-\n * variable substitution (only when `runnerVars` is supplied)\n *\n * Returns a new object (does not mutate the input).\n */\nexport function injectContext(\n obj: Record<string, unknown>,\n context: StoryboardContext,\n runnerVars?: RunnerVariables\n): Record<string, unknown> {\n return deepReplace(obj, context, runnerVars) as Record<string, unknown>;\n}\n\nfunction deepReplace(value: unknown, context: StoryboardContext, runnerVars?: RunnerVariables): unknown {\n if (typeof value === 'string') {\n // Mustache first — expands in-place within the string, so anchored\n // patterns below still apply to the post-expansion result.\n const expanded = runnerVars ? expandMustache(value, runnerVars) : value;\n\n const ctxMatch = expanded.match(/^\\$context\\.(\\w+)$/);\n if (ctxMatch?.[1]) {\n const key = ctxMatch[1];\n return key in context ? context[key] : expanded;\n }\n const genMatch = expanded.match(/^\\$generate:(uuid_v4|opaque_id)(?:#([A-Za-z0-9_.-]+))?$/);\n if (genMatch) {\n const alias = genMatch[2];\n if (alias) {\n const cache = getAliasCache(context);\n if (!(alias in cache)) cache[alias] = randomUUID();\n return cache[alias];\n }\n return randomUUID();\n }\n return expanded;\n }\n\n if (Array.isArray(value)) {\n return value.map(item => deepReplace(item, context, runnerVars));\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n result[k] = deepReplace(v, context, runnerVars);\n }\n return result;\n }\n\n return value;\n}\n\n/**\n * Expand every `{{runner.*}}` and `{{prior_step.*}}` token in a string.\n * Unknown tokens are left in place so the runner can surface a pointed\n * \"unresolved substitution\" error rather than silently shipping the\n * literal mustache tokens to an agent.\n */\n/**\n * Token shape for the outer expander. Single `[^{}]+` (excludes braces on\n * both sides) so nested or partial `{{…` can't straddle a token boundary\n * and force the engine to backtrack character-by-character. Unified prefix\n * alternation (`runner|prior_step`) keeps the two recognized names in one\n * place — the inner expander still narrows each. Closes CodeQL alert #49\n * (js/polynomial-redos).\n */\nconst MUSTACHE_TOKEN_RE = /\\{\\{((?:runner|prior_step)\\.[^{}]+)\\}\\}/g;\n\nfunction expandMustache(input: string, runnerVars: RunnerVariables): string {\n return input.replace(MUSTACHE_TOKEN_RE, (match, inner) => {\n if (inner === 'runner.webhook_base') {\n return runnerVars.webhookBase ?? match;\n }\n const webhookUrlMatch = /^runner\\.webhook_url:([A-Za-z0-9_]+)$/.exec(inner);\n if (webhookUrlMatch?.[1]) {\n if (!runnerVars.webhookBase) return match;\n const stepId = webhookUrlMatch[1];\n let opId = runnerVars.stepOperationIds.get(stepId);\n if (!opId) {\n opId = randomUUID();\n runnerVars.stepOperationIds.set(stepId, opId);\n }\n return `${runnerVars.webhookBase}/step/${stepId}/${opId}`;\n }\n const priorMatch = /^prior_step\\.([A-Za-z0-9_]+)\\.operation_id$/.exec(inner);\n if (priorMatch?.[1]) {\n return runnerVars.stepOperationIds.get(priorMatch[1]) ?? match;\n }\n return match;\n });\n}\n\n// ────────────────────────────────────────────────────────────\n// Explicit context_outputs: extract values by path\n// ────────────────────────────────────────────────────────────\n\n/**\n * Apply explicit context_outputs rules to extract values from response data.\n * Entries with `generate` set are skipped — use `applyContextOutputsWithProvenance`\n * (which accepts a context for alias-cache access) to handle those.\n *\n * Per runner-output-contract.yaml v2.0.0, paths that resolve to `undefined`,\n * `null`, or `\"\"` are equally non-resolvable — capturing null or \"\" produces\n * fabricated downstream state. The provenance-aware variant additionally\n * surfaces the failures on `ContextWriteResult.failures` so the runner can\n * synthesize a `capture_path_not_resolvable` validation result; this lower-\n * level form drops them silently and is kept for callers that don't need\n * the structured failure surface.\n */\nexport function applyContextOutputs(data: unknown, outputs: ContextOutput[]): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const output of outputs) {\n if (!output.path) continue;\n const value = resolvePath(data, output.path);\n if (value !== undefined && value !== null && value !== '') {\n result[output.key] = value;\n }\n }\n return result;\n}\n\n/**\n * Result of a context write with per-key provenance. The runner consumes\n * `provenance` to emit `context_value_rejected` hints when a later step's\n * seller response rejects a value that traces back to one of these keys.\n * `values` carries the same Record as the non-provenance call so the\n * runner's downstream `Object.assign(updatedContext, values)` path is\n * unchanged.\n */\nexport interface ContextWriteResult {\n values: Record<string, unknown>;\n provenance: Record<string, ContextProvenanceEntry>;\n /**\n * Convention-owned alias groups that must be removed before applying\n * `values`. Conditional groups only clear when the current context key\n * matches one of the response-derived values.\n */\n clearGroups?: Array<{\n keys: string[];\n when?: { key: string; values: unknown[] };\n }>;\n /**\n * `path:` entries whose declared response path did not resolve to a usable\n * value (absent, `null`, or `\"\"`). Per runner-output-contract.yaml v2.0.0,\n * the runner synthesizes a `capture_path_not_resolvable` validation result\n * for each entry — capturing null or \"\" produces fabricated downstream\n * state and is as incorrect as a missing path. Generator entries do not\n * appear here; they cannot fail to resolve. Absent or empty when every\n * `path:` entry produced a value.\n */\n failures?: Array<{ key: string; path: string; resolved: unknown }>;\n}\n\n/**\n * Like `extractContext`, but also returns provenance for each written key\n * tagging it as a convention-based extraction. `response_path` is absent\n * for convention extractors — they're hardcoded functions, not YAML paths.\n */\nexport function extractContextWithProvenance(taskName: string, data: unknown, stepId: string): ContextWriteResult {\n const values = extractContext(taskName, data);\n const clearGroups = (() => {\n const response = asRecord(data);\n switch (taskName) {\n case 'list_products':\n return response?.outcome === 'listed' && Array.isArray(response.products)\n ? [{ keys: PRODUCT_CONTEXT_KEYS }]\n : undefined;\n case 'request_proposals':\n return values.proposal_id ? [{ keys: PROPOSAL_CONTEXT_KEYS }] : undefined;\n case 'refine_proposals':\n return values.proposal_id ? [{ keys: PROPOSAL_CONTEXT_KEYS }] : undefined;\n case 'decline_proposals':\n const declinedIds = Array.isArray(response?.results)\n ? response.results\n .map(asRecord)\n .filter(result => result?.outcome === 'declined')\n .map(result => result?.proposal_id)\n .filter(proposalId => proposalId !== undefined)\n : [];\n return declinedIds.length\n ? [{ keys: PROPOSAL_CONTEXT_KEYS, when: { key: 'proposal_id', values: declinedIds } }]\n : undefined;\n default:\n return undefined;\n }\n })();\n const provenance: Record<string, ContextProvenanceEntry> = {};\n for (const key of Object.keys(values)) {\n provenance[key] = {\n source_step_id: stepId,\n source_kind: 'convention',\n source_task: taskName,\n };\n }\n return { values, provenance, ...(clearGroups && { clearGroups }) };\n}\n\n/**\n * Like `applyContextOutputs`, but also returns provenance for each written\n * key carrying the YAML `response_path` so diagnostics can cite it verbatim.\n *\n * Pass `context` to enable `generate:` entries with alias-cache coherence.\n * When an output declares `generate`, the runner mints a UUID v4 (or reuses\n * the value already cached under `output.key` if an inline `$generate:…#<alias>`\n * substitution ran in the same step). The generated value is written back into\n * the alias cache so that any later step referencing `$generate:opaque_id#<key>`\n * resolves to the same UUID.\n *\n * Omitting `context` disables alias-cache coherence: each generator entry mints\n * an independent UUID that cannot be matched by an inline `$generate:…` form.\n *\n * Generator entries fire regardless of whether `data` is present; path\n * entries are silently skipped when the resolved value is null/undefined.\n */\nexport function applyContextOutputsWithProvenance(\n data: unknown,\n outputs: ContextOutput[],\n stepId: string,\n taskName: string,\n context?: StoryboardContext\n): ContextWriteResult {\n const values: Record<string, unknown> = {};\n const provenance: Record<string, ContextProvenanceEntry> = {};\n const failures: Array<{ key: string; path: string; resolved: unknown }> = [];\n for (const output of outputs) {\n if (output.generate !== undefined) {\n // Generator entries require a context — without one the alias cache\n // can't be populated, so a later step's `$generate:opaque_id#<key>` would\n // mint an independent UUID that doesn't match the value stored here.\n // Loud error beats silent divergence.\n if (!context) {\n throw new Error(\n `applyContextOutputsWithProvenance: context_outputs entry '${output.key}' ` +\n `declares generate='${output.generate}' but no context was provided. ` +\n `Generator entries require a context for alias-cache coherence.`\n );\n }\n const cache = getAliasCache(context);\n let value: string;\n if (output.key in cache) {\n value = cache[output.key]!;\n } else {\n value = randomUUID();\n cache[output.key] = value;\n }\n values[output.key] = value;\n provenance[output.key] = {\n source_step_id: stepId,\n source_kind: 'generator',\n source_task: taskName,\n };\n } else if (output.path) {\n const value = resolvePath(data, output.path);\n // Per runner-output-contract.yaml v2.0.0 / storyboard-schema.yaml,\n // null, \"\", and structurally-absent paths are equally non-resolvable\n // for capture purposes — capturing null or \"\" produces fabricated\n // downstream state and is as incorrect as a missing path.\n const resolved = value === undefined || value === null || value === '';\n if (!resolved) {\n values[output.key] = value;\n provenance[output.key] = {\n source_step_id: stepId,\n source_kind: 'context_outputs',\n response_path: output.path,\n source_task: taskName,\n };\n } else {\n failures.push({\n key: output.key,\n path: output.path,\n resolved: value === undefined ? null : value,\n });\n }\n }\n }\n return { values, provenance, ...(failures.length > 0 ? { failures } : {}) };\n}\n\n// ────────────────────────────────────────────────────────────\n// Explicit context_inputs: inject values into request by path\n// ────────────────────────────────────────────────────────────\n\n/**\n * Apply explicit context_inputs rules to inject context values into a request.\n * Returns a new object (does not mutate the input).\n */\nexport function applyContextInputs(\n request: Record<string, unknown>,\n inputs: ContextInput[],\n context: StoryboardContext\n): Record<string, unknown> {\n const result = structuredClone(request);\n for (const input of inputs) {\n if (input.key in context) {\n setPath(result, input.inject_at, context[input.key]);\n }\n }\n return result;\n}\n\n// setPath is re-exported from ./path for backwards compat\nexport { setPath } from './path';\n"],"mappings":"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","names":["import_path"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/testing/storyboard/context.ts"],"sourcesContent":["/**\n * Context propagation for storyboard steps.\n *\n * After each successful step, known IDs and references are extracted\n * from the response and accumulated in a StoryboardContext. Before\n * executing a step, context values are injected into the request via\n * \"$context.<key>\" placeholders.\n *\n * This convention-based approach avoids requiring YAML enrichment\n * (context_outputs/context_inputs) while still enabling stateful flows.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { StoryboardContext, ContextOutput, ContextInput, ContextProvenanceEntry } from './types';\nimport { resolvePath, setPath } from './path';\nimport { getAuthoritativeMediaBuyStatus } from '../../utils/media-buy-status';\n\n// ────────────────────────────────────────────────────────────\n// Context extraction: pull known IDs from task responses\n// ────────────────────────────────────────────────────────────\n\ntype ContextExtractor = (data: unknown) => Record<string, unknown>;\n\nconst PRODUCT_CONTEXT_KEYS = [\n 'product',\n 'products',\n 'product_id',\n 'pricing_option',\n 'pricing_option_id',\n 'feed_version',\n 'pricing_version',\n];\nconst PROPOSAL_CONTEXT_KEYS = [\n 'proposal',\n 'proposals',\n 'proposal_id',\n 'proposal_status',\n 'proposal_kind',\n 'terms_digest',\n 'proposal_terms_digest',\n];\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;\n}\n\nfunction readMediaBuyStatus(record: Record<string, unknown> | undefined): unknown {\n return getAuthoritativeMediaBuyStatus(record);\n}\n\nfunction readMediaBuyFields(data: unknown): { mediaBuyId?: unknown; status?: unknown } {\n const outer = asRecord(data);\n const nested = asRecord(outer?.media_buy);\n return {\n mediaBuyId: nested?.media_buy_id ?? outer?.media_buy_id,\n status: readMediaBuyStatus(nested) ?? readMediaBuyStatus(outer),\n };\n}\n\nfunction readProposalFields(proposal: Record<string, unknown> | undefined): Record<string, unknown> {\n if (!proposal) return {};\n const extracted: Record<string, unknown> = {};\n if (proposal.proposal_id) extracted.proposal_id = proposal.proposal_id;\n if (proposal.proposal_status) extracted.proposal_status = proposal.proposal_status;\n if (proposal.proposal_kind) extracted.proposal_kind = proposal.proposal_kind;\n if (proposal.terms_digest) {\n extracted.terms_digest = proposal.terms_digest;\n extracted.proposal_terms_digest = proposal.terms_digest;\n }\n return extracted;\n}\n\nfunction readCompactMediaBuyFields(data: unknown): Record<string, unknown> {\n const outer = asRecord(data);\n if (!outer || outer.status !== 'completed') return {};\n const mediaBuyId = outer.media_buy_id;\n // Compact responses use `status` for task completion and\n // `media_buy_status` for lifecycle state. Never reinterpret a bare\n // `status: completed` as the MediaBuy's status when the optional lifecycle\n // field is absent.\n const status = readMediaBuyStatus({ media_buy_status: outer.media_buy_status });\n const acceptedProposal = asRecord(outer.accepted_proposal);\n const extracted: Record<string, unknown> = {};\n if (mediaBuyId) extracted.media_buy_id = mediaBuyId;\n if (status) extracted.media_buy_status = status;\n if (outer.revision) {\n extracted.revision = outer.revision;\n extracted.media_buy_revision = outer.revision;\n }\n if (acceptedProposal) {\n Object.assign(extracted, readProposalFields(acceptedProposal));\n }\n if (Array.isArray(outer.available_actions)) extracted.available_actions = outer.available_actions;\n return extracted;\n}\n\nexport const CONTEXT_EXTRACTORS: Record<string, ContextExtractor> = {\n sync_accounts(data) {\n const d = data as Record<string, unknown> | undefined;\n const accounts = d?.accounts as Array<Record<string, unknown>> | undefined;\n if (!accounts?.[0]) return {};\n const first = accounts[0];\n const extracted: Record<string, unknown> = {};\n if (first.account_id) extracted.account_id = first.account_id;\n if (first.status) extracted.account_status = first.status;\n // Build an account reference for downstream steps. Only include fields\n // the response actually carries — propagating `operator: undefined`\n // would serialize away on the wire (JSON.stringify drops undefined),\n // leaving the natural-key arm short of its required `operator` field\n // (#1419). The brand/operator pair stays paired or both absent.\n const accountRef: Record<string, unknown> = {};\n if (first.brand) accountRef.brand = first.brand;\n if (first.operator) accountRef.operator = first.operator;\n extracted.account = accountRef;\n return extracted;\n },\n\n list_accounts(data) {\n const d = data as Record<string, unknown> | undefined;\n const accounts = d?.accounts as Array<Record<string, unknown>> | undefined;\n if (!accounts?.[0]) return {};\n return { account_id: accounts[0].account_id };\n },\n\n get_products(data) {\n const d = asRecord(data);\n const products = d?.products as Array<Record<string, unknown>> | undefined;\n const extracted: Record<string, unknown> = {};\n if (products?.[0]) {\n extracted.products = products;\n if (products[0].product_id) extracted.product_id = products[0].product_id;\n }\n // Extract proposal_id if proposals are returned\n const proposals = d?.proposals as Array<Record<string, unknown>> | undefined;\n if (proposals?.[0]?.proposal_id) extracted.proposal_id = proposals[0].proposal_id;\n // Wholesale conditional-fetch steps need the response's scope and version\n // metadata even when `unchanged: true` legitimately omits product rows.\n if (d?.wholesale_feed_version !== undefined) extracted.wholesale_feed_version = d.wholesale_feed_version;\n if (d?.pricing_version !== undefined) extracted.pricing_version = d.pricing_version;\n if (d?.cache_scope !== undefined) extracted.cache_scope = d.cache_scope;\n return extracted;\n },\n\n list_products(data) {\n const d = asRecord(data);\n const products = d?.products as Array<Record<string, unknown>> | undefined;\n if (!products?.[0]) return {};\n const first = products[0];\n const pricingOptions = first.pricing_options as Array<Record<string, unknown>> | undefined;\n const extracted: Record<string, unknown> = {};\n if (first.product_id) extracted.product_id = first.product_id;\n if (pricingOptions?.[0]) {\n if (pricingOptions[0].pricing_option_id) extracted.pricing_option_id = pricingOptions[0].pricing_option_id;\n }\n if (d?.feed_version) extracted.feed_version = d.feed_version;\n if (d?.pricing_version) extracted.pricing_version = d.pricing_version;\n return extracted;\n },\n\n request_proposals(data) {\n const d = asRecord(data);\n const proposals = d?.proposals as Array<Record<string, unknown>> | undefined;\n if (!proposals?.[0]) return {};\n return readProposalFields(proposals[0]);\n },\n\n refine_proposals(data) {\n const d = asRecord(data);\n const results = d?.results as Array<Record<string, unknown>> | undefined;\n if (!results?.length) return {};\n const proposalResult = results.find(result => asRecord(result.proposal) || Array.isArray(result.proposals));\n const proposal =\n asRecord(proposalResult?.proposal) ??\n (proposalResult?.proposals as Array<Record<string, unknown>> | undefined)?.[0] ??\n undefined;\n return proposal ? readProposalFields(proposal) : {};\n },\n\n decline_proposals() {\n return {};\n },\n\n buy_products(data) {\n return readCompactMediaBuyFields(data);\n },\n\n accept_proposal(data) {\n return readCompactMediaBuyFields(data);\n },\n\n control_media_buy(data) {\n return readCompactMediaBuyFields(data);\n },\n\n create_media_buy(data) {\n const { mediaBuyId, status } = readMediaBuyFields(data);\n const extracted: Record<string, unknown> = {};\n if (mediaBuyId) extracted.media_buy_id = mediaBuyId;\n if (status) extracted.media_buy_status = status;\n return extracted;\n },\n\n update_media_buy(data) {\n const { mediaBuyId, status } = readMediaBuyFields(data);\n const extracted: Record<string, unknown> = {};\n if (mediaBuyId) extracted.media_buy_id = mediaBuyId;\n if (status) extracted.media_buy_status = status;\n return extracted;\n },\n\n get_media_buys(data) {\n const d = data as Record<string, unknown> | undefined;\n const buys = d?.media_buys as Array<Record<string, unknown>> | undefined;\n if (!buys?.[0]) return {};\n // Don't extract a single-resource ID from a broad-list page. When\n // has_more: true the caller is mid-pagination walk and buys[0] is not\n // the canonical buy — extracting it here causes the enricher to inject\n // media_buy_ids: [that_id] on the next step, turning a continuation into\n // an ID-lookup. Conservative: === true matches the codebase convention\n // (absent has_more is treated as terminal, not as a list-in-progress).\n const pagination = d?.pagination as Record<string, unknown> | undefined;\n if (pagination?.has_more === true) return {};\n const extracted: Record<string, unknown> = {\n media_buy_id: buys[0].media_buy_id,\n media_buy_status: readMediaBuyStatus(buys[0]),\n };\n if (buys[0].revision) {\n extracted.revision = buys[0].revision;\n extracted.media_buy_revision = buys[0].revision;\n }\n if (Array.isArray(buys[0].available_actions)) extracted.available_actions = buys[0].available_actions;\n return extracted;\n },\n\n list_creative_formats(data) {\n const d = data as Record<string, unknown> | undefined;\n const formats = d?.formats as Array<Record<string, unknown>> | undefined;\n if (!formats?.[0]) return {};\n return {\n formats,\n format_id: formats[0].format_id,\n };\n },\n\n build_creative(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n // Single response: creative_manifest\n const manifest = d?.creative_manifest as Record<string, unknown> | undefined;\n if (manifest) {\n extracted.creative_manifest = manifest;\n if (manifest.format_id) extracted.format_id = manifest.format_id;\n }\n // Multi response: creative_manifests\n const manifests = d?.creative_manifests as Array<Record<string, unknown>> | undefined;\n if (manifests?.[0]) {\n extracted.creative_manifests = manifests;\n if (manifests[0].format_id) extracted.format_id = manifests[0].format_id;\n }\n // Variant response: creatives[].variants[] (BuildCreativeVariantSuccess).\n const creatives = d?.creatives as Array<Record<string, unknown>> | undefined;\n if (creatives?.[0]) {\n extracted.creatives = creatives;\n\n const variants = creatives.flatMap(creative => {\n const creativeVariants = creative.variants as Array<Record<string, unknown>> | undefined;\n return Array.isArray(creativeVariants) ? creativeVariants : [];\n });\n if (variants[0]) {\n extracted.variants = variants;\n if (variants[0].build_variant_id) extracted.build_variant_id = variants[0].build_variant_id;\n\n const variantManifest = variants[0].creative_manifest as Record<string, unknown> | undefined;\n if (variantManifest) {\n extracted.creative_manifest ??= variantManifest;\n if (!extracted.format_id && variantManifest.format_id) extracted.format_id = variantManifest.format_id;\n }\n }\n }\n return extracted;\n },\n\n sync_creatives(data) {\n const d = data as Record<string, unknown> | undefined;\n const results = d?.creatives as Array<Record<string, unknown>> | undefined;\n if (!results?.length) return {};\n return { creative_results: results };\n },\n\n list_creatives(data) {\n const d = data as Record<string, unknown> | undefined;\n const creatives = d?.creatives as Array<Record<string, unknown>> | undefined;\n if (!creatives?.[0]) return {};\n const extracted: Record<string, unknown> = { creatives };\n if (creatives[0].creative_id) extracted.creative_id = creatives[0].creative_id;\n return extracted;\n },\n\n preview_creative(data) {\n const d = data as Record<string, unknown> | undefined;\n const previews = d?.previews as Array<Record<string, unknown>> | undefined;\n if (!previews?.length) return {};\n return { previews };\n },\n\n get_signals(data) {\n const d = data as Record<string, unknown> | undefined;\n const signals = d?.signals as Array<Record<string, unknown>> | undefined;\n if (!signals?.[0]) return {};\n return {\n signals,\n signal_id: signals[0].signal_id,\n };\n },\n\n activate_signal(data) {\n const d = data as Record<string, unknown> | undefined;\n const deployments = d?.deployments as Array<Record<string, unknown>> | undefined;\n if (!deployments?.[0]) return {};\n const first = deployments[0];\n const extracted: Record<string, unknown> = { deployments };\n if (first.activation_key) extracted.activation_key = first.activation_key;\n if (first.type) extracted.deployment_type = first.type;\n return extracted;\n },\n\n sync_catalogs(data) {\n const d = data as Record<string, unknown> | undefined;\n const catalogs = d?.catalogs as Array<Record<string, unknown>> | undefined;\n if (!catalogs?.[0]) return {};\n const extracted: Record<string, unknown> = { catalogs };\n if (catalogs[0].catalog_id) extracted.catalog_id = catalogs[0].catalog_id;\n return extracted;\n },\n\n sync_audiences(data) {\n const d = data as Record<string, unknown> | undefined;\n const audiences = d?.audiences as Array<Record<string, unknown>> | undefined;\n if (!audiences?.[0]) return {};\n const extracted: Record<string, unknown> = { audiences };\n if (audiences[0].audience_id) extracted.audience_id = audiences[0].audience_id;\n return extracted;\n },\n\n sync_event_sources(data) {\n const d = data as Record<string, unknown> | undefined;\n const sources = d?.event_sources as Array<Record<string, unknown>> | undefined;\n if (!sources?.[0]) return {};\n const extracted: Record<string, unknown> = { event_sources: sources };\n if (sources[0].event_source_id) extracted.event_source_id = sources[0].event_source_id;\n return extracted;\n },\n\n si_initiate_session(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.session_id) extracted.session_id = d.session_id;\n return extracted;\n },\n\n si_get_offering(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.offering_id) extracted.offering_id = d.offering_id;\n const offerings = d?.offerings as Array<Record<string, unknown>> | undefined;\n if (offerings?.[0]?.offering_id) extracted.offering_id = offerings[0].offering_id;\n return extracted;\n },\n\n sync_plans(data) {\n const d = data as Record<string, unknown> | undefined;\n const plans = d?.plans as Array<Record<string, unknown>> | undefined;\n if (!plans?.[0]) return {};\n return { plan_id: plans[0].plan_id };\n },\n\n create_property_list(data) {\n const d = data as Record<string, unknown> | undefined;\n const list = d?.list as Record<string, unknown> | undefined;\n if (!list) return {};\n const extracted: Record<string, unknown> = {};\n if (list.list_id) extracted.property_list_id = list.list_id;\n if (list.name) extracted.property_list_name = list.name;\n // auth_token intentionally not extracted — avoid leaking credentials into\n // storyboard context which may appear in logs or compliance reports.\n return extracted;\n },\n\n create_content_standards(data) {\n const d = data as Record<string, unknown> | undefined;\n if (!d?.standards_id) return {};\n return { content_standards_id: d.standards_id };\n },\n\n get_rights(data) {\n const d = data as Record<string, unknown> | undefined;\n const rights = d?.rights as Array<Record<string, unknown>> | undefined;\n if (!rights?.[0]?.rights_id) return {};\n return { rights_id: rights[0].rights_id };\n },\n\n acquire_rights(data) {\n const d = data as Record<string, unknown> | undefined;\n if (!d?.rights_grant_id) return {};\n return { rights_grant_id: d.rights_grant_id, rights_id: d.rights_id };\n },\n\n sync_governance(data) {\n // Governance registration — no IDs to extract, just confirmation\n return { governance_synced: true, governance_response: data };\n },\n\n check_governance(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.governance_context) extracted.governance_context = d.governance_context;\n if (d?.check_id) extracted.check_id = d.check_id;\n if (d?.plan_id) extracted.plan_id = d.plan_id;\n if (d?.verdict) extracted.governance_status = d.verdict;\n return extracted;\n },\n\n report_plan_outcome(data) {\n const d = data as Record<string, unknown> | undefined;\n const extracted: Record<string, unknown> = {};\n if (d?.outcome_id) extracted.outcome_id = d.outcome_id;\n if (d?.outcome_state) extracted.outcome_status = d.outcome_state;\n return extracted;\n },\n};\n\n/**\n * Extract context values from a task response.\n */\nexport function extractContext(taskName: string, data: unknown): Record<string, unknown> {\n const extractor = CONTEXT_EXTRACTORS[taskName];\n if (!extractor) return {};\n try {\n return extractor(data);\n } catch {\n return {};\n }\n}\n\n// ────────────────────────────────────────────────────────────\n// Context injection: substitute $context.<key> in requests\n// ────────────────────────────────────────────────────────────\n\n/**\n * Per-context alias cache for `$generate:uuid_v4#<alias>` placeholders.\n *\n * A WeakMap keyed off the StoryboardContext identity avoids landing\n * implementation-detail keys on the serialized context object and avoids\n * fragility when context is shallow-cloned between steps — the cache\n * follows the context reference rather than riding as an owned key.\n *\n * Propagation across steps is handled by `forwardAliasCache` (called by\n * the runner when it rolls context forward to the next step), keeping\n * this a deliberate design choice rather than an invisible by-reference\n * leak through `{ ...context }`.\n */\nconst aliasCaches = new WeakMap<StoryboardContext, Record<string, string>>();\n\n/**\n * Ensure an alias cache exists for the given context and return it.\n */\nfunction getAliasCache(context: StoryboardContext): Record<string, string> {\n let cache = aliasCaches.get(context);\n if (!cache) {\n cache = {};\n aliasCaches.set(context, cache);\n }\n return cache;\n}\n\n/**\n * Propagate the alias cache from one context to another — call after\n * shallow-cloning context between storyboard steps so replay tests\n * (initial + replay sharing `$generate:uuid_v4#<alias>`) resolve to the\n * same UUID. No-op when `from` has no cache.\n */\nexport function forwardAliasCache(from: StoryboardContext, to: StoryboardContext): void {\n const cache = aliasCaches.get(from);\n if (cache) aliasCaches.set(to, cache);\n}\n\n/**\n * Runner-owned substitution variables.\n *\n * Parallels `$context.*` but lives outside the serialized context object so\n * implementation details (the receiver's bound URL, per-step operation ids)\n * stay off the compliance report. Expanded within strings (embedded\n * substitution), unlike `$context.*` which matches whole strings only.\n *\n * Supported patterns:\n * - `{{runner.webhook_base}}` — base URL of the receiver.\n * - `{{runner.webhook_url:<step_id>}}` — per-step webhook URL\n * (`<base>/step/<step_id>/<operation_id>`). The operation_id is minted\n * lazily on first expansion and cached for the rest of the run so the\n * matching `{{prior_step.<step_id>.operation_id}}` reference downstream\n * resolves to the same value.\n * - `{{prior_step.<step_id>.operation_id}}` — operation_id the runner\n * allocated when expanding `{{runner.webhook_url:<step_id>}}`.\n */\nexport interface RunnerVariables {\n /** Millisecond timestamp captured once at run start for deterministic enrichment. */\n runStartMs?: number;\n /** Base URL of the runner's webhook receiver, when enabled. */\n webhookBase?: string;\n /** step_id → operation_id, filled lazily on expansion. */\n stepOperationIds: Map<string, string>;\n /**\n * Free-form slot for cross-step run state that isn't user-facing. Used\n * today to share a single `InMemoryReplayStore` / `InMemoryRevocationStore`\n * across every `expect_webhook_signature_valid` call in a run so a\n * replayed (keyid, nonce) across two deliveries of the same event is\n * actually detected. Untyped here to keep the context module free of\n * signing-module imports.\n */\n runState: Map<string, unknown>;\n}\n\nexport function createRunnerVariables(opts: { webhookBase?: string } = {}): RunnerVariables {\n return {\n runStartMs: Date.now(),\n ...(opts.webhookBase !== undefined && { webhookBase: opts.webhookBase }),\n stepOperationIds: new Map(),\n runState: new Map(),\n };\n}\n\n/**\n * Deep-walk an object and replace recognized placeholder strings:\n *\n * - `$context.<key>` → value from `context[key]` (anchored whole-string match)\n * - `$generate:uuid_v4` → fresh UUID v4 per occurrence (anchored)\n * - `$generate:uuid_v4#<alias>` → fresh UUID v4 on first occurrence, then the\n * same UUID for every subsequent occurrence of the same alias within this\n * run (anchored)\n * - `{{runner.*}}` / `{{prior_step.<id>.operation_id}}` → embedded runner-\n * variable substitution (only when `runnerVars` is supplied)\n *\n * Returns a new object (does not mutate the input).\n */\nexport function injectContext(\n obj: Record<string, unknown>,\n context: StoryboardContext,\n runnerVars?: RunnerVariables\n): Record<string, unknown> {\n return deepReplace(obj, context, runnerVars) as Record<string, unknown>;\n}\n\nfunction deepReplace(value: unknown, context: StoryboardContext, runnerVars?: RunnerVariables): unknown {\n if (typeof value === 'string') {\n // Mustache first — expands in-place within the string, so anchored\n // patterns below still apply to the post-expansion result.\n const expanded = runnerVars ? expandMustache(value, runnerVars) : value;\n\n const ctxMatch = expanded.match(/^\\$context\\.(\\w+)$/);\n if (ctxMatch?.[1]) {\n const key = ctxMatch[1];\n return key in context ? context[key] : expanded;\n }\n const genMatch = expanded.match(/^\\$generate:(uuid_v4|opaque_id)(?:#([A-Za-z0-9_.-]+))?$/);\n if (genMatch) {\n const alias = genMatch[2];\n if (alias) {\n const cache = getAliasCache(context);\n if (!(alias in cache)) cache[alias] = randomUUID();\n return cache[alias];\n }\n return randomUUID();\n }\n return expanded;\n }\n\n if (Array.isArray(value)) {\n return value.map(item => deepReplace(item, context, runnerVars));\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n result[k] = deepReplace(v, context, runnerVars);\n }\n return result;\n }\n\n return value;\n}\n\n/**\n * Expand every `{{runner.*}}` and `{{prior_step.*}}` token in a string.\n * Unknown tokens are left in place so the runner can surface a pointed\n * \"unresolved substitution\" error rather than silently shipping the\n * literal mustache tokens to an agent.\n */\n/**\n * Token shape for the outer expander. Single `[^{}]+` (excludes braces on\n * both sides) so nested or partial `{{…` can't straddle a token boundary\n * and force the engine to backtrack character-by-character. Unified prefix\n * alternation (`runner|prior_step`) keeps the two recognized names in one\n * place — the inner expander still narrows each. Closes CodeQL alert #49\n * (js/polynomial-redos).\n */\nconst MUSTACHE_TOKEN_RE = /\\{\\{((?:runner|prior_step)\\.[^{}]+)\\}\\}/g;\n\nfunction expandMustache(input: string, runnerVars: RunnerVariables): string {\n return input.replace(MUSTACHE_TOKEN_RE, (match, inner) => {\n if (inner === 'runner.webhook_base') {\n return runnerVars.webhookBase ?? match;\n }\n const webhookUrlMatch = /^runner\\.webhook_url:([A-Za-z0-9_]+)$/.exec(inner);\n if (webhookUrlMatch?.[1]) {\n if (!runnerVars.webhookBase) return match;\n const stepId = webhookUrlMatch[1];\n let opId = runnerVars.stepOperationIds.get(stepId);\n if (!opId) {\n opId = randomUUID();\n runnerVars.stepOperationIds.set(stepId, opId);\n }\n return `${runnerVars.webhookBase}/step/${stepId}/${opId}`;\n }\n const priorMatch = /^prior_step\\.([A-Za-z0-9_]+)\\.operation_id$/.exec(inner);\n if (priorMatch?.[1]) {\n return runnerVars.stepOperationIds.get(priorMatch[1]) ?? match;\n }\n return match;\n });\n}\n\n// ────────────────────────────────────────────────────────────\n// Explicit context_outputs: extract values by path\n// ────────────────────────────────────────────────────────────\n\n/**\n * Apply explicit context_outputs rules to extract values from response data.\n * Entries with `generate` set are skipped — use `applyContextOutputsWithProvenance`\n * (which accepts a context for alias-cache access) to handle those.\n *\n * Per runner-output-contract.yaml v2.0.0, paths that resolve to `undefined`,\n * `null`, or `\"\"` are equally non-resolvable — capturing null or \"\" produces\n * fabricated downstream state. The provenance-aware variant additionally\n * surfaces the failures on `ContextWriteResult.failures` so the runner can\n * synthesize a `capture_path_not_resolvable` validation result; this lower-\n * level form drops them silently and is kept for callers that don't need\n * the structured failure surface.\n */\nexport function applyContextOutputs(data: unknown, outputs: ContextOutput[]): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const output of outputs) {\n if (!output.path) continue;\n const value = resolvePath(data, output.path);\n if (value !== undefined && value !== null && value !== '') {\n result[output.key] = value;\n }\n }\n return result;\n}\n\n/**\n * Result of a context write with per-key provenance. The runner consumes\n * `provenance` to emit `context_value_rejected` hints when a later step's\n * seller response rejects a value that traces back to one of these keys.\n * `values` carries the same Record as the non-provenance call so the\n * runner's downstream `Object.assign(updatedContext, values)` path is\n * unchanged.\n */\nexport interface ContextWriteResult {\n values: Record<string, unknown>;\n provenance: Record<string, ContextProvenanceEntry>;\n /**\n * Convention-owned alias groups that must be removed before applying\n * `values`. Conditional groups only clear when the current context key\n * matches one of the response-derived values.\n */\n clearGroups?: Array<{\n keys: string[];\n when?: { key: string; values: unknown[] };\n }>;\n /**\n * `path:` entries whose declared response path did not resolve to a usable\n * value (absent, `null`, or `\"\"`). Per runner-output-contract.yaml v2.0.0,\n * the runner synthesizes a `capture_path_not_resolvable` validation result\n * for each entry — capturing null or \"\" produces fabricated downstream\n * state and is as incorrect as a missing path. Generator entries do not\n * appear here; they cannot fail to resolve. Absent or empty when every\n * `path:` entry produced a value.\n */\n failures?: Array<{ key: string; path: string; resolved: unknown }>;\n}\n\n/**\n * Like `extractContext`, but also returns provenance for each written key\n * tagging it as a convention-based extraction. `response_path` is absent\n * for convention extractors — they're hardcoded functions, not YAML paths.\n */\nexport function extractContextWithProvenance(taskName: string, data: unknown, stepId: string): ContextWriteResult {\n const values = extractContext(taskName, data);\n const clearGroups = (() => {\n const response = asRecord(data);\n switch (taskName) {\n case 'list_products':\n return response?.outcome === 'listed' && Array.isArray(response.products)\n ? [{ keys: PRODUCT_CONTEXT_KEYS }]\n : undefined;\n case 'request_proposals':\n return values.proposal_id ? [{ keys: PROPOSAL_CONTEXT_KEYS }] : undefined;\n case 'refine_proposals':\n return values.proposal_id ? [{ keys: PROPOSAL_CONTEXT_KEYS }] : undefined;\n case 'decline_proposals':\n const declinedIds = Array.isArray(response?.results)\n ? response.results\n .map(asRecord)\n .filter(result => result?.outcome === 'declined')\n .map(result => result?.proposal_id)\n .filter(proposalId => proposalId !== undefined)\n : [];\n return declinedIds.length\n ? [{ keys: PROPOSAL_CONTEXT_KEYS, when: { key: 'proposal_id', values: declinedIds } }]\n : undefined;\n default:\n return undefined;\n }\n })();\n const provenance: Record<string, ContextProvenanceEntry> = {};\n for (const key of Object.keys(values)) {\n provenance[key] = {\n source_step_id: stepId,\n source_kind: 'convention',\n source_task: taskName,\n };\n }\n return { values, provenance, ...(clearGroups && { clearGroups }) };\n}\n\n/**\n * Like `applyContextOutputs`, but also returns provenance for each written\n * key carrying the YAML `response_path` so diagnostics can cite it verbatim.\n *\n * Pass `context` to enable `generate:` entries with alias-cache coherence.\n * When an output declares `generate`, the runner mints a UUID v4 (or reuses\n * the value already cached under `output.key` if an inline `$generate:…#<alias>`\n * substitution ran in the same step). The generated value is written back into\n * the alias cache so that any later step referencing `$generate:opaque_id#<key>`\n * resolves to the same UUID.\n *\n * Omitting `context` disables alias-cache coherence: each generator entry mints\n * an independent UUID that cannot be matched by an inline `$generate:…` form.\n *\n * Generator entries fire regardless of whether `data` is present; path\n * entries are silently skipped when the resolved value is null/undefined.\n */\nexport function applyContextOutputsWithProvenance(\n data: unknown,\n outputs: ContextOutput[],\n stepId: string,\n taskName: string,\n context?: StoryboardContext\n): ContextWriteResult {\n const values: Record<string, unknown> = {};\n const provenance: Record<string, ContextProvenanceEntry> = {};\n const failures: Array<{ key: string; path: string; resolved: unknown }> = [];\n for (const output of outputs) {\n if (output.generate !== undefined) {\n // Generator entries require a context — without one the alias cache\n // can't be populated, so a later step's `$generate:opaque_id#<key>` would\n // mint an independent UUID that doesn't match the value stored here.\n // Loud error beats silent divergence.\n if (!context) {\n throw new Error(\n `applyContextOutputsWithProvenance: context_outputs entry '${output.key}' ` +\n `declares generate='${output.generate}' but no context was provided. ` +\n `Generator entries require a context for alias-cache coherence.`\n );\n }\n const cache = getAliasCache(context);\n let value: string;\n if (output.key in cache) {\n value = cache[output.key]!;\n } else {\n value = randomUUID();\n cache[output.key] = value;\n }\n values[output.key] = value;\n provenance[output.key] = {\n source_step_id: stepId,\n source_kind: 'generator',\n source_task: taskName,\n };\n } else if (output.path) {\n const value = resolvePath(data, output.path);\n // Per runner-output-contract.yaml v2.0.0 / storyboard-schema.yaml,\n // null, \"\", and structurally-absent paths are equally non-resolvable\n // for capture purposes — capturing null or \"\" produces fabricated\n // downstream state and is as incorrect as a missing path.\n const resolved = value === undefined || value === null || value === '';\n if (!resolved) {\n values[output.key] = value;\n provenance[output.key] = {\n source_step_id: stepId,\n source_kind: 'context_outputs',\n response_path: output.path,\n source_task: taskName,\n };\n } else {\n failures.push({\n key: output.key,\n path: output.path,\n resolved: value === undefined ? null : value,\n });\n }\n }\n }\n return { values, provenance, ...(failures.length > 0 ? { failures } : {}) };\n}\n\n// ────────────────────────────────────────────────────────────\n// Explicit context_inputs: inject values into request by path\n// ────────────────────────────────────────────────────────────\n\n/**\n * Apply explicit context_inputs rules to inject context values into a request.\n * Returns a new object (does not mutate the input).\n */\nexport function applyContextInputs(\n request: Record<string, unknown>,\n inputs: ContextInput[],\n context: StoryboardContext\n): Record<string, unknown> {\n const result = structuredClone(request);\n for (const input of inputs) {\n if (input.key in context) {\n setPath(result, input.inject_at, context[input.key]);\n }\n }\n return result;\n}\n\n// setPath is re-exported from ./path for backwards compat\nexport { setPath } from './path';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,yBAA2B;AAE3B,kBAAqC;AACrC,8BAA+C;AAyzB/C,IAAAA,eAAwB;AAjzBxB,MAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,MAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,SAAS,OAAqD;AACrE,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAK,QAAoC;AAC5G;AAEA,SAAS,mBAAmB,QAAsD;AAChF,aAAO,wDAA+B,MAAM;AAC9C;AAEA,SAAS,mBAAmB,MAA2D;AACrF,QAAM,QAAQ,SAAS,IAAI;AAC3B,QAAM,SAAS,SAAS,OAAO,SAAS;AACxC,SAAO;AAAA,IACL,YAAY,QAAQ,gBAAgB,OAAO;AAAA,IAC3C,QAAQ,mBAAmB,MAAM,KAAK,mBAAmB,KAAK;AAAA,EAChE;AACF;AAEA,SAAS,mBAAmB,UAAwE;AAClG,MAAI,CAAC,SAAU,QAAO,CAAC;AACvB,QAAM,YAAqC,CAAC;AAC5C,MAAI,SAAS,YAAa,WAAU,cAAc,SAAS;AAC3D,MAAI,SAAS,gBAAiB,WAAU,kBAAkB,SAAS;AACnE,MAAI,SAAS,cAAe,WAAU,gBAAgB,SAAS;AAC/D,MAAI,SAAS,cAAc;AACzB,cAAU,eAAe,SAAS;AAClC,cAAU,wBAAwB,SAAS;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,0BAA0B,MAAwC;AACzE,QAAM,QAAQ,SAAS,IAAI;AAC3B,MAAI,CAAC,SAAS,MAAM,WAAW,YAAa,QAAO,CAAC;AACpD,QAAM,aAAa,MAAM;AAKzB,QAAM,SAAS,mBAAmB,EAAE,kBAAkB,MAAM,iBAAiB,CAAC;AAC9E,QAAM,mBAAmB,SAAS,MAAM,iBAAiB;AACzD,QAAM,YAAqC,CAAC;AAC5C,MAAI,WAAY,WAAU,eAAe;AACzC,MAAI,OAAQ,WAAU,mBAAmB;AACzC,MAAI,MAAM,UAAU;AAClB,cAAU,WAAW,MAAM;AAC3B,cAAU,qBAAqB,MAAM;AAAA,EACvC;AACA,MAAI,kBAAkB;AACpB,WAAO,OAAO,WAAW,mBAAmB,gBAAgB,CAAC;AAAA,EAC/D;AACA,MAAI,MAAM,QAAQ,MAAM,iBAAiB,EAAG,WAAU,oBAAoB,MAAM;AAChF,SAAO;AACT;AAEO,MAAM,qBAAuD;AAAA,EAClE,cAAc,MAAM;AAClB,UAAM,IAAI;AACV,UAAM,WAAW,GAAG;AACpB,QAAI,CAAC,WAAW,CAAC,EAAG,QAAO,CAAC;AAC5B,UAAM,QAAQ,SAAS,CAAC;AACxB,UAAM,YAAqC,CAAC;AAC5C,QAAI,MAAM,WAAY,WAAU,aAAa,MAAM;AACnD,QAAI,MAAM,OAAQ,WAAU,iBAAiB,MAAM;AAMnD,UAAM,aAAsC,CAAC;AAC7C,QAAI,MAAM,MAAO,YAAW,QAAQ,MAAM;AAC1C,QAAI,MAAM,SAAU,YAAW,WAAW,MAAM;AAChD,cAAU,UAAU;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,MAAM;AAClB,UAAM,IAAI;AACV,UAAM,WAAW,GAAG;AACpB,QAAI,CAAC,WAAW,CAAC,EAAG,QAAO,CAAC;AAC5B,WAAO,EAAE,YAAY,SAAS,CAAC,EAAE,WAAW;AAAA,EAC9C;AAAA,EAEA,aAAa,MAAM;AACjB,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,WAAW,GAAG;AACpB,UAAM,YAAqC,CAAC;AAC5C,QAAI,WAAW,CAAC,GAAG;AACjB,gBAAU,WAAW;AACrB,UAAI,SAAS,CAAC,EAAE,WAAY,WAAU,aAAa,SAAS,CAAC,EAAE;AAAA,IACjE;AAEA,UAAM,YAAY,GAAG;AACrB,QAAI,YAAY,CAAC,GAAG,YAAa,WAAU,cAAc,UAAU,CAAC,EAAE;AAGtE,QAAI,GAAG,2BAA2B,OAAW,WAAU,yBAAyB,EAAE;AAClF,QAAI,GAAG,oBAAoB,OAAW,WAAU,kBAAkB,EAAE;AACpE,QAAI,GAAG,gBAAgB,OAAW,WAAU,cAAc,EAAE;AAC5D,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,MAAM;AAClB,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,WAAW,GAAG;AACpB,QAAI,CAAC,WAAW,CAAC,EAAG,QAAO,CAAC;AAC5B,UAAM,QAAQ,SAAS,CAAC;AACxB,UAAM,iBAAiB,MAAM;AAC7B,UAAM,YAAqC,CAAC;AAC5C,QAAI,MAAM,WAAY,WAAU,aAAa,MAAM;AACnD,QAAI,iBAAiB,CAAC,GAAG;AACvB,UAAI,eAAe,CAAC,EAAE,kBAAmB,WAAU,oBAAoB,eAAe,CAAC,EAAE;AAAA,IAC3F;AACA,QAAI,GAAG,aAAc,WAAU,eAAe,EAAE;AAChD,QAAI,GAAG,gBAAiB,WAAU,kBAAkB,EAAE;AACtD,WAAO;AAAA,EACT;AAAA,EAEA,kBAAkB,MAAM;AACtB,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,YAAY,GAAG;AACrB,QAAI,CAAC,YAAY,CAAC,EAAG,QAAO,CAAC;AAC7B,WAAO,mBAAmB,UAAU,CAAC,CAAC;AAAA,EACxC;AAAA,EAEA,iBAAiB,MAAM;AACrB,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,UAAU,GAAG;AACnB,QAAI,CAAC,SAAS,OAAQ,QAAO,CAAC;AAC9B,UAAM,iBAAiB,QAAQ,KAAK,YAAU,SAAS,OAAO,QAAQ,KAAK,MAAM,QAAQ,OAAO,SAAS,CAAC;AAC1G,UAAM,WACJ,SAAS,gBAAgB,QAAQ,KAChC,gBAAgB,YAA2D,CAAC,KAC7E;AACF,WAAO,WAAW,mBAAmB,QAAQ,IAAI,CAAC;AAAA,EACpD;AAAA,EAEA,oBAAoB;AAClB,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,aAAa,MAAM;AACjB,WAAO,0BAA0B,IAAI;AAAA,EACvC;AAAA,EAEA,gBAAgB,MAAM;AACpB,WAAO,0BAA0B,IAAI;AAAA,EACvC;AAAA,EAEA,kBAAkB,MAAM;AACtB,WAAO,0BAA0B,IAAI;AAAA,EACvC;AAAA,EAEA,iBAAiB,MAAM;AACrB,UAAM,EAAE,YAAY,OAAO,IAAI,mBAAmB,IAAI;AACtD,UAAM,YAAqC,CAAC;AAC5C,QAAI,WAAY,WAAU,eAAe;AACzC,QAAI,OAAQ,WAAU,mBAAmB;AACzC,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,MAAM;AACrB,UAAM,EAAE,YAAY,OAAO,IAAI,mBAAmB,IAAI;AACtD,UAAM,YAAqC,CAAC;AAC5C,QAAI,WAAY,WAAU,eAAe;AACzC,QAAI,OAAQ,WAAU,mBAAmB;AACzC,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,MAAM;AACnB,UAAM,IAAI;AACV,UAAM,OAAO,GAAG;AAChB,QAAI,CAAC,OAAO,CAAC,EAAG,QAAO,CAAC;AAOxB,UAAM,aAAa,GAAG;AACtB,QAAI,YAAY,aAAa,KAAM,QAAO,CAAC;AAC3C,UAAM,YAAqC;AAAA,MACzC,cAAc,KAAK,CAAC,EAAE;AAAA,MACtB,kBAAkB,mBAAmB,KAAK,CAAC,CAAC;AAAA,IAC9C;AACA,QAAI,KAAK,CAAC,EAAE,UAAU;AACpB,gBAAU,WAAW,KAAK,CAAC,EAAE;AAC7B,gBAAU,qBAAqB,KAAK,CAAC,EAAE;AAAA,IACzC;AACA,QAAI,MAAM,QAAQ,KAAK,CAAC,EAAE,iBAAiB,EAAG,WAAU,oBAAoB,KAAK,CAAC,EAAE;AACpF,WAAO;AAAA,EACT;AAAA,EAEA,sBAAsB,MAAM;AAC1B,UAAM,IAAI;AACV,UAAM,UAAU,GAAG;AACnB,QAAI,CAAC,UAAU,CAAC,EAAG,QAAO,CAAC;AAC3B,WAAO;AAAA,MACL;AAAA,MACA,WAAW,QAAQ,CAAC,EAAE;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,eAAe,MAAM;AACnB,UAAM,IAAI;AACV,UAAM,YAAqC,CAAC;AAE5C,UAAM,WAAW,GAAG;AACpB,QAAI,UAAU;AACZ,gBAAU,oBAAoB;AAC9B,UAAI,SAAS,UAAW,WAAU,YAAY,SAAS;AAAA,IACzD;AAEA,UAAM,YAAY,GAAG;AACrB,QAAI,YAAY,CAAC,GAAG;AAClB,gBAAU,qBAAqB;AAC/B,UAAI,UAAU,CAAC,EAAE,UAAW,WAAU,YAAY,UAAU,CAAC,EAAE;AAAA,IACjE;AAEA,UAAM,YAAY,GAAG;AACrB,QAAI,YAAY,CAAC,GAAG;AAClB,gBAAU,YAAY;AAEtB,YAAM,WAAW,UAAU,QAAQ,cAAY;AAC7C,cAAM,mBAAmB,SAAS;AAClC,eAAO,MAAM,QAAQ,gBAAgB,IAAI,mBAAmB,CAAC;AAAA,MAC/D,CAAC;AACD,UAAI,SAAS,CAAC,GAAG;AACf,kBAAU,WAAW;AACrB,YAAI,SAAS,CAAC,EAAE,iBAAkB,WAAU,mBAAmB,SAAS,CAAC,EAAE;AAE3E,cAAM,kBAAkB,SAAS,CAAC,EAAE;AACpC,YAAI,iBAAiB;AACnB,oBAAU,sBAAsB;AAChC,cAAI,CAAC,UAAU,aAAa,gBAAgB,UAAW,WAAU,YAAY,gBAAgB;AAAA,QAC/F;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,MAAM;AACnB,UAAM,IAAI;AACV,UAAM,UAAU,GAAG;AACnB,QAAI,CAAC,SAAS,OAAQ,QAAO,CAAC;AAC9B,WAAO,EAAE,kBAAkB,QAAQ;AAAA,EACrC;AAAA,EAEA,eAAe,MAAM;AACnB,UAAM,IAAI;AACV,UAAM,YAAY,GAAG;AACrB,QAAI,CAAC,YAAY,CAAC,EAAG,QAAO,CAAC;AAC7B,UAAM,YAAqC,EAAE,UAAU;AACvD,QAAI,UAAU,CAAC,EAAE,YAAa,WAAU,cAAc,UAAU,CAAC,EAAE;AACnE,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,MAAM;AACrB,UAAM,IAAI;AACV,UAAM,WAAW,GAAG;AACpB,QAAI,CAAC,UAAU,OAAQ,QAAO,CAAC;AAC/B,WAAO,EAAE,SAAS;AAAA,EACpB;AAAA,EAEA,YAAY,MAAM;AAChB,UAAM,IAAI;AACV,UAAM,UAAU,GAAG;AACnB,QAAI,CAAC,UAAU,CAAC,EAAG,QAAO,CAAC;AAC3B,WAAO;AAAA,MACL;AAAA,MACA,WAAW,QAAQ,CAAC,EAAE;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,gBAAgB,MAAM;AACpB,UAAM,IAAI;AACV,UAAM,cAAc,GAAG;AACvB,QAAI,CAAC,cAAc,CAAC,EAAG,QAAO,CAAC;AAC/B,UAAM,QAAQ,YAAY,CAAC;AAC3B,UAAM,YAAqC,EAAE,YAAY;AACzD,QAAI,MAAM,eAAgB,WAAU,iBAAiB,MAAM;AAC3D,QAAI,MAAM,KAAM,WAAU,kBAAkB,MAAM;AAClD,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,MAAM;AAClB,UAAM,IAAI;AACV,UAAM,WAAW,GAAG;AACpB,QAAI,CAAC,WAAW,CAAC,EAAG,QAAO,CAAC;AAC5B,UAAM,YAAqC,EAAE,SAAS;AACtD,QAAI,SAAS,CAAC,EAAE,WAAY,WAAU,aAAa,SAAS,CAAC,EAAE;AAC/D,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,MAAM;AACnB,UAAM,IAAI;AACV,UAAM,YAAY,GAAG;AACrB,QAAI,CAAC,YAAY,CAAC,EAAG,QAAO,CAAC;AAC7B,UAAM,YAAqC,EAAE,UAAU;AACvD,QAAI,UAAU,CAAC,EAAE,YAAa,WAAU,cAAc,UAAU,CAAC,EAAE;AACnE,WAAO;AAAA,EACT;AAAA,EAEA,mBAAmB,MAAM;AACvB,UAAM,IAAI;AACV,UAAM,UAAU,GAAG;AACnB,QAAI,CAAC,UAAU,CAAC,EAAG,QAAO,CAAC;AAC3B,UAAM,YAAqC,EAAE,eAAe,QAAQ;AACpE,QAAI,QAAQ,CAAC,EAAE,gBAAiB,WAAU,kBAAkB,QAAQ,CAAC,EAAE;AACvE,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,MAAM;AACxB,UAAM,IAAI;AACV,UAAM,YAAqC,CAAC;AAC5C,QAAI,GAAG,WAAY,WAAU,aAAa,EAAE;AAC5C,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,MAAM;AACpB,UAAM,IAAI;AACV,UAAM,YAAqC,CAAC;AAC5C,QAAI,GAAG,YAAa,WAAU,cAAc,EAAE;AAC9C,UAAM,YAAY,GAAG;AACrB,QAAI,YAAY,CAAC,GAAG,YAAa,WAAU,cAAc,UAAU,CAAC,EAAE;AACtE,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,MAAM;AACf,UAAM,IAAI;AACV,UAAM,QAAQ,GAAG;AACjB,QAAI,CAAC,QAAQ,CAAC,EAAG,QAAO,CAAC;AACzB,WAAO,EAAE,SAAS,MAAM,CAAC,EAAE,QAAQ;AAAA,EACrC;AAAA,EAEA,qBAAqB,MAAM;AACzB,UAAM,IAAI;AACV,UAAM,OAAO,GAAG;AAChB,QAAI,CAAC,KAAM,QAAO,CAAC;AACnB,UAAM,YAAqC,CAAC;AAC5C,QAAI,KAAK,QAAS,WAAU,mBAAmB,KAAK;AACpD,QAAI,KAAK,KAAM,WAAU,qBAAqB,KAAK;AAGnD,WAAO;AAAA,EACT;AAAA,EAEA,yBAAyB,MAAM;AAC7B,UAAM,IAAI;AACV,QAAI,CAAC,GAAG,aAAc,QAAO,CAAC;AAC9B,WAAO,EAAE,sBAAsB,EAAE,aAAa;AAAA,EAChD;AAAA,EAEA,WAAW,MAAM;AACf,UAAM,IAAI;AACV,UAAM,SAAS,GAAG;AAClB,QAAI,CAAC,SAAS,CAAC,GAAG,UAAW,QAAO,CAAC;AACrC,WAAO,EAAE,WAAW,OAAO,CAAC,EAAE,UAAU;AAAA,EAC1C;AAAA,EAEA,eAAe,MAAM;AACnB,UAAM,IAAI;AACV,QAAI,CAAC,GAAG,gBAAiB,QAAO,CAAC;AACjC,WAAO,EAAE,iBAAiB,EAAE,iBAAiB,WAAW,EAAE,UAAU;AAAA,EACtE;AAAA,EAEA,gBAAgB,MAAM;AAEpB,WAAO,EAAE,mBAAmB,MAAM,qBAAqB,KAAK;AAAA,EAC9D;AAAA,EAEA,iBAAiB,MAAM;AACrB,UAAM,IAAI;AACV,UAAM,YAAqC,CAAC;AAC5C,QAAI,GAAG,mBAAoB,WAAU,qBAAqB,EAAE;AAC5D,QAAI,GAAG,SAAU,WAAU,WAAW,EAAE;AACxC,QAAI,GAAG,QAAS,WAAU,UAAU,EAAE;AACtC,QAAI,GAAG,QAAS,WAAU,oBAAoB,EAAE;AAChD,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB,MAAM;AACxB,UAAM,IAAI;AACV,UAAM,YAAqC,CAAC;AAC5C,QAAI,GAAG,WAAY,WAAU,aAAa,EAAE;AAC5C,QAAI,GAAG,cAAe,WAAU,iBAAiB,EAAE;AACnD,WAAO;AAAA,EACT;AACF;AAKO,SAAS,eAAe,UAAkB,MAAwC;AACvF,QAAM,YAAY,mBAAmB,QAAQ;AAC7C,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,MAAI;AACF,WAAO,UAAU,IAAI;AAAA,EACvB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAmBA,MAAM,cAAc,oBAAI,QAAmD;AAK3E,SAAS,cAAc,SAAoD;AACzE,MAAI,QAAQ,YAAY,IAAI,OAAO;AACnC,MAAI,CAAC,OAAO;AACV,YAAQ,CAAC;AACT,gBAAY,IAAI,SAAS,KAAK;AAAA,EAChC;AACA,SAAO;AACT;AAQO,SAAS,kBAAkB,MAAyB,IAA6B;AACtF,QAAM,QAAQ,YAAY,IAAI,IAAI;AAClC,MAAI,MAAO,aAAY,IAAI,IAAI,KAAK;AACtC;AAsCO,SAAS,sBAAsB,OAAiC,CAAC,GAAoB;AAC1F,SAAO;AAAA,IACL,YAAY,KAAK,IAAI;AAAA,IACrB,GAAI,KAAK,gBAAgB,UAAa,EAAE,aAAa,KAAK,YAAY;AAAA,IACtE,kBAAkB,oBAAI,IAAI;AAAA,IAC1B,UAAU,oBAAI,IAAI;AAAA,EACpB;AACF;AAeO,SAAS,cACd,KACA,SACA,YACyB;AACzB,SAAO,YAAY,KAAK,SAAS,UAAU;AAC7C;AAEA,SAAS,YAAY,OAAgB,SAA4B,YAAuC;AACtG,MAAI,OAAO,UAAU,UAAU;AAG7B,UAAM,WAAW,aAAa,eAAe,OAAO,UAAU,IAAI;AAElE,UAAM,WAAW,SAAS,MAAM,oBAAoB;AACpD,QAAI,WAAW,CAAC,GAAG;AACjB,YAAM,MAAM,SAAS,CAAC;AACtB,aAAO,OAAO,UAAU,QAAQ,GAAG,IAAI;AAAA,IACzC;AACA,UAAM,WAAW,SAAS,MAAM,yDAAyD;AACzF,QAAI,UAAU;AACZ,YAAM,QAAQ,SAAS,CAAC;AACxB,UAAI,OAAO;AACT,cAAM,QAAQ,cAAc,OAAO;AACnC,YAAI,EAAE,SAAS,OAAQ,OAAM,KAAK,QAAI,+BAAW;AACjD,eAAO,MAAM,KAAK;AAAA,MACpB;AACA,iBAAO,+BAAW;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,UAAQ,YAAY,MAAM,SAAS,UAAU,CAAC;AAAA,EACjE;AAEA,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAgC,GAAG;AACrE,aAAO,CAAC,IAAI,YAAY,GAAG,SAAS,UAAU;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAgBA,MAAM,oBAAoB;AAE1B,SAAS,eAAe,OAAe,YAAqC;AAC1E,SAAO,MAAM,QAAQ,mBAAmB,CAAC,OAAO,UAAU;AACxD,QAAI,UAAU,uBAAuB;AACnC,aAAO,WAAW,eAAe;AAAA,IACnC;AACA,UAAM,kBAAkB,wCAAwC,KAAK,KAAK;AAC1E,QAAI,kBAAkB,CAAC,GAAG;AACxB,UAAI,CAAC,WAAW,YAAa,QAAO;AACpC,YAAM,SAAS,gBAAgB,CAAC;AAChC,UAAI,OAAO,WAAW,iBAAiB,IAAI,MAAM;AACjD,UAAI,CAAC,MAAM;AACT,mBAAO,+BAAW;AAClB,mBAAW,iBAAiB,IAAI,QAAQ,IAAI;AAAA,MAC9C;AACA,aAAO,GAAG,WAAW,WAAW,SAAS,MAAM,IAAI,IAAI;AAAA,IACzD;AACA,UAAM,aAAa,8CAA8C,KAAK,KAAK;AAC3E,QAAI,aAAa,CAAC,GAAG;AACnB,aAAO,WAAW,iBAAiB,IAAI,WAAW,CAAC,CAAC,KAAK;AAAA,IAC3D;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAmBO,SAAS,oBAAoB,MAAe,SAAmD;AACpG,QAAM,SAAkC,CAAC;AACzC,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,KAAM;AAClB,UAAM,YAAQ,yBAAY,MAAM,OAAO,IAAI;AAC3C,QAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACzD,aAAO,OAAO,GAAG,IAAI;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;AAuCO,SAAS,6BAA6B,UAAkB,MAAe,QAAoC;AAChH,QAAM,SAAS,eAAe,UAAU,IAAI;AAC5C,QAAM,eAAe,MAAM;AACzB,UAAM,WAAW,SAAS,IAAI;AAC9B,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO,UAAU,YAAY,YAAY,MAAM,QAAQ,SAAS,QAAQ,IACpE,CAAC,EAAE,MAAM,qBAAqB,CAAC,IAC/B;AAAA,MACN,KAAK;AACH,eAAO,OAAO,cAAc,CAAC,EAAE,MAAM,sBAAsB,CAAC,IAAI;AAAA,MAClE,KAAK;AACH,eAAO,OAAO,cAAc,CAAC,EAAE,MAAM,sBAAsB,CAAC,IAAI;AAAA,MAClE,KAAK;AACH,cAAM,cAAc,MAAM,QAAQ,UAAU,OAAO,IAC/C,SAAS,QACN,IAAI,QAAQ,EACZ,OAAO,YAAU,QAAQ,YAAY,UAAU,EAC/C,IAAI,YAAU,QAAQ,WAAW,EACjC,OAAO,gBAAc,eAAe,MAAS,IAChD,CAAC;AACL,eAAO,YAAY,SACf,CAAC,EAAE,MAAM,uBAAuB,MAAM,EAAE,KAAK,eAAe,QAAQ,YAAY,EAAE,CAAC,IACnF;AAAA,MACN;AACE,eAAO;AAAA,IACX;AAAA,EACF,GAAG;AACH,QAAM,aAAqD,CAAC;AAC5D,aAAW,OAAO,OAAO,KAAK,MAAM,GAAG;AACrC,eAAW,GAAG,IAAI;AAAA,MAChB,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,aAAa;AAAA,IACf;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,YAAY,GAAI,eAAe,EAAE,YAAY,EAAG;AACnE;AAmBO,SAAS,kCACd,MACA,SACA,QACA,UACA,SACoB;AACpB,QAAM,SAAkC,CAAC;AACzC,QAAM,aAAqD,CAAC;AAC5D,QAAM,WAAoE,CAAC;AAC3E,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,aAAa,QAAW;AAKjC,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI;AAAA,UACR,6DAA6D,OAAO,GAAG,wBAC/C,OAAO,QAAQ;AAAA,QAEzC;AAAA,MACF;AACA,YAAM,QAAQ,cAAc,OAAO;AACnC,UAAI;AACJ,UAAI,OAAO,OAAO,OAAO;AACvB,gBAAQ,MAAM,OAAO,GAAG;AAAA,MAC1B,OAAO;AACL,oBAAQ,+BAAW;AACnB,cAAM,OAAO,GAAG,IAAI;AAAA,MACtB;AACA,aAAO,OAAO,GAAG,IAAI;AACrB,iBAAW,OAAO,GAAG,IAAI;AAAA,QACvB,gBAAgB;AAAA,QAChB,aAAa;AAAA,QACb,aAAa;AAAA,MACf;AAAA,IACF,WAAW,OAAO,MAAM;AACtB,YAAM,YAAQ,yBAAY,MAAM,OAAO,IAAI;AAK3C,YAAM,WAAW,UAAU,UAAa,UAAU,QAAQ,UAAU;AACpE,UAAI,CAAC,UAAU;AACb,eAAO,OAAO,GAAG,IAAI;AACrB,mBAAW,OAAO,GAAG,IAAI;AAAA,UACvB,gBAAgB;AAAA,UAChB,aAAa;AAAA,UACb,eAAe,OAAO;AAAA,UACtB,aAAa;AAAA,QACf;AAAA,MACF,OAAO;AACL,iBAAS,KAAK;AAAA,UACZ,KAAK,OAAO;AAAA,UACZ,MAAM,OAAO;AAAA,UACb,UAAU,UAAU,SAAY,OAAO;AAAA,QACzC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,YAAY,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC,EAAG;AAC5E;AAUO,SAAS,mBACd,SACA,QACA,SACyB;AACzB,QAAM,SAAS,gBAAgB,OAAO;AACtC,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAM,OAAO,SAAS;AACxB,+BAAQ,QAAQ,MAAM,WAAW,QAAQ,MAAM,GAAG,CAAC;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AACT;","names":["import_path"]}
|
|
@@ -86,13 +86,18 @@ const CONTEXT_EXTRACTORS = {
|
|
|
86
86
|
return { account_id: accounts[0].account_id };
|
|
87
87
|
},
|
|
88
88
|
get_products(data) {
|
|
89
|
-
const d = data;
|
|
89
|
+
const d = asRecord(data);
|
|
90
90
|
const products = d?.products;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
const extracted = {};
|
|
92
|
+
if (products?.[0]) {
|
|
93
|
+
extracted.products = products;
|
|
94
|
+
if (products[0].product_id) extracted.product_id = products[0].product_id;
|
|
95
|
+
}
|
|
94
96
|
const proposals = d?.proposals;
|
|
95
97
|
if (proposals?.[0]?.proposal_id) extracted.proposal_id = proposals[0].proposal_id;
|
|
98
|
+
if (d?.wholesale_feed_version !== void 0) extracted.wholesale_feed_version = d.wholesale_feed_version;
|
|
99
|
+
if (d?.pricing_version !== void 0) extracted.pricing_version = d.pricing_version;
|
|
100
|
+
if (d?.cache_scope !== void 0) extracted.cache_scope = d.cache_scope;
|
|
96
101
|
return extracted;
|
|
97
102
|
},
|
|
98
103
|
list_products(data) {
|