Skip to content

feat(pricing): per_unit + custom vendor pricing variants (3.0 GA)#65

Merged
bokelley merged 3 commits into
mainfrom
bokelley/sdk-v3-readiness
Apr 20, 2026
Merged

feat(pricing): per_unit + custom vendor pricing variants (3.0 GA)#65
bokelley merged 3 commits into
mainfrom
bokelley/sdk-v3-readiness

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

  • Extends VendorPricingOption with MaxCPM, Unit, UnitPrice, Description, Metadata, Ext so all five AdCP 3.0 vendor-pricing variants (cpm, percent_of_media, flat_fee, per_unit, custom) round-trip.
  • Collapses SignalPricing to type SignalPricing = VendorPricingOption — upstream consolidated signal-pricing-option.json as a deprecated $ref to vendor-pricing-option.json, so two byte-identical structs invited drift.
  • Makes Currency omitempty (custom variant makes it optional per schema); per-variant required-field enforcement stays in the schema validator, not the SDK.
  • Bumps .bundle-sha256 to match the fresh upstream bundle.
  • build-signals-agent SKILL.md: one-line note flagging custom as operator-review-gated per the issue's guidance.

Upstream: adcontextprotocol/adcp#2422. Closes #63.

experimental_features on get_adcp_capabilities was already picked up by a prior regen.

Review feedback addressed

Both code-reviewer and ad-tech-protocol-expert ran before commit:

  • Blocker fixed: flat_fee test used "month"; schema enum is monthly|quarterly|annual|campaign. Changed to "monthly".
  • Should fix: the two structs were byte-identical after the extension — collapsed to a type alias as suggested.
  • Noted on struct: PricingOptionID is the wrapper field, not part of the oneOf; Go can't express oneOf at the type level, so omitempty on numerics drops legitimate zeros. Left documented rather than patched — matches how every other discriminated union in types.go is handled.

Test plan

  • adcp/pricing_test.go round-trips all 5 variants including custom without currency
  • go test ./adcp/... — green
  • go test ./... (root module) — green
  • TestSkillSkeletonsCompile — all 7 skills still compile

🤖 Generated with Claude Code

bokelley and others added 2 commits April 19, 2026 23:14
… GA)

AdCP 3.0 GA (upstream adcontextprotocol/adcp#2422) adds `per_unit` and
`custom` variants to the vendor-pricing oneOf. Extends VendorPricingOption
with MaxCPM, Unit, UnitPrice, Description, Metadata, and Ext so all five
variants (cpm, percent_of_media, flat_fee, per_unit, custom) round-trip.

Collapses SignalPricing to a type alias for VendorPricingOption — upstream
already treats signal-pricing-option.json as a deprecated $ref to
vendor-pricing-option.json, so carrying two byte-identical structs invited
drift.

Makes Currency omitempty; the custom variant treats it as optional per the
upstream schema. Per-variant required-field enforcement stays in the
schema validator layer, not the SDK.

Skill: one-line note in build-signals-agent flags custom as
operator-review-gated per the issue's guidance.

Closes #63.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the three parser-differential gaps surfaced by the upstream PR
proposing new conformance vectors (adcontextprotocol/adcp#2489):

- Reject comma-smuggled Content-Type (`application/json, text/plain`
  in one field value). RFC 9110 §8.3 — Content-Type has no list form.
- Reject duplicate-algorithm Content-Digest entries. RFC 9530 §2 —
  Dictionary-Structured-Field with duplicate keys is ambiguous for
  signature coverage.
- Reject bare-token sig-param string values (`keyid=foo` instead of
  `keyid="foo"`). RFC 8941 §3.3 — strings and tokens are distinct;
  keyid/nonce/alg/tag are string-typed per RFC 9421 §2.3.

Parser now tracks token-vs-string as paramValue.isToken and setParam
rejects tokens where strings are required.

All 10 new conformance vectors (4 positive + 6 negative) committed to
testdata/request-signing/. Existing canonicalization already handled
the positive edge cases (IPv6 authority, %2F preserved,
%7E/%2D/%5F/%2E unreserved-decode) and three of the negative cases
(duplicate Signature-Input label, JWK alg/crv mismatch, non-ASCII
host). This commit closes the remaining three.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley mentioned this pull request Apr 20, 2026
5 tasks
Upstream adcp#2489 merge bumped the bundle; regen picks up the new
REQUOTE_REQUIRED ErrorCode added in the same window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 9840c1c into main Apr 20, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regen for AdCP 3.0 GA: new custom pricing variant + experimental_features

1 participant