@adcp/client 4.22.0 → 4.23.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.
Files changed (73) hide show
  1. package/dist/lib/index.d.ts +2 -2
  2. package/dist/lib/index.d.ts.map +1 -1
  3. package/dist/lib/index.js.map +1 -1
  4. package/dist/lib/server/index.d.ts +1 -1
  5. package/dist/lib/server/index.d.ts.map +1 -1
  6. package/dist/lib/server/serve.d.ts +32 -4
  7. package/dist/lib/server/serve.d.ts.map +1 -1
  8. package/dist/lib/server/serve.js +12 -4
  9. package/dist/lib/server/serve.js.map +1 -1
  10. package/dist/lib/testing/compliance/comply.d.ts +22 -5
  11. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  12. package/dist/lib/testing/compliance/comply.js +242 -276
  13. package/dist/lib/testing/compliance/comply.js.map +1 -1
  14. package/dist/lib/testing/compliance/index.d.ts +1 -0
  15. package/dist/lib/testing/compliance/index.d.ts.map +1 -1
  16. package/dist/lib/testing/compliance/index.js +6 -1
  17. package/dist/lib/testing/compliance/index.js.map +1 -1
  18. package/dist/lib/testing/compliance/platform-storyboards.d.ts +44 -0
  19. package/dist/lib/testing/compliance/platform-storyboards.d.ts.map +1 -0
  20. package/dist/lib/testing/compliance/platform-storyboards.js +230 -0
  21. package/dist/lib/testing/compliance/platform-storyboards.js.map +1 -0
  22. package/dist/lib/testing/compliance/storyboard-tracks.d.ts +2 -9
  23. package/dist/lib/testing/compliance/storyboard-tracks.d.ts.map +1 -1
  24. package/dist/lib/testing/compliance/storyboard-tracks.js +4 -44
  25. package/dist/lib/testing/compliance/storyboard-tracks.js.map +1 -1
  26. package/dist/lib/testing/index.d.ts +1 -1
  27. package/dist/lib/testing/index.d.ts.map +1 -1
  28. package/dist/lib/testing/index.js +6 -1
  29. package/dist/lib/testing/index.js.map +1 -1
  30. package/dist/lib/types/core.generated.d.ts +241 -2
  31. package/dist/lib/types/core.generated.d.ts.map +1 -1
  32. package/dist/lib/types/core.generated.js +1 -1
  33. package/dist/lib/types/schemas.generated.d.ts +3380 -3154
  34. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  35. package/dist/lib/types/schemas.generated.js +220 -115
  36. package/dist/lib/types/schemas.generated.js.map +1 -1
  37. package/dist/lib/types/tools.generated.d.ts +267 -74
  38. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  39. package/dist/lib/version.d.ts +3 -3
  40. package/dist/lib/version.js +3 -3
  41. package/docs/guides/BUILD-AN-AGENT.md +5 -3
  42. package/docs/llms.txt +48 -32
  43. package/examples/signals-agent.ts +3 -2
  44. package/package.json +1 -1
  45. package/storyboards/audience_sync.yaml +18 -29
  46. package/storyboards/behavioral_analysis.yaml +40 -72
  47. package/storyboards/brand_rights.yaml +172 -75
  48. package/storyboards/campaign_governance_conditions.yaml +187 -0
  49. package/storyboards/campaign_governance_delivery.yaml +231 -0
  50. package/storyboards/campaign_governance_denied.yaml +135 -0
  51. package/storyboards/capability_discovery.yaml +106 -0
  52. package/storyboards/content_standards.yaml +251 -0
  53. package/storyboards/creative_ad_server.yaml +108 -16
  54. package/storyboards/creative_lifecycle.yaml +284 -0
  55. package/storyboards/creative_sales_agent.yaml +2 -6
  56. package/storyboards/creative_template.yaml +1 -5
  57. package/storyboards/error_compliance.yaml +105 -108
  58. package/storyboards/media_buy_catalog_creative.yaml +6 -4
  59. package/storyboards/media_buy_governance_escalation.yaml +9 -5
  60. package/storyboards/media_buy_guaranteed_approval.yaml +9 -7
  61. package/storyboards/media_buy_non_guaranteed.yaml +7 -6
  62. package/storyboards/media_buy_proposal_mode.yaml +9 -8
  63. package/storyboards/media_buy_seller.yaml +153 -165
  64. package/storyboards/media_buy_state_machine.yaml +100 -99
  65. package/storyboards/property_governance.yaml +239 -0
  66. package/storyboards/schema.yaml +2 -2
  67. package/storyboards/schema_validation.yaml +58 -51
  68. package/storyboards/si_session.yaml +99 -317
  69. package/storyboards/signal_marketplace.yaml +6 -5
  70. package/storyboards/signal_owned.yaml +5 -5
  71. package/storyboards/social_platform.yaml +274 -0
  72. package/storyboards/governance_content_standards.yaml +0 -213
  73. package/storyboards/governance_property_lists.yaml +0 -372
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP client library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "4.20.0";
4
+ export declare const LIBRARY_VERSION = "4.22.1";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -20,10 +20,10 @@ export declare const COMPATIBLE_ADCP_VERSIONS: readonly ["v2.5", "v2.6", "v3", "
20
20
  * Full version information
21
21
  */
22
22
  export declare const VERSION_INFO: {
23
- readonly library: "4.20.0";
23
+ readonly library: "4.22.1";
24
24
  readonly adcp: "latest";
25
25
  readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0-beta.1", "3.0.0-beta.3"];
26
- readonly generatedAt: "2026-04-03T18:46:26.762Z";
26
+ readonly generatedAt: "2026-04-08T19:27:19.775Z";
27
27
  };
28
28
  /**
29
29
  * Get the AdCP specification version this library is built for
@@ -10,7 +10,7 @@ exports.getCompatibleVersions = getCompatibleVersions;
10
10
  /**
11
11
  * AdCP client library version
12
12
  */
13
- exports.LIBRARY_VERSION = '4.20.0';
13
+ exports.LIBRARY_VERSION = '4.22.1';
14
14
  /**
15
15
  * AdCP specification version this library is built for
16
16
  */
@@ -29,10 +29,10 @@ exports.COMPATIBLE_ADCP_VERSIONS = ['v2.5', 'v2.6', 'v3', '3.0.0-beta.1', '3.0.0
29
29
  * Full version information
30
30
  */
31
31
  exports.VERSION_INFO = {
32
- library: '4.20.0',
32
+ library: '4.22.1',
33
33
  adcp: 'latest',
34
34
  compatibleVersions: exports.COMPATIBLE_ADCP_VERSIONS,
35
- generatedAt: '2026-04-03T18:46:26.762Z',
35
+ generatedAt: '2026-04-08T19:27:19.775Z',
36
36
  };
37
37
  /**
38
38
  * Get the AdCP specification version this library is built for
@@ -24,8 +24,8 @@ import {
24
24
  GetSignalsRequestSchema,
25
25
  } from '@adcp/client';
26
26
 
27
- function createAgent() {
28
- const server = createTaskCapableServer('My Signals Agent', '1.0.0');
27
+ function createAgent({ taskStore }) {
28
+ const server = createTaskCapableServer('My Signals Agent', '1.0.0', { taskStore });
29
29
 
30
30
  server.tool(
31
31
  'get_signals',
@@ -193,7 +193,7 @@ Key storyboards for server-side builders:
193
193
 
194
194
  ### HTTP Transport
195
195
 
196
- The `serve()` helper handles HTTP transport setup. Pass it a factory function that returns a configured `McpServer`:
196
+ The `serve()` helper handles HTTP transport setup. Pass it a factory function that receives a `ServeContext` and returns a configured `McpServer`:
197
197
 
198
198
  ```typescript
199
199
  import { serve } from '@adcp/client';
@@ -203,6 +203,8 @@ serve(createMyAgent, { port: 8080 }); // custom port
203
203
  serve(createMyAgent, { path: '/v1/mcp' }); // custom path
204
204
  ```
205
205
 
206
+ `serve()` creates a shared task store and passes it to your factory on every request via `{ taskStore }`. Pass it through to `createTaskCapableServer()` so MCP Tasks work correctly across stateless HTTP requests.
207
+
206
208
  `serve()` returns the underlying `http.Server` for lifecycle control (e.g., graceful shutdown).
207
209
 
208
210
  For custom routing or middleware, you can wire the transport manually:
package/docs/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ad Context Protocol (AdCP)
2
2
 
3
3
  > Generated at: 2026-04-08
4
- > Library: @adcp/client v4.20.0
4
+ > Library: @adcp/client v4.22.1
5
5
  > AdCP major version: 3
6
6
  > Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
7
7
 
@@ -17,8 +17,8 @@ AdCP is an open protocol for AI agents to buy, manage, and optimize advertising
17
17
  ```typescript
18
18
  import { createTaskCapableServer, taskToolResponse, serve, GetSignalsRequestSchema } from '@adcp/client';
19
19
 
20
- function createAgent() {
21
- const server = createTaskCapableServer('My Agent', '1.0.0');
20
+ function createAgent({ taskStore }) {
21
+ const server = createTaskCapableServer('My Agent', '1.0.0', { taskStore });
22
22
  server.tool('get_signals', 'Discover segments.', GetSignalsRequestSchema.shape, async (args) => {
23
23
  return taskToolResponse({ signals: [...], sandbox: true }, 'Found segments');
24
24
  });
@@ -191,7 +191,7 @@ Optional: `catalogs: object[]`, `catalog_ids: string[]`, `delete_missing: boolea
191
191
 
192
192
  Request parameters for AI-powered creative generation.
193
193
 
194
- Optional: `message: string`, `creative_manifest: Creative Manifest`, `creative_id: string`, `concept_id: string`, `media_buy_id: string`, `package_id: string`, `target_format_id: Format Id`, `target_format_ids: object[]`, +10 more
194
+ Optional: `message: string`, `creative_manifest: Creative Manifest`, `creative_id: string`, `concept_id: string`, `media_buy_id: string`, `package_id: string`, `target_format_id: Format Id`, `target_format_ids: object[]`, +11 more
195
195
 
196
196
  #### `preview_creative`
197
197
 
@@ -202,7 +202,7 @@ Request parameters for generating creative previews.
202
202
 
203
203
  Request parameters for discovering creative formats from this creative agent.
204
204
 
205
- Optional: `format_ids: object[]`, `type: 'audio' | 'video' | 'display' | 'dooh'`, `asset_types: string[]`, `max_width: integer`, `max_height: integer`, `min_width: integer`, `min_height: integer`, `is_responsive: boolean`, +8 more
205
+ Optional: `format_ids: object[]`, `type: 'audio' | 'video' | 'display' | 'dooh'`, `asset_types: string[]`, `max_width: integer`, `max_height: integer`, `min_width: integer`, `min_height: integer`, `is_responsive: boolean`, +10 more
206
206
 
207
207
  #### `get_creative_delivery`
208
208
 
@@ -214,7 +214,7 @@ Optional: `account: Account Ref`, `media_buy_ids: string[]`, `creative_ids: stri
214
214
 
215
215
  Request parameters for querying creative library with filtering and pagination.
216
216
 
217
- Optional: `filters: Creative Filters`, `sort: object`, `pagination: Pagination Request`, `include_assignments: boolean`, `include_snapshot: boolean`, `include_items: boolean`, `include_variables: boolean`, `fields: string[]`, +1 more
217
+ Optional: `filters: Creative Filters`, `sort: object`, `pagination: Pagination Request`, `include_assignments: boolean`, `include_snapshot: boolean`, `include_items: boolean`, `include_variables: boolean`, `include_pricing: boolean`, +3 more
218
218
 
219
219
  #### `sync_creatives`
220
220
 
@@ -416,26 +416,57 @@ These are the standard tool call sequences from the AdCP storyboards. Each flow
416
416
 
417
417
  ### Audiences
418
418
 
419
- **Audience sync** — Tests sync_audiences: account discovery, audience creation with hashed identifiers, and audience deletion.
419
+ **Audience sync** — Full audience lifecycle: account discovery, audience creation with hashed identifiers, and audience deletion.
420
420
  Flow: `list_accounts → sync_audiences`
421
421
 
422
+ **Social platform** — Social media platform that accepts audience segments, native creatives, and conversion events from buyer agents.
423
+ Flow: `sync_accounts → list_accounts → sync_audiences → sync_creatives → log_event → get_account_financials`
424
+
422
425
  ### Products
423
426
 
424
- **Behavioral analysis** — Validates product discovery behavior, response consistency, and pricing edge cases.
427
+ **Behavioral analysis** — Validates product discovery behavior: brief filtering, response consistency, and pricing edge cases.
425
428
  Flow: `get_products`
426
429
 
427
430
  ### Core
428
431
 
429
- **Brand rights flow** — Agent that provides brand identity, queries rights, and supports rights acquisition.
430
- Flow: `get_brand_identity → get_rights → acquire_rights`
432
+ **Brand identity and rights licensing** — Brand agent that serves identity assets and licenses rights for AI-generated content.
433
+ Flow: `get_brand_identity → get_rights → acquire_rights → update_rights → creative_approval`
434
+
435
+ **Capability discovery** — Buyer calls get_adcp_capabilities to discover what an agent supports before making any buying or creative decisions.
436
+ Flow: `get_adcp_capabilities`
431
437
 
432
438
  **Deterministic testing** — Uses comply_test_controller to force state transitions and simulate delivery/budget, verifying state machines and reporting.
433
439
  Flow: `comply_test_controller → list_accounts → comply_test_controller → create_media_buy → comply_test_controller → get_media_buys → comply_test_controller → sync_creatives → comply_test_controller → si_initiate_session → comply_test_controller → si_send_message → create_media_buy → comply_test_controller → get_media_buy_delivery → create_media_buy → comply_test_controller`
434
440
 
441
+ ### Campaign Governance
442
+
443
+ **Campaign governance — conditional approval** — Governance agent approves a media buy with conditions. Buyer re-checks after meeting the conditions.
444
+ Flow: `sync_plans → check_governance → create_media_buy`
445
+
446
+ **Campaign governance — delivery monitoring with drift detection** — Governance agent monitors delivery, detects budget drift past thresholds, and triggers re-evaluation.
447
+ Flow: `sync_plans → check_governance → get_media_buy_delivery → check_governance`
448
+
449
+ **Campaign governance — denied** — Governance agent denies a media buy that exceeds the agent's spending authority. No human escalation — the buy is blocked.
450
+ Flow: `sync_plans → check_governance`
451
+
452
+ **Governance denial and human escalation** — Buyer's governance agent denies a media buy that exceeds spending authority, escalates to a human who approves with conditions.
453
+ Flow: `sync_accounts → sync_governance → sync_plans → get_products → check_governance → create_media_buy → report_plan_outcome → get_plan_audit_logs`
454
+
455
+ ### Governance
456
+
457
+ **Content standards** — Define creative quality rules, calibrate content against them, and validate that delivered ads met the standards.
458
+ Flow: `create_content_standards → list_content_standards → get_content_standards → update_content_standards → calibrate_content → validate_content_delivery`
459
+
460
+ **Property governance** — Manage brand safety property lists — create inclusion/exclusion lists, query and update them, validate delivery compliance.
461
+ Flow: `create_property_list → list_property_lists → get_property_list → update_property_list → delete_property_list → validate_property_delivery`
462
+
435
463
  ### Creative
436
464
 
437
- **Creative ad server** — Stateful ad server with pre-loaded creatives. Generates serving tags per media buy.
438
- Flow: `list_creatives → list_creative_formats → build_creative → get_creative_delivery`
465
+ **Creative ad server** — Stateful ad server with pre-loaded creatives. Generates serving tags per media buy with pricing and billing.
466
+ Flow: `list_creatives → list_creative_formats → build_creative → get_creative_delivery → report_usage`
467
+
468
+ **Creative lifecycle** — Full creative lifecycle on a stateful platform: sync multiple creatives, list with filtering, build and preview across formats, observe status transitions.
469
+ Flow: `list_creative_formats → sync_creatives → list_creatives → preview_creative → build_creative`
439
470
 
440
471
  **Sales agent with creative capabilities** — Stateful sales agent that accepts pushed creative assets and renders them in its environment.
441
472
  Flow: `list_creative_formats → sync_creatives → preview_creative`
@@ -448,14 +479,6 @@ Flow: `list_creative_formats → preview_creative → build_creative`
448
479
  **Error handling and compliance** — Validates that agents return properly structured AdCP errors with correct codes, recovery hints, and transport bindings.
449
480
  Flow: `create_media_buy → get_products → create_media_buy`
450
481
 
451
- ### Governance
452
-
453
- **Governance content standards** — Content standards discovery, calibration, and delivery validation.
454
- Flow: `list_content_standards → get_content_standards → calibrate_content → validate_content_delivery`
455
-
456
- **Governance property list management** — CRUD lifecycle for property lists with filter round-trip validation.
457
- Flow: `create_property_list → get_property_list → update_property_list → list_property_lists → delete_property_list → get_property_list → create_property_list → get_property_list → delete_property_list`
458
-
459
482
  ### Media Buy
460
483
 
461
484
  **Catalog-driven creative and conversion tracking** — Seller that renders dynamic ads from product catalogs, tracks conversions, and optimizes delivery based on performance feedback.
@@ -470,23 +493,16 @@ Flow: `get_products → create_media_buy → get_media_buys → update_media_buy
470
493
  **Media buy via proposal acceptance** — Seller agent that generates curated media plan proposals the buyer can review, refine, and accept.
471
494
  Flow: `sync_accounts → get_products → create_media_buy → list_creative_formats → sync_creatives → get_media_buy_delivery`
472
495
 
473
- **Media buy state machine lifecycle** — Validates media buy state transitions: create, pause, resume, cancel, and terminal state enforcement.
474
- Flow: `get_products → create_media_buy → update_media_buy`
475
-
476
- ### Campaign Governance
477
-
478
- **Governance denial and human escalation** — Buyer's governance agent denies a media buy that exceeds spending authority, escalates to a human who approves with conditions.
479
- Flow: `sync_accounts → sync_governance → sync_plans → get_products → check_governance → create_media_buy → report_plan_outcome → get_plan_audit_logs`
480
-
481
- ### Reporting
482
-
483
496
  **Media buy seller agent** — Seller agent that receives briefs, returns products, accepts media buys, and reports delivery.
484
497
  Flow: `sync_accounts → sync_governance → get_products → create_media_buy → get_media_buys → list_creative_formats → sync_creatives → get_media_buy_delivery`
485
498
 
499
+ **Media buy state machine lifecycle** — Validates media buy state transitions: create, pause, resume, cancel, and terminal state enforcement.
500
+ Flow: `get_products → create_media_buy → update_media_buy`
501
+
486
502
  ### Sponsored Intelligence (SI)
487
503
 
488
- **Sponsored intelligence session** — SI agent that serves offerings, manages conversational sessions, and handles purchase handoffs.
489
- Flow: `si_get_offering → si_initiate_session → si_send_message → si_terminate_session → si_send_message → si_initiate_session → si_send_message → si_terminate_session`
504
+ **Sponsored intelligence session** — Conversational ad session on an AI platform — discover offerings, initiate a session, exchange messages, and terminate.
505
+ Flow: `si_get_offering → si_initiate_session → si_send_message → si_terminate_session`
490
506
 
491
507
  ### Signals
492
508
 
@@ -18,7 +18,7 @@
18
18
  */
19
19
 
20
20
  import { createTaskCapableServer, taskToolResponse, serve, GetSignalsRequestSchema } from '@adcp/client';
21
- import type { GetSignalsResponse } from '@adcp/client';
21
+ import type { GetSignalsResponse, ServeContext } from '@adcp/client';
22
22
 
23
23
  // ---------------------------------------------------------------------------
24
24
  // Audience segment catalog — typed to match the AdCP signals response schema
@@ -132,8 +132,9 @@ function querySegments(args: {
132
132
  // ---------------------------------------------------------------------------
133
133
  // Server factory
134
134
  // ---------------------------------------------------------------------------
135
- function createSignalsAgent() {
135
+ function createSignalsAgent({ taskStore }: ServeContext) {
136
136
  const server = createTaskCapableServer('Example Signals Agent', '1.0.0', {
137
+ taskStore,
137
138
  instructions: 'Signals agent providing audience segment discovery via get_signals.',
138
139
  });
139
140
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/client",
3
- "version": "4.22.0",
3
+ "version": "4.23.0",
4
4
  "description": "AdCP client library with protocol support for MCP and A2A",
5
5
  "main": "dist/lib/index.js",
6
6
  "types": "dist/lib/index.d.ts",
@@ -1,8 +1,8 @@
1
1
  id: audience_sync
2
2
  version: "1.0.0"
3
3
  title: "Audience sync"
4
- category: audiences
5
- summary: "Tests sync_audiences: account discovery, audience creation with hashed identifiers, and audience deletion."
4
+ category: audience_sync
5
+ summary: "Full audience lifecycle: account discovery, audience creation with hashed identifiers, and audience deletion."
6
6
  track: audiences
7
7
  required_tools:
8
8
  - sync_audiences
@@ -10,6 +10,7 @@ platform_types:
10
10
  - display_ad_server
11
11
  - social_platform
12
12
  - retail_media
13
+ - audio_platform
13
14
  - dsp
14
15
  - pmax_platform
15
16
 
@@ -53,20 +54,14 @@ phases:
53
54
  - id: discover_account
54
55
  title: "Discover or create account"
55
56
  narrative: |
56
- List existing accounts to find one suitable for audience sync. If no accounts
57
- exist, sync_accounts creates one. The account_id is captured for use in
57
+ List existing accounts to find one suitable for audience sync. The account
58
+ must already exist and be active. The account_id is captured for use in
58
59
  subsequent audience operations.
59
60
  task: list_accounts
60
61
  schema_ref: "account/list-accounts-request.json"
61
62
  response_schema_ref: "account/list-accounts-response.json"
62
63
  doc_ref: "/accounts/tasks/list_accounts"
63
- comply_scenario: account_setup
64
64
  stateful: false
65
- context_outputs:
66
- - name: account_id
67
- path: "accounts[0].account_id"
68
- - name: account_ref
69
- path: "accounts[0]"
70
65
  expected: |
71
66
  Return at least one account with:
72
67
  - account_id: platform-assigned identifier
@@ -98,14 +93,11 @@ phases:
98
93
  already exist on the platform for this account. This is a read-only
99
94
  discovery call.
100
95
  task: sync_audiences
101
- schema_ref: "audience/sync-audiences-request.json"
102
- response_schema_ref: "audience/sync-audiences-response.json"
103
- doc_ref: "/audiences/tasks/sync_audiences"
104
- comply_scenario: audience_sync
96
+ schema_ref: "media-buy/sync-audiences-request.json"
97
+ response_schema_ref: "media-buy/sync-audiences-response.json"
98
+ doc_ref: "/media-buy/task-reference/sync_audiences"
99
+ comply_scenario: sync_audiences
105
100
  stateful: false
106
- context_outputs:
107
- - name: existing_audience_count
108
- path: "audiences.length"
109
101
  expected: |
110
102
  Return existing audiences for the account (may be empty).
111
103
  Each audience should have an audience_id and status.
@@ -127,14 +119,11 @@ phases:
127
119
  matches identifiers against their user graph and returns the audience with
128
120
  action: created, match counts, and match rate.
129
121
  task: sync_audiences
130
- schema_ref: "audience/sync-audiences-request.json"
131
- response_schema_ref: "audience/sync-audiences-response.json"
132
- doc_ref: "/audiences/tasks/sync_audiences"
133
- comply_scenario: audience_sync
122
+ schema_ref: "media-buy/sync-audiences-request.json"
123
+ response_schema_ref: "media-buy/sync-audiences-response.json"
124
+ doc_ref: "/media-buy/task-reference/sync_audiences"
125
+ comply_scenario: sync_audiences
134
126
  stateful: true
135
- context_outputs:
136
- - name: test_audience_id
137
- path: "audiences[0].audience_id"
138
127
  expected: |
139
128
  Accept the audience and return:
140
129
  - audience_id: matches the submitted ID
@@ -151,7 +140,7 @@ phases:
151
140
  operator: "pinnacle-agency.com"
152
141
  audiences:
153
142
  - audience_id: "adcp-test-audience-001"
154
- name: "AdCP E2E Test Audience"
143
+ name: "AdCP test audience"
155
144
  add:
156
145
  - hashed_email: "a000000000000000000000000000000000000000000000000000000000000000"
157
146
  - hashed_phone: "b000000000000000000000000000000000000000000000000000000000000000"
@@ -172,10 +161,10 @@ phases:
172
161
  Clean up by deleting the test audience. The seller should acknowledge the
173
162
  deletion with action: deleted.
174
163
  task: sync_audiences
175
- schema_ref: "audience/sync-audiences-request.json"
176
- response_schema_ref: "audience/sync-audiences-response.json"
177
- doc_ref: "/audiences/tasks/sync_audiences"
178
- comply_scenario: audience_sync
164
+ schema_ref: "media-buy/sync-audiences-request.json"
165
+ response_schema_ref: "media-buy/sync-audiences-response.json"
166
+ doc_ref: "/media-buy/task-reference/sync_audiences"
167
+ comply_scenario: sync_audiences
179
168
  stateful: true
180
169
  expected: |
181
170
  Delete the test audience and return:
@@ -1,8 +1,8 @@
1
1
  id: behavioral_analysis
2
2
  version: "1.0.0"
3
3
  title: "Behavioral analysis"
4
- category: products
5
- summary: "Validates product discovery behavior, response consistency, and pricing edge cases."
4
+ category: behavioral_analysis
5
+ summary: "Validates product discovery behavior: brief filtering, response consistency, and pricing edge cases."
6
6
  track: products
7
7
  required_tools:
8
8
  - get_products
@@ -13,7 +13,6 @@ platform_types:
13
13
  - retail_media
14
14
  - search_platform
15
15
  - audio_platform
16
- - linear_tv_platform
17
16
  - dsp
18
17
  - pmax_platform
19
18
  - ai_ad_network
@@ -54,7 +53,7 @@ prerequisites:
54
53
 
55
54
  phases:
56
55
  - id: behavior_analysis
57
- title: "Behavior analysis"
56
+ title: "Brief filtering behavior"
58
57
  narrative: |
59
58
  Tests whether the agent filters products based on the brief content. Two different
60
59
  briefs are sent — one narrow (podcast audio only) and one broad (all products across
@@ -73,18 +72,13 @@ phases:
73
72
  doc_ref: "/media-buy/task-reference/get_products"
74
73
  comply_scenario: behavior_analysis
75
74
  stateful: false
76
- context_outputs:
77
- - name: narrow_product_ids
78
- path: "products[*].product_id"
79
- - name: narrow_product_count
80
- path: "products.length"
81
75
  expected: |
82
- Return products matching the narrow brief. The result set should be scoped
83
- to audio/podcast inventory if the agent performs brief filtering.
76
+ Return products matching the narrow brief. If the agent interprets briefs,
77
+ this should return fewer products than a broad request.
84
78
 
85
79
  sample_request:
86
80
  buying_mode: "brief"
87
- brief: "Looking specifically for podcast audio advertising only"
81
+ brief: "Podcast audio advertising only 30-second pre-roll spots"
88
82
  brand:
89
83
  domain: "acmeoutdoor.com"
90
84
 
@@ -98,9 +92,9 @@ phases:
98
92
  - id: get_products_broad
99
93
  title: "Get products with broad brief"
100
94
  narrative: |
101
- Send a broad brief requesting all products across all channels. Compare the
102
- result count against the narrow brief to determine whether the agent filters
103
- by brief content.
95
+ Send a broad brief requesting all available products. Compare the result count
96
+ with the narrow brief if the agent filters by brief, the broad request should
97
+ return more products.
104
98
  task: get_products
105
99
  schema_ref: "media-buy/get-products-request.json"
106
100
  response_schema_ref: "media-buy/get-products-response.json"
@@ -108,69 +102,56 @@ phases:
108
102
  comply_scenario: behavior_analysis
109
103
  stateful: false
110
104
  expected: |
111
- Return all available products. If the agent performs brief filtering, this
112
- response should contain more products than the narrow brief response.
105
+ Return all available products. The product count should be greater than or
106
+ equal to the narrow brief response.
113
107
 
114
108
  sample_request:
115
109
  buying_mode: "brief"
116
- brief: "Show all products across all channels and formats"
110
+ brief: "Show me everything all channels, all formats, all inventory"
117
111
  brand:
118
112
  domain: "acmeoutdoor.com"
119
113
 
120
114
  validations:
121
115
  - check: response_schema
122
116
  description: "Response matches get-products-response.json schema"
123
- - check: field_present
124
- path: "products"
125
- description: "Response contains a products array"
126
- - check: compare_context
127
- description: "Broad brief returns >= narrow brief product count"
128
- context_ref: narrow_product_count
129
- comparison: ">="
130
117
 
131
118
  - id: response_consistency
132
119
  title: "Response consistency"
133
120
  narrative: |
134
- Calls get_products twice with the identical brief and brand. The agent should
135
- return the same product IDs both times. Non-deterministic responses indicate
136
- randomness in product selection or caching issues.
121
+ Tests whether the agent returns deterministic results for identical inputs.
122
+ The same brief is sent twice — the response should contain the same product IDs
123
+ in both cases.
137
124
 
138
125
  steps:
139
126
  - id: get_products_first
140
- title: "First call with fixed brief"
127
+ title: "First request with identical brief"
141
128
  narrative: |
142
- Send a specific brief and capture the returned product IDs for comparison.
129
+ Send a brief and capture the product IDs returned.
143
130
  task: get_products
144
131
  schema_ref: "media-buy/get-products-request.json"
145
132
  response_schema_ref: "media-buy/get-products-response.json"
146
133
  doc_ref: "/media-buy/task-reference/get_products"
147
134
  comply_scenario: response_consistency
148
135
  stateful: false
149
- context_outputs:
150
- - name: first_call_product_ids
151
- path: "products[*].product_id"
152
136
  expected: |
153
- Return products matching the brief. Product IDs are captured for comparison
154
- with a second identical call.
137
+ Return products matching the brief. Product IDs will be compared with a
138
+ subsequent identical request.
155
139
 
156
140
  sample_request:
157
141
  buying_mode: "brief"
158
- brief: "Premium video inventory on sports and outdoor lifestyle publishers. Q2 flight, $50K budget. Adults 25-54, US and Canada."
142
+ brief: "Premium video inventory on sports publishers. Adults 25-54."
159
143
  brand:
160
144
  domain: "acmeoutdoor.com"
161
145
 
162
146
  validations:
163
147
  - check: response_schema
164
148
  description: "Response matches get-products-response.json schema"
165
- - check: field_present
166
- path: "products[0].product_id"
167
- description: "At least one product returned with a product_id"
168
149
 
169
150
  - id: get_products_second
170
- title: "Second call with identical brief"
151
+ title: "Second request with identical brief"
171
152
  narrative: |
172
- Repeat the exact same request. The returned product IDs should match
173
- those from the first call.
153
+ Send the exact same brief again. The returned product IDs should match the
154
+ first response.
174
155
  task: get_products
175
156
  schema_ref: "media-buy/get-products-request.json"
176
157
  response_schema_ref: "media-buy/get-products-response.json"
@@ -178,37 +159,31 @@ phases:
178
159
  comply_scenario: response_consistency
179
160
  stateful: false
180
161
  expected: |
181
- Return the same product IDs as the first call. Consistent responses
182
- for identical inputs are expected.
162
+ Return the same product IDs as the first request. Deterministic responses
163
+ are expected for identical inputs.
183
164
 
184
165
  sample_request:
185
166
  buying_mode: "brief"
186
- brief: "Premium video inventory on sports and outdoor lifestyle publishers. Q2 flight, $50K budget. Adults 25-54, US and Canada."
167
+ brief: "Premium video inventory on sports publishers. Adults 25-54."
187
168
  brand:
188
169
  domain: "acmeoutdoor.com"
189
170
 
190
171
  validations:
191
172
  - check: response_schema
192
173
  description: "Response matches get-products-response.json schema"
193
- - check: match_context
194
- description: "Product IDs match the first call"
195
- context_ref: first_call_product_ids
196
- path: "products[*].product_id"
197
174
 
198
175
  - id: pricing_edge_cases
199
- title: "Pricing edge cases"
176
+ title: "Pricing structure validation"
200
177
  narrative: |
201
- Validates the structure of pricing_options on returned products. Each product
202
- should declare a delivery_type (guaranteed or non_guaranteed) and well-formed
203
- pricing options with recognized fields.
178
+ Validates that products declare well-formed pricing_options with recognized
179
+ delivery_type values and complete pricing structures.
204
180
 
205
181
  steps:
206
182
  - id: get_products_pricing
207
- title: "Fetch products for pricing analysis"
183
+ title: "Validate pricing structures"
208
184
  narrative: |
209
- Request all products with pricing details. Validate that each product has
210
- a valid delivery_type and that pricing_options contain recognized fields
211
- (fixed_price, floor_price, price_guidance, min_spend_per_package).
185
+ Send a brief and inspect the pricing structures on returned products.
186
+ Every product must have a recognized delivery_type and valid pricing_options.
212
187
  task: get_products
213
188
  schema_ref: "media-buy/get-products-request.json"
214
189
  response_schema_ref: "media-buy/get-products-response.json"
@@ -216,29 +191,22 @@ phases:
216
191
  comply_scenario: pricing_edge_cases
217
192
  stateful: false
218
193
  expected: |
219
- Return products with well-formed pricing structures:
220
- - Each product has a delivery_type: guaranteed or non_guaranteed
221
- - Each pricing_option has a pricing_option_id
222
- - Pricing fields are valid (no negative values, recognized pricing models)
194
+ Products with valid pricing structures:
195
+ - delivery_type: "guaranteed" or "non_guaranteed"
196
+ - pricing_options with pricing_option_id and pricing_model
223
197
 
224
198
  sample_request:
225
199
  buying_mode: "brief"
226
- brief: "Show all products with pricing details"
200
+ brief: "All available products with detailed pricing"
227
201
  brand:
228
202
  domain: "acmeoutdoor.com"
229
203
 
230
204
  validations:
231
205
  - check: response_schema
232
206
  description: "Response matches get-products-response.json schema"
233
- - check: field_present
234
- path: "products"
235
- description: "Response contains products array"
236
207
  - check: field_present
237
208
  path: "products[0].delivery_type"
238
- description: "Each product declares guaranteed or non_guaranteed delivery"
239
- - check: field_value
240
- path: "products[*].delivery_type"
241
- allowed_values:
242
- - "guaranteed"
243
- - "non_guaranteed"
244
- description: "delivery_type is a recognized value"
209
+ description: "Products declare delivery_type"
210
+ - check: field_present
211
+ path: "products[0].pricing_options"
212
+ description: "Products include pricing_options"