You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue proposes additions to the build-time input-slot side of the creative protocol — distinct from the canonical output formats. The motivation is that as creative agents proliferate (Figma wrappers, Canva wrappers, AI generators, custom HTML renderers), they all need to advertise what inputs they accept in a way that an upstream orchestrator (or a buyer) can target generically.
This is largely a comment on #3305 (Creative Formats v2 RFC) — where build inputs collapse onto format declarations and validate_input becomes the dry-run primitive. A subset is small enough to land additively in 3.1 ahead of the full v2 redesign.
The framing throughout: canonical formats describe the output contract (PNG/HTML/MP4 the seller will accept and how it tracks); input-slot declarations describe the build-time contract (what the creative agent needs to fill in to produce that output). They live at different layers and shouldn't bleed.
Motivating example
A generic Figma-MCP wrapper exposes each Figma frame as a creative agent capability. Frame named meta_1080x1080, with named layers HEADLINE, SUBLINE, CTA, HERO_IMAGE, LOGO. The wrapper renders to a canonical image output, but its input-slot declaration needs to say:
HEADLINE: text, max 60 chars, language en (or nl-NL etc. per file)
CTA: text, must be one of ["Apply now", "View job", "Solliciteer direct"]
HERO_IMAGE: image, ≥1080×1080 — accepts a URL or a reference into a published asset library
The orchestrator (or a buyer) calls validate_input with proposed values, gets back valid: true/false plus per-slot errors, then calls the build primitive. Today there's no place in the protocol to express the picker, the language, or the catalog reference.
Proposed additions
1. allowed_values on text input slots — 3.1 candidate
Additive on text-asset-requirements.json. Closed enum of permitted strings. Validated by validate_input.
Open hint list. Discoverable by orchestrators that want to pick from a creative-agent-supplied template library; humans can override. Distinct from allowed_values (closed) so the validation semantics are clear.
{
"asset_type": "text",
"asset_role": "headline",
"max_length": 60,
"suggested_values": [
"Werken als {{role}} bij {{brand}} {{location}}",
"{{role}} gezocht in {{location}}"
]
}
(Whether suggested_values should support placeholders like {{role}} is a follow-on question — could just be plain strings the orchestrator template-fills before submitting.)
3. language on input slots — 3.1 candidate
The manifest-side text asset already carries language. Mirroring it on the input-slot requirements lets a creative agent declare per-slot locales (e.g., a Dutch-only Figma file declares language: "nl-NL" on every text slot), and validate_input can reject mismatched submissions early.
4. Repeatable input groups — v2 RFC
The output side already has item_type: "repeatable_group" (carousels, slideshows). The input side has no equivalent. The recruitment-SEA case wants "15 headline inputs + 4 description inputs"; today this has to be modeled as 15 individual slots, which doesn't compose. Proposing symmetry: an item_type: "repeatable_group" input that wraps a slot template plus min_count/max_count.
5. External-reference input slots — v2 RFC
An input slot that says: "I accept a URL, or a reference into this catalog/library." This is the clean answer to the per-location-photography pattern that today gets wedged into brand.json: photos live in a separately addressable asset library, and the hero_image input slot declares it accepts references into that library.
This intentionally does not put the catalog inbrand.json — the v2 RFC's "brand.json with override capability" framing is preserved. The catalog is its own document that input slots can target.
brand.json with override capability: (5) is the cleanest answer to the "where does catalog data live" question that I think the override design is also trying to solve.
Suggested split
3.1 (additive on text-asset-requirements.json): (1) allowed_values, (3) language.
Happy to break (1) and (3) into a separate small PR if that helps land them sooner.
Notes
The example in (5) uses JSONPath in selector — that's a sketch, not a recommendation. The real design probably wants something simpler (or a more constrained pointer scheme); that's a discussion to have if the idea has legs.
Context
This issue proposes additions to the build-time input-slot side of the creative protocol — distinct from the canonical output formats. The motivation is that as creative agents proliferate (Figma wrappers, Canva wrappers, AI generators, custom HTML renderers), they all need to advertise what inputs they accept in a way that an upstream orchestrator (or a buyer) can target generically.
This is largely a comment on #3305 (Creative Formats v2 RFC) — where build inputs collapse onto format declarations and
validate_inputbecomes the dry-run primitive. A subset is small enough to land additively in 3.1 ahead of the full v2 redesign.The framing throughout: canonical formats describe the output contract (PNG/HTML/MP4 the seller will accept and how it tracks); input-slot declarations describe the build-time contract (what the creative agent needs to fill in to produce that output). They live at different layers and shouldn't bleed.
Motivating example
A generic Figma-MCP wrapper exposes each Figma frame as a creative agent capability. Frame named
meta_1080x1080, with named layersHEADLINE,SUBLINE,CTA,HERO_IMAGE,LOGO. The wrapper renders to a canonicalimageoutput, but its input-slot declaration needs to say:HEADLINE: text, max 60 chars, languageen(ornl-NLetc. per file)CTA: text, must be one of["Apply now", "View job", "Solliciteer direct"]HERO_IMAGE: image, ≥1080×1080 — accepts a URL or a reference into a published asset libraryThe orchestrator (or a buyer) calls
validate_inputwith proposed values, gets backvalid: true/falseplus per-slot errors, then calls the build primitive. Today there's no place in the protocol to express the picker, the language, or the catalog reference.Proposed additions
1.
allowed_valueson text input slots — 3.1 candidateAdditive on
text-asset-requirements.json. Closed enum of permitted strings. Validated byvalidate_input.{ "asset_type": "text", "asset_role": "cta", "max_length": 30, "allowed_values": ["Apply now", "View job", "Solliciteer direct"] }2.
suggested_valueson text input slots — v2 RFCOpen hint list. Discoverable by orchestrators that want to pick from a creative-agent-supplied template library; humans can override. Distinct from
allowed_values(closed) so the validation semantics are clear.{ "asset_type": "text", "asset_role": "headline", "max_length": 60, "suggested_values": [ "Werken als {{role}} bij {{brand}} {{location}}", "{{role}} gezocht in {{location}}" ] }(Whether
suggested_valuesshould support placeholders like{{role}}is a follow-on question — could just be plain strings the orchestrator template-fills before submitting.)3.
languageon input slots — 3.1 candidateThe manifest-side text asset already carries
language. Mirroring it on the input-slot requirements lets a creative agent declare per-slot locales (e.g., a Dutch-only Figma file declareslanguage: "nl-NL"on every text slot), andvalidate_inputcan reject mismatched submissions early.4. Repeatable input groups — v2 RFC
The output side already has
item_type: "repeatable_group"(carousels, slideshows). The input side has no equivalent. The recruitment-SEA case wants "15 headline inputs + 4 description inputs"; today this has to be modeled as 15 individual slots, which doesn't compose. Proposing symmetry: anitem_type: "repeatable_group"input that wraps a slot template plusmin_count/max_count.5. External-reference input slots — v2 RFC
An input slot that says: "I accept a URL, or a reference into this catalog/library." This is the clean answer to the per-location-photography pattern that today gets wedged into
brand.json: photos live in a separately addressable asset library, and thehero_imageinput slot declares it accepts references into that library.{ "asset_type": "image", "asset_role": "hero_image", "min_width": 1080, "accepts_reference": { "schema": "https://example.com/photo-library.json", "selector": "$.locations[?(@.id == $location_id)].photography.exterior[*]" } }This intentionally does not put the catalog in
brand.json— the v2 RFC's "brand.json with override capability" framing is preserved. The catalog is its own document that input slots can target.Status of overlap with #3305
validate_input(already scaffolded in RFC #3305 implementation preview — v2 creative formats (full spec, not for merge) #3307): the natural validation surface for all five.format_idbecoming a string: orthogonal.brand.jsonwith override capability: (5) is the cleanest answer to the "where does catalog data live" question that I think the override design is also trying to solve.Suggested split
text-asset-requirements.json): (1)allowed_values, (3)language.suggested_values, (4) repeatable input groups, (5) external-reference inputs.Happy to break (1) and (3) into a separate small PR if that helps land them sooner.
Notes
selector— that's a sketch, not a recommendation. The real design probably wants something simpler (or a more constrained pointer scheme); that's a discussion to have if the idea has legs.asset_role: "cta"/"headline"/"hero_image"assume the canonical asset-group vocabulary from RFC #3305 implementation preview — v2 creative formats (full spec, not for merge) #3307 covers these. If it doesn't yet, the proposal still stands but the role names would shift.