@adcp/client 4.23.0 → 4.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -9
- package/bin/adcp.js +83 -18
- package/dist/lib/index.d.ts +2 -4
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +16 -12
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/server/index.d.ts +5 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +10 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/postgres-task-store.d.ts +105 -0
- package/dist/lib/server/postgres-task-store.d.ts.map +1 -0
- package/dist/lib/server/postgres-task-store.js +267 -0
- package/dist/lib/server/postgres-task-store.js.map +1 -0
- package/dist/lib/server/responses.d.ts +1 -0
- package/dist/lib/server/responses.d.ts.map +1 -1
- package/dist/lib/server/responses.js +1 -0
- package/dist/lib/server/responses.js.map +1 -1
- package/dist/lib/server/test-controller.d.ts +88 -0
- package/dist/lib/server/test-controller.d.ts.map +1 -0
- package/dist/lib/server/test-controller.js +227 -0
- package/dist/lib/server/test-controller.js.map +1 -0
- package/dist/lib/testing/agent-tester.d.ts +1 -1
- package/dist/lib/testing/agent-tester.d.ts.map +1 -1
- package/dist/lib/testing/agent-tester.js +13 -1
- package/dist/lib/testing/agent-tester.js.map +1 -1
- package/dist/lib/testing/compliance/comply.d.ts +2 -0
- package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
- package/dist/lib/testing/compliance/comply.js +76 -1
- package/dist/lib/testing/compliance/comply.js.map +1 -1
- package/dist/lib/testing/compliance/index.d.ts +1 -1
- package/dist/lib/testing/compliance/index.d.ts.map +1 -1
- package/dist/lib/testing/compliance/platform-storyboards.d.ts.map +1 -1
- package/dist/lib/testing/compliance/platform-storyboards.js +2 -0
- package/dist/lib/testing/compliance/platform-storyboards.js.map +1 -1
- package/dist/lib/testing/compliance/storyboard-tracks.d.ts.map +1 -1
- package/dist/lib/testing/compliance/storyboard-tracks.js +11 -2
- package/dist/lib/testing/compliance/storyboard-tracks.js.map +1 -1
- package/dist/lib/testing/compliance/types.d.ts +22 -1
- package/dist/lib/testing/compliance/types.d.ts.map +1 -1
- package/dist/lib/testing/orchestrator.d.ts.map +1 -1
- package/dist/lib/testing/orchestrator.js +5 -1
- package/dist/lib/testing/orchestrator.js.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.d.ts +19 -1
- package/dist/lib/testing/scenarios/brand-rights.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/brand-rights.js +138 -1
- package/dist/lib/testing/scenarios/brand-rights.js.map +1 -1
- package/dist/lib/testing/scenarios/deterministic.js +7 -7
- package/dist/lib/testing/scenarios/deterministic.js.map +1 -1
- package/dist/lib/testing/scenarios/index.d.ts +1 -1
- package/dist/lib/testing/scenarios/index.d.ts.map +1 -1
- package/dist/lib/testing/scenarios/index.js +4 -2
- package/dist/lib/testing/scenarios/index.js.map +1 -1
- package/dist/lib/testing/scenarios/media-buy.js +4 -4
- package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
- package/dist/lib/testing/storyboard/loader.d.ts +1 -0
- package/dist/lib/testing/storyboard/loader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/loader.js +14 -0
- package/dist/lib/testing/storyboard/loader.js.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-builder.js +88 -11
- package/dist/lib/testing/storyboard/request-builder.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +83 -5
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/task-map.d.ts +2 -0
- package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/task-map.js +23 -9
- package/dist/lib/testing/storyboard/task-map.js.map +1 -1
- package/dist/lib/testing/storyboard/types.d.ts +6 -2
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.js +21 -4
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/testing/types.d.ts +1 -1
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/types/core.generated.d.ts +1 -1
- package/dist/lib/types/core.generated.d.ts.map +1 -1
- package/dist/lib/types/core.generated.js +1 -1
- package/dist/lib/types/schemas.generated.d.ts +16 -13
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js +7 -4
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/types/tools.generated.d.ts +14 -5
- package/dist/lib/types/tools.generated.d.ts.map +1 -1
- package/dist/lib/utils/capabilities.d.ts +2 -2
- package/dist/lib/utils/capabilities.d.ts.map +1 -1
- package/dist/lib/utils/capabilities.js +9 -3
- package/dist/lib/utils/capabilities.js.map +1 -1
- package/dist/lib/utils/response-schemas.d.ts.map +1 -1
- package/dist/lib/utils/response-schemas.js +9 -0
- package/dist/lib/utils/response-schemas.js.map +1 -1
- package/docs/llms.txt +10 -2
- package/package.json +8 -2
- package/skills/adcp/SKILL.md +118 -33
- package/skills/build-creative-agent/SKILL.md +221 -0
- package/skills/build-generative-seller-agent/SKILL.md +288 -0
- package/skills/build-retail-media-agent/SKILL.md +237 -0
- package/skills/build-seller-agent/SKILL.md +313 -0
- package/skills/build-signals-agent/SKILL.md +203 -0
- package/storyboards/campaign_governance_conditions.yaml +2 -2
- package/storyboards/campaign_governance_delivery.yaml +1 -1
- package/storyboards/campaign_governance_denied.yaml +1 -0
- package/storyboards/creative_generative.yaml +317 -0
- package/storyboards/creative_sales_agent.yaml +2 -2
- package/storyboards/creative_template.yaml +2 -1
- package/storyboards/deterministic_testing.yaml +271 -245
- package/storyboards/media_buy_catalog_creative.yaml +2 -1
- package/storyboards/media_buy_generative_seller.yaml +581 -0
- package/storyboards/media_buy_governance_escalation.yaml +1 -1
- package/storyboards/media_buy_guaranteed_approval.yaml +14 -14
- package/storyboards/media_buy_non_guaranteed.yaml +2 -2
- package/storyboards/media_buy_proposal_mode.yaml +5 -5
- package/storyboards/media_buy_seller.yaml +10 -10
- package/storyboards/media_buy_state_machine.yaml +4 -4
- package/storyboards/schema.yaml +2 -1
- package/storyboards/signal_marketplace.yaml +3 -0
- package/storyboards/signal_owned.yaml +1 -0
- package/storyboards/test-kits/acme-outdoor.yaml +118 -0
- package/storyboards/test-kits/nova-motors.yaml +134 -0
|
@@ -16,7 +16,7 @@ narrative: |
|
|
|
16
16
|
|
|
17
17
|
The buyer either polls get_media_buys or configures a push_notification_config webhook to
|
|
18
18
|
receive a callback when the IO is signed. Once approved, the media buy transitions from
|
|
19
|
-
pending_approval to
|
|
19
|
+
pending_approval to active and the buyer can sync creatives and monitor delivery.
|
|
20
20
|
|
|
21
21
|
This storyboard isolates the guaranteed approval path — the async handshake between agent
|
|
22
22
|
automation and human decision-making that makes guaranteed buys work in practice.
|
|
@@ -264,15 +264,15 @@ phases:
|
|
|
264
264
|
narrative: |
|
|
265
265
|
The human has reviewed the IO and signed it through the setup URL. The buyer
|
|
266
266
|
polls get_media_buys again (or received a webhook notification) and sees that the
|
|
267
|
-
media buy has transitioned from pending_approval to
|
|
267
|
+
media buy has transitioned from pending_approval to active. The buy
|
|
268
268
|
is now live.
|
|
269
269
|
|
|
270
270
|
steps:
|
|
271
|
-
- id:
|
|
272
|
-
title: "Check media buy status (
|
|
271
|
+
- id: get_media_buys_active
|
|
272
|
+
title: "Check media buy status (active)"
|
|
273
273
|
narrative: |
|
|
274
274
|
After the human signs the IO, the buyer checks the media buy status again.
|
|
275
|
-
Your platform returns
|
|
275
|
+
Your platform returns active, indicating the buy is approved
|
|
276
276
|
and inventory is reserved.
|
|
277
277
|
task: get_media_buys
|
|
278
278
|
schema_ref: "media-buy/get-media-buys-request.json"
|
|
@@ -281,12 +281,12 @@ phases:
|
|
|
281
281
|
comply_scenario: media_buy_lifecycle
|
|
282
282
|
stateful: true
|
|
283
283
|
expected: |
|
|
284
|
-
Return the media buy in
|
|
284
|
+
Return the media buy in active status:
|
|
285
285
|
- media_buy_id: matches the buy created earlier
|
|
286
|
-
- status:
|
|
286
|
+
- status: active (IO has been signed)
|
|
287
287
|
- confirmed_at: timestamp when the IO was signed
|
|
288
|
-
- packages: line items
|
|
289
|
-
- valid_actions: updated for
|
|
288
|
+
- packages: line items with reserved inventory
|
|
289
|
+
- valid_actions: updated for active state (creative sync, pause, etc.)
|
|
290
290
|
|
|
291
291
|
sample_request:
|
|
292
292
|
account:
|
|
@@ -301,15 +301,15 @@ phases:
|
|
|
301
301
|
description: "Response matches get-media-buys-response.json schema"
|
|
302
302
|
- check: field_present
|
|
303
303
|
path: "media_buys[0].status"
|
|
304
|
-
description: "Media buy status is
|
|
304
|
+
description: "Media buy status is active"
|
|
305
305
|
- check: field_present
|
|
306
306
|
path: "media_buys[0].confirmed_at"
|
|
307
|
-
description: "
|
|
307
|
+
description: "Active buy includes a confirmed_at timestamp"
|
|
308
308
|
|
|
309
309
|
- id: creative_sync
|
|
310
310
|
title: "Creative sync"
|
|
311
311
|
narrative: |
|
|
312
|
-
With the IO signed and the media buy
|
|
312
|
+
With the IO signed and the media buy active, the buyer syncs creative assets
|
|
313
313
|
to your platform. Each package has creative format requirements that the buyer
|
|
314
314
|
discovered during product discovery.
|
|
315
315
|
|
|
@@ -352,7 +352,7 @@ phases:
|
|
|
352
352
|
- check: response_schema
|
|
353
353
|
description: "Response matches sync-creatives-response.json schema"
|
|
354
354
|
- check: field_present
|
|
355
|
-
path: "
|
|
355
|
+
path: "creatives[0].action"
|
|
356
356
|
description: "Each creative has an action (created/updated)"
|
|
357
357
|
|
|
358
358
|
- id: delivery_monitoring
|
|
@@ -394,5 +394,5 @@ phases:
|
|
|
394
394
|
- check: response_schema
|
|
395
395
|
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
396
396
|
- check: field_present
|
|
397
|
-
path: "
|
|
397
|
+
path: "media_buy_deliveries"
|
|
398
398
|
description: "Response contains media buy delivery data"
|
|
@@ -124,7 +124,7 @@ phases:
|
|
|
124
124
|
expected: |
|
|
125
125
|
Return the media buy in completed status:
|
|
126
126
|
- media_buy_id: your platform's identifier
|
|
127
|
-
- status:
|
|
127
|
+
- status: active (no async approval needed)
|
|
128
128
|
- confirmed_at: timestamp
|
|
129
129
|
- packages: confirmed line items with bid prices acknowledged
|
|
130
130
|
- valid_actions: pause, update_bid, get_delivery
|
|
@@ -285,5 +285,5 @@ phases:
|
|
|
285
285
|
- check: response_schema
|
|
286
286
|
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
287
287
|
- check: field_present
|
|
288
|
-
path: "
|
|
288
|
+
path: "media_buy_deliveries"
|
|
289
289
|
description: "Response contains media buy delivery data"
|
|
@@ -197,7 +197,7 @@ phases:
|
|
|
197
197
|
The buyer is satisfied with the refined proposal and accepts it by creating a
|
|
198
198
|
media buy with the proposal_id. Instead of specifying individual packages, the
|
|
199
199
|
buyer passes the proposal_id and total_budget. Your platform converts the proposal
|
|
200
|
-
into
|
|
200
|
+
into an active media buy with the exact product selections and budget allocations
|
|
201
201
|
from the proposal.
|
|
202
202
|
|
|
203
203
|
steps:
|
|
@@ -217,9 +217,9 @@ phases:
|
|
|
217
217
|
comply_scenario: create_media_buy
|
|
218
218
|
stateful: true
|
|
219
219
|
expected: |
|
|
220
|
-
Convert the proposal into
|
|
220
|
+
Convert the proposal into an active media buy:
|
|
221
221
|
- media_buy_id: your platform's identifier
|
|
222
|
-
- status:
|
|
222
|
+
- status: active
|
|
223
223
|
- confirmed_at: timestamp
|
|
224
224
|
- packages: line items derived from the proposal's budget allocations
|
|
225
225
|
- proposal_id: echoed back to confirm which proposal was accepted
|
|
@@ -324,7 +324,7 @@ phases:
|
|
|
324
324
|
- check: response_schema
|
|
325
325
|
description: "Response matches sync-creatives-response.json schema"
|
|
326
326
|
- check: field_present
|
|
327
|
-
path: "
|
|
327
|
+
path: "creatives[0].action"
|
|
328
328
|
description: "Each creative has an action (created/updated)"
|
|
329
329
|
|
|
330
330
|
- id: delivery
|
|
@@ -366,5 +366,5 @@ phases:
|
|
|
366
366
|
- check: response_schema
|
|
367
367
|
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
368
368
|
- check: field_present
|
|
369
|
-
path: "
|
|
369
|
+
path: "media_buy_deliveries"
|
|
370
370
|
description: "Response contains media buy delivery data"
|
|
@@ -303,7 +303,7 @@ phases:
|
|
|
303
303
|
- Proposal: buyer passes a proposal_id from get_products to execute a proposal
|
|
304
304
|
|
|
305
305
|
The response status tells the buyer what happens next:
|
|
306
|
-
- completed: buy is
|
|
306
|
+
- completed: buy is active and live
|
|
307
307
|
- working: your platform is processing (poll or wait for webhook)
|
|
308
308
|
- submitted: long-running async — approval workflow, IO signing, etc.
|
|
309
309
|
- input-required: need more information (budget clarification, approval)
|
|
@@ -318,8 +318,8 @@ phases:
|
|
|
318
318
|
|
|
319
319
|
Synchronous (completed):
|
|
320
320
|
- media_buy_id: your platform's identifier
|
|
321
|
-
- status:
|
|
322
|
-
- packages:
|
|
321
|
+
- status: active or pending_creatives
|
|
322
|
+
- packages: line items with pricing
|
|
323
323
|
- confirmed_at: timestamp
|
|
324
324
|
- valid_actions: what the buyer can do next
|
|
325
325
|
|
|
@@ -368,7 +368,7 @@ phases:
|
|
|
368
368
|
narrative: |
|
|
369
369
|
If create_media_buy returned working or submitted, the buyer polls for status
|
|
370
370
|
updates. Your platform returns the current state of the media buy — whether
|
|
371
|
-
it's still processing, awaiting approval, or
|
|
371
|
+
it's still processing, awaiting approval, or active.
|
|
372
372
|
|
|
373
373
|
This is also how the buyer checks for pending_approval status. If your platform
|
|
374
374
|
requires IO signing or human authorization, the buy sits at pending_approval
|
|
@@ -383,13 +383,13 @@ phases:
|
|
|
383
383
|
expected: |
|
|
384
384
|
Return the current state of the media buy:
|
|
385
385
|
- media_buy_id: matches what was returned from create_media_buy
|
|
386
|
-
- status:
|
|
386
|
+
- status: pending_creatives, pending_start, active, paused, completed, rejected, canceled
|
|
387
387
|
- packages: line items with current delivery status
|
|
388
388
|
- valid_actions: what operations are available in this state
|
|
389
389
|
|
|
390
|
-
If
|
|
391
|
-
- Include
|
|
392
|
-
-
|
|
390
|
+
If pending_creatives:
|
|
391
|
+
- Include message explaining what creatives are needed
|
|
392
|
+
- valid_actions should include sync_creatives
|
|
393
393
|
|
|
394
394
|
sample_request:
|
|
395
395
|
account:
|
|
@@ -495,7 +495,7 @@ phases:
|
|
|
495
495
|
- check: response_schema
|
|
496
496
|
description: "Response matches sync-creatives-response.json schema"
|
|
497
497
|
- check: field_present
|
|
498
|
-
path: "
|
|
498
|
+
path: "creatives[0].action"
|
|
499
499
|
description: "Each creative has an action (created/updated)"
|
|
500
500
|
|
|
501
501
|
- id: delivery_monitoring
|
|
@@ -544,5 +544,5 @@ phases:
|
|
|
544
544
|
- check: response_schema
|
|
545
545
|
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
546
546
|
- check: field_present
|
|
547
|
-
path: "
|
|
547
|
+
path: "media_buy_deliveries"
|
|
548
548
|
description: "Response contains media buy delivery data"
|
|
@@ -9,8 +9,8 @@ required_tools:
|
|
|
9
9
|
- update_media_buy
|
|
10
10
|
|
|
11
11
|
narrative: |
|
|
12
|
-
A media buy has a well-defined state machine:
|
|
13
|
-
paused, completed, canceled. Transitions between states must follow the spec — you cannot
|
|
12
|
+
A media buy has a well-defined state machine: pending_creatives, pending_start, active,
|
|
13
|
+
paused, completed, rejected, canceled. Transitions between states must follow the spec — you cannot
|
|
14
14
|
resume a canceled buy or pause a completed one.
|
|
15
15
|
|
|
16
16
|
This storyboard creates a media buy, walks it through pause/resume/cancel transitions, then
|
|
@@ -87,9 +87,9 @@ phases:
|
|
|
87
87
|
comply_scenario: create_media_buy
|
|
88
88
|
stateful: true
|
|
89
89
|
expected: |
|
|
90
|
-
Return
|
|
90
|
+
Return an active media buy with:
|
|
91
91
|
- media_buy_id
|
|
92
|
-
- status:
|
|
92
|
+
- status: active
|
|
93
93
|
|
|
94
94
|
sample_request:
|
|
95
95
|
brand:
|
package/storyboards/schema.yaml
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# id: string (unique identifier, e.g., "creative_template")
|
|
14
14
|
# version: string (semver, e.g., "1.0.0")
|
|
15
15
|
# title: string (human-readable title)
|
|
16
|
-
# category: enum (capability_discovery | schema_validation | behavioral_analysis | error_compliance | creative_template | creative_ad_server | creative_sales_agent | creative_generative | creative_lifecycle | media_buy_seller | media_buy_guaranteed_approval | media_buy_non_guaranteed | media_buy_proposal_mode | media_buy_governance_escalation | media_buy_catalog_creative | media_buy_state_machine | campaign_governance_denied | campaign_governance_conditions | campaign_governance_delivery | signal_marketplace | signal_owned | social_platform | si_session | brand_rights | property_governance | content_standards)
|
|
16
|
+
# category: enum (capability_discovery | schema_validation | behavioral_analysis | error_compliance | creative_template | creative_ad_server | creative_sales_agent | creative_generative | creative_lifecycle | media_buy_seller | media_buy_generative_seller | media_buy_guaranteed_approval | media_buy_non_guaranteed | media_buy_proposal_mode | media_buy_governance_escalation | media_buy_catalog_creative | media_buy_state_machine | campaign_governance_denied | campaign_governance_conditions | campaign_governance_delivery | signal_marketplace | signal_owned | social_platform | si_session | brand_rights | property_governance | content_standards | audience_sync)
|
|
17
17
|
# summary: string (one-line description for listings)
|
|
18
18
|
# narrative: string (paragraph explaining the overall flow)
|
|
19
19
|
#
|
|
@@ -62,4 +62,5 @@
|
|
|
62
62
|
#
|
|
63
63
|
# check: string (what to validate: "response_schema", "field_present", "field_value", "status_code")
|
|
64
64
|
# path: string (JSON path to the field, e.g., "formats[0].format_id")
|
|
65
|
+
# value: any (expected value — string, number, or boolean; required when check is "field_value")
|
|
65
66
|
# description: string (human-readable description of validation)
|
|
@@ -173,6 +173,7 @@ phases:
|
|
|
173
173
|
validations:
|
|
174
174
|
- check: field_value
|
|
175
175
|
path: "signals[0].signal_id.source"
|
|
176
|
+
value: "catalog"
|
|
176
177
|
description: "Signal source is 'catalog' (verifiable via adagents.json)"
|
|
177
178
|
- check: field_present
|
|
178
179
|
path: "signals[0].signal_id.data_provider_domain"
|
|
@@ -228,6 +229,7 @@ phases:
|
|
|
228
229
|
description: "Deployment includes type"
|
|
229
230
|
- check: field_value
|
|
230
231
|
path: "deployments[0].type"
|
|
232
|
+
value: "platform"
|
|
231
233
|
description: "Deployment type is 'platform'"
|
|
232
234
|
|
|
233
235
|
- id: agent_activation
|
|
@@ -281,4 +283,5 @@ phases:
|
|
|
281
283
|
description: "Deployment includes activation key"
|
|
282
284
|
- check: field_value
|
|
283
285
|
path: "deployments[0].type"
|
|
286
|
+
value: "agent"
|
|
284
287
|
description: "Deployment type is 'agent'"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Acme Outdoor — Sample Advertiser Test Kit
|
|
2
|
+
#
|
|
3
|
+
# Provides the "ingredients" needed to test creative agent storyboards:
|
|
4
|
+
# a brand identity, sample assets at common dimensions, and sample text.
|
|
5
|
+
#
|
|
6
|
+
# Acme Outdoor is a fictional outdoor gear brand from the AdCP character bible.
|
|
7
|
+
# Use this test kit with any storyboard that requires an advertiser brand.
|
|
8
|
+
|
|
9
|
+
id: acme_outdoor
|
|
10
|
+
name: "Acme Outdoor"
|
|
11
|
+
description: "Fictional outdoor gear brand for storyboard testing"
|
|
12
|
+
|
|
13
|
+
brand:
|
|
14
|
+
house:
|
|
15
|
+
domain: "acme-outdoor.example.com"
|
|
16
|
+
name: "Acme Outdoor"
|
|
17
|
+
brand_id: "acme_outdoor"
|
|
18
|
+
names:
|
|
19
|
+
- en: "Acme Outdoor"
|
|
20
|
+
description: "Premium outdoor gear for every adventure. From trail to summit, we make gear that performs."
|
|
21
|
+
industry: "retail"
|
|
22
|
+
keller_type: "master"
|
|
23
|
+
logos:
|
|
24
|
+
- url: "https://test-assets.adcontextprotocol.org/acme-outdoor/logo-primary.png"
|
|
25
|
+
orientation: "horizontal"
|
|
26
|
+
background: "light-bg"
|
|
27
|
+
variant: "primary"
|
|
28
|
+
width: 400
|
|
29
|
+
height: 100
|
|
30
|
+
- url: "https://test-assets.adcontextprotocol.org/acme-outdoor/logo-icon.png"
|
|
31
|
+
orientation: "square"
|
|
32
|
+
background: "transparent-bg"
|
|
33
|
+
variant: "icon"
|
|
34
|
+
width: 200
|
|
35
|
+
height: 200
|
|
36
|
+
colors:
|
|
37
|
+
primary: "#1B5E20"
|
|
38
|
+
secondary: "#FF6F00"
|
|
39
|
+
accent: "#FDD835"
|
|
40
|
+
background: "#FAFAFA"
|
|
41
|
+
text: "#212121"
|
|
42
|
+
fonts:
|
|
43
|
+
heading:
|
|
44
|
+
family: "Montserrat"
|
|
45
|
+
weight: 700
|
|
46
|
+
url: "https://fonts.googleapis.com/css2?family=Montserrat:wght@700"
|
|
47
|
+
body:
|
|
48
|
+
family: "Open Sans"
|
|
49
|
+
weight: 400
|
|
50
|
+
url: "https://fonts.googleapis.com/css2?family=Open+Sans"
|
|
51
|
+
tone:
|
|
52
|
+
voice: "Confident and adventurous, but never pretentious. We talk to people who do things, not people who buy things."
|
|
53
|
+
attributes:
|
|
54
|
+
- "active"
|
|
55
|
+
- "direct"
|
|
56
|
+
- "warm"
|
|
57
|
+
dos:
|
|
58
|
+
- "Use action verbs"
|
|
59
|
+
- "Reference real outdoor activities"
|
|
60
|
+
- "Keep it short"
|
|
61
|
+
donts:
|
|
62
|
+
- "Use superlatives without evidence"
|
|
63
|
+
- "Talk down to the reader"
|
|
64
|
+
- "Use corporate jargon"
|
|
65
|
+
|
|
66
|
+
# Sample assets at common ad dimensions.
|
|
67
|
+
# These are placeholder URLs — in production, these would point to actual hosted test images.
|
|
68
|
+
assets:
|
|
69
|
+
images:
|
|
70
|
+
- id: "hero_300x250"
|
|
71
|
+
url: "https://test-assets.adcontextprotocol.org/acme-outdoor/hero-300x250.jpg"
|
|
72
|
+
width: 300
|
|
73
|
+
height: 250
|
|
74
|
+
mime_type: "image/jpeg"
|
|
75
|
+
description: "Medium rectangle hero — hiker on mountain trail"
|
|
76
|
+
|
|
77
|
+
- id: "hero_728x90"
|
|
78
|
+
url: "https://test-assets.adcontextprotocol.org/acme-outdoor/hero-728x90.jpg"
|
|
79
|
+
width: 728
|
|
80
|
+
height: 90
|
|
81
|
+
mime_type: "image/jpeg"
|
|
82
|
+
description: "Leaderboard hero — panoramic mountain vista"
|
|
83
|
+
|
|
84
|
+
- id: "hero_320x50"
|
|
85
|
+
url: "https://test-assets.adcontextprotocol.org/acme-outdoor/hero-320x50.jpg"
|
|
86
|
+
width: 320
|
|
87
|
+
height: 50
|
|
88
|
+
mime_type: "image/jpeg"
|
|
89
|
+
description: "Mobile banner hero — trail gear close-up"
|
|
90
|
+
|
|
91
|
+
- id: "hero_160x600"
|
|
92
|
+
url: "https://test-assets.adcontextprotocol.org/acme-outdoor/hero-160x600.jpg"
|
|
93
|
+
width: 160
|
|
94
|
+
height: 600
|
|
95
|
+
mime_type: "image/jpeg"
|
|
96
|
+
description: "Wide skyscraper hero — vertical trail scene"
|
|
97
|
+
|
|
98
|
+
- id: "hero_master"
|
|
99
|
+
url: "https://test-assets.adcontextprotocol.org/acme-outdoor/hero-master.jpg"
|
|
100
|
+
width: 1200
|
|
101
|
+
height: 628
|
|
102
|
+
mime_type: "image/jpeg"
|
|
103
|
+
description: "Master hero image — high-res source for any size"
|
|
104
|
+
|
|
105
|
+
text:
|
|
106
|
+
headlines:
|
|
107
|
+
- "Summer Sale — 40% Off All Gear"
|
|
108
|
+
- "Built for the Trail"
|
|
109
|
+
- "Adventure Starts Here"
|
|
110
|
+
descriptions:
|
|
111
|
+
- "Premium outdoor gear tested on the world's toughest trails. Shop the summer collection."
|
|
112
|
+
- "From daypacks to expedition tents, gear that performs when it matters."
|
|
113
|
+
cta:
|
|
114
|
+
- "Shop Now"
|
|
115
|
+
- "Explore the Collection"
|
|
116
|
+
- "Find Your Gear"
|
|
117
|
+
|
|
118
|
+
click_url: "https://acme-outdoor.example.com/summer-sale"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
id: nova_motors
|
|
2
|
+
name: "Nova Motors"
|
|
3
|
+
description: |
|
|
4
|
+
Signal-focused test kit for the Nova Motors Volta EV launch campaign.
|
|
5
|
+
Provides sample signal definitions, pricing options, and destination
|
|
6
|
+
configurations for testing signal agent storyboards.
|
|
7
|
+
|
|
8
|
+
campaign:
|
|
9
|
+
brand: "Nova Motors"
|
|
10
|
+
product: "Volta EV"
|
|
11
|
+
brief: "Reach in-market EV buyers with high purchase propensity, near dealerships, who haven't bought a Nova vehicle before."
|
|
12
|
+
budget: 250000
|
|
13
|
+
currency: "USD"
|
|
14
|
+
markets: ["US"]
|
|
15
|
+
|
|
16
|
+
signals:
|
|
17
|
+
marketplace:
|
|
18
|
+
- signal_agent_segment_id: "trident_likely_ev_buyers"
|
|
19
|
+
name: "Likely EV Buyers"
|
|
20
|
+
data_provider_domain: "tridentauto.example"
|
|
21
|
+
signal_id: "likely_ev_buyers"
|
|
22
|
+
value_type: "binary"
|
|
23
|
+
signal_type: "marketplace"
|
|
24
|
+
coverage_percentage: 8
|
|
25
|
+
pricing:
|
|
26
|
+
- pricing_option_id: "po_trident_ev_cpm"
|
|
27
|
+
model: "cpm"
|
|
28
|
+
cpm: 3.50
|
|
29
|
+
currency: "USD"
|
|
30
|
+
|
|
31
|
+
- signal_agent_segment_id: "trident_purchase_propensity"
|
|
32
|
+
name: "Purchase Propensity"
|
|
33
|
+
data_provider_domain: "tridentauto.example"
|
|
34
|
+
signal_id: "purchase_propensity"
|
|
35
|
+
value_type: "numeric"
|
|
36
|
+
signal_type: "marketplace"
|
|
37
|
+
range:
|
|
38
|
+
min: 0
|
|
39
|
+
max: 1
|
|
40
|
+
coverage_percentage: 55
|
|
41
|
+
pricing:
|
|
42
|
+
- pricing_option_id: "po_trident_propensity_cpm"
|
|
43
|
+
model: "cpm"
|
|
44
|
+
cpm: 4.00
|
|
45
|
+
currency: "USD"
|
|
46
|
+
|
|
47
|
+
- signal_agent_segment_id: "meridian_competitor_visitors"
|
|
48
|
+
name: "Competitor Visitors"
|
|
49
|
+
data_provider_domain: "meridiangeo.example"
|
|
50
|
+
signal_id: "competitor_visitors"
|
|
51
|
+
value_type: "binary"
|
|
52
|
+
signal_type: "marketplace"
|
|
53
|
+
coverage_percentage: 6
|
|
54
|
+
pricing:
|
|
55
|
+
- pricing_option_id: "po_meridian_visitors_cpm"
|
|
56
|
+
model: "cpm"
|
|
57
|
+
cpm: 5.00
|
|
58
|
+
currency: "USD"
|
|
59
|
+
|
|
60
|
+
- signal_agent_segment_id: "shopgrid_new_to_brand"
|
|
61
|
+
name: "New to Brand"
|
|
62
|
+
data_provider_domain: "shopgrid.example"
|
|
63
|
+
signal_id: "new_to_brand"
|
|
64
|
+
value_type: "binary"
|
|
65
|
+
signal_type: "marketplace"
|
|
66
|
+
coverage_percentage: 25
|
|
67
|
+
pricing:
|
|
68
|
+
- pricing_option_id: "po_shopgrid_retail_cpm"
|
|
69
|
+
model: "cpm"
|
|
70
|
+
cpm: 3.50
|
|
71
|
+
currency: "USD"
|
|
72
|
+
|
|
73
|
+
owned:
|
|
74
|
+
- signal_agent_segment_id: "prism_high_ltv"
|
|
75
|
+
name: "High LTV Customers"
|
|
76
|
+
value_type: "binary"
|
|
77
|
+
signal_type: "owned"
|
|
78
|
+
coverage_percentage: 12
|
|
79
|
+
pricing:
|
|
80
|
+
- pricing_option_id: "po_prism_flat_monthly"
|
|
81
|
+
model: "flat_fee"
|
|
82
|
+
amount: 5000
|
|
83
|
+
period: "monthly"
|
|
84
|
+
currency: "USD"
|
|
85
|
+
|
|
86
|
+
- signal_agent_segment_id: "prism_cart_abandoner"
|
|
87
|
+
name: "Cart Abandoners"
|
|
88
|
+
value_type: "binary"
|
|
89
|
+
signal_type: "owned"
|
|
90
|
+
coverage_percentage: 18
|
|
91
|
+
pricing:
|
|
92
|
+
- pricing_option_id: "po_prism_abandoner_cpm"
|
|
93
|
+
model: "cpm"
|
|
94
|
+
cpm: 8.00
|
|
95
|
+
currency: "USD"
|
|
96
|
+
|
|
97
|
+
- signal_agent_segment_id: "prism_engagement_score"
|
|
98
|
+
name: "Engagement Score"
|
|
99
|
+
value_type: "numeric"
|
|
100
|
+
signal_type: "owned"
|
|
101
|
+
range:
|
|
102
|
+
min: 0
|
|
103
|
+
max: 100
|
|
104
|
+
coverage_percentage: 65
|
|
105
|
+
pricing:
|
|
106
|
+
- pricing_option_id: "po_prism_engagement_cpm"
|
|
107
|
+
model: "cpm"
|
|
108
|
+
cpm: 2.50
|
|
109
|
+
currency: "USD"
|
|
110
|
+
|
|
111
|
+
- signal_agent_segment_id: "prism_churn_risk"
|
|
112
|
+
name: "Churn Risk"
|
|
113
|
+
value_type: "categorical"
|
|
114
|
+
signal_type: "owned"
|
|
115
|
+
categories: ["low_risk", "medium_risk", "high_risk", "churned"]
|
|
116
|
+
coverage_percentage: 70
|
|
117
|
+
pricing:
|
|
118
|
+
- pricing_option_id: "po_prism_churn_pom"
|
|
119
|
+
model: "percent_of_media"
|
|
120
|
+
percent: 12
|
|
121
|
+
max_cpm: 3.00
|
|
122
|
+
currency: "USD"
|
|
123
|
+
|
|
124
|
+
destinations:
|
|
125
|
+
platforms:
|
|
126
|
+
- type: "platform"
|
|
127
|
+
platform: "the-trade-desk"
|
|
128
|
+
account: "agency-123-ttd"
|
|
129
|
+
- type: "platform"
|
|
130
|
+
platform: "streamhaus"
|
|
131
|
+
account: "agency-ctv-seat-456"
|
|
132
|
+
agents:
|
|
133
|
+
- type: "agent"
|
|
134
|
+
agent_url: "https://wonderstruck.salesagents.example"
|