e2a 5.2.0__tar.gz → 5.3.0__tar.gz
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.
- {e2a-5.2.0 → e2a-5.3.0}/CHANGELOG.md +32 -12
- {e2a-5.2.0 → e2a-5.3.0}/PKG-INFO +34 -7
- {e2a-5.2.0 → e2a-5.3.0}/README.md +33 -6
- {e2a-5.2.0 → e2a-5.3.0}/pyproject.toml +2 -2
- {e2a-5.2.0 → e2a-5.3.0}/scripts/generate-oag.sh +4 -3
- {e2a-5.2.0 → e2a-5.3.0}/scripts/strip-enum-validators.py +16 -5
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/__init__.py +2 -0
- e2a-5.3.0/src/e2a/v1/_event_lifecycle.py +44 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/client.py +51 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/__init__.py +4 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/messages_api.py +311 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/__init__.py +2 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/domain_suppression_added_data.py +11 -1
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/email_bounced_data.py +11 -1
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/email_complained_data.py +11 -1
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/email_delivered_data.py +11 -1
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/email_failed_data.py +11 -1
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/email_received_data.py +11 -1
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/email_sent_data.py +11 -1
- e2a-5.3.0/src/e2a/v1/generated/models/message_lifecycle_transition.py +156 -0
- e2a-5.3.0/src/e2a/v1/generated/models/page_message_lifecycle_transition.py +115 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/webhook_signature.py +43 -14
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/websocket.py +12 -13
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_contract.py +283 -11
- e2a-5.3.0/tests/test_enum_forward_compat.py +167 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_client.py +95 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_sync_client.py +57 -2
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_websocket.py +81 -1
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_webhook_payloads.py +120 -1
- e2a-5.3.0/tests/typecheck_event_envelope.py +84 -0
- e2a-5.3.0/tests/typecheck_lifecycle_payloads.py +47 -0
- e2a-5.2.0/tests/test_enum_forward_compat.py +0 -64
- e2a-5.2.0/tests/typecheck_event_envelope.py +0 -36
- {e2a-5.2.0 → e2a-5.3.0}/.gitignore +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/__init__.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/py.typed +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/_retry.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/errors.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/__init__.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/account_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/agents_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/conversations_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/domains_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/events_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/meta_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/reviews_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/templates_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api/webhooks_api.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api_client.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/api_response.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/configuration.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/exceptions.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/account_user_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/account_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/agent_identity.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/agent_suppression_added_data.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/agent_suppression_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/agent_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/api_key_export_entry.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/api_key_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/approve_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/attachment.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/attachment_meta_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/attachment_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/authentication.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/conversation_detail_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/conversation_summary_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/create_agent_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/create_agent_suppression_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/create_api_key_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/create_api_key_response.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/create_template_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/create_webhook_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/create_webhook_response.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_agent_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_api_key_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_domain_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_message_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_suppression_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_template_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_user_data_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delete_webhook_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/delivery_status_json.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/deployment_info_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/dkim_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/dmarc_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/dns_record.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/domain.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/domain_sending_failed_data.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/domain_sending_verified_data.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/domain_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/error_body.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/error_envelope.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/event_envelope.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/event_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/field_error.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/forward_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/hold_reason_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/limit_exceeded_details.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/limit_exceeded_envelope.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/limit_exceeded_error_body.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/limits_caps_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/limits_usage_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/message.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/message_body_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/message_parsed_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/message_summary_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/message_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/o_auth_connection_entry.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_agent_suppression_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_agent_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_api_key_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_conversation_summary_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_domain_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_event_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_message_summary_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_review_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_starter_template_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_suppression_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_template_summary_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_webhook_delivery_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/page_webhook_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/payload_too_large_details.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_config_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_config_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_direction_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_direction_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_event_export_entry.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_finding_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_gate_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_gate_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_holds_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_holds_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_scan_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/protection_scan_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/rate_limited_details.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/rate_limited_envelope.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/rate_limited_error_body.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/redeliver_delivery.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/redeliver_event_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/redeliver_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/register_domain_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/reject_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/reject_result_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/rendered_template_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/reply_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/retry_after_details.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/review_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/rotate_secret_response.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/send_email_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/send_result_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/sending_ramp_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/spf_result.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/starter_template_detail_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/starter_template_variable_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/starter_template_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/suppression_export_entry.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/suppression_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/template_part_error.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/template_summary_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/template_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/test_webhook_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/test_webhook_response.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/threat_category_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/too_many_recipients_details.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/unsubscribe_options.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/update_agent_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/update_message_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/update_message_result_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/update_template_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/update_webhook_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/usage_event_entry.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/user_export.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/user_export_user.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/validate_template_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/validate_template_response.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/validation_error_details.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/verify_domain_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/webhook_delivery_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/webhook_filters_request.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/webhook_filters_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/models/webhook_view.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/py.typed +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/generated/rest.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/inbound.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/pagination.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/py.typed +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/src/e2a/v1/sync_client.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/__init__.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_e2e.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_exports.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_client_side_validation.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_errors.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_inbound.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_pagination.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_v1_retry.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/test_webhook_signature.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/tests/typecheck_inbound.py +0 -0
- {e2a-5.2.0 → e2a-5.3.0}/uv.lock +0 -0
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 5.3.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **`client.messages.delete(email, message_id, *, permanent=False)`** — move a
|
|
7
|
+
message to the trash, reversible via `client.messages.restore(...)` until the
|
|
8
|
+
trash retention window expires (30 days by default), so the soft delete needs
|
|
9
|
+
no confirmation. Pass `permanent=True` to delete forever a message that is
|
|
10
|
+
already in the trash (irreversible, account scope only; the SDK supplies the
|
|
11
|
+
`?confirm=DELETE` guard the raw API requires on that path). Available on both
|
|
12
|
+
`AsyncE2AClient` and the synchronous `E2AClient`.
|
|
13
|
+
- **`client.messages.get_lifecycle(email, message_id, *, cursor=None, limit=None)`**
|
|
14
|
+
— page through a message's canonical lifecycle transitions (send, delivery,
|
|
15
|
+
bounce, review, deletion, …) as `PageMessageLifecycleTransition`. Beta.
|
|
16
|
+
|
|
17
|
+
## 5.2.0
|
|
18
|
+
|
|
19
|
+
The first publish to PyPI since 4.0.1: 5.0.0, 5.1.0, and 5.2.0 all reach users
|
|
20
|
+
in this release, so read those three sections together when upgrading from 4.x.
|
|
4
21
|
|
|
5
22
|
### Added
|
|
6
23
|
- `client.inbound.from_event(event)` returns `AsyncInboundEmail` on
|
|
@@ -41,20 +58,23 @@
|
|
|
41
58
|
``EventJSON`` → ``EventView``, ``Suppression`` → ``SuppressionView``,
|
|
42
59
|
``Result`` → ``AuthVerdict``, ``AttachmentMeta`` → ``AttachmentMetaView``.
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
(PEP 8 trailing underscore) on generated models** (was the generator-mangled
|
|
49
|
-
`var_from`). Affected models: `Message`, `MessageView`, `MessageSummaryView`,
|
|
50
|
-
`ReviewView`, `EmailReceivedData`, `EmailSentData`, `EmailFailedData`
|
|
51
|
-
(generated), plus the generated `list_messages` sender filter parameter. The
|
|
61
|
+
- **The reserved-word wire field `from` is exposed as `from_` (PEP 8 trailing
|
|
62
|
+
underscore) where a sender is still projected** (was the generator-mangled
|
|
63
|
+
`var_from`). This is the generated `list_messages` sender filter parameter
|
|
64
|
+
and the outbound-only `EmailSentData` / `EmailFailedData` models; the
|
|
52
65
|
hand-written layer's `messages.list(from_=...)` already used `from_`, so the
|
|
53
|
-
SDK
|
|
66
|
+
SDK teaches exactly one spelling, and the TypeScript SDK exposes the same
|
|
54
67
|
`from_`. The wire JSON is unchanged — requests and responses still carry
|
|
55
68
|
`from` (pydantic alias). The webhook/WS `data` payload TypedDicts are
|
|
56
|
-
wire-true dicts and keep the literal `"from"` key (access as
|
|
57
|
-
|
|
69
|
+
wire-true dicts and keep the literal `"from"` key (access as `data["from"]`).
|
|
70
|
+
|
|
71
|
+
An intermediate step on `main` also renamed the *inbound* sender projection
|
|
72
|
+
on `Message`, `MessageView`, `MessageSummaryView`, `ReviewView`, and
|
|
73
|
+
`EmailReceivedData` from `var_from` to `from_`. The DMARC-aligned contract
|
|
74
|
+
above replaced that projection with `header_from` before this release, so
|
|
75
|
+
`from_` never reached PyPI on those models and there is nothing to migrate
|
|
76
|
+
off — 4.x callers reading `message.var_from` go straight to
|
|
77
|
+
`message.header_from`.
|
|
58
78
|
|
|
59
79
|
## 5.1.0
|
|
60
80
|
|
{e2a-5.2.0 → e2a-5.3.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: e2a
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.3.0
|
|
4
4
|
Summary: Python SDK for the e2a protocol — email-to-agent authentication
|
|
5
5
|
Project-URL: Homepage, https://e2a.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/tokencanopy/e2a
|
|
@@ -141,6 +141,10 @@ retries + idempotency, and async auto-pagination.
|
|
|
141
141
|
|
|
142
142
|
## Quick Start
|
|
143
143
|
|
|
144
|
+
For signed-webhook examples that fetch and reply through the ergonomic inbound
|
|
145
|
+
facade, see the [minimal Python and TypeScript OpenAI examples with provider
|
|
146
|
+
snippets](../../examples/agent-framework-webhooks/README.md).
|
|
147
|
+
|
|
144
148
|
### Synchronous
|
|
145
149
|
|
|
146
150
|
```python
|
|
@@ -264,7 +268,11 @@ async def webhook(request):
|
|
|
264
268
|
# From, Reply-To, bodies, and attachment names/types are untrusted input.
|
|
265
269
|
print(email.envelope_from, email.verified, email.subject, email.text)
|
|
266
270
|
print("reply will target", email.reply_targets)
|
|
267
|
-
|
|
271
|
+
agent_thread_id = await get_or_create_agent_thread(email.conversation_id)
|
|
272
|
+
result = await email.reply(
|
|
273
|
+
{"text": "Got it", "conversation_id": agent_thread_id},
|
|
274
|
+
idempotency_key=f"reply:{event.id}",
|
|
275
|
+
)
|
|
268
276
|
if result.status == "pending_review":
|
|
269
277
|
print("reply is awaiting approval")
|
|
270
278
|
return {"ok": True}
|
|
@@ -375,18 +383,29 @@ page = client.messages.list("bot@agents.e2a.dev", limit=100).page()
|
|
|
375
383
|
|
|
376
384
|
### Trash and restore
|
|
377
385
|
|
|
378
|
-
|
|
379
|
-
trash with `deleted=True`, then restore
|
|
380
|
-
sync client exposes the same methods
|
|
386
|
+
`delete()` is a soft delete: agents and messages move to the trash and stay
|
|
387
|
+
restorable for about 30 days. List the trash with `deleted=True`, then restore
|
|
388
|
+
an item through the same resource. The sync client exposes the same methods
|
|
389
|
+
without `await`.
|
|
381
390
|
|
|
382
391
|
```python
|
|
392
|
+
await client.agents.delete("bot@agents.e2a.dev")
|
|
383
393
|
trashed_agents = client.agents.list(deleted=True)
|
|
384
394
|
await client.agents.restore("bot@agents.e2a.dev")
|
|
385
395
|
|
|
396
|
+
await client.messages.delete("bot@agents.e2a.dev", "msg_abc123")
|
|
386
397
|
trashed_messages = client.messages.list("bot@agents.e2a.dev", deleted=True)
|
|
387
398
|
await client.messages.restore("bot@agents.e2a.dev", "msg_abc123")
|
|
388
399
|
```
|
|
389
400
|
|
|
401
|
+
A message already in the trash can be purged early and irreversibly. That path
|
|
402
|
+
needs an account-scoped credential; the SDK supplies the API's `?confirm=DELETE`
|
|
403
|
+
guard for you:
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
await client.messages.delete("bot@agents.e2a.dev", "msg_abc123", permanent=True)
|
|
407
|
+
```
|
|
408
|
+
|
|
390
409
|
## WebSocket (real-time delivery for local agents)
|
|
391
410
|
|
|
392
411
|
```python
|
|
@@ -427,8 +446,16 @@ e2a surfaces it on the recipient's inbound — via `In-Reply-To` for humans, or
|
|
|
427
446
|
forge-resistant `X-E2A-Conversation-Id` header for same-platform agent-to-agent
|
|
428
447
|
mail. It is not a security boundary; for sender-domain authentication require
|
|
429
448
|
`message.authentication is not None and message.authentication.dmarc.status == "pass"`
|
|
430
|
-
and compare the literal `message.header_from` address separately. On first
|
|
431
|
-
conversation ID arrives `None
|
|
449
|
+
and compare the literal `message.header_from` address separately. On first
|
|
450
|
+
contact from a human the conversation ID arrives `None`. Create the agent
|
|
451
|
+
runtime's internal thread before replying, then pass its stable, non-sensitive
|
|
452
|
+
thread/session ID (or an opaque stored alias) as `conversation_id`; reuse it on
|
|
453
|
+
every later send or reply. If a later inbound ID matches a binding you
|
|
454
|
+
previously stored, resume that internal thread. Keep replying by the original
|
|
455
|
+
message ID as well — the conversation ID aligns e2a grouping with agent memory,
|
|
456
|
+
while the reply endpoint sets the email headers Gmail/Outlook use. Scope
|
|
457
|
+
bindings to the inbox and sender, and never use the conversation ID as
|
|
458
|
+
authorization.
|
|
432
459
|
|
|
433
460
|
```python
|
|
434
461
|
await client.messages.send(address, {
|
|
@@ -103,6 +103,10 @@ retries + idempotency, and async auto-pagination.
|
|
|
103
103
|
|
|
104
104
|
## Quick Start
|
|
105
105
|
|
|
106
|
+
For signed-webhook examples that fetch and reply through the ergonomic inbound
|
|
107
|
+
facade, see the [minimal Python and TypeScript OpenAI examples with provider
|
|
108
|
+
snippets](../../examples/agent-framework-webhooks/README.md).
|
|
109
|
+
|
|
106
110
|
### Synchronous
|
|
107
111
|
|
|
108
112
|
```python
|
|
@@ -226,7 +230,11 @@ async def webhook(request):
|
|
|
226
230
|
# From, Reply-To, bodies, and attachment names/types are untrusted input.
|
|
227
231
|
print(email.envelope_from, email.verified, email.subject, email.text)
|
|
228
232
|
print("reply will target", email.reply_targets)
|
|
229
|
-
|
|
233
|
+
agent_thread_id = await get_or_create_agent_thread(email.conversation_id)
|
|
234
|
+
result = await email.reply(
|
|
235
|
+
{"text": "Got it", "conversation_id": agent_thread_id},
|
|
236
|
+
idempotency_key=f"reply:{event.id}",
|
|
237
|
+
)
|
|
230
238
|
if result.status == "pending_review":
|
|
231
239
|
print("reply is awaiting approval")
|
|
232
240
|
return {"ok": True}
|
|
@@ -337,18 +345,29 @@ page = client.messages.list("bot@agents.e2a.dev", limit=100).page()
|
|
|
337
345
|
|
|
338
346
|
### Trash and restore
|
|
339
347
|
|
|
340
|
-
|
|
341
|
-
trash with `deleted=True`, then restore
|
|
342
|
-
sync client exposes the same methods
|
|
348
|
+
`delete()` is a soft delete: agents and messages move to the trash and stay
|
|
349
|
+
restorable for about 30 days. List the trash with `deleted=True`, then restore
|
|
350
|
+
an item through the same resource. The sync client exposes the same methods
|
|
351
|
+
without `await`.
|
|
343
352
|
|
|
344
353
|
```python
|
|
354
|
+
await client.agents.delete("bot@agents.e2a.dev")
|
|
345
355
|
trashed_agents = client.agents.list(deleted=True)
|
|
346
356
|
await client.agents.restore("bot@agents.e2a.dev")
|
|
347
357
|
|
|
358
|
+
await client.messages.delete("bot@agents.e2a.dev", "msg_abc123")
|
|
348
359
|
trashed_messages = client.messages.list("bot@agents.e2a.dev", deleted=True)
|
|
349
360
|
await client.messages.restore("bot@agents.e2a.dev", "msg_abc123")
|
|
350
361
|
```
|
|
351
362
|
|
|
363
|
+
A message already in the trash can be purged early and irreversibly. That path
|
|
364
|
+
needs an account-scoped credential; the SDK supplies the API's `?confirm=DELETE`
|
|
365
|
+
guard for you:
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
await client.messages.delete("bot@agents.e2a.dev", "msg_abc123", permanent=True)
|
|
369
|
+
```
|
|
370
|
+
|
|
352
371
|
## WebSocket (real-time delivery for local agents)
|
|
353
372
|
|
|
354
373
|
```python
|
|
@@ -389,8 +408,16 @@ e2a surfaces it on the recipient's inbound — via `In-Reply-To` for humans, or
|
|
|
389
408
|
forge-resistant `X-E2A-Conversation-Id` header for same-platform agent-to-agent
|
|
390
409
|
mail. It is not a security boundary; for sender-domain authentication require
|
|
391
410
|
`message.authentication is not None and message.authentication.dmarc.status == "pass"`
|
|
392
|
-
and compare the literal `message.header_from` address separately. On first
|
|
393
|
-
conversation ID arrives `None
|
|
411
|
+
and compare the literal `message.header_from` address separately. On first
|
|
412
|
+
contact from a human the conversation ID arrives `None`. Create the agent
|
|
413
|
+
runtime's internal thread before replying, then pass its stable, non-sensitive
|
|
414
|
+
thread/session ID (or an opaque stored alias) as `conversation_id`; reuse it on
|
|
415
|
+
every later send or reply. If a later inbound ID matches a binding you
|
|
416
|
+
previously stored, resume that internal thread. Keep replying by the original
|
|
417
|
+
message ID as well — the conversation ID aligns e2a grouping with agent memory,
|
|
418
|
+
while the reply endpoint sets the email headers Gmail/Outlook use. Scope
|
|
419
|
+
bindings to the inbox and sender, and never use the conversation ID as
|
|
420
|
+
authorization.
|
|
394
421
|
|
|
395
422
|
```python
|
|
396
423
|
await client.messages.send(address, {
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "e2a"
|
|
7
|
-
version = "5.
|
|
7
|
+
version = "5.3.0"
|
|
8
8
|
description = "Python SDK for the e2a protocol — email-to-agent authentication"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -51,7 +51,7 @@ ws = ["websockets>=14"]
|
|
|
51
51
|
|
|
52
52
|
[tool.mypy]
|
|
53
53
|
python_version = "3.9"
|
|
54
|
-
files = ["tests/test_e2e.py", "tests/typecheck_event_envelope.py", "tests/typecheck_inbound.py"]
|
|
54
|
+
files = ["tests/test_e2e.py", "tests/typecheck_event_envelope.py", "tests/typecheck_inbound.py", "tests/typecheck_lifecycle_payloads.py"]
|
|
55
55
|
follow_imports = "silent"
|
|
56
56
|
show_error_codes = true
|
|
57
57
|
warn_unused_ignores = true
|
|
@@ -46,9 +46,10 @@ rm -rf "$DEST"
|
|
|
46
46
|
cp -r "$TMP/e2a/v1/generated" "$DEST"
|
|
47
47
|
rm -rf "$TMP"
|
|
48
48
|
|
|
49
|
-
# Strip the generator's `*_validate_enum` validators
|
|
50
|
-
#
|
|
51
|
-
#
|
|
49
|
+
# Strip the generator's `*_validate_enum` validators from open response
|
|
50
|
+
# vocabularies so the client tolerates additive values. The post-processor
|
|
51
|
+
# preserves validators for the canonical, deliberately closed message
|
|
52
|
+
# lifecycle vocabulary.
|
|
52
53
|
python3 "$ROOT/sdks/python/scripts/strip-enum-validators.py" "$DEST"
|
|
53
54
|
|
|
54
55
|
# Normalize selected generator-known unused imports without making hand edits
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Strip OpenAPI-Generator's
|
|
3
|
-
generated models so the client tolerates unknown enum values.
|
|
2
|
+
"""Strip OpenAPI-Generator's open-set enum validators from generated models.
|
|
4
3
|
|
|
5
4
|
Why: the generator emits, for every enum-typed field, a `@field_validator` that
|
|
6
5
|
raises `ValueError` when the value isn't in a hard-coded set. On a RESPONSE
|
|
7
6
|
field that means the day the server adds a new enum value (a new event `type`,
|
|
8
7
|
`delivery_status`, `inbound_policy`, …) every deployed client crashes while
|
|
9
8
|
deserializing — turning an additive, non-breaking server change into a
|
|
10
|
-
client-breaking one. The TypeScript SDK passes unknown enum values
|
|
11
|
-
untouched; this makes Python match, keeping
|
|
9
|
+
client-breaking one. The TypeScript SDK passes unknown open-set enum values
|
|
10
|
+
through untouched; this makes Python match, keeping those fields typed as
|
|
11
|
+
plain strings.
|
|
12
|
+
|
|
13
|
+
The canonical ``MessageLifecycleTransition`` vocabulary is deliberately
|
|
14
|
+
closed and versioned. Its generated validators are retained so Python enforces
|
|
15
|
+
the same direction, stage, outcome, and reason-code contract as the API.
|
|
12
16
|
|
|
13
17
|
Run as part of generate-oag.sh (so the drift gate's regenerated output matches)
|
|
14
18
|
and idempotently re-runnable on the committed tree. Removes each block of the
|
|
@@ -30,6 +34,9 @@ import re
|
|
|
30
34
|
import sys
|
|
31
35
|
|
|
32
36
|
|
|
37
|
+
CLOSED_ENUM_MODELS = {"message_lifecycle_transition.py"}
|
|
38
|
+
|
|
39
|
+
|
|
33
40
|
def strip_file(path: str) -> bool:
|
|
34
41
|
with open(path, "r", encoding="utf-8") as f:
|
|
35
42
|
lines = f.readlines()
|
|
@@ -81,7 +88,11 @@ def main() -> int:
|
|
|
81
88
|
root = sys.argv[1] if len(sys.argv) > 1 else os.path.join(
|
|
82
89
|
os.path.dirname(__file__), "..", "src", "e2a", "v1", "generated"
|
|
83
90
|
)
|
|
84
|
-
models =
|
|
91
|
+
models = [
|
|
92
|
+
path
|
|
93
|
+
for path in glob.glob(os.path.join(root, "models", "*.py"))
|
|
94
|
+
if os.path.basename(path) not in CLOSED_ENUM_MODELS
|
|
95
|
+
]
|
|
85
96
|
touched = sum(1 for p in sorted(models) if strip_file(p))
|
|
86
97
|
print(f"strip-enum-validators: removed enum validators from {touched} model file(s)")
|
|
87
98
|
return 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Shared lifecycle coercion for v1 stable event envelopes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict
|
|
6
|
+
|
|
7
|
+
from .generated.models import MessageLifecycleTransition
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
_V1_STABLE_LIFECYCLE_EVENTS = {
|
|
11
|
+
"email.received",
|
|
12
|
+
"email.sent",
|
|
13
|
+
"email.failed",
|
|
14
|
+
"email.delivered",
|
|
15
|
+
"email.bounced",
|
|
16
|
+
"email.complained",
|
|
17
|
+
"domain.suppression_added",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def coerce_v1_stable_lifecycle(
|
|
22
|
+
schema_version: str,
|
|
23
|
+
event_type: str,
|
|
24
|
+
data: Dict[str, Any],
|
|
25
|
+
) -> Dict[str, Any]:
|
|
26
|
+
"""Return typed lifecycle rows only for the closed v1 stable contract.
|
|
27
|
+
|
|
28
|
+
When the field is absent—or the envelope version/type is outside that
|
|
29
|
+
contract—the original data object is returned unchanged. When present, a
|
|
30
|
+
shallow copy keeps ``event.raw`` as the original wire representation.
|
|
31
|
+
"""
|
|
32
|
+
if (
|
|
33
|
+
schema_version != "1"
|
|
34
|
+
or event_type not in _V1_STABLE_LIFECYCLE_EVENTS
|
|
35
|
+
or "lifecycle_transitions" not in data
|
|
36
|
+
):
|
|
37
|
+
return data
|
|
38
|
+
|
|
39
|
+
coerced = dict(data)
|
|
40
|
+
coerced["lifecycle_transitions"] = [
|
|
41
|
+
MessageLifecycleTransition.model_validate(row)
|
|
42
|
+
for row in data["lifecycle_transitions"]
|
|
43
|
+
]
|
|
44
|
+
return coerced
|
|
@@ -45,6 +45,7 @@ from .generated.models import (
|
|
|
45
45
|
DeleteAgentResult,
|
|
46
46
|
DeleteApiKeyResult,
|
|
47
47
|
DeleteDomainResult,
|
|
48
|
+
DeleteMessageResult,
|
|
48
49
|
DeleteSuppressionResult,
|
|
49
50
|
DeleteTemplateResult,
|
|
50
51
|
DeleteUserDataResult,
|
|
@@ -56,6 +57,7 @@ from .generated.models import (
|
|
|
56
57
|
AccountView,
|
|
57
58
|
AttachmentView,
|
|
58
59
|
MessageSummaryView,
|
|
60
|
+
PageMessageLifecycleTransition,
|
|
59
61
|
MessageView,
|
|
60
62
|
RedeliverEventRequest,
|
|
61
63
|
RedeliverView,
|
|
@@ -477,6 +479,55 @@ class MessagesResource:
|
|
|
477
479
|
async def get(self, email: str, message_id: str) -> MessageView:
|
|
478
480
|
return await self._c._read(lambda h: self._api.get_message(email, message_id, _headers=h))
|
|
479
481
|
|
|
482
|
+
async def get_lifecycle(
|
|
483
|
+
self,
|
|
484
|
+
email: str,
|
|
485
|
+
message_id: str,
|
|
486
|
+
*,
|
|
487
|
+
cursor: Optional[str] = None,
|
|
488
|
+
limit: Optional[int] = None,
|
|
489
|
+
) -> PageMessageLifecycleTransition:
|
|
490
|
+
"""Beta: return the ordered observations e2a recorded for one message.
|
|
491
|
+
|
|
492
|
+
The lifecycle contract may change before it is declared stable.
|
|
493
|
+
"""
|
|
494
|
+
return await self._c._read(
|
|
495
|
+
lambda h: self._api.get_message_lifecycle(
|
|
496
|
+
email,
|
|
497
|
+
message_id,
|
|
498
|
+
cursor=cursor,
|
|
499
|
+
limit=limit,
|
|
500
|
+
_headers=h,
|
|
501
|
+
)
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
async def delete(
|
|
505
|
+
self, email: str, message_id: str, *, permanent: bool = False
|
|
506
|
+
) -> DeleteMessageResult:
|
|
507
|
+
"""Move a message to the trash.
|
|
508
|
+
|
|
509
|
+
Reversible via ``restore()`` until the trash retention window expires
|
|
510
|
+
(30 days by default), so the default soft delete needs no confirmation.
|
|
511
|
+
|
|
512
|
+
Pass ``permanent=True`` to permanently delete a message that is ALREADY
|
|
513
|
+
in the trash ("delete forever") — irreversible, account scope only. The
|
|
514
|
+
typed .delete() call is the confirmation; the SDK supplies the
|
|
515
|
+
?confirm=DELETE guard the raw API requires on that path (it is ignored
|
|
516
|
+
when permanent is unset).
|
|
517
|
+
|
|
518
|
+
A message held for review cannot be deleted (409 message_held) — resolve
|
|
519
|
+
it on the review queue first. Returns the deletion receipt
|
|
520
|
+
({deleted, id}).
|
|
521
|
+
"""
|
|
522
|
+
return await self._c._write_idempotent(
|
|
523
|
+
lambda h: self._api.delete_message(
|
|
524
|
+
# `permanent or None` omits the param entirely on the soft path,
|
|
525
|
+
# matching the TS SDK's wire shape (the server treats an absent
|
|
526
|
+
# and a false `permanent` identically).
|
|
527
|
+
email, message_id, permanent=permanent or None, confirm="DELETE", _headers=h
|
|
528
|
+
)
|
|
529
|
+
)
|
|
530
|
+
|
|
480
531
|
async def restore(self, email: str, message_id: str) -> MessageView:
|
|
481
532
|
"""Restore a soft-deleted message and resume its retention clock."""
|
|
482
533
|
return await self._c._write_unsafe(
|
|
@@ -97,6 +97,7 @@ __all__ = [
|
|
|
97
97
|
"LimitsUsageView",
|
|
98
98
|
"Message",
|
|
99
99
|
"MessageBodyView",
|
|
100
|
+
"MessageLifecycleTransition",
|
|
100
101
|
"MessageParsedView",
|
|
101
102
|
"MessageSummaryView",
|
|
102
103
|
"MessageView",
|
|
@@ -107,6 +108,7 @@ __all__ = [
|
|
|
107
108
|
"PageConversationSummaryView",
|
|
108
109
|
"PageDomainView",
|
|
109
110
|
"PageEventView",
|
|
111
|
+
"PageMessageLifecycleTransition",
|
|
110
112
|
"PageMessageSummaryView",
|
|
111
113
|
"PageReviewView",
|
|
112
114
|
"PageStarterTemplateView",
|
|
@@ -260,6 +262,7 @@ from e2a.v1.generated.models.limits_caps_view import LimitsCapsView as LimitsCap
|
|
|
260
262
|
from e2a.v1.generated.models.limits_usage_view import LimitsUsageView as LimitsUsageView
|
|
261
263
|
from e2a.v1.generated.models.message import Message as Message
|
|
262
264
|
from e2a.v1.generated.models.message_body_view import MessageBodyView as MessageBodyView
|
|
265
|
+
from e2a.v1.generated.models.message_lifecycle_transition import MessageLifecycleTransition as MessageLifecycleTransition
|
|
263
266
|
from e2a.v1.generated.models.message_parsed_view import MessageParsedView as MessageParsedView
|
|
264
267
|
from e2a.v1.generated.models.message_summary_view import MessageSummaryView as MessageSummaryView
|
|
265
268
|
from e2a.v1.generated.models.message_view import MessageView as MessageView
|
|
@@ -270,6 +273,7 @@ from e2a.v1.generated.models.page_agent_view import PageAgentView as PageAgentVi
|
|
|
270
273
|
from e2a.v1.generated.models.page_conversation_summary_view import PageConversationSummaryView as PageConversationSummaryView
|
|
271
274
|
from e2a.v1.generated.models.page_domain_view import PageDomainView as PageDomainView
|
|
272
275
|
from e2a.v1.generated.models.page_event_view import PageEventView as PageEventView
|
|
276
|
+
from e2a.v1.generated.models.page_message_lifecycle_transition import PageMessageLifecycleTransition as PageMessageLifecycleTransition
|
|
273
277
|
from e2a.v1.generated.models.page_message_summary_view import PageMessageSummaryView as PageMessageSummaryView
|
|
274
278
|
from e2a.v1.generated.models.page_review_view import PageReviewView as PageReviewView
|
|
275
279
|
from e2a.v1.generated.models.page_starter_template_view import PageStarterTemplateView as PageStarterTemplateView
|