Skip to content

feat(types): strict per-asset-type slot types for Format.assets[]#920

Merged
bokelley merged 2 commits into
mainfrom
bokelley/codequal-pr118-review
Apr 24, 2026
Merged

feat(types): strict per-asset-type slot types for Format.assets[]#920
bokelley merged 2 commits into
mainfrom
bokelley/codequal-pr118-review

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

The codegen collapses the discriminated union under Format.assets[] to BaseIndividualAsset with no asset_type and no requirements field. Authors had no compile-time signal on misnamed requirement fields, wrong units, or misplaced count constraints. scope3data/agentic-adapters#118 hit all four failure modes post-merge across five social/retail adapters (Pinterest, TikTok, UniversalAds, Criteo, CitrusAd):

  1. file_types instead of formats (image) / containers (video)
  2. min_duration_seconds instead of min_duration_ms
  3. Comma-joined aspect_ratio ("1:1,16:9") instead of single-valued matching the spec regex
  4. min_count / max_count on individual asset slots instead of the repeatable_group wrapper

This PR adds:

  • Types (src/lib/types/format-asset-slots.ts) — IndividualImageAssetSlot, IndividualVideoAssetSlot, IndividualAudioAssetSlot, IndividualTextAssetSlot, IndividualMarkdownAssetSlot, IndividualHtmlAssetSlot, IndividualCssAssetSlot, IndividualJavascriptAssetSlot, IndividualVastAssetSlot, IndividualDaastAssetSlot, IndividualUrlAssetSlot, IndividualWebhookAssetSlot, IndividualBriefAssetSlot, IndividualCatalogAssetSlot, RepeatableGroupSlot, plus matching Group* variants for use inside repeatable groups. Wires the existing *AssetRequirements interfaces from core.generated.ts into a proper discriminated union.
  • Builders (src/lib/utils/format-asset-slot-builders.ts) — imageAssetSlot, videoAssetSlot, …, repeatableGroup, plus per-asset-type group helpers and a FormatAsset namespace for grouped imports.
  • Type-test gate (src/type-tests/format-asset-slots.type-test.ts) — @ts-expect-error directives covering each PR chore: release package #118 failure mode. Outside tsconfig.lib so it doesn't ship to dist; root tsconfig type-checks it. Regressions block CI's typecheck.
  • Runtime tests (test/lib/format-asset-slot-builders.test.js) — 9 tests confirming the builders emit the right wire shape.
  • Skill updatesbuild-seller-agent, build-generative-seller-agent, and build-creative-agent each gained a "format asset slot" section framed for that audience (social/retail sales, generative DSPs, ad servers/CMPs).
  • Changeset — minor bump.

Spec-side companion

Filed adcontextprotocol/adcp#3069 requesting title on the oneOf branches in list-creative-formats-response. Once that lands and codegen produces named per-asset-type interfaces natively, the hand-authored shim in this PR retires.

Additive change — existing Format.assets[] literals continue to compile.

Test plan

  • npm run build clean
  • npm run typecheck clean (the type-test file's @ts-expect-error directives all fire)
  • 44/44 builder tests pass
  • npx biome check clean on new files

🤖 Generated with Claude Code

bokelley and others added 2 commits April 24, 2026 18:15
…ssets[]

The codegen collapses the discriminated union under `Format.assets[]` to
`BaseIndividualAsset` with no `asset_type` and no `requirements`. Authors
writing format declarations had no compile-time signal on misnamed
requirement fields (`file_types` vs `formats`/`containers`), wrong units
(`min_duration_seconds` vs `min_duration_ms`), or `min_count`/`max_count`
placed on individual asset slots instead of the `repeatable_group`
wrapper. scope3data/agentic-adapters#118 hit all four post-merge across
five social/retail adapters.

Hand-authored slot types wire the existing `*AssetRequirements`
interfaces from core.generated.ts into a proper discriminated union, and
the new builders inject `item_type` + `asset_type` so callers supply
only the meaningful fields. A type-test file outside `tsconfig.lib`
asserts via `@ts-expect-error` that the four PR #118 failure modes all
fail typecheck — CI blocks regressions there first.

Skill updates frame the translation footguns for each audience: social
and retail sellers in build-seller-agent, generative DSPs in
build-generative-seller-agent, ad servers and CMPs in
build-creative-agent. Spec-side companion issue at
adcontextprotocol/adcp#3069 asks for `title` on the `oneOf` branches so
future codegen produces these types natively and the shim retires.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI's prettier --check failed on the new file. Apply --write and drop a
stale Zod-schema reference from the file header comment that no longer
applies (the Zod helper file was removed before merging).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley
bokelley merged commit d102262 into main Apr 24, 2026
9 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.

1 participant