Skip to content

Commit fd1efc4

Browse files
bokelleyclaude
andauthored
feat: storyboard UX, inline agent connect, OAuth auth (#1998)
* feat: storyboard UX improvements and OAuth auth support Short-circuit comply() when product discovery fails — skip dependent tracks instead of repeating the same error across 10+ scenarios. Saves significant time for agents with broken product schemas. Add inline agent connection form to dashboard — replaces the chat bounce for saving auth tokens and platform type. New PUT /registry/agents/:url/connect endpoint handles token storage directly. Filter storyboard picker by agent capabilities — groups into Recommended and Other based on the agent's compliance tracks. Signal storyboards show for signal agents, creative for creative agents, etc. Add creative_generative.yaml storyboard — covers the brief-driven generation flow (OpenAds, generative DSPs) with 5 phases: format discovery, generate from brief, refine, multi-format, production build. Fix resolveOwnerAuth() to fall back to OAuth tokens when no static bearer token exists, with 5-minute expiration buffer. Auto-scroll storyboard results into view after rendering. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add changeset for storyboard UX improvements Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address code review findings - Add max-length validation (4096) on auth_token input - Validate auth_type against allowed values instead of silent fallback - Validate platform_type is a string before set membership check - Combine ownership verification and org lookup into single query - Log warning when OAuth token has no expiration recorded - Preserve agentTracks context through storyboard back button navigation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add rate limiter to agent connect endpoint Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: collapse two-phase comply() into single pass The two-phase approach (run core+products first, then skip dependent tracks) is no longer needed: #1985's scenario filtering already limits comply() to only the scenarios a storyboard references, and @adcp/client's storyboard runner will handle step-by-step short-circuiting. Remove isTrackProductDependent(), foundation/remaining track splitting, and the product-availability check. comply() now runs all requested scenarios in a single testAllScenarios() call. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove unused variable flagged by CodeQL Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a412fe7 commit fd1efc4

6 files changed

Lines changed: 641 additions & 21 deletions

File tree

.changeset/storyboard-ux-fixes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"adcontextprotocol": patch
3+
---
4+
5+
Storyboard UX: short-circuit comply() when products fail, inline agent connect form, filter picker by capabilities, OAuth auth fallback, generative creative storyboard
Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
id: creative_generative
2+
version: "1.0.0"
3+
title: "Generative creative agent"
4+
category: creative_generative
5+
summary: "Agent that takes a brief and generates finished creatives from scratch — no input assets required."
6+
7+
narrative: |
8+
You run a generative creative platform — an AI ad network, a generative DSP, or any system
9+
that creates ad creatives from a natural-language brief and brand identity. The buyer doesn't
10+
push assets to you. Instead, they describe what they want, point you at a brand.json, and
11+
your agent produces finished creatives ready for trafficking.
12+
13+
This is fundamentally different from template-based transformation (Celtra) or library-based
14+
retrieval (Innovid). Your agent creates something new. The buyer sends a brief, optionally
15+
with seed assets or constraints, and your platform generates creatives — potentially in
16+
multiple formats at once.
17+
18+
This storyboard walks through the generation flow: format discovery, brief-driven generation,
19+
multi-format builds, iterative refinement, and quality progression from draft to production.
20+
21+
agent:
22+
interaction_model: stateless_generate
23+
capabilities:
24+
- supports_generation
25+
examples:
26+
- "OpenAds"
27+
- "AI ad networks"
28+
- "Generative DSPs"
29+
30+
caller:
31+
role: buyer_agent
32+
example: "Scope3 (DSP)"
33+
34+
prerequisites:
35+
description: |
36+
The caller needs a brand identity (brand.json at the brand's domain) for the agent
37+
to resolve visual identity — logos, colors, fonts, tone. The test kit provides a
38+
sample brand with campaign parameters.
39+
test_kit: "test-kits/acme-outdoor.yaml"
40+
41+
phases:
42+
- id: format_discovery
43+
title: "Discover generative formats"
44+
narrative: |
45+
The buyer needs to know what your agent can generate. Unlike a template platform
46+
where formats are fixed dimensions, generative formats describe what the agent
47+
produces — the output type, constraints, and what inputs it accepts. A generative
48+
format might be "display_300x250_generative" that accepts a brief and produces
49+
a finished banner, or "social_post_generative" that creates platform-native content.
50+
51+
steps:
52+
- id: discover_formats
53+
title: "Discover available generative formats"
54+
narrative: |
55+
The buyer asks: "What can you generate?" Your platform returns the formats
56+
you support. Each format describes the output type, dimensions, and what
57+
inputs it needs (brief text, brand reference, seed images, etc.).
58+
task: list_creative_formats
59+
schema_ref: "creative/list-creative-formats-request.json"
60+
response_schema_ref: "creative/list-creative-formats-response.json"
61+
doc_ref: "/creative/task-reference/list_creative_formats"
62+
comply_scenario: creative_sync
63+
stateful: false
64+
expected: |
65+
Return your generative formats. Each format should include:
66+
- format_id with your agent_url and a unique id
67+
- Human-readable name and description
68+
- Asset slots describing what inputs are accepted (brief text, images, etc.)
69+
- Render dimensions for the output
70+
- Variables for any dynamic fields the buyer can control
71+
72+
sample_request: {}
73+
74+
validations:
75+
- check: response_schema
76+
description: "Response matches list-creative-formats-response.json schema"
77+
- check: field_present
78+
path: "formats"
79+
description: "Response contains a formats array"
80+
- check: field_present
81+
path: "formats[0].format_id.agent_url"
82+
description: "Each format has a format_id with agent_url"
83+
84+
- id: generate_from_brief
85+
title: "Generate from brief"
86+
narrative: |
87+
The buyer describes what they want in natural language and your agent generates
88+
a creative from scratch. The brief includes the campaign message, target audience
89+
context, and a brand reference so your agent can resolve visual identity.
90+
91+
This is the core generative flow. The buyer doesn't provide finished assets —
92+
they provide intent, and your agent creates.
93+
94+
steps:
95+
- id: build_draft
96+
title: "Generate a draft creative from brief"
97+
narrative: |
98+
The buyer sends a brief describing the campaign and a target format. Your
99+
agent generates a draft creative — fast, lower-fidelity output the buyer can
100+
review before committing to a production build.
101+
102+
The brief is passed as a message alongside the target format. The brand
103+
reference lets your agent resolve brand.json for visual identity.
104+
task: build_creative
105+
schema_ref: "media-buy/build-creative-request.json"
106+
response_schema_ref: "media-buy/build-creative-response.json"
107+
doc_ref: "/creative/task-reference/build_creative"
108+
comply_scenario: creative_flow
109+
stateful: false
110+
expected: |
111+
Return a generated creative manifest:
112+
- creative_manifest with the generated assets (images, copy, serving code)
113+
- format_id matching the target format
114+
- If include_preview is true, include a preview render
115+
116+
The output should be a coherent creative that reflects the brief and brand
117+
identity — not a template with placeholder text.
118+
119+
sample_request:
120+
message: "Create a display banner for a summer outdoor gear sale. Bold, adventurous tone. Headline should emphasize 40% off. Target audience: active adults 25-54."
121+
target_format_id:
122+
agent_url: "https://your-agent.example.com"
123+
id: "display_300x250_generative"
124+
brand:
125+
domain: "acme-outdoor.example.com"
126+
quality: "draft"
127+
include_preview: true
128+
129+
validations:
130+
- check: response_schema
131+
description: "Response matches build-creative-response.json schema"
132+
- check: field_present
133+
path: "creative_manifest.assets"
134+
description: "Output manifest includes generated assets"
135+
- check: field_present
136+
path: "creative_manifest.format_id"
137+
description: "Output manifest includes format_id"
138+
139+
- id: refine
140+
title: "Refine the creative"
141+
narrative: |
142+
The buyer reviews the draft and wants changes. They send the generated manifest
143+
back with refinement instructions. Your agent modifies the creative based on the
144+
feedback — adjusting copy, swapping imagery, or changing the layout.
145+
146+
This is iterative: the buyer can refine multiple times until they're satisfied,
147+
then request a production-quality build.
148+
149+
steps:
150+
- id: refine_creative
151+
title: "Refine with feedback"
152+
narrative: |
153+
The buyer passes the generated manifest back with a message describing what
154+
to change. Your agent applies the refinements and returns an updated creative.
155+
task: build_creative
156+
schema_ref: "media-buy/build-creative-request.json"
157+
response_schema_ref: "media-buy/build-creative-response.json"
158+
doc_ref: "/creative/task-reference/build_creative"
159+
comply_scenario: creative_flow
160+
stateful: false
161+
expected: |
162+
Return a refined creative manifest reflecting the requested changes.
163+
The output should preserve what worked in the original while applying
164+
the refinements.
165+
166+
sample_request:
167+
message: "Make the headline larger. Replace the mountain imagery with a trail running scene. Add a CTA button that says 'Shop Now'."
168+
creative_manifest:
169+
format_id:
170+
agent_url: "https://your-agent.example.com"
171+
id: "display_300x250_generative"
172+
assets:
173+
- asset_id: "generated_image"
174+
asset_type: "image"
175+
url: "https://your-agent.example.com/generated/abc123.jpg"
176+
- asset_id: "headline"
177+
asset_type: "text"
178+
text: "Summer Sale — 40% Off All Gear"
179+
target_format_id:
180+
agent_url: "https://your-agent.example.com"
181+
id: "display_300x250_generative"
182+
brand:
183+
domain: "acme-outdoor.example.com"
184+
quality: "draft"
185+
include_preview: true
186+
187+
validations:
188+
- check: response_schema
189+
description: "Response matches build-creative-response.json schema"
190+
- check: field_present
191+
path: "creative_manifest.assets"
192+
description: "Refined manifest includes assets"
193+
194+
- id: multi_format
195+
title: "Multi-format generation"
196+
narrative: |
197+
The buyer needs the creative in multiple sizes. Instead of generating each
198+
format separately, they pass target_format_ids (plural) and your agent produces
199+
all formats in a single call. This is where generative agents shine — adapting
200+
a concept across formats while maintaining visual coherence.
201+
202+
steps:
203+
- id: build_multi_format
204+
title: "Generate for multiple formats"
205+
narrative: |
206+
The buyer passes the refined manifest with multiple target formats. Your
207+
agent generates a creative for each format, adapting layout, copy, and
208+
imagery to fit each size while maintaining brand consistency.
209+
task: build_creative
210+
schema_ref: "media-buy/build-creative-request.json"
211+
response_schema_ref: "media-buy/build-creative-response.json"
212+
doc_ref: "/creative/task-reference/build_creative"
213+
comply_scenario: creative_flow
214+
stateful: false
215+
expected: |
216+
Return creative manifests for each requested format in creative_manifests
217+
(plural). Each manifest should:
218+
- Have a format_id matching one of the target formats
219+
- Contain complete, format-appropriate assets
220+
- Maintain visual coherence across formats
221+
222+
If a format cannot be produced, include it with an error — don't fail
223+
the entire request.
224+
225+
sample_request:
226+
message: "Generate production-ready versions for all three sizes."
227+
creative_manifest:
228+
format_id:
229+
agent_url: "https://your-agent.example.com"
230+
id: "display_300x250_generative"
231+
assets:
232+
- asset_id: "generated_image"
233+
asset_type: "image"
234+
url: "https://your-agent.example.com/generated/abc123-refined.jpg"
235+
- asset_id: "headline"
236+
asset_type: "text"
237+
text: "Summer Sale — 40% Off All Gear"
238+
- asset_id: "cta"
239+
asset_type: "text"
240+
text: "Shop Now"
241+
target_format_ids:
242+
- agent_url: "https://your-agent.example.com"
243+
id: "display_300x250_generative"
244+
- agent_url: "https://your-agent.example.com"
245+
id: "display_728x90_generative"
246+
- agent_url: "https://your-agent.example.com"
247+
id: "display_320x50_generative"
248+
brand:
249+
domain: "acme-outdoor.example.com"
250+
quality: "production"
251+
252+
validations:
253+
- check: response_schema
254+
description: "Response matches build-creative-response.json schema"
255+
- check: field_present
256+
path: "creative_manifests"
257+
description: "Response contains creative_manifests array (plural)"
258+
259+
- id: production_build
260+
title: "Production build"
261+
narrative: |
262+
The buyer is satisfied with the concept and needs a final, production-quality
263+
creative ready for trafficking. They switch quality from draft to production.
264+
Your agent generates the finished output with full-fidelity assets.
265+
266+
steps:
267+
- id: build_production
268+
title: "Build at production quality"
269+
narrative: |
270+
The buyer requests a production-quality build of the approved concept. Your
271+
agent generates the final creative with full-fidelity rendering, polished
272+
assets, and serving code ready for trafficking.
273+
task: build_creative
274+
schema_ref: "media-buy/build-creative-request.json"
275+
response_schema_ref: "media-buy/build-creative-response.json"
276+
doc_ref: "/creative/task-reference/build_creative"
277+
comply_scenario: creative_flow
278+
stateful: false
279+
expected: |
280+
Return a production-quality creative manifest:
281+
- Full-fidelity generated assets
282+
- Serving code (HTML, JavaScript, or VAST) ready for trafficking
283+
- Provenance metadata if AI-generated (digital_source_type, ai_tool)
284+
285+
sample_request:
286+
message: "Final production build. No changes needed."
287+
creative_manifest:
288+
format_id:
289+
agent_url: "https://your-agent.example.com"
290+
id: "display_300x250_generative"
291+
assets:
292+
- asset_id: "generated_image"
293+
asset_type: "image"
294+
url: "https://your-agent.example.com/generated/abc123-refined.jpg"
295+
- asset_id: "headline"
296+
asset_type: "text"
297+
text: "Summer Sale — 40% Off All Gear"
298+
- asset_id: "cta"
299+
asset_type: "text"
300+
text: "Shop Now"
301+
target_format_id:
302+
agent_url: "https://your-agent.example.com"
303+
id: "display_300x250_generative"
304+
brand:
305+
domain: "acme-outdoor.example.com"
306+
quality: "production"
307+
include_preview: true
308+
309+
validations:
310+
- check: response_schema
311+
description: "Response matches build-creative-response.json schema"
312+
- check: field_present
313+
path: "creative_manifest.assets"
314+
description: "Production manifest includes assets"
315+
- check: field_present
316+
path: "creative_manifest.format_id"
317+
description: "Production manifest includes format_id"

0 commit comments

Comments
 (0)