Skip to content

preview_creative: flatten union schema into single object with request_type discriminant #2175

@bokelley

Description

@bokelley

Problem

preview_creative is the only tool in AdCP whose request schema is a z.union() of three variants (single, batch, variant). This means:

  1. Cannot use server.tool(name, schema.shape, handler) — unions don't have .shape. Every other tool works with this pattern.

  2. Server frameworks can't auto-register itcreateAdcpServer and similar builders wire tools to schemas automatically. preview_creative requires manual registration.

  3. Workaround is fragile — the library splits the union into three exported variant schemas (PreviewCreativeSingleRequestSchema, etc.) with a runtime assertion that the union order hasn't changed.

Proposal

Flatten the union into a single z.object():

  • request_type: 'single' | 'batch' | 'variant' — required discriminant field
  • Variant-specific fields become optional, documented as required-when for each mode
  • Validation of conditional requirements happens at the application level, not the schema level

This matches how other AdCP tools with modal behavior work — they use discriminant fields within a flat object (e.g., buying_mode on get_products, action on update_media_buy).

Impact

  • Every tool in AdCP works with server.tool(name, schema.shape, handler)
  • Server frameworks can auto-register preview_creative
  • Simpler schema, no union splitting needed
  • Slight loss of schema-level validation (conditional requirements become documentation)

Priority

Should land before 3.0 — changing the schema shape after release is breaking.

Discovered during createAdcpServer implementation (#537).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions