adcp 2.18.0__py3-none-any.whl → 3.0.0__py3-none-any.whl
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.
- adcp/ADCP_VERSION +1 -1
- adcp/__init__.py +6 -14
- adcp/__main__.py +94 -51
- adcp/adagents.py +91 -19
- adcp/client.py +865 -0
- adcp/protocols/a2a.py +84 -0
- adcp/protocols/base.py +101 -0
- adcp/protocols/mcp.py +87 -1
- adcp/server/__init__.py +49 -0
- adcp/server/base.py +368 -0
- adcp/server/content_standards.py +561 -0
- adcp/server/governance.py +491 -0
- adcp/server/mcp_tools.py +471 -0
- adcp/server/proposal.py +334 -0
- adcp/server/sponsored_intelligence.py +444 -0
- adcp/types/__init__.py +111 -23
- adcp/types/_ergonomic.py +35 -18
- adcp/types/_generated.py +419 -44
- adcp/types/aliases.py +13 -20
- adcp/types/base.py +1 -1
- adcp/types/generated_poc/adagents.py +103 -6
- adcp/types/generated_poc/content_standards/__init__.py +3 -0
- adcp/types/generated_poc/content_standards/artifact.py +208 -0
- adcp/types/generated_poc/content_standards/artifact_webhook_payload.py +64 -0
- adcp/types/generated_poc/content_standards/calibrate_content_request.py +17 -0
- adcp/types/generated_poc/content_standards/calibrate_content_response.py +74 -0
- adcp/types/generated_poc/content_standards/content_standards.py +66 -0
- adcp/types/generated_poc/content_standards/create_content_standards_request.py +97 -0
- adcp/types/generated_poc/content_standards/create_content_standards_response.py +52 -0
- adcp/types/generated_poc/content_standards/get_content_standards_request.py +21 -0
- adcp/types/generated_poc/content_standards/get_content_standards_response.py +43 -0
- adcp/types/generated_poc/content_standards/get_media_buy_artifacts_request.py +64 -0
- adcp/types/generated_poc/content_standards/get_media_buy_artifacts_response.py +117 -0
- adcp/types/generated_poc/content_standards/list_content_standards_request.py +31 -0
- adcp/types/generated_poc/content_standards/list_content_standards_response.py +48 -0
- adcp/types/generated_poc/content_standards/update_content_standards_request.py +101 -0
- adcp/types/generated_poc/content_standards/update_content_standards_response.py +34 -0
- adcp/types/generated_poc/content_standards/validate_content_delivery_request.py +59 -0
- adcp/types/generated_poc/content_standards/validate_content_delivery_response.py +85 -0
- adcp/types/generated_poc/core/activation_key.py +1 -1
- adcp/types/generated_poc/core/assets/audio_asset.py +1 -1
- adcp/types/generated_poc/core/assets/css_asset.py +1 -1
- adcp/types/generated_poc/core/assets/daast_asset.py +1 -1
- adcp/types/generated_poc/core/assets/html_asset.py +1 -1
- adcp/types/generated_poc/core/assets/image_asset.py +1 -1
- adcp/types/generated_poc/core/assets/javascript_asset.py +1 -1
- adcp/types/generated_poc/core/assets/text_asset.py +1 -1
- adcp/types/generated_poc/core/assets/url_asset.py +1 -1
- adcp/types/generated_poc/core/assets/vast_asset.py +1 -1
- adcp/types/generated_poc/core/assets/video_asset.py +1 -1
- adcp/types/generated_poc/core/assets/webhook_asset.py +1 -1
- adcp/types/generated_poc/core/async_response_data.py +1 -1
- adcp/types/generated_poc/core/brand_manifest.py +68 -5
- adcp/types/generated_poc/core/brand_manifest_ref.py +1 -1
- adcp/types/generated_poc/core/context.py +1 -1
- adcp/types/generated_poc/core/creative_asset.py +8 -7
- adcp/types/generated_poc/core/creative_assignment.py +1 -1
- adcp/types/generated_poc/core/creative_filters.py +4 -14
- adcp/types/generated_poc/core/creative_manifest.py +1 -1
- adcp/types/generated_poc/core/creative_policy.py +1 -1
- adcp/types/generated_poc/core/delivery_metrics.py +1 -1
- adcp/types/generated_poc/core/deployment.py +1 -1
- adcp/types/generated_poc/core/destination.py +1 -1
- adcp/types/generated_poc/core/error.py +1 -1
- adcp/types/generated_poc/core/ext.py +1 -1
- adcp/types/generated_poc/core/format.py +6 -5
- adcp/types/generated_poc/core/format_id.py +1 -1
- adcp/types/generated_poc/core/frequency_cap.py +1 -1
- adcp/types/generated_poc/core/identifier.py +27 -0
- adcp/types/generated_poc/core/mcp_webhook_payload.py +1 -1
- adcp/types/generated_poc/core/measurement.py +1 -1
- adcp/types/generated_poc/core/media_buy.py +1 -1
- adcp/types/generated_poc/core/media_buy_features.py +29 -0
- adcp/types/generated_poc/core/offering.py +80 -0
- adcp/types/generated_poc/core/package.py +1 -1
- adcp/types/generated_poc/core/performance_feedback.py +1 -1
- adcp/types/generated_poc/core/placement.py +1 -1
- adcp/types/generated_poc/core/pricing_option.py +8 -14
- adcp/types/generated_poc/core/product.py +1 -1
- adcp/types/generated_poc/core/product_allocation.py +48 -0
- adcp/types/generated_poc/core/product_filters.py +72 -7
- adcp/types/generated_poc/core/promoted_offerings.py +12 -21
- adcp/types/generated_poc/core/promoted_products.py +1 -1
- adcp/types/generated_poc/core/property.py +1 -1
- adcp/types/generated_poc/core/property_id.py +1 -1
- adcp/types/generated_poc/core/property_list_ref.py +26 -0
- adcp/types/generated_poc/core/property_tag.py +1 -1
- adcp/types/generated_poc/core/proposal.py +64 -0
- adcp/types/generated_poc/core/protocol_envelope.py +1 -1
- adcp/types/generated_poc/core/publisher_property_selector.py +1 -1
- adcp/types/generated_poc/core/push_notification_config.py +1 -1
- adcp/types/generated_poc/core/reporting_capabilities.py +1 -1
- adcp/types/generated_poc/core/reporting_webhook.py +70 -0
- adcp/types/generated_poc/core/response.py +1 -1
- adcp/types/generated_poc/core/signal_filters.py +1 -1
- adcp/types/generated_poc/core/start_timing.py +4 -4
- adcp/types/generated_poc/core/sub_asset.py +1 -1
- adcp/types/generated_poc/core/targeting.py +55 -14
- adcp/types/generated_poc/creative/list_creative_formats_request.py +1 -1
- adcp/types/generated_poc/creative/list_creative_formats_response.py +1 -1
- adcp/types/generated_poc/creative/preview_creative_request.py +1 -1
- adcp/types/generated_poc/creative/preview_creative_response.py +3 -2
- adcp/types/generated_poc/creative/preview_render.py +1 -1
- adcp/types/generated_poc/enums/adcp_domain.py +3 -1
- adcp/types/generated_poc/enums/asset_content_type.py +1 -1
- adcp/types/generated_poc/enums/auth_scheme.py +1 -1
- adcp/types/generated_poc/enums/available_metric.py +1 -1
- adcp/types/generated_poc/enums/channels.py +18 -8
- adcp/types/generated_poc/enums/co_branding_requirement.py +1 -1
- adcp/types/generated_poc/enums/creative_action.py +1 -1
- adcp/types/generated_poc/enums/creative_agent_capability.py +1 -1
- adcp/types/generated_poc/enums/creative_sort_field.py +1 -1
- adcp/types/generated_poc/enums/creative_status.py +2 -1
- adcp/types/generated_poc/enums/daast_tracking_event.py +1 -1
- adcp/types/generated_poc/enums/daast_version.py +1 -1
- adcp/types/generated_poc/enums/delivery_type.py +1 -1
- adcp/types/generated_poc/enums/dimension_unit.py +1 -1
- adcp/types/generated_poc/enums/feed_format.py +1 -1
- adcp/types/generated_poc/enums/feedback_source.py +1 -1
- adcp/types/generated_poc/enums/format_category.py +1 -1
- adcp/types/generated_poc/enums/format_id_parameter.py +1 -1
- adcp/types/generated_poc/enums/frequency_cap_scope.py +1 -1
- adcp/types/generated_poc/enums/geo_level.py +14 -0
- adcp/types/generated_poc/enums/history_entry_type.py +1 -1
- adcp/types/generated_poc/enums/http_method.py +1 -1
- adcp/types/generated_poc/enums/identifier_types.py +1 -1
- adcp/types/generated_poc/enums/javascript_module_type.py +1 -1
- adcp/types/generated_poc/enums/landing_page_requirement.py +1 -1
- adcp/types/generated_poc/enums/markdown_flavor.py +1 -1
- adcp/types/generated_poc/enums/media_buy_status.py +1 -1
- adcp/types/generated_poc/enums/metric_type.py +1 -1
- adcp/types/generated_poc/enums/metro_system.py +15 -0
- adcp/types/generated_poc/enums/notification_type.py +1 -1
- adcp/types/generated_poc/enums/pacing.py +1 -1
- adcp/types/generated_poc/enums/postal_system.py +19 -0
- adcp/types/generated_poc/enums/preview_output_format.py +1 -1
- adcp/types/generated_poc/enums/pricing_model.py +1 -1
- adcp/types/generated_poc/enums/property_type.py +2 -1
- adcp/types/generated_poc/enums/publisher_identifier_types.py +1 -1
- adcp/types/generated_poc/enums/reporting_frequency.py +1 -1
- adcp/types/generated_poc/enums/signal_catalog_type.py +1 -1
- adcp/types/generated_poc/enums/sort_direction.py +1 -1
- adcp/types/generated_poc/enums/task_status.py +1 -1
- adcp/types/generated_poc/enums/task_type.py +7 -1
- adcp/types/generated_poc/enums/update_frequency.py +1 -1
- adcp/types/generated_poc/enums/url_asset_type.py +1 -1
- adcp/types/generated_poc/enums/validation_mode.py +1 -1
- adcp/types/generated_poc/enums/vast_tracking_event.py +1 -1
- adcp/types/generated_poc/enums/vast_version.py +1 -1
- adcp/types/generated_poc/enums/webhook_response_type.py +1 -1
- adcp/types/generated_poc/enums/webhook_security_method.py +1 -1
- adcp/types/generated_poc/extensions/__init__.py +3 -0
- adcp/types/generated_poc/extensions/extension_meta.py +58 -0
- adcp/types/generated_poc/media_buy/build_creative_request.py +1 -1
- adcp/types/generated_poc/media_buy/build_creative_response.py +1 -1
- adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py +1 -1
- adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py +1 -1
- adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py +1 -1
- adcp/types/generated_poc/media_buy/create_media_buy_request.py +54 -26
- adcp/types/generated_poc/media_buy/create_media_buy_response.py +1 -1
- adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py +1 -1
- adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py +1 -1
- adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py +1 -1
- adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py +1 -1
- adcp/types/generated_poc/media_buy/get_products_async_response_working.py +1 -1
- adcp/types/generated_poc/media_buy/get_products_request.py +18 -3
- adcp/types/generated_poc/media_buy/get_products_response.py +14 -2
- adcp/types/generated_poc/media_buy/list_authorized_properties_request.py +1 -1
- adcp/types/generated_poc/media_buy/list_authorized_properties_response.py +2 -2
- adcp/types/generated_poc/media_buy/list_creative_formats_request.py +1 -1
- adcp/types/generated_poc/media_buy/list_creative_formats_response.py +1 -1
- adcp/types/generated_poc/media_buy/list_creatives_request.py +2 -2
- adcp/types/generated_poc/media_buy/list_creatives_response.py +7 -10
- adcp/types/generated_poc/media_buy/package_request.py +15 -6
- adcp/types/generated_poc/media_buy/package_update.py +119 -0
- adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py +1 -1
- adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py +1 -1
- adcp/types/generated_poc/media_buy/sync_creatives_async_response_input_required.py +1 -1
- adcp/types/generated_poc/media_buy/sync_creatives_async_response_submitted.py +1 -1
- adcp/types/generated_poc/media_buy/sync_creatives_async_response_working.py +1 -1
- adcp/types/generated_poc/media_buy/sync_creatives_request.py +1 -1
- adcp/types/generated_poc/media_buy/sync_creatives_response.py +1 -1
- adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py +1 -1
- adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py +1 -1
- adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py +1 -1
- adcp/types/generated_poc/media_buy/update_media_buy_request.py +20 -108
- adcp/types/generated_poc/media_buy/update_media_buy_response.py +1 -1
- adcp/types/generated_poc/pricing_options/cpc_option.py +35 -10
- adcp/types/generated_poc/pricing_options/cpcv_option.py +35 -10
- adcp/types/generated_poc/pricing_options/{cpm_auction_option.py → cpm_option.py} +23 -19
- adcp/types/generated_poc/pricing_options/cpp_option.py +39 -16
- adcp/types/generated_poc/pricing_options/cpv_option.py +37 -18
- adcp/types/generated_poc/pricing_options/flat_rate_option.py +45 -39
- adcp/types/generated_poc/pricing_options/{vcpm_auction_option.py → vcpm_option.py} +23 -14
- adcp/types/generated_poc/property/__init__.py +3 -0
- adcp/types/generated_poc/property/base_property_source.py +86 -0
- adcp/types/generated_poc/property/create_property_list_request.py +43 -0
- adcp/types/generated_poc/property/create_property_list_response.py +27 -0
- adcp/types/generated_poc/property/delete_property_list_request.py +22 -0
- adcp/types/generated_poc/property/delete_property_list_response.py +21 -0
- adcp/types/generated_poc/property/feature_requirement.py +42 -0
- adcp/types/generated_poc/property/get_property_list_request.py +34 -0
- adcp/types/generated_poc/property/get_property_list_response.py +61 -0
- adcp/types/generated_poc/property/list_property_lists_request.py +29 -0
- adcp/types/generated_poc/property/list_property_lists_response.py +39 -0
- adcp/types/generated_poc/property/property_error.py +33 -0
- adcp/types/generated_poc/property/property_feature.py +22 -0
- adcp/types/generated_poc/property/property_feature_definition.py +80 -0
- adcp/types/generated_poc/property/property_list.py +62 -0
- adcp/types/generated_poc/property/property_list_changed_webhook.py +51 -0
- adcp/types/generated_poc/property/property_list_filters.py +47 -0
- adcp/types/generated_poc/property/update_property_list_request.py +46 -0
- adcp/types/generated_poc/property/update_property_list_response.py +21 -0
- adcp/types/generated_poc/protocol/__init__.py +3 -0
- adcp/types/generated_poc/protocol/get_adcp_capabilities_request.py +34 -0
- adcp/types/generated_poc/protocol/get_adcp_capabilities_response.py +353 -0
- adcp/types/generated_poc/protocols/adcp_extension.py +18 -5
- adcp/types/generated_poc/signals/activate_signal_request.py +1 -1
- adcp/types/generated_poc/signals/activate_signal_response.py +1 -1
- adcp/types/generated_poc/signals/get_signals_request.py +1 -1
- adcp/types/generated_poc/signals/get_signals_response.py +1 -1
- adcp/types/generated_poc/sponsored_intelligence/__init__.py +3 -0
- adcp/types/generated_poc/sponsored_intelligence/si_capabilities.py +102 -0
- adcp/types/generated_poc/sponsored_intelligence/si_get_offering_request.py +34 -0
- adcp/types/generated_poc/sponsored_intelligence/si_get_offering_response.py +100 -0
- adcp/types/generated_poc/sponsored_intelligence/si_identity.py +78 -0
- adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_request.py +46 -0
- adcp/types/generated_poc/sponsored_intelligence/si_initiate_session_response.py +44 -0
- adcp/types/generated_poc/sponsored_intelligence/si_send_message_request.py +58 -0
- adcp/types/generated_poc/sponsored_intelligence/si_send_message_response.py +101 -0
- adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_request.py +60 -0
- adcp/types/generated_poc/sponsored_intelligence/si_terminate_session_response.py +54 -0
- adcp/types/generated_poc/sponsored_intelligence/si_ui_element.py +30 -0
- adcp/utils/format_assets.py +5 -5
- adcp/utils/preview_cache.py +2 -2
- {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/METADATA +1 -1
- adcp-3.0.0.dist-info/RECORD +264 -0
- {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/WHEEL +1 -1
- adcp/types/generated_poc/enums/standard_format_ids.py +0 -45
- adcp/types/generated_poc/pricing_options/cpm_fixed_option.py +0 -43
- adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py +0 -47
- adcp-2.18.0.dist-info/RECORD +0 -195
- {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/entry_points.txt +0 -0
- {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/licenses/LICENSE +0 -0
- {adcp-2.18.0.dist-info → adcp-3.0.0.dist-info}/top_level.txt +0 -0
adcp/types/aliases.py
CHANGED
|
@@ -35,9 +35,6 @@ from adcp.types._generated import (
|
|
|
35
35
|
# Activation responses
|
|
36
36
|
ActivateSignalResponse1,
|
|
37
37
|
ActivateSignalResponse2,
|
|
38
|
-
# Activation keys
|
|
39
|
-
ActivationKey1,
|
|
40
|
-
ActivationKey2,
|
|
41
38
|
# Authorized agents
|
|
42
39
|
AuthorizedAgents,
|
|
43
40
|
AuthorizedAgents1,
|
|
@@ -64,10 +61,10 @@ from adcp.types._generated import (
|
|
|
64
61
|
# Preview creative responses
|
|
65
62
|
PreviewCreativeResponse1,
|
|
66
63
|
PreviewCreativeResponse2,
|
|
67
|
-
# Preview renders
|
|
68
|
-
PreviewRender1,
|
|
69
|
-
PreviewRender2,
|
|
70
|
-
PreviewRender3,
|
|
64
|
+
# Preview renders (discriminated union by output_format)
|
|
65
|
+
PreviewRender1, # output_format='url'
|
|
66
|
+
PreviewRender2, # output_format='html'
|
|
67
|
+
PreviewRender3, # output_format='both'
|
|
71
68
|
# Publisher properties types
|
|
72
69
|
PropertyId,
|
|
73
70
|
PropertyTag,
|
|
@@ -198,12 +195,11 @@ UpdateMediaBuyPropertiesRequest = UpdateMediaBuyRequest2
|
|
|
198
195
|
# ============================================================================
|
|
199
196
|
# ACTIVATION KEY ALIASES
|
|
200
197
|
# ============================================================================
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
"""Activation key using property_tags for identification."""
|
|
198
|
+
# Note: Activation key schema changed from property_id/property_tag variants
|
|
199
|
+
# to segment_id/key_value variants. Import directly from _generated:
|
|
200
|
+
# from adcp.types._generated import ActivationKey1 as SegmentIdActivationKey
|
|
201
|
+
# from adcp.types._generated import ActivationKey2 as KeyValueActivationKey
|
|
202
|
+
# These will be added once the types are regenerated with proper schema.
|
|
207
203
|
|
|
208
204
|
# ============================================================================
|
|
209
205
|
# PREVIEW/RENDER TYPE ALIASES
|
|
@@ -216,15 +212,15 @@ PreviewCreativeStaticResponse = PreviewCreativeResponse1
|
|
|
216
212
|
PreviewCreativeInteractiveResponse = PreviewCreativeResponse2
|
|
217
213
|
"""Preview response with interactive renders (iframe embedding)."""
|
|
218
214
|
|
|
219
|
-
# Preview Render
|
|
215
|
+
# Preview Render Aliases (discriminated union by output_format)
|
|
220
216
|
UrlPreviewRender = PreviewRender1
|
|
221
|
-
"""Preview render with output_format='url'
|
|
217
|
+
"""Preview render with output_format='url' and preview_url for iframe embedding."""
|
|
222
218
|
|
|
223
219
|
HtmlPreviewRender = PreviewRender2
|
|
224
|
-
"""Preview render with output_format='html'
|
|
220
|
+
"""Preview render with output_format='html' and preview_html for direct embedding."""
|
|
225
221
|
|
|
226
222
|
BothPreviewRender = PreviewRender3
|
|
227
|
-
"""Preview render with output_format='both'
|
|
223
|
+
"""Preview render with output_format='both' and both preview_url and preview_html."""
|
|
228
224
|
|
|
229
225
|
# ============================================================================
|
|
230
226
|
# ASSET TYPE ALIASES - Delivery & Kind Discriminated Unions
|
|
@@ -700,9 +696,6 @@ __all__ = [
|
|
|
700
696
|
# Activation responses
|
|
701
697
|
"ActivateSignalSuccessResponse",
|
|
702
698
|
"ActivateSignalErrorResponse",
|
|
703
|
-
# Activation keys
|
|
704
|
-
"PropertyIdActivationKey",
|
|
705
|
-
"PropertyTagActivationKey",
|
|
706
699
|
# Asset type aliases
|
|
707
700
|
"BothPreviewRender",
|
|
708
701
|
"HtmlPreviewRender",
|
adcp/types/base.py
CHANGED
|
@@ -204,7 +204,7 @@ class AdCPBaseModel(BaseModel):
|
|
|
204
204
|
kwargs["exclude_none"] = True
|
|
205
205
|
return super().model_dump_json(**kwargs)
|
|
206
206
|
|
|
207
|
-
def
|
|
207
|
+
def model_summary(self) -> str:
|
|
208
208
|
"""Human-readable summary for protocol responses.
|
|
209
209
|
|
|
210
210
|
Returns a standardized human-readable message suitable for MCP tool
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: adagents.json
|
|
3
|
-
# timestamp: 2026-01-
|
|
3
|
+
# timestamp: 2026-01-26T13:22:19+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -59,6 +59,12 @@ class Contact(AdCPBaseModel):
|
|
|
59
59
|
min_length=1,
|
|
60
60
|
),
|
|
61
61
|
]
|
|
62
|
+
privacy_policy_url: Annotated[
|
|
63
|
+
AnyUrl | None,
|
|
64
|
+
Field(
|
|
65
|
+
description="URL to the entity's privacy policy. Used for consumer consent flows when interacting with this sales agent."
|
|
66
|
+
),
|
|
67
|
+
] = None
|
|
62
68
|
seller_id: Annotated[
|
|
63
69
|
str | None,
|
|
64
70
|
Field(
|
|
@@ -77,6 +83,32 @@ class Contact(AdCPBaseModel):
|
|
|
77
83
|
] = None
|
|
78
84
|
|
|
79
85
|
|
|
86
|
+
class PropertyFeature(AdCPBaseModel):
|
|
87
|
+
model_config = ConfigDict(
|
|
88
|
+
extra='allow',
|
|
89
|
+
)
|
|
90
|
+
features: Annotated[
|
|
91
|
+
list[str],
|
|
92
|
+
Field(
|
|
93
|
+
description="Feature IDs this agent provides (e.g., 'carbon_score', 'tag_certified_against_fraud'). Use list_property_features on the agent for full definitions.",
|
|
94
|
+
min_length=1,
|
|
95
|
+
),
|
|
96
|
+
]
|
|
97
|
+
name: Annotated[
|
|
98
|
+
str,
|
|
99
|
+
Field(
|
|
100
|
+
description="Human-readable name of the vendor/agent (e.g., 'Scope3', 'TAG', 'OneTrust')"
|
|
101
|
+
),
|
|
102
|
+
]
|
|
103
|
+
publisher_id: Annotated[
|
|
104
|
+
str | None, Field(description='Optional publisher identifier at this agent (for lookup)')
|
|
105
|
+
] = None
|
|
106
|
+
url: Annotated[
|
|
107
|
+
AnyUrl,
|
|
108
|
+
Field(description="The agent's API endpoint URL (must implement get_property_features)"),
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
|
|
80
112
|
class Tags(AdCPBaseModel):
|
|
81
113
|
model_config = ConfigDict(
|
|
82
114
|
extra='allow',
|
|
@@ -223,6 +255,12 @@ class AuthorizedSalesAgents2(AdCPBaseModel):
|
|
|
223
255
|
min_length=1,
|
|
224
256
|
),
|
|
225
257
|
] = None
|
|
258
|
+
property_features: Annotated[
|
|
259
|
+
list[PropertyFeature] | None,
|
|
260
|
+
Field(
|
|
261
|
+
description="[AdCP 3.0] Optional list of agents that provide property feature data (certifications, scores, compliance status). Used for discovery - actual data comes from querying the agent's get_property_features task."
|
|
262
|
+
),
|
|
263
|
+
] = None
|
|
226
264
|
tags: Annotated[
|
|
227
265
|
dict[str, Tags] | None,
|
|
228
266
|
Field(
|
|
@@ -238,12 +276,12 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
|
|
|
238
276
|
description='Declaration of authorized sales agents for advertising inventory. Hosted at /.well-known/adagents.json on publisher domains. Can either contain the full structure inline or reference an authoritative URL.',
|
|
239
277
|
examples=[
|
|
240
278
|
{
|
|
241
|
-
'$schema': '/schemas/
|
|
279
|
+
'$schema': '/schemas/3.0.0-beta.1/adagents.json',
|
|
242
280
|
'authoritative_location': 'https://cdn.example.com/adagents/v2/adagents.json',
|
|
243
281
|
'last_updated': '2025-01-15T10:00:00Z',
|
|
244
282
|
},
|
|
245
283
|
{
|
|
246
|
-
'$schema': '/schemas/
|
|
284
|
+
'$schema': '/schemas/3.0.0-beta.1/adagents.json',
|
|
247
285
|
'authorized_agents': [
|
|
248
286
|
{
|
|
249
287
|
'authorization_type': 'property_tags',
|
|
@@ -269,7 +307,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
|
|
|
269
307
|
},
|
|
270
308
|
},
|
|
271
309
|
{
|
|
272
|
-
'$schema': '/schemas/
|
|
310
|
+
'$schema': '/schemas/3.0.0-beta.1/adagents.json',
|
|
273
311
|
'authorized_agents': [
|
|
274
312
|
{
|
|
275
313
|
'authorization_type': 'property_tags',
|
|
@@ -282,6 +320,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
|
|
|
282
320
|
'domain': 'meta.com',
|
|
283
321
|
'email': 'adops@meta.com',
|
|
284
322
|
'name': 'Meta Advertising Operations',
|
|
323
|
+
'privacy_policy_url': 'https://www.meta.com/privacy/policy',
|
|
285
324
|
'seller_id': 'pub-meta-12345',
|
|
286
325
|
'tag_id': '12345',
|
|
287
326
|
},
|
|
@@ -334,7 +373,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
|
|
|
334
373
|
},
|
|
335
374
|
},
|
|
336
375
|
{
|
|
337
|
-
'$schema': '/schemas/
|
|
376
|
+
'$schema': '/schemas/3.0.0-beta.1/adagents.json',
|
|
338
377
|
'authorized_agents': [
|
|
339
378
|
{
|
|
340
379
|
'authorization_type': 'property_tags',
|
|
@@ -362,7 +401,7 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
|
|
|
362
401
|
},
|
|
363
402
|
},
|
|
364
403
|
{
|
|
365
|
-
'$schema': '/schemas/
|
|
404
|
+
'$schema': '/schemas/3.0.0-beta.1/adagents.json',
|
|
366
405
|
'authorized_agents': [
|
|
367
406
|
{
|
|
368
407
|
'authorization_type': 'publisher_properties',
|
|
@@ -401,6 +440,64 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg
|
|
|
401
440
|
},
|
|
402
441
|
'last_updated': '2025-01-10T17:00:00Z',
|
|
403
442
|
},
|
|
443
|
+
{
|
|
444
|
+
'$schema': '/schemas/3.0.0-beta.1/adagents.json',
|
|
445
|
+
'authorized_agents': [
|
|
446
|
+
{
|
|
447
|
+
'authorization_type': 'property_tags',
|
|
448
|
+
'authorized_for': 'All news properties',
|
|
449
|
+
'property_tags': ['news'],
|
|
450
|
+
'url': 'https://sales.news.example.com',
|
|
451
|
+
}
|
|
452
|
+
],
|
|
453
|
+
'contact': {
|
|
454
|
+
'domain': 'news.example.com',
|
|
455
|
+
'email': 'adops@news.example.com',
|
|
456
|
+
'name': 'Premium News Publisher',
|
|
457
|
+
},
|
|
458
|
+
'last_updated': '2025-01-10T18:00:00Z',
|
|
459
|
+
'properties': [
|
|
460
|
+
{
|
|
461
|
+
'identifiers': [{'type': 'domain', 'value': 'news.example.com'}],
|
|
462
|
+
'name': 'News Example',
|
|
463
|
+
'property_type': 'website',
|
|
464
|
+
'publisher_domain': 'news.example.com',
|
|
465
|
+
'tags': ['premium', 'news'],
|
|
466
|
+
}
|
|
467
|
+
],
|
|
468
|
+
'property_features': [
|
|
469
|
+
{
|
|
470
|
+
'features': ['carbon_score', 'sustainability_grade'],
|
|
471
|
+
'name': 'Scope3',
|
|
472
|
+
'publisher_id': 'pub_news_12345',
|
|
473
|
+
'url': 'https://api.scope3.com',
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
'features': [
|
|
477
|
+
'tag_certified_against_fraud',
|
|
478
|
+
'tag_brand_safety_certified',
|
|
479
|
+
],
|
|
480
|
+
'name': 'TAG',
|
|
481
|
+
'url': 'https://api.tagtoday.net',
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
'features': ['gdpr_compliant', 'tcf_registered', 'ccpa_compliant'],
|
|
485
|
+
'name': 'OneTrust',
|
|
486
|
+
'publisher_id': 'ot_news_67890',
|
|
487
|
+
'url': 'https://api.onetrust.com',
|
|
488
|
+
},
|
|
489
|
+
],
|
|
490
|
+
'tags': {
|
|
491
|
+
'news': {
|
|
492
|
+
'description': 'News and journalism content',
|
|
493
|
+
'name': 'News Properties',
|
|
494
|
+
},
|
|
495
|
+
'premium': {
|
|
496
|
+
'description': 'High-quality, brand-safe properties',
|
|
497
|
+
'name': 'Premium Properties',
|
|
498
|
+
},
|
|
499
|
+
},
|
|
500
|
+
},
|
|
404
501
|
],
|
|
405
502
|
title='Authorized Sales Agents',
|
|
406
503
|
),
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: content_standards/artifact.json
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Annotated, Any, Literal
|
|
9
|
+
|
|
10
|
+
from adcp.types.base import AdCPBaseModel
|
|
11
|
+
from pydantic import AnyUrl, AwareDatetime, ConfigDict, Field, RootModel
|
|
12
|
+
|
|
13
|
+
from ..core import format_id as format_id_1
|
|
14
|
+
from ..core import identifier
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Role(Enum):
|
|
18
|
+
title_ = 'title'
|
|
19
|
+
paragraph = 'paragraph'
|
|
20
|
+
heading = 'heading'
|
|
21
|
+
caption = 'caption'
|
|
22
|
+
quote = 'quote'
|
|
23
|
+
list_item = 'list_item'
|
|
24
|
+
description = 'description'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Assets(AdCPBaseModel):
|
|
28
|
+
content: Annotated[str, Field(description='Text content')]
|
|
29
|
+
heading_level: Annotated[
|
|
30
|
+
int | None, Field(description='Heading level (1-6), only for role=heading', ge=1, le=6)
|
|
31
|
+
] = None
|
|
32
|
+
language: Annotated[
|
|
33
|
+
str | None,
|
|
34
|
+
Field(
|
|
35
|
+
description="BCP 47 language tag for this text (e.g., 'en', 'es-MX'). Useful when artifact contains mixed-language content."
|
|
36
|
+
),
|
|
37
|
+
] = None
|
|
38
|
+
role: Annotated[
|
|
39
|
+
Role | None,
|
|
40
|
+
Field(
|
|
41
|
+
description="Role of this text in the document. Use 'title' for the main artifact title, 'description' for summaries."
|
|
42
|
+
),
|
|
43
|
+
] = None
|
|
44
|
+
type: Literal['text']
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TranscriptSource(Enum):
|
|
48
|
+
original_script = 'original_script'
|
|
49
|
+
subtitles = 'subtitles'
|
|
50
|
+
closed_captions = 'closed_captions'
|
|
51
|
+
dub = 'dub'
|
|
52
|
+
generated = 'generated'
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class TranscriptSource1(Enum):
|
|
56
|
+
original_script = 'original_script'
|
|
57
|
+
closed_captions = 'closed_captions'
|
|
58
|
+
generated = 'generated'
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class Identifiers(AdCPBaseModel):
|
|
62
|
+
model_config = ConfigDict(
|
|
63
|
+
extra='allow',
|
|
64
|
+
)
|
|
65
|
+
apple_podcast_id: Annotated[str | None, Field(description='Apple Podcasts ID')] = None
|
|
66
|
+
podcast_guid: Annotated[str | None, Field(description='Podcast GUID (from RSS feed)')] = None
|
|
67
|
+
rss_url: Annotated[AnyUrl | None, Field(description='RSS feed URL')] = None
|
|
68
|
+
spotify_show_id: Annotated[str | None, Field(description='Spotify show ID')] = None
|
|
69
|
+
youtube_video_id: Annotated[str | None, Field(description='YouTube video ID')] = None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class Metadata(AdCPBaseModel):
|
|
73
|
+
model_config = ConfigDict(
|
|
74
|
+
extra='allow',
|
|
75
|
+
)
|
|
76
|
+
author: Annotated[str | None, Field(description='Artifact author name')] = None
|
|
77
|
+
canonical: Annotated[AnyUrl | None, Field(description='Canonical URL')] = None
|
|
78
|
+
json_ld: Annotated[
|
|
79
|
+
list[dict[str, Any]] | None, Field(description='JSON-LD structured data (schema.org)')
|
|
80
|
+
] = None
|
|
81
|
+
keywords: Annotated[str | None, Field(description='Artifact keywords')] = None
|
|
82
|
+
open_graph: Annotated[
|
|
83
|
+
dict[str, Any] | None, Field(description='Open Graph protocol metadata')
|
|
84
|
+
] = None
|
|
85
|
+
twitter_card: Annotated[dict[str, Any] | None, Field(description='Twitter Card metadata')] = (
|
|
86
|
+
None
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class AssetAccess1(AdCPBaseModel):
|
|
91
|
+
method: Literal['bearer_token']
|
|
92
|
+
token: Annotated[str, Field(description='OAuth2 bearer token for Authorization header')]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class Provider(Enum):
|
|
96
|
+
gcp = 'gcp'
|
|
97
|
+
aws = 'aws'
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class AssetAccess2(AdCPBaseModel):
|
|
101
|
+
credentials: Annotated[
|
|
102
|
+
dict[str, Any] | None, Field(description='Service account credentials')
|
|
103
|
+
] = None
|
|
104
|
+
method: Literal['service_account']
|
|
105
|
+
provider: Annotated[Provider, Field(description='Cloud provider')]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class AssetAccess3(AdCPBaseModel):
|
|
109
|
+
method: Literal['signed_url']
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class AssetAccess(RootModel[AssetAccess1 | AssetAccess2 | AssetAccess3]):
|
|
113
|
+
root: Annotated[
|
|
114
|
+
AssetAccess1 | AssetAccess2 | AssetAccess3,
|
|
115
|
+
Field(description='Authentication for accessing secured asset URLs'),
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class Assets1(AdCPBaseModel):
|
|
120
|
+
access: Annotated[AssetAccess | None, Field(description='Authentication for secured URLs')] = (
|
|
121
|
+
None
|
|
122
|
+
)
|
|
123
|
+
alt_text: Annotated[str | None, Field(description='Alt text or image description')] = None
|
|
124
|
+
caption: Annotated[str | None, Field(description='Image caption')] = None
|
|
125
|
+
height: Annotated[int | None, Field(description='Image height in pixels')] = None
|
|
126
|
+
type: Literal['image']
|
|
127
|
+
url: Annotated[AnyUrl, Field(description='Image URL')]
|
|
128
|
+
width: Annotated[int | None, Field(description='Image width in pixels')] = None
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class Assets2(AdCPBaseModel):
|
|
132
|
+
access: Annotated[AssetAccess | None, Field(description='Authentication for secured URLs')] = (
|
|
133
|
+
None
|
|
134
|
+
)
|
|
135
|
+
duration_ms: Annotated[int | None, Field(description='Video duration in milliseconds')] = None
|
|
136
|
+
thumbnail_url: Annotated[AnyUrl | None, Field(description='Video thumbnail URL')] = None
|
|
137
|
+
transcript: Annotated[str | None, Field(description='Video transcript')] = None
|
|
138
|
+
transcript_source: Annotated[
|
|
139
|
+
TranscriptSource | None, Field(description='How the transcript was generated')
|
|
140
|
+
] = None
|
|
141
|
+
type: Literal['video']
|
|
142
|
+
url: Annotated[AnyUrl, Field(description='Video URL')]
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class Assets3(AdCPBaseModel):
|
|
146
|
+
access: Annotated[AssetAccess | None, Field(description='Authentication for secured URLs')] = (
|
|
147
|
+
None
|
|
148
|
+
)
|
|
149
|
+
duration_ms: Annotated[int | None, Field(description='Audio duration in milliseconds')] = None
|
|
150
|
+
transcript: Annotated[str | None, Field(description='Audio transcript')] = None
|
|
151
|
+
transcript_source: Annotated[
|
|
152
|
+
TranscriptSource1 | None, Field(description='How the transcript was generated')
|
|
153
|
+
] = None
|
|
154
|
+
type: Literal['audio']
|
|
155
|
+
url: Annotated[AnyUrl, Field(description='Audio URL')]
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class Artifact(AdCPBaseModel):
|
|
159
|
+
model_config = ConfigDict(
|
|
160
|
+
extra='allow',
|
|
161
|
+
)
|
|
162
|
+
artifact_id: Annotated[
|
|
163
|
+
str,
|
|
164
|
+
Field(
|
|
165
|
+
description="Identifier for this artifact within the property. The property owner defines the scheme (e.g., 'article_12345', 'episode_42_segment_3', 'post_abc123')."
|
|
166
|
+
),
|
|
167
|
+
]
|
|
168
|
+
assets: Annotated[
|
|
169
|
+
list[Assets | Assets1 | Assets2 | Assets3],
|
|
170
|
+
Field(
|
|
171
|
+
description='Artifact assets in document flow order - text blocks, images, video, audio'
|
|
172
|
+
),
|
|
173
|
+
]
|
|
174
|
+
format_id: Annotated[
|
|
175
|
+
format_id_1.FormatId | None,
|
|
176
|
+
Field(
|
|
177
|
+
description='Optional reference to a format definition. Uses the same format registry as creative formats.'
|
|
178
|
+
),
|
|
179
|
+
] = None
|
|
180
|
+
identifiers: Annotated[
|
|
181
|
+
Identifiers | None, Field(description='Platform-specific identifiers for this artifact')
|
|
182
|
+
] = None
|
|
183
|
+
last_update_time: Annotated[
|
|
184
|
+
AwareDatetime | None,
|
|
185
|
+
Field(description='When the artifact was last modified (ISO 8601 format)'),
|
|
186
|
+
] = None
|
|
187
|
+
metadata: Annotated[
|
|
188
|
+
Metadata | None, Field(description='Rich metadata extracted from the artifact')
|
|
189
|
+
] = None
|
|
190
|
+
property_id: Annotated[
|
|
191
|
+
identifier.Identifier,
|
|
192
|
+
Field(description='Identifier for the property where this artifact appears'),
|
|
193
|
+
]
|
|
194
|
+
published_time: Annotated[
|
|
195
|
+
AwareDatetime | None, Field(description='When the artifact was published (ISO 8601 format)')
|
|
196
|
+
] = None
|
|
197
|
+
url: Annotated[
|
|
198
|
+
AnyUrl | None,
|
|
199
|
+
Field(
|
|
200
|
+
description='Optional URL for this artifact (web page, podcast feed, video page). Not all artifacts have URLs (e.g., Instagram content, podcast segments, TV scenes).'
|
|
201
|
+
),
|
|
202
|
+
] = None
|
|
203
|
+
variant_id: Annotated[
|
|
204
|
+
str | None,
|
|
205
|
+
Field(
|
|
206
|
+
description="Identifies a specific variant of this artifact. Use for A/B tests, translations, or temporal versions. Examples: 'en', 'es-MX', 'v2', 'headline_test_b'. The combination of artifact_id + variant_id must be unique."
|
|
207
|
+
),
|
|
208
|
+
] = None
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: content_standards/artifact_webhook_payload.json
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
from adcp.types.base import AdCPBaseModel
|
|
10
|
+
from pydantic import AwareDatetime, ConfigDict, Field
|
|
11
|
+
|
|
12
|
+
from ..core import ext as ext_1
|
|
13
|
+
from . import artifact as artifact_1
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Pagination(AdCPBaseModel):
|
|
17
|
+
batch_number: Annotated[int | None, Field(description='Current batch number (1-indexed)')] = (
|
|
18
|
+
None
|
|
19
|
+
)
|
|
20
|
+
total_artifacts: Annotated[
|
|
21
|
+
int | None, Field(description='Total artifacts in the delivery period')
|
|
22
|
+
] = None
|
|
23
|
+
total_batches: Annotated[
|
|
24
|
+
int | None, Field(description='Total batches for this delivery period')
|
|
25
|
+
] = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Artifact(AdCPBaseModel):
|
|
29
|
+
artifact: Annotated[artifact_1.Artifact, Field(description='The content artifact')]
|
|
30
|
+
delivered_at: Annotated[
|
|
31
|
+
AwareDatetime, Field(description='When the impression was delivered (ISO 8601)')
|
|
32
|
+
]
|
|
33
|
+
impression_id: Annotated[
|
|
34
|
+
str | None,
|
|
35
|
+
Field(description='Optional impression identifier for correlation with delivery reports'),
|
|
36
|
+
] = None
|
|
37
|
+
package_id: Annotated[
|
|
38
|
+
str | None, Field(description='Package within the media buy this artifact relates to')
|
|
39
|
+
] = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ArtifactWebhookPayload(AdCPBaseModel):
|
|
43
|
+
model_config = ConfigDict(
|
|
44
|
+
extra='allow',
|
|
45
|
+
)
|
|
46
|
+
artifacts: Annotated[
|
|
47
|
+
list[Artifact], Field(description='Content artifacts from delivered impressions')
|
|
48
|
+
]
|
|
49
|
+
batch_id: Annotated[
|
|
50
|
+
str,
|
|
51
|
+
Field(
|
|
52
|
+
description='Unique identifier for this batch of artifacts. Use for deduplication and acknowledgment.'
|
|
53
|
+
),
|
|
54
|
+
]
|
|
55
|
+
ext: ext_1.ExtensionObject | None = None
|
|
56
|
+
media_buy_id: Annotated[
|
|
57
|
+
str, Field(description='Media buy identifier these artifacts belong to')
|
|
58
|
+
]
|
|
59
|
+
pagination: Annotated[
|
|
60
|
+
Pagination | None, Field(description='Pagination info when batching large artifact sets')
|
|
61
|
+
] = None
|
|
62
|
+
timestamp: Annotated[
|
|
63
|
+
AwareDatetime, Field(description='When this batch was generated (ISO 8601)')
|
|
64
|
+
]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: content_standards/calibrate_content_request.json
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
from adcp.types.base import AdCPBaseModel
|
|
10
|
+
from pydantic import Field
|
|
11
|
+
|
|
12
|
+
from . import artifact as artifact_1
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CalibrateContentRequest(AdCPBaseModel):
|
|
16
|
+
artifact: Annotated[artifact_1.Artifact, Field(description='Artifact to evaluate')]
|
|
17
|
+
standards_id: Annotated[str, Field(description='Standards configuration to calibrate against')]
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: content_standards/calibrate_content_response.json
|
|
3
|
+
# timestamp: 2026-01-25T21:17:54+00:00
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import Annotated, Any
|
|
9
|
+
|
|
10
|
+
from adcp.types.base import AdCPBaseModel
|
|
11
|
+
from pydantic import Field, RootModel
|
|
12
|
+
|
|
13
|
+
from ..core import error
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Status(Enum):
|
|
17
|
+
passed = 'passed'
|
|
18
|
+
failed = 'failed'
|
|
19
|
+
warning = 'warning'
|
|
20
|
+
unevaluated = 'unevaluated'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Feature(AdCPBaseModel):
|
|
24
|
+
explanation: Annotated[
|
|
25
|
+
str | None,
|
|
26
|
+
Field(description='Human-readable explanation of why this feature passed or failed'),
|
|
27
|
+
] = None
|
|
28
|
+
feature_id: Annotated[
|
|
29
|
+
str,
|
|
30
|
+
Field(
|
|
31
|
+
description='Which feature was evaluated (e.g., brand_safety, brand_suitability, competitor_adjacency)'
|
|
32
|
+
),
|
|
33
|
+
]
|
|
34
|
+
status: Annotated[Status, Field(description='Evaluation status for this feature')]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Verdict(Enum):
|
|
38
|
+
pass_ = 'pass'
|
|
39
|
+
fail = 'fail'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class CalibrateContentResponse1(AdCPBaseModel):
|
|
43
|
+
confidence: Annotated[
|
|
44
|
+
float | None, Field(description='Model confidence in the verdict (0-1)', ge=0.0, le=1.0)
|
|
45
|
+
] = None
|
|
46
|
+
errors: Annotated[
|
|
47
|
+
Any | None, Field(description='Field must not be present in success response')
|
|
48
|
+
] = None
|
|
49
|
+
explanation: Annotated[
|
|
50
|
+
str | None, Field(description='Detailed natural language explanation of the decision')
|
|
51
|
+
] = None
|
|
52
|
+
features: Annotated[
|
|
53
|
+
list[Feature] | None, Field(description='Per-feature breakdown with explanations')
|
|
54
|
+
] = None
|
|
55
|
+
verdict: Annotated[
|
|
56
|
+
Verdict, Field(description='Overall pass/fail verdict for the content evaluation')
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class CalibrateContentResponse2(AdCPBaseModel):
|
|
61
|
+
errors: list[error.Error]
|
|
62
|
+
verdict: Annotated[
|
|
63
|
+
Any | None, Field(description='Field must not be present in error response')
|
|
64
|
+
] = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class CalibrateContentResponse(RootModel[CalibrateContentResponse1 | CalibrateContentResponse2]):
|
|
68
|
+
root: Annotated[
|
|
69
|
+
CalibrateContentResponse1 | CalibrateContentResponse2,
|
|
70
|
+
Field(
|
|
71
|
+
description='Response payload with verdict and detailed explanations for collaborative calibration',
|
|
72
|
+
title='Calibrate Content Response',
|
|
73
|
+
),
|
|
74
|
+
]
|