@adcp/sdk 14.0.0-beta.0 → 14.0.0-beta.1

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.
Files changed (140) hide show
  1. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/get-account-financials-request.json +610 -0
  2. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/get-account-financials-response.json +1055 -0
  3. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/list-accounts-request.json +629 -0
  4. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/list-accounts-response.json +1558 -0
  5. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/report-usage-request.json +702 -0
  6. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/report-usage-response.json +309 -0
  7. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-accounts-request.json +1113 -0
  8. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-accounts-response.json +1567 -0
  9. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-governance-request.json +662 -0
  10. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/account/sync-governance-response.json +921 -0
  11. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/list-creatives-request.json +992 -0
  12. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/list-creatives-response.json +5965 -0
  13. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/sync-creatives-request.json +3936 -0
  14. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/creative/sync-creatives-response.json +3859 -0
  15. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/manifest.json +206 -0
  16. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-request.json +601 -0
  17. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/accept-proposal-response.json +4799 -0
  18. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-request.json +4107 -0
  19. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/buy-products-response.json +4799 -0
  20. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-request.json +3365 -0
  21. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/control-media-buy-response.json +656 -0
  22. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/decline-proposals-request.json +334 -0
  23. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/decline-proposals-response.json +271 -0
  24. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buy-delivery-request.json +1236 -0
  25. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buy-delivery-response.json +2861 -0
  26. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buys-request.json +678 -0
  27. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/get-media-buys-response.json +10861 -0
  28. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/list-products-request.json +4229 -0
  29. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/list-products-response.json +3824 -0
  30. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/log-event-request.json +421 -0
  31. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/log-event-response.json +394 -0
  32. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/media-buy-delivery-webhook-result.json +1366 -0
  33. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/provide-performance-feedback-request.json +884 -0
  34. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/provide-performance-feedback-response.json +422 -0
  35. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/refine-proposals-request.json +4335 -0
  36. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/refine-proposals-response.json +7328 -0
  37. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/request-proposals-request.json +4307 -0
  38. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/request-proposals-response.json +7105 -0
  39. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-audiences-request.json +760 -0
  40. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-audiences-response.json +541 -0
  41. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-catalogs-request.json +1142 -0
  42. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-catalogs-response.json +1153 -0
  43. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-event-sources-request.json +743 -0
  44. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/media-buy/sync-event-sources-response.json +619 -0
  45. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/get-account-financials-request.json +544 -0
  46. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/list-accounts-request.json +557 -0
  47. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/report-usage-request.json +617 -0
  48. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/sync-accounts-request.json +984 -0
  49. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/account/sync-governance-request.json +581 -0
  50. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/creative/list-creatives-request.json +878 -0
  51. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/creative/sync-creatives-request.json +3456 -0
  52. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/manifest.json +175 -0
  53. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/accept-proposal-request.json +498 -0
  54. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/buy-products-request.json +3675 -0
  55. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/control-media-buy-request.json +3030 -0
  56. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/decline-proposals-request.json +282 -0
  57. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/get-media-buy-delivery-request.json +1136 -0
  58. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/get-media-buys-request.json +597 -0
  59. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/list-products-request.json +3780 -0
  60. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/log-event-request.json +386 -0
  61. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/provide-performance-feedback-request.json +784 -0
  62. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/refine-proposals-request.json +3878 -0
  63. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/request-proposals-request.json +3852 -0
  64. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/sync-audiences-request.json +682 -0
  65. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/sync-catalogs-request.json +1016 -0
  66. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/media-buy/sync-event-sources-request.json +660 -0
  67. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/get-adcp-capabilities-request.json +51 -0
  68. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/get-task-status-request.json +534 -0
  69. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/list-tasks-request.json +692 -0
  70. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/model-context/protocol/sync-agent-notification-configs-request.json +129 -0
  71. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-adcp-capabilities-request.json +58 -0
  72. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-adcp-capabilities-response.json +8069 -0
  73. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-task-status-request.json +601 -0
  74. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/get-task-status-response.json +612 -0
  75. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/list-tasks-request.json +775 -0
  76. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/list-tasks-response.json +483 -0
  77. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/sync-agent-notification-configs-request.json +155 -0
  78. package/dist/lib/schemas-data/3.2.0-beta.0/mcp/2026-07-28/profiles/media-buy/protocol/sync-agent-notification-configs-response.json +382 -0
  79. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  80. package/dist/lib/server/create-adcp-server.d.mts +27 -0
  81. package/dist/lib/server/create-adcp-server.d.ts +27 -0
  82. package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
  83. package/dist/lib/server/create-adcp-server.js +120 -4
  84. package/dist/lib/server/create-adcp-server.js.map +1 -1
  85. package/dist/lib/server/create-adcp-server.mjs +121 -6
  86. package/dist/lib/server/create-adcp-server.mjs.map +1 -1
  87. package/dist/lib/server/decisioning/context.d.mts +6 -0
  88. package/dist/lib/server/decisioning/context.d.ts +6 -0
  89. package/dist/lib/server/decisioning/context.d.ts.map +1 -1
  90. package/dist/lib/server/decisioning/context.js.map +1 -1
  91. package/dist/lib/server/decisioning/index.d.mts +1 -1
  92. package/dist/lib/server/decisioning/index.d.ts +1 -1
  93. package/dist/lib/server/decisioning/index.d.ts.map +1 -1
  94. package/dist/lib/server/decisioning/index.js.map +1 -1
  95. package/dist/lib/server/decisioning/index.mjs.map +1 -1
  96. package/dist/lib/server/decisioning/platform.d.mts +21 -6
  97. package/dist/lib/server/decisioning/platform.d.ts +21 -6
  98. package/dist/lib/server/decisioning/platform.d.ts.map +1 -1
  99. package/dist/lib/server/decisioning/platform.js.map +1 -1
  100. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
  101. package/dist/lib/server/decisioning/runtime/from-platform.js +201 -18
  102. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  103. package/dist/lib/server/decisioning/runtime/from-platform.mjs +203 -19
  104. package/dist/lib/server/decisioning/runtime/from-platform.mjs.map +1 -1
  105. package/dist/lib/server/decisioning/runtime/to-context.d.ts.map +1 -1
  106. package/dist/lib/server/decisioning/runtime/to-context.js +6 -0
  107. package/dist/lib/server/decisioning/runtime/to-context.js.map +1 -1
  108. package/dist/lib/server/decisioning/runtime/to-context.mjs +6 -0
  109. package/dist/lib/server/decisioning/runtime/to-context.mjs.map +1 -1
  110. package/dist/lib/server/decisioning/runtime/validate-platform.d.ts.map +1 -1
  111. package/dist/lib/server/decisioning/runtime/validate-platform.js +35 -4
  112. package/dist/lib/server/decisioning/runtime/validate-platform.js.map +1 -1
  113. package/dist/lib/server/decisioning/runtime/validate-platform.mjs +35 -4
  114. package/dist/lib/server/decisioning/runtime/validate-platform.mjs.map +1 -1
  115. package/dist/lib/server/decisioning/specialisms/sales.d.mts +39 -0
  116. package/dist/lib/server/decisioning/specialisms/sales.d.ts +39 -0
  117. package/dist/lib/server/decisioning/specialisms/sales.d.ts.map +1 -1
  118. package/dist/lib/server/decisioning/specialisms/sales.js.map +1 -1
  119. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  120. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  121. package/dist/lib/validation/schema-loader.d.mts +2 -0
  122. package/dist/lib/validation/schema-loader.d.ts +2 -0
  123. package/dist/lib/validation/schema-loader.d.ts.map +1 -1
  124. package/dist/lib/validation/schema-loader.js +31 -0
  125. package/dist/lib/validation/schema-loader.js.map +1 -1
  126. package/dist/lib/validation/schema-loader.mjs +30 -0
  127. package/dist/lib/validation/schema-loader.mjs.map +1 -1
  128. package/dist/lib/version.d.mts +3 -3
  129. package/dist/lib/version.d.ts +3 -3
  130. package/dist/lib/version.js +3 -3
  131. package/dist/lib/version.js.map +1 -1
  132. package/dist/lib/version.mjs +3 -3
  133. package/dist/lib/version.mjs.map +1 -1
  134. package/docs/guides/BUILD-AN-AGENT.md +10 -1
  135. package/docs/guides/MEDIA-BUY-3.2-COMPATIBILITY.md +119 -0
  136. package/docs/llms.txt +1 -1
  137. package/docs/migration-12-to-14.md +8 -0
  138. package/docs/migration-13-to-14.md +30 -4
  139. package/docs/releases/14.0.0-beta.0.md +19 -1
  140. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"to-context.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/runtime/to-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAgC,MAAM,oBAAoB,CAAC;AAgDzF,wBAAgB,mBAAmB,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpE,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAC7C,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAqEnC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAgBlG"}
1
+ {"version":3,"file":"to-context.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/runtime/to-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAgC,MAAM,oBAAoB,CAAC;AAgDzF,wBAAgB,mBAAmB,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpE,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAC7C,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CA2EnC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAgBlG"}
@@ -71,6 +71,12 @@ function buildRequestContext(handlerCtx, ctxMetadataStore, input) {
71
71
  return {
72
72
  account,
73
73
  ...handlerCtx.agent != null && { agent: handlerCtx.agent },
74
+ ...handlerCtx.callerMutationScope != null && {
75
+ callerMutationScope: Object.freeze({ ...handlerCtx.callerMutationScope })
76
+ },
77
+ ...handlerCtx.proposalRefinementScope != null && {
78
+ proposalRefinementScope: Object.freeze({ ...handlerCtx.proposalRefinementScope })
79
+ },
74
80
  ...input != null && { input },
75
81
  state: {
76
82
  findByObject: () => [],
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/to-context.ts"],"sourcesContent":["/**\n * Translate the existing `HandlerContext` into the v6 `RequestContext` shape\n * that platform methods receive.\n *\n * The handler-style framework already resolves the account, sets sessionKey,\n * and exposes `store` + `authInfo` + `emitWebhook`. The new context layers\n * `state.*` (sync state reads), `resolve.*` (async framework-mediated\n * resolvers), and `handoffToTask(...)` (the unified hybrid-seller handoff\n * primitive) on top.\n *\n * **Stub status — v6.0 alpha.** `state.*` (workflow-step reads, proposal\n * lookups, governance JWS) and `resolve.*` (property/collection-list +\n * format fetchers) are NOT yet wired. The state readers return empty\n * results; the resolvers throw. Touching them in a platform method will\n * crash the request — the framework hasn't connected them to an underlying\n * store / fetch layer yet.\n *\n * Adopters spiking against the preview surface MUST avoid `ctx.state.*`\n * and `ctx.resolve.*` until the wire-up commits land in rc.1. Use\n * `ctx.account`, `ctx.handoffToTask(...)`, and the structured-error /\n * status-change primitives only.\n *\n * @internal — framework-internal wiring; not adopter surface. The\n * exported helpers (`buildRequestContext`, `buildHandoffContext`) are\n * called from the dispatch seam in `from-platform.ts`. Adopters should\n * never construct a `RequestContext` themselves; the framework supplies\n * one to every specialism method call.\n */\n\nimport type { HandlerContext } from '../../create-adcp-server';\nimport type { Account } from '../account';\nimport type { RequestContext, CtxMetadataAccessor } from '../context';\nimport type { TaskRegistry } from './task-registry';\nimport {\n _createTaskHandoff,\n type TaskHandoffContext,\n type TaskHandoff,\n type TaskHandoffOptions,\n} from '../async-outcome';\nimport type { CtxMetadataStore, ResourceKind, CtxMetadataRef } from '../../ctx-metadata';\n\n/**\n * Build an account-scoped CtxMetadataAccessor for a single request.\n *\n * Account scope comes from `ctx.account.id` — accessor methods don't take\n * an account param. When `account.id` is null/undefined (no-account tools),\n * the accessor methods reject — no-account tools cannot use ctx_metadata\n * (cross-tenant collision risk via missing scope).\n */\nfunction buildCtxMetadataAccessor(store: CtxMetadataStore, accountId: string): CtxMetadataAccessor {\n return {\n get(kind: ResourceKind, id: string) {\n return store.get(accountId, kind, id);\n },\n bulkGet(refs: readonly CtxMetadataRef[]) {\n return store.bulkGet(accountId, refs);\n },\n set(kind: ResourceKind, id: string, value: unknown, ttlSeconds?: number) {\n return store.set(accountId, kind, id, value, ttlSeconds);\n },\n delete(kind: ResourceKind, id: string) {\n return store.delete(accountId, kind, id);\n },\n account(id: string) {\n return store.get(accountId, 'account', id);\n },\n product(id: string) {\n return store.get(accountId, 'product', id);\n },\n mediaBuy(id: string) {\n return store.get(accountId, 'media_buy', id);\n },\n package(id: string) {\n return store.get(accountId, 'package', id);\n },\n creative(id: string) {\n return store.get(accountId, 'creative', id);\n },\n audience(id: string) {\n return store.get(accountId, 'audience', id);\n },\n signal(id: string) {\n return store.get(accountId, 'signal', id);\n },\n };\n}\n\nexport function buildRequestContext<TCtxMeta = Record<string, unknown>>(\n handlerCtx: HandlerContext<Account<TCtxMeta>>,\n ctxMetadataStore?: CtxMetadataStore,\n input?: Readonly<Record<string, unknown>>\n): RequestContext<Account<TCtxMeta>> {\n // `account` may legitimately be undefined for tools whose wire request\n // doesn't carry an `account` field AND whose `resolveAccountFromAuth`\n // returned null (`'explicit'`-mode adopters who don't model the\n // no-account tools, or buyers calling without auth). Adopter handlers\n // for those tools are responsible for either deriving the account\n // themselves (e.g., via `media_buy_id` ownership) or throwing\n // `AdcpError('ACCOUNT_NOT_FOUND')` if account is required.\n //\n // The `RequestContext.account` type is non-optional for ergonomic typing\n // — adopters writing handlers for the 90% case (tools with `account` on\n // the wire) shouldn't have to optional-chain everywhere. Adopters of\n // no-account tools either:\n // 1. Declare `resolution: 'derived'` and return a singleton from\n // `accounts.resolve(undefined)` — `ctx.account` is always set\n // 2. Implement only `'explicit'` and never claim no-account\n // specialisms — the tool is unreachable\n // 3. Read `ctx.account` defensively (`as Account | undefined` cast)\n // and look up by request body when missing\n const account = handlerCtx.account as Account<TCtxMeta>;\n\n const stubResolver = (name: string) => async (): Promise<never> => {\n throw new Error(\n `ctx.resolve.${name}: not yet wired in v6.0 alpha — landing in rc.1. ` +\n `Avoid touching ctx.resolve.* in adopter code until the framework ` +\n `connects this resolver to an underlying fetcher.`\n );\n };\n\n // Bind ctx-metadata accessor when store wired AND account scope present.\n // No-account tools (provide_performance_feedback, list_creative_formats)\n // get `ctx.ctxMetadata = undefined` even when the store is wired — cannot\n // use ctx_metadata without an account boundary (cross-tenant risk).\n const ctxMetadata =\n ctxMetadataStore != null && account != null && (account.id ?? '') !== ''\n ? buildCtxMetadataAccessor(ctxMetadataStore, account.id)\n : undefined;\n\n return {\n account,\n ...(handlerCtx.agent != null && { agent: handlerCtx.agent }),\n ...(input != null && { input }),\n state: {\n findByObject: () => [],\n findProposalById: () => null,\n governanceContext: () => null,\n workflowSteps: () => [],\n },\n resolve: {\n propertyList: stubResolver('propertyList'),\n collectionList: stubResolver('collectionList'),\n creativeFormat: stubResolver('creativeFormat'),\n },\n ctxMetadata,\n handoffToTask<TResult>(\n fn: (taskCtx: TaskHandoffContext) => Promise<TResult>,\n options?: TaskHandoffOptions\n ): TaskHandoff<TResult> {\n if (options?.task_id !== undefined) {\n if (typeof options.task_id !== 'string' || options.task_id.length === 0) {\n throw new Error('handoffToTask options.task_id must be a non-empty string');\n }\n if (options.task_id.length > 128) {\n throw new Error('handoffToTask options.task_id must be ≤ 128 characters');\n }\n }\n return _createTaskHandoff(fn, options);\n },\n };\n}\n\n/**\n * Construct a `TaskHandoffContext` from a registry + framework-issued\n * task id. The framework calls this AFTER detecting a `TaskHandoff`\n * marker on a method's return — the handoff function gets a context\n * carrying the framework-allocated `taskId` plus `update`/`heartbeat`\n * affordances.\n *\n * `update(progress)` writes the progress payload to the task record and\n * transitions status `submitted` → `working`. Buyers polling `tasks_get`\n * see the `progress` object and the `'working'` status — this is the\n * buyer-facing UX signal that distinguishes \"stuck/no news\" from\n * \"step 2/3, awaiting trafficker.\" Errors from the registry write are\n * swallowed so a transient DB hiccup doesn't abort the adopter's handoff\n * function.\n *\n * `heartbeat()` remains a no-op stub (v6.1); it is a liveness / TTL-reset\n * signal for operator infrastructure, not buyer-facing.\n */\nexport function buildHandoffContext(taskRegistry: TaskRegistry, taskId: string): TaskHandoffContext {\n return {\n id: taskId,\n update: async progress => {\n try {\n await taskRegistry.updateProgress(taskId, progress);\n } catch {\n // Swallow — a transient registry write failure must not abort the\n // adopter's background handoff function. The buyer-facing impact is\n // a missed progress event, not a failed task.\n }\n },\n heartbeat: async () => {\n await Promise.resolve();\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCA,2BAKO;AAWP,SAAS,yBAAyB,OAAyB,WAAwC;AACjG,SAAO;AAAA,IACL,IAAI,MAAoB,IAAY;AAClC,aAAO,MAAM,IAAI,WAAW,MAAM,EAAE;AAAA,IACtC;AAAA,IACA,QAAQ,MAAiC;AACvC,aAAO,MAAM,QAAQ,WAAW,IAAI;AAAA,IACtC;AAAA,IACA,IAAI,MAAoB,IAAY,OAAgB,YAAqB;AACvE,aAAO,MAAM,IAAI,WAAW,MAAM,IAAI,OAAO,UAAU;AAAA,IACzD;AAAA,IACA,OAAO,MAAoB,IAAY;AACrC,aAAO,MAAM,OAAO,WAAW,MAAM,EAAE;AAAA,IACzC;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,aAAa,EAAE;AAAA,IAC7C;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,YAAY,EAAE;AAAA,IAC5C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,YAAY,EAAE;AAAA,IAC5C;AAAA,IACA,OAAO,IAAY;AACjB,aAAO,MAAM,IAAI,WAAW,UAAU,EAAE;AAAA,IAC1C;AAAA,EACF;AACF;AAEO,SAAS,oBACd,YACA,kBACA,OACmC;AAmBnC,QAAM,UAAU,WAAW;AAE3B,QAAM,eAAe,CAAC,SAAiB,YAA4B;AACjE,UAAM,IAAI;AAAA,MACR,eAAe,IAAI;AAAA,IAGrB;AAAA,EACF;AAMA,QAAM,cACJ,oBAAoB,QAAQ,WAAW,SAAS,QAAQ,MAAM,QAAQ,KAClE,yBAAyB,kBAAkB,QAAQ,EAAE,IACrD;AAEN,SAAO;AAAA,IACL;AAAA,IACA,GAAI,WAAW,SAAS,QAAQ,EAAE,OAAO,WAAW,MAAM;AAAA,IAC1D,GAAI,SAAS,QAAQ,EAAE,MAAM;AAAA,IAC7B,OAAO;AAAA,MACL,cAAc,MAAM,CAAC;AAAA,MACrB,kBAAkB,MAAM;AAAA,MACxB,mBAAmB,MAAM;AAAA,MACzB,eAAe,MAAM,CAAC;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,MACP,cAAc,aAAa,cAAc;AAAA,MACzC,gBAAgB,aAAa,gBAAgB;AAAA,MAC7C,gBAAgB,aAAa,gBAAgB;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,cACE,IACA,SACsB;AACtB,UAAI,SAAS,YAAY,QAAW;AAClC,YAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,WAAW,GAAG;AACvE,gBAAM,IAAI,MAAM,0DAA0D;AAAA,QAC5E;AACA,YAAI,QAAQ,QAAQ,SAAS,KAAK;AAChC,gBAAM,IAAI,MAAM,6DAAwD;AAAA,QAC1E;AAAA,MACF;AACA,iBAAO,yCAAmB,IAAI,OAAO;AAAA,IACvC;AAAA,EACF;AACF;AAoBO,SAAS,oBAAoB,cAA4B,QAAoC;AAClG,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ,OAAM,aAAY;AACxB,UAAI;AACF,cAAM,aAAa,eAAe,QAAQ,QAAQ;AAAA,MACpD,QAAQ;AAAA,MAIR;AAAA,IACF;AAAA,IACA,WAAW,YAAY;AACrB,YAAM,QAAQ,QAAQ;AAAA,IACxB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/to-context.ts"],"sourcesContent":["/**\n * Translate the existing `HandlerContext` into the v6 `RequestContext` shape\n * that platform methods receive.\n *\n * The handler-style framework already resolves the account, sets sessionKey,\n * and exposes `store` + `authInfo` + `emitWebhook`. The new context layers\n * `state.*` (sync state reads), `resolve.*` (async framework-mediated\n * resolvers), and `handoffToTask(...)` (the unified hybrid-seller handoff\n * primitive) on top.\n *\n * **Stub status — v6.0 alpha.** `state.*` (workflow-step reads, proposal\n * lookups, governance JWS) and `resolve.*` (property/collection-list +\n * format fetchers) are NOT yet wired. The state readers return empty\n * results; the resolvers throw. Touching them in a platform method will\n * crash the request — the framework hasn't connected them to an underlying\n * store / fetch layer yet.\n *\n * Adopters spiking against the preview surface MUST avoid `ctx.state.*`\n * and `ctx.resolve.*` until the wire-up commits land in rc.1. Use\n * `ctx.account`, `ctx.handoffToTask(...)`, and the structured-error /\n * status-change primitives only.\n *\n * @internal — framework-internal wiring; not adopter surface. The\n * exported helpers (`buildRequestContext`, `buildHandoffContext`) are\n * called from the dispatch seam in `from-platform.ts`. Adopters should\n * never construct a `RequestContext` themselves; the framework supplies\n * one to every specialism method call.\n */\n\nimport type { HandlerContext } from '../../create-adcp-server';\nimport type { Account } from '../account';\nimport type { RequestContext, CtxMetadataAccessor } from '../context';\nimport type { TaskRegistry } from './task-registry';\nimport {\n _createTaskHandoff,\n type TaskHandoffContext,\n type TaskHandoff,\n type TaskHandoffOptions,\n} from '../async-outcome';\nimport type { CtxMetadataStore, ResourceKind, CtxMetadataRef } from '../../ctx-metadata';\n\n/**\n * Build an account-scoped CtxMetadataAccessor for a single request.\n *\n * Account scope comes from `ctx.account.id` — accessor methods don't take\n * an account param. When `account.id` is null/undefined (no-account tools),\n * the accessor methods reject — no-account tools cannot use ctx_metadata\n * (cross-tenant collision risk via missing scope).\n */\nfunction buildCtxMetadataAccessor(store: CtxMetadataStore, accountId: string): CtxMetadataAccessor {\n return {\n get(kind: ResourceKind, id: string) {\n return store.get(accountId, kind, id);\n },\n bulkGet(refs: readonly CtxMetadataRef[]) {\n return store.bulkGet(accountId, refs);\n },\n set(kind: ResourceKind, id: string, value: unknown, ttlSeconds?: number) {\n return store.set(accountId, kind, id, value, ttlSeconds);\n },\n delete(kind: ResourceKind, id: string) {\n return store.delete(accountId, kind, id);\n },\n account(id: string) {\n return store.get(accountId, 'account', id);\n },\n product(id: string) {\n return store.get(accountId, 'product', id);\n },\n mediaBuy(id: string) {\n return store.get(accountId, 'media_buy', id);\n },\n package(id: string) {\n return store.get(accountId, 'package', id);\n },\n creative(id: string) {\n return store.get(accountId, 'creative', id);\n },\n audience(id: string) {\n return store.get(accountId, 'audience', id);\n },\n signal(id: string) {\n return store.get(accountId, 'signal', id);\n },\n };\n}\n\nexport function buildRequestContext<TCtxMeta = Record<string, unknown>>(\n handlerCtx: HandlerContext<Account<TCtxMeta>>,\n ctxMetadataStore?: CtxMetadataStore,\n input?: Readonly<Record<string, unknown>>\n): RequestContext<Account<TCtxMeta>> {\n // `account` may legitimately be undefined for tools whose wire request\n // doesn't carry an `account` field AND whose `resolveAccountFromAuth`\n // returned null (`'explicit'`-mode adopters who don't model the\n // no-account tools, or buyers calling without auth). Adopter handlers\n // for those tools are responsible for either deriving the account\n // themselves (e.g., via `media_buy_id` ownership) or throwing\n // `AdcpError('ACCOUNT_NOT_FOUND')` if account is required.\n //\n // The `RequestContext.account` type is non-optional for ergonomic typing\n // — adopters writing handlers for the 90% case (tools with `account` on\n // the wire) shouldn't have to optional-chain everywhere. Adopters of\n // no-account tools either:\n // 1. Declare `resolution: 'derived'` and return a singleton from\n // `accounts.resolve(undefined)` — `ctx.account` is always set\n // 2. Implement only `'explicit'` and never claim no-account\n // specialisms — the tool is unreachable\n // 3. Read `ctx.account` defensively (`as Account | undefined` cast)\n // and look up by request body when missing\n const account = handlerCtx.account as Account<TCtxMeta>;\n\n const stubResolver = (name: string) => async (): Promise<never> => {\n throw new Error(\n `ctx.resolve.${name}: not yet wired in v6.0 alpha — landing in rc.1. ` +\n `Avoid touching ctx.resolve.* in adopter code until the framework ` +\n `connects this resolver to an underlying fetcher.`\n );\n };\n\n // Bind ctx-metadata accessor when store wired AND account scope present.\n // No-account tools (provide_performance_feedback, list_creative_formats)\n // get `ctx.ctxMetadata = undefined` even when the store is wired — cannot\n // use ctx_metadata without an account boundary (cross-tenant risk).\n const ctxMetadata =\n ctxMetadataStore != null && account != null && (account.id ?? '') !== ''\n ? buildCtxMetadataAccessor(ctxMetadataStore, account.id)\n : undefined;\n\n return {\n account,\n ...(handlerCtx.agent != null && { agent: handlerCtx.agent }),\n ...(handlerCtx.callerMutationScope != null && {\n callerMutationScope: Object.freeze({ ...handlerCtx.callerMutationScope }),\n }),\n ...(handlerCtx.proposalRefinementScope != null && {\n proposalRefinementScope: Object.freeze({ ...handlerCtx.proposalRefinementScope }),\n }),\n ...(input != null && { input }),\n state: {\n findByObject: () => [],\n findProposalById: () => null,\n governanceContext: () => null,\n workflowSteps: () => [],\n },\n resolve: {\n propertyList: stubResolver('propertyList'),\n collectionList: stubResolver('collectionList'),\n creativeFormat: stubResolver('creativeFormat'),\n },\n ctxMetadata,\n handoffToTask<TResult>(\n fn: (taskCtx: TaskHandoffContext) => Promise<TResult>,\n options?: TaskHandoffOptions\n ): TaskHandoff<TResult> {\n if (options?.task_id !== undefined) {\n if (typeof options.task_id !== 'string' || options.task_id.length === 0) {\n throw new Error('handoffToTask options.task_id must be a non-empty string');\n }\n if (options.task_id.length > 128) {\n throw new Error('handoffToTask options.task_id must be ≤ 128 characters');\n }\n }\n return _createTaskHandoff(fn, options);\n },\n };\n}\n\n/**\n * Construct a `TaskHandoffContext` from a registry + framework-issued\n * task id. The framework calls this AFTER detecting a `TaskHandoff`\n * marker on a method's return — the handoff function gets a context\n * carrying the framework-allocated `taskId` plus `update`/`heartbeat`\n * affordances.\n *\n * `update(progress)` writes the progress payload to the task record and\n * transitions status `submitted` → `working`. Buyers polling `tasks_get`\n * see the `progress` object and the `'working'` status — this is the\n * buyer-facing UX signal that distinguishes \"stuck/no news\" from\n * \"step 2/3, awaiting trafficker.\" Errors from the registry write are\n * swallowed so a transient DB hiccup doesn't abort the adopter's handoff\n * function.\n *\n * `heartbeat()` remains a no-op stub (v6.1); it is a liveness / TTL-reset\n * signal for operator infrastructure, not buyer-facing.\n */\nexport function buildHandoffContext(taskRegistry: TaskRegistry, taskId: string): TaskHandoffContext {\n return {\n id: taskId,\n update: async progress => {\n try {\n await taskRegistry.updateProgress(taskId, progress);\n } catch {\n // Swallow — a transient registry write failure must not abort the\n // adopter's background handoff function. The buyer-facing impact is\n // a missed progress event, not a failed task.\n }\n },\n heartbeat: async () => {\n await Promise.resolve();\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -49,6 +49,12 @@ function buildRequestContext(handlerCtx, ctxMetadataStore, input) {
49
49
  return {
50
50
  account,
51
51
  ...handlerCtx.agent != null && { agent: handlerCtx.agent },
52
+ ...handlerCtx.callerMutationScope != null && {
53
+ callerMutationScope: Object.freeze({ ...handlerCtx.callerMutationScope })
54
+ },
55
+ ...handlerCtx.proposalRefinementScope != null && {
56
+ proposalRefinementScope: Object.freeze({ ...handlerCtx.proposalRefinementScope })
57
+ },
52
58
  ...input != null && { input },
53
59
  state: {
54
60
  findByObject: () => [],
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/to-context.ts"],"sourcesContent":["/**\n * Translate the existing `HandlerContext` into the v6 `RequestContext` shape\n * that platform methods receive.\n *\n * The handler-style framework already resolves the account, sets sessionKey,\n * and exposes `store` + `authInfo` + `emitWebhook`. The new context layers\n * `state.*` (sync state reads), `resolve.*` (async framework-mediated\n * resolvers), and `handoffToTask(...)` (the unified hybrid-seller handoff\n * primitive) on top.\n *\n * **Stub status — v6.0 alpha.** `state.*` (workflow-step reads, proposal\n * lookups, governance JWS) and `resolve.*` (property/collection-list +\n * format fetchers) are NOT yet wired. The state readers return empty\n * results; the resolvers throw. Touching them in a platform method will\n * crash the request — the framework hasn't connected them to an underlying\n * store / fetch layer yet.\n *\n * Adopters spiking against the preview surface MUST avoid `ctx.state.*`\n * and `ctx.resolve.*` until the wire-up commits land in rc.1. Use\n * `ctx.account`, `ctx.handoffToTask(...)`, and the structured-error /\n * status-change primitives only.\n *\n * @internal — framework-internal wiring; not adopter surface. The\n * exported helpers (`buildRequestContext`, `buildHandoffContext`) are\n * called from the dispatch seam in `from-platform.ts`. Adopters should\n * never construct a `RequestContext` themselves; the framework supplies\n * one to every specialism method call.\n */\n\nimport type { HandlerContext } from '../../create-adcp-server';\nimport type { Account } from '../account';\nimport type { RequestContext, CtxMetadataAccessor } from '../context';\nimport type { TaskRegistry } from './task-registry';\nimport {\n _createTaskHandoff,\n type TaskHandoffContext,\n type TaskHandoff,\n type TaskHandoffOptions,\n} from '../async-outcome';\nimport type { CtxMetadataStore, ResourceKind, CtxMetadataRef } from '../../ctx-metadata';\n\n/**\n * Build an account-scoped CtxMetadataAccessor for a single request.\n *\n * Account scope comes from `ctx.account.id` — accessor methods don't take\n * an account param. When `account.id` is null/undefined (no-account tools),\n * the accessor methods reject — no-account tools cannot use ctx_metadata\n * (cross-tenant collision risk via missing scope).\n */\nfunction buildCtxMetadataAccessor(store: CtxMetadataStore, accountId: string): CtxMetadataAccessor {\n return {\n get(kind: ResourceKind, id: string) {\n return store.get(accountId, kind, id);\n },\n bulkGet(refs: readonly CtxMetadataRef[]) {\n return store.bulkGet(accountId, refs);\n },\n set(kind: ResourceKind, id: string, value: unknown, ttlSeconds?: number) {\n return store.set(accountId, kind, id, value, ttlSeconds);\n },\n delete(kind: ResourceKind, id: string) {\n return store.delete(accountId, kind, id);\n },\n account(id: string) {\n return store.get(accountId, 'account', id);\n },\n product(id: string) {\n return store.get(accountId, 'product', id);\n },\n mediaBuy(id: string) {\n return store.get(accountId, 'media_buy', id);\n },\n package(id: string) {\n return store.get(accountId, 'package', id);\n },\n creative(id: string) {\n return store.get(accountId, 'creative', id);\n },\n audience(id: string) {\n return store.get(accountId, 'audience', id);\n },\n signal(id: string) {\n return store.get(accountId, 'signal', id);\n },\n };\n}\n\nexport function buildRequestContext<TCtxMeta = Record<string, unknown>>(\n handlerCtx: HandlerContext<Account<TCtxMeta>>,\n ctxMetadataStore?: CtxMetadataStore,\n input?: Readonly<Record<string, unknown>>\n): RequestContext<Account<TCtxMeta>> {\n // `account` may legitimately be undefined for tools whose wire request\n // doesn't carry an `account` field AND whose `resolveAccountFromAuth`\n // returned null (`'explicit'`-mode adopters who don't model the\n // no-account tools, or buyers calling without auth). Adopter handlers\n // for those tools are responsible for either deriving the account\n // themselves (e.g., via `media_buy_id` ownership) or throwing\n // `AdcpError('ACCOUNT_NOT_FOUND')` if account is required.\n //\n // The `RequestContext.account` type is non-optional for ergonomic typing\n // — adopters writing handlers for the 90% case (tools with `account` on\n // the wire) shouldn't have to optional-chain everywhere. Adopters of\n // no-account tools either:\n // 1. Declare `resolution: 'derived'` and return a singleton from\n // `accounts.resolve(undefined)` — `ctx.account` is always set\n // 2. Implement only `'explicit'` and never claim no-account\n // specialisms — the tool is unreachable\n // 3. Read `ctx.account` defensively (`as Account | undefined` cast)\n // and look up by request body when missing\n const account = handlerCtx.account as Account<TCtxMeta>;\n\n const stubResolver = (name: string) => async (): Promise<never> => {\n throw new Error(\n `ctx.resolve.${name}: not yet wired in v6.0 alpha — landing in rc.1. ` +\n `Avoid touching ctx.resolve.* in adopter code until the framework ` +\n `connects this resolver to an underlying fetcher.`\n );\n };\n\n // Bind ctx-metadata accessor when store wired AND account scope present.\n // No-account tools (provide_performance_feedback, list_creative_formats)\n // get `ctx.ctxMetadata = undefined` even when the store is wired — cannot\n // use ctx_metadata without an account boundary (cross-tenant risk).\n const ctxMetadata =\n ctxMetadataStore != null && account != null && (account.id ?? '') !== ''\n ? buildCtxMetadataAccessor(ctxMetadataStore, account.id)\n : undefined;\n\n return {\n account,\n ...(handlerCtx.agent != null && { agent: handlerCtx.agent }),\n ...(input != null && { input }),\n state: {\n findByObject: () => [],\n findProposalById: () => null,\n governanceContext: () => null,\n workflowSteps: () => [],\n },\n resolve: {\n propertyList: stubResolver('propertyList'),\n collectionList: stubResolver('collectionList'),\n creativeFormat: stubResolver('creativeFormat'),\n },\n ctxMetadata,\n handoffToTask<TResult>(\n fn: (taskCtx: TaskHandoffContext) => Promise<TResult>,\n options?: TaskHandoffOptions\n ): TaskHandoff<TResult> {\n if (options?.task_id !== undefined) {\n if (typeof options.task_id !== 'string' || options.task_id.length === 0) {\n throw new Error('handoffToTask options.task_id must be a non-empty string');\n }\n if (options.task_id.length > 128) {\n throw new Error('handoffToTask options.task_id must be ≤ 128 characters');\n }\n }\n return _createTaskHandoff(fn, options);\n },\n };\n}\n\n/**\n * Construct a `TaskHandoffContext` from a registry + framework-issued\n * task id. The framework calls this AFTER detecting a `TaskHandoff`\n * marker on a method's return — the handoff function gets a context\n * carrying the framework-allocated `taskId` plus `update`/`heartbeat`\n * affordances.\n *\n * `update(progress)` writes the progress payload to the task record and\n * transitions status `submitted` → `working`. Buyers polling `tasks_get`\n * see the `progress` object and the `'working'` status — this is the\n * buyer-facing UX signal that distinguishes \"stuck/no news\" from\n * \"step 2/3, awaiting trafficker.\" Errors from the registry write are\n * swallowed so a transient DB hiccup doesn't abort the adopter's handoff\n * function.\n *\n * `heartbeat()` remains a no-op stub (v6.1); it is a liveness / TTL-reset\n * signal for operator infrastructure, not buyer-facing.\n */\nexport function buildHandoffContext(taskRegistry: TaskRegistry, taskId: string): TaskHandoffContext {\n return {\n id: taskId,\n update: async progress => {\n try {\n await taskRegistry.updateProgress(taskId, progress);\n } catch {\n // Swallow — a transient registry write failure must not abort the\n // adopter's background handoff function. The buyer-facing impact is\n // a missed progress event, not a failed task.\n }\n },\n heartbeat: async () => {\n await Promise.resolve();\n },\n };\n}\n"],"mappings":"AAiCA;AAAA,EACE;AAAA,OAIK;AAWP,SAAS,yBAAyB,OAAyB,WAAwC;AACjG,SAAO;AAAA,IACL,IAAI,MAAoB,IAAY;AAClC,aAAO,MAAM,IAAI,WAAW,MAAM,EAAE;AAAA,IACtC;AAAA,IACA,QAAQ,MAAiC;AACvC,aAAO,MAAM,QAAQ,WAAW,IAAI;AAAA,IACtC;AAAA,IACA,IAAI,MAAoB,IAAY,OAAgB,YAAqB;AACvE,aAAO,MAAM,IAAI,WAAW,MAAM,IAAI,OAAO,UAAU;AAAA,IACzD;AAAA,IACA,OAAO,MAAoB,IAAY;AACrC,aAAO,MAAM,OAAO,WAAW,MAAM,EAAE;AAAA,IACzC;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,aAAa,EAAE;AAAA,IAC7C;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,YAAY,EAAE;AAAA,IAC5C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,YAAY,EAAE;AAAA,IAC5C;AAAA,IACA,OAAO,IAAY;AACjB,aAAO,MAAM,IAAI,WAAW,UAAU,EAAE;AAAA,IAC1C;AAAA,EACF;AACF;AAEO,SAAS,oBACd,YACA,kBACA,OACmC;AAmBnC,QAAM,UAAU,WAAW;AAE3B,QAAM,eAAe,CAAC,SAAiB,YAA4B;AACjE,UAAM,IAAI;AAAA,MACR,eAAe,IAAI;AAAA,IAGrB;AAAA,EACF;AAMA,QAAM,cACJ,oBAAoB,QAAQ,WAAW,SAAS,QAAQ,MAAM,QAAQ,KAClE,yBAAyB,kBAAkB,QAAQ,EAAE,IACrD;AAEN,SAAO;AAAA,IACL;AAAA,IACA,GAAI,WAAW,SAAS,QAAQ,EAAE,OAAO,WAAW,MAAM;AAAA,IAC1D,GAAI,SAAS,QAAQ,EAAE,MAAM;AAAA,IAC7B,OAAO;AAAA,MACL,cAAc,MAAM,CAAC;AAAA,MACrB,kBAAkB,MAAM;AAAA,MACxB,mBAAmB,MAAM;AAAA,MACzB,eAAe,MAAM,CAAC;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,MACP,cAAc,aAAa,cAAc;AAAA,MACzC,gBAAgB,aAAa,gBAAgB;AAAA,MAC7C,gBAAgB,aAAa,gBAAgB;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,cACE,IACA,SACsB;AACtB,UAAI,SAAS,YAAY,QAAW;AAClC,YAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,WAAW,GAAG;AACvE,gBAAM,IAAI,MAAM,0DAA0D;AAAA,QAC5E;AACA,YAAI,QAAQ,QAAQ,SAAS,KAAK;AAChC,gBAAM,IAAI,MAAM,6DAAwD;AAAA,QAC1E;AAAA,MACF;AACA,aAAO,mBAAmB,IAAI,OAAO;AAAA,IACvC;AAAA,EACF;AACF;AAoBO,SAAS,oBAAoB,cAA4B,QAAoC;AAClG,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ,OAAM,aAAY;AACxB,UAAI;AACF,cAAM,aAAa,eAAe,QAAQ,QAAQ;AAAA,MACpD,QAAQ;AAAA,MAIR;AAAA,IACF;AAAA,IACA,WAAW,YAAY;AACrB,YAAM,QAAQ,QAAQ;AAAA,IACxB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/to-context.ts"],"sourcesContent":["/**\n * Translate the existing `HandlerContext` into the v6 `RequestContext` shape\n * that platform methods receive.\n *\n * The handler-style framework already resolves the account, sets sessionKey,\n * and exposes `store` + `authInfo` + `emitWebhook`. The new context layers\n * `state.*` (sync state reads), `resolve.*` (async framework-mediated\n * resolvers), and `handoffToTask(...)` (the unified hybrid-seller handoff\n * primitive) on top.\n *\n * **Stub status — v6.0 alpha.** `state.*` (workflow-step reads, proposal\n * lookups, governance JWS) and `resolve.*` (property/collection-list +\n * format fetchers) are NOT yet wired. The state readers return empty\n * results; the resolvers throw. Touching them in a platform method will\n * crash the request — the framework hasn't connected them to an underlying\n * store / fetch layer yet.\n *\n * Adopters spiking against the preview surface MUST avoid `ctx.state.*`\n * and `ctx.resolve.*` until the wire-up commits land in rc.1. Use\n * `ctx.account`, `ctx.handoffToTask(...)`, and the structured-error /\n * status-change primitives only.\n *\n * @internal — framework-internal wiring; not adopter surface. The\n * exported helpers (`buildRequestContext`, `buildHandoffContext`) are\n * called from the dispatch seam in `from-platform.ts`. Adopters should\n * never construct a `RequestContext` themselves; the framework supplies\n * one to every specialism method call.\n */\n\nimport type { HandlerContext } from '../../create-adcp-server';\nimport type { Account } from '../account';\nimport type { RequestContext, CtxMetadataAccessor } from '../context';\nimport type { TaskRegistry } from './task-registry';\nimport {\n _createTaskHandoff,\n type TaskHandoffContext,\n type TaskHandoff,\n type TaskHandoffOptions,\n} from '../async-outcome';\nimport type { CtxMetadataStore, ResourceKind, CtxMetadataRef } from '../../ctx-metadata';\n\n/**\n * Build an account-scoped CtxMetadataAccessor for a single request.\n *\n * Account scope comes from `ctx.account.id` — accessor methods don't take\n * an account param. When `account.id` is null/undefined (no-account tools),\n * the accessor methods reject — no-account tools cannot use ctx_metadata\n * (cross-tenant collision risk via missing scope).\n */\nfunction buildCtxMetadataAccessor(store: CtxMetadataStore, accountId: string): CtxMetadataAccessor {\n return {\n get(kind: ResourceKind, id: string) {\n return store.get(accountId, kind, id);\n },\n bulkGet(refs: readonly CtxMetadataRef[]) {\n return store.bulkGet(accountId, refs);\n },\n set(kind: ResourceKind, id: string, value: unknown, ttlSeconds?: number) {\n return store.set(accountId, kind, id, value, ttlSeconds);\n },\n delete(kind: ResourceKind, id: string) {\n return store.delete(accountId, kind, id);\n },\n account(id: string) {\n return store.get(accountId, 'account', id);\n },\n product(id: string) {\n return store.get(accountId, 'product', id);\n },\n mediaBuy(id: string) {\n return store.get(accountId, 'media_buy', id);\n },\n package(id: string) {\n return store.get(accountId, 'package', id);\n },\n creative(id: string) {\n return store.get(accountId, 'creative', id);\n },\n audience(id: string) {\n return store.get(accountId, 'audience', id);\n },\n signal(id: string) {\n return store.get(accountId, 'signal', id);\n },\n };\n}\n\nexport function buildRequestContext<TCtxMeta = Record<string, unknown>>(\n handlerCtx: HandlerContext<Account<TCtxMeta>>,\n ctxMetadataStore?: CtxMetadataStore,\n input?: Readonly<Record<string, unknown>>\n): RequestContext<Account<TCtxMeta>> {\n // `account` may legitimately be undefined for tools whose wire request\n // doesn't carry an `account` field AND whose `resolveAccountFromAuth`\n // returned null (`'explicit'`-mode adopters who don't model the\n // no-account tools, or buyers calling without auth). Adopter handlers\n // for those tools are responsible for either deriving the account\n // themselves (e.g., via `media_buy_id` ownership) or throwing\n // `AdcpError('ACCOUNT_NOT_FOUND')` if account is required.\n //\n // The `RequestContext.account` type is non-optional for ergonomic typing\n // — adopters writing handlers for the 90% case (tools with `account` on\n // the wire) shouldn't have to optional-chain everywhere. Adopters of\n // no-account tools either:\n // 1. Declare `resolution: 'derived'` and return a singleton from\n // `accounts.resolve(undefined)` — `ctx.account` is always set\n // 2. Implement only `'explicit'` and never claim no-account\n // specialisms — the tool is unreachable\n // 3. Read `ctx.account` defensively (`as Account | undefined` cast)\n // and look up by request body when missing\n const account = handlerCtx.account as Account<TCtxMeta>;\n\n const stubResolver = (name: string) => async (): Promise<never> => {\n throw new Error(\n `ctx.resolve.${name}: not yet wired in v6.0 alpha — landing in rc.1. ` +\n `Avoid touching ctx.resolve.* in adopter code until the framework ` +\n `connects this resolver to an underlying fetcher.`\n );\n };\n\n // Bind ctx-metadata accessor when store wired AND account scope present.\n // No-account tools (provide_performance_feedback, list_creative_formats)\n // get `ctx.ctxMetadata = undefined` even when the store is wired — cannot\n // use ctx_metadata without an account boundary (cross-tenant risk).\n const ctxMetadata =\n ctxMetadataStore != null && account != null && (account.id ?? '') !== ''\n ? buildCtxMetadataAccessor(ctxMetadataStore, account.id)\n : undefined;\n\n return {\n account,\n ...(handlerCtx.agent != null && { agent: handlerCtx.agent }),\n ...(handlerCtx.callerMutationScope != null && {\n callerMutationScope: Object.freeze({ ...handlerCtx.callerMutationScope }),\n }),\n ...(handlerCtx.proposalRefinementScope != null && {\n proposalRefinementScope: Object.freeze({ ...handlerCtx.proposalRefinementScope }),\n }),\n ...(input != null && { input }),\n state: {\n findByObject: () => [],\n findProposalById: () => null,\n governanceContext: () => null,\n workflowSteps: () => [],\n },\n resolve: {\n propertyList: stubResolver('propertyList'),\n collectionList: stubResolver('collectionList'),\n creativeFormat: stubResolver('creativeFormat'),\n },\n ctxMetadata,\n handoffToTask<TResult>(\n fn: (taskCtx: TaskHandoffContext) => Promise<TResult>,\n options?: TaskHandoffOptions\n ): TaskHandoff<TResult> {\n if (options?.task_id !== undefined) {\n if (typeof options.task_id !== 'string' || options.task_id.length === 0) {\n throw new Error('handoffToTask options.task_id must be a non-empty string');\n }\n if (options.task_id.length > 128) {\n throw new Error('handoffToTask options.task_id must be ≤ 128 characters');\n }\n }\n return _createTaskHandoff(fn, options);\n },\n };\n}\n\n/**\n * Construct a `TaskHandoffContext` from a registry + framework-issued\n * task id. The framework calls this AFTER detecting a `TaskHandoff`\n * marker on a method's return — the handoff function gets a context\n * carrying the framework-allocated `taskId` plus `update`/`heartbeat`\n * affordances.\n *\n * `update(progress)` writes the progress payload to the task record and\n * transitions status `submitted` → `working`. Buyers polling `tasks_get`\n * see the `progress` object and the `'working'` status — this is the\n * buyer-facing UX signal that distinguishes \"stuck/no news\" from\n * \"step 2/3, awaiting trafficker.\" Errors from the registry write are\n * swallowed so a transient DB hiccup doesn't abort the adopter's handoff\n * function.\n *\n * `heartbeat()` remains a no-op stub (v6.1); it is a liveness / TTL-reset\n * signal for operator infrastructure, not buyer-facing.\n */\nexport function buildHandoffContext(taskRegistry: TaskRegistry, taskId: string): TaskHandoffContext {\n return {\n id: taskId,\n update: async progress => {\n try {\n await taskRegistry.updateProgress(taskId, progress);\n } catch {\n // Swallow — a transient registry write failure must not abort the\n // adopter's background handoff function. The buyer-facing impact is\n // a missed progress event, not a failed task.\n }\n },\n heartbeat: async () => {\n await Promise.resolve();\n },\n };\n}\n"],"mappings":"AAiCA;AAAA,EACE;AAAA,OAIK;AAWP,SAAS,yBAAyB,OAAyB,WAAwC;AACjG,SAAO;AAAA,IACL,IAAI,MAAoB,IAAY;AAClC,aAAO,MAAM,IAAI,WAAW,MAAM,EAAE;AAAA,IACtC;AAAA,IACA,QAAQ,MAAiC;AACvC,aAAO,MAAM,QAAQ,WAAW,IAAI;AAAA,IACtC;AAAA,IACA,IAAI,MAAoB,IAAY,OAAgB,YAAqB;AACvE,aAAO,MAAM,IAAI,WAAW,MAAM,IAAI,OAAO,UAAU;AAAA,IACzD;AAAA,IACA,OAAO,MAAoB,IAAY;AACrC,aAAO,MAAM,OAAO,WAAW,MAAM,EAAE;AAAA,IACzC;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,aAAa,EAAE;AAAA,IAC7C;AAAA,IACA,QAAQ,IAAY;AAClB,aAAO,MAAM,IAAI,WAAW,WAAW,EAAE;AAAA,IAC3C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,YAAY,EAAE;AAAA,IAC5C;AAAA,IACA,SAAS,IAAY;AACnB,aAAO,MAAM,IAAI,WAAW,YAAY,EAAE;AAAA,IAC5C;AAAA,IACA,OAAO,IAAY;AACjB,aAAO,MAAM,IAAI,WAAW,UAAU,EAAE;AAAA,IAC1C;AAAA,EACF;AACF;AAEO,SAAS,oBACd,YACA,kBACA,OACmC;AAmBnC,QAAM,UAAU,WAAW;AAE3B,QAAM,eAAe,CAAC,SAAiB,YAA4B;AACjE,UAAM,IAAI;AAAA,MACR,eAAe,IAAI;AAAA,IAGrB;AAAA,EACF;AAMA,QAAM,cACJ,oBAAoB,QAAQ,WAAW,SAAS,QAAQ,MAAM,QAAQ,KAClE,yBAAyB,kBAAkB,QAAQ,EAAE,IACrD;AAEN,SAAO;AAAA,IACL;AAAA,IACA,GAAI,WAAW,SAAS,QAAQ,EAAE,OAAO,WAAW,MAAM;AAAA,IAC1D,GAAI,WAAW,uBAAuB,QAAQ;AAAA,MAC5C,qBAAqB,OAAO,OAAO,EAAE,GAAG,WAAW,oBAAoB,CAAC;AAAA,IAC1E;AAAA,IACA,GAAI,WAAW,2BAA2B,QAAQ;AAAA,MAChD,yBAAyB,OAAO,OAAO,EAAE,GAAG,WAAW,wBAAwB,CAAC;AAAA,IAClF;AAAA,IACA,GAAI,SAAS,QAAQ,EAAE,MAAM;AAAA,IAC7B,OAAO;AAAA,MACL,cAAc,MAAM,CAAC;AAAA,MACrB,kBAAkB,MAAM;AAAA,MACxB,mBAAmB,MAAM;AAAA,MACzB,eAAe,MAAM,CAAC;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,MACP,cAAc,aAAa,cAAc;AAAA,MACzC,gBAAgB,aAAa,gBAAgB;AAAA,MAC7C,gBAAgB,aAAa,gBAAgB;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,cACE,IACA,SACsB;AACtB,UAAI,SAAS,YAAY,QAAW;AAClC,YAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,WAAW,GAAG;AACvE,gBAAM,IAAI,MAAM,0DAA0D;AAAA,QAC5E;AACA,YAAI,QAAQ,QAAQ,SAAS,KAAK;AAChC,gBAAM,IAAI,MAAM,6DAAwD;AAAA,QAC1E;AAAA,MACF;AACA,aAAO,mBAAmB,IAAI,OAAO;AAAA,IACvC;AAAA,EACF;AACF;AAoBO,SAAS,oBAAoB,cAA4B,QAAoC;AAClG,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ,OAAM,aAAY;AACxB,UAAI;AACF,cAAM,aAAa,eAAe,QAAQ,QAAQ;AAAA,MACpD,QAAQ;AAAA,MAIR;AAAA,IACF;AAAA,IACA,WAAW,YAAY;AACrB,YAAM,QAAQ,QAAQ;AAAA,IACxB;AAAA,EACF;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"validate-platform.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/runtime/validate-platform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AA8DvD,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,EAAE,MAAM;CAG5B;AAcD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAmCpE"}
1
+ {"version":3,"file":"validate-platform.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/runtime/validate-platform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAgFvD,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;gBACnC,OAAO,EAAE,MAAM;CAG5B;AAcD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAsDpE"}
@@ -25,18 +25,35 @@ module.exports = __toCommonJS(validate_platform_exports);
25
25
  function isSalesSpecialism(s) {
26
26
  return s.startsWith("sales-");
27
27
  }
28
+ const COMPACT_CORE_METHODS = [
29
+ "listProducts",
30
+ "buyProducts",
31
+ "controlMediaBuy",
32
+ "getMediaBuys",
33
+ "getMediaBuyDelivery"
34
+ ];
35
+ const COMPACT_PROPOSAL_METHODS = [
36
+ "proposalRefinement",
37
+ "listProducts",
38
+ "requestProposals",
39
+ "refineProposals",
40
+ "declineProposals",
41
+ "acceptProposal",
42
+ "getMediaBuys",
43
+ "getMediaBuyDelivery"
44
+ ];
28
45
  const SPECIALISM_REQUIREMENTS = {
29
46
  // All sales-* specialisms share the SalesPlatform interface. Adopters
30
47
  // implement `sales` once; the specialism enum picks which buyer-side
31
48
  // storyboard the agent is validated against. Wired here per the AdCP 3.0
32
49
  // GA enum; preview specialisms (sales-streaming-tv, sales-exchange,
33
50
  // sales-retail-media) get added when they land in `AdCPSpecialism`.
34
- "sales-non-guaranteed": ["sales"],
35
- "sales-guaranteed": ["sales"],
36
- "sales-broadcast-tv": ["sales"],
51
+ "sales-non-guaranteed": [],
52
+ "sales-guaranteed": [],
53
+ "sales-broadcast-tv": [],
37
54
  "sales-social": ["sales"],
38
55
  "sales-catalog-driven": ["sales"],
39
- "sales-proposal-mode": ["sales"],
56
+ "sales-proposal-mode": [],
40
57
  // Creative specialisms share the CreativeXxxPlatform field name; adopters
41
58
  // pick the right archetype (template / generative / ad-server) at
42
59
  // construction time.
@@ -78,6 +95,20 @@ class PlatformConfigError extends Error {
78
95
  function validatePlatform(platform) {
79
96
  const claimed = platform.capabilities?.specialisms ?? [];
80
97
  const errors = [];
98
+ for (const specialism of claimed) {
99
+ const acceptsCompactLifecycle = specialism === "sales-non-guaranteed" || specialism === "sales-guaranteed" || specialism === "sales-broadcast-tv" || specialism === "sales-proposal-mode";
100
+ if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle == null) {
101
+ errors.push(`${specialism} requires platform.sales or platform.mediaBuyLifecycle`);
102
+ }
103
+ if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle != null) {
104
+ const required = specialism === "sales-proposal-mode" ? COMPACT_PROPOSAL_METHODS : COMPACT_CORE_METHODS;
105
+ for (const method of required) {
106
+ if (platform.mediaBuyLifecycle[method] == null) {
107
+ errors.push(`${specialism} requires platform.mediaBuyLifecycle.${method}`);
108
+ }
109
+ }
110
+ }
111
+ }
81
112
  for (const specialism of claimed) {
82
113
  const required = SPECIALISM_REQUIREMENTS[specialism];
83
114
  if (!required) continue;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/validate-platform.ts"],"sourcesContent":["/**\n * Runtime validation that a `DecisioningPlatform` impl matches its\n * `capabilities.specialisms[]` declaration.\n *\n * Compile-time, `RequiredPlatformsFor<S>` enforces this in TypeScript adopter\n * code. Untyped JS callers, downstream packages with relaxed `tsconfig`, and\n * Python-port adopters running this through bindings need a runtime gate.\n *\n * Mirrors the v1.0 specialism × interface mapping in\n * `src/lib/server/decisioning/platform.ts`.\n *\n * @public\n */\n\nimport type { DecisioningPlatform } from '../platform';\nimport type { AdCPSpecialism } from '../../../types/tools.generated';\n\n// Sales specialisms require channels + pricingModels on capabilities because\n// buyers read those fields from get_adcp_capabilities to know what the seller\n// trades in. Signals/governance/creative-only platforms legitimately omit them\n// (hence the fields are optional on DecisioningCapabilities), but a media-buy\n// platform serving an empty or absent channels list is a mis-configured agent.\n// Derived from the `sales-` prefix on `AdCPSpecialism` rather than a hand-\n// maintained allowlist: when preview specialisms (`sales-streaming-tv`,\n// `sales-exchange`, `sales-retail-media`) graduate into the generated enum,\n// they automatically inherit the channels + pricingModels gate. A hand-list\n// would silently let mis-configured streaming/exchange platforms through.\nfunction isSalesSpecialism(s: AdCPSpecialism): boolean {\n return s.startsWith('sales-');\n}\n\nconst SPECIALISM_REQUIREMENTS: Partial<Record<AdCPSpecialism, ReadonlyArray<keyof DecisioningPlatform>>> = {\n // All sales-* specialisms share the SalesPlatform interface. Adopters\n // implement `sales` once; the specialism enum picks which buyer-side\n // storyboard the agent is validated against. Wired here per the AdCP 3.0\n // GA enum; preview specialisms (sales-streaming-tv, sales-exchange,\n // sales-retail-media) get added when they land in `AdCPSpecialism`.\n 'sales-non-guaranteed': ['sales'],\n 'sales-guaranteed': ['sales'],\n 'sales-broadcast-tv': ['sales'],\n 'sales-social': ['sales'],\n 'sales-catalog-driven': ['sales'],\n 'sales-proposal-mode': ['sales'],\n // Creative specialisms share the CreativeXxxPlatform field name; adopters\n // pick the right archetype (template / generative / ad-server) at\n // construction time.\n 'creative-template': ['creative'],\n 'creative-generative': ['creative'],\n 'creative-ad-server': ['creative'],\n 'creative-transformers': ['creative'],\n // Audience sync is a single specialism with a single platform interface.\n 'audience-sync': ['audiences'],\n // Signal specialisms — both share the SignalsPlatform interface.\n // Marketplace = third-party data brokers; owned = first-party providers.\n 'signal-marketplace': ['signals'],\n 'signal-owned': ['signals'],\n // Sponsored Intelligence — brand-side conversational sponsored\n // experiences.\n 'sponsored-intelligence': ['sponsoredIntelligence'],\n // Campaign governance — today's two specialisms share one platform\n // interface; consolidates to `campaign-governance` when adcp#3329 lands.\n 'governance-spend-authority': ['campaignGovernance'],\n 'governance-delivery-monitor': ['campaignGovernance'],\n // Property + collection list publishing.\n 'property-lists': ['propertyLists'],\n 'collection-lists': ['collectionLists'],\n // Content standards — brand-safety / policy compliance enforcement.\n 'content-standards': ['contentStandards'],\n // Brand-rights — identity discovery + licensing for branded inventory.\n // 4 wire tools wire through `brandRights` (`get_brand_identity`,\n // `get_rights`, `acquire_rights`, `update_rights`). `creative_approval`\n // is webhook-only (`reviewCreativeApproval` on the platform interface)\n // and not in `AdcpToolMap`.\n 'brand-rights': ['brandRights'],\n};\n\nexport class PlatformConfigError extends Error {\n readonly name = 'PlatformConfigError' as const;\n constructor(message: string) {\n super(message);\n }\n}\n\n// Note on HITL tools: the v6 unified shape collapses sync/HITL into a\n// single method per tool whose return type is `Success | TaskHandoff<Success>`.\n// Adopters branch in the body and call `ctx.handoffToTask(fn)` to defer\n// to a background task. The framework detects the handoff marker at the\n// dispatch seam — there's no exactly-one validation needed because the\n// shape is the same regardless of which path the adopter takes.\n//\n// This applies to `create_media_buy` and `sync_creatives` today (the 2\n// spec-listed tools whose per-tool response oneOf includes the Submitted\n// arm). When adcontextprotocol/adcp#3392 lands, the same shape extends\n// to `update_media_buy`, `build_creative`, `sync_catalogs`, `get_products`.\n\nexport function validatePlatform(platform: DecisioningPlatform): void {\n const claimed = platform.capabilities?.specialisms ?? [];\n const errors: string[] = [];\n\n // 1. Specialism declarations match required interfaces.\n for (const specialism of claimed) {\n const required = SPECIALISM_REQUIREMENTS[specialism];\n if (!required) continue; // forward-compat for unknown specialisms\n for (const field of required) {\n if (platform[field] == null) {\n errors.push(`capabilities.specialisms claims '${specialism}'; platform.${String(field)} is missing`);\n }\n }\n }\n\n // 2. Media-buy platforms require channels + pricingModels on capabilities.\n // These fields are optional on DecisioningCapabilities so non-media-buy\n // platforms (signals, governance, creative-only) can omit them, but a\n // sales platform that omits them will emit a broken get_adcp_capabilities\n // response that buyers cannot interpret.\n const claimedSales = claimed.filter(isSalesSpecialism);\n if (claimedSales.length > 0) {\n if (platform.capabilities?.channels == null) {\n errors.push(`capabilities.channels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`);\n }\n if (platform.capabilities?.pricingModels == null) {\n errors.push(\n `capabilities.pricingModels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`\n );\n }\n }\n\n if (errors.length > 0) {\n throw new PlatformConfigError(`DecisioningPlatform configuration is incomplete:\\n - ${errors.join('\\n - ')}`);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,SAAS,kBAAkB,GAA4B;AACrD,SAAO,EAAE,WAAW,QAAQ;AAC9B;AAEA,MAAM,0BAAqG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzG,wBAAwB,CAAC,OAAO;AAAA,EAChC,oBAAoB,CAAC,OAAO;AAAA,EAC5B,sBAAsB,CAAC,OAAO;AAAA,EAC9B,gBAAgB,CAAC,OAAO;AAAA,EACxB,wBAAwB,CAAC,OAAO;AAAA,EAChC,uBAAuB,CAAC,OAAO;AAAA;AAAA;AAAA;AAAA,EAI/B,qBAAqB,CAAC,UAAU;AAAA,EAChC,uBAAuB,CAAC,UAAU;AAAA,EAClC,sBAAsB,CAAC,UAAU;AAAA,EACjC,yBAAyB,CAAC,UAAU;AAAA;AAAA,EAEpC,iBAAiB,CAAC,WAAW;AAAA;AAAA;AAAA,EAG7B,sBAAsB,CAAC,SAAS;AAAA,EAChC,gBAAgB,CAAC,SAAS;AAAA;AAAA;AAAA,EAG1B,0BAA0B,CAAC,uBAAuB;AAAA;AAAA;AAAA,EAGlD,8BAA8B,CAAC,oBAAoB;AAAA,EACnD,+BAA+B,CAAC,oBAAoB;AAAA;AAAA,EAEpD,kBAAkB,CAAC,eAAe;AAAA,EAClC,oBAAoB,CAAC,iBAAiB;AAAA;AAAA,EAEtC,qBAAqB,CAAC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxC,gBAAgB,CAAC,aAAa;AAChC;AAEO,MAAM,4BAA4B,MAAM;AAAA,EACpC,OAAO;AAAA,EAChB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AAAA,EACf;AACF;AAcO,SAAS,iBAAiB,UAAqC;AACpE,QAAM,UAAU,SAAS,cAAc,eAAe,CAAC;AACvD,QAAM,SAAmB,CAAC;AAG1B,aAAW,cAAc,SAAS;AAChC,UAAM,WAAW,wBAAwB,UAAU;AACnD,QAAI,CAAC,SAAU;AACf,eAAW,SAAS,UAAU;AAC5B,UAAI,SAAS,KAAK,KAAK,MAAM;AAC3B,eAAO,KAAK,oCAAoC,UAAU,eAAe,OAAO,KAAK,CAAC,aAAa;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAOA,QAAM,eAAe,QAAQ,OAAO,iBAAiB;AACrD,MAAI,aAAa,SAAS,GAAG;AAC3B,QAAI,SAAS,cAAc,YAAY,MAAM;AAC3C,aAAO,KAAK,uEAAuE,aAAa,KAAK,IAAI,CAAC,GAAG;AAAA,IAC/G;AACA,QAAI,SAAS,cAAc,iBAAiB,MAAM;AAChD,aAAO;AAAA,QACL,4EAA4E,aAAa,KAAK,IAAI,CAAC;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,IAAI,oBAAoB;AAAA,MAAyD,OAAO,KAAK,QAAQ,CAAC,EAAE;AAAA,EAChH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/validate-platform.ts"],"sourcesContent":["/**\n * Runtime validation that a `DecisioningPlatform` impl matches its\n * `capabilities.specialisms[]` declaration.\n *\n * Compile-time, `RequiredPlatformsFor<S>` enforces this in TypeScript adopter\n * code. Untyped JS callers, downstream packages with relaxed `tsconfig`, and\n * Python-port adopters running this through bindings need a runtime gate.\n *\n * Mirrors the v1.0 specialism × interface mapping in\n * `src/lib/server/decisioning/platform.ts`.\n *\n * @public\n */\n\nimport type { DecisioningPlatform } from '../platform';\nimport type { AdCPSpecialism } from '../../../types/tools.generated';\n\n// Sales specialisms require channels + pricingModels on capabilities because\n// buyers read those fields from get_adcp_capabilities to know what the seller\n// trades in. Signals/governance/creative-only platforms legitimately omit them\n// (hence the fields are optional on DecisioningCapabilities), but a media-buy\n// platform serving an empty or absent channels list is a mis-configured agent.\n// Derived from the `sales-` prefix on `AdCPSpecialism` rather than a hand-\n// maintained allowlist: when preview specialisms (`sales-streaming-tv`,\n// `sales-exchange`, `sales-retail-media`) graduate into the generated enum,\n// they automatically inherit the channels + pricingModels gate. A hand-list\n// would silently let mis-configured streaming/exchange platforms through.\nfunction isSalesSpecialism(s: AdCPSpecialism): boolean {\n return s.startsWith('sales-');\n}\n\nconst COMPACT_CORE_METHODS = [\n 'listProducts',\n 'buyProducts',\n 'controlMediaBuy',\n 'getMediaBuys',\n 'getMediaBuyDelivery',\n] as const;\nconst COMPACT_PROPOSAL_METHODS = [\n 'proposalRefinement',\n 'listProducts',\n 'requestProposals',\n 'refineProposals',\n 'declineProposals',\n 'acceptProposal',\n 'getMediaBuys',\n 'getMediaBuyDelivery',\n] as const;\n\nconst SPECIALISM_REQUIREMENTS: Partial<Record<AdCPSpecialism, ReadonlyArray<keyof DecisioningPlatform>>> = {\n // All sales-* specialisms share the SalesPlatform interface. Adopters\n // implement `sales` once; the specialism enum picks which buyer-side\n // storyboard the agent is validated against. Wired here per the AdCP 3.0\n // GA enum; preview specialisms (sales-streaming-tv, sales-exchange,\n // sales-retail-media) get added when they land in `AdCPSpecialism`.\n 'sales-non-guaranteed': [],\n 'sales-guaranteed': [],\n 'sales-broadcast-tv': [],\n 'sales-social': ['sales'],\n 'sales-catalog-driven': ['sales'],\n 'sales-proposal-mode': [],\n // Creative specialisms share the CreativeXxxPlatform field name; adopters\n // pick the right archetype (template / generative / ad-server) at\n // construction time.\n 'creative-template': ['creative'],\n 'creative-generative': ['creative'],\n 'creative-ad-server': ['creative'],\n 'creative-transformers': ['creative'],\n // Audience sync is a single specialism with a single platform interface.\n 'audience-sync': ['audiences'],\n // Signal specialisms — both share the SignalsPlatform interface.\n // Marketplace = third-party data brokers; owned = first-party providers.\n 'signal-marketplace': ['signals'],\n 'signal-owned': ['signals'],\n // Sponsored Intelligence — brand-side conversational sponsored\n // experiences.\n 'sponsored-intelligence': ['sponsoredIntelligence'],\n // Campaign governance — today's two specialisms share one platform\n // interface; consolidates to `campaign-governance` when adcp#3329 lands.\n 'governance-spend-authority': ['campaignGovernance'],\n 'governance-delivery-monitor': ['campaignGovernance'],\n // Property + collection list publishing.\n 'property-lists': ['propertyLists'],\n 'collection-lists': ['collectionLists'],\n // Content standards — brand-safety / policy compliance enforcement.\n 'content-standards': ['contentStandards'],\n // Brand-rights — identity discovery + licensing for branded inventory.\n // 4 wire tools wire through `brandRights` (`get_brand_identity`,\n // `get_rights`, `acquire_rights`, `update_rights`). `creative_approval`\n // is webhook-only (`reviewCreativeApproval` on the platform interface)\n // and not in `AdcpToolMap`.\n 'brand-rights': ['brandRights'],\n};\n\nexport class PlatformConfigError extends Error {\n readonly name = 'PlatformConfigError' as const;\n constructor(message: string) {\n super(message);\n }\n}\n\n// Note on HITL tools: the v6 unified shape collapses sync/HITL into a\n// single method per tool whose return type is `Success | TaskHandoff<Success>`.\n// Adopters branch in the body and call `ctx.handoffToTask(fn)` to defer\n// to a background task. The framework detects the handoff marker at the\n// dispatch seam — there's no exactly-one validation needed because the\n// shape is the same regardless of which path the adopter takes.\n//\n// This applies to `create_media_buy` and `sync_creatives` today (the 2\n// spec-listed tools whose per-tool response oneOf includes the Submitted\n// arm). When adcontextprotocol/adcp#3392 lands, the same shape extends\n// to `update_media_buy`, `build_creative`, `sync_catalogs`, `get_products`.\n\nexport function validatePlatform(platform: DecisioningPlatform): void {\n const claimed = platform.capabilities?.specialisms ?? [];\n const errors: string[] = [];\n\n for (const specialism of claimed) {\n const acceptsCompactLifecycle =\n specialism === 'sales-non-guaranteed' ||\n specialism === 'sales-guaranteed' ||\n specialism === 'sales-broadcast-tv' ||\n specialism === 'sales-proposal-mode';\n if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle == null) {\n errors.push(`${specialism} requires platform.sales or platform.mediaBuyLifecycle`);\n }\n if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle != null) {\n const required = specialism === 'sales-proposal-mode' ? COMPACT_PROPOSAL_METHODS : COMPACT_CORE_METHODS;\n for (const method of required) {\n if (platform.mediaBuyLifecycle[method] == null) {\n errors.push(`${specialism} requires platform.mediaBuyLifecycle.${method}`);\n }\n }\n }\n }\n\n // 1. Specialism declarations match required interfaces.\n for (const specialism of claimed) {\n const required = SPECIALISM_REQUIREMENTS[specialism];\n if (!required) continue; // forward-compat for unknown specialisms\n for (const field of required) {\n if (platform[field] == null) {\n errors.push(`capabilities.specialisms claims '${specialism}'; platform.${String(field)} is missing`);\n }\n }\n }\n\n // 2. Media-buy platforms require channels + pricingModels on capabilities.\n // These fields are optional on DecisioningCapabilities so non-media-buy\n // platforms (signals, governance, creative-only) can omit them, but a\n // sales platform that omits them will emit a broken get_adcp_capabilities\n // response that buyers cannot interpret.\n const claimedSales = claimed.filter(isSalesSpecialism);\n if (claimedSales.length > 0) {\n if (platform.capabilities?.channels == null) {\n errors.push(`capabilities.channels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`);\n }\n if (platform.capabilities?.pricingModels == null) {\n errors.push(\n `capabilities.pricingModels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`\n );\n }\n }\n\n if (errors.length > 0) {\n throw new PlatformConfigError(`DecisioningPlatform configuration is incomplete:\\n - ${errors.join('\\n - ')}`);\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,18 +1,35 @@
1
1
  function isSalesSpecialism(s) {
2
2
  return s.startsWith("sales-");
3
3
  }
4
+ const COMPACT_CORE_METHODS = [
5
+ "listProducts",
6
+ "buyProducts",
7
+ "controlMediaBuy",
8
+ "getMediaBuys",
9
+ "getMediaBuyDelivery"
10
+ ];
11
+ const COMPACT_PROPOSAL_METHODS = [
12
+ "proposalRefinement",
13
+ "listProducts",
14
+ "requestProposals",
15
+ "refineProposals",
16
+ "declineProposals",
17
+ "acceptProposal",
18
+ "getMediaBuys",
19
+ "getMediaBuyDelivery"
20
+ ];
4
21
  const SPECIALISM_REQUIREMENTS = {
5
22
  // All sales-* specialisms share the SalesPlatform interface. Adopters
6
23
  // implement `sales` once; the specialism enum picks which buyer-side
7
24
  // storyboard the agent is validated against. Wired here per the AdCP 3.0
8
25
  // GA enum; preview specialisms (sales-streaming-tv, sales-exchange,
9
26
  // sales-retail-media) get added when they land in `AdCPSpecialism`.
10
- "sales-non-guaranteed": ["sales"],
11
- "sales-guaranteed": ["sales"],
12
- "sales-broadcast-tv": ["sales"],
27
+ "sales-non-guaranteed": [],
28
+ "sales-guaranteed": [],
29
+ "sales-broadcast-tv": [],
13
30
  "sales-social": ["sales"],
14
31
  "sales-catalog-driven": ["sales"],
15
- "sales-proposal-mode": ["sales"],
32
+ "sales-proposal-mode": [],
16
33
  // Creative specialisms share the CreativeXxxPlatform field name; adopters
17
34
  // pick the right archetype (template / generative / ad-server) at
18
35
  // construction time.
@@ -54,6 +71,20 @@ class PlatformConfigError extends Error {
54
71
  function validatePlatform(platform) {
55
72
  const claimed = platform.capabilities?.specialisms ?? [];
56
73
  const errors = [];
74
+ for (const specialism of claimed) {
75
+ const acceptsCompactLifecycle = specialism === "sales-non-guaranteed" || specialism === "sales-guaranteed" || specialism === "sales-broadcast-tv" || specialism === "sales-proposal-mode";
76
+ if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle == null) {
77
+ errors.push(`${specialism} requires platform.sales or platform.mediaBuyLifecycle`);
78
+ }
79
+ if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle != null) {
80
+ const required = specialism === "sales-proposal-mode" ? COMPACT_PROPOSAL_METHODS : COMPACT_CORE_METHODS;
81
+ for (const method of required) {
82
+ if (platform.mediaBuyLifecycle[method] == null) {
83
+ errors.push(`${specialism} requires platform.mediaBuyLifecycle.${method}`);
84
+ }
85
+ }
86
+ }
87
+ }
57
88
  for (const specialism of claimed) {
58
89
  const required = SPECIALISM_REQUIREMENTS[specialism];
59
90
  if (!required) continue;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/validate-platform.ts"],"sourcesContent":["/**\n * Runtime validation that a `DecisioningPlatform` impl matches its\n * `capabilities.specialisms[]` declaration.\n *\n * Compile-time, `RequiredPlatformsFor<S>` enforces this in TypeScript adopter\n * code. Untyped JS callers, downstream packages with relaxed `tsconfig`, and\n * Python-port adopters running this through bindings need a runtime gate.\n *\n * Mirrors the v1.0 specialism × interface mapping in\n * `src/lib/server/decisioning/platform.ts`.\n *\n * @public\n */\n\nimport type { DecisioningPlatform } from '../platform';\nimport type { AdCPSpecialism } from '../../../types/tools.generated';\n\n// Sales specialisms require channels + pricingModels on capabilities because\n// buyers read those fields from get_adcp_capabilities to know what the seller\n// trades in. Signals/governance/creative-only platforms legitimately omit them\n// (hence the fields are optional on DecisioningCapabilities), but a media-buy\n// platform serving an empty or absent channels list is a mis-configured agent.\n// Derived from the `sales-` prefix on `AdCPSpecialism` rather than a hand-\n// maintained allowlist: when preview specialisms (`sales-streaming-tv`,\n// `sales-exchange`, `sales-retail-media`) graduate into the generated enum,\n// they automatically inherit the channels + pricingModels gate. A hand-list\n// would silently let mis-configured streaming/exchange platforms through.\nfunction isSalesSpecialism(s: AdCPSpecialism): boolean {\n return s.startsWith('sales-');\n}\n\nconst SPECIALISM_REQUIREMENTS: Partial<Record<AdCPSpecialism, ReadonlyArray<keyof DecisioningPlatform>>> = {\n // All sales-* specialisms share the SalesPlatform interface. Adopters\n // implement `sales` once; the specialism enum picks which buyer-side\n // storyboard the agent is validated against. Wired here per the AdCP 3.0\n // GA enum; preview specialisms (sales-streaming-tv, sales-exchange,\n // sales-retail-media) get added when they land in `AdCPSpecialism`.\n 'sales-non-guaranteed': ['sales'],\n 'sales-guaranteed': ['sales'],\n 'sales-broadcast-tv': ['sales'],\n 'sales-social': ['sales'],\n 'sales-catalog-driven': ['sales'],\n 'sales-proposal-mode': ['sales'],\n // Creative specialisms share the CreativeXxxPlatform field name; adopters\n // pick the right archetype (template / generative / ad-server) at\n // construction time.\n 'creative-template': ['creative'],\n 'creative-generative': ['creative'],\n 'creative-ad-server': ['creative'],\n 'creative-transformers': ['creative'],\n // Audience sync is a single specialism with a single platform interface.\n 'audience-sync': ['audiences'],\n // Signal specialisms — both share the SignalsPlatform interface.\n // Marketplace = third-party data brokers; owned = first-party providers.\n 'signal-marketplace': ['signals'],\n 'signal-owned': ['signals'],\n // Sponsored Intelligence — brand-side conversational sponsored\n // experiences.\n 'sponsored-intelligence': ['sponsoredIntelligence'],\n // Campaign governance — today's two specialisms share one platform\n // interface; consolidates to `campaign-governance` when adcp#3329 lands.\n 'governance-spend-authority': ['campaignGovernance'],\n 'governance-delivery-monitor': ['campaignGovernance'],\n // Property + collection list publishing.\n 'property-lists': ['propertyLists'],\n 'collection-lists': ['collectionLists'],\n // Content standards — brand-safety / policy compliance enforcement.\n 'content-standards': ['contentStandards'],\n // Brand-rights — identity discovery + licensing for branded inventory.\n // 4 wire tools wire through `brandRights` (`get_brand_identity`,\n // `get_rights`, `acquire_rights`, `update_rights`). `creative_approval`\n // is webhook-only (`reviewCreativeApproval` on the platform interface)\n // and not in `AdcpToolMap`.\n 'brand-rights': ['brandRights'],\n};\n\nexport class PlatformConfigError extends Error {\n readonly name = 'PlatformConfigError' as const;\n constructor(message: string) {\n super(message);\n }\n}\n\n// Note on HITL tools: the v6 unified shape collapses sync/HITL into a\n// single method per tool whose return type is `Success | TaskHandoff<Success>`.\n// Adopters branch in the body and call `ctx.handoffToTask(fn)` to defer\n// to a background task. The framework detects the handoff marker at the\n// dispatch seam — there's no exactly-one validation needed because the\n// shape is the same regardless of which path the adopter takes.\n//\n// This applies to `create_media_buy` and `sync_creatives` today (the 2\n// spec-listed tools whose per-tool response oneOf includes the Submitted\n// arm). When adcontextprotocol/adcp#3392 lands, the same shape extends\n// to `update_media_buy`, `build_creative`, `sync_catalogs`, `get_products`.\n\nexport function validatePlatform(platform: DecisioningPlatform): void {\n const claimed = platform.capabilities?.specialisms ?? [];\n const errors: string[] = [];\n\n // 1. Specialism declarations match required interfaces.\n for (const specialism of claimed) {\n const required = SPECIALISM_REQUIREMENTS[specialism];\n if (!required) continue; // forward-compat for unknown specialisms\n for (const field of required) {\n if (platform[field] == null) {\n errors.push(`capabilities.specialisms claims '${specialism}'; platform.${String(field)} is missing`);\n }\n }\n }\n\n // 2. Media-buy platforms require channels + pricingModels on capabilities.\n // These fields are optional on DecisioningCapabilities so non-media-buy\n // platforms (signals, governance, creative-only) can omit them, but a\n // sales platform that omits them will emit a broken get_adcp_capabilities\n // response that buyers cannot interpret.\n const claimedSales = claimed.filter(isSalesSpecialism);\n if (claimedSales.length > 0) {\n if (platform.capabilities?.channels == null) {\n errors.push(`capabilities.channels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`);\n }\n if (platform.capabilities?.pricingModels == null) {\n errors.push(\n `capabilities.pricingModels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`\n );\n }\n }\n\n if (errors.length > 0) {\n throw new PlatformConfigError(`DecisioningPlatform configuration is incomplete:\\n - ${errors.join('\\n - ')}`);\n }\n}\n"],"mappings":"AA2BA,SAAS,kBAAkB,GAA4B;AACrD,SAAO,EAAE,WAAW,QAAQ;AAC9B;AAEA,MAAM,0BAAqG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzG,wBAAwB,CAAC,OAAO;AAAA,EAChC,oBAAoB,CAAC,OAAO;AAAA,EAC5B,sBAAsB,CAAC,OAAO;AAAA,EAC9B,gBAAgB,CAAC,OAAO;AAAA,EACxB,wBAAwB,CAAC,OAAO;AAAA,EAChC,uBAAuB,CAAC,OAAO;AAAA;AAAA;AAAA;AAAA,EAI/B,qBAAqB,CAAC,UAAU;AAAA,EAChC,uBAAuB,CAAC,UAAU;AAAA,EAClC,sBAAsB,CAAC,UAAU;AAAA,EACjC,yBAAyB,CAAC,UAAU;AAAA;AAAA,EAEpC,iBAAiB,CAAC,WAAW;AAAA;AAAA;AAAA,EAG7B,sBAAsB,CAAC,SAAS;AAAA,EAChC,gBAAgB,CAAC,SAAS;AAAA;AAAA;AAAA,EAG1B,0BAA0B,CAAC,uBAAuB;AAAA;AAAA;AAAA,EAGlD,8BAA8B,CAAC,oBAAoB;AAAA,EACnD,+BAA+B,CAAC,oBAAoB;AAAA;AAAA,EAEpD,kBAAkB,CAAC,eAAe;AAAA,EAClC,oBAAoB,CAAC,iBAAiB;AAAA;AAAA,EAEtC,qBAAqB,CAAC,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxC,gBAAgB,CAAC,aAAa;AAChC;AAEO,MAAM,4BAA4B,MAAM;AAAA,EACpC,OAAO;AAAA,EAChB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AAAA,EACf;AACF;AAcO,SAAS,iBAAiB,UAAqC;AACpE,QAAM,UAAU,SAAS,cAAc,eAAe,CAAC;AACvD,QAAM,SAAmB,CAAC;AAG1B,aAAW,cAAc,SAAS;AAChC,UAAM,WAAW,wBAAwB,UAAU;AACnD,QAAI,CAAC,SAAU;AACf,eAAW,SAAS,UAAU;AAC5B,UAAI,SAAS,KAAK,KAAK,MAAM;AAC3B,eAAO,KAAK,oCAAoC,UAAU,eAAe,OAAO,KAAK,CAAC,aAAa;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAOA,QAAM,eAAe,QAAQ,OAAO,iBAAiB;AACrD,MAAI,aAAa,SAAS,GAAG;AAC3B,QAAI,SAAS,cAAc,YAAY,MAAM;AAC3C,aAAO,KAAK,uEAAuE,aAAa,KAAK,IAAI,CAAC,GAAG;AAAA,IAC/G;AACA,QAAI,SAAS,cAAc,iBAAiB,MAAM;AAChD,aAAO;AAAA,QACL,4EAA4E,aAAa,KAAK,IAAI,CAAC;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,IAAI,oBAAoB;AAAA,MAAyD,OAAO,KAAK,QAAQ,CAAC,EAAE;AAAA,EAChH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../../src/lib/server/decisioning/runtime/validate-platform.ts"],"sourcesContent":["/**\n * Runtime validation that a `DecisioningPlatform` impl matches its\n * `capabilities.specialisms[]` declaration.\n *\n * Compile-time, `RequiredPlatformsFor<S>` enforces this in TypeScript adopter\n * code. Untyped JS callers, downstream packages with relaxed `tsconfig`, and\n * Python-port adopters running this through bindings need a runtime gate.\n *\n * Mirrors the v1.0 specialism × interface mapping in\n * `src/lib/server/decisioning/platform.ts`.\n *\n * @public\n */\n\nimport type { DecisioningPlatform } from '../platform';\nimport type { AdCPSpecialism } from '../../../types/tools.generated';\n\n// Sales specialisms require channels + pricingModels on capabilities because\n// buyers read those fields from get_adcp_capabilities to know what the seller\n// trades in. Signals/governance/creative-only platforms legitimately omit them\n// (hence the fields are optional on DecisioningCapabilities), but a media-buy\n// platform serving an empty or absent channels list is a mis-configured agent.\n// Derived from the `sales-` prefix on `AdCPSpecialism` rather than a hand-\n// maintained allowlist: when preview specialisms (`sales-streaming-tv`,\n// `sales-exchange`, `sales-retail-media`) graduate into the generated enum,\n// they automatically inherit the channels + pricingModels gate. A hand-list\n// would silently let mis-configured streaming/exchange platforms through.\nfunction isSalesSpecialism(s: AdCPSpecialism): boolean {\n return s.startsWith('sales-');\n}\n\nconst COMPACT_CORE_METHODS = [\n 'listProducts',\n 'buyProducts',\n 'controlMediaBuy',\n 'getMediaBuys',\n 'getMediaBuyDelivery',\n] as const;\nconst COMPACT_PROPOSAL_METHODS = [\n 'proposalRefinement',\n 'listProducts',\n 'requestProposals',\n 'refineProposals',\n 'declineProposals',\n 'acceptProposal',\n 'getMediaBuys',\n 'getMediaBuyDelivery',\n] as const;\n\nconst SPECIALISM_REQUIREMENTS: Partial<Record<AdCPSpecialism, ReadonlyArray<keyof DecisioningPlatform>>> = {\n // All sales-* specialisms share the SalesPlatform interface. Adopters\n // implement `sales` once; the specialism enum picks which buyer-side\n // storyboard the agent is validated against. Wired here per the AdCP 3.0\n // GA enum; preview specialisms (sales-streaming-tv, sales-exchange,\n // sales-retail-media) get added when they land in `AdCPSpecialism`.\n 'sales-non-guaranteed': [],\n 'sales-guaranteed': [],\n 'sales-broadcast-tv': [],\n 'sales-social': ['sales'],\n 'sales-catalog-driven': ['sales'],\n 'sales-proposal-mode': [],\n // Creative specialisms share the CreativeXxxPlatform field name; adopters\n // pick the right archetype (template / generative / ad-server) at\n // construction time.\n 'creative-template': ['creative'],\n 'creative-generative': ['creative'],\n 'creative-ad-server': ['creative'],\n 'creative-transformers': ['creative'],\n // Audience sync is a single specialism with a single platform interface.\n 'audience-sync': ['audiences'],\n // Signal specialisms — both share the SignalsPlatform interface.\n // Marketplace = third-party data brokers; owned = first-party providers.\n 'signal-marketplace': ['signals'],\n 'signal-owned': ['signals'],\n // Sponsored Intelligence — brand-side conversational sponsored\n // experiences.\n 'sponsored-intelligence': ['sponsoredIntelligence'],\n // Campaign governance — today's two specialisms share one platform\n // interface; consolidates to `campaign-governance` when adcp#3329 lands.\n 'governance-spend-authority': ['campaignGovernance'],\n 'governance-delivery-monitor': ['campaignGovernance'],\n // Property + collection list publishing.\n 'property-lists': ['propertyLists'],\n 'collection-lists': ['collectionLists'],\n // Content standards — brand-safety / policy compliance enforcement.\n 'content-standards': ['contentStandards'],\n // Brand-rights — identity discovery + licensing for branded inventory.\n // 4 wire tools wire through `brandRights` (`get_brand_identity`,\n // `get_rights`, `acquire_rights`, `update_rights`). `creative_approval`\n // is webhook-only (`reviewCreativeApproval` on the platform interface)\n // and not in `AdcpToolMap`.\n 'brand-rights': ['brandRights'],\n};\n\nexport class PlatformConfigError extends Error {\n readonly name = 'PlatformConfigError' as const;\n constructor(message: string) {\n super(message);\n }\n}\n\n// Note on HITL tools: the v6 unified shape collapses sync/HITL into a\n// single method per tool whose return type is `Success | TaskHandoff<Success>`.\n// Adopters branch in the body and call `ctx.handoffToTask(fn)` to defer\n// to a background task. The framework detects the handoff marker at the\n// dispatch seam — there's no exactly-one validation needed because the\n// shape is the same regardless of which path the adopter takes.\n//\n// This applies to `create_media_buy` and `sync_creatives` today (the 2\n// spec-listed tools whose per-tool response oneOf includes the Submitted\n// arm). When adcontextprotocol/adcp#3392 lands, the same shape extends\n// to `update_media_buy`, `build_creative`, `sync_catalogs`, `get_products`.\n\nexport function validatePlatform(platform: DecisioningPlatform): void {\n const claimed = platform.capabilities?.specialisms ?? [];\n const errors: string[] = [];\n\n for (const specialism of claimed) {\n const acceptsCompactLifecycle =\n specialism === 'sales-non-guaranteed' ||\n specialism === 'sales-guaranteed' ||\n specialism === 'sales-broadcast-tv' ||\n specialism === 'sales-proposal-mode';\n if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle == null) {\n errors.push(`${specialism} requires platform.sales or platform.mediaBuyLifecycle`);\n }\n if (acceptsCompactLifecycle && platform.sales == null && platform.mediaBuyLifecycle != null) {\n const required = specialism === 'sales-proposal-mode' ? COMPACT_PROPOSAL_METHODS : COMPACT_CORE_METHODS;\n for (const method of required) {\n if (platform.mediaBuyLifecycle[method] == null) {\n errors.push(`${specialism} requires platform.mediaBuyLifecycle.${method}`);\n }\n }\n }\n }\n\n // 1. Specialism declarations match required interfaces.\n for (const specialism of claimed) {\n const required = SPECIALISM_REQUIREMENTS[specialism];\n if (!required) continue; // forward-compat for unknown specialisms\n for (const field of required) {\n if (platform[field] == null) {\n errors.push(`capabilities.specialisms claims '${specialism}'; platform.${String(field)} is missing`);\n }\n }\n }\n\n // 2. Media-buy platforms require channels + pricingModels on capabilities.\n // These fields are optional on DecisioningCapabilities so non-media-buy\n // platforms (signals, governance, creative-only) can omit them, but a\n // sales platform that omits them will emit a broken get_adcp_capabilities\n // response that buyers cannot interpret.\n const claimedSales = claimed.filter(isSalesSpecialism);\n if (claimedSales.length > 0) {\n if (platform.capabilities?.channels == null) {\n errors.push(`capabilities.channels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`);\n }\n if (platform.capabilities?.pricingModels == null) {\n errors.push(\n `capabilities.pricingModels is required for media-buy platforms (claimed: ${claimedSales.join(', ')})`\n );\n }\n }\n\n if (errors.length > 0) {\n throw new PlatformConfigError(`DecisioningPlatform configuration is incomplete:\\n - ${errors.join('\\n - ')}`);\n }\n}\n"],"mappings":"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","names":[]}
@@ -64,6 +64,8 @@ import type { RequestContext } from '../context.mjs';
64
64
  import type { TaskHandoff } from '../async-outcome.mjs';
65
65
  import type { RequireCacheScopeWhenProducts, ServerPayload } from '../../../types/server-payload.mjs';
66
66
  import type { GetProductsResponse, CreateMediaBuyError, CreateMediaBuySuccess, UpdateMediaBuySuccess, GetMediaBuysRequest, GetMediaBuysResponse, GetMediaBuyDeliveryRequest, GetMediaBuyDeliveryResponse, ProvidePerformanceFeedbackRequest, ProvidePerformanceFeedbackSuccess, ListCreativeFormatsRequest, ListCreativeFormatsResponse, ListCreativesResponse, MediaBuyStatus, SyncCatalogsRequest, SyncCatalogsSuccess, LogEventRequest, LogEventSuccess, SyncEventSourcesRequest, SyncEventSourcesSuccess, SyncCreativesError, SyncCreativesSuccess } from '../../../types/tools.generated.mjs';
67
+ import type { ProposalRefinementCapabilities } from '../../../negotiation/types.mjs';
68
+ import type { AdcpToolMap } from '../../create-adcp-server.mjs';
67
69
  import type { CanonicalSyncCreativeAsset, CanonicalCreateMediaBuyRequest, CanonicalCreativeResponse, CanonicalGetProductsRequest, CanonicalListCreativesRequest, CanonicalListCreativesResponse, CanonicalProduct, CanonicalUpdateMediaBuyRequest } from '../../../v2/projection/creative-delivery.mjs';
68
70
  type SyncCreative = CanonicalSyncCreativeAsset;
69
71
  type Ctx<TCtxMeta> = RequestContext<Account<TCtxMeta>>;
@@ -100,6 +102,13 @@ export type SyncCreativesPayload = SyncCreativesSuccessPayload | SyncCreativesEr
100
102
  export type SyncCatalogsPayload = ServerPayload<SyncCatalogsSuccess>;
101
103
  export type LogEventPayload = ServerPayload<LogEventSuccess>;
102
104
  export type SyncEventSourcesPayload = ServerPayload<SyncEventSourcesSuccess>;
105
+ export type ListProductsPayload = AdcpToolMap['list_products']['result'];
106
+ export type RequestProposalsPayload = AdcpToolMap['request_proposals']['result'];
107
+ export type DeclineProposalsPayload = AdcpToolMap['decline_proposals']['result'];
108
+ export type BuyProductsPayload = AdcpToolMap['buy_products']['result'];
109
+ export type AcceptProposalPayload = AdcpToolMap['accept_proposal']['result'];
110
+ export type ControlMediaBuyPayload = AdcpToolMap['control_media_buy']['result'];
111
+ export type RefineProposalsPayload = AdcpToolMap['refine_proposals']['result'];
103
112
  /**
104
113
  * Wire success-row shape for `sync_creatives`. Returning the array of these
105
114
  * rows from `syncCreatives` is what adopters write — the framework wraps
@@ -110,6 +119,36 @@ export type GetProductsHandlerResult = GetProductsPayload | TaskHandoff<GetProdu
110
119
  export type CreateMediaBuyHandlerResult = CreateMediaBuyPayload | TaskHandoff<CreateMediaBuySuccessPayload>;
111
120
  export type UpdateMediaBuyHandlerResult = UpdateMediaBuyPayload | TaskHandoff<UpdateMediaBuyPayload>;
112
121
  export type SyncCreativesHandlerResult = SyncCreativesRow[] | TaskHandoff<SyncCreativesRow[]>;
122
+ type CompactLifecycleHandlerResult<T> = T | TaskHandoff<T>;
123
+ /**
124
+ * Primary AdCP 3.2 media-buy lifecycle surface.
125
+ *
126
+ * This lives beside {@link SalesPlatform} so SDK 14 adopters can implement
127
+ * the compact protocol without translating it back into deprecated
128
+ * `get_products` / `create_media_buy` / `update_media_buy` methods. Keep a
129
+ * `SalesPlatform` implementation as well when the same deployment must serve
130
+ * legacy 3.0/3.1 buyers; the server advertises only the compact profile to
131
+ * 3.2 MCP discovery while retaining those older call routes.
132
+ *
133
+ * `refineProposals` requires `proposalRefinement` so capability discovery can
134
+ * declare the supported structured refinement dimensions truthfully.
135
+ *
136
+ * @public
137
+ */
138
+ export interface MediaBuyLifecyclePlatform<TCtxMeta = Record<string, unknown>> {
139
+ proposalRefinement?: ProposalRefinementCapabilities;
140
+ listProducts?(req: AdcpToolMap['list_products']['params'], ctx: Ctx<TCtxMeta>): Promise<ListProductsPayload>;
141
+ requestProposals?(req: AdcpToolMap['request_proposals']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<RequestProposalsPayload>>;
142
+ refineProposals?(req: AdcpToolMap['refine_proposals']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<RefineProposalsPayload>>;
143
+ declineProposals?(req: AdcpToolMap['decline_proposals']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<DeclineProposalsPayload>>;
144
+ buyProducts?(req: AdcpToolMap['buy_products']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<BuyProductsPayload>>;
145
+ acceptProposal?(req: AdcpToolMap['accept_proposal']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<AcceptProposalPayload>>;
146
+ controlMediaBuy?(req: AdcpToolMap['control_media_buy']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<ControlMediaBuyPayload>>;
147
+ getMediaBuys?(req: GetMediaBuysRequest, ctx: Ctx<TCtxMeta>): Promise<GetMediaBuysPayload>;
148
+ getMediaBuyDelivery?(filter: GetMediaBuyDeliveryRequest, ctx: Ctx<TCtxMeta>): Promise<GetMediaBuyDeliveryPayload>;
149
+ }
150
+ export type MediaBuyLifecycleCorePlatform<TCtxMeta = Record<string, unknown>> = Required<Pick<MediaBuyLifecyclePlatform<TCtxMeta>, 'listProducts' | 'buyProducts' | 'controlMediaBuy' | 'getMediaBuys' | 'getMediaBuyDelivery'>>;
151
+ export type MediaBuyLifecycleProposalPlatform<TCtxMeta = Record<string, unknown>> = Required<Pick<MediaBuyLifecyclePlatform<TCtxMeta>, 'proposalRefinement' | 'listProducts' | 'requestProposals' | 'refineProposals' | 'declineProposals' | 'acceptProposal' | 'getMediaBuys' | 'getMediaBuyDelivery'>>;
113
152
  export interface SalesPlatform<TCtxMeta = Record<string, unknown>> {
114
153
  /** Catalog discovery: return products directly or hand off curated discovery to a background task. */
115
154
  getProducts?(req: CanonicalGetProductsRequest, ctx: Ctx<TCtxMeta>): Promise<GetProductsHandlerResult>;
@@ -64,6 +64,8 @@ import type { RequestContext } from '../context';
64
64
  import type { TaskHandoff } from '../async-outcome';
65
65
  import type { RequireCacheScopeWhenProducts, ServerPayload } from '../../../types/server-payload';
66
66
  import type { GetProductsResponse, CreateMediaBuyError, CreateMediaBuySuccess, UpdateMediaBuySuccess, GetMediaBuysRequest, GetMediaBuysResponse, GetMediaBuyDeliveryRequest, GetMediaBuyDeliveryResponse, ProvidePerformanceFeedbackRequest, ProvidePerformanceFeedbackSuccess, ListCreativeFormatsRequest, ListCreativeFormatsResponse, ListCreativesResponse, MediaBuyStatus, SyncCatalogsRequest, SyncCatalogsSuccess, LogEventRequest, LogEventSuccess, SyncEventSourcesRequest, SyncEventSourcesSuccess, SyncCreativesError, SyncCreativesSuccess } from '../../../types/tools.generated';
67
+ import type { ProposalRefinementCapabilities } from '../../../negotiation/types';
68
+ import type { AdcpToolMap } from '../../create-adcp-server';
67
69
  import type { CanonicalSyncCreativeAsset, CanonicalCreateMediaBuyRequest, CanonicalCreativeResponse, CanonicalGetProductsRequest, CanonicalListCreativesRequest, CanonicalListCreativesResponse, CanonicalProduct, CanonicalUpdateMediaBuyRequest } from '../../../v2/projection/creative-delivery';
68
70
  type SyncCreative = CanonicalSyncCreativeAsset;
69
71
  type Ctx<TCtxMeta> = RequestContext<Account<TCtxMeta>>;
@@ -100,6 +102,13 @@ export type SyncCreativesPayload = SyncCreativesSuccessPayload | SyncCreativesEr
100
102
  export type SyncCatalogsPayload = ServerPayload<SyncCatalogsSuccess>;
101
103
  export type LogEventPayload = ServerPayload<LogEventSuccess>;
102
104
  export type SyncEventSourcesPayload = ServerPayload<SyncEventSourcesSuccess>;
105
+ export type ListProductsPayload = AdcpToolMap['list_products']['result'];
106
+ export type RequestProposalsPayload = AdcpToolMap['request_proposals']['result'];
107
+ export type DeclineProposalsPayload = AdcpToolMap['decline_proposals']['result'];
108
+ export type BuyProductsPayload = AdcpToolMap['buy_products']['result'];
109
+ export type AcceptProposalPayload = AdcpToolMap['accept_proposal']['result'];
110
+ export type ControlMediaBuyPayload = AdcpToolMap['control_media_buy']['result'];
111
+ export type RefineProposalsPayload = AdcpToolMap['refine_proposals']['result'];
103
112
  /**
104
113
  * Wire success-row shape for `sync_creatives`. Returning the array of these
105
114
  * rows from `syncCreatives` is what adopters write — the framework wraps
@@ -110,6 +119,36 @@ export type GetProductsHandlerResult = GetProductsPayload | TaskHandoff<GetProdu
110
119
  export type CreateMediaBuyHandlerResult = CreateMediaBuyPayload | TaskHandoff<CreateMediaBuySuccessPayload>;
111
120
  export type UpdateMediaBuyHandlerResult = UpdateMediaBuyPayload | TaskHandoff<UpdateMediaBuyPayload>;
112
121
  export type SyncCreativesHandlerResult = SyncCreativesRow[] | TaskHandoff<SyncCreativesRow[]>;
122
+ type CompactLifecycleHandlerResult<T> = T | TaskHandoff<T>;
123
+ /**
124
+ * Primary AdCP 3.2 media-buy lifecycle surface.
125
+ *
126
+ * This lives beside {@link SalesPlatform} so SDK 14 adopters can implement
127
+ * the compact protocol without translating it back into deprecated
128
+ * `get_products` / `create_media_buy` / `update_media_buy` methods. Keep a
129
+ * `SalesPlatform` implementation as well when the same deployment must serve
130
+ * legacy 3.0/3.1 buyers; the server advertises only the compact profile to
131
+ * 3.2 MCP discovery while retaining those older call routes.
132
+ *
133
+ * `refineProposals` requires `proposalRefinement` so capability discovery can
134
+ * declare the supported structured refinement dimensions truthfully.
135
+ *
136
+ * @public
137
+ */
138
+ export interface MediaBuyLifecyclePlatform<TCtxMeta = Record<string, unknown>> {
139
+ proposalRefinement?: ProposalRefinementCapabilities;
140
+ listProducts?(req: AdcpToolMap['list_products']['params'], ctx: Ctx<TCtxMeta>): Promise<ListProductsPayload>;
141
+ requestProposals?(req: AdcpToolMap['request_proposals']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<RequestProposalsPayload>>;
142
+ refineProposals?(req: AdcpToolMap['refine_proposals']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<RefineProposalsPayload>>;
143
+ declineProposals?(req: AdcpToolMap['decline_proposals']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<DeclineProposalsPayload>>;
144
+ buyProducts?(req: AdcpToolMap['buy_products']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<BuyProductsPayload>>;
145
+ acceptProposal?(req: AdcpToolMap['accept_proposal']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<AcceptProposalPayload>>;
146
+ controlMediaBuy?(req: AdcpToolMap['control_media_buy']['params'], ctx: Ctx<TCtxMeta>): Promise<CompactLifecycleHandlerResult<ControlMediaBuyPayload>>;
147
+ getMediaBuys?(req: GetMediaBuysRequest, ctx: Ctx<TCtxMeta>): Promise<GetMediaBuysPayload>;
148
+ getMediaBuyDelivery?(filter: GetMediaBuyDeliveryRequest, ctx: Ctx<TCtxMeta>): Promise<GetMediaBuyDeliveryPayload>;
149
+ }
150
+ export type MediaBuyLifecycleCorePlatform<TCtxMeta = Record<string, unknown>> = Required<Pick<MediaBuyLifecyclePlatform<TCtxMeta>, 'listProducts' | 'buyProducts' | 'controlMediaBuy' | 'getMediaBuys' | 'getMediaBuyDelivery'>>;
151
+ export type MediaBuyLifecycleProposalPlatform<TCtxMeta = Record<string, unknown>> = Required<Pick<MediaBuyLifecyclePlatform<TCtxMeta>, 'proposalRefinement' | 'listProducts' | 'requestProposals' | 'refineProposals' | 'declineProposals' | 'acceptProposal' | 'getMediaBuys' | 'getMediaBuyDelivery'>>;
113
152
  export interface SalesPlatform<TCtxMeta = Record<string, unknown>> {
114
153
  /** Catalog discovery: return products directly or hand off curated discovery to a background task. */
115
154
  getProducts?(req: CanonicalGetProductsRequest, ctx: Ctx<TCtxMeta>): Promise<GetProductsHandlerResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"sales.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/specialisms/sales.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sales.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/specialisms/sales.ts"],"names":[],"mappings":"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"}