Summary
Two related codegen gaps around format asset slots, both surfacing as friction for SDK consumers that want to validate or type-narrow Format.assets from creative agents:
-
Zod schemas for slot shapes are missing. The codegen produces *AssetRequirementsSchema (image, video, text, …) at dist/lib/types/schemas.generated.d.ts, and TS types for the wrapping slot shapes (IndividualAssetSlot, RepeatableGroupSlot, FormatAssetSlot) at dist/lib/types/format-asset-slots.d.ts. But it doesn't generate Zod for the slot shapes — there's no IndividualAssetSlotSchema, RepeatableGroupSlotSchema, or FormatAssetSlotSchema.
-
Format.assets is typed loosely. Per dist/lib/types/format-asset-slots.d.ts:
export interface BaseIndividualAssetSlot {
item_type: 'individual';
asset_id: string;
asset_role?: string;
required: boolean;
overlays?: Overlay[];
}
Whereas the wire format (and the proper IndividualAssetSlot discriminated union in the same file, line 77) carries asset_type plus a discriminated requirements. If Format.assets were typed as FormatAssetSlot[], consumers would get proper narrowing.
Why this matters
Today, consumers reading agent.listCreativeFormats() get back Format objects whose assets[] are typed as the narrow base. The fields are present in JSON but not in TS types. We work around this with casts:
// from a downstream consumer, paraphrased
const assetList = f.assets ?? (rawFormat.assets_required as typeof f.assets)
return assetList.map((a) => {
const raw = a as unknown as Record<string, unknown>
return {
asset_type: String(raw.asset_type ?? raw.type ?? ''),
description: String(raw.description ?? ''),
requirements: raw.requirements as Record<string, unknown>,
// ...
}
})
Two costs:
- No runtime validation of slot shape. Without a slot-level Zod schema, consumers either build their own (forking the type definitions) or trust the wire format. We'd build our own; we'd rather not.
- Lost type narrowing. A consumer that reads
slot.asset_type === "text" should get slot.requirements: TextAssetRequirements | undefined for free. Today they have to cast.
Proposed fix
(A) Generate Zod for slot shapes
Extend the JSON-Schema → Zod codegen (or whatever step produces schemas.generated.ts) to cover:
BaseIndividualAssetSlotSchema, BaseGroupAssetSlotSchema
IndividualImageAssetSlotSchema, IndividualVideoAssetSlotSchema, … (all 14 individual variants)
IndividualAssetSlotSchema — the discriminated union over asset_type
GroupAssetSlotSchema, RepeatableGroupSlotSchema
FormatAssetSlotSchema = IndividualAssetSlotSchema | RepeatableGroupSlotSchema
These shapes are already declared as TS interfaces in format-asset-slots.d.ts; the Zod codegen just needs to follow.
(B) Tighten Format.assets typing
Change Format.assets (in tools.generated) from the narrow base shape to FormatAssetSlot[]. Same wire format, more honest type. Eliminates the cast pattern shown above.
Workarounds in the meantime
We'll likely hand-roll a Zod discriminated union locally that satisfies IndividualAssetSlot from the SDK types (using satisfies z.ZodType<IndividualAssetSlot> to anchor compile-time alignment). When (A) lands, we delete ours and import yours.
Cross-links
Versions
@adcp/sdk@6.5.0. Reproducible by inspecting dist/lib/types/format-asset-slots.d.ts (TS-only types) vs dist/lib/types/schemas.generated.d.ts (no slot Zod schemas).
Summary
Two related codegen gaps around format asset slots, both surfacing as friction for SDK consumers that want to validate or type-narrow
Format.assetsfrom creative agents:Zod schemas for slot shapes are missing. The codegen produces
*AssetRequirementsSchema(image, video, text, …) atdist/lib/types/schemas.generated.d.ts, and TS types for the wrapping slot shapes (IndividualAssetSlot,RepeatableGroupSlot,FormatAssetSlot) atdist/lib/types/format-asset-slots.d.ts. But it doesn't generate Zod for the slot shapes — there's noIndividualAssetSlotSchema,RepeatableGroupSlotSchema, orFormatAssetSlotSchema.Format.assetsis typed loosely. Perdist/lib/types/format-asset-slots.d.ts:Whereas the wire format (and the proper
IndividualAssetSlotdiscriminated union in the same file, line 77) carriesasset_typeplus a discriminatedrequirements. IfFormat.assetswere typed asFormatAssetSlot[], consumers would get proper narrowing.Why this matters
Today, consumers reading
agent.listCreativeFormats()get backFormatobjects whoseassets[]are typed as the narrow base. The fields are present in JSON but not in TS types. We work around this with casts:Two costs:
slot.asset_type === "text"should getslot.requirements: TextAssetRequirements | undefinedfor free. Today they have to cast.Proposed fix
(A) Generate Zod for slot shapes
Extend the JSON-Schema → Zod codegen (or whatever step produces
schemas.generated.ts) to cover:BaseIndividualAssetSlotSchema,BaseGroupAssetSlotSchemaIndividualImageAssetSlotSchema,IndividualVideoAssetSlotSchema, … (all 14 individual variants)IndividualAssetSlotSchema— the discriminated union overasset_typeGroupAssetSlotSchema,RepeatableGroupSlotSchemaFormatAssetSlotSchema = IndividualAssetSlotSchema | RepeatableGroupSlotSchemaThese shapes are already declared as TS interfaces in
format-asset-slots.d.ts; the Zod codegen just needs to follow.(B) Tighten
Format.assetstypingChange
Format.assets(intools.generated) from the narrow base shape toFormatAssetSlot[]. Same wire format, more honest type. Eliminates the cast pattern shown above.Workarounds in the meantime
We'll likely hand-roll a Zod discriminated union locally that satisfies
IndividualAssetSlotfrom the SDK types (usingsatisfies z.ZodType<IndividualAssetSlot>to anchor compile-time alignment). When (A) lands, we delete ours and import yours.Cross-links
AssetRequirementsSchemafrom this SDK: scope3data/agentic-api#2366Versions
@adcp/sdk@6.5.0. Reproducible by inspectingdist/lib/types/format-asset-slots.d.ts(TS-only types) vsdist/lib/types/schemas.generated.d.ts(no slot Zod schemas).