feat(compat): v2.5 create_media_buy + update_media_buy adapters (stage 5c)#669
Merged
Conversation
Port of pricing-adapter.ts (inverted from JS direction) plus brand/catalog/channel translation. JS is v3→v2 (client side); our server-side use case is v2→v3, so request and response swap roles. * brand_manifest (v2.5 URL) ↔ brand.domain (v3 BrandReference) * promoted_offerings (v2.5 nested) ↔ catalog (v3 discriminated union) * Channels — lossy both directions: - video → olv+ctv, audio → streaming_audio, native → display, retail → retail_media - response collapses back, deduped * Pricing options: - rate + is_fixed ↔ fixed_price - price_guidance.floor ↔ top-level floor_price - Percentile fields stay in price_guidance 20 new tests cover both directions, idempotency on v3-already-shape, and unknown-channel pass-through. Updated test_v2_5_tool_without_adapter_raises_invalid_request to use create_media_buy (still unported in Stage 5c). Stage 5c will port create_media_buy + update_media_buy (creative-adapter.ts). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review feedback on PR #668 flagged that the v2/v3 precedence in ``_normalize_pricing_option`` is correct but undocumented. Add a test that pins ``rate`` (v2) over ``fixed_price`` (v3) when both are present — matches the JS reference implementation's behaviour and documents intent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e 5c) Closes out the v2.5 → v3 adapter catalog. Shared helpers in ``_media_buy_helpers`` (creative_ids ↔ creative_assignments, brand manifest, null-array coercion). Translations: * Package shape: v2.5 creative_ids ↔ v3 creative_assignments. The response-direction collapse drops v3-only weight + placement_ids silently — v2.5 buyers can't surface them, so the alternative (raise on every response with weights) rejects the typical case. * create_media_buy: brand_manifest URL → brand.domain. * Null-array coercion (creative_assignments / creative_ids / products set to null become absent fields). update_media_buy does NOT translate brand_manifest — updates don't carry brand in v3, and v2.5 buyers sending the field on an update are passing through metadata the handler can ignore. Tested explicitly. Updated test_v2_5_tool_without_adapter_raises_invalid_request to use check_governance (v3-added tool with no v2.5 adapter) since create_media_buy is now covered. Full v2.5 catalog now adapted: sync_creatives, list_creative_formats, preview_creative, get_products, create_media_buy, update_media_buy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review feedback on PR #669. The helper was defined byte-for-byte in both ``_media_buy_helpers.py`` and ``get_products.py``; future edits would drift. Move to ``adcp.compat.legacy.v2_5._url`` so both import the same canonical implementation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage 5c. Closes out the v2.5 → v3 adapter catalog. Stacked on #668 (Stage 5b
get_products).Summary
Two more adapters + shared helpers module. Both tools translate package shape (
creative_ids↔creative_assignments);create_media_buyadditionally translatesbrand_manifest↔brand.Lossy paths (silent — per user direction)
weightandplacement_idsdropped when v3creative_assignmentscollapse to v2.5creative_ids. v2.5 buyers have no field to surface them on; raising on every response that uses weights would reject the typical case unfairly.nullfor optional arrays; convert to absent fields.Full v2.5 catalog now adapted
sync_creatives(Stage 4)list_creative_formats,preview_creative(Stage 5)get_products(Stage 5b — feat(compat): v2.5 get_products adapter (stage 5b) #668)create_media_buy,update_media_buy(this PR)Remaining versioned-validation work
Test plan
pytest— 4515 passedcreate_media_buy/update_media_buytest_v2_5_tool_without_adapter_raises_invalid_requestto usecheck_governance(a v3-added tool with no v2.5 adapter)ruff check+mypy🤖 Generated with Claude Code